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.1 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 "tcg/tcg-op.h"
28 #include "exec/cpu_ldst.h"
29 #include "exec/helper-proto.h"
30 #include "exec/helper-gen.h"
31 #include "hw/semihosting/semihost.h"
33 #include "target/mips/trace.h"
34 #include "trace-tcg.h"
35 #include "exec/translator.h"
37 #include "qemu/qemu-print.h"
39 #define MIPS_DEBUG_DISAS 0
41 /* MIPS major opcodes */
42 #define MASK_OP_MAJOR(op) (op & (0x3F << 26))
45 /* indirect opcode tables */
46 OPC_SPECIAL
= (0x00 << 26),
47 OPC_REGIMM
= (0x01 << 26),
48 OPC_CP0
= (0x10 << 26),
49 OPC_CP1
= (0x11 << 26),
50 OPC_CP2
= (0x12 << 26),
51 OPC_CP3
= (0x13 << 26),
52 OPC_SPECIAL2
= (0x1C << 26),
53 OPC_SPECIAL3
= (0x1F << 26),
54 /* arithmetic with immediate */
55 OPC_ADDI
= (0x08 << 26),
56 OPC_ADDIU
= (0x09 << 26),
57 OPC_SLTI
= (0x0A << 26),
58 OPC_SLTIU
= (0x0B << 26),
59 /* logic with immediate */
60 OPC_ANDI
= (0x0C << 26),
61 OPC_ORI
= (0x0D << 26),
62 OPC_XORI
= (0x0E << 26),
63 OPC_LUI
= (0x0F << 26),
64 /* arithmetic with immediate */
65 OPC_DADDI
= (0x18 << 26),
66 OPC_DADDIU
= (0x19 << 26),
67 /* Jump and branches */
69 OPC_JAL
= (0x03 << 26),
70 OPC_BEQ
= (0x04 << 26), /* Unconditional if rs = rt = 0 (B) */
71 OPC_BEQL
= (0x14 << 26),
72 OPC_BNE
= (0x05 << 26),
73 OPC_BNEL
= (0x15 << 26),
74 OPC_BLEZ
= (0x06 << 26),
75 OPC_BLEZL
= (0x16 << 26),
76 OPC_BGTZ
= (0x07 << 26),
77 OPC_BGTZL
= (0x17 << 26),
78 OPC_JALX
= (0x1D << 26),
79 OPC_DAUI
= (0x1D << 26),
81 OPC_LDL
= (0x1A << 26),
82 OPC_LDR
= (0x1B << 26),
83 OPC_LB
= (0x20 << 26),
84 OPC_LH
= (0x21 << 26),
85 OPC_LWL
= (0x22 << 26),
86 OPC_LW
= (0x23 << 26),
87 OPC_LWPC
= OPC_LW
| 0x5,
88 OPC_LBU
= (0x24 << 26),
89 OPC_LHU
= (0x25 << 26),
90 OPC_LWR
= (0x26 << 26),
91 OPC_LWU
= (0x27 << 26),
92 OPC_SB
= (0x28 << 26),
93 OPC_SH
= (0x29 << 26),
94 OPC_SWL
= (0x2A << 26),
95 OPC_SW
= (0x2B << 26),
96 OPC_SDL
= (0x2C << 26),
97 OPC_SDR
= (0x2D << 26),
98 OPC_SWR
= (0x2E << 26),
99 OPC_LL
= (0x30 << 26),
100 OPC_LLD
= (0x34 << 26),
101 OPC_LD
= (0x37 << 26),
102 OPC_LDPC
= OPC_LD
| 0x5,
103 OPC_SC
= (0x38 << 26),
104 OPC_SCD
= (0x3C << 26),
105 OPC_SD
= (0x3F << 26),
106 /* Floating point load/store */
107 OPC_LWC1
= (0x31 << 26),
108 OPC_LWC2
= (0x32 << 26),
109 OPC_LDC1
= (0x35 << 26),
110 OPC_LDC2
= (0x36 << 26),
111 OPC_SWC1
= (0x39 << 26),
112 OPC_SWC2
= (0x3A << 26),
113 OPC_SDC1
= (0x3D << 26),
114 OPC_SDC2
= (0x3E << 26),
115 /* Compact Branches */
116 OPC_BLEZALC
= (0x06 << 26),
117 OPC_BGEZALC
= (0x06 << 26),
118 OPC_BGEUC
= (0x06 << 26),
119 OPC_BGTZALC
= (0x07 << 26),
120 OPC_BLTZALC
= (0x07 << 26),
121 OPC_BLTUC
= (0x07 << 26),
122 OPC_BOVC
= (0x08 << 26),
123 OPC_BEQZALC
= (0x08 << 26),
124 OPC_BEQC
= (0x08 << 26),
125 OPC_BLEZC
= (0x16 << 26),
126 OPC_BGEZC
= (0x16 << 26),
127 OPC_BGEC
= (0x16 << 26),
128 OPC_BGTZC
= (0x17 << 26),
129 OPC_BLTZC
= (0x17 << 26),
130 OPC_BLTC
= (0x17 << 26),
131 OPC_BNVC
= (0x18 << 26),
132 OPC_BNEZALC
= (0x18 << 26),
133 OPC_BNEC
= (0x18 << 26),
134 OPC_BC
= (0x32 << 26),
135 OPC_BEQZC
= (0x36 << 26),
136 OPC_JIC
= (0x36 << 26),
137 OPC_BALC
= (0x3A << 26),
138 OPC_BNEZC
= (0x3E << 26),
139 OPC_JIALC
= (0x3E << 26),
140 /* MDMX ASE specific */
141 OPC_MDMX
= (0x1E << 26),
142 /* MSA ASE, same as MDMX */
144 /* Cache and prefetch */
145 OPC_CACHE
= (0x2F << 26),
146 OPC_PREF
= (0x33 << 26),
147 /* PC-relative address computation / loads */
148 OPC_PCREL
= (0x3B << 26),
151 /* PC-relative address computation / loads */
152 #define MASK_OPC_PCREL_TOP2BITS(op) (MASK_OP_MAJOR(op) | (op & (3 << 19)))
153 #define MASK_OPC_PCREL_TOP5BITS(op) (MASK_OP_MAJOR(op) | (op & (0x1f << 16)))
155 /* Instructions determined by bits 19 and 20 */
156 OPC_ADDIUPC
= OPC_PCREL
| (0 << 19),
157 R6_OPC_LWPC
= OPC_PCREL
| (1 << 19),
158 OPC_LWUPC
= OPC_PCREL
| (2 << 19),
160 /* Instructions determined by bits 16 ... 20 */
161 OPC_AUIPC
= OPC_PCREL
| (0x1e << 16),
162 OPC_ALUIPC
= OPC_PCREL
| (0x1f << 16),
165 R6_OPC_LDPC
= OPC_PCREL
| (6 << 18),
168 /* MIPS special opcodes */
169 #define MASK_SPECIAL(op) (MASK_OP_MAJOR(op) | (op & 0x3F))
173 OPC_SLL
= 0x00 | OPC_SPECIAL
,
174 /* NOP is SLL r0, r0, 0 */
175 /* SSNOP is SLL r0, r0, 1 */
176 /* EHB is SLL r0, r0, 3 */
177 OPC_SRL
= 0x02 | OPC_SPECIAL
, /* also ROTR */
178 OPC_ROTR
= OPC_SRL
| (1 << 21),
179 OPC_SRA
= 0x03 | OPC_SPECIAL
,
180 OPC_SLLV
= 0x04 | OPC_SPECIAL
,
181 OPC_SRLV
= 0x06 | OPC_SPECIAL
, /* also ROTRV */
182 OPC_ROTRV
= OPC_SRLV
| (1 << 6),
183 OPC_SRAV
= 0x07 | OPC_SPECIAL
,
184 OPC_DSLLV
= 0x14 | OPC_SPECIAL
,
185 OPC_DSRLV
= 0x16 | OPC_SPECIAL
, /* also DROTRV */
186 OPC_DROTRV
= OPC_DSRLV
| (1 << 6),
187 OPC_DSRAV
= 0x17 | OPC_SPECIAL
,
188 OPC_DSLL
= 0x38 | OPC_SPECIAL
,
189 OPC_DSRL
= 0x3A | OPC_SPECIAL
, /* also DROTR */
190 OPC_DROTR
= OPC_DSRL
| (1 << 21),
191 OPC_DSRA
= 0x3B | OPC_SPECIAL
,
192 OPC_DSLL32
= 0x3C | OPC_SPECIAL
,
193 OPC_DSRL32
= 0x3E | OPC_SPECIAL
, /* also DROTR32 */
194 OPC_DROTR32
= OPC_DSRL32
| (1 << 21),
195 OPC_DSRA32
= 0x3F | OPC_SPECIAL
,
196 /* Multiplication / division */
197 OPC_MULT
= 0x18 | OPC_SPECIAL
,
198 OPC_MULTU
= 0x19 | OPC_SPECIAL
,
199 OPC_DIV
= 0x1A | OPC_SPECIAL
,
200 OPC_DIVU
= 0x1B | OPC_SPECIAL
,
201 OPC_DMULT
= 0x1C | OPC_SPECIAL
,
202 OPC_DMULTU
= 0x1D | OPC_SPECIAL
,
203 OPC_DDIV
= 0x1E | OPC_SPECIAL
,
204 OPC_DDIVU
= 0x1F | OPC_SPECIAL
,
206 /* 2 registers arithmetic / logic */
207 OPC_ADD
= 0x20 | OPC_SPECIAL
,
208 OPC_ADDU
= 0x21 | OPC_SPECIAL
,
209 OPC_SUB
= 0x22 | OPC_SPECIAL
,
210 OPC_SUBU
= 0x23 | OPC_SPECIAL
,
211 OPC_AND
= 0x24 | OPC_SPECIAL
,
212 OPC_OR
= 0x25 | OPC_SPECIAL
,
213 OPC_XOR
= 0x26 | OPC_SPECIAL
,
214 OPC_NOR
= 0x27 | OPC_SPECIAL
,
215 OPC_SLT
= 0x2A | OPC_SPECIAL
,
216 OPC_SLTU
= 0x2B | OPC_SPECIAL
,
217 OPC_DADD
= 0x2C | OPC_SPECIAL
,
218 OPC_DADDU
= 0x2D | OPC_SPECIAL
,
219 OPC_DSUB
= 0x2E | OPC_SPECIAL
,
220 OPC_DSUBU
= 0x2F | OPC_SPECIAL
,
222 OPC_JR
= 0x08 | OPC_SPECIAL
, /* Also JR.HB */
223 OPC_JALR
= 0x09 | OPC_SPECIAL
, /* Also JALR.HB */
225 OPC_TGE
= 0x30 | OPC_SPECIAL
,
226 OPC_TGEU
= 0x31 | OPC_SPECIAL
,
227 OPC_TLT
= 0x32 | OPC_SPECIAL
,
228 OPC_TLTU
= 0x33 | OPC_SPECIAL
,
229 OPC_TEQ
= 0x34 | OPC_SPECIAL
,
230 OPC_TNE
= 0x36 | OPC_SPECIAL
,
231 /* HI / LO registers load & stores */
232 OPC_MFHI
= 0x10 | OPC_SPECIAL
,
233 OPC_MTHI
= 0x11 | OPC_SPECIAL
,
234 OPC_MFLO
= 0x12 | OPC_SPECIAL
,
235 OPC_MTLO
= 0x13 | OPC_SPECIAL
,
236 /* Conditional moves */
237 OPC_MOVZ
= 0x0A | OPC_SPECIAL
,
238 OPC_MOVN
= 0x0B | OPC_SPECIAL
,
240 OPC_SELEQZ
= 0x35 | OPC_SPECIAL
,
241 OPC_SELNEZ
= 0x37 | OPC_SPECIAL
,
243 OPC_MOVCI
= 0x01 | OPC_SPECIAL
,
246 OPC_PMON
= 0x05 | OPC_SPECIAL
, /* unofficial */
247 OPC_SYSCALL
= 0x0C | OPC_SPECIAL
,
248 OPC_BREAK
= 0x0D | OPC_SPECIAL
,
249 OPC_SPIM
= 0x0E | OPC_SPECIAL
, /* unofficial */
250 OPC_SYNC
= 0x0F | OPC_SPECIAL
,
252 OPC_SPECIAL28_RESERVED
= 0x28 | OPC_SPECIAL
,
253 OPC_SPECIAL29_RESERVED
= 0x29 | OPC_SPECIAL
,
254 OPC_SPECIAL39_RESERVED
= 0x39 | OPC_SPECIAL
,
255 OPC_SPECIAL3D_RESERVED
= 0x3D | OPC_SPECIAL
,
259 * R6 Multiply and Divide instructions have the same opcode
260 * and function field as legacy OPC_MULT[U]/OPC_DIV[U]
262 #define MASK_R6_MULDIV(op) (MASK_SPECIAL(op) | (op & (0x7ff)))
265 R6_OPC_MUL
= OPC_MULT
| (2 << 6),
266 R6_OPC_MUH
= OPC_MULT
| (3 << 6),
267 R6_OPC_MULU
= OPC_MULTU
| (2 << 6),
268 R6_OPC_MUHU
= OPC_MULTU
| (3 << 6),
269 R6_OPC_DIV
= OPC_DIV
| (2 << 6),
270 R6_OPC_MOD
= OPC_DIV
| (3 << 6),
271 R6_OPC_DIVU
= OPC_DIVU
| (2 << 6),
272 R6_OPC_MODU
= OPC_DIVU
| (3 << 6),
274 R6_OPC_DMUL
= OPC_DMULT
| (2 << 6),
275 R6_OPC_DMUH
= OPC_DMULT
| (3 << 6),
276 R6_OPC_DMULU
= OPC_DMULTU
| (2 << 6),
277 R6_OPC_DMUHU
= OPC_DMULTU
| (3 << 6),
278 R6_OPC_DDIV
= OPC_DDIV
| (2 << 6),
279 R6_OPC_DMOD
= OPC_DDIV
| (3 << 6),
280 R6_OPC_DDIVU
= OPC_DDIVU
| (2 << 6),
281 R6_OPC_DMODU
= OPC_DDIVU
| (3 << 6),
283 R6_OPC_CLZ
= 0x10 | OPC_SPECIAL
,
284 R6_OPC_CLO
= 0x11 | OPC_SPECIAL
,
285 R6_OPC_DCLZ
= 0x12 | OPC_SPECIAL
,
286 R6_OPC_DCLO
= 0x13 | OPC_SPECIAL
,
287 R6_OPC_SDBBP
= 0x0e | OPC_SPECIAL
,
289 OPC_LSA
= 0x05 | OPC_SPECIAL
,
290 OPC_DLSA
= 0x15 | OPC_SPECIAL
,
293 /* Multiplication variants of the vr54xx. */
294 #define MASK_MUL_VR54XX(op) (MASK_SPECIAL(op) | (op & (0x1F << 6)))
297 OPC_VR54XX_MULS
= (0x03 << 6) | OPC_MULT
,
298 OPC_VR54XX_MULSU
= (0x03 << 6) | OPC_MULTU
,
299 OPC_VR54XX_MACC
= (0x05 << 6) | OPC_MULT
,
300 OPC_VR54XX_MACCU
= (0x05 << 6) | OPC_MULTU
,
301 OPC_VR54XX_MSAC
= (0x07 << 6) | OPC_MULT
,
302 OPC_VR54XX_MSACU
= (0x07 << 6) | OPC_MULTU
,
303 OPC_VR54XX_MULHI
= (0x09 << 6) | OPC_MULT
,
304 OPC_VR54XX_MULHIU
= (0x09 << 6) | OPC_MULTU
,
305 OPC_VR54XX_MULSHI
= (0x0B << 6) | OPC_MULT
,
306 OPC_VR54XX_MULSHIU
= (0x0B << 6) | OPC_MULTU
,
307 OPC_VR54XX_MACCHI
= (0x0D << 6) | OPC_MULT
,
308 OPC_VR54XX_MACCHIU
= (0x0D << 6) | OPC_MULTU
,
309 OPC_VR54XX_MSACHI
= (0x0F << 6) | OPC_MULT
,
310 OPC_VR54XX_MSACHIU
= (0x0F << 6) | OPC_MULTU
,
313 /* REGIMM (rt field) opcodes */
314 #define MASK_REGIMM(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 16)))
317 OPC_BLTZ
= (0x00 << 16) | OPC_REGIMM
,
318 OPC_BLTZL
= (0x02 << 16) | OPC_REGIMM
,
319 OPC_BGEZ
= (0x01 << 16) | OPC_REGIMM
,
320 OPC_BGEZL
= (0x03 << 16) | OPC_REGIMM
,
321 OPC_BLTZAL
= (0x10 << 16) | OPC_REGIMM
,
322 OPC_BLTZALL
= (0x12 << 16) | OPC_REGIMM
,
323 OPC_BGEZAL
= (0x11 << 16) | OPC_REGIMM
,
324 OPC_BGEZALL
= (0x13 << 16) | OPC_REGIMM
,
325 OPC_TGEI
= (0x08 << 16) | OPC_REGIMM
,
326 OPC_TGEIU
= (0x09 << 16) | OPC_REGIMM
,
327 OPC_TLTI
= (0x0A << 16) | OPC_REGIMM
,
328 OPC_TLTIU
= (0x0B << 16) | OPC_REGIMM
,
329 OPC_TEQI
= (0x0C << 16) | OPC_REGIMM
,
330 OPC_TNEI
= (0x0E << 16) | OPC_REGIMM
,
331 OPC_SIGRIE
= (0x17 << 16) | OPC_REGIMM
,
332 OPC_SYNCI
= (0x1F << 16) | OPC_REGIMM
,
334 OPC_DAHI
= (0x06 << 16) | OPC_REGIMM
,
335 OPC_DATI
= (0x1e << 16) | OPC_REGIMM
,
338 /* Special2 opcodes */
339 #define MASK_SPECIAL2(op) (MASK_OP_MAJOR(op) | (op & 0x3F))
342 /* Multiply & xxx operations */
343 OPC_MADD
= 0x00 | OPC_SPECIAL2
,
344 OPC_MADDU
= 0x01 | OPC_SPECIAL2
,
345 OPC_MUL
= 0x02 | OPC_SPECIAL2
,
346 OPC_MSUB
= 0x04 | OPC_SPECIAL2
,
347 OPC_MSUBU
= 0x05 | OPC_SPECIAL2
,
349 OPC_MULT_G_2F
= 0x10 | OPC_SPECIAL2
,
350 OPC_DMULT_G_2F
= 0x11 | OPC_SPECIAL2
,
351 OPC_MULTU_G_2F
= 0x12 | OPC_SPECIAL2
,
352 OPC_DMULTU_G_2F
= 0x13 | OPC_SPECIAL2
,
353 OPC_DIV_G_2F
= 0x14 | OPC_SPECIAL2
,
354 OPC_DDIV_G_2F
= 0x15 | OPC_SPECIAL2
,
355 OPC_DIVU_G_2F
= 0x16 | OPC_SPECIAL2
,
356 OPC_DDIVU_G_2F
= 0x17 | OPC_SPECIAL2
,
357 OPC_MOD_G_2F
= 0x1c | OPC_SPECIAL2
,
358 OPC_DMOD_G_2F
= 0x1d | OPC_SPECIAL2
,
359 OPC_MODU_G_2F
= 0x1e | OPC_SPECIAL2
,
360 OPC_DMODU_G_2F
= 0x1f | OPC_SPECIAL2
,
362 OPC_CLZ
= 0x20 | OPC_SPECIAL2
,
363 OPC_CLO
= 0x21 | OPC_SPECIAL2
,
364 OPC_DCLZ
= 0x24 | OPC_SPECIAL2
,
365 OPC_DCLO
= 0x25 | OPC_SPECIAL2
,
367 OPC_SDBBP
= 0x3F | OPC_SPECIAL2
,
370 /* Special3 opcodes */
371 #define MASK_SPECIAL3(op) (MASK_OP_MAJOR(op) | (op & 0x3F))
374 OPC_EXT
= 0x00 | OPC_SPECIAL3
,
375 OPC_DEXTM
= 0x01 | OPC_SPECIAL3
,
376 OPC_DEXTU
= 0x02 | OPC_SPECIAL3
,
377 OPC_DEXT
= 0x03 | OPC_SPECIAL3
,
378 OPC_INS
= 0x04 | OPC_SPECIAL3
,
379 OPC_DINSM
= 0x05 | OPC_SPECIAL3
,
380 OPC_DINSU
= 0x06 | OPC_SPECIAL3
,
381 OPC_DINS
= 0x07 | OPC_SPECIAL3
,
382 OPC_FORK
= 0x08 | OPC_SPECIAL3
,
383 OPC_YIELD
= 0x09 | OPC_SPECIAL3
,
384 OPC_BSHFL
= 0x20 | OPC_SPECIAL3
,
385 OPC_DBSHFL
= 0x24 | OPC_SPECIAL3
,
386 OPC_RDHWR
= 0x3B | OPC_SPECIAL3
,
387 OPC_GINV
= 0x3D | OPC_SPECIAL3
,
390 OPC_MULT_G_2E
= 0x18 | OPC_SPECIAL3
,
391 OPC_MULTU_G_2E
= 0x19 | OPC_SPECIAL3
,
392 OPC_DIV_G_2E
= 0x1A | OPC_SPECIAL3
,
393 OPC_DIVU_G_2E
= 0x1B | OPC_SPECIAL3
,
394 OPC_DMULT_G_2E
= 0x1C | OPC_SPECIAL3
,
395 OPC_DMULTU_G_2E
= 0x1D | OPC_SPECIAL3
,
396 OPC_DDIV_G_2E
= 0x1E | OPC_SPECIAL3
,
397 OPC_DDIVU_G_2E
= 0x1F | OPC_SPECIAL3
,
398 OPC_MOD_G_2E
= 0x22 | OPC_SPECIAL3
,
399 OPC_MODU_G_2E
= 0x23 | OPC_SPECIAL3
,
400 OPC_DMOD_G_2E
= 0x26 | OPC_SPECIAL3
,
401 OPC_DMODU_G_2E
= 0x27 | OPC_SPECIAL3
,
404 OPC_LX_DSP
= 0x0A | OPC_SPECIAL3
,
405 /* MIPS DSP Arithmetic */
406 OPC_ADDU_QB_DSP
= 0x10 | OPC_SPECIAL3
,
407 OPC_ADDU_OB_DSP
= 0x14 | OPC_SPECIAL3
,
408 OPC_ABSQ_S_PH_DSP
= 0x12 | OPC_SPECIAL3
,
409 OPC_ABSQ_S_QH_DSP
= 0x16 | OPC_SPECIAL3
,
410 /* OPC_ADDUH_QB_DSP is same as OPC_MULT_G_2E. */
411 /* OPC_ADDUH_QB_DSP = 0x18 | OPC_SPECIAL3, */
412 OPC_CMPU_EQ_QB_DSP
= 0x11 | OPC_SPECIAL3
,
413 OPC_CMPU_EQ_OB_DSP
= 0x15 | OPC_SPECIAL3
,
414 /* MIPS DSP GPR-Based Shift Sub-class */
415 OPC_SHLL_QB_DSP
= 0x13 | OPC_SPECIAL3
,
416 OPC_SHLL_OB_DSP
= 0x17 | OPC_SPECIAL3
,
417 /* MIPS DSP Multiply Sub-class insns */
418 /* OPC_MUL_PH_DSP is same as OPC_ADDUH_QB_DSP. */
419 /* OPC_MUL_PH_DSP = 0x18 | OPC_SPECIAL3, */
420 OPC_DPA_W_PH_DSP
= 0x30 | OPC_SPECIAL3
,
421 OPC_DPAQ_W_QH_DSP
= 0x34 | OPC_SPECIAL3
,
422 /* DSP Bit/Manipulation Sub-class */
423 OPC_INSV_DSP
= 0x0C | OPC_SPECIAL3
,
424 OPC_DINSV_DSP
= 0x0D | OPC_SPECIAL3
,
425 /* MIPS DSP Append Sub-class */
426 OPC_APPEND_DSP
= 0x31 | OPC_SPECIAL3
,
427 OPC_DAPPEND_DSP
= 0x35 | OPC_SPECIAL3
,
428 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
429 OPC_EXTR_W_DSP
= 0x38 | OPC_SPECIAL3
,
430 OPC_DEXTR_W_DSP
= 0x3C | OPC_SPECIAL3
,
433 OPC_LWLE
= 0x19 | OPC_SPECIAL3
,
434 OPC_LWRE
= 0x1A | OPC_SPECIAL3
,
435 OPC_CACHEE
= 0x1B | OPC_SPECIAL3
,
436 OPC_SBE
= 0x1C | OPC_SPECIAL3
,
437 OPC_SHE
= 0x1D | OPC_SPECIAL3
,
438 OPC_SCE
= 0x1E | OPC_SPECIAL3
,
439 OPC_SWE
= 0x1F | OPC_SPECIAL3
,
440 OPC_SWLE
= 0x21 | OPC_SPECIAL3
,
441 OPC_SWRE
= 0x22 | OPC_SPECIAL3
,
442 OPC_PREFE
= 0x23 | OPC_SPECIAL3
,
443 OPC_LBUE
= 0x28 | OPC_SPECIAL3
,
444 OPC_LHUE
= 0x29 | OPC_SPECIAL3
,
445 OPC_LBE
= 0x2C | OPC_SPECIAL3
,
446 OPC_LHE
= 0x2D | OPC_SPECIAL3
,
447 OPC_LLE
= 0x2E | OPC_SPECIAL3
,
448 OPC_LWE
= 0x2F | OPC_SPECIAL3
,
451 R6_OPC_PREF
= 0x35 | OPC_SPECIAL3
,
452 R6_OPC_CACHE
= 0x25 | OPC_SPECIAL3
,
453 R6_OPC_LL
= 0x36 | OPC_SPECIAL3
,
454 R6_OPC_SC
= 0x26 | OPC_SPECIAL3
,
455 R6_OPC_LLD
= 0x37 | OPC_SPECIAL3
,
456 R6_OPC_SCD
= 0x27 | OPC_SPECIAL3
,
459 /* Loongson EXT load/store quad word opcodes */
460 #define MASK_LOONGSON_GSLSQ(op) (MASK_OP_MAJOR(op) | (op & 0x8020))
462 OPC_GSLQ
= 0x0020 | OPC_LWC2
,
463 OPC_GSLQC1
= 0x8020 | OPC_LWC2
,
464 OPC_GSSHFL
= OPC_LWC2
,
465 OPC_GSSQ
= 0x0020 | OPC_SWC2
,
466 OPC_GSSQC1
= 0x8020 | OPC_SWC2
,
467 OPC_GSSHFS
= OPC_SWC2
,
470 /* Loongson EXT shifted load/store opcodes */
471 #define MASK_LOONGSON_GSSHFLS(op) (MASK_OP_MAJOR(op) | (op & 0xc03f))
473 OPC_GSLWLC1
= 0x4 | OPC_GSSHFL
,
474 OPC_GSLWRC1
= 0x5 | OPC_GSSHFL
,
475 OPC_GSLDLC1
= 0x6 | OPC_GSSHFL
,
476 OPC_GSLDRC1
= 0x7 | OPC_GSSHFL
,
477 OPC_GSSWLC1
= 0x4 | OPC_GSSHFS
,
478 OPC_GSSWRC1
= 0x5 | OPC_GSSHFS
,
479 OPC_GSSDLC1
= 0x6 | OPC_GSSHFS
,
480 OPC_GSSDRC1
= 0x7 | OPC_GSSHFS
,
483 /* Loongson EXT LDC2/SDC2 opcodes */
484 #define MASK_LOONGSON_LSDC2(op) (MASK_OP_MAJOR(op) | (op & 0x7))
487 OPC_GSLBX
= 0x0 | OPC_LDC2
,
488 OPC_GSLHX
= 0x1 | OPC_LDC2
,
489 OPC_GSLWX
= 0x2 | OPC_LDC2
,
490 OPC_GSLDX
= 0x3 | OPC_LDC2
,
491 OPC_GSLWXC1
= 0x6 | OPC_LDC2
,
492 OPC_GSLDXC1
= 0x7 | OPC_LDC2
,
493 OPC_GSSBX
= 0x0 | OPC_SDC2
,
494 OPC_GSSHX
= 0x1 | OPC_SDC2
,
495 OPC_GSSWX
= 0x2 | OPC_SDC2
,
496 OPC_GSSDX
= 0x3 | OPC_SDC2
,
497 OPC_GSSWXC1
= 0x6 | OPC_SDC2
,
498 OPC_GSSDXC1
= 0x7 | OPC_SDC2
,
502 #define MASK_BSHFL(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
505 OPC_WSBH
= (0x02 << 6) | OPC_BSHFL
,
506 OPC_SEB
= (0x10 << 6) | OPC_BSHFL
,
507 OPC_SEH
= (0x18 << 6) | OPC_BSHFL
,
508 OPC_ALIGN
= (0x08 << 6) | OPC_BSHFL
, /* 010.bp (010.00 to 010.11) */
509 OPC_ALIGN_1
= (0x09 << 6) | OPC_BSHFL
,
510 OPC_ALIGN_2
= (0x0A << 6) | OPC_BSHFL
,
511 OPC_ALIGN_3
= (0x0B << 6) | OPC_BSHFL
,
512 OPC_BITSWAP
= (0x00 << 6) | OPC_BSHFL
/* 00000 */
516 #define MASK_DBSHFL(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
519 OPC_DSBH
= (0x02 << 6) | OPC_DBSHFL
,
520 OPC_DSHD
= (0x05 << 6) | OPC_DBSHFL
,
521 OPC_DALIGN
= (0x08 << 6) | OPC_DBSHFL
, /* 01.bp (01.000 to 01.111) */
522 OPC_DALIGN_1
= (0x09 << 6) | OPC_DBSHFL
,
523 OPC_DALIGN_2
= (0x0A << 6) | OPC_DBSHFL
,
524 OPC_DALIGN_3
= (0x0B << 6) | OPC_DBSHFL
,
525 OPC_DALIGN_4
= (0x0C << 6) | OPC_DBSHFL
,
526 OPC_DALIGN_5
= (0x0D << 6) | OPC_DBSHFL
,
527 OPC_DALIGN_6
= (0x0E << 6) | OPC_DBSHFL
,
528 OPC_DALIGN_7
= (0x0F << 6) | OPC_DBSHFL
,
529 OPC_DBITSWAP
= (0x00 << 6) | OPC_DBSHFL
, /* 00000 */
532 /* MIPS DSP REGIMM opcodes */
534 OPC_BPOSGE32
= (0x1C << 16) | OPC_REGIMM
,
535 OPC_BPOSGE64
= (0x1D << 16) | OPC_REGIMM
,
538 #define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
541 OPC_LBUX
= (0x06 << 6) | OPC_LX_DSP
,
542 OPC_LHX
= (0x04 << 6) | OPC_LX_DSP
,
543 OPC_LWX
= (0x00 << 6) | OPC_LX_DSP
,
544 OPC_LDX
= (0x08 << 6) | OPC_LX_DSP
,
547 #define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
549 /* MIPS DSP Arithmetic Sub-class */
550 OPC_ADDQ_PH
= (0x0A << 6) | OPC_ADDU_QB_DSP
,
551 OPC_ADDQ_S_PH
= (0x0E << 6) | OPC_ADDU_QB_DSP
,
552 OPC_ADDQ_S_W
= (0x16 << 6) | OPC_ADDU_QB_DSP
,
553 OPC_ADDU_QB
= (0x00 << 6) | OPC_ADDU_QB_DSP
,
554 OPC_ADDU_S_QB
= (0x04 << 6) | OPC_ADDU_QB_DSP
,
555 OPC_ADDU_PH
= (0x08 << 6) | OPC_ADDU_QB_DSP
,
556 OPC_ADDU_S_PH
= (0x0C << 6) | OPC_ADDU_QB_DSP
,
557 OPC_SUBQ_PH
= (0x0B << 6) | OPC_ADDU_QB_DSP
,
558 OPC_SUBQ_S_PH
= (0x0F << 6) | OPC_ADDU_QB_DSP
,
559 OPC_SUBQ_S_W
= (0x17 << 6) | OPC_ADDU_QB_DSP
,
560 OPC_SUBU_QB
= (0x01 << 6) | OPC_ADDU_QB_DSP
,
561 OPC_SUBU_S_QB
= (0x05 << 6) | OPC_ADDU_QB_DSP
,
562 OPC_SUBU_PH
= (0x09 << 6) | OPC_ADDU_QB_DSP
,
563 OPC_SUBU_S_PH
= (0x0D << 6) | OPC_ADDU_QB_DSP
,
564 OPC_ADDSC
= (0x10 << 6) | OPC_ADDU_QB_DSP
,
565 OPC_ADDWC
= (0x11 << 6) | OPC_ADDU_QB_DSP
,
566 OPC_MODSUB
= (0x12 << 6) | OPC_ADDU_QB_DSP
,
567 OPC_RADDU_W_QB
= (0x14 << 6) | OPC_ADDU_QB_DSP
,
568 /* MIPS DSP Multiply Sub-class insns */
569 OPC_MULEU_S_PH_QBL
= (0x06 << 6) | OPC_ADDU_QB_DSP
,
570 OPC_MULEU_S_PH_QBR
= (0x07 << 6) | OPC_ADDU_QB_DSP
,
571 OPC_MULQ_RS_PH
= (0x1F << 6) | OPC_ADDU_QB_DSP
,
572 OPC_MULEQ_S_W_PHL
= (0x1C << 6) | OPC_ADDU_QB_DSP
,
573 OPC_MULEQ_S_W_PHR
= (0x1D << 6) | OPC_ADDU_QB_DSP
,
574 OPC_MULQ_S_PH
= (0x1E << 6) | OPC_ADDU_QB_DSP
,
577 #define OPC_ADDUH_QB_DSP OPC_MULT_G_2E
578 #define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
580 /* MIPS DSP Arithmetic Sub-class */
581 OPC_ADDUH_QB
= (0x00 << 6) | OPC_ADDUH_QB_DSP
,
582 OPC_ADDUH_R_QB
= (0x02 << 6) | OPC_ADDUH_QB_DSP
,
583 OPC_ADDQH_PH
= (0x08 << 6) | OPC_ADDUH_QB_DSP
,
584 OPC_ADDQH_R_PH
= (0x0A << 6) | OPC_ADDUH_QB_DSP
,
585 OPC_ADDQH_W
= (0x10 << 6) | OPC_ADDUH_QB_DSP
,
586 OPC_ADDQH_R_W
= (0x12 << 6) | OPC_ADDUH_QB_DSP
,
587 OPC_SUBUH_QB
= (0x01 << 6) | OPC_ADDUH_QB_DSP
,
588 OPC_SUBUH_R_QB
= (0x03 << 6) | OPC_ADDUH_QB_DSP
,
589 OPC_SUBQH_PH
= (0x09 << 6) | OPC_ADDUH_QB_DSP
,
590 OPC_SUBQH_R_PH
= (0x0B << 6) | OPC_ADDUH_QB_DSP
,
591 OPC_SUBQH_W
= (0x11 << 6) | OPC_ADDUH_QB_DSP
,
592 OPC_SUBQH_R_W
= (0x13 << 6) | OPC_ADDUH_QB_DSP
,
593 /* MIPS DSP Multiply Sub-class insns */
594 OPC_MUL_PH
= (0x0C << 6) | OPC_ADDUH_QB_DSP
,
595 OPC_MUL_S_PH
= (0x0E << 6) | OPC_ADDUH_QB_DSP
,
596 OPC_MULQ_S_W
= (0x16 << 6) | OPC_ADDUH_QB_DSP
,
597 OPC_MULQ_RS_W
= (0x17 << 6) | OPC_ADDUH_QB_DSP
,
600 #define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
602 /* MIPS DSP Arithmetic Sub-class */
603 OPC_ABSQ_S_QB
= (0x01 << 6) | OPC_ABSQ_S_PH_DSP
,
604 OPC_ABSQ_S_PH
= (0x09 << 6) | OPC_ABSQ_S_PH_DSP
,
605 OPC_ABSQ_S_W
= (0x11 << 6) | OPC_ABSQ_S_PH_DSP
,
606 OPC_PRECEQ_W_PHL
= (0x0C << 6) | OPC_ABSQ_S_PH_DSP
,
607 OPC_PRECEQ_W_PHR
= (0x0D << 6) | OPC_ABSQ_S_PH_DSP
,
608 OPC_PRECEQU_PH_QBL
= (0x04 << 6) | OPC_ABSQ_S_PH_DSP
,
609 OPC_PRECEQU_PH_QBR
= (0x05 << 6) | OPC_ABSQ_S_PH_DSP
,
610 OPC_PRECEQU_PH_QBLA
= (0x06 << 6) | OPC_ABSQ_S_PH_DSP
,
611 OPC_PRECEQU_PH_QBRA
= (0x07 << 6) | OPC_ABSQ_S_PH_DSP
,
612 OPC_PRECEU_PH_QBL
= (0x1C << 6) | OPC_ABSQ_S_PH_DSP
,
613 OPC_PRECEU_PH_QBR
= (0x1D << 6) | OPC_ABSQ_S_PH_DSP
,
614 OPC_PRECEU_PH_QBLA
= (0x1E << 6) | OPC_ABSQ_S_PH_DSP
,
615 OPC_PRECEU_PH_QBRA
= (0x1F << 6) | OPC_ABSQ_S_PH_DSP
,
616 /* DSP Bit/Manipulation Sub-class */
617 OPC_BITREV
= (0x1B << 6) | OPC_ABSQ_S_PH_DSP
,
618 OPC_REPL_QB
= (0x02 << 6) | OPC_ABSQ_S_PH_DSP
,
619 OPC_REPLV_QB
= (0x03 << 6) | OPC_ABSQ_S_PH_DSP
,
620 OPC_REPL_PH
= (0x0A << 6) | OPC_ABSQ_S_PH_DSP
,
621 OPC_REPLV_PH
= (0x0B << 6) | OPC_ABSQ_S_PH_DSP
,
624 #define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
626 /* MIPS DSP Arithmetic Sub-class */
627 OPC_PRECR_QB_PH
= (0x0D << 6) | OPC_CMPU_EQ_QB_DSP
,
628 OPC_PRECRQ_QB_PH
= (0x0C << 6) | OPC_CMPU_EQ_QB_DSP
,
629 OPC_PRECR_SRA_PH_W
= (0x1E << 6) | OPC_CMPU_EQ_QB_DSP
,
630 OPC_PRECR_SRA_R_PH_W
= (0x1F << 6) | OPC_CMPU_EQ_QB_DSP
,
631 OPC_PRECRQ_PH_W
= (0x14 << 6) | OPC_CMPU_EQ_QB_DSP
,
632 OPC_PRECRQ_RS_PH_W
= (0x15 << 6) | OPC_CMPU_EQ_QB_DSP
,
633 OPC_PRECRQU_S_QB_PH
= (0x0F << 6) | OPC_CMPU_EQ_QB_DSP
,
634 /* DSP Compare-Pick Sub-class */
635 OPC_CMPU_EQ_QB
= (0x00 << 6) | OPC_CMPU_EQ_QB_DSP
,
636 OPC_CMPU_LT_QB
= (0x01 << 6) | OPC_CMPU_EQ_QB_DSP
,
637 OPC_CMPU_LE_QB
= (0x02 << 6) | OPC_CMPU_EQ_QB_DSP
,
638 OPC_CMPGU_EQ_QB
= (0x04 << 6) | OPC_CMPU_EQ_QB_DSP
,
639 OPC_CMPGU_LT_QB
= (0x05 << 6) | OPC_CMPU_EQ_QB_DSP
,
640 OPC_CMPGU_LE_QB
= (0x06 << 6) | OPC_CMPU_EQ_QB_DSP
,
641 OPC_CMPGDU_EQ_QB
= (0x18 << 6) | OPC_CMPU_EQ_QB_DSP
,
642 OPC_CMPGDU_LT_QB
= (0x19 << 6) | OPC_CMPU_EQ_QB_DSP
,
643 OPC_CMPGDU_LE_QB
= (0x1A << 6) | OPC_CMPU_EQ_QB_DSP
,
644 OPC_CMP_EQ_PH
= (0x08 << 6) | OPC_CMPU_EQ_QB_DSP
,
645 OPC_CMP_LT_PH
= (0x09 << 6) | OPC_CMPU_EQ_QB_DSP
,
646 OPC_CMP_LE_PH
= (0x0A << 6) | OPC_CMPU_EQ_QB_DSP
,
647 OPC_PICK_QB
= (0x03 << 6) | OPC_CMPU_EQ_QB_DSP
,
648 OPC_PICK_PH
= (0x0B << 6) | OPC_CMPU_EQ_QB_DSP
,
649 OPC_PACKRL_PH
= (0x0E << 6) | OPC_CMPU_EQ_QB_DSP
,
652 #define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
654 /* MIPS DSP GPR-Based Shift Sub-class */
655 OPC_SHLL_QB
= (0x00 << 6) | OPC_SHLL_QB_DSP
,
656 OPC_SHLLV_QB
= (0x02 << 6) | OPC_SHLL_QB_DSP
,
657 OPC_SHLL_PH
= (0x08 << 6) | OPC_SHLL_QB_DSP
,
658 OPC_SHLLV_PH
= (0x0A << 6) | OPC_SHLL_QB_DSP
,
659 OPC_SHLL_S_PH
= (0x0C << 6) | OPC_SHLL_QB_DSP
,
660 OPC_SHLLV_S_PH
= (0x0E << 6) | OPC_SHLL_QB_DSP
,
661 OPC_SHLL_S_W
= (0x14 << 6) | OPC_SHLL_QB_DSP
,
662 OPC_SHLLV_S_W
= (0x16 << 6) | OPC_SHLL_QB_DSP
,
663 OPC_SHRL_QB
= (0x01 << 6) | OPC_SHLL_QB_DSP
,
664 OPC_SHRLV_QB
= (0x03 << 6) | OPC_SHLL_QB_DSP
,
665 OPC_SHRL_PH
= (0x19 << 6) | OPC_SHLL_QB_DSP
,
666 OPC_SHRLV_PH
= (0x1B << 6) | OPC_SHLL_QB_DSP
,
667 OPC_SHRA_QB
= (0x04 << 6) | OPC_SHLL_QB_DSP
,
668 OPC_SHRA_R_QB
= (0x05 << 6) | OPC_SHLL_QB_DSP
,
669 OPC_SHRAV_QB
= (0x06 << 6) | OPC_SHLL_QB_DSP
,
670 OPC_SHRAV_R_QB
= (0x07 << 6) | OPC_SHLL_QB_DSP
,
671 OPC_SHRA_PH
= (0x09 << 6) | OPC_SHLL_QB_DSP
,
672 OPC_SHRAV_PH
= (0x0B << 6) | OPC_SHLL_QB_DSP
,
673 OPC_SHRA_R_PH
= (0x0D << 6) | OPC_SHLL_QB_DSP
,
674 OPC_SHRAV_R_PH
= (0x0F << 6) | OPC_SHLL_QB_DSP
,
675 OPC_SHRA_R_W
= (0x15 << 6) | OPC_SHLL_QB_DSP
,
676 OPC_SHRAV_R_W
= (0x17 << 6) | OPC_SHLL_QB_DSP
,
679 #define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
681 /* MIPS DSP Multiply Sub-class insns */
682 OPC_DPAU_H_QBL
= (0x03 << 6) | OPC_DPA_W_PH_DSP
,
683 OPC_DPAU_H_QBR
= (0x07 << 6) | OPC_DPA_W_PH_DSP
,
684 OPC_DPSU_H_QBL
= (0x0B << 6) | OPC_DPA_W_PH_DSP
,
685 OPC_DPSU_H_QBR
= (0x0F << 6) | OPC_DPA_W_PH_DSP
,
686 OPC_DPA_W_PH
= (0x00 << 6) | OPC_DPA_W_PH_DSP
,
687 OPC_DPAX_W_PH
= (0x08 << 6) | OPC_DPA_W_PH_DSP
,
688 OPC_DPAQ_S_W_PH
= (0x04 << 6) | OPC_DPA_W_PH_DSP
,
689 OPC_DPAQX_S_W_PH
= (0x18 << 6) | OPC_DPA_W_PH_DSP
,
690 OPC_DPAQX_SA_W_PH
= (0x1A << 6) | OPC_DPA_W_PH_DSP
,
691 OPC_DPS_W_PH
= (0x01 << 6) | OPC_DPA_W_PH_DSP
,
692 OPC_DPSX_W_PH
= (0x09 << 6) | OPC_DPA_W_PH_DSP
,
693 OPC_DPSQ_S_W_PH
= (0x05 << 6) | OPC_DPA_W_PH_DSP
,
694 OPC_DPSQX_S_W_PH
= (0x19 << 6) | OPC_DPA_W_PH_DSP
,
695 OPC_DPSQX_SA_W_PH
= (0x1B << 6) | OPC_DPA_W_PH_DSP
,
696 OPC_MULSAQ_S_W_PH
= (0x06 << 6) | OPC_DPA_W_PH_DSP
,
697 OPC_DPAQ_SA_L_W
= (0x0C << 6) | OPC_DPA_W_PH_DSP
,
698 OPC_DPSQ_SA_L_W
= (0x0D << 6) | OPC_DPA_W_PH_DSP
,
699 OPC_MAQ_S_W_PHL
= (0x14 << 6) | OPC_DPA_W_PH_DSP
,
700 OPC_MAQ_S_W_PHR
= (0x16 << 6) | OPC_DPA_W_PH_DSP
,
701 OPC_MAQ_SA_W_PHL
= (0x10 << 6) | OPC_DPA_W_PH_DSP
,
702 OPC_MAQ_SA_W_PHR
= (0x12 << 6) | OPC_DPA_W_PH_DSP
,
703 OPC_MULSA_W_PH
= (0x02 << 6) | OPC_DPA_W_PH_DSP
,
706 #define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
708 /* DSP Bit/Manipulation Sub-class */
709 OPC_INSV
= (0x00 << 6) | OPC_INSV_DSP
,
712 #define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
714 /* MIPS DSP Append Sub-class */
715 OPC_APPEND
= (0x00 << 6) | OPC_APPEND_DSP
,
716 OPC_PREPEND
= (0x01 << 6) | OPC_APPEND_DSP
,
717 OPC_BALIGN
= (0x10 << 6) | OPC_APPEND_DSP
,
720 #define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
722 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
723 OPC_EXTR_W
= (0x00 << 6) | OPC_EXTR_W_DSP
,
724 OPC_EXTR_R_W
= (0x04 << 6) | OPC_EXTR_W_DSP
,
725 OPC_EXTR_RS_W
= (0x06 << 6) | OPC_EXTR_W_DSP
,
726 OPC_EXTR_S_H
= (0x0E << 6) | OPC_EXTR_W_DSP
,
727 OPC_EXTRV_S_H
= (0x0F << 6) | OPC_EXTR_W_DSP
,
728 OPC_EXTRV_W
= (0x01 << 6) | OPC_EXTR_W_DSP
,
729 OPC_EXTRV_R_W
= (0x05 << 6) | OPC_EXTR_W_DSP
,
730 OPC_EXTRV_RS_W
= (0x07 << 6) | OPC_EXTR_W_DSP
,
731 OPC_EXTP
= (0x02 << 6) | OPC_EXTR_W_DSP
,
732 OPC_EXTPV
= (0x03 << 6) | OPC_EXTR_W_DSP
,
733 OPC_EXTPDP
= (0x0A << 6) | OPC_EXTR_W_DSP
,
734 OPC_EXTPDPV
= (0x0B << 6) | OPC_EXTR_W_DSP
,
735 OPC_SHILO
= (0x1A << 6) | OPC_EXTR_W_DSP
,
736 OPC_SHILOV
= (0x1B << 6) | OPC_EXTR_W_DSP
,
737 OPC_MTHLIP
= (0x1F << 6) | OPC_EXTR_W_DSP
,
738 OPC_WRDSP
= (0x13 << 6) | OPC_EXTR_W_DSP
,
739 OPC_RDDSP
= (0x12 << 6) | OPC_EXTR_W_DSP
,
742 #define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
744 /* MIPS DSP Arithmetic Sub-class */
745 OPC_PRECEQ_L_PWL
= (0x14 << 6) | OPC_ABSQ_S_QH_DSP
,
746 OPC_PRECEQ_L_PWR
= (0x15 << 6) | OPC_ABSQ_S_QH_DSP
,
747 OPC_PRECEQ_PW_QHL
= (0x0C << 6) | OPC_ABSQ_S_QH_DSP
,
748 OPC_PRECEQ_PW_QHR
= (0x0D << 6) | OPC_ABSQ_S_QH_DSP
,
749 OPC_PRECEQ_PW_QHLA
= (0x0E << 6) | OPC_ABSQ_S_QH_DSP
,
750 OPC_PRECEQ_PW_QHRA
= (0x0F << 6) | OPC_ABSQ_S_QH_DSP
,
751 OPC_PRECEQU_QH_OBL
= (0x04 << 6) | OPC_ABSQ_S_QH_DSP
,
752 OPC_PRECEQU_QH_OBR
= (0x05 << 6) | OPC_ABSQ_S_QH_DSP
,
753 OPC_PRECEQU_QH_OBLA
= (0x06 << 6) | OPC_ABSQ_S_QH_DSP
,
754 OPC_PRECEQU_QH_OBRA
= (0x07 << 6) | OPC_ABSQ_S_QH_DSP
,
755 OPC_PRECEU_QH_OBL
= (0x1C << 6) | OPC_ABSQ_S_QH_DSP
,
756 OPC_PRECEU_QH_OBR
= (0x1D << 6) | OPC_ABSQ_S_QH_DSP
,
757 OPC_PRECEU_QH_OBLA
= (0x1E << 6) | OPC_ABSQ_S_QH_DSP
,
758 OPC_PRECEU_QH_OBRA
= (0x1F << 6) | OPC_ABSQ_S_QH_DSP
,
759 OPC_ABSQ_S_OB
= (0x01 << 6) | OPC_ABSQ_S_QH_DSP
,
760 OPC_ABSQ_S_PW
= (0x11 << 6) | OPC_ABSQ_S_QH_DSP
,
761 OPC_ABSQ_S_QH
= (0x09 << 6) | OPC_ABSQ_S_QH_DSP
,
762 /* DSP Bit/Manipulation Sub-class */
763 OPC_REPL_OB
= (0x02 << 6) | OPC_ABSQ_S_QH_DSP
,
764 OPC_REPL_PW
= (0x12 << 6) | OPC_ABSQ_S_QH_DSP
,
765 OPC_REPL_QH
= (0x0A << 6) | OPC_ABSQ_S_QH_DSP
,
766 OPC_REPLV_OB
= (0x03 << 6) | OPC_ABSQ_S_QH_DSP
,
767 OPC_REPLV_PW
= (0x13 << 6) | OPC_ABSQ_S_QH_DSP
,
768 OPC_REPLV_QH
= (0x0B << 6) | OPC_ABSQ_S_QH_DSP
,
771 #define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
773 /* MIPS DSP Multiply Sub-class insns */
774 OPC_MULEQ_S_PW_QHL
= (0x1C << 6) | OPC_ADDU_OB_DSP
,
775 OPC_MULEQ_S_PW_QHR
= (0x1D << 6) | OPC_ADDU_OB_DSP
,
776 OPC_MULEU_S_QH_OBL
= (0x06 << 6) | OPC_ADDU_OB_DSP
,
777 OPC_MULEU_S_QH_OBR
= (0x07 << 6) | OPC_ADDU_OB_DSP
,
778 OPC_MULQ_RS_QH
= (0x1F << 6) | OPC_ADDU_OB_DSP
,
779 /* MIPS DSP Arithmetic Sub-class */
780 OPC_RADDU_L_OB
= (0x14 << 6) | OPC_ADDU_OB_DSP
,
781 OPC_SUBQ_PW
= (0x13 << 6) | OPC_ADDU_OB_DSP
,
782 OPC_SUBQ_S_PW
= (0x17 << 6) | OPC_ADDU_OB_DSP
,
783 OPC_SUBQ_QH
= (0x0B << 6) | OPC_ADDU_OB_DSP
,
784 OPC_SUBQ_S_QH
= (0x0F << 6) | OPC_ADDU_OB_DSP
,
785 OPC_SUBU_OB
= (0x01 << 6) | OPC_ADDU_OB_DSP
,
786 OPC_SUBU_S_OB
= (0x05 << 6) | OPC_ADDU_OB_DSP
,
787 OPC_SUBU_QH
= (0x09 << 6) | OPC_ADDU_OB_DSP
,
788 OPC_SUBU_S_QH
= (0x0D << 6) | OPC_ADDU_OB_DSP
,
789 OPC_SUBUH_OB
= (0x19 << 6) | OPC_ADDU_OB_DSP
,
790 OPC_SUBUH_R_OB
= (0x1B << 6) | OPC_ADDU_OB_DSP
,
791 OPC_ADDQ_PW
= (0x12 << 6) | OPC_ADDU_OB_DSP
,
792 OPC_ADDQ_S_PW
= (0x16 << 6) | OPC_ADDU_OB_DSP
,
793 OPC_ADDQ_QH
= (0x0A << 6) | OPC_ADDU_OB_DSP
,
794 OPC_ADDQ_S_QH
= (0x0E << 6) | OPC_ADDU_OB_DSP
,
795 OPC_ADDU_OB
= (0x00 << 6) | OPC_ADDU_OB_DSP
,
796 OPC_ADDU_S_OB
= (0x04 << 6) | OPC_ADDU_OB_DSP
,
797 OPC_ADDU_QH
= (0x08 << 6) | OPC_ADDU_OB_DSP
,
798 OPC_ADDU_S_QH
= (0x0C << 6) | OPC_ADDU_OB_DSP
,
799 OPC_ADDUH_OB
= (0x18 << 6) | OPC_ADDU_OB_DSP
,
800 OPC_ADDUH_R_OB
= (0x1A << 6) | OPC_ADDU_OB_DSP
,
803 #define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
805 /* DSP Compare-Pick Sub-class */
806 OPC_CMP_EQ_PW
= (0x10 << 6) | OPC_CMPU_EQ_OB_DSP
,
807 OPC_CMP_LT_PW
= (0x11 << 6) | OPC_CMPU_EQ_OB_DSP
,
808 OPC_CMP_LE_PW
= (0x12 << 6) | OPC_CMPU_EQ_OB_DSP
,
809 OPC_CMP_EQ_QH
= (0x08 << 6) | OPC_CMPU_EQ_OB_DSP
,
810 OPC_CMP_LT_QH
= (0x09 << 6) | OPC_CMPU_EQ_OB_DSP
,
811 OPC_CMP_LE_QH
= (0x0A << 6) | OPC_CMPU_EQ_OB_DSP
,
812 OPC_CMPGDU_EQ_OB
= (0x18 << 6) | OPC_CMPU_EQ_OB_DSP
,
813 OPC_CMPGDU_LT_OB
= (0x19 << 6) | OPC_CMPU_EQ_OB_DSP
,
814 OPC_CMPGDU_LE_OB
= (0x1A << 6) | OPC_CMPU_EQ_OB_DSP
,
815 OPC_CMPGU_EQ_OB
= (0x04 << 6) | OPC_CMPU_EQ_OB_DSP
,
816 OPC_CMPGU_LT_OB
= (0x05 << 6) | OPC_CMPU_EQ_OB_DSP
,
817 OPC_CMPGU_LE_OB
= (0x06 << 6) | OPC_CMPU_EQ_OB_DSP
,
818 OPC_CMPU_EQ_OB
= (0x00 << 6) | OPC_CMPU_EQ_OB_DSP
,
819 OPC_CMPU_LT_OB
= (0x01 << 6) | OPC_CMPU_EQ_OB_DSP
,
820 OPC_CMPU_LE_OB
= (0x02 << 6) | OPC_CMPU_EQ_OB_DSP
,
821 OPC_PACKRL_PW
= (0x0E << 6) | OPC_CMPU_EQ_OB_DSP
,
822 OPC_PICK_OB
= (0x03 << 6) | OPC_CMPU_EQ_OB_DSP
,
823 OPC_PICK_PW
= (0x13 << 6) | OPC_CMPU_EQ_OB_DSP
,
824 OPC_PICK_QH
= (0x0B << 6) | OPC_CMPU_EQ_OB_DSP
,
825 /* MIPS DSP Arithmetic Sub-class */
826 OPC_PRECR_OB_QH
= (0x0D << 6) | OPC_CMPU_EQ_OB_DSP
,
827 OPC_PRECR_SRA_QH_PW
= (0x1E << 6) | OPC_CMPU_EQ_OB_DSP
,
828 OPC_PRECR_SRA_R_QH_PW
= (0x1F << 6) | OPC_CMPU_EQ_OB_DSP
,
829 OPC_PRECRQ_OB_QH
= (0x0C << 6) | OPC_CMPU_EQ_OB_DSP
,
830 OPC_PRECRQ_PW_L
= (0x1C << 6) | OPC_CMPU_EQ_OB_DSP
,
831 OPC_PRECRQ_QH_PW
= (0x14 << 6) | OPC_CMPU_EQ_OB_DSP
,
832 OPC_PRECRQ_RS_QH_PW
= (0x15 << 6) | OPC_CMPU_EQ_OB_DSP
,
833 OPC_PRECRQU_S_OB_QH
= (0x0F << 6) | OPC_CMPU_EQ_OB_DSP
,
836 #define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
838 /* DSP Append Sub-class */
839 OPC_DAPPEND
= (0x00 << 6) | OPC_DAPPEND_DSP
,
840 OPC_PREPENDD
= (0x03 << 6) | OPC_DAPPEND_DSP
,
841 OPC_PREPENDW
= (0x01 << 6) | OPC_DAPPEND_DSP
,
842 OPC_DBALIGN
= (0x10 << 6) | OPC_DAPPEND_DSP
,
845 #define MASK_DEXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
847 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
848 OPC_DMTHLIP
= (0x1F << 6) | OPC_DEXTR_W_DSP
,
849 OPC_DSHILO
= (0x1A << 6) | OPC_DEXTR_W_DSP
,
850 OPC_DEXTP
= (0x02 << 6) | OPC_DEXTR_W_DSP
,
851 OPC_DEXTPDP
= (0x0A << 6) | OPC_DEXTR_W_DSP
,
852 OPC_DEXTPDPV
= (0x0B << 6) | OPC_DEXTR_W_DSP
,
853 OPC_DEXTPV
= (0x03 << 6) | OPC_DEXTR_W_DSP
,
854 OPC_DEXTR_L
= (0x10 << 6) | OPC_DEXTR_W_DSP
,
855 OPC_DEXTR_R_L
= (0x14 << 6) | OPC_DEXTR_W_DSP
,
856 OPC_DEXTR_RS_L
= (0x16 << 6) | OPC_DEXTR_W_DSP
,
857 OPC_DEXTR_W
= (0x00 << 6) | OPC_DEXTR_W_DSP
,
858 OPC_DEXTR_R_W
= (0x04 << 6) | OPC_DEXTR_W_DSP
,
859 OPC_DEXTR_RS_W
= (0x06 << 6) | OPC_DEXTR_W_DSP
,
860 OPC_DEXTR_S_H
= (0x0E << 6) | OPC_DEXTR_W_DSP
,
861 OPC_DEXTRV_L
= (0x11 << 6) | OPC_DEXTR_W_DSP
,
862 OPC_DEXTRV_R_L
= (0x15 << 6) | OPC_DEXTR_W_DSP
,
863 OPC_DEXTRV_RS_L
= (0x17 << 6) | OPC_DEXTR_W_DSP
,
864 OPC_DEXTRV_S_H
= (0x0F << 6) | OPC_DEXTR_W_DSP
,
865 OPC_DEXTRV_W
= (0x01 << 6) | OPC_DEXTR_W_DSP
,
866 OPC_DEXTRV_R_W
= (0x05 << 6) | OPC_DEXTR_W_DSP
,
867 OPC_DEXTRV_RS_W
= (0x07 << 6) | OPC_DEXTR_W_DSP
,
868 OPC_DSHILOV
= (0x1B << 6) | OPC_DEXTR_W_DSP
,
871 #define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
873 /* DSP Bit/Manipulation Sub-class */
874 OPC_DINSV
= (0x00 << 6) | OPC_DINSV_DSP
,
877 #define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
879 /* MIPS DSP Multiply Sub-class insns */
880 OPC_DMADD
= (0x19 << 6) | OPC_DPAQ_W_QH_DSP
,
881 OPC_DMADDU
= (0x1D << 6) | OPC_DPAQ_W_QH_DSP
,
882 OPC_DMSUB
= (0x1B << 6) | OPC_DPAQ_W_QH_DSP
,
883 OPC_DMSUBU
= (0x1F << 6) | OPC_DPAQ_W_QH_DSP
,
884 OPC_DPA_W_QH
= (0x00 << 6) | OPC_DPAQ_W_QH_DSP
,
885 OPC_DPAQ_S_W_QH
= (0x04 << 6) | OPC_DPAQ_W_QH_DSP
,
886 OPC_DPAQ_SA_L_PW
= (0x0C << 6) | OPC_DPAQ_W_QH_DSP
,
887 OPC_DPAU_H_OBL
= (0x03 << 6) | OPC_DPAQ_W_QH_DSP
,
888 OPC_DPAU_H_OBR
= (0x07 << 6) | OPC_DPAQ_W_QH_DSP
,
889 OPC_DPS_W_QH
= (0x01 << 6) | OPC_DPAQ_W_QH_DSP
,
890 OPC_DPSQ_S_W_QH
= (0x05 << 6) | OPC_DPAQ_W_QH_DSP
,
891 OPC_DPSQ_SA_L_PW
= (0x0D << 6) | OPC_DPAQ_W_QH_DSP
,
892 OPC_DPSU_H_OBL
= (0x0B << 6) | OPC_DPAQ_W_QH_DSP
,
893 OPC_DPSU_H_OBR
= (0x0F << 6) | OPC_DPAQ_W_QH_DSP
,
894 OPC_MAQ_S_L_PWL
= (0x1C << 6) | OPC_DPAQ_W_QH_DSP
,
895 OPC_MAQ_S_L_PWR
= (0x1E << 6) | OPC_DPAQ_W_QH_DSP
,
896 OPC_MAQ_S_W_QHLL
= (0x14 << 6) | OPC_DPAQ_W_QH_DSP
,
897 OPC_MAQ_SA_W_QHLL
= (0x10 << 6) | OPC_DPAQ_W_QH_DSP
,
898 OPC_MAQ_S_W_QHLR
= (0x15 << 6) | OPC_DPAQ_W_QH_DSP
,
899 OPC_MAQ_SA_W_QHLR
= (0x11 << 6) | OPC_DPAQ_W_QH_DSP
,
900 OPC_MAQ_S_W_QHRL
= (0x16 << 6) | OPC_DPAQ_W_QH_DSP
,
901 OPC_MAQ_SA_W_QHRL
= (0x12 << 6) | OPC_DPAQ_W_QH_DSP
,
902 OPC_MAQ_S_W_QHRR
= (0x17 << 6) | OPC_DPAQ_W_QH_DSP
,
903 OPC_MAQ_SA_W_QHRR
= (0x13 << 6) | OPC_DPAQ_W_QH_DSP
,
904 OPC_MULSAQ_S_L_PW
= (0x0E << 6) | OPC_DPAQ_W_QH_DSP
,
905 OPC_MULSAQ_S_W_QH
= (0x06 << 6) | OPC_DPAQ_W_QH_DSP
,
908 #define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
910 /* MIPS DSP GPR-Based Shift Sub-class */
911 OPC_SHLL_PW
= (0x10 << 6) | OPC_SHLL_OB_DSP
,
912 OPC_SHLL_S_PW
= (0x14 << 6) | OPC_SHLL_OB_DSP
,
913 OPC_SHLLV_OB
= (0x02 << 6) | OPC_SHLL_OB_DSP
,
914 OPC_SHLLV_PW
= (0x12 << 6) | OPC_SHLL_OB_DSP
,
915 OPC_SHLLV_S_PW
= (0x16 << 6) | OPC_SHLL_OB_DSP
,
916 OPC_SHLLV_QH
= (0x0A << 6) | OPC_SHLL_OB_DSP
,
917 OPC_SHLLV_S_QH
= (0x0E << 6) | OPC_SHLL_OB_DSP
,
918 OPC_SHRA_PW
= (0x11 << 6) | OPC_SHLL_OB_DSP
,
919 OPC_SHRA_R_PW
= (0x15 << 6) | OPC_SHLL_OB_DSP
,
920 OPC_SHRAV_OB
= (0x06 << 6) | OPC_SHLL_OB_DSP
,
921 OPC_SHRAV_R_OB
= (0x07 << 6) | OPC_SHLL_OB_DSP
,
922 OPC_SHRAV_PW
= (0x13 << 6) | OPC_SHLL_OB_DSP
,
923 OPC_SHRAV_R_PW
= (0x17 << 6) | OPC_SHLL_OB_DSP
,
924 OPC_SHRAV_QH
= (0x0B << 6) | OPC_SHLL_OB_DSP
,
925 OPC_SHRAV_R_QH
= (0x0F << 6) | OPC_SHLL_OB_DSP
,
926 OPC_SHRLV_OB
= (0x03 << 6) | OPC_SHLL_OB_DSP
,
927 OPC_SHRLV_QH
= (0x1B << 6) | OPC_SHLL_OB_DSP
,
928 OPC_SHLL_OB
= (0x00 << 6) | OPC_SHLL_OB_DSP
,
929 OPC_SHLL_QH
= (0x08 << 6) | OPC_SHLL_OB_DSP
,
930 OPC_SHLL_S_QH
= (0x0C << 6) | OPC_SHLL_OB_DSP
,
931 OPC_SHRA_OB
= (0x04 << 6) | OPC_SHLL_OB_DSP
,
932 OPC_SHRA_R_OB
= (0x05 << 6) | OPC_SHLL_OB_DSP
,
933 OPC_SHRA_QH
= (0x09 << 6) | OPC_SHLL_OB_DSP
,
934 OPC_SHRA_R_QH
= (0x0D << 6) | OPC_SHLL_OB_DSP
,
935 OPC_SHRL_OB
= (0x01 << 6) | OPC_SHLL_OB_DSP
,
936 OPC_SHRL_QH
= (0x19 << 6) | OPC_SHLL_OB_DSP
,
939 /* Coprocessor 0 (rs field) */
940 #define MASK_CP0(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)))
943 OPC_MFC0
= (0x00 << 21) | OPC_CP0
,
944 OPC_DMFC0
= (0x01 << 21) | OPC_CP0
,
945 OPC_MFHC0
= (0x02 << 21) | OPC_CP0
,
946 OPC_MTC0
= (0x04 << 21) | OPC_CP0
,
947 OPC_DMTC0
= (0x05 << 21) | OPC_CP0
,
948 OPC_MTHC0
= (0x06 << 21) | OPC_CP0
,
949 OPC_MFTR
= (0x08 << 21) | OPC_CP0
,
950 OPC_RDPGPR
= (0x0A << 21) | OPC_CP0
,
951 OPC_MFMC0
= (0x0B << 21) | OPC_CP0
,
952 OPC_MTTR
= (0x0C << 21) | OPC_CP0
,
953 OPC_WRPGPR
= (0x0E << 21) | OPC_CP0
,
954 OPC_C0
= (0x10 << 21) | OPC_CP0
,
955 OPC_C0_1
= (0x11 << 21) | OPC_CP0
,
956 OPC_C0_2
= (0x12 << 21) | OPC_CP0
,
957 OPC_C0_3
= (0x13 << 21) | OPC_CP0
,
958 OPC_C0_4
= (0x14 << 21) | OPC_CP0
,
959 OPC_C0_5
= (0x15 << 21) | OPC_CP0
,
960 OPC_C0_6
= (0x16 << 21) | OPC_CP0
,
961 OPC_C0_7
= (0x17 << 21) | OPC_CP0
,
962 OPC_C0_8
= (0x18 << 21) | OPC_CP0
,
963 OPC_C0_9
= (0x19 << 21) | OPC_CP0
,
964 OPC_C0_A
= (0x1A << 21) | OPC_CP0
,
965 OPC_C0_B
= (0x1B << 21) | OPC_CP0
,
966 OPC_C0_C
= (0x1C << 21) | OPC_CP0
,
967 OPC_C0_D
= (0x1D << 21) | OPC_CP0
,
968 OPC_C0_E
= (0x1E << 21) | OPC_CP0
,
969 OPC_C0_F
= (0x1F << 21) | OPC_CP0
,
973 #define MASK_MFMC0(op) (MASK_CP0(op) | (op & 0xFFFF))
976 OPC_DMT
= 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0
,
977 OPC_EMT
= 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0
,
978 OPC_DVPE
= 0x01 | (0 << 5) | OPC_MFMC0
,
979 OPC_EVPE
= 0x01 | (1 << 5) | OPC_MFMC0
,
980 OPC_DI
= (0 << 5) | (0x0C << 11) | OPC_MFMC0
,
981 OPC_EI
= (1 << 5) | (0x0C << 11) | OPC_MFMC0
,
982 OPC_DVP
= 0x04 | (0 << 3) | (1 << 5) | (0 << 11) | OPC_MFMC0
,
983 OPC_EVP
= 0x04 | (0 << 3) | (0 << 5) | (0 << 11) | OPC_MFMC0
,
986 /* Coprocessor 0 (with rs == C0) */
987 #define MASK_C0(op) (MASK_CP0(op) | (op & 0x3F))
990 OPC_TLBR
= 0x01 | OPC_C0
,
991 OPC_TLBWI
= 0x02 | OPC_C0
,
992 OPC_TLBINV
= 0x03 | OPC_C0
,
993 OPC_TLBINVF
= 0x04 | OPC_C0
,
994 OPC_TLBWR
= 0x06 | OPC_C0
,
995 OPC_TLBP
= 0x08 | OPC_C0
,
996 OPC_RFE
= 0x10 | OPC_C0
,
997 OPC_ERET
= 0x18 | OPC_C0
,
998 OPC_DERET
= 0x1F | OPC_C0
,
999 OPC_WAIT
= 0x20 | OPC_C0
,
1002 /* Coprocessor 1 (rs field) */
1003 #define MASK_CP1(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)))
1005 /* Values for the fmt field in FP instructions */
1007 /* 0 - 15 are reserved */
1008 FMT_S
= 16, /* single fp */
1009 FMT_D
= 17, /* double fp */
1010 FMT_E
= 18, /* extended fp */
1011 FMT_Q
= 19, /* quad fp */
1012 FMT_W
= 20, /* 32-bit fixed */
1013 FMT_L
= 21, /* 64-bit fixed */
1014 FMT_PS
= 22, /* paired single fp */
1015 /* 23 - 31 are reserved */
1019 OPC_MFC1
= (0x00 << 21) | OPC_CP1
,
1020 OPC_DMFC1
= (0x01 << 21) | OPC_CP1
,
1021 OPC_CFC1
= (0x02 << 21) | OPC_CP1
,
1022 OPC_MFHC1
= (0x03 << 21) | OPC_CP1
,
1023 OPC_MTC1
= (0x04 << 21) | OPC_CP1
,
1024 OPC_DMTC1
= (0x05 << 21) | OPC_CP1
,
1025 OPC_CTC1
= (0x06 << 21) | OPC_CP1
,
1026 OPC_MTHC1
= (0x07 << 21) | OPC_CP1
,
1027 OPC_BC1
= (0x08 << 21) | OPC_CP1
, /* bc */
1028 OPC_BC1ANY2
= (0x09 << 21) | OPC_CP1
,
1029 OPC_BC1ANY4
= (0x0A << 21) | OPC_CP1
,
1030 OPC_BZ_V
= (0x0B << 21) | OPC_CP1
,
1031 OPC_BNZ_V
= (0x0F << 21) | OPC_CP1
,
1032 OPC_S_FMT
= (FMT_S
<< 21) | OPC_CP1
,
1033 OPC_D_FMT
= (FMT_D
<< 21) | OPC_CP1
,
1034 OPC_E_FMT
= (FMT_E
<< 21) | OPC_CP1
,
1035 OPC_Q_FMT
= (FMT_Q
<< 21) | OPC_CP1
,
1036 OPC_W_FMT
= (FMT_W
<< 21) | OPC_CP1
,
1037 OPC_L_FMT
= (FMT_L
<< 21) | OPC_CP1
,
1038 OPC_PS_FMT
= (FMT_PS
<< 21) | OPC_CP1
,
1039 OPC_BC1EQZ
= (0x09 << 21) | OPC_CP1
,
1040 OPC_BC1NEZ
= (0x0D << 21) | OPC_CP1
,
1041 OPC_BZ_B
= (0x18 << 21) | OPC_CP1
,
1042 OPC_BZ_H
= (0x19 << 21) | OPC_CP1
,
1043 OPC_BZ_W
= (0x1A << 21) | OPC_CP1
,
1044 OPC_BZ_D
= (0x1B << 21) | OPC_CP1
,
1045 OPC_BNZ_B
= (0x1C << 21) | OPC_CP1
,
1046 OPC_BNZ_H
= (0x1D << 21) | OPC_CP1
,
1047 OPC_BNZ_W
= (0x1E << 21) | OPC_CP1
,
1048 OPC_BNZ_D
= (0x1F << 21) | OPC_CP1
,
1051 #define MASK_CP1_FUNC(op) (MASK_CP1(op) | (op & 0x3F))
1052 #define MASK_BC1(op) (MASK_CP1(op) | (op & (0x3 << 16)))
1055 OPC_BC1F
= (0x00 << 16) | OPC_BC1
,
1056 OPC_BC1T
= (0x01 << 16) | OPC_BC1
,
1057 OPC_BC1FL
= (0x02 << 16) | OPC_BC1
,
1058 OPC_BC1TL
= (0x03 << 16) | OPC_BC1
,
1062 OPC_BC1FANY2
= (0x00 << 16) | OPC_BC1ANY2
,
1063 OPC_BC1TANY2
= (0x01 << 16) | OPC_BC1ANY2
,
1067 OPC_BC1FANY4
= (0x00 << 16) | OPC_BC1ANY4
,
1068 OPC_BC1TANY4
= (0x01 << 16) | OPC_BC1ANY4
,
1071 #define MASK_CP2(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)))
1074 OPC_MFC2
= (0x00 << 21) | OPC_CP2
,
1075 OPC_DMFC2
= (0x01 << 21) | OPC_CP2
,
1076 OPC_CFC2
= (0x02 << 21) | OPC_CP2
,
1077 OPC_MFHC2
= (0x03 << 21) | OPC_CP2
,
1078 OPC_MTC2
= (0x04 << 21) | OPC_CP2
,
1079 OPC_DMTC2
= (0x05 << 21) | OPC_CP2
,
1080 OPC_CTC2
= (0x06 << 21) | OPC_CP2
,
1081 OPC_MTHC2
= (0x07 << 21) | OPC_CP2
,
1082 OPC_BC2
= (0x08 << 21) | OPC_CP2
,
1083 OPC_BC2EQZ
= (0x09 << 21) | OPC_CP2
,
1084 OPC_BC2NEZ
= (0x0D << 21) | OPC_CP2
,
1087 #define MASK_LMMI(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
1090 OPC_PADDSH
= (24 << 21) | (0x00) | OPC_CP2
,
1091 OPC_PADDUSH
= (25 << 21) | (0x00) | OPC_CP2
,
1092 OPC_PADDH
= (26 << 21) | (0x00) | OPC_CP2
,
1093 OPC_PADDW
= (27 << 21) | (0x00) | OPC_CP2
,
1094 OPC_PADDSB
= (28 << 21) | (0x00) | OPC_CP2
,
1095 OPC_PADDUSB
= (29 << 21) | (0x00) | OPC_CP2
,
1096 OPC_PADDB
= (30 << 21) | (0x00) | OPC_CP2
,
1097 OPC_PADDD
= (31 << 21) | (0x00) | OPC_CP2
,
1099 OPC_PSUBSH
= (24 << 21) | (0x01) | OPC_CP2
,
1100 OPC_PSUBUSH
= (25 << 21) | (0x01) | OPC_CP2
,
1101 OPC_PSUBH
= (26 << 21) | (0x01) | OPC_CP2
,
1102 OPC_PSUBW
= (27 << 21) | (0x01) | OPC_CP2
,
1103 OPC_PSUBSB
= (28 << 21) | (0x01) | OPC_CP2
,
1104 OPC_PSUBUSB
= (29 << 21) | (0x01) | OPC_CP2
,
1105 OPC_PSUBB
= (30 << 21) | (0x01) | OPC_CP2
,
1106 OPC_PSUBD
= (31 << 21) | (0x01) | OPC_CP2
,
1108 OPC_PSHUFH
= (24 << 21) | (0x02) | OPC_CP2
,
1109 OPC_PACKSSWH
= (25 << 21) | (0x02) | OPC_CP2
,
1110 OPC_PACKSSHB
= (26 << 21) | (0x02) | OPC_CP2
,
1111 OPC_PACKUSHB
= (27 << 21) | (0x02) | OPC_CP2
,
1112 OPC_XOR_CP2
= (28 << 21) | (0x02) | OPC_CP2
,
1113 OPC_NOR_CP2
= (29 << 21) | (0x02) | OPC_CP2
,
1114 OPC_AND_CP2
= (30 << 21) | (0x02) | OPC_CP2
,
1115 OPC_PANDN
= (31 << 21) | (0x02) | OPC_CP2
,
1117 OPC_PUNPCKLHW
= (24 << 21) | (0x03) | OPC_CP2
,
1118 OPC_PUNPCKHHW
= (25 << 21) | (0x03) | OPC_CP2
,
1119 OPC_PUNPCKLBH
= (26 << 21) | (0x03) | OPC_CP2
,
1120 OPC_PUNPCKHBH
= (27 << 21) | (0x03) | OPC_CP2
,
1121 OPC_PINSRH_0
= (28 << 21) | (0x03) | OPC_CP2
,
1122 OPC_PINSRH_1
= (29 << 21) | (0x03) | OPC_CP2
,
1123 OPC_PINSRH_2
= (30 << 21) | (0x03) | OPC_CP2
,
1124 OPC_PINSRH_3
= (31 << 21) | (0x03) | OPC_CP2
,
1126 OPC_PAVGH
= (24 << 21) | (0x08) | OPC_CP2
,
1127 OPC_PAVGB
= (25 << 21) | (0x08) | OPC_CP2
,
1128 OPC_PMAXSH
= (26 << 21) | (0x08) | OPC_CP2
,
1129 OPC_PMINSH
= (27 << 21) | (0x08) | OPC_CP2
,
1130 OPC_PMAXUB
= (28 << 21) | (0x08) | OPC_CP2
,
1131 OPC_PMINUB
= (29 << 21) | (0x08) | OPC_CP2
,
1133 OPC_PCMPEQW
= (24 << 21) | (0x09) | OPC_CP2
,
1134 OPC_PCMPGTW
= (25 << 21) | (0x09) | OPC_CP2
,
1135 OPC_PCMPEQH
= (26 << 21) | (0x09) | OPC_CP2
,
1136 OPC_PCMPGTH
= (27 << 21) | (0x09) | OPC_CP2
,
1137 OPC_PCMPEQB
= (28 << 21) | (0x09) | OPC_CP2
,
1138 OPC_PCMPGTB
= (29 << 21) | (0x09) | OPC_CP2
,
1140 OPC_PSLLW
= (24 << 21) | (0x0A) | OPC_CP2
,
1141 OPC_PSLLH
= (25 << 21) | (0x0A) | OPC_CP2
,
1142 OPC_PMULLH
= (26 << 21) | (0x0A) | OPC_CP2
,
1143 OPC_PMULHH
= (27 << 21) | (0x0A) | OPC_CP2
,
1144 OPC_PMULUW
= (28 << 21) | (0x0A) | OPC_CP2
,
1145 OPC_PMULHUH
= (29 << 21) | (0x0A) | OPC_CP2
,
1147 OPC_PSRLW
= (24 << 21) | (0x0B) | OPC_CP2
,
1148 OPC_PSRLH
= (25 << 21) | (0x0B) | OPC_CP2
,
1149 OPC_PSRAW
= (26 << 21) | (0x0B) | OPC_CP2
,
1150 OPC_PSRAH
= (27 << 21) | (0x0B) | OPC_CP2
,
1151 OPC_PUNPCKLWD
= (28 << 21) | (0x0B) | OPC_CP2
,
1152 OPC_PUNPCKHWD
= (29 << 21) | (0x0B) | OPC_CP2
,
1154 OPC_ADDU_CP2
= (24 << 21) | (0x0C) | OPC_CP2
,
1155 OPC_OR_CP2
= (25 << 21) | (0x0C) | OPC_CP2
,
1156 OPC_ADD_CP2
= (26 << 21) | (0x0C) | OPC_CP2
,
1157 OPC_DADD_CP2
= (27 << 21) | (0x0C) | OPC_CP2
,
1158 OPC_SEQU_CP2
= (28 << 21) | (0x0C) | OPC_CP2
,
1159 OPC_SEQ_CP2
= (29 << 21) | (0x0C) | OPC_CP2
,
1161 OPC_SUBU_CP2
= (24 << 21) | (0x0D) | OPC_CP2
,
1162 OPC_PASUBUB
= (25 << 21) | (0x0D) | OPC_CP2
,
1163 OPC_SUB_CP2
= (26 << 21) | (0x0D) | OPC_CP2
,
1164 OPC_DSUB_CP2
= (27 << 21) | (0x0D) | OPC_CP2
,
1165 OPC_SLTU_CP2
= (28 << 21) | (0x0D) | OPC_CP2
,
1166 OPC_SLT_CP2
= (29 << 21) | (0x0D) | OPC_CP2
,
1168 OPC_SLL_CP2
= (24 << 21) | (0x0E) | OPC_CP2
,
1169 OPC_DSLL_CP2
= (25 << 21) | (0x0E) | OPC_CP2
,
1170 OPC_PEXTRH
= (26 << 21) | (0x0E) | OPC_CP2
,
1171 OPC_PMADDHW
= (27 << 21) | (0x0E) | OPC_CP2
,
1172 OPC_SLEU_CP2
= (28 << 21) | (0x0E) | OPC_CP2
,
1173 OPC_SLE_CP2
= (29 << 21) | (0x0E) | OPC_CP2
,
1175 OPC_SRL_CP2
= (24 << 21) | (0x0F) | OPC_CP2
,
1176 OPC_DSRL_CP2
= (25 << 21) | (0x0F) | OPC_CP2
,
1177 OPC_SRA_CP2
= (26 << 21) | (0x0F) | OPC_CP2
,
1178 OPC_DSRA_CP2
= (27 << 21) | (0x0F) | OPC_CP2
,
1179 OPC_BIADD
= (28 << 21) | (0x0F) | OPC_CP2
,
1180 OPC_PMOVMSKB
= (29 << 21) | (0x0F) | OPC_CP2
,
1184 #define MASK_CP3(op) (MASK_OP_MAJOR(op) | (op & 0x3F))
1187 OPC_LWXC1
= 0x00 | OPC_CP3
,
1188 OPC_LDXC1
= 0x01 | OPC_CP3
,
1189 OPC_LUXC1
= 0x05 | OPC_CP3
,
1190 OPC_SWXC1
= 0x08 | OPC_CP3
,
1191 OPC_SDXC1
= 0x09 | OPC_CP3
,
1192 OPC_SUXC1
= 0x0D | OPC_CP3
,
1193 OPC_PREFX
= 0x0F | OPC_CP3
,
1194 OPC_ALNV_PS
= 0x1E | OPC_CP3
,
1195 OPC_MADD_S
= 0x20 | OPC_CP3
,
1196 OPC_MADD_D
= 0x21 | OPC_CP3
,
1197 OPC_MADD_PS
= 0x26 | OPC_CP3
,
1198 OPC_MSUB_S
= 0x28 | OPC_CP3
,
1199 OPC_MSUB_D
= 0x29 | OPC_CP3
,
1200 OPC_MSUB_PS
= 0x2E | OPC_CP3
,
1201 OPC_NMADD_S
= 0x30 | OPC_CP3
,
1202 OPC_NMADD_D
= 0x31 | OPC_CP3
,
1203 OPC_NMADD_PS
= 0x36 | OPC_CP3
,
1204 OPC_NMSUB_S
= 0x38 | OPC_CP3
,
1205 OPC_NMSUB_D
= 0x39 | OPC_CP3
,
1206 OPC_NMSUB_PS
= 0x3E | OPC_CP3
,
1210 #define MASK_MSA_MINOR(op) (MASK_OP_MAJOR(op) | (op & 0x3F))
1212 OPC_MSA_I8_00
= 0x00 | OPC_MSA
,
1213 OPC_MSA_I8_01
= 0x01 | OPC_MSA
,
1214 OPC_MSA_I8_02
= 0x02 | OPC_MSA
,
1215 OPC_MSA_I5_06
= 0x06 | OPC_MSA
,
1216 OPC_MSA_I5_07
= 0x07 | OPC_MSA
,
1217 OPC_MSA_BIT_09
= 0x09 | OPC_MSA
,
1218 OPC_MSA_BIT_0A
= 0x0A | OPC_MSA
,
1219 OPC_MSA_3R_0D
= 0x0D | OPC_MSA
,
1220 OPC_MSA_3R_0E
= 0x0E | OPC_MSA
,
1221 OPC_MSA_3R_0F
= 0x0F | OPC_MSA
,
1222 OPC_MSA_3R_10
= 0x10 | OPC_MSA
,
1223 OPC_MSA_3R_11
= 0x11 | OPC_MSA
,
1224 OPC_MSA_3R_12
= 0x12 | OPC_MSA
,
1225 OPC_MSA_3R_13
= 0x13 | OPC_MSA
,
1226 OPC_MSA_3R_14
= 0x14 | OPC_MSA
,
1227 OPC_MSA_3R_15
= 0x15 | OPC_MSA
,
1228 OPC_MSA_ELM
= 0x19 | OPC_MSA
,
1229 OPC_MSA_3RF_1A
= 0x1A | OPC_MSA
,
1230 OPC_MSA_3RF_1B
= 0x1B | OPC_MSA
,
1231 OPC_MSA_3RF_1C
= 0x1C | OPC_MSA
,
1232 OPC_MSA_VEC
= 0x1E | OPC_MSA
,
1234 /* MI10 instruction */
1235 OPC_LD_B
= (0x20) | OPC_MSA
,
1236 OPC_LD_H
= (0x21) | OPC_MSA
,
1237 OPC_LD_W
= (0x22) | OPC_MSA
,
1238 OPC_LD_D
= (0x23) | OPC_MSA
,
1239 OPC_ST_B
= (0x24) | OPC_MSA
,
1240 OPC_ST_H
= (0x25) | OPC_MSA
,
1241 OPC_ST_W
= (0x26) | OPC_MSA
,
1242 OPC_ST_D
= (0x27) | OPC_MSA
,
1246 /* I5 instruction df(bits 22..21) = _b, _h, _w, _d */
1247 OPC_ADDVI_df
= (0x0 << 23) | OPC_MSA_I5_06
,
1248 OPC_CEQI_df
= (0x0 << 23) | OPC_MSA_I5_07
,
1249 OPC_SUBVI_df
= (0x1 << 23) | OPC_MSA_I5_06
,
1250 OPC_MAXI_S_df
= (0x2 << 23) | OPC_MSA_I5_06
,
1251 OPC_CLTI_S_df
= (0x2 << 23) | OPC_MSA_I5_07
,
1252 OPC_MAXI_U_df
= (0x3 << 23) | OPC_MSA_I5_06
,
1253 OPC_CLTI_U_df
= (0x3 << 23) | OPC_MSA_I5_07
,
1254 OPC_MINI_S_df
= (0x4 << 23) | OPC_MSA_I5_06
,
1255 OPC_CLEI_S_df
= (0x4 << 23) | OPC_MSA_I5_07
,
1256 OPC_MINI_U_df
= (0x5 << 23) | OPC_MSA_I5_06
,
1257 OPC_CLEI_U_df
= (0x5 << 23) | OPC_MSA_I5_07
,
1258 OPC_LDI_df
= (0x6 << 23) | OPC_MSA_I5_07
,
1260 /* I8 instruction */
1261 OPC_ANDI_B
= (0x0 << 24) | OPC_MSA_I8_00
,
1262 OPC_BMNZI_B
= (0x0 << 24) | OPC_MSA_I8_01
,
1263 OPC_SHF_B
= (0x0 << 24) | OPC_MSA_I8_02
,
1264 OPC_ORI_B
= (0x1 << 24) | OPC_MSA_I8_00
,
1265 OPC_BMZI_B
= (0x1 << 24) | OPC_MSA_I8_01
,
1266 OPC_SHF_H
= (0x1 << 24) | OPC_MSA_I8_02
,
1267 OPC_NORI_B
= (0x2 << 24) | OPC_MSA_I8_00
,
1268 OPC_BSELI_B
= (0x2 << 24) | OPC_MSA_I8_01
,
1269 OPC_SHF_W
= (0x2 << 24) | OPC_MSA_I8_02
,
1270 OPC_XORI_B
= (0x3 << 24) | OPC_MSA_I8_00
,
1272 /* VEC/2R/2RF instruction */
1273 OPC_AND_V
= (0x00 << 21) | OPC_MSA_VEC
,
1274 OPC_OR_V
= (0x01 << 21) | OPC_MSA_VEC
,
1275 OPC_NOR_V
= (0x02 << 21) | OPC_MSA_VEC
,
1276 OPC_XOR_V
= (0x03 << 21) | OPC_MSA_VEC
,
1277 OPC_BMNZ_V
= (0x04 << 21) | OPC_MSA_VEC
,
1278 OPC_BMZ_V
= (0x05 << 21) | OPC_MSA_VEC
,
1279 OPC_BSEL_V
= (0x06 << 21) | OPC_MSA_VEC
,
1281 OPC_MSA_2R
= (0x18 << 21) | OPC_MSA_VEC
,
1282 OPC_MSA_2RF
= (0x19 << 21) | OPC_MSA_VEC
,
1284 /* 2R instruction df(bits 17..16) = _b, _h, _w, _d */
1285 OPC_FILL_df
= (0x00 << 18) | OPC_MSA_2R
,
1286 OPC_PCNT_df
= (0x01 << 18) | OPC_MSA_2R
,
1287 OPC_NLOC_df
= (0x02 << 18) | OPC_MSA_2R
,
1288 OPC_NLZC_df
= (0x03 << 18) | OPC_MSA_2R
,
1290 /* 2RF instruction df(bit 16) = _w, _d */
1291 OPC_FCLASS_df
= (0x00 << 17) | OPC_MSA_2RF
,
1292 OPC_FTRUNC_S_df
= (0x01 << 17) | OPC_MSA_2RF
,
1293 OPC_FTRUNC_U_df
= (0x02 << 17) | OPC_MSA_2RF
,
1294 OPC_FSQRT_df
= (0x03 << 17) | OPC_MSA_2RF
,
1295 OPC_FRSQRT_df
= (0x04 << 17) | OPC_MSA_2RF
,
1296 OPC_FRCP_df
= (0x05 << 17) | OPC_MSA_2RF
,
1297 OPC_FRINT_df
= (0x06 << 17) | OPC_MSA_2RF
,
1298 OPC_FLOG2_df
= (0x07 << 17) | OPC_MSA_2RF
,
1299 OPC_FEXUPL_df
= (0x08 << 17) | OPC_MSA_2RF
,
1300 OPC_FEXUPR_df
= (0x09 << 17) | OPC_MSA_2RF
,
1301 OPC_FFQL_df
= (0x0A << 17) | OPC_MSA_2RF
,
1302 OPC_FFQR_df
= (0x0B << 17) | OPC_MSA_2RF
,
1303 OPC_FTINT_S_df
= (0x0C << 17) | OPC_MSA_2RF
,
1304 OPC_FTINT_U_df
= (0x0D << 17) | OPC_MSA_2RF
,
1305 OPC_FFINT_S_df
= (0x0E << 17) | OPC_MSA_2RF
,
1306 OPC_FFINT_U_df
= (0x0F << 17) | OPC_MSA_2RF
,
1308 /* 3R instruction df(bits 22..21) = _b, _h, _w, d */
1309 OPC_SLL_df
= (0x0 << 23) | OPC_MSA_3R_0D
,
1310 OPC_ADDV_df
= (0x0 << 23) | OPC_MSA_3R_0E
,
1311 OPC_CEQ_df
= (0x0 << 23) | OPC_MSA_3R_0F
,
1312 OPC_ADD_A_df
= (0x0 << 23) | OPC_MSA_3R_10
,
1313 OPC_SUBS_S_df
= (0x0 << 23) | OPC_MSA_3R_11
,
1314 OPC_MULV_df
= (0x0 << 23) | OPC_MSA_3R_12
,
1315 OPC_DOTP_S_df
= (0x0 << 23) | OPC_MSA_3R_13
,
1316 OPC_SLD_df
= (0x0 << 23) | OPC_MSA_3R_14
,
1317 OPC_VSHF_df
= (0x0 << 23) | OPC_MSA_3R_15
,
1318 OPC_SRA_df
= (0x1 << 23) | OPC_MSA_3R_0D
,
1319 OPC_SUBV_df
= (0x1 << 23) | OPC_MSA_3R_0E
,
1320 OPC_ADDS_A_df
= (0x1 << 23) | OPC_MSA_3R_10
,
1321 OPC_SUBS_U_df
= (0x1 << 23) | OPC_MSA_3R_11
,
1322 OPC_MADDV_df
= (0x1 << 23) | OPC_MSA_3R_12
,
1323 OPC_DOTP_U_df
= (0x1 << 23) | OPC_MSA_3R_13
,
1324 OPC_SPLAT_df
= (0x1 << 23) | OPC_MSA_3R_14
,
1325 OPC_SRAR_df
= (0x1 << 23) | OPC_MSA_3R_15
,
1326 OPC_SRL_df
= (0x2 << 23) | OPC_MSA_3R_0D
,
1327 OPC_MAX_S_df
= (0x2 << 23) | OPC_MSA_3R_0E
,
1328 OPC_CLT_S_df
= (0x2 << 23) | OPC_MSA_3R_0F
,
1329 OPC_ADDS_S_df
= (0x2 << 23) | OPC_MSA_3R_10
,
1330 OPC_SUBSUS_U_df
= (0x2 << 23) | OPC_MSA_3R_11
,
1331 OPC_MSUBV_df
= (0x2 << 23) | OPC_MSA_3R_12
,
1332 OPC_DPADD_S_df
= (0x2 << 23) | OPC_MSA_3R_13
,
1333 OPC_PCKEV_df
= (0x2 << 23) | OPC_MSA_3R_14
,
1334 OPC_SRLR_df
= (0x2 << 23) | OPC_MSA_3R_15
,
1335 OPC_BCLR_df
= (0x3 << 23) | OPC_MSA_3R_0D
,
1336 OPC_MAX_U_df
= (0x3 << 23) | OPC_MSA_3R_0E
,
1337 OPC_CLT_U_df
= (0x3 << 23) | OPC_MSA_3R_0F
,
1338 OPC_ADDS_U_df
= (0x3 << 23) | OPC_MSA_3R_10
,
1339 OPC_SUBSUU_S_df
= (0x3 << 23) | OPC_MSA_3R_11
,
1340 OPC_DPADD_U_df
= (0x3 << 23) | OPC_MSA_3R_13
,
1341 OPC_PCKOD_df
= (0x3 << 23) | OPC_MSA_3R_14
,
1342 OPC_BSET_df
= (0x4 << 23) | OPC_MSA_3R_0D
,
1343 OPC_MIN_S_df
= (0x4 << 23) | OPC_MSA_3R_0E
,
1344 OPC_CLE_S_df
= (0x4 << 23) | OPC_MSA_3R_0F
,
1345 OPC_AVE_S_df
= (0x4 << 23) | OPC_MSA_3R_10
,
1346 OPC_ASUB_S_df
= (0x4 << 23) | OPC_MSA_3R_11
,
1347 OPC_DIV_S_df
= (0x4 << 23) | OPC_MSA_3R_12
,
1348 OPC_DPSUB_S_df
= (0x4 << 23) | OPC_MSA_3R_13
,
1349 OPC_ILVL_df
= (0x4 << 23) | OPC_MSA_3R_14
,
1350 OPC_HADD_S_df
= (0x4 << 23) | OPC_MSA_3R_15
,
1351 OPC_BNEG_df
= (0x5 << 23) | OPC_MSA_3R_0D
,
1352 OPC_MIN_U_df
= (0x5 << 23) | OPC_MSA_3R_0E
,
1353 OPC_CLE_U_df
= (0x5 << 23) | OPC_MSA_3R_0F
,
1354 OPC_AVE_U_df
= (0x5 << 23) | OPC_MSA_3R_10
,
1355 OPC_ASUB_U_df
= (0x5 << 23) | OPC_MSA_3R_11
,
1356 OPC_DIV_U_df
= (0x5 << 23) | OPC_MSA_3R_12
,
1357 OPC_DPSUB_U_df
= (0x5 << 23) | OPC_MSA_3R_13
,
1358 OPC_ILVR_df
= (0x5 << 23) | OPC_MSA_3R_14
,
1359 OPC_HADD_U_df
= (0x5 << 23) | OPC_MSA_3R_15
,
1360 OPC_BINSL_df
= (0x6 << 23) | OPC_MSA_3R_0D
,
1361 OPC_MAX_A_df
= (0x6 << 23) | OPC_MSA_3R_0E
,
1362 OPC_AVER_S_df
= (0x6 << 23) | OPC_MSA_3R_10
,
1363 OPC_MOD_S_df
= (0x6 << 23) | OPC_MSA_3R_12
,
1364 OPC_ILVEV_df
= (0x6 << 23) | OPC_MSA_3R_14
,
1365 OPC_HSUB_S_df
= (0x6 << 23) | OPC_MSA_3R_15
,
1366 OPC_BINSR_df
= (0x7 << 23) | OPC_MSA_3R_0D
,
1367 OPC_MIN_A_df
= (0x7 << 23) | OPC_MSA_3R_0E
,
1368 OPC_AVER_U_df
= (0x7 << 23) | OPC_MSA_3R_10
,
1369 OPC_MOD_U_df
= (0x7 << 23) | OPC_MSA_3R_12
,
1370 OPC_ILVOD_df
= (0x7 << 23) | OPC_MSA_3R_14
,
1371 OPC_HSUB_U_df
= (0x7 << 23) | OPC_MSA_3R_15
,
1373 /* ELM instructions df(bits 21..16) = _b, _h, _w, _d */
1374 OPC_SLDI_df
= (0x0 << 22) | (0x00 << 16) | OPC_MSA_ELM
,
1375 OPC_CTCMSA
= (0x0 << 22) | (0x3E << 16) | OPC_MSA_ELM
,
1376 OPC_SPLATI_df
= (0x1 << 22) | (0x00 << 16) | OPC_MSA_ELM
,
1377 OPC_CFCMSA
= (0x1 << 22) | (0x3E << 16) | OPC_MSA_ELM
,
1378 OPC_COPY_S_df
= (0x2 << 22) | (0x00 << 16) | OPC_MSA_ELM
,
1379 OPC_MOVE_V
= (0x2 << 22) | (0x3E << 16) | OPC_MSA_ELM
,
1380 OPC_COPY_U_df
= (0x3 << 22) | (0x00 << 16) | OPC_MSA_ELM
,
1381 OPC_INSERT_df
= (0x4 << 22) | (0x00 << 16) | OPC_MSA_ELM
,
1382 OPC_INSVE_df
= (0x5 << 22) | (0x00 << 16) | OPC_MSA_ELM
,
1384 /* 3RF instruction _df(bit 21) = _w, _d */
1385 OPC_FCAF_df
= (0x0 << 22) | OPC_MSA_3RF_1A
,
1386 OPC_FADD_df
= (0x0 << 22) | OPC_MSA_3RF_1B
,
1387 OPC_FCUN_df
= (0x1 << 22) | OPC_MSA_3RF_1A
,
1388 OPC_FSUB_df
= (0x1 << 22) | OPC_MSA_3RF_1B
,
1389 OPC_FCOR_df
= (0x1 << 22) | OPC_MSA_3RF_1C
,
1390 OPC_FCEQ_df
= (0x2 << 22) | OPC_MSA_3RF_1A
,
1391 OPC_FMUL_df
= (0x2 << 22) | OPC_MSA_3RF_1B
,
1392 OPC_FCUNE_df
= (0x2 << 22) | OPC_MSA_3RF_1C
,
1393 OPC_FCUEQ_df
= (0x3 << 22) | OPC_MSA_3RF_1A
,
1394 OPC_FDIV_df
= (0x3 << 22) | OPC_MSA_3RF_1B
,
1395 OPC_FCNE_df
= (0x3 << 22) | OPC_MSA_3RF_1C
,
1396 OPC_FCLT_df
= (0x4 << 22) | OPC_MSA_3RF_1A
,
1397 OPC_FMADD_df
= (0x4 << 22) | OPC_MSA_3RF_1B
,
1398 OPC_MUL_Q_df
= (0x4 << 22) | OPC_MSA_3RF_1C
,
1399 OPC_FCULT_df
= (0x5 << 22) | OPC_MSA_3RF_1A
,
1400 OPC_FMSUB_df
= (0x5 << 22) | OPC_MSA_3RF_1B
,
1401 OPC_MADD_Q_df
= (0x5 << 22) | OPC_MSA_3RF_1C
,
1402 OPC_FCLE_df
= (0x6 << 22) | OPC_MSA_3RF_1A
,
1403 OPC_MSUB_Q_df
= (0x6 << 22) | OPC_MSA_3RF_1C
,
1404 OPC_FCULE_df
= (0x7 << 22) | OPC_MSA_3RF_1A
,
1405 OPC_FEXP2_df
= (0x7 << 22) | OPC_MSA_3RF_1B
,
1406 OPC_FSAF_df
= (0x8 << 22) | OPC_MSA_3RF_1A
,
1407 OPC_FEXDO_df
= (0x8 << 22) | OPC_MSA_3RF_1B
,
1408 OPC_FSUN_df
= (0x9 << 22) | OPC_MSA_3RF_1A
,
1409 OPC_FSOR_df
= (0x9 << 22) | OPC_MSA_3RF_1C
,
1410 OPC_FSEQ_df
= (0xA << 22) | OPC_MSA_3RF_1A
,
1411 OPC_FTQ_df
= (0xA << 22) | OPC_MSA_3RF_1B
,
1412 OPC_FSUNE_df
= (0xA << 22) | OPC_MSA_3RF_1C
,
1413 OPC_FSUEQ_df
= (0xB << 22) | OPC_MSA_3RF_1A
,
1414 OPC_FSNE_df
= (0xB << 22) | OPC_MSA_3RF_1C
,
1415 OPC_FSLT_df
= (0xC << 22) | OPC_MSA_3RF_1A
,
1416 OPC_FMIN_df
= (0xC << 22) | OPC_MSA_3RF_1B
,
1417 OPC_MULR_Q_df
= (0xC << 22) | OPC_MSA_3RF_1C
,
1418 OPC_FSULT_df
= (0xD << 22) | OPC_MSA_3RF_1A
,
1419 OPC_FMIN_A_df
= (0xD << 22) | OPC_MSA_3RF_1B
,
1420 OPC_MADDR_Q_df
= (0xD << 22) | OPC_MSA_3RF_1C
,
1421 OPC_FSLE_df
= (0xE << 22) | OPC_MSA_3RF_1A
,
1422 OPC_FMAX_df
= (0xE << 22) | OPC_MSA_3RF_1B
,
1423 OPC_MSUBR_Q_df
= (0xE << 22) | OPC_MSA_3RF_1C
,
1424 OPC_FSULE_df
= (0xF << 22) | OPC_MSA_3RF_1A
,
1425 OPC_FMAX_A_df
= (0xF << 22) | OPC_MSA_3RF_1B
,
1427 /* BIT instruction df(bits 22..16) = _B _H _W _D */
1428 OPC_SLLI_df
= (0x0 << 23) | OPC_MSA_BIT_09
,
1429 OPC_SAT_S_df
= (0x0 << 23) | OPC_MSA_BIT_0A
,
1430 OPC_SRAI_df
= (0x1 << 23) | OPC_MSA_BIT_09
,
1431 OPC_SAT_U_df
= (0x1 << 23) | OPC_MSA_BIT_0A
,
1432 OPC_SRLI_df
= (0x2 << 23) | OPC_MSA_BIT_09
,
1433 OPC_SRARI_df
= (0x2 << 23) | OPC_MSA_BIT_0A
,
1434 OPC_BCLRI_df
= (0x3 << 23) | OPC_MSA_BIT_09
,
1435 OPC_SRLRI_df
= (0x3 << 23) | OPC_MSA_BIT_0A
,
1436 OPC_BSETI_df
= (0x4 << 23) | OPC_MSA_BIT_09
,
1437 OPC_BNEGI_df
= (0x5 << 23) | OPC_MSA_BIT_09
,
1438 OPC_BINSLI_df
= (0x6 << 23) | OPC_MSA_BIT_09
,
1439 OPC_BINSRI_df
= (0x7 << 23) | OPC_MSA_BIT_09
,
1445 * AN OVERVIEW OF MXU EXTENSION INSTRUCTION SET
1446 * ============================================
1449 * MXU (full name: MIPS eXtension/enhanced Unit) is a SIMD extension of MIPS32
1450 * instructions set. It is designed to fit the needs of signal, graphical and
1451 * video processing applications. MXU instruction set is used in Xburst family
1452 * of microprocessors by Ingenic.
1454 * MXU unit contains 17 registers called X0-X16. X0 is always zero, and X16 is
1455 * the control register.
1458 * The notation used in MXU assembler mnemonics
1459 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1461 * Register operands:
1463 * XRa, XRb, XRc, XRd - MXU registers
1464 * Rb, Rc, Rd, Rs, Rt - general purpose MIPS registers
1466 * Non-register operands:
1468 * aptn1 - 1-bit accumulate add/subtract pattern
1469 * aptn2 - 2-bit accumulate add/subtract pattern
1470 * eptn2 - 2-bit execute add/subtract pattern
1471 * optn2 - 2-bit operand pattern
1472 * optn3 - 3-bit operand pattern
1473 * sft4 - 4-bit shift amount
1474 * strd2 - 2-bit stride amount
1478 * Level of parallelism: Operand size:
1479 * S - single operation at a time 32 - word
1480 * D - two operations in parallel 16 - half word
1481 * Q - four operations in parallel 8 - byte
1485 * ADD - Add or subtract
1486 * ADDC - Add with carry-in
1488 * ASUM - Sum together then accumulate (add or subtract)
1489 * ASUMC - Sum together then accumulate (add or subtract) with carry-in
1490 * AVG - Average between 2 operands
1491 * ABD - Absolute difference
1493 * AND - Logical bitwise 'and' operation
1495 * EXTR - Extract bits
1496 * I2M - Move from GPR register to MXU register
1497 * LDD - Load data from memory to XRF
1498 * LDI - Load data from memory to XRF (and increase the address base)
1499 * LUI - Load unsigned immediate
1501 * MULU - Unsigned multiply
1502 * MADD - 64-bit operand add 32x32 product
1503 * MSUB - 64-bit operand subtract 32x32 product
1504 * MAC - Multiply and accumulate (add or subtract)
1505 * MAD - Multiply and add or subtract
1506 * MAX - Maximum between 2 operands
1507 * MIN - Minimum between 2 operands
1508 * M2I - Move from MXU register to GPR register
1509 * MOVZ - Move if zero
1510 * MOVN - Move if non-zero
1511 * NOR - Logical bitwise 'nor' operation
1512 * OR - Logical bitwise 'or' operation
1513 * STD - Store data from XRF to memory
1514 * SDI - Store data from XRF to memory (and increase the address base)
1515 * SLT - Set of less than comparison
1516 * SAD - Sum of absolute differences
1517 * SLL - Logical shift left
1518 * SLR - Logical shift right
1519 * SAR - Arithmetic shift right
1522 * SCOP - Calculate x’s scope (-1, means x<0; 0, means x==0; 1, means x>0)
1523 * XOR - Logical bitwise 'exclusive or' operation
1527 * E - Expand results
1528 * F - Fixed point multiplication
1529 * L - Low part result
1530 * R - Doing rounding
1531 * V - Variable instead of immediate
1532 * W - Combine above L and V
1535 * The list of MXU instructions grouped by functionality
1536 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1538 * Load/Store instructions Multiplication instructions
1539 * ----------------------- ---------------------------
1541 * S32LDD XRa, Rb, s12 S32MADD XRa, XRd, Rs, Rt
1542 * S32STD XRa, Rb, s12 S32MADDU XRa, XRd, Rs, Rt
1543 * S32LDDV XRa, Rb, rc, strd2 S32MSUB XRa, XRd, Rs, Rt
1544 * S32STDV XRa, Rb, rc, strd2 S32MSUBU XRa, XRd, Rs, Rt
1545 * S32LDI XRa, Rb, s12 S32MUL XRa, XRd, Rs, Rt
1546 * S32SDI XRa, Rb, s12 S32MULU XRa, XRd, Rs, Rt
1547 * S32LDIV XRa, Rb, rc, strd2 D16MUL XRa, XRb, XRc, XRd, optn2
1548 * S32SDIV XRa, Rb, rc, strd2 D16MULE XRa, XRb, XRc, optn2
1549 * S32LDDR XRa, Rb, s12 D16MULF XRa, XRb, XRc, optn2
1550 * S32STDR XRa, Rb, s12 D16MAC XRa, XRb, XRc, XRd, aptn2, optn2
1551 * S32LDDVR XRa, Rb, rc, strd2 D16MACE XRa, XRb, XRc, XRd, aptn2, optn2
1552 * S32STDVR XRa, Rb, rc, strd2 D16MACF XRa, XRb, XRc, XRd, aptn2, optn2
1553 * S32LDIR XRa, Rb, s12 D16MADL XRa, XRb, XRc, XRd, aptn2, optn2
1554 * S32SDIR XRa, Rb, s12 S16MAD XRa, XRb, XRc, XRd, aptn1, optn2
1555 * S32LDIVR XRa, Rb, rc, strd2 Q8MUL XRa, XRb, XRc, XRd
1556 * S32SDIVR XRa, Rb, rc, strd2 Q8MULSU XRa, XRb, XRc, XRd
1557 * S16LDD XRa, Rb, s10, eptn2 Q8MAC XRa, XRb, XRc, XRd, aptn2
1558 * S16STD XRa, Rb, s10, eptn2 Q8MACSU XRa, XRb, XRc, XRd, aptn2
1559 * S16LDI XRa, Rb, s10, eptn2 Q8MADL XRa, XRb, XRc, XRd, aptn2
1560 * S16SDI XRa, Rb, s10, eptn2
1561 * S8LDD XRa, Rb, s8, eptn3
1562 * S8STD XRa, Rb, s8, eptn3 Addition and subtraction instructions
1563 * S8LDI XRa, Rb, s8, eptn3 -------------------------------------
1564 * S8SDI XRa, Rb, s8, eptn3
1565 * LXW Rd, Rs, Rt, strd2 D32ADD XRa, XRb, XRc, XRd, eptn2
1566 * LXH Rd, Rs, Rt, strd2 D32ADDC XRa, XRb, XRc, XRd
1567 * LXHU Rd, Rs, Rt, strd2 D32ACC XRa, XRb, XRc, XRd, eptn2
1568 * LXB Rd, Rs, Rt, strd2 D32ACCM XRa, XRb, XRc, XRd, eptn2
1569 * LXBU Rd, Rs, Rt, strd2 D32ASUM XRa, XRb, XRc, XRd, eptn2
1570 * S32CPS XRa, XRb, XRc
1571 * Q16ADD XRa, XRb, XRc, XRd, eptn2, optn2
1572 * Comparison instructions Q16ACC XRa, XRb, XRc, XRd, eptn2
1573 * ----------------------- Q16ACCM XRa, XRb, XRc, XRd, eptn2
1574 * D16ASUM XRa, XRb, XRc, XRd, eptn2
1575 * S32MAX XRa, XRb, XRc D16CPS XRa, XRb,
1576 * S32MIN XRa, XRb, XRc D16AVG XRa, XRb, XRc
1577 * S32SLT XRa, XRb, XRc D16AVGR XRa, XRb, XRc
1578 * S32MOVZ XRa, XRb, XRc Q8ADD XRa, XRb, XRc, eptn2
1579 * S32MOVN XRa, XRb, XRc Q8ADDE XRa, XRb, XRc, XRd, eptn2
1580 * D16MAX XRa, XRb, XRc Q8ACCE XRa, XRb, XRc, XRd, eptn2
1581 * D16MIN XRa, XRb, XRc Q8ABD XRa, XRb, XRc
1582 * D16SLT XRa, XRb, XRc Q8SAD XRa, XRb, XRc, XRd
1583 * D16MOVZ XRa, XRb, XRc Q8AVG XRa, XRb, XRc
1584 * D16MOVN XRa, XRb, XRc Q8AVGR XRa, XRb, XRc
1585 * Q8MAX XRa, XRb, XRc D8SUM XRa, XRb, XRc, XRd
1586 * Q8MIN XRa, XRb, XRc D8SUMC XRa, XRb, XRc, XRd
1587 * Q8SLT XRa, XRb, XRc
1588 * Q8SLTU XRa, XRb, XRc
1589 * Q8MOVZ XRa, XRb, XRc Shift instructions
1590 * Q8MOVN XRa, XRb, XRc ------------------
1592 * D32SLL XRa, XRb, XRc, XRd, sft4
1593 * Bitwise instructions D32SLR XRa, XRb, XRc, XRd, sft4
1594 * -------------------- D32SAR XRa, XRb, XRc, XRd, sft4
1595 * D32SARL XRa, XRb, XRc, sft4
1596 * S32NOR XRa, XRb, XRc D32SLLV XRa, XRb, Rb
1597 * S32AND XRa, XRb, XRc D32SLRV XRa, XRb, Rb
1598 * S32XOR XRa, XRb, XRc D32SARV XRa, XRb, Rb
1599 * S32OR XRa, XRb, XRc D32SARW XRa, XRb, XRc, Rb
1600 * Q16SLL XRa, XRb, XRc, XRd, sft4
1601 * Q16SLR XRa, XRb, XRc, XRd, sft4
1602 * Miscellaneous instructions Q16SAR XRa, XRb, XRc, XRd, sft4
1603 * ------------------------- Q16SLLV XRa, XRb, Rb
1604 * Q16SLRV XRa, XRb, Rb
1605 * S32SFL XRa, XRb, XRc, XRd, optn2 Q16SARV XRa, XRb, Rb
1606 * S32ALN XRa, XRb, XRc, Rb
1607 * S32ALNI XRa, XRb, XRc, s3
1608 * S32LUI XRa, s8, optn3 Move instructions
1609 * S32EXTR XRa, XRb, Rb, bits5 -----------------
1610 * S32EXTRV XRa, XRb, Rs, Rt
1611 * Q16SCOP XRa, XRb, XRc, XRd S32M2I XRa, Rb
1612 * Q16SAT XRa, XRb, XRc S32I2M XRa, Rb
1615 * The opcode organization of MXU instructions
1616 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1618 * The bits 31..26 of all MXU instructions are equal to 0x1C (also referred
1619 * as opcode SPECIAL2 in the base MIPS ISA). The organization and meaning of
1620 * other bits up to the instruction level is as follows:
1625 * ┌─ 000000 ─ OPC_MXU_S32MADD
1626 * ├─ 000001 ─ OPC_MXU_S32MADDU
1627 * ├─ 000010 ─ <not assigned> (non-MXU OPC_MUL)
1630 * ├─ 000011 ─ OPC_MXU__POOL00 ─┬─ 000 ─ OPC_MXU_S32MAX
1631 * │ ├─ 001 ─ OPC_MXU_S32MIN
1632 * │ ├─ 010 ─ OPC_MXU_D16MAX
1633 * │ ├─ 011 ─ OPC_MXU_D16MIN
1634 * │ ├─ 100 ─ OPC_MXU_Q8MAX
1635 * │ ├─ 101 ─ OPC_MXU_Q8MIN
1636 * │ ├─ 110 ─ OPC_MXU_Q8SLT
1637 * │ └─ 111 ─ OPC_MXU_Q8SLTU
1638 * ├─ 000100 ─ OPC_MXU_S32MSUB
1639 * ├─ 000101 ─ OPC_MXU_S32MSUBU 20..18
1640 * ├─ 000110 ─ OPC_MXU__POOL01 ─┬─ 000 ─ OPC_MXU_S32SLT
1641 * │ ├─ 001 ─ OPC_MXU_D16SLT
1642 * │ ├─ 010 ─ OPC_MXU_D16AVG
1643 * │ ├─ 011 ─ OPC_MXU_D16AVGR
1644 * │ ├─ 100 ─ OPC_MXU_Q8AVG
1645 * │ ├─ 101 ─ OPC_MXU_Q8AVGR
1646 * │ └─ 111 ─ OPC_MXU_Q8ADD
1649 * ├─ 000111 ─ OPC_MXU__POOL02 ─┬─ 000 ─ OPC_MXU_S32CPS
1650 * │ ├─ 010 ─ OPC_MXU_D16CPS
1651 * │ ├─ 100 ─ OPC_MXU_Q8ABD
1652 * │ └─ 110 ─ OPC_MXU_Q16SAT
1653 * ├─ 001000 ─ OPC_MXU_D16MUL
1655 * ├─ 001001 ─ OPC_MXU__POOL03 ─┬─ 00 ─ OPC_MXU_D16MULF
1656 * │ └─ 01 ─ OPC_MXU_D16MULE
1657 * ├─ 001010 ─ OPC_MXU_D16MAC
1658 * ├─ 001011 ─ OPC_MXU_D16MACF
1659 * ├─ 001100 ─ OPC_MXU_D16MADL
1660 * ├─ 001101 ─ OPC_MXU_S16MAD
1661 * ├─ 001110 ─ OPC_MXU_Q16ADD
1662 * ├─ 001111 ─ OPC_MXU_D16MACE 23
1663 * │ ┌─ 0 ─ OPC_MXU_S32LDD
1664 * ├─ 010000 ─ OPC_MXU__POOL04 ─┴─ 1 ─ OPC_MXU_S32LDDR
1667 * ├─ 010001 ─ OPC_MXU__POOL05 ─┬─ 0 ─ OPC_MXU_S32STD
1668 * │ └─ 1 ─ OPC_MXU_S32STDR
1671 * ├─ 010010 ─ OPC_MXU__POOL06 ─┬─ 0000 ─ OPC_MXU_S32LDDV
1672 * │ └─ 0001 ─ OPC_MXU_S32LDDVR
1675 * ├─ 010011 ─ OPC_MXU__POOL07 ─┬─ 0000 ─ OPC_MXU_S32STDV
1676 * │ └─ 0001 ─ OPC_MXU_S32STDVR
1679 * ├─ 010100 ─ OPC_MXU__POOL08 ─┬─ 0 ─ OPC_MXU_S32LDI
1680 * │ └─ 1 ─ OPC_MXU_S32LDIR
1683 * ├─ 010101 ─ OPC_MXU__POOL09 ─┬─ 0 ─ OPC_MXU_S32SDI
1684 * │ └─ 1 ─ OPC_MXU_S32SDIR
1687 * ├─ 010110 ─ OPC_MXU__POOL10 ─┬─ 0000 ─ OPC_MXU_S32LDIV
1688 * │ └─ 0001 ─ OPC_MXU_S32LDIVR
1691 * ├─ 010111 ─ OPC_MXU__POOL11 ─┬─ 0000 ─ OPC_MXU_S32SDIV
1692 * │ └─ 0001 ─ OPC_MXU_S32SDIVR
1693 * ├─ 011000 ─ OPC_MXU_D32ADD
1695 * MXU ├─ 011001 ─ OPC_MXU__POOL12 ─┬─ 00 ─ OPC_MXU_D32ACC
1696 * opcodes ─┤ ├─ 01 ─ OPC_MXU_D32ACCM
1697 * │ └─ 10 ─ OPC_MXU_D32ASUM
1698 * ├─ 011010 ─ <not assigned>
1700 * ├─ 011011 ─ OPC_MXU__POOL13 ─┬─ 00 ─ OPC_MXU_Q16ACC
1701 * │ ├─ 01 ─ OPC_MXU_Q16ACCM
1702 * │ └─ 10 ─ OPC_MXU_Q16ASUM
1705 * ├─ 011100 ─ OPC_MXU__POOL14 ─┬─ 00 ─ OPC_MXU_Q8ADDE
1706 * │ ├─ 01 ─ OPC_MXU_D8SUM
1707 * ├─ 011101 ─ OPC_MXU_Q8ACCE └─ 10 ─ OPC_MXU_D8SUMC
1708 * ├─ 011110 ─ <not assigned>
1709 * ├─ 011111 ─ <not assigned>
1710 * ├─ 100000 ─ <not assigned> (overlaps with CLZ)
1711 * ├─ 100001 ─ <not assigned> (overlaps with CLO)
1712 * ├─ 100010 ─ OPC_MXU_S8LDD
1713 * ├─ 100011 ─ OPC_MXU_S8STD 15..14
1714 * ├─ 100100 ─ OPC_MXU_S8LDI ┌─ 00 ─ OPC_MXU_S32MUL
1715 * ├─ 100101 ─ OPC_MXU_S8SDI ├─ 00 ─ OPC_MXU_S32MULU
1716 * │ ├─ 00 ─ OPC_MXU_S32EXTR
1717 * ├─ 100110 ─ OPC_MXU__POOL15 ─┴─ 00 ─ OPC_MXU_S32EXTRV
1720 * ├─ 100111 ─ OPC_MXU__POOL16 ─┬─ 000 ─ OPC_MXU_D32SARW
1721 * │ ├─ 001 ─ OPC_MXU_S32ALN
1722 * │ ├─ 010 ─ OPC_MXU_S32ALNI
1723 * │ ├─ 011 ─ OPC_MXU_S32LUI
1724 * │ ├─ 100 ─ OPC_MXU_S32NOR
1725 * │ ├─ 101 ─ OPC_MXU_S32AND
1726 * │ ├─ 110 ─ OPC_MXU_S32OR
1727 * │ └─ 111 ─ OPC_MXU_S32XOR
1730 * ├─ 101000 ─ OPC_MXU__POOL17 ─┬─ 000 ─ OPC_MXU_LXB
1731 * │ ├─ 001 ─ OPC_MXU_LXH
1732 * ├─ 101001 ─ <not assigned> ├─ 011 ─ OPC_MXU_LXW
1733 * ├─ 101010 ─ OPC_MXU_S16LDD ├─ 100 ─ OPC_MXU_LXBU
1734 * ├─ 101011 ─ OPC_MXU_S16STD └─ 101 ─ OPC_MXU_LXHU
1735 * ├─ 101100 ─ OPC_MXU_S16LDI
1736 * ├─ 101101 ─ OPC_MXU_S16SDI
1737 * ├─ 101110 ─ OPC_MXU_S32M2I
1738 * ├─ 101111 ─ OPC_MXU_S32I2M
1739 * ├─ 110000 ─ OPC_MXU_D32SLL
1740 * ├─ 110001 ─ OPC_MXU_D32SLR 20..18
1741 * ├─ 110010 ─ OPC_MXU_D32SARL ┌─ 000 ─ OPC_MXU_D32SLLV
1742 * ├─ 110011 ─ OPC_MXU_D32SAR ├─ 001 ─ OPC_MXU_D32SLRV
1743 * ├─ 110100 ─ OPC_MXU_Q16SLL ├─ 010 ─ OPC_MXU_D32SARV
1744 * ├─ 110101 ─ OPC_MXU_Q16SLR ├─ 011 ─ OPC_MXU_Q16SLLV
1745 * │ ├─ 100 ─ OPC_MXU_Q16SLRV
1746 * ├─ 110110 ─ OPC_MXU__POOL18 ─┴─ 101 ─ OPC_MXU_Q16SARV
1748 * ├─ 110111 ─ OPC_MXU_Q16SAR
1750 * ├─ 111000 ─ OPC_MXU__POOL19 ─┬─ 00 ─ OPC_MXU_Q8MUL
1751 * │ └─ 01 ─ OPC_MXU_Q8MULSU
1754 * ├─ 111001 ─ OPC_MXU__POOL20 ─┬─ 000 ─ OPC_MXU_Q8MOVZ
1755 * │ ├─ 001 ─ OPC_MXU_Q8MOVN
1756 * │ ├─ 010 ─ OPC_MXU_D16MOVZ
1757 * │ ├─ 011 ─ OPC_MXU_D16MOVN
1758 * │ ├─ 100 ─ OPC_MXU_S32MOVZ
1759 * │ └─ 101 ─ OPC_MXU_S32MOVN
1762 * ├─ 111010 ─ OPC_MXU__POOL21 ─┬─ 00 ─ OPC_MXU_Q8MAC
1763 * │ └─ 10 ─ OPC_MXU_Q8MACSU
1764 * ├─ 111011 ─ OPC_MXU_Q16SCOP
1765 * ├─ 111100 ─ OPC_MXU_Q8MADL
1766 * ├─ 111101 ─ OPC_MXU_S32SFL
1767 * ├─ 111110 ─ OPC_MXU_Q8SAD
1768 * └─ 111111 ─ <not assigned> (overlaps with SDBBP)
1773 * "XBurst® Instruction Set Architecture MIPS eXtension/enhanced Unit
1774 * Programming Manual", Ingenic Semiconductor Co, Ltd., revision June 2, 2017
1778 OPC_MXU_S32MADD
= 0x00,
1779 OPC_MXU_S32MADDU
= 0x01,
1780 OPC__MXU_MUL
= 0x02,
1781 OPC_MXU__POOL00
= 0x03,
1782 OPC_MXU_S32MSUB
= 0x04,
1783 OPC_MXU_S32MSUBU
= 0x05,
1784 OPC_MXU__POOL01
= 0x06,
1785 OPC_MXU__POOL02
= 0x07,
1786 OPC_MXU_D16MUL
= 0x08,
1787 OPC_MXU__POOL03
= 0x09,
1788 OPC_MXU_D16MAC
= 0x0A,
1789 OPC_MXU_D16MACF
= 0x0B,
1790 OPC_MXU_D16MADL
= 0x0C,
1791 OPC_MXU_S16MAD
= 0x0D,
1792 OPC_MXU_Q16ADD
= 0x0E,
1793 OPC_MXU_D16MACE
= 0x0F,
1794 OPC_MXU__POOL04
= 0x10,
1795 OPC_MXU__POOL05
= 0x11,
1796 OPC_MXU__POOL06
= 0x12,
1797 OPC_MXU__POOL07
= 0x13,
1798 OPC_MXU__POOL08
= 0x14,
1799 OPC_MXU__POOL09
= 0x15,
1800 OPC_MXU__POOL10
= 0x16,
1801 OPC_MXU__POOL11
= 0x17,
1802 OPC_MXU_D32ADD
= 0x18,
1803 OPC_MXU__POOL12
= 0x19,
1804 /* not assigned 0x1A */
1805 OPC_MXU__POOL13
= 0x1B,
1806 OPC_MXU__POOL14
= 0x1C,
1807 OPC_MXU_Q8ACCE
= 0x1D,
1808 /* not assigned 0x1E */
1809 /* not assigned 0x1F */
1810 /* not assigned 0x20 */
1811 /* not assigned 0x21 */
1812 OPC_MXU_S8LDD
= 0x22,
1813 OPC_MXU_S8STD
= 0x23,
1814 OPC_MXU_S8LDI
= 0x24,
1815 OPC_MXU_S8SDI
= 0x25,
1816 OPC_MXU__POOL15
= 0x26,
1817 OPC_MXU__POOL16
= 0x27,
1818 OPC_MXU__POOL17
= 0x28,
1819 /* not assigned 0x29 */
1820 OPC_MXU_S16LDD
= 0x2A,
1821 OPC_MXU_S16STD
= 0x2B,
1822 OPC_MXU_S16LDI
= 0x2C,
1823 OPC_MXU_S16SDI
= 0x2D,
1824 OPC_MXU_S32M2I
= 0x2E,
1825 OPC_MXU_S32I2M
= 0x2F,
1826 OPC_MXU_D32SLL
= 0x30,
1827 OPC_MXU_D32SLR
= 0x31,
1828 OPC_MXU_D32SARL
= 0x32,
1829 OPC_MXU_D32SAR
= 0x33,
1830 OPC_MXU_Q16SLL
= 0x34,
1831 OPC_MXU_Q16SLR
= 0x35,
1832 OPC_MXU__POOL18
= 0x36,
1833 OPC_MXU_Q16SAR
= 0x37,
1834 OPC_MXU__POOL19
= 0x38,
1835 OPC_MXU__POOL20
= 0x39,
1836 OPC_MXU__POOL21
= 0x3A,
1837 OPC_MXU_Q16SCOP
= 0x3B,
1838 OPC_MXU_Q8MADL
= 0x3C,
1839 OPC_MXU_S32SFL
= 0x3D,
1840 OPC_MXU_Q8SAD
= 0x3E,
1841 /* not assigned 0x3F */
1849 OPC_MXU_S32MAX
= 0x00,
1850 OPC_MXU_S32MIN
= 0x01,
1851 OPC_MXU_D16MAX
= 0x02,
1852 OPC_MXU_D16MIN
= 0x03,
1853 OPC_MXU_Q8MAX
= 0x04,
1854 OPC_MXU_Q8MIN
= 0x05,
1855 OPC_MXU_Q8SLT
= 0x06,
1856 OPC_MXU_Q8SLTU
= 0x07,
1863 OPC_MXU_S32SLT
= 0x00,
1864 OPC_MXU_D16SLT
= 0x01,
1865 OPC_MXU_D16AVG
= 0x02,
1866 OPC_MXU_D16AVGR
= 0x03,
1867 OPC_MXU_Q8AVG
= 0x04,
1868 OPC_MXU_Q8AVGR
= 0x05,
1869 OPC_MXU_Q8ADD
= 0x07,
1876 OPC_MXU_S32CPS
= 0x00,
1877 OPC_MXU_D16CPS
= 0x02,
1878 OPC_MXU_Q8ABD
= 0x04,
1879 OPC_MXU_Q16SAT
= 0x06,
1886 OPC_MXU_D16MULF
= 0x00,
1887 OPC_MXU_D16MULE
= 0x01,
1894 OPC_MXU_S32LDD
= 0x00,
1895 OPC_MXU_S32LDDR
= 0x01,
1902 OPC_MXU_S32STD
= 0x00,
1903 OPC_MXU_S32STDR
= 0x01,
1910 OPC_MXU_S32LDDV
= 0x00,
1911 OPC_MXU_S32LDDVR
= 0x01,
1918 OPC_MXU_S32STDV
= 0x00,
1919 OPC_MXU_S32STDVR
= 0x01,
1926 OPC_MXU_S32LDI
= 0x00,
1927 OPC_MXU_S32LDIR
= 0x01,
1934 OPC_MXU_S32SDI
= 0x00,
1935 OPC_MXU_S32SDIR
= 0x01,
1942 OPC_MXU_S32LDIV
= 0x00,
1943 OPC_MXU_S32LDIVR
= 0x01,
1950 OPC_MXU_S32SDIV
= 0x00,
1951 OPC_MXU_S32SDIVR
= 0x01,
1958 OPC_MXU_D32ACC
= 0x00,
1959 OPC_MXU_D32ACCM
= 0x01,
1960 OPC_MXU_D32ASUM
= 0x02,
1967 OPC_MXU_Q16ACC
= 0x00,
1968 OPC_MXU_Q16ACCM
= 0x01,
1969 OPC_MXU_Q16ASUM
= 0x02,
1976 OPC_MXU_Q8ADDE
= 0x00,
1977 OPC_MXU_D8SUM
= 0x01,
1978 OPC_MXU_D8SUMC
= 0x02,
1985 OPC_MXU_S32MUL
= 0x00,
1986 OPC_MXU_S32MULU
= 0x01,
1987 OPC_MXU_S32EXTR
= 0x02,
1988 OPC_MXU_S32EXTRV
= 0x03,
1995 OPC_MXU_D32SARW
= 0x00,
1996 OPC_MXU_S32ALN
= 0x01,
1997 OPC_MXU_S32ALNI
= 0x02,
1998 OPC_MXU_S32LUI
= 0x03,
1999 OPC_MXU_S32NOR
= 0x04,
2000 OPC_MXU_S32AND
= 0x05,
2001 OPC_MXU_S32OR
= 0x06,
2002 OPC_MXU_S32XOR
= 0x07,
2012 OPC_MXU_LXBU
= 0x04,
2013 OPC_MXU_LXHU
= 0x05,
2020 OPC_MXU_D32SLLV
= 0x00,
2021 OPC_MXU_D32SLRV
= 0x01,
2022 OPC_MXU_D32SARV
= 0x03,
2023 OPC_MXU_Q16SLLV
= 0x04,
2024 OPC_MXU_Q16SLRV
= 0x05,
2025 OPC_MXU_Q16SARV
= 0x07,
2032 OPC_MXU_Q8MUL
= 0x00,
2033 OPC_MXU_Q8MULSU
= 0x01,
2040 OPC_MXU_Q8MOVZ
= 0x00,
2041 OPC_MXU_Q8MOVN
= 0x01,
2042 OPC_MXU_D16MOVZ
= 0x02,
2043 OPC_MXU_D16MOVN
= 0x03,
2044 OPC_MXU_S32MOVZ
= 0x04,
2045 OPC_MXU_S32MOVN
= 0x05,
2052 OPC_MXU_Q8MAC
= 0x00,
2053 OPC_MXU_Q8MACSU
= 0x01,
2057 * Overview of the TX79-specific instruction set
2058 * =============================================
2060 * The R5900 and the C790 have 128-bit wide GPRs, where the upper 64 bits
2061 * are only used by the specific quadword (128-bit) LQ/SQ load/store
2062 * instructions and certain multimedia instructions (MMIs). These MMIs
2063 * configure the 128-bit data path as two 64-bit, four 32-bit, eight 16-bit
2064 * or sixteen 8-bit paths.
2068 * The Toshiba TX System RISC TX79 Core Architecture manual,
2069 * https://wiki.qemu.org/File:C790.pdf
2071 * Three-Operand Multiply and Multiply-Add (4 instructions)
2072 * --------------------------------------------------------
2073 * MADD [rd,] rs, rt Multiply/Add
2074 * MADDU [rd,] rs, rt Multiply/Add Unsigned
2075 * MULT [rd,] rs, rt Multiply (3-operand)
2076 * MULTU [rd,] rs, rt Multiply Unsigned (3-operand)
2078 * Multiply Instructions for Pipeline 1 (10 instructions)
2079 * ------------------------------------------------------
2080 * MULT1 [rd,] rs, rt Multiply Pipeline 1
2081 * MULTU1 [rd,] rs, rt Multiply Unsigned Pipeline 1
2082 * DIV1 rs, rt Divide Pipeline 1
2083 * DIVU1 rs, rt Divide Unsigned Pipeline 1
2084 * MADD1 [rd,] rs, rt Multiply-Add Pipeline 1
2085 * MADDU1 [rd,] rs, rt Multiply-Add Unsigned Pipeline 1
2086 * MFHI1 rd Move From HI1 Register
2087 * MFLO1 rd Move From LO1 Register
2088 * MTHI1 rs Move To HI1 Register
2089 * MTLO1 rs Move To LO1 Register
2091 * Arithmetic (19 instructions)
2092 * ----------------------------
2093 * PADDB rd, rs, rt Parallel Add Byte
2094 * PSUBB rd, rs, rt Parallel Subtract Byte
2095 * PADDH rd, rs, rt Parallel Add Halfword
2096 * PSUBH rd, rs, rt Parallel Subtract Halfword
2097 * PADDW rd, rs, rt Parallel Add Word
2098 * PSUBW rd, rs, rt Parallel Subtract Word
2099 * PADSBH rd, rs, rt Parallel Add/Subtract Halfword
2100 * PADDSB rd, rs, rt Parallel Add with Signed Saturation Byte
2101 * PSUBSB rd, rs, rt Parallel Subtract with Signed Saturation Byte
2102 * PADDSH rd, rs, rt Parallel Add with Signed Saturation Halfword
2103 * PSUBSH rd, rs, rt Parallel Subtract with Signed Saturation Halfword
2104 * PADDSW rd, rs, rt Parallel Add with Signed Saturation Word
2105 * PSUBSW rd, rs, rt Parallel Subtract with Signed Saturation Word
2106 * PADDUB rd, rs, rt Parallel Add with Unsigned saturation Byte
2107 * PSUBUB rd, rs, rt Parallel Subtract with Unsigned saturation Byte
2108 * PADDUH rd, rs, rt Parallel Add with Unsigned saturation Halfword
2109 * PSUBUH rd, rs, rt Parallel Subtract with Unsigned saturation Halfword
2110 * PADDUW rd, rs, rt Parallel Add with Unsigned saturation Word
2111 * PSUBUW rd, rs, rt Parallel Subtract with Unsigned saturation Word
2113 * Min/Max (4 instructions)
2114 * ------------------------
2115 * PMAXH rd, rs, rt Parallel Maximum Halfword
2116 * PMINH rd, rs, rt Parallel Minimum Halfword
2117 * PMAXW rd, rs, rt Parallel Maximum Word
2118 * PMINW rd, rs, rt Parallel Minimum Word
2120 * Absolute (2 instructions)
2121 * -------------------------
2122 * PABSH rd, rt Parallel Absolute Halfword
2123 * PABSW rd, rt Parallel Absolute Word
2125 * Logical (4 instructions)
2126 * ------------------------
2127 * PAND rd, rs, rt Parallel AND
2128 * POR rd, rs, rt Parallel OR
2129 * PXOR rd, rs, rt Parallel XOR
2130 * PNOR rd, rs, rt Parallel NOR
2132 * Shift (9 instructions)
2133 * ----------------------
2134 * PSLLH rd, rt, sa Parallel Shift Left Logical Halfword
2135 * PSRLH rd, rt, sa Parallel Shift Right Logical Halfword
2136 * PSRAH rd, rt, sa Parallel Shift Right Arithmetic Halfword
2137 * PSLLW rd, rt, sa Parallel Shift Left Logical Word
2138 * PSRLW rd, rt, sa Parallel Shift Right Logical Word
2139 * PSRAW rd, rt, sa Parallel Shift Right Arithmetic Word
2140 * PSLLVW rd, rt, rs Parallel Shift Left Logical Variable Word
2141 * PSRLVW rd, rt, rs Parallel Shift Right Logical Variable Word
2142 * PSRAVW rd, rt, rs Parallel Shift Right Arithmetic Variable Word
2144 * Compare (6 instructions)
2145 * ------------------------
2146 * PCGTB rd, rs, rt Parallel Compare for Greater Than Byte
2147 * PCEQB rd, rs, rt Parallel Compare for Equal Byte
2148 * PCGTH rd, rs, rt Parallel Compare for Greater Than Halfword
2149 * PCEQH rd, rs, rt Parallel Compare for Equal Halfword
2150 * PCGTW rd, rs, rt Parallel Compare for Greater Than Word
2151 * PCEQW rd, rs, rt Parallel Compare for Equal Word
2153 * LZC (1 instruction)
2154 * -------------------
2155 * PLZCW rd, rs Parallel Leading Zero or One Count Word
2157 * Quadword Load and Store (2 instructions)
2158 * ----------------------------------------
2159 * LQ rt, offset(base) Load Quadword
2160 * SQ rt, offset(base) Store Quadword
2162 * Multiply and Divide (19 instructions)
2163 * -------------------------------------
2164 * PMULTW rd, rs, rt Parallel Multiply Word
2165 * PMULTUW rd, rs, rt Parallel Multiply Unsigned Word
2166 * PDIVW rs, rt Parallel Divide Word
2167 * PDIVUW rs, rt Parallel Divide Unsigned Word
2168 * PMADDW rd, rs, rt Parallel Multiply-Add Word
2169 * PMADDUW rd, rs, rt Parallel Multiply-Add Unsigned Word
2170 * PMSUBW rd, rs, rt Parallel Multiply-Subtract Word
2171 * PMULTH rd, rs, rt Parallel Multiply Halfword
2172 * PMADDH rd, rs, rt Parallel Multiply-Add Halfword
2173 * PMSUBH rd, rs, rt Parallel Multiply-Subtract Halfword
2174 * PHMADH rd, rs, rt Parallel Horizontal Multiply-Add Halfword
2175 * PHMSBH rd, rs, rt Parallel Horizontal Multiply-Subtract Halfword
2176 * PDIVBW rs, rt Parallel Divide Broadcast Word
2177 * PMFHI rd Parallel Move From HI Register
2178 * PMFLO rd Parallel Move From LO Register
2179 * PMTHI rs Parallel Move To HI Register
2180 * PMTLO rs Parallel Move To LO Register
2181 * PMFHL rd Parallel Move From HI/LO Register
2182 * PMTHL rs Parallel Move To HI/LO Register
2184 * Pack/Extend (11 instructions)
2185 * -----------------------------
2186 * PPAC5 rd, rt Parallel Pack to 5 bits
2187 * PPACB rd, rs, rt Parallel Pack to Byte
2188 * PPACH rd, rs, rt Parallel Pack to Halfword
2189 * PPACW rd, rs, rt Parallel Pack to Word
2190 * PEXT5 rd, rt Parallel Extend Upper from 5 bits
2191 * PEXTUB rd, rs, rt Parallel Extend Upper from Byte
2192 * PEXTLB rd, rs, rt Parallel Extend Lower from Byte
2193 * PEXTUH rd, rs, rt Parallel Extend Upper from Halfword
2194 * PEXTLH rd, rs, rt Parallel Extend Lower from Halfword
2195 * PEXTUW rd, rs, rt Parallel Extend Upper from Word
2196 * PEXTLW rd, rs, rt Parallel Extend Lower from Word
2198 * Others (16 instructions)
2199 * ------------------------
2200 * PCPYH rd, rt Parallel Copy Halfword
2201 * PCPYLD rd, rs, rt Parallel Copy Lower Doubleword
2202 * PCPYUD rd, rs, rt Parallel Copy Upper Doubleword
2203 * PREVH rd, rt Parallel Reverse Halfword
2204 * PINTH rd, rs, rt Parallel Interleave Halfword
2205 * PINTEH rd, rs, rt Parallel Interleave Even Halfword
2206 * PEXEH rd, rt Parallel Exchange Even Halfword
2207 * PEXCH rd, rt Parallel Exchange Center Halfword
2208 * PEXEW rd, rt Parallel Exchange Even Word
2209 * PEXCW rd, rt Parallel Exchange Center Word
2210 * QFSRV rd, rs, rt Quadword Funnel Shift Right Variable
2211 * MFSA rd Move from Shift Amount Register
2212 * MTSA rs Move to Shift Amount Register
2213 * MTSAB rs, immediate Move Byte Count to Shift Amount Register
2214 * MTSAH rs, immediate Move Halfword Count to Shift Amount Register
2215 * PROT3W rd, rt Parallel Rotate 3 Words
2217 * MMI (MultiMedia Instruction) encodings
2218 * ======================================
2220 * MMI instructions encoding table keys:
2222 * * This code is reserved for future use. An attempt to execute it
2223 * causes a Reserved Instruction exception.
2224 * % This code indicates an instruction class. The instruction word
2225 * must be further decoded by examining additional tables that show
2226 * the values for other instruction fields.
2227 * # This code is reserved for the unsupported instructions DMULT,
2228 * DMULTU, DDIV, DDIVU, LL, LLD, SC, SCD, LWC2 and SWC2. An attempt
2229 * to execute it causes a Reserved Instruction exception.
2231 * MMI instructions encoded by opcode field (MMI, LQ, SQ):
2234 * +--------+----------------------------------------+
2236 * +--------+----------------------------------------+
2238 * opcode bits 28..26
2239 * bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
2240 * 31..29 | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111
2241 * -------+-------+-------+-------+-------+-------+-------+-------+-------
2242 * 0 000 |SPECIAL| REGIMM| J | JAL | BEQ | BNE | BLEZ | BGTZ
2243 * 1 001 | ADDI | ADDIU | SLTI | SLTIU | ANDI | ORI | XORI | LUI
2244 * 2 010 | COP0 | COP1 | * | * | BEQL | BNEL | BLEZL | BGTZL
2245 * 3 011 | DADDI | DADDIU| LDL | LDR | MMI% | * | LQ | SQ
2246 * 4 100 | LB | LH | LWL | LW | LBU | LHU | LWR | LWU
2247 * 5 101 | SB | SH | SWL | SW | SDL | SDR | SWR | CACHE
2248 * 6 110 | # | LWC1 | # | PREF | # | LDC1 | # | LD
2249 * 7 111 | # | SWC1 | # | * | # | SDC1 | # | SD
2253 MMI_OPC_CLASS_MMI
= 0x1C << 26, /* Same as OPC_SPECIAL2 */
2254 MMI_OPC_LQ
= 0x1E << 26, /* Same as OPC_MSA */
2255 MMI_OPC_SQ
= 0x1F << 26, /* Same as OPC_SPECIAL3 */
2259 * MMI instructions with opcode field = MMI:
2262 * +--------+-------------------------------+--------+
2263 * | MMI | |function|
2264 * +--------+-------------------------------+--------+
2266 * function bits 2..0
2267 * bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
2268 * 5..3 | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111
2269 * -------+-------+-------+-------+-------+-------+-------+-------+-------
2270 * 0 000 | MADD | MADDU | * | * | PLZCW | * | * | *
2271 * 1 001 | MMI0% | MMI2% | * | * | * | * | * | *
2272 * 2 010 | MFHI1 | MTHI1 | MFLO1 | MTLO1 | * | * | * | *
2273 * 3 011 | MULT1 | MULTU1| DIV1 | DIVU1 | * | * | * | *
2274 * 4 100 | MADD1 | MADDU1| * | * | * | * | * | *
2275 * 5 101 | MMI1% | MMI3% | * | * | * | * | * | *
2276 * 6 110 | PMFHL | PMTHL | * | * | PSLLH | * | PSRLH | PSRAH
2277 * 7 111 | * | * | * | * | PSLLW | * | PSRLW | PSRAW
2280 #define MASK_MMI(op) (MASK_OP_MAJOR(op) | ((op) & 0x3F))
2282 MMI_OPC_MADD
= 0x00 | MMI_OPC_CLASS_MMI
, /* Same as OPC_MADD */
2283 MMI_OPC_MADDU
= 0x01 | MMI_OPC_CLASS_MMI
, /* Same as OPC_MADDU */
2284 MMI_OPC_PLZCW
= 0x04 | MMI_OPC_CLASS_MMI
,
2285 MMI_OPC_CLASS_MMI0
= 0x08 | MMI_OPC_CLASS_MMI
,
2286 MMI_OPC_CLASS_MMI2
= 0x09 | MMI_OPC_CLASS_MMI
,
2287 MMI_OPC_MFHI1
= 0x10 | MMI_OPC_CLASS_MMI
, /* Same minor as OPC_MFHI */
2288 MMI_OPC_MTHI1
= 0x11 | MMI_OPC_CLASS_MMI
, /* Same minor as OPC_MTHI */
2289 MMI_OPC_MFLO1
= 0x12 | MMI_OPC_CLASS_MMI
, /* Same minor as OPC_MFLO */
2290 MMI_OPC_MTLO1
= 0x13 | MMI_OPC_CLASS_MMI
, /* Same minor as OPC_MTLO */
2291 MMI_OPC_MULT1
= 0x18 | MMI_OPC_CLASS_MMI
, /* Same minor as OPC_MULT */
2292 MMI_OPC_MULTU1
= 0x19 | MMI_OPC_CLASS_MMI
, /* Same min. as OPC_MULTU */
2293 MMI_OPC_DIV1
= 0x1A | MMI_OPC_CLASS_MMI
, /* Same minor as OPC_DIV */
2294 MMI_OPC_DIVU1
= 0x1B | MMI_OPC_CLASS_MMI
, /* Same minor as OPC_DIVU */
2295 MMI_OPC_MADD1
= 0x20 | MMI_OPC_CLASS_MMI
,
2296 MMI_OPC_MADDU1
= 0x21 | MMI_OPC_CLASS_MMI
,
2297 MMI_OPC_CLASS_MMI1
= 0x28 | MMI_OPC_CLASS_MMI
,
2298 MMI_OPC_CLASS_MMI3
= 0x29 | MMI_OPC_CLASS_MMI
,
2299 MMI_OPC_PMFHL
= 0x30 | MMI_OPC_CLASS_MMI
,
2300 MMI_OPC_PMTHL
= 0x31 | MMI_OPC_CLASS_MMI
,
2301 MMI_OPC_PSLLH
= 0x34 | MMI_OPC_CLASS_MMI
,
2302 MMI_OPC_PSRLH
= 0x36 | MMI_OPC_CLASS_MMI
,
2303 MMI_OPC_PSRAH
= 0x37 | MMI_OPC_CLASS_MMI
,
2304 MMI_OPC_PSLLW
= 0x3C | MMI_OPC_CLASS_MMI
,
2305 MMI_OPC_PSRLW
= 0x3E | MMI_OPC_CLASS_MMI
,
2306 MMI_OPC_PSRAW
= 0x3F | MMI_OPC_CLASS_MMI
,
2310 * MMI instructions with opcode field = MMI and bits 5..0 = MMI0:
2313 * +--------+----------------------+--------+--------+
2314 * | MMI | |function| MMI0 |
2315 * +--------+----------------------+--------+--------+
2317 * function bits 7..6
2318 * bits | 0 | 1 | 2 | 3
2319 * 10..8 | 00 | 01 | 10 | 11
2320 * -------+-------+-------+-------+-------
2321 * 0 000 | PADDW | PSUBW | PCGTW | PMAXW
2322 * 1 001 | PADDH | PSUBH | PCGTH | PMAXH
2323 * 2 010 | PADDB | PSUBB | PCGTB | *
2324 * 3 011 | * | * | * | *
2325 * 4 100 | PADDSW| PSUBSW| PEXTLW| PPACW
2326 * 5 101 | PADDSH| PSUBSH| PEXTLH| PPACH
2327 * 6 110 | PADDSB| PSUBSB| PEXTLB| PPACB
2328 * 7 111 | * | * | PEXT5 | PPAC5
2331 #define MASK_MMI0(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
2333 MMI_OPC_0_PADDW
= (0x00 << 6) | MMI_OPC_CLASS_MMI0
,
2334 MMI_OPC_0_PSUBW
= (0x01 << 6) | MMI_OPC_CLASS_MMI0
,
2335 MMI_OPC_0_PCGTW
= (0x02 << 6) | MMI_OPC_CLASS_MMI0
,
2336 MMI_OPC_0_PMAXW
= (0x03 << 6) | MMI_OPC_CLASS_MMI0
,
2337 MMI_OPC_0_PADDH
= (0x04 << 6) | MMI_OPC_CLASS_MMI0
,
2338 MMI_OPC_0_PSUBH
= (0x05 << 6) | MMI_OPC_CLASS_MMI0
,
2339 MMI_OPC_0_PCGTH
= (0x06 << 6) | MMI_OPC_CLASS_MMI0
,
2340 MMI_OPC_0_PMAXH
= (0x07 << 6) | MMI_OPC_CLASS_MMI0
,
2341 MMI_OPC_0_PADDB
= (0x08 << 6) | MMI_OPC_CLASS_MMI0
,
2342 MMI_OPC_0_PSUBB
= (0x09 << 6) | MMI_OPC_CLASS_MMI0
,
2343 MMI_OPC_0_PCGTB
= (0x0A << 6) | MMI_OPC_CLASS_MMI0
,
2344 MMI_OPC_0_PADDSW
= (0x10 << 6) | MMI_OPC_CLASS_MMI0
,
2345 MMI_OPC_0_PSUBSW
= (0x11 << 6) | MMI_OPC_CLASS_MMI0
,
2346 MMI_OPC_0_PEXTLW
= (0x12 << 6) | MMI_OPC_CLASS_MMI0
,
2347 MMI_OPC_0_PPACW
= (0x13 << 6) | MMI_OPC_CLASS_MMI0
,
2348 MMI_OPC_0_PADDSH
= (0x14 << 6) | MMI_OPC_CLASS_MMI0
,
2349 MMI_OPC_0_PSUBSH
= (0x15 << 6) | MMI_OPC_CLASS_MMI0
,
2350 MMI_OPC_0_PEXTLH
= (0x16 << 6) | MMI_OPC_CLASS_MMI0
,
2351 MMI_OPC_0_PPACH
= (0x17 << 6) | MMI_OPC_CLASS_MMI0
,
2352 MMI_OPC_0_PADDSB
= (0x18 << 6) | MMI_OPC_CLASS_MMI0
,
2353 MMI_OPC_0_PSUBSB
= (0x19 << 6) | MMI_OPC_CLASS_MMI0
,
2354 MMI_OPC_0_PEXTLB
= (0x1A << 6) | MMI_OPC_CLASS_MMI0
,
2355 MMI_OPC_0_PPACB
= (0x1B << 6) | MMI_OPC_CLASS_MMI0
,
2356 MMI_OPC_0_PEXT5
= (0x1E << 6) | MMI_OPC_CLASS_MMI0
,
2357 MMI_OPC_0_PPAC5
= (0x1F << 6) | MMI_OPC_CLASS_MMI0
,
2361 * MMI instructions with opcode field = MMI and bits 5..0 = MMI1:
2364 * +--------+----------------------+--------+--------+
2365 * | MMI | |function| MMI1 |
2366 * +--------+----------------------+--------+--------+
2368 * function bits 7..6
2369 * bits | 0 | 1 | 2 | 3
2370 * 10..8 | 00 | 01 | 10 | 11
2371 * -------+-------+-------+-------+-------
2372 * 0 000 | * | PABSW | PCEQW | PMINW
2373 * 1 001 | PADSBH| PABSH | PCEQH | PMINH
2374 * 2 010 | * | * | PCEQB | *
2375 * 3 011 | * | * | * | *
2376 * 4 100 | PADDUW| PSUBUW| PEXTUW| *
2377 * 5 101 | PADDUH| PSUBUH| PEXTUH| *
2378 * 6 110 | PADDUB| PSUBUB| PEXTUB| QFSRV
2379 * 7 111 | * | * | * | *
2382 #define MASK_MMI1(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
2384 MMI_OPC_1_PABSW
= (0x01 << 6) | MMI_OPC_CLASS_MMI1
,
2385 MMI_OPC_1_PCEQW
= (0x02 << 6) | MMI_OPC_CLASS_MMI1
,
2386 MMI_OPC_1_PMINW
= (0x03 << 6) | MMI_OPC_CLASS_MMI1
,
2387 MMI_OPC_1_PADSBH
= (0x04 << 6) | MMI_OPC_CLASS_MMI1
,
2388 MMI_OPC_1_PABSH
= (0x05 << 6) | MMI_OPC_CLASS_MMI1
,
2389 MMI_OPC_1_PCEQH
= (0x06 << 6) | MMI_OPC_CLASS_MMI1
,
2390 MMI_OPC_1_PMINH
= (0x07 << 6) | MMI_OPC_CLASS_MMI1
,
2391 MMI_OPC_1_PCEQB
= (0x0A << 6) | MMI_OPC_CLASS_MMI1
,
2392 MMI_OPC_1_PADDUW
= (0x10 << 6) | MMI_OPC_CLASS_MMI1
,
2393 MMI_OPC_1_PSUBUW
= (0x11 << 6) | MMI_OPC_CLASS_MMI1
,
2394 MMI_OPC_1_PEXTUW
= (0x12 << 6) | MMI_OPC_CLASS_MMI1
,
2395 MMI_OPC_1_PADDUH
= (0x14 << 6) | MMI_OPC_CLASS_MMI1
,
2396 MMI_OPC_1_PSUBUH
= (0x15 << 6) | MMI_OPC_CLASS_MMI1
,
2397 MMI_OPC_1_PEXTUH
= (0x16 << 6) | MMI_OPC_CLASS_MMI1
,
2398 MMI_OPC_1_PADDUB
= (0x18 << 6) | MMI_OPC_CLASS_MMI1
,
2399 MMI_OPC_1_PSUBUB
= (0x19 << 6) | MMI_OPC_CLASS_MMI1
,
2400 MMI_OPC_1_PEXTUB
= (0x1A << 6) | MMI_OPC_CLASS_MMI1
,
2401 MMI_OPC_1_QFSRV
= (0x1B << 6) | MMI_OPC_CLASS_MMI1
,
2405 * MMI instructions with opcode field = MMI and bits 5..0 = MMI2:
2408 * +--------+----------------------+--------+--------+
2409 * | MMI | |function| MMI2 |
2410 * +--------+----------------------+--------+--------+
2412 * function bits 7..6
2413 * bits | 0 | 1 | 2 | 3
2414 * 10..8 | 00 | 01 | 10 | 11
2415 * -------+-------+-------+-------+-------
2416 * 0 000 | PMADDW| * | PSLLVW| PSRLVW
2417 * 1 001 | PMSUBW| * | * | *
2418 * 2 010 | PMFHI | PMFLO | PINTH | *
2419 * 3 011 | PMULTW| PDIVW | PCPYLD| *
2420 * 4 100 | PMADDH| PHMADH| PAND | PXOR
2421 * 5 101 | PMSUBH| PHMSBH| * | *
2422 * 6 110 | * | * | PEXEH | PREVH
2423 * 7 111 | PMULTH| PDIVBW| PEXEW | PROT3W
2426 #define MASK_MMI2(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
2428 MMI_OPC_2_PMADDW
= (0x00 << 6) | MMI_OPC_CLASS_MMI2
,
2429 MMI_OPC_2_PSLLVW
= (0x02 << 6) | MMI_OPC_CLASS_MMI2
,
2430 MMI_OPC_2_PSRLVW
= (0x03 << 6) | MMI_OPC_CLASS_MMI2
,
2431 MMI_OPC_2_PMSUBW
= (0x04 << 6) | MMI_OPC_CLASS_MMI2
,
2432 MMI_OPC_2_PMFHI
= (0x08 << 6) | MMI_OPC_CLASS_MMI2
,
2433 MMI_OPC_2_PMFLO
= (0x09 << 6) | MMI_OPC_CLASS_MMI2
,
2434 MMI_OPC_2_PINTH
= (0x0A << 6) | MMI_OPC_CLASS_MMI2
,
2435 MMI_OPC_2_PMULTW
= (0x0C << 6) | MMI_OPC_CLASS_MMI2
,
2436 MMI_OPC_2_PDIVW
= (0x0D << 6) | MMI_OPC_CLASS_MMI2
,
2437 MMI_OPC_2_PCPYLD
= (0x0E << 6) | MMI_OPC_CLASS_MMI2
,
2438 MMI_OPC_2_PMADDH
= (0x10 << 6) | MMI_OPC_CLASS_MMI2
,
2439 MMI_OPC_2_PHMADH
= (0x11 << 6) | MMI_OPC_CLASS_MMI2
,
2440 MMI_OPC_2_PAND
= (0x12 << 6) | MMI_OPC_CLASS_MMI2
,
2441 MMI_OPC_2_PXOR
= (0x13 << 6) | MMI_OPC_CLASS_MMI2
,
2442 MMI_OPC_2_PMSUBH
= (0x14 << 6) | MMI_OPC_CLASS_MMI2
,
2443 MMI_OPC_2_PHMSBH
= (0x15 << 6) | MMI_OPC_CLASS_MMI2
,
2444 MMI_OPC_2_PEXEH
= (0x1A << 6) | MMI_OPC_CLASS_MMI2
,
2445 MMI_OPC_2_PREVH
= (0x1B << 6) | MMI_OPC_CLASS_MMI2
,
2446 MMI_OPC_2_PMULTH
= (0x1C << 6) | MMI_OPC_CLASS_MMI2
,
2447 MMI_OPC_2_PDIVBW
= (0x1D << 6) | MMI_OPC_CLASS_MMI2
,
2448 MMI_OPC_2_PEXEW
= (0x1E << 6) | MMI_OPC_CLASS_MMI2
,
2449 MMI_OPC_2_PROT3W
= (0x1F << 6) | MMI_OPC_CLASS_MMI2
,
2453 * MMI instructions with opcode field = MMI and bits 5..0 = MMI3:
2456 * +--------+----------------------+--------+--------+
2457 * | MMI | |function| MMI3 |
2458 * +--------+----------------------+--------+--------+
2460 * function bits 7..6
2461 * bits | 0 | 1 | 2 | 3
2462 * 10..8 | 00 | 01 | 10 | 11
2463 * -------+-------+-------+-------+-------
2464 * 0 000 |PMADDUW| * | * | PSRAVW
2465 * 1 001 | * | * | * | *
2466 * 2 010 | PMTHI | PMTLO | PINTEH| *
2467 * 3 011 |PMULTUW| PDIVUW| PCPYUD| *
2468 * 4 100 | * | * | POR | PNOR
2469 * 5 101 | * | * | * | *
2470 * 6 110 | * | * | PEXCH | PCPYH
2471 * 7 111 | * | * | PEXCW | *
2474 #define MASK_MMI3(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
2476 MMI_OPC_3_PMADDUW
= (0x00 << 6) | MMI_OPC_CLASS_MMI3
,
2477 MMI_OPC_3_PSRAVW
= (0x03 << 6) | MMI_OPC_CLASS_MMI3
,
2478 MMI_OPC_3_PMTHI
= (0x08 << 6) | MMI_OPC_CLASS_MMI3
,
2479 MMI_OPC_3_PMTLO
= (0x09 << 6) | MMI_OPC_CLASS_MMI3
,
2480 MMI_OPC_3_PINTEH
= (0x0A << 6) | MMI_OPC_CLASS_MMI3
,
2481 MMI_OPC_3_PMULTUW
= (0x0C << 6) | MMI_OPC_CLASS_MMI3
,
2482 MMI_OPC_3_PDIVUW
= (0x0D << 6) | MMI_OPC_CLASS_MMI3
,
2483 MMI_OPC_3_PCPYUD
= (0x0E << 6) | MMI_OPC_CLASS_MMI3
,
2484 MMI_OPC_3_POR
= (0x12 << 6) | MMI_OPC_CLASS_MMI3
,
2485 MMI_OPC_3_PNOR
= (0x13 << 6) | MMI_OPC_CLASS_MMI3
,
2486 MMI_OPC_3_PEXCH
= (0x1A << 6) | MMI_OPC_CLASS_MMI3
,
2487 MMI_OPC_3_PCPYH
= (0x1B << 6) | MMI_OPC_CLASS_MMI3
,
2488 MMI_OPC_3_PEXCW
= (0x1E << 6) | MMI_OPC_CLASS_MMI3
,
2491 /* global register indices */
2492 static TCGv cpu_gpr
[32], cpu_PC
;
2493 static TCGv cpu_HI
[MIPS_DSP_ACC
], cpu_LO
[MIPS_DSP_ACC
];
2494 static TCGv cpu_dspctrl
, btarget
, bcond
;
2495 static TCGv cpu_lladdr
, cpu_llval
;
2496 static TCGv_i32 hflags
;
2497 static TCGv_i32 fpu_fcr0
, fpu_fcr31
;
2498 static TCGv_i64 fpu_f64
[32];
2499 static TCGv_i64 msa_wr_d
[64];
2501 #if defined(TARGET_MIPS64)
2502 /* Upper halves of R5900's 128-bit registers: MMRs (multimedia registers) */
2503 static TCGv_i64 cpu_mmr
[32];
2506 #if !defined(TARGET_MIPS64)
2508 static TCGv mxu_gpr
[NUMBER_OF_MXU_REGISTERS
- 1];
2512 #include "exec/gen-icount.h"
2514 #define gen_helper_0e0i(name, arg) do { \
2515 TCGv_i32 helper_tmp = tcg_const_i32(arg); \
2516 gen_helper_##name(cpu_env, helper_tmp); \
2517 tcg_temp_free_i32(helper_tmp); \
2520 #define gen_helper_0e1i(name, arg1, arg2) do { \
2521 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
2522 gen_helper_##name(cpu_env, arg1, helper_tmp); \
2523 tcg_temp_free_i32(helper_tmp); \
2526 #define gen_helper_1e0i(name, ret, arg1) do { \
2527 TCGv_i32 helper_tmp = tcg_const_i32(arg1); \
2528 gen_helper_##name(ret, cpu_env, helper_tmp); \
2529 tcg_temp_free_i32(helper_tmp); \
2532 #define gen_helper_1e1i(name, ret, arg1, arg2) do { \
2533 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
2534 gen_helper_##name(ret, cpu_env, arg1, helper_tmp); \
2535 tcg_temp_free_i32(helper_tmp); \
2538 #define gen_helper_0e2i(name, arg1, arg2, arg3) do { \
2539 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
2540 gen_helper_##name(cpu_env, arg1, arg2, helper_tmp); \
2541 tcg_temp_free_i32(helper_tmp); \
2544 #define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do { \
2545 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
2546 gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp); \
2547 tcg_temp_free_i32(helper_tmp); \
2550 #define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do { \
2551 TCGv_i32 helper_tmp = tcg_const_i32(arg4); \
2552 gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp); \
2553 tcg_temp_free_i32(helper_tmp); \
2556 typedef struct DisasContext
{
2557 DisasContextBase base
;
2558 target_ulong saved_pc
;
2559 target_ulong page_start
;
2561 uint64_t insn_flags
;
2562 int32_t CP0_Config1
;
2563 int32_t CP0_Config2
;
2564 int32_t CP0_Config3
;
2565 int32_t CP0_Config5
;
2566 /* Routine used to access memory */
2568 MemOp default_tcg_memop_mask
;
2569 uint32_t hflags
, saved_hflags
;
2570 target_ulong btarget
;
2581 int CP0_LLAddr_shift
;
2593 #define DISAS_STOP DISAS_TARGET_0
2594 #define DISAS_EXIT DISAS_TARGET_1
2596 static const char * const regnames
[] = {
2597 "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
2598 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
2599 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
2600 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
2603 static const char * const regnames_HI
[] = {
2604 "HI0", "HI1", "HI2", "HI3",
2607 static const char * const regnames_LO
[] = {
2608 "LO0", "LO1", "LO2", "LO3",
2611 static const char * const fregnames
[] = {
2612 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
2613 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
2614 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
2615 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
2618 static const char * const msaregnames
[] = {
2619 "w0.d0", "w0.d1", "w1.d0", "w1.d1",
2620 "w2.d0", "w2.d1", "w3.d0", "w3.d1",
2621 "w4.d0", "w4.d1", "w5.d0", "w5.d1",
2622 "w6.d0", "w6.d1", "w7.d0", "w7.d1",
2623 "w8.d0", "w8.d1", "w9.d0", "w9.d1",
2624 "w10.d0", "w10.d1", "w11.d0", "w11.d1",
2625 "w12.d0", "w12.d1", "w13.d0", "w13.d1",
2626 "w14.d0", "w14.d1", "w15.d0", "w15.d1",
2627 "w16.d0", "w16.d1", "w17.d0", "w17.d1",
2628 "w18.d0", "w18.d1", "w19.d0", "w19.d1",
2629 "w20.d0", "w20.d1", "w21.d0", "w21.d1",
2630 "w22.d0", "w22.d1", "w23.d0", "w23.d1",
2631 "w24.d0", "w24.d1", "w25.d0", "w25.d1",
2632 "w26.d0", "w26.d1", "w27.d0", "w27.d1",
2633 "w28.d0", "w28.d1", "w29.d0", "w29.d1",
2634 "w30.d0", "w30.d1", "w31.d0", "w31.d1",
2637 #if !defined(TARGET_MIPS64)
2638 static const char * const mxuregnames
[] = {
2639 "XR1", "XR2", "XR3", "XR4", "XR5", "XR6", "XR7", "XR8",
2640 "XR9", "XR10", "XR11", "XR12", "XR13", "XR14", "XR15", "MXU_CR",
2644 #define LOG_DISAS(...) \
2646 if (MIPS_DEBUG_DISAS) { \
2647 qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__); \
2651 #define MIPS_INVAL(op) \
2653 if (MIPS_DEBUG_DISAS) { \
2654 qemu_log_mask(CPU_LOG_TB_IN_ASM, \
2655 TARGET_FMT_lx ": %08x Invalid %s %03x %03x %03x\n", \
2656 ctx->base.pc_next, ctx->opcode, op, \
2657 ctx->opcode >> 26, ctx->opcode & 0x3F, \
2658 ((ctx->opcode >> 16) & 0x1F)); \
2662 /* General purpose registers moves. */
2663 static inline void gen_load_gpr(TCGv t
, int reg
)
2666 tcg_gen_movi_tl(t
, 0);
2668 tcg_gen_mov_tl(t
, cpu_gpr
[reg
]);
2672 static inline void gen_store_gpr(TCGv t
, int reg
)
2675 tcg_gen_mov_tl(cpu_gpr
[reg
], t
);
2679 /* Moves to/from shadow registers. */
2680 static inline void gen_load_srsgpr(int from
, int to
)
2682 TCGv t0
= tcg_temp_new();
2685 tcg_gen_movi_tl(t0
, 0);
2687 TCGv_i32 t2
= tcg_temp_new_i32();
2688 TCGv_ptr addr
= tcg_temp_new_ptr();
2690 tcg_gen_ld_i32(t2
, cpu_env
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
2691 tcg_gen_shri_i32(t2
, t2
, CP0SRSCtl_PSS
);
2692 tcg_gen_andi_i32(t2
, t2
, 0xf);
2693 tcg_gen_muli_i32(t2
, t2
, sizeof(target_ulong
) * 32);
2694 tcg_gen_ext_i32_ptr(addr
, t2
);
2695 tcg_gen_add_ptr(addr
, cpu_env
, addr
);
2697 tcg_gen_ld_tl(t0
, addr
, sizeof(target_ulong
) * from
);
2698 tcg_temp_free_ptr(addr
);
2699 tcg_temp_free_i32(t2
);
2701 gen_store_gpr(t0
, to
);
2705 static inline void gen_store_srsgpr(int from
, int to
)
2708 TCGv t0
= tcg_temp_new();
2709 TCGv_i32 t2
= tcg_temp_new_i32();
2710 TCGv_ptr addr
= tcg_temp_new_ptr();
2712 gen_load_gpr(t0
, from
);
2713 tcg_gen_ld_i32(t2
, cpu_env
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
2714 tcg_gen_shri_i32(t2
, t2
, CP0SRSCtl_PSS
);
2715 tcg_gen_andi_i32(t2
, t2
, 0xf);
2716 tcg_gen_muli_i32(t2
, t2
, sizeof(target_ulong
) * 32);
2717 tcg_gen_ext_i32_ptr(addr
, t2
);
2718 tcg_gen_add_ptr(addr
, cpu_env
, addr
);
2720 tcg_gen_st_tl(t0
, addr
, sizeof(target_ulong
) * to
);
2721 tcg_temp_free_ptr(addr
);
2722 tcg_temp_free_i32(t2
);
2727 #if !defined(TARGET_MIPS64)
2728 /* MXU General purpose registers moves. */
2729 static inline void gen_load_mxu_gpr(TCGv t
, unsigned int reg
)
2732 tcg_gen_movi_tl(t
, 0);
2733 } else if (reg
<= 15) {
2734 tcg_gen_mov_tl(t
, mxu_gpr
[reg
- 1]);
2738 static inline void gen_store_mxu_gpr(TCGv t
, unsigned int reg
)
2740 if (reg
> 0 && reg
<= 15) {
2741 tcg_gen_mov_tl(mxu_gpr
[reg
- 1], t
);
2745 /* MXU control register moves. */
2746 static inline void gen_load_mxu_cr(TCGv t
)
2748 tcg_gen_mov_tl(t
, mxu_CR
);
2751 static inline void gen_store_mxu_cr(TCGv t
)
2753 /* TODO: Add handling of RW rules for MXU_CR. */
2754 tcg_gen_mov_tl(mxu_CR
, t
);
2760 static inline void gen_save_pc(target_ulong pc
)
2762 tcg_gen_movi_tl(cpu_PC
, pc
);
2765 static inline void save_cpu_state(DisasContext
*ctx
, int do_save_pc
)
2767 LOG_DISAS("hflags %08x saved %08x\n", ctx
->hflags
, ctx
->saved_hflags
);
2768 if (do_save_pc
&& ctx
->base
.pc_next
!= ctx
->saved_pc
) {
2769 gen_save_pc(ctx
->base
.pc_next
);
2770 ctx
->saved_pc
= ctx
->base
.pc_next
;
2772 if (ctx
->hflags
!= ctx
->saved_hflags
) {
2773 tcg_gen_movi_i32(hflags
, ctx
->hflags
);
2774 ctx
->saved_hflags
= ctx
->hflags
;
2775 switch (ctx
->hflags
& MIPS_HFLAG_BMASK_BASE
) {
2781 tcg_gen_movi_tl(btarget
, ctx
->btarget
);
2787 static inline void restore_cpu_state(CPUMIPSState
*env
, DisasContext
*ctx
)
2789 ctx
->saved_hflags
= ctx
->hflags
;
2790 switch (ctx
->hflags
& MIPS_HFLAG_BMASK_BASE
) {
2796 ctx
->btarget
= env
->btarget
;
2801 static inline void generate_exception_err(DisasContext
*ctx
, int excp
, int err
)
2803 TCGv_i32 texcp
= tcg_const_i32(excp
);
2804 TCGv_i32 terr
= tcg_const_i32(err
);
2805 save_cpu_state(ctx
, 1);
2806 gen_helper_raise_exception_err(cpu_env
, texcp
, terr
);
2807 tcg_temp_free_i32(terr
);
2808 tcg_temp_free_i32(texcp
);
2809 ctx
->base
.is_jmp
= DISAS_NORETURN
;
2812 static inline void generate_exception(DisasContext
*ctx
, int excp
)
2814 gen_helper_0e0i(raise_exception
, excp
);
2817 static inline void generate_exception_end(DisasContext
*ctx
, int excp
)
2819 generate_exception_err(ctx
, excp
, 0);
2822 /* Floating point register moves. */
2823 static void gen_load_fpr32(DisasContext
*ctx
, TCGv_i32 t
, int reg
)
2825 if (ctx
->hflags
& MIPS_HFLAG_FRE
) {
2826 generate_exception(ctx
, EXCP_RI
);
2828 tcg_gen_extrl_i64_i32(t
, fpu_f64
[reg
]);
2831 static void gen_store_fpr32(DisasContext
*ctx
, TCGv_i32 t
, int reg
)
2834 if (ctx
->hflags
& MIPS_HFLAG_FRE
) {
2835 generate_exception(ctx
, EXCP_RI
);
2837 t64
= tcg_temp_new_i64();
2838 tcg_gen_extu_i32_i64(t64
, t
);
2839 tcg_gen_deposit_i64(fpu_f64
[reg
], fpu_f64
[reg
], t64
, 0, 32);
2840 tcg_temp_free_i64(t64
);
2843 static void gen_load_fpr32h(DisasContext
*ctx
, TCGv_i32 t
, int reg
)
2845 if (ctx
->hflags
& MIPS_HFLAG_F64
) {
2846 tcg_gen_extrh_i64_i32(t
, fpu_f64
[reg
]);
2848 gen_load_fpr32(ctx
, t
, reg
| 1);
2852 static void gen_store_fpr32h(DisasContext
*ctx
, TCGv_i32 t
, int reg
)
2854 if (ctx
->hflags
& MIPS_HFLAG_F64
) {
2855 TCGv_i64 t64
= tcg_temp_new_i64();
2856 tcg_gen_extu_i32_i64(t64
, t
);
2857 tcg_gen_deposit_i64(fpu_f64
[reg
], fpu_f64
[reg
], t64
, 32, 32);
2858 tcg_temp_free_i64(t64
);
2860 gen_store_fpr32(ctx
, t
, reg
| 1);
2864 static void gen_load_fpr64(DisasContext
*ctx
, TCGv_i64 t
, int reg
)
2866 if (ctx
->hflags
& MIPS_HFLAG_F64
) {
2867 tcg_gen_mov_i64(t
, fpu_f64
[reg
]);
2869 tcg_gen_concat32_i64(t
, fpu_f64
[reg
& ~1], fpu_f64
[reg
| 1]);
2873 static void gen_store_fpr64(DisasContext
*ctx
, TCGv_i64 t
, int reg
)
2875 if (ctx
->hflags
& MIPS_HFLAG_F64
) {
2876 tcg_gen_mov_i64(fpu_f64
[reg
], t
);
2879 tcg_gen_deposit_i64(fpu_f64
[reg
& ~1], fpu_f64
[reg
& ~1], t
, 0, 32);
2880 t0
= tcg_temp_new_i64();
2881 tcg_gen_shri_i64(t0
, t
, 32);
2882 tcg_gen_deposit_i64(fpu_f64
[reg
| 1], fpu_f64
[reg
| 1], t0
, 0, 32);
2883 tcg_temp_free_i64(t0
);
2887 static inline int get_fp_bit(int cc
)
2896 /* Addresses computation */
2897 static inline void gen_op_addr_add(DisasContext
*ctx
, TCGv ret
, TCGv arg0
,
2900 tcg_gen_add_tl(ret
, arg0
, arg1
);
2902 #if defined(TARGET_MIPS64)
2903 if (ctx
->hflags
& MIPS_HFLAG_AWRAP
) {
2904 tcg_gen_ext32s_i64(ret
, ret
);
2909 static inline void gen_op_addr_addi(DisasContext
*ctx
, TCGv ret
, TCGv base
,
2912 tcg_gen_addi_tl(ret
, base
, ofs
);
2914 #if defined(TARGET_MIPS64)
2915 if (ctx
->hflags
& MIPS_HFLAG_AWRAP
) {
2916 tcg_gen_ext32s_i64(ret
, ret
);
2921 /* Addresses computation (translation time) */
2922 static target_long
addr_add(DisasContext
*ctx
, target_long base
,
2925 target_long sum
= base
+ offset
;
2927 #if defined(TARGET_MIPS64)
2928 if (ctx
->hflags
& MIPS_HFLAG_AWRAP
) {
2935 /* Sign-extract the low 32-bits to a target_long. */
2936 static inline void gen_move_low32(TCGv ret
, TCGv_i64 arg
)
2938 #if defined(TARGET_MIPS64)
2939 tcg_gen_ext32s_i64(ret
, arg
);
2941 tcg_gen_extrl_i64_i32(ret
, arg
);
2945 /* Sign-extract the high 32-bits to a target_long. */
2946 static inline void gen_move_high32(TCGv ret
, TCGv_i64 arg
)
2948 #if defined(TARGET_MIPS64)
2949 tcg_gen_sari_i64(ret
, arg
, 32);
2951 tcg_gen_extrh_i64_i32(ret
, arg
);
2955 static inline void check_cp0_enabled(DisasContext
*ctx
)
2957 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_CP0
))) {
2958 generate_exception_err(ctx
, EXCP_CpU
, 0);
2962 static inline void check_cp1_enabled(DisasContext
*ctx
)
2964 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_FPU
))) {
2965 generate_exception_err(ctx
, EXCP_CpU
, 1);
2970 * Verify that the processor is running with COP1X instructions enabled.
2971 * This is associated with the nabla symbol in the MIPS32 and MIPS64
2974 static inline void check_cop1x(DisasContext
*ctx
)
2976 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_COP1X
))) {
2977 generate_exception_end(ctx
, EXCP_RI
);
2982 * Verify that the processor is running with 64-bit floating-point
2983 * operations enabled.
2985 static inline void check_cp1_64bitmode(DisasContext
*ctx
)
2987 if (unlikely(~ctx
->hflags
& (MIPS_HFLAG_F64
| MIPS_HFLAG_COP1X
))) {
2988 generate_exception_end(ctx
, EXCP_RI
);
2993 * Verify if floating point register is valid; an operation is not defined
2994 * if bit 0 of any register specification is set and the FR bit in the
2995 * Status register equals zero, since the register numbers specify an
2996 * even-odd pair of adjacent coprocessor general registers. When the FR bit
2997 * in the Status register equals one, both even and odd register numbers
2998 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
3000 * Multiple 64 bit wide registers can be checked by calling
3001 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
3003 static inline void check_cp1_registers(DisasContext
*ctx
, int regs
)
3005 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_F64
) && (regs
& 1))) {
3006 generate_exception_end(ctx
, EXCP_RI
);
3011 * Verify that the processor is running with DSP instructions enabled.
3012 * This is enabled by CP0 Status register MX(24) bit.
3014 static inline void check_dsp(DisasContext
*ctx
)
3016 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_DSP
))) {
3017 if (ctx
->insn_flags
& ASE_DSP
) {
3018 generate_exception_end(ctx
, EXCP_DSPDIS
);
3020 generate_exception_end(ctx
, EXCP_RI
);
3025 static inline void check_dsp_r2(DisasContext
*ctx
)
3027 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_DSP_R2
))) {
3028 if (ctx
->insn_flags
& ASE_DSP
) {
3029 generate_exception_end(ctx
, EXCP_DSPDIS
);
3031 generate_exception_end(ctx
, EXCP_RI
);
3036 static inline void check_dsp_r3(DisasContext
*ctx
)
3038 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_DSP_R3
))) {
3039 if (ctx
->insn_flags
& ASE_DSP
) {
3040 generate_exception_end(ctx
, EXCP_DSPDIS
);
3042 generate_exception_end(ctx
, EXCP_RI
);
3048 * This code generates a "reserved instruction" exception if the
3049 * CPU does not support the instruction set corresponding to flags.
3051 static inline void check_insn(DisasContext
*ctx
, uint64_t flags
)
3053 if (unlikely(!(ctx
->insn_flags
& flags
))) {
3054 generate_exception_end(ctx
, EXCP_RI
);
3059 * This code generates a "reserved instruction" exception if the
3060 * CPU has corresponding flag set which indicates that the instruction
3063 static inline void check_insn_opc_removed(DisasContext
*ctx
, uint64_t flags
)
3065 if (unlikely(ctx
->insn_flags
& flags
)) {
3066 generate_exception_end(ctx
, EXCP_RI
);
3071 * The Linux kernel traps certain reserved instruction exceptions to
3072 * emulate the corresponding instructions. QEMU is the kernel in user
3073 * mode, so those traps are emulated by accepting the instructions.
3075 * A reserved instruction exception is generated for flagged CPUs if
3076 * QEMU runs in system mode.
3078 static inline void check_insn_opc_user_only(DisasContext
*ctx
, uint64_t flags
)
3080 #ifndef CONFIG_USER_ONLY
3081 check_insn_opc_removed(ctx
, flags
);
3086 * This code generates a "reserved instruction" exception if the
3087 * CPU does not support 64-bit paired-single (PS) floating point data type.
3089 static inline void check_ps(DisasContext
*ctx
)
3091 if (unlikely(!ctx
->ps
)) {
3092 generate_exception(ctx
, EXCP_RI
);
3094 check_cp1_64bitmode(ctx
);
3097 #ifdef TARGET_MIPS64
3099 * This code generates a "reserved instruction" exception if 64-bit
3100 * instructions are not enabled.
3102 static inline void check_mips_64(DisasContext
*ctx
)
3104 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_64
))) {
3105 generate_exception_end(ctx
, EXCP_RI
);
3110 #ifndef CONFIG_USER_ONLY
3111 static inline void check_mvh(DisasContext
*ctx
)
3113 if (unlikely(!ctx
->mvh
)) {
3114 generate_exception(ctx
, EXCP_RI
);
3120 * This code generates a "reserved instruction" exception if the
3121 * Config5 XNP bit is set.
3123 static inline void check_xnp(DisasContext
*ctx
)
3125 if (unlikely(ctx
->CP0_Config5
& (1 << CP0C5_XNP
))) {
3126 generate_exception_end(ctx
, EXCP_RI
);
3130 #ifndef CONFIG_USER_ONLY
3132 * This code generates a "reserved instruction" exception if the
3133 * Config3 PW bit is NOT set.
3135 static inline void check_pw(DisasContext
*ctx
)
3137 if (unlikely(!(ctx
->CP0_Config3
& (1 << CP0C3_PW
)))) {
3138 generate_exception_end(ctx
, EXCP_RI
);
3144 * This code generates a "reserved instruction" exception if the
3145 * Config3 MT bit is NOT set.
3147 static inline void check_mt(DisasContext
*ctx
)
3149 if (unlikely(!(ctx
->CP0_Config3
& (1 << CP0C3_MT
)))) {
3150 generate_exception_end(ctx
, EXCP_RI
);
3154 #ifndef CONFIG_USER_ONLY
3156 * This code generates a "coprocessor unusable" exception if CP0 is not
3157 * available, and, if that is not the case, generates a "reserved instruction"
3158 * exception if the Config5 MT bit is NOT set. This is needed for availability
3159 * control of some of MT ASE instructions.
3161 static inline void check_cp0_mt(DisasContext
*ctx
)
3163 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_CP0
))) {
3164 generate_exception_err(ctx
, EXCP_CpU
, 0);
3166 if (unlikely(!(ctx
->CP0_Config3
& (1 << CP0C3_MT
)))) {
3167 generate_exception_err(ctx
, EXCP_RI
, 0);
3174 * This code generates a "reserved instruction" exception if the
3175 * Config5 NMS bit is set.
3177 static inline void check_nms(DisasContext
*ctx
)
3179 if (unlikely(ctx
->CP0_Config5
& (1 << CP0C5_NMS
))) {
3180 generate_exception_end(ctx
, EXCP_RI
);
3185 * This code generates a "reserved instruction" exception if the
3186 * Config5 NMS bit is set, and Config1 DL, Config1 IL, Config2 SL,
3187 * Config2 TL, and Config5 L2C are unset.
3189 static inline void check_nms_dl_il_sl_tl_l2c(DisasContext
*ctx
)
3191 if (unlikely((ctx
->CP0_Config5
& (1 << CP0C5_NMS
)) &&
3192 !(ctx
->CP0_Config1
& (1 << CP0C1_DL
)) &&
3193 !(ctx
->CP0_Config1
& (1 << CP0C1_IL
)) &&
3194 !(ctx
->CP0_Config2
& (1 << CP0C2_SL
)) &&
3195 !(ctx
->CP0_Config2
& (1 << CP0C2_TL
)) &&
3196 !(ctx
->CP0_Config5
& (1 << CP0C5_L2C
)))) {
3197 generate_exception_end(ctx
, EXCP_RI
);
3202 * This code generates a "reserved instruction" exception if the
3203 * Config5 EVA bit is NOT set.
3205 static inline void check_eva(DisasContext
*ctx
)
3207 if (unlikely(!(ctx
->CP0_Config5
& (1 << CP0C5_EVA
)))) {
3208 generate_exception_end(ctx
, EXCP_RI
);
3214 * Define small wrappers for gen_load_fpr* so that we have a uniform
3215 * calling interface for 32 and 64-bit FPRs. No sense in changing
3216 * all callers for gen_load_fpr32 when we need the CTX parameter for
3219 #define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(ctx, x, y)
3220 #define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
3221 #define FOP_CONDS(type, abs, fmt, ifmt, bits) \
3222 static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
3223 int ft, int fs, int cc) \
3225 TCGv_i##bits fp0 = tcg_temp_new_i##bits(); \
3226 TCGv_i##bits fp1 = tcg_temp_new_i##bits(); \
3235 check_cp1_registers(ctx, fs | ft); \
3243 gen_ldcmp_fpr##bits(ctx, fp0, fs); \
3244 gen_ldcmp_fpr##bits(ctx, fp1, ft); \
3247 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); \
3250 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); \
3253 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); \
3256 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); \
3259 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); \
3262 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); \
3265 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); \
3268 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); \
3271 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); \
3274 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); \
3277 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); \
3280 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); \
3283 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); \
3286 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); \
3289 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); \
3292 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); \
3297 tcg_temp_free_i##bits(fp0); \
3298 tcg_temp_free_i##bits(fp1); \
3301 FOP_CONDS(, 0, d
, FMT_D
, 64)
3302 FOP_CONDS(abs
, 1, d
, FMT_D
, 64)
3303 FOP_CONDS(, 0, s
, FMT_S
, 32)
3304 FOP_CONDS(abs
, 1, s
, FMT_S
, 32)
3305 FOP_CONDS(, 0, ps
, FMT_PS
, 64)
3306 FOP_CONDS(abs
, 1, ps
, FMT_PS
, 64)
3309 #define FOP_CONDNS(fmt, ifmt, bits, STORE) \
3310 static inline void gen_r6_cmp_ ## fmt(DisasContext *ctx, int n, \
3311 int ft, int fs, int fd) \
3313 TCGv_i ## bits fp0 = tcg_temp_new_i ## bits(); \
3314 TCGv_i ## bits fp1 = tcg_temp_new_i ## bits(); \
3315 if (ifmt == FMT_D) { \
3316 check_cp1_registers(ctx, fs | ft | fd); \
3318 gen_ldcmp_fpr ## bits(ctx, fp0, fs); \
3319 gen_ldcmp_fpr ## bits(ctx, fp1, ft); \
3322 gen_helper_r6_cmp_ ## fmt ## _af(fp0, cpu_env, fp0, fp1); \
3325 gen_helper_r6_cmp_ ## fmt ## _un(fp0, cpu_env, fp0, fp1); \
3328 gen_helper_r6_cmp_ ## fmt ## _eq(fp0, cpu_env, fp0, fp1); \
3331 gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, cpu_env, fp0, fp1); \
3334 gen_helper_r6_cmp_ ## fmt ## _lt(fp0, cpu_env, fp0, fp1); \
3337 gen_helper_r6_cmp_ ## fmt ## _ult(fp0, cpu_env, fp0, fp1); \
3340 gen_helper_r6_cmp_ ## fmt ## _le(fp0, cpu_env, fp0, fp1); \
3343 gen_helper_r6_cmp_ ## fmt ## _ule(fp0, cpu_env, fp0, fp1); \
3346 gen_helper_r6_cmp_ ## fmt ## _saf(fp0, cpu_env, fp0, fp1); \
3349 gen_helper_r6_cmp_ ## fmt ## _sun(fp0, cpu_env, fp0, fp1); \
3352 gen_helper_r6_cmp_ ## fmt ## _seq(fp0, cpu_env, fp0, fp1); \
3355 gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, cpu_env, fp0, fp1); \
3358 gen_helper_r6_cmp_ ## fmt ## _slt(fp0, cpu_env, fp0, fp1); \
3361 gen_helper_r6_cmp_ ## fmt ## _sult(fp0, cpu_env, fp0, fp1); \
3364 gen_helper_r6_cmp_ ## fmt ## _sle(fp0, cpu_env, fp0, fp1); \
3367 gen_helper_r6_cmp_ ## fmt ## _sule(fp0, cpu_env, fp0, fp1); \
3370 gen_helper_r6_cmp_ ## fmt ## _or(fp0, cpu_env, fp0, fp1); \
3373 gen_helper_r6_cmp_ ## fmt ## _une(fp0, cpu_env, fp0, fp1); \
3376 gen_helper_r6_cmp_ ## fmt ## _ne(fp0, cpu_env, fp0, fp1); \
3379 gen_helper_r6_cmp_ ## fmt ## _sor(fp0, cpu_env, fp0, fp1); \
3382 gen_helper_r6_cmp_ ## fmt ## _sune(fp0, cpu_env, fp0, fp1); \
3385 gen_helper_r6_cmp_ ## fmt ## _sne(fp0, cpu_env, fp0, fp1); \
3391 tcg_temp_free_i ## bits(fp0); \
3392 tcg_temp_free_i ## bits(fp1); \
3395 FOP_CONDNS(d
, FMT_D
, 64, gen_store_fpr64(ctx
, fp0
, fd
))
3396 FOP_CONDNS(s
, FMT_S
, 32, gen_store_fpr32(ctx
, fp0
, fd
))
3398 #undef gen_ldcmp_fpr32
3399 #undef gen_ldcmp_fpr64
3401 /* load/store instructions. */
3402 #ifdef CONFIG_USER_ONLY
3403 #define OP_LD_ATOMIC(insn, fname) \
3404 static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \
3405 DisasContext *ctx) \
3407 TCGv t0 = tcg_temp_new(); \
3408 tcg_gen_mov_tl(t0, arg1); \
3409 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
3410 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
3411 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
3412 tcg_temp_free(t0); \
3415 #define OP_LD_ATOMIC(insn, fname) \
3416 static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \
3417 DisasContext *ctx) \
3419 gen_helper_1e1i(insn, ret, arg1, mem_idx); \
3422 OP_LD_ATOMIC(ll
, ld32s
);
3423 #if defined(TARGET_MIPS64)
3424 OP_LD_ATOMIC(lld
, ld64
);
3428 static void gen_base_offset_addr(DisasContext
*ctx
, TCGv addr
,
3429 int base
, int offset
)
3432 tcg_gen_movi_tl(addr
, offset
);
3433 } else if (offset
== 0) {
3434 gen_load_gpr(addr
, base
);
3436 tcg_gen_movi_tl(addr
, offset
);
3437 gen_op_addr_add(ctx
, addr
, cpu_gpr
[base
], addr
);
3441 static target_ulong
pc_relative_pc(DisasContext
*ctx
)
3443 target_ulong pc
= ctx
->base
.pc_next
;
3445 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
3446 int branch_bytes
= ctx
->hflags
& MIPS_HFLAG_BDS16
? 2 : 4;
3451 pc
&= ~(target_ulong
)3;
3456 static void gen_ld(DisasContext
*ctx
, uint32_t opc
,
3457 int rt
, int base
, int offset
)
3460 int mem_idx
= ctx
->mem_idx
;
3462 if (rt
== 0 && ctx
->insn_flags
& (INSN_LOONGSON2E
| INSN_LOONGSON2F
|
3465 * Loongson CPU uses a load to zero register for prefetch.
3466 * We emulate it as a NOP. On other CPU we must perform the
3467 * actual memory access.
3472 t0
= tcg_temp_new();
3473 gen_base_offset_addr(ctx
, t0
, base
, offset
);
3476 #if defined(TARGET_MIPS64)
3478 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEUL
|
3479 ctx
->default_tcg_memop_mask
);
3480 gen_store_gpr(t0
, rt
);
3483 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEQ
|
3484 ctx
->default_tcg_memop_mask
);
3485 gen_store_gpr(t0
, rt
);
3489 op_ld_lld(t0
, t0
, mem_idx
, ctx
);
3490 gen_store_gpr(t0
, rt
);
3493 t1
= tcg_temp_new();
3495 * Do a byte access to possibly trigger a page
3496 * fault with the unaligned address.
3498 tcg_gen_qemu_ld_tl(t1
, t0
, mem_idx
, MO_UB
);
3499 tcg_gen_andi_tl(t1
, t0
, 7);
3500 #ifndef TARGET_WORDS_BIGENDIAN
3501 tcg_gen_xori_tl(t1
, t1
, 7);
3503 tcg_gen_shli_tl(t1
, t1
, 3);
3504 tcg_gen_andi_tl(t0
, t0
, ~7);
3505 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEQ
);
3506 tcg_gen_shl_tl(t0
, t0
, t1
);
3507 t2
= tcg_const_tl(-1);
3508 tcg_gen_shl_tl(t2
, t2
, t1
);
3509 gen_load_gpr(t1
, rt
);
3510 tcg_gen_andc_tl(t1
, t1
, t2
);
3512 tcg_gen_or_tl(t0
, t0
, t1
);
3514 gen_store_gpr(t0
, rt
);
3517 t1
= tcg_temp_new();
3519 * Do a byte access to possibly trigger a page
3520 * fault with the unaligned address.
3522 tcg_gen_qemu_ld_tl(t1
, t0
, mem_idx
, MO_UB
);
3523 tcg_gen_andi_tl(t1
, t0
, 7);
3524 #ifdef TARGET_WORDS_BIGENDIAN
3525 tcg_gen_xori_tl(t1
, t1
, 7);
3527 tcg_gen_shli_tl(t1
, t1
, 3);
3528 tcg_gen_andi_tl(t0
, t0
, ~7);
3529 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEQ
);
3530 tcg_gen_shr_tl(t0
, t0
, t1
);
3531 tcg_gen_xori_tl(t1
, t1
, 63);
3532 t2
= tcg_const_tl(0xfffffffffffffffeull
);
3533 tcg_gen_shl_tl(t2
, t2
, t1
);
3534 gen_load_gpr(t1
, rt
);
3535 tcg_gen_and_tl(t1
, t1
, t2
);
3537 tcg_gen_or_tl(t0
, t0
, t1
);
3539 gen_store_gpr(t0
, rt
);
3542 t1
= tcg_const_tl(pc_relative_pc(ctx
));
3543 gen_op_addr_add(ctx
, t0
, t0
, t1
);
3545 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEQ
);
3546 gen_store_gpr(t0
, rt
);
3550 t1
= tcg_const_tl(pc_relative_pc(ctx
));
3551 gen_op_addr_add(ctx
, t0
, t0
, t1
);
3553 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TESL
);
3554 gen_store_gpr(t0
, rt
);
3557 mem_idx
= MIPS_HFLAG_UM
;
3560 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TESL
|
3561 ctx
->default_tcg_memop_mask
);
3562 gen_store_gpr(t0
, rt
);
3565 mem_idx
= MIPS_HFLAG_UM
;
3568 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TESW
|
3569 ctx
->default_tcg_memop_mask
);
3570 gen_store_gpr(t0
, rt
);
3573 mem_idx
= MIPS_HFLAG_UM
;
3576 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEUW
|
3577 ctx
->default_tcg_memop_mask
);
3578 gen_store_gpr(t0
, rt
);
3581 mem_idx
= MIPS_HFLAG_UM
;
3584 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_SB
);
3585 gen_store_gpr(t0
, rt
);
3588 mem_idx
= MIPS_HFLAG_UM
;
3591 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_UB
);
3592 gen_store_gpr(t0
, rt
);
3595 mem_idx
= MIPS_HFLAG_UM
;
3598 t1
= tcg_temp_new();
3600 * Do a byte access to possibly trigger a page
3601 * fault with the unaligned address.
3603 tcg_gen_qemu_ld_tl(t1
, t0
, mem_idx
, MO_UB
);
3604 tcg_gen_andi_tl(t1
, t0
, 3);
3605 #ifndef TARGET_WORDS_BIGENDIAN
3606 tcg_gen_xori_tl(t1
, t1
, 3);
3608 tcg_gen_shli_tl(t1
, t1
, 3);
3609 tcg_gen_andi_tl(t0
, t0
, ~3);
3610 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEUL
);
3611 tcg_gen_shl_tl(t0
, t0
, t1
);
3612 t2
= tcg_const_tl(-1);
3613 tcg_gen_shl_tl(t2
, t2
, t1
);
3614 gen_load_gpr(t1
, rt
);
3615 tcg_gen_andc_tl(t1
, t1
, t2
);
3617 tcg_gen_or_tl(t0
, t0
, t1
);
3619 tcg_gen_ext32s_tl(t0
, t0
);
3620 gen_store_gpr(t0
, rt
);
3623 mem_idx
= MIPS_HFLAG_UM
;
3626 t1
= tcg_temp_new();
3628 * Do a byte access to possibly trigger a page
3629 * fault with the unaligned address.
3631 tcg_gen_qemu_ld_tl(t1
, t0
, mem_idx
, MO_UB
);
3632 tcg_gen_andi_tl(t1
, t0
, 3);
3633 #ifdef TARGET_WORDS_BIGENDIAN
3634 tcg_gen_xori_tl(t1
, t1
, 3);
3636 tcg_gen_shli_tl(t1
, t1
, 3);
3637 tcg_gen_andi_tl(t0
, t0
, ~3);
3638 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEUL
);
3639 tcg_gen_shr_tl(t0
, t0
, t1
);
3640 tcg_gen_xori_tl(t1
, t1
, 31);
3641 t2
= tcg_const_tl(0xfffffffeull
);
3642 tcg_gen_shl_tl(t2
, t2
, t1
);
3643 gen_load_gpr(t1
, rt
);
3644 tcg_gen_and_tl(t1
, t1
, t2
);
3646 tcg_gen_or_tl(t0
, t0
, t1
);
3648 tcg_gen_ext32s_tl(t0
, t0
);
3649 gen_store_gpr(t0
, rt
);
3652 mem_idx
= MIPS_HFLAG_UM
;
3656 op_ld_ll(t0
, t0
, mem_idx
, ctx
);
3657 gen_store_gpr(t0
, rt
);
3663 static void gen_llwp(DisasContext
*ctx
, uint32_t base
, int16_t offset
,
3664 uint32_t reg1
, uint32_t reg2
)
3666 TCGv taddr
= tcg_temp_new();
3667 TCGv_i64 tval
= tcg_temp_new_i64();
3668 TCGv tmp1
= tcg_temp_new();
3669 TCGv tmp2
= tcg_temp_new();
3671 gen_base_offset_addr(ctx
, taddr
, base
, offset
);
3672 tcg_gen_qemu_ld64(tval
, taddr
, ctx
->mem_idx
);
3673 #ifdef TARGET_WORDS_BIGENDIAN
3674 tcg_gen_extr_i64_tl(tmp2
, tmp1
, tval
);
3676 tcg_gen_extr_i64_tl(tmp1
, tmp2
, tval
);
3678 gen_store_gpr(tmp1
, reg1
);
3679 tcg_temp_free(tmp1
);
3680 gen_store_gpr(tmp2
, reg2
);
3681 tcg_temp_free(tmp2
);
3682 tcg_gen_st_i64(tval
, cpu_env
, offsetof(CPUMIPSState
, llval_wp
));
3683 tcg_temp_free_i64(tval
);
3684 tcg_gen_st_tl(taddr
, cpu_env
, offsetof(CPUMIPSState
, lladdr
));
3685 tcg_temp_free(taddr
);
3689 static void gen_st(DisasContext
*ctx
, uint32_t opc
, int rt
,
3690 int base
, int offset
)
3692 TCGv t0
= tcg_temp_new();
3693 TCGv t1
= tcg_temp_new();
3694 int mem_idx
= ctx
->mem_idx
;
3696 gen_base_offset_addr(ctx
, t0
, base
, offset
);
3697 gen_load_gpr(t1
, rt
);
3699 #if defined(TARGET_MIPS64)
3701 tcg_gen_qemu_st_tl(t1
, t0
, mem_idx
, MO_TEQ
|
3702 ctx
->default_tcg_memop_mask
);
3705 gen_helper_0e2i(sdl
, t1
, t0
, mem_idx
);
3708 gen_helper_0e2i(sdr
, t1
, t0
, mem_idx
);
3712 mem_idx
= MIPS_HFLAG_UM
;
3715 tcg_gen_qemu_st_tl(t1
, t0
, mem_idx
, MO_TEUL
|
3716 ctx
->default_tcg_memop_mask
);
3719 mem_idx
= MIPS_HFLAG_UM
;
3722 tcg_gen_qemu_st_tl(t1
, t0
, mem_idx
, MO_TEUW
|
3723 ctx
->default_tcg_memop_mask
);
3726 mem_idx
= MIPS_HFLAG_UM
;
3729 tcg_gen_qemu_st_tl(t1
, t0
, mem_idx
, MO_8
);
3732 mem_idx
= MIPS_HFLAG_UM
;
3735 gen_helper_0e2i(swl
, t1
, t0
, mem_idx
);
3738 mem_idx
= MIPS_HFLAG_UM
;
3741 gen_helper_0e2i(swr
, t1
, t0
, mem_idx
);
3749 /* Store conditional */
3750 static void gen_st_cond(DisasContext
*ctx
, int rt
, int base
, int offset
,
3751 MemOp tcg_mo
, bool eva
)
3754 TCGLabel
*l1
= gen_new_label();
3755 TCGLabel
*done
= gen_new_label();
3757 t0
= tcg_temp_new();
3758 addr
= tcg_temp_new();
3759 /* compare the address against that of the preceding LL */
3760 gen_base_offset_addr(ctx
, addr
, base
, offset
);
3761 tcg_gen_brcond_tl(TCG_COND_EQ
, addr
, cpu_lladdr
, l1
);
3762 tcg_temp_free(addr
);
3763 tcg_gen_movi_tl(t0
, 0);
3764 gen_store_gpr(t0
, rt
);
3768 /* generate cmpxchg */
3769 val
= tcg_temp_new();
3770 gen_load_gpr(val
, rt
);
3771 tcg_gen_atomic_cmpxchg_tl(t0
, cpu_lladdr
, cpu_llval
, val
,
3772 eva
? MIPS_HFLAG_UM
: ctx
->mem_idx
, tcg_mo
);
3773 tcg_gen_setcond_tl(TCG_COND_EQ
, t0
, t0
, cpu_llval
);
3774 gen_store_gpr(t0
, rt
);
3777 gen_set_label(done
);
3782 static void gen_scwp(DisasContext
*ctx
, uint32_t base
, int16_t offset
,
3783 uint32_t reg1
, uint32_t reg2
, bool eva
)
3785 TCGv taddr
= tcg_temp_local_new();
3786 TCGv lladdr
= tcg_temp_local_new();
3787 TCGv_i64 tval
= tcg_temp_new_i64();
3788 TCGv_i64 llval
= tcg_temp_new_i64();
3789 TCGv_i64 val
= tcg_temp_new_i64();
3790 TCGv tmp1
= tcg_temp_new();
3791 TCGv tmp2
= tcg_temp_new();
3792 TCGLabel
*lab_fail
= gen_new_label();
3793 TCGLabel
*lab_done
= gen_new_label();
3795 gen_base_offset_addr(ctx
, taddr
, base
, offset
);
3797 tcg_gen_ld_tl(lladdr
, cpu_env
, offsetof(CPUMIPSState
, lladdr
));
3798 tcg_gen_brcond_tl(TCG_COND_NE
, taddr
, lladdr
, lab_fail
);
3800 gen_load_gpr(tmp1
, reg1
);
3801 gen_load_gpr(tmp2
, reg2
);
3803 #ifdef TARGET_WORDS_BIGENDIAN
3804 tcg_gen_concat_tl_i64(tval
, tmp2
, tmp1
);
3806 tcg_gen_concat_tl_i64(tval
, tmp1
, tmp2
);
3809 tcg_gen_ld_i64(llval
, cpu_env
, offsetof(CPUMIPSState
, llval_wp
));
3810 tcg_gen_atomic_cmpxchg_i64(val
, taddr
, llval
, tval
,
3811 eva
? MIPS_HFLAG_UM
: ctx
->mem_idx
, MO_64
);
3813 tcg_gen_movi_tl(cpu_gpr
[reg1
], 1);
3815 tcg_gen_brcond_i64(TCG_COND_EQ
, val
, llval
, lab_done
);
3817 gen_set_label(lab_fail
);
3820 tcg_gen_movi_tl(cpu_gpr
[reg1
], 0);
3822 gen_set_label(lab_done
);
3823 tcg_gen_movi_tl(lladdr
, -1);
3824 tcg_gen_st_tl(lladdr
, cpu_env
, offsetof(CPUMIPSState
, lladdr
));
3827 /* Load and store */
3828 static void gen_flt_ldst(DisasContext
*ctx
, uint32_t opc
, int ft
,
3832 * Don't do NOP if destination is zero: we must perform the actual
3838 TCGv_i32 fp0
= tcg_temp_new_i32();
3839 tcg_gen_qemu_ld_i32(fp0
, t0
, ctx
->mem_idx
, MO_TESL
|
3840 ctx
->default_tcg_memop_mask
);
3841 gen_store_fpr32(ctx
, fp0
, ft
);
3842 tcg_temp_free_i32(fp0
);
3847 TCGv_i32 fp0
= tcg_temp_new_i32();
3848 gen_load_fpr32(ctx
, fp0
, ft
);
3849 tcg_gen_qemu_st_i32(fp0
, t0
, ctx
->mem_idx
, MO_TEUL
|
3850 ctx
->default_tcg_memop_mask
);
3851 tcg_temp_free_i32(fp0
);
3856 TCGv_i64 fp0
= tcg_temp_new_i64();
3857 tcg_gen_qemu_ld_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
|
3858 ctx
->default_tcg_memop_mask
);
3859 gen_store_fpr64(ctx
, fp0
, ft
);
3860 tcg_temp_free_i64(fp0
);
3865 TCGv_i64 fp0
= tcg_temp_new_i64();
3866 gen_load_fpr64(ctx
, fp0
, ft
);
3867 tcg_gen_qemu_st_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
|
3868 ctx
->default_tcg_memop_mask
);
3869 tcg_temp_free_i64(fp0
);
3873 MIPS_INVAL("flt_ldst");
3874 generate_exception_end(ctx
, EXCP_RI
);
3879 static void gen_cop1_ldst(DisasContext
*ctx
, uint32_t op
, int rt
,
3880 int rs
, int16_t imm
)
3882 TCGv t0
= tcg_temp_new();
3884 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
3885 check_cp1_enabled(ctx
);
3889 check_insn(ctx
, ISA_MIPS2
);
3892 gen_base_offset_addr(ctx
, t0
, rs
, imm
);
3893 gen_flt_ldst(ctx
, op
, rt
, t0
);
3896 generate_exception_err(ctx
, EXCP_CpU
, 1);
3901 /* Arithmetic with immediate operand */
3902 static void gen_arith_imm(DisasContext
*ctx
, uint32_t opc
,
3903 int rt
, int rs
, int imm
)
3905 target_ulong uimm
= (target_long
)imm
; /* Sign extend to 32/64 bits */
3907 if (rt
== 0 && opc
!= OPC_ADDI
&& opc
!= OPC_DADDI
) {
3909 * If no destination, treat it as a NOP.
3910 * For addi, we must generate the overflow exception when needed.
3917 TCGv t0
= tcg_temp_local_new();
3918 TCGv t1
= tcg_temp_new();
3919 TCGv t2
= tcg_temp_new();
3920 TCGLabel
*l1
= gen_new_label();
3922 gen_load_gpr(t1
, rs
);
3923 tcg_gen_addi_tl(t0
, t1
, uimm
);
3924 tcg_gen_ext32s_tl(t0
, t0
);
3926 tcg_gen_xori_tl(t1
, t1
, ~uimm
);
3927 tcg_gen_xori_tl(t2
, t0
, uimm
);
3928 tcg_gen_and_tl(t1
, t1
, t2
);
3930 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
3932 /* operands of same sign, result different sign */
3933 generate_exception(ctx
, EXCP_OVERFLOW
);
3935 tcg_gen_ext32s_tl(t0
, t0
);
3936 gen_store_gpr(t0
, rt
);
3942 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
3943 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
3945 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
3948 #if defined(TARGET_MIPS64)
3951 TCGv t0
= tcg_temp_local_new();
3952 TCGv t1
= tcg_temp_new();
3953 TCGv t2
= tcg_temp_new();
3954 TCGLabel
*l1
= gen_new_label();
3956 gen_load_gpr(t1
, rs
);
3957 tcg_gen_addi_tl(t0
, t1
, uimm
);
3959 tcg_gen_xori_tl(t1
, t1
, ~uimm
);
3960 tcg_gen_xori_tl(t2
, t0
, uimm
);
3961 tcg_gen_and_tl(t1
, t1
, t2
);
3963 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
3965 /* operands of same sign, result different sign */
3966 generate_exception(ctx
, EXCP_OVERFLOW
);
3968 gen_store_gpr(t0
, rt
);
3974 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
3976 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
3983 /* Logic with immediate operand */
3984 static void gen_logic_imm(DisasContext
*ctx
, uint32_t opc
,
3985 int rt
, int rs
, int16_t imm
)
3990 /* If no destination, treat it as a NOP. */
3993 uimm
= (uint16_t)imm
;
3996 if (likely(rs
!= 0)) {
3997 tcg_gen_andi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
3999 tcg_gen_movi_tl(cpu_gpr
[rt
], 0);
4004 tcg_gen_ori_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
4006 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
4010 if (likely(rs
!= 0)) {
4011 tcg_gen_xori_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
4013 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
4017 if (rs
!= 0 && (ctx
->insn_flags
& ISA_MIPS32R6
)) {
4019 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], imm
<< 16);
4020 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
4022 tcg_gen_movi_tl(cpu_gpr
[rt
], imm
<< 16);
4031 /* Set on less than with immediate operand */
4032 static void gen_slt_imm(DisasContext
*ctx
, uint32_t opc
,
4033 int rt
, int rs
, int16_t imm
)
4035 target_ulong uimm
= (target_long
)imm
; /* Sign extend to 32/64 bits */
4039 /* If no destination, treat it as a NOP. */
4042 t0
= tcg_temp_new();
4043 gen_load_gpr(t0
, rs
);
4046 tcg_gen_setcondi_tl(TCG_COND_LT
, cpu_gpr
[rt
], t0
, uimm
);
4049 tcg_gen_setcondi_tl(TCG_COND_LTU
, cpu_gpr
[rt
], t0
, uimm
);
4055 /* Shifts with immediate operand */
4056 static void gen_shift_imm(DisasContext
*ctx
, uint32_t opc
,
4057 int rt
, int rs
, int16_t imm
)
4059 target_ulong uimm
= ((uint16_t)imm
) & 0x1f;
4063 /* If no destination, treat it as a NOP. */
4067 t0
= tcg_temp_new();
4068 gen_load_gpr(t0
, rs
);
4071 tcg_gen_shli_tl(t0
, t0
, uimm
);
4072 tcg_gen_ext32s_tl(cpu_gpr
[rt
], t0
);
4075 tcg_gen_sari_tl(cpu_gpr
[rt
], t0
, uimm
);
4079 tcg_gen_ext32u_tl(t0
, t0
);
4080 tcg_gen_shri_tl(cpu_gpr
[rt
], t0
, uimm
);
4082 tcg_gen_ext32s_tl(cpu_gpr
[rt
], t0
);
4087 TCGv_i32 t1
= tcg_temp_new_i32();
4089 tcg_gen_trunc_tl_i32(t1
, t0
);
4090 tcg_gen_rotri_i32(t1
, t1
, uimm
);
4091 tcg_gen_ext_i32_tl(cpu_gpr
[rt
], t1
);
4092 tcg_temp_free_i32(t1
);
4094 tcg_gen_ext32s_tl(cpu_gpr
[rt
], t0
);
4097 #if defined(TARGET_MIPS64)
4099 tcg_gen_shli_tl(cpu_gpr
[rt
], t0
, uimm
);
4102 tcg_gen_sari_tl(cpu_gpr
[rt
], t0
, uimm
);
4105 tcg_gen_shri_tl(cpu_gpr
[rt
], t0
, uimm
);
4109 tcg_gen_rotri_tl(cpu_gpr
[rt
], t0
, uimm
);
4111 tcg_gen_mov_tl(cpu_gpr
[rt
], t0
);
4115 tcg_gen_shli_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
4118 tcg_gen_sari_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
4121 tcg_gen_shri_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
4124 tcg_gen_rotri_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
4132 static void gen_arith(DisasContext
*ctx
, uint32_t opc
,
4133 int rd
, int rs
, int rt
)
4135 if (rd
== 0 && opc
!= OPC_ADD
&& opc
!= OPC_SUB
4136 && opc
!= OPC_DADD
&& opc
!= OPC_DSUB
) {
4138 * If no destination, treat it as a NOP.
4139 * For add & sub, we must generate the overflow exception when needed.
4147 TCGv t0
= tcg_temp_local_new();
4148 TCGv t1
= tcg_temp_new();
4149 TCGv t2
= tcg_temp_new();
4150 TCGLabel
*l1
= gen_new_label();
4152 gen_load_gpr(t1
, rs
);
4153 gen_load_gpr(t2
, rt
);
4154 tcg_gen_add_tl(t0
, t1
, t2
);
4155 tcg_gen_ext32s_tl(t0
, t0
);
4156 tcg_gen_xor_tl(t1
, t1
, t2
);
4157 tcg_gen_xor_tl(t2
, t0
, t2
);
4158 tcg_gen_andc_tl(t1
, t2
, t1
);
4160 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
4162 /* operands of same sign, result different sign */
4163 generate_exception(ctx
, EXCP_OVERFLOW
);
4165 gen_store_gpr(t0
, rd
);
4170 if (rs
!= 0 && rt
!= 0) {
4171 tcg_gen_add_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
4172 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
4173 } else if (rs
== 0 && rt
!= 0) {
4174 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
4175 } else if (rs
!= 0 && rt
== 0) {
4176 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
4178 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4183 TCGv t0
= tcg_temp_local_new();
4184 TCGv t1
= tcg_temp_new();
4185 TCGv t2
= tcg_temp_new();
4186 TCGLabel
*l1
= gen_new_label();
4188 gen_load_gpr(t1
, rs
);
4189 gen_load_gpr(t2
, rt
);
4190 tcg_gen_sub_tl(t0
, t1
, t2
);
4191 tcg_gen_ext32s_tl(t0
, t0
);
4192 tcg_gen_xor_tl(t2
, t1
, t2
);
4193 tcg_gen_xor_tl(t1
, t0
, t1
);
4194 tcg_gen_and_tl(t1
, t1
, t2
);
4196 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
4199 * operands of different sign, first operand and the result
4202 generate_exception(ctx
, EXCP_OVERFLOW
);
4204 gen_store_gpr(t0
, rd
);
4209 if (rs
!= 0 && rt
!= 0) {
4210 tcg_gen_sub_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
4211 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
4212 } else if (rs
== 0 && rt
!= 0) {
4213 tcg_gen_neg_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
4214 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
4215 } else if (rs
!= 0 && rt
== 0) {
4216 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
4218 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4221 #if defined(TARGET_MIPS64)
4224 TCGv t0
= tcg_temp_local_new();
4225 TCGv t1
= tcg_temp_new();
4226 TCGv t2
= tcg_temp_new();
4227 TCGLabel
*l1
= gen_new_label();
4229 gen_load_gpr(t1
, rs
);
4230 gen_load_gpr(t2
, rt
);
4231 tcg_gen_add_tl(t0
, t1
, t2
);
4232 tcg_gen_xor_tl(t1
, t1
, t2
);
4233 tcg_gen_xor_tl(t2
, t0
, t2
);
4234 tcg_gen_andc_tl(t1
, t2
, t1
);
4236 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
4238 /* operands of same sign, result different sign */
4239 generate_exception(ctx
, EXCP_OVERFLOW
);
4241 gen_store_gpr(t0
, rd
);
4246 if (rs
!= 0 && rt
!= 0) {
4247 tcg_gen_add_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
4248 } else if (rs
== 0 && rt
!= 0) {
4249 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
4250 } else if (rs
!= 0 && rt
== 0) {
4251 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
4253 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4258 TCGv t0
= tcg_temp_local_new();
4259 TCGv t1
= tcg_temp_new();
4260 TCGv t2
= tcg_temp_new();
4261 TCGLabel
*l1
= gen_new_label();
4263 gen_load_gpr(t1
, rs
);
4264 gen_load_gpr(t2
, rt
);
4265 tcg_gen_sub_tl(t0
, t1
, t2
);
4266 tcg_gen_xor_tl(t2
, t1
, t2
);
4267 tcg_gen_xor_tl(t1
, t0
, t1
);
4268 tcg_gen_and_tl(t1
, t1
, t2
);
4270 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
4273 * Operands of different sign, first operand and result different
4276 generate_exception(ctx
, EXCP_OVERFLOW
);
4278 gen_store_gpr(t0
, rd
);
4283 if (rs
!= 0 && rt
!= 0) {
4284 tcg_gen_sub_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
4285 } else if (rs
== 0 && rt
!= 0) {
4286 tcg_gen_neg_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
4287 } else if (rs
!= 0 && rt
== 0) {
4288 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
4290 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4295 if (likely(rs
!= 0 && rt
!= 0)) {
4296 tcg_gen_mul_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
4297 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
4299 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4305 /* Conditional move */
4306 static void gen_cond_move(DisasContext
*ctx
, uint32_t opc
,
4307 int rd
, int rs
, int rt
)
4312 /* If no destination, treat it as a NOP. */
4316 t0
= tcg_temp_new();
4317 gen_load_gpr(t0
, rt
);
4318 t1
= tcg_const_tl(0);
4319 t2
= tcg_temp_new();
4320 gen_load_gpr(t2
, rs
);
4323 tcg_gen_movcond_tl(TCG_COND_NE
, cpu_gpr
[rd
], t0
, t1
, t2
, cpu_gpr
[rd
]);
4326 tcg_gen_movcond_tl(TCG_COND_EQ
, cpu_gpr
[rd
], t0
, t1
, t2
, cpu_gpr
[rd
]);
4329 tcg_gen_movcond_tl(TCG_COND_NE
, cpu_gpr
[rd
], t0
, t1
, t2
, t1
);
4332 tcg_gen_movcond_tl(TCG_COND_EQ
, cpu_gpr
[rd
], t0
, t1
, t2
, t1
);
4341 static void gen_logic(DisasContext
*ctx
, uint32_t opc
,
4342 int rd
, int rs
, int rt
)
4345 /* If no destination, treat it as a NOP. */
4351 if (likely(rs
!= 0 && rt
!= 0)) {
4352 tcg_gen_and_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
4354 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4358 if (rs
!= 0 && rt
!= 0) {
4359 tcg_gen_nor_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
4360 } else if (rs
== 0 && rt
!= 0) {
4361 tcg_gen_not_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
4362 } else if (rs
!= 0 && rt
== 0) {
4363 tcg_gen_not_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
4365 tcg_gen_movi_tl(cpu_gpr
[rd
], ~((target_ulong
)0));
4369 if (likely(rs
!= 0 && rt
!= 0)) {
4370 tcg_gen_or_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
4371 } else if (rs
== 0 && rt
!= 0) {
4372 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
4373 } else if (rs
!= 0 && rt
== 0) {
4374 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
4376 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4380 if (likely(rs
!= 0 && rt
!= 0)) {
4381 tcg_gen_xor_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
4382 } else if (rs
== 0 && rt
!= 0) {
4383 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
4384 } else if (rs
!= 0 && rt
== 0) {
4385 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
4387 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4393 /* Set on lower than */
4394 static void gen_slt(DisasContext
*ctx
, uint32_t opc
,
4395 int rd
, int rs
, int rt
)
4400 /* If no destination, treat it as a NOP. */
4404 t0
= tcg_temp_new();
4405 t1
= tcg_temp_new();
4406 gen_load_gpr(t0
, rs
);
4407 gen_load_gpr(t1
, rt
);
4410 tcg_gen_setcond_tl(TCG_COND_LT
, cpu_gpr
[rd
], t0
, t1
);
4413 tcg_gen_setcond_tl(TCG_COND_LTU
, cpu_gpr
[rd
], t0
, t1
);
4421 static void gen_shift(DisasContext
*ctx
, uint32_t opc
,
4422 int rd
, int rs
, int rt
)
4428 * If no destination, treat it as a NOP.
4429 * For add & sub, we must generate the overflow exception when needed.
4434 t0
= tcg_temp_new();
4435 t1
= tcg_temp_new();
4436 gen_load_gpr(t0
, rs
);
4437 gen_load_gpr(t1
, rt
);
4440 tcg_gen_andi_tl(t0
, t0
, 0x1f);
4441 tcg_gen_shl_tl(t0
, t1
, t0
);
4442 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
4445 tcg_gen_andi_tl(t0
, t0
, 0x1f);
4446 tcg_gen_sar_tl(cpu_gpr
[rd
], t1
, t0
);
4449 tcg_gen_ext32u_tl(t1
, t1
);
4450 tcg_gen_andi_tl(t0
, t0
, 0x1f);
4451 tcg_gen_shr_tl(t0
, t1
, t0
);
4452 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
4456 TCGv_i32 t2
= tcg_temp_new_i32();
4457 TCGv_i32 t3
= tcg_temp_new_i32();
4459 tcg_gen_trunc_tl_i32(t2
, t0
);
4460 tcg_gen_trunc_tl_i32(t3
, t1
);
4461 tcg_gen_andi_i32(t2
, t2
, 0x1f);
4462 tcg_gen_rotr_i32(t2
, t3
, t2
);
4463 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
4464 tcg_temp_free_i32(t2
);
4465 tcg_temp_free_i32(t3
);
4468 #if defined(TARGET_MIPS64)
4470 tcg_gen_andi_tl(t0
, t0
, 0x3f);
4471 tcg_gen_shl_tl(cpu_gpr
[rd
], t1
, t0
);
4474 tcg_gen_andi_tl(t0
, t0
, 0x3f);
4475 tcg_gen_sar_tl(cpu_gpr
[rd
], t1
, t0
);
4478 tcg_gen_andi_tl(t0
, t0
, 0x3f);
4479 tcg_gen_shr_tl(cpu_gpr
[rd
], t1
, t0
);
4482 tcg_gen_andi_tl(t0
, t0
, 0x3f);
4483 tcg_gen_rotr_tl(cpu_gpr
[rd
], t1
, t0
);
4491 #if defined(TARGET_MIPS64)
4492 /* Copy GPR to and from TX79 HI1/LO1 register. */
4493 static void gen_HILO1_tx79(DisasContext
*ctx
, uint32_t opc
, int reg
)
4495 if (reg
== 0 && (opc
== MMI_OPC_MFHI1
|| opc
== MMI_OPC_MFLO1
)) {
4502 tcg_gen_mov_tl(cpu_gpr
[reg
], cpu_HI
[1]);
4505 tcg_gen_mov_tl(cpu_gpr
[reg
], cpu_LO
[1]);
4509 tcg_gen_mov_tl(cpu_HI
[1], cpu_gpr
[reg
]);
4511 tcg_gen_movi_tl(cpu_HI
[1], 0);
4516 tcg_gen_mov_tl(cpu_LO
[1], cpu_gpr
[reg
]);
4518 tcg_gen_movi_tl(cpu_LO
[1], 0);
4522 MIPS_INVAL("mfthilo1 TX79");
4523 generate_exception_end(ctx
, EXCP_RI
);
4529 /* Arithmetic on HI/LO registers */
4530 static void gen_HILO(DisasContext
*ctx
, uint32_t opc
, int acc
, int reg
)
4532 if (reg
== 0 && (opc
== OPC_MFHI
|| opc
== OPC_MFLO
)) {
4543 #if defined(TARGET_MIPS64)
4545 tcg_gen_ext32s_tl(cpu_gpr
[reg
], cpu_HI
[acc
]);
4549 tcg_gen_mov_tl(cpu_gpr
[reg
], cpu_HI
[acc
]);
4553 #if defined(TARGET_MIPS64)
4555 tcg_gen_ext32s_tl(cpu_gpr
[reg
], cpu_LO
[acc
]);
4559 tcg_gen_mov_tl(cpu_gpr
[reg
], cpu_LO
[acc
]);
4564 #if defined(TARGET_MIPS64)
4566 tcg_gen_ext32s_tl(cpu_HI
[acc
], cpu_gpr
[reg
]);
4570 tcg_gen_mov_tl(cpu_HI
[acc
], cpu_gpr
[reg
]);
4573 tcg_gen_movi_tl(cpu_HI
[acc
], 0);
4578 #if defined(TARGET_MIPS64)
4580 tcg_gen_ext32s_tl(cpu_LO
[acc
], cpu_gpr
[reg
]);
4584 tcg_gen_mov_tl(cpu_LO
[acc
], cpu_gpr
[reg
]);
4587 tcg_gen_movi_tl(cpu_LO
[acc
], 0);
4593 static inline void gen_r6_ld(target_long addr
, int reg
, int memidx
,
4596 TCGv t0
= tcg_const_tl(addr
);
4597 tcg_gen_qemu_ld_tl(t0
, t0
, memidx
, memop
);
4598 gen_store_gpr(t0
, reg
);
4602 static inline void gen_pcrel(DisasContext
*ctx
, int opc
, target_ulong pc
,
4608 switch (MASK_OPC_PCREL_TOP2BITS(opc
)) {
4611 offset
= sextract32(ctx
->opcode
<< 2, 0, 21);
4612 addr
= addr_add(ctx
, pc
, offset
);
4613 tcg_gen_movi_tl(cpu_gpr
[rs
], addr
);
4617 offset
= sextract32(ctx
->opcode
<< 2, 0, 21);
4618 addr
= addr_add(ctx
, pc
, offset
);
4619 gen_r6_ld(addr
, rs
, ctx
->mem_idx
, MO_TESL
);
4621 #if defined(TARGET_MIPS64)
4624 offset
= sextract32(ctx
->opcode
<< 2, 0, 21);
4625 addr
= addr_add(ctx
, pc
, offset
);
4626 gen_r6_ld(addr
, rs
, ctx
->mem_idx
, MO_TEUL
);
4630 switch (MASK_OPC_PCREL_TOP5BITS(opc
)) {
4633 offset
= sextract32(ctx
->opcode
, 0, 16) << 16;
4634 addr
= addr_add(ctx
, pc
, offset
);
4635 tcg_gen_movi_tl(cpu_gpr
[rs
], addr
);
4640 offset
= sextract32(ctx
->opcode
, 0, 16) << 16;
4641 addr
= ~0xFFFF & addr_add(ctx
, pc
, offset
);
4642 tcg_gen_movi_tl(cpu_gpr
[rs
], addr
);
4645 #if defined(TARGET_MIPS64)
4646 case R6_OPC_LDPC
: /* bits 16 and 17 are part of immediate */
4647 case R6_OPC_LDPC
+ (1 << 16):
4648 case R6_OPC_LDPC
+ (2 << 16):
4649 case R6_OPC_LDPC
+ (3 << 16):
4651 offset
= sextract32(ctx
->opcode
<< 3, 0, 21);
4652 addr
= addr_add(ctx
, (pc
& ~0x7), offset
);
4653 gen_r6_ld(addr
, rs
, ctx
->mem_idx
, MO_TEQ
);
4657 MIPS_INVAL("OPC_PCREL");
4658 generate_exception_end(ctx
, EXCP_RI
);
4665 static void gen_r6_muldiv(DisasContext
*ctx
, int opc
, int rd
, int rs
, int rt
)
4674 t0
= tcg_temp_new();
4675 t1
= tcg_temp_new();
4677 gen_load_gpr(t0
, rs
);
4678 gen_load_gpr(t1
, rt
);
4683 TCGv t2
= tcg_temp_new();
4684 TCGv t3
= tcg_temp_new();
4685 tcg_gen_ext32s_tl(t0
, t0
);
4686 tcg_gen_ext32s_tl(t1
, t1
);
4687 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, INT_MIN
);
4688 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1);
4689 tcg_gen_and_tl(t2
, t2
, t3
);
4690 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
4691 tcg_gen_or_tl(t2
, t2
, t3
);
4692 tcg_gen_movi_tl(t3
, 0);
4693 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
4694 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
4695 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
4702 TCGv t2
= tcg_temp_new();
4703 TCGv t3
= tcg_temp_new();
4704 tcg_gen_ext32s_tl(t0
, t0
);
4705 tcg_gen_ext32s_tl(t1
, t1
);
4706 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, INT_MIN
);
4707 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1);
4708 tcg_gen_and_tl(t2
, t2
, t3
);
4709 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
4710 tcg_gen_or_tl(t2
, t2
, t3
);
4711 tcg_gen_movi_tl(t3
, 0);
4712 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
4713 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
4714 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
4721 TCGv t2
= tcg_const_tl(0);
4722 TCGv t3
= tcg_const_tl(1);
4723 tcg_gen_ext32u_tl(t0
, t0
);
4724 tcg_gen_ext32u_tl(t1
, t1
);
4725 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
4726 tcg_gen_divu_tl(cpu_gpr
[rd
], t0
, t1
);
4727 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
4734 TCGv t2
= tcg_const_tl(0);
4735 TCGv t3
= tcg_const_tl(1);
4736 tcg_gen_ext32u_tl(t0
, t0
);
4737 tcg_gen_ext32u_tl(t1
, t1
);
4738 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
4739 tcg_gen_remu_tl(cpu_gpr
[rd
], t0
, t1
);
4740 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
4747 TCGv_i32 t2
= tcg_temp_new_i32();
4748 TCGv_i32 t3
= tcg_temp_new_i32();
4749 tcg_gen_trunc_tl_i32(t2
, t0
);
4750 tcg_gen_trunc_tl_i32(t3
, t1
);
4751 tcg_gen_mul_i32(t2
, t2
, t3
);
4752 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
4753 tcg_temp_free_i32(t2
);
4754 tcg_temp_free_i32(t3
);
4759 TCGv_i32 t2
= tcg_temp_new_i32();
4760 TCGv_i32 t3
= tcg_temp_new_i32();
4761 tcg_gen_trunc_tl_i32(t2
, t0
);
4762 tcg_gen_trunc_tl_i32(t3
, t1
);
4763 tcg_gen_muls2_i32(t2
, t3
, t2
, t3
);
4764 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t3
);
4765 tcg_temp_free_i32(t2
);
4766 tcg_temp_free_i32(t3
);
4771 TCGv_i32 t2
= tcg_temp_new_i32();
4772 TCGv_i32 t3
= tcg_temp_new_i32();
4773 tcg_gen_trunc_tl_i32(t2
, t0
);
4774 tcg_gen_trunc_tl_i32(t3
, t1
);
4775 tcg_gen_mul_i32(t2
, t2
, t3
);
4776 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
4777 tcg_temp_free_i32(t2
);
4778 tcg_temp_free_i32(t3
);
4783 TCGv_i32 t2
= tcg_temp_new_i32();
4784 TCGv_i32 t3
= tcg_temp_new_i32();
4785 tcg_gen_trunc_tl_i32(t2
, t0
);
4786 tcg_gen_trunc_tl_i32(t3
, t1
);
4787 tcg_gen_mulu2_i32(t2
, t3
, t2
, t3
);
4788 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t3
);
4789 tcg_temp_free_i32(t2
);
4790 tcg_temp_free_i32(t3
);
4793 #if defined(TARGET_MIPS64)
4796 TCGv t2
= tcg_temp_new();
4797 TCGv t3
= tcg_temp_new();
4798 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, -1LL << 63);
4799 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1LL);
4800 tcg_gen_and_tl(t2
, t2
, t3
);
4801 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
4802 tcg_gen_or_tl(t2
, t2
, t3
);
4803 tcg_gen_movi_tl(t3
, 0);
4804 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
4805 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
4812 TCGv t2
= tcg_temp_new();
4813 TCGv t3
= tcg_temp_new();
4814 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, -1LL << 63);
4815 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1LL);
4816 tcg_gen_and_tl(t2
, t2
, t3
);
4817 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
4818 tcg_gen_or_tl(t2
, t2
, t3
);
4819 tcg_gen_movi_tl(t3
, 0);
4820 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
4821 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
4828 TCGv t2
= tcg_const_tl(0);
4829 TCGv t3
= tcg_const_tl(1);
4830 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
4831 tcg_gen_divu_i64(cpu_gpr
[rd
], t0
, t1
);
4838 TCGv t2
= tcg_const_tl(0);
4839 TCGv t3
= tcg_const_tl(1);
4840 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
4841 tcg_gen_remu_i64(cpu_gpr
[rd
], t0
, t1
);
4847 tcg_gen_mul_i64(cpu_gpr
[rd
], t0
, t1
);
4851 TCGv t2
= tcg_temp_new();
4852 tcg_gen_muls2_i64(t2
, cpu_gpr
[rd
], t0
, t1
);
4857 tcg_gen_mul_i64(cpu_gpr
[rd
], t0
, t1
);
4861 TCGv t2
= tcg_temp_new();
4862 tcg_gen_mulu2_i64(t2
, cpu_gpr
[rd
], t0
, t1
);
4868 MIPS_INVAL("r6 mul/div");
4869 generate_exception_end(ctx
, EXCP_RI
);
4877 #if defined(TARGET_MIPS64)
4878 static void gen_div1_tx79(DisasContext
*ctx
, uint32_t opc
, int rs
, int rt
)
4882 t0
= tcg_temp_new();
4883 t1
= tcg_temp_new();
4885 gen_load_gpr(t0
, rs
);
4886 gen_load_gpr(t1
, rt
);
4891 TCGv t2
= tcg_temp_new();
4892 TCGv t3
= tcg_temp_new();
4893 tcg_gen_ext32s_tl(t0
, t0
);
4894 tcg_gen_ext32s_tl(t1
, t1
);
4895 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, INT_MIN
);
4896 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1);
4897 tcg_gen_and_tl(t2
, t2
, t3
);
4898 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
4899 tcg_gen_or_tl(t2
, t2
, t3
);
4900 tcg_gen_movi_tl(t3
, 0);
4901 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
4902 tcg_gen_div_tl(cpu_LO
[1], t0
, t1
);
4903 tcg_gen_rem_tl(cpu_HI
[1], t0
, t1
);
4904 tcg_gen_ext32s_tl(cpu_LO
[1], cpu_LO
[1]);
4905 tcg_gen_ext32s_tl(cpu_HI
[1], cpu_HI
[1]);
4912 TCGv t2
= tcg_const_tl(0);
4913 TCGv t3
= tcg_const_tl(1);
4914 tcg_gen_ext32u_tl(t0
, t0
);
4915 tcg_gen_ext32u_tl(t1
, t1
);
4916 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
4917 tcg_gen_divu_tl(cpu_LO
[1], t0
, t1
);
4918 tcg_gen_remu_tl(cpu_HI
[1], t0
, t1
);
4919 tcg_gen_ext32s_tl(cpu_LO
[1], cpu_LO
[1]);
4920 tcg_gen_ext32s_tl(cpu_HI
[1], cpu_HI
[1]);
4926 MIPS_INVAL("div1 TX79");
4927 generate_exception_end(ctx
, EXCP_RI
);
4936 static void gen_muldiv(DisasContext
*ctx
, uint32_t opc
,
4937 int acc
, int rs
, int rt
)
4941 t0
= tcg_temp_new();
4942 t1
= tcg_temp_new();
4944 gen_load_gpr(t0
, rs
);
4945 gen_load_gpr(t1
, rt
);
4954 TCGv t2
= tcg_temp_new();
4955 TCGv t3
= tcg_temp_new();
4956 tcg_gen_ext32s_tl(t0
, t0
);
4957 tcg_gen_ext32s_tl(t1
, t1
);
4958 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, INT_MIN
);
4959 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1);
4960 tcg_gen_and_tl(t2
, t2
, t3
);
4961 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
4962 tcg_gen_or_tl(t2
, t2
, t3
);
4963 tcg_gen_movi_tl(t3
, 0);
4964 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
4965 tcg_gen_div_tl(cpu_LO
[acc
], t0
, t1
);
4966 tcg_gen_rem_tl(cpu_HI
[acc
], t0
, t1
);
4967 tcg_gen_ext32s_tl(cpu_LO
[acc
], cpu_LO
[acc
]);
4968 tcg_gen_ext32s_tl(cpu_HI
[acc
], cpu_HI
[acc
]);
4975 TCGv t2
= tcg_const_tl(0);
4976 TCGv t3
= tcg_const_tl(1);
4977 tcg_gen_ext32u_tl(t0
, t0
);
4978 tcg_gen_ext32u_tl(t1
, t1
);
4979 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
4980 tcg_gen_divu_tl(cpu_LO
[acc
], t0
, t1
);
4981 tcg_gen_remu_tl(cpu_HI
[acc
], t0
, t1
);
4982 tcg_gen_ext32s_tl(cpu_LO
[acc
], cpu_LO
[acc
]);
4983 tcg_gen_ext32s_tl(cpu_HI
[acc
], cpu_HI
[acc
]);
4990 TCGv_i32 t2
= tcg_temp_new_i32();
4991 TCGv_i32 t3
= tcg_temp_new_i32();
4992 tcg_gen_trunc_tl_i32(t2
, t0
);
4993 tcg_gen_trunc_tl_i32(t3
, t1
);
4994 tcg_gen_muls2_i32(t2
, t3
, t2
, t3
);
4995 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
4996 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
4997 tcg_temp_free_i32(t2
);
4998 tcg_temp_free_i32(t3
);
5003 TCGv_i32 t2
= tcg_temp_new_i32();
5004 TCGv_i32 t3
= tcg_temp_new_i32();
5005 tcg_gen_trunc_tl_i32(t2
, t0
);
5006 tcg_gen_trunc_tl_i32(t3
, t1
);
5007 tcg_gen_mulu2_i32(t2
, t3
, t2
, t3
);
5008 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
5009 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
5010 tcg_temp_free_i32(t2
);
5011 tcg_temp_free_i32(t3
);
5014 #if defined(TARGET_MIPS64)
5017 TCGv t2
= tcg_temp_new();
5018 TCGv t3
= tcg_temp_new();
5019 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, -1LL << 63);
5020 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1LL);
5021 tcg_gen_and_tl(t2
, t2
, t3
);
5022 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
5023 tcg_gen_or_tl(t2
, t2
, t3
);
5024 tcg_gen_movi_tl(t3
, 0);
5025 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
5026 tcg_gen_div_tl(cpu_LO
[acc
], t0
, t1
);
5027 tcg_gen_rem_tl(cpu_HI
[acc
], t0
, t1
);
5034 TCGv t2
= tcg_const_tl(0);
5035 TCGv t3
= tcg_const_tl(1);
5036 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
5037 tcg_gen_divu_i64(cpu_LO
[acc
], t0
, t1
);
5038 tcg_gen_remu_i64(cpu_HI
[acc
], t0
, t1
);
5044 tcg_gen_muls2_i64(cpu_LO
[acc
], cpu_HI
[acc
], t0
, t1
);
5047 tcg_gen_mulu2_i64(cpu_LO
[acc
], cpu_HI
[acc
], t0
, t1
);
5052 TCGv_i64 t2
= tcg_temp_new_i64();
5053 TCGv_i64 t3
= tcg_temp_new_i64();
5055 tcg_gen_ext_tl_i64(t2
, t0
);
5056 tcg_gen_ext_tl_i64(t3
, t1
);
5057 tcg_gen_mul_i64(t2
, t2
, t3
);
5058 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
5059 tcg_gen_add_i64(t2
, t2
, t3
);
5060 tcg_temp_free_i64(t3
);
5061 gen_move_low32(cpu_LO
[acc
], t2
);
5062 gen_move_high32(cpu_HI
[acc
], t2
);
5063 tcg_temp_free_i64(t2
);
5068 TCGv_i64 t2
= tcg_temp_new_i64();
5069 TCGv_i64 t3
= tcg_temp_new_i64();
5071 tcg_gen_ext32u_tl(t0
, t0
);
5072 tcg_gen_ext32u_tl(t1
, t1
);
5073 tcg_gen_extu_tl_i64(t2
, t0
);
5074 tcg_gen_extu_tl_i64(t3
, t1
);
5075 tcg_gen_mul_i64(t2
, t2
, t3
);
5076 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
5077 tcg_gen_add_i64(t2
, t2
, t3
);
5078 tcg_temp_free_i64(t3
);
5079 gen_move_low32(cpu_LO
[acc
], t2
);
5080 gen_move_high32(cpu_HI
[acc
], t2
);
5081 tcg_temp_free_i64(t2
);
5086 TCGv_i64 t2
= tcg_temp_new_i64();
5087 TCGv_i64 t3
= tcg_temp_new_i64();
5089 tcg_gen_ext_tl_i64(t2
, t0
);
5090 tcg_gen_ext_tl_i64(t3
, t1
);
5091 tcg_gen_mul_i64(t2
, t2
, t3
);
5092 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
5093 tcg_gen_sub_i64(t2
, t3
, t2
);
5094 tcg_temp_free_i64(t3
);
5095 gen_move_low32(cpu_LO
[acc
], t2
);
5096 gen_move_high32(cpu_HI
[acc
], t2
);
5097 tcg_temp_free_i64(t2
);
5102 TCGv_i64 t2
= tcg_temp_new_i64();
5103 TCGv_i64 t3
= tcg_temp_new_i64();
5105 tcg_gen_ext32u_tl(t0
, t0
);
5106 tcg_gen_ext32u_tl(t1
, t1
);
5107 tcg_gen_extu_tl_i64(t2
, t0
);
5108 tcg_gen_extu_tl_i64(t3
, t1
);
5109 tcg_gen_mul_i64(t2
, t2
, t3
);
5110 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
5111 tcg_gen_sub_i64(t2
, t3
, t2
);
5112 tcg_temp_free_i64(t3
);
5113 gen_move_low32(cpu_LO
[acc
], t2
);
5114 gen_move_high32(cpu_HI
[acc
], t2
);
5115 tcg_temp_free_i64(t2
);
5119 MIPS_INVAL("mul/div");
5120 generate_exception_end(ctx
, EXCP_RI
);
5129 * These MULT[U] and MADD[U] instructions implemented in for example
5130 * the Toshiba/Sony R5900 and the Toshiba TX19, TX39 and TX79 core
5131 * architectures are special three-operand variants with the syntax
5133 * MULT[U][1] rd, rs, rt
5137 * (rd, LO, HI) <- rs * rt
5141 * MADD[U][1] rd, rs, rt
5145 * (rd, LO, HI) <- (LO, HI) + rs * rt
5147 * where the low-order 32-bits of the result is placed into both the
5148 * GPR rd and the special register LO. The high-order 32-bits of the
5149 * result is placed into the special register HI.
5151 * If the GPR rd is omitted in assembly language, it is taken to be 0,
5152 * which is the zero register that always reads as 0.
5154 static void gen_mul_txx9(DisasContext
*ctx
, uint32_t opc
,
5155 int rd
, int rs
, int rt
)
5157 TCGv t0
= tcg_temp_new();
5158 TCGv t1
= tcg_temp_new();
5161 gen_load_gpr(t0
, rs
);
5162 gen_load_gpr(t1
, rt
);
5170 TCGv_i32 t2
= tcg_temp_new_i32();
5171 TCGv_i32 t3
= tcg_temp_new_i32();
5172 tcg_gen_trunc_tl_i32(t2
, t0
);
5173 tcg_gen_trunc_tl_i32(t3
, t1
);
5174 tcg_gen_muls2_i32(t2
, t3
, t2
, t3
);
5176 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
5178 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
5179 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
5180 tcg_temp_free_i32(t2
);
5181 tcg_temp_free_i32(t3
);
5184 case MMI_OPC_MULTU1
:
5189 TCGv_i32 t2
= tcg_temp_new_i32();
5190 TCGv_i32 t3
= tcg_temp_new_i32();
5191 tcg_gen_trunc_tl_i32(t2
, t0
);
5192 tcg_gen_trunc_tl_i32(t3
, t1
);
5193 tcg_gen_mulu2_i32(t2
, t3
, t2
, t3
);
5195 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
5197 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
5198 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
5199 tcg_temp_free_i32(t2
);
5200 tcg_temp_free_i32(t3
);
5208 TCGv_i64 t2
= tcg_temp_new_i64();
5209 TCGv_i64 t3
= tcg_temp_new_i64();
5211 tcg_gen_ext_tl_i64(t2
, t0
);
5212 tcg_gen_ext_tl_i64(t3
, t1
);
5213 tcg_gen_mul_i64(t2
, t2
, t3
);
5214 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
5215 tcg_gen_add_i64(t2
, t2
, t3
);
5216 tcg_temp_free_i64(t3
);
5217 gen_move_low32(cpu_LO
[acc
], t2
);
5218 gen_move_high32(cpu_HI
[acc
], t2
);
5220 gen_move_low32(cpu_gpr
[rd
], t2
);
5222 tcg_temp_free_i64(t2
);
5225 case MMI_OPC_MADDU1
:
5230 TCGv_i64 t2
= tcg_temp_new_i64();
5231 TCGv_i64 t3
= tcg_temp_new_i64();
5233 tcg_gen_ext32u_tl(t0
, t0
);
5234 tcg_gen_ext32u_tl(t1
, t1
);
5235 tcg_gen_extu_tl_i64(t2
, t0
);
5236 tcg_gen_extu_tl_i64(t3
, t1
);
5237 tcg_gen_mul_i64(t2
, t2
, t3
);
5238 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
5239 tcg_gen_add_i64(t2
, t2
, t3
);
5240 tcg_temp_free_i64(t3
);
5241 gen_move_low32(cpu_LO
[acc
], t2
);
5242 gen_move_high32(cpu_HI
[acc
], t2
);
5244 gen_move_low32(cpu_gpr
[rd
], t2
);
5246 tcg_temp_free_i64(t2
);
5250 MIPS_INVAL("mul/madd TXx9");
5251 generate_exception_end(ctx
, EXCP_RI
);
5260 static void gen_mul_vr54xx(DisasContext
*ctx
, uint32_t opc
,
5261 int rd
, int rs
, int rt
)
5263 TCGv t0
= tcg_temp_new();
5264 TCGv t1
= tcg_temp_new();
5266 gen_load_gpr(t0
, rs
);
5267 gen_load_gpr(t1
, rt
);
5270 case OPC_VR54XX_MULS
:
5271 gen_helper_muls(t0
, cpu_env
, t0
, t1
);
5273 case OPC_VR54XX_MULSU
:
5274 gen_helper_mulsu(t0
, cpu_env
, t0
, t1
);
5276 case OPC_VR54XX_MACC
:
5277 gen_helper_macc(t0
, cpu_env
, t0
, t1
);
5279 case OPC_VR54XX_MACCU
:
5280 gen_helper_maccu(t0
, cpu_env
, t0
, t1
);
5282 case OPC_VR54XX_MSAC
:
5283 gen_helper_msac(t0
, cpu_env
, t0
, t1
);
5285 case OPC_VR54XX_MSACU
:
5286 gen_helper_msacu(t0
, cpu_env
, t0
, t1
);
5288 case OPC_VR54XX_MULHI
:
5289 gen_helper_mulhi(t0
, cpu_env
, t0
, t1
);
5291 case OPC_VR54XX_MULHIU
:
5292 gen_helper_mulhiu(t0
, cpu_env
, t0
, t1
);
5294 case OPC_VR54XX_MULSHI
:
5295 gen_helper_mulshi(t0
, cpu_env
, t0
, t1
);
5297 case OPC_VR54XX_MULSHIU
:
5298 gen_helper_mulshiu(t0
, cpu_env
, t0
, t1
);
5300 case OPC_VR54XX_MACCHI
:
5301 gen_helper_macchi(t0
, cpu_env
, t0
, t1
);
5303 case OPC_VR54XX_MACCHIU
:
5304 gen_helper_macchiu(t0
, cpu_env
, t0
, t1
);
5306 case OPC_VR54XX_MSACHI
:
5307 gen_helper_msachi(t0
, cpu_env
, t0
, t1
);
5309 case OPC_VR54XX_MSACHIU
:
5310 gen_helper_msachiu(t0
, cpu_env
, t0
, t1
);
5313 MIPS_INVAL("mul vr54xx");
5314 generate_exception_end(ctx
, EXCP_RI
);
5317 gen_store_gpr(t0
, rd
);
5324 static void gen_cl(DisasContext
*ctx
, uint32_t opc
,
5334 gen_load_gpr(t0
, rs
);
5339 #if defined(TARGET_MIPS64)
5343 tcg_gen_not_tl(t0
, t0
);
5352 tcg_gen_ext32u_tl(t0
, t0
);
5353 tcg_gen_clzi_tl(t0
, t0
, TARGET_LONG_BITS
);
5354 tcg_gen_subi_tl(t0
, t0
, TARGET_LONG_BITS
- 32);
5356 #if defined(TARGET_MIPS64)
5361 tcg_gen_clzi_i64(t0
, t0
, 64);
5367 /* Godson integer instructions */
5368 static void gen_loongson_integer(DisasContext
*ctx
, uint32_t opc
,
5369 int rd
, int rs
, int rt
)
5381 case OPC_MULTU_G_2E
:
5382 case OPC_MULTU_G_2F
:
5383 #if defined(TARGET_MIPS64)
5384 case OPC_DMULT_G_2E
:
5385 case OPC_DMULT_G_2F
:
5386 case OPC_DMULTU_G_2E
:
5387 case OPC_DMULTU_G_2F
:
5389 t0
= tcg_temp_new();
5390 t1
= tcg_temp_new();
5393 t0
= tcg_temp_local_new();
5394 t1
= tcg_temp_local_new();
5398 gen_load_gpr(t0
, rs
);
5399 gen_load_gpr(t1
, rt
);
5404 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
5405 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
5407 case OPC_MULTU_G_2E
:
5408 case OPC_MULTU_G_2F
:
5409 tcg_gen_ext32u_tl(t0
, t0
);
5410 tcg_gen_ext32u_tl(t1
, t1
);
5411 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
5412 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
5417 TCGLabel
*l1
= gen_new_label();
5418 TCGLabel
*l2
= gen_new_label();
5419 TCGLabel
*l3
= gen_new_label();
5420 tcg_gen_ext32s_tl(t0
, t0
);
5421 tcg_gen_ext32s_tl(t1
, t1
);
5422 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
5423 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
5426 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, INT_MIN
, l2
);
5427 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1, l2
);
5428 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
5431 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
5432 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
5439 TCGLabel
*l1
= gen_new_label();
5440 TCGLabel
*l2
= gen_new_label();
5441 tcg_gen_ext32u_tl(t0
, t0
);
5442 tcg_gen_ext32u_tl(t1
, t1
);
5443 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
5444 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
5447 tcg_gen_divu_tl(cpu_gpr
[rd
], t0
, t1
);
5448 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
5455 TCGLabel
*l1
= gen_new_label();
5456 TCGLabel
*l2
= gen_new_label();
5457 TCGLabel
*l3
= gen_new_label();
5458 tcg_gen_ext32u_tl(t0
, t0
);
5459 tcg_gen_ext32u_tl(t1
, t1
);
5460 tcg_gen_brcondi_tl(TCG_COND_EQ
, t1
, 0, l1
);
5461 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, INT_MIN
, l2
);
5462 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1, l2
);
5464 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
5467 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
5468 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
5475 TCGLabel
*l1
= gen_new_label();
5476 TCGLabel
*l2
= gen_new_label();
5477 tcg_gen_ext32u_tl(t0
, t0
);
5478 tcg_gen_ext32u_tl(t1
, t1
);
5479 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
5480 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
5483 tcg_gen_remu_tl(cpu_gpr
[rd
], t0
, t1
);
5484 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
5488 #if defined(TARGET_MIPS64)
5489 case OPC_DMULT_G_2E
:
5490 case OPC_DMULT_G_2F
:
5491 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
5493 case OPC_DMULTU_G_2E
:
5494 case OPC_DMULTU_G_2F
:
5495 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
5500 TCGLabel
*l1
= gen_new_label();
5501 TCGLabel
*l2
= gen_new_label();
5502 TCGLabel
*l3
= gen_new_label();
5503 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
5504 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
5507 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, -1LL << 63, l2
);
5508 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1LL, l2
);
5509 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
5512 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
5516 case OPC_DDIVU_G_2E
:
5517 case OPC_DDIVU_G_2F
:
5519 TCGLabel
*l1
= gen_new_label();
5520 TCGLabel
*l2
= gen_new_label();
5521 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
5522 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
5525 tcg_gen_divu_tl(cpu_gpr
[rd
], t0
, t1
);
5532 TCGLabel
*l1
= gen_new_label();
5533 TCGLabel
*l2
= gen_new_label();
5534 TCGLabel
*l3
= gen_new_label();
5535 tcg_gen_brcondi_tl(TCG_COND_EQ
, t1
, 0, l1
);
5536 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, -1LL << 63, l2
);
5537 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1LL, l2
);
5539 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
5542 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
5546 case OPC_DMODU_G_2E
:
5547 case OPC_DMODU_G_2F
:
5549 TCGLabel
*l1
= gen_new_label();
5550 TCGLabel
*l2
= gen_new_label();
5551 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
5552 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
5555 tcg_gen_remu_tl(cpu_gpr
[rd
], t0
, t1
);
5566 /* Loongson multimedia instructions */
5567 static void gen_loongson_multimedia(DisasContext
*ctx
, int rd
, int rs
, int rt
)
5569 uint32_t opc
, shift_max
;
5573 opc
= MASK_LMMI(ctx
->opcode
);
5579 t0
= tcg_temp_local_new_i64();
5580 t1
= tcg_temp_local_new_i64();
5583 t0
= tcg_temp_new_i64();
5584 t1
= tcg_temp_new_i64();
5588 check_cp1_enabled(ctx
);
5589 gen_load_fpr64(ctx
, t0
, rs
);
5590 gen_load_fpr64(ctx
, t1
, rt
);
5594 gen_helper_paddsh(t0
, t0
, t1
);
5597 gen_helper_paddush(t0
, t0
, t1
);
5600 gen_helper_paddh(t0
, t0
, t1
);
5603 gen_helper_paddw(t0
, t0
, t1
);
5606 gen_helper_paddsb(t0
, t0
, t1
);
5609 gen_helper_paddusb(t0
, t0
, t1
);
5612 gen_helper_paddb(t0
, t0
, t1
);
5616 gen_helper_psubsh(t0
, t0
, t1
);
5619 gen_helper_psubush(t0
, t0
, t1
);
5622 gen_helper_psubh(t0
, t0
, t1
);
5625 gen_helper_psubw(t0
, t0
, t1
);
5628 gen_helper_psubsb(t0
, t0
, t1
);
5631 gen_helper_psubusb(t0
, t0
, t1
);
5634 gen_helper_psubb(t0
, t0
, t1
);
5638 gen_helper_pshufh(t0
, t0
, t1
);
5641 gen_helper_packsswh(t0
, t0
, t1
);
5644 gen_helper_packsshb(t0
, t0
, t1
);
5647 gen_helper_packushb(t0
, t0
, t1
);
5651 gen_helper_punpcklhw(t0
, t0
, t1
);
5654 gen_helper_punpckhhw(t0
, t0
, t1
);
5657 gen_helper_punpcklbh(t0
, t0
, t1
);
5660 gen_helper_punpckhbh(t0
, t0
, t1
);
5663 gen_helper_punpcklwd(t0
, t0
, t1
);
5666 gen_helper_punpckhwd(t0
, t0
, t1
);
5670 gen_helper_pavgh(t0
, t0
, t1
);
5673 gen_helper_pavgb(t0
, t0
, t1
);
5676 gen_helper_pmaxsh(t0
, t0
, t1
);
5679 gen_helper_pminsh(t0
, t0
, t1
);
5682 gen_helper_pmaxub(t0
, t0
, t1
);
5685 gen_helper_pminub(t0
, t0
, t1
);
5689 gen_helper_pcmpeqw(t0
, t0
, t1
);
5692 gen_helper_pcmpgtw(t0
, t0
, t1
);
5695 gen_helper_pcmpeqh(t0
, t0
, t1
);
5698 gen_helper_pcmpgth(t0
, t0
, t1
);
5701 gen_helper_pcmpeqb(t0
, t0
, t1
);
5704 gen_helper_pcmpgtb(t0
, t0
, t1
);
5708 gen_helper_psllw(t0
, t0
, t1
);
5711 gen_helper_psllh(t0
, t0
, t1
);
5714 gen_helper_psrlw(t0
, t0
, t1
);
5717 gen_helper_psrlh(t0
, t0
, t1
);
5720 gen_helper_psraw(t0
, t0
, t1
);
5723 gen_helper_psrah(t0
, t0
, t1
);
5727 gen_helper_pmullh(t0
, t0
, t1
);
5730 gen_helper_pmulhh(t0
, t0
, t1
);
5733 gen_helper_pmulhuh(t0
, t0
, t1
);
5736 gen_helper_pmaddhw(t0
, t0
, t1
);
5740 gen_helper_pasubub(t0
, t0
, t1
);
5743 gen_helper_biadd(t0
, t0
);
5746 gen_helper_pmovmskb(t0
, t0
);
5750 tcg_gen_add_i64(t0
, t0
, t1
);
5753 tcg_gen_sub_i64(t0
, t0
, t1
);
5756 tcg_gen_xor_i64(t0
, t0
, t1
);
5759 tcg_gen_nor_i64(t0
, t0
, t1
);
5762 tcg_gen_and_i64(t0
, t0
, t1
);
5765 tcg_gen_or_i64(t0
, t0
, t1
);
5769 tcg_gen_andc_i64(t0
, t1
, t0
);
5773 tcg_gen_deposit_i64(t0
, t0
, t1
, 0, 16);
5776 tcg_gen_deposit_i64(t0
, t0
, t1
, 16, 16);
5779 tcg_gen_deposit_i64(t0
, t0
, t1
, 32, 16);
5782 tcg_gen_deposit_i64(t0
, t0
, t1
, 48, 16);
5786 tcg_gen_andi_i64(t1
, t1
, 3);
5787 tcg_gen_shli_i64(t1
, t1
, 4);
5788 tcg_gen_shr_i64(t0
, t0
, t1
);
5789 tcg_gen_ext16u_i64(t0
, t0
);
5793 tcg_gen_add_i64(t0
, t0
, t1
);
5794 tcg_gen_ext32s_i64(t0
, t0
);
5797 tcg_gen_sub_i64(t0
, t0
, t1
);
5798 tcg_gen_ext32s_i64(t0
, t0
);
5820 /* Make sure shift count isn't TCG undefined behaviour. */
5821 tcg_gen_andi_i64(t1
, t1
, shift_max
- 1);
5826 tcg_gen_shl_i64(t0
, t0
, t1
);
5831 * Since SRA is UndefinedResult without sign-extended inputs,
5832 * we can treat SRA and DSRA the same.
5834 tcg_gen_sar_i64(t0
, t0
, t1
);
5837 /* We want to shift in zeros for SRL; zero-extend first. */
5838 tcg_gen_ext32u_i64(t0
, t0
);
5841 tcg_gen_shr_i64(t0
, t0
, t1
);
5845 if (shift_max
== 32) {
5846 tcg_gen_ext32s_i64(t0
, t0
);
5849 /* Shifts larger than MAX produce zero. */
5850 tcg_gen_setcondi_i64(TCG_COND_LTU
, t1
, t1
, shift_max
);
5851 tcg_gen_neg_i64(t1
, t1
);
5852 tcg_gen_and_i64(t0
, t0
, t1
);
5858 TCGv_i64 t2
= tcg_temp_new_i64();
5859 TCGLabel
*lab
= gen_new_label();
5861 tcg_gen_mov_i64(t2
, t0
);
5862 tcg_gen_add_i64(t0
, t1
, t2
);
5863 if (opc
== OPC_ADD_CP2
) {
5864 tcg_gen_ext32s_i64(t0
, t0
);
5866 tcg_gen_xor_i64(t1
, t1
, t2
);
5867 tcg_gen_xor_i64(t2
, t2
, t0
);
5868 tcg_gen_andc_i64(t1
, t2
, t1
);
5869 tcg_temp_free_i64(t2
);
5870 tcg_gen_brcondi_i64(TCG_COND_GE
, t1
, 0, lab
);
5871 generate_exception(ctx
, EXCP_OVERFLOW
);
5879 TCGv_i64 t2
= tcg_temp_new_i64();
5880 TCGLabel
*lab
= gen_new_label();
5882 tcg_gen_mov_i64(t2
, t0
);
5883 tcg_gen_sub_i64(t0
, t1
, t2
);
5884 if (opc
== OPC_SUB_CP2
) {
5885 tcg_gen_ext32s_i64(t0
, t0
);
5887 tcg_gen_xor_i64(t1
, t1
, t2
);
5888 tcg_gen_xor_i64(t2
, t2
, t0
);
5889 tcg_gen_and_i64(t1
, t1
, t2
);
5890 tcg_temp_free_i64(t2
);
5891 tcg_gen_brcondi_i64(TCG_COND_GE
, t1
, 0, lab
);
5892 generate_exception(ctx
, EXCP_OVERFLOW
);
5898 tcg_gen_ext32u_i64(t0
, t0
);
5899 tcg_gen_ext32u_i64(t1
, t1
);
5900 tcg_gen_mul_i64(t0
, t0
, t1
);
5909 cond
= TCG_COND_LTU
;
5917 cond
= TCG_COND_LEU
;
5924 int cc
= (ctx
->opcode
>> 8) & 0x7;
5925 TCGv_i64 t64
= tcg_temp_new_i64();
5926 TCGv_i32 t32
= tcg_temp_new_i32();
5928 tcg_gen_setcond_i64(cond
, t64
, t0
, t1
);
5929 tcg_gen_extrl_i64_i32(t32
, t64
);
5930 tcg_gen_deposit_i32(fpu_fcr31
, fpu_fcr31
, t32
,
5933 tcg_temp_free_i32(t32
);
5934 tcg_temp_free_i64(t64
);
5939 MIPS_INVAL("loongson_cp2");
5940 generate_exception_end(ctx
, EXCP_RI
);
5944 gen_store_fpr64(ctx
, t0
, rd
);
5947 tcg_temp_free_i64(t0
);
5948 tcg_temp_free_i64(t1
);
5951 static void gen_loongson_lswc2(DisasContext
*ctx
, int rt
,
5956 #if defined(TARGET_MIPS64)
5957 int lsq_rt1
= ctx
->opcode
& 0x1f;
5958 int lsq_offset
= sextract32(ctx
->opcode
, 6, 9) << 4;
5960 int shf_offset
= sextract32(ctx
->opcode
, 6, 8);
5962 t0
= tcg_temp_new();
5964 switch (MASK_LOONGSON_GSLSQ(ctx
->opcode
)) {
5965 #if defined(TARGET_MIPS64)
5967 t1
= tcg_temp_new();
5968 gen_base_offset_addr(ctx
, t0
, rs
, lsq_offset
);
5969 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
|
5970 ctx
->default_tcg_memop_mask
);
5971 gen_base_offset_addr(ctx
, t0
, rs
, lsq_offset
+ 8);
5972 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
|
5973 ctx
->default_tcg_memop_mask
);
5974 gen_store_gpr(t1
, rt
);
5975 gen_store_gpr(t0
, lsq_rt1
);
5979 check_cp1_enabled(ctx
);
5980 t1
= tcg_temp_new();
5981 gen_base_offset_addr(ctx
, t0
, rs
, lsq_offset
);
5982 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
|
5983 ctx
->default_tcg_memop_mask
);
5984 gen_base_offset_addr(ctx
, t0
, rs
, lsq_offset
+ 8);
5985 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
|
5986 ctx
->default_tcg_memop_mask
);
5987 gen_store_fpr64(ctx
, t1
, rt
);
5988 gen_store_fpr64(ctx
, t0
, lsq_rt1
);
5992 t1
= tcg_temp_new();
5993 gen_base_offset_addr(ctx
, t0
, rs
, lsq_offset
);
5994 gen_load_gpr(t1
, rt
);
5995 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
|
5996 ctx
->default_tcg_memop_mask
);
5997 gen_base_offset_addr(ctx
, t0
, rs
, lsq_offset
+ 8);
5998 gen_load_gpr(t1
, lsq_rt1
);
5999 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
|
6000 ctx
->default_tcg_memop_mask
);
6004 check_cp1_enabled(ctx
);
6005 t1
= tcg_temp_new();
6006 gen_base_offset_addr(ctx
, t0
, rs
, lsq_offset
);
6007 gen_load_fpr64(ctx
, t1
, rt
);
6008 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
|
6009 ctx
->default_tcg_memop_mask
);
6010 gen_base_offset_addr(ctx
, t0
, rs
, lsq_offset
+ 8);
6011 gen_load_fpr64(ctx
, t1
, lsq_rt1
);
6012 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
|
6013 ctx
->default_tcg_memop_mask
);
6018 switch (MASK_LOONGSON_GSSHFLS(ctx
->opcode
)) {
6020 check_cp1_enabled(ctx
);
6021 gen_base_offset_addr(ctx
, t0
, rs
, shf_offset
);
6022 t1
= tcg_temp_new();
6023 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
6024 tcg_gen_andi_tl(t1
, t0
, 3);
6025 #ifndef TARGET_WORDS_BIGENDIAN
6026 tcg_gen_xori_tl(t1
, t1
, 3);
6028 tcg_gen_shli_tl(t1
, t1
, 3);
6029 tcg_gen_andi_tl(t0
, t0
, ~3);
6030 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEUL
);
6031 tcg_gen_shl_tl(t0
, t0
, t1
);
6032 t2
= tcg_const_tl(-1);
6033 tcg_gen_shl_tl(t2
, t2
, t1
);
6034 fp0
= tcg_temp_new_i32();
6035 gen_load_fpr32(ctx
, fp0
, rt
);
6036 tcg_gen_ext_i32_tl(t1
, fp0
);
6037 tcg_gen_andc_tl(t1
, t1
, t2
);
6039 tcg_gen_or_tl(t0
, t0
, t1
);
6041 #if defined(TARGET_MIPS64)
6042 tcg_gen_extrl_i64_i32(fp0
, t0
);
6044 tcg_gen_ext32s_tl(fp0
, t0
);
6046 gen_store_fpr32(ctx
, fp0
, rt
);
6047 tcg_temp_free_i32(fp0
);
6050 check_cp1_enabled(ctx
);
6051 gen_base_offset_addr(ctx
, t0
, rs
, shf_offset
);
6052 t1
= tcg_temp_new();
6053 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
6054 tcg_gen_andi_tl(t1
, t0
, 3);
6055 #ifdef TARGET_WORDS_BIGENDIAN
6056 tcg_gen_xori_tl(t1
, t1
, 3);
6058 tcg_gen_shli_tl(t1
, t1
, 3);
6059 tcg_gen_andi_tl(t0
, t0
, ~3);
6060 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEUL
);
6061 tcg_gen_shr_tl(t0
, t0
, t1
);
6062 tcg_gen_xori_tl(t1
, t1
, 31);
6063 t2
= tcg_const_tl(0xfffffffeull
);
6064 tcg_gen_shl_tl(t2
, t2
, t1
);
6065 fp0
= tcg_temp_new_i32();
6066 gen_load_fpr32(ctx
, fp0
, rt
);
6067 tcg_gen_ext_i32_tl(t1
, fp0
);
6068 tcg_gen_and_tl(t1
, t1
, t2
);
6070 tcg_gen_or_tl(t0
, t0
, t1
);
6072 #if defined(TARGET_MIPS64)
6073 tcg_gen_extrl_i64_i32(fp0
, t0
);
6075 tcg_gen_ext32s_tl(fp0
, t0
);
6077 gen_store_fpr32(ctx
, fp0
, rt
);
6078 tcg_temp_free_i32(fp0
);
6080 #if defined(TARGET_MIPS64)
6082 check_cp1_enabled(ctx
);
6083 gen_base_offset_addr(ctx
, t0
, rs
, shf_offset
);
6084 t1
= tcg_temp_new();
6085 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
6086 tcg_gen_andi_tl(t1
, t0
, 7);
6087 #ifndef TARGET_WORDS_BIGENDIAN
6088 tcg_gen_xori_tl(t1
, t1
, 7);
6090 tcg_gen_shli_tl(t1
, t1
, 3);
6091 tcg_gen_andi_tl(t0
, t0
, ~7);
6092 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
);
6093 tcg_gen_shl_tl(t0
, t0
, t1
);
6094 t2
= tcg_const_tl(-1);
6095 tcg_gen_shl_tl(t2
, t2
, t1
);
6096 gen_load_fpr64(ctx
, t1
, rt
);
6097 tcg_gen_andc_tl(t1
, t1
, t2
);
6099 tcg_gen_or_tl(t0
, t0
, t1
);
6101 gen_store_fpr64(ctx
, t0
, rt
);
6104 check_cp1_enabled(ctx
);
6105 gen_base_offset_addr(ctx
, t0
, rs
, shf_offset
);
6106 t1
= tcg_temp_new();
6107 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
6108 tcg_gen_andi_tl(t1
, t0
, 7);
6109 #ifdef TARGET_WORDS_BIGENDIAN
6110 tcg_gen_xori_tl(t1
, t1
, 7);
6112 tcg_gen_shli_tl(t1
, t1
, 3);
6113 tcg_gen_andi_tl(t0
, t0
, ~7);
6114 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
);
6115 tcg_gen_shr_tl(t0
, t0
, t1
);
6116 tcg_gen_xori_tl(t1
, t1
, 63);
6117 t2
= tcg_const_tl(0xfffffffffffffffeull
);
6118 tcg_gen_shl_tl(t2
, t2
, t1
);
6119 gen_load_fpr64(ctx
, t1
, rt
);
6120 tcg_gen_and_tl(t1
, t1
, t2
);
6122 tcg_gen_or_tl(t0
, t0
, t1
);
6124 gen_store_fpr64(ctx
, t0
, rt
);
6128 MIPS_INVAL("loongson_gsshfl");
6129 generate_exception_end(ctx
, EXCP_RI
);
6134 switch (MASK_LOONGSON_GSSHFLS(ctx
->opcode
)) {
6136 check_cp1_enabled(ctx
);
6137 t1
= tcg_temp_new();
6138 gen_base_offset_addr(ctx
, t0
, rs
, shf_offset
);
6139 fp0
= tcg_temp_new_i32();
6140 gen_load_fpr32(ctx
, fp0
, rt
);
6141 tcg_gen_ext_i32_tl(t1
, fp0
);
6142 gen_helper_0e2i(swl
, t1
, t0
, ctx
->mem_idx
);
6143 tcg_temp_free_i32(fp0
);
6147 check_cp1_enabled(ctx
);
6148 t1
= tcg_temp_new();
6149 gen_base_offset_addr(ctx
, t0
, rs
, shf_offset
);
6150 fp0
= tcg_temp_new_i32();
6151 gen_load_fpr32(ctx
, fp0
, rt
);
6152 tcg_gen_ext_i32_tl(t1
, fp0
);
6153 gen_helper_0e2i(swr
, t1
, t0
, ctx
->mem_idx
);
6154 tcg_temp_free_i32(fp0
);
6157 #if defined(TARGET_MIPS64)
6159 check_cp1_enabled(ctx
);
6160 t1
= tcg_temp_new();
6161 gen_base_offset_addr(ctx
, t0
, rs
, shf_offset
);
6162 gen_load_fpr64(ctx
, t1
, rt
);
6163 gen_helper_0e2i(sdl
, t1
, t0
, ctx
->mem_idx
);
6167 check_cp1_enabled(ctx
);
6168 t1
= tcg_temp_new();
6169 gen_base_offset_addr(ctx
, t0
, rs
, shf_offset
);
6170 gen_load_fpr64(ctx
, t1
, rt
);
6171 gen_helper_0e2i(sdr
, t1
, t0
, ctx
->mem_idx
);
6176 MIPS_INVAL("loongson_gsshfs");
6177 generate_exception_end(ctx
, EXCP_RI
);
6182 MIPS_INVAL("loongson_gslsq");
6183 generate_exception_end(ctx
, EXCP_RI
);
6189 /* Loongson EXT LDC2/SDC2 */
6190 static void gen_loongson_lsdc2(DisasContext
*ctx
, int rt
,
6193 int offset
= sextract32(ctx
->opcode
, 3, 8);
6194 uint32_t opc
= MASK_LOONGSON_LSDC2(ctx
->opcode
);
6198 /* Pre-conditions */
6204 /* prefetch, implement as NOP */
6215 #if defined(TARGET_MIPS64)
6218 check_cp1_enabled(ctx
);
6219 /* prefetch, implement as NOP */
6225 #if defined(TARGET_MIPS64)
6228 check_cp1_enabled(ctx
);
6231 MIPS_INVAL("loongson_lsdc2");
6232 generate_exception_end(ctx
, EXCP_RI
);
6237 t0
= tcg_temp_new();
6239 gen_base_offset_addr(ctx
, t0
, rs
, offset
);
6240 gen_op_addr_add(ctx
, t0
, cpu_gpr
[rd
], t0
);
6244 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_SB
);
6245 gen_store_gpr(t0
, rt
);
6248 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESW
|
6249 ctx
->default_tcg_memop_mask
);
6250 gen_store_gpr(t0
, rt
);
6253 gen_base_offset_addr(ctx
, t0
, rs
, offset
);
6255 gen_op_addr_add(ctx
, t0
, cpu_gpr
[rd
], t0
);
6257 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESL
|
6258 ctx
->default_tcg_memop_mask
);
6259 gen_store_gpr(t0
, rt
);
6261 #if defined(TARGET_MIPS64)
6263 gen_base_offset_addr(ctx
, t0
, rs
, offset
);
6265 gen_op_addr_add(ctx
, t0
, cpu_gpr
[rd
], t0
);
6267 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
|
6268 ctx
->default_tcg_memop_mask
);
6269 gen_store_gpr(t0
, rt
);
6273 check_cp1_enabled(ctx
);
6274 gen_base_offset_addr(ctx
, t0
, rs
, offset
);
6276 gen_op_addr_add(ctx
, t0
, cpu_gpr
[rd
], t0
);
6278 fp0
= tcg_temp_new_i32();
6279 tcg_gen_qemu_ld_i32(fp0
, t0
, ctx
->mem_idx
, MO_TESL
|
6280 ctx
->default_tcg_memop_mask
);
6281 gen_store_fpr32(ctx
, fp0
, rt
);
6282 tcg_temp_free_i32(fp0
);
6284 #if defined(TARGET_MIPS64)
6286 check_cp1_enabled(ctx
);
6287 gen_base_offset_addr(ctx
, t0
, rs
, offset
);
6289 gen_op_addr_add(ctx
, t0
, cpu_gpr
[rd
], t0
);
6291 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
|
6292 ctx
->default_tcg_memop_mask
);
6293 gen_store_fpr64(ctx
, t0
, rt
);
6297 t1
= tcg_temp_new();
6298 gen_load_gpr(t1
, rt
);
6299 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_SB
);
6303 t1
= tcg_temp_new();
6304 gen_load_gpr(t1
, rt
);
6305 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUW
|
6306 ctx
->default_tcg_memop_mask
);
6310 t1
= tcg_temp_new();
6311 gen_load_gpr(t1
, rt
);
6312 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
|
6313 ctx
->default_tcg_memop_mask
);
6316 #if defined(TARGET_MIPS64)
6318 t1
= tcg_temp_new();
6319 gen_load_gpr(t1
, rt
);
6320 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
|
6321 ctx
->default_tcg_memop_mask
);
6326 fp0
= tcg_temp_new_i32();
6327 gen_load_fpr32(ctx
, fp0
, rt
);
6328 tcg_gen_qemu_st_i32(fp0
, t0
, ctx
->mem_idx
, MO_TEUL
|
6329 ctx
->default_tcg_memop_mask
);
6330 tcg_temp_free_i32(fp0
);
6332 #if defined(TARGET_MIPS64)
6334 t1
= tcg_temp_new();
6335 gen_load_fpr64(ctx
, t1
, rt
);
6336 tcg_gen_qemu_st_i64(t1
, t0
, ctx
->mem_idx
, MO_TEQ
|
6337 ctx
->default_tcg_memop_mask
);
6349 static void gen_trap(DisasContext
*ctx
, uint32_t opc
,
6350 int rs
, int rt
, int16_t imm
)
6353 TCGv t0
= tcg_temp_new();
6354 TCGv t1
= tcg_temp_new();
6357 /* Load needed operands */
6365 /* Compare two registers */
6367 gen_load_gpr(t0
, rs
);
6368 gen_load_gpr(t1
, rt
);
6378 /* Compare register to immediate */
6379 if (rs
!= 0 || imm
!= 0) {
6380 gen_load_gpr(t0
, rs
);
6381 tcg_gen_movi_tl(t1
, (int32_t)imm
);
6388 case OPC_TEQ
: /* rs == rs */
6389 case OPC_TEQI
: /* r0 == 0 */
6390 case OPC_TGE
: /* rs >= rs */
6391 case OPC_TGEI
: /* r0 >= 0 */
6392 case OPC_TGEU
: /* rs >= rs unsigned */
6393 case OPC_TGEIU
: /* r0 >= 0 unsigned */
6395 generate_exception_end(ctx
, EXCP_TRAP
);
6397 case OPC_TLT
: /* rs < rs */
6398 case OPC_TLTI
: /* r0 < 0 */
6399 case OPC_TLTU
: /* rs < rs unsigned */
6400 case OPC_TLTIU
: /* r0 < 0 unsigned */
6401 case OPC_TNE
: /* rs != rs */
6402 case OPC_TNEI
: /* r0 != 0 */
6403 /* Never trap: treat as NOP. */
6407 TCGLabel
*l1
= gen_new_label();
6412 tcg_gen_brcond_tl(TCG_COND_NE
, t0
, t1
, l1
);
6416 tcg_gen_brcond_tl(TCG_COND_LT
, t0
, t1
, l1
);
6420 tcg_gen_brcond_tl(TCG_COND_LTU
, t0
, t1
, l1
);
6424 tcg_gen_brcond_tl(TCG_COND_GE
, t0
, t1
, l1
);
6428 tcg_gen_brcond_tl(TCG_COND_GEU
, t0
, t1
, l1
);
6432 tcg_gen_brcond_tl(TCG_COND_EQ
, t0
, t1
, l1
);
6435 generate_exception(ctx
, EXCP_TRAP
);
6442 static inline bool use_goto_tb(DisasContext
*ctx
, target_ulong dest
)
6444 if (unlikely(ctx
->base
.singlestep_enabled
)) {
6448 #ifndef CONFIG_USER_ONLY
6449 return (ctx
->base
.tb
->pc
& TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
);
6455 static inline void gen_goto_tb(DisasContext
*ctx
, int n
, target_ulong dest
)
6457 if (use_goto_tb(ctx
, dest
)) {
6460 tcg_gen_exit_tb(ctx
->base
.tb
, n
);
6463 if (ctx
->base
.singlestep_enabled
) {
6464 save_cpu_state(ctx
, 0);
6465 gen_helper_raise_exception_debug(cpu_env
);
6467 tcg_gen_lookup_and_goto_ptr();
6471 /* Branches (before delay slot) */
6472 static void gen_compute_branch(DisasContext
*ctx
, uint32_t opc
,
6474 int rs
, int rt
, int32_t offset
,
6477 target_ulong btgt
= -1;
6479 int bcond_compute
= 0;
6480 TCGv t0
= tcg_temp_new();
6481 TCGv t1
= tcg_temp_new();
6483 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
6484 #ifdef MIPS_DEBUG_DISAS
6485 LOG_DISAS("Branch in delay / forbidden slot at PC 0x"
6486 TARGET_FMT_lx
"\n", ctx
->base
.pc_next
);
6488 generate_exception_end(ctx
, EXCP_RI
);
6492 /* Load needed operands */
6498 /* Compare two registers */
6500 gen_load_gpr(t0
, rs
);
6501 gen_load_gpr(t1
, rt
);
6504 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ offset
;
6518 /* Compare to zero */
6520 gen_load_gpr(t0
, rs
);
6523 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ offset
;
6526 #if defined(TARGET_MIPS64)
6528 tcg_gen_andi_tl(t0
, cpu_dspctrl
, 0x7F);
6530 tcg_gen_andi_tl(t0
, cpu_dspctrl
, 0x3F);
6533 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ offset
;
6538 /* Jump to immediate */
6539 btgt
= ((ctx
->base
.pc_next
+ insn_bytes
) & (int32_t)0xF0000000) |
6544 /* Jump to register */
6545 if (offset
!= 0 && offset
!= 16) {
6547 * Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
6548 * others are reserved.
6550 MIPS_INVAL("jump hint");
6551 generate_exception_end(ctx
, EXCP_RI
);
6554 gen_load_gpr(btarget
, rs
);
6557 MIPS_INVAL("branch/jump");
6558 generate_exception_end(ctx
, EXCP_RI
);
6561 if (bcond_compute
== 0) {
6562 /* No condition to be computed */
6564 case OPC_BEQ
: /* rx == rx */
6565 case OPC_BEQL
: /* rx == rx likely */
6566 case OPC_BGEZ
: /* 0 >= 0 */
6567 case OPC_BGEZL
: /* 0 >= 0 likely */
6568 case OPC_BLEZ
: /* 0 <= 0 */
6569 case OPC_BLEZL
: /* 0 <= 0 likely */
6571 ctx
->hflags
|= MIPS_HFLAG_B
;
6573 case OPC_BGEZAL
: /* 0 >= 0 */
6574 case OPC_BGEZALL
: /* 0 >= 0 likely */
6575 /* Always take and link */
6577 ctx
->hflags
|= MIPS_HFLAG_B
;
6579 case OPC_BNE
: /* rx != rx */
6580 case OPC_BGTZ
: /* 0 > 0 */
6581 case OPC_BLTZ
: /* 0 < 0 */
6584 case OPC_BLTZAL
: /* 0 < 0 */
6586 * Handle as an unconditional branch to get correct delay
6590 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ delayslot_size
;
6591 ctx
->hflags
|= MIPS_HFLAG_B
;
6593 case OPC_BLTZALL
: /* 0 < 0 likely */
6594 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 8);
6595 /* Skip the instruction in the delay slot */
6596 ctx
->base
.pc_next
+= 4;
6598 case OPC_BNEL
: /* rx != rx likely */
6599 case OPC_BGTZL
: /* 0 > 0 likely */
6600 case OPC_BLTZL
: /* 0 < 0 likely */
6601 /* Skip the instruction in the delay slot */
6602 ctx
->base
.pc_next
+= 4;
6605 ctx
->hflags
|= MIPS_HFLAG_B
;
6608 ctx
->hflags
|= MIPS_HFLAG_BX
;
6612 ctx
->hflags
|= MIPS_HFLAG_B
;
6615 ctx
->hflags
|= MIPS_HFLAG_BR
;
6619 ctx
->hflags
|= MIPS_HFLAG_BR
;
6622 MIPS_INVAL("branch/jump");
6623 generate_exception_end(ctx
, EXCP_RI
);
6629 tcg_gen_setcond_tl(TCG_COND_EQ
, bcond
, t0
, t1
);
6632 tcg_gen_setcond_tl(TCG_COND_EQ
, bcond
, t0
, t1
);
6635 tcg_gen_setcond_tl(TCG_COND_NE
, bcond
, t0
, t1
);
6638 tcg_gen_setcond_tl(TCG_COND_NE
, bcond
, t0
, t1
);
6641 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
6644 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
6647 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_GT
, bcond
, t0
, 0);
6658 tcg_gen_setcondi_tl(TCG_COND_GT
, bcond
, t0
, 0);
6661 tcg_gen_setcondi_tl(TCG_COND_LE
, bcond
, t0
, 0);
6664 tcg_gen_setcondi_tl(TCG_COND_LE
, bcond
, t0
, 0);
6667 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
6670 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
6673 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 32);
6675 #if defined(TARGET_MIPS64)
6677 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 64);
6681 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
6684 ctx
->hflags
|= MIPS_HFLAG_BC
;
6687 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
6690 ctx
->hflags
|= MIPS_HFLAG_BL
;
6693 MIPS_INVAL("conditional branch/jump");
6694 generate_exception_end(ctx
, EXCP_RI
);
6699 ctx
->btarget
= btgt
;
6701 switch (delayslot_size
) {
6703 ctx
->hflags
|= MIPS_HFLAG_BDS16
;
6706 ctx
->hflags
|= MIPS_HFLAG_BDS32
;
6711 int post_delay
= insn_bytes
+ delayslot_size
;
6712 int lowbit
= !!(ctx
->hflags
& MIPS_HFLAG_M16
);
6714 tcg_gen_movi_tl(cpu_gpr
[blink
],
6715 ctx
->base
.pc_next
+ post_delay
+ lowbit
);
6719 if (insn_bytes
== 2) {
6720 ctx
->hflags
|= MIPS_HFLAG_B16
;
6727 /* nanoMIPS Branches */
6728 static void gen_compute_branch_nm(DisasContext
*ctx
, uint32_t opc
,
6730 int rs
, int rt
, int32_t offset
)
6732 target_ulong btgt
= -1;
6733 int bcond_compute
= 0;
6734 TCGv t0
= tcg_temp_new();
6735 TCGv t1
= tcg_temp_new();
6737 /* Load needed operands */
6741 /* Compare two registers */
6743 gen_load_gpr(t0
, rs
);
6744 gen_load_gpr(t1
, rt
);
6747 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ offset
;
6750 /* Compare to zero */
6752 gen_load_gpr(t0
, rs
);
6755 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ offset
;
6758 tcg_gen_andi_tl(t0
, cpu_dspctrl
, 0x3F);
6760 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ offset
;
6764 /* Jump to register */
6765 if (offset
!= 0 && offset
!= 16) {
6767 * Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
6768 * others are reserved.
6770 MIPS_INVAL("jump hint");
6771 generate_exception_end(ctx
, EXCP_RI
);
6774 gen_load_gpr(btarget
, rs
);
6777 MIPS_INVAL("branch/jump");
6778 generate_exception_end(ctx
, EXCP_RI
);
6781 if (bcond_compute
== 0) {
6782 /* No condition to be computed */
6784 case OPC_BEQ
: /* rx == rx */
6786 ctx
->hflags
|= MIPS_HFLAG_B
;
6788 case OPC_BGEZAL
: /* 0 >= 0 */
6789 /* Always take and link */
6790 tcg_gen_movi_tl(cpu_gpr
[31],
6791 ctx
->base
.pc_next
+ insn_bytes
);
6792 ctx
->hflags
|= MIPS_HFLAG_B
;
6794 case OPC_BNE
: /* rx != rx */
6795 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 8);
6796 /* Skip the instruction in the delay slot */
6797 ctx
->base
.pc_next
+= 4;
6800 ctx
->hflags
|= MIPS_HFLAG_BR
;
6804 tcg_gen_movi_tl(cpu_gpr
[rt
],
6805 ctx
->base
.pc_next
+ insn_bytes
);
6807 ctx
->hflags
|= MIPS_HFLAG_BR
;
6810 MIPS_INVAL("branch/jump");
6811 generate_exception_end(ctx
, EXCP_RI
);
6817 tcg_gen_setcond_tl(TCG_COND_EQ
, bcond
, t0
, t1
);
6820 tcg_gen_setcond_tl(TCG_COND_NE
, bcond
, t0
, t1
);
6823 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
6824 tcg_gen_movi_tl(cpu_gpr
[31],
6825 ctx
->base
.pc_next
+ insn_bytes
);
6828 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 32);
6830 ctx
->hflags
|= MIPS_HFLAG_BC
;
6833 MIPS_INVAL("conditional branch/jump");
6834 generate_exception_end(ctx
, EXCP_RI
);
6839 ctx
->btarget
= btgt
;
6842 if (insn_bytes
== 2) {
6843 ctx
->hflags
|= MIPS_HFLAG_B16
;
6850 /* special3 bitfield operations */
6851 static void gen_bitops(DisasContext
*ctx
, uint32_t opc
, int rt
,
6852 int rs
, int lsb
, int msb
)
6854 TCGv t0
= tcg_temp_new();
6855 TCGv t1
= tcg_temp_new();
6857 gen_load_gpr(t1
, rs
);
6860 if (lsb
+ msb
> 31) {
6864 tcg_gen_extract_tl(t0
, t1
, lsb
, msb
+ 1);
6867 * The two checks together imply that lsb == 0,
6868 * so this is a simple sign-extension.
6870 tcg_gen_ext32s_tl(t0
, t1
);
6873 #if defined(TARGET_MIPS64)
6882 if (lsb
+ msb
> 63) {
6885 tcg_gen_extract_tl(t0
, t1
, lsb
, msb
+ 1);
6892 gen_load_gpr(t0
, rt
);
6893 tcg_gen_deposit_tl(t0
, t0
, t1
, lsb
, msb
- lsb
+ 1);
6894 tcg_gen_ext32s_tl(t0
, t0
);
6896 #if defined(TARGET_MIPS64)
6907 gen_load_gpr(t0
, rt
);
6908 tcg_gen_deposit_tl(t0
, t0
, t1
, lsb
, msb
- lsb
+ 1);
6913 MIPS_INVAL("bitops");
6914 generate_exception_end(ctx
, EXCP_RI
);
6919 gen_store_gpr(t0
, rt
);
6924 static void gen_bshfl(DisasContext
*ctx
, uint32_t op2
, int rt
, int rd
)
6929 /* If no destination, treat it as a NOP. */
6933 t0
= tcg_temp_new();
6934 gen_load_gpr(t0
, rt
);
6938 TCGv t1
= tcg_temp_new();
6939 TCGv t2
= tcg_const_tl(0x00FF00FF);
6941 tcg_gen_shri_tl(t1
, t0
, 8);
6942 tcg_gen_and_tl(t1
, t1
, t2
);
6943 tcg_gen_and_tl(t0
, t0
, t2
);
6944 tcg_gen_shli_tl(t0
, t0
, 8);
6945 tcg_gen_or_tl(t0
, t0
, t1
);
6948 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
6952 tcg_gen_ext8s_tl(cpu_gpr
[rd
], t0
);
6955 tcg_gen_ext16s_tl(cpu_gpr
[rd
], t0
);
6957 #if defined(TARGET_MIPS64)
6960 TCGv t1
= tcg_temp_new();
6961 TCGv t2
= tcg_const_tl(0x00FF00FF00FF00FFULL
);
6963 tcg_gen_shri_tl(t1
, t0
, 8);
6964 tcg_gen_and_tl(t1
, t1
, t2
);
6965 tcg_gen_and_tl(t0
, t0
, t2
);
6966 tcg_gen_shli_tl(t0
, t0
, 8);
6967 tcg_gen_or_tl(cpu_gpr
[rd
], t0
, t1
);
6974 TCGv t1
= tcg_temp_new();
6975 TCGv t2
= tcg_const_tl(0x0000FFFF0000FFFFULL
);
6977 tcg_gen_shri_tl(t1
, t0
, 16);
6978 tcg_gen_and_tl(t1
, t1
, t2
);
6979 tcg_gen_and_tl(t0
, t0
, t2
);
6980 tcg_gen_shli_tl(t0
, t0
, 16);
6981 tcg_gen_or_tl(t0
, t0
, t1
);
6982 tcg_gen_shri_tl(t1
, t0
, 32);
6983 tcg_gen_shli_tl(t0
, t0
, 32);
6984 tcg_gen_or_tl(cpu_gpr
[rd
], t0
, t1
);
6991 MIPS_INVAL("bsfhl");
6992 generate_exception_end(ctx
, EXCP_RI
);
6999 static void gen_lsa(DisasContext
*ctx
, int opc
, int rd
, int rs
, int rt
,
7008 t0
= tcg_temp_new();
7009 t1
= tcg_temp_new();
7010 gen_load_gpr(t0
, rs
);
7011 gen_load_gpr(t1
, rt
);
7012 tcg_gen_shli_tl(t0
, t0
, imm2
+ 1);
7013 tcg_gen_add_tl(cpu_gpr
[rd
], t0
, t1
);
7014 if (opc
== OPC_LSA
) {
7015 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
7024 static void gen_align_bits(DisasContext
*ctx
, int wordsz
, int rd
, int rs
,
7032 t0
= tcg_temp_new();
7033 if (bits
== 0 || bits
== wordsz
) {
7035 gen_load_gpr(t0
, rt
);
7037 gen_load_gpr(t0
, rs
);
7041 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
7043 #if defined(TARGET_MIPS64)
7045 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
7050 TCGv t1
= tcg_temp_new();
7051 gen_load_gpr(t0
, rt
);
7052 gen_load_gpr(t1
, rs
);
7056 TCGv_i64 t2
= tcg_temp_new_i64();
7057 tcg_gen_concat_tl_i64(t2
, t1
, t0
);
7058 tcg_gen_shri_i64(t2
, t2
, 32 - bits
);
7059 gen_move_low32(cpu_gpr
[rd
], t2
);
7060 tcg_temp_free_i64(t2
);
7063 #if defined(TARGET_MIPS64)
7065 tcg_gen_shli_tl(t0
, t0
, bits
);
7066 tcg_gen_shri_tl(t1
, t1
, 64 - bits
);
7067 tcg_gen_or_tl(cpu_gpr
[rd
], t1
, t0
);
7077 static void gen_align(DisasContext
*ctx
, int wordsz
, int rd
, int rs
, int rt
,
7080 gen_align_bits(ctx
, wordsz
, rd
, rs
, rt
, bp
* 8);
7083 static void gen_ext(DisasContext
*ctx
, int wordsz
, int rd
, int rs
, int rt
,
7086 gen_align_bits(ctx
, wordsz
, rd
, rs
, rt
, wordsz
- shift
);
7089 static void gen_bitswap(DisasContext
*ctx
, int opc
, int rd
, int rt
)
7096 t0
= tcg_temp_new();
7097 gen_load_gpr(t0
, rt
);
7100 gen_helper_bitswap(cpu_gpr
[rd
], t0
);
7102 #if defined(TARGET_MIPS64)
7104 gen_helper_dbitswap(cpu_gpr
[rd
], t0
);
7111 #ifndef CONFIG_USER_ONLY
7112 /* CP0 (MMU and control) */
7113 static inline void gen_mthc0_entrylo(TCGv arg
, target_ulong off
)
7115 TCGv_i64 t0
= tcg_temp_new_i64();
7116 TCGv_i64 t1
= tcg_temp_new_i64();
7118 tcg_gen_ext_tl_i64(t0
, arg
);
7119 tcg_gen_ld_i64(t1
, cpu_env
, off
);
7120 #if defined(TARGET_MIPS64)
7121 tcg_gen_deposit_i64(t1
, t1
, t0
, 30, 32);
7123 tcg_gen_concat32_i64(t1
, t1
, t0
);
7125 tcg_gen_st_i64(t1
, cpu_env
, off
);
7126 tcg_temp_free_i64(t1
);
7127 tcg_temp_free_i64(t0
);
7130 static inline void gen_mthc0_store64(TCGv arg
, target_ulong off
)
7132 TCGv_i64 t0
= tcg_temp_new_i64();
7133 TCGv_i64 t1
= tcg_temp_new_i64();
7135 tcg_gen_ext_tl_i64(t0
, arg
);
7136 tcg_gen_ld_i64(t1
, cpu_env
, off
);
7137 tcg_gen_concat32_i64(t1
, t1
, t0
);
7138 tcg_gen_st_i64(t1
, cpu_env
, off
);
7139 tcg_temp_free_i64(t1
);
7140 tcg_temp_free_i64(t0
);
7143 static inline void gen_mfhc0_entrylo(TCGv arg
, target_ulong off
)
7145 TCGv_i64 t0
= tcg_temp_new_i64();
7147 tcg_gen_ld_i64(t0
, cpu_env
, off
);
7148 #if defined(TARGET_MIPS64)
7149 tcg_gen_shri_i64(t0
, t0
, 30);
7151 tcg_gen_shri_i64(t0
, t0
, 32);
7153 gen_move_low32(arg
, t0
);
7154 tcg_temp_free_i64(t0
);
7157 static inline void gen_mfhc0_load64(TCGv arg
, target_ulong off
, int shift
)
7159 TCGv_i64 t0
= tcg_temp_new_i64();
7161 tcg_gen_ld_i64(t0
, cpu_env
, off
);
7162 tcg_gen_shri_i64(t0
, t0
, 32 + shift
);
7163 gen_move_low32(arg
, t0
);
7164 tcg_temp_free_i64(t0
);
7167 static inline void gen_mfc0_load32(TCGv arg
, target_ulong off
)
7169 TCGv_i32 t0
= tcg_temp_new_i32();
7171 tcg_gen_ld_i32(t0
, cpu_env
, off
);
7172 tcg_gen_ext_i32_tl(arg
, t0
);
7173 tcg_temp_free_i32(t0
);
7176 static inline void gen_mfc0_load64(TCGv arg
, target_ulong off
)
7178 tcg_gen_ld_tl(arg
, cpu_env
, off
);
7179 tcg_gen_ext32s_tl(arg
, arg
);
7182 static inline void gen_mtc0_store32(TCGv arg
, target_ulong off
)
7184 TCGv_i32 t0
= tcg_temp_new_i32();
7186 tcg_gen_trunc_tl_i32(t0
, arg
);
7187 tcg_gen_st_i32(t0
, cpu_env
, off
);
7188 tcg_temp_free_i32(t0
);
7191 #define CP0_CHECK(c) \
7194 goto cp0_unimplemented; \
7198 static void gen_mfhc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
7200 const char *register_name
= "invalid";
7203 case CP0_REGISTER_02
:
7206 CP0_CHECK(ctx
->hflags
& MIPS_HFLAG_ELPA
);
7207 gen_mfhc0_entrylo(arg
, offsetof(CPUMIPSState
, CP0_EntryLo0
));
7208 register_name
= "EntryLo0";
7211 goto cp0_unimplemented
;
7214 case CP0_REGISTER_03
:
7216 case CP0_REG03__ENTRYLO1
:
7217 CP0_CHECK(ctx
->hflags
& MIPS_HFLAG_ELPA
);
7218 gen_mfhc0_entrylo(arg
, offsetof(CPUMIPSState
, CP0_EntryLo1
));
7219 register_name
= "EntryLo1";
7222 goto cp0_unimplemented
;
7225 case CP0_REGISTER_09
:
7227 case CP0_REG09__SAAR
:
7228 CP0_CHECK(ctx
->saar
);
7229 gen_helper_mfhc0_saar(arg
, cpu_env
);
7230 register_name
= "SAAR";
7233 goto cp0_unimplemented
;
7236 case CP0_REGISTER_17
:
7238 case CP0_REG17__LLADDR
:
7239 gen_mfhc0_load64(arg
, offsetof(CPUMIPSState
, CP0_LLAddr
),
7240 ctx
->CP0_LLAddr_shift
);
7241 register_name
= "LLAddr";
7243 case CP0_REG17__MAAR
:
7244 CP0_CHECK(ctx
->mrp
);
7245 gen_helper_mfhc0_maar(arg
, cpu_env
);
7246 register_name
= "MAAR";
7249 goto cp0_unimplemented
;
7252 case CP0_REGISTER_19
:
7254 case CP0_REG19__WATCHHI0
:
7255 case CP0_REG19__WATCHHI1
:
7256 case CP0_REG19__WATCHHI2
:
7257 case CP0_REG19__WATCHHI3
:
7258 case CP0_REG19__WATCHHI4
:
7259 case CP0_REG19__WATCHHI5
:
7260 case CP0_REG19__WATCHHI6
:
7261 case CP0_REG19__WATCHHI7
:
7262 /* upper 32 bits are only available when Config5MI != 0 */
7264 gen_mfhc0_load64(arg
, offsetof(CPUMIPSState
, CP0_WatchHi
[sel
]), 0);
7265 register_name
= "WatchHi";
7268 goto cp0_unimplemented
;
7271 case CP0_REGISTER_28
:
7277 gen_mfhc0_load64(arg
, offsetof(CPUMIPSState
, CP0_TagLo
), 0);
7278 register_name
= "TagLo";
7281 goto cp0_unimplemented
;
7285 goto cp0_unimplemented
;
7287 trace_mips_translate_c0("mfhc0", register_name
, reg
, sel
);
7291 qemu_log_mask(LOG_UNIMP
, "mfhc0 %s (reg %d sel %d)\n",
7292 register_name
, reg
, sel
);
7293 tcg_gen_movi_tl(arg
, 0);
7296 static void gen_mthc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
7298 const char *register_name
= "invalid";
7299 uint64_t mask
= ctx
->PAMask
>> 36;
7302 case CP0_REGISTER_02
:
7305 CP0_CHECK(ctx
->hflags
& MIPS_HFLAG_ELPA
);
7306 tcg_gen_andi_tl(arg
, arg
, mask
);
7307 gen_mthc0_entrylo(arg
, offsetof(CPUMIPSState
, CP0_EntryLo0
));
7308 register_name
= "EntryLo0";
7311 goto cp0_unimplemented
;
7314 case CP0_REGISTER_03
:
7316 case CP0_REG03__ENTRYLO1
:
7317 CP0_CHECK(ctx
->hflags
& MIPS_HFLAG_ELPA
);
7318 tcg_gen_andi_tl(arg
, arg
, mask
);
7319 gen_mthc0_entrylo(arg
, offsetof(CPUMIPSState
, CP0_EntryLo1
));
7320 register_name
= "EntryLo1";
7323 goto cp0_unimplemented
;
7326 case CP0_REGISTER_09
:
7328 case CP0_REG09__SAAR
:
7329 CP0_CHECK(ctx
->saar
);
7330 gen_helper_mthc0_saar(cpu_env
, arg
);
7331 register_name
= "SAAR";
7334 goto cp0_unimplemented
;
7337 case CP0_REGISTER_17
:
7339 case CP0_REG17__LLADDR
:
7341 * LLAddr is read-only (the only exception is bit 0 if LLB is
7342 * supported); the CP0_LLAddr_rw_bitmask does not seem to be
7343 * relevant for modern MIPS cores supporting MTHC0, therefore
7344 * treating MTHC0 to LLAddr as NOP.
7346 register_name
= "LLAddr";
7348 case CP0_REG17__MAAR
:
7349 CP0_CHECK(ctx
->mrp
);
7350 gen_helper_mthc0_maar(cpu_env
, arg
);
7351 register_name
= "MAAR";
7354 goto cp0_unimplemented
;
7357 case CP0_REGISTER_19
:
7359 case CP0_REG19__WATCHHI0
:
7360 case CP0_REG19__WATCHHI1
:
7361 case CP0_REG19__WATCHHI2
:
7362 case CP0_REG19__WATCHHI3
:
7363 case CP0_REG19__WATCHHI4
:
7364 case CP0_REG19__WATCHHI5
:
7365 case CP0_REG19__WATCHHI6
:
7366 case CP0_REG19__WATCHHI7
:
7367 /* upper 32 bits are only available when Config5MI != 0 */
7369 gen_helper_0e1i(mthc0_watchhi
, arg
, sel
);
7370 register_name
= "WatchHi";
7373 goto cp0_unimplemented
;
7376 case CP0_REGISTER_28
:
7382 tcg_gen_andi_tl(arg
, arg
, mask
);
7383 gen_mthc0_store64(arg
, offsetof(CPUMIPSState
, CP0_TagLo
));
7384 register_name
= "TagLo";
7387 goto cp0_unimplemented
;
7391 goto cp0_unimplemented
;
7393 trace_mips_translate_c0("mthc0", register_name
, reg
, sel
);
7396 qemu_log_mask(LOG_UNIMP
, "mthc0 %s (reg %d sel %d)\n",
7397 register_name
, reg
, sel
);
7400 static inline void gen_mfc0_unimplemented(DisasContext
*ctx
, TCGv arg
)
7402 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
7403 tcg_gen_movi_tl(arg
, 0);
7405 tcg_gen_movi_tl(arg
, ~0);
7409 static void gen_mfc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
7411 const char *register_name
= "invalid";
7414 check_insn(ctx
, ISA_MIPS32
);
7418 case CP0_REGISTER_00
:
7420 case CP0_REG00__INDEX
:
7421 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Index
));
7422 register_name
= "Index";
7424 case CP0_REG00__MVPCONTROL
:
7425 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7426 gen_helper_mfc0_mvpcontrol(arg
, cpu_env
);
7427 register_name
= "MVPControl";
7429 case CP0_REG00__MVPCONF0
:
7430 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7431 gen_helper_mfc0_mvpconf0(arg
, cpu_env
);
7432 register_name
= "MVPConf0";
7434 case CP0_REG00__MVPCONF1
:
7435 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7436 gen_helper_mfc0_mvpconf1(arg
, cpu_env
);
7437 register_name
= "MVPConf1";
7439 case CP0_REG00__VPCONTROL
:
7441 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPControl
));
7442 register_name
= "VPControl";
7445 goto cp0_unimplemented
;
7448 case CP0_REGISTER_01
:
7450 case CP0_REG01__RANDOM
:
7451 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS32R6
));
7452 gen_helper_mfc0_random(arg
, cpu_env
);
7453 register_name
= "Random";
7455 case CP0_REG01__VPECONTROL
:
7456 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7457 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEControl
));
7458 register_name
= "VPEControl";
7460 case CP0_REG01__VPECONF0
:
7461 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7462 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf0
));
7463 register_name
= "VPEConf0";
7465 case CP0_REG01__VPECONF1
:
7466 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7467 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf1
));
7468 register_name
= "VPEConf1";
7470 case CP0_REG01__YQMASK
:
7471 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7472 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_YQMask
));
7473 register_name
= "YQMask";
7475 case CP0_REG01__VPESCHEDULE
:
7476 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7477 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_VPESchedule
));
7478 register_name
= "VPESchedule";
7480 case CP0_REG01__VPESCHEFBACK
:
7481 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7482 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
7483 register_name
= "VPEScheFBack";
7485 case CP0_REG01__VPEOPT
:
7486 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7487 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEOpt
));
7488 register_name
= "VPEOpt";
7491 goto cp0_unimplemented
;
7494 case CP0_REGISTER_02
:
7496 case CP0_REG02__ENTRYLO0
:
7498 TCGv_i64 tmp
= tcg_temp_new_i64();
7499 tcg_gen_ld_i64(tmp
, cpu_env
,
7500 offsetof(CPUMIPSState
, CP0_EntryLo0
));
7501 #if defined(TARGET_MIPS64)
7503 /* Move RI/XI fields to bits 31:30 */
7504 tcg_gen_shri_tl(arg
, tmp
, CP0EnLo_XI
);
7505 tcg_gen_deposit_tl(tmp
, tmp
, arg
, 30, 2);
7508 gen_move_low32(arg
, tmp
);
7509 tcg_temp_free_i64(tmp
);
7511 register_name
= "EntryLo0";
7513 case CP0_REG02__TCSTATUS
:
7514 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7515 gen_helper_mfc0_tcstatus(arg
, cpu_env
);
7516 register_name
= "TCStatus";
7518 case CP0_REG02__TCBIND
:
7519 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7520 gen_helper_mfc0_tcbind(arg
, cpu_env
);
7521 register_name
= "TCBind";
7523 case CP0_REG02__TCRESTART
:
7524 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7525 gen_helper_mfc0_tcrestart(arg
, cpu_env
);
7526 register_name
= "TCRestart";
7528 case CP0_REG02__TCHALT
:
7529 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7530 gen_helper_mfc0_tchalt(arg
, cpu_env
);
7531 register_name
= "TCHalt";
7533 case CP0_REG02__TCCONTEXT
:
7534 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7535 gen_helper_mfc0_tccontext(arg
, cpu_env
);
7536 register_name
= "TCContext";
7538 case CP0_REG02__TCSCHEDULE
:
7539 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7540 gen_helper_mfc0_tcschedule(arg
, cpu_env
);
7541 register_name
= "TCSchedule";
7543 case CP0_REG02__TCSCHEFBACK
:
7544 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7545 gen_helper_mfc0_tcschefback(arg
, cpu_env
);
7546 register_name
= "TCScheFBack";
7549 goto cp0_unimplemented
;
7552 case CP0_REGISTER_03
:
7554 case CP0_REG03__ENTRYLO1
:
7556 TCGv_i64 tmp
= tcg_temp_new_i64();
7557 tcg_gen_ld_i64(tmp
, cpu_env
,
7558 offsetof(CPUMIPSState
, CP0_EntryLo1
));
7559 #if defined(TARGET_MIPS64)
7561 /* Move RI/XI fields to bits 31:30 */
7562 tcg_gen_shri_tl(arg
, tmp
, CP0EnLo_XI
);
7563 tcg_gen_deposit_tl(tmp
, tmp
, arg
, 30, 2);
7566 gen_move_low32(arg
, tmp
);
7567 tcg_temp_free_i64(tmp
);
7569 register_name
= "EntryLo1";
7571 case CP0_REG03__GLOBALNUM
:
7573 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_GlobalNumber
));
7574 register_name
= "GlobalNumber";
7577 goto cp0_unimplemented
;
7580 case CP0_REGISTER_04
:
7582 case CP0_REG04__CONTEXT
:
7583 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_Context
));
7584 tcg_gen_ext32s_tl(arg
, arg
);
7585 register_name
= "Context";
7587 case CP0_REG04__CONTEXTCONFIG
:
7589 /* gen_helper_mfc0_contextconfig(arg); */
7590 register_name
= "ContextConfig";
7591 goto cp0_unimplemented
;
7592 case CP0_REG04__USERLOCAL
:
7593 CP0_CHECK(ctx
->ulri
);
7594 tcg_gen_ld_tl(arg
, cpu_env
,
7595 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
7596 tcg_gen_ext32s_tl(arg
, arg
);
7597 register_name
= "UserLocal";
7599 case CP0_REG04__MMID
:
7601 gen_helper_mtc0_memorymapid(cpu_env
, arg
);
7602 register_name
= "MMID";
7605 goto cp0_unimplemented
;
7608 case CP0_REGISTER_05
:
7610 case CP0_REG05__PAGEMASK
:
7611 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageMask
));
7612 register_name
= "PageMask";
7614 case CP0_REG05__PAGEGRAIN
:
7615 check_insn(ctx
, ISA_MIPS32R2
);
7616 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageGrain
));
7617 register_name
= "PageGrain";
7619 case CP0_REG05__SEGCTL0
:
7621 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_SegCtl0
));
7622 tcg_gen_ext32s_tl(arg
, arg
);
7623 register_name
= "SegCtl0";
7625 case CP0_REG05__SEGCTL1
:
7627 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_SegCtl1
));
7628 tcg_gen_ext32s_tl(arg
, arg
);
7629 register_name
= "SegCtl1";
7631 case CP0_REG05__SEGCTL2
:
7633 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_SegCtl2
));
7634 tcg_gen_ext32s_tl(arg
, arg
);
7635 register_name
= "SegCtl2";
7637 case CP0_REG05__PWBASE
:
7639 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PWBase
));
7640 register_name
= "PWBase";
7642 case CP0_REG05__PWFIELD
:
7644 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PWField
));
7645 register_name
= "PWField";
7647 case CP0_REG05__PWSIZE
:
7649 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PWSize
));
7650 register_name
= "PWSize";
7653 goto cp0_unimplemented
;
7656 case CP0_REGISTER_06
:
7658 case CP0_REG06__WIRED
:
7659 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Wired
));
7660 register_name
= "Wired";
7662 case CP0_REG06__SRSCONF0
:
7663 check_insn(ctx
, ISA_MIPS32R2
);
7664 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf0
));
7665 register_name
= "SRSConf0";
7667 case CP0_REG06__SRSCONF1
:
7668 check_insn(ctx
, ISA_MIPS32R2
);
7669 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf1
));
7670 register_name
= "SRSConf1";
7672 case CP0_REG06__SRSCONF2
:
7673 check_insn(ctx
, ISA_MIPS32R2
);
7674 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf2
));
7675 register_name
= "SRSConf2";
7677 case CP0_REG06__SRSCONF3
:
7678 check_insn(ctx
, ISA_MIPS32R2
);
7679 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf3
));
7680 register_name
= "SRSConf3";
7682 case CP0_REG06__SRSCONF4
:
7683 check_insn(ctx
, ISA_MIPS32R2
);
7684 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf4
));
7685 register_name
= "SRSConf4";
7687 case CP0_REG06__PWCTL
:
7689 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PWCtl
));
7690 register_name
= "PWCtl";
7693 goto cp0_unimplemented
;
7696 case CP0_REGISTER_07
:
7698 case CP0_REG07__HWRENA
:
7699 check_insn(ctx
, ISA_MIPS32R2
);
7700 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_HWREna
));
7701 register_name
= "HWREna";
7704 goto cp0_unimplemented
;
7707 case CP0_REGISTER_08
:
7709 case CP0_REG08__BADVADDR
:
7710 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_BadVAddr
));
7711 tcg_gen_ext32s_tl(arg
, arg
);
7712 register_name
= "BadVAddr";
7714 case CP0_REG08__BADINSTR
:
7716 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstr
));
7717 register_name
= "BadInstr";
7719 case CP0_REG08__BADINSTRP
:
7721 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstrP
));
7722 register_name
= "BadInstrP";
7724 case CP0_REG08__BADINSTRX
:
7726 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstrX
));
7727 tcg_gen_andi_tl(arg
, arg
, ~0xffff);
7728 register_name
= "BadInstrX";
7731 goto cp0_unimplemented
;
7734 case CP0_REGISTER_09
:
7736 case CP0_REG09__COUNT
:
7737 /* Mark as an IO operation because we read the time. */
7738 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
7741 gen_helper_mfc0_count(arg
, cpu_env
);
7743 * Break the TB to be able to take timer interrupts immediately
7744 * after reading count. DISAS_STOP isn't sufficient, we need to
7745 * ensure we break completely out of translated code.
7747 gen_save_pc(ctx
->base
.pc_next
+ 4);
7748 ctx
->base
.is_jmp
= DISAS_EXIT
;
7749 register_name
= "Count";
7751 case CP0_REG09__SAARI
:
7752 CP0_CHECK(ctx
->saar
);
7753 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SAARI
));
7754 register_name
= "SAARI";
7756 case CP0_REG09__SAAR
:
7757 CP0_CHECK(ctx
->saar
);
7758 gen_helper_mfc0_saar(arg
, cpu_env
);
7759 register_name
= "SAAR";
7762 goto cp0_unimplemented
;
7765 case CP0_REGISTER_10
:
7767 case CP0_REG10__ENTRYHI
:
7768 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryHi
));
7769 tcg_gen_ext32s_tl(arg
, arg
);
7770 register_name
= "EntryHi";
7773 goto cp0_unimplemented
;
7776 case CP0_REGISTER_11
:
7778 case CP0_REG11__COMPARE
:
7779 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Compare
));
7780 register_name
= "Compare";
7782 /* 6,7 are implementation dependent */
7784 goto cp0_unimplemented
;
7787 case CP0_REGISTER_12
:
7789 case CP0_REG12__STATUS
:
7790 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Status
));
7791 register_name
= "Status";
7793 case CP0_REG12__INTCTL
:
7794 check_insn(ctx
, ISA_MIPS32R2
);
7795 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_IntCtl
));
7796 register_name
= "IntCtl";
7798 case CP0_REG12__SRSCTL
:
7799 check_insn(ctx
, ISA_MIPS32R2
);
7800 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
7801 register_name
= "SRSCtl";
7803 case CP0_REG12__SRSMAP
:
7804 check_insn(ctx
, ISA_MIPS32R2
);
7805 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
7806 register_name
= "SRSMap";
7809 goto cp0_unimplemented
;
7812 case CP0_REGISTER_13
:
7814 case CP0_REG13__CAUSE
:
7815 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Cause
));
7816 register_name
= "Cause";
7819 goto cp0_unimplemented
;
7822 case CP0_REGISTER_14
:
7824 case CP0_REG14__EPC
:
7825 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
7826 tcg_gen_ext32s_tl(arg
, arg
);
7827 register_name
= "EPC";
7830 goto cp0_unimplemented
;
7833 case CP0_REGISTER_15
:
7835 case CP0_REG15__PRID
:
7836 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PRid
));
7837 register_name
= "PRid";
7839 case CP0_REG15__EBASE
:
7840 check_insn(ctx
, ISA_MIPS32R2
);
7841 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EBase
));
7842 tcg_gen_ext32s_tl(arg
, arg
);
7843 register_name
= "EBase";
7845 case CP0_REG15__CMGCRBASE
:
7846 check_insn(ctx
, ISA_MIPS32R2
);
7847 CP0_CHECK(ctx
->cmgcr
);
7848 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_CMGCRBase
));
7849 tcg_gen_ext32s_tl(arg
, arg
);
7850 register_name
= "CMGCRBase";
7853 goto cp0_unimplemented
;
7856 case CP0_REGISTER_16
:
7858 case CP0_REG16__CONFIG
:
7859 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config0
));
7860 register_name
= "Config";
7862 case CP0_REG16__CONFIG1
:
7863 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config1
));
7864 register_name
= "Config1";
7866 case CP0_REG16__CONFIG2
:
7867 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config2
));
7868 register_name
= "Config2";
7870 case CP0_REG16__CONFIG3
:
7871 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config3
));
7872 register_name
= "Config3";
7874 case CP0_REG16__CONFIG4
:
7875 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config4
));
7876 register_name
= "Config4";
7878 case CP0_REG16__CONFIG5
:
7879 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config5
));
7880 register_name
= "Config5";
7882 /* 6,7 are implementation dependent */
7883 case CP0_REG16__CONFIG6
:
7884 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config6
));
7885 register_name
= "Config6";
7887 case CP0_REG16__CONFIG7
:
7888 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config7
));
7889 register_name
= "Config7";
7892 goto cp0_unimplemented
;
7895 case CP0_REGISTER_17
:
7897 case CP0_REG17__LLADDR
:
7898 gen_helper_mfc0_lladdr(arg
, cpu_env
);
7899 register_name
= "LLAddr";
7901 case CP0_REG17__MAAR
:
7902 CP0_CHECK(ctx
->mrp
);
7903 gen_helper_mfc0_maar(arg
, cpu_env
);
7904 register_name
= "MAAR";
7906 case CP0_REG17__MAARI
:
7907 CP0_CHECK(ctx
->mrp
);
7908 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_MAARI
));
7909 register_name
= "MAARI";
7912 goto cp0_unimplemented
;
7915 case CP0_REGISTER_18
:
7917 case CP0_REG18__WATCHLO0
:
7918 case CP0_REG18__WATCHLO1
:
7919 case CP0_REG18__WATCHLO2
:
7920 case CP0_REG18__WATCHLO3
:
7921 case CP0_REG18__WATCHLO4
:
7922 case CP0_REG18__WATCHLO5
:
7923 case CP0_REG18__WATCHLO6
:
7924 case CP0_REG18__WATCHLO7
:
7925 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
7926 gen_helper_1e0i(mfc0_watchlo
, arg
, sel
);
7927 register_name
= "WatchLo";
7930 goto cp0_unimplemented
;
7933 case CP0_REGISTER_19
:
7935 case CP0_REG19__WATCHHI0
:
7936 case CP0_REG19__WATCHHI1
:
7937 case CP0_REG19__WATCHHI2
:
7938 case CP0_REG19__WATCHHI3
:
7939 case CP0_REG19__WATCHHI4
:
7940 case CP0_REG19__WATCHHI5
:
7941 case CP0_REG19__WATCHHI6
:
7942 case CP0_REG19__WATCHHI7
:
7943 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
7944 gen_helper_1e0i(mfc0_watchhi
, arg
, sel
);
7945 register_name
= "WatchHi";
7948 goto cp0_unimplemented
;
7951 case CP0_REGISTER_20
:
7953 case CP0_REG20__XCONTEXT
:
7954 #if defined(TARGET_MIPS64)
7955 check_insn(ctx
, ISA_MIPS3
);
7956 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_XContext
));
7957 tcg_gen_ext32s_tl(arg
, arg
);
7958 register_name
= "XContext";
7962 goto cp0_unimplemented
;
7965 case CP0_REGISTER_21
:
7966 /* Officially reserved, but sel 0 is used for R1x000 framemask */
7967 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS32R6
));
7970 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Framemask
));
7971 register_name
= "Framemask";
7974 goto cp0_unimplemented
;
7977 case CP0_REGISTER_22
:
7978 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
7979 register_name
= "'Diagnostic"; /* implementation dependent */
7981 case CP0_REGISTER_23
:
7983 case CP0_REG23__DEBUG
:
7984 gen_helper_mfc0_debug(arg
, cpu_env
); /* EJTAG support */
7985 register_name
= "Debug";
7987 case CP0_REG23__TRACECONTROL
:
7988 /* PDtrace support */
7989 /* gen_helper_mfc0_tracecontrol(arg); */
7990 register_name
= "TraceControl";
7991 goto cp0_unimplemented
;
7992 case CP0_REG23__TRACECONTROL2
:
7993 /* PDtrace support */
7994 /* gen_helper_mfc0_tracecontrol2(arg); */
7995 register_name
= "TraceControl2";
7996 goto cp0_unimplemented
;
7997 case CP0_REG23__USERTRACEDATA1
:
7998 /* PDtrace support */
7999 /* gen_helper_mfc0_usertracedata1(arg);*/
8000 register_name
= "UserTraceData1";
8001 goto cp0_unimplemented
;
8002 case CP0_REG23__TRACEIBPC
:
8003 /* PDtrace support */
8004 /* gen_helper_mfc0_traceibpc(arg); */
8005 register_name
= "TraceIBPC";
8006 goto cp0_unimplemented
;
8007 case CP0_REG23__TRACEDBPC
:
8008 /* PDtrace support */
8009 /* gen_helper_mfc0_tracedbpc(arg); */
8010 register_name
= "TraceDBPC";
8011 goto cp0_unimplemented
;
8013 goto cp0_unimplemented
;
8016 case CP0_REGISTER_24
:
8018 case CP0_REG24__DEPC
:
8020 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
8021 tcg_gen_ext32s_tl(arg
, arg
);
8022 register_name
= "DEPC";
8025 goto cp0_unimplemented
;
8028 case CP0_REGISTER_25
:
8030 case CP0_REG25__PERFCTL0
:
8031 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Performance0
));
8032 register_name
= "Performance0";
8034 case CP0_REG25__PERFCNT0
:
8035 /* gen_helper_mfc0_performance1(arg); */
8036 register_name
= "Performance1";
8037 goto cp0_unimplemented
;
8038 case CP0_REG25__PERFCTL1
:
8039 /* gen_helper_mfc0_performance2(arg); */
8040 register_name
= "Performance2";
8041 goto cp0_unimplemented
;
8042 case CP0_REG25__PERFCNT1
:
8043 /* gen_helper_mfc0_performance3(arg); */
8044 register_name
= "Performance3";
8045 goto cp0_unimplemented
;
8046 case CP0_REG25__PERFCTL2
:
8047 /* gen_helper_mfc0_performance4(arg); */
8048 register_name
= "Performance4";
8049 goto cp0_unimplemented
;
8050 case CP0_REG25__PERFCNT2
:
8051 /* gen_helper_mfc0_performance5(arg); */
8052 register_name
= "Performance5";
8053 goto cp0_unimplemented
;
8054 case CP0_REG25__PERFCTL3
:
8055 /* gen_helper_mfc0_performance6(arg); */
8056 register_name
= "Performance6";
8057 goto cp0_unimplemented
;
8058 case CP0_REG25__PERFCNT3
:
8059 /* gen_helper_mfc0_performance7(arg); */
8060 register_name
= "Performance7";
8061 goto cp0_unimplemented
;
8063 goto cp0_unimplemented
;
8066 case CP0_REGISTER_26
:
8068 case CP0_REG26__ERRCTL
:
8069 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_ErrCtl
));
8070 register_name
= "ErrCtl";
8073 goto cp0_unimplemented
;
8076 case CP0_REGISTER_27
:
8078 case CP0_REG27__CACHERR
:
8079 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
8080 register_name
= "CacheErr";
8083 goto cp0_unimplemented
;
8086 case CP0_REGISTER_28
:
8088 case CP0_REG28__TAGLO
:
8089 case CP0_REG28__TAGLO1
:
8090 case CP0_REG28__TAGLO2
:
8091 case CP0_REG28__TAGLO3
:
8093 TCGv_i64 tmp
= tcg_temp_new_i64();
8094 tcg_gen_ld_i64(tmp
, cpu_env
, offsetof(CPUMIPSState
, CP0_TagLo
));
8095 gen_move_low32(arg
, tmp
);
8096 tcg_temp_free_i64(tmp
);
8098 register_name
= "TagLo";
8100 case CP0_REG28__DATALO
:
8101 case CP0_REG28__DATALO1
:
8102 case CP0_REG28__DATALO2
:
8103 case CP0_REG28__DATALO3
:
8104 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataLo
));
8105 register_name
= "DataLo";
8108 goto cp0_unimplemented
;
8111 case CP0_REGISTER_29
:
8113 case CP0_REG29__TAGHI
:
8114 case CP0_REG29__TAGHI1
:
8115 case CP0_REG29__TAGHI2
:
8116 case CP0_REG29__TAGHI3
:
8117 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagHi
));
8118 register_name
= "TagHi";
8120 case CP0_REG29__DATAHI
:
8121 case CP0_REG29__DATAHI1
:
8122 case CP0_REG29__DATAHI2
:
8123 case CP0_REG29__DATAHI3
:
8124 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataHi
));
8125 register_name
= "DataHi";
8128 goto cp0_unimplemented
;
8131 case CP0_REGISTER_30
:
8133 case CP0_REG30__ERROREPC
:
8134 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
8135 tcg_gen_ext32s_tl(arg
, arg
);
8136 register_name
= "ErrorEPC";
8139 goto cp0_unimplemented
;
8142 case CP0_REGISTER_31
:
8144 case CP0_REG31__DESAVE
:
8146 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
8147 register_name
= "DESAVE";
8149 case CP0_REG31__KSCRATCH1
:
8150 case CP0_REG31__KSCRATCH2
:
8151 case CP0_REG31__KSCRATCH3
:
8152 case CP0_REG31__KSCRATCH4
:
8153 case CP0_REG31__KSCRATCH5
:
8154 case CP0_REG31__KSCRATCH6
:
8155 CP0_CHECK(ctx
->kscrexist
& (1 << sel
));
8156 tcg_gen_ld_tl(arg
, cpu_env
,
8157 offsetof(CPUMIPSState
, CP0_KScratch
[sel
- 2]));
8158 tcg_gen_ext32s_tl(arg
, arg
);
8159 register_name
= "KScratch";
8162 goto cp0_unimplemented
;
8166 goto cp0_unimplemented
;
8168 trace_mips_translate_c0("mfc0", register_name
, reg
, sel
);
8172 qemu_log_mask(LOG_UNIMP
, "mfc0 %s (reg %d sel %d)\n",
8173 register_name
, reg
, sel
);
8174 gen_mfc0_unimplemented(ctx
, arg
);
8177 static void gen_mtc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
8179 const char *register_name
= "invalid";
8182 check_insn(ctx
, ISA_MIPS32
);
8185 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
8190 case CP0_REGISTER_00
:
8192 case CP0_REG00__INDEX
:
8193 gen_helper_mtc0_index(cpu_env
, arg
);
8194 register_name
= "Index";
8196 case CP0_REG00__MVPCONTROL
:
8197 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8198 gen_helper_mtc0_mvpcontrol(cpu_env
, arg
);
8199 register_name
= "MVPControl";
8201 case CP0_REG00__MVPCONF0
:
8202 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8204 register_name
= "MVPConf0";
8206 case CP0_REG00__MVPCONF1
:
8207 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8209 register_name
= "MVPConf1";
8211 case CP0_REG00__VPCONTROL
:
8214 register_name
= "VPControl";
8217 goto cp0_unimplemented
;
8220 case CP0_REGISTER_01
:
8222 case CP0_REG01__RANDOM
:
8224 register_name
= "Random";
8226 case CP0_REG01__VPECONTROL
:
8227 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8228 gen_helper_mtc0_vpecontrol(cpu_env
, arg
);
8229 register_name
= "VPEControl";
8231 case CP0_REG01__VPECONF0
:
8232 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8233 gen_helper_mtc0_vpeconf0(cpu_env
, arg
);
8234 register_name
= "VPEConf0";
8236 case CP0_REG01__VPECONF1
:
8237 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8238 gen_helper_mtc0_vpeconf1(cpu_env
, arg
);
8239 register_name
= "VPEConf1";
8241 case CP0_REG01__YQMASK
:
8242 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8243 gen_helper_mtc0_yqmask(cpu_env
, arg
);
8244 register_name
= "YQMask";
8246 case CP0_REG01__VPESCHEDULE
:
8247 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8248 tcg_gen_st_tl(arg
, cpu_env
,
8249 offsetof(CPUMIPSState
, CP0_VPESchedule
));
8250 register_name
= "VPESchedule";
8252 case CP0_REG01__VPESCHEFBACK
:
8253 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8254 tcg_gen_st_tl(arg
, cpu_env
,
8255 offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
8256 register_name
= "VPEScheFBack";
8258 case CP0_REG01__VPEOPT
:
8259 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8260 gen_helper_mtc0_vpeopt(cpu_env
, arg
);
8261 register_name
= "VPEOpt";
8264 goto cp0_unimplemented
;
8267 case CP0_REGISTER_02
:
8269 case CP0_REG02__ENTRYLO0
:
8270 gen_helper_mtc0_entrylo0(cpu_env
, arg
);
8271 register_name
= "EntryLo0";
8273 case CP0_REG02__TCSTATUS
:
8274 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8275 gen_helper_mtc0_tcstatus(cpu_env
, arg
);
8276 register_name
= "TCStatus";
8278 case CP0_REG02__TCBIND
:
8279 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8280 gen_helper_mtc0_tcbind(cpu_env
, arg
);
8281 register_name
= "TCBind";
8283 case CP0_REG02__TCRESTART
:
8284 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8285 gen_helper_mtc0_tcrestart(cpu_env
, arg
);
8286 register_name
= "TCRestart";
8288 case CP0_REG02__TCHALT
:
8289 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8290 gen_helper_mtc0_tchalt(cpu_env
, arg
);
8291 register_name
= "TCHalt";
8293 case CP0_REG02__TCCONTEXT
:
8294 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8295 gen_helper_mtc0_tccontext(cpu_env
, arg
);
8296 register_name
= "TCContext";
8298 case CP0_REG02__TCSCHEDULE
:
8299 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8300 gen_helper_mtc0_tcschedule(cpu_env
, arg
);
8301 register_name
= "TCSchedule";
8303 case CP0_REG02__TCSCHEFBACK
:
8304 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8305 gen_helper_mtc0_tcschefback(cpu_env
, arg
);
8306 register_name
= "TCScheFBack";
8309 goto cp0_unimplemented
;
8312 case CP0_REGISTER_03
:
8314 case CP0_REG03__ENTRYLO1
:
8315 gen_helper_mtc0_entrylo1(cpu_env
, arg
);
8316 register_name
= "EntryLo1";
8318 case CP0_REG03__GLOBALNUM
:
8321 register_name
= "GlobalNumber";
8324 goto cp0_unimplemented
;
8327 case CP0_REGISTER_04
:
8329 case CP0_REG04__CONTEXT
:
8330 gen_helper_mtc0_context(cpu_env
, arg
);
8331 register_name
= "Context";
8333 case CP0_REG04__CONTEXTCONFIG
:
8335 /* gen_helper_mtc0_contextconfig(arg); */
8336 register_name
= "ContextConfig";
8337 goto cp0_unimplemented
;
8338 case CP0_REG04__USERLOCAL
:
8339 CP0_CHECK(ctx
->ulri
);
8340 tcg_gen_st_tl(arg
, cpu_env
,
8341 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
8342 register_name
= "UserLocal";
8344 case CP0_REG04__MMID
:
8346 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_MemoryMapID
));
8347 register_name
= "MMID";
8350 goto cp0_unimplemented
;
8353 case CP0_REGISTER_05
:
8355 case CP0_REG05__PAGEMASK
:
8356 gen_helper_mtc0_pagemask(cpu_env
, arg
);
8357 register_name
= "PageMask";
8359 case CP0_REG05__PAGEGRAIN
:
8360 check_insn(ctx
, ISA_MIPS32R2
);
8361 gen_helper_mtc0_pagegrain(cpu_env
, arg
);
8362 register_name
= "PageGrain";
8363 ctx
->base
.is_jmp
= DISAS_STOP
;
8365 case CP0_REG05__SEGCTL0
:
8367 gen_helper_mtc0_segctl0(cpu_env
, arg
);
8368 register_name
= "SegCtl0";
8370 case CP0_REG05__SEGCTL1
:
8372 gen_helper_mtc0_segctl1(cpu_env
, arg
);
8373 register_name
= "SegCtl1";
8375 case CP0_REG05__SEGCTL2
:
8377 gen_helper_mtc0_segctl2(cpu_env
, arg
);
8378 register_name
= "SegCtl2";
8380 case CP0_REG05__PWBASE
:
8382 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_PWBase
));
8383 register_name
= "PWBase";
8385 case CP0_REG05__PWFIELD
:
8387 gen_helper_mtc0_pwfield(cpu_env
, arg
);
8388 register_name
= "PWField";
8390 case CP0_REG05__PWSIZE
:
8392 gen_helper_mtc0_pwsize(cpu_env
, arg
);
8393 register_name
= "PWSize";
8396 goto cp0_unimplemented
;
8399 case CP0_REGISTER_06
:
8401 case CP0_REG06__WIRED
:
8402 gen_helper_mtc0_wired(cpu_env
, arg
);
8403 register_name
= "Wired";
8405 case CP0_REG06__SRSCONF0
:
8406 check_insn(ctx
, ISA_MIPS32R2
);
8407 gen_helper_mtc0_srsconf0(cpu_env
, arg
);
8408 register_name
= "SRSConf0";
8410 case CP0_REG06__SRSCONF1
:
8411 check_insn(ctx
, ISA_MIPS32R2
);
8412 gen_helper_mtc0_srsconf1(cpu_env
, arg
);
8413 register_name
= "SRSConf1";
8415 case CP0_REG06__SRSCONF2
:
8416 check_insn(ctx
, ISA_MIPS32R2
);
8417 gen_helper_mtc0_srsconf2(cpu_env
, arg
);
8418 register_name
= "SRSConf2";
8420 case CP0_REG06__SRSCONF3
:
8421 check_insn(ctx
, ISA_MIPS32R2
);
8422 gen_helper_mtc0_srsconf3(cpu_env
, arg
);
8423 register_name
= "SRSConf3";
8425 case CP0_REG06__SRSCONF4
:
8426 check_insn(ctx
, ISA_MIPS32R2
);
8427 gen_helper_mtc0_srsconf4(cpu_env
, arg
);
8428 register_name
= "SRSConf4";
8430 case CP0_REG06__PWCTL
:
8432 gen_helper_mtc0_pwctl(cpu_env
, arg
);
8433 register_name
= "PWCtl";
8436 goto cp0_unimplemented
;
8439 case CP0_REGISTER_07
:
8441 case CP0_REG07__HWRENA
:
8442 check_insn(ctx
, ISA_MIPS32R2
);
8443 gen_helper_mtc0_hwrena(cpu_env
, arg
);
8444 ctx
->base
.is_jmp
= DISAS_STOP
;
8445 register_name
= "HWREna";
8448 goto cp0_unimplemented
;
8451 case CP0_REGISTER_08
:
8453 case CP0_REG08__BADVADDR
:
8455 register_name
= "BadVAddr";
8457 case CP0_REG08__BADINSTR
:
8459 register_name
= "BadInstr";
8461 case CP0_REG08__BADINSTRP
:
8463 register_name
= "BadInstrP";
8465 case CP0_REG08__BADINSTRX
:
8467 register_name
= "BadInstrX";
8470 goto cp0_unimplemented
;
8473 case CP0_REGISTER_09
:
8475 case CP0_REG09__COUNT
:
8476 gen_helper_mtc0_count(cpu_env
, arg
);
8477 register_name
= "Count";
8479 case CP0_REG09__SAARI
:
8480 CP0_CHECK(ctx
->saar
);
8481 gen_helper_mtc0_saari(cpu_env
, arg
);
8482 register_name
= "SAARI";
8484 case CP0_REG09__SAAR
:
8485 CP0_CHECK(ctx
->saar
);
8486 gen_helper_mtc0_saar(cpu_env
, arg
);
8487 register_name
= "SAAR";
8490 goto cp0_unimplemented
;
8493 case CP0_REGISTER_10
:
8495 case CP0_REG10__ENTRYHI
:
8496 gen_helper_mtc0_entryhi(cpu_env
, arg
);
8497 register_name
= "EntryHi";
8500 goto cp0_unimplemented
;
8503 case CP0_REGISTER_11
:
8505 case CP0_REG11__COMPARE
:
8506 gen_helper_mtc0_compare(cpu_env
, arg
);
8507 register_name
= "Compare";
8509 /* 6,7 are implementation dependent */
8511 goto cp0_unimplemented
;
8514 case CP0_REGISTER_12
:
8516 case CP0_REG12__STATUS
:
8517 save_cpu_state(ctx
, 1);
8518 gen_helper_mtc0_status(cpu_env
, arg
);
8519 /* DISAS_STOP isn't good enough here, hflags may have changed. */
8520 gen_save_pc(ctx
->base
.pc_next
+ 4);
8521 ctx
->base
.is_jmp
= DISAS_EXIT
;
8522 register_name
= "Status";
8524 case CP0_REG12__INTCTL
:
8525 check_insn(ctx
, ISA_MIPS32R2
);
8526 gen_helper_mtc0_intctl(cpu_env
, arg
);
8527 /* Stop translation as we may have switched the execution mode */
8528 ctx
->base
.is_jmp
= DISAS_STOP
;
8529 register_name
= "IntCtl";
8531 case CP0_REG12__SRSCTL
:
8532 check_insn(ctx
, ISA_MIPS32R2
);
8533 gen_helper_mtc0_srsctl(cpu_env
, arg
);
8534 /* Stop translation as we may have switched the execution mode */
8535 ctx
->base
.is_jmp
= DISAS_STOP
;
8536 register_name
= "SRSCtl";
8538 case CP0_REG12__SRSMAP
:
8539 check_insn(ctx
, ISA_MIPS32R2
);
8540 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
8541 /* Stop translation as we may have switched the execution mode */
8542 ctx
->base
.is_jmp
= DISAS_STOP
;
8543 register_name
= "SRSMap";
8546 goto cp0_unimplemented
;
8549 case CP0_REGISTER_13
:
8551 case CP0_REG13__CAUSE
:
8552 save_cpu_state(ctx
, 1);
8553 gen_helper_mtc0_cause(cpu_env
, arg
);
8555 * Stop translation as we may have triggered an interrupt.
8556 * DISAS_STOP isn't sufficient, we need to ensure we break out of
8557 * translated code to check for pending interrupts.
8559 gen_save_pc(ctx
->base
.pc_next
+ 4);
8560 ctx
->base
.is_jmp
= DISAS_EXIT
;
8561 register_name
= "Cause";
8564 goto cp0_unimplemented
;
8567 case CP0_REGISTER_14
:
8569 case CP0_REG14__EPC
:
8570 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
8571 register_name
= "EPC";
8574 goto cp0_unimplemented
;
8577 case CP0_REGISTER_15
:
8579 case CP0_REG15__PRID
:
8581 register_name
= "PRid";
8583 case CP0_REG15__EBASE
:
8584 check_insn(ctx
, ISA_MIPS32R2
);
8585 gen_helper_mtc0_ebase(cpu_env
, arg
);
8586 register_name
= "EBase";
8589 goto cp0_unimplemented
;
8592 case CP0_REGISTER_16
:
8594 case CP0_REG16__CONFIG
:
8595 gen_helper_mtc0_config0(cpu_env
, arg
);
8596 register_name
= "Config";
8597 /* Stop translation as we may have switched the execution mode */
8598 ctx
->base
.is_jmp
= DISAS_STOP
;
8600 case CP0_REG16__CONFIG1
:
8601 /* ignored, read only */
8602 register_name
= "Config1";
8604 case CP0_REG16__CONFIG2
:
8605 gen_helper_mtc0_config2(cpu_env
, arg
);
8606 register_name
= "Config2";
8607 /* Stop translation as we may have switched the execution mode */
8608 ctx
->base
.is_jmp
= DISAS_STOP
;
8610 case CP0_REG16__CONFIG3
:
8611 gen_helper_mtc0_config3(cpu_env
, arg
);
8612 register_name
= "Config3";
8613 /* Stop translation as we may have switched the execution mode */
8614 ctx
->base
.is_jmp
= DISAS_STOP
;
8616 case CP0_REG16__CONFIG4
:
8617 gen_helper_mtc0_config4(cpu_env
, arg
);
8618 register_name
= "Config4";
8619 ctx
->base
.is_jmp
= DISAS_STOP
;
8621 case CP0_REG16__CONFIG5
:
8622 gen_helper_mtc0_config5(cpu_env
, arg
);
8623 register_name
= "Config5";
8624 /* Stop translation as we may have switched the execution mode */
8625 ctx
->base
.is_jmp
= DISAS_STOP
;
8627 /* 6,7 are implementation dependent */
8628 case CP0_REG16__CONFIG6
:
8630 register_name
= "Config6";
8632 case CP0_REG16__CONFIG7
:
8634 register_name
= "Config7";
8637 register_name
= "Invalid config selector";
8638 goto cp0_unimplemented
;
8641 case CP0_REGISTER_17
:
8643 case CP0_REG17__LLADDR
:
8644 gen_helper_mtc0_lladdr(cpu_env
, arg
);
8645 register_name
= "LLAddr";
8647 case CP0_REG17__MAAR
:
8648 CP0_CHECK(ctx
->mrp
);
8649 gen_helper_mtc0_maar(cpu_env
, arg
);
8650 register_name
= "MAAR";
8652 case CP0_REG17__MAARI
:
8653 CP0_CHECK(ctx
->mrp
);
8654 gen_helper_mtc0_maari(cpu_env
, arg
);
8655 register_name
= "MAARI";
8658 goto cp0_unimplemented
;
8661 case CP0_REGISTER_18
:
8663 case CP0_REG18__WATCHLO0
:
8664 case CP0_REG18__WATCHLO1
:
8665 case CP0_REG18__WATCHLO2
:
8666 case CP0_REG18__WATCHLO3
:
8667 case CP0_REG18__WATCHLO4
:
8668 case CP0_REG18__WATCHLO5
:
8669 case CP0_REG18__WATCHLO6
:
8670 case CP0_REG18__WATCHLO7
:
8671 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
8672 gen_helper_0e1i(mtc0_watchlo
, arg
, sel
);
8673 register_name
= "WatchLo";
8676 goto cp0_unimplemented
;
8679 case CP0_REGISTER_19
:
8681 case CP0_REG19__WATCHHI0
:
8682 case CP0_REG19__WATCHHI1
:
8683 case CP0_REG19__WATCHHI2
:
8684 case CP0_REG19__WATCHHI3
:
8685 case CP0_REG19__WATCHHI4
:
8686 case CP0_REG19__WATCHHI5
:
8687 case CP0_REG19__WATCHHI6
:
8688 case CP0_REG19__WATCHHI7
:
8689 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
8690 gen_helper_0e1i(mtc0_watchhi
, arg
, sel
);
8691 register_name
= "WatchHi";
8694 goto cp0_unimplemented
;
8697 case CP0_REGISTER_20
:
8699 case CP0_REG20__XCONTEXT
:
8700 #if defined(TARGET_MIPS64)
8701 check_insn(ctx
, ISA_MIPS3
);
8702 gen_helper_mtc0_xcontext(cpu_env
, arg
);
8703 register_name
= "XContext";
8707 goto cp0_unimplemented
;
8710 case CP0_REGISTER_21
:
8711 /* Officially reserved, but sel 0 is used for R1x000 framemask */
8712 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS32R6
));
8715 gen_helper_mtc0_framemask(cpu_env
, arg
);
8716 register_name
= "Framemask";
8719 goto cp0_unimplemented
;
8722 case CP0_REGISTER_22
:
8724 register_name
= "Diagnostic"; /* implementation dependent */
8726 case CP0_REGISTER_23
:
8728 case CP0_REG23__DEBUG
:
8729 gen_helper_mtc0_debug(cpu_env
, arg
); /* EJTAG support */
8730 /* DISAS_STOP isn't good enough here, hflags may have changed. */
8731 gen_save_pc(ctx
->base
.pc_next
+ 4);
8732 ctx
->base
.is_jmp
= DISAS_EXIT
;
8733 register_name
= "Debug";
8735 case CP0_REG23__TRACECONTROL
:
8736 /* PDtrace support */
8737 /* gen_helper_mtc0_tracecontrol(cpu_env, arg); */
8738 register_name
= "TraceControl";
8739 /* Stop translation as we may have switched the execution mode */
8740 ctx
->base
.is_jmp
= DISAS_STOP
;
8741 goto cp0_unimplemented
;
8742 case CP0_REG23__TRACECONTROL2
:
8743 /* PDtrace support */
8744 /* gen_helper_mtc0_tracecontrol2(cpu_env, arg); */
8745 register_name
= "TraceControl2";
8746 /* Stop translation as we may have switched the execution mode */
8747 ctx
->base
.is_jmp
= DISAS_STOP
;
8748 goto cp0_unimplemented
;
8749 case CP0_REG23__USERTRACEDATA1
:
8750 /* Stop translation as we may have switched the execution mode */
8751 ctx
->base
.is_jmp
= DISAS_STOP
;
8752 /* PDtrace support */
8753 /* gen_helper_mtc0_usertracedata1(cpu_env, arg);*/
8754 register_name
= "UserTraceData";
8755 /* Stop translation as we may have switched the execution mode */
8756 ctx
->base
.is_jmp
= DISAS_STOP
;
8757 goto cp0_unimplemented
;
8758 case CP0_REG23__TRACEIBPC
:
8759 /* PDtrace support */
8760 /* gen_helper_mtc0_traceibpc(cpu_env, arg); */
8761 /* Stop translation as we may have switched the execution mode */
8762 ctx
->base
.is_jmp
= DISAS_STOP
;
8763 register_name
= "TraceIBPC";
8764 goto cp0_unimplemented
;
8765 case CP0_REG23__TRACEDBPC
:
8766 /* PDtrace support */
8767 /* gen_helper_mtc0_tracedbpc(cpu_env, arg); */
8768 /* Stop translation as we may have switched the execution mode */
8769 ctx
->base
.is_jmp
= DISAS_STOP
;
8770 register_name
= "TraceDBPC";
8771 goto cp0_unimplemented
;
8773 goto cp0_unimplemented
;
8776 case CP0_REGISTER_24
:
8778 case CP0_REG24__DEPC
:
8780 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
8781 register_name
= "DEPC";
8784 goto cp0_unimplemented
;
8787 case CP0_REGISTER_25
:
8789 case CP0_REG25__PERFCTL0
:
8790 gen_helper_mtc0_performance0(cpu_env
, arg
);
8791 register_name
= "Performance0";
8793 case CP0_REG25__PERFCNT0
:
8794 /* gen_helper_mtc0_performance1(arg); */
8795 register_name
= "Performance1";
8796 goto cp0_unimplemented
;
8797 case CP0_REG25__PERFCTL1
:
8798 /* gen_helper_mtc0_performance2(arg); */
8799 register_name
= "Performance2";
8800 goto cp0_unimplemented
;
8801 case CP0_REG25__PERFCNT1
:
8802 /* gen_helper_mtc0_performance3(arg); */
8803 register_name
= "Performance3";
8804 goto cp0_unimplemented
;
8805 case CP0_REG25__PERFCTL2
:
8806 /* gen_helper_mtc0_performance4(arg); */
8807 register_name
= "Performance4";
8808 goto cp0_unimplemented
;
8809 case CP0_REG25__PERFCNT2
:
8810 /* gen_helper_mtc0_performance5(arg); */
8811 register_name
= "Performance5";
8812 goto cp0_unimplemented
;
8813 case CP0_REG25__PERFCTL3
:
8814 /* gen_helper_mtc0_performance6(arg); */
8815 register_name
= "Performance6";
8816 goto cp0_unimplemented
;
8817 case CP0_REG25__PERFCNT3
:
8818 /* gen_helper_mtc0_performance7(arg); */
8819 register_name
= "Performance7";
8820 goto cp0_unimplemented
;
8822 goto cp0_unimplemented
;
8825 case CP0_REGISTER_26
:
8827 case CP0_REG26__ERRCTL
:
8828 gen_helper_mtc0_errctl(cpu_env
, arg
);
8829 ctx
->base
.is_jmp
= DISAS_STOP
;
8830 register_name
= "ErrCtl";
8833 goto cp0_unimplemented
;
8836 case CP0_REGISTER_27
:
8838 case CP0_REG27__CACHERR
:
8840 register_name
= "CacheErr";
8843 goto cp0_unimplemented
;
8846 case CP0_REGISTER_28
:
8848 case CP0_REG28__TAGLO
:
8849 case CP0_REG28__TAGLO1
:
8850 case CP0_REG28__TAGLO2
:
8851 case CP0_REG28__TAGLO3
:
8852 gen_helper_mtc0_taglo(cpu_env
, arg
);
8853 register_name
= "TagLo";
8855 case CP0_REG28__DATALO
:
8856 case CP0_REG28__DATALO1
:
8857 case CP0_REG28__DATALO2
:
8858 case CP0_REG28__DATALO3
:
8859 gen_helper_mtc0_datalo(cpu_env
, arg
);
8860 register_name
= "DataLo";
8863 goto cp0_unimplemented
;
8866 case CP0_REGISTER_29
:
8868 case CP0_REG29__TAGHI
:
8869 case CP0_REG29__TAGHI1
:
8870 case CP0_REG29__TAGHI2
:
8871 case CP0_REG29__TAGHI3
:
8872 gen_helper_mtc0_taghi(cpu_env
, arg
);
8873 register_name
= "TagHi";
8875 case CP0_REG29__DATAHI
:
8876 case CP0_REG29__DATAHI1
:
8877 case CP0_REG29__DATAHI2
:
8878 case CP0_REG29__DATAHI3
:
8879 gen_helper_mtc0_datahi(cpu_env
, arg
);
8880 register_name
= "DataHi";
8883 register_name
= "invalid sel";
8884 goto cp0_unimplemented
;
8887 case CP0_REGISTER_30
:
8889 case CP0_REG30__ERROREPC
:
8890 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
8891 register_name
= "ErrorEPC";
8894 goto cp0_unimplemented
;
8897 case CP0_REGISTER_31
:
8899 case CP0_REG31__DESAVE
:
8901 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
8902 register_name
= "DESAVE";
8904 case CP0_REG31__KSCRATCH1
:
8905 case CP0_REG31__KSCRATCH2
:
8906 case CP0_REG31__KSCRATCH3
:
8907 case CP0_REG31__KSCRATCH4
:
8908 case CP0_REG31__KSCRATCH5
:
8909 case CP0_REG31__KSCRATCH6
:
8910 CP0_CHECK(ctx
->kscrexist
& (1 << sel
));
8911 tcg_gen_st_tl(arg
, cpu_env
,
8912 offsetof(CPUMIPSState
, CP0_KScratch
[sel
- 2]));
8913 register_name
= "KScratch";
8916 goto cp0_unimplemented
;
8920 goto cp0_unimplemented
;
8922 trace_mips_translate_c0("mtc0", register_name
, reg
, sel
);
8924 /* For simplicity assume that all writes can cause interrupts. */
8925 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
8927 * DISAS_STOP isn't sufficient, we need to ensure we break out of
8928 * translated code to check for pending interrupts.
8930 gen_save_pc(ctx
->base
.pc_next
+ 4);
8931 ctx
->base
.is_jmp
= DISAS_EXIT
;
8936 qemu_log_mask(LOG_UNIMP
, "mtc0 %s (reg %d sel %d)\n",
8937 register_name
, reg
, sel
);
8940 #if defined(TARGET_MIPS64)
8941 static void gen_dmfc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
8943 const char *register_name
= "invalid";
8946 check_insn(ctx
, ISA_MIPS32
);
8950 case CP0_REGISTER_00
:
8952 case CP0_REG00__INDEX
:
8953 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Index
));
8954 register_name
= "Index";
8956 case CP0_REG00__MVPCONTROL
:
8957 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8958 gen_helper_mfc0_mvpcontrol(arg
, cpu_env
);
8959 register_name
= "MVPControl";
8961 case CP0_REG00__MVPCONF0
:
8962 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8963 gen_helper_mfc0_mvpconf0(arg
, cpu_env
);
8964 register_name
= "MVPConf0";
8966 case CP0_REG00__MVPCONF1
:
8967 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8968 gen_helper_mfc0_mvpconf1(arg
, cpu_env
);
8969 register_name
= "MVPConf1";
8971 case CP0_REG00__VPCONTROL
:
8973 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPControl
));
8974 register_name
= "VPControl";
8977 goto cp0_unimplemented
;
8980 case CP0_REGISTER_01
:
8982 case CP0_REG01__RANDOM
:
8983 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS32R6
));
8984 gen_helper_mfc0_random(arg
, cpu_env
);
8985 register_name
= "Random";
8987 case CP0_REG01__VPECONTROL
:
8988 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8989 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEControl
));
8990 register_name
= "VPEControl";
8992 case CP0_REG01__VPECONF0
:
8993 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8994 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf0
));
8995 register_name
= "VPEConf0";
8997 case CP0_REG01__VPECONF1
:
8998 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8999 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf1
));
9000 register_name
= "VPEConf1";
9002 case CP0_REG01__YQMASK
:
9003 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9004 tcg_gen_ld_tl(arg
, cpu_env
,
9005 offsetof(CPUMIPSState
, CP0_YQMask
));
9006 register_name
= "YQMask";
9008 case CP0_REG01__VPESCHEDULE
:
9009 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9010 tcg_gen_ld_tl(arg
, cpu_env
,
9011 offsetof(CPUMIPSState
, CP0_VPESchedule
));
9012 register_name
= "VPESchedule";
9014 case CP0_REG01__VPESCHEFBACK
:
9015 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9016 tcg_gen_ld_tl(arg
, cpu_env
,
9017 offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
9018 register_name
= "VPEScheFBack";
9020 case CP0_REG01__VPEOPT
:
9021 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9022 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEOpt
));
9023 register_name
= "VPEOpt";
9026 goto cp0_unimplemented
;
9029 case CP0_REGISTER_02
:
9031 case CP0_REG02__ENTRYLO0
:
9032 tcg_gen_ld_tl(arg
, cpu_env
,
9033 offsetof(CPUMIPSState
, CP0_EntryLo0
));
9034 register_name
= "EntryLo0";
9036 case CP0_REG02__TCSTATUS
:
9037 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9038 gen_helper_mfc0_tcstatus(arg
, cpu_env
);
9039 register_name
= "TCStatus";
9041 case CP0_REG02__TCBIND
:
9042 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9043 gen_helper_mfc0_tcbind(arg
, cpu_env
);
9044 register_name
= "TCBind";
9046 case CP0_REG02__TCRESTART
:
9047 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9048 gen_helper_dmfc0_tcrestart(arg
, cpu_env
);
9049 register_name
= "TCRestart";
9051 case CP0_REG02__TCHALT
:
9052 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9053 gen_helper_dmfc0_tchalt(arg
, cpu_env
);
9054 register_name
= "TCHalt";
9056 case CP0_REG02__TCCONTEXT
:
9057 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9058 gen_helper_dmfc0_tccontext(arg
, cpu_env
);
9059 register_name
= "TCContext";
9061 case CP0_REG02__TCSCHEDULE
:
9062 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9063 gen_helper_dmfc0_tcschedule(arg
, cpu_env
);
9064 register_name
= "TCSchedule";
9066 case CP0_REG02__TCSCHEFBACK
:
9067 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9068 gen_helper_dmfc0_tcschefback(arg
, cpu_env
);
9069 register_name
= "TCScheFBack";
9072 goto cp0_unimplemented
;
9075 case CP0_REGISTER_03
:
9077 case CP0_REG03__ENTRYLO1
:
9078 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryLo1
));
9079 register_name
= "EntryLo1";
9081 case CP0_REG03__GLOBALNUM
:
9083 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_GlobalNumber
));
9084 register_name
= "GlobalNumber";
9087 goto cp0_unimplemented
;
9090 case CP0_REGISTER_04
:
9092 case CP0_REG04__CONTEXT
:
9093 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_Context
));
9094 register_name
= "Context";
9096 case CP0_REG04__CONTEXTCONFIG
:
9098 /* gen_helper_dmfc0_contextconfig(arg); */
9099 register_name
= "ContextConfig";
9100 goto cp0_unimplemented
;
9101 case CP0_REG04__USERLOCAL
:
9102 CP0_CHECK(ctx
->ulri
);
9103 tcg_gen_ld_tl(arg
, cpu_env
,
9104 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
9105 register_name
= "UserLocal";
9107 case CP0_REG04__MMID
:
9109 gen_helper_mtc0_memorymapid(cpu_env
, arg
);
9110 register_name
= "MMID";
9113 goto cp0_unimplemented
;
9116 case CP0_REGISTER_05
:
9118 case CP0_REG05__PAGEMASK
:
9119 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageMask
));
9120 register_name
= "PageMask";
9122 case CP0_REG05__PAGEGRAIN
:
9123 check_insn(ctx
, ISA_MIPS32R2
);
9124 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageGrain
));
9125 register_name
= "PageGrain";
9127 case CP0_REG05__SEGCTL0
:
9129 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_SegCtl0
));
9130 register_name
= "SegCtl0";
9132 case CP0_REG05__SEGCTL1
:
9134 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_SegCtl1
));
9135 register_name
= "SegCtl1";
9137 case CP0_REG05__SEGCTL2
:
9139 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_SegCtl2
));
9140 register_name
= "SegCtl2";
9142 case CP0_REG05__PWBASE
:
9144 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_PWBase
));
9145 register_name
= "PWBase";
9147 case CP0_REG05__PWFIELD
:
9149 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_PWField
));
9150 register_name
= "PWField";
9152 case CP0_REG05__PWSIZE
:
9154 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_PWSize
));
9155 register_name
= "PWSize";
9158 goto cp0_unimplemented
;
9161 case CP0_REGISTER_06
:
9163 case CP0_REG06__WIRED
:
9164 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Wired
));
9165 register_name
= "Wired";
9167 case CP0_REG06__SRSCONF0
:
9168 check_insn(ctx
, ISA_MIPS32R2
);
9169 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf0
));
9170 register_name
= "SRSConf0";
9172 case CP0_REG06__SRSCONF1
:
9173 check_insn(ctx
, ISA_MIPS32R2
);
9174 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf1
));
9175 register_name
= "SRSConf1";
9177 case CP0_REG06__SRSCONF2
:
9178 check_insn(ctx
, ISA_MIPS32R2
);
9179 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf2
));
9180 register_name
= "SRSConf2";
9182 case CP0_REG06__SRSCONF3
:
9183 check_insn(ctx
, ISA_MIPS32R2
);
9184 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf3
));
9185 register_name
= "SRSConf3";
9187 case CP0_REG06__SRSCONF4
:
9188 check_insn(ctx
, ISA_MIPS32R2
);
9189 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf4
));
9190 register_name
= "SRSConf4";
9192 case CP0_REG06__PWCTL
:
9194 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PWCtl
));
9195 register_name
= "PWCtl";
9198 goto cp0_unimplemented
;
9201 case CP0_REGISTER_07
:
9203 case CP0_REG07__HWRENA
:
9204 check_insn(ctx
, ISA_MIPS32R2
);
9205 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_HWREna
));
9206 register_name
= "HWREna";
9209 goto cp0_unimplemented
;
9212 case CP0_REGISTER_08
:
9214 case CP0_REG08__BADVADDR
:
9215 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_BadVAddr
));
9216 register_name
= "BadVAddr";
9218 case CP0_REG08__BADINSTR
:
9220 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstr
));
9221 register_name
= "BadInstr";
9223 case CP0_REG08__BADINSTRP
:
9225 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstrP
));
9226 register_name
= "BadInstrP";
9228 case CP0_REG08__BADINSTRX
:
9230 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstrX
));
9231 tcg_gen_andi_tl(arg
, arg
, ~0xffff);
9232 register_name
= "BadInstrX";
9235 goto cp0_unimplemented
;
9238 case CP0_REGISTER_09
:
9240 case CP0_REG09__COUNT
:
9241 /* Mark as an IO operation because we read the time. */
9242 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
9245 gen_helper_mfc0_count(arg
, cpu_env
);
9247 * Break the TB to be able to take timer interrupts immediately
9248 * after reading count. DISAS_STOP isn't sufficient, we need to
9249 * ensure we break completely out of translated code.
9251 gen_save_pc(ctx
->base
.pc_next
+ 4);
9252 ctx
->base
.is_jmp
= DISAS_EXIT
;
9253 register_name
= "Count";
9255 case CP0_REG09__SAARI
:
9256 CP0_CHECK(ctx
->saar
);
9257 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SAARI
));
9258 register_name
= "SAARI";
9260 case CP0_REG09__SAAR
:
9261 CP0_CHECK(ctx
->saar
);
9262 gen_helper_dmfc0_saar(arg
, cpu_env
);
9263 register_name
= "SAAR";
9266 goto cp0_unimplemented
;
9269 case CP0_REGISTER_10
:
9271 case CP0_REG10__ENTRYHI
:
9272 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryHi
));
9273 register_name
= "EntryHi";
9276 goto cp0_unimplemented
;
9279 case CP0_REGISTER_11
:
9281 case CP0_REG11__COMPARE
:
9282 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Compare
));
9283 register_name
= "Compare";
9285 /* 6,7 are implementation dependent */
9287 goto cp0_unimplemented
;
9290 case CP0_REGISTER_12
:
9292 case CP0_REG12__STATUS
:
9293 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Status
));
9294 register_name
= "Status";
9296 case CP0_REG12__INTCTL
:
9297 check_insn(ctx
, ISA_MIPS32R2
);
9298 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_IntCtl
));
9299 register_name
= "IntCtl";
9301 case CP0_REG12__SRSCTL
:
9302 check_insn(ctx
, ISA_MIPS32R2
);
9303 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
9304 register_name
= "SRSCtl";
9306 case CP0_REG12__SRSMAP
:
9307 check_insn(ctx
, ISA_MIPS32R2
);
9308 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
9309 register_name
= "SRSMap";
9312 goto cp0_unimplemented
;
9315 case CP0_REGISTER_13
:
9317 case CP0_REG13__CAUSE
:
9318 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Cause
));
9319 register_name
= "Cause";
9322 goto cp0_unimplemented
;
9325 case CP0_REGISTER_14
:
9327 case CP0_REG14__EPC
:
9328 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
9329 register_name
= "EPC";
9332 goto cp0_unimplemented
;
9335 case CP0_REGISTER_15
:
9337 case CP0_REG15__PRID
:
9338 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PRid
));
9339 register_name
= "PRid";
9341 case CP0_REG15__EBASE
:
9342 check_insn(ctx
, ISA_MIPS32R2
);
9343 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EBase
));
9344 register_name
= "EBase";
9346 case CP0_REG15__CMGCRBASE
:
9347 check_insn(ctx
, ISA_MIPS32R2
);
9348 CP0_CHECK(ctx
->cmgcr
);
9349 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_CMGCRBase
));
9350 register_name
= "CMGCRBase";
9353 goto cp0_unimplemented
;
9356 case CP0_REGISTER_16
:
9358 case CP0_REG16__CONFIG
:
9359 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config0
));
9360 register_name
= "Config";
9362 case CP0_REG16__CONFIG1
:
9363 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config1
));
9364 register_name
= "Config1";
9366 case CP0_REG16__CONFIG2
:
9367 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config2
));
9368 register_name
= "Config2";
9370 case CP0_REG16__CONFIG3
:
9371 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config3
));
9372 register_name
= "Config3";
9374 case CP0_REG16__CONFIG4
:
9375 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config4
));
9376 register_name
= "Config4";
9378 case CP0_REG16__CONFIG5
:
9379 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config5
));
9380 register_name
= "Config5";
9382 /* 6,7 are implementation dependent */
9383 case CP0_REG16__CONFIG6
:
9384 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config6
));
9385 register_name
= "Config6";
9387 case CP0_REG16__CONFIG7
:
9388 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config7
));
9389 register_name
= "Config7";
9392 goto cp0_unimplemented
;
9395 case CP0_REGISTER_17
:
9397 case CP0_REG17__LLADDR
:
9398 gen_helper_dmfc0_lladdr(arg
, cpu_env
);
9399 register_name
= "LLAddr";
9401 case CP0_REG17__MAAR
:
9402 CP0_CHECK(ctx
->mrp
);
9403 gen_helper_dmfc0_maar(arg
, cpu_env
);
9404 register_name
= "MAAR";
9406 case CP0_REG17__MAARI
:
9407 CP0_CHECK(ctx
->mrp
);
9408 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_MAARI
));
9409 register_name
= "MAARI";
9412 goto cp0_unimplemented
;
9415 case CP0_REGISTER_18
:
9417 case CP0_REG18__WATCHLO0
:
9418 case CP0_REG18__WATCHLO1
:
9419 case CP0_REG18__WATCHLO2
:
9420 case CP0_REG18__WATCHLO3
:
9421 case CP0_REG18__WATCHLO4
:
9422 case CP0_REG18__WATCHLO5
:
9423 case CP0_REG18__WATCHLO6
:
9424 case CP0_REG18__WATCHLO7
:
9425 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
9426 gen_helper_1e0i(dmfc0_watchlo
, arg
, sel
);
9427 register_name
= "WatchLo";
9430 goto cp0_unimplemented
;
9433 case CP0_REGISTER_19
:
9435 case CP0_REG19__WATCHHI0
:
9436 case CP0_REG19__WATCHHI1
:
9437 case CP0_REG19__WATCHHI2
:
9438 case CP0_REG19__WATCHHI3
:
9439 case CP0_REG19__WATCHHI4
:
9440 case CP0_REG19__WATCHHI5
:
9441 case CP0_REG19__WATCHHI6
:
9442 case CP0_REG19__WATCHHI7
:
9443 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
9444 gen_helper_1e0i(dmfc0_watchhi
, arg
, sel
);
9445 register_name
= "WatchHi";
9448 goto cp0_unimplemented
;
9451 case CP0_REGISTER_20
:
9453 case CP0_REG20__XCONTEXT
:
9454 check_insn(ctx
, ISA_MIPS3
);
9455 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_XContext
));
9456 register_name
= "XContext";
9459 goto cp0_unimplemented
;
9462 case CP0_REGISTER_21
:
9463 /* Officially reserved, but sel 0 is used for R1x000 framemask */
9464 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS32R6
));
9467 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Framemask
));
9468 register_name
= "Framemask";
9471 goto cp0_unimplemented
;
9474 case CP0_REGISTER_22
:
9475 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
9476 register_name
= "'Diagnostic"; /* implementation dependent */
9478 case CP0_REGISTER_23
:
9480 case CP0_REG23__DEBUG
:
9481 gen_helper_mfc0_debug(arg
, cpu_env
); /* EJTAG support */
9482 register_name
= "Debug";
9484 case CP0_REG23__TRACECONTROL
:
9485 /* PDtrace support */
9486 /* gen_helper_dmfc0_tracecontrol(arg, cpu_env); */
9487 register_name
= "TraceControl";
9488 goto cp0_unimplemented
;
9489 case CP0_REG23__TRACECONTROL2
:
9490 /* PDtrace support */
9491 /* gen_helper_dmfc0_tracecontrol2(arg, cpu_env); */
9492 register_name
= "TraceControl2";
9493 goto cp0_unimplemented
;
9494 case CP0_REG23__USERTRACEDATA1
:
9495 /* PDtrace support */
9496 /* gen_helper_dmfc0_usertracedata1(arg, cpu_env);*/
9497 register_name
= "UserTraceData1";
9498 goto cp0_unimplemented
;
9499 case CP0_REG23__TRACEIBPC
:
9500 /* PDtrace support */
9501 /* gen_helper_dmfc0_traceibpc(arg, cpu_env); */
9502 register_name
= "TraceIBPC";
9503 goto cp0_unimplemented
;
9504 case CP0_REG23__TRACEDBPC
:
9505 /* PDtrace support */
9506 /* gen_helper_dmfc0_tracedbpc(arg, cpu_env); */
9507 register_name
= "TraceDBPC";
9508 goto cp0_unimplemented
;
9510 goto cp0_unimplemented
;
9513 case CP0_REGISTER_24
:
9515 case CP0_REG24__DEPC
:
9517 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
9518 register_name
= "DEPC";
9521 goto cp0_unimplemented
;
9524 case CP0_REGISTER_25
:
9526 case CP0_REG25__PERFCTL0
:
9527 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Performance0
));
9528 register_name
= "Performance0";
9530 case CP0_REG25__PERFCNT0
:
9531 /* gen_helper_dmfc0_performance1(arg); */
9532 register_name
= "Performance1";
9533 goto cp0_unimplemented
;
9534 case CP0_REG25__PERFCTL1
:
9535 /* gen_helper_dmfc0_performance2(arg); */
9536 register_name
= "Performance2";
9537 goto cp0_unimplemented
;
9538 case CP0_REG25__PERFCNT1
:
9539 /* gen_helper_dmfc0_performance3(arg); */
9540 register_name
= "Performance3";
9541 goto cp0_unimplemented
;
9542 case CP0_REG25__PERFCTL2
:
9543 /* gen_helper_dmfc0_performance4(arg); */
9544 register_name
= "Performance4";
9545 goto cp0_unimplemented
;
9546 case CP0_REG25__PERFCNT2
:
9547 /* gen_helper_dmfc0_performance5(arg); */
9548 register_name
= "Performance5";
9549 goto cp0_unimplemented
;
9550 case CP0_REG25__PERFCTL3
:
9551 /* gen_helper_dmfc0_performance6(arg); */
9552 register_name
= "Performance6";
9553 goto cp0_unimplemented
;
9554 case CP0_REG25__PERFCNT3
:
9555 /* gen_helper_dmfc0_performance7(arg); */
9556 register_name
= "Performance7";
9557 goto cp0_unimplemented
;
9559 goto cp0_unimplemented
;
9562 case CP0_REGISTER_26
:
9564 case CP0_REG26__ERRCTL
:
9565 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_ErrCtl
));
9566 register_name
= "ErrCtl";
9569 goto cp0_unimplemented
;
9572 case CP0_REGISTER_27
:
9575 case CP0_REG27__CACHERR
:
9576 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
9577 register_name
= "CacheErr";
9580 goto cp0_unimplemented
;
9583 case CP0_REGISTER_28
:
9585 case CP0_REG28__TAGLO
:
9586 case CP0_REG28__TAGLO1
:
9587 case CP0_REG28__TAGLO2
:
9588 case CP0_REG28__TAGLO3
:
9589 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagLo
));
9590 register_name
= "TagLo";
9592 case CP0_REG28__DATALO
:
9593 case CP0_REG28__DATALO1
:
9594 case CP0_REG28__DATALO2
:
9595 case CP0_REG28__DATALO3
:
9596 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataLo
));
9597 register_name
= "DataLo";
9600 goto cp0_unimplemented
;
9603 case CP0_REGISTER_29
:
9605 case CP0_REG29__TAGHI
:
9606 case CP0_REG29__TAGHI1
:
9607 case CP0_REG29__TAGHI2
:
9608 case CP0_REG29__TAGHI3
:
9609 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagHi
));
9610 register_name
= "TagHi";
9612 case CP0_REG29__DATAHI
:
9613 case CP0_REG29__DATAHI1
:
9614 case CP0_REG29__DATAHI2
:
9615 case CP0_REG29__DATAHI3
:
9616 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataHi
));
9617 register_name
= "DataHi";
9620 goto cp0_unimplemented
;
9623 case CP0_REGISTER_30
:
9625 case CP0_REG30__ERROREPC
:
9626 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
9627 register_name
= "ErrorEPC";
9630 goto cp0_unimplemented
;
9633 case CP0_REGISTER_31
:
9635 case CP0_REG31__DESAVE
:
9637 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
9638 register_name
= "DESAVE";
9640 case CP0_REG31__KSCRATCH1
:
9641 case CP0_REG31__KSCRATCH2
:
9642 case CP0_REG31__KSCRATCH3
:
9643 case CP0_REG31__KSCRATCH4
:
9644 case CP0_REG31__KSCRATCH5
:
9645 case CP0_REG31__KSCRATCH6
:
9646 CP0_CHECK(ctx
->kscrexist
& (1 << sel
));
9647 tcg_gen_ld_tl(arg
, cpu_env
,
9648 offsetof(CPUMIPSState
, CP0_KScratch
[sel
- 2]));
9649 register_name
= "KScratch";
9652 goto cp0_unimplemented
;
9656 goto cp0_unimplemented
;
9658 trace_mips_translate_c0("dmfc0", register_name
, reg
, sel
);
9662 qemu_log_mask(LOG_UNIMP
, "dmfc0 %s (reg %d sel %d)\n",
9663 register_name
, reg
, sel
);
9664 gen_mfc0_unimplemented(ctx
, arg
);
9667 static void gen_dmtc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
9669 const char *register_name
= "invalid";
9672 check_insn(ctx
, ISA_MIPS32
);
9675 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
9680 case CP0_REGISTER_00
:
9682 case CP0_REG00__INDEX
:
9683 gen_helper_mtc0_index(cpu_env
, arg
);
9684 register_name
= "Index";
9686 case CP0_REG00__MVPCONTROL
:
9687 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9688 gen_helper_mtc0_mvpcontrol(cpu_env
, arg
);
9689 register_name
= "MVPControl";
9691 case CP0_REG00__MVPCONF0
:
9692 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9694 register_name
= "MVPConf0";
9696 case CP0_REG00__MVPCONF1
:
9697 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9699 register_name
= "MVPConf1";
9701 case CP0_REG00__VPCONTROL
:
9704 register_name
= "VPControl";
9707 goto cp0_unimplemented
;
9710 case CP0_REGISTER_01
:
9712 case CP0_REG01__RANDOM
:
9714 register_name
= "Random";
9716 case CP0_REG01__VPECONTROL
:
9717 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9718 gen_helper_mtc0_vpecontrol(cpu_env
, arg
);
9719 register_name
= "VPEControl";
9721 case CP0_REG01__VPECONF0
:
9722 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9723 gen_helper_mtc0_vpeconf0(cpu_env
, arg
);
9724 register_name
= "VPEConf0";
9726 case CP0_REG01__VPECONF1
:
9727 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9728 gen_helper_mtc0_vpeconf1(cpu_env
, arg
);
9729 register_name
= "VPEConf1";
9731 case CP0_REG01__YQMASK
:
9732 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9733 gen_helper_mtc0_yqmask(cpu_env
, arg
);
9734 register_name
= "YQMask";
9736 case CP0_REG01__VPESCHEDULE
:
9737 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9738 tcg_gen_st_tl(arg
, cpu_env
,
9739 offsetof(CPUMIPSState
, CP0_VPESchedule
));
9740 register_name
= "VPESchedule";
9742 case CP0_REG01__VPESCHEFBACK
:
9743 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9744 tcg_gen_st_tl(arg
, cpu_env
,
9745 offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
9746 register_name
= "VPEScheFBack";
9748 case CP0_REG01__VPEOPT
:
9749 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9750 gen_helper_mtc0_vpeopt(cpu_env
, arg
);
9751 register_name
= "VPEOpt";
9754 goto cp0_unimplemented
;
9757 case CP0_REGISTER_02
:
9759 case CP0_REG02__ENTRYLO0
:
9760 gen_helper_dmtc0_entrylo0(cpu_env
, arg
);
9761 register_name
= "EntryLo0";
9763 case CP0_REG02__TCSTATUS
:
9764 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9765 gen_helper_mtc0_tcstatus(cpu_env
, arg
);
9766 register_name
= "TCStatus";
9768 case CP0_REG02__TCBIND
:
9769 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9770 gen_helper_mtc0_tcbind(cpu_env
, arg
);
9771 register_name
= "TCBind";
9773 case CP0_REG02__TCRESTART
:
9774 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9775 gen_helper_mtc0_tcrestart(cpu_env
, arg
);
9776 register_name
= "TCRestart";
9778 case CP0_REG02__TCHALT
:
9779 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9780 gen_helper_mtc0_tchalt(cpu_env
, arg
);
9781 register_name
= "TCHalt";
9783 case CP0_REG02__TCCONTEXT
:
9784 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9785 gen_helper_mtc0_tccontext(cpu_env
, arg
);
9786 register_name
= "TCContext";
9788 case CP0_REG02__TCSCHEDULE
:
9789 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9790 gen_helper_mtc0_tcschedule(cpu_env
, arg
);
9791 register_name
= "TCSchedule";
9793 case CP0_REG02__TCSCHEFBACK
:
9794 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9795 gen_helper_mtc0_tcschefback(cpu_env
, arg
);
9796 register_name
= "TCScheFBack";
9799 goto cp0_unimplemented
;
9802 case CP0_REGISTER_03
:
9804 case CP0_REG03__ENTRYLO1
:
9805 gen_helper_dmtc0_entrylo1(cpu_env
, arg
);
9806 register_name
= "EntryLo1";
9808 case CP0_REG03__GLOBALNUM
:
9811 register_name
= "GlobalNumber";
9814 goto cp0_unimplemented
;
9817 case CP0_REGISTER_04
:
9819 case CP0_REG04__CONTEXT
:
9820 gen_helper_mtc0_context(cpu_env
, arg
);
9821 register_name
= "Context";
9823 case CP0_REG04__CONTEXTCONFIG
:
9825 /* gen_helper_dmtc0_contextconfig(arg); */
9826 register_name
= "ContextConfig";
9827 goto cp0_unimplemented
;
9828 case CP0_REG04__USERLOCAL
:
9829 CP0_CHECK(ctx
->ulri
);
9830 tcg_gen_st_tl(arg
, cpu_env
,
9831 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
9832 register_name
= "UserLocal";
9834 case CP0_REG04__MMID
:
9836 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_MemoryMapID
));
9837 register_name
= "MMID";
9840 goto cp0_unimplemented
;
9843 case CP0_REGISTER_05
:
9845 case CP0_REG05__PAGEMASK
:
9846 gen_helper_mtc0_pagemask(cpu_env
, arg
);
9847 register_name
= "PageMask";
9849 case CP0_REG05__PAGEGRAIN
:
9850 check_insn(ctx
, ISA_MIPS32R2
);
9851 gen_helper_mtc0_pagegrain(cpu_env
, arg
);
9852 register_name
= "PageGrain";
9854 case CP0_REG05__SEGCTL0
:
9856 gen_helper_mtc0_segctl0(cpu_env
, arg
);
9857 register_name
= "SegCtl0";
9859 case CP0_REG05__SEGCTL1
:
9861 gen_helper_mtc0_segctl1(cpu_env
, arg
);
9862 register_name
= "SegCtl1";
9864 case CP0_REG05__SEGCTL2
:
9866 gen_helper_mtc0_segctl2(cpu_env
, arg
);
9867 register_name
= "SegCtl2";
9869 case CP0_REG05__PWBASE
:
9871 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_PWBase
));
9872 register_name
= "PWBase";
9874 case CP0_REG05__PWFIELD
:
9876 gen_helper_mtc0_pwfield(cpu_env
, arg
);
9877 register_name
= "PWField";
9879 case CP0_REG05__PWSIZE
:
9881 gen_helper_mtc0_pwsize(cpu_env
, arg
);
9882 register_name
= "PWSize";
9885 goto cp0_unimplemented
;
9888 case CP0_REGISTER_06
:
9890 case CP0_REG06__WIRED
:
9891 gen_helper_mtc0_wired(cpu_env
, arg
);
9892 register_name
= "Wired";
9894 case CP0_REG06__SRSCONF0
:
9895 check_insn(ctx
, ISA_MIPS32R2
);
9896 gen_helper_mtc0_srsconf0(cpu_env
, arg
);
9897 register_name
= "SRSConf0";
9899 case CP0_REG06__SRSCONF1
:
9900 check_insn(ctx
, ISA_MIPS32R2
);
9901 gen_helper_mtc0_srsconf1(cpu_env
, arg
);
9902 register_name
= "SRSConf1";
9904 case CP0_REG06__SRSCONF2
:
9905 check_insn(ctx
, ISA_MIPS32R2
);
9906 gen_helper_mtc0_srsconf2(cpu_env
, arg
);
9907 register_name
= "SRSConf2";
9909 case CP0_REG06__SRSCONF3
:
9910 check_insn(ctx
, ISA_MIPS32R2
);
9911 gen_helper_mtc0_srsconf3(cpu_env
, arg
);
9912 register_name
= "SRSConf3";
9914 case CP0_REG06__SRSCONF4
:
9915 check_insn(ctx
, ISA_MIPS32R2
);
9916 gen_helper_mtc0_srsconf4(cpu_env
, arg
);
9917 register_name
= "SRSConf4";
9919 case CP0_REG06__PWCTL
:
9921 gen_helper_mtc0_pwctl(cpu_env
, arg
);
9922 register_name
= "PWCtl";
9925 goto cp0_unimplemented
;
9928 case CP0_REGISTER_07
:
9930 case CP0_REG07__HWRENA
:
9931 check_insn(ctx
, ISA_MIPS32R2
);
9932 gen_helper_mtc0_hwrena(cpu_env
, arg
);
9933 ctx
->base
.is_jmp
= DISAS_STOP
;
9934 register_name
= "HWREna";
9937 goto cp0_unimplemented
;
9940 case CP0_REGISTER_08
:
9942 case CP0_REG08__BADVADDR
:
9944 register_name
= "BadVAddr";
9946 case CP0_REG08__BADINSTR
:
9948 register_name
= "BadInstr";
9950 case CP0_REG08__BADINSTRP
:
9952 register_name
= "BadInstrP";
9954 case CP0_REG08__BADINSTRX
:
9956 register_name
= "BadInstrX";
9959 goto cp0_unimplemented
;
9962 case CP0_REGISTER_09
:
9964 case CP0_REG09__COUNT
:
9965 gen_helper_mtc0_count(cpu_env
, arg
);
9966 register_name
= "Count";
9968 case CP0_REG09__SAARI
:
9969 CP0_CHECK(ctx
->saar
);
9970 gen_helper_mtc0_saari(cpu_env
, arg
);
9971 register_name
= "SAARI";
9973 case CP0_REG09__SAAR
:
9974 CP0_CHECK(ctx
->saar
);
9975 gen_helper_mtc0_saar(cpu_env
, arg
);
9976 register_name
= "SAAR";
9979 goto cp0_unimplemented
;
9981 /* Stop translation as we may have switched the execution mode */
9982 ctx
->base
.is_jmp
= DISAS_STOP
;
9984 case CP0_REGISTER_10
:
9986 case CP0_REG10__ENTRYHI
:
9987 gen_helper_mtc0_entryhi(cpu_env
, arg
);
9988 register_name
= "EntryHi";
9991 goto cp0_unimplemented
;
9994 case CP0_REGISTER_11
:
9996 case CP0_REG11__COMPARE
:
9997 gen_helper_mtc0_compare(cpu_env
, arg
);
9998 register_name
= "Compare";
10000 /* 6,7 are implementation dependent */
10002 goto cp0_unimplemented
;
10004 /* Stop translation as we may have switched the execution mode */
10005 ctx
->base
.is_jmp
= DISAS_STOP
;
10007 case CP0_REGISTER_12
:
10009 case CP0_REG12__STATUS
:
10010 save_cpu_state(ctx
, 1);
10011 gen_helper_mtc0_status(cpu_env
, arg
);
10012 /* DISAS_STOP isn't good enough here, hflags may have changed. */
10013 gen_save_pc(ctx
->base
.pc_next
+ 4);
10014 ctx
->base
.is_jmp
= DISAS_EXIT
;
10015 register_name
= "Status";
10017 case CP0_REG12__INTCTL
:
10018 check_insn(ctx
, ISA_MIPS32R2
);
10019 gen_helper_mtc0_intctl(cpu_env
, arg
);
10020 /* Stop translation as we may have switched the execution mode */
10021 ctx
->base
.is_jmp
= DISAS_STOP
;
10022 register_name
= "IntCtl";
10024 case CP0_REG12__SRSCTL
:
10025 check_insn(ctx
, ISA_MIPS32R2
);
10026 gen_helper_mtc0_srsctl(cpu_env
, arg
);
10027 /* Stop translation as we may have switched the execution mode */
10028 ctx
->base
.is_jmp
= DISAS_STOP
;
10029 register_name
= "SRSCtl";
10031 case CP0_REG12__SRSMAP
:
10032 check_insn(ctx
, ISA_MIPS32R2
);
10033 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
10034 /* Stop translation as we may have switched the execution mode */
10035 ctx
->base
.is_jmp
= DISAS_STOP
;
10036 register_name
= "SRSMap";
10039 goto cp0_unimplemented
;
10042 case CP0_REGISTER_13
:
10044 case CP0_REG13__CAUSE
:
10045 save_cpu_state(ctx
, 1);
10046 gen_helper_mtc0_cause(cpu_env
, arg
);
10048 * Stop translation as we may have triggered an interrupt.
10049 * DISAS_STOP isn't sufficient, we need to ensure we break out of
10050 * translated code to check for pending interrupts.
10052 gen_save_pc(ctx
->base
.pc_next
+ 4);
10053 ctx
->base
.is_jmp
= DISAS_EXIT
;
10054 register_name
= "Cause";
10057 goto cp0_unimplemented
;
10060 case CP0_REGISTER_14
:
10062 case CP0_REG14__EPC
:
10063 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
10064 register_name
= "EPC";
10067 goto cp0_unimplemented
;
10070 case CP0_REGISTER_15
:
10072 case CP0_REG15__PRID
:
10074 register_name
= "PRid";
10076 case CP0_REG15__EBASE
:
10077 check_insn(ctx
, ISA_MIPS32R2
);
10078 gen_helper_mtc0_ebase(cpu_env
, arg
);
10079 register_name
= "EBase";
10082 goto cp0_unimplemented
;
10085 case CP0_REGISTER_16
:
10087 case CP0_REG16__CONFIG
:
10088 gen_helper_mtc0_config0(cpu_env
, arg
);
10089 register_name
= "Config";
10090 /* Stop translation as we may have switched the execution mode */
10091 ctx
->base
.is_jmp
= DISAS_STOP
;
10093 case CP0_REG16__CONFIG1
:
10094 /* ignored, read only */
10095 register_name
= "Config1";
10097 case CP0_REG16__CONFIG2
:
10098 gen_helper_mtc0_config2(cpu_env
, arg
);
10099 register_name
= "Config2";
10100 /* Stop translation as we may have switched the execution mode */
10101 ctx
->base
.is_jmp
= DISAS_STOP
;
10103 case CP0_REG16__CONFIG3
:
10104 gen_helper_mtc0_config3(cpu_env
, arg
);
10105 register_name
= "Config3";
10106 /* Stop translation as we may have switched the execution mode */
10107 ctx
->base
.is_jmp
= DISAS_STOP
;
10109 case CP0_REG16__CONFIG4
:
10110 /* currently ignored */
10111 register_name
= "Config4";
10113 case CP0_REG16__CONFIG5
:
10114 gen_helper_mtc0_config5(cpu_env
, arg
);
10115 register_name
= "Config5";
10116 /* Stop translation as we may have switched the execution mode */
10117 ctx
->base
.is_jmp
= DISAS_STOP
;
10119 /* 6,7 are implementation dependent */
10121 register_name
= "Invalid config selector";
10122 goto cp0_unimplemented
;
10125 case CP0_REGISTER_17
:
10127 case CP0_REG17__LLADDR
:
10128 gen_helper_mtc0_lladdr(cpu_env
, arg
);
10129 register_name
= "LLAddr";
10131 case CP0_REG17__MAAR
:
10132 CP0_CHECK(ctx
->mrp
);
10133 gen_helper_mtc0_maar(cpu_env
, arg
);
10134 register_name
= "MAAR";
10136 case CP0_REG17__MAARI
:
10137 CP0_CHECK(ctx
->mrp
);
10138 gen_helper_mtc0_maari(cpu_env
, arg
);
10139 register_name
= "MAARI";
10142 goto cp0_unimplemented
;
10145 case CP0_REGISTER_18
:
10147 case CP0_REG18__WATCHLO0
:
10148 case CP0_REG18__WATCHLO1
:
10149 case CP0_REG18__WATCHLO2
:
10150 case CP0_REG18__WATCHLO3
:
10151 case CP0_REG18__WATCHLO4
:
10152 case CP0_REG18__WATCHLO5
:
10153 case CP0_REG18__WATCHLO6
:
10154 case CP0_REG18__WATCHLO7
:
10155 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
10156 gen_helper_0e1i(mtc0_watchlo
, arg
, sel
);
10157 register_name
= "WatchLo";
10160 goto cp0_unimplemented
;
10163 case CP0_REGISTER_19
:
10165 case CP0_REG19__WATCHHI0
:
10166 case CP0_REG19__WATCHHI1
:
10167 case CP0_REG19__WATCHHI2
:
10168 case CP0_REG19__WATCHHI3
:
10169 case CP0_REG19__WATCHHI4
:
10170 case CP0_REG19__WATCHHI5
:
10171 case CP0_REG19__WATCHHI6
:
10172 case CP0_REG19__WATCHHI7
:
10173 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
10174 gen_helper_0e1i(mtc0_watchhi
, arg
, sel
);
10175 register_name
= "WatchHi";
10178 goto cp0_unimplemented
;
10181 case CP0_REGISTER_20
:
10183 case CP0_REG20__XCONTEXT
:
10184 check_insn(ctx
, ISA_MIPS3
);
10185 gen_helper_mtc0_xcontext(cpu_env
, arg
);
10186 register_name
= "XContext";
10189 goto cp0_unimplemented
;
10192 case CP0_REGISTER_21
:
10193 /* Officially reserved, but sel 0 is used for R1x000 framemask */
10194 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS32R6
));
10197 gen_helper_mtc0_framemask(cpu_env
, arg
);
10198 register_name
= "Framemask";
10201 goto cp0_unimplemented
;
10204 case CP0_REGISTER_22
:
10206 register_name
= "Diagnostic"; /* implementation dependent */
10208 case CP0_REGISTER_23
:
10210 case CP0_REG23__DEBUG
:
10211 gen_helper_mtc0_debug(cpu_env
, arg
); /* EJTAG support */
10212 /* DISAS_STOP isn't good enough here, hflags may have changed. */
10213 gen_save_pc(ctx
->base
.pc_next
+ 4);
10214 ctx
->base
.is_jmp
= DISAS_EXIT
;
10215 register_name
= "Debug";
10217 case CP0_REG23__TRACECONTROL
:
10218 /* PDtrace support */
10219 /* gen_helper_mtc0_tracecontrol(cpu_env, arg); */
10220 /* Stop translation as we may have switched the execution mode */
10221 ctx
->base
.is_jmp
= DISAS_STOP
;
10222 register_name
= "TraceControl";
10223 goto cp0_unimplemented
;
10224 case CP0_REG23__TRACECONTROL2
:
10225 /* PDtrace support */
10226 /* gen_helper_mtc0_tracecontrol2(cpu_env, arg); */
10227 /* Stop translation as we may have switched the execution mode */
10228 ctx
->base
.is_jmp
= DISAS_STOP
;
10229 register_name
= "TraceControl2";
10230 goto cp0_unimplemented
;
10231 case CP0_REG23__USERTRACEDATA1
:
10232 /* PDtrace support */
10233 /* gen_helper_mtc0_usertracedata1(cpu_env, arg);*/
10234 /* Stop translation as we may have switched the execution mode */
10235 ctx
->base
.is_jmp
= DISAS_STOP
;
10236 register_name
= "UserTraceData1";
10237 goto cp0_unimplemented
;
10238 case CP0_REG23__TRACEIBPC
:
10239 /* PDtrace support */
10240 /* gen_helper_mtc0_traceibpc(cpu_env, arg); */
10241 /* Stop translation as we may have switched the execution mode */
10242 ctx
->base
.is_jmp
= DISAS_STOP
;
10243 register_name
= "TraceIBPC";
10244 goto cp0_unimplemented
;
10245 case CP0_REG23__TRACEDBPC
:
10246 /* PDtrace support */
10247 /* gen_helper_mtc0_tracedbpc(cpu_env, arg); */
10248 /* Stop translation as we may have switched the execution mode */
10249 ctx
->base
.is_jmp
= DISAS_STOP
;
10250 register_name
= "TraceDBPC";
10251 goto cp0_unimplemented
;
10253 goto cp0_unimplemented
;
10256 case CP0_REGISTER_24
:
10258 case CP0_REG24__DEPC
:
10259 /* EJTAG support */
10260 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
10261 register_name
= "DEPC";
10264 goto cp0_unimplemented
;
10267 case CP0_REGISTER_25
:
10269 case CP0_REG25__PERFCTL0
:
10270 gen_helper_mtc0_performance0(cpu_env
, arg
);
10271 register_name
= "Performance0";
10273 case CP0_REG25__PERFCNT0
:
10274 /* gen_helper_mtc0_performance1(cpu_env, arg); */
10275 register_name
= "Performance1";
10276 goto cp0_unimplemented
;
10277 case CP0_REG25__PERFCTL1
:
10278 /* gen_helper_mtc0_performance2(cpu_env, arg); */
10279 register_name
= "Performance2";
10280 goto cp0_unimplemented
;
10281 case CP0_REG25__PERFCNT1
:
10282 /* gen_helper_mtc0_performance3(cpu_env, arg); */
10283 register_name
= "Performance3";
10284 goto cp0_unimplemented
;
10285 case CP0_REG25__PERFCTL2
:
10286 /* gen_helper_mtc0_performance4(cpu_env, arg); */
10287 register_name
= "Performance4";
10288 goto cp0_unimplemented
;
10289 case CP0_REG25__PERFCNT2
:
10290 /* gen_helper_mtc0_performance5(cpu_env, arg); */
10291 register_name
= "Performance5";
10292 goto cp0_unimplemented
;
10293 case CP0_REG25__PERFCTL3
:
10294 /* gen_helper_mtc0_performance6(cpu_env, arg); */
10295 register_name
= "Performance6";
10296 goto cp0_unimplemented
;
10297 case CP0_REG25__PERFCNT3
:
10298 /* gen_helper_mtc0_performance7(cpu_env, arg); */
10299 register_name
= "Performance7";
10300 goto cp0_unimplemented
;
10302 goto cp0_unimplemented
;
10305 case CP0_REGISTER_26
:
10307 case CP0_REG26__ERRCTL
:
10308 gen_helper_mtc0_errctl(cpu_env
, arg
);
10309 ctx
->base
.is_jmp
= DISAS_STOP
;
10310 register_name
= "ErrCtl";
10313 goto cp0_unimplemented
;
10316 case CP0_REGISTER_27
:
10318 case CP0_REG27__CACHERR
:
10320 register_name
= "CacheErr";
10323 goto cp0_unimplemented
;
10326 case CP0_REGISTER_28
:
10328 case CP0_REG28__TAGLO
:
10329 case CP0_REG28__TAGLO1
:
10330 case CP0_REG28__TAGLO2
:
10331 case CP0_REG28__TAGLO3
:
10332 gen_helper_mtc0_taglo(cpu_env
, arg
);
10333 register_name
= "TagLo";
10335 case CP0_REG28__DATALO
:
10336 case CP0_REG28__DATALO1
:
10337 case CP0_REG28__DATALO2
:
10338 case CP0_REG28__DATALO3
:
10339 gen_helper_mtc0_datalo(cpu_env
, arg
);
10340 register_name
= "DataLo";
10343 goto cp0_unimplemented
;
10346 case CP0_REGISTER_29
:
10348 case CP0_REG29__TAGHI
:
10349 case CP0_REG29__TAGHI1
:
10350 case CP0_REG29__TAGHI2
:
10351 case CP0_REG29__TAGHI3
:
10352 gen_helper_mtc0_taghi(cpu_env
, arg
);
10353 register_name
= "TagHi";
10355 case CP0_REG29__DATAHI
:
10356 case CP0_REG29__DATAHI1
:
10357 case CP0_REG29__DATAHI2
:
10358 case CP0_REG29__DATAHI3
:
10359 gen_helper_mtc0_datahi(cpu_env
, arg
);
10360 register_name
= "DataHi";
10363 register_name
= "invalid sel";
10364 goto cp0_unimplemented
;
10367 case CP0_REGISTER_30
:
10369 case CP0_REG30__ERROREPC
:
10370 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
10371 register_name
= "ErrorEPC";
10374 goto cp0_unimplemented
;
10377 case CP0_REGISTER_31
:
10379 case CP0_REG31__DESAVE
:
10380 /* EJTAG support */
10381 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
10382 register_name
= "DESAVE";
10384 case CP0_REG31__KSCRATCH1
:
10385 case CP0_REG31__KSCRATCH2
:
10386 case CP0_REG31__KSCRATCH3
:
10387 case CP0_REG31__KSCRATCH4
:
10388 case CP0_REG31__KSCRATCH5
:
10389 case CP0_REG31__KSCRATCH6
:
10390 CP0_CHECK(ctx
->kscrexist
& (1 << sel
));
10391 tcg_gen_st_tl(arg
, cpu_env
,
10392 offsetof(CPUMIPSState
, CP0_KScratch
[sel
- 2]));
10393 register_name
= "KScratch";
10396 goto cp0_unimplemented
;
10400 goto cp0_unimplemented
;
10402 trace_mips_translate_c0("dmtc0", register_name
, reg
, sel
);
10404 /* For simplicity assume that all writes can cause interrupts. */
10405 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
10407 * DISAS_STOP isn't sufficient, we need to ensure we break out of
10408 * translated code to check for pending interrupts.
10410 gen_save_pc(ctx
->base
.pc_next
+ 4);
10411 ctx
->base
.is_jmp
= DISAS_EXIT
;
10416 qemu_log_mask(LOG_UNIMP
, "dmtc0 %s (reg %d sel %d)\n",
10417 register_name
, reg
, sel
);
10419 #endif /* TARGET_MIPS64 */
10421 static void gen_mftr(CPUMIPSState
*env
, DisasContext
*ctx
, int rt
, int rd
,
10422 int u
, int sel
, int h
)
10424 int other_tc
= env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
);
10425 TCGv t0
= tcg_temp_local_new();
10427 if ((env
->CP0_VPEConf0
& (1 << CP0VPEC0_MVP
)) == 0 &&
10428 ((env
->tcs
[other_tc
].CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)) !=
10429 (env
->active_tc
.CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)))) {
10430 tcg_gen_movi_tl(t0
, -1);
10431 } else if ((env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
)) >
10432 (env
->mvp
->CP0_MVPConf0
& (0xff << CP0MVPC0_PTC
))) {
10433 tcg_gen_movi_tl(t0
, -1);
10434 } else if (u
== 0) {
10439 gen_helper_mftc0_vpecontrol(t0
, cpu_env
);
10442 gen_helper_mftc0_vpeconf0(t0
, cpu_env
);
10452 gen_helper_mftc0_tcstatus(t0
, cpu_env
);
10455 gen_helper_mftc0_tcbind(t0
, cpu_env
);
10458 gen_helper_mftc0_tcrestart(t0
, cpu_env
);
10461 gen_helper_mftc0_tchalt(t0
, cpu_env
);
10464 gen_helper_mftc0_tccontext(t0
, cpu_env
);
10467 gen_helper_mftc0_tcschedule(t0
, cpu_env
);
10470 gen_helper_mftc0_tcschefback(t0
, cpu_env
);
10473 gen_mfc0(ctx
, t0
, rt
, sel
);
10480 gen_helper_mftc0_entryhi(t0
, cpu_env
);
10483 gen_mfc0(ctx
, t0
, rt
, sel
);
10490 gen_helper_mftc0_status(t0
, cpu_env
);
10493 gen_mfc0(ctx
, t0
, rt
, sel
);
10500 gen_helper_mftc0_cause(t0
, cpu_env
);
10510 gen_helper_mftc0_epc(t0
, cpu_env
);
10520 gen_helper_mftc0_ebase(t0
, cpu_env
);
10537 gen_helper_mftc0_configx(t0
, cpu_env
, tcg_const_tl(sel
));
10547 gen_helper_mftc0_debug(t0
, cpu_env
);
10550 gen_mfc0(ctx
, t0
, rt
, sel
);
10555 gen_mfc0(ctx
, t0
, rt
, sel
);
10559 /* GPR registers. */
10561 gen_helper_1e0i(mftgpr
, t0
, rt
);
10563 /* Auxiliary CPU registers */
10567 gen_helper_1e0i(mftlo
, t0
, 0);
10570 gen_helper_1e0i(mfthi
, t0
, 0);
10573 gen_helper_1e0i(mftacx
, t0
, 0);
10576 gen_helper_1e0i(mftlo
, t0
, 1);
10579 gen_helper_1e0i(mfthi
, t0
, 1);
10582 gen_helper_1e0i(mftacx
, t0
, 1);
10585 gen_helper_1e0i(mftlo
, t0
, 2);
10588 gen_helper_1e0i(mfthi
, t0
, 2);
10591 gen_helper_1e0i(mftacx
, t0
, 2);
10594 gen_helper_1e0i(mftlo
, t0
, 3);
10597 gen_helper_1e0i(mfthi
, t0
, 3);
10600 gen_helper_1e0i(mftacx
, t0
, 3);
10603 gen_helper_mftdsp(t0
, cpu_env
);
10609 /* Floating point (COP1). */
10611 /* XXX: For now we support only a single FPU context. */
10613 TCGv_i32 fp0
= tcg_temp_new_i32();
10615 gen_load_fpr32(ctx
, fp0
, rt
);
10616 tcg_gen_ext_i32_tl(t0
, fp0
);
10617 tcg_temp_free_i32(fp0
);
10619 TCGv_i32 fp0
= tcg_temp_new_i32();
10621 gen_load_fpr32h(ctx
, fp0
, rt
);
10622 tcg_gen_ext_i32_tl(t0
, fp0
);
10623 tcg_temp_free_i32(fp0
);
10627 /* XXX: For now we support only a single FPU context. */
10628 gen_helper_1e0i(cfc1
, t0
, rt
);
10630 /* COP2: Not implemented. */
10638 trace_mips_translate_tr("mftr", rt
, u
, sel
, h
);
10639 gen_store_gpr(t0
, rd
);
10645 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt
, u
, sel
, h
);
10646 generate_exception_end(ctx
, EXCP_RI
);
10649 static void gen_mttr(CPUMIPSState
*env
, DisasContext
*ctx
, int rd
, int rt
,
10650 int u
, int sel
, int h
)
10652 int other_tc
= env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
);
10653 TCGv t0
= tcg_temp_local_new();
10655 gen_load_gpr(t0
, rt
);
10656 if ((env
->CP0_VPEConf0
& (1 << CP0VPEC0_MVP
)) == 0 &&
10657 ((env
->tcs
[other_tc
].CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)) !=
10658 (env
->active_tc
.CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)))) {
10661 } else if ((env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
)) >
10662 (env
->mvp
->CP0_MVPConf0
& (0xff << CP0MVPC0_PTC
))) {
10665 } else if (u
== 0) {
10670 gen_helper_mttc0_vpecontrol(cpu_env
, t0
);
10673 gen_helper_mttc0_vpeconf0(cpu_env
, t0
);
10683 gen_helper_mttc0_tcstatus(cpu_env
, t0
);
10686 gen_helper_mttc0_tcbind(cpu_env
, t0
);
10689 gen_helper_mttc0_tcrestart(cpu_env
, t0
);
10692 gen_helper_mttc0_tchalt(cpu_env
, t0
);
10695 gen_helper_mttc0_tccontext(cpu_env
, t0
);
10698 gen_helper_mttc0_tcschedule(cpu_env
, t0
);
10701 gen_helper_mttc0_tcschefback(cpu_env
, t0
);
10704 gen_mtc0(ctx
, t0
, rd
, sel
);
10711 gen_helper_mttc0_entryhi(cpu_env
, t0
);
10714 gen_mtc0(ctx
, t0
, rd
, sel
);
10721 gen_helper_mttc0_status(cpu_env
, t0
);
10724 gen_mtc0(ctx
, t0
, rd
, sel
);
10731 gen_helper_mttc0_cause(cpu_env
, t0
);
10741 gen_helper_mttc0_ebase(cpu_env
, t0
);
10751 gen_helper_mttc0_debug(cpu_env
, t0
);
10754 gen_mtc0(ctx
, t0
, rd
, sel
);
10759 gen_mtc0(ctx
, t0
, rd
, sel
);
10763 /* GPR registers. */
10765 gen_helper_0e1i(mttgpr
, t0
, rd
);
10767 /* Auxiliary CPU registers */
10771 gen_helper_0e1i(mttlo
, t0
, 0);
10774 gen_helper_0e1i(mtthi
, t0
, 0);
10777 gen_helper_0e1i(mttacx
, t0
, 0);
10780 gen_helper_0e1i(mttlo
, t0
, 1);
10783 gen_helper_0e1i(mtthi
, t0
, 1);
10786 gen_helper_0e1i(mttacx
, t0
, 1);
10789 gen_helper_0e1i(mttlo
, t0
, 2);
10792 gen_helper_0e1i(mtthi
, t0
, 2);
10795 gen_helper_0e1i(mttacx
, t0
, 2);
10798 gen_helper_0e1i(mttlo
, t0
, 3);
10801 gen_helper_0e1i(mtthi
, t0
, 3);
10804 gen_helper_0e1i(mttacx
, t0
, 3);
10807 gen_helper_mttdsp(cpu_env
, t0
);
10813 /* Floating point (COP1). */
10815 /* XXX: For now we support only a single FPU context. */
10817 TCGv_i32 fp0
= tcg_temp_new_i32();
10819 tcg_gen_trunc_tl_i32(fp0
, t0
);
10820 gen_store_fpr32(ctx
, fp0
, rd
);
10821 tcg_temp_free_i32(fp0
);
10823 TCGv_i32 fp0
= tcg_temp_new_i32();
10825 tcg_gen_trunc_tl_i32(fp0
, t0
);
10826 gen_store_fpr32h(ctx
, fp0
, rd
);
10827 tcg_temp_free_i32(fp0
);
10831 /* XXX: For now we support only a single FPU context. */
10833 TCGv_i32 fs_tmp
= tcg_const_i32(rd
);
10835 gen_helper_0e2i(ctc1
, t0
, fs_tmp
, rt
);
10836 tcg_temp_free_i32(fs_tmp
);
10838 /* Stop translation as we may have changed hflags */
10839 ctx
->base
.is_jmp
= DISAS_STOP
;
10841 /* COP2: Not implemented. */
10849 trace_mips_translate_tr("mttr", rd
, u
, sel
, h
);
10855 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd
, u
, sel
, h
);
10856 generate_exception_end(ctx
, EXCP_RI
);
10859 static void gen_cp0(CPUMIPSState
*env
, DisasContext
*ctx
, uint32_t opc
,
10862 const char *opn
= "ldst";
10864 check_cp0_enabled(ctx
);
10868 /* Treat as NOP. */
10871 gen_mfc0(ctx
, cpu_gpr
[rt
], rd
, ctx
->opcode
& 0x7);
10876 TCGv t0
= tcg_temp_new();
10878 gen_load_gpr(t0
, rt
);
10879 gen_mtc0(ctx
, t0
, rd
, ctx
->opcode
& 0x7);
10884 #if defined(TARGET_MIPS64)
10886 check_insn(ctx
, ISA_MIPS3
);
10888 /* Treat as NOP. */
10891 gen_dmfc0(ctx
, cpu_gpr
[rt
], rd
, ctx
->opcode
& 0x7);
10895 check_insn(ctx
, ISA_MIPS3
);
10897 TCGv t0
= tcg_temp_new();
10899 gen_load_gpr(t0
, rt
);
10900 gen_dmtc0(ctx
, t0
, rd
, ctx
->opcode
& 0x7);
10909 /* Treat as NOP. */
10912 gen_mfhc0(ctx
, cpu_gpr
[rt
], rd
, ctx
->opcode
& 0x7);
10918 TCGv t0
= tcg_temp_new();
10919 gen_load_gpr(t0
, rt
);
10920 gen_mthc0(ctx
, t0
, rd
, ctx
->opcode
& 0x7);
10926 check_cp0_enabled(ctx
);
10928 /* Treat as NOP. */
10931 gen_mftr(env
, ctx
, rt
, rd
, (ctx
->opcode
>> 5) & 1,
10932 ctx
->opcode
& 0x7, (ctx
->opcode
>> 4) & 1);
10936 check_cp0_enabled(ctx
);
10937 gen_mttr(env
, ctx
, rd
, rt
, (ctx
->opcode
>> 5) & 1,
10938 ctx
->opcode
& 0x7, (ctx
->opcode
>> 4) & 1);
10943 if (!env
->tlb
->helper_tlbwi
) {
10946 gen_helper_tlbwi(cpu_env
);
10950 if (ctx
->ie
>= 2) {
10951 if (!env
->tlb
->helper_tlbinv
) {
10954 gen_helper_tlbinv(cpu_env
);
10955 } /* treat as nop if TLBINV not supported */
10959 if (ctx
->ie
>= 2) {
10960 if (!env
->tlb
->helper_tlbinvf
) {
10963 gen_helper_tlbinvf(cpu_env
);
10964 } /* treat as nop if TLBINV not supported */
10968 if (!env
->tlb
->helper_tlbwr
) {
10971 gen_helper_tlbwr(cpu_env
);
10975 if (!env
->tlb
->helper_tlbp
) {
10978 gen_helper_tlbp(cpu_env
);
10982 if (!env
->tlb
->helper_tlbr
) {
10985 gen_helper_tlbr(cpu_env
);
10987 case OPC_ERET
: /* OPC_ERETNC */
10988 if ((ctx
->insn_flags
& ISA_MIPS32R6
) &&
10989 (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
10992 int bit_shift
= (ctx
->hflags
& MIPS_HFLAG_M16
) ? 16 : 6;
10993 if (ctx
->opcode
& (1 << bit_shift
)) {
10996 check_insn(ctx
, ISA_MIPS32R5
);
10997 gen_helper_eretnc(cpu_env
);
11001 check_insn(ctx
, ISA_MIPS2
);
11002 gen_helper_eret(cpu_env
);
11004 ctx
->base
.is_jmp
= DISAS_EXIT
;
11009 check_insn(ctx
, ISA_MIPS32
);
11010 if ((ctx
->insn_flags
& ISA_MIPS32R6
) &&
11011 (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
11014 if (!(ctx
->hflags
& MIPS_HFLAG_DM
)) {
11016 generate_exception_end(ctx
, EXCP_RI
);
11018 gen_helper_deret(cpu_env
);
11019 ctx
->base
.is_jmp
= DISAS_EXIT
;
11024 check_insn(ctx
, ISA_MIPS3
| ISA_MIPS32
);
11025 if ((ctx
->insn_flags
& ISA_MIPS32R6
) &&
11026 (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
11029 /* If we get an exception, we want to restart at next instruction */
11030 ctx
->base
.pc_next
+= 4;
11031 save_cpu_state(ctx
, 1);
11032 ctx
->base
.pc_next
-= 4;
11033 gen_helper_wait(cpu_env
);
11034 ctx
->base
.is_jmp
= DISAS_NORETURN
;
11039 generate_exception_end(ctx
, EXCP_RI
);
11042 (void)opn
; /* avoid a compiler warning */
11044 #endif /* !CONFIG_USER_ONLY */
11046 /* CP1 Branches (before delay slot) */
11047 static void gen_compute_branch1(DisasContext
*ctx
, uint32_t op
,
11048 int32_t cc
, int32_t offset
)
11050 target_ulong btarget
;
11051 TCGv_i32 t0
= tcg_temp_new_i32();
11053 if ((ctx
->insn_flags
& ISA_MIPS32R6
) && (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
11054 generate_exception_end(ctx
, EXCP_RI
);
11059 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32
);
11062 btarget
= ctx
->base
.pc_next
+ 4 + offset
;
11066 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
11067 tcg_gen_not_i32(t0
, t0
);
11068 tcg_gen_andi_i32(t0
, t0
, 1);
11069 tcg_gen_extu_i32_tl(bcond
, t0
);
11072 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
11073 tcg_gen_not_i32(t0
, t0
);
11074 tcg_gen_andi_i32(t0
, t0
, 1);
11075 tcg_gen_extu_i32_tl(bcond
, t0
);
11078 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
11079 tcg_gen_andi_i32(t0
, t0
, 1);
11080 tcg_gen_extu_i32_tl(bcond
, t0
);
11083 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
11084 tcg_gen_andi_i32(t0
, t0
, 1);
11085 tcg_gen_extu_i32_tl(bcond
, t0
);
11087 ctx
->hflags
|= MIPS_HFLAG_BL
;
11091 TCGv_i32 t1
= tcg_temp_new_i32();
11092 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
11093 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 1));
11094 tcg_gen_nand_i32(t0
, t0
, t1
);
11095 tcg_temp_free_i32(t1
);
11096 tcg_gen_andi_i32(t0
, t0
, 1);
11097 tcg_gen_extu_i32_tl(bcond
, t0
);
11102 TCGv_i32 t1
= tcg_temp_new_i32();
11103 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
11104 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 1));
11105 tcg_gen_or_i32(t0
, t0
, t1
);
11106 tcg_temp_free_i32(t1
);
11107 tcg_gen_andi_i32(t0
, t0
, 1);
11108 tcg_gen_extu_i32_tl(bcond
, t0
);
11113 TCGv_i32 t1
= tcg_temp_new_i32();
11114 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
11115 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 1));
11116 tcg_gen_and_i32(t0
, t0
, t1
);
11117 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 2));
11118 tcg_gen_and_i32(t0
, t0
, t1
);
11119 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 3));
11120 tcg_gen_nand_i32(t0
, t0
, t1
);
11121 tcg_temp_free_i32(t1
);
11122 tcg_gen_andi_i32(t0
, t0
, 1);
11123 tcg_gen_extu_i32_tl(bcond
, t0
);
11128 TCGv_i32 t1
= tcg_temp_new_i32();
11129 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
11130 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 1));
11131 tcg_gen_or_i32(t0
, t0
, t1
);
11132 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 2));
11133 tcg_gen_or_i32(t0
, t0
, t1
);
11134 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 3));
11135 tcg_gen_or_i32(t0
, t0
, t1
);
11136 tcg_temp_free_i32(t1
);
11137 tcg_gen_andi_i32(t0
, t0
, 1);
11138 tcg_gen_extu_i32_tl(bcond
, t0
);
11141 ctx
->hflags
|= MIPS_HFLAG_BC
;
11144 MIPS_INVAL("cp1 cond branch");
11145 generate_exception_end(ctx
, EXCP_RI
);
11148 ctx
->btarget
= btarget
;
11149 ctx
->hflags
|= MIPS_HFLAG_BDS32
;
11151 tcg_temp_free_i32(t0
);
11154 /* R6 CP1 Branches */
11155 static void gen_compute_branch1_r6(DisasContext
*ctx
, uint32_t op
,
11156 int32_t ft
, int32_t offset
,
11157 int delayslot_size
)
11159 target_ulong btarget
;
11160 TCGv_i64 t0
= tcg_temp_new_i64();
11162 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
11163 #ifdef MIPS_DEBUG_DISAS
11164 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
11165 "\n", ctx
->base
.pc_next
);
11167 generate_exception_end(ctx
, EXCP_RI
);
11171 gen_load_fpr64(ctx
, t0
, ft
);
11172 tcg_gen_andi_i64(t0
, t0
, 1);
11174 btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
11178 tcg_gen_xori_i64(t0
, t0
, 1);
11179 ctx
->hflags
|= MIPS_HFLAG_BC
;
11182 /* t0 already set */
11183 ctx
->hflags
|= MIPS_HFLAG_BC
;
11186 MIPS_INVAL("cp1 cond branch");
11187 generate_exception_end(ctx
, EXCP_RI
);
11191 tcg_gen_trunc_i64_tl(bcond
, t0
);
11193 ctx
->btarget
= btarget
;
11195 switch (delayslot_size
) {
11197 ctx
->hflags
|= MIPS_HFLAG_BDS16
;
11200 ctx
->hflags
|= MIPS_HFLAG_BDS32
;
11205 tcg_temp_free_i64(t0
);
11208 /* Coprocessor 1 (FPU) */
11210 #define FOP(func, fmt) (((fmt) << 21) | (func))
11213 OPC_ADD_S
= FOP(0, FMT_S
),
11214 OPC_SUB_S
= FOP(1, FMT_S
),
11215 OPC_MUL_S
= FOP(2, FMT_S
),
11216 OPC_DIV_S
= FOP(3, FMT_S
),
11217 OPC_SQRT_S
= FOP(4, FMT_S
),
11218 OPC_ABS_S
= FOP(5, FMT_S
),
11219 OPC_MOV_S
= FOP(6, FMT_S
),
11220 OPC_NEG_S
= FOP(7, FMT_S
),
11221 OPC_ROUND_L_S
= FOP(8, FMT_S
),
11222 OPC_TRUNC_L_S
= FOP(9, FMT_S
),
11223 OPC_CEIL_L_S
= FOP(10, FMT_S
),
11224 OPC_FLOOR_L_S
= FOP(11, FMT_S
),
11225 OPC_ROUND_W_S
= FOP(12, FMT_S
),
11226 OPC_TRUNC_W_S
= FOP(13, FMT_S
),
11227 OPC_CEIL_W_S
= FOP(14, FMT_S
),
11228 OPC_FLOOR_W_S
= FOP(15, FMT_S
),
11229 OPC_SEL_S
= FOP(16, FMT_S
),
11230 OPC_MOVCF_S
= FOP(17, FMT_S
),
11231 OPC_MOVZ_S
= FOP(18, FMT_S
),
11232 OPC_MOVN_S
= FOP(19, FMT_S
),
11233 OPC_SELEQZ_S
= FOP(20, FMT_S
),
11234 OPC_RECIP_S
= FOP(21, FMT_S
),
11235 OPC_RSQRT_S
= FOP(22, FMT_S
),
11236 OPC_SELNEZ_S
= FOP(23, FMT_S
),
11237 OPC_MADDF_S
= FOP(24, FMT_S
),
11238 OPC_MSUBF_S
= FOP(25, FMT_S
),
11239 OPC_RINT_S
= FOP(26, FMT_S
),
11240 OPC_CLASS_S
= FOP(27, FMT_S
),
11241 OPC_MIN_S
= FOP(28, FMT_S
),
11242 OPC_RECIP2_S
= FOP(28, FMT_S
),
11243 OPC_MINA_S
= FOP(29, FMT_S
),
11244 OPC_RECIP1_S
= FOP(29, FMT_S
),
11245 OPC_MAX_S
= FOP(30, FMT_S
),
11246 OPC_RSQRT1_S
= FOP(30, FMT_S
),
11247 OPC_MAXA_S
= FOP(31, FMT_S
),
11248 OPC_RSQRT2_S
= FOP(31, FMT_S
),
11249 OPC_CVT_D_S
= FOP(33, FMT_S
),
11250 OPC_CVT_W_S
= FOP(36, FMT_S
),
11251 OPC_CVT_L_S
= FOP(37, FMT_S
),
11252 OPC_CVT_PS_S
= FOP(38, FMT_S
),
11253 OPC_CMP_F_S
= FOP(48, FMT_S
),
11254 OPC_CMP_UN_S
= FOP(49, FMT_S
),
11255 OPC_CMP_EQ_S
= FOP(50, FMT_S
),
11256 OPC_CMP_UEQ_S
= FOP(51, FMT_S
),
11257 OPC_CMP_OLT_S
= FOP(52, FMT_S
),
11258 OPC_CMP_ULT_S
= FOP(53, FMT_S
),
11259 OPC_CMP_OLE_S
= FOP(54, FMT_S
),
11260 OPC_CMP_ULE_S
= FOP(55, FMT_S
),
11261 OPC_CMP_SF_S
= FOP(56, FMT_S
),
11262 OPC_CMP_NGLE_S
= FOP(57, FMT_S
),
11263 OPC_CMP_SEQ_S
= FOP(58, FMT_S
),
11264 OPC_CMP_NGL_S
= FOP(59, FMT_S
),
11265 OPC_CMP_LT_S
= FOP(60, FMT_S
),
11266 OPC_CMP_NGE_S
= FOP(61, FMT_S
),
11267 OPC_CMP_LE_S
= FOP(62, FMT_S
),
11268 OPC_CMP_NGT_S
= FOP(63, FMT_S
),
11270 OPC_ADD_D
= FOP(0, FMT_D
),
11271 OPC_SUB_D
= FOP(1, FMT_D
),
11272 OPC_MUL_D
= FOP(2, FMT_D
),
11273 OPC_DIV_D
= FOP(3, FMT_D
),
11274 OPC_SQRT_D
= FOP(4, FMT_D
),
11275 OPC_ABS_D
= FOP(5, FMT_D
),
11276 OPC_MOV_D
= FOP(6, FMT_D
),
11277 OPC_NEG_D
= FOP(7, FMT_D
),
11278 OPC_ROUND_L_D
= FOP(8, FMT_D
),
11279 OPC_TRUNC_L_D
= FOP(9, FMT_D
),
11280 OPC_CEIL_L_D
= FOP(10, FMT_D
),
11281 OPC_FLOOR_L_D
= FOP(11, FMT_D
),
11282 OPC_ROUND_W_D
= FOP(12, FMT_D
),
11283 OPC_TRUNC_W_D
= FOP(13, FMT_D
),
11284 OPC_CEIL_W_D
= FOP(14, FMT_D
),
11285 OPC_FLOOR_W_D
= FOP(15, FMT_D
),
11286 OPC_SEL_D
= FOP(16, FMT_D
),
11287 OPC_MOVCF_D
= FOP(17, FMT_D
),
11288 OPC_MOVZ_D
= FOP(18, FMT_D
),
11289 OPC_MOVN_D
= FOP(19, FMT_D
),
11290 OPC_SELEQZ_D
= FOP(20, FMT_D
),
11291 OPC_RECIP_D
= FOP(21, FMT_D
),
11292 OPC_RSQRT_D
= FOP(22, FMT_D
),
11293 OPC_SELNEZ_D
= FOP(23, FMT_D
),
11294 OPC_MADDF_D
= FOP(24, FMT_D
),
11295 OPC_MSUBF_D
= FOP(25, FMT_D
),
11296 OPC_RINT_D
= FOP(26, FMT_D
),
11297 OPC_CLASS_D
= FOP(27, FMT_D
),
11298 OPC_MIN_D
= FOP(28, FMT_D
),
11299 OPC_RECIP2_D
= FOP(28, FMT_D
),
11300 OPC_MINA_D
= FOP(29, FMT_D
),
11301 OPC_RECIP1_D
= FOP(29, FMT_D
),
11302 OPC_MAX_D
= FOP(30, FMT_D
),
11303 OPC_RSQRT1_D
= FOP(30, FMT_D
),
11304 OPC_MAXA_D
= FOP(31, FMT_D
),
11305 OPC_RSQRT2_D
= FOP(31, FMT_D
),
11306 OPC_CVT_S_D
= FOP(32, FMT_D
),
11307 OPC_CVT_W_D
= FOP(36, FMT_D
),
11308 OPC_CVT_L_D
= FOP(37, FMT_D
),
11309 OPC_CMP_F_D
= FOP(48, FMT_D
),
11310 OPC_CMP_UN_D
= FOP(49, FMT_D
),
11311 OPC_CMP_EQ_D
= FOP(50, FMT_D
),
11312 OPC_CMP_UEQ_D
= FOP(51, FMT_D
),
11313 OPC_CMP_OLT_D
= FOP(52, FMT_D
),
11314 OPC_CMP_ULT_D
= FOP(53, FMT_D
),
11315 OPC_CMP_OLE_D
= FOP(54, FMT_D
),
11316 OPC_CMP_ULE_D
= FOP(55, FMT_D
),
11317 OPC_CMP_SF_D
= FOP(56, FMT_D
),
11318 OPC_CMP_NGLE_D
= FOP(57, FMT_D
),
11319 OPC_CMP_SEQ_D
= FOP(58, FMT_D
),
11320 OPC_CMP_NGL_D
= FOP(59, FMT_D
),
11321 OPC_CMP_LT_D
= FOP(60, FMT_D
),
11322 OPC_CMP_NGE_D
= FOP(61, FMT_D
),
11323 OPC_CMP_LE_D
= FOP(62, FMT_D
),
11324 OPC_CMP_NGT_D
= FOP(63, FMT_D
),
11326 OPC_CVT_S_W
= FOP(32, FMT_W
),
11327 OPC_CVT_D_W
= FOP(33, FMT_W
),
11328 OPC_CVT_S_L
= FOP(32, FMT_L
),
11329 OPC_CVT_D_L
= FOP(33, FMT_L
),
11330 OPC_CVT_PS_PW
= FOP(38, FMT_W
),
11332 OPC_ADD_PS
= FOP(0, FMT_PS
),
11333 OPC_SUB_PS
= FOP(1, FMT_PS
),
11334 OPC_MUL_PS
= FOP(2, FMT_PS
),
11335 OPC_DIV_PS
= FOP(3, FMT_PS
),
11336 OPC_ABS_PS
= FOP(5, FMT_PS
),
11337 OPC_MOV_PS
= FOP(6, FMT_PS
),
11338 OPC_NEG_PS
= FOP(7, FMT_PS
),
11339 OPC_MOVCF_PS
= FOP(17, FMT_PS
),
11340 OPC_MOVZ_PS
= FOP(18, FMT_PS
),
11341 OPC_MOVN_PS
= FOP(19, FMT_PS
),
11342 OPC_ADDR_PS
= FOP(24, FMT_PS
),
11343 OPC_MULR_PS
= FOP(26, FMT_PS
),
11344 OPC_RECIP2_PS
= FOP(28, FMT_PS
),
11345 OPC_RECIP1_PS
= FOP(29, FMT_PS
),
11346 OPC_RSQRT1_PS
= FOP(30, FMT_PS
),
11347 OPC_RSQRT2_PS
= FOP(31, FMT_PS
),
11349 OPC_CVT_S_PU
= FOP(32, FMT_PS
),
11350 OPC_CVT_PW_PS
= FOP(36, FMT_PS
),
11351 OPC_CVT_S_PL
= FOP(40, FMT_PS
),
11352 OPC_PLL_PS
= FOP(44, FMT_PS
),
11353 OPC_PLU_PS
= FOP(45, FMT_PS
),
11354 OPC_PUL_PS
= FOP(46, FMT_PS
),
11355 OPC_PUU_PS
= FOP(47, FMT_PS
),
11356 OPC_CMP_F_PS
= FOP(48, FMT_PS
),
11357 OPC_CMP_UN_PS
= FOP(49, FMT_PS
),
11358 OPC_CMP_EQ_PS
= FOP(50, FMT_PS
),
11359 OPC_CMP_UEQ_PS
= FOP(51, FMT_PS
),
11360 OPC_CMP_OLT_PS
= FOP(52, FMT_PS
),
11361 OPC_CMP_ULT_PS
= FOP(53, FMT_PS
),
11362 OPC_CMP_OLE_PS
= FOP(54, FMT_PS
),
11363 OPC_CMP_ULE_PS
= FOP(55, FMT_PS
),
11364 OPC_CMP_SF_PS
= FOP(56, FMT_PS
),
11365 OPC_CMP_NGLE_PS
= FOP(57, FMT_PS
),
11366 OPC_CMP_SEQ_PS
= FOP(58, FMT_PS
),
11367 OPC_CMP_NGL_PS
= FOP(59, FMT_PS
),
11368 OPC_CMP_LT_PS
= FOP(60, FMT_PS
),
11369 OPC_CMP_NGE_PS
= FOP(61, FMT_PS
),
11370 OPC_CMP_LE_PS
= FOP(62, FMT_PS
),
11371 OPC_CMP_NGT_PS
= FOP(63, FMT_PS
),
11375 R6_OPC_CMP_AF_S
= FOP(0, FMT_W
),
11376 R6_OPC_CMP_UN_S
= FOP(1, FMT_W
),
11377 R6_OPC_CMP_EQ_S
= FOP(2, FMT_W
),
11378 R6_OPC_CMP_UEQ_S
= FOP(3, FMT_W
),
11379 R6_OPC_CMP_LT_S
= FOP(4, FMT_W
),
11380 R6_OPC_CMP_ULT_S
= FOP(5, FMT_W
),
11381 R6_OPC_CMP_LE_S
= FOP(6, FMT_W
),
11382 R6_OPC_CMP_ULE_S
= FOP(7, FMT_W
),
11383 R6_OPC_CMP_SAF_S
= FOP(8, FMT_W
),
11384 R6_OPC_CMP_SUN_S
= FOP(9, FMT_W
),
11385 R6_OPC_CMP_SEQ_S
= FOP(10, FMT_W
),
11386 R6_OPC_CMP_SEUQ_S
= FOP(11, FMT_W
),
11387 R6_OPC_CMP_SLT_S
= FOP(12, FMT_W
),
11388 R6_OPC_CMP_SULT_S
= FOP(13, FMT_W
),
11389 R6_OPC_CMP_SLE_S
= FOP(14, FMT_W
),
11390 R6_OPC_CMP_SULE_S
= FOP(15, FMT_W
),
11391 R6_OPC_CMP_OR_S
= FOP(17, FMT_W
),
11392 R6_OPC_CMP_UNE_S
= FOP(18, FMT_W
),
11393 R6_OPC_CMP_NE_S
= FOP(19, FMT_W
),
11394 R6_OPC_CMP_SOR_S
= FOP(25, FMT_W
),
11395 R6_OPC_CMP_SUNE_S
= FOP(26, FMT_W
),
11396 R6_OPC_CMP_SNE_S
= FOP(27, FMT_W
),
11398 R6_OPC_CMP_AF_D
= FOP(0, FMT_L
),
11399 R6_OPC_CMP_UN_D
= FOP(1, FMT_L
),
11400 R6_OPC_CMP_EQ_D
= FOP(2, FMT_L
),
11401 R6_OPC_CMP_UEQ_D
= FOP(3, FMT_L
),
11402 R6_OPC_CMP_LT_D
= FOP(4, FMT_L
),
11403 R6_OPC_CMP_ULT_D
= FOP(5, FMT_L
),
11404 R6_OPC_CMP_LE_D
= FOP(6, FMT_L
),
11405 R6_OPC_CMP_ULE_D
= FOP(7, FMT_L
),
11406 R6_OPC_CMP_SAF_D
= FOP(8, FMT_L
),
11407 R6_OPC_CMP_SUN_D
= FOP(9, FMT_L
),
11408 R6_OPC_CMP_SEQ_D
= FOP(10, FMT_L
),
11409 R6_OPC_CMP_SEUQ_D
= FOP(11, FMT_L
),
11410 R6_OPC_CMP_SLT_D
= FOP(12, FMT_L
),
11411 R6_OPC_CMP_SULT_D
= FOP(13, FMT_L
),
11412 R6_OPC_CMP_SLE_D
= FOP(14, FMT_L
),
11413 R6_OPC_CMP_SULE_D
= FOP(15, FMT_L
),
11414 R6_OPC_CMP_OR_D
= FOP(17, FMT_L
),
11415 R6_OPC_CMP_UNE_D
= FOP(18, FMT_L
),
11416 R6_OPC_CMP_NE_D
= FOP(19, FMT_L
),
11417 R6_OPC_CMP_SOR_D
= FOP(25, FMT_L
),
11418 R6_OPC_CMP_SUNE_D
= FOP(26, FMT_L
),
11419 R6_OPC_CMP_SNE_D
= FOP(27, FMT_L
),
11422 static void gen_cp1(DisasContext
*ctx
, uint32_t opc
, int rt
, int fs
)
11424 TCGv t0
= tcg_temp_new();
11429 TCGv_i32 fp0
= tcg_temp_new_i32();
11431 gen_load_fpr32(ctx
, fp0
, fs
);
11432 tcg_gen_ext_i32_tl(t0
, fp0
);
11433 tcg_temp_free_i32(fp0
);
11435 gen_store_gpr(t0
, rt
);
11438 gen_load_gpr(t0
, rt
);
11440 TCGv_i32 fp0
= tcg_temp_new_i32();
11442 tcg_gen_trunc_tl_i32(fp0
, t0
);
11443 gen_store_fpr32(ctx
, fp0
, fs
);
11444 tcg_temp_free_i32(fp0
);
11448 gen_helper_1e0i(cfc1
, t0
, fs
);
11449 gen_store_gpr(t0
, rt
);
11452 gen_load_gpr(t0
, rt
);
11453 save_cpu_state(ctx
, 0);
11455 TCGv_i32 fs_tmp
= tcg_const_i32(fs
);
11457 gen_helper_0e2i(ctc1
, t0
, fs_tmp
, rt
);
11458 tcg_temp_free_i32(fs_tmp
);
11460 /* Stop translation as we may have changed hflags */
11461 ctx
->base
.is_jmp
= DISAS_STOP
;
11463 #if defined(TARGET_MIPS64)
11465 gen_load_fpr64(ctx
, t0
, fs
);
11466 gen_store_gpr(t0
, rt
);
11469 gen_load_gpr(t0
, rt
);
11470 gen_store_fpr64(ctx
, t0
, fs
);
11475 TCGv_i32 fp0
= tcg_temp_new_i32();
11477 gen_load_fpr32h(ctx
, fp0
, fs
);
11478 tcg_gen_ext_i32_tl(t0
, fp0
);
11479 tcg_temp_free_i32(fp0
);
11481 gen_store_gpr(t0
, rt
);
11484 gen_load_gpr(t0
, rt
);
11486 TCGv_i32 fp0
= tcg_temp_new_i32();
11488 tcg_gen_trunc_tl_i32(fp0
, t0
);
11489 gen_store_fpr32h(ctx
, fp0
, fs
);
11490 tcg_temp_free_i32(fp0
);
11494 MIPS_INVAL("cp1 move");
11495 generate_exception_end(ctx
, EXCP_RI
);
11503 static void gen_movci(DisasContext
*ctx
, int rd
, int rs
, int cc
, int tf
)
11510 /* Treat as NOP. */
11515 cond
= TCG_COND_EQ
;
11517 cond
= TCG_COND_NE
;
11520 l1
= gen_new_label();
11521 t0
= tcg_temp_new_i32();
11522 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
11523 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
11524 tcg_temp_free_i32(t0
);
11526 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
11528 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
11533 static inline void gen_movcf_s(DisasContext
*ctx
, int fs
, int fd
, int cc
,
11537 TCGv_i32 t0
= tcg_temp_new_i32();
11538 TCGLabel
*l1
= gen_new_label();
11541 cond
= TCG_COND_EQ
;
11543 cond
= TCG_COND_NE
;
11546 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
11547 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
11548 gen_load_fpr32(ctx
, t0
, fs
);
11549 gen_store_fpr32(ctx
, t0
, fd
);
11551 tcg_temp_free_i32(t0
);
11554 static inline void gen_movcf_d(DisasContext
*ctx
, int fs
, int fd
, int cc
,
11558 TCGv_i32 t0
= tcg_temp_new_i32();
11560 TCGLabel
*l1
= gen_new_label();
11563 cond
= TCG_COND_EQ
;
11565 cond
= TCG_COND_NE
;
11568 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
11569 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
11570 tcg_temp_free_i32(t0
);
11571 fp0
= tcg_temp_new_i64();
11572 gen_load_fpr64(ctx
, fp0
, fs
);
11573 gen_store_fpr64(ctx
, fp0
, fd
);
11574 tcg_temp_free_i64(fp0
);
11578 static inline void gen_movcf_ps(DisasContext
*ctx
, int fs
, int fd
,
11582 TCGv_i32 t0
= tcg_temp_new_i32();
11583 TCGLabel
*l1
= gen_new_label();
11584 TCGLabel
*l2
= gen_new_label();
11587 cond
= TCG_COND_EQ
;
11589 cond
= TCG_COND_NE
;
11592 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
11593 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
11594 gen_load_fpr32(ctx
, t0
, fs
);
11595 gen_store_fpr32(ctx
, t0
, fd
);
11598 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
+ 1));
11599 tcg_gen_brcondi_i32(cond
, t0
, 0, l2
);
11600 gen_load_fpr32h(ctx
, t0
, fs
);
11601 gen_store_fpr32h(ctx
, t0
, fd
);
11602 tcg_temp_free_i32(t0
);
11606 static void gen_sel_s(DisasContext
*ctx
, enum fopcode op1
, int fd
, int ft
,
11609 TCGv_i32 t1
= tcg_const_i32(0);
11610 TCGv_i32 fp0
= tcg_temp_new_i32();
11611 TCGv_i32 fp1
= tcg_temp_new_i32();
11612 TCGv_i32 fp2
= tcg_temp_new_i32();
11613 gen_load_fpr32(ctx
, fp0
, fd
);
11614 gen_load_fpr32(ctx
, fp1
, ft
);
11615 gen_load_fpr32(ctx
, fp2
, fs
);
11619 tcg_gen_andi_i32(fp0
, fp0
, 1);
11620 tcg_gen_movcond_i32(TCG_COND_NE
, fp0
, fp0
, t1
, fp1
, fp2
);
11623 tcg_gen_andi_i32(fp1
, fp1
, 1);
11624 tcg_gen_movcond_i32(TCG_COND_EQ
, fp0
, fp1
, t1
, fp2
, t1
);
11627 tcg_gen_andi_i32(fp1
, fp1
, 1);
11628 tcg_gen_movcond_i32(TCG_COND_NE
, fp0
, fp1
, t1
, fp2
, t1
);
11631 MIPS_INVAL("gen_sel_s");
11632 generate_exception_end(ctx
, EXCP_RI
);
11636 gen_store_fpr32(ctx
, fp0
, fd
);
11637 tcg_temp_free_i32(fp2
);
11638 tcg_temp_free_i32(fp1
);
11639 tcg_temp_free_i32(fp0
);
11640 tcg_temp_free_i32(t1
);
11643 static void gen_sel_d(DisasContext
*ctx
, enum fopcode op1
, int fd
, int ft
,
11646 TCGv_i64 t1
= tcg_const_i64(0);
11647 TCGv_i64 fp0
= tcg_temp_new_i64();
11648 TCGv_i64 fp1
= tcg_temp_new_i64();
11649 TCGv_i64 fp2
= tcg_temp_new_i64();
11650 gen_load_fpr64(ctx
, fp0
, fd
);
11651 gen_load_fpr64(ctx
, fp1
, ft
);
11652 gen_load_fpr64(ctx
, fp2
, fs
);
11656 tcg_gen_andi_i64(fp0
, fp0
, 1);
11657 tcg_gen_movcond_i64(TCG_COND_NE
, fp0
, fp0
, t1
, fp1
, fp2
);
11660 tcg_gen_andi_i64(fp1
, fp1
, 1);
11661 tcg_gen_movcond_i64(TCG_COND_EQ
, fp0
, fp1
, t1
, fp2
, t1
);
11664 tcg_gen_andi_i64(fp1
, fp1
, 1);
11665 tcg_gen_movcond_i64(TCG_COND_NE
, fp0
, fp1
, t1
, fp2
, t1
);
11668 MIPS_INVAL("gen_sel_d");
11669 generate_exception_end(ctx
, EXCP_RI
);
11673 gen_store_fpr64(ctx
, fp0
, fd
);
11674 tcg_temp_free_i64(fp2
);
11675 tcg_temp_free_i64(fp1
);
11676 tcg_temp_free_i64(fp0
);
11677 tcg_temp_free_i64(t1
);
11680 static void gen_farith(DisasContext
*ctx
, enum fopcode op1
,
11681 int ft
, int fs
, int fd
, int cc
)
11683 uint32_t func
= ctx
->opcode
& 0x3f;
11687 TCGv_i32 fp0
= tcg_temp_new_i32();
11688 TCGv_i32 fp1
= tcg_temp_new_i32();
11690 gen_load_fpr32(ctx
, fp0
, fs
);
11691 gen_load_fpr32(ctx
, fp1
, ft
);
11692 gen_helper_float_add_s(fp0
, cpu_env
, fp0
, fp1
);
11693 tcg_temp_free_i32(fp1
);
11694 gen_store_fpr32(ctx
, fp0
, fd
);
11695 tcg_temp_free_i32(fp0
);
11700 TCGv_i32 fp0
= tcg_temp_new_i32();
11701 TCGv_i32 fp1
= tcg_temp_new_i32();
11703 gen_load_fpr32(ctx
, fp0
, fs
);
11704 gen_load_fpr32(ctx
, fp1
, ft
);
11705 gen_helper_float_sub_s(fp0
, cpu_env
, fp0
, fp1
);
11706 tcg_temp_free_i32(fp1
);
11707 gen_store_fpr32(ctx
, fp0
, fd
);
11708 tcg_temp_free_i32(fp0
);
11713 TCGv_i32 fp0
= tcg_temp_new_i32();
11714 TCGv_i32 fp1
= tcg_temp_new_i32();
11716 gen_load_fpr32(ctx
, fp0
, fs
);
11717 gen_load_fpr32(ctx
, fp1
, ft
);
11718 gen_helper_float_mul_s(fp0
, cpu_env
, fp0
, fp1
);
11719 tcg_temp_free_i32(fp1
);
11720 gen_store_fpr32(ctx
, fp0
, fd
);
11721 tcg_temp_free_i32(fp0
);
11726 TCGv_i32 fp0
= tcg_temp_new_i32();
11727 TCGv_i32 fp1
= tcg_temp_new_i32();
11729 gen_load_fpr32(ctx
, fp0
, fs
);
11730 gen_load_fpr32(ctx
, fp1
, ft
);
11731 gen_helper_float_div_s(fp0
, cpu_env
, fp0
, fp1
);
11732 tcg_temp_free_i32(fp1
);
11733 gen_store_fpr32(ctx
, fp0
, fd
);
11734 tcg_temp_free_i32(fp0
);
11739 TCGv_i32 fp0
= tcg_temp_new_i32();
11741 gen_load_fpr32(ctx
, fp0
, fs
);
11742 gen_helper_float_sqrt_s(fp0
, cpu_env
, fp0
);
11743 gen_store_fpr32(ctx
, fp0
, fd
);
11744 tcg_temp_free_i32(fp0
);
11749 TCGv_i32 fp0
= tcg_temp_new_i32();
11751 gen_load_fpr32(ctx
, fp0
, fs
);
11752 if (ctx
->abs2008
) {
11753 tcg_gen_andi_i32(fp0
, fp0
, 0x7fffffffUL
);
11755 gen_helper_float_abs_s(fp0
, fp0
);
11757 gen_store_fpr32(ctx
, fp0
, fd
);
11758 tcg_temp_free_i32(fp0
);
11763 TCGv_i32 fp0
= tcg_temp_new_i32();
11765 gen_load_fpr32(ctx
, fp0
, fs
);
11766 gen_store_fpr32(ctx
, fp0
, fd
);
11767 tcg_temp_free_i32(fp0
);
11772 TCGv_i32 fp0
= tcg_temp_new_i32();
11774 gen_load_fpr32(ctx
, fp0
, fs
);
11775 if (ctx
->abs2008
) {
11776 tcg_gen_xori_i32(fp0
, fp0
, 1UL << 31);
11778 gen_helper_float_chs_s(fp0
, fp0
);
11780 gen_store_fpr32(ctx
, fp0
, fd
);
11781 tcg_temp_free_i32(fp0
);
11784 case OPC_ROUND_L_S
:
11785 check_cp1_64bitmode(ctx
);
11787 TCGv_i32 fp32
= tcg_temp_new_i32();
11788 TCGv_i64 fp64
= tcg_temp_new_i64();
11790 gen_load_fpr32(ctx
, fp32
, fs
);
11791 if (ctx
->nan2008
) {
11792 gen_helper_float_round_2008_l_s(fp64
, cpu_env
, fp32
);
11794 gen_helper_float_round_l_s(fp64
, cpu_env
, fp32
);
11796 tcg_temp_free_i32(fp32
);
11797 gen_store_fpr64(ctx
, fp64
, fd
);
11798 tcg_temp_free_i64(fp64
);
11801 case OPC_TRUNC_L_S
:
11802 check_cp1_64bitmode(ctx
);
11804 TCGv_i32 fp32
= tcg_temp_new_i32();
11805 TCGv_i64 fp64
= tcg_temp_new_i64();
11807 gen_load_fpr32(ctx
, fp32
, fs
);
11808 if (ctx
->nan2008
) {
11809 gen_helper_float_trunc_2008_l_s(fp64
, cpu_env
, fp32
);
11811 gen_helper_float_trunc_l_s(fp64
, cpu_env
, fp32
);
11813 tcg_temp_free_i32(fp32
);
11814 gen_store_fpr64(ctx
, fp64
, fd
);
11815 tcg_temp_free_i64(fp64
);
11819 check_cp1_64bitmode(ctx
);
11821 TCGv_i32 fp32
= tcg_temp_new_i32();
11822 TCGv_i64 fp64
= tcg_temp_new_i64();
11824 gen_load_fpr32(ctx
, fp32
, fs
);
11825 if (ctx
->nan2008
) {
11826 gen_helper_float_ceil_2008_l_s(fp64
, cpu_env
, fp32
);
11828 gen_helper_float_ceil_l_s(fp64
, cpu_env
, fp32
);
11830 tcg_temp_free_i32(fp32
);
11831 gen_store_fpr64(ctx
, fp64
, fd
);
11832 tcg_temp_free_i64(fp64
);
11835 case OPC_FLOOR_L_S
:
11836 check_cp1_64bitmode(ctx
);
11838 TCGv_i32 fp32
= tcg_temp_new_i32();
11839 TCGv_i64 fp64
= tcg_temp_new_i64();
11841 gen_load_fpr32(ctx
, fp32
, fs
);
11842 if (ctx
->nan2008
) {
11843 gen_helper_float_floor_2008_l_s(fp64
, cpu_env
, fp32
);
11845 gen_helper_float_floor_l_s(fp64
, cpu_env
, fp32
);
11847 tcg_temp_free_i32(fp32
);
11848 gen_store_fpr64(ctx
, fp64
, fd
);
11849 tcg_temp_free_i64(fp64
);
11852 case OPC_ROUND_W_S
:
11854 TCGv_i32 fp0
= tcg_temp_new_i32();
11856 gen_load_fpr32(ctx
, fp0
, fs
);
11857 if (ctx
->nan2008
) {
11858 gen_helper_float_round_2008_w_s(fp0
, cpu_env
, fp0
);
11860 gen_helper_float_round_w_s(fp0
, cpu_env
, fp0
);
11862 gen_store_fpr32(ctx
, fp0
, fd
);
11863 tcg_temp_free_i32(fp0
);
11866 case OPC_TRUNC_W_S
:
11868 TCGv_i32 fp0
= tcg_temp_new_i32();
11870 gen_load_fpr32(ctx
, fp0
, fs
);
11871 if (ctx
->nan2008
) {
11872 gen_helper_float_trunc_2008_w_s(fp0
, cpu_env
, fp0
);
11874 gen_helper_float_trunc_w_s(fp0
, cpu_env
, fp0
);
11876 gen_store_fpr32(ctx
, fp0
, fd
);
11877 tcg_temp_free_i32(fp0
);
11882 TCGv_i32 fp0
= tcg_temp_new_i32();
11884 gen_load_fpr32(ctx
, fp0
, fs
);
11885 if (ctx
->nan2008
) {
11886 gen_helper_float_ceil_2008_w_s(fp0
, cpu_env
, fp0
);
11888 gen_helper_float_ceil_w_s(fp0
, cpu_env
, fp0
);
11890 gen_store_fpr32(ctx
, fp0
, fd
);
11891 tcg_temp_free_i32(fp0
);
11894 case OPC_FLOOR_W_S
:
11896 TCGv_i32 fp0
= tcg_temp_new_i32();
11898 gen_load_fpr32(ctx
, fp0
, fs
);
11899 if (ctx
->nan2008
) {
11900 gen_helper_float_floor_2008_w_s(fp0
, cpu_env
, fp0
);
11902 gen_helper_float_floor_w_s(fp0
, cpu_env
, fp0
);
11904 gen_store_fpr32(ctx
, fp0
, fd
);
11905 tcg_temp_free_i32(fp0
);
11909 check_insn(ctx
, ISA_MIPS32R6
);
11910 gen_sel_s(ctx
, op1
, fd
, ft
, fs
);
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_opc_removed(ctx
, ISA_MIPS32R6
);
11922 gen_movcf_s(ctx
, fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
11925 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
11927 TCGLabel
*l1
= gen_new_label();
11931 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
11933 fp0
= tcg_temp_new_i32();
11934 gen_load_fpr32(ctx
, fp0
, fs
);
11935 gen_store_fpr32(ctx
, fp0
, fd
);
11936 tcg_temp_free_i32(fp0
);
11941 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
11943 TCGLabel
*l1
= gen_new_label();
11947 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
11948 fp0
= tcg_temp_new_i32();
11949 gen_load_fpr32(ctx
, fp0
, fs
);
11950 gen_store_fpr32(ctx
, fp0
, fd
);
11951 tcg_temp_free_i32(fp0
);
11958 TCGv_i32 fp0
= tcg_temp_new_i32();
11960 gen_load_fpr32(ctx
, fp0
, fs
);
11961 gen_helper_float_recip_s(fp0
, cpu_env
, fp0
);
11962 gen_store_fpr32(ctx
, fp0
, fd
);
11963 tcg_temp_free_i32(fp0
);
11968 TCGv_i32 fp0
= tcg_temp_new_i32();
11970 gen_load_fpr32(ctx
, fp0
, fs
);
11971 gen_helper_float_rsqrt_s(fp0
, cpu_env
, fp0
);
11972 gen_store_fpr32(ctx
, fp0
, fd
);
11973 tcg_temp_free_i32(fp0
);
11977 check_insn(ctx
, ISA_MIPS32R6
);
11979 TCGv_i32 fp0
= tcg_temp_new_i32();
11980 TCGv_i32 fp1
= tcg_temp_new_i32();
11981 TCGv_i32 fp2
= tcg_temp_new_i32();
11982 gen_load_fpr32(ctx
, fp0
, fs
);
11983 gen_load_fpr32(ctx
, fp1
, ft
);
11984 gen_load_fpr32(ctx
, fp2
, fd
);
11985 gen_helper_float_maddf_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
11986 gen_store_fpr32(ctx
, fp2
, fd
);
11987 tcg_temp_free_i32(fp2
);
11988 tcg_temp_free_i32(fp1
);
11989 tcg_temp_free_i32(fp0
);
11993 check_insn(ctx
, ISA_MIPS32R6
);
11995 TCGv_i32 fp0
= tcg_temp_new_i32();
11996 TCGv_i32 fp1
= tcg_temp_new_i32();
11997 TCGv_i32 fp2
= tcg_temp_new_i32();
11998 gen_load_fpr32(ctx
, fp0
, fs
);
11999 gen_load_fpr32(ctx
, fp1
, ft
);
12000 gen_load_fpr32(ctx
, fp2
, fd
);
12001 gen_helper_float_msubf_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12002 gen_store_fpr32(ctx
, fp2
, fd
);
12003 tcg_temp_free_i32(fp2
);
12004 tcg_temp_free_i32(fp1
);
12005 tcg_temp_free_i32(fp0
);
12009 check_insn(ctx
, ISA_MIPS32R6
);
12011 TCGv_i32 fp0
= tcg_temp_new_i32();
12012 gen_load_fpr32(ctx
, fp0
, fs
);
12013 gen_helper_float_rint_s(fp0
, cpu_env
, fp0
);
12014 gen_store_fpr32(ctx
, fp0
, fd
);
12015 tcg_temp_free_i32(fp0
);
12019 check_insn(ctx
, ISA_MIPS32R6
);
12021 TCGv_i32 fp0
= tcg_temp_new_i32();
12022 gen_load_fpr32(ctx
, fp0
, fs
);
12023 gen_helper_float_class_s(fp0
, cpu_env
, fp0
);
12024 gen_store_fpr32(ctx
, fp0
, fd
);
12025 tcg_temp_free_i32(fp0
);
12028 case OPC_MIN_S
: /* OPC_RECIP2_S */
12029 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
12031 TCGv_i32 fp0
= tcg_temp_new_i32();
12032 TCGv_i32 fp1
= tcg_temp_new_i32();
12033 TCGv_i32 fp2
= tcg_temp_new_i32();
12034 gen_load_fpr32(ctx
, fp0
, fs
);
12035 gen_load_fpr32(ctx
, fp1
, ft
);
12036 gen_helper_float_min_s(fp2
, cpu_env
, fp0
, fp1
);
12037 gen_store_fpr32(ctx
, fp2
, fd
);
12038 tcg_temp_free_i32(fp2
);
12039 tcg_temp_free_i32(fp1
);
12040 tcg_temp_free_i32(fp0
);
12043 check_cp1_64bitmode(ctx
);
12045 TCGv_i32 fp0
= tcg_temp_new_i32();
12046 TCGv_i32 fp1
= tcg_temp_new_i32();
12048 gen_load_fpr32(ctx
, fp0
, fs
);
12049 gen_load_fpr32(ctx
, fp1
, ft
);
12050 gen_helper_float_recip2_s(fp0
, cpu_env
, fp0
, fp1
);
12051 tcg_temp_free_i32(fp1
);
12052 gen_store_fpr32(ctx
, fp0
, fd
);
12053 tcg_temp_free_i32(fp0
);
12057 case OPC_MINA_S
: /* OPC_RECIP1_S */
12058 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
12060 TCGv_i32 fp0
= tcg_temp_new_i32();
12061 TCGv_i32 fp1
= tcg_temp_new_i32();
12062 TCGv_i32 fp2
= tcg_temp_new_i32();
12063 gen_load_fpr32(ctx
, fp0
, fs
);
12064 gen_load_fpr32(ctx
, fp1
, ft
);
12065 gen_helper_float_mina_s(fp2
, cpu_env
, fp0
, fp1
);
12066 gen_store_fpr32(ctx
, fp2
, fd
);
12067 tcg_temp_free_i32(fp2
);
12068 tcg_temp_free_i32(fp1
);
12069 tcg_temp_free_i32(fp0
);
12072 check_cp1_64bitmode(ctx
);
12074 TCGv_i32 fp0
= tcg_temp_new_i32();
12076 gen_load_fpr32(ctx
, fp0
, fs
);
12077 gen_helper_float_recip1_s(fp0
, cpu_env
, fp0
);
12078 gen_store_fpr32(ctx
, fp0
, fd
);
12079 tcg_temp_free_i32(fp0
);
12083 case OPC_MAX_S
: /* OPC_RSQRT1_S */
12084 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
12086 TCGv_i32 fp0
= tcg_temp_new_i32();
12087 TCGv_i32 fp1
= tcg_temp_new_i32();
12088 gen_load_fpr32(ctx
, fp0
, fs
);
12089 gen_load_fpr32(ctx
, fp1
, ft
);
12090 gen_helper_float_max_s(fp1
, cpu_env
, fp0
, fp1
);
12091 gen_store_fpr32(ctx
, fp1
, fd
);
12092 tcg_temp_free_i32(fp1
);
12093 tcg_temp_free_i32(fp0
);
12096 check_cp1_64bitmode(ctx
);
12098 TCGv_i32 fp0
= tcg_temp_new_i32();
12100 gen_load_fpr32(ctx
, fp0
, fs
);
12101 gen_helper_float_rsqrt1_s(fp0
, cpu_env
, fp0
);
12102 gen_store_fpr32(ctx
, fp0
, fd
);
12103 tcg_temp_free_i32(fp0
);
12107 case OPC_MAXA_S
: /* OPC_RSQRT2_S */
12108 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
12110 TCGv_i32 fp0
= tcg_temp_new_i32();
12111 TCGv_i32 fp1
= tcg_temp_new_i32();
12112 gen_load_fpr32(ctx
, fp0
, fs
);
12113 gen_load_fpr32(ctx
, fp1
, ft
);
12114 gen_helper_float_maxa_s(fp1
, cpu_env
, fp0
, fp1
);
12115 gen_store_fpr32(ctx
, fp1
, fd
);
12116 tcg_temp_free_i32(fp1
);
12117 tcg_temp_free_i32(fp0
);
12120 check_cp1_64bitmode(ctx
);
12122 TCGv_i32 fp0
= tcg_temp_new_i32();
12123 TCGv_i32 fp1
= tcg_temp_new_i32();
12125 gen_load_fpr32(ctx
, fp0
, fs
);
12126 gen_load_fpr32(ctx
, fp1
, ft
);
12127 gen_helper_float_rsqrt2_s(fp0
, cpu_env
, fp0
, fp1
);
12128 tcg_temp_free_i32(fp1
);
12129 gen_store_fpr32(ctx
, fp0
, fd
);
12130 tcg_temp_free_i32(fp0
);
12135 check_cp1_registers(ctx
, fd
);
12137 TCGv_i32 fp32
= tcg_temp_new_i32();
12138 TCGv_i64 fp64
= tcg_temp_new_i64();
12140 gen_load_fpr32(ctx
, fp32
, fs
);
12141 gen_helper_float_cvtd_s(fp64
, cpu_env
, fp32
);
12142 tcg_temp_free_i32(fp32
);
12143 gen_store_fpr64(ctx
, fp64
, fd
);
12144 tcg_temp_free_i64(fp64
);
12149 TCGv_i32 fp0
= tcg_temp_new_i32();
12151 gen_load_fpr32(ctx
, fp0
, fs
);
12152 if (ctx
->nan2008
) {
12153 gen_helper_float_cvt_2008_w_s(fp0
, cpu_env
, fp0
);
12155 gen_helper_float_cvt_w_s(fp0
, cpu_env
, fp0
);
12157 gen_store_fpr32(ctx
, fp0
, fd
);
12158 tcg_temp_free_i32(fp0
);
12162 check_cp1_64bitmode(ctx
);
12164 TCGv_i32 fp32
= tcg_temp_new_i32();
12165 TCGv_i64 fp64
= tcg_temp_new_i64();
12167 gen_load_fpr32(ctx
, fp32
, fs
);
12168 if (ctx
->nan2008
) {
12169 gen_helper_float_cvt_2008_l_s(fp64
, cpu_env
, fp32
);
12171 gen_helper_float_cvt_l_s(fp64
, cpu_env
, fp32
);
12173 tcg_temp_free_i32(fp32
);
12174 gen_store_fpr64(ctx
, fp64
, fd
);
12175 tcg_temp_free_i64(fp64
);
12181 TCGv_i64 fp64
= tcg_temp_new_i64();
12182 TCGv_i32 fp32_0
= tcg_temp_new_i32();
12183 TCGv_i32 fp32_1
= tcg_temp_new_i32();
12185 gen_load_fpr32(ctx
, fp32_0
, fs
);
12186 gen_load_fpr32(ctx
, fp32_1
, ft
);
12187 tcg_gen_concat_i32_i64(fp64
, fp32_1
, fp32_0
);
12188 tcg_temp_free_i32(fp32_1
);
12189 tcg_temp_free_i32(fp32_0
);
12190 gen_store_fpr64(ctx
, fp64
, fd
);
12191 tcg_temp_free_i64(fp64
);
12197 case OPC_CMP_UEQ_S
:
12198 case OPC_CMP_OLT_S
:
12199 case OPC_CMP_ULT_S
:
12200 case OPC_CMP_OLE_S
:
12201 case OPC_CMP_ULE_S
:
12203 case OPC_CMP_NGLE_S
:
12204 case OPC_CMP_SEQ_S
:
12205 case OPC_CMP_NGL_S
:
12207 case OPC_CMP_NGE_S
:
12209 case OPC_CMP_NGT_S
:
12210 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
12211 if (ctx
->opcode
& (1 << 6)) {
12212 gen_cmpabs_s(ctx
, func
- 48, ft
, fs
, cc
);
12214 gen_cmp_s(ctx
, func
- 48, ft
, fs
, cc
);
12218 check_cp1_registers(ctx
, fs
| ft
| fd
);
12220 TCGv_i64 fp0
= tcg_temp_new_i64();
12221 TCGv_i64 fp1
= tcg_temp_new_i64();
12223 gen_load_fpr64(ctx
, fp0
, fs
);
12224 gen_load_fpr64(ctx
, fp1
, ft
);
12225 gen_helper_float_add_d(fp0
, cpu_env
, fp0
, fp1
);
12226 tcg_temp_free_i64(fp1
);
12227 gen_store_fpr64(ctx
, fp0
, fd
);
12228 tcg_temp_free_i64(fp0
);
12232 check_cp1_registers(ctx
, fs
| ft
| fd
);
12234 TCGv_i64 fp0
= tcg_temp_new_i64();
12235 TCGv_i64 fp1
= tcg_temp_new_i64();
12237 gen_load_fpr64(ctx
, fp0
, fs
);
12238 gen_load_fpr64(ctx
, fp1
, ft
);
12239 gen_helper_float_sub_d(fp0
, cpu_env
, fp0
, fp1
);
12240 tcg_temp_free_i64(fp1
);
12241 gen_store_fpr64(ctx
, fp0
, fd
);
12242 tcg_temp_free_i64(fp0
);
12246 check_cp1_registers(ctx
, fs
| ft
| fd
);
12248 TCGv_i64 fp0
= tcg_temp_new_i64();
12249 TCGv_i64 fp1
= tcg_temp_new_i64();
12251 gen_load_fpr64(ctx
, fp0
, fs
);
12252 gen_load_fpr64(ctx
, fp1
, ft
);
12253 gen_helper_float_mul_d(fp0
, cpu_env
, fp0
, fp1
);
12254 tcg_temp_free_i64(fp1
);
12255 gen_store_fpr64(ctx
, fp0
, fd
);
12256 tcg_temp_free_i64(fp0
);
12260 check_cp1_registers(ctx
, fs
| ft
| fd
);
12262 TCGv_i64 fp0
= tcg_temp_new_i64();
12263 TCGv_i64 fp1
= tcg_temp_new_i64();
12265 gen_load_fpr64(ctx
, fp0
, fs
);
12266 gen_load_fpr64(ctx
, fp1
, ft
);
12267 gen_helper_float_div_d(fp0
, cpu_env
, fp0
, fp1
);
12268 tcg_temp_free_i64(fp1
);
12269 gen_store_fpr64(ctx
, fp0
, fd
);
12270 tcg_temp_free_i64(fp0
);
12274 check_cp1_registers(ctx
, fs
| fd
);
12276 TCGv_i64 fp0
= tcg_temp_new_i64();
12278 gen_load_fpr64(ctx
, fp0
, fs
);
12279 gen_helper_float_sqrt_d(fp0
, cpu_env
, fp0
);
12280 gen_store_fpr64(ctx
, fp0
, fd
);
12281 tcg_temp_free_i64(fp0
);
12285 check_cp1_registers(ctx
, fs
| fd
);
12287 TCGv_i64 fp0
= tcg_temp_new_i64();
12289 gen_load_fpr64(ctx
, fp0
, fs
);
12290 if (ctx
->abs2008
) {
12291 tcg_gen_andi_i64(fp0
, fp0
, 0x7fffffffffffffffULL
);
12293 gen_helper_float_abs_d(fp0
, fp0
);
12295 gen_store_fpr64(ctx
, fp0
, fd
);
12296 tcg_temp_free_i64(fp0
);
12300 check_cp1_registers(ctx
, fs
| fd
);
12302 TCGv_i64 fp0
= tcg_temp_new_i64();
12304 gen_load_fpr64(ctx
, fp0
, fs
);
12305 gen_store_fpr64(ctx
, fp0
, fd
);
12306 tcg_temp_free_i64(fp0
);
12310 check_cp1_registers(ctx
, fs
| fd
);
12312 TCGv_i64 fp0
= tcg_temp_new_i64();
12314 gen_load_fpr64(ctx
, fp0
, fs
);
12315 if (ctx
->abs2008
) {
12316 tcg_gen_xori_i64(fp0
, fp0
, 1ULL << 63);
12318 gen_helper_float_chs_d(fp0
, fp0
);
12320 gen_store_fpr64(ctx
, fp0
, fd
);
12321 tcg_temp_free_i64(fp0
);
12324 case OPC_ROUND_L_D
:
12325 check_cp1_64bitmode(ctx
);
12327 TCGv_i64 fp0
= tcg_temp_new_i64();
12329 gen_load_fpr64(ctx
, fp0
, fs
);
12330 if (ctx
->nan2008
) {
12331 gen_helper_float_round_2008_l_d(fp0
, cpu_env
, fp0
);
12333 gen_helper_float_round_l_d(fp0
, cpu_env
, fp0
);
12335 gen_store_fpr64(ctx
, fp0
, fd
);
12336 tcg_temp_free_i64(fp0
);
12339 case OPC_TRUNC_L_D
:
12340 check_cp1_64bitmode(ctx
);
12342 TCGv_i64 fp0
= tcg_temp_new_i64();
12344 gen_load_fpr64(ctx
, fp0
, fs
);
12345 if (ctx
->nan2008
) {
12346 gen_helper_float_trunc_2008_l_d(fp0
, cpu_env
, fp0
);
12348 gen_helper_float_trunc_l_d(fp0
, cpu_env
, fp0
);
12350 gen_store_fpr64(ctx
, fp0
, fd
);
12351 tcg_temp_free_i64(fp0
);
12355 check_cp1_64bitmode(ctx
);
12357 TCGv_i64 fp0
= tcg_temp_new_i64();
12359 gen_load_fpr64(ctx
, fp0
, fs
);
12360 if (ctx
->nan2008
) {
12361 gen_helper_float_ceil_2008_l_d(fp0
, cpu_env
, fp0
);
12363 gen_helper_float_ceil_l_d(fp0
, cpu_env
, fp0
);
12365 gen_store_fpr64(ctx
, fp0
, fd
);
12366 tcg_temp_free_i64(fp0
);
12369 case OPC_FLOOR_L_D
:
12370 check_cp1_64bitmode(ctx
);
12372 TCGv_i64 fp0
= tcg_temp_new_i64();
12374 gen_load_fpr64(ctx
, fp0
, fs
);
12375 if (ctx
->nan2008
) {
12376 gen_helper_float_floor_2008_l_d(fp0
, cpu_env
, fp0
);
12378 gen_helper_float_floor_l_d(fp0
, cpu_env
, fp0
);
12380 gen_store_fpr64(ctx
, fp0
, fd
);
12381 tcg_temp_free_i64(fp0
);
12384 case OPC_ROUND_W_D
:
12385 check_cp1_registers(ctx
, fs
);
12387 TCGv_i32 fp32
= tcg_temp_new_i32();
12388 TCGv_i64 fp64
= tcg_temp_new_i64();
12390 gen_load_fpr64(ctx
, fp64
, fs
);
12391 if (ctx
->nan2008
) {
12392 gen_helper_float_round_2008_w_d(fp32
, cpu_env
, fp64
);
12394 gen_helper_float_round_w_d(fp32
, cpu_env
, fp64
);
12396 tcg_temp_free_i64(fp64
);
12397 gen_store_fpr32(ctx
, fp32
, fd
);
12398 tcg_temp_free_i32(fp32
);
12401 case OPC_TRUNC_W_D
:
12402 check_cp1_registers(ctx
, fs
);
12404 TCGv_i32 fp32
= tcg_temp_new_i32();
12405 TCGv_i64 fp64
= tcg_temp_new_i64();
12407 gen_load_fpr64(ctx
, fp64
, fs
);
12408 if (ctx
->nan2008
) {
12409 gen_helper_float_trunc_2008_w_d(fp32
, cpu_env
, fp64
);
12411 gen_helper_float_trunc_w_d(fp32
, cpu_env
, fp64
);
12413 tcg_temp_free_i64(fp64
);
12414 gen_store_fpr32(ctx
, fp32
, fd
);
12415 tcg_temp_free_i32(fp32
);
12419 check_cp1_registers(ctx
, fs
);
12421 TCGv_i32 fp32
= tcg_temp_new_i32();
12422 TCGv_i64 fp64
= tcg_temp_new_i64();
12424 gen_load_fpr64(ctx
, fp64
, fs
);
12425 if (ctx
->nan2008
) {
12426 gen_helper_float_ceil_2008_w_d(fp32
, cpu_env
, fp64
);
12428 gen_helper_float_ceil_w_d(fp32
, cpu_env
, fp64
);
12430 tcg_temp_free_i64(fp64
);
12431 gen_store_fpr32(ctx
, fp32
, fd
);
12432 tcg_temp_free_i32(fp32
);
12435 case OPC_FLOOR_W_D
:
12436 check_cp1_registers(ctx
, fs
);
12438 TCGv_i32 fp32
= tcg_temp_new_i32();
12439 TCGv_i64 fp64
= tcg_temp_new_i64();
12441 gen_load_fpr64(ctx
, fp64
, fs
);
12442 if (ctx
->nan2008
) {
12443 gen_helper_float_floor_2008_w_d(fp32
, cpu_env
, fp64
);
12445 gen_helper_float_floor_w_d(fp32
, cpu_env
, fp64
);
12447 tcg_temp_free_i64(fp64
);
12448 gen_store_fpr32(ctx
, fp32
, fd
);
12449 tcg_temp_free_i32(fp32
);
12453 check_insn(ctx
, ISA_MIPS32R6
);
12454 gen_sel_d(ctx
, op1
, fd
, ft
, fs
);
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_opc_removed(ctx
, ISA_MIPS32R6
);
12466 gen_movcf_d(ctx
, fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
12469 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
12471 TCGLabel
*l1
= gen_new_label();
12475 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
12477 fp0
= tcg_temp_new_i64();
12478 gen_load_fpr64(ctx
, fp0
, fs
);
12479 gen_store_fpr64(ctx
, fp0
, fd
);
12480 tcg_temp_free_i64(fp0
);
12485 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
12487 TCGLabel
*l1
= gen_new_label();
12491 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
12492 fp0
= tcg_temp_new_i64();
12493 gen_load_fpr64(ctx
, fp0
, fs
);
12494 gen_store_fpr64(ctx
, fp0
, fd
);
12495 tcg_temp_free_i64(fp0
);
12501 check_cp1_registers(ctx
, fs
| fd
);
12503 TCGv_i64 fp0
= tcg_temp_new_i64();
12505 gen_load_fpr64(ctx
, fp0
, fs
);
12506 gen_helper_float_recip_d(fp0
, cpu_env
, fp0
);
12507 gen_store_fpr64(ctx
, fp0
, fd
);
12508 tcg_temp_free_i64(fp0
);
12512 check_cp1_registers(ctx
, fs
| fd
);
12514 TCGv_i64 fp0
= tcg_temp_new_i64();
12516 gen_load_fpr64(ctx
, fp0
, fs
);
12517 gen_helper_float_rsqrt_d(fp0
, cpu_env
, fp0
);
12518 gen_store_fpr64(ctx
, fp0
, fd
);
12519 tcg_temp_free_i64(fp0
);
12523 check_insn(ctx
, ISA_MIPS32R6
);
12525 TCGv_i64 fp0
= tcg_temp_new_i64();
12526 TCGv_i64 fp1
= tcg_temp_new_i64();
12527 TCGv_i64 fp2
= tcg_temp_new_i64();
12528 gen_load_fpr64(ctx
, fp0
, fs
);
12529 gen_load_fpr64(ctx
, fp1
, ft
);
12530 gen_load_fpr64(ctx
, fp2
, fd
);
12531 gen_helper_float_maddf_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12532 gen_store_fpr64(ctx
, fp2
, fd
);
12533 tcg_temp_free_i64(fp2
);
12534 tcg_temp_free_i64(fp1
);
12535 tcg_temp_free_i64(fp0
);
12539 check_insn(ctx
, ISA_MIPS32R6
);
12541 TCGv_i64 fp0
= tcg_temp_new_i64();
12542 TCGv_i64 fp1
= tcg_temp_new_i64();
12543 TCGv_i64 fp2
= tcg_temp_new_i64();
12544 gen_load_fpr64(ctx
, fp0
, fs
);
12545 gen_load_fpr64(ctx
, fp1
, ft
);
12546 gen_load_fpr64(ctx
, fp2
, fd
);
12547 gen_helper_float_msubf_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12548 gen_store_fpr64(ctx
, fp2
, fd
);
12549 tcg_temp_free_i64(fp2
);
12550 tcg_temp_free_i64(fp1
);
12551 tcg_temp_free_i64(fp0
);
12555 check_insn(ctx
, ISA_MIPS32R6
);
12557 TCGv_i64 fp0
= tcg_temp_new_i64();
12558 gen_load_fpr64(ctx
, fp0
, fs
);
12559 gen_helper_float_rint_d(fp0
, cpu_env
, fp0
);
12560 gen_store_fpr64(ctx
, fp0
, fd
);
12561 tcg_temp_free_i64(fp0
);
12565 check_insn(ctx
, ISA_MIPS32R6
);
12567 TCGv_i64 fp0
= tcg_temp_new_i64();
12568 gen_load_fpr64(ctx
, fp0
, fs
);
12569 gen_helper_float_class_d(fp0
, cpu_env
, fp0
);
12570 gen_store_fpr64(ctx
, fp0
, fd
);
12571 tcg_temp_free_i64(fp0
);
12574 case OPC_MIN_D
: /* OPC_RECIP2_D */
12575 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
12577 TCGv_i64 fp0
= tcg_temp_new_i64();
12578 TCGv_i64 fp1
= tcg_temp_new_i64();
12579 gen_load_fpr64(ctx
, fp0
, fs
);
12580 gen_load_fpr64(ctx
, fp1
, ft
);
12581 gen_helper_float_min_d(fp1
, cpu_env
, fp0
, fp1
);
12582 gen_store_fpr64(ctx
, fp1
, fd
);
12583 tcg_temp_free_i64(fp1
);
12584 tcg_temp_free_i64(fp0
);
12587 check_cp1_64bitmode(ctx
);
12589 TCGv_i64 fp0
= tcg_temp_new_i64();
12590 TCGv_i64 fp1
= tcg_temp_new_i64();
12592 gen_load_fpr64(ctx
, fp0
, fs
);
12593 gen_load_fpr64(ctx
, fp1
, ft
);
12594 gen_helper_float_recip2_d(fp0
, cpu_env
, fp0
, fp1
);
12595 tcg_temp_free_i64(fp1
);
12596 gen_store_fpr64(ctx
, fp0
, fd
);
12597 tcg_temp_free_i64(fp0
);
12601 case OPC_MINA_D
: /* OPC_RECIP1_D */
12602 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
12604 TCGv_i64 fp0
= tcg_temp_new_i64();
12605 TCGv_i64 fp1
= tcg_temp_new_i64();
12606 gen_load_fpr64(ctx
, fp0
, fs
);
12607 gen_load_fpr64(ctx
, fp1
, ft
);
12608 gen_helper_float_mina_d(fp1
, cpu_env
, fp0
, fp1
);
12609 gen_store_fpr64(ctx
, fp1
, fd
);
12610 tcg_temp_free_i64(fp1
);
12611 tcg_temp_free_i64(fp0
);
12614 check_cp1_64bitmode(ctx
);
12616 TCGv_i64 fp0
= tcg_temp_new_i64();
12618 gen_load_fpr64(ctx
, fp0
, fs
);
12619 gen_helper_float_recip1_d(fp0
, cpu_env
, fp0
);
12620 gen_store_fpr64(ctx
, fp0
, fd
);
12621 tcg_temp_free_i64(fp0
);
12625 case OPC_MAX_D
: /* OPC_RSQRT1_D */
12626 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
12628 TCGv_i64 fp0
= tcg_temp_new_i64();
12629 TCGv_i64 fp1
= tcg_temp_new_i64();
12630 gen_load_fpr64(ctx
, fp0
, fs
);
12631 gen_load_fpr64(ctx
, fp1
, ft
);
12632 gen_helper_float_max_d(fp1
, cpu_env
, fp0
, fp1
);
12633 gen_store_fpr64(ctx
, fp1
, fd
);
12634 tcg_temp_free_i64(fp1
);
12635 tcg_temp_free_i64(fp0
);
12638 check_cp1_64bitmode(ctx
);
12640 TCGv_i64 fp0
= tcg_temp_new_i64();
12642 gen_load_fpr64(ctx
, fp0
, fs
);
12643 gen_helper_float_rsqrt1_d(fp0
, cpu_env
, fp0
);
12644 gen_store_fpr64(ctx
, fp0
, fd
);
12645 tcg_temp_free_i64(fp0
);
12649 case OPC_MAXA_D
: /* OPC_RSQRT2_D */
12650 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
12652 TCGv_i64 fp0
= tcg_temp_new_i64();
12653 TCGv_i64 fp1
= tcg_temp_new_i64();
12654 gen_load_fpr64(ctx
, fp0
, fs
);
12655 gen_load_fpr64(ctx
, fp1
, ft
);
12656 gen_helper_float_maxa_d(fp1
, cpu_env
, fp0
, fp1
);
12657 gen_store_fpr64(ctx
, fp1
, fd
);
12658 tcg_temp_free_i64(fp1
);
12659 tcg_temp_free_i64(fp0
);
12662 check_cp1_64bitmode(ctx
);
12664 TCGv_i64 fp0
= tcg_temp_new_i64();
12665 TCGv_i64 fp1
= tcg_temp_new_i64();
12667 gen_load_fpr64(ctx
, fp0
, fs
);
12668 gen_load_fpr64(ctx
, fp1
, ft
);
12669 gen_helper_float_rsqrt2_d(fp0
, cpu_env
, fp0
, fp1
);
12670 tcg_temp_free_i64(fp1
);
12671 gen_store_fpr64(ctx
, fp0
, fd
);
12672 tcg_temp_free_i64(fp0
);
12679 case OPC_CMP_UEQ_D
:
12680 case OPC_CMP_OLT_D
:
12681 case OPC_CMP_ULT_D
:
12682 case OPC_CMP_OLE_D
:
12683 case OPC_CMP_ULE_D
:
12685 case OPC_CMP_NGLE_D
:
12686 case OPC_CMP_SEQ_D
:
12687 case OPC_CMP_NGL_D
:
12689 case OPC_CMP_NGE_D
:
12691 case OPC_CMP_NGT_D
:
12692 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
12693 if (ctx
->opcode
& (1 << 6)) {
12694 gen_cmpabs_d(ctx
, func
- 48, ft
, fs
, cc
);
12696 gen_cmp_d(ctx
, func
- 48, ft
, fs
, cc
);
12700 check_cp1_registers(ctx
, fs
);
12702 TCGv_i32 fp32
= tcg_temp_new_i32();
12703 TCGv_i64 fp64
= tcg_temp_new_i64();
12705 gen_load_fpr64(ctx
, fp64
, fs
);
12706 gen_helper_float_cvts_d(fp32
, cpu_env
, fp64
);
12707 tcg_temp_free_i64(fp64
);
12708 gen_store_fpr32(ctx
, fp32
, fd
);
12709 tcg_temp_free_i32(fp32
);
12713 check_cp1_registers(ctx
, fs
);
12715 TCGv_i32 fp32
= tcg_temp_new_i32();
12716 TCGv_i64 fp64
= tcg_temp_new_i64();
12718 gen_load_fpr64(ctx
, fp64
, fs
);
12719 if (ctx
->nan2008
) {
12720 gen_helper_float_cvt_2008_w_d(fp32
, cpu_env
, fp64
);
12722 gen_helper_float_cvt_w_d(fp32
, cpu_env
, fp64
);
12724 tcg_temp_free_i64(fp64
);
12725 gen_store_fpr32(ctx
, fp32
, fd
);
12726 tcg_temp_free_i32(fp32
);
12730 check_cp1_64bitmode(ctx
);
12732 TCGv_i64 fp0
= tcg_temp_new_i64();
12734 gen_load_fpr64(ctx
, fp0
, fs
);
12735 if (ctx
->nan2008
) {
12736 gen_helper_float_cvt_2008_l_d(fp0
, cpu_env
, fp0
);
12738 gen_helper_float_cvt_l_d(fp0
, cpu_env
, fp0
);
12740 gen_store_fpr64(ctx
, fp0
, fd
);
12741 tcg_temp_free_i64(fp0
);
12746 TCGv_i32 fp0
= tcg_temp_new_i32();
12748 gen_load_fpr32(ctx
, fp0
, fs
);
12749 gen_helper_float_cvts_w(fp0
, cpu_env
, fp0
);
12750 gen_store_fpr32(ctx
, fp0
, fd
);
12751 tcg_temp_free_i32(fp0
);
12755 check_cp1_registers(ctx
, fd
);
12757 TCGv_i32 fp32
= tcg_temp_new_i32();
12758 TCGv_i64 fp64
= tcg_temp_new_i64();
12760 gen_load_fpr32(ctx
, fp32
, fs
);
12761 gen_helper_float_cvtd_w(fp64
, cpu_env
, fp32
);
12762 tcg_temp_free_i32(fp32
);
12763 gen_store_fpr64(ctx
, fp64
, fd
);
12764 tcg_temp_free_i64(fp64
);
12768 check_cp1_64bitmode(ctx
);
12770 TCGv_i32 fp32
= tcg_temp_new_i32();
12771 TCGv_i64 fp64
= tcg_temp_new_i64();
12773 gen_load_fpr64(ctx
, fp64
, fs
);
12774 gen_helper_float_cvts_l(fp32
, cpu_env
, fp64
);
12775 tcg_temp_free_i64(fp64
);
12776 gen_store_fpr32(ctx
, fp32
, fd
);
12777 tcg_temp_free_i32(fp32
);
12781 check_cp1_64bitmode(ctx
);
12783 TCGv_i64 fp0
= tcg_temp_new_i64();
12785 gen_load_fpr64(ctx
, fp0
, fs
);
12786 gen_helper_float_cvtd_l(fp0
, cpu_env
, fp0
);
12787 gen_store_fpr64(ctx
, fp0
, fd
);
12788 tcg_temp_free_i64(fp0
);
12791 case OPC_CVT_PS_PW
:
12794 TCGv_i64 fp0
= tcg_temp_new_i64();
12796 gen_load_fpr64(ctx
, fp0
, fs
);
12797 gen_helper_float_cvtps_pw(fp0
, cpu_env
, fp0
);
12798 gen_store_fpr64(ctx
, fp0
, fd
);
12799 tcg_temp_free_i64(fp0
);
12805 TCGv_i64 fp0
= tcg_temp_new_i64();
12806 TCGv_i64 fp1
= tcg_temp_new_i64();
12808 gen_load_fpr64(ctx
, fp0
, fs
);
12809 gen_load_fpr64(ctx
, fp1
, ft
);
12810 gen_helper_float_add_ps(fp0
, cpu_env
, fp0
, fp1
);
12811 tcg_temp_free_i64(fp1
);
12812 gen_store_fpr64(ctx
, fp0
, fd
);
12813 tcg_temp_free_i64(fp0
);
12819 TCGv_i64 fp0
= tcg_temp_new_i64();
12820 TCGv_i64 fp1
= tcg_temp_new_i64();
12822 gen_load_fpr64(ctx
, fp0
, fs
);
12823 gen_load_fpr64(ctx
, fp1
, ft
);
12824 gen_helper_float_sub_ps(fp0
, cpu_env
, fp0
, fp1
);
12825 tcg_temp_free_i64(fp1
);
12826 gen_store_fpr64(ctx
, fp0
, fd
);
12827 tcg_temp_free_i64(fp0
);
12833 TCGv_i64 fp0
= tcg_temp_new_i64();
12834 TCGv_i64 fp1
= tcg_temp_new_i64();
12836 gen_load_fpr64(ctx
, fp0
, fs
);
12837 gen_load_fpr64(ctx
, fp1
, ft
);
12838 gen_helper_float_mul_ps(fp0
, cpu_env
, fp0
, fp1
);
12839 tcg_temp_free_i64(fp1
);
12840 gen_store_fpr64(ctx
, fp0
, fd
);
12841 tcg_temp_free_i64(fp0
);
12847 TCGv_i64 fp0
= tcg_temp_new_i64();
12849 gen_load_fpr64(ctx
, fp0
, fs
);
12850 gen_helper_float_abs_ps(fp0
, fp0
);
12851 gen_store_fpr64(ctx
, fp0
, fd
);
12852 tcg_temp_free_i64(fp0
);
12858 TCGv_i64 fp0
= tcg_temp_new_i64();
12860 gen_load_fpr64(ctx
, fp0
, fs
);
12861 gen_store_fpr64(ctx
, fp0
, fd
);
12862 tcg_temp_free_i64(fp0
);
12868 TCGv_i64 fp0
= tcg_temp_new_i64();
12870 gen_load_fpr64(ctx
, fp0
, fs
);
12871 gen_helper_float_chs_ps(fp0
, fp0
);
12872 gen_store_fpr64(ctx
, fp0
, fd
);
12873 tcg_temp_free_i64(fp0
);
12878 gen_movcf_ps(ctx
, fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
12883 TCGLabel
*l1
= gen_new_label();
12887 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
12889 fp0
= tcg_temp_new_i64();
12890 gen_load_fpr64(ctx
, fp0
, fs
);
12891 gen_store_fpr64(ctx
, fp0
, fd
);
12892 tcg_temp_free_i64(fp0
);
12899 TCGLabel
*l1
= gen_new_label();
12903 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
12904 fp0
= tcg_temp_new_i64();
12905 gen_load_fpr64(ctx
, fp0
, fs
);
12906 gen_store_fpr64(ctx
, fp0
, fd
);
12907 tcg_temp_free_i64(fp0
);
12915 TCGv_i64 fp0
= tcg_temp_new_i64();
12916 TCGv_i64 fp1
= tcg_temp_new_i64();
12918 gen_load_fpr64(ctx
, fp0
, ft
);
12919 gen_load_fpr64(ctx
, fp1
, fs
);
12920 gen_helper_float_addr_ps(fp0
, cpu_env
, fp0
, fp1
);
12921 tcg_temp_free_i64(fp1
);
12922 gen_store_fpr64(ctx
, fp0
, fd
);
12923 tcg_temp_free_i64(fp0
);
12929 TCGv_i64 fp0
= tcg_temp_new_i64();
12930 TCGv_i64 fp1
= tcg_temp_new_i64();
12932 gen_load_fpr64(ctx
, fp0
, ft
);
12933 gen_load_fpr64(ctx
, fp1
, fs
);
12934 gen_helper_float_mulr_ps(fp0
, cpu_env
, fp0
, fp1
);
12935 tcg_temp_free_i64(fp1
);
12936 gen_store_fpr64(ctx
, fp0
, fd
);
12937 tcg_temp_free_i64(fp0
);
12940 case OPC_RECIP2_PS
:
12943 TCGv_i64 fp0
= tcg_temp_new_i64();
12944 TCGv_i64 fp1
= tcg_temp_new_i64();
12946 gen_load_fpr64(ctx
, fp0
, fs
);
12947 gen_load_fpr64(ctx
, fp1
, ft
);
12948 gen_helper_float_recip2_ps(fp0
, cpu_env
, fp0
, fp1
);
12949 tcg_temp_free_i64(fp1
);
12950 gen_store_fpr64(ctx
, fp0
, fd
);
12951 tcg_temp_free_i64(fp0
);
12954 case OPC_RECIP1_PS
:
12957 TCGv_i64 fp0
= tcg_temp_new_i64();
12959 gen_load_fpr64(ctx
, fp0
, fs
);
12960 gen_helper_float_recip1_ps(fp0
, cpu_env
, fp0
);
12961 gen_store_fpr64(ctx
, fp0
, fd
);
12962 tcg_temp_free_i64(fp0
);
12965 case OPC_RSQRT1_PS
:
12968 TCGv_i64 fp0
= tcg_temp_new_i64();
12970 gen_load_fpr64(ctx
, fp0
, fs
);
12971 gen_helper_float_rsqrt1_ps(fp0
, cpu_env
, fp0
);
12972 gen_store_fpr64(ctx
, fp0
, fd
);
12973 tcg_temp_free_i64(fp0
);
12976 case OPC_RSQRT2_PS
:
12979 TCGv_i64 fp0
= tcg_temp_new_i64();
12980 TCGv_i64 fp1
= tcg_temp_new_i64();
12982 gen_load_fpr64(ctx
, fp0
, fs
);
12983 gen_load_fpr64(ctx
, fp1
, ft
);
12984 gen_helper_float_rsqrt2_ps(fp0
, cpu_env
, fp0
, fp1
);
12985 tcg_temp_free_i64(fp1
);
12986 gen_store_fpr64(ctx
, fp0
, fd
);
12987 tcg_temp_free_i64(fp0
);
12991 check_cp1_64bitmode(ctx
);
12993 TCGv_i32 fp0
= tcg_temp_new_i32();
12995 gen_load_fpr32h(ctx
, fp0
, fs
);
12996 gen_helper_float_cvts_pu(fp0
, cpu_env
, fp0
);
12997 gen_store_fpr32(ctx
, fp0
, fd
);
12998 tcg_temp_free_i32(fp0
);
13001 case OPC_CVT_PW_PS
:
13004 TCGv_i64 fp0
= tcg_temp_new_i64();
13006 gen_load_fpr64(ctx
, fp0
, fs
);
13007 gen_helper_float_cvtpw_ps(fp0
, cpu_env
, fp0
);
13008 gen_store_fpr64(ctx
, fp0
, fd
);
13009 tcg_temp_free_i64(fp0
);
13013 check_cp1_64bitmode(ctx
);
13015 TCGv_i32 fp0
= tcg_temp_new_i32();
13017 gen_load_fpr32(ctx
, fp0
, fs
);
13018 gen_helper_float_cvts_pl(fp0
, cpu_env
, fp0
);
13019 gen_store_fpr32(ctx
, fp0
, fd
);
13020 tcg_temp_free_i32(fp0
);
13026 TCGv_i32 fp0
= tcg_temp_new_i32();
13027 TCGv_i32 fp1
= tcg_temp_new_i32();
13029 gen_load_fpr32(ctx
, fp0
, fs
);
13030 gen_load_fpr32(ctx
, fp1
, ft
);
13031 gen_store_fpr32h(ctx
, fp0
, fd
);
13032 gen_store_fpr32(ctx
, fp1
, fd
);
13033 tcg_temp_free_i32(fp0
);
13034 tcg_temp_free_i32(fp1
);
13040 TCGv_i32 fp0
= tcg_temp_new_i32();
13041 TCGv_i32 fp1
= tcg_temp_new_i32();
13043 gen_load_fpr32(ctx
, fp0
, fs
);
13044 gen_load_fpr32h(ctx
, fp1
, ft
);
13045 gen_store_fpr32(ctx
, fp1
, fd
);
13046 gen_store_fpr32h(ctx
, fp0
, fd
);
13047 tcg_temp_free_i32(fp0
);
13048 tcg_temp_free_i32(fp1
);
13054 TCGv_i32 fp0
= tcg_temp_new_i32();
13055 TCGv_i32 fp1
= tcg_temp_new_i32();
13057 gen_load_fpr32h(ctx
, fp0
, fs
);
13058 gen_load_fpr32(ctx
, fp1
, ft
);
13059 gen_store_fpr32(ctx
, fp1
, fd
);
13060 gen_store_fpr32h(ctx
, fp0
, fd
);
13061 tcg_temp_free_i32(fp0
);
13062 tcg_temp_free_i32(fp1
);
13068 TCGv_i32 fp0
= tcg_temp_new_i32();
13069 TCGv_i32 fp1
= tcg_temp_new_i32();
13071 gen_load_fpr32h(ctx
, fp0
, fs
);
13072 gen_load_fpr32h(ctx
, fp1
, ft
);
13073 gen_store_fpr32(ctx
, fp1
, fd
);
13074 gen_store_fpr32h(ctx
, fp0
, fd
);
13075 tcg_temp_free_i32(fp0
);
13076 tcg_temp_free_i32(fp1
);
13080 case OPC_CMP_UN_PS
:
13081 case OPC_CMP_EQ_PS
:
13082 case OPC_CMP_UEQ_PS
:
13083 case OPC_CMP_OLT_PS
:
13084 case OPC_CMP_ULT_PS
:
13085 case OPC_CMP_OLE_PS
:
13086 case OPC_CMP_ULE_PS
:
13087 case OPC_CMP_SF_PS
:
13088 case OPC_CMP_NGLE_PS
:
13089 case OPC_CMP_SEQ_PS
:
13090 case OPC_CMP_NGL_PS
:
13091 case OPC_CMP_LT_PS
:
13092 case OPC_CMP_NGE_PS
:
13093 case OPC_CMP_LE_PS
:
13094 case OPC_CMP_NGT_PS
:
13095 if (ctx
->opcode
& (1 << 6)) {
13096 gen_cmpabs_ps(ctx
, func
- 48, ft
, fs
, cc
);
13098 gen_cmp_ps(ctx
, func
- 48, ft
, fs
, cc
);
13102 MIPS_INVAL("farith");
13103 generate_exception_end(ctx
, EXCP_RI
);
13108 /* Coprocessor 3 (FPU) */
13109 static void gen_flt3_ldst(DisasContext
*ctx
, uint32_t opc
,
13110 int fd
, int fs
, int base
, int index
)
13112 TCGv t0
= tcg_temp_new();
13115 gen_load_gpr(t0
, index
);
13116 } else if (index
== 0) {
13117 gen_load_gpr(t0
, base
);
13119 gen_op_addr_add(ctx
, t0
, cpu_gpr
[base
], cpu_gpr
[index
]);
13122 * Don't do NOP if destination is zero: we must perform the actual
13129 TCGv_i32 fp0
= tcg_temp_new_i32();
13131 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESL
);
13132 tcg_gen_trunc_tl_i32(fp0
, t0
);
13133 gen_store_fpr32(ctx
, fp0
, fd
);
13134 tcg_temp_free_i32(fp0
);
13139 check_cp1_registers(ctx
, fd
);
13141 TCGv_i64 fp0
= tcg_temp_new_i64();
13142 tcg_gen_qemu_ld_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
13143 gen_store_fpr64(ctx
, fp0
, fd
);
13144 tcg_temp_free_i64(fp0
);
13148 check_cp1_64bitmode(ctx
);
13149 tcg_gen_andi_tl(t0
, t0
, ~0x7);
13151 TCGv_i64 fp0
= tcg_temp_new_i64();
13153 tcg_gen_qemu_ld_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
13154 gen_store_fpr64(ctx
, fp0
, fd
);
13155 tcg_temp_free_i64(fp0
);
13161 TCGv_i32 fp0
= tcg_temp_new_i32();
13162 gen_load_fpr32(ctx
, fp0
, fs
);
13163 tcg_gen_qemu_st_i32(fp0
, t0
, ctx
->mem_idx
, MO_TEUL
);
13164 tcg_temp_free_i32(fp0
);
13169 check_cp1_registers(ctx
, fs
);
13171 TCGv_i64 fp0
= tcg_temp_new_i64();
13172 gen_load_fpr64(ctx
, fp0
, fs
);
13173 tcg_gen_qemu_st_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
13174 tcg_temp_free_i64(fp0
);
13178 check_cp1_64bitmode(ctx
);
13179 tcg_gen_andi_tl(t0
, t0
, ~0x7);
13181 TCGv_i64 fp0
= tcg_temp_new_i64();
13182 gen_load_fpr64(ctx
, fp0
, fs
);
13183 tcg_gen_qemu_st_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
13184 tcg_temp_free_i64(fp0
);
13191 static void gen_flt3_arith(DisasContext
*ctx
, uint32_t opc
,
13192 int fd
, int fr
, int fs
, int ft
)
13198 TCGv t0
= tcg_temp_local_new();
13199 TCGv_i32 fp
= tcg_temp_new_i32();
13200 TCGv_i32 fph
= tcg_temp_new_i32();
13201 TCGLabel
*l1
= gen_new_label();
13202 TCGLabel
*l2
= gen_new_label();
13204 gen_load_gpr(t0
, fr
);
13205 tcg_gen_andi_tl(t0
, t0
, 0x7);
13207 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, 0, l1
);
13208 gen_load_fpr32(ctx
, fp
, fs
);
13209 gen_load_fpr32h(ctx
, fph
, fs
);
13210 gen_store_fpr32(ctx
, fp
, fd
);
13211 gen_store_fpr32h(ctx
, fph
, fd
);
13214 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, 4, l2
);
13216 #ifdef TARGET_WORDS_BIGENDIAN
13217 gen_load_fpr32(ctx
, fp
, fs
);
13218 gen_load_fpr32h(ctx
, fph
, ft
);
13219 gen_store_fpr32h(ctx
, fp
, fd
);
13220 gen_store_fpr32(ctx
, fph
, fd
);
13222 gen_load_fpr32h(ctx
, fph
, fs
);
13223 gen_load_fpr32(ctx
, fp
, ft
);
13224 gen_store_fpr32(ctx
, fph
, fd
);
13225 gen_store_fpr32h(ctx
, fp
, fd
);
13228 tcg_temp_free_i32(fp
);
13229 tcg_temp_free_i32(fph
);
13235 TCGv_i32 fp0
= tcg_temp_new_i32();
13236 TCGv_i32 fp1
= tcg_temp_new_i32();
13237 TCGv_i32 fp2
= tcg_temp_new_i32();
13239 gen_load_fpr32(ctx
, fp0
, fs
);
13240 gen_load_fpr32(ctx
, fp1
, ft
);
13241 gen_load_fpr32(ctx
, fp2
, fr
);
13242 gen_helper_float_madd_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
13243 tcg_temp_free_i32(fp0
);
13244 tcg_temp_free_i32(fp1
);
13245 gen_store_fpr32(ctx
, fp2
, fd
);
13246 tcg_temp_free_i32(fp2
);
13251 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
13253 TCGv_i64 fp0
= tcg_temp_new_i64();
13254 TCGv_i64 fp1
= tcg_temp_new_i64();
13255 TCGv_i64 fp2
= tcg_temp_new_i64();
13257 gen_load_fpr64(ctx
, fp0
, fs
);
13258 gen_load_fpr64(ctx
, fp1
, ft
);
13259 gen_load_fpr64(ctx
, fp2
, fr
);
13260 gen_helper_float_madd_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
13261 tcg_temp_free_i64(fp0
);
13262 tcg_temp_free_i64(fp1
);
13263 gen_store_fpr64(ctx
, fp2
, fd
);
13264 tcg_temp_free_i64(fp2
);
13270 TCGv_i64 fp0
= tcg_temp_new_i64();
13271 TCGv_i64 fp1
= tcg_temp_new_i64();
13272 TCGv_i64 fp2
= tcg_temp_new_i64();
13274 gen_load_fpr64(ctx
, fp0
, fs
);
13275 gen_load_fpr64(ctx
, fp1
, ft
);
13276 gen_load_fpr64(ctx
, fp2
, fr
);
13277 gen_helper_float_madd_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
13278 tcg_temp_free_i64(fp0
);
13279 tcg_temp_free_i64(fp1
);
13280 gen_store_fpr64(ctx
, fp2
, fd
);
13281 tcg_temp_free_i64(fp2
);
13287 TCGv_i32 fp0
= tcg_temp_new_i32();
13288 TCGv_i32 fp1
= tcg_temp_new_i32();
13289 TCGv_i32 fp2
= tcg_temp_new_i32();
13291 gen_load_fpr32(ctx
, fp0
, fs
);
13292 gen_load_fpr32(ctx
, fp1
, ft
);
13293 gen_load_fpr32(ctx
, fp2
, fr
);
13294 gen_helper_float_msub_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
13295 tcg_temp_free_i32(fp0
);
13296 tcg_temp_free_i32(fp1
);
13297 gen_store_fpr32(ctx
, fp2
, fd
);
13298 tcg_temp_free_i32(fp2
);
13303 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
13305 TCGv_i64 fp0
= tcg_temp_new_i64();
13306 TCGv_i64 fp1
= tcg_temp_new_i64();
13307 TCGv_i64 fp2
= tcg_temp_new_i64();
13309 gen_load_fpr64(ctx
, fp0
, fs
);
13310 gen_load_fpr64(ctx
, fp1
, ft
);
13311 gen_load_fpr64(ctx
, fp2
, fr
);
13312 gen_helper_float_msub_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
13313 tcg_temp_free_i64(fp0
);
13314 tcg_temp_free_i64(fp1
);
13315 gen_store_fpr64(ctx
, fp2
, fd
);
13316 tcg_temp_free_i64(fp2
);
13322 TCGv_i64 fp0
= tcg_temp_new_i64();
13323 TCGv_i64 fp1
= tcg_temp_new_i64();
13324 TCGv_i64 fp2
= tcg_temp_new_i64();
13326 gen_load_fpr64(ctx
, fp0
, fs
);
13327 gen_load_fpr64(ctx
, fp1
, ft
);
13328 gen_load_fpr64(ctx
, fp2
, fr
);
13329 gen_helper_float_msub_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
13330 tcg_temp_free_i64(fp0
);
13331 tcg_temp_free_i64(fp1
);
13332 gen_store_fpr64(ctx
, fp2
, fd
);
13333 tcg_temp_free_i64(fp2
);
13339 TCGv_i32 fp0
= tcg_temp_new_i32();
13340 TCGv_i32 fp1
= tcg_temp_new_i32();
13341 TCGv_i32 fp2
= tcg_temp_new_i32();
13343 gen_load_fpr32(ctx
, fp0
, fs
);
13344 gen_load_fpr32(ctx
, fp1
, ft
);
13345 gen_load_fpr32(ctx
, fp2
, fr
);
13346 gen_helper_float_nmadd_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
13347 tcg_temp_free_i32(fp0
);
13348 tcg_temp_free_i32(fp1
);
13349 gen_store_fpr32(ctx
, fp2
, fd
);
13350 tcg_temp_free_i32(fp2
);
13355 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
13357 TCGv_i64 fp0
= tcg_temp_new_i64();
13358 TCGv_i64 fp1
= tcg_temp_new_i64();
13359 TCGv_i64 fp2
= tcg_temp_new_i64();
13361 gen_load_fpr64(ctx
, fp0
, fs
);
13362 gen_load_fpr64(ctx
, fp1
, ft
);
13363 gen_load_fpr64(ctx
, fp2
, fr
);
13364 gen_helper_float_nmadd_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
13365 tcg_temp_free_i64(fp0
);
13366 tcg_temp_free_i64(fp1
);
13367 gen_store_fpr64(ctx
, fp2
, fd
);
13368 tcg_temp_free_i64(fp2
);
13374 TCGv_i64 fp0
= tcg_temp_new_i64();
13375 TCGv_i64 fp1
= tcg_temp_new_i64();
13376 TCGv_i64 fp2
= tcg_temp_new_i64();
13378 gen_load_fpr64(ctx
, fp0
, fs
);
13379 gen_load_fpr64(ctx
, fp1
, ft
);
13380 gen_load_fpr64(ctx
, fp2
, fr
);
13381 gen_helper_float_nmadd_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
13382 tcg_temp_free_i64(fp0
);
13383 tcg_temp_free_i64(fp1
);
13384 gen_store_fpr64(ctx
, fp2
, fd
);
13385 tcg_temp_free_i64(fp2
);
13391 TCGv_i32 fp0
= tcg_temp_new_i32();
13392 TCGv_i32 fp1
= tcg_temp_new_i32();
13393 TCGv_i32 fp2
= tcg_temp_new_i32();
13395 gen_load_fpr32(ctx
, fp0
, fs
);
13396 gen_load_fpr32(ctx
, fp1
, ft
);
13397 gen_load_fpr32(ctx
, fp2
, fr
);
13398 gen_helper_float_nmsub_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
13399 tcg_temp_free_i32(fp0
);
13400 tcg_temp_free_i32(fp1
);
13401 gen_store_fpr32(ctx
, fp2
, fd
);
13402 tcg_temp_free_i32(fp2
);
13407 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
13409 TCGv_i64 fp0
= tcg_temp_new_i64();
13410 TCGv_i64 fp1
= tcg_temp_new_i64();
13411 TCGv_i64 fp2
= tcg_temp_new_i64();
13413 gen_load_fpr64(ctx
, fp0
, fs
);
13414 gen_load_fpr64(ctx
, fp1
, ft
);
13415 gen_load_fpr64(ctx
, fp2
, fr
);
13416 gen_helper_float_nmsub_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
13417 tcg_temp_free_i64(fp0
);
13418 tcg_temp_free_i64(fp1
);
13419 gen_store_fpr64(ctx
, fp2
, fd
);
13420 tcg_temp_free_i64(fp2
);
13426 TCGv_i64 fp0
= tcg_temp_new_i64();
13427 TCGv_i64 fp1
= tcg_temp_new_i64();
13428 TCGv_i64 fp2
= tcg_temp_new_i64();
13430 gen_load_fpr64(ctx
, fp0
, fs
);
13431 gen_load_fpr64(ctx
, fp1
, ft
);
13432 gen_load_fpr64(ctx
, fp2
, fr
);
13433 gen_helper_float_nmsub_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
13434 tcg_temp_free_i64(fp0
);
13435 tcg_temp_free_i64(fp1
);
13436 gen_store_fpr64(ctx
, fp2
, fd
);
13437 tcg_temp_free_i64(fp2
);
13441 MIPS_INVAL("flt3_arith");
13442 generate_exception_end(ctx
, EXCP_RI
);
13447 static void gen_rdhwr(DisasContext
*ctx
, int rt
, int rd
, int sel
)
13451 #if !defined(CONFIG_USER_ONLY)
13453 * The Linux kernel will emulate rdhwr if it's not supported natively.
13454 * Therefore only check the ISA in system mode.
13456 check_insn(ctx
, ISA_MIPS32R2
);
13458 t0
= tcg_temp_new();
13462 gen_helper_rdhwr_cpunum(t0
, cpu_env
);
13463 gen_store_gpr(t0
, rt
);
13466 gen_helper_rdhwr_synci_step(t0
, cpu_env
);
13467 gen_store_gpr(t0
, rt
);
13470 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
13473 gen_helper_rdhwr_cc(t0
, cpu_env
);
13474 gen_store_gpr(t0
, rt
);
13476 * Break the TB to be able to take timer interrupts immediately
13477 * after reading count. DISAS_STOP isn't sufficient, we need to ensure
13478 * we break completely out of translated code.
13480 gen_save_pc(ctx
->base
.pc_next
+ 4);
13481 ctx
->base
.is_jmp
= DISAS_EXIT
;
13484 gen_helper_rdhwr_ccres(t0
, cpu_env
);
13485 gen_store_gpr(t0
, rt
);
13488 check_insn(ctx
, ISA_MIPS32R6
);
13491 * Performance counter registers are not implemented other than
13492 * control register 0.
13494 generate_exception(ctx
, EXCP_RI
);
13496 gen_helper_rdhwr_performance(t0
, cpu_env
);
13497 gen_store_gpr(t0
, rt
);
13500 check_insn(ctx
, ISA_MIPS32R6
);
13501 gen_helper_rdhwr_xnp(t0
, cpu_env
);
13502 gen_store_gpr(t0
, rt
);
13505 #if defined(CONFIG_USER_ONLY)
13506 tcg_gen_ld_tl(t0
, cpu_env
,
13507 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
13508 gen_store_gpr(t0
, rt
);
13511 if ((ctx
->hflags
& MIPS_HFLAG_CP0
) ||
13512 (ctx
->hflags
& MIPS_HFLAG_HWRENA_ULR
)) {
13513 tcg_gen_ld_tl(t0
, cpu_env
,
13514 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
13515 gen_store_gpr(t0
, rt
);
13517 generate_exception_end(ctx
, EXCP_RI
);
13521 default: /* Invalid */
13522 MIPS_INVAL("rdhwr");
13523 generate_exception_end(ctx
, EXCP_RI
);
13529 static inline void clear_branch_hflags(DisasContext
*ctx
)
13531 ctx
->hflags
&= ~MIPS_HFLAG_BMASK
;
13532 if (ctx
->base
.is_jmp
== DISAS_NEXT
) {
13533 save_cpu_state(ctx
, 0);
13536 * It is not safe to save ctx->hflags as hflags may be changed
13537 * in execution time by the instruction in delay / forbidden slot.
13539 tcg_gen_andi_i32(hflags
, hflags
, ~MIPS_HFLAG_BMASK
);
13543 static void gen_branch(DisasContext
*ctx
, int insn_bytes
)
13545 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
13546 int proc_hflags
= ctx
->hflags
& MIPS_HFLAG_BMASK
;
13547 /* Branches completion */
13548 clear_branch_hflags(ctx
);
13549 ctx
->base
.is_jmp
= DISAS_NORETURN
;
13550 /* FIXME: Need to clear can_do_io. */
13551 switch (proc_hflags
& MIPS_HFLAG_BMASK_BASE
) {
13552 case MIPS_HFLAG_FBNSLOT
:
13553 gen_goto_tb(ctx
, 0, ctx
->base
.pc_next
+ insn_bytes
);
13556 /* unconditional branch */
13557 if (proc_hflags
& MIPS_HFLAG_BX
) {
13558 tcg_gen_xori_i32(hflags
, hflags
, MIPS_HFLAG_M16
);
13560 gen_goto_tb(ctx
, 0, ctx
->btarget
);
13562 case MIPS_HFLAG_BL
:
13563 /* blikely taken case */
13564 gen_goto_tb(ctx
, 0, ctx
->btarget
);
13566 case MIPS_HFLAG_BC
:
13567 /* Conditional branch */
13569 TCGLabel
*l1
= gen_new_label();
13571 tcg_gen_brcondi_tl(TCG_COND_NE
, bcond
, 0, l1
);
13572 gen_goto_tb(ctx
, 1, ctx
->base
.pc_next
+ insn_bytes
);
13574 gen_goto_tb(ctx
, 0, ctx
->btarget
);
13577 case MIPS_HFLAG_BR
:
13578 /* unconditional branch to register */
13579 if (ctx
->insn_flags
& (ASE_MIPS16
| ASE_MICROMIPS
)) {
13580 TCGv t0
= tcg_temp_new();
13581 TCGv_i32 t1
= tcg_temp_new_i32();
13583 tcg_gen_andi_tl(t0
, btarget
, 0x1);
13584 tcg_gen_trunc_tl_i32(t1
, t0
);
13586 tcg_gen_andi_i32(hflags
, hflags
, ~(uint32_t)MIPS_HFLAG_M16
);
13587 tcg_gen_shli_i32(t1
, t1
, MIPS_HFLAG_M16_SHIFT
);
13588 tcg_gen_or_i32(hflags
, hflags
, t1
);
13589 tcg_temp_free_i32(t1
);
13591 tcg_gen_andi_tl(cpu_PC
, btarget
, ~(target_ulong
)0x1);
13593 tcg_gen_mov_tl(cpu_PC
, btarget
);
13595 if (ctx
->base
.singlestep_enabled
) {
13596 save_cpu_state(ctx
, 0);
13597 gen_helper_raise_exception_debug(cpu_env
);
13599 tcg_gen_lookup_and_goto_ptr();
13602 fprintf(stderr
, "unknown branch 0x%x\n", proc_hflags
);
13608 /* Compact Branches */
13609 static void gen_compute_compact_branch(DisasContext
*ctx
, uint32_t opc
,
13610 int rs
, int rt
, int32_t offset
)
13612 int bcond_compute
= 0;
13613 TCGv t0
= tcg_temp_new();
13614 TCGv t1
= tcg_temp_new();
13615 int m16_lowbit
= (ctx
->hflags
& MIPS_HFLAG_M16
) != 0;
13617 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
13618 #ifdef MIPS_DEBUG_DISAS
13619 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
13620 "\n", ctx
->base
.pc_next
);
13622 generate_exception_end(ctx
, EXCP_RI
);
13626 /* Load needed operands and calculate btarget */
13628 /* compact branch */
13629 case OPC_BOVC
: /* OPC_BEQZALC, OPC_BEQC */
13630 case OPC_BNVC
: /* OPC_BNEZALC, OPC_BNEC */
13631 gen_load_gpr(t0
, rs
);
13632 gen_load_gpr(t1
, rt
);
13634 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
13635 if (rs
<= rt
&& rs
== 0) {
13636 /* OPC_BEQZALC, OPC_BNEZALC */
13637 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 4 + m16_lowbit
);
13640 case OPC_BLEZC
: /* OPC_BGEZC, OPC_BGEC */
13641 case OPC_BGTZC
: /* OPC_BLTZC, OPC_BLTC */
13642 gen_load_gpr(t0
, rs
);
13643 gen_load_gpr(t1
, rt
);
13645 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
13647 case OPC_BLEZALC
: /* OPC_BGEZALC, OPC_BGEUC */
13648 case OPC_BGTZALC
: /* OPC_BLTZALC, OPC_BLTUC */
13649 if (rs
== 0 || rs
== rt
) {
13650 /* OPC_BLEZALC, OPC_BGEZALC */
13651 /* OPC_BGTZALC, OPC_BLTZALC */
13652 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 4 + m16_lowbit
);
13654 gen_load_gpr(t0
, rs
);
13655 gen_load_gpr(t1
, rt
);
13657 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
13661 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
13666 /* OPC_BEQZC, OPC_BNEZC */
13667 gen_load_gpr(t0
, rs
);
13669 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
13671 /* OPC_JIC, OPC_JIALC */
13672 TCGv tbase
= tcg_temp_new();
13673 TCGv toffset
= tcg_temp_new();
13675 gen_load_gpr(tbase
, rt
);
13676 tcg_gen_movi_tl(toffset
, offset
);
13677 gen_op_addr_add(ctx
, btarget
, tbase
, toffset
);
13678 tcg_temp_free(tbase
);
13679 tcg_temp_free(toffset
);
13683 MIPS_INVAL("Compact branch/jump");
13684 generate_exception_end(ctx
, EXCP_RI
);
13688 if (bcond_compute
== 0) {
13689 /* Uncoditional compact branch */
13692 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 4 + m16_lowbit
);
13695 ctx
->hflags
|= MIPS_HFLAG_BR
;
13698 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 4 + m16_lowbit
);
13701 ctx
->hflags
|= MIPS_HFLAG_B
;
13704 MIPS_INVAL("Compact branch/jump");
13705 generate_exception_end(ctx
, EXCP_RI
);
13709 /* Generating branch here as compact branches don't have delay slot */
13710 gen_branch(ctx
, 4);
13712 /* Conditional compact branch */
13713 TCGLabel
*fs
= gen_new_label();
13714 save_cpu_state(ctx
, 0);
13717 case OPC_BLEZALC
: /* OPC_BGEZALC, OPC_BGEUC */
13718 if (rs
== 0 && rt
!= 0) {
13720 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE
), t1
, 0, fs
);
13721 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
13723 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE
), t1
, 0, fs
);
13726 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU
), t0
, t1
, fs
);
13729 case OPC_BGTZALC
: /* OPC_BLTZALC, OPC_BLTUC */
13730 if (rs
== 0 && rt
!= 0) {
13732 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT
), t1
, 0, fs
);
13733 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
13735 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT
), t1
, 0, fs
);
13738 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU
), t0
, t1
, fs
);
13741 case OPC_BLEZC
: /* OPC_BGEZC, OPC_BGEC */
13742 if (rs
== 0 && rt
!= 0) {
13744 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE
), t1
, 0, fs
);
13745 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
13747 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE
), t1
, 0, fs
);
13750 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE
), t0
, t1
, fs
);
13753 case OPC_BGTZC
: /* OPC_BLTZC, OPC_BLTC */
13754 if (rs
== 0 && rt
!= 0) {
13756 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT
), t1
, 0, fs
);
13757 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
13759 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT
), t1
, 0, fs
);
13762 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT
), t0
, t1
, fs
);
13765 case OPC_BOVC
: /* OPC_BEQZALC, OPC_BEQC */
13766 case OPC_BNVC
: /* OPC_BNEZALC, OPC_BNEC */
13768 /* OPC_BOVC, OPC_BNVC */
13769 TCGv t2
= tcg_temp_new();
13770 TCGv t3
= tcg_temp_new();
13771 TCGv t4
= tcg_temp_new();
13772 TCGv input_overflow
= tcg_temp_new();
13774 gen_load_gpr(t0
, rs
);
13775 gen_load_gpr(t1
, rt
);
13776 tcg_gen_ext32s_tl(t2
, t0
);
13777 tcg_gen_setcond_tl(TCG_COND_NE
, input_overflow
, t2
, t0
);
13778 tcg_gen_ext32s_tl(t3
, t1
);
13779 tcg_gen_setcond_tl(TCG_COND_NE
, t4
, t3
, t1
);
13780 tcg_gen_or_tl(input_overflow
, input_overflow
, t4
);
13782 tcg_gen_add_tl(t4
, t2
, t3
);
13783 tcg_gen_ext32s_tl(t4
, t4
);
13784 tcg_gen_xor_tl(t2
, t2
, t3
);
13785 tcg_gen_xor_tl(t3
, t4
, t3
);
13786 tcg_gen_andc_tl(t2
, t3
, t2
);
13787 tcg_gen_setcondi_tl(TCG_COND_LT
, t4
, t2
, 0);
13788 tcg_gen_or_tl(t4
, t4
, input_overflow
);
13789 if (opc
== OPC_BOVC
) {
13791 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE
), t4
, 0, fs
);
13794 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ
), t4
, 0, fs
);
13796 tcg_temp_free(input_overflow
);
13800 } else if (rs
< rt
&& rs
== 0) {
13801 /* OPC_BEQZALC, OPC_BNEZALC */
13802 if (opc
== OPC_BEQZALC
) {
13804 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ
), t1
, 0, fs
);
13807 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE
), t1
, 0, fs
);
13810 /* OPC_BEQC, OPC_BNEC */
13811 if (opc
== OPC_BEQC
) {
13813 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ
), t0
, t1
, fs
);
13816 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE
), t0
, t1
, fs
);
13821 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ
), t0
, 0, fs
);
13824 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE
), t0
, 0, fs
);
13827 MIPS_INVAL("Compact conditional branch/jump");
13828 generate_exception_end(ctx
, EXCP_RI
);
13832 /* Generating branch here as compact branches don't have delay slot */
13833 gen_goto_tb(ctx
, 1, ctx
->btarget
);
13836 ctx
->hflags
|= MIPS_HFLAG_FBNSLOT
;
13844 /* ISA extensions (ASEs) */
13845 /* MIPS16 extension to MIPS32 */
13847 /* MIPS16 major opcodes */
13849 M16_OPC_ADDIUSP
= 0x00,
13850 M16_OPC_ADDIUPC
= 0x01,
13852 M16_OPC_JAL
= 0x03,
13853 M16_OPC_BEQZ
= 0x04,
13854 M16_OPC_BNEQZ
= 0x05,
13855 M16_OPC_SHIFT
= 0x06,
13857 M16_OPC_RRIA
= 0x08,
13858 M16_OPC_ADDIU8
= 0x09,
13859 M16_OPC_SLTI
= 0x0a,
13860 M16_OPC_SLTIU
= 0x0b,
13863 M16_OPC_CMPI
= 0x0e,
13867 M16_OPC_LWSP
= 0x12,
13869 M16_OPC_LBU
= 0x14,
13870 M16_OPC_LHU
= 0x15,
13871 M16_OPC_LWPC
= 0x16,
13872 M16_OPC_LWU
= 0x17,
13875 M16_OPC_SWSP
= 0x1a,
13877 M16_OPC_RRR
= 0x1c,
13879 M16_OPC_EXTEND
= 0x1e,
13883 /* I8 funct field */
13902 /* RR funct field */
13936 /* I64 funct field */
13944 I64_DADDIUPC
= 0x6,
13948 /* RR ry field for CNVT */
13950 RR_RY_CNVT_ZEB
= 0x0,
13951 RR_RY_CNVT_ZEH
= 0x1,
13952 RR_RY_CNVT_ZEW
= 0x2,
13953 RR_RY_CNVT_SEB
= 0x4,
13954 RR_RY_CNVT_SEH
= 0x5,
13955 RR_RY_CNVT_SEW
= 0x6,
13958 static int xlat(int r
)
13960 static int map
[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
13965 static void gen_mips16_save(DisasContext
*ctx
,
13966 int xsregs
, int aregs
,
13967 int do_ra
, int do_s0
, int do_s1
,
13970 TCGv t0
= tcg_temp_new();
13971 TCGv t1
= tcg_temp_new();
13972 TCGv t2
= tcg_temp_new();
14002 generate_exception_end(ctx
, EXCP_RI
);
14008 gen_base_offset_addr(ctx
, t0
, 29, 12);
14009 gen_load_gpr(t1
, 7);
14010 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
14013 gen_base_offset_addr(ctx
, t0
, 29, 8);
14014 gen_load_gpr(t1
, 6);
14015 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
14018 gen_base_offset_addr(ctx
, t0
, 29, 4);
14019 gen_load_gpr(t1
, 5);
14020 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
14023 gen_base_offset_addr(ctx
, t0
, 29, 0);
14024 gen_load_gpr(t1
, 4);
14025 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
14028 gen_load_gpr(t0
, 29);
14030 #define DECR_AND_STORE(reg) do { \
14031 tcg_gen_movi_tl(t2, -4); \
14032 gen_op_addr_add(ctx, t0, t0, t2); \
14033 gen_load_gpr(t1, reg); \
14034 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \
14038 DECR_AND_STORE(31);
14043 DECR_AND_STORE(30);
14046 DECR_AND_STORE(23);
14049 DECR_AND_STORE(22);
14052 DECR_AND_STORE(21);
14055 DECR_AND_STORE(20);
14058 DECR_AND_STORE(19);
14061 DECR_AND_STORE(18);
14065 DECR_AND_STORE(17);
14068 DECR_AND_STORE(16);
14098 generate_exception_end(ctx
, EXCP_RI
);
14114 #undef DECR_AND_STORE
14116 tcg_gen_movi_tl(t2
, -framesize
);
14117 gen_op_addr_add(ctx
, cpu_gpr
[29], cpu_gpr
[29], t2
);
14123 static void gen_mips16_restore(DisasContext
*ctx
,
14124 int xsregs
, int aregs
,
14125 int do_ra
, int do_s0
, int do_s1
,
14129 TCGv t0
= tcg_temp_new();
14130 TCGv t1
= tcg_temp_new();
14131 TCGv t2
= tcg_temp_new();
14133 tcg_gen_movi_tl(t2
, framesize
);
14134 gen_op_addr_add(ctx
, t0
, cpu_gpr
[29], t2
);
14136 #define DECR_AND_LOAD(reg) do { \
14137 tcg_gen_movi_tl(t2, -4); \
14138 gen_op_addr_add(ctx, t0, t0, t2); \
14139 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \
14140 gen_store_gpr(t1, reg); \
14204 generate_exception_end(ctx
, EXCP_RI
);
14220 #undef DECR_AND_LOAD
14222 tcg_gen_movi_tl(t2
, framesize
);
14223 gen_op_addr_add(ctx
, cpu_gpr
[29], cpu_gpr
[29], t2
);
14229 static void gen_addiupc(DisasContext
*ctx
, int rx
, int imm
,
14230 int is_64_bit
, int extended
)
14234 if (extended
&& (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
14235 generate_exception_end(ctx
, EXCP_RI
);
14239 t0
= tcg_temp_new();
14241 tcg_gen_movi_tl(t0
, pc_relative_pc(ctx
));
14242 tcg_gen_addi_tl(cpu_gpr
[rx
], t0
, imm
);
14244 tcg_gen_ext32s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
14250 static void gen_cache_operation(DisasContext
*ctx
, uint32_t op
, int base
,
14253 TCGv_i32 t0
= tcg_const_i32(op
);
14254 TCGv t1
= tcg_temp_new();
14255 gen_base_offset_addr(ctx
, t1
, base
, offset
);
14256 gen_helper_cache(cpu_env
, t1
, t0
);
14259 #if defined(TARGET_MIPS64)
14260 static void decode_i64_mips16(DisasContext
*ctx
,
14261 int ry
, int funct
, int16_t offset
,
14266 check_insn(ctx
, ISA_MIPS3
);
14267 check_mips_64(ctx
);
14268 offset
= extended
? offset
: offset
<< 3;
14269 gen_ld(ctx
, OPC_LD
, ry
, 29, offset
);
14272 check_insn(ctx
, ISA_MIPS3
);
14273 check_mips_64(ctx
);
14274 offset
= extended
? offset
: offset
<< 3;
14275 gen_st(ctx
, OPC_SD
, ry
, 29, offset
);
14278 check_insn(ctx
, ISA_MIPS3
);
14279 check_mips_64(ctx
);
14280 offset
= extended
? offset
: (ctx
->opcode
& 0xff) << 3;
14281 gen_st(ctx
, OPC_SD
, 31, 29, offset
);
14284 check_insn(ctx
, ISA_MIPS3
);
14285 check_mips_64(ctx
);
14286 offset
= extended
? offset
: ((int8_t)ctx
->opcode
) << 3;
14287 gen_arith_imm(ctx
, OPC_DADDIU
, 29, 29, offset
);
14290 check_insn(ctx
, ISA_MIPS3
);
14291 check_mips_64(ctx
);
14292 if (extended
&& (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
14293 generate_exception_end(ctx
, EXCP_RI
);
14295 offset
= extended
? offset
: offset
<< 3;
14296 gen_ld(ctx
, OPC_LDPC
, ry
, 0, offset
);
14300 check_insn(ctx
, ISA_MIPS3
);
14301 check_mips_64(ctx
);
14302 offset
= extended
? offset
: ((int8_t)(offset
<< 3)) >> 3;
14303 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, ry
, offset
);
14306 check_insn(ctx
, ISA_MIPS3
);
14307 check_mips_64(ctx
);
14308 offset
= extended
? offset
: offset
<< 2;
14309 gen_addiupc(ctx
, ry
, offset
, 1, extended
);
14312 check_insn(ctx
, ISA_MIPS3
);
14313 check_mips_64(ctx
);
14314 offset
= extended
? offset
: offset
<< 2;
14315 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, 29, offset
);
14321 static int decode_extended_mips16_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
14323 int extend
= cpu_lduw_code(env
, ctx
->base
.pc_next
+ 2);
14324 int op
, rx
, ry
, funct
, sa
;
14325 int16_t imm
, offset
;
14327 ctx
->opcode
= (ctx
->opcode
<< 16) | extend
;
14328 op
= (ctx
->opcode
>> 11) & 0x1f;
14329 sa
= (ctx
->opcode
>> 22) & 0x1f;
14330 funct
= (ctx
->opcode
>> 8) & 0x7;
14331 rx
= xlat((ctx
->opcode
>> 8) & 0x7);
14332 ry
= xlat((ctx
->opcode
>> 5) & 0x7);
14333 offset
= imm
= (int16_t) (((ctx
->opcode
>> 16) & 0x1f) << 11
14334 | ((ctx
->opcode
>> 21) & 0x3f) << 5
14335 | (ctx
->opcode
& 0x1f));
14338 * The extended opcodes cleverly reuse the opcodes from their 16-bit
14342 case M16_OPC_ADDIUSP
:
14343 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 29, imm
);
14345 case M16_OPC_ADDIUPC
:
14346 gen_addiupc(ctx
, rx
, imm
, 0, 1);
14349 gen_compute_branch(ctx
, OPC_BEQ
, 4, 0, 0, offset
<< 1, 0);
14350 /* No delay slot, so just process as a normal instruction */
14353 gen_compute_branch(ctx
, OPC_BEQ
, 4, rx
, 0, offset
<< 1, 0);
14354 /* No delay slot, so just process as a normal instruction */
14356 case M16_OPC_BNEQZ
:
14357 gen_compute_branch(ctx
, OPC_BNE
, 4, rx
, 0, offset
<< 1, 0);
14358 /* No delay slot, so just process as a normal instruction */
14360 case M16_OPC_SHIFT
:
14361 switch (ctx
->opcode
& 0x3) {
14363 gen_shift_imm(ctx
, OPC_SLL
, rx
, ry
, sa
);
14366 #if defined(TARGET_MIPS64)
14367 check_mips_64(ctx
);
14368 gen_shift_imm(ctx
, OPC_DSLL
, rx
, ry
, sa
);
14370 generate_exception_end(ctx
, EXCP_RI
);
14374 gen_shift_imm(ctx
, OPC_SRL
, rx
, ry
, sa
);
14377 gen_shift_imm(ctx
, OPC_SRA
, rx
, ry
, sa
);
14381 #if defined(TARGET_MIPS64)
14383 check_insn(ctx
, ISA_MIPS3
);
14384 check_mips_64(ctx
);
14385 gen_ld(ctx
, OPC_LD
, ry
, rx
, offset
);
14389 imm
= ctx
->opcode
& 0xf;
14390 imm
= imm
| ((ctx
->opcode
>> 20) & 0x7f) << 4;
14391 imm
= imm
| ((ctx
->opcode
>> 16) & 0xf) << 11;
14392 imm
= (int16_t) (imm
<< 1) >> 1;
14393 if ((ctx
->opcode
>> 4) & 0x1) {
14394 #if defined(TARGET_MIPS64)
14395 check_mips_64(ctx
);
14396 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, rx
, imm
);
14398 generate_exception_end(ctx
, EXCP_RI
);
14401 gen_arith_imm(ctx
, OPC_ADDIU
, ry
, rx
, imm
);
14404 case M16_OPC_ADDIU8
:
14405 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, rx
, imm
);
14408 gen_slt_imm(ctx
, OPC_SLTI
, 24, rx
, imm
);
14410 case M16_OPC_SLTIU
:
14411 gen_slt_imm(ctx
, OPC_SLTIU
, 24, rx
, imm
);
14416 gen_compute_branch(ctx
, OPC_BEQ
, 4, 24, 0, offset
<< 1, 0);
14419 gen_compute_branch(ctx
, OPC_BNE
, 4, 24, 0, offset
<< 1, 0);
14422 gen_st(ctx
, OPC_SW
, 31, 29, imm
);
14425 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, imm
);
14428 check_insn(ctx
, ISA_MIPS32
);
14430 int xsregs
= (ctx
->opcode
>> 24) & 0x7;
14431 int aregs
= (ctx
->opcode
>> 16) & 0xf;
14432 int do_ra
= (ctx
->opcode
>> 6) & 0x1;
14433 int do_s0
= (ctx
->opcode
>> 5) & 0x1;
14434 int do_s1
= (ctx
->opcode
>> 4) & 0x1;
14435 int framesize
= (((ctx
->opcode
>> 20) & 0xf) << 4
14436 | (ctx
->opcode
& 0xf)) << 3;
14438 if (ctx
->opcode
& (1 << 7)) {
14439 gen_mips16_save(ctx
, xsregs
, aregs
,
14440 do_ra
, do_s0
, do_s1
,
14443 gen_mips16_restore(ctx
, xsregs
, aregs
,
14444 do_ra
, do_s0
, do_s1
,
14450 generate_exception_end(ctx
, EXCP_RI
);
14455 tcg_gen_movi_tl(cpu_gpr
[rx
], (uint16_t) imm
);
14458 tcg_gen_xori_tl(cpu_gpr
[24], cpu_gpr
[rx
], (uint16_t) imm
);
14460 #if defined(TARGET_MIPS64)
14462 check_insn(ctx
, ISA_MIPS3
);
14463 check_mips_64(ctx
);
14464 gen_st(ctx
, OPC_SD
, ry
, rx
, offset
);
14468 gen_ld(ctx
, OPC_LB
, ry
, rx
, offset
);
14471 gen_ld(ctx
, OPC_LH
, ry
, rx
, offset
);
14474 gen_ld(ctx
, OPC_LW
, rx
, 29, offset
);
14477 gen_ld(ctx
, OPC_LW
, ry
, rx
, offset
);
14480 gen_ld(ctx
, OPC_LBU
, ry
, rx
, offset
);
14483 gen_ld(ctx
, OPC_LHU
, ry
, rx
, offset
);
14486 gen_ld(ctx
, OPC_LWPC
, rx
, 0, offset
);
14488 #if defined(TARGET_MIPS64)
14490 check_insn(ctx
, ISA_MIPS3
);
14491 check_mips_64(ctx
);
14492 gen_ld(ctx
, OPC_LWU
, ry
, rx
, offset
);
14496 gen_st(ctx
, OPC_SB
, ry
, rx
, offset
);
14499 gen_st(ctx
, OPC_SH
, ry
, rx
, offset
);
14502 gen_st(ctx
, OPC_SW
, rx
, 29, offset
);
14505 gen_st(ctx
, OPC_SW
, ry
, rx
, offset
);
14507 #if defined(TARGET_MIPS64)
14509 decode_i64_mips16(ctx
, ry
, funct
, offset
, 1);
14513 generate_exception_end(ctx
, EXCP_RI
);
14520 static inline bool is_uhi(int sdbbp_code
)
14522 #ifdef CONFIG_USER_ONLY
14525 return semihosting_enabled() && sdbbp_code
== 1;
14529 #ifdef CONFIG_USER_ONLY
14530 /* The above should dead-code away any calls to this..*/
14531 static inline void gen_helper_do_semihosting(void *env
)
14533 g_assert_not_reached();
14537 static int decode_mips16_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
14541 int op
, cnvt_op
, op1
, offset
;
14545 op
= (ctx
->opcode
>> 11) & 0x1f;
14546 sa
= (ctx
->opcode
>> 2) & 0x7;
14547 sa
= sa
== 0 ? 8 : sa
;
14548 rx
= xlat((ctx
->opcode
>> 8) & 0x7);
14549 cnvt_op
= (ctx
->opcode
>> 5) & 0x7;
14550 ry
= xlat((ctx
->opcode
>> 5) & 0x7);
14551 op1
= offset
= ctx
->opcode
& 0x1f;
14556 case M16_OPC_ADDIUSP
:
14558 int16_t imm
= ((uint8_t) ctx
->opcode
) << 2;
14560 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 29, imm
);
14563 case M16_OPC_ADDIUPC
:
14564 gen_addiupc(ctx
, rx
, ((uint8_t) ctx
->opcode
) << 2, 0, 0);
14567 offset
= (ctx
->opcode
& 0x7ff) << 1;
14568 offset
= (int16_t)(offset
<< 4) >> 4;
14569 gen_compute_branch(ctx
, OPC_BEQ
, 2, 0, 0, offset
, 0);
14570 /* No delay slot, so just process as a normal instruction */
14573 offset
= cpu_lduw_code(env
, ctx
->base
.pc_next
+ 2);
14574 offset
= (((ctx
->opcode
& 0x1f) << 21)
14575 | ((ctx
->opcode
>> 5) & 0x1f) << 16
14577 op
= ((ctx
->opcode
>> 10) & 0x1) ? OPC_JALX
: OPC_JAL
;
14578 gen_compute_branch(ctx
, op
, 4, rx
, ry
, offset
, 2);
14582 gen_compute_branch(ctx
, OPC_BEQ
, 2, rx
, 0,
14583 ((int8_t)ctx
->opcode
) << 1, 0);
14584 /* No delay slot, so just process as a normal instruction */
14586 case M16_OPC_BNEQZ
:
14587 gen_compute_branch(ctx
, OPC_BNE
, 2, rx
, 0,
14588 ((int8_t)ctx
->opcode
) << 1, 0);
14589 /* No delay slot, so just process as a normal instruction */
14591 case M16_OPC_SHIFT
:
14592 switch (ctx
->opcode
& 0x3) {
14594 gen_shift_imm(ctx
, OPC_SLL
, rx
, ry
, sa
);
14597 #if defined(TARGET_MIPS64)
14598 check_insn(ctx
, ISA_MIPS3
);
14599 check_mips_64(ctx
);
14600 gen_shift_imm(ctx
, OPC_DSLL
, rx
, ry
, sa
);
14602 generate_exception_end(ctx
, EXCP_RI
);
14606 gen_shift_imm(ctx
, OPC_SRL
, rx
, ry
, sa
);
14609 gen_shift_imm(ctx
, OPC_SRA
, rx
, ry
, sa
);
14613 #if defined(TARGET_MIPS64)
14615 check_insn(ctx
, ISA_MIPS3
);
14616 check_mips_64(ctx
);
14617 gen_ld(ctx
, OPC_LD
, ry
, rx
, offset
<< 3);
14622 int16_t imm
= (int8_t)((ctx
->opcode
& 0xf) << 4) >> 4;
14624 if ((ctx
->opcode
>> 4) & 1) {
14625 #if defined(TARGET_MIPS64)
14626 check_insn(ctx
, ISA_MIPS3
);
14627 check_mips_64(ctx
);
14628 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, rx
, imm
);
14630 generate_exception_end(ctx
, EXCP_RI
);
14633 gen_arith_imm(ctx
, OPC_ADDIU
, ry
, rx
, imm
);
14637 case M16_OPC_ADDIU8
:
14639 int16_t imm
= (int8_t) ctx
->opcode
;
14641 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, rx
, imm
);
14646 int16_t imm
= (uint8_t) ctx
->opcode
;
14647 gen_slt_imm(ctx
, OPC_SLTI
, 24, rx
, imm
);
14650 case M16_OPC_SLTIU
:
14652 int16_t imm
= (uint8_t) ctx
->opcode
;
14653 gen_slt_imm(ctx
, OPC_SLTIU
, 24, rx
, imm
);
14660 funct
= (ctx
->opcode
>> 8) & 0x7;
14663 gen_compute_branch(ctx
, OPC_BEQ
, 2, 24, 0,
14664 ((int8_t)ctx
->opcode
) << 1, 0);
14667 gen_compute_branch(ctx
, OPC_BNE
, 2, 24, 0,
14668 ((int8_t)ctx
->opcode
) << 1, 0);
14671 gen_st(ctx
, OPC_SW
, 31, 29, (ctx
->opcode
& 0xff) << 2);
14674 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29,
14675 ((int8_t)ctx
->opcode
) << 3);
14678 check_insn(ctx
, ISA_MIPS32
);
14680 int do_ra
= ctx
->opcode
& (1 << 6);
14681 int do_s0
= ctx
->opcode
& (1 << 5);
14682 int do_s1
= ctx
->opcode
& (1 << 4);
14683 int framesize
= ctx
->opcode
& 0xf;
14685 if (framesize
== 0) {
14688 framesize
= framesize
<< 3;
14691 if (ctx
->opcode
& (1 << 7)) {
14692 gen_mips16_save(ctx
, 0, 0,
14693 do_ra
, do_s0
, do_s1
, framesize
);
14695 gen_mips16_restore(ctx
, 0, 0,
14696 do_ra
, do_s0
, do_s1
, framesize
);
14702 int rz
= xlat(ctx
->opcode
& 0x7);
14704 reg32
= (((ctx
->opcode
>> 3) & 0x3) << 3) |
14705 ((ctx
->opcode
>> 5) & 0x7);
14706 gen_arith(ctx
, OPC_ADDU
, reg32
, rz
, 0);
14710 reg32
= ctx
->opcode
& 0x1f;
14711 gen_arith(ctx
, OPC_ADDU
, ry
, reg32
, 0);
14714 generate_exception_end(ctx
, EXCP_RI
);
14721 int16_t imm
= (uint8_t) ctx
->opcode
;
14723 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 0, imm
);
14728 int16_t imm
= (uint8_t) ctx
->opcode
;
14729 gen_logic_imm(ctx
, OPC_XORI
, 24, rx
, imm
);
14732 #if defined(TARGET_MIPS64)
14734 check_insn(ctx
, ISA_MIPS3
);
14735 check_mips_64(ctx
);
14736 gen_st(ctx
, OPC_SD
, ry
, rx
, offset
<< 3);
14740 gen_ld(ctx
, OPC_LB
, ry
, rx
, offset
);
14743 gen_ld(ctx
, OPC_LH
, ry
, rx
, offset
<< 1);
14746 gen_ld(ctx
, OPC_LW
, rx
, 29, ((uint8_t)ctx
->opcode
) << 2);
14749 gen_ld(ctx
, OPC_LW
, ry
, rx
, offset
<< 2);
14752 gen_ld(ctx
, OPC_LBU
, ry
, rx
, offset
);
14755 gen_ld(ctx
, OPC_LHU
, ry
, rx
, offset
<< 1);
14758 gen_ld(ctx
, OPC_LWPC
, rx
, 0, ((uint8_t)ctx
->opcode
) << 2);
14760 #if defined(TARGET_MIPS64)
14762 check_insn(ctx
, ISA_MIPS3
);
14763 check_mips_64(ctx
);
14764 gen_ld(ctx
, OPC_LWU
, ry
, rx
, offset
<< 2);
14768 gen_st(ctx
, OPC_SB
, ry
, rx
, offset
);
14771 gen_st(ctx
, OPC_SH
, ry
, rx
, offset
<< 1);
14774 gen_st(ctx
, OPC_SW
, rx
, 29, ((uint8_t)ctx
->opcode
) << 2);
14777 gen_st(ctx
, OPC_SW
, ry
, rx
, offset
<< 2);
14781 int rz
= xlat((ctx
->opcode
>> 2) & 0x7);
14784 switch (ctx
->opcode
& 0x3) {
14786 mips32_op
= OPC_ADDU
;
14789 mips32_op
= OPC_SUBU
;
14791 #if defined(TARGET_MIPS64)
14793 mips32_op
= OPC_DADDU
;
14794 check_insn(ctx
, ISA_MIPS3
);
14795 check_mips_64(ctx
);
14798 mips32_op
= OPC_DSUBU
;
14799 check_insn(ctx
, ISA_MIPS3
);
14800 check_mips_64(ctx
);
14804 generate_exception_end(ctx
, EXCP_RI
);
14808 gen_arith(ctx
, mips32_op
, rz
, rx
, ry
);
14817 int nd
= (ctx
->opcode
>> 7) & 0x1;
14818 int link
= (ctx
->opcode
>> 6) & 0x1;
14819 int ra
= (ctx
->opcode
>> 5) & 0x1;
14822 check_insn(ctx
, ISA_MIPS32
);
14831 gen_compute_branch(ctx
, op
, 2, ra
? 31 : rx
, 31, 0,
14836 if (is_uhi(extract32(ctx
->opcode
, 5, 6))) {
14837 gen_helper_do_semihosting(cpu_env
);
14840 * XXX: not clear which exception should be raised
14841 * when in debug mode...
14843 check_insn(ctx
, ISA_MIPS32
);
14844 generate_exception_end(ctx
, EXCP_DBp
);
14848 gen_slt(ctx
, OPC_SLT
, 24, rx
, ry
);
14851 gen_slt(ctx
, OPC_SLTU
, 24, rx
, ry
);
14854 generate_exception_end(ctx
, EXCP_BREAK
);
14857 gen_shift(ctx
, OPC_SLLV
, ry
, rx
, ry
);
14860 gen_shift(ctx
, OPC_SRLV
, ry
, rx
, ry
);
14863 gen_shift(ctx
, OPC_SRAV
, ry
, rx
, ry
);
14865 #if defined(TARGET_MIPS64)
14867 check_insn(ctx
, ISA_MIPS3
);
14868 check_mips_64(ctx
);
14869 gen_shift_imm(ctx
, OPC_DSRL
, ry
, ry
, sa
);
14873 gen_logic(ctx
, OPC_XOR
, 24, rx
, ry
);
14876 gen_arith(ctx
, OPC_SUBU
, rx
, 0, ry
);
14879 gen_logic(ctx
, OPC_AND
, rx
, rx
, ry
);
14882 gen_logic(ctx
, OPC_OR
, rx
, rx
, ry
);
14885 gen_logic(ctx
, OPC_XOR
, rx
, rx
, ry
);
14888 gen_logic(ctx
, OPC_NOR
, rx
, ry
, 0);
14891 gen_HILO(ctx
, OPC_MFHI
, 0, rx
);
14894 check_insn(ctx
, ISA_MIPS32
);
14896 case RR_RY_CNVT_ZEB
:
14897 tcg_gen_ext8u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
14899 case RR_RY_CNVT_ZEH
:
14900 tcg_gen_ext16u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
14902 case RR_RY_CNVT_SEB
:
14903 tcg_gen_ext8s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
14905 case RR_RY_CNVT_SEH
:
14906 tcg_gen_ext16s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
14908 #if defined(TARGET_MIPS64)
14909 case RR_RY_CNVT_ZEW
:
14910 check_insn(ctx
, ISA_MIPS32
);
14911 check_mips_64(ctx
);
14912 tcg_gen_ext32u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
14914 case RR_RY_CNVT_SEW
:
14915 check_insn(ctx
, ISA_MIPS32
);
14916 check_mips_64(ctx
);
14917 tcg_gen_ext32s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
14921 generate_exception_end(ctx
, EXCP_RI
);
14926 gen_HILO(ctx
, OPC_MFLO
, 0, rx
);
14928 #if defined(TARGET_MIPS64)
14930 check_insn(ctx
, ISA_MIPS3
);
14931 check_mips_64(ctx
);
14932 gen_shift_imm(ctx
, OPC_DSRA
, ry
, ry
, sa
);
14935 check_insn(ctx
, ISA_MIPS3
);
14936 check_mips_64(ctx
);
14937 gen_shift(ctx
, OPC_DSLLV
, ry
, rx
, ry
);
14940 check_insn(ctx
, ISA_MIPS3
);
14941 check_mips_64(ctx
);
14942 gen_shift(ctx
, OPC_DSRLV
, ry
, rx
, ry
);
14945 check_insn(ctx
, ISA_MIPS3
);
14946 check_mips_64(ctx
);
14947 gen_shift(ctx
, OPC_DSRAV
, ry
, rx
, ry
);
14951 gen_muldiv(ctx
, OPC_MULT
, 0, rx
, ry
);
14954 gen_muldiv(ctx
, OPC_MULTU
, 0, rx
, ry
);
14957 gen_muldiv(ctx
, OPC_DIV
, 0, rx
, ry
);
14960 gen_muldiv(ctx
, OPC_DIVU
, 0, rx
, ry
);
14962 #if defined(TARGET_MIPS64)
14964 check_insn(ctx
, ISA_MIPS3
);
14965 check_mips_64(ctx
);
14966 gen_muldiv(ctx
, OPC_DMULT
, 0, rx
, ry
);
14969 check_insn(ctx
, ISA_MIPS3
);
14970 check_mips_64(ctx
);
14971 gen_muldiv(ctx
, OPC_DMULTU
, 0, rx
, ry
);
14974 check_insn(ctx
, ISA_MIPS3
);
14975 check_mips_64(ctx
);
14976 gen_muldiv(ctx
, OPC_DDIV
, 0, rx
, ry
);
14979 check_insn(ctx
, ISA_MIPS3
);
14980 check_mips_64(ctx
);
14981 gen_muldiv(ctx
, OPC_DDIVU
, 0, rx
, ry
);
14985 generate_exception_end(ctx
, EXCP_RI
);
14989 case M16_OPC_EXTEND
:
14990 decode_extended_mips16_opc(env
, ctx
);
14993 #if defined(TARGET_MIPS64)
14995 funct
= (ctx
->opcode
>> 8) & 0x7;
14996 decode_i64_mips16(ctx
, ry
, funct
, offset
, 0);
15000 generate_exception_end(ctx
, EXCP_RI
);
15007 /* microMIPS extension to MIPS32/MIPS64 */
15010 * microMIPS32/microMIPS64 major opcodes
15012 * 1. MIPS Architecture for Programmers Volume II-B:
15013 * The microMIPS32 Instruction Set (Revision 3.05)
15015 * Table 6.2 microMIPS32 Encoding of Major Opcode Field
15017 * 2. MIPS Architecture For Programmers Volume II-A:
15018 * The MIPS64 Instruction Set (Revision 3.51)
15048 POOL32S
= 0x16, /* MIPS64 */
15049 DADDIU32
= 0x17, /* MIPS64 */
15078 /* 0x29 is reserved */
15091 /* 0x31 is reserved */
15104 SD32
= 0x36, /* MIPS64 */
15105 LD32
= 0x37, /* MIPS64 */
15107 /* 0x39 is reserved */
15123 /* PCREL Instructions perform PC-Relative address calculation. bits 20..16 */
15145 /* POOL32A encoding of minor opcode field */
15149 * These opcodes are distinguished only by bits 9..6; those bits are
15150 * what are recorded below.
15188 /* The following can be distinguished by their lower 6 bits. */
15198 /* POOL32AXF encoding of minor opcode field extension */
15201 * 1. MIPS Architecture for Programmers Volume II-B:
15202 * The microMIPS32 Instruction Set (Revision 3.05)
15204 * Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
15206 * 2. MIPS Architecture for Programmers VolumeIV-e:
15207 * The MIPS DSP Application-Specific Extension
15208 * to the microMIPS32 Architecture (Revision 2.34)
15210 * Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
15225 /* begin of microMIPS32 DSP */
15227 /* bits 13..12 for 0x01 */
15233 /* bits 13..12 for 0x2a */
15239 /* bits 13..12 for 0x32 */
15243 /* end of microMIPS32 DSP */
15245 /* bits 15..12 for 0x2c */
15262 /* bits 15..12 for 0x34 */
15270 /* bits 15..12 for 0x3c */
15272 JR
= 0x0, /* alias */
15280 /* bits 15..12 for 0x05 */
15284 /* bits 15..12 for 0x0d */
15296 /* bits 15..12 for 0x15 */
15302 /* bits 15..12 for 0x1d */
15306 /* bits 15..12 for 0x2d */
15311 /* bits 15..12 for 0x35 */
15318 /* POOL32B encoding of minor opcode field (bits 15..12) */
15334 /* POOL32C encoding of minor opcode field (bits 15..12) */
15355 /* POOL32C LD-EVA encoding of minor opcode field (bits 11..9) */
15368 /* POOL32C ST-EVA encoding of minor opcode field (bits 11..9) */
15381 /* POOL32F encoding of minor opcode field (bits 5..0) */
15384 /* These are the bit 7..6 values */
15393 /* These are the bit 8..6 values */
15418 MOVZ_FMT_05
= 0x05,
15452 CABS_COND_FMT
= 0x1c, /* MIPS3D */
15459 /* POOL32Fxf encoding of minor opcode extension field */
15497 /* POOL32I encoding of minor opcode field (bits 25..21) */
15527 /* These overlap and are distinguished by bit16 of the instruction */
15536 /* POOL16A encoding of minor opcode field */
15543 /* POOL16B encoding of minor opcode field */
15550 /* POOL16C encoding of minor opcode field */
15570 /* R6 POOL16C encoding of minor opcode field (bits 0..5) */
15594 /* POOL16D encoding of minor opcode field */
15601 /* POOL16E encoding of minor opcode field */
15608 static int mmreg(int r
)
15610 static const int map
[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
15615 /* Used for 16-bit store instructions. */
15616 static int mmreg2(int r
)
15618 static const int map
[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
15623 #define uMIPS_RD(op) ((op >> 7) & 0x7)
15624 #define uMIPS_RS(op) ((op >> 4) & 0x7)
15625 #define uMIPS_RS2(op) uMIPS_RS(op)
15626 #define uMIPS_RS1(op) ((op >> 1) & 0x7)
15627 #define uMIPS_RD5(op) ((op >> 5) & 0x1f)
15628 #define uMIPS_RS5(op) (op & 0x1f)
15630 /* Signed immediate */
15631 #define SIMM(op, start, width) \
15632 ((int32_t)(((op >> start) & ((~0U) >> (32 - width))) \
15635 /* Zero-extended immediate */
15636 #define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32 - width)))
15638 static void gen_addiur1sp(DisasContext
*ctx
)
15640 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
15642 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, 29, ((ctx
->opcode
>> 1) & 0x3f) << 2);
15645 static void gen_addiur2(DisasContext
*ctx
)
15647 static const int decoded_imm
[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
15648 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
15649 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
15651 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, rs
, decoded_imm
[ZIMM(ctx
->opcode
, 1, 3)]);
15654 static void gen_addiusp(DisasContext
*ctx
)
15656 int encoded
= ZIMM(ctx
->opcode
, 1, 9);
15659 if (encoded
<= 1) {
15660 decoded
= 256 + encoded
;
15661 } else if (encoded
<= 255) {
15663 } else if (encoded
<= 509) {
15664 decoded
= encoded
- 512;
15666 decoded
= encoded
- 768;
15669 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, decoded
<< 2);
15672 static void gen_addius5(DisasContext
*ctx
)
15674 int imm
= SIMM(ctx
->opcode
, 1, 4);
15675 int rd
= (ctx
->opcode
>> 5) & 0x1f;
15677 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, rd
, imm
);
15680 static void gen_andi16(DisasContext
*ctx
)
15682 static const int decoded_imm
[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
15683 31, 32, 63, 64, 255, 32768, 65535 };
15684 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
15685 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
15686 int encoded
= ZIMM(ctx
->opcode
, 0, 4);
15688 gen_logic_imm(ctx
, OPC_ANDI
, rd
, rs
, decoded_imm
[encoded
]);
15691 static void gen_ldst_multiple(DisasContext
*ctx
, uint32_t opc
, int reglist
,
15692 int base
, int16_t offset
)
15697 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
15698 generate_exception_end(ctx
, EXCP_RI
);
15702 t0
= tcg_temp_new();
15704 gen_base_offset_addr(ctx
, t0
, base
, offset
);
15706 t1
= tcg_const_tl(reglist
);
15707 t2
= tcg_const_i32(ctx
->mem_idx
);
15709 save_cpu_state(ctx
, 1);
15712 gen_helper_lwm(cpu_env
, t0
, t1
, t2
);
15715 gen_helper_swm(cpu_env
, t0
, t1
, t2
);
15717 #ifdef TARGET_MIPS64
15719 gen_helper_ldm(cpu_env
, t0
, t1
, t2
);
15722 gen_helper_sdm(cpu_env
, t0
, t1
, t2
);
15728 tcg_temp_free_i32(t2
);
15732 static void gen_pool16c_insn(DisasContext
*ctx
)
15734 int rd
= mmreg((ctx
->opcode
>> 3) & 0x7);
15735 int rs
= mmreg(ctx
->opcode
& 0x7);
15737 switch (((ctx
->opcode
) >> 4) & 0x3f) {
15742 gen_logic(ctx
, OPC_NOR
, rd
, rs
, 0);
15748 gen_logic(ctx
, OPC_XOR
, rd
, rd
, rs
);
15754 gen_logic(ctx
, OPC_AND
, rd
, rd
, rs
);
15760 gen_logic(ctx
, OPC_OR
, rd
, rd
, rs
);
15767 static const int lwm_convert
[] = { 0x11, 0x12, 0x13, 0x14 };
15768 int offset
= ZIMM(ctx
->opcode
, 0, 4);
15770 gen_ldst_multiple(ctx
, LWM32
, lwm_convert
[(ctx
->opcode
>> 4) & 0x3],
15779 static const int swm_convert
[] = { 0x11, 0x12, 0x13, 0x14 };
15780 int offset
= ZIMM(ctx
->opcode
, 0, 4);
15782 gen_ldst_multiple(ctx
, SWM32
, swm_convert
[(ctx
->opcode
>> 4) & 0x3],
15789 int reg
= ctx
->opcode
& 0x1f;
15791 gen_compute_branch(ctx
, OPC_JR
, 2, reg
, 0, 0, 4);
15797 int reg
= ctx
->opcode
& 0x1f;
15798 gen_compute_branch(ctx
, OPC_JR
, 2, reg
, 0, 0, 0);
15800 * Let normal delay slot handling in our caller take us
15801 * to the branch target.
15807 gen_compute_branch(ctx
, OPC_JALR
, 2, ctx
->opcode
& 0x1f, 31, 0, 4);
15808 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
15812 gen_compute_branch(ctx
, OPC_JALR
, 2, ctx
->opcode
& 0x1f, 31, 0, 2);
15813 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
15817 gen_HILO(ctx
, OPC_MFHI
, 0, uMIPS_RS5(ctx
->opcode
));
15821 gen_HILO(ctx
, OPC_MFLO
, 0, uMIPS_RS5(ctx
->opcode
));
15824 generate_exception_end(ctx
, EXCP_BREAK
);
15827 if (is_uhi(extract32(ctx
->opcode
, 0, 4))) {
15828 gen_helper_do_semihosting(cpu_env
);
15831 * XXX: not clear which exception should be raised
15832 * when in debug mode...
15834 check_insn(ctx
, ISA_MIPS32
);
15835 generate_exception_end(ctx
, EXCP_DBp
);
15838 case JRADDIUSP
+ 0:
15839 case JRADDIUSP
+ 1:
15841 int imm
= ZIMM(ctx
->opcode
, 0, 5);
15842 gen_compute_branch(ctx
, OPC_JR
, 2, 31, 0, 0, 0);
15843 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, imm
<< 2);
15845 * Let normal delay slot handling in our caller take us
15846 * to the branch target.
15851 generate_exception_end(ctx
, EXCP_RI
);
15856 static inline void gen_movep(DisasContext
*ctx
, int enc_dest
, int enc_rt
,
15859 int rd
, rs
, re
, rt
;
15860 static const int rd_enc
[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
15861 static const int re_enc
[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
15862 static const int rs_rt_enc
[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
15863 rd
= rd_enc
[enc_dest
];
15864 re
= re_enc
[enc_dest
];
15865 rs
= rs_rt_enc
[enc_rs
];
15866 rt
= rs_rt_enc
[enc_rt
];
15868 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
15870 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
15873 tcg_gen_mov_tl(cpu_gpr
[re
], cpu_gpr
[rt
]);
15875 tcg_gen_movi_tl(cpu_gpr
[re
], 0);
15879 static void gen_pool16c_r6_insn(DisasContext
*ctx
)
15881 int rt
= mmreg((ctx
->opcode
>> 7) & 0x7);
15882 int rs
= mmreg((ctx
->opcode
>> 4) & 0x7);
15884 switch (ctx
->opcode
& 0xf) {
15886 gen_logic(ctx
, OPC_NOR
, rt
, rs
, 0);
15889 gen_logic(ctx
, OPC_AND
, rt
, rt
, rs
);
15893 int lwm_converted
= 0x11 + extract32(ctx
->opcode
, 8, 2);
15894 int offset
= extract32(ctx
->opcode
, 4, 4);
15895 gen_ldst_multiple(ctx
, LWM32
, lwm_converted
, 29, offset
<< 2);
15898 case R6_JRC16
: /* JRCADDIUSP */
15899 if ((ctx
->opcode
>> 4) & 1) {
15901 int imm
= extract32(ctx
->opcode
, 5, 5);
15902 gen_compute_branch(ctx
, OPC_JR
, 2, 31, 0, 0, 0);
15903 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, imm
<< 2);
15906 rs
= extract32(ctx
->opcode
, 5, 5);
15907 gen_compute_branch(ctx
, OPC_JR
, 2, rs
, 0, 0, 0);
15919 int enc_dest
= uMIPS_RD(ctx
->opcode
);
15920 int enc_rt
= uMIPS_RS2(ctx
->opcode
);
15921 int enc_rs
= (ctx
->opcode
& 3) | ((ctx
->opcode
>> 1) & 4);
15922 gen_movep(ctx
, enc_dest
, enc_rt
, enc_rs
);
15926 gen_logic(ctx
, OPC_XOR
, rt
, rt
, rs
);
15929 gen_logic(ctx
, OPC_OR
, rt
, rt
, rs
);
15933 int swm_converted
= 0x11 + extract32(ctx
->opcode
, 8, 2);
15934 int offset
= extract32(ctx
->opcode
, 4, 4);
15935 gen_ldst_multiple(ctx
, SWM32
, swm_converted
, 29, offset
<< 2);
15938 case JALRC16
: /* BREAK16, SDBBP16 */
15939 switch (ctx
->opcode
& 0x3f) {
15941 case JALRC16
+ 0x20:
15943 gen_compute_branch(ctx
, OPC_JALR
, 2, (ctx
->opcode
>> 5) & 0x1f,
15948 generate_exception(ctx
, EXCP_BREAK
);
15952 if (is_uhi(extract32(ctx
->opcode
, 6, 4))) {
15953 gen_helper_do_semihosting(cpu_env
);
15955 if (ctx
->hflags
& MIPS_HFLAG_SBRI
) {
15956 generate_exception(ctx
, EXCP_RI
);
15958 generate_exception(ctx
, EXCP_DBp
);
15965 generate_exception(ctx
, EXCP_RI
);
15970 static void gen_ldxs(DisasContext
*ctx
, int base
, int index
, int rd
)
15972 TCGv t0
= tcg_temp_new();
15973 TCGv t1
= tcg_temp_new();
15975 gen_load_gpr(t0
, base
);
15978 gen_load_gpr(t1
, index
);
15979 tcg_gen_shli_tl(t1
, t1
, 2);
15980 gen_op_addr_add(ctx
, t0
, t1
, t0
);
15983 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TESL
);
15984 gen_store_gpr(t1
, rd
);
15990 static void gen_ldst_pair(DisasContext
*ctx
, uint32_t opc
, int rd
,
15991 int base
, int16_t offset
)
15995 if (ctx
->hflags
& MIPS_HFLAG_BMASK
|| rd
== 31) {
15996 generate_exception_end(ctx
, EXCP_RI
);
16000 t0
= tcg_temp_new();
16001 t1
= tcg_temp_new();
16003 gen_base_offset_addr(ctx
, t0
, base
, offset
);
16008 generate_exception_end(ctx
, EXCP_RI
);
16011 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TESL
);
16012 gen_store_gpr(t1
, rd
);
16013 tcg_gen_movi_tl(t1
, 4);
16014 gen_op_addr_add(ctx
, t0
, t0
, t1
);
16015 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TESL
);
16016 gen_store_gpr(t1
, rd
+ 1);
16019 gen_load_gpr(t1
, rd
);
16020 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
16021 tcg_gen_movi_tl(t1
, 4);
16022 gen_op_addr_add(ctx
, t0
, t0
, t1
);
16023 gen_load_gpr(t1
, rd
+ 1);
16024 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
16026 #ifdef TARGET_MIPS64
16029 generate_exception_end(ctx
, EXCP_RI
);
16032 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
16033 gen_store_gpr(t1
, rd
);
16034 tcg_gen_movi_tl(t1
, 8);
16035 gen_op_addr_add(ctx
, t0
, t0
, t1
);
16036 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
16037 gen_store_gpr(t1
, rd
+ 1);
16040 gen_load_gpr(t1
, rd
);
16041 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
16042 tcg_gen_movi_tl(t1
, 8);
16043 gen_op_addr_add(ctx
, t0
, t0
, t1
);
16044 gen_load_gpr(t1
, rd
+ 1);
16045 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
16053 static void gen_sync(int stype
)
16055 TCGBar tcg_mo
= TCG_BAR_SC
;
16058 case 0x4: /* SYNC_WMB */
16059 tcg_mo
|= TCG_MO_ST_ST
;
16061 case 0x10: /* SYNC_MB */
16062 tcg_mo
|= TCG_MO_ALL
;
16064 case 0x11: /* SYNC_ACQUIRE */
16065 tcg_mo
|= TCG_MO_LD_LD
| TCG_MO_LD_ST
;
16067 case 0x12: /* SYNC_RELEASE */
16068 tcg_mo
|= TCG_MO_ST_ST
| TCG_MO_LD_ST
;
16070 case 0x13: /* SYNC_RMB */
16071 tcg_mo
|= TCG_MO_LD_LD
;
16074 tcg_mo
|= TCG_MO_ALL
;
16078 tcg_gen_mb(tcg_mo
);
16081 static void gen_pool32axf(CPUMIPSState
*env
, DisasContext
*ctx
, int rt
, int rs
)
16083 int extension
= (ctx
->opcode
>> 6) & 0x3f;
16084 int minor
= (ctx
->opcode
>> 12) & 0xf;
16085 uint32_t mips32_op
;
16087 switch (extension
) {
16089 mips32_op
= OPC_TEQ
;
16092 mips32_op
= OPC_TGE
;
16095 mips32_op
= OPC_TGEU
;
16098 mips32_op
= OPC_TLT
;
16101 mips32_op
= OPC_TLTU
;
16104 mips32_op
= OPC_TNE
;
16106 gen_trap(ctx
, mips32_op
, rs
, rt
, -1);
16108 #ifndef CONFIG_USER_ONLY
16111 check_cp0_enabled(ctx
);
16113 /* Treat as NOP. */
16116 gen_mfc0(ctx
, cpu_gpr
[rt
], rs
, (ctx
->opcode
>> 11) & 0x7);
16120 check_cp0_enabled(ctx
);
16122 TCGv t0
= tcg_temp_new();
16124 gen_load_gpr(t0
, rt
);
16125 gen_mtc0(ctx
, t0
, rs
, (ctx
->opcode
>> 11) & 0x7);
16131 switch (minor
& 3) {
16133 gen_muldiv(ctx
, OPC_MADD
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
16136 gen_muldiv(ctx
, OPC_MADDU
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
16139 gen_muldiv(ctx
, OPC_MSUB
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
16142 gen_muldiv(ctx
, OPC_MSUBU
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
16145 goto pool32axf_invalid
;
16149 switch (minor
& 3) {
16151 gen_muldiv(ctx
, OPC_MULT
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
16154 gen_muldiv(ctx
, OPC_MULTU
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
16157 goto pool32axf_invalid
;
16163 check_insn(ctx
, ISA_MIPS32R6
);
16164 gen_bitswap(ctx
, OPC_BITSWAP
, rs
, rt
);
16167 gen_bshfl(ctx
, OPC_SEB
, rs
, rt
);
16170 gen_bshfl(ctx
, OPC_SEH
, rs
, rt
);
16173 mips32_op
= OPC_CLO
;
16176 mips32_op
= OPC_CLZ
;
16178 check_insn(ctx
, ISA_MIPS32
);
16179 gen_cl(ctx
, mips32_op
, rt
, rs
);
16182 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16183 gen_rdhwr(ctx
, rt
, rs
, 0);
16186 gen_bshfl(ctx
, OPC_WSBH
, rs
, rt
);
16189 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16190 mips32_op
= OPC_MULT
;
16193 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16194 mips32_op
= OPC_MULTU
;
16197 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16198 mips32_op
= OPC_DIV
;
16201 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16202 mips32_op
= OPC_DIVU
;
16205 check_insn(ctx
, ISA_MIPS32
);
16206 gen_muldiv(ctx
, mips32_op
, 0, rs
, rt
);
16209 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16210 mips32_op
= OPC_MADD
;
16213 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16214 mips32_op
= OPC_MADDU
;
16217 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16218 mips32_op
= OPC_MSUB
;
16221 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16222 mips32_op
= OPC_MSUBU
;
16224 check_insn(ctx
, ISA_MIPS32
);
16225 gen_muldiv(ctx
, mips32_op
, 0, rs
, rt
);
16228 goto pool32axf_invalid
;
16239 generate_exception_err(ctx
, EXCP_CpU
, 2);
16242 goto pool32axf_invalid
;
16247 case JALR
: /* JALRC */
16248 case JALR_HB
: /* JALRC_HB */
16249 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
16250 /* JALRC, JALRC_HB */
16251 gen_compute_branch(ctx
, OPC_JALR
, 4, rs
, rt
, 0, 0);
16253 /* JALR, JALR_HB */
16254 gen_compute_branch(ctx
, OPC_JALR
, 4, rs
, rt
, 0, 4);
16255 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
16260 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16261 gen_compute_branch(ctx
, OPC_JALR
, 4, rs
, rt
, 0, 2);
16262 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
16265 goto pool32axf_invalid
;
16271 check_cp0_enabled(ctx
);
16272 check_insn(ctx
, ISA_MIPS32R2
);
16273 gen_load_srsgpr(rs
, rt
);
16276 check_cp0_enabled(ctx
);
16277 check_insn(ctx
, ISA_MIPS32R2
);
16278 gen_store_srsgpr(rs
, rt
);
16281 goto pool32axf_invalid
;
16284 #ifndef CONFIG_USER_ONLY
16288 mips32_op
= OPC_TLBP
;
16291 mips32_op
= OPC_TLBR
;
16294 mips32_op
= OPC_TLBWI
;
16297 mips32_op
= OPC_TLBWR
;
16300 mips32_op
= OPC_TLBINV
;
16303 mips32_op
= OPC_TLBINVF
;
16306 mips32_op
= OPC_WAIT
;
16309 mips32_op
= OPC_DERET
;
16312 mips32_op
= OPC_ERET
;
16314 gen_cp0(env
, ctx
, mips32_op
, rt
, rs
);
16317 goto pool32axf_invalid
;
16323 check_cp0_enabled(ctx
);
16325 TCGv t0
= tcg_temp_new();
16327 save_cpu_state(ctx
, 1);
16328 gen_helper_di(t0
, cpu_env
);
16329 gen_store_gpr(t0
, rs
);
16331 * Stop translation as we may have switched the execution
16334 ctx
->base
.is_jmp
= DISAS_STOP
;
16339 check_cp0_enabled(ctx
);
16341 TCGv t0
= tcg_temp_new();
16343 save_cpu_state(ctx
, 1);
16344 gen_helper_ei(t0
, cpu_env
);
16345 gen_store_gpr(t0
, rs
);
16347 * DISAS_STOP isn't sufficient, we need to ensure we break out
16348 * of translated code to check for pending interrupts.
16350 gen_save_pc(ctx
->base
.pc_next
+ 4);
16351 ctx
->base
.is_jmp
= DISAS_EXIT
;
16356 goto pool32axf_invalid
;
16363 gen_sync(extract32(ctx
->opcode
, 16, 5));
16366 generate_exception_end(ctx
, EXCP_SYSCALL
);
16369 if (is_uhi(extract32(ctx
->opcode
, 16, 10))) {
16370 gen_helper_do_semihosting(cpu_env
);
16372 check_insn(ctx
, ISA_MIPS32
);
16373 if (ctx
->hflags
& MIPS_HFLAG_SBRI
) {
16374 generate_exception_end(ctx
, EXCP_RI
);
16376 generate_exception_end(ctx
, EXCP_DBp
);
16381 goto pool32axf_invalid
;
16385 switch (minor
& 3) {
16387 gen_HILO(ctx
, OPC_MFHI
, minor
>> 2, rs
);
16390 gen_HILO(ctx
, OPC_MFLO
, minor
>> 2, rs
);
16393 gen_HILO(ctx
, OPC_MTHI
, minor
>> 2, rs
);
16396 gen_HILO(ctx
, OPC_MTLO
, minor
>> 2, rs
);
16399 goto pool32axf_invalid
;
16403 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16406 gen_HILO(ctx
, OPC_MFHI
, 0, rs
);
16409 gen_HILO(ctx
, OPC_MFLO
, 0, rs
);
16412 gen_HILO(ctx
, OPC_MTHI
, 0, rs
);
16415 gen_HILO(ctx
, OPC_MTLO
, 0, rs
);
16418 goto pool32axf_invalid
;
16423 MIPS_INVAL("pool32axf");
16424 generate_exception_end(ctx
, EXCP_RI
);
16430 * Values for microMIPS fmt field. Variable-width, depending on which
16431 * formats the instruction supports.
16450 static void gen_pool32fxf(DisasContext
*ctx
, int rt
, int rs
)
16452 int extension
= (ctx
->opcode
>> 6) & 0x3ff;
16453 uint32_t mips32_op
;
16455 #define FLOAT_1BIT_FMT(opc, fmt) ((fmt << 8) | opc)
16456 #define FLOAT_2BIT_FMT(opc, fmt) ((fmt << 7) | opc)
16457 #define COND_FLOAT_MOV(opc, cond) ((cond << 7) | opc)
16459 switch (extension
) {
16460 case FLOAT_1BIT_FMT(CFC1
, 0):
16461 mips32_op
= OPC_CFC1
;
16463 case FLOAT_1BIT_FMT(CTC1
, 0):
16464 mips32_op
= OPC_CTC1
;
16466 case FLOAT_1BIT_FMT(MFC1
, 0):
16467 mips32_op
= OPC_MFC1
;
16469 case FLOAT_1BIT_FMT(MTC1
, 0):
16470 mips32_op
= OPC_MTC1
;
16472 case FLOAT_1BIT_FMT(MFHC1
, 0):
16473 mips32_op
= OPC_MFHC1
;
16475 case FLOAT_1BIT_FMT(MTHC1
, 0):
16476 mips32_op
= OPC_MTHC1
;
16478 gen_cp1(ctx
, mips32_op
, rt
, rs
);
16481 /* Reciprocal square root */
16482 case FLOAT_1BIT_FMT(RSQRT_FMT
, FMT_SD_S
):
16483 mips32_op
= OPC_RSQRT_S
;
16485 case FLOAT_1BIT_FMT(RSQRT_FMT
, FMT_SD_D
):
16486 mips32_op
= OPC_RSQRT_D
;
16490 case FLOAT_1BIT_FMT(SQRT_FMT
, FMT_SD_S
):
16491 mips32_op
= OPC_SQRT_S
;
16493 case FLOAT_1BIT_FMT(SQRT_FMT
, FMT_SD_D
):
16494 mips32_op
= OPC_SQRT_D
;
16498 case FLOAT_1BIT_FMT(RECIP_FMT
, FMT_SD_S
):
16499 mips32_op
= OPC_RECIP_S
;
16501 case FLOAT_1BIT_FMT(RECIP_FMT
, FMT_SD_D
):
16502 mips32_op
= OPC_RECIP_D
;
16506 case FLOAT_1BIT_FMT(FLOOR_L
, FMT_SD_S
):
16507 mips32_op
= OPC_FLOOR_L_S
;
16509 case FLOAT_1BIT_FMT(FLOOR_L
, FMT_SD_D
):
16510 mips32_op
= OPC_FLOOR_L_D
;
16512 case FLOAT_1BIT_FMT(FLOOR_W
, FMT_SD_S
):
16513 mips32_op
= OPC_FLOOR_W_S
;
16515 case FLOAT_1BIT_FMT(FLOOR_W
, FMT_SD_D
):
16516 mips32_op
= OPC_FLOOR_W_D
;
16520 case FLOAT_1BIT_FMT(CEIL_L
, FMT_SD_S
):
16521 mips32_op
= OPC_CEIL_L_S
;
16523 case FLOAT_1BIT_FMT(CEIL_L
, FMT_SD_D
):
16524 mips32_op
= OPC_CEIL_L_D
;
16526 case FLOAT_1BIT_FMT(CEIL_W
, FMT_SD_S
):
16527 mips32_op
= OPC_CEIL_W_S
;
16529 case FLOAT_1BIT_FMT(CEIL_W
, FMT_SD_D
):
16530 mips32_op
= OPC_CEIL_W_D
;
16534 case FLOAT_1BIT_FMT(TRUNC_L
, FMT_SD_S
):
16535 mips32_op
= OPC_TRUNC_L_S
;
16537 case FLOAT_1BIT_FMT(TRUNC_L
, FMT_SD_D
):
16538 mips32_op
= OPC_TRUNC_L_D
;
16540 case FLOAT_1BIT_FMT(TRUNC_W
, FMT_SD_S
):
16541 mips32_op
= OPC_TRUNC_W_S
;
16543 case FLOAT_1BIT_FMT(TRUNC_W
, FMT_SD_D
):
16544 mips32_op
= OPC_TRUNC_W_D
;
16548 case FLOAT_1BIT_FMT(ROUND_L
, FMT_SD_S
):
16549 mips32_op
= OPC_ROUND_L_S
;
16551 case FLOAT_1BIT_FMT(ROUND_L
, FMT_SD_D
):
16552 mips32_op
= OPC_ROUND_L_D
;
16554 case FLOAT_1BIT_FMT(ROUND_W
, FMT_SD_S
):
16555 mips32_op
= OPC_ROUND_W_S
;
16557 case FLOAT_1BIT_FMT(ROUND_W
, FMT_SD_D
):
16558 mips32_op
= OPC_ROUND_W_D
;
16561 /* Integer to floating-point conversion */
16562 case FLOAT_1BIT_FMT(CVT_L
, FMT_SD_S
):
16563 mips32_op
= OPC_CVT_L_S
;
16565 case FLOAT_1BIT_FMT(CVT_L
, FMT_SD_D
):
16566 mips32_op
= OPC_CVT_L_D
;
16568 case FLOAT_1BIT_FMT(CVT_W
, FMT_SD_S
):
16569 mips32_op
= OPC_CVT_W_S
;
16571 case FLOAT_1BIT_FMT(CVT_W
, FMT_SD_D
):
16572 mips32_op
= OPC_CVT_W_D
;
16575 /* Paired-foo conversions */
16576 case FLOAT_1BIT_FMT(CVT_S_PL
, 0):
16577 mips32_op
= OPC_CVT_S_PL
;
16579 case FLOAT_1BIT_FMT(CVT_S_PU
, 0):
16580 mips32_op
= OPC_CVT_S_PU
;
16582 case FLOAT_1BIT_FMT(CVT_PW_PS
, 0):
16583 mips32_op
= OPC_CVT_PW_PS
;
16585 case FLOAT_1BIT_FMT(CVT_PS_PW
, 0):
16586 mips32_op
= OPC_CVT_PS_PW
;
16589 /* Floating-point moves */
16590 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_S
):
16591 mips32_op
= OPC_MOV_S
;
16593 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_D
):
16594 mips32_op
= OPC_MOV_D
;
16596 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_PS
):
16597 mips32_op
= OPC_MOV_PS
;
16600 /* Absolute value */
16601 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_S
):
16602 mips32_op
= OPC_ABS_S
;
16604 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_D
):
16605 mips32_op
= OPC_ABS_D
;
16607 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_PS
):
16608 mips32_op
= OPC_ABS_PS
;
16612 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_S
):
16613 mips32_op
= OPC_NEG_S
;
16615 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_D
):
16616 mips32_op
= OPC_NEG_D
;
16618 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_PS
):
16619 mips32_op
= OPC_NEG_PS
;
16622 /* Reciprocal square root step */
16623 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_S
):
16624 mips32_op
= OPC_RSQRT1_S
;
16626 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_D
):
16627 mips32_op
= OPC_RSQRT1_D
;
16629 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_PS
):
16630 mips32_op
= OPC_RSQRT1_PS
;
16633 /* Reciprocal step */
16634 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_S
):
16635 mips32_op
= OPC_RECIP1_S
;
16637 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_D
):
16638 mips32_op
= OPC_RECIP1_S
;
16640 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_PS
):
16641 mips32_op
= OPC_RECIP1_PS
;
16644 /* Conversions from double */
16645 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_S
):
16646 mips32_op
= OPC_CVT_D_S
;
16648 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_W
):
16649 mips32_op
= OPC_CVT_D_W
;
16651 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_L
):
16652 mips32_op
= OPC_CVT_D_L
;
16655 /* Conversions from single */
16656 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_D
):
16657 mips32_op
= OPC_CVT_S_D
;
16659 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_W
):
16660 mips32_op
= OPC_CVT_S_W
;
16662 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_L
):
16663 mips32_op
= OPC_CVT_S_L
;
16665 gen_farith(ctx
, mips32_op
, -1, rs
, rt
, 0);
16668 /* Conditional moves on floating-point codes */
16669 case COND_FLOAT_MOV(MOVT
, 0):
16670 case COND_FLOAT_MOV(MOVT
, 1):
16671 case COND_FLOAT_MOV(MOVT
, 2):
16672 case COND_FLOAT_MOV(MOVT
, 3):
16673 case COND_FLOAT_MOV(MOVT
, 4):
16674 case COND_FLOAT_MOV(MOVT
, 5):
16675 case COND_FLOAT_MOV(MOVT
, 6):
16676 case COND_FLOAT_MOV(MOVT
, 7):
16677 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16678 gen_movci(ctx
, rt
, rs
, (ctx
->opcode
>> 13) & 0x7, 1);
16680 case COND_FLOAT_MOV(MOVF
, 0):
16681 case COND_FLOAT_MOV(MOVF
, 1):
16682 case COND_FLOAT_MOV(MOVF
, 2):
16683 case COND_FLOAT_MOV(MOVF
, 3):
16684 case COND_FLOAT_MOV(MOVF
, 4):
16685 case COND_FLOAT_MOV(MOVF
, 5):
16686 case COND_FLOAT_MOV(MOVF
, 6):
16687 case COND_FLOAT_MOV(MOVF
, 7):
16688 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16689 gen_movci(ctx
, rt
, rs
, (ctx
->opcode
>> 13) & 0x7, 0);
16692 MIPS_INVAL("pool32fxf");
16693 generate_exception_end(ctx
, EXCP_RI
);
16698 static void decode_micromips32_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
16702 int rt
, rs
, rd
, rr
;
16704 uint32_t op
, minor
, minor2
, mips32_op
;
16705 uint32_t cond
, fmt
, cc
;
16707 insn
= cpu_lduw_code(env
, ctx
->base
.pc_next
+ 2);
16708 ctx
->opcode
= (ctx
->opcode
<< 16) | insn
;
16710 rt
= (ctx
->opcode
>> 21) & 0x1f;
16711 rs
= (ctx
->opcode
>> 16) & 0x1f;
16712 rd
= (ctx
->opcode
>> 11) & 0x1f;
16713 rr
= (ctx
->opcode
>> 6) & 0x1f;
16714 imm
= (int16_t) ctx
->opcode
;
16716 op
= (ctx
->opcode
>> 26) & 0x3f;
16719 minor
= ctx
->opcode
& 0x3f;
16722 minor
= (ctx
->opcode
>> 6) & 0xf;
16725 mips32_op
= OPC_SLL
;
16728 mips32_op
= OPC_SRA
;
16731 mips32_op
= OPC_SRL
;
16734 mips32_op
= OPC_ROTR
;
16736 gen_shift_imm(ctx
, mips32_op
, rt
, rs
, rd
);
16739 check_insn(ctx
, ISA_MIPS32R6
);
16740 gen_cond_move(ctx
, OPC_SELEQZ
, rd
, rs
, rt
);
16743 check_insn(ctx
, ISA_MIPS32R6
);
16744 gen_cond_move(ctx
, OPC_SELNEZ
, rd
, rs
, rt
);
16747 check_insn(ctx
, ISA_MIPS32R6
);
16748 gen_rdhwr(ctx
, rt
, rs
, extract32(ctx
->opcode
, 11, 3));
16751 goto pool32a_invalid
;
16755 minor
= (ctx
->opcode
>> 6) & 0xf;
16759 mips32_op
= OPC_ADD
;
16762 mips32_op
= OPC_ADDU
;
16765 mips32_op
= OPC_SUB
;
16768 mips32_op
= OPC_SUBU
;
16771 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16772 mips32_op
= OPC_MUL
;
16774 gen_arith(ctx
, mips32_op
, rd
, rs
, rt
);
16778 mips32_op
= OPC_SLLV
;
16781 mips32_op
= OPC_SRLV
;
16784 mips32_op
= OPC_SRAV
;
16787 mips32_op
= OPC_ROTRV
;
16789 gen_shift(ctx
, mips32_op
, rd
, rs
, rt
);
16791 /* Logical operations */
16793 mips32_op
= OPC_AND
;
16796 mips32_op
= OPC_OR
;
16799 mips32_op
= OPC_NOR
;
16802 mips32_op
= OPC_XOR
;
16804 gen_logic(ctx
, mips32_op
, rd
, rs
, rt
);
16806 /* Set less than */
16808 mips32_op
= OPC_SLT
;
16811 mips32_op
= OPC_SLTU
;
16813 gen_slt(ctx
, mips32_op
, rd
, rs
, rt
);
16816 goto pool32a_invalid
;
16820 minor
= (ctx
->opcode
>> 6) & 0xf;
16822 /* Conditional moves */
16823 case MOVN
: /* MUL */
16824 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
16826 gen_r6_muldiv(ctx
, R6_OPC_MUL
, rd
, rs
, rt
);
16829 gen_cond_move(ctx
, OPC_MOVN
, rd
, rs
, rt
);
16832 case MOVZ
: /* MUH */
16833 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
16835 gen_r6_muldiv(ctx
, R6_OPC_MUH
, rd
, rs
, rt
);
16838 gen_cond_move(ctx
, OPC_MOVZ
, rd
, rs
, rt
);
16842 check_insn(ctx
, ISA_MIPS32R6
);
16843 gen_r6_muldiv(ctx
, R6_OPC_MULU
, rd
, rs
, rt
);
16846 check_insn(ctx
, ISA_MIPS32R6
);
16847 gen_r6_muldiv(ctx
, R6_OPC_MUHU
, rd
, rs
, rt
);
16849 case LWXS
: /* DIV */
16850 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
16852 gen_r6_muldiv(ctx
, R6_OPC_DIV
, rd
, rs
, rt
);
16855 gen_ldxs(ctx
, rs
, rt
, rd
);
16859 check_insn(ctx
, ISA_MIPS32R6
);
16860 gen_r6_muldiv(ctx
, R6_OPC_MOD
, rd
, rs
, rt
);
16863 check_insn(ctx
, ISA_MIPS32R6
);
16864 gen_r6_muldiv(ctx
, R6_OPC_DIVU
, rd
, rs
, rt
);
16867 check_insn(ctx
, ISA_MIPS32R6
);
16868 gen_r6_muldiv(ctx
, R6_OPC_MODU
, rd
, rs
, rt
);
16871 goto pool32a_invalid
;
16875 gen_bitops(ctx
, OPC_INS
, rt
, rs
, rr
, rd
);
16878 check_insn(ctx
, ISA_MIPS32R6
);
16879 gen_lsa(ctx
, OPC_LSA
, rd
, rs
, rt
,
16880 extract32(ctx
->opcode
, 9, 2));
16883 check_insn(ctx
, ISA_MIPS32R6
);
16884 gen_align(ctx
, 32, rd
, rs
, rt
, extract32(ctx
->opcode
, 9, 2));
16887 gen_bitops(ctx
, OPC_EXT
, rt
, rs
, rr
, rd
);
16890 gen_pool32axf(env
, ctx
, rt
, rs
);
16893 generate_exception_end(ctx
, EXCP_BREAK
);
16896 check_insn(ctx
, ISA_MIPS32R6
);
16897 generate_exception_end(ctx
, EXCP_RI
);
16901 MIPS_INVAL("pool32a");
16902 generate_exception_end(ctx
, EXCP_RI
);
16907 minor
= (ctx
->opcode
>> 12) & 0xf;
16910 check_cp0_enabled(ctx
);
16911 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
16912 gen_cache_operation(ctx
, rt
, rs
, imm
);
16917 /* COP2: Not implemented. */
16918 generate_exception_err(ctx
, EXCP_CpU
, 2);
16920 #ifdef TARGET_MIPS64
16923 check_insn(ctx
, ISA_MIPS3
);
16924 check_mips_64(ctx
);
16929 gen_ldst_pair(ctx
, minor
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
16931 #ifdef TARGET_MIPS64
16934 check_insn(ctx
, ISA_MIPS3
);
16935 check_mips_64(ctx
);
16940 gen_ldst_multiple(ctx
, minor
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
16943 MIPS_INVAL("pool32b");
16944 generate_exception_end(ctx
, EXCP_RI
);
16949 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
16950 minor
= ctx
->opcode
& 0x3f;
16951 check_cp1_enabled(ctx
);
16954 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16955 mips32_op
= OPC_ALNV_PS
;
16958 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16959 mips32_op
= OPC_MADD_S
;
16962 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16963 mips32_op
= OPC_MADD_D
;
16966 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16967 mips32_op
= OPC_MADD_PS
;
16970 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16971 mips32_op
= OPC_MSUB_S
;
16974 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16975 mips32_op
= OPC_MSUB_D
;
16978 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16979 mips32_op
= OPC_MSUB_PS
;
16982 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16983 mips32_op
= OPC_NMADD_S
;
16986 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16987 mips32_op
= OPC_NMADD_D
;
16990 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16991 mips32_op
= OPC_NMADD_PS
;
16994 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16995 mips32_op
= OPC_NMSUB_S
;
16998 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16999 mips32_op
= OPC_NMSUB_D
;
17002 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17003 mips32_op
= OPC_NMSUB_PS
;
17005 gen_flt3_arith(ctx
, mips32_op
, rd
, rr
, rs
, rt
);
17007 case CABS_COND_FMT
:
17008 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17009 cond
= (ctx
->opcode
>> 6) & 0xf;
17010 cc
= (ctx
->opcode
>> 13) & 0x7;
17011 fmt
= (ctx
->opcode
>> 10) & 0x3;
17014 gen_cmpabs_s(ctx
, cond
, rt
, rs
, cc
);
17017 gen_cmpabs_d(ctx
, cond
, rt
, rs
, cc
);
17020 gen_cmpabs_ps(ctx
, cond
, rt
, rs
, cc
);
17023 goto pool32f_invalid
;
17027 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17028 cond
= (ctx
->opcode
>> 6) & 0xf;
17029 cc
= (ctx
->opcode
>> 13) & 0x7;
17030 fmt
= (ctx
->opcode
>> 10) & 0x3;
17033 gen_cmp_s(ctx
, cond
, rt
, rs
, cc
);
17036 gen_cmp_d(ctx
, cond
, rt
, rs
, cc
);
17039 gen_cmp_ps(ctx
, cond
, rt
, rs
, cc
);
17042 goto pool32f_invalid
;
17046 check_insn(ctx
, ISA_MIPS32R6
);
17047 gen_r6_cmp_s(ctx
, (ctx
->opcode
>> 6) & 0x1f, rt
, rs
, rd
);
17050 check_insn(ctx
, ISA_MIPS32R6
);
17051 gen_r6_cmp_d(ctx
, (ctx
->opcode
>> 6) & 0x1f, rt
, rs
, rd
);
17054 gen_pool32fxf(ctx
, rt
, rs
);
17058 switch ((ctx
->opcode
>> 6) & 0x7) {
17060 mips32_op
= OPC_PLL_PS
;
17063 mips32_op
= OPC_PLU_PS
;
17066 mips32_op
= OPC_PUL_PS
;
17069 mips32_op
= OPC_PUU_PS
;
17072 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17073 mips32_op
= OPC_CVT_PS_S
;
17075 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
17078 goto pool32f_invalid
;
17082 check_insn(ctx
, ISA_MIPS32R6
);
17083 switch ((ctx
->opcode
>> 9) & 0x3) {
17085 gen_farith(ctx
, OPC_MIN_S
, rt
, rs
, rd
, 0);
17088 gen_farith(ctx
, OPC_MIN_D
, rt
, rs
, rd
, 0);
17091 goto pool32f_invalid
;
17096 switch ((ctx
->opcode
>> 6) & 0x7) {
17098 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17099 mips32_op
= OPC_LWXC1
;
17102 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17103 mips32_op
= OPC_SWXC1
;
17106 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17107 mips32_op
= OPC_LDXC1
;
17110 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17111 mips32_op
= OPC_SDXC1
;
17114 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17115 mips32_op
= OPC_LUXC1
;
17118 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17119 mips32_op
= OPC_SUXC1
;
17121 gen_flt3_ldst(ctx
, mips32_op
, rd
, rd
, rt
, rs
);
17124 goto pool32f_invalid
;
17128 check_insn(ctx
, ISA_MIPS32R6
);
17129 switch ((ctx
->opcode
>> 9) & 0x3) {
17131 gen_farith(ctx
, OPC_MAX_S
, rt
, rs
, rd
, 0);
17134 gen_farith(ctx
, OPC_MAX_D
, rt
, rs
, rd
, 0);
17137 goto pool32f_invalid
;
17142 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17143 fmt
= (ctx
->opcode
>> 9) & 0x3;
17144 switch ((ctx
->opcode
>> 6) & 0x7) {
17148 mips32_op
= OPC_RSQRT2_S
;
17151 mips32_op
= OPC_RSQRT2_D
;
17154 mips32_op
= OPC_RSQRT2_PS
;
17157 goto pool32f_invalid
;
17163 mips32_op
= OPC_RECIP2_S
;
17166 mips32_op
= OPC_RECIP2_D
;
17169 mips32_op
= OPC_RECIP2_PS
;
17172 goto pool32f_invalid
;
17176 mips32_op
= OPC_ADDR_PS
;
17179 mips32_op
= OPC_MULR_PS
;
17181 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
17184 goto pool32f_invalid
;
17188 /* MOV[FT].fmt, PREFX, RINT.fmt, CLASS.fmt*/
17189 cc
= (ctx
->opcode
>> 13) & 0x7;
17190 fmt
= (ctx
->opcode
>> 9) & 0x3;
17191 switch ((ctx
->opcode
>> 6) & 0x7) {
17192 case MOVF_FMT
: /* RINT_FMT */
17193 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
17197 gen_farith(ctx
, OPC_RINT_S
, 0, rt
, rs
, 0);
17200 gen_farith(ctx
, OPC_RINT_D
, 0, rt
, rs
, 0);
17203 goto pool32f_invalid
;
17209 gen_movcf_s(ctx
, rs
, rt
, cc
, 0);
17212 gen_movcf_d(ctx
, rs
, rt
, cc
, 0);
17216 gen_movcf_ps(ctx
, rs
, rt
, cc
, 0);
17219 goto pool32f_invalid
;
17223 case MOVT_FMT
: /* CLASS_FMT */
17224 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
17228 gen_farith(ctx
, OPC_CLASS_S
, 0, rt
, rs
, 0);
17231 gen_farith(ctx
, OPC_CLASS_D
, 0, rt
, rs
, 0);
17234 goto pool32f_invalid
;
17240 gen_movcf_s(ctx
, rs
, rt
, cc
, 1);
17243 gen_movcf_d(ctx
, rs
, rt
, cc
, 1);
17247 gen_movcf_ps(ctx
, rs
, rt
, cc
, 1);
17250 goto pool32f_invalid
;
17255 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17258 goto pool32f_invalid
;
17261 #define FINSN_3ARG_SDPS(prfx) \
17262 switch ((ctx->opcode >> 8) & 0x3) { \
17264 mips32_op = OPC_##prfx##_S; \
17267 mips32_op = OPC_##prfx##_D; \
17269 case FMT_SDPS_PS: \
17271 mips32_op = OPC_##prfx##_PS; \
17274 goto pool32f_invalid; \
17277 check_insn(ctx
, ISA_MIPS32R6
);
17278 switch ((ctx
->opcode
>> 9) & 0x3) {
17280 gen_farith(ctx
, OPC_MINA_S
, rt
, rs
, rd
, 0);
17283 gen_farith(ctx
, OPC_MINA_D
, rt
, rs
, rd
, 0);
17286 goto pool32f_invalid
;
17290 check_insn(ctx
, ISA_MIPS32R6
);
17291 switch ((ctx
->opcode
>> 9) & 0x3) {
17293 gen_farith(ctx
, OPC_MAXA_S
, rt
, rs
, rd
, 0);
17296 gen_farith(ctx
, OPC_MAXA_D
, rt
, rs
, rd
, 0);
17299 goto pool32f_invalid
;
17303 /* regular FP ops */
17304 switch ((ctx
->opcode
>> 6) & 0x3) {
17306 FINSN_3ARG_SDPS(ADD
);
17309 FINSN_3ARG_SDPS(SUB
);
17312 FINSN_3ARG_SDPS(MUL
);
17315 fmt
= (ctx
->opcode
>> 8) & 0x3;
17317 mips32_op
= OPC_DIV_D
;
17318 } else if (fmt
== 0) {
17319 mips32_op
= OPC_DIV_S
;
17321 goto pool32f_invalid
;
17325 goto pool32f_invalid
;
17330 switch ((ctx
->opcode
>> 6) & 0x7) {
17331 case MOVN_FMT
: /* SELEQZ_FMT */
17332 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
17334 switch ((ctx
->opcode
>> 9) & 0x3) {
17336 gen_sel_s(ctx
, OPC_SELEQZ_S
, rd
, rt
, rs
);
17339 gen_sel_d(ctx
, OPC_SELEQZ_D
, rd
, rt
, rs
);
17342 goto pool32f_invalid
;
17346 FINSN_3ARG_SDPS(MOVN
);
17350 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17351 FINSN_3ARG_SDPS(MOVN
);
17353 case MOVZ_FMT
: /* SELNEZ_FMT */
17354 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
17356 switch ((ctx
->opcode
>> 9) & 0x3) {
17358 gen_sel_s(ctx
, OPC_SELNEZ_S
, rd
, rt
, rs
);
17361 gen_sel_d(ctx
, OPC_SELNEZ_D
, rd
, rt
, rs
);
17364 goto pool32f_invalid
;
17368 FINSN_3ARG_SDPS(MOVZ
);
17372 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17373 FINSN_3ARG_SDPS(MOVZ
);
17376 check_insn(ctx
, ISA_MIPS32R6
);
17377 switch ((ctx
->opcode
>> 9) & 0x3) {
17379 gen_sel_s(ctx
, OPC_SEL_S
, rd
, rt
, rs
);
17382 gen_sel_d(ctx
, OPC_SEL_D
, rd
, rt
, rs
);
17385 goto pool32f_invalid
;
17389 check_insn(ctx
, ISA_MIPS32R6
);
17390 switch ((ctx
->opcode
>> 9) & 0x3) {
17392 mips32_op
= OPC_MADDF_S
;
17395 mips32_op
= OPC_MADDF_D
;
17398 goto pool32f_invalid
;
17402 check_insn(ctx
, ISA_MIPS32R6
);
17403 switch ((ctx
->opcode
>> 9) & 0x3) {
17405 mips32_op
= OPC_MSUBF_S
;
17408 mips32_op
= OPC_MSUBF_D
;
17411 goto pool32f_invalid
;
17415 goto pool32f_invalid
;
17419 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
17423 MIPS_INVAL("pool32f");
17424 generate_exception_end(ctx
, EXCP_RI
);
17428 generate_exception_err(ctx
, EXCP_CpU
, 1);
17432 minor
= (ctx
->opcode
>> 21) & 0x1f;
17435 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17436 gen_compute_branch(ctx
, OPC_BLTZ
, 4, rs
, -1, imm
<< 1, 4);
17439 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17440 gen_compute_branch(ctx
, OPC_BLTZAL
, 4, rs
, -1, imm
<< 1, 4);
17441 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
17444 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17445 gen_compute_branch(ctx
, OPC_BLTZAL
, 4, rs
, -1, imm
<< 1, 2);
17446 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
17449 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17450 gen_compute_branch(ctx
, OPC_BGEZ
, 4, rs
, -1, imm
<< 1, 4);
17453 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17454 gen_compute_branch(ctx
, OPC_BGEZAL
, 4, rs
, -1, imm
<< 1, 4);
17455 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
17458 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17459 gen_compute_branch(ctx
, OPC_BGEZAL
, 4, rs
, -1, imm
<< 1, 2);
17460 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
17463 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17464 gen_compute_branch(ctx
, OPC_BLEZ
, 4, rs
, -1, imm
<< 1, 4);
17467 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17468 gen_compute_branch(ctx
, OPC_BGTZ
, 4, rs
, -1, imm
<< 1, 4);
17472 case TLTI
: /* BC1EQZC */
17473 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
17475 check_cp1_enabled(ctx
);
17476 gen_compute_branch1_r6(ctx
, OPC_BC1EQZ
, rs
, imm
<< 1, 0);
17479 mips32_op
= OPC_TLTI
;
17483 case TGEI
: /* BC1NEZC */
17484 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
17486 check_cp1_enabled(ctx
);
17487 gen_compute_branch1_r6(ctx
, OPC_BC1NEZ
, rs
, imm
<< 1, 0);
17490 mips32_op
= OPC_TGEI
;
17495 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17496 mips32_op
= OPC_TLTIU
;
17499 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17500 mips32_op
= OPC_TGEIU
;
17502 case TNEI
: /* SYNCI */
17503 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
17506 * Break the TB to be able to sync copied instructions
17509 ctx
->base
.is_jmp
= DISAS_STOP
;
17512 mips32_op
= OPC_TNEI
;
17517 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17518 mips32_op
= OPC_TEQI
;
17520 gen_trap(ctx
, mips32_op
, rs
, -1, imm
);
17525 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17526 gen_compute_branch(ctx
, minor
== BNEZC
? OPC_BNE
: OPC_BEQ
,
17527 4, rs
, 0, imm
<< 1, 0);
17529 * Compact branches don't have a delay slot, so just let
17530 * the normal delay slot handling take us to the branch
17535 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17536 gen_logic_imm(ctx
, OPC_LUI
, rs
, 0, imm
);
17539 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17541 * Break the TB to be able to sync copied instructions
17544 ctx
->base
.is_jmp
= DISAS_STOP
;
17548 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17549 /* COP2: Not implemented. */
17550 generate_exception_err(ctx
, EXCP_CpU
, 2);
17553 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17554 mips32_op
= (ctx
->opcode
& (1 << 16)) ? OPC_BC1FANY2
: OPC_BC1F
;
17557 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17558 mips32_op
= (ctx
->opcode
& (1 << 16)) ? OPC_BC1TANY2
: OPC_BC1T
;
17561 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17562 mips32_op
= OPC_BC1FANY4
;
17565 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17566 mips32_op
= OPC_BC1TANY4
;
17569 check_insn(ctx
, ASE_MIPS3D
);
17572 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
17573 check_cp1_enabled(ctx
);
17574 gen_compute_branch1(ctx
, mips32_op
,
17575 (ctx
->opcode
>> 18) & 0x7, imm
<< 1);
17577 generate_exception_err(ctx
, EXCP_CpU
, 1);
17582 /* MIPS DSP: not implemented */
17585 MIPS_INVAL("pool32i");
17586 generate_exception_end(ctx
, EXCP_RI
);
17591 minor
= (ctx
->opcode
>> 12) & 0xf;
17592 offset
= sextract32(ctx
->opcode
, 0,
17593 (ctx
->insn_flags
& ISA_MIPS32R6
) ? 9 : 12);
17596 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17597 mips32_op
= OPC_LWL
;
17600 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17601 mips32_op
= OPC_SWL
;
17604 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17605 mips32_op
= OPC_LWR
;
17608 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17609 mips32_op
= OPC_SWR
;
17611 #if defined(TARGET_MIPS64)
17613 check_insn(ctx
, ISA_MIPS3
);
17614 check_mips_64(ctx
);
17615 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17616 mips32_op
= OPC_LDL
;
17619 check_insn(ctx
, ISA_MIPS3
);
17620 check_mips_64(ctx
);
17621 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17622 mips32_op
= OPC_SDL
;
17625 check_insn(ctx
, ISA_MIPS3
);
17626 check_mips_64(ctx
);
17627 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17628 mips32_op
= OPC_LDR
;
17631 check_insn(ctx
, ISA_MIPS3
);
17632 check_mips_64(ctx
);
17633 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17634 mips32_op
= OPC_SDR
;
17637 check_insn(ctx
, ISA_MIPS3
);
17638 check_mips_64(ctx
);
17639 mips32_op
= OPC_LWU
;
17642 check_insn(ctx
, ISA_MIPS3
);
17643 check_mips_64(ctx
);
17644 mips32_op
= OPC_LLD
;
17648 mips32_op
= OPC_LL
;
17651 gen_ld(ctx
, mips32_op
, rt
, rs
, offset
);
17654 gen_st(ctx
, mips32_op
, rt
, rs
, offset
);
17657 gen_st_cond(ctx
, rt
, rs
, offset
, MO_TESL
, false);
17659 #if defined(TARGET_MIPS64)
17661 check_insn(ctx
, ISA_MIPS3
);
17662 check_mips_64(ctx
);
17663 gen_st_cond(ctx
, rt
, rs
, offset
, MO_TEQ
, false);
17668 MIPS_INVAL("pool32c ld-eva");
17669 generate_exception_end(ctx
, EXCP_RI
);
17672 check_cp0_enabled(ctx
);
17674 minor2
= (ctx
->opcode
>> 9) & 0x7;
17675 offset
= sextract32(ctx
->opcode
, 0, 9);
17678 mips32_op
= OPC_LBUE
;
17681 mips32_op
= OPC_LHUE
;
17684 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17685 mips32_op
= OPC_LWLE
;
17688 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17689 mips32_op
= OPC_LWRE
;
17692 mips32_op
= OPC_LBE
;
17695 mips32_op
= OPC_LHE
;
17698 mips32_op
= OPC_LLE
;
17701 mips32_op
= OPC_LWE
;
17707 MIPS_INVAL("pool32c st-eva");
17708 generate_exception_end(ctx
, EXCP_RI
);
17711 check_cp0_enabled(ctx
);
17713 minor2
= (ctx
->opcode
>> 9) & 0x7;
17714 offset
= sextract32(ctx
->opcode
, 0, 9);
17717 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17718 mips32_op
= OPC_SWLE
;
17721 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17722 mips32_op
= OPC_SWRE
;
17725 /* Treat as no-op */
17726 if ((ctx
->insn_flags
& ISA_MIPS32R6
) && (rt
>= 24)) {
17727 /* hint codes 24-31 are reserved and signal RI */
17728 generate_exception(ctx
, EXCP_RI
);
17732 /* Treat as no-op */
17733 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
17734 gen_cache_operation(ctx
, rt
, rs
, offset
);
17738 mips32_op
= OPC_SBE
;
17741 mips32_op
= OPC_SHE
;
17744 gen_st_cond(ctx
, rt
, rs
, offset
, MO_TESL
, true);
17747 mips32_op
= OPC_SWE
;
17752 /* Treat as no-op */
17753 if ((ctx
->insn_flags
& ISA_MIPS32R6
) && (rt
>= 24)) {
17754 /* hint codes 24-31 are reserved and signal RI */
17755 generate_exception(ctx
, EXCP_RI
);
17759 MIPS_INVAL("pool32c");
17760 generate_exception_end(ctx
, EXCP_RI
);
17764 case ADDI32
: /* AUI, LUI */
17765 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
17767 gen_logic_imm(ctx
, OPC_LUI
, rt
, rs
, imm
);
17770 mips32_op
= OPC_ADDI
;
17775 mips32_op
= OPC_ADDIU
;
17777 gen_arith_imm(ctx
, mips32_op
, rt
, rs
, imm
);
17780 /* Logical operations */
17782 mips32_op
= OPC_ORI
;
17785 mips32_op
= OPC_XORI
;
17788 mips32_op
= OPC_ANDI
;
17790 gen_logic_imm(ctx
, mips32_op
, rt
, rs
, imm
);
17793 /* Set less than immediate */
17795 mips32_op
= OPC_SLTI
;
17798 mips32_op
= OPC_SLTIU
;
17800 gen_slt_imm(ctx
, mips32_op
, rt
, rs
, imm
);
17803 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17804 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
17805 gen_compute_branch(ctx
, OPC_JALX
, 4, rt
, rs
, offset
, 4);
17806 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
17808 case JALS32
: /* BOVC, BEQC, BEQZALC */
17809 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
17812 mips32_op
= OPC_BOVC
;
17813 } else if (rs
< rt
&& rs
== 0) {
17815 mips32_op
= OPC_BEQZALC
;
17818 mips32_op
= OPC_BEQC
;
17820 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
17823 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1;
17824 gen_compute_branch(ctx
, OPC_JAL
, 4, rt
, rs
, offset
, 2);
17825 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
17828 case BEQ32
: /* BC */
17829 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
17831 gen_compute_compact_branch(ctx
, OPC_BC
, 0, 0,
17832 sextract32(ctx
->opcode
<< 1, 0, 27));
17835 gen_compute_branch(ctx
, OPC_BEQ
, 4, rt
, rs
, imm
<< 1, 4);
17838 case BNE32
: /* BALC */
17839 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
17841 gen_compute_compact_branch(ctx
, OPC_BALC
, 0, 0,
17842 sextract32(ctx
->opcode
<< 1, 0, 27));
17845 gen_compute_branch(ctx
, OPC_BNE
, 4, rt
, rs
, imm
<< 1, 4);
17848 case J32
: /* BGTZC, BLTZC, BLTC */
17849 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
17850 if (rs
== 0 && rt
!= 0) {
17852 mips32_op
= OPC_BGTZC
;
17853 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
17855 mips32_op
= OPC_BLTZC
;
17858 mips32_op
= OPC_BLTC
;
17860 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
17863 gen_compute_branch(ctx
, OPC_J
, 4, rt
, rs
,
17864 (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1, 4);
17867 case JAL32
: /* BLEZC, BGEZC, BGEC */
17868 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
17869 if (rs
== 0 && rt
!= 0) {
17871 mips32_op
= OPC_BLEZC
;
17872 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
17874 mips32_op
= OPC_BGEZC
;
17877 mips32_op
= OPC_BGEC
;
17879 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
17882 gen_compute_branch(ctx
, OPC_JAL
, 4, rt
, rs
,
17883 (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1, 4);
17884 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
17887 /* Floating point (COP1) */
17889 mips32_op
= OPC_LWC1
;
17892 mips32_op
= OPC_LDC1
;
17895 mips32_op
= OPC_SWC1
;
17898 mips32_op
= OPC_SDC1
;
17900 gen_cop1_ldst(ctx
, mips32_op
, rt
, rs
, imm
);
17902 case ADDIUPC
: /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
17903 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
17904 /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
17905 switch ((ctx
->opcode
>> 16) & 0x1f) {
17914 gen_pcrel(ctx
, OPC_ADDIUPC
, ctx
->base
.pc_next
& ~0x3, rt
);
17917 gen_pcrel(ctx
, OPC_AUIPC
, ctx
->base
.pc_next
, rt
);
17920 gen_pcrel(ctx
, OPC_ALUIPC
, ctx
->base
.pc_next
, rt
);
17930 gen_pcrel(ctx
, R6_OPC_LWPC
, ctx
->base
.pc_next
& ~0x3, rt
);
17933 generate_exception(ctx
, EXCP_RI
);
17938 int reg
= mmreg(ZIMM(ctx
->opcode
, 23, 3));
17939 offset
= SIMM(ctx
->opcode
, 0, 23) << 2;
17941 gen_addiupc(ctx
, reg
, offset
, 0, 0);
17944 case BNVC
: /* BNEC, BNEZALC */
17945 check_insn(ctx
, ISA_MIPS32R6
);
17948 mips32_op
= OPC_BNVC
;
17949 } else if (rs
< rt
&& rs
== 0) {
17951 mips32_op
= OPC_BNEZALC
;
17954 mips32_op
= OPC_BNEC
;
17956 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
17958 case R6_BNEZC
: /* JIALC */
17959 check_insn(ctx
, ISA_MIPS32R6
);
17962 gen_compute_compact_branch(ctx
, OPC_BNEZC
, rt
, 0,
17963 sextract32(ctx
->opcode
<< 1, 0, 22));
17966 gen_compute_compact_branch(ctx
, OPC_JIALC
, 0, rs
, imm
);
17969 case R6_BEQZC
: /* JIC */
17970 check_insn(ctx
, ISA_MIPS32R6
);
17973 gen_compute_compact_branch(ctx
, OPC_BEQZC
, rt
, 0,
17974 sextract32(ctx
->opcode
<< 1, 0, 22));
17977 gen_compute_compact_branch(ctx
, OPC_JIC
, 0, rs
, imm
);
17980 case BLEZALC
: /* BGEZALC, BGEUC */
17981 check_insn(ctx
, ISA_MIPS32R6
);
17982 if (rs
== 0 && rt
!= 0) {
17984 mips32_op
= OPC_BLEZALC
;
17985 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
17987 mips32_op
= OPC_BGEZALC
;
17990 mips32_op
= OPC_BGEUC
;
17992 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
17994 case BGTZALC
: /* BLTZALC, BLTUC */
17995 check_insn(ctx
, ISA_MIPS32R6
);
17996 if (rs
== 0 && rt
!= 0) {
17998 mips32_op
= OPC_BGTZALC
;
17999 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
18001 mips32_op
= OPC_BLTZALC
;
18004 mips32_op
= OPC_BLTUC
;
18006 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
18008 /* Loads and stores */
18010 mips32_op
= OPC_LB
;
18013 mips32_op
= OPC_LBU
;
18016 mips32_op
= OPC_LH
;
18019 mips32_op
= OPC_LHU
;
18022 mips32_op
= OPC_LW
;
18024 #ifdef TARGET_MIPS64
18026 check_insn(ctx
, ISA_MIPS3
);
18027 check_mips_64(ctx
);
18028 mips32_op
= OPC_LD
;
18031 check_insn(ctx
, ISA_MIPS3
);
18032 check_mips_64(ctx
);
18033 mips32_op
= OPC_SD
;
18037 mips32_op
= OPC_SB
;
18040 mips32_op
= OPC_SH
;
18043 mips32_op
= OPC_SW
;
18046 gen_ld(ctx
, mips32_op
, rt
, rs
, imm
);
18049 gen_st(ctx
, mips32_op
, rt
, rs
, imm
);
18052 generate_exception_end(ctx
, EXCP_RI
);
18057 static int decode_micromips_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
18061 /* make sure instructions are on a halfword boundary */
18062 if (ctx
->base
.pc_next
& 0x1) {
18063 env
->CP0_BadVAddr
= ctx
->base
.pc_next
;
18064 generate_exception_end(ctx
, EXCP_AdEL
);
18068 op
= (ctx
->opcode
>> 10) & 0x3f;
18069 /* Enforce properly-sized instructions in a delay slot */
18070 if (ctx
->hflags
& MIPS_HFLAG_BDS_STRICT
) {
18071 switch (op
& 0x7) { /* MSB-3..MSB-5 */
18073 /* POOL32A, POOL32B, POOL32I, POOL32C */
18075 /* ADDI32, ADDIU32, ORI32, XORI32, SLTI32, SLTIU32, ANDI32, JALX32 */
18077 /* LBU32, LHU32, POOL32F, JALS32, BEQ32, BNE32, J32, JAL32 */
18079 /* SB32, SH32, ADDIUPC, SWC132, SDC132, SW32 */
18081 /* LB32, LH32, LWC132, LDC132, LW32 */
18082 if (ctx
->hflags
& MIPS_HFLAG_BDS16
) {
18083 generate_exception_end(ctx
, EXCP_RI
);
18088 /* POOL16A, POOL16B, POOL16C, LWGP16, POOL16F */
18090 /* LBU16, LHU16, LWSP16, LW16, SB16, SH16, SWSP16, SW16 */
18092 /* MOVE16, ANDI16, POOL16D, POOL16E, BEQZ16, BNEZ16, B16, LI16 */
18093 if (ctx
->hflags
& MIPS_HFLAG_BDS32
) {
18094 generate_exception_end(ctx
, EXCP_RI
);
18104 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
18105 int rs1
= mmreg(uMIPS_RS1(ctx
->opcode
));
18106 int rs2
= mmreg(uMIPS_RS2(ctx
->opcode
));
18109 switch (ctx
->opcode
& 0x1) {
18117 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
18119 * In the Release 6, the register number location in
18120 * the instruction encoding has changed.
18122 gen_arith(ctx
, opc
, rs1
, rd
, rs2
);
18124 gen_arith(ctx
, opc
, rd
, rs1
, rs2
);
18130 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
18131 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
18132 int amount
= (ctx
->opcode
>> 1) & 0x7;
18134 amount
= amount
== 0 ? 8 : amount
;
18136 switch (ctx
->opcode
& 0x1) {
18145 gen_shift_imm(ctx
, opc
, rd
, rs
, amount
);
18149 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
18150 gen_pool16c_r6_insn(ctx
);
18152 gen_pool16c_insn(ctx
);
18157 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
18158 int rb
= 28; /* GP */
18159 int16_t offset
= SIMM(ctx
->opcode
, 0, 7) << 2;
18161 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
18165 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
18166 if (ctx
->opcode
& 1) {
18167 generate_exception_end(ctx
, EXCP_RI
);
18170 int enc_dest
= uMIPS_RD(ctx
->opcode
);
18171 int enc_rt
= uMIPS_RS2(ctx
->opcode
);
18172 int enc_rs
= uMIPS_RS1(ctx
->opcode
);
18173 gen_movep(ctx
, enc_dest
, enc_rt
, enc_rs
);
18178 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
18179 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
18180 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4);
18181 offset
= (offset
== 0xf ? -1 : offset
);
18183 gen_ld(ctx
, OPC_LBU
, rd
, rb
, offset
);
18188 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
18189 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
18190 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 1;
18192 gen_ld(ctx
, OPC_LHU
, rd
, rb
, offset
);
18197 int rd
= (ctx
->opcode
>> 5) & 0x1f;
18198 int rb
= 29; /* SP */
18199 int16_t offset
= ZIMM(ctx
->opcode
, 0, 5) << 2;
18201 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
18206 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
18207 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
18208 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 2;
18210 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
18215 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
18216 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
18217 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4);
18219 gen_st(ctx
, OPC_SB
, rd
, rb
, offset
);
18224 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
18225 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
18226 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 1;
18228 gen_st(ctx
, OPC_SH
, rd
, rb
, offset
);
18233 int rd
= (ctx
->opcode
>> 5) & 0x1f;
18234 int rb
= 29; /* SP */
18235 int16_t offset
= ZIMM(ctx
->opcode
, 0, 5) << 2;
18237 gen_st(ctx
, OPC_SW
, rd
, rb
, offset
);
18242 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
18243 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
18244 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 2;
18246 gen_st(ctx
, OPC_SW
, rd
, rb
, offset
);
18251 int rd
= uMIPS_RD5(ctx
->opcode
);
18252 int rs
= uMIPS_RS5(ctx
->opcode
);
18254 gen_arith(ctx
, OPC_ADDU
, rd
, rs
, 0);
18261 switch (ctx
->opcode
& 0x1) {
18271 switch (ctx
->opcode
& 0x1) {
18276 gen_addiur1sp(ctx
);
18280 case B16
: /* BC16 */
18281 gen_compute_branch(ctx
, OPC_BEQ
, 2, 0, 0,
18282 sextract32(ctx
->opcode
, 0, 10) << 1,
18283 (ctx
->insn_flags
& ISA_MIPS32R6
) ? 0 : 4);
18285 case BNEZ16
: /* BNEZC16 */
18286 case BEQZ16
: /* BEQZC16 */
18287 gen_compute_branch(ctx
, op
== BNEZ16
? OPC_BNE
: OPC_BEQ
, 2,
18288 mmreg(uMIPS_RD(ctx
->opcode
)),
18289 0, sextract32(ctx
->opcode
, 0, 7) << 1,
18290 (ctx
->insn_flags
& ISA_MIPS32R6
) ? 0 : 4);
18295 int reg
= mmreg(uMIPS_RD(ctx
->opcode
));
18296 int imm
= ZIMM(ctx
->opcode
, 0, 7);
18298 imm
= (imm
== 0x7f ? -1 : imm
);
18299 tcg_gen_movi_tl(cpu_gpr
[reg
], imm
);
18305 generate_exception_end(ctx
, EXCP_RI
);
18308 decode_micromips32_opc(env
, ctx
);
18321 /* MAJOR, P16, and P32 pools opcodes */
18325 NM_MOVE_BALC
= 0x02,
18333 NM_P16_SHIFT
= 0x0c,
18351 NM_P_LS_U12
= 0x21,
18361 NM_P16_ADDU
= 0x2c,
18375 NM_MOVEPREV
= 0x3f,
18378 /* POOL32A instruction pool */
18380 NM_POOL32A0
= 0x00,
18381 NM_SPECIAL2
= 0x01,
18384 NM_POOL32A5
= 0x05,
18385 NM_POOL32A7
= 0x07,
18388 /* P.GP.W instruction pool */
18390 NM_ADDIUGP_W
= 0x00,
18395 /* P48I instruction pool */
18399 NM_ADDIUGP48
= 0x02,
18400 NM_ADDIUPC48
= 0x03,
18405 /* P.U12 instruction pool */
18414 NM_ADDIUNEG
= 0x08,
18421 /* POOL32F instruction pool */
18423 NM_POOL32F_0
= 0x00,
18424 NM_POOL32F_3
= 0x03,
18425 NM_POOL32F_5
= 0x05,
18428 /* POOL32S instruction pool */
18430 NM_POOL32S_0
= 0x00,
18431 NM_POOL32S_4
= 0x04,
18434 /* P.LUI instruction pool */
18440 /* P.GP.BH instruction pool */
18445 NM_ADDIUGP_B
= 0x03,
18448 NM_P_GP_CP1
= 0x06,
18451 /* P.LS.U12 instruction pool */
18456 NM_P_PREFU12
= 0x03,
18469 /* P.LS.S9 instruction pool */
18475 NM_P_LS_UAWM
= 0x05,
18478 /* P.BAL instruction pool */
18484 /* P.J instruction pool */
18487 NM_JALRC_HB
= 0x01,
18488 NM_P_BALRSC
= 0x08,
18491 /* P.BR1 instruction pool */
18499 /* P.BR2 instruction pool */
18506 /* P.BRI instruction pool */
18518 /* P16.SHIFT instruction pool */
18524 /* POOL16C instruction pool */
18526 NM_POOL16C_0
= 0x00,
18530 /* P16.A1 instruction pool */
18532 NM_ADDIUR1SP
= 0x01,
18535 /* P16.A2 instruction pool */
18538 NM_P_ADDIURS5
= 0x01,
18541 /* P16.ADDU instruction pool */
18547 /* P16.SR instruction pool */
18550 NM_RESTORE_JRC16
= 0x01,
18553 /* P16.4X4 instruction pool */
18559 /* P16.LB instruction pool */
18566 /* P16.LH instruction pool */
18573 /* P.RI instruction pool */
18576 NM_P_SYSCALL
= 0x01,
18581 /* POOL32A0 instruction pool */
18616 NM_D_E_MT_VPE
= 0x56,
18624 /* CRC32 instruction pool */
18634 /* POOL32A5 instruction pool */
18636 NM_CMP_EQ_PH
= 0x00,
18637 NM_CMP_LT_PH
= 0x08,
18638 NM_CMP_LE_PH
= 0x10,
18639 NM_CMPGU_EQ_QB
= 0x18,
18640 NM_CMPGU_LT_QB
= 0x20,
18641 NM_CMPGU_LE_QB
= 0x28,
18642 NM_CMPGDU_EQ_QB
= 0x30,
18643 NM_CMPGDU_LT_QB
= 0x38,
18644 NM_CMPGDU_LE_QB
= 0x40,
18645 NM_CMPU_EQ_QB
= 0x48,
18646 NM_CMPU_LT_QB
= 0x50,
18647 NM_CMPU_LE_QB
= 0x58,
18648 NM_ADDQ_S_W
= 0x60,
18649 NM_SUBQ_S_W
= 0x68,
18653 NM_ADDQ_S_PH
= 0x01,
18654 NM_ADDQH_R_PH
= 0x09,
18655 NM_ADDQH_R_W
= 0x11,
18656 NM_ADDU_S_QB
= 0x19,
18657 NM_ADDU_S_PH
= 0x21,
18658 NM_ADDUH_R_QB
= 0x29,
18659 NM_SHRAV_R_PH
= 0x31,
18660 NM_SHRAV_R_QB
= 0x39,
18661 NM_SUBQ_S_PH
= 0x41,
18662 NM_SUBQH_R_PH
= 0x49,
18663 NM_SUBQH_R_W
= 0x51,
18664 NM_SUBU_S_QB
= 0x59,
18665 NM_SUBU_S_PH
= 0x61,
18666 NM_SUBUH_R_QB
= 0x69,
18667 NM_SHLLV_S_PH
= 0x71,
18668 NM_PRECR_SRA_R_PH_W
= 0x79,
18670 NM_MULEU_S_PH_QBL
= 0x12,
18671 NM_MULEU_S_PH_QBR
= 0x1a,
18672 NM_MULQ_RS_PH
= 0x22,
18673 NM_MULQ_S_PH
= 0x2a,
18674 NM_MULQ_RS_W
= 0x32,
18675 NM_MULQ_S_W
= 0x3a,
18678 NM_SHRAV_R_W
= 0x5a,
18679 NM_SHRLV_PH
= 0x62,
18680 NM_SHRLV_QB
= 0x6a,
18681 NM_SHLLV_QB
= 0x72,
18682 NM_SHLLV_S_W
= 0x7a,
18686 NM_MULEQ_S_W_PHL
= 0x04,
18687 NM_MULEQ_S_W_PHR
= 0x0c,
18689 NM_MUL_S_PH
= 0x05,
18690 NM_PRECR_QB_PH
= 0x0d,
18691 NM_PRECRQ_QB_PH
= 0x15,
18692 NM_PRECRQ_PH_W
= 0x1d,
18693 NM_PRECRQ_RS_PH_W
= 0x25,
18694 NM_PRECRQU_S_QB_PH
= 0x2d,
18695 NM_PACKRL_PH
= 0x35,
18699 NM_SHRA_R_W
= 0x5e,
18700 NM_SHRA_R_PH
= 0x66,
18701 NM_SHLL_S_PH
= 0x76,
18702 NM_SHLL_S_W
= 0x7e,
18707 /* POOL32A7 instruction pool */
18712 NM_POOL32AXF
= 0x07,
18715 /* P.SR instruction pool */
18721 /* P.SHIFT instruction pool */
18729 /* P.ROTX instruction pool */
18734 /* P.INS instruction pool */
18739 /* P.EXT instruction pool */
18744 /* POOL32F_0 (fmt) instruction pool */
18749 NM_SELEQZ_S
= 0x07,
18750 NM_SELEQZ_D
= 0x47,
18754 NM_SELNEZ_S
= 0x0f,
18755 NM_SELNEZ_D
= 0x4f,
18770 /* POOL32F_3 instruction pool */
18774 NM_MINA_FMT
= 0x04,
18775 NM_MAXA_FMT
= 0x05,
18776 NM_POOL32FXF
= 0x07,
18779 /* POOL32F_5 instruction pool */
18781 NM_CMP_CONDN_S
= 0x00,
18782 NM_CMP_CONDN_D
= 0x02,
18785 /* P.GP.LH instruction pool */
18791 /* P.GP.SH instruction pool */
18796 /* P.GP.CP1 instruction pool */
18804 /* P.LS.S0 instruction pool */
18821 NM_P_PREFS9
= 0x03,
18827 /* P.LS.S1 instruction pool */
18829 NM_ASET_ACLR
= 0x02,
18837 /* P.LS.E0 instruction pool */
18853 /* P.PREFE instruction pool */
18859 /* P.LLE instruction pool */
18865 /* P.SCE instruction pool */
18871 /* P.LS.WM instruction pool */
18877 /* P.LS.UAWM instruction pool */
18883 /* P.BR3A instruction pool */
18889 NM_BPOSGE32C
= 0x04,
18892 /* P16.RI instruction pool */
18894 NM_P16_SYSCALL
= 0x01,
18899 /* POOL16C_0 instruction pool */
18901 NM_POOL16C_00
= 0x00,
18904 /* P16.JRC instruction pool */
18910 /* P.SYSCALL instruction pool */
18916 /* P.TRAP instruction pool */
18922 /* P.CMOVE instruction pool */
18928 /* POOL32Axf instruction pool */
18930 NM_POOL32AXF_1
= 0x01,
18931 NM_POOL32AXF_2
= 0x02,
18932 NM_POOL32AXF_4
= 0x04,
18933 NM_POOL32AXF_5
= 0x05,
18934 NM_POOL32AXF_7
= 0x07,
18937 /* POOL32Axf_1 instruction pool */
18939 NM_POOL32AXF_1_0
= 0x00,
18940 NM_POOL32AXF_1_1
= 0x01,
18941 NM_POOL32AXF_1_3
= 0x03,
18942 NM_POOL32AXF_1_4
= 0x04,
18943 NM_POOL32AXF_1_5
= 0x05,
18944 NM_POOL32AXF_1_7
= 0x07,
18947 /* POOL32Axf_2 instruction pool */
18949 NM_POOL32AXF_2_0_7
= 0x00,
18950 NM_POOL32AXF_2_8_15
= 0x01,
18951 NM_POOL32AXF_2_16_23
= 0x02,
18952 NM_POOL32AXF_2_24_31
= 0x03,
18955 /* POOL32Axf_7 instruction pool */
18957 NM_SHRA_R_QB
= 0x0,
18962 /* POOL32Axf_1_0 instruction pool */
18970 /* POOL32Axf_1_1 instruction pool */
18976 /* POOL32Axf_1_3 instruction pool */
18984 /* POOL32Axf_1_4 instruction pool */
18990 /* POOL32Axf_1_5 instruction pool */
18992 NM_MAQ_S_W_PHR
= 0x0,
18993 NM_MAQ_S_W_PHL
= 0x1,
18994 NM_MAQ_SA_W_PHR
= 0x2,
18995 NM_MAQ_SA_W_PHL
= 0x3,
18998 /* POOL32Axf_1_7 instruction pool */
19002 NM_EXTR_RS_W
= 0x2,
19006 /* POOL32Axf_2_0_7 instruction pool */
19009 NM_DPAQ_S_W_PH
= 0x1,
19011 NM_DPSQ_S_W_PH
= 0x3,
19018 /* POOL32Axf_2_8_15 instruction pool */
19020 NM_DPAX_W_PH
= 0x0,
19021 NM_DPAQ_SA_L_W
= 0x1,
19022 NM_DPSX_W_PH
= 0x2,
19023 NM_DPSQ_SA_L_W
= 0x3,
19026 NM_EXTRV_R_W
= 0x7,
19029 /* POOL32Axf_2_16_23 instruction pool */
19031 NM_DPAU_H_QBL
= 0x0,
19032 NM_DPAQX_S_W_PH
= 0x1,
19033 NM_DPSU_H_QBL
= 0x2,
19034 NM_DPSQX_S_W_PH
= 0x3,
19037 NM_MULSA_W_PH
= 0x6,
19038 NM_EXTRV_RS_W
= 0x7,
19041 /* POOL32Axf_2_24_31 instruction pool */
19043 NM_DPAU_H_QBR
= 0x0,
19044 NM_DPAQX_SA_W_PH
= 0x1,
19045 NM_DPSU_H_QBR
= 0x2,
19046 NM_DPSQX_SA_W_PH
= 0x3,
19049 NM_MULSAQ_S_W_PH
= 0x6,
19050 NM_EXTRV_S_H
= 0x7,
19053 /* POOL32Axf_{4, 5} instruction pool */
19072 /* nanoMIPS DSP instructions */
19073 NM_ABSQ_S_QB
= 0x00,
19074 NM_ABSQ_S_PH
= 0x08,
19075 NM_ABSQ_S_W
= 0x10,
19076 NM_PRECEQ_W_PHL
= 0x28,
19077 NM_PRECEQ_W_PHR
= 0x30,
19078 NM_PRECEQU_PH_QBL
= 0x38,
19079 NM_PRECEQU_PH_QBR
= 0x48,
19080 NM_PRECEU_PH_QBL
= 0x58,
19081 NM_PRECEU_PH_QBR
= 0x68,
19082 NM_PRECEQU_PH_QBLA
= 0x39,
19083 NM_PRECEQU_PH_QBRA
= 0x49,
19084 NM_PRECEU_PH_QBLA
= 0x59,
19085 NM_PRECEU_PH_QBRA
= 0x69,
19086 NM_REPLV_PH
= 0x01,
19087 NM_REPLV_QB
= 0x09,
19090 NM_RADDU_W_QB
= 0x78,
19096 /* PP.SR instruction pool */
19100 NM_RESTORE_JRC
= 0x03,
19103 /* P.SR.F instruction pool */
19106 NM_RESTOREF
= 0x01,
19109 /* P16.SYSCALL instruction pool */
19111 NM_SYSCALL16
= 0x00,
19112 NM_HYPCALL16
= 0x01,
19115 /* POOL16C_00 instruction pool */
19123 /* PP.LSX and PP.LSXS instruction pool */
19161 /* ERETx instruction pool */
19167 /* POOL32FxF_{0, 1} insturction pool */
19176 NM_CVT_S_PL
= 0x84,
19177 NM_CVT_S_PU
= 0xa4,
19179 NM_CVT_L_S
= 0x004,
19180 NM_CVT_L_D
= 0x104,
19181 NM_CVT_W_S
= 0x024,
19182 NM_CVT_W_D
= 0x124,
19184 NM_RSQRT_S
= 0x008,
19185 NM_RSQRT_D
= 0x108,
19190 NM_RECIP_S
= 0x048,
19191 NM_RECIP_D
= 0x148,
19193 NM_FLOOR_L_S
= 0x00c,
19194 NM_FLOOR_L_D
= 0x10c,
19196 NM_FLOOR_W_S
= 0x02c,
19197 NM_FLOOR_W_D
= 0x12c,
19199 NM_CEIL_L_S
= 0x04c,
19200 NM_CEIL_L_D
= 0x14c,
19201 NM_CEIL_W_S
= 0x06c,
19202 NM_CEIL_W_D
= 0x16c,
19203 NM_TRUNC_L_S
= 0x08c,
19204 NM_TRUNC_L_D
= 0x18c,
19205 NM_TRUNC_W_S
= 0x0ac,
19206 NM_TRUNC_W_D
= 0x1ac,
19207 NM_ROUND_L_S
= 0x0cc,
19208 NM_ROUND_L_D
= 0x1cc,
19209 NM_ROUND_W_S
= 0x0ec,
19210 NM_ROUND_W_D
= 0x1ec,
19218 NM_CVT_D_S
= 0x04d,
19219 NM_CVT_D_W
= 0x0cd,
19220 NM_CVT_D_L
= 0x14d,
19221 NM_CVT_S_D
= 0x06d,
19222 NM_CVT_S_W
= 0x0ed,
19223 NM_CVT_S_L
= 0x16d,
19226 /* P.LL instruction pool */
19232 /* P.SC instruction pool */
19238 /* P.DVP instruction pool */
19247 * nanoMIPS decoding engine
19252 /* extraction utilities */
19254 #define NANOMIPS_EXTRACT_RT3(op) ((op >> 7) & 0x7)
19255 #define NANOMIPS_EXTRACT_RS3(op) ((op >> 4) & 0x7)
19256 #define NANOMIPS_EXTRACT_RD3(op) ((op >> 1) & 0x7)
19257 #define NANOMIPS_EXTRACT_RD5(op) ((op >> 5) & 0x1f)
19258 #define NANOMIPS_EXTRACT_RS5(op) (op & 0x1f)
19260 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3'). */
19261 static inline int decode_gpr_gpr3(int r
)
19263 static const int map
[] = { 16, 17, 18, 19, 4, 5, 6, 7 };
19265 return map
[r
& 0x7];
19268 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3.src.store'). */
19269 static inline int decode_gpr_gpr3_src_store(int r
)
19271 static const int map
[] = { 0, 17, 18, 19, 4, 5, 6, 7 };
19273 return map
[r
& 0x7];
19276 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4'). */
19277 static inline int decode_gpr_gpr4(int r
)
19279 static const int map
[] = { 8, 9, 10, 11, 4, 5, 6, 7,
19280 16, 17, 18, 19, 20, 21, 22, 23 };
19282 return map
[r
& 0xf];
19285 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4.zero'). */
19286 static inline int decode_gpr_gpr4_zero(int r
)
19288 static const int map
[] = { 8, 9, 10, 0, 4, 5, 6, 7,
19289 16, 17, 18, 19, 20, 21, 22, 23 };
19291 return map
[r
& 0xf];
19295 static void gen_adjust_sp(DisasContext
*ctx
, int u
)
19297 gen_op_addr_addi(ctx
, cpu_gpr
[29], cpu_gpr
[29], u
);
19300 static void gen_save(DisasContext
*ctx
, uint8_t rt
, uint8_t count
,
19301 uint8_t gp
, uint16_t u
)
19304 TCGv va
= tcg_temp_new();
19305 TCGv t0
= tcg_temp_new();
19307 while (counter
!= count
) {
19308 bool use_gp
= gp
&& (counter
== count
- 1);
19309 int this_rt
= use_gp
? 28 : (rt
& 0x10) | ((rt
+ counter
) & 0x1f);
19310 int this_offset
= -((counter
+ 1) << 2);
19311 gen_base_offset_addr(ctx
, va
, 29, this_offset
);
19312 gen_load_gpr(t0
, this_rt
);
19313 tcg_gen_qemu_st_tl(t0
, va
, ctx
->mem_idx
,
19314 (MO_TEUL
| ctx
->default_tcg_memop_mask
));
19318 /* adjust stack pointer */
19319 gen_adjust_sp(ctx
, -u
);
19325 static void gen_restore(DisasContext
*ctx
, uint8_t rt
, uint8_t count
,
19326 uint8_t gp
, uint16_t u
)
19329 TCGv va
= tcg_temp_new();
19330 TCGv t0
= tcg_temp_new();
19332 while (counter
!= count
) {
19333 bool use_gp
= gp
&& (counter
== count
- 1);
19334 int this_rt
= use_gp
? 28 : (rt
& 0x10) | ((rt
+ counter
) & 0x1f);
19335 int this_offset
= u
- ((counter
+ 1) << 2);
19336 gen_base_offset_addr(ctx
, va
, 29, this_offset
);
19337 tcg_gen_qemu_ld_tl(t0
, va
, ctx
->mem_idx
, MO_TESL
|
19338 ctx
->default_tcg_memop_mask
);
19339 tcg_gen_ext32s_tl(t0
, t0
);
19340 gen_store_gpr(t0
, this_rt
);
19344 /* adjust stack pointer */
19345 gen_adjust_sp(ctx
, u
);
19351 static void gen_pool16c_nanomips_insn(DisasContext
*ctx
)
19353 int rt
= decode_gpr_gpr3(NANOMIPS_EXTRACT_RT3(ctx
->opcode
));
19354 int rs
= decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx
->opcode
));
19356 switch (extract32(ctx
->opcode
, 2, 2)) {
19358 gen_logic(ctx
, OPC_NOR
, rt
, rs
, 0);
19361 gen_logic(ctx
, OPC_AND
, rt
, rt
, rs
);
19364 gen_logic(ctx
, OPC_XOR
, rt
, rt
, rs
);
19367 gen_logic(ctx
, OPC_OR
, rt
, rt
, rs
);
19372 static void gen_pool32a0_nanomips_insn(CPUMIPSState
*env
, DisasContext
*ctx
)
19374 int rt
= extract32(ctx
->opcode
, 21, 5);
19375 int rs
= extract32(ctx
->opcode
, 16, 5);
19376 int rd
= extract32(ctx
->opcode
, 11, 5);
19378 switch (extract32(ctx
->opcode
, 3, 7)) {
19380 switch (extract32(ctx
->opcode
, 10, 1)) {
19383 gen_trap(ctx
, OPC_TEQ
, rs
, rt
, -1);
19387 gen_trap(ctx
, OPC_TNE
, rs
, rt
, -1);
19393 gen_rdhwr(ctx
, rt
, rs
, extract32(ctx
->opcode
, 11, 3));
19397 gen_bshfl(ctx
, OPC_SEB
, rs
, rt
);
19400 gen_bshfl(ctx
, OPC_SEH
, rs
, rt
);
19403 gen_shift(ctx
, OPC_SLLV
, rd
, rt
, rs
);
19406 gen_shift(ctx
, OPC_SRLV
, rd
, rt
, rs
);
19409 gen_shift(ctx
, OPC_SRAV
, rd
, rt
, rs
);
19412 gen_shift(ctx
, OPC_ROTRV
, rd
, rt
, rs
);
19415 gen_arith(ctx
, OPC_ADD
, rd
, rs
, rt
);
19418 gen_arith(ctx
, OPC_ADDU
, rd
, rs
, rt
);
19422 gen_arith(ctx
, OPC_SUB
, rd
, rs
, rt
);
19425 gen_arith(ctx
, OPC_SUBU
, rd
, rs
, rt
);
19428 switch (extract32(ctx
->opcode
, 10, 1)) {
19430 gen_cond_move(ctx
, OPC_MOVZ
, rd
, rs
, rt
);
19433 gen_cond_move(ctx
, OPC_MOVN
, rd
, rs
, rt
);
19438 gen_logic(ctx
, OPC_AND
, rd
, rs
, rt
);
19441 gen_logic(ctx
, OPC_OR
, rd
, rs
, rt
);
19444 gen_logic(ctx
, OPC_NOR
, rd
, rs
, rt
);
19447 gen_logic(ctx
, OPC_XOR
, rd
, rs
, rt
);
19450 gen_slt(ctx
, OPC_SLT
, rd
, rs
, rt
);
19455 #ifndef CONFIG_USER_ONLY
19456 TCGv t0
= tcg_temp_new();
19457 switch (extract32(ctx
->opcode
, 10, 1)) {
19460 check_cp0_enabled(ctx
);
19461 gen_helper_dvp(t0
, cpu_env
);
19462 gen_store_gpr(t0
, rt
);
19467 check_cp0_enabled(ctx
);
19468 gen_helper_evp(t0
, cpu_env
);
19469 gen_store_gpr(t0
, rt
);
19476 gen_slt(ctx
, OPC_SLTU
, rd
, rs
, rt
);
19481 TCGv t0
= tcg_temp_new();
19482 TCGv t1
= tcg_temp_new();
19483 TCGv t2
= tcg_temp_new();
19485 gen_load_gpr(t1
, rs
);
19486 gen_load_gpr(t2
, rt
);
19487 tcg_gen_add_tl(t0
, t1
, t2
);
19488 tcg_gen_ext32s_tl(t0
, t0
);
19489 tcg_gen_xor_tl(t1
, t1
, t2
);
19490 tcg_gen_xor_tl(t2
, t0
, t2
);
19491 tcg_gen_andc_tl(t1
, t2
, t1
);
19493 /* operands of same sign, result different sign */
19494 tcg_gen_setcondi_tl(TCG_COND_LT
, t0
, t1
, 0);
19495 gen_store_gpr(t0
, rd
);
19503 gen_r6_muldiv(ctx
, R6_OPC_MUL
, rd
, rs
, rt
);
19506 gen_r6_muldiv(ctx
, R6_OPC_MUH
, rd
, rs
, rt
);
19509 gen_r6_muldiv(ctx
, R6_OPC_MULU
, rd
, rs
, rt
);
19512 gen_r6_muldiv(ctx
, R6_OPC_MUHU
, rd
, rs
, rt
);
19515 gen_r6_muldiv(ctx
, R6_OPC_DIV
, rd
, rs
, rt
);
19518 gen_r6_muldiv(ctx
, R6_OPC_MOD
, rd
, rs
, rt
);
19521 gen_r6_muldiv(ctx
, R6_OPC_DIVU
, rd
, rs
, rt
);
19524 gen_r6_muldiv(ctx
, R6_OPC_MODU
, rd
, rs
, rt
);
19526 #ifndef CONFIG_USER_ONLY
19528 check_cp0_enabled(ctx
);
19530 /* Treat as NOP. */
19533 gen_mfc0(ctx
, cpu_gpr
[rt
], rs
, extract32(ctx
->opcode
, 11, 3));
19536 check_cp0_enabled(ctx
);
19538 TCGv t0
= tcg_temp_new();
19540 gen_load_gpr(t0
, rt
);
19541 gen_mtc0(ctx
, t0
, rs
, extract32(ctx
->opcode
, 11, 3));
19545 case NM_D_E_MT_VPE
:
19547 uint8_t sc
= extract32(ctx
->opcode
, 10, 1);
19548 TCGv t0
= tcg_temp_new();
19555 gen_helper_dmt(t0
);
19556 gen_store_gpr(t0
, rt
);
19557 } else if (rs
== 0) {
19560 gen_helper_dvpe(t0
, cpu_env
);
19561 gen_store_gpr(t0
, rt
);
19563 generate_exception_end(ctx
, EXCP_RI
);
19570 gen_helper_emt(t0
);
19571 gen_store_gpr(t0
, rt
);
19572 } else if (rs
== 0) {
19575 gen_helper_evpe(t0
, cpu_env
);
19576 gen_store_gpr(t0
, rt
);
19578 generate_exception_end(ctx
, EXCP_RI
);
19589 TCGv t0
= tcg_temp_new();
19590 TCGv t1
= tcg_temp_new();
19592 gen_load_gpr(t0
, rt
);
19593 gen_load_gpr(t1
, rs
);
19594 gen_helper_fork(t0
, t1
);
19601 check_cp0_enabled(ctx
);
19603 /* Treat as NOP. */
19606 gen_mftr(env
, ctx
, rs
, rt
, extract32(ctx
->opcode
, 10, 1),
19607 extract32(ctx
->opcode
, 11, 5), extract32(ctx
->opcode
, 3, 1));
19611 check_cp0_enabled(ctx
);
19612 gen_mttr(env
, ctx
, rs
, rt
, extract32(ctx
->opcode
, 10, 1),
19613 extract32(ctx
->opcode
, 11, 5), extract32(ctx
->opcode
, 3, 1));
19618 TCGv t0
= tcg_temp_new();
19620 gen_load_gpr(t0
, rs
);
19621 gen_helper_yield(t0
, cpu_env
, t0
);
19622 gen_store_gpr(t0
, rt
);
19628 generate_exception_end(ctx
, EXCP_RI
);
19634 static void gen_pool32axf_1_5_nanomips_insn(DisasContext
*ctx
, uint32_t opc
,
19635 int ret
, int v1
, int v2
)
19641 t0
= tcg_temp_new_i32();
19643 v0_t
= tcg_temp_new();
19644 v1_t
= tcg_temp_new();
19646 tcg_gen_movi_i32(t0
, v2
>> 3);
19648 gen_load_gpr(v0_t
, ret
);
19649 gen_load_gpr(v1_t
, v1
);
19652 case NM_MAQ_S_W_PHR
:
19654 gen_helper_maq_s_w_phr(t0
, v1_t
, v0_t
, cpu_env
);
19656 case NM_MAQ_S_W_PHL
:
19658 gen_helper_maq_s_w_phl(t0
, v1_t
, v0_t
, cpu_env
);
19660 case NM_MAQ_SA_W_PHR
:
19662 gen_helper_maq_sa_w_phr(t0
, v1_t
, v0_t
, cpu_env
);
19664 case NM_MAQ_SA_W_PHL
:
19666 gen_helper_maq_sa_w_phl(t0
, v1_t
, v0_t
, cpu_env
);
19669 generate_exception_end(ctx
, EXCP_RI
);
19673 tcg_temp_free_i32(t0
);
19675 tcg_temp_free(v0_t
);
19676 tcg_temp_free(v1_t
);
19680 static void gen_pool32axf_1_nanomips_insn(DisasContext
*ctx
, uint32_t opc
,
19681 int ret
, int v1
, int v2
)
19684 TCGv t0
= tcg_temp_new();
19685 TCGv t1
= tcg_temp_new();
19686 TCGv v0_t
= tcg_temp_new();
19688 gen_load_gpr(v0_t
, v1
);
19691 case NM_POOL32AXF_1_0
:
19693 switch (extract32(ctx
->opcode
, 12, 2)) {
19695 gen_HILO(ctx
, OPC_MFHI
, v2
>> 3, ret
);
19698 gen_HILO(ctx
, OPC_MFLO
, v2
>> 3, ret
);
19701 gen_HILO(ctx
, OPC_MTHI
, v2
>> 3, v1
);
19704 gen_HILO(ctx
, OPC_MTLO
, v2
>> 3, v1
);
19708 case NM_POOL32AXF_1_1
:
19710 switch (extract32(ctx
->opcode
, 12, 2)) {
19712 tcg_gen_movi_tl(t0
, v2
);
19713 gen_helper_mthlip(t0
, v0_t
, cpu_env
);
19716 tcg_gen_movi_tl(t0
, v2
>> 3);
19717 gen_helper_shilo(t0
, v0_t
, cpu_env
);
19720 generate_exception_end(ctx
, EXCP_RI
);
19724 case NM_POOL32AXF_1_3
:
19726 imm
= extract32(ctx
->opcode
, 14, 7);
19727 switch (extract32(ctx
->opcode
, 12, 2)) {
19729 tcg_gen_movi_tl(t0
, imm
);
19730 gen_helper_rddsp(t0
, t0
, cpu_env
);
19731 gen_store_gpr(t0
, ret
);
19734 gen_load_gpr(t0
, ret
);
19735 tcg_gen_movi_tl(t1
, imm
);
19736 gen_helper_wrdsp(t0
, t1
, cpu_env
);
19739 tcg_gen_movi_tl(t0
, v2
>> 3);
19740 tcg_gen_movi_tl(t1
, v1
);
19741 gen_helper_extp(t0
, t0
, t1
, cpu_env
);
19742 gen_store_gpr(t0
, ret
);
19745 tcg_gen_movi_tl(t0
, v2
>> 3);
19746 tcg_gen_movi_tl(t1
, v1
);
19747 gen_helper_extpdp(t0
, t0
, t1
, cpu_env
);
19748 gen_store_gpr(t0
, ret
);
19752 case NM_POOL32AXF_1_4
:
19754 tcg_gen_movi_tl(t0
, v2
>> 2);
19755 switch (extract32(ctx
->opcode
, 12, 1)) {
19757 gen_helper_shll_qb(t0
, t0
, v0_t
, cpu_env
);
19758 gen_store_gpr(t0
, ret
);
19761 gen_helper_shrl_qb(t0
, t0
, v0_t
);
19762 gen_store_gpr(t0
, ret
);
19766 case NM_POOL32AXF_1_5
:
19767 opc
= extract32(ctx
->opcode
, 12, 2);
19768 gen_pool32axf_1_5_nanomips_insn(ctx
, opc
, ret
, v1
, v2
);
19770 case NM_POOL32AXF_1_7
:
19772 tcg_gen_movi_tl(t0
, v2
>> 3);
19773 tcg_gen_movi_tl(t1
, v1
);
19774 switch (extract32(ctx
->opcode
, 12, 2)) {
19776 gen_helper_extr_w(t0
, t0
, t1
, cpu_env
);
19777 gen_store_gpr(t0
, ret
);
19780 gen_helper_extr_r_w(t0
, t0
, t1
, cpu_env
);
19781 gen_store_gpr(t0
, ret
);
19784 gen_helper_extr_rs_w(t0
, t0
, t1
, cpu_env
);
19785 gen_store_gpr(t0
, ret
);
19788 gen_helper_extr_s_h(t0
, t0
, t1
, cpu_env
);
19789 gen_store_gpr(t0
, ret
);
19794 generate_exception_end(ctx
, EXCP_RI
);
19800 tcg_temp_free(v0_t
);
19803 static void gen_pool32axf_2_multiply(DisasContext
*ctx
, uint32_t opc
,
19804 TCGv v0
, TCGv v1
, int rd
)
19808 t0
= tcg_temp_new_i32();
19810 tcg_gen_movi_i32(t0
, rd
>> 3);
19813 case NM_POOL32AXF_2_0_7
:
19814 switch (extract32(ctx
->opcode
, 9, 3)) {
19817 gen_helper_dpa_w_ph(t0
, v1
, v0
, cpu_env
);
19819 case NM_DPAQ_S_W_PH
:
19821 gen_helper_dpaq_s_w_ph(t0
, v1
, v0
, cpu_env
);
19825 gen_helper_dps_w_ph(t0
, v1
, v0
, cpu_env
);
19827 case NM_DPSQ_S_W_PH
:
19829 gen_helper_dpsq_s_w_ph(t0
, v1
, v0
, cpu_env
);
19832 generate_exception_end(ctx
, EXCP_RI
);
19836 case NM_POOL32AXF_2_8_15
:
19837 switch (extract32(ctx
->opcode
, 9, 3)) {
19840 gen_helper_dpax_w_ph(t0
, v0
, v1
, cpu_env
);
19842 case NM_DPAQ_SA_L_W
:
19844 gen_helper_dpaq_sa_l_w(t0
, v0
, v1
, cpu_env
);
19848 gen_helper_dpsx_w_ph(t0
, v0
, v1
, cpu_env
);
19850 case NM_DPSQ_SA_L_W
:
19852 gen_helper_dpsq_sa_l_w(t0
, v0
, v1
, cpu_env
);
19855 generate_exception_end(ctx
, EXCP_RI
);
19859 case NM_POOL32AXF_2_16_23
:
19860 switch (extract32(ctx
->opcode
, 9, 3)) {
19861 case NM_DPAU_H_QBL
:
19863 gen_helper_dpau_h_qbl(t0
, v0
, v1
, cpu_env
);
19865 case NM_DPAQX_S_W_PH
:
19867 gen_helper_dpaqx_s_w_ph(t0
, v0
, v1
, cpu_env
);
19869 case NM_DPSU_H_QBL
:
19871 gen_helper_dpsu_h_qbl(t0
, v0
, v1
, cpu_env
);
19873 case NM_DPSQX_S_W_PH
:
19875 gen_helper_dpsqx_s_w_ph(t0
, v0
, v1
, cpu_env
);
19877 case NM_MULSA_W_PH
:
19879 gen_helper_mulsa_w_ph(t0
, v0
, v1
, cpu_env
);
19882 generate_exception_end(ctx
, EXCP_RI
);
19886 case NM_POOL32AXF_2_24_31
:
19887 switch (extract32(ctx
->opcode
, 9, 3)) {
19888 case NM_DPAU_H_QBR
:
19890 gen_helper_dpau_h_qbr(t0
, v1
, v0
, cpu_env
);
19892 case NM_DPAQX_SA_W_PH
:
19894 gen_helper_dpaqx_sa_w_ph(t0
, v1
, v0
, cpu_env
);
19896 case NM_DPSU_H_QBR
:
19898 gen_helper_dpsu_h_qbr(t0
, v1
, v0
, cpu_env
);
19900 case NM_DPSQX_SA_W_PH
:
19902 gen_helper_dpsqx_sa_w_ph(t0
, v1
, v0
, cpu_env
);
19904 case NM_MULSAQ_S_W_PH
:
19906 gen_helper_mulsaq_s_w_ph(t0
, v1
, v0
, cpu_env
);
19909 generate_exception_end(ctx
, EXCP_RI
);
19914 generate_exception_end(ctx
, EXCP_RI
);
19918 tcg_temp_free_i32(t0
);
19921 static void gen_pool32axf_2_nanomips_insn(DisasContext
*ctx
, uint32_t opc
,
19922 int rt
, int rs
, int rd
)
19925 TCGv t0
= tcg_temp_new();
19926 TCGv t1
= tcg_temp_new();
19927 TCGv v0_t
= tcg_temp_new();
19928 TCGv v1_t
= tcg_temp_new();
19930 gen_load_gpr(v0_t
, rt
);
19931 gen_load_gpr(v1_t
, rs
);
19934 case NM_POOL32AXF_2_0_7
:
19935 switch (extract32(ctx
->opcode
, 9, 3)) {
19937 case NM_DPAQ_S_W_PH
:
19939 case NM_DPSQ_S_W_PH
:
19940 gen_pool32axf_2_multiply(ctx
, opc
, v0_t
, v1_t
, rd
);
19945 gen_load_gpr(t0
, rs
);
19947 if (rd
!= 0 && rd
!= 2) {
19948 tcg_gen_shli_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], 8 * rd
);
19949 tcg_gen_ext32u_tl(t0
, t0
);
19950 tcg_gen_shri_tl(t0
, t0
, 8 * (4 - rd
));
19951 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
19953 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
19959 int acc
= extract32(ctx
->opcode
, 14, 2);
19960 TCGv_i64 t2
= tcg_temp_new_i64();
19961 TCGv_i64 t3
= tcg_temp_new_i64();
19963 gen_load_gpr(t0
, rt
);
19964 gen_load_gpr(t1
, rs
);
19965 tcg_gen_ext_tl_i64(t2
, t0
);
19966 tcg_gen_ext_tl_i64(t3
, t1
);
19967 tcg_gen_mul_i64(t2
, t2
, t3
);
19968 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
19969 tcg_gen_add_i64(t2
, t2
, t3
);
19970 tcg_temp_free_i64(t3
);
19971 gen_move_low32(cpu_LO
[acc
], t2
);
19972 gen_move_high32(cpu_HI
[acc
], t2
);
19973 tcg_temp_free_i64(t2
);
19979 int acc
= extract32(ctx
->opcode
, 14, 2);
19980 TCGv_i32 t2
= tcg_temp_new_i32();
19981 TCGv_i32 t3
= tcg_temp_new_i32();
19983 gen_load_gpr(t0
, rs
);
19984 gen_load_gpr(t1
, rt
);
19985 tcg_gen_trunc_tl_i32(t2
, t0
);
19986 tcg_gen_trunc_tl_i32(t3
, t1
);
19987 tcg_gen_muls2_i32(t2
, t3
, t2
, t3
);
19988 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
19989 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
19990 tcg_temp_free_i32(t2
);
19991 tcg_temp_free_i32(t3
);
19996 gen_load_gpr(v1_t
, rs
);
19997 tcg_gen_movi_tl(t0
, rd
>> 3);
19998 gen_helper_extr_w(t0
, t0
, v1_t
, cpu_env
);
19999 gen_store_gpr(t0
, ret
);
20003 case NM_POOL32AXF_2_8_15
:
20004 switch (extract32(ctx
->opcode
, 9, 3)) {
20006 case NM_DPAQ_SA_L_W
:
20008 case NM_DPSQ_SA_L_W
:
20009 gen_pool32axf_2_multiply(ctx
, opc
, v0_t
, v1_t
, rd
);
20014 int acc
= extract32(ctx
->opcode
, 14, 2);
20015 TCGv_i64 t2
= tcg_temp_new_i64();
20016 TCGv_i64 t3
= tcg_temp_new_i64();
20018 gen_load_gpr(t0
, rs
);
20019 gen_load_gpr(t1
, rt
);
20020 tcg_gen_ext32u_tl(t0
, t0
);
20021 tcg_gen_ext32u_tl(t1
, t1
);
20022 tcg_gen_extu_tl_i64(t2
, t0
);
20023 tcg_gen_extu_tl_i64(t3
, t1
);
20024 tcg_gen_mul_i64(t2
, t2
, t3
);
20025 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
20026 tcg_gen_add_i64(t2
, t2
, t3
);
20027 tcg_temp_free_i64(t3
);
20028 gen_move_low32(cpu_LO
[acc
], t2
);
20029 gen_move_high32(cpu_HI
[acc
], t2
);
20030 tcg_temp_free_i64(t2
);
20036 int acc
= extract32(ctx
->opcode
, 14, 2);
20037 TCGv_i32 t2
= tcg_temp_new_i32();
20038 TCGv_i32 t3
= tcg_temp_new_i32();
20040 gen_load_gpr(t0
, rs
);
20041 gen_load_gpr(t1
, rt
);
20042 tcg_gen_trunc_tl_i32(t2
, t0
);
20043 tcg_gen_trunc_tl_i32(t3
, t1
);
20044 tcg_gen_mulu2_i32(t2
, t3
, t2
, t3
);
20045 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
20046 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
20047 tcg_temp_free_i32(t2
);
20048 tcg_temp_free_i32(t3
);
20053 tcg_gen_movi_tl(t0
, rd
>> 3);
20054 gen_helper_extr_r_w(t0
, t0
, v1_t
, cpu_env
);
20055 gen_store_gpr(t0
, ret
);
20058 generate_exception_end(ctx
, EXCP_RI
);
20062 case NM_POOL32AXF_2_16_23
:
20063 switch (extract32(ctx
->opcode
, 9, 3)) {
20064 case NM_DPAU_H_QBL
:
20065 case NM_DPAQX_S_W_PH
:
20066 case NM_DPSU_H_QBL
:
20067 case NM_DPSQX_S_W_PH
:
20068 case NM_MULSA_W_PH
:
20069 gen_pool32axf_2_multiply(ctx
, opc
, v0_t
, v1_t
, rd
);
20073 tcg_gen_movi_tl(t0
, rd
>> 3);
20074 gen_helper_extp(t0
, t0
, v1_t
, cpu_env
);
20075 gen_store_gpr(t0
, ret
);
20080 int acc
= extract32(ctx
->opcode
, 14, 2);
20081 TCGv_i64 t2
= tcg_temp_new_i64();
20082 TCGv_i64 t3
= tcg_temp_new_i64();
20084 gen_load_gpr(t0
, rs
);
20085 gen_load_gpr(t1
, rt
);
20086 tcg_gen_ext_tl_i64(t2
, t0
);
20087 tcg_gen_ext_tl_i64(t3
, t1
);
20088 tcg_gen_mul_i64(t2
, t2
, t3
);
20089 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
20090 tcg_gen_sub_i64(t2
, t3
, t2
);
20091 tcg_temp_free_i64(t3
);
20092 gen_move_low32(cpu_LO
[acc
], t2
);
20093 gen_move_high32(cpu_HI
[acc
], t2
);
20094 tcg_temp_free_i64(t2
);
20097 case NM_EXTRV_RS_W
:
20099 tcg_gen_movi_tl(t0
, rd
>> 3);
20100 gen_helper_extr_rs_w(t0
, t0
, v1_t
, cpu_env
);
20101 gen_store_gpr(t0
, ret
);
20105 case NM_POOL32AXF_2_24_31
:
20106 switch (extract32(ctx
->opcode
, 9, 3)) {
20107 case NM_DPAU_H_QBR
:
20108 case NM_DPAQX_SA_W_PH
:
20109 case NM_DPSU_H_QBR
:
20110 case NM_DPSQX_SA_W_PH
:
20111 case NM_MULSAQ_S_W_PH
:
20112 gen_pool32axf_2_multiply(ctx
, opc
, v0_t
, v1_t
, rd
);
20116 tcg_gen_movi_tl(t0
, rd
>> 3);
20117 gen_helper_extpdp(t0
, t0
, v1_t
, cpu_env
);
20118 gen_store_gpr(t0
, ret
);
20123 int acc
= extract32(ctx
->opcode
, 14, 2);
20124 TCGv_i64 t2
= tcg_temp_new_i64();
20125 TCGv_i64 t3
= tcg_temp_new_i64();
20127 gen_load_gpr(t0
, rs
);
20128 gen_load_gpr(t1
, rt
);
20129 tcg_gen_ext32u_tl(t0
, t0
);
20130 tcg_gen_ext32u_tl(t1
, t1
);
20131 tcg_gen_extu_tl_i64(t2
, t0
);
20132 tcg_gen_extu_tl_i64(t3
, t1
);
20133 tcg_gen_mul_i64(t2
, t2
, t3
);
20134 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
20135 tcg_gen_sub_i64(t2
, t3
, t2
);
20136 tcg_temp_free_i64(t3
);
20137 gen_move_low32(cpu_LO
[acc
], t2
);
20138 gen_move_high32(cpu_HI
[acc
], t2
);
20139 tcg_temp_free_i64(t2
);
20144 tcg_gen_movi_tl(t0
, rd
>> 3);
20145 gen_helper_extr_s_h(t0
, t0
, v0_t
, cpu_env
);
20146 gen_store_gpr(t0
, ret
);
20151 generate_exception_end(ctx
, EXCP_RI
);
20158 tcg_temp_free(v0_t
);
20159 tcg_temp_free(v1_t
);
20162 static void gen_pool32axf_4_nanomips_insn(DisasContext
*ctx
, uint32_t opc
,
20166 TCGv t0
= tcg_temp_new();
20167 TCGv v0_t
= tcg_temp_new();
20169 gen_load_gpr(v0_t
, rs
);
20174 gen_helper_absq_s_qb(v0_t
, v0_t
, cpu_env
);
20175 gen_store_gpr(v0_t
, ret
);
20179 gen_helper_absq_s_ph(v0_t
, v0_t
, cpu_env
);
20180 gen_store_gpr(v0_t
, ret
);
20184 gen_helper_absq_s_w(v0_t
, v0_t
, cpu_env
);
20185 gen_store_gpr(v0_t
, ret
);
20187 case NM_PRECEQ_W_PHL
:
20189 tcg_gen_andi_tl(v0_t
, v0_t
, 0xFFFF0000);
20190 tcg_gen_ext32s_tl(v0_t
, v0_t
);
20191 gen_store_gpr(v0_t
, ret
);
20193 case NM_PRECEQ_W_PHR
:
20195 tcg_gen_andi_tl(v0_t
, v0_t
, 0x0000FFFF);
20196 tcg_gen_shli_tl(v0_t
, v0_t
, 16);
20197 tcg_gen_ext32s_tl(v0_t
, v0_t
);
20198 gen_store_gpr(v0_t
, ret
);
20200 case NM_PRECEQU_PH_QBL
:
20202 gen_helper_precequ_ph_qbl(v0_t
, v0_t
);
20203 gen_store_gpr(v0_t
, ret
);
20205 case NM_PRECEQU_PH_QBR
:
20207 gen_helper_precequ_ph_qbr(v0_t
, v0_t
);
20208 gen_store_gpr(v0_t
, ret
);
20210 case NM_PRECEQU_PH_QBLA
:
20212 gen_helper_precequ_ph_qbla(v0_t
, v0_t
);
20213 gen_store_gpr(v0_t
, ret
);
20215 case NM_PRECEQU_PH_QBRA
:
20217 gen_helper_precequ_ph_qbra(v0_t
, v0_t
);
20218 gen_store_gpr(v0_t
, ret
);
20220 case NM_PRECEU_PH_QBL
:
20222 gen_helper_preceu_ph_qbl(v0_t
, v0_t
);
20223 gen_store_gpr(v0_t
, ret
);
20225 case NM_PRECEU_PH_QBR
:
20227 gen_helper_preceu_ph_qbr(v0_t
, v0_t
);
20228 gen_store_gpr(v0_t
, ret
);
20230 case NM_PRECEU_PH_QBLA
:
20232 gen_helper_preceu_ph_qbla(v0_t
, v0_t
);
20233 gen_store_gpr(v0_t
, ret
);
20235 case NM_PRECEU_PH_QBRA
:
20237 gen_helper_preceu_ph_qbra(v0_t
, v0_t
);
20238 gen_store_gpr(v0_t
, ret
);
20242 tcg_gen_ext16u_tl(v0_t
, v0_t
);
20243 tcg_gen_shli_tl(t0
, v0_t
, 16);
20244 tcg_gen_or_tl(v0_t
, v0_t
, t0
);
20245 tcg_gen_ext32s_tl(v0_t
, v0_t
);
20246 gen_store_gpr(v0_t
, ret
);
20250 tcg_gen_ext8u_tl(v0_t
, v0_t
);
20251 tcg_gen_shli_tl(t0
, v0_t
, 8);
20252 tcg_gen_or_tl(v0_t
, v0_t
, t0
);
20253 tcg_gen_shli_tl(t0
, v0_t
, 16);
20254 tcg_gen_or_tl(v0_t
, v0_t
, t0
);
20255 tcg_gen_ext32s_tl(v0_t
, v0_t
);
20256 gen_store_gpr(v0_t
, ret
);
20260 gen_helper_bitrev(v0_t
, v0_t
);
20261 gen_store_gpr(v0_t
, ret
);
20266 TCGv tv0
= tcg_temp_new();
20268 gen_load_gpr(tv0
, rt
);
20269 gen_helper_insv(v0_t
, cpu_env
, v0_t
, tv0
);
20270 gen_store_gpr(v0_t
, ret
);
20271 tcg_temp_free(tv0
);
20274 case NM_RADDU_W_QB
:
20276 gen_helper_raddu_w_qb(v0_t
, v0_t
);
20277 gen_store_gpr(v0_t
, ret
);
20280 gen_bitswap(ctx
, OPC_BITSWAP
, ret
, rs
);
20284 gen_cl(ctx
, OPC_CLO
, ret
, rs
);
20288 gen_cl(ctx
, OPC_CLZ
, ret
, rs
);
20291 gen_bshfl(ctx
, OPC_WSBH
, ret
, rs
);
20294 generate_exception_end(ctx
, EXCP_RI
);
20298 tcg_temp_free(v0_t
);
20302 static void gen_pool32axf_7_nanomips_insn(DisasContext
*ctx
, uint32_t opc
,
20303 int rt
, int rs
, int rd
)
20305 TCGv t0
= tcg_temp_new();
20306 TCGv rs_t
= tcg_temp_new();
20308 gen_load_gpr(rs_t
, rs
);
20313 tcg_gen_movi_tl(t0
, rd
>> 2);
20314 switch (extract32(ctx
->opcode
, 12, 1)) {
20317 gen_helper_shra_qb(t0
, t0
, rs_t
);
20318 gen_store_gpr(t0
, rt
);
20322 gen_helper_shra_r_qb(t0
, t0
, rs_t
);
20323 gen_store_gpr(t0
, rt
);
20329 tcg_gen_movi_tl(t0
, rd
>> 1);
20330 gen_helper_shrl_ph(t0
, t0
, rs_t
);
20331 gen_store_gpr(t0
, rt
);
20337 target_long result
;
20338 imm
= extract32(ctx
->opcode
, 13, 8);
20339 result
= (uint32_t)imm
<< 24 |
20340 (uint32_t)imm
<< 16 |
20341 (uint32_t)imm
<< 8 |
20343 result
= (int32_t)result
;
20344 tcg_gen_movi_tl(t0
, result
);
20345 gen_store_gpr(t0
, rt
);
20349 generate_exception_end(ctx
, EXCP_RI
);
20353 tcg_temp_free(rs_t
);
20357 static void gen_pool32axf_nanomips_insn(CPUMIPSState
*env
, DisasContext
*ctx
)
20359 int rt
= extract32(ctx
->opcode
, 21, 5);
20360 int rs
= extract32(ctx
->opcode
, 16, 5);
20361 int rd
= extract32(ctx
->opcode
, 11, 5);
20363 switch (extract32(ctx
->opcode
, 6, 3)) {
20364 case NM_POOL32AXF_1
:
20366 int32_t op1
= extract32(ctx
->opcode
, 9, 3);
20367 gen_pool32axf_1_nanomips_insn(ctx
, op1
, rt
, rs
, rd
);
20370 case NM_POOL32AXF_2
:
20372 int32_t op1
= extract32(ctx
->opcode
, 12, 2);
20373 gen_pool32axf_2_nanomips_insn(ctx
, op1
, rt
, rs
, rd
);
20376 case NM_POOL32AXF_4
:
20378 int32_t op1
= extract32(ctx
->opcode
, 9, 7);
20379 gen_pool32axf_4_nanomips_insn(ctx
, op1
, rt
, rs
);
20382 case NM_POOL32AXF_5
:
20383 switch (extract32(ctx
->opcode
, 9, 7)) {
20384 #ifndef CONFIG_USER_ONLY
20386 gen_cp0(env
, ctx
, OPC_TLBP
, 0, 0);
20389 gen_cp0(env
, ctx
, OPC_TLBR
, 0, 0);
20392 gen_cp0(env
, ctx
, OPC_TLBWI
, 0, 0);
20395 gen_cp0(env
, ctx
, OPC_TLBWR
, 0, 0);
20398 gen_cp0(env
, ctx
, OPC_TLBINV
, 0, 0);
20401 gen_cp0(env
, ctx
, OPC_TLBINVF
, 0, 0);
20404 check_cp0_enabled(ctx
);
20406 TCGv t0
= tcg_temp_new();
20408 save_cpu_state(ctx
, 1);
20409 gen_helper_di(t0
, cpu_env
);
20410 gen_store_gpr(t0
, rt
);
20411 /* Stop translation as we may have switched the execution mode */
20412 ctx
->base
.is_jmp
= DISAS_STOP
;
20417 check_cp0_enabled(ctx
);
20419 TCGv t0
= tcg_temp_new();
20421 save_cpu_state(ctx
, 1);
20422 gen_helper_ei(t0
, cpu_env
);
20423 gen_store_gpr(t0
, rt
);
20424 /* Stop translation as we may have switched the execution mode */
20425 ctx
->base
.is_jmp
= DISAS_STOP
;
20430 gen_load_srsgpr(rs
, rt
);
20433 gen_store_srsgpr(rs
, rt
);
20436 gen_cp0(env
, ctx
, OPC_WAIT
, 0, 0);
20439 gen_cp0(env
, ctx
, OPC_DERET
, 0, 0);
20442 gen_cp0(env
, ctx
, OPC_ERET
, 0, 0);
20446 generate_exception_end(ctx
, EXCP_RI
);
20450 case NM_POOL32AXF_7
:
20452 int32_t op1
= extract32(ctx
->opcode
, 9, 3);
20453 gen_pool32axf_7_nanomips_insn(ctx
, op1
, rt
, rs
, rd
);
20457 generate_exception_end(ctx
, EXCP_RI
);
20462 /* Immediate Value Compact Branches */
20463 static void gen_compute_imm_branch(DisasContext
*ctx
, uint32_t opc
,
20464 int rt
, int32_t imm
, int32_t offset
)
20466 TCGCond cond
= TCG_COND_ALWAYS
;
20467 TCGv t0
= tcg_temp_new();
20468 TCGv t1
= tcg_temp_new();
20470 gen_load_gpr(t0
, rt
);
20471 tcg_gen_movi_tl(t1
, imm
);
20472 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
20474 /* Load needed operands and calculate btarget */
20477 if (rt
== 0 && imm
== 0) {
20478 /* Unconditional branch */
20479 } else if (rt
== 0 && imm
!= 0) {
20483 cond
= TCG_COND_EQ
;
20489 if (imm
>= 32 && !(ctx
->hflags
& MIPS_HFLAG_64
)) {
20490 generate_exception_end(ctx
, EXCP_RI
);
20492 } else if (rt
== 0 && opc
== NM_BBEQZC
) {
20493 /* Unconditional branch */
20494 } else if (rt
== 0 && opc
== NM_BBNEZC
) {
20498 tcg_gen_shri_tl(t0
, t0
, imm
);
20499 tcg_gen_andi_tl(t0
, t0
, 1);
20500 tcg_gen_movi_tl(t1
, 0);
20501 if (opc
== NM_BBEQZC
) {
20502 cond
= TCG_COND_EQ
;
20504 cond
= TCG_COND_NE
;
20509 if (rt
== 0 && imm
== 0) {
20512 } else if (rt
== 0 && imm
!= 0) {
20513 /* Unconditional branch */
20515 cond
= TCG_COND_NE
;
20519 if (rt
== 0 && imm
== 0) {
20520 /* Unconditional branch */
20522 cond
= TCG_COND_GE
;
20526 cond
= TCG_COND_LT
;
20529 if (rt
== 0 && imm
== 0) {
20530 /* Unconditional branch */
20532 cond
= TCG_COND_GEU
;
20536 cond
= TCG_COND_LTU
;
20539 MIPS_INVAL("Immediate Value Compact branch");
20540 generate_exception_end(ctx
, EXCP_RI
);
20544 /* branch completion */
20545 clear_branch_hflags(ctx
);
20546 ctx
->base
.is_jmp
= DISAS_NORETURN
;
20548 if (cond
== TCG_COND_ALWAYS
) {
20549 /* Uncoditional compact branch */
20550 gen_goto_tb(ctx
, 0, ctx
->btarget
);
20552 /* Conditional compact branch */
20553 TCGLabel
*fs
= gen_new_label();
20555 tcg_gen_brcond_tl(tcg_invert_cond(cond
), t0
, t1
, fs
);
20557 gen_goto_tb(ctx
, 1, ctx
->btarget
);
20560 gen_goto_tb(ctx
, 0, ctx
->base
.pc_next
+ 4);
20568 /* P.BALRSC type nanoMIPS R6 branches: BALRSC and BRSC */
20569 static void gen_compute_nanomips_pbalrsc_branch(DisasContext
*ctx
, int rs
,
20572 TCGv t0
= tcg_temp_new();
20573 TCGv t1
= tcg_temp_new();
20576 gen_load_gpr(t0
, rs
);
20580 tcg_gen_movi_tl(cpu_gpr
[rt
], ctx
->base
.pc_next
+ 4);
20583 /* calculate btarget */
20584 tcg_gen_shli_tl(t0
, t0
, 1);
20585 tcg_gen_movi_tl(t1
, ctx
->base
.pc_next
+ 4);
20586 gen_op_addr_add(ctx
, btarget
, t1
, t0
);
20588 /* branch completion */
20589 clear_branch_hflags(ctx
);
20590 ctx
->base
.is_jmp
= DISAS_NORETURN
;
20592 /* unconditional branch to register */
20593 tcg_gen_mov_tl(cpu_PC
, btarget
);
20594 tcg_gen_lookup_and_goto_ptr();
20600 /* nanoMIPS Branches */
20601 static void gen_compute_compact_branch_nm(DisasContext
*ctx
, uint32_t opc
,
20602 int rs
, int rt
, int32_t offset
)
20604 int bcond_compute
= 0;
20605 TCGv t0
= tcg_temp_new();
20606 TCGv t1
= tcg_temp_new();
20608 /* Load needed operands and calculate btarget */
20610 /* compact branch */
20613 gen_load_gpr(t0
, rs
);
20614 gen_load_gpr(t1
, rt
);
20616 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
20620 if (rs
== 0 || rs
== rt
) {
20621 /* OPC_BLEZALC, OPC_BGEZALC */
20622 /* OPC_BGTZALC, OPC_BLTZALC */
20623 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 4);
20625 gen_load_gpr(t0
, rs
);
20626 gen_load_gpr(t1
, rt
);
20628 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
20631 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
20635 /* OPC_BEQZC, OPC_BNEZC */
20636 gen_load_gpr(t0
, rs
);
20638 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
20640 /* OPC_JIC, OPC_JIALC */
20641 TCGv tbase
= tcg_temp_new();
20642 TCGv toffset
= tcg_temp_new();
20644 gen_load_gpr(tbase
, rt
);
20645 tcg_gen_movi_tl(toffset
, offset
);
20646 gen_op_addr_add(ctx
, btarget
, tbase
, toffset
);
20647 tcg_temp_free(tbase
);
20648 tcg_temp_free(toffset
);
20652 MIPS_INVAL("Compact branch/jump");
20653 generate_exception_end(ctx
, EXCP_RI
);
20657 if (bcond_compute
== 0) {
20658 /* Uncoditional compact branch */
20661 gen_goto_tb(ctx
, 0, ctx
->btarget
);
20664 MIPS_INVAL("Compact branch/jump");
20665 generate_exception_end(ctx
, EXCP_RI
);
20669 /* Conditional compact branch */
20670 TCGLabel
*fs
= gen_new_label();
20674 if (rs
== 0 && rt
!= 0) {
20676 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE
), t1
, 0, fs
);
20677 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
20679 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE
), t1
, 0, fs
);
20682 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU
), t0
, t1
, fs
);
20686 if (rs
== 0 && rt
!= 0) {
20688 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT
), t1
, 0, fs
);
20689 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
20691 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT
), t1
, 0, fs
);
20694 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU
), t0
, t1
, fs
);
20698 if (rs
== 0 && rt
!= 0) {
20700 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE
), t1
, 0, fs
);
20701 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
20703 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE
), t1
, 0, fs
);
20706 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE
), t0
, t1
, fs
);
20710 if (rs
== 0 && rt
!= 0) {
20712 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT
), t1
, 0, fs
);
20713 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
20715 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT
), t1
, 0, fs
);
20718 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT
), t0
, t1
, fs
);
20722 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ
), t0
, 0, fs
);
20725 MIPS_INVAL("Compact conditional branch/jump");
20726 generate_exception_end(ctx
, EXCP_RI
);
20730 /* branch completion */
20731 clear_branch_hflags(ctx
);
20732 ctx
->base
.is_jmp
= DISAS_NORETURN
;
20734 /* Generating branch here as compact branches don't have delay slot */
20735 gen_goto_tb(ctx
, 1, ctx
->btarget
);
20738 gen_goto_tb(ctx
, 0, ctx
->base
.pc_next
+ 4);
20747 /* nanoMIPS CP1 Branches */
20748 static void gen_compute_branch_cp1_nm(DisasContext
*ctx
, uint32_t op
,
20749 int32_t ft
, int32_t offset
)
20751 target_ulong btarget
;
20752 TCGv_i64 t0
= tcg_temp_new_i64();
20754 gen_load_fpr64(ctx
, t0
, ft
);
20755 tcg_gen_andi_i64(t0
, t0
, 1);
20757 btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
20761 tcg_gen_xori_i64(t0
, t0
, 1);
20762 ctx
->hflags
|= MIPS_HFLAG_BC
;
20765 /* t0 already set */
20766 ctx
->hflags
|= MIPS_HFLAG_BC
;
20769 MIPS_INVAL("cp1 cond branch");
20770 generate_exception_end(ctx
, EXCP_RI
);
20774 tcg_gen_trunc_i64_tl(bcond
, t0
);
20776 ctx
->btarget
= btarget
;
20779 tcg_temp_free_i64(t0
);
20783 static void gen_p_lsx(DisasContext
*ctx
, int rd
, int rs
, int rt
)
20786 t0
= tcg_temp_new();
20787 t1
= tcg_temp_new();
20789 gen_load_gpr(t0
, rs
);
20790 gen_load_gpr(t1
, rt
);
20792 if ((extract32(ctx
->opcode
, 6, 1)) == 1) {
20793 /* PP.LSXS instructions require shifting */
20794 switch (extract32(ctx
->opcode
, 7, 4)) {
20800 tcg_gen_shli_tl(t0
, t0
, 1);
20808 tcg_gen_shli_tl(t0
, t0
, 2);
20812 tcg_gen_shli_tl(t0
, t0
, 3);
20816 gen_op_addr_add(ctx
, t0
, t0
, t1
);
20818 switch (extract32(ctx
->opcode
, 7, 4)) {
20820 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
,
20822 gen_store_gpr(t0
, rd
);
20826 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
,
20828 gen_store_gpr(t0
, rd
);
20832 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
,
20834 gen_store_gpr(t0
, rd
);
20837 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
,
20839 gen_store_gpr(t0
, rd
);
20843 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
,
20845 gen_store_gpr(t0
, rd
);
20849 gen_load_gpr(t1
, rd
);
20850 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
,
20856 gen_load_gpr(t1
, rd
);
20857 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
,
20863 gen_load_gpr(t1
, rd
);
20864 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
,
20868 /*case NM_LWC1XS:*/
20870 /*case NM_LDC1XS:*/
20872 /*case NM_SWC1XS:*/
20874 /*case NM_SDC1XS:*/
20875 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
20876 check_cp1_enabled(ctx
);
20877 switch (extract32(ctx
->opcode
, 7, 4)) {
20879 /*case NM_LWC1XS:*/
20880 gen_flt_ldst(ctx
, OPC_LWC1
, rd
, t0
);
20883 /*case NM_LDC1XS:*/
20884 gen_flt_ldst(ctx
, OPC_LDC1
, rd
, t0
);
20887 /*case NM_SWC1XS:*/
20888 gen_flt_ldst(ctx
, OPC_SWC1
, rd
, t0
);
20891 /*case NM_SDC1XS:*/
20892 gen_flt_ldst(ctx
, OPC_SDC1
, rd
, t0
);
20896 generate_exception_err(ctx
, EXCP_CpU
, 1);
20900 generate_exception_end(ctx
, EXCP_RI
);
20908 static void gen_pool32f_nanomips_insn(DisasContext
*ctx
)
20912 rt
= extract32(ctx
->opcode
, 21, 5);
20913 rs
= extract32(ctx
->opcode
, 16, 5);
20914 rd
= extract32(ctx
->opcode
, 11, 5);
20916 if (!(ctx
->CP0_Config1
& (1 << CP0C1_FP
))) {
20917 generate_exception_end(ctx
, EXCP_RI
);
20920 check_cp1_enabled(ctx
);
20921 switch (extract32(ctx
->opcode
, 0, 3)) {
20923 switch (extract32(ctx
->opcode
, 3, 7)) {
20925 gen_farith(ctx
, OPC_RINT_S
, 0, rt
, rs
, 0);
20928 gen_farith(ctx
, OPC_RINT_D
, 0, rt
, rs
, 0);
20931 gen_farith(ctx
, OPC_CLASS_S
, 0, rt
, rs
, 0);
20934 gen_farith(ctx
, OPC_CLASS_D
, 0, rt
, rs
, 0);
20937 gen_farith(ctx
, OPC_ADD_S
, rt
, rs
, rd
, 0);
20940 gen_farith(ctx
, OPC_ADD_D
, rt
, rs
, rd
, 0);
20943 gen_farith(ctx
, OPC_SUB_S
, rt
, rs
, rd
, 0);
20946 gen_farith(ctx
, OPC_SUB_D
, rt
, rs
, rd
, 0);
20949 gen_farith(ctx
, OPC_MUL_S
, rt
, rs
, rd
, 0);
20952 gen_farith(ctx
, OPC_MUL_D
, rt
, rs
, rd
, 0);
20955 gen_farith(ctx
, OPC_DIV_S
, rt
, rs
, rd
, 0);
20958 gen_farith(ctx
, OPC_DIV_D
, rt
, rs
, rd
, 0);
20961 gen_sel_s(ctx
, OPC_SELEQZ_S
, rd
, rt
, rs
);
20964 gen_sel_d(ctx
, OPC_SELEQZ_D
, rd
, rt
, rs
);
20967 gen_sel_s(ctx
, OPC_SELNEZ_S
, rd
, rt
, rs
);
20970 gen_sel_d(ctx
, OPC_SELNEZ_D
, rd
, rt
, rs
);
20973 gen_sel_s(ctx
, OPC_SEL_S
, rd
, rt
, rs
);
20976 gen_sel_d(ctx
, OPC_SEL_D
, rd
, rt
, rs
);
20979 gen_farith(ctx
, OPC_MADDF_S
, rt
, rs
, rd
, 0);
20982 gen_farith(ctx
, OPC_MADDF_D
, rt
, rs
, rd
, 0);
20985 gen_farith(ctx
, OPC_MSUBF_S
, rt
, rs
, rd
, 0);
20988 gen_farith(ctx
, OPC_MSUBF_D
, rt
, rs
, rd
, 0);
20991 generate_exception_end(ctx
, EXCP_RI
);
20996 switch (extract32(ctx
->opcode
, 3, 3)) {
20998 switch (extract32(ctx
->opcode
, 9, 1)) {
21000 gen_farith(ctx
, OPC_MIN_S
, rt
, rs
, rd
, 0);
21003 gen_farith(ctx
, OPC_MIN_D
, rt
, rs
, rd
, 0);
21008 switch (extract32(ctx
->opcode
, 9, 1)) {
21010 gen_farith(ctx
, OPC_MAX_S
, rt
, rs
, rd
, 0);
21013 gen_farith(ctx
, OPC_MAX_D
, rt
, rs
, rd
, 0);
21018 switch (extract32(ctx
->opcode
, 9, 1)) {
21020 gen_farith(ctx
, OPC_MINA_S
, rt
, rs
, rd
, 0);
21023 gen_farith(ctx
, OPC_MINA_D
, rt
, rs
, rd
, 0);
21028 switch (extract32(ctx
->opcode
, 9, 1)) {
21030 gen_farith(ctx
, OPC_MAXA_S
, rt
, rs
, rd
, 0);
21033 gen_farith(ctx
, OPC_MAXA_D
, rt
, rs
, rd
, 0);
21038 switch (extract32(ctx
->opcode
, 6, 8)) {
21040 gen_cp1(ctx
, OPC_CFC1
, rt
, rs
);
21043 gen_cp1(ctx
, OPC_CTC1
, rt
, rs
);
21046 gen_cp1(ctx
, OPC_MFC1
, rt
, rs
);
21049 gen_cp1(ctx
, OPC_MTC1
, rt
, rs
);
21052 gen_cp1(ctx
, OPC_MFHC1
, rt
, rs
);
21055 gen_cp1(ctx
, OPC_MTHC1
, rt
, rs
);
21058 gen_farith(ctx
, OPC_CVT_S_PL
, -1, rs
, rt
, 0);
21061 gen_farith(ctx
, OPC_CVT_S_PU
, -1, rs
, rt
, 0);
21064 switch (extract32(ctx
->opcode
, 6, 9)) {
21066 gen_farith(ctx
, OPC_CVT_L_S
, -1, rs
, rt
, 0);
21069 gen_farith(ctx
, OPC_CVT_L_D
, -1, rs
, rt
, 0);
21072 gen_farith(ctx
, OPC_CVT_W_S
, -1, rs
, rt
, 0);
21075 gen_farith(ctx
, OPC_CVT_W_D
, -1, rs
, rt
, 0);
21078 gen_farith(ctx
, OPC_RSQRT_S
, -1, rs
, rt
, 0);
21081 gen_farith(ctx
, OPC_RSQRT_D
, -1, rs
, rt
, 0);
21084 gen_farith(ctx
, OPC_SQRT_S
, -1, rs
, rt
, 0);
21087 gen_farith(ctx
, OPC_SQRT_D
, -1, rs
, rt
, 0);
21090 gen_farith(ctx
, OPC_RECIP_S
, -1, rs
, rt
, 0);
21093 gen_farith(ctx
, OPC_RECIP_D
, -1, rs
, rt
, 0);
21096 gen_farith(ctx
, OPC_FLOOR_L_S
, -1, rs
, rt
, 0);
21099 gen_farith(ctx
, OPC_FLOOR_L_D
, -1, rs
, rt
, 0);
21102 gen_farith(ctx
, OPC_FLOOR_W_S
, -1, rs
, rt
, 0);
21105 gen_farith(ctx
, OPC_FLOOR_W_D
, -1, rs
, rt
, 0);
21108 gen_farith(ctx
, OPC_CEIL_L_S
, -1, rs
, rt
, 0);
21111 gen_farith(ctx
, OPC_CEIL_L_D
, -1, rs
, rt
, 0);
21114 gen_farith(ctx
, OPC_CEIL_W_S
, -1, rs
, rt
, 0);
21117 gen_farith(ctx
, OPC_CEIL_W_D
, -1, rs
, rt
, 0);
21120 gen_farith(ctx
, OPC_TRUNC_L_S
, -1, rs
, rt
, 0);
21123 gen_farith(ctx
, OPC_TRUNC_L_D
, -1, rs
, rt
, 0);
21126 gen_farith(ctx
, OPC_TRUNC_W_S
, -1, rs
, rt
, 0);
21129 gen_farith(ctx
, OPC_TRUNC_W_D
, -1, rs
, rt
, 0);
21132 gen_farith(ctx
, OPC_ROUND_L_S
, -1, rs
, rt
, 0);
21135 gen_farith(ctx
, OPC_ROUND_L_D
, -1, rs
, rt
, 0);
21138 gen_farith(ctx
, OPC_ROUND_W_S
, -1, rs
, rt
, 0);
21141 gen_farith(ctx
, OPC_ROUND_W_D
, -1, rs
, rt
, 0);
21144 gen_farith(ctx
, OPC_MOV_S
, -1, rs
, rt
, 0);
21147 gen_farith(ctx
, OPC_MOV_D
, -1, rs
, rt
, 0);
21150 gen_farith(ctx
, OPC_ABS_S
, -1, rs
, rt
, 0);
21153 gen_farith(ctx
, OPC_ABS_D
, -1, rs
, rt
, 0);
21156 gen_farith(ctx
, OPC_NEG_S
, -1, rs
, rt
, 0);
21159 gen_farith(ctx
, OPC_NEG_D
, -1, rs
, rt
, 0);
21162 gen_farith(ctx
, OPC_CVT_D_S
, -1, rs
, rt
, 0);
21165 gen_farith(ctx
, OPC_CVT_D_W
, -1, rs
, rt
, 0);
21168 gen_farith(ctx
, OPC_CVT_D_L
, -1, rs
, rt
, 0);
21171 gen_farith(ctx
, OPC_CVT_S_D
, -1, rs
, rt
, 0);
21174 gen_farith(ctx
, OPC_CVT_S_W
, -1, rs
, rt
, 0);
21177 gen_farith(ctx
, OPC_CVT_S_L
, -1, rs
, rt
, 0);
21180 generate_exception_end(ctx
, EXCP_RI
);
21189 switch (extract32(ctx
->opcode
, 3, 3)) {
21190 case NM_CMP_CONDN_S
:
21191 gen_r6_cmp_s(ctx
, extract32(ctx
->opcode
, 6, 5), rt
, rs
, rd
);
21193 case NM_CMP_CONDN_D
:
21194 gen_r6_cmp_d(ctx
, extract32(ctx
->opcode
, 6, 5), rt
, rs
, rd
);
21197 generate_exception_end(ctx
, EXCP_RI
);
21202 generate_exception_end(ctx
, EXCP_RI
);
21207 static void gen_pool32a5_nanomips_insn(DisasContext
*ctx
, int opc
,
21208 int rd
, int rs
, int rt
)
21211 TCGv t0
= tcg_temp_new();
21212 TCGv v1_t
= tcg_temp_new();
21213 TCGv v2_t
= tcg_temp_new();
21215 gen_load_gpr(v1_t
, rs
);
21216 gen_load_gpr(v2_t
, rt
);
21221 gen_helper_cmp_eq_ph(v1_t
, v2_t
, cpu_env
);
21225 gen_helper_cmp_lt_ph(v1_t
, v2_t
, cpu_env
);
21229 gen_helper_cmp_le_ph(v1_t
, v2_t
, cpu_env
);
21231 case NM_CMPU_EQ_QB
:
21233 gen_helper_cmpu_eq_qb(v1_t
, v2_t
, cpu_env
);
21235 case NM_CMPU_LT_QB
:
21237 gen_helper_cmpu_lt_qb(v1_t
, v2_t
, cpu_env
);
21239 case NM_CMPU_LE_QB
:
21241 gen_helper_cmpu_le_qb(v1_t
, v2_t
, cpu_env
);
21243 case NM_CMPGU_EQ_QB
:
21245 gen_helper_cmpgu_eq_qb(v1_t
, v1_t
, v2_t
);
21246 gen_store_gpr(v1_t
, ret
);
21248 case NM_CMPGU_LT_QB
:
21250 gen_helper_cmpgu_lt_qb(v1_t
, v1_t
, v2_t
);
21251 gen_store_gpr(v1_t
, ret
);
21253 case NM_CMPGU_LE_QB
:
21255 gen_helper_cmpgu_le_qb(v1_t
, v1_t
, v2_t
);
21256 gen_store_gpr(v1_t
, ret
);
21258 case NM_CMPGDU_EQ_QB
:
21260 gen_helper_cmpgu_eq_qb(v1_t
, v1_t
, v2_t
);
21261 tcg_gen_deposit_tl(cpu_dspctrl
, cpu_dspctrl
, v1_t
, 24, 4);
21262 gen_store_gpr(v1_t
, ret
);
21264 case NM_CMPGDU_LT_QB
:
21266 gen_helper_cmpgu_lt_qb(v1_t
, v1_t
, v2_t
);
21267 tcg_gen_deposit_tl(cpu_dspctrl
, cpu_dspctrl
, v1_t
, 24, 4);
21268 gen_store_gpr(v1_t
, ret
);
21270 case NM_CMPGDU_LE_QB
:
21272 gen_helper_cmpgu_le_qb(v1_t
, v1_t
, v2_t
);
21273 tcg_gen_deposit_tl(cpu_dspctrl
, cpu_dspctrl
, v1_t
, 24, 4);
21274 gen_store_gpr(v1_t
, ret
);
21278 gen_helper_packrl_ph(v1_t
, v1_t
, v2_t
);
21279 gen_store_gpr(v1_t
, ret
);
21283 gen_helper_pick_qb(v1_t
, v1_t
, v2_t
, cpu_env
);
21284 gen_store_gpr(v1_t
, ret
);
21288 gen_helper_pick_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21289 gen_store_gpr(v1_t
, ret
);
21293 gen_helper_addq_s_w(v1_t
, v1_t
, v2_t
, cpu_env
);
21294 gen_store_gpr(v1_t
, ret
);
21298 gen_helper_subq_s_w(v1_t
, v1_t
, v2_t
, cpu_env
);
21299 gen_store_gpr(v1_t
, ret
);
21303 gen_helper_addsc(v1_t
, v1_t
, v2_t
, cpu_env
);
21304 gen_store_gpr(v1_t
, ret
);
21308 gen_helper_addwc(v1_t
, v1_t
, v2_t
, cpu_env
);
21309 gen_store_gpr(v1_t
, ret
);
21313 switch (extract32(ctx
->opcode
, 10, 1)) {
21316 gen_helper_addq_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21317 gen_store_gpr(v1_t
, ret
);
21321 gen_helper_addq_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21322 gen_store_gpr(v1_t
, ret
);
21326 case NM_ADDQH_R_PH
:
21328 switch (extract32(ctx
->opcode
, 10, 1)) {
21331 gen_helper_addqh_ph(v1_t
, v1_t
, v2_t
);
21332 gen_store_gpr(v1_t
, ret
);
21336 gen_helper_addqh_r_ph(v1_t
, v1_t
, v2_t
);
21337 gen_store_gpr(v1_t
, ret
);
21343 switch (extract32(ctx
->opcode
, 10, 1)) {
21346 gen_helper_addqh_w(v1_t
, v1_t
, v2_t
);
21347 gen_store_gpr(v1_t
, ret
);
21351 gen_helper_addqh_r_w(v1_t
, v1_t
, v2_t
);
21352 gen_store_gpr(v1_t
, ret
);
21358 switch (extract32(ctx
->opcode
, 10, 1)) {
21361 gen_helper_addu_qb(v1_t
, v1_t
, v2_t
, cpu_env
);
21362 gen_store_gpr(v1_t
, ret
);
21366 gen_helper_addu_s_qb(v1_t
, v1_t
, v2_t
, cpu_env
);
21367 gen_store_gpr(v1_t
, ret
);
21373 switch (extract32(ctx
->opcode
, 10, 1)) {
21376 gen_helper_addu_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21377 gen_store_gpr(v1_t
, ret
);
21381 gen_helper_addu_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21382 gen_store_gpr(v1_t
, ret
);
21386 case NM_ADDUH_R_QB
:
21388 switch (extract32(ctx
->opcode
, 10, 1)) {
21391 gen_helper_adduh_qb(v1_t
, v1_t
, v2_t
);
21392 gen_store_gpr(v1_t
, ret
);
21396 gen_helper_adduh_r_qb(v1_t
, v1_t
, v2_t
);
21397 gen_store_gpr(v1_t
, ret
);
21401 case NM_SHRAV_R_PH
:
21403 switch (extract32(ctx
->opcode
, 10, 1)) {
21406 gen_helper_shra_ph(v1_t
, v1_t
, v2_t
);
21407 gen_store_gpr(v1_t
, ret
);
21411 gen_helper_shra_r_ph(v1_t
, v1_t
, v2_t
);
21412 gen_store_gpr(v1_t
, ret
);
21416 case NM_SHRAV_R_QB
:
21418 switch (extract32(ctx
->opcode
, 10, 1)) {
21421 gen_helper_shra_qb(v1_t
, v1_t
, v2_t
);
21422 gen_store_gpr(v1_t
, ret
);
21426 gen_helper_shra_r_qb(v1_t
, v1_t
, v2_t
);
21427 gen_store_gpr(v1_t
, ret
);
21433 switch (extract32(ctx
->opcode
, 10, 1)) {
21436 gen_helper_subq_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21437 gen_store_gpr(v1_t
, ret
);
21441 gen_helper_subq_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21442 gen_store_gpr(v1_t
, ret
);
21446 case NM_SUBQH_R_PH
:
21448 switch (extract32(ctx
->opcode
, 10, 1)) {
21451 gen_helper_subqh_ph(v1_t
, v1_t
, v2_t
);
21452 gen_store_gpr(v1_t
, ret
);
21456 gen_helper_subqh_r_ph(v1_t
, v1_t
, v2_t
);
21457 gen_store_gpr(v1_t
, ret
);
21463 switch (extract32(ctx
->opcode
, 10, 1)) {
21466 gen_helper_subqh_w(v1_t
, v1_t
, v2_t
);
21467 gen_store_gpr(v1_t
, ret
);
21471 gen_helper_subqh_r_w(v1_t
, v1_t
, v2_t
);
21472 gen_store_gpr(v1_t
, ret
);
21478 switch (extract32(ctx
->opcode
, 10, 1)) {
21481 gen_helper_subu_qb(v1_t
, v1_t
, v2_t
, cpu_env
);
21482 gen_store_gpr(v1_t
, ret
);
21486 gen_helper_subu_s_qb(v1_t
, v1_t
, v2_t
, cpu_env
);
21487 gen_store_gpr(v1_t
, ret
);
21493 switch (extract32(ctx
->opcode
, 10, 1)) {
21496 gen_helper_subu_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21497 gen_store_gpr(v1_t
, ret
);
21501 gen_helper_subu_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21502 gen_store_gpr(v1_t
, ret
);
21506 case NM_SUBUH_R_QB
:
21508 switch (extract32(ctx
->opcode
, 10, 1)) {
21511 gen_helper_subuh_qb(v1_t
, v1_t
, v2_t
);
21512 gen_store_gpr(v1_t
, ret
);
21516 gen_helper_subuh_r_qb(v1_t
, v1_t
, v2_t
);
21517 gen_store_gpr(v1_t
, ret
);
21521 case NM_SHLLV_S_PH
:
21523 switch (extract32(ctx
->opcode
, 10, 1)) {
21526 gen_helper_shll_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21527 gen_store_gpr(v1_t
, ret
);
21531 gen_helper_shll_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21532 gen_store_gpr(v1_t
, ret
);
21536 case NM_PRECR_SRA_R_PH_W
:
21538 switch (extract32(ctx
->opcode
, 10, 1)) {
21540 /* PRECR_SRA_PH_W */
21542 TCGv_i32 sa_t
= tcg_const_i32(rd
);
21543 gen_helper_precr_sra_ph_w(v1_t
, sa_t
, v1_t
,
21545 gen_store_gpr(v1_t
, rt
);
21546 tcg_temp_free_i32(sa_t
);
21550 /* PRECR_SRA_R_PH_W */
21552 TCGv_i32 sa_t
= tcg_const_i32(rd
);
21553 gen_helper_precr_sra_r_ph_w(v1_t
, sa_t
, v1_t
,
21555 gen_store_gpr(v1_t
, rt
);
21556 tcg_temp_free_i32(sa_t
);
21561 case NM_MULEU_S_PH_QBL
:
21563 gen_helper_muleu_s_ph_qbl(v1_t
, v1_t
, v2_t
, cpu_env
);
21564 gen_store_gpr(v1_t
, ret
);
21566 case NM_MULEU_S_PH_QBR
:
21568 gen_helper_muleu_s_ph_qbr(v1_t
, v1_t
, v2_t
, cpu_env
);
21569 gen_store_gpr(v1_t
, ret
);
21571 case NM_MULQ_RS_PH
:
21573 gen_helper_mulq_rs_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21574 gen_store_gpr(v1_t
, ret
);
21578 gen_helper_mulq_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21579 gen_store_gpr(v1_t
, ret
);
21583 gen_helper_mulq_rs_w(v1_t
, v1_t
, v2_t
, cpu_env
);
21584 gen_store_gpr(v1_t
, ret
);
21588 gen_helper_mulq_s_w(v1_t
, v1_t
, v2_t
, cpu_env
);
21589 gen_store_gpr(v1_t
, ret
);
21593 gen_load_gpr(t0
, rs
);
21595 tcg_gen_deposit_tl(cpu_gpr
[rt
], t0
, cpu_gpr
[rt
], rd
, 32 - rd
);
21597 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
21601 gen_helper_modsub(v1_t
, v1_t
, v2_t
);
21602 gen_store_gpr(v1_t
, ret
);
21606 gen_helper_shra_r_w(v1_t
, v1_t
, v2_t
);
21607 gen_store_gpr(v1_t
, ret
);
21611 gen_helper_shrl_ph(v1_t
, v1_t
, v2_t
);
21612 gen_store_gpr(v1_t
, ret
);
21616 gen_helper_shrl_qb(v1_t
, v1_t
, v2_t
);
21617 gen_store_gpr(v1_t
, ret
);
21621 gen_helper_shll_qb(v1_t
, v1_t
, v2_t
, cpu_env
);
21622 gen_store_gpr(v1_t
, ret
);
21626 gen_helper_shll_s_w(v1_t
, v1_t
, v2_t
, cpu_env
);
21627 gen_store_gpr(v1_t
, ret
);
21632 TCGv tv0
= tcg_temp_new();
21633 TCGv tv1
= tcg_temp_new();
21634 int16_t imm
= extract32(ctx
->opcode
, 16, 7);
21636 tcg_gen_movi_tl(tv0
, rd
>> 3);
21637 tcg_gen_movi_tl(tv1
, imm
);
21638 gen_helper_shilo(tv0
, tv1
, cpu_env
);
21641 case NM_MULEQ_S_W_PHL
:
21643 gen_helper_muleq_s_w_phl(v1_t
, v1_t
, v2_t
, cpu_env
);
21644 gen_store_gpr(v1_t
, ret
);
21646 case NM_MULEQ_S_W_PHR
:
21648 gen_helper_muleq_s_w_phr(v1_t
, v1_t
, v2_t
, cpu_env
);
21649 gen_store_gpr(v1_t
, ret
);
21653 switch (extract32(ctx
->opcode
, 10, 1)) {
21656 gen_helper_mul_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21657 gen_store_gpr(v1_t
, ret
);
21661 gen_helper_mul_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21662 gen_store_gpr(v1_t
, ret
);
21666 case NM_PRECR_QB_PH
:
21668 gen_helper_precr_qb_ph(v1_t
, v1_t
, v2_t
);
21669 gen_store_gpr(v1_t
, ret
);
21671 case NM_PRECRQ_QB_PH
:
21673 gen_helper_precrq_qb_ph(v1_t
, v1_t
, v2_t
);
21674 gen_store_gpr(v1_t
, ret
);
21676 case NM_PRECRQ_PH_W
:
21678 gen_helper_precrq_ph_w(v1_t
, v1_t
, v2_t
);
21679 gen_store_gpr(v1_t
, ret
);
21681 case NM_PRECRQ_RS_PH_W
:
21683 gen_helper_precrq_rs_ph_w(v1_t
, v1_t
, v2_t
, cpu_env
);
21684 gen_store_gpr(v1_t
, ret
);
21686 case NM_PRECRQU_S_QB_PH
:
21688 gen_helper_precrqu_s_qb_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21689 gen_store_gpr(v1_t
, ret
);
21693 tcg_gen_movi_tl(t0
, rd
);
21694 gen_helper_shra_r_w(v1_t
, t0
, v1_t
);
21695 gen_store_gpr(v1_t
, rt
);
21699 tcg_gen_movi_tl(t0
, rd
>> 1);
21700 switch (extract32(ctx
->opcode
, 10, 1)) {
21703 gen_helper_shra_ph(v1_t
, t0
, v1_t
);
21704 gen_store_gpr(v1_t
, rt
);
21708 gen_helper_shra_r_ph(v1_t
, t0
, v1_t
);
21709 gen_store_gpr(v1_t
, rt
);
21715 tcg_gen_movi_tl(t0
, rd
>> 1);
21716 switch (extract32(ctx
->opcode
, 10, 2)) {
21719 gen_helper_shll_ph(v1_t
, t0
, v1_t
, cpu_env
);
21720 gen_store_gpr(v1_t
, rt
);
21724 gen_helper_shll_s_ph(v1_t
, t0
, v1_t
, cpu_env
);
21725 gen_store_gpr(v1_t
, rt
);
21728 generate_exception_end(ctx
, EXCP_RI
);
21734 tcg_gen_movi_tl(t0
, rd
);
21735 gen_helper_shll_s_w(v1_t
, t0
, v1_t
, cpu_env
);
21736 gen_store_gpr(v1_t
, rt
);
21742 imm
= sextract32(ctx
->opcode
, 11, 11);
21743 imm
= (int16_t)(imm
<< 6) >> 6;
21745 tcg_gen_movi_tl(cpu_gpr
[rt
], dup_const(MO_16
, imm
));
21750 generate_exception_end(ctx
, EXCP_RI
);
21755 static int decode_nanomips_32_48_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
21763 insn
= cpu_lduw_code(env
, ctx
->base
.pc_next
+ 2);
21764 ctx
->opcode
= (ctx
->opcode
<< 16) | insn
;
21766 rt
= extract32(ctx
->opcode
, 21, 5);
21767 rs
= extract32(ctx
->opcode
, 16, 5);
21768 rd
= extract32(ctx
->opcode
, 11, 5);
21770 op
= extract32(ctx
->opcode
, 26, 6);
21775 switch (extract32(ctx
->opcode
, 19, 2)) {
21778 generate_exception_end(ctx
, EXCP_RI
);
21781 if ((extract32(ctx
->opcode
, 18, 1)) == NM_SYSCALL
) {
21782 generate_exception_end(ctx
, EXCP_SYSCALL
);
21784 generate_exception_end(ctx
, EXCP_RI
);
21788 generate_exception_end(ctx
, EXCP_BREAK
);
21791 if (is_uhi(extract32(ctx
->opcode
, 0, 19))) {
21792 gen_helper_do_semihosting(cpu_env
);
21794 if (ctx
->hflags
& MIPS_HFLAG_SBRI
) {
21795 generate_exception_end(ctx
, EXCP_RI
);
21797 generate_exception_end(ctx
, EXCP_DBp
);
21804 imm
= extract32(ctx
->opcode
, 0, 16);
21806 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], imm
);
21808 tcg_gen_movi_tl(cpu_gpr
[rt
], imm
);
21810 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
21815 offset
= sextract32(ctx
->opcode
, 0, 1) << 21 |
21816 extract32(ctx
->opcode
, 1, 20) << 1;
21817 target_long addr
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
21818 tcg_gen_movi_tl(cpu_gpr
[rt
], addr
);
21822 switch (ctx
->opcode
& 0x07) {
21824 gen_pool32a0_nanomips_insn(env
, ctx
);
21828 int32_t op1
= extract32(ctx
->opcode
, 3, 7);
21829 gen_pool32a5_nanomips_insn(ctx
, op1
, rd
, rs
, rt
);
21833 switch (extract32(ctx
->opcode
, 3, 3)) {
21835 gen_p_lsx(ctx
, rd
, rs
, rt
);
21839 * In nanoMIPS, the shift field directly encodes the shift
21840 * amount, meaning that the supported shift values are in
21841 * the range 0 to 3 (instead of 1 to 4 in MIPSR6).
21843 gen_lsa(ctx
, OPC_LSA
, rd
, rs
, rt
,
21844 extract32(ctx
->opcode
, 9, 2) - 1);
21847 gen_ext(ctx
, 32, rd
, rs
, rt
, extract32(ctx
->opcode
, 6, 5));
21850 gen_pool32axf_nanomips_insn(env
, ctx
);
21853 generate_exception_end(ctx
, EXCP_RI
);
21858 generate_exception_end(ctx
, EXCP_RI
);
21863 switch (ctx
->opcode
& 0x03) {
21866 offset
= extract32(ctx
->opcode
, 0, 21);
21867 gen_op_addr_addi(ctx
, cpu_gpr
[rt
], cpu_gpr
[28], offset
);
21871 gen_ld(ctx
, OPC_LW
, rt
, 28, extract32(ctx
->opcode
, 2, 19) << 2);
21874 gen_st(ctx
, OPC_SW
, rt
, 28, extract32(ctx
->opcode
, 2, 19) << 2);
21877 generate_exception_end(ctx
, EXCP_RI
);
21883 insn
= cpu_lduw_code(env
, ctx
->base
.pc_next
+ 4);
21884 target_long addr_off
= extract32(ctx
->opcode
, 0, 16) | insn
<< 16;
21885 switch (extract32(ctx
->opcode
, 16, 5)) {
21889 tcg_gen_movi_tl(cpu_gpr
[rt
], addr_off
);
21895 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], addr_off
);
21896 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
21902 gen_op_addr_addi(ctx
, cpu_gpr
[rt
], cpu_gpr
[28], addr_off
);
21908 target_long addr
= addr_add(ctx
, ctx
->base
.pc_next
+ 6,
21911 tcg_gen_movi_tl(cpu_gpr
[rt
], addr
);
21918 t0
= tcg_temp_new();
21920 target_long addr
= addr_add(ctx
, ctx
->base
.pc_next
+ 6,
21923 tcg_gen_movi_tl(t0
, addr
);
21924 tcg_gen_qemu_ld_tl(cpu_gpr
[rt
], t0
, ctx
->mem_idx
, MO_TESL
);
21932 t0
= tcg_temp_new();
21933 t1
= tcg_temp_new();
21935 target_long addr
= addr_add(ctx
, ctx
->base
.pc_next
+ 6,
21938 tcg_gen_movi_tl(t0
, addr
);
21939 gen_load_gpr(t1
, rt
);
21941 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
21948 generate_exception_end(ctx
, EXCP_RI
);
21954 switch (extract32(ctx
->opcode
, 12, 4)) {
21956 gen_logic_imm(ctx
, OPC_ORI
, rt
, rs
, extract32(ctx
->opcode
, 0, 12));
21959 gen_logic_imm(ctx
, OPC_XORI
, rt
, rs
, extract32(ctx
->opcode
, 0, 12));
21962 gen_logic_imm(ctx
, OPC_ANDI
, rt
, rs
, extract32(ctx
->opcode
, 0, 12));
21965 switch (extract32(ctx
->opcode
, 20, 1)) {
21967 switch (ctx
->opcode
& 3) {
21969 gen_save(ctx
, rt
, extract32(ctx
->opcode
, 16, 4),
21970 extract32(ctx
->opcode
, 2, 1),
21971 extract32(ctx
->opcode
, 3, 9) << 3);
21974 case NM_RESTORE_JRC
:
21975 gen_restore(ctx
, rt
, extract32(ctx
->opcode
, 16, 4),
21976 extract32(ctx
->opcode
, 2, 1),
21977 extract32(ctx
->opcode
, 3, 9) << 3);
21978 if ((ctx
->opcode
& 3) == NM_RESTORE_JRC
) {
21979 gen_compute_branch_nm(ctx
, OPC_JR
, 2, 31, 0, 0);
21983 generate_exception_end(ctx
, EXCP_RI
);
21988 generate_exception_end(ctx
, EXCP_RI
);
21993 gen_slt_imm(ctx
, OPC_SLTI
, rt
, rs
, extract32(ctx
->opcode
, 0, 12));
21996 gen_slt_imm(ctx
, OPC_SLTIU
, rt
, rs
, extract32(ctx
->opcode
, 0, 12));
22000 TCGv t0
= tcg_temp_new();
22002 imm
= extract32(ctx
->opcode
, 0, 12);
22003 gen_load_gpr(t0
, rs
);
22004 tcg_gen_setcondi_tl(TCG_COND_EQ
, t0
, t0
, imm
);
22005 gen_store_gpr(t0
, rt
);
22011 imm
= (int16_t) extract32(ctx
->opcode
, 0, 12);
22012 gen_arith_imm(ctx
, OPC_ADDIU
, rt
, rs
, -imm
);
22016 int shift
= extract32(ctx
->opcode
, 0, 5);
22017 switch (extract32(ctx
->opcode
, 5, 4)) {
22019 if (rt
== 0 && shift
== 0) {
22021 } else if (rt
== 0 && shift
== 3) {
22022 /* EHB - treat as NOP */
22023 } else if (rt
== 0 && shift
== 5) {
22024 /* PAUSE - treat as NOP */
22025 } else if (rt
== 0 && shift
== 6) {
22027 gen_sync(extract32(ctx
->opcode
, 16, 5));
22030 gen_shift_imm(ctx
, OPC_SLL
, rt
, rs
,
22031 extract32(ctx
->opcode
, 0, 5));
22035 gen_shift_imm(ctx
, OPC_SRL
, rt
, rs
,
22036 extract32(ctx
->opcode
, 0, 5));
22039 gen_shift_imm(ctx
, OPC_SRA
, rt
, rs
,
22040 extract32(ctx
->opcode
, 0, 5));
22043 gen_shift_imm(ctx
, OPC_ROTR
, rt
, rs
,
22044 extract32(ctx
->opcode
, 0, 5));
22052 TCGv t0
= tcg_temp_new();
22053 TCGv_i32 shift
= tcg_const_i32(extract32(ctx
->opcode
, 0, 5));
22054 TCGv_i32 shiftx
= tcg_const_i32(extract32(ctx
->opcode
, 7, 4)
22056 TCGv_i32 stripe
= tcg_const_i32(extract32(ctx
->opcode
, 6, 1));
22058 gen_load_gpr(t0
, rs
);
22059 gen_helper_rotx(cpu_gpr
[rt
], t0
, shift
, shiftx
, stripe
);
22062 tcg_temp_free_i32(shift
);
22063 tcg_temp_free_i32(shiftx
);
22064 tcg_temp_free_i32(stripe
);
22068 switch (((ctx
->opcode
>> 10) & 2) |
22069 (extract32(ctx
->opcode
, 5, 1))) {
22072 gen_bitops(ctx
, OPC_INS
, rt
, rs
, extract32(ctx
->opcode
, 0, 5),
22073 extract32(ctx
->opcode
, 6, 5));
22076 generate_exception_end(ctx
, EXCP_RI
);
22081 switch (((ctx
->opcode
>> 10) & 2) |
22082 (extract32(ctx
->opcode
, 5, 1))) {
22085 gen_bitops(ctx
, OPC_EXT
, rt
, rs
, extract32(ctx
->opcode
, 0, 5),
22086 extract32(ctx
->opcode
, 6, 5));
22089 generate_exception_end(ctx
, EXCP_RI
);
22094 generate_exception_end(ctx
, EXCP_RI
);
22099 gen_pool32f_nanomips_insn(ctx
);
22104 switch (extract32(ctx
->opcode
, 1, 1)) {
22107 tcg_gen_movi_tl(cpu_gpr
[rt
],
22108 sextract32(ctx
->opcode
, 0, 1) << 31 |
22109 extract32(ctx
->opcode
, 2, 10) << 21 |
22110 extract32(ctx
->opcode
, 12, 9) << 12);
22115 offset
= sextract32(ctx
->opcode
, 0, 1) << 31 |
22116 extract32(ctx
->opcode
, 2, 10) << 21 |
22117 extract32(ctx
->opcode
, 12, 9) << 12;
22119 addr
= ~0xFFF & addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
22120 tcg_gen_movi_tl(cpu_gpr
[rt
], addr
);
22127 uint32_t u
= extract32(ctx
->opcode
, 0, 18);
22129 switch (extract32(ctx
->opcode
, 18, 3)) {
22131 gen_ld(ctx
, OPC_LB
, rt
, 28, u
);
22134 gen_st(ctx
, OPC_SB
, rt
, 28, u
);
22137 gen_ld(ctx
, OPC_LBU
, rt
, 28, u
);
22141 gen_op_addr_addi(ctx
, cpu_gpr
[rt
], cpu_gpr
[28], u
);
22146 switch (ctx
->opcode
& 1) {
22148 gen_ld(ctx
, OPC_LH
, rt
, 28, u
);
22151 gen_ld(ctx
, OPC_LHU
, rt
, 28, u
);
22157 switch (ctx
->opcode
& 1) {
22159 gen_st(ctx
, OPC_SH
, rt
, 28, u
);
22162 generate_exception_end(ctx
, EXCP_RI
);
22168 switch (ctx
->opcode
& 0x3) {
22170 gen_cop1_ldst(ctx
, OPC_LWC1
, rt
, 28, u
);
22173 gen_cop1_ldst(ctx
, OPC_LDC1
, rt
, 28, u
);
22176 gen_cop1_ldst(ctx
, OPC_SWC1
, rt
, 28, u
);
22179 gen_cop1_ldst(ctx
, OPC_SDC1
, rt
, 28, u
);
22184 generate_exception_end(ctx
, EXCP_RI
);
22191 uint32_t u
= extract32(ctx
->opcode
, 0, 12);
22193 switch (extract32(ctx
->opcode
, 12, 4)) {
22198 * Break the TB to be able to sync copied instructions
22201 ctx
->base
.is_jmp
= DISAS_STOP
;
22204 /* Treat as NOP. */
22208 gen_ld(ctx
, OPC_LB
, rt
, rs
, u
);
22211 gen_ld(ctx
, OPC_LH
, rt
, rs
, u
);
22214 gen_ld(ctx
, OPC_LW
, rt
, rs
, u
);
22217 gen_ld(ctx
, OPC_LBU
, rt
, rs
, u
);
22220 gen_ld(ctx
, OPC_LHU
, rt
, rs
, u
);
22223 gen_st(ctx
, OPC_SB
, rt
, rs
, u
);
22226 gen_st(ctx
, OPC_SH
, rt
, rs
, u
);
22229 gen_st(ctx
, OPC_SW
, rt
, rs
, u
);
22232 gen_cop1_ldst(ctx
, OPC_LWC1
, rt
, rs
, u
);
22235 gen_cop1_ldst(ctx
, OPC_LDC1
, rt
, rs
, u
);
22238 gen_cop1_ldst(ctx
, OPC_SWC1
, rt
, rs
, u
);
22241 gen_cop1_ldst(ctx
, OPC_SDC1
, rt
, rs
, u
);
22244 generate_exception_end(ctx
, EXCP_RI
);
22251 int32_t s
= (sextract32(ctx
->opcode
, 15, 1) << 8) |
22252 extract32(ctx
->opcode
, 0, 8);
22254 switch (extract32(ctx
->opcode
, 8, 3)) {
22256 switch (extract32(ctx
->opcode
, 11, 4)) {
22258 gen_ld(ctx
, OPC_LB
, rt
, rs
, s
);
22261 gen_ld(ctx
, OPC_LH
, rt
, rs
, s
);
22264 gen_ld(ctx
, OPC_LW
, rt
, rs
, s
);
22267 gen_ld(ctx
, OPC_LBU
, rt
, rs
, s
);
22270 gen_ld(ctx
, OPC_LHU
, rt
, rs
, s
);
22273 gen_st(ctx
, OPC_SB
, rt
, rs
, s
);
22276 gen_st(ctx
, OPC_SH
, rt
, rs
, s
);
22279 gen_st(ctx
, OPC_SW
, rt
, rs
, s
);
22282 gen_cop1_ldst(ctx
, OPC_LWC1
, rt
, rs
, s
);
22285 gen_cop1_ldst(ctx
, OPC_LDC1
, rt
, rs
, s
);
22288 gen_cop1_ldst(ctx
, OPC_SWC1
, rt
, rs
, s
);
22291 gen_cop1_ldst(ctx
, OPC_SDC1
, rt
, rs
, s
);
22297 * Break the TB to be able to sync copied instructions
22300 ctx
->base
.is_jmp
= DISAS_STOP
;
22303 /* Treat as NOP. */
22307 generate_exception_end(ctx
, EXCP_RI
);
22312 switch (extract32(ctx
->opcode
, 11, 4)) {
22317 TCGv t0
= tcg_temp_new();
22318 TCGv t1
= tcg_temp_new();
22320 gen_base_offset_addr(ctx
, t0
, rs
, s
);
22322 switch (extract32(ctx
->opcode
, 11, 4)) {
22324 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESW
|
22326 gen_store_gpr(t0
, rt
);
22329 gen_load_gpr(t1
, rt
);
22330 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUW
|
22339 switch (ctx
->opcode
& 0x03) {
22341 gen_ld(ctx
, OPC_LL
, rt
, rs
, s
);
22345 gen_llwp(ctx
, rs
, 0, rt
, extract32(ctx
->opcode
, 3, 5));
22350 switch (ctx
->opcode
& 0x03) {
22352 gen_st_cond(ctx
, rt
, rs
, s
, MO_TESL
, false);
22356 gen_scwp(ctx
, rs
, 0, rt
, extract32(ctx
->opcode
, 3, 5),
22362 check_cp0_enabled(ctx
);
22363 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
22364 gen_cache_operation(ctx
, rt
, rs
, s
);
22370 switch (extract32(ctx
->opcode
, 11, 4)) {
22373 check_cp0_enabled(ctx
);
22374 gen_ld(ctx
, OPC_LBE
, rt
, rs
, s
);
22378 check_cp0_enabled(ctx
);
22379 gen_st(ctx
, OPC_SBE
, rt
, rs
, s
);
22383 check_cp0_enabled(ctx
);
22384 gen_ld(ctx
, OPC_LBUE
, rt
, rs
, s
);
22388 /* case NM_SYNCIE */
22390 check_cp0_enabled(ctx
);
22392 * Break the TB to be able to sync copied instructions
22395 ctx
->base
.is_jmp
= DISAS_STOP
;
22397 /* case NM_PREFE */
22399 check_cp0_enabled(ctx
);
22400 /* Treat as NOP. */
22405 check_cp0_enabled(ctx
);
22406 gen_ld(ctx
, OPC_LHE
, rt
, rs
, s
);
22410 check_cp0_enabled(ctx
);
22411 gen_st(ctx
, OPC_SHE
, rt
, rs
, s
);
22415 check_cp0_enabled(ctx
);
22416 gen_ld(ctx
, OPC_LHUE
, rt
, rs
, s
);
22419 check_nms_dl_il_sl_tl_l2c(ctx
);
22420 gen_cache_operation(ctx
, rt
, rs
, s
);
22424 check_cp0_enabled(ctx
);
22425 gen_ld(ctx
, OPC_LWE
, rt
, rs
, s
);
22429 check_cp0_enabled(ctx
);
22430 gen_st(ctx
, OPC_SWE
, rt
, rs
, s
);
22433 switch (extract32(ctx
->opcode
, 2, 2)) {
22437 check_cp0_enabled(ctx
);
22438 gen_ld(ctx
, OPC_LLE
, rt
, rs
, s
);
22443 check_cp0_enabled(ctx
);
22444 gen_llwp(ctx
, rs
, 0, rt
, extract32(ctx
->opcode
, 3, 5));
22447 generate_exception_end(ctx
, EXCP_RI
);
22452 switch (extract32(ctx
->opcode
, 2, 2)) {
22456 check_cp0_enabled(ctx
);
22457 gen_st_cond(ctx
, rt
, rs
, s
, MO_TESL
, true);
22462 check_cp0_enabled(ctx
);
22463 gen_scwp(ctx
, rs
, 0, rt
, extract32(ctx
->opcode
, 3, 5),
22467 generate_exception_end(ctx
, EXCP_RI
);
22477 int count
= extract32(ctx
->opcode
, 12, 3);
22480 offset
= sextract32(ctx
->opcode
, 15, 1) << 8 |
22481 extract32(ctx
->opcode
, 0, 8);
22482 TCGv va
= tcg_temp_new();
22483 TCGv t1
= tcg_temp_new();
22484 MemOp memop
= (extract32(ctx
->opcode
, 8, 3)) ==
22485 NM_P_LS_UAWM
? MO_UNALN
: 0;
22487 count
= (count
== 0) ? 8 : count
;
22488 while (counter
!= count
) {
22489 int this_rt
= ((rt
+ counter
) & 0x1f) | (rt
& 0x10);
22490 int this_offset
= offset
+ (counter
<< 2);
22492 gen_base_offset_addr(ctx
, va
, rs
, this_offset
);
22494 switch (extract32(ctx
->opcode
, 11, 1)) {
22496 tcg_gen_qemu_ld_tl(t1
, va
, ctx
->mem_idx
,
22498 gen_store_gpr(t1
, this_rt
);
22499 if ((this_rt
== rs
) &&
22500 (counter
!= (count
- 1))) {
22501 /* UNPREDICTABLE */
22505 this_rt
= (rt
== 0) ? 0 : this_rt
;
22506 gen_load_gpr(t1
, this_rt
);
22507 tcg_gen_qemu_st_tl(t1
, va
, ctx
->mem_idx
,
22518 generate_exception_end(ctx
, EXCP_RI
);
22526 TCGv t0
= tcg_temp_new();
22527 int32_t s
= sextract32(ctx
->opcode
, 0, 1) << 21 |
22528 extract32(ctx
->opcode
, 1, 20) << 1;
22529 rd
= (extract32(ctx
->opcode
, 24, 1)) == 0 ? 4 : 5;
22530 rt
= decode_gpr_gpr4_zero(extract32(ctx
->opcode
, 25, 1) << 3 |
22531 extract32(ctx
->opcode
, 21, 3));
22532 gen_load_gpr(t0
, rt
);
22533 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
22534 gen_compute_branch_nm(ctx
, OPC_BGEZAL
, 4, 0, 0, s
);
22540 int32_t s
= sextract32(ctx
->opcode
, 0, 1) << 25 |
22541 extract32(ctx
->opcode
, 1, 24) << 1;
22543 if ((extract32(ctx
->opcode
, 25, 1)) == 0) {
22545 gen_compute_branch_nm(ctx
, OPC_BEQ
, 4, 0, 0, s
);
22548 gen_compute_branch_nm(ctx
, OPC_BGEZAL
, 4, 0, 0, s
);
22553 switch (extract32(ctx
->opcode
, 12, 4)) {
22556 gen_compute_branch_nm(ctx
, OPC_JALR
, 4, rs
, rt
, 0);
22559 gen_compute_nanomips_pbalrsc_branch(ctx
, rs
, rt
);
22562 generate_exception_end(ctx
, EXCP_RI
);
22568 int32_t s
= sextract32(ctx
->opcode
, 0, 1) << 14 |
22569 extract32(ctx
->opcode
, 1, 13) << 1;
22570 switch (extract32(ctx
->opcode
, 14, 2)) {
22573 gen_compute_branch_nm(ctx
, OPC_BEQ
, 4, rs
, rt
, s
);
22576 s
= sextract32(ctx
->opcode
, 0, 1) << 14 |
22577 extract32(ctx
->opcode
, 1, 13) << 1;
22578 check_cp1_enabled(ctx
);
22579 switch (extract32(ctx
->opcode
, 16, 5)) {
22581 gen_compute_branch_cp1_nm(ctx
, OPC_BC1EQZ
, rt
, s
);
22584 gen_compute_branch_cp1_nm(ctx
, OPC_BC1NEZ
, rt
, s
);
22589 int32_t imm
= extract32(ctx
->opcode
, 1, 13) |
22590 extract32(ctx
->opcode
, 0, 1) << 13;
22592 gen_compute_branch_nm(ctx
, OPC_BPOSGE32
, 4, -1, -2,
22597 generate_exception_end(ctx
, EXCP_RI
);
22603 gen_compute_compact_branch_nm(ctx
, OPC_BC
, rs
, rt
, s
);
22605 gen_compute_compact_branch_nm(ctx
, OPC_BGEC
, rs
, rt
, s
);
22609 if (rs
== rt
|| rt
== 0) {
22610 gen_compute_compact_branch_nm(ctx
, OPC_BC
, 0, 0, s
);
22611 } else if (rs
== 0) {
22612 gen_compute_compact_branch_nm(ctx
, OPC_BEQZC
, rt
, 0, s
);
22614 gen_compute_compact_branch_nm(ctx
, OPC_BGEUC
, rs
, rt
, s
);
22622 int32_t s
= sextract32(ctx
->opcode
, 0, 1) << 14 |
22623 extract32(ctx
->opcode
, 1, 13) << 1;
22624 switch (extract32(ctx
->opcode
, 14, 2)) {
22627 gen_compute_branch_nm(ctx
, OPC_BNE
, 4, rs
, rt
, s
);
22630 if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
22632 ctx
->hflags
|= MIPS_HFLAG_FBNSLOT
;
22634 gen_compute_compact_branch_nm(ctx
, OPC_BLTC
, rs
, rt
, s
);
22638 if (rs
== 0 || rs
== rt
) {
22640 ctx
->hflags
|= MIPS_HFLAG_FBNSLOT
;
22642 gen_compute_compact_branch_nm(ctx
, OPC_BLTUC
, rs
, rt
, s
);
22646 generate_exception_end(ctx
, EXCP_RI
);
22653 int32_t s
= sextract32(ctx
->opcode
, 0, 1) << 11 |
22654 extract32(ctx
->opcode
, 1, 10) << 1;
22655 uint32_t u
= extract32(ctx
->opcode
, 11, 7);
22657 gen_compute_imm_branch(ctx
, extract32(ctx
->opcode
, 18, 3),
22662 generate_exception_end(ctx
, EXCP_RI
);
22668 static int decode_nanomips_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
22671 int rt
= decode_gpr_gpr3(NANOMIPS_EXTRACT_RT3(ctx
->opcode
));
22672 int rs
= decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx
->opcode
));
22673 int rd
= decode_gpr_gpr3(NANOMIPS_EXTRACT_RD3(ctx
->opcode
));
22677 /* make sure instructions are on a halfword boundary */
22678 if (ctx
->base
.pc_next
& 0x1) {
22679 TCGv tmp
= tcg_const_tl(ctx
->base
.pc_next
);
22680 tcg_gen_st_tl(tmp
, cpu_env
, offsetof(CPUMIPSState
, CP0_BadVAddr
));
22681 tcg_temp_free(tmp
);
22682 generate_exception_end(ctx
, EXCP_AdEL
);
22686 op
= extract32(ctx
->opcode
, 10, 6);
22689 rt
= NANOMIPS_EXTRACT_RD5(ctx
->opcode
);
22692 rs
= NANOMIPS_EXTRACT_RS5(ctx
->opcode
);
22693 gen_arith(ctx
, OPC_ADDU
, rt
, rs
, 0);
22696 switch (extract32(ctx
->opcode
, 3, 2)) {
22697 case NM_P16_SYSCALL
:
22698 if (extract32(ctx
->opcode
, 2, 1) == 0) {
22699 generate_exception_end(ctx
, EXCP_SYSCALL
);
22701 generate_exception_end(ctx
, EXCP_RI
);
22705 generate_exception_end(ctx
, EXCP_BREAK
);
22708 if (is_uhi(extract32(ctx
->opcode
, 0, 3))) {
22709 gen_helper_do_semihosting(cpu_env
);
22711 if (ctx
->hflags
& MIPS_HFLAG_SBRI
) {
22712 generate_exception_end(ctx
, EXCP_RI
);
22714 generate_exception_end(ctx
, EXCP_DBp
);
22719 generate_exception_end(ctx
, EXCP_RI
);
22726 int shift
= extract32(ctx
->opcode
, 0, 3);
22728 shift
= (shift
== 0) ? 8 : shift
;
22730 switch (extract32(ctx
->opcode
, 3, 1)) {
22738 gen_shift_imm(ctx
, opc
, rt
, rs
, shift
);
22742 switch (ctx
->opcode
& 1) {
22744 gen_pool16c_nanomips_insn(ctx
);
22747 gen_ldxs(ctx
, rt
, rs
, rd
);
22752 switch (extract32(ctx
->opcode
, 6, 1)) {
22754 imm
= extract32(ctx
->opcode
, 0, 6) << 2;
22755 gen_arith_imm(ctx
, OPC_ADDIU
, rt
, 29, imm
);
22758 generate_exception_end(ctx
, EXCP_RI
);
22763 switch (extract32(ctx
->opcode
, 3, 1)) {
22765 imm
= extract32(ctx
->opcode
, 0, 3) << 2;
22766 gen_arith_imm(ctx
, OPC_ADDIU
, rt
, rs
, imm
);
22768 case NM_P_ADDIURS5
:
22769 rt
= extract32(ctx
->opcode
, 5, 5);
22771 /* imm = sign_extend(s[3] . s[2:0] , from_nbits = 4) */
22772 imm
= (sextract32(ctx
->opcode
, 4, 1) << 3) |
22773 (extract32(ctx
->opcode
, 0, 3));
22774 gen_arith_imm(ctx
, OPC_ADDIU
, rt
, rt
, imm
);
22780 switch (ctx
->opcode
& 0x1) {
22782 gen_arith(ctx
, OPC_ADDU
, rd
, rs
, rt
);
22785 gen_arith(ctx
, OPC_SUBU
, rd
, rs
, rt
);
22790 rt
= (extract32(ctx
->opcode
, 9, 1) << 3) |
22791 extract32(ctx
->opcode
, 5, 3);
22792 rs
= (extract32(ctx
->opcode
, 4, 1) << 3) |
22793 extract32(ctx
->opcode
, 0, 3);
22794 rt
= decode_gpr_gpr4(rt
);
22795 rs
= decode_gpr_gpr4(rs
);
22796 switch ((extract32(ctx
->opcode
, 7, 2) & 0x2) |
22797 (extract32(ctx
->opcode
, 3, 1))) {
22800 gen_arith(ctx
, OPC_ADDU
, rt
, rs
, rt
);
22804 gen_r6_muldiv(ctx
, R6_OPC_MUL
, rt
, rs
, rt
);
22807 generate_exception_end(ctx
, EXCP_RI
);
22813 int imm
= extract32(ctx
->opcode
, 0, 7);
22814 imm
= (imm
== 0x7f ? -1 : imm
);
22816 tcg_gen_movi_tl(cpu_gpr
[rt
], imm
);
22822 uint32_t u
= extract32(ctx
->opcode
, 0, 4);
22823 u
= (u
== 12) ? 0xff :
22824 (u
== 13) ? 0xffff : u
;
22825 gen_logic_imm(ctx
, OPC_ANDI
, rt
, rs
, u
);
22829 offset
= extract32(ctx
->opcode
, 0, 2);
22830 switch (extract32(ctx
->opcode
, 2, 2)) {
22832 gen_ld(ctx
, OPC_LB
, rt
, rs
, offset
);
22835 rt
= decode_gpr_gpr3_src_store(
22836 NANOMIPS_EXTRACT_RT3(ctx
->opcode
));
22837 gen_st(ctx
, OPC_SB
, rt
, rs
, offset
);
22840 gen_ld(ctx
, OPC_LBU
, rt
, rs
, offset
);
22843 generate_exception_end(ctx
, EXCP_RI
);
22848 offset
= extract32(ctx
->opcode
, 1, 2) << 1;
22849 switch ((extract32(ctx
->opcode
, 3, 1) << 1) | (ctx
->opcode
& 1)) {
22851 gen_ld(ctx
, OPC_LH
, rt
, rs
, offset
);
22854 rt
= decode_gpr_gpr3_src_store(
22855 NANOMIPS_EXTRACT_RT3(ctx
->opcode
));
22856 gen_st(ctx
, OPC_SH
, rt
, rs
, offset
);
22859 gen_ld(ctx
, OPC_LHU
, rt
, rs
, offset
);
22862 generate_exception_end(ctx
, EXCP_RI
);
22867 offset
= extract32(ctx
->opcode
, 0, 4) << 2;
22868 gen_ld(ctx
, OPC_LW
, rt
, rs
, offset
);
22871 rt
= NANOMIPS_EXTRACT_RD5(ctx
->opcode
);
22872 offset
= extract32(ctx
->opcode
, 0, 5) << 2;
22873 gen_ld(ctx
, OPC_LW
, rt
, 29, offset
);
22877 rt
= (extract32(ctx
->opcode
, 9, 1) << 3) |
22878 extract32(ctx
->opcode
, 5, 3);
22879 rs
= (extract32(ctx
->opcode
, 4, 1) << 3) |
22880 extract32(ctx
->opcode
, 0, 3);
22881 offset
= (extract32(ctx
->opcode
, 3, 1) << 3) |
22882 (extract32(ctx
->opcode
, 8, 1) << 2);
22883 rt
= decode_gpr_gpr4(rt
);
22884 rs
= decode_gpr_gpr4(rs
);
22885 gen_ld(ctx
, OPC_LW
, rt
, rs
, offset
);
22889 rt
= (extract32(ctx
->opcode
, 9, 1) << 3) |
22890 extract32(ctx
->opcode
, 5, 3);
22891 rs
= (extract32(ctx
->opcode
, 4, 1) << 3) |
22892 extract32(ctx
->opcode
, 0, 3);
22893 offset
= (extract32(ctx
->opcode
, 3, 1) << 3) |
22894 (extract32(ctx
->opcode
, 8, 1) << 2);
22895 rt
= decode_gpr_gpr4_zero(rt
);
22896 rs
= decode_gpr_gpr4(rs
);
22897 gen_st(ctx
, OPC_SW
, rt
, rs
, offset
);
22900 offset
= extract32(ctx
->opcode
, 0, 7) << 2;
22901 gen_ld(ctx
, OPC_LW
, rt
, 28, offset
);
22904 rt
= NANOMIPS_EXTRACT_RD5(ctx
->opcode
);
22905 offset
= extract32(ctx
->opcode
, 0, 5) << 2;
22906 gen_st(ctx
, OPC_SW
, rt
, 29, offset
);
22909 rt
= decode_gpr_gpr3_src_store(
22910 NANOMIPS_EXTRACT_RT3(ctx
->opcode
));
22911 rs
= decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx
->opcode
));
22912 offset
= extract32(ctx
->opcode
, 0, 4) << 2;
22913 gen_st(ctx
, OPC_SW
, rt
, rs
, offset
);
22916 rt
= decode_gpr_gpr3_src_store(
22917 NANOMIPS_EXTRACT_RT3(ctx
->opcode
));
22918 offset
= extract32(ctx
->opcode
, 0, 7) << 2;
22919 gen_st(ctx
, OPC_SW
, rt
, 28, offset
);
22922 gen_compute_branch_nm(ctx
, OPC_BEQ
, 2, 0, 0,
22923 (sextract32(ctx
->opcode
, 0, 1) << 10) |
22924 (extract32(ctx
->opcode
, 1, 9) << 1));
22927 gen_compute_branch_nm(ctx
, OPC_BGEZAL
, 2, 0, 0,
22928 (sextract32(ctx
->opcode
, 0, 1) << 10) |
22929 (extract32(ctx
->opcode
, 1, 9) << 1));
22932 gen_compute_branch_nm(ctx
, OPC_BEQ
, 2, rt
, 0,
22933 (sextract32(ctx
->opcode
, 0, 1) << 7) |
22934 (extract32(ctx
->opcode
, 1, 6) << 1));
22937 gen_compute_branch_nm(ctx
, OPC_BNE
, 2, rt
, 0,
22938 (sextract32(ctx
->opcode
, 0, 1) << 7) |
22939 (extract32(ctx
->opcode
, 1, 6) << 1));
22942 switch (ctx
->opcode
& 0xf) {
22945 switch (extract32(ctx
->opcode
, 4, 1)) {
22947 gen_compute_branch_nm(ctx
, OPC_JR
, 2,
22948 extract32(ctx
->opcode
, 5, 5), 0, 0);
22951 gen_compute_branch_nm(ctx
, OPC_JALR
, 2,
22952 extract32(ctx
->opcode
, 5, 5), 31, 0);
22959 uint32_t opc
= extract32(ctx
->opcode
, 4, 3) <
22960 extract32(ctx
->opcode
, 7, 3) ? OPC_BEQ
: OPC_BNE
;
22961 gen_compute_branch_nm(ctx
, opc
, 2, rs
, rt
,
22962 extract32(ctx
->opcode
, 0, 4) << 1);
22969 int count
= extract32(ctx
->opcode
, 0, 4);
22970 int u
= extract32(ctx
->opcode
, 4, 4) << 4;
22972 rt
= 30 + extract32(ctx
->opcode
, 9, 1);
22973 switch (extract32(ctx
->opcode
, 8, 1)) {
22975 gen_save(ctx
, rt
, count
, 0, u
);
22977 case NM_RESTORE_JRC16
:
22978 gen_restore(ctx
, rt
, count
, 0, u
);
22979 gen_compute_branch_nm(ctx
, OPC_JR
, 2, 31, 0, 0);
22988 static const int gpr2reg1
[] = {4, 5, 6, 7};
22989 static const int gpr2reg2
[] = {5, 6, 7, 8};
22991 int rd2
= extract32(ctx
->opcode
, 3, 1) << 1 |
22992 extract32(ctx
->opcode
, 8, 1);
22993 int r1
= gpr2reg1
[rd2
];
22994 int r2
= gpr2reg2
[rd2
];
22995 int r3
= extract32(ctx
->opcode
, 4, 1) << 3 |
22996 extract32(ctx
->opcode
, 0, 3);
22997 int r4
= extract32(ctx
->opcode
, 9, 1) << 3 |
22998 extract32(ctx
->opcode
, 5, 3);
22999 TCGv t0
= tcg_temp_new();
23000 TCGv t1
= tcg_temp_new();
23001 if (op
== NM_MOVEP
) {
23004 rs
= decode_gpr_gpr4_zero(r3
);
23005 rt
= decode_gpr_gpr4_zero(r4
);
23007 rd
= decode_gpr_gpr4(r3
);
23008 re
= decode_gpr_gpr4(r4
);
23012 gen_load_gpr(t0
, rs
);
23013 gen_load_gpr(t1
, rt
);
23014 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
23015 tcg_gen_mov_tl(cpu_gpr
[re
], t1
);
23021 return decode_nanomips_32_48_opc(env
, ctx
);
23028 /* SmartMIPS extension to MIPS32 */
23030 #if defined(TARGET_MIPS64)
23032 /* MDMX extension to MIPS64 */
23036 /* MIPSDSP functions. */
23037 static void gen_mipsdsp_ld(DisasContext
*ctx
, uint32_t opc
,
23038 int rd
, int base
, int offset
)
23043 t0
= tcg_temp_new();
23046 gen_load_gpr(t0
, offset
);
23047 } else if (offset
== 0) {
23048 gen_load_gpr(t0
, base
);
23050 gen_op_addr_add(ctx
, t0
, cpu_gpr
[base
], cpu_gpr
[offset
]);
23055 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_UB
);
23056 gen_store_gpr(t0
, rd
);
23059 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESW
);
23060 gen_store_gpr(t0
, rd
);
23063 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESL
);
23064 gen_store_gpr(t0
, rd
);
23066 #if defined(TARGET_MIPS64)
23068 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
);
23069 gen_store_gpr(t0
, rd
);
23076 static void gen_mipsdsp_arith(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
23077 int ret
, int v1
, int v2
)
23083 /* Treat as NOP. */
23087 v1_t
= tcg_temp_new();
23088 v2_t
= tcg_temp_new();
23090 gen_load_gpr(v1_t
, v1
);
23091 gen_load_gpr(v2_t
, v2
);
23094 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
23095 case OPC_MULT_G_2E
:
23099 gen_helper_adduh_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
23101 case OPC_ADDUH_R_QB
:
23102 gen_helper_adduh_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
23105 gen_helper_addqh_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
23107 case OPC_ADDQH_R_PH
:
23108 gen_helper_addqh_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
23111 gen_helper_addqh_w(cpu_gpr
[ret
], v1_t
, v2_t
);
23113 case OPC_ADDQH_R_W
:
23114 gen_helper_addqh_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
23117 gen_helper_subuh_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
23119 case OPC_SUBUH_R_QB
:
23120 gen_helper_subuh_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
23123 gen_helper_subqh_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
23125 case OPC_SUBQH_R_PH
:
23126 gen_helper_subqh_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
23129 gen_helper_subqh_w(cpu_gpr
[ret
], v1_t
, v2_t
);
23131 case OPC_SUBQH_R_W
:
23132 gen_helper_subqh_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
23136 case OPC_ABSQ_S_PH_DSP
:
23138 case OPC_ABSQ_S_QB
:
23140 gen_helper_absq_s_qb(cpu_gpr
[ret
], v2_t
, cpu_env
);
23142 case OPC_ABSQ_S_PH
:
23144 gen_helper_absq_s_ph(cpu_gpr
[ret
], v2_t
, cpu_env
);
23148 gen_helper_absq_s_w(cpu_gpr
[ret
], v2_t
, cpu_env
);
23150 case OPC_PRECEQ_W_PHL
:
23152 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0xFFFF0000);
23153 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
23155 case OPC_PRECEQ_W_PHR
:
23157 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0x0000FFFF);
23158 tcg_gen_shli_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], 16);
23159 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
23161 case OPC_PRECEQU_PH_QBL
:
23163 gen_helper_precequ_ph_qbl(cpu_gpr
[ret
], v2_t
);
23165 case OPC_PRECEQU_PH_QBR
:
23167 gen_helper_precequ_ph_qbr(cpu_gpr
[ret
], v2_t
);
23169 case OPC_PRECEQU_PH_QBLA
:
23171 gen_helper_precequ_ph_qbla(cpu_gpr
[ret
], v2_t
);
23173 case OPC_PRECEQU_PH_QBRA
:
23175 gen_helper_precequ_ph_qbra(cpu_gpr
[ret
], v2_t
);
23177 case OPC_PRECEU_PH_QBL
:
23179 gen_helper_preceu_ph_qbl(cpu_gpr
[ret
], v2_t
);
23181 case OPC_PRECEU_PH_QBR
:
23183 gen_helper_preceu_ph_qbr(cpu_gpr
[ret
], v2_t
);
23185 case OPC_PRECEU_PH_QBLA
:
23187 gen_helper_preceu_ph_qbla(cpu_gpr
[ret
], v2_t
);
23189 case OPC_PRECEU_PH_QBRA
:
23191 gen_helper_preceu_ph_qbra(cpu_gpr
[ret
], v2_t
);
23195 case OPC_ADDU_QB_DSP
:
23199 gen_helper_addq_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23201 case OPC_ADDQ_S_PH
:
23203 gen_helper_addq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23207 gen_helper_addq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23211 gen_helper_addu_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23213 case OPC_ADDU_S_QB
:
23215 gen_helper_addu_s_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23219 gen_helper_addu_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23221 case OPC_ADDU_S_PH
:
23223 gen_helper_addu_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23227 gen_helper_subq_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23229 case OPC_SUBQ_S_PH
:
23231 gen_helper_subq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23235 gen_helper_subq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23239 gen_helper_subu_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23241 case OPC_SUBU_S_QB
:
23243 gen_helper_subu_s_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23247 gen_helper_subu_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23249 case OPC_SUBU_S_PH
:
23251 gen_helper_subu_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23255 gen_helper_addsc(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23259 gen_helper_addwc(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23263 gen_helper_modsub(cpu_gpr
[ret
], v1_t
, v2_t
);
23265 case OPC_RADDU_W_QB
:
23267 gen_helper_raddu_w_qb(cpu_gpr
[ret
], v1_t
);
23271 case OPC_CMPU_EQ_QB_DSP
:
23273 case OPC_PRECR_QB_PH
:
23275 gen_helper_precr_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
23277 case OPC_PRECRQ_QB_PH
:
23279 gen_helper_precrq_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
23281 case OPC_PRECR_SRA_PH_W
:
23284 TCGv_i32 sa_t
= tcg_const_i32(v2
);
23285 gen_helper_precr_sra_ph_w(cpu_gpr
[ret
], sa_t
, v1_t
,
23287 tcg_temp_free_i32(sa_t
);
23290 case OPC_PRECR_SRA_R_PH_W
:
23293 TCGv_i32 sa_t
= tcg_const_i32(v2
);
23294 gen_helper_precr_sra_r_ph_w(cpu_gpr
[ret
], sa_t
, v1_t
,
23296 tcg_temp_free_i32(sa_t
);
23299 case OPC_PRECRQ_PH_W
:
23301 gen_helper_precrq_ph_w(cpu_gpr
[ret
], v1_t
, v2_t
);
23303 case OPC_PRECRQ_RS_PH_W
:
23305 gen_helper_precrq_rs_ph_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23307 case OPC_PRECRQU_S_QB_PH
:
23309 gen_helper_precrqu_s_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23313 #ifdef TARGET_MIPS64
23314 case OPC_ABSQ_S_QH_DSP
:
23316 case OPC_PRECEQ_L_PWL
:
23318 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0xFFFFFFFF00000000ull
);
23320 case OPC_PRECEQ_L_PWR
:
23322 tcg_gen_shli_tl(cpu_gpr
[ret
], v2_t
, 32);
23324 case OPC_PRECEQ_PW_QHL
:
23326 gen_helper_preceq_pw_qhl(cpu_gpr
[ret
], v2_t
);
23328 case OPC_PRECEQ_PW_QHR
:
23330 gen_helper_preceq_pw_qhr(cpu_gpr
[ret
], v2_t
);
23332 case OPC_PRECEQ_PW_QHLA
:
23334 gen_helper_preceq_pw_qhla(cpu_gpr
[ret
], v2_t
);
23336 case OPC_PRECEQ_PW_QHRA
:
23338 gen_helper_preceq_pw_qhra(cpu_gpr
[ret
], v2_t
);
23340 case OPC_PRECEQU_QH_OBL
:
23342 gen_helper_precequ_qh_obl(cpu_gpr
[ret
], v2_t
);
23344 case OPC_PRECEQU_QH_OBR
:
23346 gen_helper_precequ_qh_obr(cpu_gpr
[ret
], v2_t
);
23348 case OPC_PRECEQU_QH_OBLA
:
23350 gen_helper_precequ_qh_obla(cpu_gpr
[ret
], v2_t
);
23352 case OPC_PRECEQU_QH_OBRA
:
23354 gen_helper_precequ_qh_obra(cpu_gpr
[ret
], v2_t
);
23356 case OPC_PRECEU_QH_OBL
:
23358 gen_helper_preceu_qh_obl(cpu_gpr
[ret
], v2_t
);
23360 case OPC_PRECEU_QH_OBR
:
23362 gen_helper_preceu_qh_obr(cpu_gpr
[ret
], v2_t
);
23364 case OPC_PRECEU_QH_OBLA
:
23366 gen_helper_preceu_qh_obla(cpu_gpr
[ret
], v2_t
);
23368 case OPC_PRECEU_QH_OBRA
:
23370 gen_helper_preceu_qh_obra(cpu_gpr
[ret
], v2_t
);
23372 case OPC_ABSQ_S_OB
:
23374 gen_helper_absq_s_ob(cpu_gpr
[ret
], v2_t
, cpu_env
);
23376 case OPC_ABSQ_S_PW
:
23378 gen_helper_absq_s_pw(cpu_gpr
[ret
], v2_t
, cpu_env
);
23380 case OPC_ABSQ_S_QH
:
23382 gen_helper_absq_s_qh(cpu_gpr
[ret
], v2_t
, cpu_env
);
23386 case OPC_ADDU_OB_DSP
:
23388 case OPC_RADDU_L_OB
:
23390 gen_helper_raddu_l_ob(cpu_gpr
[ret
], v1_t
);
23394 gen_helper_subq_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23396 case OPC_SUBQ_S_PW
:
23398 gen_helper_subq_s_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23402 gen_helper_subq_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23404 case OPC_SUBQ_S_QH
:
23406 gen_helper_subq_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23410 gen_helper_subu_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23412 case OPC_SUBU_S_OB
:
23414 gen_helper_subu_s_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23418 gen_helper_subu_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23420 case OPC_SUBU_S_QH
:
23422 gen_helper_subu_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23426 gen_helper_subuh_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
23428 case OPC_SUBUH_R_OB
:
23430 gen_helper_subuh_r_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
23434 gen_helper_addq_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23436 case OPC_ADDQ_S_PW
:
23438 gen_helper_addq_s_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23442 gen_helper_addq_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23444 case OPC_ADDQ_S_QH
:
23446 gen_helper_addq_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23450 gen_helper_addu_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23452 case OPC_ADDU_S_OB
:
23454 gen_helper_addu_s_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23458 gen_helper_addu_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23460 case OPC_ADDU_S_QH
:
23462 gen_helper_addu_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23466 gen_helper_adduh_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
23468 case OPC_ADDUH_R_OB
:
23470 gen_helper_adduh_r_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
23474 case OPC_CMPU_EQ_OB_DSP
:
23476 case OPC_PRECR_OB_QH
:
23478 gen_helper_precr_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
);
23480 case OPC_PRECR_SRA_QH_PW
:
23483 TCGv_i32 ret_t
= tcg_const_i32(ret
);
23484 gen_helper_precr_sra_qh_pw(v2_t
, v1_t
, v2_t
, ret_t
);
23485 tcg_temp_free_i32(ret_t
);
23488 case OPC_PRECR_SRA_R_QH_PW
:
23491 TCGv_i32 sa_v
= tcg_const_i32(ret
);
23492 gen_helper_precr_sra_r_qh_pw(v2_t
, v1_t
, v2_t
, sa_v
);
23493 tcg_temp_free_i32(sa_v
);
23496 case OPC_PRECRQ_OB_QH
:
23498 gen_helper_precrq_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
);
23500 case OPC_PRECRQ_PW_L
:
23502 gen_helper_precrq_pw_l(cpu_gpr
[ret
], v1_t
, v2_t
);
23504 case OPC_PRECRQ_QH_PW
:
23506 gen_helper_precrq_qh_pw(cpu_gpr
[ret
], v1_t
, v2_t
);
23508 case OPC_PRECRQ_RS_QH_PW
:
23510 gen_helper_precrq_rs_qh_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23512 case OPC_PRECRQU_S_OB_QH
:
23514 gen_helper_precrqu_s_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23521 tcg_temp_free(v1_t
);
23522 tcg_temp_free(v2_t
);
23525 static void gen_mipsdsp_shift(DisasContext
*ctx
, uint32_t opc
,
23526 int ret
, int v1
, int v2
)
23534 /* Treat as NOP. */
23538 t0
= tcg_temp_new();
23539 v1_t
= tcg_temp_new();
23540 v2_t
= tcg_temp_new();
23542 tcg_gen_movi_tl(t0
, v1
);
23543 gen_load_gpr(v1_t
, v1
);
23544 gen_load_gpr(v2_t
, v2
);
23547 case OPC_SHLL_QB_DSP
:
23549 op2
= MASK_SHLL_QB(ctx
->opcode
);
23553 gen_helper_shll_qb(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
23557 gen_helper_shll_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23561 gen_helper_shll_ph(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
23565 gen_helper_shll_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23567 case OPC_SHLL_S_PH
:
23569 gen_helper_shll_s_ph(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
23571 case OPC_SHLLV_S_PH
:
23573 gen_helper_shll_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23577 gen_helper_shll_s_w(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
23579 case OPC_SHLLV_S_W
:
23581 gen_helper_shll_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23585 gen_helper_shrl_qb(cpu_gpr
[ret
], t0
, v2_t
);
23589 gen_helper_shrl_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
23593 gen_helper_shrl_ph(cpu_gpr
[ret
], t0
, v2_t
);
23597 gen_helper_shrl_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
23601 gen_helper_shra_qb(cpu_gpr
[ret
], t0
, v2_t
);
23603 case OPC_SHRA_R_QB
:
23605 gen_helper_shra_r_qb(cpu_gpr
[ret
], t0
, v2_t
);
23609 gen_helper_shra_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
23611 case OPC_SHRAV_R_QB
:
23613 gen_helper_shra_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
23617 gen_helper_shra_ph(cpu_gpr
[ret
], t0
, v2_t
);
23619 case OPC_SHRA_R_PH
:
23621 gen_helper_shra_r_ph(cpu_gpr
[ret
], t0
, v2_t
);
23625 gen_helper_shra_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
23627 case OPC_SHRAV_R_PH
:
23629 gen_helper_shra_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
23633 gen_helper_shra_r_w(cpu_gpr
[ret
], t0
, v2_t
);
23635 case OPC_SHRAV_R_W
:
23637 gen_helper_shra_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
23639 default: /* Invalid */
23640 MIPS_INVAL("MASK SHLL.QB");
23641 generate_exception_end(ctx
, EXCP_RI
);
23646 #ifdef TARGET_MIPS64
23647 case OPC_SHLL_OB_DSP
:
23648 op2
= MASK_SHLL_OB(ctx
->opcode
);
23652 gen_helper_shll_pw(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
23656 gen_helper_shll_pw(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
23658 case OPC_SHLL_S_PW
:
23660 gen_helper_shll_s_pw(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
23662 case OPC_SHLLV_S_PW
:
23664 gen_helper_shll_s_pw(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
23668 gen_helper_shll_ob(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
23672 gen_helper_shll_ob(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
23676 gen_helper_shll_qh(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
23680 gen_helper_shll_qh(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
23682 case OPC_SHLL_S_QH
:
23684 gen_helper_shll_s_qh(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
23686 case OPC_SHLLV_S_QH
:
23688 gen_helper_shll_s_qh(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
23692 gen_helper_shra_ob(cpu_gpr
[ret
], v2_t
, t0
);
23696 gen_helper_shra_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
23698 case OPC_SHRA_R_OB
:
23700 gen_helper_shra_r_ob(cpu_gpr
[ret
], v2_t
, t0
);
23702 case OPC_SHRAV_R_OB
:
23704 gen_helper_shra_r_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
23708 gen_helper_shra_pw(cpu_gpr
[ret
], v2_t
, t0
);
23712 gen_helper_shra_pw(cpu_gpr
[ret
], v2_t
, v1_t
);
23714 case OPC_SHRA_R_PW
:
23716 gen_helper_shra_r_pw(cpu_gpr
[ret
], v2_t
, t0
);
23718 case OPC_SHRAV_R_PW
:
23720 gen_helper_shra_r_pw(cpu_gpr
[ret
], v2_t
, v1_t
);
23724 gen_helper_shra_qh(cpu_gpr
[ret
], v2_t
, t0
);
23728 gen_helper_shra_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
23730 case OPC_SHRA_R_QH
:
23732 gen_helper_shra_r_qh(cpu_gpr
[ret
], v2_t
, t0
);
23734 case OPC_SHRAV_R_QH
:
23736 gen_helper_shra_r_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
23740 gen_helper_shrl_ob(cpu_gpr
[ret
], v2_t
, t0
);
23744 gen_helper_shrl_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
23748 gen_helper_shrl_qh(cpu_gpr
[ret
], v2_t
, t0
);
23752 gen_helper_shrl_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
23754 default: /* Invalid */
23755 MIPS_INVAL("MASK SHLL.OB");
23756 generate_exception_end(ctx
, EXCP_RI
);
23764 tcg_temp_free(v1_t
);
23765 tcg_temp_free(v2_t
);
23768 static void gen_mipsdsp_multiply(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
23769 int ret
, int v1
, int v2
, int check_ret
)
23775 if ((ret
== 0) && (check_ret
== 1)) {
23776 /* Treat as NOP. */
23780 t0
= tcg_temp_new_i32();
23781 v1_t
= tcg_temp_new();
23782 v2_t
= tcg_temp_new();
23784 tcg_gen_movi_i32(t0
, ret
);
23785 gen_load_gpr(v1_t
, v1
);
23786 gen_load_gpr(v2_t
, v2
);
23790 * OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
23791 * the same mask and op1.
23793 case OPC_MULT_G_2E
:
23797 gen_helper_mul_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23800 gen_helper_mul_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23803 gen_helper_mulq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23805 case OPC_MULQ_RS_W
:
23806 gen_helper_mulq_rs_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23810 case OPC_DPA_W_PH_DSP
:
23812 case OPC_DPAU_H_QBL
:
23814 gen_helper_dpau_h_qbl(t0
, v1_t
, v2_t
, cpu_env
);
23816 case OPC_DPAU_H_QBR
:
23818 gen_helper_dpau_h_qbr(t0
, v1_t
, v2_t
, cpu_env
);
23820 case OPC_DPSU_H_QBL
:
23822 gen_helper_dpsu_h_qbl(t0
, v1_t
, v2_t
, cpu_env
);
23824 case OPC_DPSU_H_QBR
:
23826 gen_helper_dpsu_h_qbr(t0
, v1_t
, v2_t
, cpu_env
);
23830 gen_helper_dpa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23832 case OPC_DPAX_W_PH
:
23834 gen_helper_dpax_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23836 case OPC_DPAQ_S_W_PH
:
23838 gen_helper_dpaq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23840 case OPC_DPAQX_S_W_PH
:
23842 gen_helper_dpaqx_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23844 case OPC_DPAQX_SA_W_PH
:
23846 gen_helper_dpaqx_sa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23850 gen_helper_dps_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23852 case OPC_DPSX_W_PH
:
23854 gen_helper_dpsx_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23856 case OPC_DPSQ_S_W_PH
:
23858 gen_helper_dpsq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23860 case OPC_DPSQX_S_W_PH
:
23862 gen_helper_dpsqx_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23864 case OPC_DPSQX_SA_W_PH
:
23866 gen_helper_dpsqx_sa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23868 case OPC_MULSAQ_S_W_PH
:
23870 gen_helper_mulsaq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23872 case OPC_DPAQ_SA_L_W
:
23874 gen_helper_dpaq_sa_l_w(t0
, v1_t
, v2_t
, cpu_env
);
23876 case OPC_DPSQ_SA_L_W
:
23878 gen_helper_dpsq_sa_l_w(t0
, v1_t
, v2_t
, cpu_env
);
23880 case OPC_MAQ_S_W_PHL
:
23882 gen_helper_maq_s_w_phl(t0
, v1_t
, v2_t
, cpu_env
);
23884 case OPC_MAQ_S_W_PHR
:
23886 gen_helper_maq_s_w_phr(t0
, v1_t
, v2_t
, cpu_env
);
23888 case OPC_MAQ_SA_W_PHL
:
23890 gen_helper_maq_sa_w_phl(t0
, v1_t
, v2_t
, cpu_env
);
23892 case OPC_MAQ_SA_W_PHR
:
23894 gen_helper_maq_sa_w_phr(t0
, v1_t
, v2_t
, cpu_env
);
23896 case OPC_MULSA_W_PH
:
23898 gen_helper_mulsa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23902 #ifdef TARGET_MIPS64
23903 case OPC_DPAQ_W_QH_DSP
:
23905 int ac
= ret
& 0x03;
23906 tcg_gen_movi_i32(t0
, ac
);
23911 gen_helper_dmadd(v1_t
, v2_t
, t0
, cpu_env
);
23915 gen_helper_dmaddu(v1_t
, v2_t
, t0
, cpu_env
);
23919 gen_helper_dmsub(v1_t
, v2_t
, t0
, cpu_env
);
23923 gen_helper_dmsubu(v1_t
, v2_t
, t0
, cpu_env
);
23927 gen_helper_dpa_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
23929 case OPC_DPAQ_S_W_QH
:
23931 gen_helper_dpaq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
23933 case OPC_DPAQ_SA_L_PW
:
23935 gen_helper_dpaq_sa_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
23937 case OPC_DPAU_H_OBL
:
23939 gen_helper_dpau_h_obl(v1_t
, v2_t
, t0
, cpu_env
);
23941 case OPC_DPAU_H_OBR
:
23943 gen_helper_dpau_h_obr(v1_t
, v2_t
, t0
, cpu_env
);
23947 gen_helper_dps_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
23949 case OPC_DPSQ_S_W_QH
:
23951 gen_helper_dpsq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
23953 case OPC_DPSQ_SA_L_PW
:
23955 gen_helper_dpsq_sa_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
23957 case OPC_DPSU_H_OBL
:
23959 gen_helper_dpsu_h_obl(v1_t
, v2_t
, t0
, cpu_env
);
23961 case OPC_DPSU_H_OBR
:
23963 gen_helper_dpsu_h_obr(v1_t
, v2_t
, t0
, cpu_env
);
23965 case OPC_MAQ_S_L_PWL
:
23967 gen_helper_maq_s_l_pwl(v1_t
, v2_t
, t0
, cpu_env
);
23969 case OPC_MAQ_S_L_PWR
:
23971 gen_helper_maq_s_l_pwr(v1_t
, v2_t
, t0
, cpu_env
);
23973 case OPC_MAQ_S_W_QHLL
:
23975 gen_helper_maq_s_w_qhll(v1_t
, v2_t
, t0
, cpu_env
);
23977 case OPC_MAQ_SA_W_QHLL
:
23979 gen_helper_maq_sa_w_qhll(v1_t
, v2_t
, t0
, cpu_env
);
23981 case OPC_MAQ_S_W_QHLR
:
23983 gen_helper_maq_s_w_qhlr(v1_t
, v2_t
, t0
, cpu_env
);
23985 case OPC_MAQ_SA_W_QHLR
:
23987 gen_helper_maq_sa_w_qhlr(v1_t
, v2_t
, t0
, cpu_env
);
23989 case OPC_MAQ_S_W_QHRL
:
23991 gen_helper_maq_s_w_qhrl(v1_t
, v2_t
, t0
, cpu_env
);
23993 case OPC_MAQ_SA_W_QHRL
:
23995 gen_helper_maq_sa_w_qhrl(v1_t
, v2_t
, t0
, cpu_env
);
23997 case OPC_MAQ_S_W_QHRR
:
23999 gen_helper_maq_s_w_qhrr(v1_t
, v2_t
, t0
, cpu_env
);
24001 case OPC_MAQ_SA_W_QHRR
:
24003 gen_helper_maq_sa_w_qhrr(v1_t
, v2_t
, t0
, cpu_env
);
24005 case OPC_MULSAQ_S_L_PW
:
24007 gen_helper_mulsaq_s_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
24009 case OPC_MULSAQ_S_W_QH
:
24011 gen_helper_mulsaq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
24017 case OPC_ADDU_QB_DSP
:
24019 case OPC_MULEU_S_PH_QBL
:
24021 gen_helper_muleu_s_ph_qbl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
24023 case OPC_MULEU_S_PH_QBR
:
24025 gen_helper_muleu_s_ph_qbr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
24027 case OPC_MULQ_RS_PH
:
24029 gen_helper_mulq_rs_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
24031 case OPC_MULEQ_S_W_PHL
:
24033 gen_helper_muleq_s_w_phl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
24035 case OPC_MULEQ_S_W_PHR
:
24037 gen_helper_muleq_s_w_phr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
24039 case OPC_MULQ_S_PH
:
24041 gen_helper_mulq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
24045 #ifdef TARGET_MIPS64
24046 case OPC_ADDU_OB_DSP
:
24048 case OPC_MULEQ_S_PW_QHL
:
24050 gen_helper_muleq_s_pw_qhl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
24052 case OPC_MULEQ_S_PW_QHR
:
24054 gen_helper_muleq_s_pw_qhr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
24056 case OPC_MULEU_S_QH_OBL
:
24058 gen_helper_muleu_s_qh_obl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
24060 case OPC_MULEU_S_QH_OBR
:
24062 gen_helper_muleu_s_qh_obr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
24064 case OPC_MULQ_RS_QH
:
24066 gen_helper_mulq_rs_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
24073 tcg_temp_free_i32(t0
);
24074 tcg_temp_free(v1_t
);
24075 tcg_temp_free(v2_t
);
24078 static void gen_mipsdsp_bitinsn(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
24086 /* Treat as NOP. */
24090 t0
= tcg_temp_new();
24091 val_t
= tcg_temp_new();
24092 gen_load_gpr(val_t
, val
);
24095 case OPC_ABSQ_S_PH_DSP
:
24099 gen_helper_bitrev(cpu_gpr
[ret
], val_t
);
24104 target_long result
;
24105 imm
= (ctx
->opcode
>> 16) & 0xFF;
24106 result
= (uint32_t)imm
<< 24 |
24107 (uint32_t)imm
<< 16 |
24108 (uint32_t)imm
<< 8 |
24110 result
= (int32_t)result
;
24111 tcg_gen_movi_tl(cpu_gpr
[ret
], result
);
24116 tcg_gen_ext8u_tl(cpu_gpr
[ret
], val_t
);
24117 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 8);
24118 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
24119 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
24120 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
24121 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
24126 imm
= (ctx
->opcode
>> 16) & 0x03FF;
24127 imm
= (int16_t)(imm
<< 6) >> 6;
24128 tcg_gen_movi_tl(cpu_gpr
[ret
], \
24129 (target_long
)((int32_t)imm
<< 16 | \
24135 tcg_gen_ext16u_tl(cpu_gpr
[ret
], val_t
);
24136 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
24137 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
24138 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
24142 #ifdef TARGET_MIPS64
24143 case OPC_ABSQ_S_QH_DSP
:
24150 imm
= (ctx
->opcode
>> 16) & 0xFF;
24151 temp
= ((uint64_t)imm
<< 8) | (uint64_t)imm
;
24152 temp
= (temp
<< 16) | temp
;
24153 temp
= (temp
<< 32) | temp
;
24154 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
24162 imm
= (ctx
->opcode
>> 16) & 0x03FF;
24163 imm
= (int16_t)(imm
<< 6) >> 6;
24164 temp
= ((target_long
)imm
<< 32) \
24165 | ((target_long
)imm
& 0xFFFFFFFF);
24166 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
24174 imm
= (ctx
->opcode
>> 16) & 0x03FF;
24175 imm
= (int16_t)(imm
<< 6) >> 6;
24177 temp
= ((uint64_t)(uint16_t)imm
<< 48) |
24178 ((uint64_t)(uint16_t)imm
<< 32) |
24179 ((uint64_t)(uint16_t)imm
<< 16) |
24180 (uint64_t)(uint16_t)imm
;
24181 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
24186 tcg_gen_ext8u_tl(cpu_gpr
[ret
], val_t
);
24187 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 8);
24188 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
24189 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
24190 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
24191 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
24192 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
24196 tcg_gen_ext32u_i64(cpu_gpr
[ret
], val_t
);
24197 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
24198 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
24202 tcg_gen_ext16u_tl(cpu_gpr
[ret
], val_t
);
24203 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
24204 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
24205 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
24206 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
24213 tcg_temp_free(val_t
);
24216 static void gen_mipsdsp_add_cmp_pick(DisasContext
*ctx
,
24217 uint32_t op1
, uint32_t op2
,
24218 int ret
, int v1
, int v2
, int check_ret
)
24224 if ((ret
== 0) && (check_ret
== 1)) {
24225 /* Treat as NOP. */
24229 t1
= tcg_temp_new();
24230 v1_t
= tcg_temp_new();
24231 v2_t
= tcg_temp_new();
24233 gen_load_gpr(v1_t
, v1
);
24234 gen_load_gpr(v2_t
, v2
);
24237 case OPC_CMPU_EQ_QB_DSP
:
24239 case OPC_CMPU_EQ_QB
:
24241 gen_helper_cmpu_eq_qb(v1_t
, v2_t
, cpu_env
);
24243 case OPC_CMPU_LT_QB
:
24245 gen_helper_cmpu_lt_qb(v1_t
, v2_t
, cpu_env
);
24247 case OPC_CMPU_LE_QB
:
24249 gen_helper_cmpu_le_qb(v1_t
, v2_t
, cpu_env
);
24251 case OPC_CMPGU_EQ_QB
:
24253 gen_helper_cmpgu_eq_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
24255 case OPC_CMPGU_LT_QB
:
24257 gen_helper_cmpgu_lt_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
24259 case OPC_CMPGU_LE_QB
:
24261 gen_helper_cmpgu_le_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
24263 case OPC_CMPGDU_EQ_QB
:
24265 gen_helper_cmpgu_eq_qb(t1
, v1_t
, v2_t
);
24266 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
24267 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
24268 tcg_gen_shli_tl(t1
, t1
, 24);
24269 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
24271 case OPC_CMPGDU_LT_QB
:
24273 gen_helper_cmpgu_lt_qb(t1
, v1_t
, v2_t
);
24274 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
24275 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
24276 tcg_gen_shli_tl(t1
, t1
, 24);
24277 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
24279 case OPC_CMPGDU_LE_QB
:
24281 gen_helper_cmpgu_le_qb(t1
, v1_t
, v2_t
);
24282 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
24283 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
24284 tcg_gen_shli_tl(t1
, t1
, 24);
24285 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
24287 case OPC_CMP_EQ_PH
:
24289 gen_helper_cmp_eq_ph(v1_t
, v2_t
, cpu_env
);
24291 case OPC_CMP_LT_PH
:
24293 gen_helper_cmp_lt_ph(v1_t
, v2_t
, cpu_env
);
24295 case OPC_CMP_LE_PH
:
24297 gen_helper_cmp_le_ph(v1_t
, v2_t
, cpu_env
);
24301 gen_helper_pick_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
24305 gen_helper_pick_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
24307 case OPC_PACKRL_PH
:
24309 gen_helper_packrl_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
24313 #ifdef TARGET_MIPS64
24314 case OPC_CMPU_EQ_OB_DSP
:
24316 case OPC_CMP_EQ_PW
:
24318 gen_helper_cmp_eq_pw(v1_t
, v2_t
, cpu_env
);
24320 case OPC_CMP_LT_PW
:
24322 gen_helper_cmp_lt_pw(v1_t
, v2_t
, cpu_env
);
24324 case OPC_CMP_LE_PW
:
24326 gen_helper_cmp_le_pw(v1_t
, v2_t
, cpu_env
);
24328 case OPC_CMP_EQ_QH
:
24330 gen_helper_cmp_eq_qh(v1_t
, v2_t
, cpu_env
);
24332 case OPC_CMP_LT_QH
:
24334 gen_helper_cmp_lt_qh(v1_t
, v2_t
, cpu_env
);
24336 case OPC_CMP_LE_QH
:
24338 gen_helper_cmp_le_qh(v1_t
, v2_t
, cpu_env
);
24340 case OPC_CMPGDU_EQ_OB
:
24342 gen_helper_cmpgdu_eq_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
24344 case OPC_CMPGDU_LT_OB
:
24346 gen_helper_cmpgdu_lt_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
24348 case OPC_CMPGDU_LE_OB
:
24350 gen_helper_cmpgdu_le_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
24352 case OPC_CMPGU_EQ_OB
:
24354 gen_helper_cmpgu_eq_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
24356 case OPC_CMPGU_LT_OB
:
24358 gen_helper_cmpgu_lt_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
24360 case OPC_CMPGU_LE_OB
:
24362 gen_helper_cmpgu_le_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
24364 case OPC_CMPU_EQ_OB
:
24366 gen_helper_cmpu_eq_ob(v1_t
, v2_t
, cpu_env
);
24368 case OPC_CMPU_LT_OB
:
24370 gen_helper_cmpu_lt_ob(v1_t
, v2_t
, cpu_env
);
24372 case OPC_CMPU_LE_OB
:
24374 gen_helper_cmpu_le_ob(v1_t
, v2_t
, cpu_env
);
24376 case OPC_PACKRL_PW
:
24378 gen_helper_packrl_pw(cpu_gpr
[ret
], v1_t
, v2_t
);
24382 gen_helper_pick_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
24386 gen_helper_pick_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
24390 gen_helper_pick_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
24398 tcg_temp_free(v1_t
);
24399 tcg_temp_free(v2_t
);
24402 static void gen_mipsdsp_append(CPUMIPSState
*env
, DisasContext
*ctx
,
24403 uint32_t op1
, int rt
, int rs
, int sa
)
24410 /* Treat as NOP. */
24414 t0
= tcg_temp_new();
24415 gen_load_gpr(t0
, rs
);
24418 case OPC_APPEND_DSP
:
24419 switch (MASK_APPEND(ctx
->opcode
)) {
24422 tcg_gen_deposit_tl(cpu_gpr
[rt
], t0
, cpu_gpr
[rt
], sa
, 32 - sa
);
24424 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
24428 tcg_gen_ext32u_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
24429 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], sa
);
24430 tcg_gen_shli_tl(t0
, t0
, 32 - sa
);
24431 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
24433 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
24437 if (sa
!= 0 && sa
!= 2) {
24438 tcg_gen_shli_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 8 * sa
);
24439 tcg_gen_ext32u_tl(t0
, t0
);
24440 tcg_gen_shri_tl(t0
, t0
, 8 * (4 - sa
));
24441 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
24443 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
24445 default: /* Invalid */
24446 MIPS_INVAL("MASK APPEND");
24447 generate_exception_end(ctx
, EXCP_RI
);
24451 #ifdef TARGET_MIPS64
24452 case OPC_DAPPEND_DSP
:
24453 switch (MASK_DAPPEND(ctx
->opcode
)) {
24456 tcg_gen_deposit_tl(cpu_gpr
[rt
], t0
, cpu_gpr
[rt
], sa
, 64 - sa
);
24460 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 0x20 | sa
);
24461 tcg_gen_shli_tl(t0
, t0
, 64 - (0x20 | sa
));
24462 tcg_gen_or_tl(cpu_gpr
[rt
], t0
, t0
);
24466 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], sa
);
24467 tcg_gen_shli_tl(t0
, t0
, 64 - sa
);
24468 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
24473 if (sa
!= 0 && sa
!= 2 && sa
!= 4) {
24474 tcg_gen_shli_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 8 * sa
);
24475 tcg_gen_shri_tl(t0
, t0
, 8 * (8 - sa
));
24476 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
24479 default: /* Invalid */
24480 MIPS_INVAL("MASK DAPPEND");
24481 generate_exception_end(ctx
, EXCP_RI
);
24490 static void gen_mipsdsp_accinsn(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
24491 int ret
, int v1
, int v2
, int check_ret
)
24500 if ((ret
== 0) && (check_ret
== 1)) {
24501 /* Treat as NOP. */
24505 t0
= tcg_temp_new();
24506 t1
= tcg_temp_new();
24507 v1_t
= tcg_temp_new();
24508 v2_t
= tcg_temp_new();
24510 gen_load_gpr(v1_t
, v1
);
24511 gen_load_gpr(v2_t
, v2
);
24514 case OPC_EXTR_W_DSP
:
24518 tcg_gen_movi_tl(t0
, v2
);
24519 tcg_gen_movi_tl(t1
, v1
);
24520 gen_helper_extr_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24523 tcg_gen_movi_tl(t0
, v2
);
24524 tcg_gen_movi_tl(t1
, v1
);
24525 gen_helper_extr_r_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24527 case OPC_EXTR_RS_W
:
24528 tcg_gen_movi_tl(t0
, v2
);
24529 tcg_gen_movi_tl(t1
, v1
);
24530 gen_helper_extr_rs_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24533 tcg_gen_movi_tl(t0
, v2
);
24534 tcg_gen_movi_tl(t1
, v1
);
24535 gen_helper_extr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24537 case OPC_EXTRV_S_H
:
24538 tcg_gen_movi_tl(t0
, v2
);
24539 gen_helper_extr_s_h(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24542 tcg_gen_movi_tl(t0
, v2
);
24543 gen_helper_extr_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24545 case OPC_EXTRV_R_W
:
24546 tcg_gen_movi_tl(t0
, v2
);
24547 gen_helper_extr_r_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24549 case OPC_EXTRV_RS_W
:
24550 tcg_gen_movi_tl(t0
, v2
);
24551 gen_helper_extr_rs_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24554 tcg_gen_movi_tl(t0
, v2
);
24555 tcg_gen_movi_tl(t1
, v1
);
24556 gen_helper_extp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24559 tcg_gen_movi_tl(t0
, v2
);
24560 gen_helper_extp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24563 tcg_gen_movi_tl(t0
, v2
);
24564 tcg_gen_movi_tl(t1
, v1
);
24565 gen_helper_extpdp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24568 tcg_gen_movi_tl(t0
, v2
);
24569 gen_helper_extpdp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24572 imm
= (ctx
->opcode
>> 20) & 0x3F;
24573 tcg_gen_movi_tl(t0
, ret
);
24574 tcg_gen_movi_tl(t1
, imm
);
24575 gen_helper_shilo(t0
, t1
, cpu_env
);
24578 tcg_gen_movi_tl(t0
, ret
);
24579 gen_helper_shilo(t0
, v1_t
, cpu_env
);
24582 tcg_gen_movi_tl(t0
, ret
);
24583 gen_helper_mthlip(t0
, v1_t
, cpu_env
);
24586 imm
= (ctx
->opcode
>> 11) & 0x3FF;
24587 tcg_gen_movi_tl(t0
, imm
);
24588 gen_helper_wrdsp(v1_t
, t0
, cpu_env
);
24591 imm
= (ctx
->opcode
>> 16) & 0x03FF;
24592 tcg_gen_movi_tl(t0
, imm
);
24593 gen_helper_rddsp(cpu_gpr
[ret
], t0
, cpu_env
);
24597 #ifdef TARGET_MIPS64
24598 case OPC_DEXTR_W_DSP
:
24602 tcg_gen_movi_tl(t0
, ret
);
24603 gen_helper_dmthlip(v1_t
, t0
, cpu_env
);
24607 int shift
= (ctx
->opcode
>> 19) & 0x7F;
24608 int ac
= (ctx
->opcode
>> 11) & 0x03;
24609 tcg_gen_movi_tl(t0
, shift
);
24610 tcg_gen_movi_tl(t1
, ac
);
24611 gen_helper_dshilo(t0
, t1
, cpu_env
);
24616 int ac
= (ctx
->opcode
>> 11) & 0x03;
24617 tcg_gen_movi_tl(t0
, ac
);
24618 gen_helper_dshilo(v1_t
, t0
, cpu_env
);
24622 tcg_gen_movi_tl(t0
, v2
);
24623 tcg_gen_movi_tl(t1
, v1
);
24625 gen_helper_dextp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24628 tcg_gen_movi_tl(t0
, v2
);
24629 gen_helper_dextp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24632 tcg_gen_movi_tl(t0
, v2
);
24633 tcg_gen_movi_tl(t1
, v1
);
24634 gen_helper_dextpdp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24637 tcg_gen_movi_tl(t0
, v2
);
24638 gen_helper_dextpdp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24641 tcg_gen_movi_tl(t0
, v2
);
24642 tcg_gen_movi_tl(t1
, v1
);
24643 gen_helper_dextr_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24645 case OPC_DEXTR_R_L
:
24646 tcg_gen_movi_tl(t0
, v2
);
24647 tcg_gen_movi_tl(t1
, v1
);
24648 gen_helper_dextr_r_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24650 case OPC_DEXTR_RS_L
:
24651 tcg_gen_movi_tl(t0
, v2
);
24652 tcg_gen_movi_tl(t1
, v1
);
24653 gen_helper_dextr_rs_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24656 tcg_gen_movi_tl(t0
, v2
);
24657 tcg_gen_movi_tl(t1
, v1
);
24658 gen_helper_dextr_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24660 case OPC_DEXTR_R_W
:
24661 tcg_gen_movi_tl(t0
, v2
);
24662 tcg_gen_movi_tl(t1
, v1
);
24663 gen_helper_dextr_r_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24665 case OPC_DEXTR_RS_W
:
24666 tcg_gen_movi_tl(t0
, v2
);
24667 tcg_gen_movi_tl(t1
, v1
);
24668 gen_helper_dextr_rs_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24670 case OPC_DEXTR_S_H
:
24671 tcg_gen_movi_tl(t0
, v2
);
24672 tcg_gen_movi_tl(t1
, v1
);
24673 gen_helper_dextr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24675 case OPC_DEXTRV_S_H
:
24676 tcg_gen_movi_tl(t0
, v2
);
24677 tcg_gen_movi_tl(t1
, v1
);
24678 gen_helper_dextr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24681 tcg_gen_movi_tl(t0
, v2
);
24682 gen_helper_dextr_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24684 case OPC_DEXTRV_R_L
:
24685 tcg_gen_movi_tl(t0
, v2
);
24686 gen_helper_dextr_r_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24688 case OPC_DEXTRV_RS_L
:
24689 tcg_gen_movi_tl(t0
, v2
);
24690 gen_helper_dextr_rs_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24693 tcg_gen_movi_tl(t0
, v2
);
24694 gen_helper_dextr_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24696 case OPC_DEXTRV_R_W
:
24697 tcg_gen_movi_tl(t0
, v2
);
24698 gen_helper_dextr_r_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24700 case OPC_DEXTRV_RS_W
:
24701 tcg_gen_movi_tl(t0
, v2
);
24702 gen_helper_dextr_rs_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24711 tcg_temp_free(v1_t
);
24712 tcg_temp_free(v2_t
);
24715 /* End MIPSDSP functions. */
24717 static void decode_opc_special_r6(CPUMIPSState
*env
, DisasContext
*ctx
)
24719 int rs
, rt
, rd
, sa
;
24722 rs
= (ctx
->opcode
>> 21) & 0x1f;
24723 rt
= (ctx
->opcode
>> 16) & 0x1f;
24724 rd
= (ctx
->opcode
>> 11) & 0x1f;
24725 sa
= (ctx
->opcode
>> 6) & 0x1f;
24727 op1
= MASK_SPECIAL(ctx
->opcode
);
24730 gen_lsa(ctx
, op1
, rd
, rs
, rt
, extract32(ctx
->opcode
, 6, 2));
24736 op2
= MASK_R6_MULDIV(ctx
->opcode
);
24746 gen_r6_muldiv(ctx
, op2
, rd
, rs
, rt
);
24749 MIPS_INVAL("special_r6 muldiv");
24750 generate_exception_end(ctx
, EXCP_RI
);
24756 gen_cond_move(ctx
, op1
, rd
, rs
, rt
);
24760 if (rt
== 0 && sa
== 1) {
24762 * Major opcode and function field is shared with preR6 MFHI/MTHI.
24763 * We need additionally to check other fields.
24765 gen_cl(ctx
, op1
, rd
, rs
);
24767 generate_exception_end(ctx
, EXCP_RI
);
24771 if (is_uhi(extract32(ctx
->opcode
, 6, 20))) {
24772 gen_helper_do_semihosting(cpu_env
);
24774 if (ctx
->hflags
& MIPS_HFLAG_SBRI
) {
24775 generate_exception_end(ctx
, EXCP_RI
);
24777 generate_exception_end(ctx
, EXCP_DBp
);
24781 #if defined(TARGET_MIPS64)
24783 check_mips_64(ctx
);
24784 gen_lsa(ctx
, op1
, rd
, rs
, rt
, extract32(ctx
->opcode
, 6, 2));
24788 if (rt
== 0 && sa
== 1) {
24790 * Major opcode and function field is shared with preR6 MFHI/MTHI.
24791 * We need additionally to check other fields.
24793 check_mips_64(ctx
);
24794 gen_cl(ctx
, op1
, rd
, rs
);
24796 generate_exception_end(ctx
, EXCP_RI
);
24804 op2
= MASK_R6_MULDIV(ctx
->opcode
);
24814 check_mips_64(ctx
);
24815 gen_r6_muldiv(ctx
, op2
, rd
, rs
, rt
);
24818 MIPS_INVAL("special_r6 muldiv");
24819 generate_exception_end(ctx
, EXCP_RI
);
24824 default: /* Invalid */
24825 MIPS_INVAL("special_r6");
24826 generate_exception_end(ctx
, EXCP_RI
);
24831 static void decode_opc_special_tx79(CPUMIPSState
*env
, DisasContext
*ctx
)
24833 int rs
= extract32(ctx
->opcode
, 21, 5);
24834 int rt
= extract32(ctx
->opcode
, 16, 5);
24835 int rd
= extract32(ctx
->opcode
, 11, 5);
24836 uint32_t op1
= MASK_SPECIAL(ctx
->opcode
);
24839 case OPC_MOVN
: /* Conditional move */
24841 gen_cond_move(ctx
, op1
, rd
, rs
, rt
);
24843 case OPC_MFHI
: /* Move from HI/LO */
24845 gen_HILO(ctx
, op1
, 0, rd
);
24848 case OPC_MTLO
: /* Move to HI/LO */
24849 gen_HILO(ctx
, op1
, 0, rs
);
24853 gen_mul_txx9(ctx
, op1
, rd
, rs
, rt
);
24857 gen_muldiv(ctx
, op1
, 0, rs
, rt
);
24859 #if defined(TARGET_MIPS64)
24864 check_insn_opc_user_only(ctx
, INSN_R5900
);
24865 gen_muldiv(ctx
, op1
, 0, rs
, rt
);
24869 gen_compute_branch(ctx
, op1
, 4, rs
, 0, 0, 4);
24871 default: /* Invalid */
24872 MIPS_INVAL("special_tx79");
24873 generate_exception_end(ctx
, EXCP_RI
);
24878 static void decode_opc_special_legacy(CPUMIPSState
*env
, DisasContext
*ctx
)
24880 int rs
, rt
, rd
, sa
;
24883 rs
= (ctx
->opcode
>> 21) & 0x1f;
24884 rt
= (ctx
->opcode
>> 16) & 0x1f;
24885 rd
= (ctx
->opcode
>> 11) & 0x1f;
24886 sa
= (ctx
->opcode
>> 6) & 0x1f;
24888 op1
= MASK_SPECIAL(ctx
->opcode
);
24890 case OPC_MOVN
: /* Conditional move */
24892 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32
|
24893 INSN_LOONGSON2E
| INSN_LOONGSON2F
);
24894 gen_cond_move(ctx
, op1
, rd
, rs
, rt
);
24896 case OPC_MFHI
: /* Move from HI/LO */
24898 gen_HILO(ctx
, op1
, rs
& 3, rd
);
24901 case OPC_MTLO
: /* Move to HI/LO */
24902 gen_HILO(ctx
, op1
, rd
& 3, rs
);
24905 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32
);
24906 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
24907 check_cp1_enabled(ctx
);
24908 gen_movci(ctx
, rd
, rs
, (ctx
->opcode
>> 18) & 0x7,
24909 (ctx
->opcode
>> 16) & 1);
24911 generate_exception_err(ctx
, EXCP_CpU
, 1);
24917 check_insn(ctx
, INSN_VR54XX
);
24918 op1
= MASK_MUL_VR54XX(ctx
->opcode
);
24919 gen_mul_vr54xx(ctx
, op1
, rd
, rs
, rt
);
24921 gen_muldiv(ctx
, op1
, rd
& 3, rs
, rt
);
24926 gen_muldiv(ctx
, op1
, 0, rs
, rt
);
24928 #if defined(TARGET_MIPS64)
24933 check_insn(ctx
, ISA_MIPS3
);
24934 check_mips_64(ctx
);
24935 gen_muldiv(ctx
, op1
, 0, rs
, rt
);
24939 gen_compute_branch(ctx
, op1
, 4, rs
, rd
, sa
, 4);
24942 #ifdef MIPS_STRICT_STANDARD
24943 MIPS_INVAL("SPIM");
24944 generate_exception_end(ctx
, EXCP_RI
);
24946 /* Implemented as RI exception for now. */
24947 MIPS_INVAL("spim (unofficial)");
24948 generate_exception_end(ctx
, EXCP_RI
);
24951 default: /* Invalid */
24952 MIPS_INVAL("special_legacy");
24953 generate_exception_end(ctx
, EXCP_RI
);
24958 static void decode_opc_special(CPUMIPSState
*env
, DisasContext
*ctx
)
24960 int rs
, rt
, rd
, sa
;
24963 rs
= (ctx
->opcode
>> 21) & 0x1f;
24964 rt
= (ctx
->opcode
>> 16) & 0x1f;
24965 rd
= (ctx
->opcode
>> 11) & 0x1f;
24966 sa
= (ctx
->opcode
>> 6) & 0x1f;
24968 op1
= MASK_SPECIAL(ctx
->opcode
);
24970 case OPC_SLL
: /* Shift with immediate */
24971 if (sa
== 5 && rd
== 0 &&
24972 rs
== 0 && rt
== 0) { /* PAUSE */
24973 if ((ctx
->insn_flags
& ISA_MIPS32R6
) &&
24974 (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
24975 generate_exception_end(ctx
, EXCP_RI
);
24981 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
24984 switch ((ctx
->opcode
>> 21) & 0x1f) {
24986 /* rotr is decoded as srl on non-R2 CPUs */
24987 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
24992 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
24995 generate_exception_end(ctx
, EXCP_RI
);
25003 gen_arith(ctx
, op1
, rd
, rs
, rt
);
25005 case OPC_SLLV
: /* Shifts */
25007 gen_shift(ctx
, op1
, rd
, rs
, rt
);
25010 switch ((ctx
->opcode
>> 6) & 0x1f) {
25012 /* rotrv is decoded as srlv on non-R2 CPUs */
25013 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
25018 gen_shift(ctx
, op1
, rd
, rs
, rt
);
25021 generate_exception_end(ctx
, EXCP_RI
);
25025 case OPC_SLT
: /* Set on less than */
25027 gen_slt(ctx
, op1
, rd
, rs
, rt
);
25029 case OPC_AND
: /* Logic*/
25033 gen_logic(ctx
, op1
, rd
, rs
, rt
);
25036 gen_compute_branch(ctx
, op1
, 4, rs
, rd
, sa
, 4);
25038 case OPC_TGE
: /* Traps */
25044 check_insn(ctx
, ISA_MIPS2
);
25045 gen_trap(ctx
, op1
, rs
, rt
, -1);
25047 case OPC_LSA
: /* OPC_PMON */
25048 if ((ctx
->insn_flags
& ISA_MIPS32R6
) ||
25049 (env
->CP0_Config3
& (1 << CP0C3_MSAP
))) {
25050 decode_opc_special_r6(env
, ctx
);
25052 /* Pmon entry point, also R4010 selsl */
25053 #ifdef MIPS_STRICT_STANDARD
25054 MIPS_INVAL("PMON / selsl");
25055 generate_exception_end(ctx
, EXCP_RI
);
25057 gen_helper_0e0i(pmon
, sa
);
25062 generate_exception_end(ctx
, EXCP_SYSCALL
);
25065 generate_exception_end(ctx
, EXCP_BREAK
);
25068 check_insn(ctx
, ISA_MIPS2
);
25069 gen_sync(extract32(ctx
->opcode
, 6, 5));
25072 #if defined(TARGET_MIPS64)
25073 /* MIPS64 specific opcodes */
25078 check_insn(ctx
, ISA_MIPS3
);
25079 check_mips_64(ctx
);
25080 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
25083 switch ((ctx
->opcode
>> 21) & 0x1f) {
25085 /* drotr is decoded as dsrl on non-R2 CPUs */
25086 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
25091 check_insn(ctx
, ISA_MIPS3
);
25092 check_mips_64(ctx
);
25093 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
25096 generate_exception_end(ctx
, EXCP_RI
);
25101 switch ((ctx
->opcode
>> 21) & 0x1f) {
25103 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
25104 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
25109 check_insn(ctx
, ISA_MIPS3
);
25110 check_mips_64(ctx
);
25111 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
25114 generate_exception_end(ctx
, EXCP_RI
);
25122 check_insn(ctx
, ISA_MIPS3
);
25123 check_mips_64(ctx
);
25124 gen_arith(ctx
, op1
, rd
, rs
, rt
);
25128 check_insn(ctx
, ISA_MIPS3
);
25129 check_mips_64(ctx
);
25130 gen_shift(ctx
, op1
, rd
, rs
, rt
);
25133 switch ((ctx
->opcode
>> 6) & 0x1f) {
25135 /* drotrv is decoded as dsrlv on non-R2 CPUs */
25136 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
25141 check_insn(ctx
, ISA_MIPS3
);
25142 check_mips_64(ctx
);
25143 gen_shift(ctx
, op1
, rd
, rs
, rt
);
25146 generate_exception_end(ctx
, EXCP_RI
);
25151 if ((ctx
->insn_flags
& ISA_MIPS32R6
) ||
25152 (env
->CP0_Config3
& (1 << CP0C3_MSAP
))) {
25153 decode_opc_special_r6(env
, ctx
);
25158 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
25159 decode_opc_special_r6(env
, ctx
);
25160 } else if (ctx
->insn_flags
& INSN_R5900
) {
25161 decode_opc_special_tx79(env
, ctx
);
25163 decode_opc_special_legacy(env
, ctx
);
25169 #if defined(TARGET_MIPS64)
25173 * MMI (MultiMedia Interface) ASE instructions
25174 * ===========================================
25178 * MMI instructions category: data communication
25179 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
25181 * PCPYH PEXCH PEXTLB PINTH PPACB PEXT5 PREVH
25182 * PCPYLD PEXCW PEXTLH PINTEH PPACH PPAC5 PROT3W
25183 * PCPYUD PEXEH PEXTLW PPACW
25192 * Parallel Copy Halfword
25194 * 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
25195 * +-----------+---------+---------+---------+---------+-----------+
25196 * | MMI |0 0 0 0 0| rt | rd | PCPYH | MMI3 |
25197 * +-----------+---------+---------+---------+---------+-----------+
25199 static void gen_mmi_pcpyh(DisasContext
*ctx
)
25201 uint32_t pd
, rt
, rd
;
25204 opcode
= ctx
->opcode
;
25206 pd
= extract32(opcode
, 21, 5);
25207 rt
= extract32(opcode
, 16, 5);
25208 rd
= extract32(opcode
, 11, 5);
25210 if (unlikely(pd
!= 0)) {
25211 generate_exception_end(ctx
, EXCP_RI
);
25212 } else if (rd
== 0) {
25214 } else if (rt
== 0) {
25215 tcg_gen_movi_i64(cpu_gpr
[rd
], 0);
25216 tcg_gen_movi_i64(cpu_mmr
[rd
], 0);
25218 TCGv_i64 t0
= tcg_temp_new();
25219 TCGv_i64 t1
= tcg_temp_new();
25220 uint64_t mask
= (1ULL << 16) - 1;
25222 tcg_gen_andi_i64(t0
, cpu_gpr
[rt
], mask
);
25223 tcg_gen_movi_i64(t1
, 0);
25224 tcg_gen_or_i64(t1
, t0
, t1
);
25225 tcg_gen_shli_i64(t0
, t0
, 16);
25226 tcg_gen_or_i64(t1
, t0
, t1
);
25227 tcg_gen_shli_i64(t0
, t0
, 16);
25228 tcg_gen_or_i64(t1
, t0
, t1
);
25229 tcg_gen_shli_i64(t0
, t0
, 16);
25230 tcg_gen_or_i64(t1
, t0
, t1
);
25232 tcg_gen_mov_i64(cpu_gpr
[rd
], t1
);
25234 tcg_gen_andi_i64(t0
, cpu_mmr
[rt
], mask
);
25235 tcg_gen_movi_i64(t1
, 0);
25236 tcg_gen_or_i64(t1
, t0
, t1
);
25237 tcg_gen_shli_i64(t0
, t0
, 16);
25238 tcg_gen_or_i64(t1
, t0
, t1
);
25239 tcg_gen_shli_i64(t0
, t0
, 16);
25240 tcg_gen_or_i64(t1
, t0
, t1
);
25241 tcg_gen_shli_i64(t0
, t0
, 16);
25242 tcg_gen_or_i64(t1
, t0
, t1
);
25244 tcg_gen_mov_i64(cpu_mmr
[rd
], t1
);
25252 * PCPYLD rd, rs, rt
25254 * Parallel Copy Lower Doubleword
25256 * 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
25257 * +-----------+---------+---------+---------+---------+-----------+
25258 * | MMI | rs | rt | rd | PCPYLD | MMI2 |
25259 * +-----------+---------+---------+---------+---------+-----------+
25261 static void gen_mmi_pcpyld(DisasContext
*ctx
)
25263 uint32_t rs
, rt
, rd
;
25266 opcode
= ctx
->opcode
;
25268 rs
= extract32(opcode
, 21, 5);
25269 rt
= extract32(opcode
, 16, 5);
25270 rd
= extract32(opcode
, 11, 5);
25276 tcg_gen_movi_i64(cpu_mmr
[rd
], 0);
25278 tcg_gen_mov_i64(cpu_mmr
[rd
], cpu_gpr
[rs
]);
25281 tcg_gen_movi_i64(cpu_gpr
[rd
], 0);
25284 tcg_gen_mov_i64(cpu_gpr
[rd
], cpu_gpr
[rt
]);
25291 * PCPYUD rd, rs, rt
25293 * Parallel Copy Upper Doubleword
25295 * 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
25296 * +-----------+---------+---------+---------+---------+-----------+
25297 * | MMI | rs | rt | rd | PCPYUD | MMI3 |
25298 * +-----------+---------+---------+---------+---------+-----------+
25300 static void gen_mmi_pcpyud(DisasContext
*ctx
)
25302 uint32_t rs
, rt
, rd
;
25305 opcode
= ctx
->opcode
;
25307 rs
= extract32(opcode
, 21, 5);
25308 rt
= extract32(opcode
, 16, 5);
25309 rd
= extract32(opcode
, 11, 5);
25315 tcg_gen_movi_i64(cpu_gpr
[rd
], 0);
25317 tcg_gen_mov_i64(cpu_gpr
[rd
], cpu_mmr
[rs
]);
25320 tcg_gen_movi_i64(cpu_mmr
[rd
], 0);
25323 tcg_gen_mov_i64(cpu_mmr
[rd
], cpu_mmr
[rt
]);
25332 #if !defined(TARGET_MIPS64)
25334 /* MXU accumulate add/subtract 1-bit pattern 'aptn1' */
25335 #define MXU_APTN1_A 0
25336 #define MXU_APTN1_S 1
25338 /* MXU accumulate add/subtract 2-bit pattern 'aptn2' */
25339 #define MXU_APTN2_AA 0
25340 #define MXU_APTN2_AS 1
25341 #define MXU_APTN2_SA 2
25342 #define MXU_APTN2_SS 3
25344 /* MXU execute add/subtract 2-bit pattern 'eptn2' */
25345 #define MXU_EPTN2_AA 0
25346 #define MXU_EPTN2_AS 1
25347 #define MXU_EPTN2_SA 2
25348 #define MXU_EPTN2_SS 3
25350 /* MXU operand getting pattern 'optn2' */
25351 #define MXU_OPTN2_PTN0 0
25352 #define MXU_OPTN2_PTN1 1
25353 #define MXU_OPTN2_PTN2 2
25354 #define MXU_OPTN2_PTN3 3
25355 /* alternative naming scheme for 'optn2' */
25356 #define MXU_OPTN2_WW 0
25357 #define MXU_OPTN2_LW 1
25358 #define MXU_OPTN2_HW 2
25359 #define MXU_OPTN2_XW 3
25361 /* MXU operand getting pattern 'optn3' */
25362 #define MXU_OPTN3_PTN0 0
25363 #define MXU_OPTN3_PTN1 1
25364 #define MXU_OPTN3_PTN2 2
25365 #define MXU_OPTN3_PTN3 3
25366 #define MXU_OPTN3_PTN4 4
25367 #define MXU_OPTN3_PTN5 5
25368 #define MXU_OPTN3_PTN6 6
25369 #define MXU_OPTN3_PTN7 7
25373 * S32I2M XRa, rb - Register move from GRF to XRF
25375 static void gen_mxu_s32i2m(DisasContext
*ctx
)
25380 t0
= tcg_temp_new();
25382 XRa
= extract32(ctx
->opcode
, 6, 5);
25383 Rb
= extract32(ctx
->opcode
, 16, 5);
25385 gen_load_gpr(t0
, Rb
);
25387 gen_store_mxu_gpr(t0
, XRa
);
25388 } else if (XRa
== 16) {
25389 gen_store_mxu_cr(t0
);
25396 * S32M2I XRa, rb - Register move from XRF to GRF
25398 static void gen_mxu_s32m2i(DisasContext
*ctx
)
25403 t0
= tcg_temp_new();
25405 XRa
= extract32(ctx
->opcode
, 6, 5);
25406 Rb
= extract32(ctx
->opcode
, 16, 5);
25409 gen_load_mxu_gpr(t0
, XRa
);
25410 } else if (XRa
== 16) {
25411 gen_load_mxu_cr(t0
);
25414 gen_store_gpr(t0
, Rb
);
25420 * S8LDD XRa, Rb, s8, optn3 - Load a byte from memory to XRF
25422 static void gen_mxu_s8ldd(DisasContext
*ctx
)
25425 uint32_t XRa
, Rb
, s8
, optn3
;
25427 t0
= tcg_temp_new();
25428 t1
= tcg_temp_new();
25430 XRa
= extract32(ctx
->opcode
, 6, 4);
25431 s8
= extract32(ctx
->opcode
, 10, 8);
25432 optn3
= extract32(ctx
->opcode
, 18, 3);
25433 Rb
= extract32(ctx
->opcode
, 21, 5);
25435 gen_load_gpr(t0
, Rb
);
25436 tcg_gen_addi_tl(t0
, t0
, (int8_t)s8
);
25439 /* XRa[7:0] = tmp8 */
25440 case MXU_OPTN3_PTN0
:
25441 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
25442 gen_load_mxu_gpr(t0
, XRa
);
25443 tcg_gen_deposit_tl(t0
, t0
, t1
, 0, 8);
25445 /* XRa[15:8] = tmp8 */
25446 case MXU_OPTN3_PTN1
:
25447 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
25448 gen_load_mxu_gpr(t0
, XRa
);
25449 tcg_gen_deposit_tl(t0
, t0
, t1
, 8, 8);
25451 /* XRa[23:16] = tmp8 */
25452 case MXU_OPTN3_PTN2
:
25453 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
25454 gen_load_mxu_gpr(t0
, XRa
);
25455 tcg_gen_deposit_tl(t0
, t0
, t1
, 16, 8);
25457 /* XRa[31:24] = tmp8 */
25458 case MXU_OPTN3_PTN3
:
25459 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
25460 gen_load_mxu_gpr(t0
, XRa
);
25461 tcg_gen_deposit_tl(t0
, t0
, t1
, 24, 8);
25463 /* XRa = {8'b0, tmp8, 8'b0, tmp8} */
25464 case MXU_OPTN3_PTN4
:
25465 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
25466 tcg_gen_deposit_tl(t0
, t1
, t1
, 16, 16);
25468 /* XRa = {tmp8, 8'b0, tmp8, 8'b0} */
25469 case MXU_OPTN3_PTN5
:
25470 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
25471 tcg_gen_shli_tl(t1
, t1
, 8);
25472 tcg_gen_deposit_tl(t0
, t1
, t1
, 16, 16);
25474 /* XRa = {{8{sign of tmp8}}, tmp8, {8{sign of tmp8}}, tmp8} */
25475 case MXU_OPTN3_PTN6
:
25476 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_SB
);
25477 tcg_gen_mov_tl(t0
, t1
);
25478 tcg_gen_andi_tl(t0
, t0
, 0xFF00FFFF);
25479 tcg_gen_shli_tl(t1
, t1
, 16);
25480 tcg_gen_or_tl(t0
, t0
, t1
);
25482 /* XRa = {tmp8, tmp8, tmp8, tmp8} */
25483 case MXU_OPTN3_PTN7
:
25484 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
25485 tcg_gen_deposit_tl(t1
, t1
, t1
, 8, 8);
25486 tcg_gen_deposit_tl(t0
, t1
, t1
, 16, 16);
25490 gen_store_mxu_gpr(t0
, XRa
);
25497 * D16MUL XRa, XRb, XRc, XRd, optn2 - Signed 16 bit pattern multiplication
25499 static void gen_mxu_d16mul(DisasContext
*ctx
)
25501 TCGv t0
, t1
, t2
, t3
;
25502 uint32_t XRa
, XRb
, XRc
, XRd
, optn2
;
25504 t0
= tcg_temp_new();
25505 t1
= tcg_temp_new();
25506 t2
= tcg_temp_new();
25507 t3
= tcg_temp_new();
25509 XRa
= extract32(ctx
->opcode
, 6, 4);
25510 XRb
= extract32(ctx
->opcode
, 10, 4);
25511 XRc
= extract32(ctx
->opcode
, 14, 4);
25512 XRd
= extract32(ctx
->opcode
, 18, 4);
25513 optn2
= extract32(ctx
->opcode
, 22, 2);
25515 gen_load_mxu_gpr(t1
, XRb
);
25516 tcg_gen_sextract_tl(t0
, t1
, 0, 16);
25517 tcg_gen_sextract_tl(t1
, t1
, 16, 16);
25518 gen_load_mxu_gpr(t3
, XRc
);
25519 tcg_gen_sextract_tl(t2
, t3
, 0, 16);
25520 tcg_gen_sextract_tl(t3
, t3
, 16, 16);
25523 case MXU_OPTN2_WW
: /* XRB.H*XRC.H == lop, XRB.L*XRC.L == rop */
25524 tcg_gen_mul_tl(t3
, t1
, t3
);
25525 tcg_gen_mul_tl(t2
, t0
, t2
);
25527 case MXU_OPTN2_LW
: /* XRB.L*XRC.H == lop, XRB.L*XRC.L == rop */
25528 tcg_gen_mul_tl(t3
, t0
, t3
);
25529 tcg_gen_mul_tl(t2
, t0
, t2
);
25531 case MXU_OPTN2_HW
: /* XRB.H*XRC.H == lop, XRB.H*XRC.L == rop */
25532 tcg_gen_mul_tl(t3
, t1
, t3
);
25533 tcg_gen_mul_tl(t2
, t1
, t2
);
25535 case MXU_OPTN2_XW
: /* XRB.L*XRC.H == lop, XRB.H*XRC.L == rop */
25536 tcg_gen_mul_tl(t3
, t0
, t3
);
25537 tcg_gen_mul_tl(t2
, t1
, t2
);
25540 gen_store_mxu_gpr(t3
, XRa
);
25541 gen_store_mxu_gpr(t2
, XRd
);
25550 * D16MAC XRa, XRb, XRc, XRd, aptn2, optn2 - Signed 16 bit pattern multiply
25553 static void gen_mxu_d16mac(DisasContext
*ctx
)
25555 TCGv t0
, t1
, t2
, t3
;
25556 uint32_t XRa
, XRb
, XRc
, XRd
, optn2
, aptn2
;
25558 t0
= tcg_temp_new();
25559 t1
= tcg_temp_new();
25560 t2
= tcg_temp_new();
25561 t3
= tcg_temp_new();
25563 XRa
= extract32(ctx
->opcode
, 6, 4);
25564 XRb
= extract32(ctx
->opcode
, 10, 4);
25565 XRc
= extract32(ctx
->opcode
, 14, 4);
25566 XRd
= extract32(ctx
->opcode
, 18, 4);
25567 optn2
= extract32(ctx
->opcode
, 22, 2);
25568 aptn2
= extract32(ctx
->opcode
, 24, 2);
25570 gen_load_mxu_gpr(t1
, XRb
);
25571 tcg_gen_sextract_tl(t0
, t1
, 0, 16);
25572 tcg_gen_sextract_tl(t1
, t1
, 16, 16);
25574 gen_load_mxu_gpr(t3
, XRc
);
25575 tcg_gen_sextract_tl(t2
, t3
, 0, 16);
25576 tcg_gen_sextract_tl(t3
, t3
, 16, 16);
25579 case MXU_OPTN2_WW
: /* XRB.H*XRC.H == lop, XRB.L*XRC.L == rop */
25580 tcg_gen_mul_tl(t3
, t1
, t3
);
25581 tcg_gen_mul_tl(t2
, t0
, t2
);
25583 case MXU_OPTN2_LW
: /* XRB.L*XRC.H == lop, XRB.L*XRC.L == rop */
25584 tcg_gen_mul_tl(t3
, t0
, t3
);
25585 tcg_gen_mul_tl(t2
, t0
, t2
);
25587 case MXU_OPTN2_HW
: /* XRB.H*XRC.H == lop, XRB.H*XRC.L == rop */
25588 tcg_gen_mul_tl(t3
, t1
, t3
);
25589 tcg_gen_mul_tl(t2
, t1
, t2
);
25591 case MXU_OPTN2_XW
: /* XRB.L*XRC.H == lop, XRB.H*XRC.L == rop */
25592 tcg_gen_mul_tl(t3
, t0
, t3
);
25593 tcg_gen_mul_tl(t2
, t1
, t2
);
25596 gen_load_mxu_gpr(t0
, XRa
);
25597 gen_load_mxu_gpr(t1
, XRd
);
25601 tcg_gen_add_tl(t3
, t0
, t3
);
25602 tcg_gen_add_tl(t2
, t1
, t2
);
25605 tcg_gen_add_tl(t3
, t0
, t3
);
25606 tcg_gen_sub_tl(t2
, t1
, t2
);
25609 tcg_gen_sub_tl(t3
, t0
, t3
);
25610 tcg_gen_add_tl(t2
, t1
, t2
);
25613 tcg_gen_sub_tl(t3
, t0
, t3
);
25614 tcg_gen_sub_tl(t2
, t1
, t2
);
25617 gen_store_mxu_gpr(t3
, XRa
);
25618 gen_store_mxu_gpr(t2
, XRd
);
25627 * Q8MUL XRa, XRb, XRc, XRd - Parallel unsigned 8 bit pattern multiply
25628 * Q8MULSU XRa, XRb, XRc, XRd - Parallel signed 8 bit pattern multiply
25630 static void gen_mxu_q8mul_q8mulsu(DisasContext
*ctx
)
25632 TCGv t0
, t1
, t2
, t3
, t4
, t5
, t6
, t7
;
25633 uint32_t XRa
, XRb
, XRc
, XRd
, sel
;
25635 t0
= tcg_temp_new();
25636 t1
= tcg_temp_new();
25637 t2
= tcg_temp_new();
25638 t3
= tcg_temp_new();
25639 t4
= tcg_temp_new();
25640 t5
= tcg_temp_new();
25641 t6
= tcg_temp_new();
25642 t7
= tcg_temp_new();
25644 XRa
= extract32(ctx
->opcode
, 6, 4);
25645 XRb
= extract32(ctx
->opcode
, 10, 4);
25646 XRc
= extract32(ctx
->opcode
, 14, 4);
25647 XRd
= extract32(ctx
->opcode
, 18, 4);
25648 sel
= extract32(ctx
->opcode
, 22, 2);
25650 gen_load_mxu_gpr(t3
, XRb
);
25651 gen_load_mxu_gpr(t7
, XRc
);
25655 tcg_gen_ext8s_tl(t0
, t3
);
25656 tcg_gen_shri_tl(t3
, t3
, 8);
25657 tcg_gen_ext8s_tl(t1
, t3
);
25658 tcg_gen_shri_tl(t3
, t3
, 8);
25659 tcg_gen_ext8s_tl(t2
, t3
);
25660 tcg_gen_shri_tl(t3
, t3
, 8);
25661 tcg_gen_ext8s_tl(t3
, t3
);
25664 tcg_gen_ext8u_tl(t0
, t3
);
25665 tcg_gen_shri_tl(t3
, t3
, 8);
25666 tcg_gen_ext8u_tl(t1
, t3
);
25667 tcg_gen_shri_tl(t3
, t3
, 8);
25668 tcg_gen_ext8u_tl(t2
, t3
);
25669 tcg_gen_shri_tl(t3
, t3
, 8);
25670 tcg_gen_ext8u_tl(t3
, t3
);
25673 tcg_gen_ext8u_tl(t4
, t7
);
25674 tcg_gen_shri_tl(t7
, t7
, 8);
25675 tcg_gen_ext8u_tl(t5
, t7
);
25676 tcg_gen_shri_tl(t7
, t7
, 8);
25677 tcg_gen_ext8u_tl(t6
, t7
);
25678 tcg_gen_shri_tl(t7
, t7
, 8);
25679 tcg_gen_ext8u_tl(t7
, t7
);
25681 tcg_gen_mul_tl(t0
, t0
, t4
);
25682 tcg_gen_mul_tl(t1
, t1
, t5
);
25683 tcg_gen_mul_tl(t2
, t2
, t6
);
25684 tcg_gen_mul_tl(t3
, t3
, t7
);
25686 tcg_gen_andi_tl(t0
, t0
, 0xFFFF);
25687 tcg_gen_andi_tl(t1
, t1
, 0xFFFF);
25688 tcg_gen_andi_tl(t2
, t2
, 0xFFFF);
25689 tcg_gen_andi_tl(t3
, t3
, 0xFFFF);
25691 tcg_gen_shli_tl(t1
, t1
, 16);
25692 tcg_gen_shli_tl(t3
, t3
, 16);
25694 tcg_gen_or_tl(t0
, t0
, t1
);
25695 tcg_gen_or_tl(t1
, t2
, t3
);
25697 gen_store_mxu_gpr(t0
, XRd
);
25698 gen_store_mxu_gpr(t1
, XRa
);
25711 * S32LDD XRa, Rb, S12 - Load a word from memory to XRF
25712 * S32LDDR XRa, Rb, S12 - Load a word from memory to XRF, reversed byte seq.
25714 static void gen_mxu_s32ldd_s32lddr(DisasContext
*ctx
)
25717 uint32_t XRa
, Rb
, s12
, sel
;
25719 t0
= tcg_temp_new();
25720 t1
= tcg_temp_new();
25722 XRa
= extract32(ctx
->opcode
, 6, 4);
25723 s12
= extract32(ctx
->opcode
, 10, 10);
25724 sel
= extract32(ctx
->opcode
, 20, 1);
25725 Rb
= extract32(ctx
->opcode
, 21, 5);
25727 gen_load_gpr(t0
, Rb
);
25729 tcg_gen_movi_tl(t1
, s12
);
25730 tcg_gen_shli_tl(t1
, t1
, 2);
25732 tcg_gen_ori_tl(t1
, t1
, 0xFFFFF000);
25734 tcg_gen_add_tl(t1
, t0
, t1
);
25735 tcg_gen_qemu_ld_tl(t1
, t1
, ctx
->mem_idx
, MO_SL
);
25739 tcg_gen_bswap32_tl(t1
, t1
);
25741 gen_store_mxu_gpr(t1
, XRa
);
25749 * MXU instruction category: logic
25750 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
25752 * S32NOR S32AND S32OR S32XOR
25756 * S32NOR XRa, XRb, XRc
25757 * Update XRa with the result of logical bitwise 'nor' operation
25758 * applied to the content of XRb and XRc.
25760 * 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
25761 * +-----------+---------+-----+-------+-------+-------+-----------+
25762 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL16|
25763 * +-----------+---------+-----+-------+-------+-------+-----------+
25765 static void gen_mxu_S32NOR(DisasContext
*ctx
)
25767 uint32_t pad
, XRc
, XRb
, XRa
;
25769 pad
= extract32(ctx
->opcode
, 21, 5);
25770 XRc
= extract32(ctx
->opcode
, 14, 4);
25771 XRb
= extract32(ctx
->opcode
, 10, 4);
25772 XRa
= extract32(ctx
->opcode
, 6, 4);
25774 if (unlikely(pad
!= 0)) {
25775 /* opcode padding incorrect -> do nothing */
25776 } else if (unlikely(XRa
== 0)) {
25777 /* destination is zero register -> do nothing */
25778 } else if (unlikely((XRb
== 0) && (XRc
== 0))) {
25779 /* both operands zero registers -> just set destination to all 1s */
25780 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0xFFFFFFFF);
25781 } else if (unlikely(XRb
== 0)) {
25782 /* XRb zero register -> just set destination to the negation of XRc */
25783 tcg_gen_not_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRc
- 1]);
25784 } else if (unlikely(XRc
== 0)) {
25785 /* XRa zero register -> just set destination to the negation of XRb */
25786 tcg_gen_not_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25787 } else if (unlikely(XRb
== XRc
)) {
25788 /* both operands same -> just set destination to the negation of XRb */
25789 tcg_gen_not_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25791 /* the most general case */
25792 tcg_gen_nor_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1], mxu_gpr
[XRc
- 1]);
25797 * S32AND XRa, XRb, XRc
25798 * Update XRa with the result of logical bitwise 'and' operation
25799 * applied to the content of XRb and XRc.
25801 * 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
25802 * +-----------+---------+-----+-------+-------+-------+-----------+
25803 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL16|
25804 * +-----------+---------+-----+-------+-------+-------+-----------+
25806 static void gen_mxu_S32AND(DisasContext
*ctx
)
25808 uint32_t pad
, XRc
, XRb
, XRa
;
25810 pad
= extract32(ctx
->opcode
, 21, 5);
25811 XRc
= extract32(ctx
->opcode
, 14, 4);
25812 XRb
= extract32(ctx
->opcode
, 10, 4);
25813 XRa
= extract32(ctx
->opcode
, 6, 4);
25815 if (unlikely(pad
!= 0)) {
25816 /* opcode padding incorrect -> do nothing */
25817 } else if (unlikely(XRa
== 0)) {
25818 /* destination is zero register -> do nothing */
25819 } else if (unlikely((XRb
== 0) || (XRc
== 0))) {
25820 /* one of operands zero register -> just set destination to all 0s */
25821 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0);
25822 } else if (unlikely(XRb
== XRc
)) {
25823 /* both operands same -> just set destination to one of them */
25824 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25826 /* the most general case */
25827 tcg_gen_and_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1], mxu_gpr
[XRc
- 1]);
25832 * S32OR XRa, XRb, XRc
25833 * Update XRa with the result of logical bitwise 'or' operation
25834 * applied to the content of XRb and XRc.
25836 * 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
25837 * +-----------+---------+-----+-------+-------+-------+-----------+
25838 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL16|
25839 * +-----------+---------+-----+-------+-------+-------+-----------+
25841 static void gen_mxu_S32OR(DisasContext
*ctx
)
25843 uint32_t pad
, XRc
, XRb
, XRa
;
25845 pad
= extract32(ctx
->opcode
, 21, 5);
25846 XRc
= extract32(ctx
->opcode
, 14, 4);
25847 XRb
= extract32(ctx
->opcode
, 10, 4);
25848 XRa
= extract32(ctx
->opcode
, 6, 4);
25850 if (unlikely(pad
!= 0)) {
25851 /* opcode padding incorrect -> do nothing */
25852 } else if (unlikely(XRa
== 0)) {
25853 /* destination is zero register -> do nothing */
25854 } else if (unlikely((XRb
== 0) && (XRc
== 0))) {
25855 /* both operands zero registers -> just set destination to all 0s */
25856 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0);
25857 } else if (unlikely(XRb
== 0)) {
25858 /* XRb zero register -> just set destination to the content of XRc */
25859 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRc
- 1]);
25860 } else if (unlikely(XRc
== 0)) {
25861 /* XRc zero register -> just set destination to the content of XRb */
25862 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25863 } else if (unlikely(XRb
== XRc
)) {
25864 /* both operands same -> just set destination to one of them */
25865 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25867 /* the most general case */
25868 tcg_gen_or_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1], mxu_gpr
[XRc
- 1]);
25873 * S32XOR XRa, XRb, XRc
25874 * Update XRa with the result of logical bitwise 'xor' operation
25875 * applied to the content of XRb and XRc.
25877 * 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
25878 * +-----------+---------+-----+-------+-------+-------+-----------+
25879 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL16|
25880 * +-----------+---------+-----+-------+-------+-------+-----------+
25882 static void gen_mxu_S32XOR(DisasContext
*ctx
)
25884 uint32_t pad
, XRc
, XRb
, XRa
;
25886 pad
= extract32(ctx
->opcode
, 21, 5);
25887 XRc
= extract32(ctx
->opcode
, 14, 4);
25888 XRb
= extract32(ctx
->opcode
, 10, 4);
25889 XRa
= extract32(ctx
->opcode
, 6, 4);
25891 if (unlikely(pad
!= 0)) {
25892 /* opcode padding incorrect -> do nothing */
25893 } else if (unlikely(XRa
== 0)) {
25894 /* destination is zero register -> do nothing */
25895 } else if (unlikely((XRb
== 0) && (XRc
== 0))) {
25896 /* both operands zero registers -> just set destination to all 0s */
25897 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0);
25898 } else if (unlikely(XRb
== 0)) {
25899 /* XRb zero register -> just set destination to the content of XRc */
25900 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRc
- 1]);
25901 } else if (unlikely(XRc
== 0)) {
25902 /* XRc zero register -> just set destination to the content of XRb */
25903 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25904 } else if (unlikely(XRb
== XRc
)) {
25905 /* both operands same -> just set destination to all 0s */
25906 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0);
25908 /* the most general case */
25909 tcg_gen_xor_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1], mxu_gpr
[XRc
- 1]);
25915 * MXU instruction category max/min
25916 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
25918 * S32MAX D16MAX Q8MAX
25919 * S32MIN D16MIN Q8MIN
25923 * S32MAX XRa, XRb, XRc
25924 * Update XRa with the maximum of signed 32-bit integers contained
25927 * S32MIN XRa, XRb, XRc
25928 * Update XRa with the minimum of signed 32-bit integers contained
25931 * 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
25932 * +-----------+---------+-----+-------+-------+-------+-----------+
25933 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL00|
25934 * +-----------+---------+-----+-------+-------+-------+-----------+
25936 static void gen_mxu_S32MAX_S32MIN(DisasContext
*ctx
)
25938 uint32_t pad
, opc
, XRc
, XRb
, XRa
;
25940 pad
= extract32(ctx
->opcode
, 21, 5);
25941 opc
= extract32(ctx
->opcode
, 18, 3);
25942 XRc
= extract32(ctx
->opcode
, 14, 4);
25943 XRb
= extract32(ctx
->opcode
, 10, 4);
25944 XRa
= extract32(ctx
->opcode
, 6, 4);
25946 if (unlikely(pad
!= 0)) {
25947 /* opcode padding incorrect -> do nothing */
25948 } else if (unlikely(XRa
== 0)) {
25949 /* destination is zero register -> do nothing */
25950 } else if (unlikely((XRb
== 0) && (XRc
== 0))) {
25951 /* both operands zero registers -> just set destination to zero */
25952 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0);
25953 } else if (unlikely((XRb
== 0) || (XRc
== 0))) {
25954 /* exactly one operand is zero register - find which one is not...*/
25955 uint32_t XRx
= XRb
? XRb
: XRc
;
25956 /* ...and do max/min operation with one operand 0 */
25957 if (opc
== OPC_MXU_S32MAX
) {
25958 tcg_gen_smax_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRx
- 1], 0);
25960 tcg_gen_smin_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRx
- 1], 0);
25962 } else if (unlikely(XRb
== XRc
)) {
25963 /* both operands same -> just set destination to one of them */
25964 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25966 /* the most general case */
25967 if (opc
== OPC_MXU_S32MAX
) {
25968 tcg_gen_smax_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1],
25971 tcg_gen_smin_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1],
25979 * Update XRa with the 16-bit-wise maximums of signed integers
25980 * contained in XRb and XRc.
25983 * Update XRa with the 16-bit-wise minimums of signed integers
25984 * contained in XRb and XRc.
25986 * 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
25987 * +-----------+---------+-----+-------+-------+-------+-----------+
25988 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL00|
25989 * +-----------+---------+-----+-------+-------+-------+-----------+
25991 static void gen_mxu_D16MAX_D16MIN(DisasContext
*ctx
)
25993 uint32_t pad
, opc
, XRc
, XRb
, XRa
;
25995 pad
= extract32(ctx
->opcode
, 21, 5);
25996 opc
= extract32(ctx
->opcode
, 18, 3);
25997 XRc
= extract32(ctx
->opcode
, 14, 4);
25998 XRb
= extract32(ctx
->opcode
, 10, 4);
25999 XRa
= extract32(ctx
->opcode
, 6, 4);
26001 if (unlikely(pad
!= 0)) {
26002 /* opcode padding incorrect -> do nothing */
26003 } else if (unlikely(XRc
== 0)) {
26004 /* destination is zero register -> do nothing */
26005 } else if (unlikely((XRb
== 0) && (XRa
== 0))) {
26006 /* both operands zero registers -> just set destination to zero */
26007 tcg_gen_movi_i32(mxu_gpr
[XRc
- 1], 0);
26008 } else if (unlikely((XRb
== 0) || (XRa
== 0))) {
26009 /* exactly one operand is zero register - find which one is not...*/
26010 uint32_t XRx
= XRb
? XRb
: XRc
;
26011 /* ...and do half-word-wise max/min with one operand 0 */
26012 TCGv_i32 t0
= tcg_temp_new();
26013 TCGv_i32 t1
= tcg_const_i32(0);
26015 /* the left half-word first */
26016 tcg_gen_andi_i32(t0
, mxu_gpr
[XRx
- 1], 0xFFFF0000);
26017 if (opc
== OPC_MXU_D16MAX
) {
26018 tcg_gen_smax_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
26020 tcg_gen_smin_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
26023 /* the right half-word */
26024 tcg_gen_andi_i32(t0
, mxu_gpr
[XRx
- 1], 0x0000FFFF);
26025 /* move half-words to the leftmost position */
26026 tcg_gen_shli_i32(t0
, t0
, 16);
26027 /* t0 will be max/min of t0 and t1 */
26028 if (opc
== OPC_MXU_D16MAX
) {
26029 tcg_gen_smax_i32(t0
, t0
, t1
);
26031 tcg_gen_smin_i32(t0
, t0
, t1
);
26033 /* return resulting half-words to its original position */
26034 tcg_gen_shri_i32(t0
, t0
, 16);
26035 /* finally update the destination */
26036 tcg_gen_or_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRa
- 1], t0
);
26040 } else if (unlikely(XRb
== XRc
)) {
26041 /* both operands same -> just set destination to one of them */
26042 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
26044 /* the most general case */
26045 TCGv_i32 t0
= tcg_temp_new();
26046 TCGv_i32 t1
= tcg_temp_new();
26048 /* the left half-word first */
26049 tcg_gen_andi_i32(t0
, mxu_gpr
[XRb
- 1], 0xFFFF0000);
26050 tcg_gen_andi_i32(t1
, mxu_gpr
[XRc
- 1], 0xFFFF0000);
26051 if (opc
== OPC_MXU_D16MAX
) {
26052 tcg_gen_smax_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
26054 tcg_gen_smin_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
26057 /* the right half-word */
26058 tcg_gen_andi_i32(t0
, mxu_gpr
[XRb
- 1], 0x0000FFFF);
26059 tcg_gen_andi_i32(t1
, mxu_gpr
[XRc
- 1], 0x0000FFFF);
26060 /* move half-words to the leftmost position */
26061 tcg_gen_shli_i32(t0
, t0
, 16);
26062 tcg_gen_shli_i32(t1
, t1
, 16);
26063 /* t0 will be max/min of t0 and t1 */
26064 if (opc
== OPC_MXU_D16MAX
) {
26065 tcg_gen_smax_i32(t0
, t0
, t1
);
26067 tcg_gen_smin_i32(t0
, t0
, t1
);
26069 /* return resulting half-words to its original position */
26070 tcg_gen_shri_i32(t0
, t0
, 16);
26071 /* finally update the destination */
26072 tcg_gen_or_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRa
- 1], t0
);
26081 * Update XRa with the 8-bit-wise maximums of signed integers
26082 * contained in XRb and XRc.
26085 * Update XRa with the 8-bit-wise minimums of signed integers
26086 * contained in XRb and XRc.
26088 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26089 * +-----------+---------+-----+-------+-------+-------+-----------+
26090 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL00|
26091 * +-----------+---------+-----+-------+-------+-------+-----------+
26093 static void gen_mxu_Q8MAX_Q8MIN(DisasContext
*ctx
)
26095 uint32_t pad
, opc
, XRc
, XRb
, XRa
;
26097 pad
= extract32(ctx
->opcode
, 21, 5);
26098 opc
= extract32(ctx
->opcode
, 18, 3);
26099 XRc
= extract32(ctx
->opcode
, 14, 4);
26100 XRb
= extract32(ctx
->opcode
, 10, 4);
26101 XRa
= extract32(ctx
->opcode
, 6, 4);
26103 if (unlikely(pad
!= 0)) {
26104 /* opcode padding incorrect -> do nothing */
26105 } else if (unlikely(XRa
== 0)) {
26106 /* destination is zero register -> do nothing */
26107 } else if (unlikely((XRb
== 0) && (XRc
== 0))) {
26108 /* both operands zero registers -> just set destination to zero */
26109 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0);
26110 } else if (unlikely((XRb
== 0) || (XRc
== 0))) {
26111 /* exactly one operand is zero register - make it be the first...*/
26112 uint32_t XRx
= XRb
? XRb
: XRc
;
26113 /* ...and do byte-wise max/min with one operand 0 */
26114 TCGv_i32 t0
= tcg_temp_new();
26115 TCGv_i32 t1
= tcg_const_i32(0);
26118 /* the leftmost byte (byte 3) first */
26119 tcg_gen_andi_i32(t0
, mxu_gpr
[XRx
- 1], 0xFF000000);
26120 if (opc
== OPC_MXU_Q8MAX
) {
26121 tcg_gen_smax_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
26123 tcg_gen_smin_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
26126 /* bytes 2, 1, 0 */
26127 for (i
= 2; i
>= 0; i
--) {
26128 /* extract the byte */
26129 tcg_gen_andi_i32(t0
, mxu_gpr
[XRx
- 1], 0xFF << (8 * i
));
26130 /* move the byte to the leftmost position */
26131 tcg_gen_shli_i32(t0
, t0
, 8 * (3 - i
));
26132 /* t0 will be max/min of t0 and t1 */
26133 if (opc
== OPC_MXU_Q8MAX
) {
26134 tcg_gen_smax_i32(t0
, t0
, t1
);
26136 tcg_gen_smin_i32(t0
, t0
, t1
);
26138 /* return resulting byte to its original position */
26139 tcg_gen_shri_i32(t0
, t0
, 8 * (3 - i
));
26140 /* finally update the destination */
26141 tcg_gen_or_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRa
- 1], t0
);
26146 } else if (unlikely(XRb
== XRc
)) {
26147 /* both operands same -> just set destination to one of them */
26148 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
26150 /* the most general case */
26151 TCGv_i32 t0
= tcg_temp_new();
26152 TCGv_i32 t1
= tcg_temp_new();
26155 /* the leftmost bytes (bytes 3) first */
26156 tcg_gen_andi_i32(t0
, mxu_gpr
[XRb
- 1], 0xFF000000);
26157 tcg_gen_andi_i32(t1
, mxu_gpr
[XRc
- 1], 0xFF000000);
26158 if (opc
== OPC_MXU_Q8MAX
) {
26159 tcg_gen_smax_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
26161 tcg_gen_smin_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
26164 /* bytes 2, 1, 0 */
26165 for (i
= 2; i
>= 0; i
--) {
26166 /* extract corresponding bytes */
26167 tcg_gen_andi_i32(t0
, mxu_gpr
[XRb
- 1], 0xFF << (8 * i
));
26168 tcg_gen_andi_i32(t1
, mxu_gpr
[XRc
- 1], 0xFF << (8 * i
));
26169 /* move the bytes to the leftmost position */
26170 tcg_gen_shli_i32(t0
, t0
, 8 * (3 - i
));
26171 tcg_gen_shli_i32(t1
, t1
, 8 * (3 - i
));
26172 /* t0 will be max/min of t0 and t1 */
26173 if (opc
== OPC_MXU_Q8MAX
) {
26174 tcg_gen_smax_i32(t0
, t0
, t1
);
26176 tcg_gen_smin_i32(t0
, t0
, t1
);
26178 /* return resulting byte to its original position */
26179 tcg_gen_shri_i32(t0
, t0
, 8 * (3 - i
));
26180 /* finally update the destination */
26181 tcg_gen_or_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRa
- 1], t0
);
26191 * MXU instruction category: align
26192 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
26198 * S32ALNI XRc, XRb, XRa, optn3
26199 * Arrange bytes from XRb and XRc according to one of five sets of
26200 * rules determined by optn3, and place the result in XRa.
26202 * 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
26203 * +-----------+-----+---+-----+-------+-------+-------+-----------+
26204 * | SPECIAL2 |optn3|0 0|x x x| XRc | XRb | XRa |MXU__POOL16|
26205 * +-----------+-----+---+-----+-------+-------+-------+-----------+
26208 static void gen_mxu_S32ALNI(DisasContext
*ctx
)
26210 uint32_t optn3
, pad
, XRc
, XRb
, XRa
;
26212 optn3
= extract32(ctx
->opcode
, 23, 3);
26213 pad
= extract32(ctx
->opcode
, 21, 2);
26214 XRc
= extract32(ctx
->opcode
, 14, 4);
26215 XRb
= extract32(ctx
->opcode
, 10, 4);
26216 XRa
= extract32(ctx
->opcode
, 6, 4);
26218 if (unlikely(pad
!= 0)) {
26219 /* opcode padding incorrect -> do nothing */
26220 } else if (unlikely(XRa
== 0)) {
26221 /* destination is zero register -> do nothing */
26222 } else if (unlikely((XRb
== 0) && (XRc
== 0))) {
26223 /* both operands zero registers -> just set destination to all 0s */
26224 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0);
26225 } else if (unlikely(XRb
== 0)) {
26226 /* XRb zero register -> just appropriatelly shift XRc into XRa */
26228 case MXU_OPTN3_PTN0
:
26229 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0);
26231 case MXU_OPTN3_PTN1
:
26232 case MXU_OPTN3_PTN2
:
26233 case MXU_OPTN3_PTN3
:
26234 tcg_gen_shri_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRc
- 1],
26237 case MXU_OPTN3_PTN4
:
26238 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRc
- 1]);
26241 } else if (unlikely(XRc
== 0)) {
26242 /* XRc zero register -> just appropriatelly shift XRb into XRa */
26244 case MXU_OPTN3_PTN0
:
26245 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
26247 case MXU_OPTN3_PTN1
:
26248 case MXU_OPTN3_PTN2
:
26249 case MXU_OPTN3_PTN3
:
26250 tcg_gen_shri_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1], 8 * optn3
);
26252 case MXU_OPTN3_PTN4
:
26253 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0);
26256 } else if (unlikely(XRb
== XRc
)) {
26257 /* both operands same -> just rotation or moving from any of them */
26259 case MXU_OPTN3_PTN0
:
26260 case MXU_OPTN3_PTN4
:
26261 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
26263 case MXU_OPTN3_PTN1
:
26264 case MXU_OPTN3_PTN2
:
26265 case MXU_OPTN3_PTN3
:
26266 tcg_gen_rotli_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1], 8 * optn3
);
26270 /* the most general case */
26272 case MXU_OPTN3_PTN0
:
26276 /* +---------------+ */
26277 /* | A B C D | E F G H */
26278 /* +-------+-------+ */
26283 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
26286 case MXU_OPTN3_PTN1
:
26290 /* +-------------------+ */
26291 /* A | B C D E | F G H */
26292 /* +---------+---------+ */
26297 TCGv_i32 t0
= tcg_temp_new();
26298 TCGv_i32 t1
= tcg_temp_new();
26300 tcg_gen_andi_i32(t0
, mxu_gpr
[XRb
- 1], 0x00FFFFFF);
26301 tcg_gen_shli_i32(t0
, t0
, 8);
26303 tcg_gen_andi_i32(t1
, mxu_gpr
[XRc
- 1], 0xFF000000);
26304 tcg_gen_shri_i32(t1
, t1
, 24);
26306 tcg_gen_or_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
26312 case MXU_OPTN3_PTN2
:
26316 /* +-------------------+ */
26317 /* A B | C D E F | G H */
26318 /* +---------+---------+ */
26323 TCGv_i32 t0
= tcg_temp_new();
26324 TCGv_i32 t1
= tcg_temp_new();
26326 tcg_gen_andi_i32(t0
, mxu_gpr
[XRb
- 1], 0x0000FFFF);
26327 tcg_gen_shli_i32(t0
, t0
, 16);
26329 tcg_gen_andi_i32(t1
, mxu_gpr
[XRc
- 1], 0xFFFF0000);
26330 tcg_gen_shri_i32(t1
, t1
, 16);
26332 tcg_gen_or_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
26338 case MXU_OPTN3_PTN3
:
26342 /* +-------------------+ */
26343 /* A B C | D E F G | H */
26344 /* +---------+---------+ */
26349 TCGv_i32 t0
= tcg_temp_new();
26350 TCGv_i32 t1
= tcg_temp_new();
26352 tcg_gen_andi_i32(t0
, mxu_gpr
[XRb
- 1], 0x000000FF);
26353 tcg_gen_shli_i32(t0
, t0
, 24);
26355 tcg_gen_andi_i32(t1
, mxu_gpr
[XRc
- 1], 0xFFFFFF00);
26356 tcg_gen_shri_i32(t1
, t1
, 8);
26358 tcg_gen_or_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
26364 case MXU_OPTN3_PTN4
:
26368 /* +---------------+ */
26369 /* A B C D | E F G H | */
26370 /* +-------+-------+ */
26375 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRc
- 1]);
26384 * Decoding engine for MXU
26385 * =======================
26390 * Decode MXU pool00
26392 * 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
26393 * +-----------+---------+-----+-------+-------+-------+-----------+
26394 * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL00|
26395 * +-----------+---------+-----+-------+-------+-------+-----------+
26398 static void decode_opc_mxu__pool00(CPUMIPSState
*env
, DisasContext
*ctx
)
26400 uint32_t opcode
= extract32(ctx
->opcode
, 18, 3);
26403 case OPC_MXU_S32MAX
:
26404 case OPC_MXU_S32MIN
:
26405 gen_mxu_S32MAX_S32MIN(ctx
);
26407 case OPC_MXU_D16MAX
:
26408 case OPC_MXU_D16MIN
:
26409 gen_mxu_D16MAX_D16MIN(ctx
);
26411 case OPC_MXU_Q8MAX
:
26412 case OPC_MXU_Q8MIN
:
26413 gen_mxu_Q8MAX_Q8MIN(ctx
);
26415 case OPC_MXU_Q8SLT
:
26416 /* TODO: Implement emulation of Q8SLT instruction. */
26417 MIPS_INVAL("OPC_MXU_Q8SLT");
26418 generate_exception_end(ctx
, EXCP_RI
);
26420 case OPC_MXU_Q8SLTU
:
26421 /* TODO: Implement emulation of Q8SLTU instruction. */
26422 MIPS_INVAL("OPC_MXU_Q8SLTU");
26423 generate_exception_end(ctx
, EXCP_RI
);
26426 MIPS_INVAL("decode_opc_mxu");
26427 generate_exception_end(ctx
, EXCP_RI
);
26434 * Decode MXU pool01
26436 * S32SLT, D16SLT, D16AVG, D16AVGR, Q8AVG, Q8AVGR:
26437 * 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
26438 * +-----------+---------+-----+-------+-------+-------+-----------+
26439 * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL01|
26440 * +-----------+---------+-----+-------+-------+-------+-----------+
26443 * 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
26444 * +-----------+---+-----+-----+-------+-------+-------+-----------+
26445 * | SPECIAL2 |en2|0 0 0|x x x| XRc | XRb | XRa |MXU__POOL01|
26446 * +-----------+---+-----+-----+-------+-------+-------+-----------+
26449 static void decode_opc_mxu__pool01(CPUMIPSState
*env
, DisasContext
*ctx
)
26451 uint32_t opcode
= extract32(ctx
->opcode
, 18, 3);
26454 case OPC_MXU_S32SLT
:
26455 /* TODO: Implement emulation of S32SLT instruction. */
26456 MIPS_INVAL("OPC_MXU_S32SLT");
26457 generate_exception_end(ctx
, EXCP_RI
);
26459 case OPC_MXU_D16SLT
:
26460 /* TODO: Implement emulation of D16SLT instruction. */
26461 MIPS_INVAL("OPC_MXU_D16SLT");
26462 generate_exception_end(ctx
, EXCP_RI
);
26464 case OPC_MXU_D16AVG
:
26465 /* TODO: Implement emulation of D16AVG instruction. */
26466 MIPS_INVAL("OPC_MXU_D16AVG");
26467 generate_exception_end(ctx
, EXCP_RI
);
26469 case OPC_MXU_D16AVGR
:
26470 /* TODO: Implement emulation of D16AVGR instruction. */
26471 MIPS_INVAL("OPC_MXU_D16AVGR");
26472 generate_exception_end(ctx
, EXCP_RI
);
26474 case OPC_MXU_Q8AVG
:
26475 /* TODO: Implement emulation of Q8AVG instruction. */
26476 MIPS_INVAL("OPC_MXU_Q8AVG");
26477 generate_exception_end(ctx
, EXCP_RI
);
26479 case OPC_MXU_Q8AVGR
:
26480 /* TODO: Implement emulation of Q8AVGR instruction. */
26481 MIPS_INVAL("OPC_MXU_Q8AVGR");
26482 generate_exception_end(ctx
, EXCP_RI
);
26484 case OPC_MXU_Q8ADD
:
26485 /* TODO: Implement emulation of Q8ADD instruction. */
26486 MIPS_INVAL("OPC_MXU_Q8ADD");
26487 generate_exception_end(ctx
, EXCP_RI
);
26490 MIPS_INVAL("decode_opc_mxu");
26491 generate_exception_end(ctx
, EXCP_RI
);
26498 * Decode MXU pool02
26500 * 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
26501 * +-----------+---------+-----+-------+-------+-------+-----------+
26502 * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL02|
26503 * +-----------+---------+-----+-------+-------+-------+-----------+
26506 static void decode_opc_mxu__pool02(CPUMIPSState
*env
, DisasContext
*ctx
)
26508 uint32_t opcode
= extract32(ctx
->opcode
, 18, 3);
26511 case OPC_MXU_S32CPS
:
26512 /* TODO: Implement emulation of S32CPS instruction. */
26513 MIPS_INVAL("OPC_MXU_S32CPS");
26514 generate_exception_end(ctx
, EXCP_RI
);
26516 case OPC_MXU_D16CPS
:
26517 /* TODO: Implement emulation of D16CPS instruction. */
26518 MIPS_INVAL("OPC_MXU_D16CPS");
26519 generate_exception_end(ctx
, EXCP_RI
);
26521 case OPC_MXU_Q8ABD
:
26522 /* TODO: Implement emulation of Q8ABD instruction. */
26523 MIPS_INVAL("OPC_MXU_Q8ABD");
26524 generate_exception_end(ctx
, EXCP_RI
);
26526 case OPC_MXU_Q16SAT
:
26527 /* TODO: Implement emulation of Q16SAT instruction. */
26528 MIPS_INVAL("OPC_MXU_Q16SAT");
26529 generate_exception_end(ctx
, EXCP_RI
);
26532 MIPS_INVAL("decode_opc_mxu");
26533 generate_exception_end(ctx
, EXCP_RI
);
26540 * Decode MXU pool03
26543 * 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
26544 * +-----------+---+---+-------+-------+-------+-------+-----------+
26545 * | SPECIAL2 |x x|on2|0 0 0 0| XRc | XRb | XRa |MXU__POOL03|
26546 * +-----------+---+---+-------+-------+-------+-------+-----------+
26549 * 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
26550 * +-----------+---+---+-------+-------+-------+-------+-----------+
26551 * | SPECIAL2 |x x|on2| Xd | XRc | XRb | XRa |MXU__POOL03|
26552 * +-----------+---+---+-------+-------+-------+-------+-----------+
26555 static void decode_opc_mxu__pool03(CPUMIPSState
*env
, DisasContext
*ctx
)
26557 uint32_t opcode
= extract32(ctx
->opcode
, 24, 2);
26560 case OPC_MXU_D16MULF
:
26561 /* TODO: Implement emulation of D16MULF instruction. */
26562 MIPS_INVAL("OPC_MXU_D16MULF");
26563 generate_exception_end(ctx
, EXCP_RI
);
26565 case OPC_MXU_D16MULE
:
26566 /* TODO: Implement emulation of D16MULE instruction. */
26567 MIPS_INVAL("OPC_MXU_D16MULE");
26568 generate_exception_end(ctx
, EXCP_RI
);
26571 MIPS_INVAL("decode_opc_mxu");
26572 generate_exception_end(ctx
, EXCP_RI
);
26579 * Decode MXU pool04
26581 * 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
26582 * +-----------+---------+-+-------------------+-------+-----------+
26583 * | SPECIAL2 | rb |x| s12 | XRa |MXU__POOL04|
26584 * +-----------+---------+-+-------------------+-------+-----------+
26587 static void decode_opc_mxu__pool04(CPUMIPSState
*env
, DisasContext
*ctx
)
26589 uint32_t opcode
= extract32(ctx
->opcode
, 20, 1);
26592 case OPC_MXU_S32LDD
:
26593 case OPC_MXU_S32LDDR
:
26594 gen_mxu_s32ldd_s32lddr(ctx
);
26597 MIPS_INVAL("decode_opc_mxu");
26598 generate_exception_end(ctx
, EXCP_RI
);
26605 * Decode MXU pool05
26607 * 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
26608 * +-----------+---------+-+-------------------+-------+-----------+
26609 * | SPECIAL2 | rb |x| s12 | XRa |MXU__POOL05|
26610 * +-----------+---------+-+-------------------+-------+-----------+
26613 static void decode_opc_mxu__pool05(CPUMIPSState
*env
, DisasContext
*ctx
)
26615 uint32_t opcode
= extract32(ctx
->opcode
, 20, 1);
26618 case OPC_MXU_S32STD
:
26619 /* TODO: Implement emulation of S32STD instruction. */
26620 MIPS_INVAL("OPC_MXU_S32STD");
26621 generate_exception_end(ctx
, EXCP_RI
);
26623 case OPC_MXU_S32STDR
:
26624 /* TODO: Implement emulation of S32STDR instruction. */
26625 MIPS_INVAL("OPC_MXU_S32STDR");
26626 generate_exception_end(ctx
, EXCP_RI
);
26629 MIPS_INVAL("decode_opc_mxu");
26630 generate_exception_end(ctx
, EXCP_RI
);
26637 * Decode MXU pool06
26639 * 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
26640 * +-----------+---------+---------+---+-------+-------+-----------+
26641 * | SPECIAL2 | rb | rc |st2|x x x x| XRa |MXU__POOL06|
26642 * +-----------+---------+---------+---+-------+-------+-----------+
26645 static void decode_opc_mxu__pool06(CPUMIPSState
*env
, DisasContext
*ctx
)
26647 uint32_t opcode
= extract32(ctx
->opcode
, 10, 4);
26650 case OPC_MXU_S32LDDV
:
26651 /* TODO: Implement emulation of S32LDDV instruction. */
26652 MIPS_INVAL("OPC_MXU_S32LDDV");
26653 generate_exception_end(ctx
, EXCP_RI
);
26655 case OPC_MXU_S32LDDVR
:
26656 /* TODO: Implement emulation of S32LDDVR instruction. */
26657 MIPS_INVAL("OPC_MXU_S32LDDVR");
26658 generate_exception_end(ctx
, EXCP_RI
);
26661 MIPS_INVAL("decode_opc_mxu");
26662 generate_exception_end(ctx
, EXCP_RI
);
26669 * Decode MXU pool07
26671 * 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
26672 * +-----------+---------+---------+---+-------+-------+-----------+
26673 * | SPECIAL2 | rb | rc |st2|x x x x| XRa |MXU__POOL07|
26674 * +-----------+---------+---------+---+-------+-------+-----------+
26677 static void decode_opc_mxu__pool07(CPUMIPSState
*env
, DisasContext
*ctx
)
26679 uint32_t opcode
= extract32(ctx
->opcode
, 10, 4);
26682 case OPC_MXU_S32STDV
:
26683 /* TODO: Implement emulation of S32TDV instruction. */
26684 MIPS_INVAL("OPC_MXU_S32TDV");
26685 generate_exception_end(ctx
, EXCP_RI
);
26687 case OPC_MXU_S32STDVR
:
26688 /* TODO: Implement emulation of S32TDVR instruction. */
26689 MIPS_INVAL("OPC_MXU_S32TDVR");
26690 generate_exception_end(ctx
, EXCP_RI
);
26693 MIPS_INVAL("decode_opc_mxu");
26694 generate_exception_end(ctx
, EXCP_RI
);
26701 * Decode MXU pool08
26703 * 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
26704 * +-----------+---------+-+-------------------+-------+-----------+
26705 * | SPECIAL2 | rb |x| s12 | XRa |MXU__POOL08|
26706 * +-----------+---------+-+-------------------+-------+-----------+
26709 static void decode_opc_mxu__pool08(CPUMIPSState
*env
, DisasContext
*ctx
)
26711 uint32_t opcode
= extract32(ctx
->opcode
, 20, 1);
26714 case OPC_MXU_S32LDI
:
26715 /* TODO: Implement emulation of S32LDI instruction. */
26716 MIPS_INVAL("OPC_MXU_S32LDI");
26717 generate_exception_end(ctx
, EXCP_RI
);
26719 case OPC_MXU_S32LDIR
:
26720 /* TODO: Implement emulation of S32LDIR instruction. */
26721 MIPS_INVAL("OPC_MXU_S32LDIR");
26722 generate_exception_end(ctx
, EXCP_RI
);
26725 MIPS_INVAL("decode_opc_mxu");
26726 generate_exception_end(ctx
, EXCP_RI
);
26733 * Decode MXU pool09
26735 * 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
26736 * +-----------+---------+-+-------------------+-------+-----------+
26737 * | SPECIAL2 | rb |x| s12 | XRa |MXU__POOL09|
26738 * +-----------+---------+-+-------------------+-------+-----------+
26741 static void decode_opc_mxu__pool09(CPUMIPSState
*env
, DisasContext
*ctx
)
26743 uint32_t opcode
= extract32(ctx
->opcode
, 5, 0);
26746 case OPC_MXU_S32SDI
:
26747 /* TODO: Implement emulation of S32SDI instruction. */
26748 MIPS_INVAL("OPC_MXU_S32SDI");
26749 generate_exception_end(ctx
, EXCP_RI
);
26751 case OPC_MXU_S32SDIR
:
26752 /* TODO: Implement emulation of S32SDIR instruction. */
26753 MIPS_INVAL("OPC_MXU_S32SDIR");
26754 generate_exception_end(ctx
, EXCP_RI
);
26757 MIPS_INVAL("decode_opc_mxu");
26758 generate_exception_end(ctx
, EXCP_RI
);
26765 * Decode MXU pool10
26767 * 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
26768 * +-----------+---------+---------+---+-------+-------+-----------+
26769 * | SPECIAL2 | rb | rc |st2|x x x x| XRa |MXU__POOL10|
26770 * +-----------+---------+---------+---+-------+-------+-----------+
26773 static void decode_opc_mxu__pool10(CPUMIPSState
*env
, DisasContext
*ctx
)
26775 uint32_t opcode
= extract32(ctx
->opcode
, 5, 0);
26778 case OPC_MXU_S32LDIV
:
26779 /* TODO: Implement emulation of S32LDIV instruction. */
26780 MIPS_INVAL("OPC_MXU_S32LDIV");
26781 generate_exception_end(ctx
, EXCP_RI
);
26783 case OPC_MXU_S32LDIVR
:
26784 /* TODO: Implement emulation of S32LDIVR instruction. */
26785 MIPS_INVAL("OPC_MXU_S32LDIVR");
26786 generate_exception_end(ctx
, EXCP_RI
);
26789 MIPS_INVAL("decode_opc_mxu");
26790 generate_exception_end(ctx
, EXCP_RI
);
26797 * Decode MXU pool11
26799 * 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
26800 * +-----------+---------+---------+---+-------+-------+-----------+
26801 * | SPECIAL2 | rb | rc |st2|x x x x| XRa |MXU__POOL11|
26802 * +-----------+---------+---------+---+-------+-------+-----------+
26805 static void decode_opc_mxu__pool11(CPUMIPSState
*env
, DisasContext
*ctx
)
26807 uint32_t opcode
= extract32(ctx
->opcode
, 10, 4);
26810 case OPC_MXU_S32SDIV
:
26811 /* TODO: Implement emulation of S32SDIV instruction. */
26812 MIPS_INVAL("OPC_MXU_S32SDIV");
26813 generate_exception_end(ctx
, EXCP_RI
);
26815 case OPC_MXU_S32SDIVR
:
26816 /* TODO: Implement emulation of S32SDIVR instruction. */
26817 MIPS_INVAL("OPC_MXU_S32SDIVR");
26818 generate_exception_end(ctx
, EXCP_RI
);
26821 MIPS_INVAL("decode_opc_mxu");
26822 generate_exception_end(ctx
, EXCP_RI
);
26829 * Decode MXU pool12
26831 * 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
26832 * +-----------+---+---+-------+-------+-------+-------+-----------+
26833 * | SPECIAL2 |an2|x x| Xd | XRc | XRb | XRa |MXU__POOL12|
26834 * +-----------+---+---+-------+-------+-------+-------+-----------+
26837 static void decode_opc_mxu__pool12(CPUMIPSState
*env
, DisasContext
*ctx
)
26839 uint32_t opcode
= extract32(ctx
->opcode
, 22, 2);
26842 case OPC_MXU_D32ACC
:
26843 /* TODO: Implement emulation of D32ACC instruction. */
26844 MIPS_INVAL("OPC_MXU_D32ACC");
26845 generate_exception_end(ctx
, EXCP_RI
);
26847 case OPC_MXU_D32ACCM
:
26848 /* TODO: Implement emulation of D32ACCM instruction. */
26849 MIPS_INVAL("OPC_MXU_D32ACCM");
26850 generate_exception_end(ctx
, EXCP_RI
);
26852 case OPC_MXU_D32ASUM
:
26853 /* TODO: Implement emulation of D32ASUM instruction. */
26854 MIPS_INVAL("OPC_MXU_D32ASUM");
26855 generate_exception_end(ctx
, EXCP_RI
);
26858 MIPS_INVAL("decode_opc_mxu");
26859 generate_exception_end(ctx
, EXCP_RI
);
26866 * Decode MXU pool13
26868 * 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
26869 * +-----------+---+---+-------+-------+-------+-------+-----------+
26870 * | SPECIAL2 |en2|x x|0 0 0 0| XRc | XRb | XRa |MXU__POOL13|
26871 * +-----------+---+---+-------+-------+-------+-------+-----------+
26874 static void decode_opc_mxu__pool13(CPUMIPSState
*env
, DisasContext
*ctx
)
26876 uint32_t opcode
= extract32(ctx
->opcode
, 22, 2);
26879 case OPC_MXU_Q16ACC
:
26880 /* TODO: Implement emulation of Q16ACC instruction. */
26881 MIPS_INVAL("OPC_MXU_Q16ACC");
26882 generate_exception_end(ctx
, EXCP_RI
);
26884 case OPC_MXU_Q16ACCM
:
26885 /* TODO: Implement emulation of Q16ACCM instruction. */
26886 MIPS_INVAL("OPC_MXU_Q16ACCM");
26887 generate_exception_end(ctx
, EXCP_RI
);
26889 case OPC_MXU_Q16ASUM
:
26890 /* TODO: Implement emulation of Q16ASUM instruction. */
26891 MIPS_INVAL("OPC_MXU_Q16ASUM");
26892 generate_exception_end(ctx
, EXCP_RI
);
26895 MIPS_INVAL("decode_opc_mxu");
26896 generate_exception_end(ctx
, EXCP_RI
);
26903 * Decode MXU pool14
26906 * 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
26907 * +-----------+---+---+-------+-------+-------+-------+-----------+
26908 * | SPECIAL2 |0 0|x x| XRd | XRc | XRb | XRa |MXU__POOL14|
26909 * +-----------+---+---+-------+-------+-------+-------+-----------+
26912 * 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
26913 * +-----------+---+---+-------+-------+-------+-------+-----------+
26914 * | SPECIAL2 |en2|x x|0 0 0 0| XRc | XRb | XRa |MXU__POOL14|
26915 * +-----------+---+---+-------+-------+-------+-------+-----------+
26918 static void decode_opc_mxu__pool14(CPUMIPSState
*env
, DisasContext
*ctx
)
26920 uint32_t opcode
= extract32(ctx
->opcode
, 22, 2);
26923 case OPC_MXU_Q8ADDE
:
26924 /* TODO: Implement emulation of Q8ADDE instruction. */
26925 MIPS_INVAL("OPC_MXU_Q8ADDE");
26926 generate_exception_end(ctx
, EXCP_RI
);
26928 case OPC_MXU_D8SUM
:
26929 /* TODO: Implement emulation of D8SUM instruction. */
26930 MIPS_INVAL("OPC_MXU_D8SUM");
26931 generate_exception_end(ctx
, EXCP_RI
);
26933 case OPC_MXU_D8SUMC
:
26934 /* TODO: Implement emulation of D8SUMC instruction. */
26935 MIPS_INVAL("OPC_MXU_D8SUMC");
26936 generate_exception_end(ctx
, EXCP_RI
);
26939 MIPS_INVAL("decode_opc_mxu");
26940 generate_exception_end(ctx
, EXCP_RI
);
26947 * Decode MXU pool15
26949 * S32MUL, S32MULU, S32EXTRV:
26950 * 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
26951 * +-----------+---------+---------+---+-------+-------+-----------+
26952 * | SPECIAL2 | rs | rt |x x| XRd | XRa |MXU__POOL15|
26953 * +-----------+---------+---------+---+-------+-------+-----------+
26956 * 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
26957 * +-----------+---------+---------+---+-------+-------+-----------+
26958 * | SPECIAL2 | rb | sft5 |x x| XRd | XRa |MXU__POOL15|
26959 * +-----------+---------+---------+---+-------+-------+-----------+
26962 static void decode_opc_mxu__pool15(CPUMIPSState
*env
, DisasContext
*ctx
)
26964 uint32_t opcode
= extract32(ctx
->opcode
, 14, 2);
26967 case OPC_MXU_S32MUL
:
26968 /* TODO: Implement emulation of S32MUL instruction. */
26969 MIPS_INVAL("OPC_MXU_S32MUL");
26970 generate_exception_end(ctx
, EXCP_RI
);
26972 case OPC_MXU_S32MULU
:
26973 /* TODO: Implement emulation of S32MULU instruction. */
26974 MIPS_INVAL("OPC_MXU_S32MULU");
26975 generate_exception_end(ctx
, EXCP_RI
);
26977 case OPC_MXU_S32EXTR
:
26978 /* TODO: Implement emulation of S32EXTR instruction. */
26979 MIPS_INVAL("OPC_MXU_S32EXTR");
26980 generate_exception_end(ctx
, EXCP_RI
);
26982 case OPC_MXU_S32EXTRV
:
26983 /* TODO: Implement emulation of S32EXTRV instruction. */
26984 MIPS_INVAL("OPC_MXU_S32EXTRV");
26985 generate_exception_end(ctx
, EXCP_RI
);
26988 MIPS_INVAL("decode_opc_mxu");
26989 generate_exception_end(ctx
, EXCP_RI
);
26996 * Decode MXU pool16
26999 * 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
27000 * +-----------+---------+-----+-------+-------+-------+-----------+
27001 * | SPECIAL2 | rb |x x x| XRc | XRb | XRa |MXU__POOL16|
27002 * +-----------+---------+-----+-------+-------+-------+-----------+
27005 * 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
27006 * +-----------+---------+-----+-------+-------+-------+-----------+
27007 * | SPECIAL2 | rs |x x x| XRc | XRb | XRa |MXU__POOL16|
27008 * +-----------+---------+-----+-------+-------+-------+-----------+
27011 * 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
27012 * +-----------+-----+---+-----+-------+-------+-------+-----------+
27013 * | SPECIAL2 | s3 |0 0|x x x| XRc | XRb | XRa |MXU__POOL16|
27014 * +-----------+-----+---+-----+-------+-------+-------+-----------+
27017 * 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
27018 * +-----------+-----+---+-----+-------+---------------+-----------+
27019 * | SPECIAL2 |optn3|0 0|x x x| XRc | s8 |MXU__POOL16|
27020 * +-----------+-----+---+-----+-------+---------------+-----------+
27022 * S32NOR, S32AND, S32OR, S32XOR:
27023 * 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
27024 * +-----------+---------+-----+-------+-------+-------+-----------+
27025 * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL16|
27026 * +-----------+---------+-----+-------+-------+-------+-----------+
27029 static void decode_opc_mxu__pool16(CPUMIPSState
*env
, DisasContext
*ctx
)
27031 uint32_t opcode
= extract32(ctx
->opcode
, 18, 3);
27034 case OPC_MXU_D32SARW
:
27035 /* TODO: Implement emulation of D32SARW instruction. */
27036 MIPS_INVAL("OPC_MXU_D32SARW");
27037 generate_exception_end(ctx
, EXCP_RI
);
27039 case OPC_MXU_S32ALN
:
27040 /* TODO: Implement emulation of S32ALN instruction. */
27041 MIPS_INVAL("OPC_MXU_S32ALN");
27042 generate_exception_end(ctx
, EXCP_RI
);
27044 case OPC_MXU_S32ALNI
:
27045 gen_mxu_S32ALNI(ctx
);
27047 case OPC_MXU_S32LUI
:
27048 /* TODO: Implement emulation of S32LUI instruction. */
27049 MIPS_INVAL("OPC_MXU_S32LUI");
27050 generate_exception_end(ctx
, EXCP_RI
);
27052 case OPC_MXU_S32NOR
:
27053 gen_mxu_S32NOR(ctx
);
27055 case OPC_MXU_S32AND
:
27056 gen_mxu_S32AND(ctx
);
27058 case OPC_MXU_S32OR
:
27059 gen_mxu_S32OR(ctx
);
27061 case OPC_MXU_S32XOR
:
27062 gen_mxu_S32XOR(ctx
);
27065 MIPS_INVAL("decode_opc_mxu");
27066 generate_exception_end(ctx
, EXCP_RI
);
27073 * Decode MXU pool17
27075 * 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
27076 * +-----------+---------+---------+---+---------+-----+-----------+
27077 * | SPECIAL2 | rs | rt |0 0| rd |x x x|MXU__POOL15|
27078 * +-----------+---------+---------+---+---------+-----+-----------+
27081 static void decode_opc_mxu__pool17(CPUMIPSState
*env
, DisasContext
*ctx
)
27083 uint32_t opcode
= extract32(ctx
->opcode
, 6, 2);
27087 /* TODO: Implement emulation of LXW instruction. */
27088 MIPS_INVAL("OPC_MXU_LXW");
27089 generate_exception_end(ctx
, EXCP_RI
);
27092 /* TODO: Implement emulation of LXH instruction. */
27093 MIPS_INVAL("OPC_MXU_LXH");
27094 generate_exception_end(ctx
, EXCP_RI
);
27097 /* TODO: Implement emulation of LXHU instruction. */
27098 MIPS_INVAL("OPC_MXU_LXHU");
27099 generate_exception_end(ctx
, EXCP_RI
);
27102 /* TODO: Implement emulation of LXB instruction. */
27103 MIPS_INVAL("OPC_MXU_LXB");
27104 generate_exception_end(ctx
, EXCP_RI
);
27107 /* TODO: Implement emulation of LXBU instruction. */
27108 MIPS_INVAL("OPC_MXU_LXBU");
27109 generate_exception_end(ctx
, EXCP_RI
);
27112 MIPS_INVAL("decode_opc_mxu");
27113 generate_exception_end(ctx
, EXCP_RI
);
27119 * Decode MXU pool18
27121 * 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
27122 * +-----------+---------+-----+-------+-------+-------+-----------+
27123 * | SPECIAL2 | rb |x x x| XRd | XRa |0 0 0 0|MXU__POOL18|
27124 * +-----------+---------+-----+-------+-------+-------+-----------+
27127 static void decode_opc_mxu__pool18(CPUMIPSState
*env
, DisasContext
*ctx
)
27129 uint32_t opcode
= extract32(ctx
->opcode
, 18, 3);
27132 case OPC_MXU_D32SLLV
:
27133 /* TODO: Implement emulation of D32SLLV instruction. */
27134 MIPS_INVAL("OPC_MXU_D32SLLV");
27135 generate_exception_end(ctx
, EXCP_RI
);
27137 case OPC_MXU_D32SLRV
:
27138 /* TODO: Implement emulation of D32SLRV instruction. */
27139 MIPS_INVAL("OPC_MXU_D32SLRV");
27140 generate_exception_end(ctx
, EXCP_RI
);
27142 case OPC_MXU_D32SARV
:
27143 /* TODO: Implement emulation of D32SARV instruction. */
27144 MIPS_INVAL("OPC_MXU_D32SARV");
27145 generate_exception_end(ctx
, EXCP_RI
);
27147 case OPC_MXU_Q16SLLV
:
27148 /* TODO: Implement emulation of Q16SLLV instruction. */
27149 MIPS_INVAL("OPC_MXU_Q16SLLV");
27150 generate_exception_end(ctx
, EXCP_RI
);
27152 case OPC_MXU_Q16SLRV
:
27153 /* TODO: Implement emulation of Q16SLRV instruction. */
27154 MIPS_INVAL("OPC_MXU_Q16SLRV");
27155 generate_exception_end(ctx
, EXCP_RI
);
27157 case OPC_MXU_Q16SARV
:
27158 /* TODO: Implement emulation of Q16SARV instruction. */
27159 MIPS_INVAL("OPC_MXU_Q16SARV");
27160 generate_exception_end(ctx
, EXCP_RI
);
27163 MIPS_INVAL("decode_opc_mxu");
27164 generate_exception_end(ctx
, EXCP_RI
);
27171 * Decode MXU pool19
27173 * 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
27174 * +-----------+---+---+-------+-------+-------+-------+-----------+
27175 * | SPECIAL2 |0 0|x x| XRd | XRc | XRb | XRa |MXU__POOL19|
27176 * +-----------+---+---+-------+-------+-------+-------+-----------+
27179 static void decode_opc_mxu__pool19(CPUMIPSState
*env
, DisasContext
*ctx
)
27181 uint32_t opcode
= extract32(ctx
->opcode
, 22, 2);
27184 case OPC_MXU_Q8MUL
:
27185 case OPC_MXU_Q8MULSU
:
27186 gen_mxu_q8mul_q8mulsu(ctx
);
27189 MIPS_INVAL("decode_opc_mxu");
27190 generate_exception_end(ctx
, EXCP_RI
);
27197 * Decode MXU pool20
27199 * 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
27200 * +-----------+---------+-----+-------+-------+-------+-----------+
27201 * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL20|
27202 * +-----------+---------+-----+-------+-------+-------+-----------+
27205 static void decode_opc_mxu__pool20(CPUMIPSState
*env
, DisasContext
*ctx
)
27207 uint32_t opcode
= extract32(ctx
->opcode
, 18, 3);
27210 case OPC_MXU_Q8MOVZ
:
27211 /* TODO: Implement emulation of Q8MOVZ instruction. */
27212 MIPS_INVAL("OPC_MXU_Q8MOVZ");
27213 generate_exception_end(ctx
, EXCP_RI
);
27215 case OPC_MXU_Q8MOVN
:
27216 /* TODO: Implement emulation of Q8MOVN instruction. */
27217 MIPS_INVAL("OPC_MXU_Q8MOVN");
27218 generate_exception_end(ctx
, EXCP_RI
);
27220 case OPC_MXU_D16MOVZ
:
27221 /* TODO: Implement emulation of D16MOVZ instruction. */
27222 MIPS_INVAL("OPC_MXU_D16MOVZ");
27223 generate_exception_end(ctx
, EXCP_RI
);
27225 case OPC_MXU_D16MOVN
:
27226 /* TODO: Implement emulation of D16MOVN instruction. */
27227 MIPS_INVAL("OPC_MXU_D16MOVN");
27228 generate_exception_end(ctx
, EXCP_RI
);
27230 case OPC_MXU_S32MOVZ
:
27231 /* TODO: Implement emulation of S32MOVZ instruction. */
27232 MIPS_INVAL("OPC_MXU_S32MOVZ");
27233 generate_exception_end(ctx
, EXCP_RI
);
27235 case OPC_MXU_S32MOVN
:
27236 /* TODO: Implement emulation of S32MOVN instruction. */
27237 MIPS_INVAL("OPC_MXU_S32MOVN");
27238 generate_exception_end(ctx
, EXCP_RI
);
27241 MIPS_INVAL("decode_opc_mxu");
27242 generate_exception_end(ctx
, EXCP_RI
);
27249 * Decode MXU pool21
27251 * 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
27252 * +-----------+---+---+-------+-------+-------+-------+-----------+
27253 * | SPECIAL2 |an2|x x| XRd | XRc | XRb | XRa |MXU__POOL21|
27254 * +-----------+---+---+-------+-------+-------+-------+-----------+
27257 static void decode_opc_mxu__pool21(CPUMIPSState
*env
, DisasContext
*ctx
)
27259 uint32_t opcode
= extract32(ctx
->opcode
, 22, 2);
27262 case OPC_MXU_Q8MAC
:
27263 /* TODO: Implement emulation of Q8MAC instruction. */
27264 MIPS_INVAL("OPC_MXU_Q8MAC");
27265 generate_exception_end(ctx
, EXCP_RI
);
27267 case OPC_MXU_Q8MACSU
:
27268 /* TODO: Implement emulation of Q8MACSU instruction. */
27269 MIPS_INVAL("OPC_MXU_Q8MACSU");
27270 generate_exception_end(ctx
, EXCP_RI
);
27273 MIPS_INVAL("decode_opc_mxu");
27274 generate_exception_end(ctx
, EXCP_RI
);
27281 * Main MXU decoding function
27283 * 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
27284 * +-----------+---------------------------------------+-----------+
27285 * | SPECIAL2 | |x x x x x x|
27286 * +-----------+---------------------------------------+-----------+
27289 static void decode_opc_mxu(CPUMIPSState
*env
, DisasContext
*ctx
)
27292 * TODO: Investigate necessity of including handling of
27293 * CLZ, CLO, SDBB in this function, as they belong to
27294 * SPECIAL2 opcode space for regular pre-R6 MIPS ISAs.
27296 uint32_t opcode
= extract32(ctx
->opcode
, 0, 6);
27298 if (opcode
== OPC__MXU_MUL
) {
27299 uint32_t rs
, rt
, rd
, op1
;
27301 rs
= extract32(ctx
->opcode
, 21, 5);
27302 rt
= extract32(ctx
->opcode
, 16, 5);
27303 rd
= extract32(ctx
->opcode
, 11, 5);
27304 op1
= MASK_SPECIAL2(ctx
->opcode
);
27306 gen_arith(ctx
, op1
, rd
, rs
, rt
);
27311 if (opcode
== OPC_MXU_S32M2I
) {
27312 gen_mxu_s32m2i(ctx
);
27316 if (opcode
== OPC_MXU_S32I2M
) {
27317 gen_mxu_s32i2m(ctx
);
27322 TCGv t_mxu_cr
= tcg_temp_new();
27323 TCGLabel
*l_exit
= gen_new_label();
27325 gen_load_mxu_cr(t_mxu_cr
);
27326 tcg_gen_andi_tl(t_mxu_cr
, t_mxu_cr
, MXU_CR_MXU_EN
);
27327 tcg_gen_brcondi_tl(TCG_COND_NE
, t_mxu_cr
, MXU_CR_MXU_EN
, l_exit
);
27330 case OPC_MXU_S32MADD
:
27331 /* TODO: Implement emulation of S32MADD instruction. */
27332 MIPS_INVAL("OPC_MXU_S32MADD");
27333 generate_exception_end(ctx
, EXCP_RI
);
27335 case OPC_MXU_S32MADDU
:
27336 /* TODO: Implement emulation of S32MADDU instruction. */
27337 MIPS_INVAL("OPC_MXU_S32MADDU");
27338 generate_exception_end(ctx
, EXCP_RI
);
27340 case OPC_MXU__POOL00
:
27341 decode_opc_mxu__pool00(env
, ctx
);
27343 case OPC_MXU_S32MSUB
:
27344 /* TODO: Implement emulation of S32MSUB instruction. */
27345 MIPS_INVAL("OPC_MXU_S32MSUB");
27346 generate_exception_end(ctx
, EXCP_RI
);
27348 case OPC_MXU_S32MSUBU
:
27349 /* TODO: Implement emulation of S32MSUBU instruction. */
27350 MIPS_INVAL("OPC_MXU_S32MSUBU");
27351 generate_exception_end(ctx
, EXCP_RI
);
27353 case OPC_MXU__POOL01
:
27354 decode_opc_mxu__pool01(env
, ctx
);
27356 case OPC_MXU__POOL02
:
27357 decode_opc_mxu__pool02(env
, ctx
);
27359 case OPC_MXU_D16MUL
:
27360 gen_mxu_d16mul(ctx
);
27362 case OPC_MXU__POOL03
:
27363 decode_opc_mxu__pool03(env
, ctx
);
27365 case OPC_MXU_D16MAC
:
27366 gen_mxu_d16mac(ctx
);
27368 case OPC_MXU_D16MACF
:
27369 /* TODO: Implement emulation of D16MACF instruction. */
27370 MIPS_INVAL("OPC_MXU_D16MACF");
27371 generate_exception_end(ctx
, EXCP_RI
);
27373 case OPC_MXU_D16MADL
:
27374 /* TODO: Implement emulation of D16MADL instruction. */
27375 MIPS_INVAL("OPC_MXU_D16MADL");
27376 generate_exception_end(ctx
, EXCP_RI
);
27378 case OPC_MXU_S16MAD
:
27379 /* TODO: Implement emulation of S16MAD instruction. */
27380 MIPS_INVAL("OPC_MXU_S16MAD");
27381 generate_exception_end(ctx
, EXCP_RI
);
27383 case OPC_MXU_Q16ADD
:
27384 /* TODO: Implement emulation of Q16ADD instruction. */
27385 MIPS_INVAL("OPC_MXU_Q16ADD");
27386 generate_exception_end(ctx
, EXCP_RI
);
27388 case OPC_MXU_D16MACE
:
27389 /* TODO: Implement emulation of D16MACE instruction. */
27390 MIPS_INVAL("OPC_MXU_D16MACE");
27391 generate_exception_end(ctx
, EXCP_RI
);
27393 case OPC_MXU__POOL04
:
27394 decode_opc_mxu__pool04(env
, ctx
);
27396 case OPC_MXU__POOL05
:
27397 decode_opc_mxu__pool05(env
, ctx
);
27399 case OPC_MXU__POOL06
:
27400 decode_opc_mxu__pool06(env
, ctx
);
27402 case OPC_MXU__POOL07
:
27403 decode_opc_mxu__pool07(env
, ctx
);
27405 case OPC_MXU__POOL08
:
27406 decode_opc_mxu__pool08(env
, ctx
);
27408 case OPC_MXU__POOL09
:
27409 decode_opc_mxu__pool09(env
, ctx
);
27411 case OPC_MXU__POOL10
:
27412 decode_opc_mxu__pool10(env
, ctx
);
27414 case OPC_MXU__POOL11
:
27415 decode_opc_mxu__pool11(env
, ctx
);
27417 case OPC_MXU_D32ADD
:
27418 /* TODO: Implement emulation of D32ADD instruction. */
27419 MIPS_INVAL("OPC_MXU_D32ADD");
27420 generate_exception_end(ctx
, EXCP_RI
);
27422 case OPC_MXU__POOL12
:
27423 decode_opc_mxu__pool12(env
, ctx
);
27425 case OPC_MXU__POOL13
:
27426 decode_opc_mxu__pool13(env
, ctx
);
27428 case OPC_MXU__POOL14
:
27429 decode_opc_mxu__pool14(env
, ctx
);
27431 case OPC_MXU_Q8ACCE
:
27432 /* TODO: Implement emulation of Q8ACCE instruction. */
27433 MIPS_INVAL("OPC_MXU_Q8ACCE");
27434 generate_exception_end(ctx
, EXCP_RI
);
27436 case OPC_MXU_S8LDD
:
27437 gen_mxu_s8ldd(ctx
);
27439 case OPC_MXU_S8STD
:
27440 /* TODO: Implement emulation of S8STD instruction. */
27441 MIPS_INVAL("OPC_MXU_S8STD");
27442 generate_exception_end(ctx
, EXCP_RI
);
27444 case OPC_MXU_S8LDI
:
27445 /* TODO: Implement emulation of S8LDI instruction. */
27446 MIPS_INVAL("OPC_MXU_S8LDI");
27447 generate_exception_end(ctx
, EXCP_RI
);
27449 case OPC_MXU_S8SDI
:
27450 /* TODO: Implement emulation of S8SDI instruction. */
27451 MIPS_INVAL("OPC_MXU_S8SDI");
27452 generate_exception_end(ctx
, EXCP_RI
);
27454 case OPC_MXU__POOL15
:
27455 decode_opc_mxu__pool15(env
, ctx
);
27457 case OPC_MXU__POOL16
:
27458 decode_opc_mxu__pool16(env
, ctx
);
27460 case OPC_MXU__POOL17
:
27461 decode_opc_mxu__pool17(env
, ctx
);
27463 case OPC_MXU_S16LDD
:
27464 /* TODO: Implement emulation of S16LDD instruction. */
27465 MIPS_INVAL("OPC_MXU_S16LDD");
27466 generate_exception_end(ctx
, EXCP_RI
);
27468 case OPC_MXU_S16STD
:
27469 /* TODO: Implement emulation of S16STD instruction. */
27470 MIPS_INVAL("OPC_MXU_S16STD");
27471 generate_exception_end(ctx
, EXCP_RI
);
27473 case OPC_MXU_S16LDI
:
27474 /* TODO: Implement emulation of S16LDI instruction. */
27475 MIPS_INVAL("OPC_MXU_S16LDI");
27476 generate_exception_end(ctx
, EXCP_RI
);
27478 case OPC_MXU_S16SDI
:
27479 /* TODO: Implement emulation of S16SDI instruction. */
27480 MIPS_INVAL("OPC_MXU_S16SDI");
27481 generate_exception_end(ctx
, EXCP_RI
);
27483 case OPC_MXU_D32SLL
:
27484 /* TODO: Implement emulation of D32SLL instruction. */
27485 MIPS_INVAL("OPC_MXU_D32SLL");
27486 generate_exception_end(ctx
, EXCP_RI
);
27488 case OPC_MXU_D32SLR
:
27489 /* TODO: Implement emulation of D32SLR instruction. */
27490 MIPS_INVAL("OPC_MXU_D32SLR");
27491 generate_exception_end(ctx
, EXCP_RI
);
27493 case OPC_MXU_D32SARL
:
27494 /* TODO: Implement emulation of D32SARL instruction. */
27495 MIPS_INVAL("OPC_MXU_D32SARL");
27496 generate_exception_end(ctx
, EXCP_RI
);
27498 case OPC_MXU_D32SAR
:
27499 /* TODO: Implement emulation of D32SAR instruction. */
27500 MIPS_INVAL("OPC_MXU_D32SAR");
27501 generate_exception_end(ctx
, EXCP_RI
);
27503 case OPC_MXU_Q16SLL
:
27504 /* TODO: Implement emulation of Q16SLL instruction. */
27505 MIPS_INVAL("OPC_MXU_Q16SLL");
27506 generate_exception_end(ctx
, EXCP_RI
);
27508 case OPC_MXU_Q16SLR
:
27509 /* TODO: Implement emulation of Q16SLR instruction. */
27510 MIPS_INVAL("OPC_MXU_Q16SLR");
27511 generate_exception_end(ctx
, EXCP_RI
);
27513 case OPC_MXU__POOL18
:
27514 decode_opc_mxu__pool18(env
, ctx
);
27516 case OPC_MXU_Q16SAR
:
27517 /* TODO: Implement emulation of Q16SAR instruction. */
27518 MIPS_INVAL("OPC_MXU_Q16SAR");
27519 generate_exception_end(ctx
, EXCP_RI
);
27521 case OPC_MXU__POOL19
:
27522 decode_opc_mxu__pool19(env
, ctx
);
27524 case OPC_MXU__POOL20
:
27525 decode_opc_mxu__pool20(env
, ctx
);
27527 case OPC_MXU__POOL21
:
27528 decode_opc_mxu__pool21(env
, ctx
);
27530 case OPC_MXU_Q16SCOP
:
27531 /* TODO: Implement emulation of Q16SCOP instruction. */
27532 MIPS_INVAL("OPC_MXU_Q16SCOP");
27533 generate_exception_end(ctx
, EXCP_RI
);
27535 case OPC_MXU_Q8MADL
:
27536 /* TODO: Implement emulation of Q8MADL instruction. */
27537 MIPS_INVAL("OPC_MXU_Q8MADL");
27538 generate_exception_end(ctx
, EXCP_RI
);
27540 case OPC_MXU_S32SFL
:
27541 /* TODO: Implement emulation of S32SFL instruction. */
27542 MIPS_INVAL("OPC_MXU_S32SFL");
27543 generate_exception_end(ctx
, EXCP_RI
);
27545 case OPC_MXU_Q8SAD
:
27546 /* TODO: Implement emulation of Q8SAD instruction. */
27547 MIPS_INVAL("OPC_MXU_Q8SAD");
27548 generate_exception_end(ctx
, EXCP_RI
);
27551 MIPS_INVAL("decode_opc_mxu");
27552 generate_exception_end(ctx
, EXCP_RI
);
27555 gen_set_label(l_exit
);
27556 tcg_temp_free(t_mxu_cr
);
27560 #endif /* !defined(TARGET_MIPS64) */
27563 static void decode_opc_special2_legacy(CPUMIPSState
*env
, DisasContext
*ctx
)
27568 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
27570 rs
= (ctx
->opcode
>> 21) & 0x1f;
27571 rt
= (ctx
->opcode
>> 16) & 0x1f;
27572 rd
= (ctx
->opcode
>> 11) & 0x1f;
27574 op1
= MASK_SPECIAL2(ctx
->opcode
);
27576 case OPC_MADD
: /* Multiply and add/sub */
27580 check_insn(ctx
, ISA_MIPS32
);
27581 gen_muldiv(ctx
, op1
, rd
& 3, rs
, rt
);
27584 gen_arith(ctx
, op1
, rd
, rs
, rt
);
27587 case OPC_DIVU_G_2F
:
27588 case OPC_MULT_G_2F
:
27589 case OPC_MULTU_G_2F
:
27591 case OPC_MODU_G_2F
:
27592 check_insn(ctx
, INSN_LOONGSON2F
| ASE_LEXT
);
27593 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
27597 check_insn(ctx
, ISA_MIPS32
);
27598 gen_cl(ctx
, op1
, rd
, rs
);
27601 if (is_uhi(extract32(ctx
->opcode
, 6, 20))) {
27602 gen_helper_do_semihosting(cpu_env
);
27605 * XXX: not clear which exception should be raised
27606 * when in debug mode...
27608 check_insn(ctx
, ISA_MIPS32
);
27609 generate_exception_end(ctx
, EXCP_DBp
);
27612 #if defined(TARGET_MIPS64)
27615 check_insn(ctx
, ISA_MIPS32
);
27616 check_mips_64(ctx
);
27617 gen_cl(ctx
, op1
, rd
, rs
);
27619 case OPC_DMULT_G_2F
:
27620 case OPC_DMULTU_G_2F
:
27621 case OPC_DDIV_G_2F
:
27622 case OPC_DDIVU_G_2F
:
27623 case OPC_DMOD_G_2F
:
27624 case OPC_DMODU_G_2F
:
27625 check_insn(ctx
, INSN_LOONGSON2F
| ASE_LEXT
);
27626 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
27629 default: /* Invalid */
27630 MIPS_INVAL("special2_legacy");
27631 generate_exception_end(ctx
, EXCP_RI
);
27636 static void decode_opc_special3_r6(CPUMIPSState
*env
, DisasContext
*ctx
)
27638 int rs
, rt
, rd
, sa
;
27642 rs
= (ctx
->opcode
>> 21) & 0x1f;
27643 rt
= (ctx
->opcode
>> 16) & 0x1f;
27644 rd
= (ctx
->opcode
>> 11) & 0x1f;
27645 sa
= (ctx
->opcode
>> 6) & 0x1f;
27646 imm
= (int16_t)ctx
->opcode
>> 7;
27648 op1
= MASK_SPECIAL3(ctx
->opcode
);
27652 /* hint codes 24-31 are reserved and signal RI */
27653 generate_exception_end(ctx
, EXCP_RI
);
27655 /* Treat as NOP. */
27658 check_cp0_enabled(ctx
);
27659 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
27660 gen_cache_operation(ctx
, rt
, rs
, imm
);
27664 gen_st_cond(ctx
, rt
, rs
, imm
, MO_TESL
, false);
27667 gen_ld(ctx
, op1
, rt
, rs
, imm
);
27672 /* Treat as NOP. */
27675 op2
= MASK_BSHFL(ctx
->opcode
);
27681 gen_align(ctx
, 32, rd
, rs
, rt
, sa
& 3);
27684 gen_bitswap(ctx
, op2
, rd
, rt
);
27689 #ifndef CONFIG_USER_ONLY
27691 if (unlikely(ctx
->gi
<= 1)) {
27692 generate_exception_end(ctx
, EXCP_RI
);
27694 check_cp0_enabled(ctx
);
27695 switch ((ctx
->opcode
>> 6) & 3) {
27696 case 0: /* GINVI */
27697 /* Treat as NOP. */
27699 case 2: /* GINVT */
27700 gen_helper_0e1i(ginvt
, cpu_gpr
[rs
], extract32(ctx
->opcode
, 8, 2));
27703 generate_exception_end(ctx
, EXCP_RI
);
27708 #if defined(TARGET_MIPS64)
27710 gen_st_cond(ctx
, rt
, rs
, imm
, MO_TEQ
, false);
27713 gen_ld(ctx
, op1
, rt
, rs
, imm
);
27716 check_mips_64(ctx
);
27719 /* Treat as NOP. */
27722 op2
= MASK_DBSHFL(ctx
->opcode
);
27732 gen_align(ctx
, 64, rd
, rs
, rt
, sa
& 7);
27735 gen_bitswap(ctx
, op2
, rd
, rt
);
27742 default: /* Invalid */
27743 MIPS_INVAL("special3_r6");
27744 generate_exception_end(ctx
, EXCP_RI
);
27749 static void decode_opc_special3_legacy(CPUMIPSState
*env
, DisasContext
*ctx
)
27754 rs
= (ctx
->opcode
>> 21) & 0x1f;
27755 rt
= (ctx
->opcode
>> 16) & 0x1f;
27756 rd
= (ctx
->opcode
>> 11) & 0x1f;
27758 op1
= MASK_SPECIAL3(ctx
->opcode
);
27761 case OPC_DIVU_G_2E
:
27763 case OPC_MODU_G_2E
:
27764 case OPC_MULT_G_2E
:
27765 case OPC_MULTU_G_2E
:
27767 * OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
27768 * the same mask and op1.
27770 if ((ctx
->insn_flags
& ASE_DSP_R2
) && (op1
== OPC_MULT_G_2E
)) {
27771 op2
= MASK_ADDUH_QB(ctx
->opcode
);
27774 case OPC_ADDUH_R_QB
:
27776 case OPC_ADDQH_R_PH
:
27778 case OPC_ADDQH_R_W
:
27780 case OPC_SUBUH_R_QB
:
27782 case OPC_SUBQH_R_PH
:
27784 case OPC_SUBQH_R_W
:
27785 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
27790 case OPC_MULQ_RS_W
:
27791 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
27794 MIPS_INVAL("MASK ADDUH.QB");
27795 generate_exception_end(ctx
, EXCP_RI
);
27798 } else if (ctx
->insn_flags
& INSN_LOONGSON2E
) {
27799 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
27801 generate_exception_end(ctx
, EXCP_RI
);
27805 op2
= MASK_LX(ctx
->opcode
);
27807 #if defined(TARGET_MIPS64)
27813 gen_mipsdsp_ld(ctx
, op2
, rd
, rs
, rt
);
27815 default: /* Invalid */
27816 MIPS_INVAL("MASK LX");
27817 generate_exception_end(ctx
, EXCP_RI
);
27821 case OPC_ABSQ_S_PH_DSP
:
27822 op2
= MASK_ABSQ_S_PH(ctx
->opcode
);
27824 case OPC_ABSQ_S_QB
:
27825 case OPC_ABSQ_S_PH
:
27827 case OPC_PRECEQ_W_PHL
:
27828 case OPC_PRECEQ_W_PHR
:
27829 case OPC_PRECEQU_PH_QBL
:
27830 case OPC_PRECEQU_PH_QBR
:
27831 case OPC_PRECEQU_PH_QBLA
:
27832 case OPC_PRECEQU_PH_QBRA
:
27833 case OPC_PRECEU_PH_QBL
:
27834 case OPC_PRECEU_PH_QBR
:
27835 case OPC_PRECEU_PH_QBLA
:
27836 case OPC_PRECEU_PH_QBRA
:
27837 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
27844 gen_mipsdsp_bitinsn(ctx
, op1
, op2
, rd
, rt
);
27847 MIPS_INVAL("MASK ABSQ_S.PH");
27848 generate_exception_end(ctx
, EXCP_RI
);
27852 case OPC_ADDU_QB_DSP
:
27853 op2
= MASK_ADDU_QB(ctx
->opcode
);
27856 case OPC_ADDQ_S_PH
:
27859 case OPC_ADDU_S_QB
:
27861 case OPC_ADDU_S_PH
:
27863 case OPC_SUBQ_S_PH
:
27866 case OPC_SUBU_S_QB
:
27868 case OPC_SUBU_S_PH
:
27872 case OPC_RADDU_W_QB
:
27873 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
27875 case OPC_MULEU_S_PH_QBL
:
27876 case OPC_MULEU_S_PH_QBR
:
27877 case OPC_MULQ_RS_PH
:
27878 case OPC_MULEQ_S_W_PHL
:
27879 case OPC_MULEQ_S_W_PHR
:
27880 case OPC_MULQ_S_PH
:
27881 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
27883 default: /* Invalid */
27884 MIPS_INVAL("MASK ADDU.QB");
27885 generate_exception_end(ctx
, EXCP_RI
);
27890 case OPC_CMPU_EQ_QB_DSP
:
27891 op2
= MASK_CMPU_EQ_QB(ctx
->opcode
);
27893 case OPC_PRECR_SRA_PH_W
:
27894 case OPC_PRECR_SRA_R_PH_W
:
27895 gen_mipsdsp_arith(ctx
, op1
, op2
, rt
, rs
, rd
);
27897 case OPC_PRECR_QB_PH
:
27898 case OPC_PRECRQ_QB_PH
:
27899 case OPC_PRECRQ_PH_W
:
27900 case OPC_PRECRQ_RS_PH_W
:
27901 case OPC_PRECRQU_S_QB_PH
:
27902 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
27904 case OPC_CMPU_EQ_QB
:
27905 case OPC_CMPU_LT_QB
:
27906 case OPC_CMPU_LE_QB
:
27907 case OPC_CMP_EQ_PH
:
27908 case OPC_CMP_LT_PH
:
27909 case OPC_CMP_LE_PH
:
27910 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
27912 case OPC_CMPGU_EQ_QB
:
27913 case OPC_CMPGU_LT_QB
:
27914 case OPC_CMPGU_LE_QB
:
27915 case OPC_CMPGDU_EQ_QB
:
27916 case OPC_CMPGDU_LT_QB
:
27917 case OPC_CMPGDU_LE_QB
:
27920 case OPC_PACKRL_PH
:
27921 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
27923 default: /* Invalid */
27924 MIPS_INVAL("MASK CMPU.EQ.QB");
27925 generate_exception_end(ctx
, EXCP_RI
);
27929 case OPC_SHLL_QB_DSP
:
27930 gen_mipsdsp_shift(ctx
, op1
, rd
, rs
, rt
);
27932 case OPC_DPA_W_PH_DSP
:
27933 op2
= MASK_DPA_W_PH(ctx
->opcode
);
27935 case OPC_DPAU_H_QBL
:
27936 case OPC_DPAU_H_QBR
:
27937 case OPC_DPSU_H_QBL
:
27938 case OPC_DPSU_H_QBR
:
27940 case OPC_DPAX_W_PH
:
27941 case OPC_DPAQ_S_W_PH
:
27942 case OPC_DPAQX_S_W_PH
:
27943 case OPC_DPAQX_SA_W_PH
:
27945 case OPC_DPSX_W_PH
:
27946 case OPC_DPSQ_S_W_PH
:
27947 case OPC_DPSQX_S_W_PH
:
27948 case OPC_DPSQX_SA_W_PH
:
27949 case OPC_MULSAQ_S_W_PH
:
27950 case OPC_DPAQ_SA_L_W
:
27951 case OPC_DPSQ_SA_L_W
:
27952 case OPC_MAQ_S_W_PHL
:
27953 case OPC_MAQ_S_W_PHR
:
27954 case OPC_MAQ_SA_W_PHL
:
27955 case OPC_MAQ_SA_W_PHR
:
27956 case OPC_MULSA_W_PH
:
27957 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
27959 default: /* Invalid */
27960 MIPS_INVAL("MASK DPAW.PH");
27961 generate_exception_end(ctx
, EXCP_RI
);
27966 op2
= MASK_INSV(ctx
->opcode
);
27977 t0
= tcg_temp_new();
27978 t1
= tcg_temp_new();
27980 gen_load_gpr(t0
, rt
);
27981 gen_load_gpr(t1
, rs
);
27983 gen_helper_insv(cpu_gpr
[rt
], cpu_env
, t1
, t0
);
27989 default: /* Invalid */
27990 MIPS_INVAL("MASK INSV");
27991 generate_exception_end(ctx
, EXCP_RI
);
27995 case OPC_APPEND_DSP
:
27996 gen_mipsdsp_append(env
, ctx
, op1
, rt
, rs
, rd
);
27998 case OPC_EXTR_W_DSP
:
27999 op2
= MASK_EXTR_W(ctx
->opcode
);
28003 case OPC_EXTR_RS_W
:
28005 case OPC_EXTRV_S_H
:
28007 case OPC_EXTRV_R_W
:
28008 case OPC_EXTRV_RS_W
:
28013 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rt
, rs
, rd
, 1);
28016 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
28022 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
28024 default: /* Invalid */
28025 MIPS_INVAL("MASK EXTR.W");
28026 generate_exception_end(ctx
, EXCP_RI
);
28030 #if defined(TARGET_MIPS64)
28031 case OPC_DDIV_G_2E
:
28032 case OPC_DDIVU_G_2E
:
28033 case OPC_DMULT_G_2E
:
28034 case OPC_DMULTU_G_2E
:
28035 case OPC_DMOD_G_2E
:
28036 case OPC_DMODU_G_2E
:
28037 check_insn(ctx
, INSN_LOONGSON2E
);
28038 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
28040 case OPC_ABSQ_S_QH_DSP
:
28041 op2
= MASK_ABSQ_S_QH(ctx
->opcode
);
28043 case OPC_PRECEQ_L_PWL
:
28044 case OPC_PRECEQ_L_PWR
:
28045 case OPC_PRECEQ_PW_QHL
:
28046 case OPC_PRECEQ_PW_QHR
:
28047 case OPC_PRECEQ_PW_QHLA
:
28048 case OPC_PRECEQ_PW_QHRA
:
28049 case OPC_PRECEQU_QH_OBL
:
28050 case OPC_PRECEQU_QH_OBR
:
28051 case OPC_PRECEQU_QH_OBLA
:
28052 case OPC_PRECEQU_QH_OBRA
:
28053 case OPC_PRECEU_QH_OBL
:
28054 case OPC_PRECEU_QH_OBR
:
28055 case OPC_PRECEU_QH_OBLA
:
28056 case OPC_PRECEU_QH_OBRA
:
28057 case OPC_ABSQ_S_OB
:
28058 case OPC_ABSQ_S_PW
:
28059 case OPC_ABSQ_S_QH
:
28060 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
28068 gen_mipsdsp_bitinsn(ctx
, op1
, op2
, rd
, rt
);
28070 default: /* Invalid */
28071 MIPS_INVAL("MASK ABSQ_S.QH");
28072 generate_exception_end(ctx
, EXCP_RI
);
28076 case OPC_ADDU_OB_DSP
:
28077 op2
= MASK_ADDU_OB(ctx
->opcode
);
28079 case OPC_RADDU_L_OB
:
28081 case OPC_SUBQ_S_PW
:
28083 case OPC_SUBQ_S_QH
:
28085 case OPC_SUBU_S_OB
:
28087 case OPC_SUBU_S_QH
:
28089 case OPC_SUBUH_R_OB
:
28091 case OPC_ADDQ_S_PW
:
28093 case OPC_ADDQ_S_QH
:
28095 case OPC_ADDU_S_OB
:
28097 case OPC_ADDU_S_QH
:
28099 case OPC_ADDUH_R_OB
:
28100 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
28102 case OPC_MULEQ_S_PW_QHL
:
28103 case OPC_MULEQ_S_PW_QHR
:
28104 case OPC_MULEU_S_QH_OBL
:
28105 case OPC_MULEU_S_QH_OBR
:
28106 case OPC_MULQ_RS_QH
:
28107 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
28109 default: /* Invalid */
28110 MIPS_INVAL("MASK ADDU.OB");
28111 generate_exception_end(ctx
, EXCP_RI
);
28115 case OPC_CMPU_EQ_OB_DSP
:
28116 op2
= MASK_CMPU_EQ_OB(ctx
->opcode
);
28118 case OPC_PRECR_SRA_QH_PW
:
28119 case OPC_PRECR_SRA_R_QH_PW
:
28120 /* Return value is rt. */
28121 gen_mipsdsp_arith(ctx
, op1
, op2
, rt
, rs
, rd
);
28123 case OPC_PRECR_OB_QH
:
28124 case OPC_PRECRQ_OB_QH
:
28125 case OPC_PRECRQ_PW_L
:
28126 case OPC_PRECRQ_QH_PW
:
28127 case OPC_PRECRQ_RS_QH_PW
:
28128 case OPC_PRECRQU_S_OB_QH
:
28129 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
28131 case OPC_CMPU_EQ_OB
:
28132 case OPC_CMPU_LT_OB
:
28133 case OPC_CMPU_LE_OB
:
28134 case OPC_CMP_EQ_QH
:
28135 case OPC_CMP_LT_QH
:
28136 case OPC_CMP_LE_QH
:
28137 case OPC_CMP_EQ_PW
:
28138 case OPC_CMP_LT_PW
:
28139 case OPC_CMP_LE_PW
:
28140 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
28142 case OPC_CMPGDU_EQ_OB
:
28143 case OPC_CMPGDU_LT_OB
:
28144 case OPC_CMPGDU_LE_OB
:
28145 case OPC_CMPGU_EQ_OB
:
28146 case OPC_CMPGU_LT_OB
:
28147 case OPC_CMPGU_LE_OB
:
28148 case OPC_PACKRL_PW
:
28152 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
28154 default: /* Invalid */
28155 MIPS_INVAL("MASK CMPU_EQ.OB");
28156 generate_exception_end(ctx
, EXCP_RI
);
28160 case OPC_DAPPEND_DSP
:
28161 gen_mipsdsp_append(env
, ctx
, op1
, rt
, rs
, rd
);
28163 case OPC_DEXTR_W_DSP
:
28164 op2
= MASK_DEXTR_W(ctx
->opcode
);
28171 case OPC_DEXTR_R_L
:
28172 case OPC_DEXTR_RS_L
:
28174 case OPC_DEXTR_R_W
:
28175 case OPC_DEXTR_RS_W
:
28176 case OPC_DEXTR_S_H
:
28178 case OPC_DEXTRV_R_L
:
28179 case OPC_DEXTRV_RS_L
:
28180 case OPC_DEXTRV_S_H
:
28182 case OPC_DEXTRV_R_W
:
28183 case OPC_DEXTRV_RS_W
:
28184 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rt
, rs
, rd
, 1);
28189 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
28191 default: /* Invalid */
28192 MIPS_INVAL("MASK EXTR.W");
28193 generate_exception_end(ctx
, EXCP_RI
);
28197 case OPC_DPAQ_W_QH_DSP
:
28198 op2
= MASK_DPAQ_W_QH(ctx
->opcode
);
28200 case OPC_DPAU_H_OBL
:
28201 case OPC_DPAU_H_OBR
:
28202 case OPC_DPSU_H_OBL
:
28203 case OPC_DPSU_H_OBR
:
28205 case OPC_DPAQ_S_W_QH
:
28207 case OPC_DPSQ_S_W_QH
:
28208 case OPC_MULSAQ_S_W_QH
:
28209 case OPC_DPAQ_SA_L_PW
:
28210 case OPC_DPSQ_SA_L_PW
:
28211 case OPC_MULSAQ_S_L_PW
:
28212 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
28214 case OPC_MAQ_S_W_QHLL
:
28215 case OPC_MAQ_S_W_QHLR
:
28216 case OPC_MAQ_S_W_QHRL
:
28217 case OPC_MAQ_S_W_QHRR
:
28218 case OPC_MAQ_SA_W_QHLL
:
28219 case OPC_MAQ_SA_W_QHLR
:
28220 case OPC_MAQ_SA_W_QHRL
:
28221 case OPC_MAQ_SA_W_QHRR
:
28222 case OPC_MAQ_S_L_PWL
:
28223 case OPC_MAQ_S_L_PWR
:
28228 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
28230 default: /* Invalid */
28231 MIPS_INVAL("MASK DPAQ.W.QH");
28232 generate_exception_end(ctx
, EXCP_RI
);
28236 case OPC_DINSV_DSP
:
28237 op2
= MASK_INSV(ctx
->opcode
);
28248 t0
= tcg_temp_new();
28249 t1
= tcg_temp_new();
28251 gen_load_gpr(t0
, rt
);
28252 gen_load_gpr(t1
, rs
);
28254 gen_helper_dinsv(cpu_gpr
[rt
], cpu_env
, t1
, t0
);
28260 default: /* Invalid */
28261 MIPS_INVAL("MASK DINSV");
28262 generate_exception_end(ctx
, EXCP_RI
);
28266 case OPC_SHLL_OB_DSP
:
28267 gen_mipsdsp_shift(ctx
, op1
, rd
, rs
, rt
);
28270 default: /* Invalid */
28271 MIPS_INVAL("special3_legacy");
28272 generate_exception_end(ctx
, EXCP_RI
);
28278 #if defined(TARGET_MIPS64)
28280 static void decode_mmi0(CPUMIPSState
*env
, DisasContext
*ctx
)
28282 uint32_t opc
= MASK_MMI0(ctx
->opcode
);
28285 case MMI_OPC_0_PADDW
: /* TODO: MMI_OPC_0_PADDW */
28286 case MMI_OPC_0_PSUBW
: /* TODO: MMI_OPC_0_PSUBW */
28287 case MMI_OPC_0_PCGTW
: /* TODO: MMI_OPC_0_PCGTW */
28288 case MMI_OPC_0_PMAXW
: /* TODO: MMI_OPC_0_PMAXW */
28289 case MMI_OPC_0_PADDH
: /* TODO: MMI_OPC_0_PADDH */
28290 case MMI_OPC_0_PSUBH
: /* TODO: MMI_OPC_0_PSUBH */
28291 case MMI_OPC_0_PCGTH
: /* TODO: MMI_OPC_0_PCGTH */
28292 case MMI_OPC_0_PMAXH
: /* TODO: MMI_OPC_0_PMAXH */
28293 case MMI_OPC_0_PADDB
: /* TODO: MMI_OPC_0_PADDB */
28294 case MMI_OPC_0_PSUBB
: /* TODO: MMI_OPC_0_PSUBB */
28295 case MMI_OPC_0_PCGTB
: /* TODO: MMI_OPC_0_PCGTB */
28296 case MMI_OPC_0_PADDSW
: /* TODO: MMI_OPC_0_PADDSW */
28297 case MMI_OPC_0_PSUBSW
: /* TODO: MMI_OPC_0_PSUBSW */
28298 case MMI_OPC_0_PEXTLW
: /* TODO: MMI_OPC_0_PEXTLW */
28299 case MMI_OPC_0_PPACW
: /* TODO: MMI_OPC_0_PPACW */
28300 case MMI_OPC_0_PADDSH
: /* TODO: MMI_OPC_0_PADDSH */
28301 case MMI_OPC_0_PSUBSH
: /* TODO: MMI_OPC_0_PSUBSH */
28302 case MMI_OPC_0_PEXTLH
: /* TODO: MMI_OPC_0_PEXTLH */
28303 case MMI_OPC_0_PPACH
: /* TODO: MMI_OPC_0_PPACH */
28304 case MMI_OPC_0_PADDSB
: /* TODO: MMI_OPC_0_PADDSB */
28305 case MMI_OPC_0_PSUBSB
: /* TODO: MMI_OPC_0_PSUBSB */
28306 case MMI_OPC_0_PEXTLB
: /* TODO: MMI_OPC_0_PEXTLB */
28307 case MMI_OPC_0_PPACB
: /* TODO: MMI_OPC_0_PPACB */
28308 case MMI_OPC_0_PEXT5
: /* TODO: MMI_OPC_0_PEXT5 */
28309 case MMI_OPC_0_PPAC5
: /* TODO: MMI_OPC_0_PPAC5 */
28310 generate_exception_end(ctx
, EXCP_RI
); /* TODO: MMI_OPC_CLASS_MMI0 */
28313 MIPS_INVAL("TX79 MMI class MMI0");
28314 generate_exception_end(ctx
, EXCP_RI
);
28319 static void decode_mmi1(CPUMIPSState
*env
, DisasContext
*ctx
)
28321 uint32_t opc
= MASK_MMI1(ctx
->opcode
);
28324 case MMI_OPC_1_PABSW
: /* TODO: MMI_OPC_1_PABSW */
28325 case MMI_OPC_1_PCEQW
: /* TODO: MMI_OPC_1_PCEQW */
28326 case MMI_OPC_1_PMINW
: /* TODO: MMI_OPC_1_PMINW */
28327 case MMI_OPC_1_PADSBH
: /* TODO: MMI_OPC_1_PADSBH */
28328 case MMI_OPC_1_PABSH
: /* TODO: MMI_OPC_1_PABSH */
28329 case MMI_OPC_1_PCEQH
: /* TODO: MMI_OPC_1_PCEQH */
28330 case MMI_OPC_1_PMINH
: /* TODO: MMI_OPC_1_PMINH */
28331 case MMI_OPC_1_PCEQB
: /* TODO: MMI_OPC_1_PCEQB */
28332 case MMI_OPC_1_PADDUW
: /* TODO: MMI_OPC_1_PADDUW */
28333 case MMI_OPC_1_PSUBUW
: /* TODO: MMI_OPC_1_PSUBUW */
28334 case MMI_OPC_1_PEXTUW
: /* TODO: MMI_OPC_1_PEXTUW */
28335 case MMI_OPC_1_PADDUH
: /* TODO: MMI_OPC_1_PADDUH */
28336 case MMI_OPC_1_PSUBUH
: /* TODO: MMI_OPC_1_PSUBUH */
28337 case MMI_OPC_1_PEXTUH
: /* TODO: MMI_OPC_1_PEXTUH */
28338 case MMI_OPC_1_PADDUB
: /* TODO: MMI_OPC_1_PADDUB */
28339 case MMI_OPC_1_PSUBUB
: /* TODO: MMI_OPC_1_PSUBUB */
28340 case MMI_OPC_1_PEXTUB
: /* TODO: MMI_OPC_1_PEXTUB */
28341 case MMI_OPC_1_QFSRV
: /* TODO: MMI_OPC_1_QFSRV */
28342 generate_exception_end(ctx
, EXCP_RI
); /* TODO: MMI_OPC_CLASS_MMI1 */
28345 MIPS_INVAL("TX79 MMI class MMI1");
28346 generate_exception_end(ctx
, EXCP_RI
);
28351 static void decode_mmi2(CPUMIPSState
*env
, DisasContext
*ctx
)
28353 uint32_t opc
= MASK_MMI2(ctx
->opcode
);
28356 case MMI_OPC_2_PMADDW
: /* TODO: MMI_OPC_2_PMADDW */
28357 case MMI_OPC_2_PSLLVW
: /* TODO: MMI_OPC_2_PSLLVW */
28358 case MMI_OPC_2_PSRLVW
: /* TODO: MMI_OPC_2_PSRLVW */
28359 case MMI_OPC_2_PMSUBW
: /* TODO: MMI_OPC_2_PMSUBW */
28360 case MMI_OPC_2_PMFHI
: /* TODO: MMI_OPC_2_PMFHI */
28361 case MMI_OPC_2_PMFLO
: /* TODO: MMI_OPC_2_PMFLO */
28362 case MMI_OPC_2_PINTH
: /* TODO: MMI_OPC_2_PINTH */
28363 case MMI_OPC_2_PMULTW
: /* TODO: MMI_OPC_2_PMULTW */
28364 case MMI_OPC_2_PDIVW
: /* TODO: MMI_OPC_2_PDIVW */
28365 case MMI_OPC_2_PMADDH
: /* TODO: MMI_OPC_2_PMADDH */
28366 case MMI_OPC_2_PHMADH
: /* TODO: MMI_OPC_2_PHMADH */
28367 case MMI_OPC_2_PAND
: /* TODO: MMI_OPC_2_PAND */
28368 case MMI_OPC_2_PXOR
: /* TODO: MMI_OPC_2_PXOR */
28369 case MMI_OPC_2_PMSUBH
: /* TODO: MMI_OPC_2_PMSUBH */
28370 case MMI_OPC_2_PHMSBH
: /* TODO: MMI_OPC_2_PHMSBH */
28371 case MMI_OPC_2_PEXEH
: /* TODO: MMI_OPC_2_PEXEH */
28372 case MMI_OPC_2_PREVH
: /* TODO: MMI_OPC_2_PREVH */
28373 case MMI_OPC_2_PMULTH
: /* TODO: MMI_OPC_2_PMULTH */
28374 case MMI_OPC_2_PDIVBW
: /* TODO: MMI_OPC_2_PDIVBW */
28375 case MMI_OPC_2_PEXEW
: /* TODO: MMI_OPC_2_PEXEW */
28376 case MMI_OPC_2_PROT3W
: /* TODO: MMI_OPC_2_PROT3W */
28377 generate_exception_end(ctx
, EXCP_RI
); /* TODO: MMI_OPC_CLASS_MMI2 */
28379 case MMI_OPC_2_PCPYLD
:
28380 gen_mmi_pcpyld(ctx
);
28383 MIPS_INVAL("TX79 MMI class MMI2");
28384 generate_exception_end(ctx
, EXCP_RI
);
28389 static void decode_mmi3(CPUMIPSState
*env
, DisasContext
*ctx
)
28391 uint32_t opc
= MASK_MMI3(ctx
->opcode
);
28394 case MMI_OPC_3_PMADDUW
: /* TODO: MMI_OPC_3_PMADDUW */
28395 case MMI_OPC_3_PSRAVW
: /* TODO: MMI_OPC_3_PSRAVW */
28396 case MMI_OPC_3_PMTHI
: /* TODO: MMI_OPC_3_PMTHI */
28397 case MMI_OPC_3_PMTLO
: /* TODO: MMI_OPC_3_PMTLO */
28398 case MMI_OPC_3_PINTEH
: /* TODO: MMI_OPC_3_PINTEH */
28399 case MMI_OPC_3_PMULTUW
: /* TODO: MMI_OPC_3_PMULTUW */
28400 case MMI_OPC_3_PDIVUW
: /* TODO: MMI_OPC_3_PDIVUW */
28401 case MMI_OPC_3_POR
: /* TODO: MMI_OPC_3_POR */
28402 case MMI_OPC_3_PNOR
: /* TODO: MMI_OPC_3_PNOR */
28403 case MMI_OPC_3_PEXCH
: /* TODO: MMI_OPC_3_PEXCH */
28404 case MMI_OPC_3_PEXCW
: /* TODO: MMI_OPC_3_PEXCW */
28405 generate_exception_end(ctx
, EXCP_RI
); /* TODO: MMI_OPC_CLASS_MMI3 */
28407 case MMI_OPC_3_PCPYH
:
28408 gen_mmi_pcpyh(ctx
);
28410 case MMI_OPC_3_PCPYUD
:
28411 gen_mmi_pcpyud(ctx
);
28414 MIPS_INVAL("TX79 MMI class MMI3");
28415 generate_exception_end(ctx
, EXCP_RI
);
28420 static void decode_mmi(CPUMIPSState
*env
, DisasContext
*ctx
)
28422 uint32_t opc
= MASK_MMI(ctx
->opcode
);
28423 int rs
= extract32(ctx
->opcode
, 21, 5);
28424 int rt
= extract32(ctx
->opcode
, 16, 5);
28425 int rd
= extract32(ctx
->opcode
, 11, 5);
28428 case MMI_OPC_CLASS_MMI0
:
28429 decode_mmi0(env
, ctx
);
28431 case MMI_OPC_CLASS_MMI1
:
28432 decode_mmi1(env
, ctx
);
28434 case MMI_OPC_CLASS_MMI2
:
28435 decode_mmi2(env
, ctx
);
28437 case MMI_OPC_CLASS_MMI3
:
28438 decode_mmi3(env
, ctx
);
28440 case MMI_OPC_MULT1
:
28441 case MMI_OPC_MULTU1
:
28443 case MMI_OPC_MADDU
:
28444 case MMI_OPC_MADD1
:
28445 case MMI_OPC_MADDU1
:
28446 gen_mul_txx9(ctx
, opc
, rd
, rs
, rt
);
28449 case MMI_OPC_DIVU1
:
28450 gen_div1_tx79(ctx
, opc
, rs
, rt
);
28452 case MMI_OPC_MTLO1
:
28453 case MMI_OPC_MTHI1
:
28454 gen_HILO1_tx79(ctx
, opc
, rs
);
28456 case MMI_OPC_MFLO1
:
28457 case MMI_OPC_MFHI1
:
28458 gen_HILO1_tx79(ctx
, opc
, rd
);
28460 case MMI_OPC_PLZCW
: /* TODO: MMI_OPC_PLZCW */
28461 case MMI_OPC_PMFHL
: /* TODO: MMI_OPC_PMFHL */
28462 case MMI_OPC_PMTHL
: /* TODO: MMI_OPC_PMTHL */
28463 case MMI_OPC_PSLLH
: /* TODO: MMI_OPC_PSLLH */
28464 case MMI_OPC_PSRLH
: /* TODO: MMI_OPC_PSRLH */
28465 case MMI_OPC_PSRAH
: /* TODO: MMI_OPC_PSRAH */
28466 case MMI_OPC_PSLLW
: /* TODO: MMI_OPC_PSLLW */
28467 case MMI_OPC_PSRLW
: /* TODO: MMI_OPC_PSRLW */
28468 case MMI_OPC_PSRAW
: /* TODO: MMI_OPC_PSRAW */
28469 generate_exception_end(ctx
, EXCP_RI
); /* TODO: MMI_OPC_CLASS_MMI */
28472 MIPS_INVAL("TX79 MMI class");
28473 generate_exception_end(ctx
, EXCP_RI
);
28478 static void gen_mmi_lq(CPUMIPSState
*env
, DisasContext
*ctx
)
28480 generate_exception_end(ctx
, EXCP_RI
); /* TODO: MMI_OPC_LQ */
28483 static void gen_mmi_sq(DisasContext
*ctx
, int base
, int rt
, int offset
)
28485 generate_exception_end(ctx
, EXCP_RI
); /* TODO: MMI_OPC_SQ */
28489 * The TX79-specific instruction Store Quadword
28491 * +--------+-------+-------+------------------------+
28492 * | 011111 | base | rt | offset | SQ
28493 * +--------+-------+-------+------------------------+
28496 * has the same opcode as the Read Hardware Register instruction
28498 * +--------+-------+-------+-------+-------+--------+
28499 * | 011111 | 00000 | rt | rd | 00000 | 111011 | RDHWR
28500 * +--------+-------+-------+-------+-------+--------+
28503 * that is required, trapped and emulated by the Linux kernel. However, all
28504 * RDHWR encodings yield address error exceptions on the TX79 since the SQ
28505 * offset is odd. Therefore all valid SQ instructions can execute normally.
28506 * In user mode, QEMU must verify the upper and lower 11 bits to distinguish
28507 * between SQ and RDHWR, as the Linux kernel does.
28509 static void decode_mmi_sq(CPUMIPSState
*env
, DisasContext
*ctx
)
28511 int base
= extract32(ctx
->opcode
, 21, 5);
28512 int rt
= extract32(ctx
->opcode
, 16, 5);
28513 int offset
= extract32(ctx
->opcode
, 0, 16);
28515 #ifdef CONFIG_USER_ONLY
28516 uint32_t op1
= MASK_SPECIAL3(ctx
->opcode
);
28517 uint32_t op2
= extract32(ctx
->opcode
, 6, 5);
28519 if (base
== 0 && op2
== 0 && op1
== OPC_RDHWR
) {
28520 int rd
= extract32(ctx
->opcode
, 11, 5);
28522 gen_rdhwr(ctx
, rt
, rd
, 0);
28527 gen_mmi_sq(ctx
, base
, rt
, offset
);
28532 static void decode_opc_special3(CPUMIPSState
*env
, DisasContext
*ctx
)
28534 int rs
, rt
, rd
, sa
;
28538 rs
= (ctx
->opcode
>> 21) & 0x1f;
28539 rt
= (ctx
->opcode
>> 16) & 0x1f;
28540 rd
= (ctx
->opcode
>> 11) & 0x1f;
28541 sa
= (ctx
->opcode
>> 6) & 0x1f;
28542 imm
= sextract32(ctx
->opcode
, 7, 9);
28544 op1
= MASK_SPECIAL3(ctx
->opcode
);
28547 * EVA loads and stores overlap Loongson 2E instructions decoded by
28548 * decode_opc_special3_legacy(), so be careful to allow their decoding when
28555 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
28563 check_cp0_enabled(ctx
);
28564 gen_ld(ctx
, op1
, rt
, rs
, imm
);
28568 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
28573 check_cp0_enabled(ctx
);
28574 gen_st(ctx
, op1
, rt
, rs
, imm
);
28577 check_cp0_enabled(ctx
);
28578 gen_st_cond(ctx
, rt
, rs
, imm
, MO_TESL
, true);
28581 check_cp0_enabled(ctx
);
28582 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
28583 gen_cache_operation(ctx
, rt
, rs
, imm
);
28585 /* Treat as NOP. */
28588 check_cp0_enabled(ctx
);
28589 /* Treat as NOP. */
28597 check_insn(ctx
, ISA_MIPS32R2
);
28598 gen_bitops(ctx
, op1
, rt
, rs
, sa
, rd
);
28601 op2
= MASK_BSHFL(ctx
->opcode
);
28608 check_insn(ctx
, ISA_MIPS32R6
);
28609 decode_opc_special3_r6(env
, ctx
);
28612 check_insn(ctx
, ISA_MIPS32R2
);
28613 gen_bshfl(ctx
, op2
, rt
, rd
);
28617 #if defined(TARGET_MIPS64)
28624 check_insn(ctx
, ISA_MIPS32R2
);
28625 check_mips_64(ctx
);
28626 gen_bitops(ctx
, op1
, rt
, rs
, sa
, rd
);
28629 op2
= MASK_DBSHFL(ctx
->opcode
);
28640 check_insn(ctx
, ISA_MIPS32R6
);
28641 decode_opc_special3_r6(env
, ctx
);
28644 check_insn(ctx
, ISA_MIPS32R2
);
28645 check_mips_64(ctx
);
28646 op2
= MASK_DBSHFL(ctx
->opcode
);
28647 gen_bshfl(ctx
, op2
, rt
, rd
);
28653 gen_rdhwr(ctx
, rt
, rd
, extract32(ctx
->opcode
, 6, 3));
28658 TCGv t0
= tcg_temp_new();
28659 TCGv t1
= tcg_temp_new();
28661 gen_load_gpr(t0
, rt
);
28662 gen_load_gpr(t1
, rs
);
28663 gen_helper_fork(t0
, t1
);
28671 TCGv t0
= tcg_temp_new();
28673 gen_load_gpr(t0
, rs
);
28674 gen_helper_yield(t0
, cpu_env
, t0
);
28675 gen_store_gpr(t0
, rd
);
28680 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
28681 decode_opc_special3_r6(env
, ctx
);
28683 decode_opc_special3_legacy(env
, ctx
);
28688 /* MIPS SIMD Architecture (MSA) */
28689 static inline int check_msa_access(DisasContext
*ctx
)
28691 if (unlikely((ctx
->hflags
& MIPS_HFLAG_FPU
) &&
28692 !(ctx
->hflags
& MIPS_HFLAG_F64
))) {
28693 generate_exception_end(ctx
, EXCP_RI
);
28697 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_MSA
))) {
28698 if (ctx
->insn_flags
& ASE_MSA
) {
28699 generate_exception_end(ctx
, EXCP_MSADIS
);
28702 generate_exception_end(ctx
, EXCP_RI
);
28709 static void gen_check_zero_element(TCGv tresult
, uint8_t df
, uint8_t wt
)
28711 /* generates tcg ops to check if any element is 0 */
28712 /* Note this function only works with MSA_WRLEN = 128 */
28713 uint64_t eval_zero_or_big
= 0;
28714 uint64_t eval_big
= 0;
28715 TCGv_i64 t0
= tcg_temp_new_i64();
28716 TCGv_i64 t1
= tcg_temp_new_i64();
28719 eval_zero_or_big
= 0x0101010101010101ULL
;
28720 eval_big
= 0x8080808080808080ULL
;
28723 eval_zero_or_big
= 0x0001000100010001ULL
;
28724 eval_big
= 0x8000800080008000ULL
;
28727 eval_zero_or_big
= 0x0000000100000001ULL
;
28728 eval_big
= 0x8000000080000000ULL
;
28731 eval_zero_or_big
= 0x0000000000000001ULL
;
28732 eval_big
= 0x8000000000000000ULL
;
28735 tcg_gen_subi_i64(t0
, msa_wr_d
[wt
<< 1], eval_zero_or_big
);
28736 tcg_gen_andc_i64(t0
, t0
, msa_wr_d
[wt
<< 1]);
28737 tcg_gen_andi_i64(t0
, t0
, eval_big
);
28738 tcg_gen_subi_i64(t1
, msa_wr_d
[(wt
<< 1) + 1], eval_zero_or_big
);
28739 tcg_gen_andc_i64(t1
, t1
, msa_wr_d
[(wt
<< 1) + 1]);
28740 tcg_gen_andi_i64(t1
, t1
, eval_big
);
28741 tcg_gen_or_i64(t0
, t0
, t1
);
28742 /* if all bits are zero then all elements are not zero */
28743 /* if some bit is non-zero then some element is zero */
28744 tcg_gen_setcondi_i64(TCG_COND_NE
, t0
, t0
, 0);
28745 tcg_gen_trunc_i64_tl(tresult
, t0
);
28746 tcg_temp_free_i64(t0
);
28747 tcg_temp_free_i64(t1
);
28750 static void gen_msa_branch(CPUMIPSState
*env
, DisasContext
*ctx
, uint32_t op1
)
28752 uint8_t df
= (ctx
->opcode
>> 21) & 0x3;
28753 uint8_t wt
= (ctx
->opcode
>> 16) & 0x1f;
28754 int64_t s16
= (int16_t)ctx
->opcode
;
28756 check_msa_access(ctx
);
28758 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
28759 generate_exception_end(ctx
, EXCP_RI
);
28766 TCGv_i64 t0
= tcg_temp_new_i64();
28767 tcg_gen_or_i64(t0
, msa_wr_d
[wt
<< 1], msa_wr_d
[(wt
<< 1) + 1]);
28768 tcg_gen_setcondi_i64((op1
== OPC_BZ_V
) ?
28769 TCG_COND_EQ
: TCG_COND_NE
, t0
, t0
, 0);
28770 tcg_gen_trunc_i64_tl(bcond
, t0
);
28771 tcg_temp_free_i64(t0
);
28778 gen_check_zero_element(bcond
, df
, wt
);
28784 gen_check_zero_element(bcond
, df
, wt
);
28785 tcg_gen_setcondi_tl(TCG_COND_EQ
, bcond
, bcond
, 0);
28789 ctx
->btarget
= ctx
->base
.pc_next
+ (s16
<< 2) + 4;
28791 ctx
->hflags
|= MIPS_HFLAG_BC
;
28792 ctx
->hflags
|= MIPS_HFLAG_BDS32
;
28795 static void gen_msa_i8(CPUMIPSState
*env
, DisasContext
*ctx
)
28797 #define MASK_MSA_I8(op) (MASK_MSA_MINOR(op) | (op & (0x03 << 24)))
28798 uint8_t i8
= (ctx
->opcode
>> 16) & 0xff;
28799 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
28800 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
28802 TCGv_i32 twd
= tcg_const_i32(wd
);
28803 TCGv_i32 tws
= tcg_const_i32(ws
);
28804 TCGv_i32 ti8
= tcg_const_i32(i8
);
28806 switch (MASK_MSA_I8(ctx
->opcode
)) {
28808 gen_helper_msa_andi_b(cpu_env
, twd
, tws
, ti8
);
28811 gen_helper_msa_ori_b(cpu_env
, twd
, tws
, ti8
);
28814 gen_helper_msa_nori_b(cpu_env
, twd
, tws
, ti8
);
28817 gen_helper_msa_xori_b(cpu_env
, twd
, tws
, ti8
);
28820 gen_helper_msa_bmnzi_b(cpu_env
, twd
, tws
, ti8
);
28823 gen_helper_msa_bmzi_b(cpu_env
, twd
, tws
, ti8
);
28826 gen_helper_msa_bseli_b(cpu_env
, twd
, tws
, ti8
);
28832 uint8_t df
= (ctx
->opcode
>> 24) & 0x3;
28833 if (df
== DF_DOUBLE
) {
28834 generate_exception_end(ctx
, EXCP_RI
);
28836 TCGv_i32 tdf
= tcg_const_i32(df
);
28837 gen_helper_msa_shf_df(cpu_env
, tdf
, twd
, tws
, ti8
);
28838 tcg_temp_free_i32(tdf
);
28843 MIPS_INVAL("MSA instruction");
28844 generate_exception_end(ctx
, EXCP_RI
);
28848 tcg_temp_free_i32(twd
);
28849 tcg_temp_free_i32(tws
);
28850 tcg_temp_free_i32(ti8
);
28853 static void gen_msa_i5(CPUMIPSState
*env
, DisasContext
*ctx
)
28855 #define MASK_MSA_I5(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
28856 uint8_t df
= (ctx
->opcode
>> 21) & 0x3;
28857 int8_t s5
= (int8_t) sextract32(ctx
->opcode
, 16, 5);
28858 uint8_t u5
= (ctx
->opcode
>> 16) & 0x1f;
28859 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
28860 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
28862 TCGv_i32 tdf
= tcg_const_i32(df
);
28863 TCGv_i32 twd
= tcg_const_i32(wd
);
28864 TCGv_i32 tws
= tcg_const_i32(ws
);
28865 TCGv_i32 timm
= tcg_temp_new_i32();
28866 tcg_gen_movi_i32(timm
, u5
);
28868 switch (MASK_MSA_I5(ctx
->opcode
)) {
28870 gen_helper_msa_addvi_df(cpu_env
, tdf
, twd
, tws
, timm
);
28873 gen_helper_msa_subvi_df(cpu_env
, tdf
, twd
, tws
, timm
);
28875 case OPC_MAXI_S_df
:
28876 tcg_gen_movi_i32(timm
, s5
);
28877 gen_helper_msa_maxi_s_df(cpu_env
, tdf
, twd
, tws
, timm
);
28879 case OPC_MAXI_U_df
:
28880 gen_helper_msa_maxi_u_df(cpu_env
, tdf
, twd
, tws
, timm
);
28882 case OPC_MINI_S_df
:
28883 tcg_gen_movi_i32(timm
, s5
);
28884 gen_helper_msa_mini_s_df(cpu_env
, tdf
, twd
, tws
, timm
);
28886 case OPC_MINI_U_df
:
28887 gen_helper_msa_mini_u_df(cpu_env
, tdf
, twd
, tws
, timm
);
28890 tcg_gen_movi_i32(timm
, s5
);
28891 gen_helper_msa_ceqi_df(cpu_env
, tdf
, twd
, tws
, timm
);
28893 case OPC_CLTI_S_df
:
28894 tcg_gen_movi_i32(timm
, s5
);
28895 gen_helper_msa_clti_s_df(cpu_env
, tdf
, twd
, tws
, timm
);
28897 case OPC_CLTI_U_df
:
28898 gen_helper_msa_clti_u_df(cpu_env
, tdf
, twd
, tws
, timm
);
28900 case OPC_CLEI_S_df
:
28901 tcg_gen_movi_i32(timm
, s5
);
28902 gen_helper_msa_clei_s_df(cpu_env
, tdf
, twd
, tws
, timm
);
28904 case OPC_CLEI_U_df
:
28905 gen_helper_msa_clei_u_df(cpu_env
, tdf
, twd
, tws
, timm
);
28909 int32_t s10
= sextract32(ctx
->opcode
, 11, 10);
28910 tcg_gen_movi_i32(timm
, s10
);
28911 gen_helper_msa_ldi_df(cpu_env
, tdf
, twd
, timm
);
28915 MIPS_INVAL("MSA instruction");
28916 generate_exception_end(ctx
, EXCP_RI
);
28920 tcg_temp_free_i32(tdf
);
28921 tcg_temp_free_i32(twd
);
28922 tcg_temp_free_i32(tws
);
28923 tcg_temp_free_i32(timm
);
28926 static void gen_msa_bit(CPUMIPSState
*env
, DisasContext
*ctx
)
28928 #define MASK_MSA_BIT(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
28929 uint8_t dfm
= (ctx
->opcode
>> 16) & 0x7f;
28930 uint32_t df
= 0, m
= 0;
28931 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
28932 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
28939 if ((dfm
& 0x40) == 0x00) {
28942 } else if ((dfm
& 0x60) == 0x40) {
28945 } else if ((dfm
& 0x70) == 0x60) {
28948 } else if ((dfm
& 0x78) == 0x70) {
28952 generate_exception_end(ctx
, EXCP_RI
);
28956 tdf
= tcg_const_i32(df
);
28957 tm
= tcg_const_i32(m
);
28958 twd
= tcg_const_i32(wd
);
28959 tws
= tcg_const_i32(ws
);
28961 switch (MASK_MSA_BIT(ctx
->opcode
)) {
28963 gen_helper_msa_slli_df(cpu_env
, tdf
, twd
, tws
, tm
);
28966 gen_helper_msa_srai_df(cpu_env
, tdf
, twd
, tws
, tm
);
28969 gen_helper_msa_srli_df(cpu_env
, tdf
, twd
, tws
, tm
);
28972 gen_helper_msa_bclri_df(cpu_env
, tdf
, twd
, tws
, tm
);
28975 gen_helper_msa_bseti_df(cpu_env
, tdf
, twd
, tws
, tm
);
28978 gen_helper_msa_bnegi_df(cpu_env
, tdf
, twd
, tws
, tm
);
28980 case OPC_BINSLI_df
:
28981 gen_helper_msa_binsli_df(cpu_env
, tdf
, twd
, tws
, tm
);
28983 case OPC_BINSRI_df
:
28984 gen_helper_msa_binsri_df(cpu_env
, tdf
, twd
, tws
, tm
);
28987 gen_helper_msa_sat_s_df(cpu_env
, tdf
, twd
, tws
, tm
);
28990 gen_helper_msa_sat_u_df(cpu_env
, tdf
, twd
, tws
, tm
);
28993 gen_helper_msa_srari_df(cpu_env
, tdf
, twd
, tws
, tm
);
28996 gen_helper_msa_srlri_df(cpu_env
, tdf
, twd
, tws
, tm
);
28999 MIPS_INVAL("MSA instruction");
29000 generate_exception_end(ctx
, EXCP_RI
);
29004 tcg_temp_free_i32(tdf
);
29005 tcg_temp_free_i32(tm
);
29006 tcg_temp_free_i32(twd
);
29007 tcg_temp_free_i32(tws
);
29010 static void gen_msa_3r(CPUMIPSState
*env
, DisasContext
*ctx
)
29012 #define MASK_MSA_3R(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
29013 uint8_t df
= (ctx
->opcode
>> 21) & 0x3;
29014 uint8_t wt
= (ctx
->opcode
>> 16) & 0x1f;
29015 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
29016 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
29018 TCGv_i32 tdf
= tcg_const_i32(df
);
29019 TCGv_i32 twd
= tcg_const_i32(wd
);
29020 TCGv_i32 tws
= tcg_const_i32(ws
);
29021 TCGv_i32 twt
= tcg_const_i32(wt
);
29023 switch (MASK_MSA_3R(ctx
->opcode
)) {
29027 gen_helper_msa_binsl_b(cpu_env
, twd
, tws
, twt
);
29030 gen_helper_msa_binsl_h(cpu_env
, twd
, tws
, twt
);
29033 gen_helper_msa_binsl_w(cpu_env
, twd
, tws
, twt
);
29036 gen_helper_msa_binsl_d(cpu_env
, twd
, tws
, twt
);
29043 gen_helper_msa_binsr_b(cpu_env
, twd
, tws
, twt
);
29046 gen_helper_msa_binsr_h(cpu_env
, twd
, tws
, twt
);
29049 gen_helper_msa_binsr_w(cpu_env
, twd
, tws
, twt
);
29052 gen_helper_msa_binsr_d(cpu_env
, twd
, tws
, twt
);
29059 gen_helper_msa_bclr_b(cpu_env
, twd
, tws
, twt
);
29062 gen_helper_msa_bclr_h(cpu_env
, twd
, tws
, twt
);
29065 gen_helper_msa_bclr_w(cpu_env
, twd
, tws
, twt
);
29068 gen_helper_msa_bclr_d(cpu_env
, twd
, tws
, twt
);
29075 gen_helper_msa_bneg_b(cpu_env
, twd
, tws
, twt
);
29078 gen_helper_msa_bneg_h(cpu_env
, twd
, tws
, twt
);
29081 gen_helper_msa_bneg_w(cpu_env
, twd
, tws
, twt
);
29084 gen_helper_msa_bneg_d(cpu_env
, twd
, tws
, twt
);
29091 gen_helper_msa_bset_b(cpu_env
, twd
, tws
, twt
);
29094 gen_helper_msa_bset_h(cpu_env
, twd
, tws
, twt
);
29097 gen_helper_msa_bset_w(cpu_env
, twd
, tws
, twt
);
29100 gen_helper_msa_bset_d(cpu_env
, twd
, tws
, twt
);
29107 gen_helper_msa_add_a_b(cpu_env
, twd
, tws
, twt
);
29110 gen_helper_msa_add_a_h(cpu_env
, twd
, tws
, twt
);
29113 gen_helper_msa_add_a_w(cpu_env
, twd
, tws
, twt
);
29116 gen_helper_msa_add_a_d(cpu_env
, twd
, tws
, twt
);
29120 case OPC_ADDS_A_df
:
29123 gen_helper_msa_adds_a_b(cpu_env
, twd
, tws
, twt
);
29126 gen_helper_msa_adds_a_h(cpu_env
, twd
, tws
, twt
);
29129 gen_helper_msa_adds_a_w(cpu_env
, twd
, tws
, twt
);
29132 gen_helper_msa_adds_a_d(cpu_env
, twd
, tws
, twt
);
29136 case OPC_ADDS_S_df
:
29139 gen_helper_msa_adds_s_b(cpu_env
, twd
, tws
, twt
);
29142 gen_helper_msa_adds_s_h(cpu_env
, twd
, tws
, twt
);
29145 gen_helper_msa_adds_s_w(cpu_env
, twd
, tws
, twt
);
29148 gen_helper_msa_adds_s_d(cpu_env
, twd
, tws
, twt
);
29152 case OPC_ADDS_U_df
:
29155 gen_helper_msa_adds_u_b(cpu_env
, twd
, tws
, twt
);
29158 gen_helper_msa_adds_u_h(cpu_env
, twd
, tws
, twt
);
29161 gen_helper_msa_adds_u_w(cpu_env
, twd
, tws
, twt
);
29164 gen_helper_msa_adds_u_d(cpu_env
, twd
, tws
, twt
);
29171 gen_helper_msa_addv_b(cpu_env
, twd
, tws
, twt
);
29174 gen_helper_msa_addv_h(cpu_env
, twd
, tws
, twt
);
29177 gen_helper_msa_addv_w(cpu_env
, twd
, tws
, twt
);
29180 gen_helper_msa_addv_d(cpu_env
, twd
, tws
, twt
);
29187 gen_helper_msa_ave_s_b(cpu_env
, twd
, tws
, twt
);
29190 gen_helper_msa_ave_s_h(cpu_env
, twd
, tws
, twt
);
29193 gen_helper_msa_ave_s_w(cpu_env
, twd
, tws
, twt
);
29196 gen_helper_msa_ave_s_d(cpu_env
, twd
, tws
, twt
);
29203 gen_helper_msa_ave_u_b(cpu_env
, twd
, tws
, twt
);
29206 gen_helper_msa_ave_u_h(cpu_env
, twd
, tws
, twt
);
29209 gen_helper_msa_ave_u_w(cpu_env
, twd
, tws
, twt
);
29212 gen_helper_msa_ave_u_d(cpu_env
, twd
, tws
, twt
);
29216 case OPC_AVER_S_df
:
29219 gen_helper_msa_aver_s_b(cpu_env
, twd
, tws
, twt
);
29222 gen_helper_msa_aver_s_h(cpu_env
, twd
, tws
, twt
);
29225 gen_helper_msa_aver_s_w(cpu_env
, twd
, tws
, twt
);
29228 gen_helper_msa_aver_s_d(cpu_env
, twd
, tws
, twt
);
29232 case OPC_AVER_U_df
:
29235 gen_helper_msa_aver_u_b(cpu_env
, twd
, tws
, twt
);
29238 gen_helper_msa_aver_u_h(cpu_env
, twd
, tws
, twt
);
29241 gen_helper_msa_aver_u_w(cpu_env
, twd
, tws
, twt
);
29244 gen_helper_msa_aver_u_d(cpu_env
, twd
, tws
, twt
);
29251 gen_helper_msa_ceq_b(cpu_env
, twd
, tws
, twt
);
29254 gen_helper_msa_ceq_h(cpu_env
, twd
, tws
, twt
);
29257 gen_helper_msa_ceq_w(cpu_env
, twd
, tws
, twt
);
29260 gen_helper_msa_ceq_d(cpu_env
, twd
, tws
, twt
);
29267 gen_helper_msa_cle_s_b(cpu_env
, twd
, tws
, twt
);
29270 gen_helper_msa_cle_s_h(cpu_env
, twd
, tws
, twt
);
29273 gen_helper_msa_cle_s_w(cpu_env
, twd
, tws
, twt
);
29276 gen_helper_msa_cle_s_d(cpu_env
, twd
, tws
, twt
);
29283 gen_helper_msa_cle_u_b(cpu_env
, twd
, tws
, twt
);
29286 gen_helper_msa_cle_u_h(cpu_env
, twd
, tws
, twt
);
29289 gen_helper_msa_cle_u_w(cpu_env
, twd
, tws
, twt
);
29292 gen_helper_msa_cle_u_d(cpu_env
, twd
, tws
, twt
);
29299 gen_helper_msa_clt_s_b(cpu_env
, twd
, tws
, twt
);
29302 gen_helper_msa_clt_s_h(cpu_env
, twd
, tws
, twt
);
29305 gen_helper_msa_clt_s_w(cpu_env
, twd
, tws
, twt
);
29308 gen_helper_msa_clt_s_d(cpu_env
, twd
, tws
, twt
);
29315 gen_helper_msa_clt_u_b(cpu_env
, twd
, tws
, twt
);
29318 gen_helper_msa_clt_u_h(cpu_env
, twd
, tws
, twt
);
29321 gen_helper_msa_clt_u_w(cpu_env
, twd
, tws
, twt
);
29324 gen_helper_msa_clt_u_d(cpu_env
, twd
, tws
, twt
);
29331 gen_helper_msa_div_s_b(cpu_env
, twd
, tws
, twt
);
29334 gen_helper_msa_div_s_h(cpu_env
, twd
, tws
, twt
);
29337 gen_helper_msa_div_s_w(cpu_env
, twd
, tws
, twt
);
29340 gen_helper_msa_div_s_d(cpu_env
, twd
, tws
, twt
);
29347 gen_helper_msa_div_u_b(cpu_env
, twd
, tws
, twt
);
29350 gen_helper_msa_div_u_h(cpu_env
, twd
, tws
, twt
);
29353 gen_helper_msa_div_u_w(cpu_env
, twd
, tws
, twt
);
29356 gen_helper_msa_div_u_d(cpu_env
, twd
, tws
, twt
);
29363 gen_helper_msa_max_a_b(cpu_env
, twd
, tws
, twt
);
29366 gen_helper_msa_max_a_h(cpu_env
, twd
, tws
, twt
);
29369 gen_helper_msa_max_a_w(cpu_env
, twd
, tws
, twt
);
29372 gen_helper_msa_max_a_d(cpu_env
, twd
, tws
, twt
);
29379 gen_helper_msa_max_s_b(cpu_env
, twd
, tws
, twt
);
29382 gen_helper_msa_max_s_h(cpu_env
, twd
, tws
, twt
);
29385 gen_helper_msa_max_s_w(cpu_env
, twd
, tws
, twt
);
29388 gen_helper_msa_max_s_d(cpu_env
, twd
, tws
, twt
);
29395 gen_helper_msa_max_u_b(cpu_env
, twd
, tws
, twt
);
29398 gen_helper_msa_max_u_h(cpu_env
, twd
, tws
, twt
);
29401 gen_helper_msa_max_u_w(cpu_env
, twd
, tws
, twt
);
29404 gen_helper_msa_max_u_d(cpu_env
, twd
, tws
, twt
);
29411 gen_helper_msa_min_a_b(cpu_env
, twd
, tws
, twt
);
29414 gen_helper_msa_min_a_h(cpu_env
, twd
, tws
, twt
);
29417 gen_helper_msa_min_a_w(cpu_env
, twd
, tws
, twt
);
29420 gen_helper_msa_min_a_d(cpu_env
, twd
, tws
, twt
);
29427 gen_helper_msa_min_s_b(cpu_env
, twd
, tws
, twt
);
29430 gen_helper_msa_min_s_h(cpu_env
, twd
, tws
, twt
);
29433 gen_helper_msa_min_s_w(cpu_env
, twd
, tws
, twt
);
29436 gen_helper_msa_min_s_d(cpu_env
, twd
, tws
, twt
);
29443 gen_helper_msa_min_u_b(cpu_env
, twd
, tws
, twt
);
29446 gen_helper_msa_min_u_h(cpu_env
, twd
, tws
, twt
);
29449 gen_helper_msa_min_u_w(cpu_env
, twd
, tws
, twt
);
29452 gen_helper_msa_min_u_d(cpu_env
, twd
, tws
, twt
);
29459 gen_helper_msa_mod_s_b(cpu_env
, twd
, tws
, twt
);
29462 gen_helper_msa_mod_s_h(cpu_env
, twd
, tws
, twt
);
29465 gen_helper_msa_mod_s_w(cpu_env
, twd
, tws
, twt
);
29468 gen_helper_msa_mod_s_d(cpu_env
, twd
, tws
, twt
);
29475 gen_helper_msa_mod_u_b(cpu_env
, twd
, tws
, twt
);
29478 gen_helper_msa_mod_u_h(cpu_env
, twd
, tws
, twt
);
29481 gen_helper_msa_mod_u_w(cpu_env
, twd
, tws
, twt
);
29484 gen_helper_msa_mod_u_d(cpu_env
, twd
, tws
, twt
);
29491 gen_helper_msa_maddv_b(cpu_env
, twd
, tws
, twt
);
29494 gen_helper_msa_maddv_h(cpu_env
, twd
, tws
, twt
);
29497 gen_helper_msa_maddv_w(cpu_env
, twd
, tws
, twt
);
29500 gen_helper_msa_maddv_d(cpu_env
, twd
, tws
, twt
);
29507 gen_helper_msa_msubv_b(cpu_env
, twd
, tws
, twt
);
29510 gen_helper_msa_msubv_h(cpu_env
, twd
, tws
, twt
);
29513 gen_helper_msa_msubv_w(cpu_env
, twd
, tws
, twt
);
29516 gen_helper_msa_msubv_d(cpu_env
, twd
, tws
, twt
);
29520 case OPC_ASUB_S_df
:
29523 gen_helper_msa_asub_s_b(cpu_env
, twd
, tws
, twt
);
29526 gen_helper_msa_asub_s_h(cpu_env
, twd
, tws
, twt
);
29529 gen_helper_msa_asub_s_w(cpu_env
, twd
, tws
, twt
);
29532 gen_helper_msa_asub_s_d(cpu_env
, twd
, tws
, twt
);
29536 case OPC_ASUB_U_df
:
29539 gen_helper_msa_asub_u_b(cpu_env
, twd
, tws
, twt
);
29542 gen_helper_msa_asub_u_h(cpu_env
, twd
, tws
, twt
);
29545 gen_helper_msa_asub_u_w(cpu_env
, twd
, tws
, twt
);
29548 gen_helper_msa_asub_u_d(cpu_env
, twd
, tws
, twt
);
29555 gen_helper_msa_ilvev_b(cpu_env
, twd
, tws
, twt
);
29558 gen_helper_msa_ilvev_h(cpu_env
, twd
, tws
, twt
);
29561 gen_helper_msa_ilvev_w(cpu_env
, twd
, tws
, twt
);
29564 gen_helper_msa_ilvev_d(cpu_env
, twd
, tws
, twt
);
29571 gen_helper_msa_ilvod_b(cpu_env
, twd
, tws
, twt
);
29574 gen_helper_msa_ilvod_h(cpu_env
, twd
, tws
, twt
);
29577 gen_helper_msa_ilvod_w(cpu_env
, twd
, tws
, twt
);
29580 gen_helper_msa_ilvod_d(cpu_env
, twd
, tws
, twt
);
29587 gen_helper_msa_ilvl_b(cpu_env
, twd
, tws
, twt
);
29590 gen_helper_msa_ilvl_h(cpu_env
, twd
, tws
, twt
);
29593 gen_helper_msa_ilvl_w(cpu_env
, twd
, tws
, twt
);
29596 gen_helper_msa_ilvl_d(cpu_env
, twd
, tws
, twt
);
29603 gen_helper_msa_ilvr_b(cpu_env
, twd
, tws
, twt
);
29606 gen_helper_msa_ilvr_h(cpu_env
, twd
, tws
, twt
);
29609 gen_helper_msa_ilvr_w(cpu_env
, twd
, tws
, twt
);
29612 gen_helper_msa_ilvr_d(cpu_env
, twd
, tws
, twt
);
29619 gen_helper_msa_pckev_b(cpu_env
, twd
, tws
, twt
);
29622 gen_helper_msa_pckev_h(cpu_env
, twd
, tws
, twt
);
29625 gen_helper_msa_pckev_w(cpu_env
, twd
, tws
, twt
);
29628 gen_helper_msa_pckev_d(cpu_env
, twd
, tws
, twt
);
29635 gen_helper_msa_pckod_b(cpu_env
, twd
, tws
, twt
);
29638 gen_helper_msa_pckod_h(cpu_env
, twd
, tws
, twt
);
29641 gen_helper_msa_pckod_w(cpu_env
, twd
, tws
, twt
);
29644 gen_helper_msa_pckod_d(cpu_env
, twd
, tws
, twt
);
29651 gen_helper_msa_sll_b(cpu_env
, twd
, tws
, twt
);
29654 gen_helper_msa_sll_h(cpu_env
, twd
, tws
, twt
);
29657 gen_helper_msa_sll_w(cpu_env
, twd
, tws
, twt
);
29660 gen_helper_msa_sll_d(cpu_env
, twd
, tws
, twt
);
29667 gen_helper_msa_sra_b(cpu_env
, twd
, tws
, twt
);
29670 gen_helper_msa_sra_h(cpu_env
, twd
, tws
, twt
);
29673 gen_helper_msa_sra_w(cpu_env
, twd
, tws
, twt
);
29676 gen_helper_msa_sra_d(cpu_env
, twd
, tws
, twt
);
29683 gen_helper_msa_srar_b(cpu_env
, twd
, tws
, twt
);
29686 gen_helper_msa_srar_h(cpu_env
, twd
, tws
, twt
);
29689 gen_helper_msa_srar_w(cpu_env
, twd
, tws
, twt
);
29692 gen_helper_msa_srar_d(cpu_env
, twd
, tws
, twt
);
29699 gen_helper_msa_srl_b(cpu_env
, twd
, tws
, twt
);
29702 gen_helper_msa_srl_h(cpu_env
, twd
, tws
, twt
);
29705 gen_helper_msa_srl_w(cpu_env
, twd
, tws
, twt
);
29708 gen_helper_msa_srl_d(cpu_env
, twd
, tws
, twt
);
29715 gen_helper_msa_srlr_b(cpu_env
, twd
, tws
, twt
);
29718 gen_helper_msa_srlr_h(cpu_env
, twd
, tws
, twt
);
29721 gen_helper_msa_srlr_w(cpu_env
, twd
, tws
, twt
);
29724 gen_helper_msa_srlr_d(cpu_env
, twd
, tws
, twt
);
29728 case OPC_SUBS_S_df
:
29731 gen_helper_msa_subs_s_b(cpu_env
, twd
, tws
, twt
);
29734 gen_helper_msa_subs_s_h(cpu_env
, twd
, tws
, twt
);
29737 gen_helper_msa_subs_s_w(cpu_env
, twd
, tws
, twt
);
29740 gen_helper_msa_subs_s_d(cpu_env
, twd
, tws
, twt
);
29747 gen_helper_msa_mulv_b(cpu_env
, twd
, tws
, twt
);
29750 gen_helper_msa_mulv_h(cpu_env
, twd
, tws
, twt
);
29753 gen_helper_msa_mulv_w(cpu_env
, twd
, tws
, twt
);
29756 gen_helper_msa_mulv_d(cpu_env
, twd
, tws
, twt
);
29761 gen_helper_msa_sld_df(cpu_env
, tdf
, twd
, tws
, twt
);
29764 gen_helper_msa_vshf_df(cpu_env
, tdf
, twd
, tws
, twt
);
29769 gen_helper_msa_subv_b(cpu_env
, twd
, tws
, twt
);
29772 gen_helper_msa_subv_h(cpu_env
, twd
, tws
, twt
);
29775 gen_helper_msa_subv_w(cpu_env
, twd
, tws
, twt
);
29778 gen_helper_msa_subv_d(cpu_env
, twd
, tws
, twt
);
29782 case OPC_SUBS_U_df
:
29785 gen_helper_msa_subs_u_b(cpu_env
, twd
, tws
, twt
);
29788 gen_helper_msa_subs_u_h(cpu_env
, twd
, tws
, twt
);
29791 gen_helper_msa_subs_u_w(cpu_env
, twd
, tws
, twt
);
29794 gen_helper_msa_subs_u_d(cpu_env
, twd
, tws
, twt
);
29799 gen_helper_msa_splat_df(cpu_env
, tdf
, twd
, tws
, twt
);
29801 case OPC_SUBSUS_U_df
:
29804 gen_helper_msa_subsus_u_b(cpu_env
, twd
, tws
, twt
);
29807 gen_helper_msa_subsus_u_h(cpu_env
, twd
, tws
, twt
);
29810 gen_helper_msa_subsus_u_w(cpu_env
, twd
, tws
, twt
);
29813 gen_helper_msa_subsus_u_d(cpu_env
, twd
, tws
, twt
);
29817 case OPC_SUBSUU_S_df
:
29820 gen_helper_msa_subsuu_s_b(cpu_env
, twd
, tws
, twt
);
29823 gen_helper_msa_subsuu_s_h(cpu_env
, twd
, tws
, twt
);
29826 gen_helper_msa_subsuu_s_w(cpu_env
, twd
, tws
, twt
);
29829 gen_helper_msa_subsuu_s_d(cpu_env
, twd
, tws
, twt
);
29834 case OPC_DOTP_S_df
:
29835 case OPC_DOTP_U_df
:
29836 case OPC_DPADD_S_df
:
29837 case OPC_DPADD_U_df
:
29838 case OPC_DPSUB_S_df
:
29839 case OPC_HADD_S_df
:
29840 case OPC_DPSUB_U_df
:
29841 case OPC_HADD_U_df
:
29842 case OPC_HSUB_S_df
:
29843 case OPC_HSUB_U_df
:
29844 if (df
== DF_BYTE
) {
29845 generate_exception_end(ctx
, EXCP_RI
);
29848 switch (MASK_MSA_3R(ctx
->opcode
)) {
29849 case OPC_HADD_S_df
:
29852 gen_helper_msa_hadd_s_h(cpu_env
, twd
, tws
, twt
);
29855 gen_helper_msa_hadd_s_w(cpu_env
, twd
, tws
, twt
);
29858 gen_helper_msa_hadd_s_d(cpu_env
, twd
, tws
, twt
);
29862 case OPC_HADD_U_df
:
29865 gen_helper_msa_hadd_u_h(cpu_env
, twd
, tws
, twt
);
29868 gen_helper_msa_hadd_u_w(cpu_env
, twd
, tws
, twt
);
29871 gen_helper_msa_hadd_u_d(cpu_env
, twd
, tws
, twt
);
29875 case OPC_HSUB_S_df
:
29878 gen_helper_msa_hsub_s_h(cpu_env
, twd
, tws
, twt
);
29881 gen_helper_msa_hsub_s_w(cpu_env
, twd
, tws
, twt
);
29884 gen_helper_msa_hsub_s_d(cpu_env
, twd
, tws
, twt
);
29888 case OPC_HSUB_U_df
:
29891 gen_helper_msa_hsub_u_h(cpu_env
, twd
, tws
, twt
);
29894 gen_helper_msa_hsub_u_w(cpu_env
, twd
, tws
, twt
);
29897 gen_helper_msa_hsub_u_d(cpu_env
, twd
, tws
, twt
);
29901 case OPC_DOTP_S_df
:
29904 gen_helper_msa_dotp_s_h(cpu_env
, twd
, tws
, twt
);
29907 gen_helper_msa_dotp_s_w(cpu_env
, twd
, tws
, twt
);
29910 gen_helper_msa_dotp_s_d(cpu_env
, twd
, tws
, twt
);
29914 case OPC_DOTP_U_df
:
29917 gen_helper_msa_dotp_u_h(cpu_env
, twd
, tws
, twt
);
29920 gen_helper_msa_dotp_u_w(cpu_env
, twd
, tws
, twt
);
29923 gen_helper_msa_dotp_u_d(cpu_env
, twd
, tws
, twt
);
29927 case OPC_DPADD_S_df
:
29930 gen_helper_msa_dpadd_s_h(cpu_env
, twd
, tws
, twt
);
29933 gen_helper_msa_dpadd_s_w(cpu_env
, twd
, tws
, twt
);
29936 gen_helper_msa_dpadd_s_d(cpu_env
, twd
, tws
, twt
);
29940 case OPC_DPADD_U_df
:
29943 gen_helper_msa_dpadd_u_h(cpu_env
, twd
, tws
, twt
);
29946 gen_helper_msa_dpadd_u_w(cpu_env
, twd
, tws
, twt
);
29949 gen_helper_msa_dpadd_u_d(cpu_env
, twd
, tws
, twt
);
29953 case OPC_DPSUB_S_df
:
29956 gen_helper_msa_dpsub_s_h(cpu_env
, twd
, tws
, twt
);
29959 gen_helper_msa_dpsub_s_w(cpu_env
, twd
, tws
, twt
);
29962 gen_helper_msa_dpsub_s_d(cpu_env
, twd
, tws
, twt
);
29966 case OPC_DPSUB_U_df
:
29969 gen_helper_msa_dpsub_u_h(cpu_env
, twd
, tws
, twt
);
29972 gen_helper_msa_dpsub_u_w(cpu_env
, twd
, tws
, twt
);
29975 gen_helper_msa_dpsub_u_d(cpu_env
, twd
, tws
, twt
);
29982 MIPS_INVAL("MSA instruction");
29983 generate_exception_end(ctx
, EXCP_RI
);
29986 tcg_temp_free_i32(twd
);
29987 tcg_temp_free_i32(tws
);
29988 tcg_temp_free_i32(twt
);
29989 tcg_temp_free_i32(tdf
);
29992 static void gen_msa_elm_3e(CPUMIPSState
*env
, DisasContext
*ctx
)
29994 #define MASK_MSA_ELM_DF3E(op) (MASK_MSA_MINOR(op) | (op & (0x3FF << 16)))
29995 uint8_t source
= (ctx
->opcode
>> 11) & 0x1f;
29996 uint8_t dest
= (ctx
->opcode
>> 6) & 0x1f;
29997 TCGv telm
= tcg_temp_new();
29998 TCGv_i32 tsr
= tcg_const_i32(source
);
29999 TCGv_i32 tdt
= tcg_const_i32(dest
);
30001 switch (MASK_MSA_ELM_DF3E(ctx
->opcode
)) {
30003 gen_load_gpr(telm
, source
);
30004 gen_helper_msa_ctcmsa(cpu_env
, telm
, tdt
);
30007 gen_helper_msa_cfcmsa(telm
, cpu_env
, tsr
);
30008 gen_store_gpr(telm
, dest
);
30011 gen_helper_msa_move_v(cpu_env
, tdt
, tsr
);
30014 MIPS_INVAL("MSA instruction");
30015 generate_exception_end(ctx
, EXCP_RI
);
30019 tcg_temp_free(telm
);
30020 tcg_temp_free_i32(tdt
);
30021 tcg_temp_free_i32(tsr
);
30024 static void gen_msa_elm_df(CPUMIPSState
*env
, DisasContext
*ctx
, uint32_t df
,
30027 #define MASK_MSA_ELM(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
30028 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
30029 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
30031 TCGv_i32 tws
= tcg_const_i32(ws
);
30032 TCGv_i32 twd
= tcg_const_i32(wd
);
30033 TCGv_i32 tn
= tcg_const_i32(n
);
30034 TCGv_i32 tdf
= tcg_const_i32(df
);
30036 switch (MASK_MSA_ELM(ctx
->opcode
)) {
30038 gen_helper_msa_sldi_df(cpu_env
, tdf
, twd
, tws
, tn
);
30040 case OPC_SPLATI_df
:
30041 gen_helper_msa_splati_df(cpu_env
, tdf
, twd
, tws
, tn
);
30044 gen_helper_msa_insve_df(cpu_env
, tdf
, twd
, tws
, tn
);
30046 case OPC_COPY_S_df
:
30047 case OPC_COPY_U_df
:
30048 case OPC_INSERT_df
:
30049 #if !defined(TARGET_MIPS64)
30050 /* Double format valid only for MIPS64 */
30051 if (df
== DF_DOUBLE
) {
30052 generate_exception_end(ctx
, EXCP_RI
);
30055 if ((MASK_MSA_ELM(ctx
->opcode
) == OPC_COPY_U_df
) &&
30057 generate_exception_end(ctx
, EXCP_RI
);
30061 switch (MASK_MSA_ELM(ctx
->opcode
)) {
30062 case OPC_COPY_S_df
:
30063 if (likely(wd
!= 0)) {
30066 gen_helper_msa_copy_s_b(cpu_env
, twd
, tws
, tn
);
30069 gen_helper_msa_copy_s_h(cpu_env
, twd
, tws
, tn
);
30072 gen_helper_msa_copy_s_w(cpu_env
, twd
, tws
, tn
);
30074 #if defined(TARGET_MIPS64)
30076 gen_helper_msa_copy_s_d(cpu_env
, twd
, tws
, tn
);
30084 case OPC_COPY_U_df
:
30085 if (likely(wd
!= 0)) {
30088 gen_helper_msa_copy_u_b(cpu_env
, twd
, tws
, tn
);
30091 gen_helper_msa_copy_u_h(cpu_env
, twd
, tws
, tn
);
30093 #if defined(TARGET_MIPS64)
30095 gen_helper_msa_copy_u_w(cpu_env
, twd
, tws
, tn
);
30103 case OPC_INSERT_df
:
30106 gen_helper_msa_insert_b(cpu_env
, twd
, tws
, tn
);
30109 gen_helper_msa_insert_h(cpu_env
, twd
, tws
, tn
);
30112 gen_helper_msa_insert_w(cpu_env
, twd
, tws
, tn
);
30114 #if defined(TARGET_MIPS64)
30116 gen_helper_msa_insert_d(cpu_env
, twd
, tws
, tn
);
30126 MIPS_INVAL("MSA instruction");
30127 generate_exception_end(ctx
, EXCP_RI
);
30129 tcg_temp_free_i32(twd
);
30130 tcg_temp_free_i32(tws
);
30131 tcg_temp_free_i32(tn
);
30132 tcg_temp_free_i32(tdf
);
30135 static void gen_msa_elm(CPUMIPSState
*env
, DisasContext
*ctx
)
30137 uint8_t dfn
= (ctx
->opcode
>> 16) & 0x3f;
30138 uint32_t df
= 0, n
= 0;
30140 if ((dfn
& 0x30) == 0x00) {
30143 } else if ((dfn
& 0x38) == 0x20) {
30146 } else if ((dfn
& 0x3c) == 0x30) {
30149 } else if ((dfn
& 0x3e) == 0x38) {
30152 } else if (dfn
== 0x3E) {
30153 /* CTCMSA, CFCMSA, MOVE.V */
30154 gen_msa_elm_3e(env
, ctx
);
30157 generate_exception_end(ctx
, EXCP_RI
);
30161 gen_msa_elm_df(env
, ctx
, df
, n
);
30164 static void gen_msa_3rf(CPUMIPSState
*env
, DisasContext
*ctx
)
30166 #define MASK_MSA_3RF(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
30167 uint8_t df
= (ctx
->opcode
>> 21) & 0x1;
30168 uint8_t wt
= (ctx
->opcode
>> 16) & 0x1f;
30169 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
30170 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
30172 TCGv_i32 twd
= tcg_const_i32(wd
);
30173 TCGv_i32 tws
= tcg_const_i32(ws
);
30174 TCGv_i32 twt
= tcg_const_i32(wt
);
30175 TCGv_i32 tdf
= tcg_temp_new_i32();
30177 /* adjust df value for floating-point instruction */
30178 tcg_gen_movi_i32(tdf
, df
+ 2);
30180 switch (MASK_MSA_3RF(ctx
->opcode
)) {
30182 gen_helper_msa_fcaf_df(cpu_env
, tdf
, twd
, tws
, twt
);
30185 gen_helper_msa_fadd_df(cpu_env
, tdf
, twd
, tws
, twt
);
30188 gen_helper_msa_fcun_df(cpu_env
, tdf
, twd
, tws
, twt
);
30191 gen_helper_msa_fsub_df(cpu_env
, tdf
, twd
, tws
, twt
);
30194 gen_helper_msa_fcor_df(cpu_env
, tdf
, twd
, tws
, twt
);
30197 gen_helper_msa_fceq_df(cpu_env
, tdf
, twd
, tws
, twt
);
30200 gen_helper_msa_fmul_df(cpu_env
, tdf
, twd
, tws
, twt
);
30203 gen_helper_msa_fcune_df(cpu_env
, tdf
, twd
, tws
, twt
);
30206 gen_helper_msa_fcueq_df(cpu_env
, tdf
, twd
, tws
, twt
);
30209 gen_helper_msa_fdiv_df(cpu_env
, tdf
, twd
, tws
, twt
);
30212 gen_helper_msa_fcne_df(cpu_env
, tdf
, twd
, tws
, twt
);
30215 gen_helper_msa_fclt_df(cpu_env
, tdf
, twd
, tws
, twt
);
30218 gen_helper_msa_fmadd_df(cpu_env
, tdf
, twd
, tws
, twt
);
30221 tcg_gen_movi_i32(tdf
, df
+ 1);
30222 gen_helper_msa_mul_q_df(cpu_env
, tdf
, twd
, tws
, twt
);
30225 gen_helper_msa_fcult_df(cpu_env
, tdf
, twd
, tws
, twt
);
30228 gen_helper_msa_fmsub_df(cpu_env
, tdf
, twd
, tws
, twt
);
30230 case OPC_MADD_Q_df
:
30231 tcg_gen_movi_i32(tdf
, df
+ 1);
30232 gen_helper_msa_madd_q_df(cpu_env
, tdf
, twd
, tws
, twt
);
30235 gen_helper_msa_fcle_df(cpu_env
, tdf
, twd
, tws
, twt
);
30237 case OPC_MSUB_Q_df
:
30238 tcg_gen_movi_i32(tdf
, df
+ 1);
30239 gen_helper_msa_msub_q_df(cpu_env
, tdf
, twd
, tws
, twt
);
30242 gen_helper_msa_fcule_df(cpu_env
, tdf
, twd
, tws
, twt
);
30245 gen_helper_msa_fexp2_df(cpu_env
, tdf
, twd
, tws
, twt
);
30248 gen_helper_msa_fsaf_df(cpu_env
, tdf
, twd
, tws
, twt
);
30251 gen_helper_msa_fexdo_df(cpu_env
, tdf
, twd
, tws
, twt
);
30254 gen_helper_msa_fsun_df(cpu_env
, tdf
, twd
, tws
, twt
);
30257 gen_helper_msa_fsor_df(cpu_env
, tdf
, twd
, tws
, twt
);
30260 gen_helper_msa_fseq_df(cpu_env
, tdf
, twd
, tws
, twt
);
30263 gen_helper_msa_ftq_df(cpu_env
, tdf
, twd
, tws
, twt
);
30266 gen_helper_msa_fsune_df(cpu_env
, tdf
, twd
, tws
, twt
);
30269 gen_helper_msa_fsueq_df(cpu_env
, tdf
, twd
, tws
, twt
);
30272 gen_helper_msa_fsne_df(cpu_env
, tdf
, twd
, tws
, twt
);
30275 gen_helper_msa_fslt_df(cpu_env
, tdf
, twd
, tws
, twt
);
30278 gen_helper_msa_fmin_df(cpu_env
, tdf
, twd
, tws
, twt
);
30280 case OPC_MULR_Q_df
:
30281 tcg_gen_movi_i32(tdf
, df
+ 1);
30282 gen_helper_msa_mulr_q_df(cpu_env
, tdf
, twd
, tws
, twt
);
30285 gen_helper_msa_fsult_df(cpu_env
, tdf
, twd
, tws
, twt
);
30287 case OPC_FMIN_A_df
:
30288 gen_helper_msa_fmin_a_df(cpu_env
, tdf
, twd
, tws
, twt
);
30290 case OPC_MADDR_Q_df
:
30291 tcg_gen_movi_i32(tdf
, df
+ 1);
30292 gen_helper_msa_maddr_q_df(cpu_env
, tdf
, twd
, tws
, twt
);
30295 gen_helper_msa_fsle_df(cpu_env
, tdf
, twd
, tws
, twt
);
30298 gen_helper_msa_fmax_df(cpu_env
, tdf
, twd
, tws
, twt
);
30300 case OPC_MSUBR_Q_df
:
30301 tcg_gen_movi_i32(tdf
, df
+ 1);
30302 gen_helper_msa_msubr_q_df(cpu_env
, tdf
, twd
, tws
, twt
);
30305 gen_helper_msa_fsule_df(cpu_env
, tdf
, twd
, tws
, twt
);
30307 case OPC_FMAX_A_df
:
30308 gen_helper_msa_fmax_a_df(cpu_env
, tdf
, twd
, tws
, twt
);
30311 MIPS_INVAL("MSA instruction");
30312 generate_exception_end(ctx
, EXCP_RI
);
30316 tcg_temp_free_i32(twd
);
30317 tcg_temp_free_i32(tws
);
30318 tcg_temp_free_i32(twt
);
30319 tcg_temp_free_i32(tdf
);
30322 static void gen_msa_2r(CPUMIPSState
*env
, DisasContext
*ctx
)
30324 #define MASK_MSA_2R(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
30325 (op & (0x7 << 18)))
30326 uint8_t wt
= (ctx
->opcode
>> 16) & 0x1f;
30327 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
30328 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
30329 uint8_t df
= (ctx
->opcode
>> 16) & 0x3;
30330 TCGv_i32 twd
= tcg_const_i32(wd
);
30331 TCGv_i32 tws
= tcg_const_i32(ws
);
30332 TCGv_i32 twt
= tcg_const_i32(wt
);
30333 TCGv_i32 tdf
= tcg_const_i32(df
);
30335 switch (MASK_MSA_2R(ctx
->opcode
)) {
30337 #if !defined(TARGET_MIPS64)
30338 /* Double format valid only for MIPS64 */
30339 if (df
== DF_DOUBLE
) {
30340 generate_exception_end(ctx
, EXCP_RI
);
30344 gen_helper_msa_fill_df(cpu_env
, tdf
, twd
, tws
); /* trs */
30349 gen_helper_msa_nloc_b(cpu_env
, twd
, tws
);
30352 gen_helper_msa_nloc_h(cpu_env
, twd
, tws
);
30355 gen_helper_msa_nloc_w(cpu_env
, twd
, tws
);
30358 gen_helper_msa_nloc_d(cpu_env
, twd
, tws
);
30365 gen_helper_msa_nlzc_b(cpu_env
, twd
, tws
);
30368 gen_helper_msa_nlzc_h(cpu_env
, twd
, tws
);
30371 gen_helper_msa_nlzc_w(cpu_env
, twd
, tws
);
30374 gen_helper_msa_nlzc_d(cpu_env
, twd
, tws
);
30381 gen_helper_msa_pcnt_b(cpu_env
, twd
, tws
);
30384 gen_helper_msa_pcnt_h(cpu_env
, twd
, tws
);
30387 gen_helper_msa_pcnt_w(cpu_env
, twd
, tws
);
30390 gen_helper_msa_pcnt_d(cpu_env
, twd
, tws
);
30395 MIPS_INVAL("MSA instruction");
30396 generate_exception_end(ctx
, EXCP_RI
);
30400 tcg_temp_free_i32(twd
);
30401 tcg_temp_free_i32(tws
);
30402 tcg_temp_free_i32(twt
);
30403 tcg_temp_free_i32(tdf
);
30406 static void gen_msa_2rf(CPUMIPSState
*env
, DisasContext
*ctx
)
30408 #define MASK_MSA_2RF(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
30409 (op & (0xf << 17)))
30410 uint8_t wt
= (ctx
->opcode
>> 16) & 0x1f;
30411 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
30412 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
30413 uint8_t df
= (ctx
->opcode
>> 16) & 0x1;
30414 TCGv_i32 twd
= tcg_const_i32(wd
);
30415 TCGv_i32 tws
= tcg_const_i32(ws
);
30416 TCGv_i32 twt
= tcg_const_i32(wt
);
30417 /* adjust df value for floating-point instruction */
30418 TCGv_i32 tdf
= tcg_const_i32(df
+ 2);
30420 switch (MASK_MSA_2RF(ctx
->opcode
)) {
30421 case OPC_FCLASS_df
:
30422 gen_helper_msa_fclass_df(cpu_env
, tdf
, twd
, tws
);
30424 case OPC_FTRUNC_S_df
:
30425 gen_helper_msa_ftrunc_s_df(cpu_env
, tdf
, twd
, tws
);
30427 case OPC_FTRUNC_U_df
:
30428 gen_helper_msa_ftrunc_u_df(cpu_env
, tdf
, twd
, tws
);
30431 gen_helper_msa_fsqrt_df(cpu_env
, tdf
, twd
, tws
);
30433 case OPC_FRSQRT_df
:
30434 gen_helper_msa_frsqrt_df(cpu_env
, tdf
, twd
, tws
);
30437 gen_helper_msa_frcp_df(cpu_env
, tdf
, twd
, tws
);
30440 gen_helper_msa_frint_df(cpu_env
, tdf
, twd
, tws
);
30443 gen_helper_msa_flog2_df(cpu_env
, tdf
, twd
, tws
);
30445 case OPC_FEXUPL_df
:
30446 gen_helper_msa_fexupl_df(cpu_env
, tdf
, twd
, tws
);
30448 case OPC_FEXUPR_df
:
30449 gen_helper_msa_fexupr_df(cpu_env
, tdf
, twd
, tws
);
30452 gen_helper_msa_ffql_df(cpu_env
, tdf
, twd
, tws
);
30455 gen_helper_msa_ffqr_df(cpu_env
, tdf
, twd
, tws
);
30457 case OPC_FTINT_S_df
:
30458 gen_helper_msa_ftint_s_df(cpu_env
, tdf
, twd
, tws
);
30460 case OPC_FTINT_U_df
:
30461 gen_helper_msa_ftint_u_df(cpu_env
, tdf
, twd
, tws
);
30463 case OPC_FFINT_S_df
:
30464 gen_helper_msa_ffint_s_df(cpu_env
, tdf
, twd
, tws
);
30466 case OPC_FFINT_U_df
:
30467 gen_helper_msa_ffint_u_df(cpu_env
, tdf
, twd
, tws
);
30471 tcg_temp_free_i32(twd
);
30472 tcg_temp_free_i32(tws
);
30473 tcg_temp_free_i32(twt
);
30474 tcg_temp_free_i32(tdf
);
30477 static void gen_msa_vec_v(CPUMIPSState
*env
, DisasContext
*ctx
)
30479 #define MASK_MSA_VEC(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)))
30480 uint8_t wt
= (ctx
->opcode
>> 16) & 0x1f;
30481 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
30482 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
30483 TCGv_i32 twd
= tcg_const_i32(wd
);
30484 TCGv_i32 tws
= tcg_const_i32(ws
);
30485 TCGv_i32 twt
= tcg_const_i32(wt
);
30487 switch (MASK_MSA_VEC(ctx
->opcode
)) {
30489 gen_helper_msa_and_v(cpu_env
, twd
, tws
, twt
);
30492 gen_helper_msa_or_v(cpu_env
, twd
, tws
, twt
);
30495 gen_helper_msa_nor_v(cpu_env
, twd
, tws
, twt
);
30498 gen_helper_msa_xor_v(cpu_env
, twd
, tws
, twt
);
30501 gen_helper_msa_bmnz_v(cpu_env
, twd
, tws
, twt
);
30504 gen_helper_msa_bmz_v(cpu_env
, twd
, tws
, twt
);
30507 gen_helper_msa_bsel_v(cpu_env
, twd
, tws
, twt
);
30510 MIPS_INVAL("MSA instruction");
30511 generate_exception_end(ctx
, EXCP_RI
);
30515 tcg_temp_free_i32(twd
);
30516 tcg_temp_free_i32(tws
);
30517 tcg_temp_free_i32(twt
);
30520 static void gen_msa_vec(CPUMIPSState
*env
, DisasContext
*ctx
)
30522 switch (MASK_MSA_VEC(ctx
->opcode
)) {
30530 gen_msa_vec_v(env
, ctx
);
30533 gen_msa_2r(env
, ctx
);
30536 gen_msa_2rf(env
, ctx
);
30539 MIPS_INVAL("MSA instruction");
30540 generate_exception_end(ctx
, EXCP_RI
);
30545 static void gen_msa(CPUMIPSState
*env
, DisasContext
*ctx
)
30547 uint32_t opcode
= ctx
->opcode
;
30548 check_insn(ctx
, ASE_MSA
);
30549 check_msa_access(ctx
);
30551 switch (MASK_MSA_MINOR(opcode
)) {
30552 case OPC_MSA_I8_00
:
30553 case OPC_MSA_I8_01
:
30554 case OPC_MSA_I8_02
:
30555 gen_msa_i8(env
, ctx
);
30557 case OPC_MSA_I5_06
:
30558 case OPC_MSA_I5_07
:
30559 gen_msa_i5(env
, ctx
);
30561 case OPC_MSA_BIT_09
:
30562 case OPC_MSA_BIT_0A
:
30563 gen_msa_bit(env
, ctx
);
30565 case OPC_MSA_3R_0D
:
30566 case OPC_MSA_3R_0E
:
30567 case OPC_MSA_3R_0F
:
30568 case OPC_MSA_3R_10
:
30569 case OPC_MSA_3R_11
:
30570 case OPC_MSA_3R_12
:
30571 case OPC_MSA_3R_13
:
30572 case OPC_MSA_3R_14
:
30573 case OPC_MSA_3R_15
:
30574 gen_msa_3r(env
, ctx
);
30577 gen_msa_elm(env
, ctx
);
30579 case OPC_MSA_3RF_1A
:
30580 case OPC_MSA_3RF_1B
:
30581 case OPC_MSA_3RF_1C
:
30582 gen_msa_3rf(env
, ctx
);
30585 gen_msa_vec(env
, ctx
);
30596 int32_t s10
= sextract32(ctx
->opcode
, 16, 10);
30597 uint8_t rs
= (ctx
->opcode
>> 11) & 0x1f;
30598 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
30599 uint8_t df
= (ctx
->opcode
>> 0) & 0x3;
30601 TCGv_i32 twd
= tcg_const_i32(wd
);
30602 TCGv taddr
= tcg_temp_new();
30603 gen_base_offset_addr(ctx
, taddr
, rs
, s10
<< df
);
30605 switch (MASK_MSA_MINOR(opcode
)) {
30607 gen_helper_msa_ld_b(cpu_env
, twd
, taddr
);
30610 gen_helper_msa_ld_h(cpu_env
, twd
, taddr
);
30613 gen_helper_msa_ld_w(cpu_env
, twd
, taddr
);
30616 gen_helper_msa_ld_d(cpu_env
, twd
, taddr
);
30619 gen_helper_msa_st_b(cpu_env
, twd
, taddr
);
30622 gen_helper_msa_st_h(cpu_env
, twd
, taddr
);
30625 gen_helper_msa_st_w(cpu_env
, twd
, taddr
);
30628 gen_helper_msa_st_d(cpu_env
, twd
, taddr
);
30632 tcg_temp_free_i32(twd
);
30633 tcg_temp_free(taddr
);
30637 MIPS_INVAL("MSA instruction");
30638 generate_exception_end(ctx
, EXCP_RI
);
30644 static void decode_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
30647 int rs
, rt
, rd
, sa
;
30651 /* make sure instructions are on a word boundary */
30652 if (ctx
->base
.pc_next
& 0x3) {
30653 env
->CP0_BadVAddr
= ctx
->base
.pc_next
;
30654 generate_exception_err(ctx
, EXCP_AdEL
, EXCP_INST_NOTAVAIL
);
30658 /* Handle blikely not taken case */
30659 if ((ctx
->hflags
& MIPS_HFLAG_BMASK_BASE
) == MIPS_HFLAG_BL
) {
30660 TCGLabel
*l1
= gen_new_label();
30662 tcg_gen_brcondi_tl(TCG_COND_NE
, bcond
, 0, l1
);
30663 tcg_gen_movi_i32(hflags
, ctx
->hflags
& ~MIPS_HFLAG_BMASK
);
30664 gen_goto_tb(ctx
, 1, ctx
->base
.pc_next
+ 4);
30668 op
= MASK_OP_MAJOR(ctx
->opcode
);
30669 rs
= (ctx
->opcode
>> 21) & 0x1f;
30670 rt
= (ctx
->opcode
>> 16) & 0x1f;
30671 rd
= (ctx
->opcode
>> 11) & 0x1f;
30672 sa
= (ctx
->opcode
>> 6) & 0x1f;
30673 imm
= (int16_t)ctx
->opcode
;
30676 decode_opc_special(env
, ctx
);
30679 #if defined(TARGET_MIPS64)
30680 if ((ctx
->insn_flags
& INSN_R5900
) && (ctx
->insn_flags
& ASE_MMI
)) {
30681 decode_mmi(env
, ctx
);
30683 if (ctx
->insn_flags
& ASE_MXU
) {
30684 decode_opc_mxu(env
, ctx
);
30687 decode_opc_special2_legacy(env
, ctx
);
30691 #if defined(TARGET_MIPS64)
30692 if (ctx
->insn_flags
& INSN_R5900
) {
30693 decode_mmi_sq(env
, ctx
); /* MMI_OPC_SQ */
30695 decode_opc_special3(env
, ctx
);
30698 decode_opc_special3(env
, ctx
);
30702 op1
= MASK_REGIMM(ctx
->opcode
);
30704 case OPC_BLTZL
: /* REGIMM branches */
30708 check_insn(ctx
, ISA_MIPS2
);
30709 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
30713 gen_compute_branch(ctx
, op1
, 4, rs
, -1, imm
<< 2, 4);
30717 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
30719 /* OPC_NAL, OPC_BAL */
30720 gen_compute_branch(ctx
, op1
, 4, 0, -1, imm
<< 2, 4);
30722 generate_exception_end(ctx
, EXCP_RI
);
30725 gen_compute_branch(ctx
, op1
, 4, rs
, -1, imm
<< 2, 4);
30728 case OPC_TGEI
: /* REGIMM traps */
30735 check_insn(ctx
, ISA_MIPS2
);
30736 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
30737 gen_trap(ctx
, op1
, rs
, -1, imm
);
30740 check_insn(ctx
, ISA_MIPS32R6
);
30741 generate_exception_end(ctx
, EXCP_RI
);
30744 check_insn(ctx
, ISA_MIPS32R2
);
30746 * Break the TB to be able to sync copied instructions
30749 ctx
->base
.is_jmp
= DISAS_STOP
;
30751 case OPC_BPOSGE32
: /* MIPS DSP branch */
30752 #if defined(TARGET_MIPS64)
30756 gen_compute_branch(ctx
, op1
, 4, -1, -2, (int32_t)imm
<< 2, 4);
30758 #if defined(TARGET_MIPS64)
30760 check_insn(ctx
, ISA_MIPS32R6
);
30761 check_mips_64(ctx
);
30763 tcg_gen_addi_tl(cpu_gpr
[rs
], cpu_gpr
[rs
], (int64_t)imm
<< 32);
30767 check_insn(ctx
, ISA_MIPS32R6
);
30768 check_mips_64(ctx
);
30770 tcg_gen_addi_tl(cpu_gpr
[rs
], cpu_gpr
[rs
], (int64_t)imm
<< 48);
30774 default: /* Invalid */
30775 MIPS_INVAL("regimm");
30776 generate_exception_end(ctx
, EXCP_RI
);
30781 check_cp0_enabled(ctx
);
30782 op1
= MASK_CP0(ctx
->opcode
);
30790 #if defined(TARGET_MIPS64)
30794 #ifndef CONFIG_USER_ONLY
30795 gen_cp0(env
, ctx
, op1
, rt
, rd
);
30796 #endif /* !CONFIG_USER_ONLY */
30814 #ifndef CONFIG_USER_ONLY
30815 gen_cp0(env
, ctx
, MASK_C0(ctx
->opcode
), rt
, rd
);
30816 #endif /* !CONFIG_USER_ONLY */
30819 #ifndef CONFIG_USER_ONLY
30822 TCGv t0
= tcg_temp_new();
30824 op2
= MASK_MFMC0(ctx
->opcode
);
30828 gen_helper_dmt(t0
);
30829 gen_store_gpr(t0
, rt
);
30833 gen_helper_emt(t0
);
30834 gen_store_gpr(t0
, rt
);
30838 gen_helper_dvpe(t0
, cpu_env
);
30839 gen_store_gpr(t0
, rt
);
30843 gen_helper_evpe(t0
, cpu_env
);
30844 gen_store_gpr(t0
, rt
);
30847 check_insn(ctx
, ISA_MIPS32R6
);
30849 gen_helper_dvp(t0
, cpu_env
);
30850 gen_store_gpr(t0
, rt
);
30854 check_insn(ctx
, ISA_MIPS32R6
);
30856 gen_helper_evp(t0
, cpu_env
);
30857 gen_store_gpr(t0
, rt
);
30861 check_insn(ctx
, ISA_MIPS32R2
);
30862 save_cpu_state(ctx
, 1);
30863 gen_helper_di(t0
, cpu_env
);
30864 gen_store_gpr(t0
, rt
);
30866 * Stop translation as we may have switched
30867 * the execution mode.
30869 ctx
->base
.is_jmp
= DISAS_STOP
;
30872 check_insn(ctx
, ISA_MIPS32R2
);
30873 save_cpu_state(ctx
, 1);
30874 gen_helper_ei(t0
, cpu_env
);
30875 gen_store_gpr(t0
, rt
);
30877 * DISAS_STOP isn't sufficient, we need to ensure we break
30878 * out of translated code to check for pending interrupts.
30880 gen_save_pc(ctx
->base
.pc_next
+ 4);
30881 ctx
->base
.is_jmp
= DISAS_EXIT
;
30883 default: /* Invalid */
30884 MIPS_INVAL("mfmc0");
30885 generate_exception_end(ctx
, EXCP_RI
);
30890 #endif /* !CONFIG_USER_ONLY */
30893 check_insn(ctx
, ISA_MIPS32R2
);
30894 gen_load_srsgpr(rt
, rd
);
30897 check_insn(ctx
, ISA_MIPS32R2
);
30898 gen_store_srsgpr(rt
, rd
);
30902 generate_exception_end(ctx
, EXCP_RI
);
30906 case OPC_BOVC
: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */
30907 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
30908 /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */
30909 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
30912 /* Arithmetic with immediate opcode */
30913 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
30917 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
30919 case OPC_SLTI
: /* Set on less than with immediate opcode */
30921 gen_slt_imm(ctx
, op
, rt
, rs
, imm
);
30923 case OPC_ANDI
: /* Arithmetic with immediate opcode */
30924 case OPC_LUI
: /* OPC_AUI */
30927 gen_logic_imm(ctx
, op
, rt
, rs
, imm
);
30929 case OPC_J
: /* Jump */
30931 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
30932 gen_compute_branch(ctx
, op
, 4, rs
, rt
, offset
, 4);
30935 case OPC_BLEZC
: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */
30936 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
30938 generate_exception_end(ctx
, EXCP_RI
);
30941 /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */
30942 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
30945 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
30948 case OPC_BGTZC
: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */
30949 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
30951 generate_exception_end(ctx
, EXCP_RI
);
30954 /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */
30955 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
30958 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
30961 case OPC_BLEZALC
: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */
30964 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
30966 check_insn(ctx
, ISA_MIPS32R6
);
30967 /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */
30968 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
30971 case OPC_BGTZALC
: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */
30974 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
30976 check_insn(ctx
, ISA_MIPS32R6
);
30977 /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */
30978 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
30983 check_insn(ctx
, ISA_MIPS2
);
30984 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
30988 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
30990 case OPC_LL
: /* Load and stores */
30991 check_insn(ctx
, ISA_MIPS2
);
30992 if (ctx
->insn_flags
& INSN_R5900
) {
30993 check_insn_opc_user_only(ctx
, INSN_R5900
);
30998 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
31006 gen_ld(ctx
, op
, rt
, rs
, imm
);
31010 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
31015 gen_st(ctx
, op
, rt
, rs
, imm
);
31018 check_insn(ctx
, ISA_MIPS2
);
31019 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
31020 if (ctx
->insn_flags
& INSN_R5900
) {
31021 check_insn_opc_user_only(ctx
, INSN_R5900
);
31023 gen_st_cond(ctx
, rt
, rs
, imm
, MO_TESL
, false);
31026 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
31027 check_cp0_enabled(ctx
);
31028 check_insn(ctx
, ISA_MIPS3
| ISA_MIPS32
);
31029 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
31030 gen_cache_operation(ctx
, rt
, rs
, imm
);
31032 /* Treat as NOP. */
31035 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
31036 if (ctx
->insn_flags
& INSN_R5900
) {
31037 /* Treat as NOP. */
31039 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32
);
31040 /* Treat as NOP. */
31044 /* Floating point (COP1). */
31049 gen_cop1_ldst(ctx
, op
, rt
, rs
, imm
);
31053 op1
= MASK_CP1(ctx
->opcode
);
31058 check_cp1_enabled(ctx
);
31059 check_insn(ctx
, ISA_MIPS32R2
);
31065 check_cp1_enabled(ctx
);
31066 gen_cp1(ctx
, op1
, rt
, rd
);
31068 #if defined(TARGET_MIPS64)
31071 check_cp1_enabled(ctx
);
31072 check_insn(ctx
, ISA_MIPS3
);
31073 check_mips_64(ctx
);
31074 gen_cp1(ctx
, op1
, rt
, rd
);
31077 case OPC_BC1EQZ
: /* OPC_BC1ANY2 */
31078 check_cp1_enabled(ctx
);
31079 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
31081 gen_compute_branch1_r6(ctx
, MASK_CP1(ctx
->opcode
),
31086 check_insn(ctx
, ASE_MIPS3D
);
31087 gen_compute_branch1(ctx
, MASK_BC1(ctx
->opcode
),
31088 (rt
>> 2) & 0x7, imm
<< 2);
31092 check_cp1_enabled(ctx
);
31093 check_insn(ctx
, ISA_MIPS32R6
);
31094 gen_compute_branch1_r6(ctx
, MASK_CP1(ctx
->opcode
),
31098 check_cp1_enabled(ctx
);
31099 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
31101 check_insn(ctx
, ASE_MIPS3D
);
31104 check_cp1_enabled(ctx
);
31105 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
31106 gen_compute_branch1(ctx
, MASK_BC1(ctx
->opcode
),
31107 (rt
>> 2) & 0x7, imm
<< 2);
31114 check_cp1_enabled(ctx
);
31115 gen_farith(ctx
, ctx
->opcode
& FOP(0x3f, 0x1f), rt
, rd
, sa
,
31121 int r6_op
= ctx
->opcode
& FOP(0x3f, 0x1f);
31122 check_cp1_enabled(ctx
);
31123 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
31125 case R6_OPC_CMP_AF_S
:
31126 case R6_OPC_CMP_UN_S
:
31127 case R6_OPC_CMP_EQ_S
:
31128 case R6_OPC_CMP_UEQ_S
:
31129 case R6_OPC_CMP_LT_S
:
31130 case R6_OPC_CMP_ULT_S
:
31131 case R6_OPC_CMP_LE_S
:
31132 case R6_OPC_CMP_ULE_S
:
31133 case R6_OPC_CMP_SAF_S
:
31134 case R6_OPC_CMP_SUN_S
:
31135 case R6_OPC_CMP_SEQ_S
:
31136 case R6_OPC_CMP_SEUQ_S
:
31137 case R6_OPC_CMP_SLT_S
:
31138 case R6_OPC_CMP_SULT_S
:
31139 case R6_OPC_CMP_SLE_S
:
31140 case R6_OPC_CMP_SULE_S
:
31141 case R6_OPC_CMP_OR_S
:
31142 case R6_OPC_CMP_UNE_S
:
31143 case R6_OPC_CMP_NE_S
:
31144 case R6_OPC_CMP_SOR_S
:
31145 case R6_OPC_CMP_SUNE_S
:
31146 case R6_OPC_CMP_SNE_S
:
31147 gen_r6_cmp_s(ctx
, ctx
->opcode
& 0x1f, rt
, rd
, sa
);
31149 case R6_OPC_CMP_AF_D
:
31150 case R6_OPC_CMP_UN_D
:
31151 case R6_OPC_CMP_EQ_D
:
31152 case R6_OPC_CMP_UEQ_D
:
31153 case R6_OPC_CMP_LT_D
:
31154 case R6_OPC_CMP_ULT_D
:
31155 case R6_OPC_CMP_LE_D
:
31156 case R6_OPC_CMP_ULE_D
:
31157 case R6_OPC_CMP_SAF_D
:
31158 case R6_OPC_CMP_SUN_D
:
31159 case R6_OPC_CMP_SEQ_D
:
31160 case R6_OPC_CMP_SEUQ_D
:
31161 case R6_OPC_CMP_SLT_D
:
31162 case R6_OPC_CMP_SULT_D
:
31163 case R6_OPC_CMP_SLE_D
:
31164 case R6_OPC_CMP_SULE_D
:
31165 case R6_OPC_CMP_OR_D
:
31166 case R6_OPC_CMP_UNE_D
:
31167 case R6_OPC_CMP_NE_D
:
31168 case R6_OPC_CMP_SOR_D
:
31169 case R6_OPC_CMP_SUNE_D
:
31170 case R6_OPC_CMP_SNE_D
:
31171 gen_r6_cmp_d(ctx
, ctx
->opcode
& 0x1f, rt
, rd
, sa
);
31174 gen_farith(ctx
, ctx
->opcode
& FOP(0x3f, 0x1f),
31175 rt
, rd
, sa
, (imm
>> 8) & 0x7);
31180 gen_farith(ctx
, ctx
->opcode
& FOP(0x3f, 0x1f), rt
, rd
, sa
,
31195 check_insn(ctx
, ASE_MSA
);
31196 gen_msa_branch(env
, ctx
, op1
);
31200 generate_exception_end(ctx
, EXCP_RI
);
31205 /* Compact branches [R6] and COP2 [non-R6] */
31206 case OPC_BC
: /* OPC_LWC2 */
31207 case OPC_BALC
: /* OPC_SWC2 */
31208 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
31209 /* OPC_BC, OPC_BALC */
31210 gen_compute_compact_branch(ctx
, op
, 0, 0,
31211 sextract32(ctx
->opcode
<< 2, 0, 28));
31212 } else if (ctx
->insn_flags
& ASE_LEXT
) {
31213 gen_loongson_lswc2(ctx
, rt
, rs
, rd
);
31215 /* OPC_LWC2, OPC_SWC2 */
31216 /* COP2: Not implemented. */
31217 generate_exception_err(ctx
, EXCP_CpU
, 2);
31220 case OPC_BEQZC
: /* OPC_JIC, OPC_LDC2 */
31221 case OPC_BNEZC
: /* OPC_JIALC, OPC_SDC2 */
31222 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
31224 /* OPC_BEQZC, OPC_BNEZC */
31225 gen_compute_compact_branch(ctx
, op
, rs
, 0,
31226 sextract32(ctx
->opcode
<< 2, 0, 23));
31228 /* OPC_JIC, OPC_JIALC */
31229 gen_compute_compact_branch(ctx
, op
, 0, rt
, imm
);
31231 } else if (ctx
->insn_flags
& ASE_LEXT
) {
31232 gen_loongson_lsdc2(ctx
, rt
, rs
, rd
);
31234 /* OPC_LWC2, OPC_SWC2 */
31235 /* COP2: Not implemented. */
31236 generate_exception_err(ctx
, EXCP_CpU
, 2);
31240 check_insn(ctx
, ASE_LMMI
);
31241 /* Note that these instructions use different fields. */
31242 gen_loongson_multimedia(ctx
, sa
, rd
, rt
);
31246 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
31247 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
31248 check_cp1_enabled(ctx
);
31249 op1
= MASK_CP3(ctx
->opcode
);
31253 check_insn(ctx
, ISA_MIPS5
| ISA_MIPS32R2
);
31259 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32R2
);
31260 gen_flt3_ldst(ctx
, op1
, sa
, rd
, rs
, rt
);
31263 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32R2
);
31264 /* Treat as NOP. */
31267 check_insn(ctx
, ISA_MIPS5
| ISA_MIPS32R2
);
31281 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32R2
);
31282 gen_flt3_arith(ctx
, op1
, sa
, rs
, rd
, rt
);
31286 generate_exception_end(ctx
, EXCP_RI
);
31290 generate_exception_err(ctx
, EXCP_CpU
, 1);
31294 #if defined(TARGET_MIPS64)
31295 /* MIPS64 opcodes */
31297 if (ctx
->insn_flags
& INSN_R5900
) {
31298 check_insn_opc_user_only(ctx
, INSN_R5900
);
31303 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
31307 check_insn(ctx
, ISA_MIPS3
);
31308 check_mips_64(ctx
);
31309 gen_ld(ctx
, op
, rt
, rs
, imm
);
31313 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
31316 check_insn(ctx
, ISA_MIPS3
);
31317 check_mips_64(ctx
);
31318 gen_st(ctx
, op
, rt
, rs
, imm
);
31321 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
31322 check_insn(ctx
, ISA_MIPS3
);
31323 if (ctx
->insn_flags
& INSN_R5900
) {
31324 check_insn_opc_user_only(ctx
, INSN_R5900
);
31326 check_mips_64(ctx
);
31327 gen_st_cond(ctx
, rt
, rs
, imm
, MO_TEQ
, false);
31329 case OPC_BNVC
: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */
31330 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
31331 /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */
31332 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
31335 check_insn(ctx
, ISA_MIPS3
);
31336 check_mips_64(ctx
);
31337 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
31341 check_insn(ctx
, ISA_MIPS3
);
31342 check_mips_64(ctx
);
31343 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
31346 case OPC_BNVC
: /* OPC_BNEZALC, OPC_BNEC */
31347 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
31348 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
31350 MIPS_INVAL("major opcode");
31351 generate_exception_end(ctx
, EXCP_RI
);
31355 case OPC_DAUI
: /* OPC_JALX */
31356 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
31357 #if defined(TARGET_MIPS64)
31359 check_mips_64(ctx
);
31361 generate_exception(ctx
, EXCP_RI
);
31362 } else if (rt
!= 0) {
31363 TCGv t0
= tcg_temp_new();
31364 gen_load_gpr(t0
, rs
);
31365 tcg_gen_addi_tl(cpu_gpr
[rt
], t0
, imm
<< 16);
31369 generate_exception_end(ctx
, EXCP_RI
);
31370 MIPS_INVAL("major opcode");
31374 check_insn(ctx
, ASE_MIPS16
| ASE_MICROMIPS
);
31375 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
31376 gen_compute_branch(ctx
, op
, 4, rs
, rt
, offset
, 4);
31379 case OPC_MSA
: /* OPC_MDMX */
31380 if (ctx
->insn_flags
& INSN_R5900
) {
31381 #if defined(TARGET_MIPS64)
31382 gen_mmi_lq(env
, ctx
); /* MMI_OPC_LQ */
31385 /* MDMX: Not implemented. */
31390 check_insn(ctx
, ISA_MIPS32R6
);
31391 gen_pcrel(ctx
, ctx
->opcode
, ctx
->base
.pc_next
, rs
);
31393 default: /* Invalid */
31394 MIPS_INVAL("major opcode");
31395 generate_exception_end(ctx
, EXCP_RI
);
31400 static void mips_tr_init_disas_context(DisasContextBase
*dcbase
, CPUState
*cs
)
31402 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
31403 CPUMIPSState
*env
= cs
->env_ptr
;
31405 ctx
->page_start
= ctx
->base
.pc_first
& TARGET_PAGE_MASK
;
31406 ctx
->saved_pc
= -1;
31407 ctx
->insn_flags
= env
->insn_flags
;
31408 ctx
->CP0_Config1
= env
->CP0_Config1
;
31409 ctx
->CP0_Config2
= env
->CP0_Config2
;
31410 ctx
->CP0_Config3
= env
->CP0_Config3
;
31411 ctx
->CP0_Config5
= env
->CP0_Config5
;
31413 ctx
->kscrexist
= (env
->CP0_Config4
>> CP0C4_KScrExist
) & 0xff;
31414 ctx
->rxi
= (env
->CP0_Config3
>> CP0C3_RXI
) & 1;
31415 ctx
->ie
= (env
->CP0_Config4
>> CP0C4_IE
) & 3;
31416 ctx
->bi
= (env
->CP0_Config3
>> CP0C3_BI
) & 1;
31417 ctx
->bp
= (env
->CP0_Config3
>> CP0C3_BP
) & 1;
31418 ctx
->PAMask
= env
->PAMask
;
31419 ctx
->mvh
= (env
->CP0_Config5
>> CP0C5_MVH
) & 1;
31420 ctx
->eva
= (env
->CP0_Config5
>> CP0C5_EVA
) & 1;
31421 ctx
->sc
= (env
->CP0_Config3
>> CP0C3_SC
) & 1;
31422 ctx
->CP0_LLAddr_shift
= env
->CP0_LLAddr_shift
;
31423 ctx
->cmgcr
= (env
->CP0_Config3
>> CP0C3_CMGCR
) & 1;
31424 /* Restore delay slot state from the tb context. */
31425 ctx
->hflags
= (uint32_t)ctx
->base
.tb
->flags
; /* FIXME: maybe use 64 bits? */
31426 ctx
->ulri
= (env
->CP0_Config3
>> CP0C3_ULRI
) & 1;
31427 ctx
->ps
= ((env
->active_fpu
.fcr0
>> FCR0_PS
) & 1) ||
31428 (env
->insn_flags
& (INSN_LOONGSON2E
| INSN_LOONGSON2F
));
31429 ctx
->vp
= (env
->CP0_Config5
>> CP0C5_VP
) & 1;
31430 ctx
->mrp
= (env
->CP0_Config5
>> CP0C5_MRP
) & 1;
31431 ctx
->nan2008
= (env
->active_fpu
.fcr31
>> FCR31_NAN2008
) & 1;
31432 ctx
->abs2008
= (env
->active_fpu
.fcr31
>> FCR31_ABS2008
) & 1;
31433 ctx
->mi
= (env
->CP0_Config5
>> CP0C5_MI
) & 1;
31434 ctx
->gi
= (env
->CP0_Config5
>> CP0C5_GI
) & 3;
31435 restore_cpu_state(env
, ctx
);
31436 #ifdef CONFIG_USER_ONLY
31437 ctx
->mem_idx
= MIPS_HFLAG_UM
;
31439 ctx
->mem_idx
= hflags_mmu_index(ctx
->hflags
);
31441 ctx
->default_tcg_memop_mask
= (ctx
->insn_flags
& (ISA_MIPS32R6
|
31442 INSN_LOONGSON3A
)) ? MO_UNALN
: MO_ALIGN
;
31444 LOG_DISAS("\ntb %p idx %d hflags %04x\n", ctx
->base
.tb
, ctx
->mem_idx
,
31448 static void mips_tr_tb_start(DisasContextBase
*dcbase
, CPUState
*cs
)
31452 static void mips_tr_insn_start(DisasContextBase
*dcbase
, CPUState
*cs
)
31454 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
31456 tcg_gen_insn_start(ctx
->base
.pc_next
, ctx
->hflags
& MIPS_HFLAG_BMASK
,
31460 static bool mips_tr_breakpoint_check(DisasContextBase
*dcbase
, CPUState
*cs
,
31461 const CPUBreakpoint
*bp
)
31463 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
31465 save_cpu_state(ctx
, 1);
31466 ctx
->base
.is_jmp
= DISAS_NORETURN
;
31467 gen_helper_raise_exception_debug(cpu_env
);
31469 * The address covered by the breakpoint must be included in
31470 * [tb->pc, tb->pc + tb->size) in order to for it to be
31471 * properly cleared -- thus we increment the PC here so that
31472 * the logic setting tb->size below does the right thing.
31474 ctx
->base
.pc_next
+= 4;
31478 static void mips_tr_translate_insn(DisasContextBase
*dcbase
, CPUState
*cs
)
31480 CPUMIPSState
*env
= cs
->env_ptr
;
31481 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
31485 is_slot
= ctx
->hflags
& MIPS_HFLAG_BMASK
;
31486 if (ctx
->insn_flags
& ISA_NANOMIPS32
) {
31487 ctx
->opcode
= cpu_lduw_code(env
, ctx
->base
.pc_next
);
31488 insn_bytes
= decode_nanomips_opc(env
, ctx
);
31489 } else if (!(ctx
->hflags
& MIPS_HFLAG_M16
)) {
31490 ctx
->opcode
= cpu_ldl_code(env
, ctx
->base
.pc_next
);
31492 decode_opc(env
, ctx
);
31493 } else if (ctx
->insn_flags
& ASE_MICROMIPS
) {
31494 ctx
->opcode
= cpu_lduw_code(env
, ctx
->base
.pc_next
);
31495 insn_bytes
= decode_micromips_opc(env
, ctx
);
31496 } else if (ctx
->insn_flags
& ASE_MIPS16
) {
31497 ctx
->opcode
= cpu_lduw_code(env
, ctx
->base
.pc_next
);
31498 insn_bytes
= decode_mips16_opc(env
, ctx
);
31500 generate_exception_end(ctx
, EXCP_RI
);
31501 g_assert(ctx
->base
.is_jmp
== DISAS_NORETURN
);
31505 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
31506 if (!(ctx
->hflags
& (MIPS_HFLAG_BDS16
| MIPS_HFLAG_BDS32
|
31507 MIPS_HFLAG_FBNSLOT
))) {
31509 * Force to generate branch as there is neither delay nor
31514 if ((ctx
->hflags
& MIPS_HFLAG_M16
) &&
31515 (ctx
->hflags
& MIPS_HFLAG_FBNSLOT
)) {
31517 * Force to generate branch as microMIPS R6 doesn't restrict
31518 * branches in the forbidden slot.
31524 gen_branch(ctx
, insn_bytes
);
31526 ctx
->base
.pc_next
+= insn_bytes
;
31528 if (ctx
->base
.is_jmp
!= DISAS_NEXT
) {
31532 * Execute a branch and its delay slot as a single instruction.
31533 * This is what GDB expects and is consistent with what the
31534 * hardware does (e.g. if a delay slot instruction faults, the
31535 * reported PC is the PC of the branch).
31537 if (ctx
->base
.singlestep_enabled
&&
31538 (ctx
->hflags
& MIPS_HFLAG_BMASK
) == 0) {
31539 ctx
->base
.is_jmp
= DISAS_TOO_MANY
;
31541 if (ctx
->base
.pc_next
- ctx
->page_start
>= TARGET_PAGE_SIZE
) {
31542 ctx
->base
.is_jmp
= DISAS_TOO_MANY
;
31546 static void mips_tr_tb_stop(DisasContextBase
*dcbase
, CPUState
*cs
)
31548 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
31550 if (ctx
->base
.singlestep_enabled
&& ctx
->base
.is_jmp
!= DISAS_NORETURN
) {
31551 save_cpu_state(ctx
, ctx
->base
.is_jmp
!= DISAS_EXIT
);
31552 gen_helper_raise_exception_debug(cpu_env
);
31554 switch (ctx
->base
.is_jmp
) {
31556 gen_save_pc(ctx
->base
.pc_next
);
31557 tcg_gen_lookup_and_goto_ptr();
31560 case DISAS_TOO_MANY
:
31561 save_cpu_state(ctx
, 0);
31562 gen_goto_tb(ctx
, 0, ctx
->base
.pc_next
);
31565 tcg_gen_exit_tb(NULL
, 0);
31567 case DISAS_NORETURN
:
31570 g_assert_not_reached();
31575 static void mips_tr_disas_log(const DisasContextBase
*dcbase
, CPUState
*cs
)
31577 qemu_log("IN: %s\n", lookup_symbol(dcbase
->pc_first
));
31578 log_target_disas(cs
, dcbase
->pc_first
, dcbase
->tb
->size
);
31581 static const TranslatorOps mips_tr_ops
= {
31582 .init_disas_context
= mips_tr_init_disas_context
,
31583 .tb_start
= mips_tr_tb_start
,
31584 .insn_start
= mips_tr_insn_start
,
31585 .breakpoint_check
= mips_tr_breakpoint_check
,
31586 .translate_insn
= mips_tr_translate_insn
,
31587 .tb_stop
= mips_tr_tb_stop
,
31588 .disas_log
= mips_tr_disas_log
,
31591 void gen_intermediate_code(CPUState
*cs
, TranslationBlock
*tb
, int max_insns
)
31595 translator_loop(&mips_tr_ops
, &ctx
.base
, cs
, tb
, max_insns
);
31598 static void fpu_dump_state(CPUMIPSState
*env
, FILE * f
, int flags
)
31601 int is_fpu64
= !!(env
->hflags
& MIPS_HFLAG_F64
);
31603 #define printfpr(fp) \
31606 qemu_fprintf(f, "w:%08x d:%016" PRIx64 \
31607 " fd:%13g fs:%13g psu: %13g\n", \
31608 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
31609 (double)(fp)->fd, \
31610 (double)(fp)->fs[FP_ENDIAN_IDX], \
31611 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
31614 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
31615 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
31616 qemu_fprintf(f, "w:%08x d:%016" PRIx64 \
31617 " fd:%13g fs:%13g psu:%13g\n", \
31618 tmp.w[FP_ENDIAN_IDX], tmp.d, \
31620 (double)tmp.fs[FP_ENDIAN_IDX], \
31621 (double)tmp.fs[!FP_ENDIAN_IDX]); \
31627 "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
31628 env
->active_fpu
.fcr0
, env
->active_fpu
.fcr31
, is_fpu64
,
31629 get_float_exception_flags(&env
->active_fpu
.fp_status
));
31630 for (i
= 0; i
< 32; (is_fpu64
) ? i
++ : (i
+= 2)) {
31631 qemu_fprintf(f
, "%3s: ", fregnames
[i
]);
31632 printfpr(&env
->active_fpu
.fpr
[i
]);
31638 void mips_cpu_dump_state(CPUState
*cs
, FILE *f
, int flags
)
31640 MIPSCPU
*cpu
= MIPS_CPU(cs
);
31641 CPUMIPSState
*env
= &cpu
->env
;
31644 qemu_fprintf(f
, "pc=0x" TARGET_FMT_lx
" HI=0x" TARGET_FMT_lx
31645 " LO=0x" TARGET_FMT_lx
" ds %04x "
31646 TARGET_FMT_lx
" " TARGET_FMT_ld
"\n",
31647 env
->active_tc
.PC
, env
->active_tc
.HI
[0], env
->active_tc
.LO
[0],
31648 env
->hflags
, env
->btarget
, env
->bcond
);
31649 for (i
= 0; i
< 32; i
++) {
31650 if ((i
& 3) == 0) {
31651 qemu_fprintf(f
, "GPR%02d:", i
);
31653 qemu_fprintf(f
, " %s " TARGET_FMT_lx
,
31654 regnames
[i
], env
->active_tc
.gpr
[i
]);
31655 if ((i
& 3) == 3) {
31656 qemu_fprintf(f
, "\n");
31660 qemu_fprintf(f
, "CP0 Status 0x%08x Cause 0x%08x EPC 0x"
31661 TARGET_FMT_lx
"\n",
31662 env
->CP0_Status
, env
->CP0_Cause
, env
->CP0_EPC
);
31663 qemu_fprintf(f
, " Config0 0x%08x Config1 0x%08x LLAddr 0x%016"
31665 env
->CP0_Config0
, env
->CP0_Config1
, env
->CP0_LLAddr
);
31666 qemu_fprintf(f
, " Config2 0x%08x Config3 0x%08x\n",
31667 env
->CP0_Config2
, env
->CP0_Config3
);
31668 qemu_fprintf(f
, " Config4 0x%08x Config5 0x%08x\n",
31669 env
->CP0_Config4
, env
->CP0_Config5
);
31670 if ((flags
& CPU_DUMP_FPU
) && (env
->hflags
& MIPS_HFLAG_FPU
)) {
31671 fpu_dump_state(env
, f
, flags
);
31675 void mips_tcg_init(void)
31680 for (i
= 1; i
< 32; i
++)
31681 cpu_gpr
[i
] = tcg_global_mem_new(cpu_env
,
31682 offsetof(CPUMIPSState
,
31686 for (i
= 0; i
< 32; i
++) {
31687 int off
= offsetof(CPUMIPSState
, active_fpu
.fpr
[i
].wr
.d
[0]);
31689 tcg_global_mem_new_i64(cpu_env
, off
, msaregnames
[i
* 2]);
31691 * The scalar floating-point unit (FPU) registers are mapped on
31692 * the MSA vector registers.
31694 fpu_f64
[i
] = msa_wr_d
[i
* 2];
31695 off
= offsetof(CPUMIPSState
, active_fpu
.fpr
[i
].wr
.d
[1]);
31696 msa_wr_d
[i
* 2 + 1] =
31697 tcg_global_mem_new_i64(cpu_env
, off
, msaregnames
[i
* 2 + 1]);
31700 cpu_PC
= tcg_global_mem_new(cpu_env
,
31701 offsetof(CPUMIPSState
, active_tc
.PC
), "PC");
31702 for (i
= 0; i
< MIPS_DSP_ACC
; i
++) {
31703 cpu_HI
[i
] = tcg_global_mem_new(cpu_env
,
31704 offsetof(CPUMIPSState
, active_tc
.HI
[i
]),
31706 cpu_LO
[i
] = tcg_global_mem_new(cpu_env
,
31707 offsetof(CPUMIPSState
, active_tc
.LO
[i
]),
31710 cpu_dspctrl
= tcg_global_mem_new(cpu_env
,
31711 offsetof(CPUMIPSState
,
31712 active_tc
.DSPControl
),
31714 bcond
= tcg_global_mem_new(cpu_env
,
31715 offsetof(CPUMIPSState
, bcond
), "bcond");
31716 btarget
= tcg_global_mem_new(cpu_env
,
31717 offsetof(CPUMIPSState
, btarget
), "btarget");
31718 hflags
= tcg_global_mem_new_i32(cpu_env
,
31719 offsetof(CPUMIPSState
, hflags
), "hflags");
31721 fpu_fcr0
= tcg_global_mem_new_i32(cpu_env
,
31722 offsetof(CPUMIPSState
, active_fpu
.fcr0
),
31724 fpu_fcr31
= tcg_global_mem_new_i32(cpu_env
,
31725 offsetof(CPUMIPSState
, active_fpu
.fcr31
),
31727 cpu_lladdr
= tcg_global_mem_new(cpu_env
, offsetof(CPUMIPSState
, lladdr
),
31729 cpu_llval
= tcg_global_mem_new(cpu_env
, offsetof(CPUMIPSState
, llval
),
31732 #if defined(TARGET_MIPS64)
31734 for (i
= 1; i
< 32; i
++) {
31735 cpu_mmr
[i
] = tcg_global_mem_new_i64(cpu_env
,
31736 offsetof(CPUMIPSState
,
31742 #if !defined(TARGET_MIPS64)
31743 for (i
= 0; i
< NUMBER_OF_MXU_REGISTERS
- 1; i
++) {
31744 mxu_gpr
[i
] = tcg_global_mem_new(cpu_env
,
31745 offsetof(CPUMIPSState
,
31746 active_tc
.mxu_gpr
[i
]),
31750 mxu_CR
= tcg_global_mem_new(cpu_env
,
31751 offsetof(CPUMIPSState
, active_tc
.mxu_cr
),
31752 mxuregnames
[NUMBER_OF_MXU_REGISTERS
- 1]);
31756 void restore_state_to_opc(CPUMIPSState
*env
, TranslationBlock
*tb
,
31757 target_ulong
*data
)
31759 env
->active_tc
.PC
= data
[0];
31760 env
->hflags
&= ~MIPS_HFLAG_BMASK
;
31761 env
->hflags
|= data
[1];
31762 switch (env
->hflags
& MIPS_HFLAG_BMASK_BASE
) {
31763 case MIPS_HFLAG_BR
:
31765 case MIPS_HFLAG_BC
:
31766 case MIPS_HFLAG_BL
:
31768 env
->btarget
= data
[2];