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"
38 #include "fpu_helper.h"
39 #include "translate.h"
42 /* indirect opcode tables */
43 OPC_SPECIAL
= (0x00 << 26),
44 OPC_REGIMM
= (0x01 << 26),
45 OPC_CP0
= (0x10 << 26),
46 OPC_CP2
= (0x12 << 26),
47 OPC_CP3
= (0x13 << 26),
48 OPC_SPECIAL2
= (0x1C << 26),
49 OPC_SPECIAL3
= (0x1F << 26),
50 /* arithmetic with immediate */
51 OPC_ADDI
= (0x08 << 26),
52 OPC_ADDIU
= (0x09 << 26),
53 OPC_SLTI
= (0x0A << 26),
54 OPC_SLTIU
= (0x0B << 26),
55 /* logic with immediate */
56 OPC_ANDI
= (0x0C << 26),
57 OPC_ORI
= (0x0D << 26),
58 OPC_XORI
= (0x0E << 26),
59 OPC_LUI
= (0x0F << 26),
60 /* arithmetic with immediate */
61 OPC_DADDI
= (0x18 << 26),
62 OPC_DADDIU
= (0x19 << 26),
63 /* Jump and branches */
65 OPC_JAL
= (0x03 << 26),
66 OPC_BEQ
= (0x04 << 26), /* Unconditional if rs = rt = 0 (B) */
67 OPC_BEQL
= (0x14 << 26),
68 OPC_BNE
= (0x05 << 26),
69 OPC_BNEL
= (0x15 << 26),
70 OPC_BLEZ
= (0x06 << 26),
71 OPC_BLEZL
= (0x16 << 26),
72 OPC_BGTZ
= (0x07 << 26),
73 OPC_BGTZL
= (0x17 << 26),
74 OPC_JALX
= (0x1D << 26),
75 OPC_DAUI
= (0x1D << 26),
77 OPC_LDL
= (0x1A << 26),
78 OPC_LDR
= (0x1B << 26),
79 OPC_LB
= (0x20 << 26),
80 OPC_LH
= (0x21 << 26),
81 OPC_LWL
= (0x22 << 26),
82 OPC_LW
= (0x23 << 26),
83 OPC_LWPC
= OPC_LW
| 0x5,
84 OPC_LBU
= (0x24 << 26),
85 OPC_LHU
= (0x25 << 26),
86 OPC_LWR
= (0x26 << 26),
87 OPC_LWU
= (0x27 << 26),
88 OPC_SB
= (0x28 << 26),
89 OPC_SH
= (0x29 << 26),
90 OPC_SWL
= (0x2A << 26),
91 OPC_SW
= (0x2B << 26),
92 OPC_SDL
= (0x2C << 26),
93 OPC_SDR
= (0x2D << 26),
94 OPC_SWR
= (0x2E << 26),
95 OPC_LL
= (0x30 << 26),
96 OPC_LLD
= (0x34 << 26),
97 OPC_LD
= (0x37 << 26),
98 OPC_LDPC
= OPC_LD
| 0x5,
99 OPC_SC
= (0x38 << 26),
100 OPC_SCD
= (0x3C << 26),
101 OPC_SD
= (0x3F << 26),
102 /* Floating point load/store */
103 OPC_LWC1
= (0x31 << 26),
104 OPC_LWC2
= (0x32 << 26),
105 OPC_LDC1
= (0x35 << 26),
106 OPC_LDC2
= (0x36 << 26),
107 OPC_SWC1
= (0x39 << 26),
108 OPC_SWC2
= (0x3A << 26),
109 OPC_SDC1
= (0x3D << 26),
110 OPC_SDC2
= (0x3E << 26),
111 /* Compact Branches */
112 OPC_BLEZALC
= (0x06 << 26),
113 OPC_BGEZALC
= (0x06 << 26),
114 OPC_BGEUC
= (0x06 << 26),
115 OPC_BGTZALC
= (0x07 << 26),
116 OPC_BLTZALC
= (0x07 << 26),
117 OPC_BLTUC
= (0x07 << 26),
118 OPC_BOVC
= (0x08 << 26),
119 OPC_BEQZALC
= (0x08 << 26),
120 OPC_BEQC
= (0x08 << 26),
121 OPC_BLEZC
= (0x16 << 26),
122 OPC_BGEZC
= (0x16 << 26),
123 OPC_BGEC
= (0x16 << 26),
124 OPC_BGTZC
= (0x17 << 26),
125 OPC_BLTZC
= (0x17 << 26),
126 OPC_BLTC
= (0x17 << 26),
127 OPC_BNVC
= (0x18 << 26),
128 OPC_BNEZALC
= (0x18 << 26),
129 OPC_BNEC
= (0x18 << 26),
130 OPC_BC
= (0x32 << 26),
131 OPC_BEQZC
= (0x36 << 26),
132 OPC_JIC
= (0x36 << 26),
133 OPC_BALC
= (0x3A << 26),
134 OPC_BNEZC
= (0x3E << 26),
135 OPC_JIALC
= (0x3E << 26),
136 /* MDMX ASE specific */
137 OPC_MDMX
= (0x1E << 26),
138 /* MSA ASE, same as MDMX */
140 /* Cache and prefetch */
141 OPC_CACHE
= (0x2F << 26),
142 OPC_PREF
= (0x33 << 26),
143 /* PC-relative address computation / loads */
144 OPC_PCREL
= (0x3B << 26),
147 /* PC-relative address computation / loads */
148 #define MASK_OPC_PCREL_TOP2BITS(op) (MASK_OP_MAJOR(op) | (op & (3 << 19)))
149 #define MASK_OPC_PCREL_TOP5BITS(op) (MASK_OP_MAJOR(op) | (op & (0x1f << 16)))
151 /* Instructions determined by bits 19 and 20 */
152 OPC_ADDIUPC
= OPC_PCREL
| (0 << 19),
153 R6_OPC_LWPC
= OPC_PCREL
| (1 << 19),
154 OPC_LWUPC
= OPC_PCREL
| (2 << 19),
156 /* Instructions determined by bits 16 ... 20 */
157 OPC_AUIPC
= OPC_PCREL
| (0x1e << 16),
158 OPC_ALUIPC
= OPC_PCREL
| (0x1f << 16),
161 R6_OPC_LDPC
= OPC_PCREL
| (6 << 18),
164 /* MIPS special opcodes */
165 #define MASK_SPECIAL(op) (MASK_OP_MAJOR(op) | (op & 0x3F))
169 OPC_SLL
= 0x00 | OPC_SPECIAL
,
170 /* NOP is SLL r0, r0, 0 */
171 /* SSNOP is SLL r0, r0, 1 */
172 /* EHB is SLL r0, r0, 3 */
173 OPC_SRL
= 0x02 | OPC_SPECIAL
, /* also ROTR */
174 OPC_ROTR
= OPC_SRL
| (1 << 21),
175 OPC_SRA
= 0x03 | OPC_SPECIAL
,
176 OPC_SLLV
= 0x04 | OPC_SPECIAL
,
177 OPC_SRLV
= 0x06 | OPC_SPECIAL
, /* also ROTRV */
178 OPC_ROTRV
= OPC_SRLV
| (1 << 6),
179 OPC_SRAV
= 0x07 | OPC_SPECIAL
,
180 OPC_DSLLV
= 0x14 | OPC_SPECIAL
,
181 OPC_DSRLV
= 0x16 | OPC_SPECIAL
, /* also DROTRV */
182 OPC_DROTRV
= OPC_DSRLV
| (1 << 6),
183 OPC_DSRAV
= 0x17 | OPC_SPECIAL
,
184 OPC_DSLL
= 0x38 | OPC_SPECIAL
,
185 OPC_DSRL
= 0x3A | OPC_SPECIAL
, /* also DROTR */
186 OPC_DROTR
= OPC_DSRL
| (1 << 21),
187 OPC_DSRA
= 0x3B | OPC_SPECIAL
,
188 OPC_DSLL32
= 0x3C | OPC_SPECIAL
,
189 OPC_DSRL32
= 0x3E | OPC_SPECIAL
, /* also DROTR32 */
190 OPC_DROTR32
= OPC_DSRL32
| (1 << 21),
191 OPC_DSRA32
= 0x3F | OPC_SPECIAL
,
192 /* Multiplication / division */
193 OPC_MULT
= 0x18 | OPC_SPECIAL
,
194 OPC_MULTU
= 0x19 | OPC_SPECIAL
,
195 OPC_DIV
= 0x1A | OPC_SPECIAL
,
196 OPC_DIVU
= 0x1B | OPC_SPECIAL
,
197 OPC_DMULT
= 0x1C | OPC_SPECIAL
,
198 OPC_DMULTU
= 0x1D | OPC_SPECIAL
,
199 OPC_DDIV
= 0x1E | OPC_SPECIAL
,
200 OPC_DDIVU
= 0x1F | OPC_SPECIAL
,
202 /* 2 registers arithmetic / logic */
203 OPC_ADD
= 0x20 | OPC_SPECIAL
,
204 OPC_ADDU
= 0x21 | OPC_SPECIAL
,
205 OPC_SUB
= 0x22 | OPC_SPECIAL
,
206 OPC_SUBU
= 0x23 | OPC_SPECIAL
,
207 OPC_AND
= 0x24 | OPC_SPECIAL
,
208 OPC_OR
= 0x25 | OPC_SPECIAL
,
209 OPC_XOR
= 0x26 | OPC_SPECIAL
,
210 OPC_NOR
= 0x27 | OPC_SPECIAL
,
211 OPC_SLT
= 0x2A | OPC_SPECIAL
,
212 OPC_SLTU
= 0x2B | OPC_SPECIAL
,
213 OPC_DADD
= 0x2C | OPC_SPECIAL
,
214 OPC_DADDU
= 0x2D | OPC_SPECIAL
,
215 OPC_DSUB
= 0x2E | OPC_SPECIAL
,
216 OPC_DSUBU
= 0x2F | OPC_SPECIAL
,
218 OPC_JR
= 0x08 | OPC_SPECIAL
, /* Also JR.HB */
219 OPC_JALR
= 0x09 | OPC_SPECIAL
, /* Also JALR.HB */
221 OPC_TGE
= 0x30 | OPC_SPECIAL
,
222 OPC_TGEU
= 0x31 | OPC_SPECIAL
,
223 OPC_TLT
= 0x32 | OPC_SPECIAL
,
224 OPC_TLTU
= 0x33 | OPC_SPECIAL
,
225 OPC_TEQ
= 0x34 | OPC_SPECIAL
,
226 OPC_TNE
= 0x36 | OPC_SPECIAL
,
227 /* HI / LO registers load & stores */
228 OPC_MFHI
= 0x10 | OPC_SPECIAL
,
229 OPC_MTHI
= 0x11 | OPC_SPECIAL
,
230 OPC_MFLO
= 0x12 | OPC_SPECIAL
,
231 OPC_MTLO
= 0x13 | OPC_SPECIAL
,
232 /* Conditional moves */
233 OPC_MOVZ
= 0x0A | OPC_SPECIAL
,
234 OPC_MOVN
= 0x0B | OPC_SPECIAL
,
236 OPC_SELEQZ
= 0x35 | OPC_SPECIAL
,
237 OPC_SELNEZ
= 0x37 | OPC_SPECIAL
,
239 OPC_MOVCI
= 0x01 | OPC_SPECIAL
,
242 OPC_PMON
= 0x05 | OPC_SPECIAL
, /* unofficial */
243 OPC_SYSCALL
= 0x0C | OPC_SPECIAL
,
244 OPC_BREAK
= 0x0D | OPC_SPECIAL
,
245 OPC_SPIM
= 0x0E | OPC_SPECIAL
, /* unofficial */
246 OPC_SYNC
= 0x0F | OPC_SPECIAL
,
248 OPC_SPECIAL28_RESERVED
= 0x28 | OPC_SPECIAL
,
249 OPC_SPECIAL29_RESERVED
= 0x29 | OPC_SPECIAL
,
250 OPC_SPECIAL39_RESERVED
= 0x39 | OPC_SPECIAL
,
251 OPC_SPECIAL3D_RESERVED
= 0x3D | OPC_SPECIAL
,
255 * R6 Multiply and Divide instructions have the same opcode
256 * and function field as legacy OPC_MULT[U]/OPC_DIV[U]
258 #define MASK_R6_MULDIV(op) (MASK_SPECIAL(op) | (op & (0x7ff)))
261 R6_OPC_MUL
= OPC_MULT
| (2 << 6),
262 R6_OPC_MUH
= OPC_MULT
| (3 << 6),
263 R6_OPC_MULU
= OPC_MULTU
| (2 << 6),
264 R6_OPC_MUHU
= OPC_MULTU
| (3 << 6),
265 R6_OPC_DIV
= OPC_DIV
| (2 << 6),
266 R6_OPC_MOD
= OPC_DIV
| (3 << 6),
267 R6_OPC_DIVU
= OPC_DIVU
| (2 << 6),
268 R6_OPC_MODU
= OPC_DIVU
| (3 << 6),
270 R6_OPC_DMUL
= OPC_DMULT
| (2 << 6),
271 R6_OPC_DMUH
= OPC_DMULT
| (3 << 6),
272 R6_OPC_DMULU
= OPC_DMULTU
| (2 << 6),
273 R6_OPC_DMUHU
= OPC_DMULTU
| (3 << 6),
274 R6_OPC_DDIV
= OPC_DDIV
| (2 << 6),
275 R6_OPC_DMOD
= OPC_DDIV
| (3 << 6),
276 R6_OPC_DDIVU
= OPC_DDIVU
| (2 << 6),
277 R6_OPC_DMODU
= OPC_DDIVU
| (3 << 6),
279 R6_OPC_CLZ
= 0x10 | OPC_SPECIAL
,
280 R6_OPC_CLO
= 0x11 | OPC_SPECIAL
,
281 R6_OPC_DCLZ
= 0x12 | OPC_SPECIAL
,
282 R6_OPC_DCLO
= 0x13 | OPC_SPECIAL
,
283 R6_OPC_SDBBP
= 0x0e | OPC_SPECIAL
,
285 OPC_LSA
= 0x05 | OPC_SPECIAL
,
286 OPC_DLSA
= 0x15 | OPC_SPECIAL
,
289 /* Multiplication variants of the vr54xx. */
290 #define MASK_MUL_VR54XX(op) (MASK_SPECIAL(op) | (op & (0x1F << 6)))
293 OPC_VR54XX_MULS
= (0x03 << 6) | OPC_MULT
,
294 OPC_VR54XX_MULSU
= (0x03 << 6) | OPC_MULTU
,
295 OPC_VR54XX_MACC
= (0x05 << 6) | OPC_MULT
,
296 OPC_VR54XX_MACCU
= (0x05 << 6) | OPC_MULTU
,
297 OPC_VR54XX_MSAC
= (0x07 << 6) | OPC_MULT
,
298 OPC_VR54XX_MSACU
= (0x07 << 6) | OPC_MULTU
,
299 OPC_VR54XX_MULHI
= (0x09 << 6) | OPC_MULT
,
300 OPC_VR54XX_MULHIU
= (0x09 << 6) | OPC_MULTU
,
301 OPC_VR54XX_MULSHI
= (0x0B << 6) | OPC_MULT
,
302 OPC_VR54XX_MULSHIU
= (0x0B << 6) | OPC_MULTU
,
303 OPC_VR54XX_MACCHI
= (0x0D << 6) | OPC_MULT
,
304 OPC_VR54XX_MACCHIU
= (0x0D << 6) | OPC_MULTU
,
305 OPC_VR54XX_MSACHI
= (0x0F << 6) | OPC_MULT
,
306 OPC_VR54XX_MSACHIU
= (0x0F << 6) | OPC_MULTU
,
309 /* REGIMM (rt field) opcodes */
310 #define MASK_REGIMM(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 16)))
313 OPC_BLTZ
= (0x00 << 16) | OPC_REGIMM
,
314 OPC_BLTZL
= (0x02 << 16) | OPC_REGIMM
,
315 OPC_BGEZ
= (0x01 << 16) | OPC_REGIMM
,
316 OPC_BGEZL
= (0x03 << 16) | OPC_REGIMM
,
317 OPC_BLTZAL
= (0x10 << 16) | OPC_REGIMM
,
318 OPC_BLTZALL
= (0x12 << 16) | OPC_REGIMM
,
319 OPC_BGEZAL
= (0x11 << 16) | OPC_REGIMM
,
320 OPC_BGEZALL
= (0x13 << 16) | OPC_REGIMM
,
321 OPC_TGEI
= (0x08 << 16) | OPC_REGIMM
,
322 OPC_TGEIU
= (0x09 << 16) | OPC_REGIMM
,
323 OPC_TLTI
= (0x0A << 16) | OPC_REGIMM
,
324 OPC_TLTIU
= (0x0B << 16) | OPC_REGIMM
,
325 OPC_TEQI
= (0x0C << 16) | OPC_REGIMM
,
326 OPC_TNEI
= (0x0E << 16) | OPC_REGIMM
,
327 OPC_SIGRIE
= (0x17 << 16) | OPC_REGIMM
,
328 OPC_SYNCI
= (0x1F << 16) | OPC_REGIMM
,
330 OPC_DAHI
= (0x06 << 16) | OPC_REGIMM
,
331 OPC_DATI
= (0x1e << 16) | OPC_REGIMM
,
334 /* Special2 opcodes */
335 #define MASK_SPECIAL2(op) (MASK_OP_MAJOR(op) | (op & 0x3F))
338 /* Multiply & xxx operations */
339 OPC_MADD
= 0x00 | OPC_SPECIAL2
,
340 OPC_MADDU
= 0x01 | OPC_SPECIAL2
,
341 OPC_MUL
= 0x02 | OPC_SPECIAL2
,
342 OPC_MSUB
= 0x04 | OPC_SPECIAL2
,
343 OPC_MSUBU
= 0x05 | OPC_SPECIAL2
,
345 OPC_MULT_G_2F
= 0x10 | OPC_SPECIAL2
,
346 OPC_DMULT_G_2F
= 0x11 | OPC_SPECIAL2
,
347 OPC_MULTU_G_2F
= 0x12 | OPC_SPECIAL2
,
348 OPC_DMULTU_G_2F
= 0x13 | OPC_SPECIAL2
,
349 OPC_DIV_G_2F
= 0x14 | OPC_SPECIAL2
,
350 OPC_DDIV_G_2F
= 0x15 | OPC_SPECIAL2
,
351 OPC_DIVU_G_2F
= 0x16 | OPC_SPECIAL2
,
352 OPC_DDIVU_G_2F
= 0x17 | OPC_SPECIAL2
,
353 OPC_MOD_G_2F
= 0x1c | OPC_SPECIAL2
,
354 OPC_DMOD_G_2F
= 0x1d | OPC_SPECIAL2
,
355 OPC_MODU_G_2F
= 0x1e | OPC_SPECIAL2
,
356 OPC_DMODU_G_2F
= 0x1f | OPC_SPECIAL2
,
358 OPC_CLZ
= 0x20 | OPC_SPECIAL2
,
359 OPC_CLO
= 0x21 | OPC_SPECIAL2
,
360 OPC_DCLZ
= 0x24 | OPC_SPECIAL2
,
361 OPC_DCLO
= 0x25 | OPC_SPECIAL2
,
363 OPC_SDBBP
= 0x3F | OPC_SPECIAL2
,
366 /* Special3 opcodes */
367 #define MASK_SPECIAL3(op) (MASK_OP_MAJOR(op) | (op & 0x3F))
370 OPC_EXT
= 0x00 | OPC_SPECIAL3
,
371 OPC_DEXTM
= 0x01 | OPC_SPECIAL3
,
372 OPC_DEXTU
= 0x02 | OPC_SPECIAL3
,
373 OPC_DEXT
= 0x03 | OPC_SPECIAL3
,
374 OPC_INS
= 0x04 | OPC_SPECIAL3
,
375 OPC_DINSM
= 0x05 | OPC_SPECIAL3
,
376 OPC_DINSU
= 0x06 | OPC_SPECIAL3
,
377 OPC_DINS
= 0x07 | OPC_SPECIAL3
,
378 OPC_FORK
= 0x08 | OPC_SPECIAL3
,
379 OPC_YIELD
= 0x09 | OPC_SPECIAL3
,
380 OPC_BSHFL
= 0x20 | OPC_SPECIAL3
,
381 OPC_DBSHFL
= 0x24 | OPC_SPECIAL3
,
382 OPC_RDHWR
= 0x3B | OPC_SPECIAL3
,
383 OPC_GINV
= 0x3D | OPC_SPECIAL3
,
386 OPC_MULT_G_2E
= 0x18 | OPC_SPECIAL3
,
387 OPC_MULTU_G_2E
= 0x19 | OPC_SPECIAL3
,
388 OPC_DIV_G_2E
= 0x1A | OPC_SPECIAL3
,
389 OPC_DIVU_G_2E
= 0x1B | OPC_SPECIAL3
,
390 OPC_DMULT_G_2E
= 0x1C | OPC_SPECIAL3
,
391 OPC_DMULTU_G_2E
= 0x1D | OPC_SPECIAL3
,
392 OPC_DDIV_G_2E
= 0x1E | OPC_SPECIAL3
,
393 OPC_DDIVU_G_2E
= 0x1F | OPC_SPECIAL3
,
394 OPC_MOD_G_2E
= 0x22 | OPC_SPECIAL3
,
395 OPC_MODU_G_2E
= 0x23 | OPC_SPECIAL3
,
396 OPC_DMOD_G_2E
= 0x26 | OPC_SPECIAL3
,
397 OPC_DMODU_G_2E
= 0x27 | OPC_SPECIAL3
,
400 OPC_LX_DSP
= 0x0A | OPC_SPECIAL3
,
401 /* MIPS DSP Arithmetic */
402 OPC_ADDU_QB_DSP
= 0x10 | OPC_SPECIAL3
,
403 OPC_ADDU_OB_DSP
= 0x14 | OPC_SPECIAL3
,
404 OPC_ABSQ_S_PH_DSP
= 0x12 | OPC_SPECIAL3
,
405 OPC_ABSQ_S_QH_DSP
= 0x16 | OPC_SPECIAL3
,
406 /* OPC_ADDUH_QB_DSP is same as OPC_MULT_G_2E. */
407 /* OPC_ADDUH_QB_DSP = 0x18 | OPC_SPECIAL3, */
408 OPC_CMPU_EQ_QB_DSP
= 0x11 | OPC_SPECIAL3
,
409 OPC_CMPU_EQ_OB_DSP
= 0x15 | OPC_SPECIAL3
,
410 /* MIPS DSP GPR-Based Shift Sub-class */
411 OPC_SHLL_QB_DSP
= 0x13 | OPC_SPECIAL3
,
412 OPC_SHLL_OB_DSP
= 0x17 | OPC_SPECIAL3
,
413 /* MIPS DSP Multiply Sub-class insns */
414 /* OPC_MUL_PH_DSP is same as OPC_ADDUH_QB_DSP. */
415 /* OPC_MUL_PH_DSP = 0x18 | OPC_SPECIAL3, */
416 OPC_DPA_W_PH_DSP
= 0x30 | OPC_SPECIAL3
,
417 OPC_DPAQ_W_QH_DSP
= 0x34 | OPC_SPECIAL3
,
418 /* DSP Bit/Manipulation Sub-class */
419 OPC_INSV_DSP
= 0x0C | OPC_SPECIAL3
,
420 OPC_DINSV_DSP
= 0x0D | OPC_SPECIAL3
,
421 /* MIPS DSP Append Sub-class */
422 OPC_APPEND_DSP
= 0x31 | OPC_SPECIAL3
,
423 OPC_DAPPEND_DSP
= 0x35 | OPC_SPECIAL3
,
424 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
425 OPC_EXTR_W_DSP
= 0x38 | OPC_SPECIAL3
,
426 OPC_DEXTR_W_DSP
= 0x3C | OPC_SPECIAL3
,
429 OPC_LWLE
= 0x19 | OPC_SPECIAL3
,
430 OPC_LWRE
= 0x1A | OPC_SPECIAL3
,
431 OPC_CACHEE
= 0x1B | OPC_SPECIAL3
,
432 OPC_SBE
= 0x1C | OPC_SPECIAL3
,
433 OPC_SHE
= 0x1D | OPC_SPECIAL3
,
434 OPC_SCE
= 0x1E | OPC_SPECIAL3
,
435 OPC_SWE
= 0x1F | OPC_SPECIAL3
,
436 OPC_SWLE
= 0x21 | OPC_SPECIAL3
,
437 OPC_SWRE
= 0x22 | OPC_SPECIAL3
,
438 OPC_PREFE
= 0x23 | OPC_SPECIAL3
,
439 OPC_LBUE
= 0x28 | OPC_SPECIAL3
,
440 OPC_LHUE
= 0x29 | OPC_SPECIAL3
,
441 OPC_LBE
= 0x2C | OPC_SPECIAL3
,
442 OPC_LHE
= 0x2D | OPC_SPECIAL3
,
443 OPC_LLE
= 0x2E | OPC_SPECIAL3
,
444 OPC_LWE
= 0x2F | OPC_SPECIAL3
,
447 R6_OPC_PREF
= 0x35 | OPC_SPECIAL3
,
448 R6_OPC_CACHE
= 0x25 | OPC_SPECIAL3
,
449 R6_OPC_LL
= 0x36 | OPC_SPECIAL3
,
450 R6_OPC_SC
= 0x26 | OPC_SPECIAL3
,
451 R6_OPC_LLD
= 0x37 | OPC_SPECIAL3
,
452 R6_OPC_SCD
= 0x27 | OPC_SPECIAL3
,
455 /* Loongson EXT load/store quad word opcodes */
456 #define MASK_LOONGSON_GSLSQ(op) (MASK_OP_MAJOR(op) | (op & 0x8020))
458 OPC_GSLQ
= 0x0020 | OPC_LWC2
,
459 OPC_GSLQC1
= 0x8020 | OPC_LWC2
,
460 OPC_GSSHFL
= OPC_LWC2
,
461 OPC_GSSQ
= 0x0020 | OPC_SWC2
,
462 OPC_GSSQC1
= 0x8020 | OPC_SWC2
,
463 OPC_GSSHFS
= OPC_SWC2
,
466 /* Loongson EXT shifted load/store opcodes */
467 #define MASK_LOONGSON_GSSHFLS(op) (MASK_OP_MAJOR(op) | (op & 0xc03f))
469 OPC_GSLWLC1
= 0x4 | OPC_GSSHFL
,
470 OPC_GSLWRC1
= 0x5 | OPC_GSSHFL
,
471 OPC_GSLDLC1
= 0x6 | OPC_GSSHFL
,
472 OPC_GSLDRC1
= 0x7 | OPC_GSSHFL
,
473 OPC_GSSWLC1
= 0x4 | OPC_GSSHFS
,
474 OPC_GSSWRC1
= 0x5 | OPC_GSSHFS
,
475 OPC_GSSDLC1
= 0x6 | OPC_GSSHFS
,
476 OPC_GSSDRC1
= 0x7 | OPC_GSSHFS
,
479 /* Loongson EXT LDC2/SDC2 opcodes */
480 #define MASK_LOONGSON_LSDC2(op) (MASK_OP_MAJOR(op) | (op & 0x7))
483 OPC_GSLBX
= 0x0 | OPC_LDC2
,
484 OPC_GSLHX
= 0x1 | OPC_LDC2
,
485 OPC_GSLWX
= 0x2 | OPC_LDC2
,
486 OPC_GSLDX
= 0x3 | OPC_LDC2
,
487 OPC_GSLWXC1
= 0x6 | OPC_LDC2
,
488 OPC_GSLDXC1
= 0x7 | OPC_LDC2
,
489 OPC_GSSBX
= 0x0 | OPC_SDC2
,
490 OPC_GSSHX
= 0x1 | OPC_SDC2
,
491 OPC_GSSWX
= 0x2 | OPC_SDC2
,
492 OPC_GSSDX
= 0x3 | OPC_SDC2
,
493 OPC_GSSWXC1
= 0x6 | OPC_SDC2
,
494 OPC_GSSDXC1
= 0x7 | OPC_SDC2
,
498 #define MASK_BSHFL(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
501 OPC_WSBH
= (0x02 << 6) | OPC_BSHFL
,
502 OPC_SEB
= (0x10 << 6) | OPC_BSHFL
,
503 OPC_SEH
= (0x18 << 6) | OPC_BSHFL
,
504 OPC_ALIGN
= (0x08 << 6) | OPC_BSHFL
, /* 010.bp (010.00 to 010.11) */
505 OPC_ALIGN_1
= (0x09 << 6) | OPC_BSHFL
,
506 OPC_ALIGN_2
= (0x0A << 6) | OPC_BSHFL
,
507 OPC_ALIGN_3
= (0x0B << 6) | OPC_BSHFL
,
508 OPC_BITSWAP
= (0x00 << 6) | OPC_BSHFL
/* 00000 */
512 #define MASK_DBSHFL(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
515 OPC_DSBH
= (0x02 << 6) | OPC_DBSHFL
,
516 OPC_DSHD
= (0x05 << 6) | OPC_DBSHFL
,
517 OPC_DALIGN
= (0x08 << 6) | OPC_DBSHFL
, /* 01.bp (01.000 to 01.111) */
518 OPC_DALIGN_1
= (0x09 << 6) | OPC_DBSHFL
,
519 OPC_DALIGN_2
= (0x0A << 6) | OPC_DBSHFL
,
520 OPC_DALIGN_3
= (0x0B << 6) | OPC_DBSHFL
,
521 OPC_DALIGN_4
= (0x0C << 6) | OPC_DBSHFL
,
522 OPC_DALIGN_5
= (0x0D << 6) | OPC_DBSHFL
,
523 OPC_DALIGN_6
= (0x0E << 6) | OPC_DBSHFL
,
524 OPC_DALIGN_7
= (0x0F << 6) | OPC_DBSHFL
,
525 OPC_DBITSWAP
= (0x00 << 6) | OPC_DBSHFL
, /* 00000 */
528 /* MIPS DSP REGIMM opcodes */
530 OPC_BPOSGE32
= (0x1C << 16) | OPC_REGIMM
,
531 OPC_BPOSGE64
= (0x1D << 16) | OPC_REGIMM
,
534 #define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
537 OPC_LBUX
= (0x06 << 6) | OPC_LX_DSP
,
538 OPC_LHX
= (0x04 << 6) | OPC_LX_DSP
,
539 OPC_LWX
= (0x00 << 6) | OPC_LX_DSP
,
540 OPC_LDX
= (0x08 << 6) | OPC_LX_DSP
,
543 #define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
545 /* MIPS DSP Arithmetic Sub-class */
546 OPC_ADDQ_PH
= (0x0A << 6) | OPC_ADDU_QB_DSP
,
547 OPC_ADDQ_S_PH
= (0x0E << 6) | OPC_ADDU_QB_DSP
,
548 OPC_ADDQ_S_W
= (0x16 << 6) | OPC_ADDU_QB_DSP
,
549 OPC_ADDU_QB
= (0x00 << 6) | OPC_ADDU_QB_DSP
,
550 OPC_ADDU_S_QB
= (0x04 << 6) | OPC_ADDU_QB_DSP
,
551 OPC_ADDU_PH
= (0x08 << 6) | OPC_ADDU_QB_DSP
,
552 OPC_ADDU_S_PH
= (0x0C << 6) | OPC_ADDU_QB_DSP
,
553 OPC_SUBQ_PH
= (0x0B << 6) | OPC_ADDU_QB_DSP
,
554 OPC_SUBQ_S_PH
= (0x0F << 6) | OPC_ADDU_QB_DSP
,
555 OPC_SUBQ_S_W
= (0x17 << 6) | OPC_ADDU_QB_DSP
,
556 OPC_SUBU_QB
= (0x01 << 6) | OPC_ADDU_QB_DSP
,
557 OPC_SUBU_S_QB
= (0x05 << 6) | OPC_ADDU_QB_DSP
,
558 OPC_SUBU_PH
= (0x09 << 6) | OPC_ADDU_QB_DSP
,
559 OPC_SUBU_S_PH
= (0x0D << 6) | OPC_ADDU_QB_DSP
,
560 OPC_ADDSC
= (0x10 << 6) | OPC_ADDU_QB_DSP
,
561 OPC_ADDWC
= (0x11 << 6) | OPC_ADDU_QB_DSP
,
562 OPC_MODSUB
= (0x12 << 6) | OPC_ADDU_QB_DSP
,
563 OPC_RADDU_W_QB
= (0x14 << 6) | OPC_ADDU_QB_DSP
,
564 /* MIPS DSP Multiply Sub-class insns */
565 OPC_MULEU_S_PH_QBL
= (0x06 << 6) | OPC_ADDU_QB_DSP
,
566 OPC_MULEU_S_PH_QBR
= (0x07 << 6) | OPC_ADDU_QB_DSP
,
567 OPC_MULQ_RS_PH
= (0x1F << 6) | OPC_ADDU_QB_DSP
,
568 OPC_MULEQ_S_W_PHL
= (0x1C << 6) | OPC_ADDU_QB_DSP
,
569 OPC_MULEQ_S_W_PHR
= (0x1D << 6) | OPC_ADDU_QB_DSP
,
570 OPC_MULQ_S_PH
= (0x1E << 6) | OPC_ADDU_QB_DSP
,
573 #define OPC_ADDUH_QB_DSP OPC_MULT_G_2E
574 #define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
576 /* MIPS DSP Arithmetic Sub-class */
577 OPC_ADDUH_QB
= (0x00 << 6) | OPC_ADDUH_QB_DSP
,
578 OPC_ADDUH_R_QB
= (0x02 << 6) | OPC_ADDUH_QB_DSP
,
579 OPC_ADDQH_PH
= (0x08 << 6) | OPC_ADDUH_QB_DSP
,
580 OPC_ADDQH_R_PH
= (0x0A << 6) | OPC_ADDUH_QB_DSP
,
581 OPC_ADDQH_W
= (0x10 << 6) | OPC_ADDUH_QB_DSP
,
582 OPC_ADDQH_R_W
= (0x12 << 6) | OPC_ADDUH_QB_DSP
,
583 OPC_SUBUH_QB
= (0x01 << 6) | OPC_ADDUH_QB_DSP
,
584 OPC_SUBUH_R_QB
= (0x03 << 6) | OPC_ADDUH_QB_DSP
,
585 OPC_SUBQH_PH
= (0x09 << 6) | OPC_ADDUH_QB_DSP
,
586 OPC_SUBQH_R_PH
= (0x0B << 6) | OPC_ADDUH_QB_DSP
,
587 OPC_SUBQH_W
= (0x11 << 6) | OPC_ADDUH_QB_DSP
,
588 OPC_SUBQH_R_W
= (0x13 << 6) | OPC_ADDUH_QB_DSP
,
589 /* MIPS DSP Multiply Sub-class insns */
590 OPC_MUL_PH
= (0x0C << 6) | OPC_ADDUH_QB_DSP
,
591 OPC_MUL_S_PH
= (0x0E << 6) | OPC_ADDUH_QB_DSP
,
592 OPC_MULQ_S_W
= (0x16 << 6) | OPC_ADDUH_QB_DSP
,
593 OPC_MULQ_RS_W
= (0x17 << 6) | OPC_ADDUH_QB_DSP
,
596 #define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
598 /* MIPS DSP Arithmetic Sub-class */
599 OPC_ABSQ_S_QB
= (0x01 << 6) | OPC_ABSQ_S_PH_DSP
,
600 OPC_ABSQ_S_PH
= (0x09 << 6) | OPC_ABSQ_S_PH_DSP
,
601 OPC_ABSQ_S_W
= (0x11 << 6) | OPC_ABSQ_S_PH_DSP
,
602 OPC_PRECEQ_W_PHL
= (0x0C << 6) | OPC_ABSQ_S_PH_DSP
,
603 OPC_PRECEQ_W_PHR
= (0x0D << 6) | OPC_ABSQ_S_PH_DSP
,
604 OPC_PRECEQU_PH_QBL
= (0x04 << 6) | OPC_ABSQ_S_PH_DSP
,
605 OPC_PRECEQU_PH_QBR
= (0x05 << 6) | OPC_ABSQ_S_PH_DSP
,
606 OPC_PRECEQU_PH_QBLA
= (0x06 << 6) | OPC_ABSQ_S_PH_DSP
,
607 OPC_PRECEQU_PH_QBRA
= (0x07 << 6) | OPC_ABSQ_S_PH_DSP
,
608 OPC_PRECEU_PH_QBL
= (0x1C << 6) | OPC_ABSQ_S_PH_DSP
,
609 OPC_PRECEU_PH_QBR
= (0x1D << 6) | OPC_ABSQ_S_PH_DSP
,
610 OPC_PRECEU_PH_QBLA
= (0x1E << 6) | OPC_ABSQ_S_PH_DSP
,
611 OPC_PRECEU_PH_QBRA
= (0x1F << 6) | OPC_ABSQ_S_PH_DSP
,
612 /* DSP Bit/Manipulation Sub-class */
613 OPC_BITREV
= (0x1B << 6) | OPC_ABSQ_S_PH_DSP
,
614 OPC_REPL_QB
= (0x02 << 6) | OPC_ABSQ_S_PH_DSP
,
615 OPC_REPLV_QB
= (0x03 << 6) | OPC_ABSQ_S_PH_DSP
,
616 OPC_REPL_PH
= (0x0A << 6) | OPC_ABSQ_S_PH_DSP
,
617 OPC_REPLV_PH
= (0x0B << 6) | OPC_ABSQ_S_PH_DSP
,
620 #define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
622 /* MIPS DSP Arithmetic Sub-class */
623 OPC_PRECR_QB_PH
= (0x0D << 6) | OPC_CMPU_EQ_QB_DSP
,
624 OPC_PRECRQ_QB_PH
= (0x0C << 6) | OPC_CMPU_EQ_QB_DSP
,
625 OPC_PRECR_SRA_PH_W
= (0x1E << 6) | OPC_CMPU_EQ_QB_DSP
,
626 OPC_PRECR_SRA_R_PH_W
= (0x1F << 6) | OPC_CMPU_EQ_QB_DSP
,
627 OPC_PRECRQ_PH_W
= (0x14 << 6) | OPC_CMPU_EQ_QB_DSP
,
628 OPC_PRECRQ_RS_PH_W
= (0x15 << 6) | OPC_CMPU_EQ_QB_DSP
,
629 OPC_PRECRQU_S_QB_PH
= (0x0F << 6) | OPC_CMPU_EQ_QB_DSP
,
630 /* DSP Compare-Pick Sub-class */
631 OPC_CMPU_EQ_QB
= (0x00 << 6) | OPC_CMPU_EQ_QB_DSP
,
632 OPC_CMPU_LT_QB
= (0x01 << 6) | OPC_CMPU_EQ_QB_DSP
,
633 OPC_CMPU_LE_QB
= (0x02 << 6) | OPC_CMPU_EQ_QB_DSP
,
634 OPC_CMPGU_EQ_QB
= (0x04 << 6) | OPC_CMPU_EQ_QB_DSP
,
635 OPC_CMPGU_LT_QB
= (0x05 << 6) | OPC_CMPU_EQ_QB_DSP
,
636 OPC_CMPGU_LE_QB
= (0x06 << 6) | OPC_CMPU_EQ_QB_DSP
,
637 OPC_CMPGDU_EQ_QB
= (0x18 << 6) | OPC_CMPU_EQ_QB_DSP
,
638 OPC_CMPGDU_LT_QB
= (0x19 << 6) | OPC_CMPU_EQ_QB_DSP
,
639 OPC_CMPGDU_LE_QB
= (0x1A << 6) | OPC_CMPU_EQ_QB_DSP
,
640 OPC_CMP_EQ_PH
= (0x08 << 6) | OPC_CMPU_EQ_QB_DSP
,
641 OPC_CMP_LT_PH
= (0x09 << 6) | OPC_CMPU_EQ_QB_DSP
,
642 OPC_CMP_LE_PH
= (0x0A << 6) | OPC_CMPU_EQ_QB_DSP
,
643 OPC_PICK_QB
= (0x03 << 6) | OPC_CMPU_EQ_QB_DSP
,
644 OPC_PICK_PH
= (0x0B << 6) | OPC_CMPU_EQ_QB_DSP
,
645 OPC_PACKRL_PH
= (0x0E << 6) | OPC_CMPU_EQ_QB_DSP
,
648 #define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
650 /* MIPS DSP GPR-Based Shift Sub-class */
651 OPC_SHLL_QB
= (0x00 << 6) | OPC_SHLL_QB_DSP
,
652 OPC_SHLLV_QB
= (0x02 << 6) | OPC_SHLL_QB_DSP
,
653 OPC_SHLL_PH
= (0x08 << 6) | OPC_SHLL_QB_DSP
,
654 OPC_SHLLV_PH
= (0x0A << 6) | OPC_SHLL_QB_DSP
,
655 OPC_SHLL_S_PH
= (0x0C << 6) | OPC_SHLL_QB_DSP
,
656 OPC_SHLLV_S_PH
= (0x0E << 6) | OPC_SHLL_QB_DSP
,
657 OPC_SHLL_S_W
= (0x14 << 6) | OPC_SHLL_QB_DSP
,
658 OPC_SHLLV_S_W
= (0x16 << 6) | OPC_SHLL_QB_DSP
,
659 OPC_SHRL_QB
= (0x01 << 6) | OPC_SHLL_QB_DSP
,
660 OPC_SHRLV_QB
= (0x03 << 6) | OPC_SHLL_QB_DSP
,
661 OPC_SHRL_PH
= (0x19 << 6) | OPC_SHLL_QB_DSP
,
662 OPC_SHRLV_PH
= (0x1B << 6) | OPC_SHLL_QB_DSP
,
663 OPC_SHRA_QB
= (0x04 << 6) | OPC_SHLL_QB_DSP
,
664 OPC_SHRA_R_QB
= (0x05 << 6) | OPC_SHLL_QB_DSP
,
665 OPC_SHRAV_QB
= (0x06 << 6) | OPC_SHLL_QB_DSP
,
666 OPC_SHRAV_R_QB
= (0x07 << 6) | OPC_SHLL_QB_DSP
,
667 OPC_SHRA_PH
= (0x09 << 6) | OPC_SHLL_QB_DSP
,
668 OPC_SHRAV_PH
= (0x0B << 6) | OPC_SHLL_QB_DSP
,
669 OPC_SHRA_R_PH
= (0x0D << 6) | OPC_SHLL_QB_DSP
,
670 OPC_SHRAV_R_PH
= (0x0F << 6) | OPC_SHLL_QB_DSP
,
671 OPC_SHRA_R_W
= (0x15 << 6) | OPC_SHLL_QB_DSP
,
672 OPC_SHRAV_R_W
= (0x17 << 6) | OPC_SHLL_QB_DSP
,
675 #define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
677 /* MIPS DSP Multiply Sub-class insns */
678 OPC_DPAU_H_QBL
= (0x03 << 6) | OPC_DPA_W_PH_DSP
,
679 OPC_DPAU_H_QBR
= (0x07 << 6) | OPC_DPA_W_PH_DSP
,
680 OPC_DPSU_H_QBL
= (0x0B << 6) | OPC_DPA_W_PH_DSP
,
681 OPC_DPSU_H_QBR
= (0x0F << 6) | OPC_DPA_W_PH_DSP
,
682 OPC_DPA_W_PH
= (0x00 << 6) | OPC_DPA_W_PH_DSP
,
683 OPC_DPAX_W_PH
= (0x08 << 6) | OPC_DPA_W_PH_DSP
,
684 OPC_DPAQ_S_W_PH
= (0x04 << 6) | OPC_DPA_W_PH_DSP
,
685 OPC_DPAQX_S_W_PH
= (0x18 << 6) | OPC_DPA_W_PH_DSP
,
686 OPC_DPAQX_SA_W_PH
= (0x1A << 6) | OPC_DPA_W_PH_DSP
,
687 OPC_DPS_W_PH
= (0x01 << 6) | OPC_DPA_W_PH_DSP
,
688 OPC_DPSX_W_PH
= (0x09 << 6) | OPC_DPA_W_PH_DSP
,
689 OPC_DPSQ_S_W_PH
= (0x05 << 6) | OPC_DPA_W_PH_DSP
,
690 OPC_DPSQX_S_W_PH
= (0x19 << 6) | OPC_DPA_W_PH_DSP
,
691 OPC_DPSQX_SA_W_PH
= (0x1B << 6) | OPC_DPA_W_PH_DSP
,
692 OPC_MULSAQ_S_W_PH
= (0x06 << 6) | OPC_DPA_W_PH_DSP
,
693 OPC_DPAQ_SA_L_W
= (0x0C << 6) | OPC_DPA_W_PH_DSP
,
694 OPC_DPSQ_SA_L_W
= (0x0D << 6) | OPC_DPA_W_PH_DSP
,
695 OPC_MAQ_S_W_PHL
= (0x14 << 6) | OPC_DPA_W_PH_DSP
,
696 OPC_MAQ_S_W_PHR
= (0x16 << 6) | OPC_DPA_W_PH_DSP
,
697 OPC_MAQ_SA_W_PHL
= (0x10 << 6) | OPC_DPA_W_PH_DSP
,
698 OPC_MAQ_SA_W_PHR
= (0x12 << 6) | OPC_DPA_W_PH_DSP
,
699 OPC_MULSA_W_PH
= (0x02 << 6) | OPC_DPA_W_PH_DSP
,
702 #define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
704 /* DSP Bit/Manipulation Sub-class */
705 OPC_INSV
= (0x00 << 6) | OPC_INSV_DSP
,
708 #define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
710 /* MIPS DSP Append Sub-class */
711 OPC_APPEND
= (0x00 << 6) | OPC_APPEND_DSP
,
712 OPC_PREPEND
= (0x01 << 6) | OPC_APPEND_DSP
,
713 OPC_BALIGN
= (0x10 << 6) | OPC_APPEND_DSP
,
716 #define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
718 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
719 OPC_EXTR_W
= (0x00 << 6) | OPC_EXTR_W_DSP
,
720 OPC_EXTR_R_W
= (0x04 << 6) | OPC_EXTR_W_DSP
,
721 OPC_EXTR_RS_W
= (0x06 << 6) | OPC_EXTR_W_DSP
,
722 OPC_EXTR_S_H
= (0x0E << 6) | OPC_EXTR_W_DSP
,
723 OPC_EXTRV_S_H
= (0x0F << 6) | OPC_EXTR_W_DSP
,
724 OPC_EXTRV_W
= (0x01 << 6) | OPC_EXTR_W_DSP
,
725 OPC_EXTRV_R_W
= (0x05 << 6) | OPC_EXTR_W_DSP
,
726 OPC_EXTRV_RS_W
= (0x07 << 6) | OPC_EXTR_W_DSP
,
727 OPC_EXTP
= (0x02 << 6) | OPC_EXTR_W_DSP
,
728 OPC_EXTPV
= (0x03 << 6) | OPC_EXTR_W_DSP
,
729 OPC_EXTPDP
= (0x0A << 6) | OPC_EXTR_W_DSP
,
730 OPC_EXTPDPV
= (0x0B << 6) | OPC_EXTR_W_DSP
,
731 OPC_SHILO
= (0x1A << 6) | OPC_EXTR_W_DSP
,
732 OPC_SHILOV
= (0x1B << 6) | OPC_EXTR_W_DSP
,
733 OPC_MTHLIP
= (0x1F << 6) | OPC_EXTR_W_DSP
,
734 OPC_WRDSP
= (0x13 << 6) | OPC_EXTR_W_DSP
,
735 OPC_RDDSP
= (0x12 << 6) | OPC_EXTR_W_DSP
,
738 #define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
740 /* MIPS DSP Arithmetic Sub-class */
741 OPC_PRECEQ_L_PWL
= (0x14 << 6) | OPC_ABSQ_S_QH_DSP
,
742 OPC_PRECEQ_L_PWR
= (0x15 << 6) | OPC_ABSQ_S_QH_DSP
,
743 OPC_PRECEQ_PW_QHL
= (0x0C << 6) | OPC_ABSQ_S_QH_DSP
,
744 OPC_PRECEQ_PW_QHR
= (0x0D << 6) | OPC_ABSQ_S_QH_DSP
,
745 OPC_PRECEQ_PW_QHLA
= (0x0E << 6) | OPC_ABSQ_S_QH_DSP
,
746 OPC_PRECEQ_PW_QHRA
= (0x0F << 6) | OPC_ABSQ_S_QH_DSP
,
747 OPC_PRECEQU_QH_OBL
= (0x04 << 6) | OPC_ABSQ_S_QH_DSP
,
748 OPC_PRECEQU_QH_OBR
= (0x05 << 6) | OPC_ABSQ_S_QH_DSP
,
749 OPC_PRECEQU_QH_OBLA
= (0x06 << 6) | OPC_ABSQ_S_QH_DSP
,
750 OPC_PRECEQU_QH_OBRA
= (0x07 << 6) | OPC_ABSQ_S_QH_DSP
,
751 OPC_PRECEU_QH_OBL
= (0x1C << 6) | OPC_ABSQ_S_QH_DSP
,
752 OPC_PRECEU_QH_OBR
= (0x1D << 6) | OPC_ABSQ_S_QH_DSP
,
753 OPC_PRECEU_QH_OBLA
= (0x1E << 6) | OPC_ABSQ_S_QH_DSP
,
754 OPC_PRECEU_QH_OBRA
= (0x1F << 6) | OPC_ABSQ_S_QH_DSP
,
755 OPC_ABSQ_S_OB
= (0x01 << 6) | OPC_ABSQ_S_QH_DSP
,
756 OPC_ABSQ_S_PW
= (0x11 << 6) | OPC_ABSQ_S_QH_DSP
,
757 OPC_ABSQ_S_QH
= (0x09 << 6) | OPC_ABSQ_S_QH_DSP
,
758 /* DSP Bit/Manipulation Sub-class */
759 OPC_REPL_OB
= (0x02 << 6) | OPC_ABSQ_S_QH_DSP
,
760 OPC_REPL_PW
= (0x12 << 6) | OPC_ABSQ_S_QH_DSP
,
761 OPC_REPL_QH
= (0x0A << 6) | OPC_ABSQ_S_QH_DSP
,
762 OPC_REPLV_OB
= (0x03 << 6) | OPC_ABSQ_S_QH_DSP
,
763 OPC_REPLV_PW
= (0x13 << 6) | OPC_ABSQ_S_QH_DSP
,
764 OPC_REPLV_QH
= (0x0B << 6) | OPC_ABSQ_S_QH_DSP
,
767 #define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
769 /* MIPS DSP Multiply Sub-class insns */
770 OPC_MULEQ_S_PW_QHL
= (0x1C << 6) | OPC_ADDU_OB_DSP
,
771 OPC_MULEQ_S_PW_QHR
= (0x1D << 6) | OPC_ADDU_OB_DSP
,
772 OPC_MULEU_S_QH_OBL
= (0x06 << 6) | OPC_ADDU_OB_DSP
,
773 OPC_MULEU_S_QH_OBR
= (0x07 << 6) | OPC_ADDU_OB_DSP
,
774 OPC_MULQ_RS_QH
= (0x1F << 6) | OPC_ADDU_OB_DSP
,
775 /* MIPS DSP Arithmetic Sub-class */
776 OPC_RADDU_L_OB
= (0x14 << 6) | OPC_ADDU_OB_DSP
,
777 OPC_SUBQ_PW
= (0x13 << 6) | OPC_ADDU_OB_DSP
,
778 OPC_SUBQ_S_PW
= (0x17 << 6) | OPC_ADDU_OB_DSP
,
779 OPC_SUBQ_QH
= (0x0B << 6) | OPC_ADDU_OB_DSP
,
780 OPC_SUBQ_S_QH
= (0x0F << 6) | OPC_ADDU_OB_DSP
,
781 OPC_SUBU_OB
= (0x01 << 6) | OPC_ADDU_OB_DSP
,
782 OPC_SUBU_S_OB
= (0x05 << 6) | OPC_ADDU_OB_DSP
,
783 OPC_SUBU_QH
= (0x09 << 6) | OPC_ADDU_OB_DSP
,
784 OPC_SUBU_S_QH
= (0x0D << 6) | OPC_ADDU_OB_DSP
,
785 OPC_SUBUH_OB
= (0x19 << 6) | OPC_ADDU_OB_DSP
,
786 OPC_SUBUH_R_OB
= (0x1B << 6) | OPC_ADDU_OB_DSP
,
787 OPC_ADDQ_PW
= (0x12 << 6) | OPC_ADDU_OB_DSP
,
788 OPC_ADDQ_S_PW
= (0x16 << 6) | OPC_ADDU_OB_DSP
,
789 OPC_ADDQ_QH
= (0x0A << 6) | OPC_ADDU_OB_DSP
,
790 OPC_ADDQ_S_QH
= (0x0E << 6) | OPC_ADDU_OB_DSP
,
791 OPC_ADDU_OB
= (0x00 << 6) | OPC_ADDU_OB_DSP
,
792 OPC_ADDU_S_OB
= (0x04 << 6) | OPC_ADDU_OB_DSP
,
793 OPC_ADDU_QH
= (0x08 << 6) | OPC_ADDU_OB_DSP
,
794 OPC_ADDU_S_QH
= (0x0C << 6) | OPC_ADDU_OB_DSP
,
795 OPC_ADDUH_OB
= (0x18 << 6) | OPC_ADDU_OB_DSP
,
796 OPC_ADDUH_R_OB
= (0x1A << 6) | OPC_ADDU_OB_DSP
,
799 #define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
801 /* DSP Compare-Pick Sub-class */
802 OPC_CMP_EQ_PW
= (0x10 << 6) | OPC_CMPU_EQ_OB_DSP
,
803 OPC_CMP_LT_PW
= (0x11 << 6) | OPC_CMPU_EQ_OB_DSP
,
804 OPC_CMP_LE_PW
= (0x12 << 6) | OPC_CMPU_EQ_OB_DSP
,
805 OPC_CMP_EQ_QH
= (0x08 << 6) | OPC_CMPU_EQ_OB_DSP
,
806 OPC_CMP_LT_QH
= (0x09 << 6) | OPC_CMPU_EQ_OB_DSP
,
807 OPC_CMP_LE_QH
= (0x0A << 6) | OPC_CMPU_EQ_OB_DSP
,
808 OPC_CMPGDU_EQ_OB
= (0x18 << 6) | OPC_CMPU_EQ_OB_DSP
,
809 OPC_CMPGDU_LT_OB
= (0x19 << 6) | OPC_CMPU_EQ_OB_DSP
,
810 OPC_CMPGDU_LE_OB
= (0x1A << 6) | OPC_CMPU_EQ_OB_DSP
,
811 OPC_CMPGU_EQ_OB
= (0x04 << 6) | OPC_CMPU_EQ_OB_DSP
,
812 OPC_CMPGU_LT_OB
= (0x05 << 6) | OPC_CMPU_EQ_OB_DSP
,
813 OPC_CMPGU_LE_OB
= (0x06 << 6) | OPC_CMPU_EQ_OB_DSP
,
814 OPC_CMPU_EQ_OB
= (0x00 << 6) | OPC_CMPU_EQ_OB_DSP
,
815 OPC_CMPU_LT_OB
= (0x01 << 6) | OPC_CMPU_EQ_OB_DSP
,
816 OPC_CMPU_LE_OB
= (0x02 << 6) | OPC_CMPU_EQ_OB_DSP
,
817 OPC_PACKRL_PW
= (0x0E << 6) | OPC_CMPU_EQ_OB_DSP
,
818 OPC_PICK_OB
= (0x03 << 6) | OPC_CMPU_EQ_OB_DSP
,
819 OPC_PICK_PW
= (0x13 << 6) | OPC_CMPU_EQ_OB_DSP
,
820 OPC_PICK_QH
= (0x0B << 6) | OPC_CMPU_EQ_OB_DSP
,
821 /* MIPS DSP Arithmetic Sub-class */
822 OPC_PRECR_OB_QH
= (0x0D << 6) | OPC_CMPU_EQ_OB_DSP
,
823 OPC_PRECR_SRA_QH_PW
= (0x1E << 6) | OPC_CMPU_EQ_OB_DSP
,
824 OPC_PRECR_SRA_R_QH_PW
= (0x1F << 6) | OPC_CMPU_EQ_OB_DSP
,
825 OPC_PRECRQ_OB_QH
= (0x0C << 6) | OPC_CMPU_EQ_OB_DSP
,
826 OPC_PRECRQ_PW_L
= (0x1C << 6) | OPC_CMPU_EQ_OB_DSP
,
827 OPC_PRECRQ_QH_PW
= (0x14 << 6) | OPC_CMPU_EQ_OB_DSP
,
828 OPC_PRECRQ_RS_QH_PW
= (0x15 << 6) | OPC_CMPU_EQ_OB_DSP
,
829 OPC_PRECRQU_S_OB_QH
= (0x0F << 6) | OPC_CMPU_EQ_OB_DSP
,
832 #define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
834 /* DSP Append Sub-class */
835 OPC_DAPPEND
= (0x00 << 6) | OPC_DAPPEND_DSP
,
836 OPC_PREPENDD
= (0x03 << 6) | OPC_DAPPEND_DSP
,
837 OPC_PREPENDW
= (0x01 << 6) | OPC_DAPPEND_DSP
,
838 OPC_DBALIGN
= (0x10 << 6) | OPC_DAPPEND_DSP
,
841 #define MASK_DEXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
843 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
844 OPC_DMTHLIP
= (0x1F << 6) | OPC_DEXTR_W_DSP
,
845 OPC_DSHILO
= (0x1A << 6) | OPC_DEXTR_W_DSP
,
846 OPC_DEXTP
= (0x02 << 6) | OPC_DEXTR_W_DSP
,
847 OPC_DEXTPDP
= (0x0A << 6) | OPC_DEXTR_W_DSP
,
848 OPC_DEXTPDPV
= (0x0B << 6) | OPC_DEXTR_W_DSP
,
849 OPC_DEXTPV
= (0x03 << 6) | OPC_DEXTR_W_DSP
,
850 OPC_DEXTR_L
= (0x10 << 6) | OPC_DEXTR_W_DSP
,
851 OPC_DEXTR_R_L
= (0x14 << 6) | OPC_DEXTR_W_DSP
,
852 OPC_DEXTR_RS_L
= (0x16 << 6) | OPC_DEXTR_W_DSP
,
853 OPC_DEXTR_W
= (0x00 << 6) | OPC_DEXTR_W_DSP
,
854 OPC_DEXTR_R_W
= (0x04 << 6) | OPC_DEXTR_W_DSP
,
855 OPC_DEXTR_RS_W
= (0x06 << 6) | OPC_DEXTR_W_DSP
,
856 OPC_DEXTR_S_H
= (0x0E << 6) | OPC_DEXTR_W_DSP
,
857 OPC_DEXTRV_L
= (0x11 << 6) | OPC_DEXTR_W_DSP
,
858 OPC_DEXTRV_R_L
= (0x15 << 6) | OPC_DEXTR_W_DSP
,
859 OPC_DEXTRV_RS_L
= (0x17 << 6) | OPC_DEXTR_W_DSP
,
860 OPC_DEXTRV_S_H
= (0x0F << 6) | OPC_DEXTR_W_DSP
,
861 OPC_DEXTRV_W
= (0x01 << 6) | OPC_DEXTR_W_DSP
,
862 OPC_DEXTRV_R_W
= (0x05 << 6) | OPC_DEXTR_W_DSP
,
863 OPC_DEXTRV_RS_W
= (0x07 << 6) | OPC_DEXTR_W_DSP
,
864 OPC_DSHILOV
= (0x1B << 6) | OPC_DEXTR_W_DSP
,
867 #define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
869 /* DSP Bit/Manipulation Sub-class */
870 OPC_DINSV
= (0x00 << 6) | OPC_DINSV_DSP
,
873 #define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
875 /* MIPS DSP Multiply Sub-class insns */
876 OPC_DMADD
= (0x19 << 6) | OPC_DPAQ_W_QH_DSP
,
877 OPC_DMADDU
= (0x1D << 6) | OPC_DPAQ_W_QH_DSP
,
878 OPC_DMSUB
= (0x1B << 6) | OPC_DPAQ_W_QH_DSP
,
879 OPC_DMSUBU
= (0x1F << 6) | OPC_DPAQ_W_QH_DSP
,
880 OPC_DPA_W_QH
= (0x00 << 6) | OPC_DPAQ_W_QH_DSP
,
881 OPC_DPAQ_S_W_QH
= (0x04 << 6) | OPC_DPAQ_W_QH_DSP
,
882 OPC_DPAQ_SA_L_PW
= (0x0C << 6) | OPC_DPAQ_W_QH_DSP
,
883 OPC_DPAU_H_OBL
= (0x03 << 6) | OPC_DPAQ_W_QH_DSP
,
884 OPC_DPAU_H_OBR
= (0x07 << 6) | OPC_DPAQ_W_QH_DSP
,
885 OPC_DPS_W_QH
= (0x01 << 6) | OPC_DPAQ_W_QH_DSP
,
886 OPC_DPSQ_S_W_QH
= (0x05 << 6) | OPC_DPAQ_W_QH_DSP
,
887 OPC_DPSQ_SA_L_PW
= (0x0D << 6) | OPC_DPAQ_W_QH_DSP
,
888 OPC_DPSU_H_OBL
= (0x0B << 6) | OPC_DPAQ_W_QH_DSP
,
889 OPC_DPSU_H_OBR
= (0x0F << 6) | OPC_DPAQ_W_QH_DSP
,
890 OPC_MAQ_S_L_PWL
= (0x1C << 6) | OPC_DPAQ_W_QH_DSP
,
891 OPC_MAQ_S_L_PWR
= (0x1E << 6) | OPC_DPAQ_W_QH_DSP
,
892 OPC_MAQ_S_W_QHLL
= (0x14 << 6) | OPC_DPAQ_W_QH_DSP
,
893 OPC_MAQ_SA_W_QHLL
= (0x10 << 6) | OPC_DPAQ_W_QH_DSP
,
894 OPC_MAQ_S_W_QHLR
= (0x15 << 6) | OPC_DPAQ_W_QH_DSP
,
895 OPC_MAQ_SA_W_QHLR
= (0x11 << 6) | OPC_DPAQ_W_QH_DSP
,
896 OPC_MAQ_S_W_QHRL
= (0x16 << 6) | OPC_DPAQ_W_QH_DSP
,
897 OPC_MAQ_SA_W_QHRL
= (0x12 << 6) | OPC_DPAQ_W_QH_DSP
,
898 OPC_MAQ_S_W_QHRR
= (0x17 << 6) | OPC_DPAQ_W_QH_DSP
,
899 OPC_MAQ_SA_W_QHRR
= (0x13 << 6) | OPC_DPAQ_W_QH_DSP
,
900 OPC_MULSAQ_S_L_PW
= (0x0E << 6) | OPC_DPAQ_W_QH_DSP
,
901 OPC_MULSAQ_S_W_QH
= (0x06 << 6) | OPC_DPAQ_W_QH_DSP
,
904 #define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
906 /* MIPS DSP GPR-Based Shift Sub-class */
907 OPC_SHLL_PW
= (0x10 << 6) | OPC_SHLL_OB_DSP
,
908 OPC_SHLL_S_PW
= (0x14 << 6) | OPC_SHLL_OB_DSP
,
909 OPC_SHLLV_OB
= (0x02 << 6) | OPC_SHLL_OB_DSP
,
910 OPC_SHLLV_PW
= (0x12 << 6) | OPC_SHLL_OB_DSP
,
911 OPC_SHLLV_S_PW
= (0x16 << 6) | OPC_SHLL_OB_DSP
,
912 OPC_SHLLV_QH
= (0x0A << 6) | OPC_SHLL_OB_DSP
,
913 OPC_SHLLV_S_QH
= (0x0E << 6) | OPC_SHLL_OB_DSP
,
914 OPC_SHRA_PW
= (0x11 << 6) | OPC_SHLL_OB_DSP
,
915 OPC_SHRA_R_PW
= (0x15 << 6) | OPC_SHLL_OB_DSP
,
916 OPC_SHRAV_OB
= (0x06 << 6) | OPC_SHLL_OB_DSP
,
917 OPC_SHRAV_R_OB
= (0x07 << 6) | OPC_SHLL_OB_DSP
,
918 OPC_SHRAV_PW
= (0x13 << 6) | OPC_SHLL_OB_DSP
,
919 OPC_SHRAV_R_PW
= (0x17 << 6) | OPC_SHLL_OB_DSP
,
920 OPC_SHRAV_QH
= (0x0B << 6) | OPC_SHLL_OB_DSP
,
921 OPC_SHRAV_R_QH
= (0x0F << 6) | OPC_SHLL_OB_DSP
,
922 OPC_SHRLV_OB
= (0x03 << 6) | OPC_SHLL_OB_DSP
,
923 OPC_SHRLV_QH
= (0x1B << 6) | OPC_SHLL_OB_DSP
,
924 OPC_SHLL_OB
= (0x00 << 6) | OPC_SHLL_OB_DSP
,
925 OPC_SHLL_QH
= (0x08 << 6) | OPC_SHLL_OB_DSP
,
926 OPC_SHLL_S_QH
= (0x0C << 6) | OPC_SHLL_OB_DSP
,
927 OPC_SHRA_OB
= (0x04 << 6) | OPC_SHLL_OB_DSP
,
928 OPC_SHRA_R_OB
= (0x05 << 6) | OPC_SHLL_OB_DSP
,
929 OPC_SHRA_QH
= (0x09 << 6) | OPC_SHLL_OB_DSP
,
930 OPC_SHRA_R_QH
= (0x0D << 6) | OPC_SHLL_OB_DSP
,
931 OPC_SHRL_OB
= (0x01 << 6) | OPC_SHLL_OB_DSP
,
932 OPC_SHRL_QH
= (0x19 << 6) | OPC_SHLL_OB_DSP
,
935 /* Coprocessor 0 (rs field) */
936 #define MASK_CP0(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)))
939 OPC_MFC0
= (0x00 << 21) | OPC_CP0
,
940 OPC_DMFC0
= (0x01 << 21) | OPC_CP0
,
941 OPC_MFHC0
= (0x02 << 21) | OPC_CP0
,
942 OPC_MTC0
= (0x04 << 21) | OPC_CP0
,
943 OPC_DMTC0
= (0x05 << 21) | OPC_CP0
,
944 OPC_MTHC0
= (0x06 << 21) | OPC_CP0
,
945 OPC_MFTR
= (0x08 << 21) | OPC_CP0
,
946 OPC_RDPGPR
= (0x0A << 21) | OPC_CP0
,
947 OPC_MFMC0
= (0x0B << 21) | OPC_CP0
,
948 OPC_MTTR
= (0x0C << 21) | OPC_CP0
,
949 OPC_WRPGPR
= (0x0E << 21) | OPC_CP0
,
950 OPC_C0
= (0x10 << 21) | OPC_CP0
,
951 OPC_C0_1
= (0x11 << 21) | OPC_CP0
,
952 OPC_C0_2
= (0x12 << 21) | OPC_CP0
,
953 OPC_C0_3
= (0x13 << 21) | OPC_CP0
,
954 OPC_C0_4
= (0x14 << 21) | OPC_CP0
,
955 OPC_C0_5
= (0x15 << 21) | OPC_CP0
,
956 OPC_C0_6
= (0x16 << 21) | OPC_CP0
,
957 OPC_C0_7
= (0x17 << 21) | OPC_CP0
,
958 OPC_C0_8
= (0x18 << 21) | OPC_CP0
,
959 OPC_C0_9
= (0x19 << 21) | OPC_CP0
,
960 OPC_C0_A
= (0x1A << 21) | OPC_CP0
,
961 OPC_C0_B
= (0x1B << 21) | OPC_CP0
,
962 OPC_C0_C
= (0x1C << 21) | OPC_CP0
,
963 OPC_C0_D
= (0x1D << 21) | OPC_CP0
,
964 OPC_C0_E
= (0x1E << 21) | OPC_CP0
,
965 OPC_C0_F
= (0x1F << 21) | OPC_CP0
,
969 #define MASK_MFMC0(op) (MASK_CP0(op) | (op & 0xFFFF))
972 OPC_DMT
= 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0
,
973 OPC_EMT
= 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0
,
974 OPC_DVPE
= 0x01 | (0 << 5) | OPC_MFMC0
,
975 OPC_EVPE
= 0x01 | (1 << 5) | OPC_MFMC0
,
976 OPC_DI
= (0 << 5) | (0x0C << 11) | OPC_MFMC0
,
977 OPC_EI
= (1 << 5) | (0x0C << 11) | OPC_MFMC0
,
978 OPC_DVP
= 0x04 | (0 << 3) | (1 << 5) | (0 << 11) | OPC_MFMC0
,
979 OPC_EVP
= 0x04 | (0 << 3) | (0 << 5) | (0 << 11) | OPC_MFMC0
,
982 /* Coprocessor 0 (with rs == C0) */
983 #define MASK_C0(op) (MASK_CP0(op) | (op & 0x3F))
986 OPC_TLBR
= 0x01 | OPC_C0
,
987 OPC_TLBWI
= 0x02 | OPC_C0
,
988 OPC_TLBINV
= 0x03 | OPC_C0
,
989 OPC_TLBINVF
= 0x04 | OPC_C0
,
990 OPC_TLBWR
= 0x06 | OPC_C0
,
991 OPC_TLBP
= 0x08 | OPC_C0
,
992 OPC_RFE
= 0x10 | OPC_C0
,
993 OPC_ERET
= 0x18 | OPC_C0
,
994 OPC_DERET
= 0x1F | OPC_C0
,
995 OPC_WAIT
= 0x20 | OPC_C0
,
998 #define MASK_CP2(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)))
1001 OPC_MFC2
= (0x00 << 21) | OPC_CP2
,
1002 OPC_DMFC2
= (0x01 << 21) | OPC_CP2
,
1003 OPC_CFC2
= (0x02 << 21) | OPC_CP2
,
1004 OPC_MFHC2
= (0x03 << 21) | OPC_CP2
,
1005 OPC_MTC2
= (0x04 << 21) | OPC_CP2
,
1006 OPC_DMTC2
= (0x05 << 21) | OPC_CP2
,
1007 OPC_CTC2
= (0x06 << 21) | OPC_CP2
,
1008 OPC_MTHC2
= (0x07 << 21) | OPC_CP2
,
1009 OPC_BC2
= (0x08 << 21) | OPC_CP2
,
1010 OPC_BC2EQZ
= (0x09 << 21) | OPC_CP2
,
1011 OPC_BC2NEZ
= (0x0D << 21) | OPC_CP2
,
1014 #define MASK_LMMI(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
1017 OPC_PADDSH
= (24 << 21) | (0x00) | OPC_CP2
,
1018 OPC_PADDUSH
= (25 << 21) | (0x00) | OPC_CP2
,
1019 OPC_PADDH
= (26 << 21) | (0x00) | OPC_CP2
,
1020 OPC_PADDW
= (27 << 21) | (0x00) | OPC_CP2
,
1021 OPC_PADDSB
= (28 << 21) | (0x00) | OPC_CP2
,
1022 OPC_PADDUSB
= (29 << 21) | (0x00) | OPC_CP2
,
1023 OPC_PADDB
= (30 << 21) | (0x00) | OPC_CP2
,
1024 OPC_PADDD
= (31 << 21) | (0x00) | OPC_CP2
,
1026 OPC_PSUBSH
= (24 << 21) | (0x01) | OPC_CP2
,
1027 OPC_PSUBUSH
= (25 << 21) | (0x01) | OPC_CP2
,
1028 OPC_PSUBH
= (26 << 21) | (0x01) | OPC_CP2
,
1029 OPC_PSUBW
= (27 << 21) | (0x01) | OPC_CP2
,
1030 OPC_PSUBSB
= (28 << 21) | (0x01) | OPC_CP2
,
1031 OPC_PSUBUSB
= (29 << 21) | (0x01) | OPC_CP2
,
1032 OPC_PSUBB
= (30 << 21) | (0x01) | OPC_CP2
,
1033 OPC_PSUBD
= (31 << 21) | (0x01) | OPC_CP2
,
1035 OPC_PSHUFH
= (24 << 21) | (0x02) | OPC_CP2
,
1036 OPC_PACKSSWH
= (25 << 21) | (0x02) | OPC_CP2
,
1037 OPC_PACKSSHB
= (26 << 21) | (0x02) | OPC_CP2
,
1038 OPC_PACKUSHB
= (27 << 21) | (0x02) | OPC_CP2
,
1039 OPC_XOR_CP2
= (28 << 21) | (0x02) | OPC_CP2
,
1040 OPC_NOR_CP2
= (29 << 21) | (0x02) | OPC_CP2
,
1041 OPC_AND_CP2
= (30 << 21) | (0x02) | OPC_CP2
,
1042 OPC_PANDN
= (31 << 21) | (0x02) | OPC_CP2
,
1044 OPC_PUNPCKLHW
= (24 << 21) | (0x03) | OPC_CP2
,
1045 OPC_PUNPCKHHW
= (25 << 21) | (0x03) | OPC_CP2
,
1046 OPC_PUNPCKLBH
= (26 << 21) | (0x03) | OPC_CP2
,
1047 OPC_PUNPCKHBH
= (27 << 21) | (0x03) | OPC_CP2
,
1048 OPC_PINSRH_0
= (28 << 21) | (0x03) | OPC_CP2
,
1049 OPC_PINSRH_1
= (29 << 21) | (0x03) | OPC_CP2
,
1050 OPC_PINSRH_2
= (30 << 21) | (0x03) | OPC_CP2
,
1051 OPC_PINSRH_3
= (31 << 21) | (0x03) | OPC_CP2
,
1053 OPC_PAVGH
= (24 << 21) | (0x08) | OPC_CP2
,
1054 OPC_PAVGB
= (25 << 21) | (0x08) | OPC_CP2
,
1055 OPC_PMAXSH
= (26 << 21) | (0x08) | OPC_CP2
,
1056 OPC_PMINSH
= (27 << 21) | (0x08) | OPC_CP2
,
1057 OPC_PMAXUB
= (28 << 21) | (0x08) | OPC_CP2
,
1058 OPC_PMINUB
= (29 << 21) | (0x08) | OPC_CP2
,
1060 OPC_PCMPEQW
= (24 << 21) | (0x09) | OPC_CP2
,
1061 OPC_PCMPGTW
= (25 << 21) | (0x09) | OPC_CP2
,
1062 OPC_PCMPEQH
= (26 << 21) | (0x09) | OPC_CP2
,
1063 OPC_PCMPGTH
= (27 << 21) | (0x09) | OPC_CP2
,
1064 OPC_PCMPEQB
= (28 << 21) | (0x09) | OPC_CP2
,
1065 OPC_PCMPGTB
= (29 << 21) | (0x09) | OPC_CP2
,
1067 OPC_PSLLW
= (24 << 21) | (0x0A) | OPC_CP2
,
1068 OPC_PSLLH
= (25 << 21) | (0x0A) | OPC_CP2
,
1069 OPC_PMULLH
= (26 << 21) | (0x0A) | OPC_CP2
,
1070 OPC_PMULHH
= (27 << 21) | (0x0A) | OPC_CP2
,
1071 OPC_PMULUW
= (28 << 21) | (0x0A) | OPC_CP2
,
1072 OPC_PMULHUH
= (29 << 21) | (0x0A) | OPC_CP2
,
1074 OPC_PSRLW
= (24 << 21) | (0x0B) | OPC_CP2
,
1075 OPC_PSRLH
= (25 << 21) | (0x0B) | OPC_CP2
,
1076 OPC_PSRAW
= (26 << 21) | (0x0B) | OPC_CP2
,
1077 OPC_PSRAH
= (27 << 21) | (0x0B) | OPC_CP2
,
1078 OPC_PUNPCKLWD
= (28 << 21) | (0x0B) | OPC_CP2
,
1079 OPC_PUNPCKHWD
= (29 << 21) | (0x0B) | OPC_CP2
,
1081 OPC_ADDU_CP2
= (24 << 21) | (0x0C) | OPC_CP2
,
1082 OPC_OR_CP2
= (25 << 21) | (0x0C) | OPC_CP2
,
1083 OPC_ADD_CP2
= (26 << 21) | (0x0C) | OPC_CP2
,
1084 OPC_DADD_CP2
= (27 << 21) | (0x0C) | OPC_CP2
,
1085 OPC_SEQU_CP2
= (28 << 21) | (0x0C) | OPC_CP2
,
1086 OPC_SEQ_CP2
= (29 << 21) | (0x0C) | OPC_CP2
,
1088 OPC_SUBU_CP2
= (24 << 21) | (0x0D) | OPC_CP2
,
1089 OPC_PASUBUB
= (25 << 21) | (0x0D) | OPC_CP2
,
1090 OPC_SUB_CP2
= (26 << 21) | (0x0D) | OPC_CP2
,
1091 OPC_DSUB_CP2
= (27 << 21) | (0x0D) | OPC_CP2
,
1092 OPC_SLTU_CP2
= (28 << 21) | (0x0D) | OPC_CP2
,
1093 OPC_SLT_CP2
= (29 << 21) | (0x0D) | OPC_CP2
,
1095 OPC_SLL_CP2
= (24 << 21) | (0x0E) | OPC_CP2
,
1096 OPC_DSLL_CP2
= (25 << 21) | (0x0E) | OPC_CP2
,
1097 OPC_PEXTRH
= (26 << 21) | (0x0E) | OPC_CP2
,
1098 OPC_PMADDHW
= (27 << 21) | (0x0E) | OPC_CP2
,
1099 OPC_SLEU_CP2
= (28 << 21) | (0x0E) | OPC_CP2
,
1100 OPC_SLE_CP2
= (29 << 21) | (0x0E) | OPC_CP2
,
1102 OPC_SRL_CP2
= (24 << 21) | (0x0F) | OPC_CP2
,
1103 OPC_DSRL_CP2
= (25 << 21) | (0x0F) | OPC_CP2
,
1104 OPC_SRA_CP2
= (26 << 21) | (0x0F) | OPC_CP2
,
1105 OPC_DSRA_CP2
= (27 << 21) | (0x0F) | OPC_CP2
,
1106 OPC_BIADD
= (28 << 21) | (0x0F) | OPC_CP2
,
1107 OPC_PMOVMSKB
= (29 << 21) | (0x0F) | OPC_CP2
,
1111 #define MASK_CP3(op) (MASK_OP_MAJOR(op) | (op & 0x3F))
1114 OPC_LWXC1
= 0x00 | OPC_CP3
,
1115 OPC_LDXC1
= 0x01 | OPC_CP3
,
1116 OPC_LUXC1
= 0x05 | OPC_CP3
,
1117 OPC_SWXC1
= 0x08 | OPC_CP3
,
1118 OPC_SDXC1
= 0x09 | OPC_CP3
,
1119 OPC_SUXC1
= 0x0D | OPC_CP3
,
1120 OPC_PREFX
= 0x0F | OPC_CP3
,
1121 OPC_ALNV_PS
= 0x1E | OPC_CP3
,
1122 OPC_MADD_S
= 0x20 | OPC_CP3
,
1123 OPC_MADD_D
= 0x21 | OPC_CP3
,
1124 OPC_MADD_PS
= 0x26 | OPC_CP3
,
1125 OPC_MSUB_S
= 0x28 | OPC_CP3
,
1126 OPC_MSUB_D
= 0x29 | OPC_CP3
,
1127 OPC_MSUB_PS
= 0x2E | OPC_CP3
,
1128 OPC_NMADD_S
= 0x30 | OPC_CP3
,
1129 OPC_NMADD_D
= 0x31 | OPC_CP3
,
1130 OPC_NMADD_PS
= 0x36 | OPC_CP3
,
1131 OPC_NMSUB_S
= 0x38 | OPC_CP3
,
1132 OPC_NMSUB_D
= 0x39 | OPC_CP3
,
1133 OPC_NMSUB_PS
= 0x3E | OPC_CP3
,
1137 #define MASK_MSA_MINOR(op) (MASK_OP_MAJOR(op) | (op & 0x3F))
1139 OPC_MSA_I8_00
= 0x00 | OPC_MSA
,
1140 OPC_MSA_I8_01
= 0x01 | OPC_MSA
,
1141 OPC_MSA_I8_02
= 0x02 | OPC_MSA
,
1142 OPC_MSA_I5_06
= 0x06 | OPC_MSA
,
1143 OPC_MSA_I5_07
= 0x07 | OPC_MSA
,
1144 OPC_MSA_BIT_09
= 0x09 | OPC_MSA
,
1145 OPC_MSA_BIT_0A
= 0x0A | OPC_MSA
,
1146 OPC_MSA_3R_0D
= 0x0D | OPC_MSA
,
1147 OPC_MSA_3R_0E
= 0x0E | OPC_MSA
,
1148 OPC_MSA_3R_0F
= 0x0F | OPC_MSA
,
1149 OPC_MSA_3R_10
= 0x10 | OPC_MSA
,
1150 OPC_MSA_3R_11
= 0x11 | OPC_MSA
,
1151 OPC_MSA_3R_12
= 0x12 | OPC_MSA
,
1152 OPC_MSA_3R_13
= 0x13 | OPC_MSA
,
1153 OPC_MSA_3R_14
= 0x14 | OPC_MSA
,
1154 OPC_MSA_3R_15
= 0x15 | OPC_MSA
,
1155 OPC_MSA_ELM
= 0x19 | OPC_MSA
,
1156 OPC_MSA_3RF_1A
= 0x1A | OPC_MSA
,
1157 OPC_MSA_3RF_1B
= 0x1B | OPC_MSA
,
1158 OPC_MSA_3RF_1C
= 0x1C | OPC_MSA
,
1159 OPC_MSA_VEC
= 0x1E | OPC_MSA
,
1161 /* MI10 instruction */
1162 OPC_LD_B
= (0x20) | OPC_MSA
,
1163 OPC_LD_H
= (0x21) | OPC_MSA
,
1164 OPC_LD_W
= (0x22) | OPC_MSA
,
1165 OPC_LD_D
= (0x23) | OPC_MSA
,
1166 OPC_ST_B
= (0x24) | OPC_MSA
,
1167 OPC_ST_H
= (0x25) | OPC_MSA
,
1168 OPC_ST_W
= (0x26) | OPC_MSA
,
1169 OPC_ST_D
= (0x27) | OPC_MSA
,
1173 /* I5 instruction df(bits 22..21) = _b, _h, _w, _d */
1174 OPC_ADDVI_df
= (0x0 << 23) | OPC_MSA_I5_06
,
1175 OPC_CEQI_df
= (0x0 << 23) | OPC_MSA_I5_07
,
1176 OPC_SUBVI_df
= (0x1 << 23) | OPC_MSA_I5_06
,
1177 OPC_MAXI_S_df
= (0x2 << 23) | OPC_MSA_I5_06
,
1178 OPC_CLTI_S_df
= (0x2 << 23) | OPC_MSA_I5_07
,
1179 OPC_MAXI_U_df
= (0x3 << 23) | OPC_MSA_I5_06
,
1180 OPC_CLTI_U_df
= (0x3 << 23) | OPC_MSA_I5_07
,
1181 OPC_MINI_S_df
= (0x4 << 23) | OPC_MSA_I5_06
,
1182 OPC_CLEI_S_df
= (0x4 << 23) | OPC_MSA_I5_07
,
1183 OPC_MINI_U_df
= (0x5 << 23) | OPC_MSA_I5_06
,
1184 OPC_CLEI_U_df
= (0x5 << 23) | OPC_MSA_I5_07
,
1185 OPC_LDI_df
= (0x6 << 23) | OPC_MSA_I5_07
,
1187 /* I8 instruction */
1188 OPC_ANDI_B
= (0x0 << 24) | OPC_MSA_I8_00
,
1189 OPC_BMNZI_B
= (0x0 << 24) | OPC_MSA_I8_01
,
1190 OPC_SHF_B
= (0x0 << 24) | OPC_MSA_I8_02
,
1191 OPC_ORI_B
= (0x1 << 24) | OPC_MSA_I8_00
,
1192 OPC_BMZI_B
= (0x1 << 24) | OPC_MSA_I8_01
,
1193 OPC_SHF_H
= (0x1 << 24) | OPC_MSA_I8_02
,
1194 OPC_NORI_B
= (0x2 << 24) | OPC_MSA_I8_00
,
1195 OPC_BSELI_B
= (0x2 << 24) | OPC_MSA_I8_01
,
1196 OPC_SHF_W
= (0x2 << 24) | OPC_MSA_I8_02
,
1197 OPC_XORI_B
= (0x3 << 24) | OPC_MSA_I8_00
,
1199 /* VEC/2R/2RF instruction */
1200 OPC_AND_V
= (0x00 << 21) | OPC_MSA_VEC
,
1201 OPC_OR_V
= (0x01 << 21) | OPC_MSA_VEC
,
1202 OPC_NOR_V
= (0x02 << 21) | OPC_MSA_VEC
,
1203 OPC_XOR_V
= (0x03 << 21) | OPC_MSA_VEC
,
1204 OPC_BMNZ_V
= (0x04 << 21) | OPC_MSA_VEC
,
1205 OPC_BMZ_V
= (0x05 << 21) | OPC_MSA_VEC
,
1206 OPC_BSEL_V
= (0x06 << 21) | OPC_MSA_VEC
,
1208 OPC_MSA_2R
= (0x18 << 21) | OPC_MSA_VEC
,
1209 OPC_MSA_2RF
= (0x19 << 21) | OPC_MSA_VEC
,
1211 /* 2R instruction df(bits 17..16) = _b, _h, _w, _d */
1212 OPC_FILL_df
= (0x00 << 18) | OPC_MSA_2R
,
1213 OPC_PCNT_df
= (0x01 << 18) | OPC_MSA_2R
,
1214 OPC_NLOC_df
= (0x02 << 18) | OPC_MSA_2R
,
1215 OPC_NLZC_df
= (0x03 << 18) | OPC_MSA_2R
,
1217 /* 2RF instruction df(bit 16) = _w, _d */
1218 OPC_FCLASS_df
= (0x00 << 17) | OPC_MSA_2RF
,
1219 OPC_FTRUNC_S_df
= (0x01 << 17) | OPC_MSA_2RF
,
1220 OPC_FTRUNC_U_df
= (0x02 << 17) | OPC_MSA_2RF
,
1221 OPC_FSQRT_df
= (0x03 << 17) | OPC_MSA_2RF
,
1222 OPC_FRSQRT_df
= (0x04 << 17) | OPC_MSA_2RF
,
1223 OPC_FRCP_df
= (0x05 << 17) | OPC_MSA_2RF
,
1224 OPC_FRINT_df
= (0x06 << 17) | OPC_MSA_2RF
,
1225 OPC_FLOG2_df
= (0x07 << 17) | OPC_MSA_2RF
,
1226 OPC_FEXUPL_df
= (0x08 << 17) | OPC_MSA_2RF
,
1227 OPC_FEXUPR_df
= (0x09 << 17) | OPC_MSA_2RF
,
1228 OPC_FFQL_df
= (0x0A << 17) | OPC_MSA_2RF
,
1229 OPC_FFQR_df
= (0x0B << 17) | OPC_MSA_2RF
,
1230 OPC_FTINT_S_df
= (0x0C << 17) | OPC_MSA_2RF
,
1231 OPC_FTINT_U_df
= (0x0D << 17) | OPC_MSA_2RF
,
1232 OPC_FFINT_S_df
= (0x0E << 17) | OPC_MSA_2RF
,
1233 OPC_FFINT_U_df
= (0x0F << 17) | OPC_MSA_2RF
,
1235 /* 3R instruction df(bits 22..21) = _b, _h, _w, d */
1236 OPC_SLL_df
= (0x0 << 23) | OPC_MSA_3R_0D
,
1237 OPC_ADDV_df
= (0x0 << 23) | OPC_MSA_3R_0E
,
1238 OPC_CEQ_df
= (0x0 << 23) | OPC_MSA_3R_0F
,
1239 OPC_ADD_A_df
= (0x0 << 23) | OPC_MSA_3R_10
,
1240 OPC_SUBS_S_df
= (0x0 << 23) | OPC_MSA_3R_11
,
1241 OPC_MULV_df
= (0x0 << 23) | OPC_MSA_3R_12
,
1242 OPC_DOTP_S_df
= (0x0 << 23) | OPC_MSA_3R_13
,
1243 OPC_SLD_df
= (0x0 << 23) | OPC_MSA_3R_14
,
1244 OPC_VSHF_df
= (0x0 << 23) | OPC_MSA_3R_15
,
1245 OPC_SRA_df
= (0x1 << 23) | OPC_MSA_3R_0D
,
1246 OPC_SUBV_df
= (0x1 << 23) | OPC_MSA_3R_0E
,
1247 OPC_ADDS_A_df
= (0x1 << 23) | OPC_MSA_3R_10
,
1248 OPC_SUBS_U_df
= (0x1 << 23) | OPC_MSA_3R_11
,
1249 OPC_MADDV_df
= (0x1 << 23) | OPC_MSA_3R_12
,
1250 OPC_DOTP_U_df
= (0x1 << 23) | OPC_MSA_3R_13
,
1251 OPC_SPLAT_df
= (0x1 << 23) | OPC_MSA_3R_14
,
1252 OPC_SRAR_df
= (0x1 << 23) | OPC_MSA_3R_15
,
1253 OPC_SRL_df
= (0x2 << 23) | OPC_MSA_3R_0D
,
1254 OPC_MAX_S_df
= (0x2 << 23) | OPC_MSA_3R_0E
,
1255 OPC_CLT_S_df
= (0x2 << 23) | OPC_MSA_3R_0F
,
1256 OPC_ADDS_S_df
= (0x2 << 23) | OPC_MSA_3R_10
,
1257 OPC_SUBSUS_U_df
= (0x2 << 23) | OPC_MSA_3R_11
,
1258 OPC_MSUBV_df
= (0x2 << 23) | OPC_MSA_3R_12
,
1259 OPC_DPADD_S_df
= (0x2 << 23) | OPC_MSA_3R_13
,
1260 OPC_PCKEV_df
= (0x2 << 23) | OPC_MSA_3R_14
,
1261 OPC_SRLR_df
= (0x2 << 23) | OPC_MSA_3R_15
,
1262 OPC_BCLR_df
= (0x3 << 23) | OPC_MSA_3R_0D
,
1263 OPC_MAX_U_df
= (0x3 << 23) | OPC_MSA_3R_0E
,
1264 OPC_CLT_U_df
= (0x3 << 23) | OPC_MSA_3R_0F
,
1265 OPC_ADDS_U_df
= (0x3 << 23) | OPC_MSA_3R_10
,
1266 OPC_SUBSUU_S_df
= (0x3 << 23) | OPC_MSA_3R_11
,
1267 OPC_DPADD_U_df
= (0x3 << 23) | OPC_MSA_3R_13
,
1268 OPC_PCKOD_df
= (0x3 << 23) | OPC_MSA_3R_14
,
1269 OPC_BSET_df
= (0x4 << 23) | OPC_MSA_3R_0D
,
1270 OPC_MIN_S_df
= (0x4 << 23) | OPC_MSA_3R_0E
,
1271 OPC_CLE_S_df
= (0x4 << 23) | OPC_MSA_3R_0F
,
1272 OPC_AVE_S_df
= (0x4 << 23) | OPC_MSA_3R_10
,
1273 OPC_ASUB_S_df
= (0x4 << 23) | OPC_MSA_3R_11
,
1274 OPC_DIV_S_df
= (0x4 << 23) | OPC_MSA_3R_12
,
1275 OPC_DPSUB_S_df
= (0x4 << 23) | OPC_MSA_3R_13
,
1276 OPC_ILVL_df
= (0x4 << 23) | OPC_MSA_3R_14
,
1277 OPC_HADD_S_df
= (0x4 << 23) | OPC_MSA_3R_15
,
1278 OPC_BNEG_df
= (0x5 << 23) | OPC_MSA_3R_0D
,
1279 OPC_MIN_U_df
= (0x5 << 23) | OPC_MSA_3R_0E
,
1280 OPC_CLE_U_df
= (0x5 << 23) | OPC_MSA_3R_0F
,
1281 OPC_AVE_U_df
= (0x5 << 23) | OPC_MSA_3R_10
,
1282 OPC_ASUB_U_df
= (0x5 << 23) | OPC_MSA_3R_11
,
1283 OPC_DIV_U_df
= (0x5 << 23) | OPC_MSA_3R_12
,
1284 OPC_DPSUB_U_df
= (0x5 << 23) | OPC_MSA_3R_13
,
1285 OPC_ILVR_df
= (0x5 << 23) | OPC_MSA_3R_14
,
1286 OPC_HADD_U_df
= (0x5 << 23) | OPC_MSA_3R_15
,
1287 OPC_BINSL_df
= (0x6 << 23) | OPC_MSA_3R_0D
,
1288 OPC_MAX_A_df
= (0x6 << 23) | OPC_MSA_3R_0E
,
1289 OPC_AVER_S_df
= (0x6 << 23) | OPC_MSA_3R_10
,
1290 OPC_MOD_S_df
= (0x6 << 23) | OPC_MSA_3R_12
,
1291 OPC_ILVEV_df
= (0x6 << 23) | OPC_MSA_3R_14
,
1292 OPC_HSUB_S_df
= (0x6 << 23) | OPC_MSA_3R_15
,
1293 OPC_BINSR_df
= (0x7 << 23) | OPC_MSA_3R_0D
,
1294 OPC_MIN_A_df
= (0x7 << 23) | OPC_MSA_3R_0E
,
1295 OPC_AVER_U_df
= (0x7 << 23) | OPC_MSA_3R_10
,
1296 OPC_MOD_U_df
= (0x7 << 23) | OPC_MSA_3R_12
,
1297 OPC_ILVOD_df
= (0x7 << 23) | OPC_MSA_3R_14
,
1298 OPC_HSUB_U_df
= (0x7 << 23) | OPC_MSA_3R_15
,
1300 /* ELM instructions df(bits 21..16) = _b, _h, _w, _d */
1301 OPC_SLDI_df
= (0x0 << 22) | (0x00 << 16) | OPC_MSA_ELM
,
1302 OPC_CTCMSA
= (0x0 << 22) | (0x3E << 16) | OPC_MSA_ELM
,
1303 OPC_SPLATI_df
= (0x1 << 22) | (0x00 << 16) | OPC_MSA_ELM
,
1304 OPC_CFCMSA
= (0x1 << 22) | (0x3E << 16) | OPC_MSA_ELM
,
1305 OPC_COPY_S_df
= (0x2 << 22) | (0x00 << 16) | OPC_MSA_ELM
,
1306 OPC_MOVE_V
= (0x2 << 22) | (0x3E << 16) | OPC_MSA_ELM
,
1307 OPC_COPY_U_df
= (0x3 << 22) | (0x00 << 16) | OPC_MSA_ELM
,
1308 OPC_INSERT_df
= (0x4 << 22) | (0x00 << 16) | OPC_MSA_ELM
,
1309 OPC_INSVE_df
= (0x5 << 22) | (0x00 << 16) | OPC_MSA_ELM
,
1311 /* 3RF instruction _df(bit 21) = _w, _d */
1312 OPC_FCAF_df
= (0x0 << 22) | OPC_MSA_3RF_1A
,
1313 OPC_FADD_df
= (0x0 << 22) | OPC_MSA_3RF_1B
,
1314 OPC_FCUN_df
= (0x1 << 22) | OPC_MSA_3RF_1A
,
1315 OPC_FSUB_df
= (0x1 << 22) | OPC_MSA_3RF_1B
,
1316 OPC_FCOR_df
= (0x1 << 22) | OPC_MSA_3RF_1C
,
1317 OPC_FCEQ_df
= (0x2 << 22) | OPC_MSA_3RF_1A
,
1318 OPC_FMUL_df
= (0x2 << 22) | OPC_MSA_3RF_1B
,
1319 OPC_FCUNE_df
= (0x2 << 22) | OPC_MSA_3RF_1C
,
1320 OPC_FCUEQ_df
= (0x3 << 22) | OPC_MSA_3RF_1A
,
1321 OPC_FDIV_df
= (0x3 << 22) | OPC_MSA_3RF_1B
,
1322 OPC_FCNE_df
= (0x3 << 22) | OPC_MSA_3RF_1C
,
1323 OPC_FCLT_df
= (0x4 << 22) | OPC_MSA_3RF_1A
,
1324 OPC_FMADD_df
= (0x4 << 22) | OPC_MSA_3RF_1B
,
1325 OPC_MUL_Q_df
= (0x4 << 22) | OPC_MSA_3RF_1C
,
1326 OPC_FCULT_df
= (0x5 << 22) | OPC_MSA_3RF_1A
,
1327 OPC_FMSUB_df
= (0x5 << 22) | OPC_MSA_3RF_1B
,
1328 OPC_MADD_Q_df
= (0x5 << 22) | OPC_MSA_3RF_1C
,
1329 OPC_FCLE_df
= (0x6 << 22) | OPC_MSA_3RF_1A
,
1330 OPC_MSUB_Q_df
= (0x6 << 22) | OPC_MSA_3RF_1C
,
1331 OPC_FCULE_df
= (0x7 << 22) | OPC_MSA_3RF_1A
,
1332 OPC_FEXP2_df
= (0x7 << 22) | OPC_MSA_3RF_1B
,
1333 OPC_FSAF_df
= (0x8 << 22) | OPC_MSA_3RF_1A
,
1334 OPC_FEXDO_df
= (0x8 << 22) | OPC_MSA_3RF_1B
,
1335 OPC_FSUN_df
= (0x9 << 22) | OPC_MSA_3RF_1A
,
1336 OPC_FSOR_df
= (0x9 << 22) | OPC_MSA_3RF_1C
,
1337 OPC_FSEQ_df
= (0xA << 22) | OPC_MSA_3RF_1A
,
1338 OPC_FTQ_df
= (0xA << 22) | OPC_MSA_3RF_1B
,
1339 OPC_FSUNE_df
= (0xA << 22) | OPC_MSA_3RF_1C
,
1340 OPC_FSUEQ_df
= (0xB << 22) | OPC_MSA_3RF_1A
,
1341 OPC_FSNE_df
= (0xB << 22) | OPC_MSA_3RF_1C
,
1342 OPC_FSLT_df
= (0xC << 22) | OPC_MSA_3RF_1A
,
1343 OPC_FMIN_df
= (0xC << 22) | OPC_MSA_3RF_1B
,
1344 OPC_MULR_Q_df
= (0xC << 22) | OPC_MSA_3RF_1C
,
1345 OPC_FSULT_df
= (0xD << 22) | OPC_MSA_3RF_1A
,
1346 OPC_FMIN_A_df
= (0xD << 22) | OPC_MSA_3RF_1B
,
1347 OPC_MADDR_Q_df
= (0xD << 22) | OPC_MSA_3RF_1C
,
1348 OPC_FSLE_df
= (0xE << 22) | OPC_MSA_3RF_1A
,
1349 OPC_FMAX_df
= (0xE << 22) | OPC_MSA_3RF_1B
,
1350 OPC_MSUBR_Q_df
= (0xE << 22) | OPC_MSA_3RF_1C
,
1351 OPC_FSULE_df
= (0xF << 22) | OPC_MSA_3RF_1A
,
1352 OPC_FMAX_A_df
= (0xF << 22) | OPC_MSA_3RF_1B
,
1354 /* BIT instruction df(bits 22..16) = _B _H _W _D */
1355 OPC_SLLI_df
= (0x0 << 23) | OPC_MSA_BIT_09
,
1356 OPC_SAT_S_df
= (0x0 << 23) | OPC_MSA_BIT_0A
,
1357 OPC_SRAI_df
= (0x1 << 23) | OPC_MSA_BIT_09
,
1358 OPC_SAT_U_df
= (0x1 << 23) | OPC_MSA_BIT_0A
,
1359 OPC_SRLI_df
= (0x2 << 23) | OPC_MSA_BIT_09
,
1360 OPC_SRARI_df
= (0x2 << 23) | OPC_MSA_BIT_0A
,
1361 OPC_BCLRI_df
= (0x3 << 23) | OPC_MSA_BIT_09
,
1362 OPC_SRLRI_df
= (0x3 << 23) | OPC_MSA_BIT_0A
,
1363 OPC_BSETI_df
= (0x4 << 23) | OPC_MSA_BIT_09
,
1364 OPC_BNEGI_df
= (0x5 << 23) | OPC_MSA_BIT_09
,
1365 OPC_BINSLI_df
= (0x6 << 23) | OPC_MSA_BIT_09
,
1366 OPC_BINSRI_df
= (0x7 << 23) | OPC_MSA_BIT_09
,
1372 * AN OVERVIEW OF MXU EXTENSION INSTRUCTION SET
1373 * ============================================
1376 * MXU (full name: MIPS eXtension/enhanced Unit) is a SIMD extension of MIPS32
1377 * instructions set. It is designed to fit the needs of signal, graphical and
1378 * video processing applications. MXU instruction set is used in Xburst family
1379 * of microprocessors by Ingenic.
1381 * MXU unit contains 17 registers called X0-X16. X0 is always zero, and X16 is
1382 * the control register.
1385 * The notation used in MXU assembler mnemonics
1386 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1388 * Register operands:
1390 * XRa, XRb, XRc, XRd - MXU registers
1391 * Rb, Rc, Rd, Rs, Rt - general purpose MIPS registers
1393 * Non-register operands:
1395 * aptn1 - 1-bit accumulate add/subtract pattern
1396 * aptn2 - 2-bit accumulate add/subtract pattern
1397 * eptn2 - 2-bit execute add/subtract pattern
1398 * optn2 - 2-bit operand pattern
1399 * optn3 - 3-bit operand pattern
1400 * sft4 - 4-bit shift amount
1401 * strd2 - 2-bit stride amount
1405 * Level of parallelism: Operand size:
1406 * S - single operation at a time 32 - word
1407 * D - two operations in parallel 16 - half word
1408 * Q - four operations in parallel 8 - byte
1412 * ADD - Add or subtract
1413 * ADDC - Add with carry-in
1415 * ASUM - Sum together then accumulate (add or subtract)
1416 * ASUMC - Sum together then accumulate (add or subtract) with carry-in
1417 * AVG - Average between 2 operands
1418 * ABD - Absolute difference
1420 * AND - Logical bitwise 'and' operation
1422 * EXTR - Extract bits
1423 * I2M - Move from GPR register to MXU register
1424 * LDD - Load data from memory to XRF
1425 * LDI - Load data from memory to XRF (and increase the address base)
1426 * LUI - Load unsigned immediate
1428 * MULU - Unsigned multiply
1429 * MADD - 64-bit operand add 32x32 product
1430 * MSUB - 64-bit operand subtract 32x32 product
1431 * MAC - Multiply and accumulate (add or subtract)
1432 * MAD - Multiply and add or subtract
1433 * MAX - Maximum between 2 operands
1434 * MIN - Minimum between 2 operands
1435 * M2I - Move from MXU register to GPR register
1436 * MOVZ - Move if zero
1437 * MOVN - Move if non-zero
1438 * NOR - Logical bitwise 'nor' operation
1439 * OR - Logical bitwise 'or' operation
1440 * STD - Store data from XRF to memory
1441 * SDI - Store data from XRF to memory (and increase the address base)
1442 * SLT - Set of less than comparison
1443 * SAD - Sum of absolute differences
1444 * SLL - Logical shift left
1445 * SLR - Logical shift right
1446 * SAR - Arithmetic shift right
1449 * SCOP - Calculate x’s scope (-1, means x<0; 0, means x==0; 1, means x>0)
1450 * XOR - Logical bitwise 'exclusive or' operation
1454 * E - Expand results
1455 * F - Fixed point multiplication
1456 * L - Low part result
1457 * R - Doing rounding
1458 * V - Variable instead of immediate
1459 * W - Combine above L and V
1462 * The list of MXU instructions grouped by functionality
1463 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1465 * Load/Store instructions Multiplication instructions
1466 * ----------------------- ---------------------------
1468 * S32LDD XRa, Rb, s12 S32MADD XRa, XRd, Rs, Rt
1469 * S32STD XRa, Rb, s12 S32MADDU XRa, XRd, Rs, Rt
1470 * S32LDDV XRa, Rb, rc, strd2 S32MSUB XRa, XRd, Rs, Rt
1471 * S32STDV XRa, Rb, rc, strd2 S32MSUBU XRa, XRd, Rs, Rt
1472 * S32LDI XRa, Rb, s12 S32MUL XRa, XRd, Rs, Rt
1473 * S32SDI XRa, Rb, s12 S32MULU XRa, XRd, Rs, Rt
1474 * S32LDIV XRa, Rb, rc, strd2 D16MUL XRa, XRb, XRc, XRd, optn2
1475 * S32SDIV XRa, Rb, rc, strd2 D16MULE XRa, XRb, XRc, optn2
1476 * S32LDDR XRa, Rb, s12 D16MULF XRa, XRb, XRc, optn2
1477 * S32STDR XRa, Rb, s12 D16MAC XRa, XRb, XRc, XRd, aptn2, optn2
1478 * S32LDDVR XRa, Rb, rc, strd2 D16MACE XRa, XRb, XRc, XRd, aptn2, optn2
1479 * S32STDVR XRa, Rb, rc, strd2 D16MACF XRa, XRb, XRc, XRd, aptn2, optn2
1480 * S32LDIR XRa, Rb, s12 D16MADL XRa, XRb, XRc, XRd, aptn2, optn2
1481 * S32SDIR XRa, Rb, s12 S16MAD XRa, XRb, XRc, XRd, aptn1, optn2
1482 * S32LDIVR XRa, Rb, rc, strd2 Q8MUL XRa, XRb, XRc, XRd
1483 * S32SDIVR XRa, Rb, rc, strd2 Q8MULSU XRa, XRb, XRc, XRd
1484 * S16LDD XRa, Rb, s10, eptn2 Q8MAC XRa, XRb, XRc, XRd, aptn2
1485 * S16STD XRa, Rb, s10, eptn2 Q8MACSU XRa, XRb, XRc, XRd, aptn2
1486 * S16LDI XRa, Rb, s10, eptn2 Q8MADL XRa, XRb, XRc, XRd, aptn2
1487 * S16SDI XRa, Rb, s10, eptn2
1488 * S8LDD XRa, Rb, s8, eptn3
1489 * S8STD XRa, Rb, s8, eptn3 Addition and subtraction instructions
1490 * S8LDI XRa, Rb, s8, eptn3 -------------------------------------
1491 * S8SDI XRa, Rb, s8, eptn3
1492 * LXW Rd, Rs, Rt, strd2 D32ADD XRa, XRb, XRc, XRd, eptn2
1493 * LXH Rd, Rs, Rt, strd2 D32ADDC XRa, XRb, XRc, XRd
1494 * LXHU Rd, Rs, Rt, strd2 D32ACC XRa, XRb, XRc, XRd, eptn2
1495 * LXB Rd, Rs, Rt, strd2 D32ACCM XRa, XRb, XRc, XRd, eptn2
1496 * LXBU Rd, Rs, Rt, strd2 D32ASUM XRa, XRb, XRc, XRd, eptn2
1497 * S32CPS XRa, XRb, XRc
1498 * Q16ADD XRa, XRb, XRc, XRd, eptn2, optn2
1499 * Comparison instructions Q16ACC XRa, XRb, XRc, XRd, eptn2
1500 * ----------------------- Q16ACCM XRa, XRb, XRc, XRd, eptn2
1501 * D16ASUM XRa, XRb, XRc, XRd, eptn2
1502 * S32MAX XRa, XRb, XRc D16CPS XRa, XRb,
1503 * S32MIN XRa, XRb, XRc D16AVG XRa, XRb, XRc
1504 * S32SLT XRa, XRb, XRc D16AVGR XRa, XRb, XRc
1505 * S32MOVZ XRa, XRb, XRc Q8ADD XRa, XRb, XRc, eptn2
1506 * S32MOVN XRa, XRb, XRc Q8ADDE XRa, XRb, XRc, XRd, eptn2
1507 * D16MAX XRa, XRb, XRc Q8ACCE XRa, XRb, XRc, XRd, eptn2
1508 * D16MIN XRa, XRb, XRc Q8ABD XRa, XRb, XRc
1509 * D16SLT XRa, XRb, XRc Q8SAD XRa, XRb, XRc, XRd
1510 * D16MOVZ XRa, XRb, XRc Q8AVG XRa, XRb, XRc
1511 * D16MOVN XRa, XRb, XRc Q8AVGR XRa, XRb, XRc
1512 * Q8MAX XRa, XRb, XRc D8SUM XRa, XRb, XRc, XRd
1513 * Q8MIN XRa, XRb, XRc D8SUMC XRa, XRb, XRc, XRd
1514 * Q8SLT XRa, XRb, XRc
1515 * Q8SLTU XRa, XRb, XRc
1516 * Q8MOVZ XRa, XRb, XRc Shift instructions
1517 * Q8MOVN XRa, XRb, XRc ------------------
1519 * D32SLL XRa, XRb, XRc, XRd, sft4
1520 * Bitwise instructions D32SLR XRa, XRb, XRc, XRd, sft4
1521 * -------------------- D32SAR XRa, XRb, XRc, XRd, sft4
1522 * D32SARL XRa, XRb, XRc, sft4
1523 * S32NOR XRa, XRb, XRc D32SLLV XRa, XRb, Rb
1524 * S32AND XRa, XRb, XRc D32SLRV XRa, XRb, Rb
1525 * S32XOR XRa, XRb, XRc D32SARV XRa, XRb, Rb
1526 * S32OR XRa, XRb, XRc D32SARW XRa, XRb, XRc, Rb
1527 * Q16SLL XRa, XRb, XRc, XRd, sft4
1528 * Q16SLR XRa, XRb, XRc, XRd, sft4
1529 * Miscellaneous instructions Q16SAR XRa, XRb, XRc, XRd, sft4
1530 * ------------------------- Q16SLLV XRa, XRb, Rb
1531 * Q16SLRV XRa, XRb, Rb
1532 * S32SFL XRa, XRb, XRc, XRd, optn2 Q16SARV XRa, XRb, Rb
1533 * S32ALN XRa, XRb, XRc, Rb
1534 * S32ALNI XRa, XRb, XRc, s3
1535 * S32LUI XRa, s8, optn3 Move instructions
1536 * S32EXTR XRa, XRb, Rb, bits5 -----------------
1537 * S32EXTRV XRa, XRb, Rs, Rt
1538 * Q16SCOP XRa, XRb, XRc, XRd S32M2I XRa, Rb
1539 * Q16SAT XRa, XRb, XRc S32I2M XRa, Rb
1542 * The opcode organization of MXU instructions
1543 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1545 * The bits 31..26 of all MXU instructions are equal to 0x1C (also referred
1546 * as opcode SPECIAL2 in the base MIPS ISA). The organization and meaning of
1547 * other bits up to the instruction level is as follows:
1552 * ┌─ 000000 ─ OPC_MXU_S32MADD
1553 * ├─ 000001 ─ OPC_MXU_S32MADDU
1554 * ├─ 000010 ─ <not assigned> (non-MXU OPC_MUL)
1557 * ├─ 000011 ─ OPC_MXU__POOL00 ─┬─ 000 ─ OPC_MXU_S32MAX
1558 * │ ├─ 001 ─ OPC_MXU_S32MIN
1559 * │ ├─ 010 ─ OPC_MXU_D16MAX
1560 * │ ├─ 011 ─ OPC_MXU_D16MIN
1561 * │ ├─ 100 ─ OPC_MXU_Q8MAX
1562 * │ ├─ 101 ─ OPC_MXU_Q8MIN
1563 * │ ├─ 110 ─ OPC_MXU_Q8SLT
1564 * │ └─ 111 ─ OPC_MXU_Q8SLTU
1565 * ├─ 000100 ─ OPC_MXU_S32MSUB
1566 * ├─ 000101 ─ OPC_MXU_S32MSUBU 20..18
1567 * ├─ 000110 ─ OPC_MXU__POOL01 ─┬─ 000 ─ OPC_MXU_S32SLT
1568 * │ ├─ 001 ─ OPC_MXU_D16SLT
1569 * │ ├─ 010 ─ OPC_MXU_D16AVG
1570 * │ ├─ 011 ─ OPC_MXU_D16AVGR
1571 * │ ├─ 100 ─ OPC_MXU_Q8AVG
1572 * │ ├─ 101 ─ OPC_MXU_Q8AVGR
1573 * │ └─ 111 ─ OPC_MXU_Q8ADD
1576 * ├─ 000111 ─ OPC_MXU__POOL02 ─┬─ 000 ─ OPC_MXU_S32CPS
1577 * │ ├─ 010 ─ OPC_MXU_D16CPS
1578 * │ ├─ 100 ─ OPC_MXU_Q8ABD
1579 * │ └─ 110 ─ OPC_MXU_Q16SAT
1580 * ├─ 001000 ─ OPC_MXU_D16MUL
1582 * ├─ 001001 ─ OPC_MXU__POOL03 ─┬─ 00 ─ OPC_MXU_D16MULF
1583 * │ └─ 01 ─ OPC_MXU_D16MULE
1584 * ├─ 001010 ─ OPC_MXU_D16MAC
1585 * ├─ 001011 ─ OPC_MXU_D16MACF
1586 * ├─ 001100 ─ OPC_MXU_D16MADL
1587 * ├─ 001101 ─ OPC_MXU_S16MAD
1588 * ├─ 001110 ─ OPC_MXU_Q16ADD
1589 * ├─ 001111 ─ OPC_MXU_D16MACE 23
1590 * │ ┌─ 0 ─ OPC_MXU_S32LDD
1591 * ├─ 010000 ─ OPC_MXU__POOL04 ─┴─ 1 ─ OPC_MXU_S32LDDR
1594 * ├─ 010001 ─ OPC_MXU__POOL05 ─┬─ 0 ─ OPC_MXU_S32STD
1595 * │ └─ 1 ─ OPC_MXU_S32STDR
1598 * ├─ 010010 ─ OPC_MXU__POOL06 ─┬─ 0000 ─ OPC_MXU_S32LDDV
1599 * │ └─ 0001 ─ OPC_MXU_S32LDDVR
1602 * ├─ 010011 ─ OPC_MXU__POOL07 ─┬─ 0000 ─ OPC_MXU_S32STDV
1603 * │ └─ 0001 ─ OPC_MXU_S32STDVR
1606 * ├─ 010100 ─ OPC_MXU__POOL08 ─┬─ 0 ─ OPC_MXU_S32LDI
1607 * │ └─ 1 ─ OPC_MXU_S32LDIR
1610 * ├─ 010101 ─ OPC_MXU__POOL09 ─┬─ 0 ─ OPC_MXU_S32SDI
1611 * │ └─ 1 ─ OPC_MXU_S32SDIR
1614 * ├─ 010110 ─ OPC_MXU__POOL10 ─┬─ 0000 ─ OPC_MXU_S32LDIV
1615 * │ └─ 0001 ─ OPC_MXU_S32LDIVR
1618 * ├─ 010111 ─ OPC_MXU__POOL11 ─┬─ 0000 ─ OPC_MXU_S32SDIV
1619 * │ └─ 0001 ─ OPC_MXU_S32SDIVR
1620 * ├─ 011000 ─ OPC_MXU_D32ADD
1622 * MXU ├─ 011001 ─ OPC_MXU__POOL12 ─┬─ 00 ─ OPC_MXU_D32ACC
1623 * opcodes ─┤ ├─ 01 ─ OPC_MXU_D32ACCM
1624 * │ └─ 10 ─ OPC_MXU_D32ASUM
1625 * ├─ 011010 ─ <not assigned>
1627 * ├─ 011011 ─ OPC_MXU__POOL13 ─┬─ 00 ─ OPC_MXU_Q16ACC
1628 * │ ├─ 01 ─ OPC_MXU_Q16ACCM
1629 * │ └─ 10 ─ OPC_MXU_Q16ASUM
1632 * ├─ 011100 ─ OPC_MXU__POOL14 ─┬─ 00 ─ OPC_MXU_Q8ADDE
1633 * │ ├─ 01 ─ OPC_MXU_D8SUM
1634 * ├─ 011101 ─ OPC_MXU_Q8ACCE └─ 10 ─ OPC_MXU_D8SUMC
1635 * ├─ 011110 ─ <not assigned>
1636 * ├─ 011111 ─ <not assigned>
1637 * ├─ 100000 ─ <not assigned> (overlaps with CLZ)
1638 * ├─ 100001 ─ <not assigned> (overlaps with CLO)
1639 * ├─ 100010 ─ OPC_MXU_S8LDD
1640 * ├─ 100011 ─ OPC_MXU_S8STD 15..14
1641 * ├─ 100100 ─ OPC_MXU_S8LDI ┌─ 00 ─ OPC_MXU_S32MUL
1642 * ├─ 100101 ─ OPC_MXU_S8SDI ├─ 00 ─ OPC_MXU_S32MULU
1643 * │ ├─ 00 ─ OPC_MXU_S32EXTR
1644 * ├─ 100110 ─ OPC_MXU__POOL15 ─┴─ 00 ─ OPC_MXU_S32EXTRV
1647 * ├─ 100111 ─ OPC_MXU__POOL16 ─┬─ 000 ─ OPC_MXU_D32SARW
1648 * │ ├─ 001 ─ OPC_MXU_S32ALN
1649 * │ ├─ 010 ─ OPC_MXU_S32ALNI
1650 * │ ├─ 011 ─ OPC_MXU_S32LUI
1651 * │ ├─ 100 ─ OPC_MXU_S32NOR
1652 * │ ├─ 101 ─ OPC_MXU_S32AND
1653 * │ ├─ 110 ─ OPC_MXU_S32OR
1654 * │ └─ 111 ─ OPC_MXU_S32XOR
1657 * ├─ 101000 ─ OPC_MXU__POOL17 ─┬─ 000 ─ OPC_MXU_LXB
1658 * │ ├─ 001 ─ OPC_MXU_LXH
1659 * ├─ 101001 ─ <not assigned> ├─ 011 ─ OPC_MXU_LXW
1660 * ├─ 101010 ─ OPC_MXU_S16LDD ├─ 100 ─ OPC_MXU_LXBU
1661 * ├─ 101011 ─ OPC_MXU_S16STD └─ 101 ─ OPC_MXU_LXHU
1662 * ├─ 101100 ─ OPC_MXU_S16LDI
1663 * ├─ 101101 ─ OPC_MXU_S16SDI
1664 * ├─ 101110 ─ OPC_MXU_S32M2I
1665 * ├─ 101111 ─ OPC_MXU_S32I2M
1666 * ├─ 110000 ─ OPC_MXU_D32SLL
1667 * ├─ 110001 ─ OPC_MXU_D32SLR 20..18
1668 * ├─ 110010 ─ OPC_MXU_D32SARL ┌─ 000 ─ OPC_MXU_D32SLLV
1669 * ├─ 110011 ─ OPC_MXU_D32SAR ├─ 001 ─ OPC_MXU_D32SLRV
1670 * ├─ 110100 ─ OPC_MXU_Q16SLL ├─ 010 ─ OPC_MXU_D32SARV
1671 * ├─ 110101 ─ OPC_MXU_Q16SLR ├─ 011 ─ OPC_MXU_Q16SLLV
1672 * │ ├─ 100 ─ OPC_MXU_Q16SLRV
1673 * ├─ 110110 ─ OPC_MXU__POOL18 ─┴─ 101 ─ OPC_MXU_Q16SARV
1675 * ├─ 110111 ─ OPC_MXU_Q16SAR
1677 * ├─ 111000 ─ OPC_MXU__POOL19 ─┬─ 00 ─ OPC_MXU_Q8MUL
1678 * │ └─ 01 ─ OPC_MXU_Q8MULSU
1681 * ├─ 111001 ─ OPC_MXU__POOL20 ─┬─ 000 ─ OPC_MXU_Q8MOVZ
1682 * │ ├─ 001 ─ OPC_MXU_Q8MOVN
1683 * │ ├─ 010 ─ OPC_MXU_D16MOVZ
1684 * │ ├─ 011 ─ OPC_MXU_D16MOVN
1685 * │ ├─ 100 ─ OPC_MXU_S32MOVZ
1686 * │ └─ 101 ─ OPC_MXU_S32MOVN
1689 * ├─ 111010 ─ OPC_MXU__POOL21 ─┬─ 00 ─ OPC_MXU_Q8MAC
1690 * │ └─ 10 ─ OPC_MXU_Q8MACSU
1691 * ├─ 111011 ─ OPC_MXU_Q16SCOP
1692 * ├─ 111100 ─ OPC_MXU_Q8MADL
1693 * ├─ 111101 ─ OPC_MXU_S32SFL
1694 * ├─ 111110 ─ OPC_MXU_Q8SAD
1695 * └─ 111111 ─ <not assigned> (overlaps with SDBBP)
1700 * "XBurst® Instruction Set Architecture MIPS eXtension/enhanced Unit
1701 * Programming Manual", Ingenic Semiconductor Co, Ltd., revision June 2, 2017
1705 OPC_MXU_S32MADD
= 0x00,
1706 OPC_MXU_S32MADDU
= 0x01,
1707 OPC__MXU_MUL
= 0x02,
1708 OPC_MXU__POOL00
= 0x03,
1709 OPC_MXU_S32MSUB
= 0x04,
1710 OPC_MXU_S32MSUBU
= 0x05,
1711 OPC_MXU__POOL01
= 0x06,
1712 OPC_MXU__POOL02
= 0x07,
1713 OPC_MXU_D16MUL
= 0x08,
1714 OPC_MXU__POOL03
= 0x09,
1715 OPC_MXU_D16MAC
= 0x0A,
1716 OPC_MXU_D16MACF
= 0x0B,
1717 OPC_MXU_D16MADL
= 0x0C,
1718 OPC_MXU_S16MAD
= 0x0D,
1719 OPC_MXU_Q16ADD
= 0x0E,
1720 OPC_MXU_D16MACE
= 0x0F,
1721 OPC_MXU__POOL04
= 0x10,
1722 OPC_MXU__POOL05
= 0x11,
1723 OPC_MXU__POOL06
= 0x12,
1724 OPC_MXU__POOL07
= 0x13,
1725 OPC_MXU__POOL08
= 0x14,
1726 OPC_MXU__POOL09
= 0x15,
1727 OPC_MXU__POOL10
= 0x16,
1728 OPC_MXU__POOL11
= 0x17,
1729 OPC_MXU_D32ADD
= 0x18,
1730 OPC_MXU__POOL12
= 0x19,
1731 /* not assigned 0x1A */
1732 OPC_MXU__POOL13
= 0x1B,
1733 OPC_MXU__POOL14
= 0x1C,
1734 OPC_MXU_Q8ACCE
= 0x1D,
1735 /* not assigned 0x1E */
1736 /* not assigned 0x1F */
1737 /* not assigned 0x20 */
1738 /* not assigned 0x21 */
1739 OPC_MXU_S8LDD
= 0x22,
1740 OPC_MXU_S8STD
= 0x23,
1741 OPC_MXU_S8LDI
= 0x24,
1742 OPC_MXU_S8SDI
= 0x25,
1743 OPC_MXU__POOL15
= 0x26,
1744 OPC_MXU__POOL16
= 0x27,
1745 OPC_MXU__POOL17
= 0x28,
1746 /* not assigned 0x29 */
1747 OPC_MXU_S16LDD
= 0x2A,
1748 OPC_MXU_S16STD
= 0x2B,
1749 OPC_MXU_S16LDI
= 0x2C,
1750 OPC_MXU_S16SDI
= 0x2D,
1751 OPC_MXU_S32M2I
= 0x2E,
1752 OPC_MXU_S32I2M
= 0x2F,
1753 OPC_MXU_D32SLL
= 0x30,
1754 OPC_MXU_D32SLR
= 0x31,
1755 OPC_MXU_D32SARL
= 0x32,
1756 OPC_MXU_D32SAR
= 0x33,
1757 OPC_MXU_Q16SLL
= 0x34,
1758 OPC_MXU_Q16SLR
= 0x35,
1759 OPC_MXU__POOL18
= 0x36,
1760 OPC_MXU_Q16SAR
= 0x37,
1761 OPC_MXU__POOL19
= 0x38,
1762 OPC_MXU__POOL20
= 0x39,
1763 OPC_MXU__POOL21
= 0x3A,
1764 OPC_MXU_Q16SCOP
= 0x3B,
1765 OPC_MXU_Q8MADL
= 0x3C,
1766 OPC_MXU_S32SFL
= 0x3D,
1767 OPC_MXU_Q8SAD
= 0x3E,
1768 /* not assigned 0x3F */
1776 OPC_MXU_S32MAX
= 0x00,
1777 OPC_MXU_S32MIN
= 0x01,
1778 OPC_MXU_D16MAX
= 0x02,
1779 OPC_MXU_D16MIN
= 0x03,
1780 OPC_MXU_Q8MAX
= 0x04,
1781 OPC_MXU_Q8MIN
= 0x05,
1782 OPC_MXU_Q8SLT
= 0x06,
1783 OPC_MXU_Q8SLTU
= 0x07,
1790 OPC_MXU_S32SLT
= 0x00,
1791 OPC_MXU_D16SLT
= 0x01,
1792 OPC_MXU_D16AVG
= 0x02,
1793 OPC_MXU_D16AVGR
= 0x03,
1794 OPC_MXU_Q8AVG
= 0x04,
1795 OPC_MXU_Q8AVGR
= 0x05,
1796 OPC_MXU_Q8ADD
= 0x07,
1803 OPC_MXU_S32CPS
= 0x00,
1804 OPC_MXU_D16CPS
= 0x02,
1805 OPC_MXU_Q8ABD
= 0x04,
1806 OPC_MXU_Q16SAT
= 0x06,
1813 OPC_MXU_D16MULF
= 0x00,
1814 OPC_MXU_D16MULE
= 0x01,
1821 OPC_MXU_S32LDD
= 0x00,
1822 OPC_MXU_S32LDDR
= 0x01,
1829 OPC_MXU_S32STD
= 0x00,
1830 OPC_MXU_S32STDR
= 0x01,
1837 OPC_MXU_S32LDDV
= 0x00,
1838 OPC_MXU_S32LDDVR
= 0x01,
1845 OPC_MXU_S32STDV
= 0x00,
1846 OPC_MXU_S32STDVR
= 0x01,
1853 OPC_MXU_S32LDI
= 0x00,
1854 OPC_MXU_S32LDIR
= 0x01,
1861 OPC_MXU_S32SDI
= 0x00,
1862 OPC_MXU_S32SDIR
= 0x01,
1869 OPC_MXU_S32LDIV
= 0x00,
1870 OPC_MXU_S32LDIVR
= 0x01,
1877 OPC_MXU_S32SDIV
= 0x00,
1878 OPC_MXU_S32SDIVR
= 0x01,
1885 OPC_MXU_D32ACC
= 0x00,
1886 OPC_MXU_D32ACCM
= 0x01,
1887 OPC_MXU_D32ASUM
= 0x02,
1894 OPC_MXU_Q16ACC
= 0x00,
1895 OPC_MXU_Q16ACCM
= 0x01,
1896 OPC_MXU_Q16ASUM
= 0x02,
1903 OPC_MXU_Q8ADDE
= 0x00,
1904 OPC_MXU_D8SUM
= 0x01,
1905 OPC_MXU_D8SUMC
= 0x02,
1912 OPC_MXU_S32MUL
= 0x00,
1913 OPC_MXU_S32MULU
= 0x01,
1914 OPC_MXU_S32EXTR
= 0x02,
1915 OPC_MXU_S32EXTRV
= 0x03,
1922 OPC_MXU_D32SARW
= 0x00,
1923 OPC_MXU_S32ALN
= 0x01,
1924 OPC_MXU_S32ALNI
= 0x02,
1925 OPC_MXU_S32LUI
= 0x03,
1926 OPC_MXU_S32NOR
= 0x04,
1927 OPC_MXU_S32AND
= 0x05,
1928 OPC_MXU_S32OR
= 0x06,
1929 OPC_MXU_S32XOR
= 0x07,
1939 OPC_MXU_LXBU
= 0x04,
1940 OPC_MXU_LXHU
= 0x05,
1947 OPC_MXU_D32SLLV
= 0x00,
1948 OPC_MXU_D32SLRV
= 0x01,
1949 OPC_MXU_D32SARV
= 0x03,
1950 OPC_MXU_Q16SLLV
= 0x04,
1951 OPC_MXU_Q16SLRV
= 0x05,
1952 OPC_MXU_Q16SARV
= 0x07,
1959 OPC_MXU_Q8MUL
= 0x00,
1960 OPC_MXU_Q8MULSU
= 0x01,
1967 OPC_MXU_Q8MOVZ
= 0x00,
1968 OPC_MXU_Q8MOVN
= 0x01,
1969 OPC_MXU_D16MOVZ
= 0x02,
1970 OPC_MXU_D16MOVN
= 0x03,
1971 OPC_MXU_S32MOVZ
= 0x04,
1972 OPC_MXU_S32MOVN
= 0x05,
1979 OPC_MXU_Q8MAC
= 0x00,
1980 OPC_MXU_Q8MACSU
= 0x01,
1984 * Overview of the TX79-specific instruction set
1985 * =============================================
1987 * The R5900 and the C790 have 128-bit wide GPRs, where the upper 64 bits
1988 * are only used by the specific quadword (128-bit) LQ/SQ load/store
1989 * instructions and certain multimedia instructions (MMIs). These MMIs
1990 * configure the 128-bit data path as two 64-bit, four 32-bit, eight 16-bit
1991 * or sixteen 8-bit paths.
1995 * The Toshiba TX System RISC TX79 Core Architecture manual,
1996 * https://wiki.qemu.org/File:C790.pdf
1998 * Three-Operand Multiply and Multiply-Add (4 instructions)
1999 * --------------------------------------------------------
2000 * MADD [rd,] rs, rt Multiply/Add
2001 * MADDU [rd,] rs, rt Multiply/Add Unsigned
2002 * MULT [rd,] rs, rt Multiply (3-operand)
2003 * MULTU [rd,] rs, rt Multiply Unsigned (3-operand)
2005 * Multiply Instructions for Pipeline 1 (10 instructions)
2006 * ------------------------------------------------------
2007 * MULT1 [rd,] rs, rt Multiply Pipeline 1
2008 * MULTU1 [rd,] rs, rt Multiply Unsigned Pipeline 1
2009 * DIV1 rs, rt Divide Pipeline 1
2010 * DIVU1 rs, rt Divide Unsigned Pipeline 1
2011 * MADD1 [rd,] rs, rt Multiply-Add Pipeline 1
2012 * MADDU1 [rd,] rs, rt Multiply-Add Unsigned Pipeline 1
2013 * MFHI1 rd Move From HI1 Register
2014 * MFLO1 rd Move From LO1 Register
2015 * MTHI1 rs Move To HI1 Register
2016 * MTLO1 rs Move To LO1 Register
2018 * Arithmetic (19 instructions)
2019 * ----------------------------
2020 * PADDB rd, rs, rt Parallel Add Byte
2021 * PSUBB rd, rs, rt Parallel Subtract Byte
2022 * PADDH rd, rs, rt Parallel Add Halfword
2023 * PSUBH rd, rs, rt Parallel Subtract Halfword
2024 * PADDW rd, rs, rt Parallel Add Word
2025 * PSUBW rd, rs, rt Parallel Subtract Word
2026 * PADSBH rd, rs, rt Parallel Add/Subtract Halfword
2027 * PADDSB rd, rs, rt Parallel Add with Signed Saturation Byte
2028 * PSUBSB rd, rs, rt Parallel Subtract with Signed Saturation Byte
2029 * PADDSH rd, rs, rt Parallel Add with Signed Saturation Halfword
2030 * PSUBSH rd, rs, rt Parallel Subtract with Signed Saturation Halfword
2031 * PADDSW rd, rs, rt Parallel Add with Signed Saturation Word
2032 * PSUBSW rd, rs, rt Parallel Subtract with Signed Saturation Word
2033 * PADDUB rd, rs, rt Parallel Add with Unsigned saturation Byte
2034 * PSUBUB rd, rs, rt Parallel Subtract with Unsigned saturation Byte
2035 * PADDUH rd, rs, rt Parallel Add with Unsigned saturation Halfword
2036 * PSUBUH rd, rs, rt Parallel Subtract with Unsigned saturation Halfword
2037 * PADDUW rd, rs, rt Parallel Add with Unsigned saturation Word
2038 * PSUBUW rd, rs, rt Parallel Subtract with Unsigned saturation Word
2040 * Min/Max (4 instructions)
2041 * ------------------------
2042 * PMAXH rd, rs, rt Parallel Maximum Halfword
2043 * PMINH rd, rs, rt Parallel Minimum Halfword
2044 * PMAXW rd, rs, rt Parallel Maximum Word
2045 * PMINW rd, rs, rt Parallel Minimum Word
2047 * Absolute (2 instructions)
2048 * -------------------------
2049 * PABSH rd, rt Parallel Absolute Halfword
2050 * PABSW rd, rt Parallel Absolute Word
2052 * Logical (4 instructions)
2053 * ------------------------
2054 * PAND rd, rs, rt Parallel AND
2055 * POR rd, rs, rt Parallel OR
2056 * PXOR rd, rs, rt Parallel XOR
2057 * PNOR rd, rs, rt Parallel NOR
2059 * Shift (9 instructions)
2060 * ----------------------
2061 * PSLLH rd, rt, sa Parallel Shift Left Logical Halfword
2062 * PSRLH rd, rt, sa Parallel Shift Right Logical Halfword
2063 * PSRAH rd, rt, sa Parallel Shift Right Arithmetic Halfword
2064 * PSLLW rd, rt, sa Parallel Shift Left Logical Word
2065 * PSRLW rd, rt, sa Parallel Shift Right Logical Word
2066 * PSRAW rd, rt, sa Parallel Shift Right Arithmetic Word
2067 * PSLLVW rd, rt, rs Parallel Shift Left Logical Variable Word
2068 * PSRLVW rd, rt, rs Parallel Shift Right Logical Variable Word
2069 * PSRAVW rd, rt, rs Parallel Shift Right Arithmetic Variable Word
2071 * Compare (6 instructions)
2072 * ------------------------
2073 * PCGTB rd, rs, rt Parallel Compare for Greater Than Byte
2074 * PCEQB rd, rs, rt Parallel Compare for Equal Byte
2075 * PCGTH rd, rs, rt Parallel Compare for Greater Than Halfword
2076 * PCEQH rd, rs, rt Parallel Compare for Equal Halfword
2077 * PCGTW rd, rs, rt Parallel Compare for Greater Than Word
2078 * PCEQW rd, rs, rt Parallel Compare for Equal Word
2080 * LZC (1 instruction)
2081 * -------------------
2082 * PLZCW rd, rs Parallel Leading Zero or One Count Word
2084 * Quadword Load and Store (2 instructions)
2085 * ----------------------------------------
2086 * LQ rt, offset(base) Load Quadword
2087 * SQ rt, offset(base) Store Quadword
2089 * Multiply and Divide (19 instructions)
2090 * -------------------------------------
2091 * PMULTW rd, rs, rt Parallel Multiply Word
2092 * PMULTUW rd, rs, rt Parallel Multiply Unsigned Word
2093 * PDIVW rs, rt Parallel Divide Word
2094 * PDIVUW rs, rt Parallel Divide Unsigned Word
2095 * PMADDW rd, rs, rt Parallel Multiply-Add Word
2096 * PMADDUW rd, rs, rt Parallel Multiply-Add Unsigned Word
2097 * PMSUBW rd, rs, rt Parallel Multiply-Subtract Word
2098 * PMULTH rd, rs, rt Parallel Multiply Halfword
2099 * PMADDH rd, rs, rt Parallel Multiply-Add Halfword
2100 * PMSUBH rd, rs, rt Parallel Multiply-Subtract Halfword
2101 * PHMADH rd, rs, rt Parallel Horizontal Multiply-Add Halfword
2102 * PHMSBH rd, rs, rt Parallel Horizontal Multiply-Subtract Halfword
2103 * PDIVBW rs, rt Parallel Divide Broadcast Word
2104 * PMFHI rd Parallel Move From HI Register
2105 * PMFLO rd Parallel Move From LO Register
2106 * PMTHI rs Parallel Move To HI Register
2107 * PMTLO rs Parallel Move To LO Register
2108 * PMFHL rd Parallel Move From HI/LO Register
2109 * PMTHL rs Parallel Move To HI/LO Register
2111 * Pack/Extend (11 instructions)
2112 * -----------------------------
2113 * PPAC5 rd, rt Parallel Pack to 5 bits
2114 * PPACB rd, rs, rt Parallel Pack to Byte
2115 * PPACH rd, rs, rt Parallel Pack to Halfword
2116 * PPACW rd, rs, rt Parallel Pack to Word
2117 * PEXT5 rd, rt Parallel Extend Upper from 5 bits
2118 * PEXTUB rd, rs, rt Parallel Extend Upper from Byte
2119 * PEXTLB rd, rs, rt Parallel Extend Lower from Byte
2120 * PEXTUH rd, rs, rt Parallel Extend Upper from Halfword
2121 * PEXTLH rd, rs, rt Parallel Extend Lower from Halfword
2122 * PEXTUW rd, rs, rt Parallel Extend Upper from Word
2123 * PEXTLW rd, rs, rt Parallel Extend Lower from Word
2125 * Others (16 instructions)
2126 * ------------------------
2127 * PCPYH rd, rt Parallel Copy Halfword
2128 * PCPYLD rd, rs, rt Parallel Copy Lower Doubleword
2129 * PCPYUD rd, rs, rt Parallel Copy Upper Doubleword
2130 * PREVH rd, rt Parallel Reverse Halfword
2131 * PINTH rd, rs, rt Parallel Interleave Halfword
2132 * PINTEH rd, rs, rt Parallel Interleave Even Halfword
2133 * PEXEH rd, rt Parallel Exchange Even Halfword
2134 * PEXCH rd, rt Parallel Exchange Center Halfword
2135 * PEXEW rd, rt Parallel Exchange Even Word
2136 * PEXCW rd, rt Parallel Exchange Center Word
2137 * QFSRV rd, rs, rt Quadword Funnel Shift Right Variable
2138 * MFSA rd Move from Shift Amount Register
2139 * MTSA rs Move to Shift Amount Register
2140 * MTSAB rs, immediate Move Byte Count to Shift Amount Register
2141 * MTSAH rs, immediate Move Halfword Count to Shift Amount Register
2142 * PROT3W rd, rt Parallel Rotate 3 Words
2144 * MMI (MultiMedia Instruction) encodings
2145 * ======================================
2147 * MMI instructions encoding table keys:
2149 * * This code is reserved for future use. An attempt to execute it
2150 * causes a Reserved Instruction exception.
2151 * % This code indicates an instruction class. The instruction word
2152 * must be further decoded by examining additional tables that show
2153 * the values for other instruction fields.
2154 * # This code is reserved for the unsupported instructions DMULT,
2155 * DMULTU, DDIV, DDIVU, LL, LLD, SC, SCD, LWC2 and SWC2. An attempt
2156 * to execute it causes a Reserved Instruction exception.
2158 * MMI instructions encoded by opcode field (MMI, LQ, SQ):
2161 * +--------+----------------------------------------+
2163 * +--------+----------------------------------------+
2165 * opcode bits 28..26
2166 * bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
2167 * 31..29 | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111
2168 * -------+-------+-------+-------+-------+-------+-------+-------+-------
2169 * 0 000 |SPECIAL| REGIMM| J | JAL | BEQ | BNE | BLEZ | BGTZ
2170 * 1 001 | ADDI | ADDIU | SLTI | SLTIU | ANDI | ORI | XORI | LUI
2171 * 2 010 | COP0 | COP1 | * | * | BEQL | BNEL | BLEZL | BGTZL
2172 * 3 011 | DADDI | DADDIU| LDL | LDR | MMI% | * | LQ | SQ
2173 * 4 100 | LB | LH | LWL | LW | LBU | LHU | LWR | LWU
2174 * 5 101 | SB | SH | SWL | SW | SDL | SDR | SWR | CACHE
2175 * 6 110 | # | LWC1 | # | PREF | # | LDC1 | # | LD
2176 * 7 111 | # | SWC1 | # | * | # | SDC1 | # | SD
2180 MMI_OPC_CLASS_MMI
= 0x1C << 26, /* Same as OPC_SPECIAL2 */
2181 MMI_OPC_LQ
= 0x1E << 26, /* Same as OPC_MSA */
2182 MMI_OPC_SQ
= 0x1F << 26, /* Same as OPC_SPECIAL3 */
2186 * MMI instructions with opcode field = MMI:
2189 * +--------+-------------------------------+--------+
2190 * | MMI | |function|
2191 * +--------+-------------------------------+--------+
2193 * function bits 2..0
2194 * bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
2195 * 5..3 | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111
2196 * -------+-------+-------+-------+-------+-------+-------+-------+-------
2197 * 0 000 | MADD | MADDU | * | * | PLZCW | * | * | *
2198 * 1 001 | MMI0% | MMI2% | * | * | * | * | * | *
2199 * 2 010 | MFHI1 | MTHI1 | MFLO1 | MTLO1 | * | * | * | *
2200 * 3 011 | MULT1 | MULTU1| DIV1 | DIVU1 | * | * | * | *
2201 * 4 100 | MADD1 | MADDU1| * | * | * | * | * | *
2202 * 5 101 | MMI1% | MMI3% | * | * | * | * | * | *
2203 * 6 110 | PMFHL | PMTHL | * | * | PSLLH | * | PSRLH | PSRAH
2204 * 7 111 | * | * | * | * | PSLLW | * | PSRLW | PSRAW
2207 #define MASK_MMI(op) (MASK_OP_MAJOR(op) | ((op) & 0x3F))
2209 MMI_OPC_MADD
= 0x00 | MMI_OPC_CLASS_MMI
, /* Same as OPC_MADD */
2210 MMI_OPC_MADDU
= 0x01 | MMI_OPC_CLASS_MMI
, /* Same as OPC_MADDU */
2211 MMI_OPC_PLZCW
= 0x04 | MMI_OPC_CLASS_MMI
,
2212 MMI_OPC_CLASS_MMI0
= 0x08 | MMI_OPC_CLASS_MMI
,
2213 MMI_OPC_CLASS_MMI2
= 0x09 | MMI_OPC_CLASS_MMI
,
2214 MMI_OPC_MFHI1
= 0x10 | MMI_OPC_CLASS_MMI
, /* Same minor as OPC_MFHI */
2215 MMI_OPC_MTHI1
= 0x11 | MMI_OPC_CLASS_MMI
, /* Same minor as OPC_MTHI */
2216 MMI_OPC_MFLO1
= 0x12 | MMI_OPC_CLASS_MMI
, /* Same minor as OPC_MFLO */
2217 MMI_OPC_MTLO1
= 0x13 | MMI_OPC_CLASS_MMI
, /* Same minor as OPC_MTLO */
2218 MMI_OPC_MULT1
= 0x18 | MMI_OPC_CLASS_MMI
, /* Same minor as OPC_MULT */
2219 MMI_OPC_MULTU1
= 0x19 | MMI_OPC_CLASS_MMI
, /* Same min. as OPC_MULTU */
2220 MMI_OPC_DIV1
= 0x1A | MMI_OPC_CLASS_MMI
, /* Same minor as OPC_DIV */
2221 MMI_OPC_DIVU1
= 0x1B | MMI_OPC_CLASS_MMI
, /* Same minor as OPC_DIVU */
2222 MMI_OPC_MADD1
= 0x20 | MMI_OPC_CLASS_MMI
,
2223 MMI_OPC_MADDU1
= 0x21 | MMI_OPC_CLASS_MMI
,
2224 MMI_OPC_CLASS_MMI1
= 0x28 | MMI_OPC_CLASS_MMI
,
2225 MMI_OPC_CLASS_MMI3
= 0x29 | MMI_OPC_CLASS_MMI
,
2226 MMI_OPC_PMFHL
= 0x30 | MMI_OPC_CLASS_MMI
,
2227 MMI_OPC_PMTHL
= 0x31 | MMI_OPC_CLASS_MMI
,
2228 MMI_OPC_PSLLH
= 0x34 | MMI_OPC_CLASS_MMI
,
2229 MMI_OPC_PSRLH
= 0x36 | MMI_OPC_CLASS_MMI
,
2230 MMI_OPC_PSRAH
= 0x37 | MMI_OPC_CLASS_MMI
,
2231 MMI_OPC_PSLLW
= 0x3C | MMI_OPC_CLASS_MMI
,
2232 MMI_OPC_PSRLW
= 0x3E | MMI_OPC_CLASS_MMI
,
2233 MMI_OPC_PSRAW
= 0x3F | MMI_OPC_CLASS_MMI
,
2237 * MMI instructions with opcode field = MMI and bits 5..0 = MMI0:
2240 * +--------+----------------------+--------+--------+
2241 * | MMI | |function| MMI0 |
2242 * +--------+----------------------+--------+--------+
2244 * function bits 7..6
2245 * bits | 0 | 1 | 2 | 3
2246 * 10..8 | 00 | 01 | 10 | 11
2247 * -------+-------+-------+-------+-------
2248 * 0 000 | PADDW | PSUBW | PCGTW | PMAXW
2249 * 1 001 | PADDH | PSUBH | PCGTH | PMAXH
2250 * 2 010 | PADDB | PSUBB | PCGTB | *
2251 * 3 011 | * | * | * | *
2252 * 4 100 | PADDSW| PSUBSW| PEXTLW| PPACW
2253 * 5 101 | PADDSH| PSUBSH| PEXTLH| PPACH
2254 * 6 110 | PADDSB| PSUBSB| PEXTLB| PPACB
2255 * 7 111 | * | * | PEXT5 | PPAC5
2258 #define MASK_MMI0(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
2260 MMI_OPC_0_PADDW
= (0x00 << 6) | MMI_OPC_CLASS_MMI0
,
2261 MMI_OPC_0_PSUBW
= (0x01 << 6) | MMI_OPC_CLASS_MMI0
,
2262 MMI_OPC_0_PCGTW
= (0x02 << 6) | MMI_OPC_CLASS_MMI0
,
2263 MMI_OPC_0_PMAXW
= (0x03 << 6) | MMI_OPC_CLASS_MMI0
,
2264 MMI_OPC_0_PADDH
= (0x04 << 6) | MMI_OPC_CLASS_MMI0
,
2265 MMI_OPC_0_PSUBH
= (0x05 << 6) | MMI_OPC_CLASS_MMI0
,
2266 MMI_OPC_0_PCGTH
= (0x06 << 6) | MMI_OPC_CLASS_MMI0
,
2267 MMI_OPC_0_PMAXH
= (0x07 << 6) | MMI_OPC_CLASS_MMI0
,
2268 MMI_OPC_0_PADDB
= (0x08 << 6) | MMI_OPC_CLASS_MMI0
,
2269 MMI_OPC_0_PSUBB
= (0x09 << 6) | MMI_OPC_CLASS_MMI0
,
2270 MMI_OPC_0_PCGTB
= (0x0A << 6) | MMI_OPC_CLASS_MMI0
,
2271 MMI_OPC_0_PADDSW
= (0x10 << 6) | MMI_OPC_CLASS_MMI0
,
2272 MMI_OPC_0_PSUBSW
= (0x11 << 6) | MMI_OPC_CLASS_MMI0
,
2273 MMI_OPC_0_PEXTLW
= (0x12 << 6) | MMI_OPC_CLASS_MMI0
,
2274 MMI_OPC_0_PPACW
= (0x13 << 6) | MMI_OPC_CLASS_MMI0
,
2275 MMI_OPC_0_PADDSH
= (0x14 << 6) | MMI_OPC_CLASS_MMI0
,
2276 MMI_OPC_0_PSUBSH
= (0x15 << 6) | MMI_OPC_CLASS_MMI0
,
2277 MMI_OPC_0_PEXTLH
= (0x16 << 6) | MMI_OPC_CLASS_MMI0
,
2278 MMI_OPC_0_PPACH
= (0x17 << 6) | MMI_OPC_CLASS_MMI0
,
2279 MMI_OPC_0_PADDSB
= (0x18 << 6) | MMI_OPC_CLASS_MMI0
,
2280 MMI_OPC_0_PSUBSB
= (0x19 << 6) | MMI_OPC_CLASS_MMI0
,
2281 MMI_OPC_0_PEXTLB
= (0x1A << 6) | MMI_OPC_CLASS_MMI0
,
2282 MMI_OPC_0_PPACB
= (0x1B << 6) | MMI_OPC_CLASS_MMI0
,
2283 MMI_OPC_0_PEXT5
= (0x1E << 6) | MMI_OPC_CLASS_MMI0
,
2284 MMI_OPC_0_PPAC5
= (0x1F << 6) | MMI_OPC_CLASS_MMI0
,
2288 * MMI instructions with opcode field = MMI and bits 5..0 = MMI1:
2291 * +--------+----------------------+--------+--------+
2292 * | MMI | |function| MMI1 |
2293 * +--------+----------------------+--------+--------+
2295 * function bits 7..6
2296 * bits | 0 | 1 | 2 | 3
2297 * 10..8 | 00 | 01 | 10 | 11
2298 * -------+-------+-------+-------+-------
2299 * 0 000 | * | PABSW | PCEQW | PMINW
2300 * 1 001 | PADSBH| PABSH | PCEQH | PMINH
2301 * 2 010 | * | * | PCEQB | *
2302 * 3 011 | * | * | * | *
2303 * 4 100 | PADDUW| PSUBUW| PEXTUW| *
2304 * 5 101 | PADDUH| PSUBUH| PEXTUH| *
2305 * 6 110 | PADDUB| PSUBUB| PEXTUB| QFSRV
2306 * 7 111 | * | * | * | *
2309 #define MASK_MMI1(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
2311 MMI_OPC_1_PABSW
= (0x01 << 6) | MMI_OPC_CLASS_MMI1
,
2312 MMI_OPC_1_PCEQW
= (0x02 << 6) | MMI_OPC_CLASS_MMI1
,
2313 MMI_OPC_1_PMINW
= (0x03 << 6) | MMI_OPC_CLASS_MMI1
,
2314 MMI_OPC_1_PADSBH
= (0x04 << 6) | MMI_OPC_CLASS_MMI1
,
2315 MMI_OPC_1_PABSH
= (0x05 << 6) | MMI_OPC_CLASS_MMI1
,
2316 MMI_OPC_1_PCEQH
= (0x06 << 6) | MMI_OPC_CLASS_MMI1
,
2317 MMI_OPC_1_PMINH
= (0x07 << 6) | MMI_OPC_CLASS_MMI1
,
2318 MMI_OPC_1_PCEQB
= (0x0A << 6) | MMI_OPC_CLASS_MMI1
,
2319 MMI_OPC_1_PADDUW
= (0x10 << 6) | MMI_OPC_CLASS_MMI1
,
2320 MMI_OPC_1_PSUBUW
= (0x11 << 6) | MMI_OPC_CLASS_MMI1
,
2321 MMI_OPC_1_PEXTUW
= (0x12 << 6) | MMI_OPC_CLASS_MMI1
,
2322 MMI_OPC_1_PADDUH
= (0x14 << 6) | MMI_OPC_CLASS_MMI1
,
2323 MMI_OPC_1_PSUBUH
= (0x15 << 6) | MMI_OPC_CLASS_MMI1
,
2324 MMI_OPC_1_PEXTUH
= (0x16 << 6) | MMI_OPC_CLASS_MMI1
,
2325 MMI_OPC_1_PADDUB
= (0x18 << 6) | MMI_OPC_CLASS_MMI1
,
2326 MMI_OPC_1_PSUBUB
= (0x19 << 6) | MMI_OPC_CLASS_MMI1
,
2327 MMI_OPC_1_PEXTUB
= (0x1A << 6) | MMI_OPC_CLASS_MMI1
,
2328 MMI_OPC_1_QFSRV
= (0x1B << 6) | MMI_OPC_CLASS_MMI1
,
2332 * MMI instructions with opcode field = MMI and bits 5..0 = MMI2:
2335 * +--------+----------------------+--------+--------+
2336 * | MMI | |function| MMI2 |
2337 * +--------+----------------------+--------+--------+
2339 * function bits 7..6
2340 * bits | 0 | 1 | 2 | 3
2341 * 10..8 | 00 | 01 | 10 | 11
2342 * -------+-------+-------+-------+-------
2343 * 0 000 | PMADDW| * | PSLLVW| PSRLVW
2344 * 1 001 | PMSUBW| * | * | *
2345 * 2 010 | PMFHI | PMFLO | PINTH | *
2346 * 3 011 | PMULTW| PDIVW | PCPYLD| *
2347 * 4 100 | PMADDH| PHMADH| PAND | PXOR
2348 * 5 101 | PMSUBH| PHMSBH| * | *
2349 * 6 110 | * | * | PEXEH | PREVH
2350 * 7 111 | PMULTH| PDIVBW| PEXEW | PROT3W
2353 #define MASK_MMI2(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
2355 MMI_OPC_2_PMADDW
= (0x00 << 6) | MMI_OPC_CLASS_MMI2
,
2356 MMI_OPC_2_PSLLVW
= (0x02 << 6) | MMI_OPC_CLASS_MMI2
,
2357 MMI_OPC_2_PSRLVW
= (0x03 << 6) | MMI_OPC_CLASS_MMI2
,
2358 MMI_OPC_2_PMSUBW
= (0x04 << 6) | MMI_OPC_CLASS_MMI2
,
2359 MMI_OPC_2_PMFHI
= (0x08 << 6) | MMI_OPC_CLASS_MMI2
,
2360 MMI_OPC_2_PMFLO
= (0x09 << 6) | MMI_OPC_CLASS_MMI2
,
2361 MMI_OPC_2_PINTH
= (0x0A << 6) | MMI_OPC_CLASS_MMI2
,
2362 MMI_OPC_2_PMULTW
= (0x0C << 6) | MMI_OPC_CLASS_MMI2
,
2363 MMI_OPC_2_PDIVW
= (0x0D << 6) | MMI_OPC_CLASS_MMI2
,
2364 MMI_OPC_2_PCPYLD
= (0x0E << 6) | MMI_OPC_CLASS_MMI2
,
2365 MMI_OPC_2_PMADDH
= (0x10 << 6) | MMI_OPC_CLASS_MMI2
,
2366 MMI_OPC_2_PHMADH
= (0x11 << 6) | MMI_OPC_CLASS_MMI2
,
2367 MMI_OPC_2_PAND
= (0x12 << 6) | MMI_OPC_CLASS_MMI2
,
2368 MMI_OPC_2_PXOR
= (0x13 << 6) | MMI_OPC_CLASS_MMI2
,
2369 MMI_OPC_2_PMSUBH
= (0x14 << 6) | MMI_OPC_CLASS_MMI2
,
2370 MMI_OPC_2_PHMSBH
= (0x15 << 6) | MMI_OPC_CLASS_MMI2
,
2371 MMI_OPC_2_PEXEH
= (0x1A << 6) | MMI_OPC_CLASS_MMI2
,
2372 MMI_OPC_2_PREVH
= (0x1B << 6) | MMI_OPC_CLASS_MMI2
,
2373 MMI_OPC_2_PMULTH
= (0x1C << 6) | MMI_OPC_CLASS_MMI2
,
2374 MMI_OPC_2_PDIVBW
= (0x1D << 6) | MMI_OPC_CLASS_MMI2
,
2375 MMI_OPC_2_PEXEW
= (0x1E << 6) | MMI_OPC_CLASS_MMI2
,
2376 MMI_OPC_2_PROT3W
= (0x1F << 6) | MMI_OPC_CLASS_MMI2
,
2380 * MMI instructions with opcode field = MMI and bits 5..0 = MMI3:
2383 * +--------+----------------------+--------+--------+
2384 * | MMI | |function| MMI3 |
2385 * +--------+----------------------+--------+--------+
2387 * function bits 7..6
2388 * bits | 0 | 1 | 2 | 3
2389 * 10..8 | 00 | 01 | 10 | 11
2390 * -------+-------+-------+-------+-------
2391 * 0 000 |PMADDUW| * | * | PSRAVW
2392 * 1 001 | * | * | * | *
2393 * 2 010 | PMTHI | PMTLO | PINTEH| *
2394 * 3 011 |PMULTUW| PDIVUW| PCPYUD| *
2395 * 4 100 | * | * | POR | PNOR
2396 * 5 101 | * | * | * | *
2397 * 6 110 | * | * | PEXCH | PCPYH
2398 * 7 111 | * | * | PEXCW | *
2401 #define MASK_MMI3(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
2403 MMI_OPC_3_PMADDUW
= (0x00 << 6) | MMI_OPC_CLASS_MMI3
,
2404 MMI_OPC_3_PSRAVW
= (0x03 << 6) | MMI_OPC_CLASS_MMI3
,
2405 MMI_OPC_3_PMTHI
= (0x08 << 6) | MMI_OPC_CLASS_MMI3
,
2406 MMI_OPC_3_PMTLO
= (0x09 << 6) | MMI_OPC_CLASS_MMI3
,
2407 MMI_OPC_3_PINTEH
= (0x0A << 6) | MMI_OPC_CLASS_MMI3
,
2408 MMI_OPC_3_PMULTUW
= (0x0C << 6) | MMI_OPC_CLASS_MMI3
,
2409 MMI_OPC_3_PDIVUW
= (0x0D << 6) | MMI_OPC_CLASS_MMI3
,
2410 MMI_OPC_3_PCPYUD
= (0x0E << 6) | MMI_OPC_CLASS_MMI3
,
2411 MMI_OPC_3_POR
= (0x12 << 6) | MMI_OPC_CLASS_MMI3
,
2412 MMI_OPC_3_PNOR
= (0x13 << 6) | MMI_OPC_CLASS_MMI3
,
2413 MMI_OPC_3_PEXCH
= (0x1A << 6) | MMI_OPC_CLASS_MMI3
,
2414 MMI_OPC_3_PCPYH
= (0x1B << 6) | MMI_OPC_CLASS_MMI3
,
2415 MMI_OPC_3_PEXCW
= (0x1E << 6) | MMI_OPC_CLASS_MMI3
,
2418 /* global register indices */
2419 TCGv cpu_gpr
[32], cpu_PC
;
2420 static TCGv cpu_HI
[MIPS_DSP_ACC
], cpu_LO
[MIPS_DSP_ACC
];
2421 static TCGv cpu_dspctrl
, btarget
;
2423 static TCGv cpu_lladdr
, cpu_llval
;
2424 static TCGv_i32 hflags
;
2425 TCGv_i32 fpu_fcr0
, fpu_fcr31
;
2426 TCGv_i64 fpu_f64
[32];
2427 static TCGv_i64 msa_wr_d
[64];
2429 #if defined(TARGET_MIPS64)
2430 /* Upper halves of R5900's 128-bit registers: MMRs (multimedia registers) */
2431 static TCGv_i64 cpu_mmr
[32];
2434 #if !defined(TARGET_MIPS64)
2436 static TCGv mxu_gpr
[NUMBER_OF_MXU_REGISTERS
- 1];
2440 #include "exec/gen-icount.h"
2442 #define gen_helper_0e0i(name, arg) do { \
2443 TCGv_i32 helper_tmp = tcg_const_i32(arg); \
2444 gen_helper_##name(cpu_env, helper_tmp); \
2445 tcg_temp_free_i32(helper_tmp); \
2448 #define gen_helper_0e1i(name, arg1, arg2) do { \
2449 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
2450 gen_helper_##name(cpu_env, arg1, helper_tmp); \
2451 tcg_temp_free_i32(helper_tmp); \
2454 #define gen_helper_1e0i(name, ret, arg1) do { \
2455 TCGv_i32 helper_tmp = tcg_const_i32(arg1); \
2456 gen_helper_##name(ret, cpu_env, helper_tmp); \
2457 tcg_temp_free_i32(helper_tmp); \
2460 #define gen_helper_1e1i(name, ret, arg1, arg2) do { \
2461 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
2462 gen_helper_##name(ret, cpu_env, arg1, helper_tmp); \
2463 tcg_temp_free_i32(helper_tmp); \
2466 #define gen_helper_0e2i(name, arg1, arg2, arg3) do { \
2467 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
2468 gen_helper_##name(cpu_env, arg1, arg2, helper_tmp); \
2469 tcg_temp_free_i32(helper_tmp); \
2472 #define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do { \
2473 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
2474 gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp); \
2475 tcg_temp_free_i32(helper_tmp); \
2478 #define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do { \
2479 TCGv_i32 helper_tmp = tcg_const_i32(arg4); \
2480 gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp); \
2481 tcg_temp_free_i32(helper_tmp); \
2484 #define DISAS_STOP DISAS_TARGET_0
2485 #define DISAS_EXIT DISAS_TARGET_1
2487 static const char * const regnames
[] = {
2488 "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
2489 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
2490 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
2491 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
2494 static const char * const regnames_HI
[] = {
2495 "HI0", "HI1", "HI2", "HI3",
2498 static const char * const regnames_LO
[] = {
2499 "LO0", "LO1", "LO2", "LO3",
2502 static const char * const fregnames
[] = {
2503 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
2504 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
2505 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
2506 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
2509 static const char * const msaregnames
[] = {
2510 "w0.d0", "w0.d1", "w1.d0", "w1.d1",
2511 "w2.d0", "w2.d1", "w3.d0", "w3.d1",
2512 "w4.d0", "w4.d1", "w5.d0", "w5.d1",
2513 "w6.d0", "w6.d1", "w7.d0", "w7.d1",
2514 "w8.d0", "w8.d1", "w9.d0", "w9.d1",
2515 "w10.d0", "w10.d1", "w11.d0", "w11.d1",
2516 "w12.d0", "w12.d1", "w13.d0", "w13.d1",
2517 "w14.d0", "w14.d1", "w15.d0", "w15.d1",
2518 "w16.d0", "w16.d1", "w17.d0", "w17.d1",
2519 "w18.d0", "w18.d1", "w19.d0", "w19.d1",
2520 "w20.d0", "w20.d1", "w21.d0", "w21.d1",
2521 "w22.d0", "w22.d1", "w23.d0", "w23.d1",
2522 "w24.d0", "w24.d1", "w25.d0", "w25.d1",
2523 "w26.d0", "w26.d1", "w27.d0", "w27.d1",
2524 "w28.d0", "w28.d1", "w29.d0", "w29.d1",
2525 "w30.d0", "w30.d1", "w31.d0", "w31.d1",
2528 #if !defined(TARGET_MIPS64)
2529 static const char * const mxuregnames
[] = {
2530 "XR1", "XR2", "XR3", "XR4", "XR5", "XR6", "XR7", "XR8",
2531 "XR9", "XR10", "XR11", "XR12", "XR13", "XR14", "XR15", "MXU_CR",
2535 /* General purpose registers moves. */
2536 void gen_load_gpr(TCGv t
, int reg
)
2539 tcg_gen_movi_tl(t
, 0);
2541 tcg_gen_mov_tl(t
, cpu_gpr
[reg
]);
2545 void gen_store_gpr(TCGv t
, int reg
)
2548 tcg_gen_mov_tl(cpu_gpr
[reg
], t
);
2552 /* Moves to/from shadow registers. */
2553 static inline void gen_load_srsgpr(int from
, int to
)
2555 TCGv t0
= tcg_temp_new();
2558 tcg_gen_movi_tl(t0
, 0);
2560 TCGv_i32 t2
= tcg_temp_new_i32();
2561 TCGv_ptr addr
= tcg_temp_new_ptr();
2563 tcg_gen_ld_i32(t2
, cpu_env
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
2564 tcg_gen_shri_i32(t2
, t2
, CP0SRSCtl_PSS
);
2565 tcg_gen_andi_i32(t2
, t2
, 0xf);
2566 tcg_gen_muli_i32(t2
, t2
, sizeof(target_ulong
) * 32);
2567 tcg_gen_ext_i32_ptr(addr
, t2
);
2568 tcg_gen_add_ptr(addr
, cpu_env
, addr
);
2570 tcg_gen_ld_tl(t0
, addr
, sizeof(target_ulong
) * from
);
2571 tcg_temp_free_ptr(addr
);
2572 tcg_temp_free_i32(t2
);
2574 gen_store_gpr(t0
, to
);
2578 static inline void gen_store_srsgpr(int from
, int to
)
2581 TCGv t0
= tcg_temp_new();
2582 TCGv_i32 t2
= tcg_temp_new_i32();
2583 TCGv_ptr addr
= tcg_temp_new_ptr();
2585 gen_load_gpr(t0
, from
);
2586 tcg_gen_ld_i32(t2
, cpu_env
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
2587 tcg_gen_shri_i32(t2
, t2
, CP0SRSCtl_PSS
);
2588 tcg_gen_andi_i32(t2
, t2
, 0xf);
2589 tcg_gen_muli_i32(t2
, t2
, sizeof(target_ulong
) * 32);
2590 tcg_gen_ext_i32_ptr(addr
, t2
);
2591 tcg_gen_add_ptr(addr
, cpu_env
, addr
);
2593 tcg_gen_st_tl(t0
, addr
, sizeof(target_ulong
) * to
);
2594 tcg_temp_free_ptr(addr
);
2595 tcg_temp_free_i32(t2
);
2600 #if !defined(TARGET_MIPS64)
2601 /* MXU General purpose registers moves. */
2602 static inline void gen_load_mxu_gpr(TCGv t
, unsigned int reg
)
2605 tcg_gen_movi_tl(t
, 0);
2606 } else if (reg
<= 15) {
2607 tcg_gen_mov_tl(t
, mxu_gpr
[reg
- 1]);
2611 static inline void gen_store_mxu_gpr(TCGv t
, unsigned int reg
)
2613 if (reg
> 0 && reg
<= 15) {
2614 tcg_gen_mov_tl(mxu_gpr
[reg
- 1], t
);
2618 /* MXU control register moves. */
2619 static inline void gen_load_mxu_cr(TCGv t
)
2621 tcg_gen_mov_tl(t
, mxu_CR
);
2624 static inline void gen_store_mxu_cr(TCGv t
)
2626 /* TODO: Add handling of RW rules for MXU_CR. */
2627 tcg_gen_mov_tl(mxu_CR
, t
);
2633 static inline void gen_save_pc(target_ulong pc
)
2635 tcg_gen_movi_tl(cpu_PC
, pc
);
2638 static inline void save_cpu_state(DisasContext
*ctx
, int do_save_pc
)
2640 LOG_DISAS("hflags %08x saved %08x\n", ctx
->hflags
, ctx
->saved_hflags
);
2641 if (do_save_pc
&& ctx
->base
.pc_next
!= ctx
->saved_pc
) {
2642 gen_save_pc(ctx
->base
.pc_next
);
2643 ctx
->saved_pc
= ctx
->base
.pc_next
;
2645 if (ctx
->hflags
!= ctx
->saved_hflags
) {
2646 tcg_gen_movi_i32(hflags
, ctx
->hflags
);
2647 ctx
->saved_hflags
= ctx
->hflags
;
2648 switch (ctx
->hflags
& MIPS_HFLAG_BMASK_BASE
) {
2654 tcg_gen_movi_tl(btarget
, ctx
->btarget
);
2660 static inline void restore_cpu_state(CPUMIPSState
*env
, DisasContext
*ctx
)
2662 ctx
->saved_hflags
= ctx
->hflags
;
2663 switch (ctx
->hflags
& MIPS_HFLAG_BMASK_BASE
) {
2669 ctx
->btarget
= env
->btarget
;
2674 void generate_exception_err(DisasContext
*ctx
, int excp
, int err
)
2676 TCGv_i32 texcp
= tcg_const_i32(excp
);
2677 TCGv_i32 terr
= tcg_const_i32(err
);
2678 save_cpu_state(ctx
, 1);
2679 gen_helper_raise_exception_err(cpu_env
, texcp
, terr
);
2680 tcg_temp_free_i32(terr
);
2681 tcg_temp_free_i32(texcp
);
2682 ctx
->base
.is_jmp
= DISAS_NORETURN
;
2685 void generate_exception(DisasContext
*ctx
, int excp
)
2687 gen_helper_0e0i(raise_exception
, excp
);
2690 void generate_exception_end(DisasContext
*ctx
, int excp
)
2692 generate_exception_err(ctx
, excp
, 0);
2695 void gen_reserved_instruction(DisasContext
*ctx
)
2697 generate_exception_end(ctx
, EXCP_RI
);
2700 /* Floating point register moves. */
2701 void gen_load_fpr32(DisasContext
*ctx
, TCGv_i32 t
, int reg
)
2703 if (ctx
->hflags
& MIPS_HFLAG_FRE
) {
2704 generate_exception(ctx
, EXCP_RI
);
2706 tcg_gen_extrl_i64_i32(t
, fpu_f64
[reg
]);
2709 void gen_store_fpr32(DisasContext
*ctx
, TCGv_i32 t
, int reg
)
2712 if (ctx
->hflags
& MIPS_HFLAG_FRE
) {
2713 generate_exception(ctx
, EXCP_RI
);
2715 t64
= tcg_temp_new_i64();
2716 tcg_gen_extu_i32_i64(t64
, t
);
2717 tcg_gen_deposit_i64(fpu_f64
[reg
], fpu_f64
[reg
], t64
, 0, 32);
2718 tcg_temp_free_i64(t64
);
2721 static void gen_load_fpr32h(DisasContext
*ctx
, TCGv_i32 t
, int reg
)
2723 if (ctx
->hflags
& MIPS_HFLAG_F64
) {
2724 tcg_gen_extrh_i64_i32(t
, fpu_f64
[reg
]);
2726 gen_load_fpr32(ctx
, t
, reg
| 1);
2730 static void gen_store_fpr32h(DisasContext
*ctx
, TCGv_i32 t
, int reg
)
2732 if (ctx
->hflags
& MIPS_HFLAG_F64
) {
2733 TCGv_i64 t64
= tcg_temp_new_i64();
2734 tcg_gen_extu_i32_i64(t64
, t
);
2735 tcg_gen_deposit_i64(fpu_f64
[reg
], fpu_f64
[reg
], t64
, 32, 32);
2736 tcg_temp_free_i64(t64
);
2738 gen_store_fpr32(ctx
, t
, reg
| 1);
2742 void gen_load_fpr64(DisasContext
*ctx
, TCGv_i64 t
, int reg
)
2744 if (ctx
->hflags
& MIPS_HFLAG_F64
) {
2745 tcg_gen_mov_i64(t
, fpu_f64
[reg
]);
2747 tcg_gen_concat32_i64(t
, fpu_f64
[reg
& ~1], fpu_f64
[reg
| 1]);
2751 void gen_store_fpr64(DisasContext
*ctx
, TCGv_i64 t
, int reg
)
2753 if (ctx
->hflags
& MIPS_HFLAG_F64
) {
2754 tcg_gen_mov_i64(fpu_f64
[reg
], t
);
2757 tcg_gen_deposit_i64(fpu_f64
[reg
& ~1], fpu_f64
[reg
& ~1], t
, 0, 32);
2758 t0
= tcg_temp_new_i64();
2759 tcg_gen_shri_i64(t0
, t
, 32);
2760 tcg_gen_deposit_i64(fpu_f64
[reg
| 1], fpu_f64
[reg
| 1], t0
, 0, 32);
2761 tcg_temp_free_i64(t0
);
2765 int get_fp_bit(int cc
)
2774 /* Addresses computation */
2775 void gen_op_addr_add(DisasContext
*ctx
, TCGv ret
, TCGv arg0
, TCGv arg1
)
2777 tcg_gen_add_tl(ret
, arg0
, arg1
);
2779 #if defined(TARGET_MIPS64)
2780 if (ctx
->hflags
& MIPS_HFLAG_AWRAP
) {
2781 tcg_gen_ext32s_i64(ret
, ret
);
2786 static inline void gen_op_addr_addi(DisasContext
*ctx
, TCGv ret
, TCGv base
,
2789 tcg_gen_addi_tl(ret
, base
, ofs
);
2791 #if defined(TARGET_MIPS64)
2792 if (ctx
->hflags
& MIPS_HFLAG_AWRAP
) {
2793 tcg_gen_ext32s_i64(ret
, ret
);
2798 /* Addresses computation (translation time) */
2799 static target_long
addr_add(DisasContext
*ctx
, target_long base
,
2802 target_long sum
= base
+ offset
;
2804 #if defined(TARGET_MIPS64)
2805 if (ctx
->hflags
& MIPS_HFLAG_AWRAP
) {
2812 /* Sign-extract the low 32-bits to a target_long. */
2813 void gen_move_low32(TCGv ret
, TCGv_i64 arg
)
2815 #if defined(TARGET_MIPS64)
2816 tcg_gen_ext32s_i64(ret
, arg
);
2818 tcg_gen_extrl_i64_i32(ret
, arg
);
2822 /* Sign-extract the high 32-bits to a target_long. */
2823 void gen_move_high32(TCGv ret
, TCGv_i64 arg
)
2825 #if defined(TARGET_MIPS64)
2826 tcg_gen_sari_i64(ret
, arg
, 32);
2828 tcg_gen_extrh_i64_i32(ret
, arg
);
2832 void check_cp0_enabled(DisasContext
*ctx
)
2834 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_CP0
))) {
2835 generate_exception_end(ctx
, EXCP_CpU
);
2839 void check_cp1_enabled(DisasContext
*ctx
)
2841 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_FPU
))) {
2842 generate_exception_err(ctx
, EXCP_CpU
, 1);
2847 * Verify that the processor is running with COP1X instructions enabled.
2848 * This is associated with the nabla symbol in the MIPS32 and MIPS64
2851 void check_cop1x(DisasContext
*ctx
)
2853 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_COP1X
))) {
2854 gen_reserved_instruction(ctx
);
2859 * Verify that the processor is running with 64-bit floating-point
2860 * operations enabled.
2862 void check_cp1_64bitmode(DisasContext
*ctx
)
2864 if (unlikely(~ctx
->hflags
& (MIPS_HFLAG_F64
| MIPS_HFLAG_COP1X
))) {
2865 gen_reserved_instruction(ctx
);
2870 * Verify if floating point register is valid; an operation is not defined
2871 * if bit 0 of any register specification is set and the FR bit in the
2872 * Status register equals zero, since the register numbers specify an
2873 * even-odd pair of adjacent coprocessor general registers. When the FR bit
2874 * in the Status register equals one, both even and odd register numbers
2875 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
2877 * Multiple 64 bit wide registers can be checked by calling
2878 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
2880 void check_cp1_registers(DisasContext
*ctx
, int regs
)
2882 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_F64
) && (regs
& 1))) {
2883 gen_reserved_instruction(ctx
);
2888 * Verify that the processor is running with DSP instructions enabled.
2889 * This is enabled by CP0 Status register MX(24) bit.
2891 static inline void check_dsp(DisasContext
*ctx
)
2893 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_DSP
))) {
2894 if (ctx
->insn_flags
& ASE_DSP
) {
2895 generate_exception_end(ctx
, EXCP_DSPDIS
);
2897 gen_reserved_instruction(ctx
);
2902 static inline void check_dsp_r2(DisasContext
*ctx
)
2904 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_DSP_R2
))) {
2905 if (ctx
->insn_flags
& ASE_DSP
) {
2906 generate_exception_end(ctx
, EXCP_DSPDIS
);
2908 gen_reserved_instruction(ctx
);
2913 static inline void check_dsp_r3(DisasContext
*ctx
)
2915 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_DSP_R3
))) {
2916 if (ctx
->insn_flags
& ASE_DSP
) {
2917 generate_exception_end(ctx
, EXCP_DSPDIS
);
2919 gen_reserved_instruction(ctx
);
2925 * This code generates a "reserved instruction" exception if the
2926 * CPU does not support the instruction set corresponding to flags.
2928 void check_insn(DisasContext
*ctx
, uint64_t flags
)
2930 if (unlikely(!(ctx
->insn_flags
& flags
))) {
2931 gen_reserved_instruction(ctx
);
2936 * This code generates a "reserved instruction" exception if the
2937 * CPU has corresponding flag set which indicates that the instruction
2940 static inline void check_insn_opc_removed(DisasContext
*ctx
, uint64_t flags
)
2942 if (unlikely(ctx
->insn_flags
& flags
)) {
2943 gen_reserved_instruction(ctx
);
2948 * The Linux kernel traps certain reserved instruction exceptions to
2949 * emulate the corresponding instructions. QEMU is the kernel in user
2950 * mode, so those traps are emulated by accepting the instructions.
2952 * A reserved instruction exception is generated for flagged CPUs if
2953 * QEMU runs in system mode.
2955 static inline void check_insn_opc_user_only(DisasContext
*ctx
, uint64_t flags
)
2957 #ifndef CONFIG_USER_ONLY
2958 check_insn_opc_removed(ctx
, flags
);
2963 * This code generates a "reserved instruction" exception if the
2964 * CPU does not support 64-bit paired-single (PS) floating point data type.
2966 static inline void check_ps(DisasContext
*ctx
)
2968 if (unlikely(!ctx
->ps
)) {
2969 generate_exception(ctx
, EXCP_RI
);
2971 check_cp1_64bitmode(ctx
);
2975 * This code generates a "reserved instruction" exception if cpu is not
2976 * 64-bit or 64-bit instructions are not enabled.
2978 void check_mips_64(DisasContext
*ctx
)
2980 if (unlikely((TARGET_LONG_BITS
!= 64) || !(ctx
->hflags
& MIPS_HFLAG_64
))) {
2981 gen_reserved_instruction(ctx
);
2985 #ifndef CONFIG_USER_ONLY
2986 static inline void check_mvh(DisasContext
*ctx
)
2988 if (unlikely(!ctx
->mvh
)) {
2989 generate_exception(ctx
, EXCP_RI
);
2995 * This code generates a "reserved instruction" exception if the
2996 * Config5 XNP bit is set.
2998 static inline void check_xnp(DisasContext
*ctx
)
3000 if (unlikely(ctx
->CP0_Config5
& (1 << CP0C5_XNP
))) {
3001 gen_reserved_instruction(ctx
);
3005 #ifndef CONFIG_USER_ONLY
3007 * This code generates a "reserved instruction" exception if the
3008 * Config3 PW bit is NOT set.
3010 static inline void check_pw(DisasContext
*ctx
)
3012 if (unlikely(!(ctx
->CP0_Config3
& (1 << CP0C3_PW
)))) {
3013 gen_reserved_instruction(ctx
);
3019 * This code generates a "reserved instruction" exception if the
3020 * Config3 MT bit is NOT set.
3022 static inline void check_mt(DisasContext
*ctx
)
3024 if (unlikely(!(ctx
->CP0_Config3
& (1 << CP0C3_MT
)))) {
3025 gen_reserved_instruction(ctx
);
3029 #ifndef CONFIG_USER_ONLY
3031 * This code generates a "coprocessor unusable" exception if CP0 is not
3032 * available, and, if that is not the case, generates a "reserved instruction"
3033 * exception if the Config5 MT bit is NOT set. This is needed for availability
3034 * control of some of MT ASE instructions.
3036 static inline void check_cp0_mt(DisasContext
*ctx
)
3038 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_CP0
))) {
3039 generate_exception_end(ctx
, EXCP_CpU
);
3041 if (unlikely(!(ctx
->CP0_Config3
& (1 << CP0C3_MT
)))) {
3042 gen_reserved_instruction(ctx
);
3049 * This code generates a "reserved instruction" exception if the
3050 * Config5 NMS bit is set.
3052 static inline void check_nms(DisasContext
*ctx
)
3054 if (unlikely(ctx
->CP0_Config5
& (1 << CP0C5_NMS
))) {
3055 gen_reserved_instruction(ctx
);
3060 * This code generates a "reserved instruction" exception if the
3061 * Config5 NMS bit is set, and Config1 DL, Config1 IL, Config2 SL,
3062 * Config2 TL, and Config5 L2C are unset.
3064 static inline void check_nms_dl_il_sl_tl_l2c(DisasContext
*ctx
)
3066 if (unlikely((ctx
->CP0_Config5
& (1 << CP0C5_NMS
)) &&
3067 !(ctx
->CP0_Config1
& (1 << CP0C1_DL
)) &&
3068 !(ctx
->CP0_Config1
& (1 << CP0C1_IL
)) &&
3069 !(ctx
->CP0_Config2
& (1 << CP0C2_SL
)) &&
3070 !(ctx
->CP0_Config2
& (1 << CP0C2_TL
)) &&
3071 !(ctx
->CP0_Config5
& (1 << CP0C5_L2C
)))) {
3072 gen_reserved_instruction(ctx
);
3077 * This code generates a "reserved instruction" exception if the
3078 * Config5 EVA bit is NOT set.
3080 static inline void check_eva(DisasContext
*ctx
)
3082 if (unlikely(!(ctx
->CP0_Config5
& (1 << CP0C5_EVA
)))) {
3083 gen_reserved_instruction(ctx
);
3089 * Define small wrappers for gen_load_fpr* so that we have a uniform
3090 * calling interface for 32 and 64-bit FPRs. No sense in changing
3091 * all callers for gen_load_fpr32 when we need the CTX parameter for
3094 #define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(ctx, x, y)
3095 #define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
3096 #define FOP_CONDS(type, abs, fmt, ifmt, bits) \
3097 static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
3098 int ft, int fs, int cc) \
3100 TCGv_i##bits fp0 = tcg_temp_new_i##bits(); \
3101 TCGv_i##bits fp1 = tcg_temp_new_i##bits(); \
3110 check_cp1_registers(ctx, fs | ft); \
3118 gen_ldcmp_fpr##bits(ctx, fp0, fs); \
3119 gen_ldcmp_fpr##bits(ctx, fp1, ft); \
3122 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); \
3125 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); \
3128 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); \
3131 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); \
3134 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); \
3137 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); \
3140 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); \
3143 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); \
3146 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); \
3149 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); \
3152 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); \
3155 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); \
3158 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); \
3161 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); \
3164 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); \
3167 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); \
3172 tcg_temp_free_i##bits(fp0); \
3173 tcg_temp_free_i##bits(fp1); \
3176 FOP_CONDS(, 0, d
, FMT_D
, 64)
3177 FOP_CONDS(abs
, 1, d
, FMT_D
, 64)
3178 FOP_CONDS(, 0, s
, FMT_S
, 32)
3179 FOP_CONDS(abs
, 1, s
, FMT_S
, 32)
3180 FOP_CONDS(, 0, ps
, FMT_PS
, 64)
3181 FOP_CONDS(abs
, 1, ps
, FMT_PS
, 64)
3184 #define FOP_CONDNS(fmt, ifmt, bits, STORE) \
3185 static inline void gen_r6_cmp_ ## fmt(DisasContext *ctx, int n, \
3186 int ft, int fs, int fd) \
3188 TCGv_i ## bits fp0 = tcg_temp_new_i ## bits(); \
3189 TCGv_i ## bits fp1 = tcg_temp_new_i ## bits(); \
3190 if (ifmt == FMT_D) { \
3191 check_cp1_registers(ctx, fs | ft | fd); \
3193 gen_ldcmp_fpr ## bits(ctx, fp0, fs); \
3194 gen_ldcmp_fpr ## bits(ctx, fp1, ft); \
3197 gen_helper_r6_cmp_ ## fmt ## _af(fp0, cpu_env, fp0, fp1); \
3200 gen_helper_r6_cmp_ ## fmt ## _un(fp0, cpu_env, fp0, fp1); \
3203 gen_helper_r6_cmp_ ## fmt ## _eq(fp0, cpu_env, fp0, fp1); \
3206 gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, cpu_env, fp0, fp1); \
3209 gen_helper_r6_cmp_ ## fmt ## _lt(fp0, cpu_env, fp0, fp1); \
3212 gen_helper_r6_cmp_ ## fmt ## _ult(fp0, cpu_env, fp0, fp1); \
3215 gen_helper_r6_cmp_ ## fmt ## _le(fp0, cpu_env, fp0, fp1); \
3218 gen_helper_r6_cmp_ ## fmt ## _ule(fp0, cpu_env, fp0, fp1); \
3221 gen_helper_r6_cmp_ ## fmt ## _saf(fp0, cpu_env, fp0, fp1); \
3224 gen_helper_r6_cmp_ ## fmt ## _sun(fp0, cpu_env, fp0, fp1); \
3227 gen_helper_r6_cmp_ ## fmt ## _seq(fp0, cpu_env, fp0, fp1); \
3230 gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, cpu_env, fp0, fp1); \
3233 gen_helper_r6_cmp_ ## fmt ## _slt(fp0, cpu_env, fp0, fp1); \
3236 gen_helper_r6_cmp_ ## fmt ## _sult(fp0, cpu_env, fp0, fp1); \
3239 gen_helper_r6_cmp_ ## fmt ## _sle(fp0, cpu_env, fp0, fp1); \
3242 gen_helper_r6_cmp_ ## fmt ## _sule(fp0, cpu_env, fp0, fp1); \
3245 gen_helper_r6_cmp_ ## fmt ## _or(fp0, cpu_env, fp0, fp1); \
3248 gen_helper_r6_cmp_ ## fmt ## _une(fp0, cpu_env, fp0, fp1); \
3251 gen_helper_r6_cmp_ ## fmt ## _ne(fp0, cpu_env, fp0, fp1); \
3254 gen_helper_r6_cmp_ ## fmt ## _sor(fp0, cpu_env, fp0, fp1); \
3257 gen_helper_r6_cmp_ ## fmt ## _sune(fp0, cpu_env, fp0, fp1); \
3260 gen_helper_r6_cmp_ ## fmt ## _sne(fp0, cpu_env, fp0, fp1); \
3266 tcg_temp_free_i ## bits(fp0); \
3267 tcg_temp_free_i ## bits(fp1); \
3270 FOP_CONDNS(d
, FMT_D
, 64, gen_store_fpr64(ctx
, fp0
, fd
))
3271 FOP_CONDNS(s
, FMT_S
, 32, gen_store_fpr32(ctx
, fp0
, fd
))
3273 #undef gen_ldcmp_fpr32
3274 #undef gen_ldcmp_fpr64
3276 /* load/store instructions. */
3277 #ifdef CONFIG_USER_ONLY
3278 #define OP_LD_ATOMIC(insn, fname) \
3279 static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \
3280 DisasContext *ctx) \
3282 TCGv t0 = tcg_temp_new(); \
3283 tcg_gen_mov_tl(t0, arg1); \
3284 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
3285 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
3286 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
3287 tcg_temp_free(t0); \
3290 #define OP_LD_ATOMIC(insn, fname) \
3291 static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \
3292 DisasContext *ctx) \
3294 gen_helper_1e1i(insn, ret, arg1, mem_idx); \
3297 OP_LD_ATOMIC(ll
, ld32s
);
3298 #if defined(TARGET_MIPS64)
3299 OP_LD_ATOMIC(lld
, ld64
);
3303 void gen_base_offset_addr(DisasContext
*ctx
, TCGv addr
, int base
, int offset
)
3306 tcg_gen_movi_tl(addr
, offset
);
3307 } else if (offset
== 0) {
3308 gen_load_gpr(addr
, base
);
3310 tcg_gen_movi_tl(addr
, offset
);
3311 gen_op_addr_add(ctx
, addr
, cpu_gpr
[base
], addr
);
3315 static target_ulong
pc_relative_pc(DisasContext
*ctx
)
3317 target_ulong pc
= ctx
->base
.pc_next
;
3319 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
3320 int branch_bytes
= ctx
->hflags
& MIPS_HFLAG_BDS16
? 2 : 4;
3325 pc
&= ~(target_ulong
)3;
3330 static void gen_ld(DisasContext
*ctx
, uint32_t opc
,
3331 int rt
, int base
, int offset
)
3334 int mem_idx
= ctx
->mem_idx
;
3336 if (rt
== 0 && ctx
->insn_flags
& (INSN_LOONGSON2E
| INSN_LOONGSON2F
|
3339 * Loongson CPU uses a load to zero register for prefetch.
3340 * We emulate it as a NOP. On other CPU we must perform the
3341 * actual memory access.
3346 t0
= tcg_temp_new();
3347 gen_base_offset_addr(ctx
, t0
, base
, offset
);
3350 #if defined(TARGET_MIPS64)
3352 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEUL
|
3353 ctx
->default_tcg_memop_mask
);
3354 gen_store_gpr(t0
, rt
);
3357 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEQ
|
3358 ctx
->default_tcg_memop_mask
);
3359 gen_store_gpr(t0
, rt
);
3363 op_ld_lld(t0
, t0
, mem_idx
, ctx
);
3364 gen_store_gpr(t0
, rt
);
3367 t1
= tcg_temp_new();
3369 * Do a byte access to possibly trigger a page
3370 * fault with the unaligned address.
3372 tcg_gen_qemu_ld_tl(t1
, t0
, mem_idx
, MO_UB
);
3373 tcg_gen_andi_tl(t1
, t0
, 7);
3374 #ifndef TARGET_WORDS_BIGENDIAN
3375 tcg_gen_xori_tl(t1
, t1
, 7);
3377 tcg_gen_shli_tl(t1
, t1
, 3);
3378 tcg_gen_andi_tl(t0
, t0
, ~7);
3379 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEQ
);
3380 tcg_gen_shl_tl(t0
, t0
, t1
);
3381 t2
= tcg_const_tl(-1);
3382 tcg_gen_shl_tl(t2
, t2
, t1
);
3383 gen_load_gpr(t1
, rt
);
3384 tcg_gen_andc_tl(t1
, t1
, t2
);
3386 tcg_gen_or_tl(t0
, t0
, t1
);
3388 gen_store_gpr(t0
, rt
);
3391 t1
= tcg_temp_new();
3393 * Do a byte access to possibly trigger a page
3394 * fault with the unaligned address.
3396 tcg_gen_qemu_ld_tl(t1
, t0
, mem_idx
, MO_UB
);
3397 tcg_gen_andi_tl(t1
, t0
, 7);
3398 #ifdef TARGET_WORDS_BIGENDIAN
3399 tcg_gen_xori_tl(t1
, t1
, 7);
3401 tcg_gen_shli_tl(t1
, t1
, 3);
3402 tcg_gen_andi_tl(t0
, t0
, ~7);
3403 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEQ
);
3404 tcg_gen_shr_tl(t0
, t0
, t1
);
3405 tcg_gen_xori_tl(t1
, t1
, 63);
3406 t2
= tcg_const_tl(0xfffffffffffffffeull
);
3407 tcg_gen_shl_tl(t2
, t2
, t1
);
3408 gen_load_gpr(t1
, rt
);
3409 tcg_gen_and_tl(t1
, t1
, t2
);
3411 tcg_gen_or_tl(t0
, t0
, t1
);
3413 gen_store_gpr(t0
, rt
);
3416 t1
= tcg_const_tl(pc_relative_pc(ctx
));
3417 gen_op_addr_add(ctx
, t0
, t0
, t1
);
3419 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEQ
);
3420 gen_store_gpr(t0
, rt
);
3424 t1
= tcg_const_tl(pc_relative_pc(ctx
));
3425 gen_op_addr_add(ctx
, t0
, t0
, t1
);
3427 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TESL
);
3428 gen_store_gpr(t0
, rt
);
3431 mem_idx
= MIPS_HFLAG_UM
;
3434 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TESL
|
3435 ctx
->default_tcg_memop_mask
);
3436 gen_store_gpr(t0
, rt
);
3439 mem_idx
= MIPS_HFLAG_UM
;
3442 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TESW
|
3443 ctx
->default_tcg_memop_mask
);
3444 gen_store_gpr(t0
, rt
);
3447 mem_idx
= MIPS_HFLAG_UM
;
3450 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEUW
|
3451 ctx
->default_tcg_memop_mask
);
3452 gen_store_gpr(t0
, rt
);
3455 mem_idx
= MIPS_HFLAG_UM
;
3458 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_SB
);
3459 gen_store_gpr(t0
, rt
);
3462 mem_idx
= MIPS_HFLAG_UM
;
3465 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_UB
);
3466 gen_store_gpr(t0
, rt
);
3469 mem_idx
= MIPS_HFLAG_UM
;
3472 t1
= tcg_temp_new();
3474 * Do a byte access to possibly trigger a page
3475 * fault with the unaligned address.
3477 tcg_gen_qemu_ld_tl(t1
, t0
, mem_idx
, MO_UB
);
3478 tcg_gen_andi_tl(t1
, t0
, 3);
3479 #ifndef TARGET_WORDS_BIGENDIAN
3480 tcg_gen_xori_tl(t1
, t1
, 3);
3482 tcg_gen_shli_tl(t1
, t1
, 3);
3483 tcg_gen_andi_tl(t0
, t0
, ~3);
3484 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEUL
);
3485 tcg_gen_shl_tl(t0
, t0
, t1
);
3486 t2
= tcg_const_tl(-1);
3487 tcg_gen_shl_tl(t2
, t2
, t1
);
3488 gen_load_gpr(t1
, rt
);
3489 tcg_gen_andc_tl(t1
, t1
, t2
);
3491 tcg_gen_or_tl(t0
, t0
, t1
);
3493 tcg_gen_ext32s_tl(t0
, t0
);
3494 gen_store_gpr(t0
, rt
);
3497 mem_idx
= MIPS_HFLAG_UM
;
3500 t1
= tcg_temp_new();
3502 * Do a byte access to possibly trigger a page
3503 * fault with the unaligned address.
3505 tcg_gen_qemu_ld_tl(t1
, t0
, mem_idx
, MO_UB
);
3506 tcg_gen_andi_tl(t1
, t0
, 3);
3507 #ifdef TARGET_WORDS_BIGENDIAN
3508 tcg_gen_xori_tl(t1
, t1
, 3);
3510 tcg_gen_shli_tl(t1
, t1
, 3);
3511 tcg_gen_andi_tl(t0
, t0
, ~3);
3512 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEUL
);
3513 tcg_gen_shr_tl(t0
, t0
, t1
);
3514 tcg_gen_xori_tl(t1
, t1
, 31);
3515 t2
= tcg_const_tl(0xfffffffeull
);
3516 tcg_gen_shl_tl(t2
, t2
, t1
);
3517 gen_load_gpr(t1
, rt
);
3518 tcg_gen_and_tl(t1
, t1
, t2
);
3520 tcg_gen_or_tl(t0
, t0
, t1
);
3522 tcg_gen_ext32s_tl(t0
, t0
);
3523 gen_store_gpr(t0
, rt
);
3526 mem_idx
= MIPS_HFLAG_UM
;
3530 op_ld_ll(t0
, t0
, mem_idx
, ctx
);
3531 gen_store_gpr(t0
, rt
);
3537 static void gen_llwp(DisasContext
*ctx
, uint32_t base
, int16_t offset
,
3538 uint32_t reg1
, uint32_t reg2
)
3540 TCGv taddr
= tcg_temp_new();
3541 TCGv_i64 tval
= tcg_temp_new_i64();
3542 TCGv tmp1
= tcg_temp_new();
3543 TCGv tmp2
= tcg_temp_new();
3545 gen_base_offset_addr(ctx
, taddr
, base
, offset
);
3546 tcg_gen_qemu_ld64(tval
, taddr
, ctx
->mem_idx
);
3547 #ifdef TARGET_WORDS_BIGENDIAN
3548 tcg_gen_extr_i64_tl(tmp2
, tmp1
, tval
);
3550 tcg_gen_extr_i64_tl(tmp1
, tmp2
, tval
);
3552 gen_store_gpr(tmp1
, reg1
);
3553 tcg_temp_free(tmp1
);
3554 gen_store_gpr(tmp2
, reg2
);
3555 tcg_temp_free(tmp2
);
3556 tcg_gen_st_i64(tval
, cpu_env
, offsetof(CPUMIPSState
, llval_wp
));
3557 tcg_temp_free_i64(tval
);
3558 tcg_gen_st_tl(taddr
, cpu_env
, offsetof(CPUMIPSState
, lladdr
));
3559 tcg_temp_free(taddr
);
3563 static void gen_st(DisasContext
*ctx
, uint32_t opc
, int rt
,
3564 int base
, int offset
)
3566 TCGv t0
= tcg_temp_new();
3567 TCGv t1
= tcg_temp_new();
3568 int mem_idx
= ctx
->mem_idx
;
3570 gen_base_offset_addr(ctx
, t0
, base
, offset
);
3571 gen_load_gpr(t1
, rt
);
3573 #if defined(TARGET_MIPS64)
3575 tcg_gen_qemu_st_tl(t1
, t0
, mem_idx
, MO_TEQ
|
3576 ctx
->default_tcg_memop_mask
);
3579 gen_helper_0e2i(sdl
, t1
, t0
, mem_idx
);
3582 gen_helper_0e2i(sdr
, t1
, t0
, mem_idx
);
3586 mem_idx
= MIPS_HFLAG_UM
;
3589 tcg_gen_qemu_st_tl(t1
, t0
, mem_idx
, MO_TEUL
|
3590 ctx
->default_tcg_memop_mask
);
3593 mem_idx
= MIPS_HFLAG_UM
;
3596 tcg_gen_qemu_st_tl(t1
, t0
, mem_idx
, MO_TEUW
|
3597 ctx
->default_tcg_memop_mask
);
3600 mem_idx
= MIPS_HFLAG_UM
;
3603 tcg_gen_qemu_st_tl(t1
, t0
, mem_idx
, MO_8
);
3606 mem_idx
= MIPS_HFLAG_UM
;
3609 gen_helper_0e2i(swl
, t1
, t0
, mem_idx
);
3612 mem_idx
= MIPS_HFLAG_UM
;
3615 gen_helper_0e2i(swr
, t1
, t0
, mem_idx
);
3623 /* Store conditional */
3624 static void gen_st_cond(DisasContext
*ctx
, int rt
, int base
, int offset
,
3625 MemOp tcg_mo
, bool eva
)
3628 TCGLabel
*l1
= gen_new_label();
3629 TCGLabel
*done
= gen_new_label();
3631 t0
= tcg_temp_new();
3632 addr
= tcg_temp_new();
3633 /* compare the address against that of the preceding LL */
3634 gen_base_offset_addr(ctx
, addr
, base
, offset
);
3635 tcg_gen_brcond_tl(TCG_COND_EQ
, addr
, cpu_lladdr
, l1
);
3636 tcg_temp_free(addr
);
3637 tcg_gen_movi_tl(t0
, 0);
3638 gen_store_gpr(t0
, rt
);
3642 /* generate cmpxchg */
3643 val
= tcg_temp_new();
3644 gen_load_gpr(val
, rt
);
3645 tcg_gen_atomic_cmpxchg_tl(t0
, cpu_lladdr
, cpu_llval
, val
,
3646 eva
? MIPS_HFLAG_UM
: ctx
->mem_idx
, tcg_mo
);
3647 tcg_gen_setcond_tl(TCG_COND_EQ
, t0
, t0
, cpu_llval
);
3648 gen_store_gpr(t0
, rt
);
3651 gen_set_label(done
);
3656 static void gen_scwp(DisasContext
*ctx
, uint32_t base
, int16_t offset
,
3657 uint32_t reg1
, uint32_t reg2
, bool eva
)
3659 TCGv taddr
= tcg_temp_local_new();
3660 TCGv lladdr
= tcg_temp_local_new();
3661 TCGv_i64 tval
= tcg_temp_new_i64();
3662 TCGv_i64 llval
= tcg_temp_new_i64();
3663 TCGv_i64 val
= tcg_temp_new_i64();
3664 TCGv tmp1
= tcg_temp_new();
3665 TCGv tmp2
= tcg_temp_new();
3666 TCGLabel
*lab_fail
= gen_new_label();
3667 TCGLabel
*lab_done
= gen_new_label();
3669 gen_base_offset_addr(ctx
, taddr
, base
, offset
);
3671 tcg_gen_ld_tl(lladdr
, cpu_env
, offsetof(CPUMIPSState
, lladdr
));
3672 tcg_gen_brcond_tl(TCG_COND_NE
, taddr
, lladdr
, lab_fail
);
3674 gen_load_gpr(tmp1
, reg1
);
3675 gen_load_gpr(tmp2
, reg2
);
3677 #ifdef TARGET_WORDS_BIGENDIAN
3678 tcg_gen_concat_tl_i64(tval
, tmp2
, tmp1
);
3680 tcg_gen_concat_tl_i64(tval
, tmp1
, tmp2
);
3683 tcg_gen_ld_i64(llval
, cpu_env
, offsetof(CPUMIPSState
, llval_wp
));
3684 tcg_gen_atomic_cmpxchg_i64(val
, taddr
, llval
, tval
,
3685 eva
? MIPS_HFLAG_UM
: ctx
->mem_idx
, MO_64
);
3687 tcg_gen_movi_tl(cpu_gpr
[reg1
], 1);
3689 tcg_gen_brcond_i64(TCG_COND_EQ
, val
, llval
, lab_done
);
3691 gen_set_label(lab_fail
);
3694 tcg_gen_movi_tl(cpu_gpr
[reg1
], 0);
3696 gen_set_label(lab_done
);
3697 tcg_gen_movi_tl(lladdr
, -1);
3698 tcg_gen_st_tl(lladdr
, cpu_env
, offsetof(CPUMIPSState
, lladdr
));
3701 /* Load and store */
3702 static void gen_flt_ldst(DisasContext
*ctx
, uint32_t opc
, int ft
,
3706 * Don't do NOP if destination is zero: we must perform the actual
3712 TCGv_i32 fp0
= tcg_temp_new_i32();
3713 tcg_gen_qemu_ld_i32(fp0
, t0
, ctx
->mem_idx
, MO_TESL
|
3714 ctx
->default_tcg_memop_mask
);
3715 gen_store_fpr32(ctx
, fp0
, ft
);
3716 tcg_temp_free_i32(fp0
);
3721 TCGv_i32 fp0
= tcg_temp_new_i32();
3722 gen_load_fpr32(ctx
, fp0
, ft
);
3723 tcg_gen_qemu_st_i32(fp0
, t0
, ctx
->mem_idx
, MO_TEUL
|
3724 ctx
->default_tcg_memop_mask
);
3725 tcg_temp_free_i32(fp0
);
3730 TCGv_i64 fp0
= tcg_temp_new_i64();
3731 tcg_gen_qemu_ld_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
|
3732 ctx
->default_tcg_memop_mask
);
3733 gen_store_fpr64(ctx
, fp0
, ft
);
3734 tcg_temp_free_i64(fp0
);
3739 TCGv_i64 fp0
= tcg_temp_new_i64();
3740 gen_load_fpr64(ctx
, fp0
, ft
);
3741 tcg_gen_qemu_st_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
|
3742 ctx
->default_tcg_memop_mask
);
3743 tcg_temp_free_i64(fp0
);
3747 MIPS_INVAL("flt_ldst");
3748 gen_reserved_instruction(ctx
);
3753 static void gen_cop1_ldst(DisasContext
*ctx
, uint32_t op
, int rt
,
3754 int rs
, int16_t imm
)
3756 TCGv t0
= tcg_temp_new();
3758 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
3759 check_cp1_enabled(ctx
);
3763 check_insn(ctx
, ISA_MIPS2
);
3766 gen_base_offset_addr(ctx
, t0
, rs
, imm
);
3767 gen_flt_ldst(ctx
, op
, rt
, t0
);
3770 generate_exception_err(ctx
, EXCP_CpU
, 1);
3775 /* Arithmetic with immediate operand */
3776 static void gen_arith_imm(DisasContext
*ctx
, uint32_t opc
,
3777 int rt
, int rs
, int imm
)
3779 target_ulong uimm
= (target_long
)imm
; /* Sign extend to 32/64 bits */
3781 if (rt
== 0 && opc
!= OPC_ADDI
&& opc
!= OPC_DADDI
) {
3783 * If no destination, treat it as a NOP.
3784 * For addi, we must generate the overflow exception when needed.
3791 TCGv t0
= tcg_temp_local_new();
3792 TCGv t1
= tcg_temp_new();
3793 TCGv t2
= tcg_temp_new();
3794 TCGLabel
*l1
= gen_new_label();
3796 gen_load_gpr(t1
, rs
);
3797 tcg_gen_addi_tl(t0
, t1
, uimm
);
3798 tcg_gen_ext32s_tl(t0
, t0
);
3800 tcg_gen_xori_tl(t1
, t1
, ~uimm
);
3801 tcg_gen_xori_tl(t2
, t0
, uimm
);
3802 tcg_gen_and_tl(t1
, t1
, t2
);
3804 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
3806 /* operands of same sign, result different sign */
3807 generate_exception(ctx
, EXCP_OVERFLOW
);
3809 tcg_gen_ext32s_tl(t0
, t0
);
3810 gen_store_gpr(t0
, rt
);
3816 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
3817 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
3819 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
3822 #if defined(TARGET_MIPS64)
3825 TCGv t0
= tcg_temp_local_new();
3826 TCGv t1
= tcg_temp_new();
3827 TCGv t2
= tcg_temp_new();
3828 TCGLabel
*l1
= gen_new_label();
3830 gen_load_gpr(t1
, rs
);
3831 tcg_gen_addi_tl(t0
, t1
, uimm
);
3833 tcg_gen_xori_tl(t1
, t1
, ~uimm
);
3834 tcg_gen_xori_tl(t2
, t0
, uimm
);
3835 tcg_gen_and_tl(t1
, t1
, t2
);
3837 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
3839 /* operands of same sign, result different sign */
3840 generate_exception(ctx
, EXCP_OVERFLOW
);
3842 gen_store_gpr(t0
, rt
);
3848 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
3850 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
3857 /* Logic with immediate operand */
3858 static void gen_logic_imm(DisasContext
*ctx
, uint32_t opc
,
3859 int rt
, int rs
, int16_t imm
)
3864 /* If no destination, treat it as a NOP. */
3867 uimm
= (uint16_t)imm
;
3870 if (likely(rs
!= 0)) {
3871 tcg_gen_andi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
3873 tcg_gen_movi_tl(cpu_gpr
[rt
], 0);
3878 tcg_gen_ori_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
3880 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
3884 if (likely(rs
!= 0)) {
3885 tcg_gen_xori_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
3887 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
3891 if (rs
!= 0 && (ctx
->insn_flags
& ISA_MIPS_R6
)) {
3893 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], imm
<< 16);
3894 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
3896 tcg_gen_movi_tl(cpu_gpr
[rt
], imm
<< 16);
3905 /* Set on less than with immediate operand */
3906 static void gen_slt_imm(DisasContext
*ctx
, uint32_t opc
,
3907 int rt
, int rs
, int16_t imm
)
3909 target_ulong uimm
= (target_long
)imm
; /* Sign extend to 32/64 bits */
3913 /* If no destination, treat it as a NOP. */
3916 t0
= tcg_temp_new();
3917 gen_load_gpr(t0
, rs
);
3920 tcg_gen_setcondi_tl(TCG_COND_LT
, cpu_gpr
[rt
], t0
, uimm
);
3923 tcg_gen_setcondi_tl(TCG_COND_LTU
, cpu_gpr
[rt
], t0
, uimm
);
3929 /* Shifts with immediate operand */
3930 static void gen_shift_imm(DisasContext
*ctx
, uint32_t opc
,
3931 int rt
, int rs
, int16_t imm
)
3933 target_ulong uimm
= ((uint16_t)imm
) & 0x1f;
3937 /* If no destination, treat it as a NOP. */
3941 t0
= tcg_temp_new();
3942 gen_load_gpr(t0
, rs
);
3945 tcg_gen_shli_tl(t0
, t0
, uimm
);
3946 tcg_gen_ext32s_tl(cpu_gpr
[rt
], t0
);
3949 tcg_gen_sari_tl(cpu_gpr
[rt
], t0
, uimm
);
3953 tcg_gen_ext32u_tl(t0
, t0
);
3954 tcg_gen_shri_tl(cpu_gpr
[rt
], t0
, uimm
);
3956 tcg_gen_ext32s_tl(cpu_gpr
[rt
], t0
);
3961 TCGv_i32 t1
= tcg_temp_new_i32();
3963 tcg_gen_trunc_tl_i32(t1
, t0
);
3964 tcg_gen_rotri_i32(t1
, t1
, uimm
);
3965 tcg_gen_ext_i32_tl(cpu_gpr
[rt
], t1
);
3966 tcg_temp_free_i32(t1
);
3968 tcg_gen_ext32s_tl(cpu_gpr
[rt
], t0
);
3971 #if defined(TARGET_MIPS64)
3973 tcg_gen_shli_tl(cpu_gpr
[rt
], t0
, uimm
);
3976 tcg_gen_sari_tl(cpu_gpr
[rt
], t0
, uimm
);
3979 tcg_gen_shri_tl(cpu_gpr
[rt
], t0
, uimm
);
3983 tcg_gen_rotri_tl(cpu_gpr
[rt
], t0
, uimm
);
3985 tcg_gen_mov_tl(cpu_gpr
[rt
], t0
);
3989 tcg_gen_shli_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
3992 tcg_gen_sari_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
3995 tcg_gen_shri_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
3998 tcg_gen_rotri_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
4006 static void gen_arith(DisasContext
*ctx
, uint32_t opc
,
4007 int rd
, int rs
, int rt
)
4009 if (rd
== 0 && opc
!= OPC_ADD
&& opc
!= OPC_SUB
4010 && opc
!= OPC_DADD
&& opc
!= OPC_DSUB
) {
4012 * If no destination, treat it as a NOP.
4013 * For add & sub, we must generate the overflow exception when needed.
4021 TCGv t0
= tcg_temp_local_new();
4022 TCGv t1
= tcg_temp_new();
4023 TCGv t2
= tcg_temp_new();
4024 TCGLabel
*l1
= gen_new_label();
4026 gen_load_gpr(t1
, rs
);
4027 gen_load_gpr(t2
, rt
);
4028 tcg_gen_add_tl(t0
, t1
, t2
);
4029 tcg_gen_ext32s_tl(t0
, t0
);
4030 tcg_gen_xor_tl(t1
, t1
, t2
);
4031 tcg_gen_xor_tl(t2
, t0
, t2
);
4032 tcg_gen_andc_tl(t1
, t2
, t1
);
4034 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
4036 /* operands of same sign, result different sign */
4037 generate_exception(ctx
, EXCP_OVERFLOW
);
4039 gen_store_gpr(t0
, rd
);
4044 if (rs
!= 0 && rt
!= 0) {
4045 tcg_gen_add_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
4046 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
4047 } else if (rs
== 0 && rt
!= 0) {
4048 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
4049 } else if (rs
!= 0 && rt
== 0) {
4050 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
4052 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4057 TCGv t0
= tcg_temp_local_new();
4058 TCGv t1
= tcg_temp_new();
4059 TCGv t2
= tcg_temp_new();
4060 TCGLabel
*l1
= gen_new_label();
4062 gen_load_gpr(t1
, rs
);
4063 gen_load_gpr(t2
, rt
);
4064 tcg_gen_sub_tl(t0
, t1
, t2
);
4065 tcg_gen_ext32s_tl(t0
, t0
);
4066 tcg_gen_xor_tl(t2
, t1
, t2
);
4067 tcg_gen_xor_tl(t1
, t0
, t1
);
4068 tcg_gen_and_tl(t1
, t1
, t2
);
4070 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
4073 * operands of different sign, first operand and the result
4076 generate_exception(ctx
, EXCP_OVERFLOW
);
4078 gen_store_gpr(t0
, rd
);
4083 if (rs
!= 0 && rt
!= 0) {
4084 tcg_gen_sub_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
4085 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
4086 } else if (rs
== 0 && rt
!= 0) {
4087 tcg_gen_neg_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
4088 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
4089 } else if (rs
!= 0 && rt
== 0) {
4090 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
4092 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4095 #if defined(TARGET_MIPS64)
4098 TCGv t0
= tcg_temp_local_new();
4099 TCGv t1
= tcg_temp_new();
4100 TCGv t2
= tcg_temp_new();
4101 TCGLabel
*l1
= gen_new_label();
4103 gen_load_gpr(t1
, rs
);
4104 gen_load_gpr(t2
, rt
);
4105 tcg_gen_add_tl(t0
, t1
, t2
);
4106 tcg_gen_xor_tl(t1
, t1
, t2
);
4107 tcg_gen_xor_tl(t2
, t0
, t2
);
4108 tcg_gen_andc_tl(t1
, t2
, t1
);
4110 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
4112 /* operands of same sign, result different sign */
4113 generate_exception(ctx
, EXCP_OVERFLOW
);
4115 gen_store_gpr(t0
, rd
);
4120 if (rs
!= 0 && rt
!= 0) {
4121 tcg_gen_add_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
4122 } else if (rs
== 0 && rt
!= 0) {
4123 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
4124 } else if (rs
!= 0 && rt
== 0) {
4125 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
4127 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4132 TCGv t0
= tcg_temp_local_new();
4133 TCGv t1
= tcg_temp_new();
4134 TCGv t2
= tcg_temp_new();
4135 TCGLabel
*l1
= gen_new_label();
4137 gen_load_gpr(t1
, rs
);
4138 gen_load_gpr(t2
, rt
);
4139 tcg_gen_sub_tl(t0
, t1
, t2
);
4140 tcg_gen_xor_tl(t2
, t1
, t2
);
4141 tcg_gen_xor_tl(t1
, t0
, t1
);
4142 tcg_gen_and_tl(t1
, t1
, t2
);
4144 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
4147 * Operands of different sign, first operand and result different
4150 generate_exception(ctx
, EXCP_OVERFLOW
);
4152 gen_store_gpr(t0
, rd
);
4157 if (rs
!= 0 && rt
!= 0) {
4158 tcg_gen_sub_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
4159 } else if (rs
== 0 && rt
!= 0) {
4160 tcg_gen_neg_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
4161 } else if (rs
!= 0 && rt
== 0) {
4162 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
4164 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4169 if (likely(rs
!= 0 && rt
!= 0)) {
4170 tcg_gen_mul_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
4171 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
4173 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4179 /* Conditional move */
4180 static void gen_cond_move(DisasContext
*ctx
, uint32_t opc
,
4181 int rd
, int rs
, int rt
)
4186 /* If no destination, treat it as a NOP. */
4190 t0
= tcg_temp_new();
4191 gen_load_gpr(t0
, rt
);
4192 t1
= tcg_const_tl(0);
4193 t2
= tcg_temp_new();
4194 gen_load_gpr(t2
, rs
);
4197 tcg_gen_movcond_tl(TCG_COND_NE
, cpu_gpr
[rd
], t0
, t1
, t2
, cpu_gpr
[rd
]);
4200 tcg_gen_movcond_tl(TCG_COND_EQ
, cpu_gpr
[rd
], t0
, t1
, t2
, cpu_gpr
[rd
]);
4203 tcg_gen_movcond_tl(TCG_COND_NE
, cpu_gpr
[rd
], t0
, t1
, t2
, t1
);
4206 tcg_gen_movcond_tl(TCG_COND_EQ
, cpu_gpr
[rd
], t0
, t1
, t2
, t1
);
4215 static void gen_logic(DisasContext
*ctx
, uint32_t opc
,
4216 int rd
, int rs
, int rt
)
4219 /* If no destination, treat it as a NOP. */
4225 if (likely(rs
!= 0 && rt
!= 0)) {
4226 tcg_gen_and_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
4228 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4232 if (rs
!= 0 && rt
!= 0) {
4233 tcg_gen_nor_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
4234 } else if (rs
== 0 && rt
!= 0) {
4235 tcg_gen_not_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
4236 } else if (rs
!= 0 && rt
== 0) {
4237 tcg_gen_not_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
4239 tcg_gen_movi_tl(cpu_gpr
[rd
], ~((target_ulong
)0));
4243 if (likely(rs
!= 0 && rt
!= 0)) {
4244 tcg_gen_or_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
4245 } else if (rs
== 0 && rt
!= 0) {
4246 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
4247 } else if (rs
!= 0 && rt
== 0) {
4248 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
4250 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4254 if (likely(rs
!= 0 && rt
!= 0)) {
4255 tcg_gen_xor_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
4256 } else if (rs
== 0 && rt
!= 0) {
4257 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
4258 } else if (rs
!= 0 && rt
== 0) {
4259 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
4261 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4267 /* Set on lower than */
4268 static void gen_slt(DisasContext
*ctx
, uint32_t opc
,
4269 int rd
, int rs
, int rt
)
4274 /* If no destination, treat it as a NOP. */
4278 t0
= tcg_temp_new();
4279 t1
= tcg_temp_new();
4280 gen_load_gpr(t0
, rs
);
4281 gen_load_gpr(t1
, rt
);
4284 tcg_gen_setcond_tl(TCG_COND_LT
, cpu_gpr
[rd
], t0
, t1
);
4287 tcg_gen_setcond_tl(TCG_COND_LTU
, cpu_gpr
[rd
], t0
, t1
);
4295 static void gen_shift(DisasContext
*ctx
, uint32_t opc
,
4296 int rd
, int rs
, int rt
)
4302 * If no destination, treat it as a NOP.
4303 * For add & sub, we must generate the overflow exception when needed.
4308 t0
= tcg_temp_new();
4309 t1
= tcg_temp_new();
4310 gen_load_gpr(t0
, rs
);
4311 gen_load_gpr(t1
, rt
);
4314 tcg_gen_andi_tl(t0
, t0
, 0x1f);
4315 tcg_gen_shl_tl(t0
, t1
, t0
);
4316 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
4319 tcg_gen_andi_tl(t0
, t0
, 0x1f);
4320 tcg_gen_sar_tl(cpu_gpr
[rd
], t1
, t0
);
4323 tcg_gen_ext32u_tl(t1
, t1
);
4324 tcg_gen_andi_tl(t0
, t0
, 0x1f);
4325 tcg_gen_shr_tl(t0
, t1
, t0
);
4326 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
4330 TCGv_i32 t2
= tcg_temp_new_i32();
4331 TCGv_i32 t3
= tcg_temp_new_i32();
4333 tcg_gen_trunc_tl_i32(t2
, t0
);
4334 tcg_gen_trunc_tl_i32(t3
, t1
);
4335 tcg_gen_andi_i32(t2
, t2
, 0x1f);
4336 tcg_gen_rotr_i32(t2
, t3
, t2
);
4337 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
4338 tcg_temp_free_i32(t2
);
4339 tcg_temp_free_i32(t3
);
4342 #if defined(TARGET_MIPS64)
4344 tcg_gen_andi_tl(t0
, t0
, 0x3f);
4345 tcg_gen_shl_tl(cpu_gpr
[rd
], t1
, t0
);
4348 tcg_gen_andi_tl(t0
, t0
, 0x3f);
4349 tcg_gen_sar_tl(cpu_gpr
[rd
], t1
, t0
);
4352 tcg_gen_andi_tl(t0
, t0
, 0x3f);
4353 tcg_gen_shr_tl(cpu_gpr
[rd
], t1
, t0
);
4356 tcg_gen_andi_tl(t0
, t0
, 0x3f);
4357 tcg_gen_rotr_tl(cpu_gpr
[rd
], t1
, t0
);
4365 #if defined(TARGET_MIPS64)
4366 /* Copy GPR to and from TX79 HI1/LO1 register. */
4367 static void gen_HILO1_tx79(DisasContext
*ctx
, uint32_t opc
, int reg
)
4369 if (reg
== 0 && (opc
== MMI_OPC_MFHI1
|| opc
== MMI_OPC_MFLO1
)) {
4376 tcg_gen_mov_tl(cpu_gpr
[reg
], cpu_HI
[1]);
4379 tcg_gen_mov_tl(cpu_gpr
[reg
], cpu_LO
[1]);
4383 tcg_gen_mov_tl(cpu_HI
[1], cpu_gpr
[reg
]);
4385 tcg_gen_movi_tl(cpu_HI
[1], 0);
4390 tcg_gen_mov_tl(cpu_LO
[1], cpu_gpr
[reg
]);
4392 tcg_gen_movi_tl(cpu_LO
[1], 0);
4396 MIPS_INVAL("mfthilo1 TX79");
4397 gen_reserved_instruction(ctx
);
4403 /* Arithmetic on HI/LO registers */
4404 static void gen_HILO(DisasContext
*ctx
, uint32_t opc
, int acc
, int reg
)
4406 if (reg
== 0 && (opc
== OPC_MFHI
|| opc
== OPC_MFLO
)) {
4417 #if defined(TARGET_MIPS64)
4419 tcg_gen_ext32s_tl(cpu_gpr
[reg
], cpu_HI
[acc
]);
4423 tcg_gen_mov_tl(cpu_gpr
[reg
], cpu_HI
[acc
]);
4427 #if defined(TARGET_MIPS64)
4429 tcg_gen_ext32s_tl(cpu_gpr
[reg
], cpu_LO
[acc
]);
4433 tcg_gen_mov_tl(cpu_gpr
[reg
], cpu_LO
[acc
]);
4438 #if defined(TARGET_MIPS64)
4440 tcg_gen_ext32s_tl(cpu_HI
[acc
], cpu_gpr
[reg
]);
4444 tcg_gen_mov_tl(cpu_HI
[acc
], cpu_gpr
[reg
]);
4447 tcg_gen_movi_tl(cpu_HI
[acc
], 0);
4452 #if defined(TARGET_MIPS64)
4454 tcg_gen_ext32s_tl(cpu_LO
[acc
], cpu_gpr
[reg
]);
4458 tcg_gen_mov_tl(cpu_LO
[acc
], cpu_gpr
[reg
]);
4461 tcg_gen_movi_tl(cpu_LO
[acc
], 0);
4467 static inline void gen_r6_ld(target_long addr
, int reg
, int memidx
,
4470 TCGv t0
= tcg_const_tl(addr
);
4471 tcg_gen_qemu_ld_tl(t0
, t0
, memidx
, memop
);
4472 gen_store_gpr(t0
, reg
);
4476 static inline void gen_pcrel(DisasContext
*ctx
, int opc
, target_ulong pc
,
4482 switch (MASK_OPC_PCREL_TOP2BITS(opc
)) {
4485 offset
= sextract32(ctx
->opcode
<< 2, 0, 21);
4486 addr
= addr_add(ctx
, pc
, offset
);
4487 tcg_gen_movi_tl(cpu_gpr
[rs
], addr
);
4491 offset
= sextract32(ctx
->opcode
<< 2, 0, 21);
4492 addr
= addr_add(ctx
, pc
, offset
);
4493 gen_r6_ld(addr
, rs
, ctx
->mem_idx
, MO_TESL
);
4495 #if defined(TARGET_MIPS64)
4498 offset
= sextract32(ctx
->opcode
<< 2, 0, 21);
4499 addr
= addr_add(ctx
, pc
, offset
);
4500 gen_r6_ld(addr
, rs
, ctx
->mem_idx
, MO_TEUL
);
4504 switch (MASK_OPC_PCREL_TOP5BITS(opc
)) {
4507 offset
= sextract32(ctx
->opcode
, 0, 16) << 16;
4508 addr
= addr_add(ctx
, pc
, offset
);
4509 tcg_gen_movi_tl(cpu_gpr
[rs
], addr
);
4514 offset
= sextract32(ctx
->opcode
, 0, 16) << 16;
4515 addr
= ~0xFFFF & addr_add(ctx
, pc
, offset
);
4516 tcg_gen_movi_tl(cpu_gpr
[rs
], addr
);
4519 #if defined(TARGET_MIPS64)
4520 case R6_OPC_LDPC
: /* bits 16 and 17 are part of immediate */
4521 case R6_OPC_LDPC
+ (1 << 16):
4522 case R6_OPC_LDPC
+ (2 << 16):
4523 case R6_OPC_LDPC
+ (3 << 16):
4525 offset
= sextract32(ctx
->opcode
<< 3, 0, 21);
4526 addr
= addr_add(ctx
, (pc
& ~0x7), offset
);
4527 gen_r6_ld(addr
, rs
, ctx
->mem_idx
, MO_TEQ
);
4531 MIPS_INVAL("OPC_PCREL");
4532 gen_reserved_instruction(ctx
);
4539 static void gen_r6_muldiv(DisasContext
*ctx
, int opc
, int rd
, int rs
, int rt
)
4548 t0
= tcg_temp_new();
4549 t1
= tcg_temp_new();
4551 gen_load_gpr(t0
, rs
);
4552 gen_load_gpr(t1
, rt
);
4557 TCGv t2
= tcg_temp_new();
4558 TCGv t3
= tcg_temp_new();
4559 tcg_gen_ext32s_tl(t0
, t0
);
4560 tcg_gen_ext32s_tl(t1
, t1
);
4561 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, INT_MIN
);
4562 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1);
4563 tcg_gen_and_tl(t2
, t2
, t3
);
4564 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
4565 tcg_gen_or_tl(t2
, t2
, t3
);
4566 tcg_gen_movi_tl(t3
, 0);
4567 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
4568 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
4569 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
4576 TCGv t2
= tcg_temp_new();
4577 TCGv t3
= tcg_temp_new();
4578 tcg_gen_ext32s_tl(t0
, t0
);
4579 tcg_gen_ext32s_tl(t1
, t1
);
4580 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, INT_MIN
);
4581 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1);
4582 tcg_gen_and_tl(t2
, t2
, t3
);
4583 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
4584 tcg_gen_or_tl(t2
, t2
, t3
);
4585 tcg_gen_movi_tl(t3
, 0);
4586 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
4587 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
4588 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
4595 TCGv t2
= tcg_const_tl(0);
4596 TCGv t3
= tcg_const_tl(1);
4597 tcg_gen_ext32u_tl(t0
, t0
);
4598 tcg_gen_ext32u_tl(t1
, t1
);
4599 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
4600 tcg_gen_divu_tl(cpu_gpr
[rd
], t0
, t1
);
4601 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
4608 TCGv t2
= tcg_const_tl(0);
4609 TCGv t3
= tcg_const_tl(1);
4610 tcg_gen_ext32u_tl(t0
, t0
);
4611 tcg_gen_ext32u_tl(t1
, t1
);
4612 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
4613 tcg_gen_remu_tl(cpu_gpr
[rd
], t0
, t1
);
4614 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
4621 TCGv_i32 t2
= tcg_temp_new_i32();
4622 TCGv_i32 t3
= tcg_temp_new_i32();
4623 tcg_gen_trunc_tl_i32(t2
, t0
);
4624 tcg_gen_trunc_tl_i32(t3
, t1
);
4625 tcg_gen_mul_i32(t2
, t2
, t3
);
4626 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
4627 tcg_temp_free_i32(t2
);
4628 tcg_temp_free_i32(t3
);
4633 TCGv_i32 t2
= tcg_temp_new_i32();
4634 TCGv_i32 t3
= tcg_temp_new_i32();
4635 tcg_gen_trunc_tl_i32(t2
, t0
);
4636 tcg_gen_trunc_tl_i32(t3
, t1
);
4637 tcg_gen_muls2_i32(t2
, t3
, t2
, t3
);
4638 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t3
);
4639 tcg_temp_free_i32(t2
);
4640 tcg_temp_free_i32(t3
);
4645 TCGv_i32 t2
= tcg_temp_new_i32();
4646 TCGv_i32 t3
= tcg_temp_new_i32();
4647 tcg_gen_trunc_tl_i32(t2
, t0
);
4648 tcg_gen_trunc_tl_i32(t3
, t1
);
4649 tcg_gen_mul_i32(t2
, t2
, t3
);
4650 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
4651 tcg_temp_free_i32(t2
);
4652 tcg_temp_free_i32(t3
);
4657 TCGv_i32 t2
= tcg_temp_new_i32();
4658 TCGv_i32 t3
= tcg_temp_new_i32();
4659 tcg_gen_trunc_tl_i32(t2
, t0
);
4660 tcg_gen_trunc_tl_i32(t3
, t1
);
4661 tcg_gen_mulu2_i32(t2
, t3
, t2
, t3
);
4662 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t3
);
4663 tcg_temp_free_i32(t2
);
4664 tcg_temp_free_i32(t3
);
4667 #if defined(TARGET_MIPS64)
4670 TCGv t2
= tcg_temp_new();
4671 TCGv t3
= tcg_temp_new();
4672 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, -1LL << 63);
4673 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1LL);
4674 tcg_gen_and_tl(t2
, t2
, t3
);
4675 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
4676 tcg_gen_or_tl(t2
, t2
, t3
);
4677 tcg_gen_movi_tl(t3
, 0);
4678 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
4679 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
4686 TCGv t2
= tcg_temp_new();
4687 TCGv t3
= tcg_temp_new();
4688 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, -1LL << 63);
4689 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1LL);
4690 tcg_gen_and_tl(t2
, t2
, t3
);
4691 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
4692 tcg_gen_or_tl(t2
, t2
, t3
);
4693 tcg_gen_movi_tl(t3
, 0);
4694 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
4695 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
4702 TCGv t2
= tcg_const_tl(0);
4703 TCGv t3
= tcg_const_tl(1);
4704 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
4705 tcg_gen_divu_i64(cpu_gpr
[rd
], t0
, t1
);
4712 TCGv t2
= tcg_const_tl(0);
4713 TCGv t3
= tcg_const_tl(1);
4714 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
4715 tcg_gen_remu_i64(cpu_gpr
[rd
], t0
, t1
);
4721 tcg_gen_mul_i64(cpu_gpr
[rd
], t0
, t1
);
4725 TCGv t2
= tcg_temp_new();
4726 tcg_gen_muls2_i64(t2
, cpu_gpr
[rd
], t0
, t1
);
4731 tcg_gen_mul_i64(cpu_gpr
[rd
], t0
, t1
);
4735 TCGv t2
= tcg_temp_new();
4736 tcg_gen_mulu2_i64(t2
, cpu_gpr
[rd
], t0
, t1
);
4742 MIPS_INVAL("r6 mul/div");
4743 gen_reserved_instruction(ctx
);
4751 #if defined(TARGET_MIPS64)
4752 static void gen_div1_tx79(DisasContext
*ctx
, uint32_t opc
, int rs
, int rt
)
4756 t0
= tcg_temp_new();
4757 t1
= tcg_temp_new();
4759 gen_load_gpr(t0
, rs
);
4760 gen_load_gpr(t1
, rt
);
4765 TCGv t2
= tcg_temp_new();
4766 TCGv t3
= tcg_temp_new();
4767 tcg_gen_ext32s_tl(t0
, t0
);
4768 tcg_gen_ext32s_tl(t1
, t1
);
4769 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, INT_MIN
);
4770 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1);
4771 tcg_gen_and_tl(t2
, t2
, t3
);
4772 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
4773 tcg_gen_or_tl(t2
, t2
, t3
);
4774 tcg_gen_movi_tl(t3
, 0);
4775 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
4776 tcg_gen_div_tl(cpu_LO
[1], t0
, t1
);
4777 tcg_gen_rem_tl(cpu_HI
[1], t0
, t1
);
4778 tcg_gen_ext32s_tl(cpu_LO
[1], cpu_LO
[1]);
4779 tcg_gen_ext32s_tl(cpu_HI
[1], cpu_HI
[1]);
4786 TCGv t2
= tcg_const_tl(0);
4787 TCGv t3
= tcg_const_tl(1);
4788 tcg_gen_ext32u_tl(t0
, t0
);
4789 tcg_gen_ext32u_tl(t1
, t1
);
4790 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
4791 tcg_gen_divu_tl(cpu_LO
[1], t0
, t1
);
4792 tcg_gen_remu_tl(cpu_HI
[1], t0
, t1
);
4793 tcg_gen_ext32s_tl(cpu_LO
[1], cpu_LO
[1]);
4794 tcg_gen_ext32s_tl(cpu_HI
[1], cpu_HI
[1]);
4800 MIPS_INVAL("div1 TX79");
4801 gen_reserved_instruction(ctx
);
4810 static void gen_muldiv(DisasContext
*ctx
, uint32_t opc
,
4811 int acc
, int rs
, int rt
)
4815 t0
= tcg_temp_new();
4816 t1
= tcg_temp_new();
4818 gen_load_gpr(t0
, rs
);
4819 gen_load_gpr(t1
, rt
);
4828 TCGv t2
= tcg_temp_new();
4829 TCGv t3
= tcg_temp_new();
4830 tcg_gen_ext32s_tl(t0
, t0
);
4831 tcg_gen_ext32s_tl(t1
, t1
);
4832 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, INT_MIN
);
4833 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1);
4834 tcg_gen_and_tl(t2
, t2
, t3
);
4835 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
4836 tcg_gen_or_tl(t2
, t2
, t3
);
4837 tcg_gen_movi_tl(t3
, 0);
4838 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
4839 tcg_gen_div_tl(cpu_LO
[acc
], t0
, t1
);
4840 tcg_gen_rem_tl(cpu_HI
[acc
], t0
, t1
);
4841 tcg_gen_ext32s_tl(cpu_LO
[acc
], cpu_LO
[acc
]);
4842 tcg_gen_ext32s_tl(cpu_HI
[acc
], cpu_HI
[acc
]);
4849 TCGv t2
= tcg_const_tl(0);
4850 TCGv t3
= tcg_const_tl(1);
4851 tcg_gen_ext32u_tl(t0
, t0
);
4852 tcg_gen_ext32u_tl(t1
, t1
);
4853 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
4854 tcg_gen_divu_tl(cpu_LO
[acc
], t0
, t1
);
4855 tcg_gen_remu_tl(cpu_HI
[acc
], t0
, t1
);
4856 tcg_gen_ext32s_tl(cpu_LO
[acc
], cpu_LO
[acc
]);
4857 tcg_gen_ext32s_tl(cpu_HI
[acc
], cpu_HI
[acc
]);
4864 TCGv_i32 t2
= tcg_temp_new_i32();
4865 TCGv_i32 t3
= tcg_temp_new_i32();
4866 tcg_gen_trunc_tl_i32(t2
, t0
);
4867 tcg_gen_trunc_tl_i32(t3
, t1
);
4868 tcg_gen_muls2_i32(t2
, t3
, t2
, t3
);
4869 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
4870 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
4871 tcg_temp_free_i32(t2
);
4872 tcg_temp_free_i32(t3
);
4877 TCGv_i32 t2
= tcg_temp_new_i32();
4878 TCGv_i32 t3
= tcg_temp_new_i32();
4879 tcg_gen_trunc_tl_i32(t2
, t0
);
4880 tcg_gen_trunc_tl_i32(t3
, t1
);
4881 tcg_gen_mulu2_i32(t2
, t3
, t2
, t3
);
4882 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
4883 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
4884 tcg_temp_free_i32(t2
);
4885 tcg_temp_free_i32(t3
);
4888 #if defined(TARGET_MIPS64)
4891 TCGv t2
= tcg_temp_new();
4892 TCGv t3
= tcg_temp_new();
4893 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, -1LL << 63);
4894 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1LL);
4895 tcg_gen_and_tl(t2
, t2
, t3
);
4896 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
4897 tcg_gen_or_tl(t2
, t2
, t3
);
4898 tcg_gen_movi_tl(t3
, 0);
4899 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
4900 tcg_gen_div_tl(cpu_LO
[acc
], t0
, t1
);
4901 tcg_gen_rem_tl(cpu_HI
[acc
], t0
, t1
);
4908 TCGv t2
= tcg_const_tl(0);
4909 TCGv t3
= tcg_const_tl(1);
4910 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
4911 tcg_gen_divu_i64(cpu_LO
[acc
], t0
, t1
);
4912 tcg_gen_remu_i64(cpu_HI
[acc
], t0
, t1
);
4918 tcg_gen_muls2_i64(cpu_LO
[acc
], cpu_HI
[acc
], t0
, t1
);
4921 tcg_gen_mulu2_i64(cpu_LO
[acc
], cpu_HI
[acc
], t0
, t1
);
4926 TCGv_i64 t2
= tcg_temp_new_i64();
4927 TCGv_i64 t3
= tcg_temp_new_i64();
4929 tcg_gen_ext_tl_i64(t2
, t0
);
4930 tcg_gen_ext_tl_i64(t3
, t1
);
4931 tcg_gen_mul_i64(t2
, t2
, t3
);
4932 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
4933 tcg_gen_add_i64(t2
, t2
, t3
);
4934 tcg_temp_free_i64(t3
);
4935 gen_move_low32(cpu_LO
[acc
], t2
);
4936 gen_move_high32(cpu_HI
[acc
], t2
);
4937 tcg_temp_free_i64(t2
);
4942 TCGv_i64 t2
= tcg_temp_new_i64();
4943 TCGv_i64 t3
= tcg_temp_new_i64();
4945 tcg_gen_ext32u_tl(t0
, t0
);
4946 tcg_gen_ext32u_tl(t1
, t1
);
4947 tcg_gen_extu_tl_i64(t2
, t0
);
4948 tcg_gen_extu_tl_i64(t3
, t1
);
4949 tcg_gen_mul_i64(t2
, t2
, t3
);
4950 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
4951 tcg_gen_add_i64(t2
, t2
, t3
);
4952 tcg_temp_free_i64(t3
);
4953 gen_move_low32(cpu_LO
[acc
], t2
);
4954 gen_move_high32(cpu_HI
[acc
], t2
);
4955 tcg_temp_free_i64(t2
);
4960 TCGv_i64 t2
= tcg_temp_new_i64();
4961 TCGv_i64 t3
= tcg_temp_new_i64();
4963 tcg_gen_ext_tl_i64(t2
, t0
);
4964 tcg_gen_ext_tl_i64(t3
, t1
);
4965 tcg_gen_mul_i64(t2
, t2
, t3
);
4966 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
4967 tcg_gen_sub_i64(t2
, t3
, t2
);
4968 tcg_temp_free_i64(t3
);
4969 gen_move_low32(cpu_LO
[acc
], t2
);
4970 gen_move_high32(cpu_HI
[acc
], t2
);
4971 tcg_temp_free_i64(t2
);
4976 TCGv_i64 t2
= tcg_temp_new_i64();
4977 TCGv_i64 t3
= tcg_temp_new_i64();
4979 tcg_gen_ext32u_tl(t0
, t0
);
4980 tcg_gen_ext32u_tl(t1
, t1
);
4981 tcg_gen_extu_tl_i64(t2
, t0
);
4982 tcg_gen_extu_tl_i64(t3
, t1
);
4983 tcg_gen_mul_i64(t2
, t2
, t3
);
4984 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
4985 tcg_gen_sub_i64(t2
, t3
, t2
);
4986 tcg_temp_free_i64(t3
);
4987 gen_move_low32(cpu_LO
[acc
], t2
);
4988 gen_move_high32(cpu_HI
[acc
], t2
);
4989 tcg_temp_free_i64(t2
);
4993 MIPS_INVAL("mul/div");
4994 gen_reserved_instruction(ctx
);
5003 * These MULT[U] and MADD[U] instructions implemented in for example
5004 * the Toshiba/Sony R5900 and the Toshiba TX19, TX39 and TX79 core
5005 * architectures are special three-operand variants with the syntax
5007 * MULT[U][1] rd, rs, rt
5011 * (rd, LO, HI) <- rs * rt
5015 * MADD[U][1] rd, rs, rt
5019 * (rd, LO, HI) <- (LO, HI) + rs * rt
5021 * where the low-order 32-bits of the result is placed into both the
5022 * GPR rd and the special register LO. The high-order 32-bits of the
5023 * result is placed into the special register HI.
5025 * If the GPR rd is omitted in assembly language, it is taken to be 0,
5026 * which is the zero register that always reads as 0.
5028 static void gen_mul_txx9(DisasContext
*ctx
, uint32_t opc
,
5029 int rd
, int rs
, int rt
)
5031 TCGv t0
= tcg_temp_new();
5032 TCGv t1
= tcg_temp_new();
5035 gen_load_gpr(t0
, rs
);
5036 gen_load_gpr(t1
, rt
);
5044 TCGv_i32 t2
= tcg_temp_new_i32();
5045 TCGv_i32 t3
= tcg_temp_new_i32();
5046 tcg_gen_trunc_tl_i32(t2
, t0
);
5047 tcg_gen_trunc_tl_i32(t3
, t1
);
5048 tcg_gen_muls2_i32(t2
, t3
, t2
, t3
);
5050 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
5052 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
5053 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
5054 tcg_temp_free_i32(t2
);
5055 tcg_temp_free_i32(t3
);
5058 case MMI_OPC_MULTU1
:
5063 TCGv_i32 t2
= tcg_temp_new_i32();
5064 TCGv_i32 t3
= tcg_temp_new_i32();
5065 tcg_gen_trunc_tl_i32(t2
, t0
);
5066 tcg_gen_trunc_tl_i32(t3
, t1
);
5067 tcg_gen_mulu2_i32(t2
, t3
, t2
, t3
);
5069 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
5071 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
5072 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
5073 tcg_temp_free_i32(t2
);
5074 tcg_temp_free_i32(t3
);
5082 TCGv_i64 t2
= tcg_temp_new_i64();
5083 TCGv_i64 t3
= tcg_temp_new_i64();
5085 tcg_gen_ext_tl_i64(t2
, t0
);
5086 tcg_gen_ext_tl_i64(t3
, t1
);
5087 tcg_gen_mul_i64(t2
, t2
, t3
);
5088 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
5089 tcg_gen_add_i64(t2
, t2
, t3
);
5090 tcg_temp_free_i64(t3
);
5091 gen_move_low32(cpu_LO
[acc
], t2
);
5092 gen_move_high32(cpu_HI
[acc
], t2
);
5094 gen_move_low32(cpu_gpr
[rd
], t2
);
5096 tcg_temp_free_i64(t2
);
5099 case MMI_OPC_MADDU1
:
5104 TCGv_i64 t2
= tcg_temp_new_i64();
5105 TCGv_i64 t3
= tcg_temp_new_i64();
5107 tcg_gen_ext32u_tl(t0
, t0
);
5108 tcg_gen_ext32u_tl(t1
, t1
);
5109 tcg_gen_extu_tl_i64(t2
, t0
);
5110 tcg_gen_extu_tl_i64(t3
, t1
);
5111 tcg_gen_mul_i64(t2
, t2
, t3
);
5112 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
5113 tcg_gen_add_i64(t2
, t2
, t3
);
5114 tcg_temp_free_i64(t3
);
5115 gen_move_low32(cpu_LO
[acc
], t2
);
5116 gen_move_high32(cpu_HI
[acc
], t2
);
5118 gen_move_low32(cpu_gpr
[rd
], t2
);
5120 tcg_temp_free_i64(t2
);
5124 MIPS_INVAL("mul/madd TXx9");
5125 gen_reserved_instruction(ctx
);
5134 static void gen_mul_vr54xx(DisasContext
*ctx
, uint32_t opc
,
5135 int rd
, int rs
, int rt
)
5137 TCGv t0
= tcg_temp_new();
5138 TCGv t1
= tcg_temp_new();
5140 gen_load_gpr(t0
, rs
);
5141 gen_load_gpr(t1
, rt
);
5144 case OPC_VR54XX_MULS
:
5145 gen_helper_muls(t0
, cpu_env
, t0
, t1
);
5147 case OPC_VR54XX_MULSU
:
5148 gen_helper_mulsu(t0
, cpu_env
, t0
, t1
);
5150 case OPC_VR54XX_MACC
:
5151 gen_helper_macc(t0
, cpu_env
, t0
, t1
);
5153 case OPC_VR54XX_MACCU
:
5154 gen_helper_maccu(t0
, cpu_env
, t0
, t1
);
5156 case OPC_VR54XX_MSAC
:
5157 gen_helper_msac(t0
, cpu_env
, t0
, t1
);
5159 case OPC_VR54XX_MSACU
:
5160 gen_helper_msacu(t0
, cpu_env
, t0
, t1
);
5162 case OPC_VR54XX_MULHI
:
5163 gen_helper_mulhi(t0
, cpu_env
, t0
, t1
);
5165 case OPC_VR54XX_MULHIU
:
5166 gen_helper_mulhiu(t0
, cpu_env
, t0
, t1
);
5168 case OPC_VR54XX_MULSHI
:
5169 gen_helper_mulshi(t0
, cpu_env
, t0
, t1
);
5171 case OPC_VR54XX_MULSHIU
:
5172 gen_helper_mulshiu(t0
, cpu_env
, t0
, t1
);
5174 case OPC_VR54XX_MACCHI
:
5175 gen_helper_macchi(t0
, cpu_env
, t0
, t1
);
5177 case OPC_VR54XX_MACCHIU
:
5178 gen_helper_macchiu(t0
, cpu_env
, t0
, t1
);
5180 case OPC_VR54XX_MSACHI
:
5181 gen_helper_msachi(t0
, cpu_env
, t0
, t1
);
5183 case OPC_VR54XX_MSACHIU
:
5184 gen_helper_msachiu(t0
, cpu_env
, t0
, t1
);
5187 MIPS_INVAL("mul vr54xx");
5188 gen_reserved_instruction(ctx
);
5191 gen_store_gpr(t0
, rd
);
5198 static void gen_cl(DisasContext
*ctx
, uint32_t opc
,
5208 gen_load_gpr(t0
, rs
);
5213 #if defined(TARGET_MIPS64)
5217 tcg_gen_not_tl(t0
, t0
);
5226 tcg_gen_ext32u_tl(t0
, t0
);
5227 tcg_gen_clzi_tl(t0
, t0
, TARGET_LONG_BITS
);
5228 tcg_gen_subi_tl(t0
, t0
, TARGET_LONG_BITS
- 32);
5230 #if defined(TARGET_MIPS64)
5235 tcg_gen_clzi_i64(t0
, t0
, 64);
5241 /* Godson integer instructions */
5242 static void gen_loongson_integer(DisasContext
*ctx
, uint32_t opc
,
5243 int rd
, int rs
, int rt
)
5255 case OPC_MULTU_G_2E
:
5256 case OPC_MULTU_G_2F
:
5257 #if defined(TARGET_MIPS64)
5258 case OPC_DMULT_G_2E
:
5259 case OPC_DMULT_G_2F
:
5260 case OPC_DMULTU_G_2E
:
5261 case OPC_DMULTU_G_2F
:
5263 t0
= tcg_temp_new();
5264 t1
= tcg_temp_new();
5267 t0
= tcg_temp_local_new();
5268 t1
= tcg_temp_local_new();
5272 gen_load_gpr(t0
, rs
);
5273 gen_load_gpr(t1
, rt
);
5278 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
5279 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
5281 case OPC_MULTU_G_2E
:
5282 case OPC_MULTU_G_2F
:
5283 tcg_gen_ext32u_tl(t0
, t0
);
5284 tcg_gen_ext32u_tl(t1
, t1
);
5285 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
5286 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
5291 TCGLabel
*l1
= gen_new_label();
5292 TCGLabel
*l2
= gen_new_label();
5293 TCGLabel
*l3
= gen_new_label();
5294 tcg_gen_ext32s_tl(t0
, t0
);
5295 tcg_gen_ext32s_tl(t1
, t1
);
5296 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
5297 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
5300 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, INT_MIN
, l2
);
5301 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1, l2
);
5302 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
5305 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
5306 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
5313 TCGLabel
*l1
= gen_new_label();
5314 TCGLabel
*l2
= gen_new_label();
5315 tcg_gen_ext32u_tl(t0
, t0
);
5316 tcg_gen_ext32u_tl(t1
, t1
);
5317 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
5318 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
5321 tcg_gen_divu_tl(cpu_gpr
[rd
], t0
, t1
);
5322 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
5329 TCGLabel
*l1
= gen_new_label();
5330 TCGLabel
*l2
= gen_new_label();
5331 TCGLabel
*l3
= gen_new_label();
5332 tcg_gen_ext32u_tl(t0
, t0
);
5333 tcg_gen_ext32u_tl(t1
, t1
);
5334 tcg_gen_brcondi_tl(TCG_COND_EQ
, t1
, 0, l1
);
5335 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, INT_MIN
, l2
);
5336 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1, l2
);
5338 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
5341 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
5342 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
5349 TCGLabel
*l1
= gen_new_label();
5350 TCGLabel
*l2
= gen_new_label();
5351 tcg_gen_ext32u_tl(t0
, t0
);
5352 tcg_gen_ext32u_tl(t1
, t1
);
5353 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
5354 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
5357 tcg_gen_remu_tl(cpu_gpr
[rd
], t0
, t1
);
5358 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
5362 #if defined(TARGET_MIPS64)
5363 case OPC_DMULT_G_2E
:
5364 case OPC_DMULT_G_2F
:
5365 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
5367 case OPC_DMULTU_G_2E
:
5368 case OPC_DMULTU_G_2F
:
5369 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
5374 TCGLabel
*l1
= gen_new_label();
5375 TCGLabel
*l2
= gen_new_label();
5376 TCGLabel
*l3
= gen_new_label();
5377 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
5378 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
5381 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, -1LL << 63, l2
);
5382 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1LL, l2
);
5383 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
5386 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
5390 case OPC_DDIVU_G_2E
:
5391 case OPC_DDIVU_G_2F
:
5393 TCGLabel
*l1
= gen_new_label();
5394 TCGLabel
*l2
= gen_new_label();
5395 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
5396 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
5399 tcg_gen_divu_tl(cpu_gpr
[rd
], t0
, t1
);
5406 TCGLabel
*l1
= gen_new_label();
5407 TCGLabel
*l2
= gen_new_label();
5408 TCGLabel
*l3
= gen_new_label();
5409 tcg_gen_brcondi_tl(TCG_COND_EQ
, t1
, 0, l1
);
5410 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, -1LL << 63, l2
);
5411 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1LL, l2
);
5413 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
5416 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
5420 case OPC_DMODU_G_2E
:
5421 case OPC_DMODU_G_2F
:
5423 TCGLabel
*l1
= gen_new_label();
5424 TCGLabel
*l2
= gen_new_label();
5425 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
5426 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
5429 tcg_gen_remu_tl(cpu_gpr
[rd
], t0
, t1
);
5440 /* Loongson multimedia instructions */
5441 static void gen_loongson_multimedia(DisasContext
*ctx
, int rd
, int rs
, int rt
)
5443 uint32_t opc
, shift_max
;
5447 opc
= MASK_LMMI(ctx
->opcode
);
5453 t0
= tcg_temp_local_new_i64();
5454 t1
= tcg_temp_local_new_i64();
5457 t0
= tcg_temp_new_i64();
5458 t1
= tcg_temp_new_i64();
5462 check_cp1_enabled(ctx
);
5463 gen_load_fpr64(ctx
, t0
, rs
);
5464 gen_load_fpr64(ctx
, t1
, rt
);
5468 gen_helper_paddsh(t0
, t0
, t1
);
5471 gen_helper_paddush(t0
, t0
, t1
);
5474 gen_helper_paddh(t0
, t0
, t1
);
5477 gen_helper_paddw(t0
, t0
, t1
);
5480 gen_helper_paddsb(t0
, t0
, t1
);
5483 gen_helper_paddusb(t0
, t0
, t1
);
5486 gen_helper_paddb(t0
, t0
, t1
);
5490 gen_helper_psubsh(t0
, t0
, t1
);
5493 gen_helper_psubush(t0
, t0
, t1
);
5496 gen_helper_psubh(t0
, t0
, t1
);
5499 gen_helper_psubw(t0
, t0
, t1
);
5502 gen_helper_psubsb(t0
, t0
, t1
);
5505 gen_helper_psubusb(t0
, t0
, t1
);
5508 gen_helper_psubb(t0
, t0
, t1
);
5512 gen_helper_pshufh(t0
, t0
, t1
);
5515 gen_helper_packsswh(t0
, t0
, t1
);
5518 gen_helper_packsshb(t0
, t0
, t1
);
5521 gen_helper_packushb(t0
, t0
, t1
);
5525 gen_helper_punpcklhw(t0
, t0
, t1
);
5528 gen_helper_punpckhhw(t0
, t0
, t1
);
5531 gen_helper_punpcklbh(t0
, t0
, t1
);
5534 gen_helper_punpckhbh(t0
, t0
, t1
);
5537 gen_helper_punpcklwd(t0
, t0
, t1
);
5540 gen_helper_punpckhwd(t0
, t0
, t1
);
5544 gen_helper_pavgh(t0
, t0
, t1
);
5547 gen_helper_pavgb(t0
, t0
, t1
);
5550 gen_helper_pmaxsh(t0
, t0
, t1
);
5553 gen_helper_pminsh(t0
, t0
, t1
);
5556 gen_helper_pmaxub(t0
, t0
, t1
);
5559 gen_helper_pminub(t0
, t0
, t1
);
5563 gen_helper_pcmpeqw(t0
, t0
, t1
);
5566 gen_helper_pcmpgtw(t0
, t0
, t1
);
5569 gen_helper_pcmpeqh(t0
, t0
, t1
);
5572 gen_helper_pcmpgth(t0
, t0
, t1
);
5575 gen_helper_pcmpeqb(t0
, t0
, t1
);
5578 gen_helper_pcmpgtb(t0
, t0
, t1
);
5582 gen_helper_psllw(t0
, t0
, t1
);
5585 gen_helper_psllh(t0
, t0
, t1
);
5588 gen_helper_psrlw(t0
, t0
, t1
);
5591 gen_helper_psrlh(t0
, t0
, t1
);
5594 gen_helper_psraw(t0
, t0
, t1
);
5597 gen_helper_psrah(t0
, t0
, t1
);
5601 gen_helper_pmullh(t0
, t0
, t1
);
5604 gen_helper_pmulhh(t0
, t0
, t1
);
5607 gen_helper_pmulhuh(t0
, t0
, t1
);
5610 gen_helper_pmaddhw(t0
, t0
, t1
);
5614 gen_helper_pasubub(t0
, t0
, t1
);
5617 gen_helper_biadd(t0
, t0
);
5620 gen_helper_pmovmskb(t0
, t0
);
5624 tcg_gen_add_i64(t0
, t0
, t1
);
5627 tcg_gen_sub_i64(t0
, t0
, t1
);
5630 tcg_gen_xor_i64(t0
, t0
, t1
);
5633 tcg_gen_nor_i64(t0
, t0
, t1
);
5636 tcg_gen_and_i64(t0
, t0
, t1
);
5639 tcg_gen_or_i64(t0
, t0
, t1
);
5643 tcg_gen_andc_i64(t0
, t1
, t0
);
5647 tcg_gen_deposit_i64(t0
, t0
, t1
, 0, 16);
5650 tcg_gen_deposit_i64(t0
, t0
, t1
, 16, 16);
5653 tcg_gen_deposit_i64(t0
, t0
, t1
, 32, 16);
5656 tcg_gen_deposit_i64(t0
, t0
, t1
, 48, 16);
5660 tcg_gen_andi_i64(t1
, t1
, 3);
5661 tcg_gen_shli_i64(t1
, t1
, 4);
5662 tcg_gen_shr_i64(t0
, t0
, t1
);
5663 tcg_gen_ext16u_i64(t0
, t0
);
5667 tcg_gen_add_i64(t0
, t0
, t1
);
5668 tcg_gen_ext32s_i64(t0
, t0
);
5671 tcg_gen_sub_i64(t0
, t0
, t1
);
5672 tcg_gen_ext32s_i64(t0
, t0
);
5694 /* Make sure shift count isn't TCG undefined behaviour. */
5695 tcg_gen_andi_i64(t1
, t1
, shift_max
- 1);
5700 tcg_gen_shl_i64(t0
, t0
, t1
);
5705 * Since SRA is UndefinedResult without sign-extended inputs,
5706 * we can treat SRA and DSRA the same.
5708 tcg_gen_sar_i64(t0
, t0
, t1
);
5711 /* We want to shift in zeros for SRL; zero-extend first. */
5712 tcg_gen_ext32u_i64(t0
, t0
);
5715 tcg_gen_shr_i64(t0
, t0
, t1
);
5719 if (shift_max
== 32) {
5720 tcg_gen_ext32s_i64(t0
, t0
);
5723 /* Shifts larger than MAX produce zero. */
5724 tcg_gen_setcondi_i64(TCG_COND_LTU
, t1
, t1
, shift_max
);
5725 tcg_gen_neg_i64(t1
, t1
);
5726 tcg_gen_and_i64(t0
, t0
, t1
);
5732 TCGv_i64 t2
= tcg_temp_new_i64();
5733 TCGLabel
*lab
= gen_new_label();
5735 tcg_gen_mov_i64(t2
, t0
);
5736 tcg_gen_add_i64(t0
, t1
, t2
);
5737 if (opc
== OPC_ADD_CP2
) {
5738 tcg_gen_ext32s_i64(t0
, t0
);
5740 tcg_gen_xor_i64(t1
, t1
, t2
);
5741 tcg_gen_xor_i64(t2
, t2
, t0
);
5742 tcg_gen_andc_i64(t1
, t2
, t1
);
5743 tcg_temp_free_i64(t2
);
5744 tcg_gen_brcondi_i64(TCG_COND_GE
, t1
, 0, lab
);
5745 generate_exception(ctx
, EXCP_OVERFLOW
);
5753 TCGv_i64 t2
= tcg_temp_new_i64();
5754 TCGLabel
*lab
= gen_new_label();
5756 tcg_gen_mov_i64(t2
, t0
);
5757 tcg_gen_sub_i64(t0
, t1
, t2
);
5758 if (opc
== OPC_SUB_CP2
) {
5759 tcg_gen_ext32s_i64(t0
, t0
);
5761 tcg_gen_xor_i64(t1
, t1
, t2
);
5762 tcg_gen_xor_i64(t2
, t2
, t0
);
5763 tcg_gen_and_i64(t1
, t1
, t2
);
5764 tcg_temp_free_i64(t2
);
5765 tcg_gen_brcondi_i64(TCG_COND_GE
, t1
, 0, lab
);
5766 generate_exception(ctx
, EXCP_OVERFLOW
);
5772 tcg_gen_ext32u_i64(t0
, t0
);
5773 tcg_gen_ext32u_i64(t1
, t1
);
5774 tcg_gen_mul_i64(t0
, t0
, t1
);
5783 cond
= TCG_COND_LTU
;
5791 cond
= TCG_COND_LEU
;
5798 int cc
= (ctx
->opcode
>> 8) & 0x7;
5799 TCGv_i64 t64
= tcg_temp_new_i64();
5800 TCGv_i32 t32
= tcg_temp_new_i32();
5802 tcg_gen_setcond_i64(cond
, t64
, t0
, t1
);
5803 tcg_gen_extrl_i64_i32(t32
, t64
);
5804 tcg_gen_deposit_i32(fpu_fcr31
, fpu_fcr31
, t32
,
5807 tcg_temp_free_i32(t32
);
5808 tcg_temp_free_i64(t64
);
5813 MIPS_INVAL("loongson_cp2");
5814 gen_reserved_instruction(ctx
);
5818 gen_store_fpr64(ctx
, t0
, rd
);
5821 tcg_temp_free_i64(t0
);
5822 tcg_temp_free_i64(t1
);
5825 static void gen_loongson_lswc2(DisasContext
*ctx
, int rt
,
5830 #if defined(TARGET_MIPS64)
5831 int lsq_rt1
= ctx
->opcode
& 0x1f;
5832 int lsq_offset
= sextract32(ctx
->opcode
, 6, 9) << 4;
5834 int shf_offset
= sextract32(ctx
->opcode
, 6, 8);
5836 t0
= tcg_temp_new();
5838 switch (MASK_LOONGSON_GSLSQ(ctx
->opcode
)) {
5839 #if defined(TARGET_MIPS64)
5841 t1
= tcg_temp_new();
5842 gen_base_offset_addr(ctx
, t0
, rs
, lsq_offset
);
5843 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
|
5844 ctx
->default_tcg_memop_mask
);
5845 gen_base_offset_addr(ctx
, t0
, rs
, lsq_offset
+ 8);
5846 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
|
5847 ctx
->default_tcg_memop_mask
);
5848 gen_store_gpr(t1
, rt
);
5849 gen_store_gpr(t0
, lsq_rt1
);
5853 check_cp1_enabled(ctx
);
5854 t1
= tcg_temp_new();
5855 gen_base_offset_addr(ctx
, t0
, rs
, lsq_offset
);
5856 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
|
5857 ctx
->default_tcg_memop_mask
);
5858 gen_base_offset_addr(ctx
, t0
, rs
, lsq_offset
+ 8);
5859 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
|
5860 ctx
->default_tcg_memop_mask
);
5861 gen_store_fpr64(ctx
, t1
, rt
);
5862 gen_store_fpr64(ctx
, t0
, lsq_rt1
);
5866 t1
= tcg_temp_new();
5867 gen_base_offset_addr(ctx
, t0
, rs
, lsq_offset
);
5868 gen_load_gpr(t1
, rt
);
5869 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
|
5870 ctx
->default_tcg_memop_mask
);
5871 gen_base_offset_addr(ctx
, t0
, rs
, lsq_offset
+ 8);
5872 gen_load_gpr(t1
, lsq_rt1
);
5873 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
|
5874 ctx
->default_tcg_memop_mask
);
5878 check_cp1_enabled(ctx
);
5879 t1
= tcg_temp_new();
5880 gen_base_offset_addr(ctx
, t0
, rs
, lsq_offset
);
5881 gen_load_fpr64(ctx
, t1
, rt
);
5882 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
|
5883 ctx
->default_tcg_memop_mask
);
5884 gen_base_offset_addr(ctx
, t0
, rs
, lsq_offset
+ 8);
5885 gen_load_fpr64(ctx
, t1
, lsq_rt1
);
5886 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
|
5887 ctx
->default_tcg_memop_mask
);
5892 switch (MASK_LOONGSON_GSSHFLS(ctx
->opcode
)) {
5894 check_cp1_enabled(ctx
);
5895 gen_base_offset_addr(ctx
, t0
, rs
, shf_offset
);
5896 t1
= tcg_temp_new();
5897 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
5898 tcg_gen_andi_tl(t1
, t0
, 3);
5899 #ifndef TARGET_WORDS_BIGENDIAN
5900 tcg_gen_xori_tl(t1
, t1
, 3);
5902 tcg_gen_shli_tl(t1
, t1
, 3);
5903 tcg_gen_andi_tl(t0
, t0
, ~3);
5904 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEUL
);
5905 tcg_gen_shl_tl(t0
, t0
, t1
);
5906 t2
= tcg_const_tl(-1);
5907 tcg_gen_shl_tl(t2
, t2
, t1
);
5908 fp0
= tcg_temp_new_i32();
5909 gen_load_fpr32(ctx
, fp0
, rt
);
5910 tcg_gen_ext_i32_tl(t1
, fp0
);
5911 tcg_gen_andc_tl(t1
, t1
, t2
);
5913 tcg_gen_or_tl(t0
, t0
, t1
);
5915 #if defined(TARGET_MIPS64)
5916 tcg_gen_extrl_i64_i32(fp0
, t0
);
5918 tcg_gen_ext32s_tl(fp0
, t0
);
5920 gen_store_fpr32(ctx
, fp0
, rt
);
5921 tcg_temp_free_i32(fp0
);
5924 check_cp1_enabled(ctx
);
5925 gen_base_offset_addr(ctx
, t0
, rs
, shf_offset
);
5926 t1
= tcg_temp_new();
5927 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
5928 tcg_gen_andi_tl(t1
, t0
, 3);
5929 #ifdef TARGET_WORDS_BIGENDIAN
5930 tcg_gen_xori_tl(t1
, t1
, 3);
5932 tcg_gen_shli_tl(t1
, t1
, 3);
5933 tcg_gen_andi_tl(t0
, t0
, ~3);
5934 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEUL
);
5935 tcg_gen_shr_tl(t0
, t0
, t1
);
5936 tcg_gen_xori_tl(t1
, t1
, 31);
5937 t2
= tcg_const_tl(0xfffffffeull
);
5938 tcg_gen_shl_tl(t2
, t2
, t1
);
5939 fp0
= tcg_temp_new_i32();
5940 gen_load_fpr32(ctx
, fp0
, rt
);
5941 tcg_gen_ext_i32_tl(t1
, fp0
);
5942 tcg_gen_and_tl(t1
, t1
, t2
);
5944 tcg_gen_or_tl(t0
, t0
, t1
);
5946 #if defined(TARGET_MIPS64)
5947 tcg_gen_extrl_i64_i32(fp0
, t0
);
5949 tcg_gen_ext32s_tl(fp0
, t0
);
5951 gen_store_fpr32(ctx
, fp0
, rt
);
5952 tcg_temp_free_i32(fp0
);
5954 #if defined(TARGET_MIPS64)
5956 check_cp1_enabled(ctx
);
5957 gen_base_offset_addr(ctx
, t0
, rs
, shf_offset
);
5958 t1
= tcg_temp_new();
5959 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
5960 tcg_gen_andi_tl(t1
, t0
, 7);
5961 #ifndef TARGET_WORDS_BIGENDIAN
5962 tcg_gen_xori_tl(t1
, t1
, 7);
5964 tcg_gen_shli_tl(t1
, t1
, 3);
5965 tcg_gen_andi_tl(t0
, t0
, ~7);
5966 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
);
5967 tcg_gen_shl_tl(t0
, t0
, t1
);
5968 t2
= tcg_const_tl(-1);
5969 tcg_gen_shl_tl(t2
, t2
, t1
);
5970 gen_load_fpr64(ctx
, t1
, rt
);
5971 tcg_gen_andc_tl(t1
, t1
, t2
);
5973 tcg_gen_or_tl(t0
, t0
, t1
);
5975 gen_store_fpr64(ctx
, t0
, rt
);
5978 check_cp1_enabled(ctx
);
5979 gen_base_offset_addr(ctx
, t0
, rs
, shf_offset
);
5980 t1
= tcg_temp_new();
5981 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
5982 tcg_gen_andi_tl(t1
, t0
, 7);
5983 #ifdef TARGET_WORDS_BIGENDIAN
5984 tcg_gen_xori_tl(t1
, t1
, 7);
5986 tcg_gen_shli_tl(t1
, t1
, 3);
5987 tcg_gen_andi_tl(t0
, t0
, ~7);
5988 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
);
5989 tcg_gen_shr_tl(t0
, t0
, t1
);
5990 tcg_gen_xori_tl(t1
, t1
, 63);
5991 t2
= tcg_const_tl(0xfffffffffffffffeull
);
5992 tcg_gen_shl_tl(t2
, t2
, t1
);
5993 gen_load_fpr64(ctx
, t1
, rt
);
5994 tcg_gen_and_tl(t1
, t1
, t2
);
5996 tcg_gen_or_tl(t0
, t0
, t1
);
5998 gen_store_fpr64(ctx
, t0
, rt
);
6002 MIPS_INVAL("loongson_gsshfl");
6003 gen_reserved_instruction(ctx
);
6008 switch (MASK_LOONGSON_GSSHFLS(ctx
->opcode
)) {
6010 check_cp1_enabled(ctx
);
6011 t1
= tcg_temp_new();
6012 gen_base_offset_addr(ctx
, t0
, rs
, shf_offset
);
6013 fp0
= tcg_temp_new_i32();
6014 gen_load_fpr32(ctx
, fp0
, rt
);
6015 tcg_gen_ext_i32_tl(t1
, fp0
);
6016 gen_helper_0e2i(swl
, t1
, t0
, ctx
->mem_idx
);
6017 tcg_temp_free_i32(fp0
);
6021 check_cp1_enabled(ctx
);
6022 t1
= tcg_temp_new();
6023 gen_base_offset_addr(ctx
, t0
, rs
, shf_offset
);
6024 fp0
= tcg_temp_new_i32();
6025 gen_load_fpr32(ctx
, fp0
, rt
);
6026 tcg_gen_ext_i32_tl(t1
, fp0
);
6027 gen_helper_0e2i(swr
, t1
, t0
, ctx
->mem_idx
);
6028 tcg_temp_free_i32(fp0
);
6031 #if defined(TARGET_MIPS64)
6033 check_cp1_enabled(ctx
);
6034 t1
= tcg_temp_new();
6035 gen_base_offset_addr(ctx
, t0
, rs
, shf_offset
);
6036 gen_load_fpr64(ctx
, t1
, rt
);
6037 gen_helper_0e2i(sdl
, t1
, t0
, ctx
->mem_idx
);
6041 check_cp1_enabled(ctx
);
6042 t1
= tcg_temp_new();
6043 gen_base_offset_addr(ctx
, t0
, rs
, shf_offset
);
6044 gen_load_fpr64(ctx
, t1
, rt
);
6045 gen_helper_0e2i(sdr
, t1
, t0
, ctx
->mem_idx
);
6050 MIPS_INVAL("loongson_gsshfs");
6051 gen_reserved_instruction(ctx
);
6056 MIPS_INVAL("loongson_gslsq");
6057 gen_reserved_instruction(ctx
);
6063 /* Loongson EXT LDC2/SDC2 */
6064 static void gen_loongson_lsdc2(DisasContext
*ctx
, int rt
,
6067 int offset
= sextract32(ctx
->opcode
, 3, 8);
6068 uint32_t opc
= MASK_LOONGSON_LSDC2(ctx
->opcode
);
6072 /* Pre-conditions */
6078 /* prefetch, implement as NOP */
6089 #if defined(TARGET_MIPS64)
6092 check_cp1_enabled(ctx
);
6093 /* prefetch, implement as NOP */
6099 #if defined(TARGET_MIPS64)
6102 check_cp1_enabled(ctx
);
6105 MIPS_INVAL("loongson_lsdc2");
6106 gen_reserved_instruction(ctx
);
6111 t0
= tcg_temp_new();
6113 gen_base_offset_addr(ctx
, t0
, rs
, offset
);
6114 gen_op_addr_add(ctx
, t0
, cpu_gpr
[rd
], t0
);
6118 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_SB
);
6119 gen_store_gpr(t0
, rt
);
6122 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESW
|
6123 ctx
->default_tcg_memop_mask
);
6124 gen_store_gpr(t0
, rt
);
6127 gen_base_offset_addr(ctx
, t0
, rs
, offset
);
6129 gen_op_addr_add(ctx
, t0
, cpu_gpr
[rd
], t0
);
6131 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESL
|
6132 ctx
->default_tcg_memop_mask
);
6133 gen_store_gpr(t0
, rt
);
6135 #if defined(TARGET_MIPS64)
6137 gen_base_offset_addr(ctx
, t0
, rs
, offset
);
6139 gen_op_addr_add(ctx
, t0
, cpu_gpr
[rd
], t0
);
6141 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
|
6142 ctx
->default_tcg_memop_mask
);
6143 gen_store_gpr(t0
, rt
);
6147 check_cp1_enabled(ctx
);
6148 gen_base_offset_addr(ctx
, t0
, rs
, offset
);
6150 gen_op_addr_add(ctx
, t0
, cpu_gpr
[rd
], t0
);
6152 fp0
= tcg_temp_new_i32();
6153 tcg_gen_qemu_ld_i32(fp0
, t0
, ctx
->mem_idx
, MO_TESL
|
6154 ctx
->default_tcg_memop_mask
);
6155 gen_store_fpr32(ctx
, fp0
, rt
);
6156 tcg_temp_free_i32(fp0
);
6158 #if defined(TARGET_MIPS64)
6160 check_cp1_enabled(ctx
);
6161 gen_base_offset_addr(ctx
, t0
, rs
, offset
);
6163 gen_op_addr_add(ctx
, t0
, cpu_gpr
[rd
], t0
);
6165 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
|
6166 ctx
->default_tcg_memop_mask
);
6167 gen_store_fpr64(ctx
, t0
, rt
);
6171 t1
= tcg_temp_new();
6172 gen_load_gpr(t1
, rt
);
6173 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_SB
);
6177 t1
= tcg_temp_new();
6178 gen_load_gpr(t1
, rt
);
6179 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUW
|
6180 ctx
->default_tcg_memop_mask
);
6184 t1
= tcg_temp_new();
6185 gen_load_gpr(t1
, rt
);
6186 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
|
6187 ctx
->default_tcg_memop_mask
);
6190 #if defined(TARGET_MIPS64)
6192 t1
= tcg_temp_new();
6193 gen_load_gpr(t1
, rt
);
6194 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
|
6195 ctx
->default_tcg_memop_mask
);
6200 fp0
= tcg_temp_new_i32();
6201 gen_load_fpr32(ctx
, fp0
, rt
);
6202 tcg_gen_qemu_st_i32(fp0
, t0
, ctx
->mem_idx
, MO_TEUL
|
6203 ctx
->default_tcg_memop_mask
);
6204 tcg_temp_free_i32(fp0
);
6206 #if defined(TARGET_MIPS64)
6208 t1
= tcg_temp_new();
6209 gen_load_fpr64(ctx
, t1
, rt
);
6210 tcg_gen_qemu_st_i64(t1
, t0
, ctx
->mem_idx
, MO_TEQ
|
6211 ctx
->default_tcg_memop_mask
);
6223 static void gen_trap(DisasContext
*ctx
, uint32_t opc
,
6224 int rs
, int rt
, int16_t imm
)
6227 TCGv t0
= tcg_temp_new();
6228 TCGv t1
= tcg_temp_new();
6231 /* Load needed operands */
6239 /* Compare two registers */
6241 gen_load_gpr(t0
, rs
);
6242 gen_load_gpr(t1
, rt
);
6252 /* Compare register to immediate */
6253 if (rs
!= 0 || imm
!= 0) {
6254 gen_load_gpr(t0
, rs
);
6255 tcg_gen_movi_tl(t1
, (int32_t)imm
);
6262 case OPC_TEQ
: /* rs == rs */
6263 case OPC_TEQI
: /* r0 == 0 */
6264 case OPC_TGE
: /* rs >= rs */
6265 case OPC_TGEI
: /* r0 >= 0 */
6266 case OPC_TGEU
: /* rs >= rs unsigned */
6267 case OPC_TGEIU
: /* r0 >= 0 unsigned */
6269 generate_exception_end(ctx
, EXCP_TRAP
);
6271 case OPC_TLT
: /* rs < rs */
6272 case OPC_TLTI
: /* r0 < 0 */
6273 case OPC_TLTU
: /* rs < rs unsigned */
6274 case OPC_TLTIU
: /* r0 < 0 unsigned */
6275 case OPC_TNE
: /* rs != rs */
6276 case OPC_TNEI
: /* r0 != 0 */
6277 /* Never trap: treat as NOP. */
6281 TCGLabel
*l1
= gen_new_label();
6286 tcg_gen_brcond_tl(TCG_COND_NE
, t0
, t1
, l1
);
6290 tcg_gen_brcond_tl(TCG_COND_LT
, t0
, t1
, l1
);
6294 tcg_gen_brcond_tl(TCG_COND_LTU
, t0
, t1
, l1
);
6298 tcg_gen_brcond_tl(TCG_COND_GE
, t0
, t1
, l1
);
6302 tcg_gen_brcond_tl(TCG_COND_GEU
, t0
, t1
, l1
);
6306 tcg_gen_brcond_tl(TCG_COND_EQ
, t0
, t1
, l1
);
6309 generate_exception(ctx
, EXCP_TRAP
);
6316 static inline bool use_goto_tb(DisasContext
*ctx
, target_ulong dest
)
6318 if (unlikely(ctx
->base
.singlestep_enabled
)) {
6322 #ifndef CONFIG_USER_ONLY
6323 return (ctx
->base
.tb
->pc
& TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
);
6329 static inline void gen_goto_tb(DisasContext
*ctx
, int n
, target_ulong dest
)
6331 if (use_goto_tb(ctx
, dest
)) {
6334 tcg_gen_exit_tb(ctx
->base
.tb
, n
);
6337 if (ctx
->base
.singlestep_enabled
) {
6338 save_cpu_state(ctx
, 0);
6339 gen_helper_raise_exception_debug(cpu_env
);
6341 tcg_gen_lookup_and_goto_ptr();
6345 /* Branches (before delay slot) */
6346 static void gen_compute_branch(DisasContext
*ctx
, uint32_t opc
,
6348 int rs
, int rt
, int32_t offset
,
6351 target_ulong btgt
= -1;
6353 int bcond_compute
= 0;
6354 TCGv t0
= tcg_temp_new();
6355 TCGv t1
= tcg_temp_new();
6357 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
6358 #ifdef MIPS_DEBUG_DISAS
6359 LOG_DISAS("Branch in delay / forbidden slot at PC 0x"
6360 TARGET_FMT_lx
"\n", ctx
->base
.pc_next
);
6362 gen_reserved_instruction(ctx
);
6366 /* Load needed operands */
6372 /* Compare two registers */
6374 gen_load_gpr(t0
, rs
);
6375 gen_load_gpr(t1
, rt
);
6378 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ offset
;
6392 /* Compare to zero */
6394 gen_load_gpr(t0
, rs
);
6397 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ offset
;
6400 #if defined(TARGET_MIPS64)
6402 tcg_gen_andi_tl(t0
, cpu_dspctrl
, 0x7F);
6404 tcg_gen_andi_tl(t0
, cpu_dspctrl
, 0x3F);
6407 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ offset
;
6412 /* Jump to immediate */
6413 btgt
= ((ctx
->base
.pc_next
+ insn_bytes
) & (int32_t)0xF0000000) |
6418 /* Jump to register */
6419 if (offset
!= 0 && offset
!= 16) {
6421 * Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
6422 * others are reserved.
6424 MIPS_INVAL("jump hint");
6425 gen_reserved_instruction(ctx
);
6428 gen_load_gpr(btarget
, rs
);
6431 MIPS_INVAL("branch/jump");
6432 gen_reserved_instruction(ctx
);
6435 if (bcond_compute
== 0) {
6436 /* No condition to be computed */
6438 case OPC_BEQ
: /* rx == rx */
6439 case OPC_BEQL
: /* rx == rx likely */
6440 case OPC_BGEZ
: /* 0 >= 0 */
6441 case OPC_BGEZL
: /* 0 >= 0 likely */
6442 case OPC_BLEZ
: /* 0 <= 0 */
6443 case OPC_BLEZL
: /* 0 <= 0 likely */
6445 ctx
->hflags
|= MIPS_HFLAG_B
;
6447 case OPC_BGEZAL
: /* 0 >= 0 */
6448 case OPC_BGEZALL
: /* 0 >= 0 likely */
6449 /* Always take and link */
6451 ctx
->hflags
|= MIPS_HFLAG_B
;
6453 case OPC_BNE
: /* rx != rx */
6454 case OPC_BGTZ
: /* 0 > 0 */
6455 case OPC_BLTZ
: /* 0 < 0 */
6458 case OPC_BLTZAL
: /* 0 < 0 */
6460 * Handle as an unconditional branch to get correct delay
6464 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ delayslot_size
;
6465 ctx
->hflags
|= MIPS_HFLAG_B
;
6467 case OPC_BLTZALL
: /* 0 < 0 likely */
6468 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 8);
6469 /* Skip the instruction in the delay slot */
6470 ctx
->base
.pc_next
+= 4;
6472 case OPC_BNEL
: /* rx != rx likely */
6473 case OPC_BGTZL
: /* 0 > 0 likely */
6474 case OPC_BLTZL
: /* 0 < 0 likely */
6475 /* Skip the instruction in the delay slot */
6476 ctx
->base
.pc_next
+= 4;
6479 ctx
->hflags
|= MIPS_HFLAG_B
;
6482 ctx
->hflags
|= MIPS_HFLAG_BX
;
6486 ctx
->hflags
|= MIPS_HFLAG_B
;
6489 ctx
->hflags
|= MIPS_HFLAG_BR
;
6493 ctx
->hflags
|= MIPS_HFLAG_BR
;
6496 MIPS_INVAL("branch/jump");
6497 gen_reserved_instruction(ctx
);
6503 tcg_gen_setcond_tl(TCG_COND_EQ
, bcond
, t0
, t1
);
6506 tcg_gen_setcond_tl(TCG_COND_EQ
, bcond
, t0
, t1
);
6509 tcg_gen_setcond_tl(TCG_COND_NE
, bcond
, t0
, t1
);
6512 tcg_gen_setcond_tl(TCG_COND_NE
, bcond
, t0
, t1
);
6515 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
6518 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
6521 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
6525 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
6529 tcg_gen_setcondi_tl(TCG_COND_GT
, bcond
, t0
, 0);
6532 tcg_gen_setcondi_tl(TCG_COND_GT
, bcond
, t0
, 0);
6535 tcg_gen_setcondi_tl(TCG_COND_LE
, bcond
, t0
, 0);
6538 tcg_gen_setcondi_tl(TCG_COND_LE
, bcond
, t0
, 0);
6541 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
6544 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
6547 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 32);
6549 #if defined(TARGET_MIPS64)
6551 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 64);
6555 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
6558 ctx
->hflags
|= MIPS_HFLAG_BC
;
6561 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
6564 ctx
->hflags
|= MIPS_HFLAG_BL
;
6567 MIPS_INVAL("conditional branch/jump");
6568 gen_reserved_instruction(ctx
);
6573 ctx
->btarget
= btgt
;
6575 switch (delayslot_size
) {
6577 ctx
->hflags
|= MIPS_HFLAG_BDS16
;
6580 ctx
->hflags
|= MIPS_HFLAG_BDS32
;
6585 int post_delay
= insn_bytes
+ delayslot_size
;
6586 int lowbit
= !!(ctx
->hflags
& MIPS_HFLAG_M16
);
6588 tcg_gen_movi_tl(cpu_gpr
[blink
],
6589 ctx
->base
.pc_next
+ post_delay
+ lowbit
);
6593 if (insn_bytes
== 2) {
6594 ctx
->hflags
|= MIPS_HFLAG_B16
;
6601 /* nanoMIPS Branches */
6602 static void gen_compute_branch_nm(DisasContext
*ctx
, uint32_t opc
,
6604 int rs
, int rt
, int32_t offset
)
6606 target_ulong btgt
= -1;
6607 int bcond_compute
= 0;
6608 TCGv t0
= tcg_temp_new();
6609 TCGv t1
= tcg_temp_new();
6611 /* Load needed operands */
6615 /* Compare two registers */
6617 gen_load_gpr(t0
, rs
);
6618 gen_load_gpr(t1
, rt
);
6621 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ offset
;
6624 /* Compare to zero */
6626 gen_load_gpr(t0
, rs
);
6629 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ offset
;
6632 tcg_gen_andi_tl(t0
, cpu_dspctrl
, 0x3F);
6634 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ offset
;
6638 /* Jump to register */
6639 if (offset
!= 0 && offset
!= 16) {
6641 * Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
6642 * others are reserved.
6644 MIPS_INVAL("jump hint");
6645 gen_reserved_instruction(ctx
);
6648 gen_load_gpr(btarget
, rs
);
6651 MIPS_INVAL("branch/jump");
6652 gen_reserved_instruction(ctx
);
6655 if (bcond_compute
== 0) {
6656 /* No condition to be computed */
6658 case OPC_BEQ
: /* rx == rx */
6660 ctx
->hflags
|= MIPS_HFLAG_B
;
6662 case OPC_BGEZAL
: /* 0 >= 0 */
6663 /* Always take and link */
6664 tcg_gen_movi_tl(cpu_gpr
[31],
6665 ctx
->base
.pc_next
+ insn_bytes
);
6666 ctx
->hflags
|= MIPS_HFLAG_B
;
6668 case OPC_BNE
: /* rx != rx */
6669 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 8);
6670 /* Skip the instruction in the delay slot */
6671 ctx
->base
.pc_next
+= 4;
6674 ctx
->hflags
|= MIPS_HFLAG_BR
;
6678 tcg_gen_movi_tl(cpu_gpr
[rt
],
6679 ctx
->base
.pc_next
+ insn_bytes
);
6681 ctx
->hflags
|= MIPS_HFLAG_BR
;
6684 MIPS_INVAL("branch/jump");
6685 gen_reserved_instruction(ctx
);
6691 tcg_gen_setcond_tl(TCG_COND_EQ
, bcond
, t0
, t1
);
6694 tcg_gen_setcond_tl(TCG_COND_NE
, bcond
, t0
, t1
);
6697 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
6698 tcg_gen_movi_tl(cpu_gpr
[31],
6699 ctx
->base
.pc_next
+ insn_bytes
);
6702 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 32);
6704 ctx
->hflags
|= MIPS_HFLAG_BC
;
6707 MIPS_INVAL("conditional branch/jump");
6708 gen_reserved_instruction(ctx
);
6713 ctx
->btarget
= btgt
;
6716 if (insn_bytes
== 2) {
6717 ctx
->hflags
|= MIPS_HFLAG_B16
;
6724 /* special3 bitfield operations */
6725 static void gen_bitops(DisasContext
*ctx
, uint32_t opc
, int rt
,
6726 int rs
, int lsb
, int msb
)
6728 TCGv t0
= tcg_temp_new();
6729 TCGv t1
= tcg_temp_new();
6731 gen_load_gpr(t1
, rs
);
6734 if (lsb
+ msb
> 31) {
6738 tcg_gen_extract_tl(t0
, t1
, lsb
, msb
+ 1);
6741 * The two checks together imply that lsb == 0,
6742 * so this is a simple sign-extension.
6744 tcg_gen_ext32s_tl(t0
, t1
);
6747 #if defined(TARGET_MIPS64)
6756 if (lsb
+ msb
> 63) {
6759 tcg_gen_extract_tl(t0
, t1
, lsb
, msb
+ 1);
6766 gen_load_gpr(t0
, rt
);
6767 tcg_gen_deposit_tl(t0
, t0
, t1
, lsb
, msb
- lsb
+ 1);
6768 tcg_gen_ext32s_tl(t0
, t0
);
6770 #if defined(TARGET_MIPS64)
6781 gen_load_gpr(t0
, rt
);
6782 tcg_gen_deposit_tl(t0
, t0
, t1
, lsb
, msb
- lsb
+ 1);
6787 MIPS_INVAL("bitops");
6788 gen_reserved_instruction(ctx
);
6793 gen_store_gpr(t0
, rt
);
6798 static void gen_bshfl(DisasContext
*ctx
, uint32_t op2
, int rt
, int rd
)
6803 /* If no destination, treat it as a NOP. */
6807 t0
= tcg_temp_new();
6808 gen_load_gpr(t0
, rt
);
6812 TCGv t1
= tcg_temp_new();
6813 TCGv t2
= tcg_const_tl(0x00FF00FF);
6815 tcg_gen_shri_tl(t1
, t0
, 8);
6816 tcg_gen_and_tl(t1
, t1
, t2
);
6817 tcg_gen_and_tl(t0
, t0
, t2
);
6818 tcg_gen_shli_tl(t0
, t0
, 8);
6819 tcg_gen_or_tl(t0
, t0
, t1
);
6822 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
6826 tcg_gen_ext8s_tl(cpu_gpr
[rd
], t0
);
6829 tcg_gen_ext16s_tl(cpu_gpr
[rd
], t0
);
6831 #if defined(TARGET_MIPS64)
6834 TCGv t1
= tcg_temp_new();
6835 TCGv t2
= tcg_const_tl(0x00FF00FF00FF00FFULL
);
6837 tcg_gen_shri_tl(t1
, t0
, 8);
6838 tcg_gen_and_tl(t1
, t1
, t2
);
6839 tcg_gen_and_tl(t0
, t0
, t2
);
6840 tcg_gen_shli_tl(t0
, t0
, 8);
6841 tcg_gen_or_tl(cpu_gpr
[rd
], t0
, t1
);
6848 TCGv t1
= tcg_temp_new();
6849 TCGv t2
= tcg_const_tl(0x0000FFFF0000FFFFULL
);
6851 tcg_gen_shri_tl(t1
, t0
, 16);
6852 tcg_gen_and_tl(t1
, t1
, t2
);
6853 tcg_gen_and_tl(t0
, t0
, t2
);
6854 tcg_gen_shli_tl(t0
, t0
, 16);
6855 tcg_gen_or_tl(t0
, t0
, t1
);
6856 tcg_gen_shri_tl(t1
, t0
, 32);
6857 tcg_gen_shli_tl(t0
, t0
, 32);
6858 tcg_gen_or_tl(cpu_gpr
[rd
], t0
, t1
);
6865 MIPS_INVAL("bsfhl");
6866 gen_reserved_instruction(ctx
);
6873 static void gen_lsa(DisasContext
*ctx
, int opc
, int rd
, int rs
, int rt
,
6882 t0
= tcg_temp_new();
6883 t1
= tcg_temp_new();
6884 gen_load_gpr(t0
, rs
);
6885 gen_load_gpr(t1
, rt
);
6886 tcg_gen_shli_tl(t0
, t0
, imm2
+ 1);
6887 tcg_gen_add_tl(cpu_gpr
[rd
], t0
, t1
);
6888 if (opc
== OPC_LSA
) {
6889 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
6898 static void gen_align_bits(DisasContext
*ctx
, int wordsz
, int rd
, int rs
,
6906 t0
= tcg_temp_new();
6907 if (bits
== 0 || bits
== wordsz
) {
6909 gen_load_gpr(t0
, rt
);
6911 gen_load_gpr(t0
, rs
);
6915 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
6917 #if defined(TARGET_MIPS64)
6919 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
6924 TCGv t1
= tcg_temp_new();
6925 gen_load_gpr(t0
, rt
);
6926 gen_load_gpr(t1
, rs
);
6930 TCGv_i64 t2
= tcg_temp_new_i64();
6931 tcg_gen_concat_tl_i64(t2
, t1
, t0
);
6932 tcg_gen_shri_i64(t2
, t2
, 32 - bits
);
6933 gen_move_low32(cpu_gpr
[rd
], t2
);
6934 tcg_temp_free_i64(t2
);
6937 #if defined(TARGET_MIPS64)
6939 tcg_gen_shli_tl(t0
, t0
, bits
);
6940 tcg_gen_shri_tl(t1
, t1
, 64 - bits
);
6941 tcg_gen_or_tl(cpu_gpr
[rd
], t1
, t0
);
6951 static void gen_align(DisasContext
*ctx
, int wordsz
, int rd
, int rs
, int rt
,
6954 gen_align_bits(ctx
, wordsz
, rd
, rs
, rt
, bp
* 8);
6957 static void gen_ext(DisasContext
*ctx
, int wordsz
, int rd
, int rs
, int rt
,
6960 gen_align_bits(ctx
, wordsz
, rd
, rs
, rt
, wordsz
- shift
);
6963 static void gen_bitswap(DisasContext
*ctx
, int opc
, int rd
, int rt
)
6970 t0
= tcg_temp_new();
6971 gen_load_gpr(t0
, rt
);
6974 gen_helper_bitswap(cpu_gpr
[rd
], t0
);
6976 #if defined(TARGET_MIPS64)
6978 gen_helper_dbitswap(cpu_gpr
[rd
], t0
);
6985 #ifndef CONFIG_USER_ONLY
6986 /* CP0 (MMU and control) */
6987 static inline void gen_mthc0_entrylo(TCGv arg
, target_ulong off
)
6989 TCGv_i64 t0
= tcg_temp_new_i64();
6990 TCGv_i64 t1
= tcg_temp_new_i64();
6992 tcg_gen_ext_tl_i64(t0
, arg
);
6993 tcg_gen_ld_i64(t1
, cpu_env
, off
);
6994 #if defined(TARGET_MIPS64)
6995 tcg_gen_deposit_i64(t1
, t1
, t0
, 30, 32);
6997 tcg_gen_concat32_i64(t1
, t1
, t0
);
6999 tcg_gen_st_i64(t1
, cpu_env
, off
);
7000 tcg_temp_free_i64(t1
);
7001 tcg_temp_free_i64(t0
);
7004 static inline void gen_mthc0_store64(TCGv arg
, target_ulong off
)
7006 TCGv_i64 t0
= tcg_temp_new_i64();
7007 TCGv_i64 t1
= tcg_temp_new_i64();
7009 tcg_gen_ext_tl_i64(t0
, arg
);
7010 tcg_gen_ld_i64(t1
, cpu_env
, off
);
7011 tcg_gen_concat32_i64(t1
, t1
, t0
);
7012 tcg_gen_st_i64(t1
, cpu_env
, off
);
7013 tcg_temp_free_i64(t1
);
7014 tcg_temp_free_i64(t0
);
7017 static inline void gen_mfhc0_entrylo(TCGv arg
, target_ulong off
)
7019 TCGv_i64 t0
= tcg_temp_new_i64();
7021 tcg_gen_ld_i64(t0
, cpu_env
, off
);
7022 #if defined(TARGET_MIPS64)
7023 tcg_gen_shri_i64(t0
, t0
, 30);
7025 tcg_gen_shri_i64(t0
, t0
, 32);
7027 gen_move_low32(arg
, t0
);
7028 tcg_temp_free_i64(t0
);
7031 static inline void gen_mfhc0_load64(TCGv arg
, target_ulong off
, int shift
)
7033 TCGv_i64 t0
= tcg_temp_new_i64();
7035 tcg_gen_ld_i64(t0
, cpu_env
, off
);
7036 tcg_gen_shri_i64(t0
, t0
, 32 + shift
);
7037 gen_move_low32(arg
, t0
);
7038 tcg_temp_free_i64(t0
);
7041 static inline void gen_mfc0_load32(TCGv arg
, target_ulong off
)
7043 TCGv_i32 t0
= tcg_temp_new_i32();
7045 tcg_gen_ld_i32(t0
, cpu_env
, off
);
7046 tcg_gen_ext_i32_tl(arg
, t0
);
7047 tcg_temp_free_i32(t0
);
7050 static inline void gen_mfc0_load64(TCGv arg
, target_ulong off
)
7052 tcg_gen_ld_tl(arg
, cpu_env
, off
);
7053 tcg_gen_ext32s_tl(arg
, arg
);
7056 static inline void gen_mtc0_store32(TCGv arg
, target_ulong off
)
7058 TCGv_i32 t0
= tcg_temp_new_i32();
7060 tcg_gen_trunc_tl_i32(t0
, arg
);
7061 tcg_gen_st_i32(t0
, cpu_env
, off
);
7062 tcg_temp_free_i32(t0
);
7065 #define CP0_CHECK(c) \
7068 goto cp0_unimplemented; \
7072 static void gen_mfhc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
7074 const char *register_name
= "invalid";
7077 case CP0_REGISTER_02
:
7080 CP0_CHECK(ctx
->hflags
& MIPS_HFLAG_ELPA
);
7081 gen_mfhc0_entrylo(arg
, offsetof(CPUMIPSState
, CP0_EntryLo0
));
7082 register_name
= "EntryLo0";
7085 goto cp0_unimplemented
;
7088 case CP0_REGISTER_03
:
7090 case CP0_REG03__ENTRYLO1
:
7091 CP0_CHECK(ctx
->hflags
& MIPS_HFLAG_ELPA
);
7092 gen_mfhc0_entrylo(arg
, offsetof(CPUMIPSState
, CP0_EntryLo1
));
7093 register_name
= "EntryLo1";
7096 goto cp0_unimplemented
;
7099 case CP0_REGISTER_09
:
7101 case CP0_REG09__SAAR
:
7102 CP0_CHECK(ctx
->saar
);
7103 gen_helper_mfhc0_saar(arg
, cpu_env
);
7104 register_name
= "SAAR";
7107 goto cp0_unimplemented
;
7110 case CP0_REGISTER_17
:
7112 case CP0_REG17__LLADDR
:
7113 gen_mfhc0_load64(arg
, offsetof(CPUMIPSState
, CP0_LLAddr
),
7114 ctx
->CP0_LLAddr_shift
);
7115 register_name
= "LLAddr";
7117 case CP0_REG17__MAAR
:
7118 CP0_CHECK(ctx
->mrp
);
7119 gen_helper_mfhc0_maar(arg
, cpu_env
);
7120 register_name
= "MAAR";
7123 goto cp0_unimplemented
;
7126 case CP0_REGISTER_19
:
7128 case CP0_REG19__WATCHHI0
:
7129 case CP0_REG19__WATCHHI1
:
7130 case CP0_REG19__WATCHHI2
:
7131 case CP0_REG19__WATCHHI3
:
7132 case CP0_REG19__WATCHHI4
:
7133 case CP0_REG19__WATCHHI5
:
7134 case CP0_REG19__WATCHHI6
:
7135 case CP0_REG19__WATCHHI7
:
7136 /* upper 32 bits are only available when Config5MI != 0 */
7138 gen_mfhc0_load64(arg
, offsetof(CPUMIPSState
, CP0_WatchHi
[sel
]), 0);
7139 register_name
= "WatchHi";
7142 goto cp0_unimplemented
;
7145 case CP0_REGISTER_28
:
7151 gen_mfhc0_load64(arg
, offsetof(CPUMIPSState
, CP0_TagLo
), 0);
7152 register_name
= "TagLo";
7155 goto cp0_unimplemented
;
7159 goto cp0_unimplemented
;
7161 trace_mips_translate_c0("mfhc0", register_name
, reg
, sel
);
7165 qemu_log_mask(LOG_UNIMP
, "mfhc0 %s (reg %d sel %d)\n",
7166 register_name
, reg
, sel
);
7167 tcg_gen_movi_tl(arg
, 0);
7170 static void gen_mthc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
7172 const char *register_name
= "invalid";
7173 uint64_t mask
= ctx
->PAMask
>> 36;
7176 case CP0_REGISTER_02
:
7179 CP0_CHECK(ctx
->hflags
& MIPS_HFLAG_ELPA
);
7180 tcg_gen_andi_tl(arg
, arg
, mask
);
7181 gen_mthc0_entrylo(arg
, offsetof(CPUMIPSState
, CP0_EntryLo0
));
7182 register_name
= "EntryLo0";
7185 goto cp0_unimplemented
;
7188 case CP0_REGISTER_03
:
7190 case CP0_REG03__ENTRYLO1
:
7191 CP0_CHECK(ctx
->hflags
& MIPS_HFLAG_ELPA
);
7192 tcg_gen_andi_tl(arg
, arg
, mask
);
7193 gen_mthc0_entrylo(arg
, offsetof(CPUMIPSState
, CP0_EntryLo1
));
7194 register_name
= "EntryLo1";
7197 goto cp0_unimplemented
;
7200 case CP0_REGISTER_09
:
7202 case CP0_REG09__SAAR
:
7203 CP0_CHECK(ctx
->saar
);
7204 gen_helper_mthc0_saar(cpu_env
, arg
);
7205 register_name
= "SAAR";
7208 goto cp0_unimplemented
;
7211 case CP0_REGISTER_17
:
7213 case CP0_REG17__LLADDR
:
7215 * LLAddr is read-only (the only exception is bit 0 if LLB is
7216 * supported); the CP0_LLAddr_rw_bitmask does not seem to be
7217 * relevant for modern MIPS cores supporting MTHC0, therefore
7218 * treating MTHC0 to LLAddr as NOP.
7220 register_name
= "LLAddr";
7222 case CP0_REG17__MAAR
:
7223 CP0_CHECK(ctx
->mrp
);
7224 gen_helper_mthc0_maar(cpu_env
, arg
);
7225 register_name
= "MAAR";
7228 goto cp0_unimplemented
;
7231 case CP0_REGISTER_19
:
7233 case CP0_REG19__WATCHHI0
:
7234 case CP0_REG19__WATCHHI1
:
7235 case CP0_REG19__WATCHHI2
:
7236 case CP0_REG19__WATCHHI3
:
7237 case CP0_REG19__WATCHHI4
:
7238 case CP0_REG19__WATCHHI5
:
7239 case CP0_REG19__WATCHHI6
:
7240 case CP0_REG19__WATCHHI7
:
7241 /* upper 32 bits are only available when Config5MI != 0 */
7243 gen_helper_0e1i(mthc0_watchhi
, arg
, sel
);
7244 register_name
= "WatchHi";
7247 goto cp0_unimplemented
;
7250 case CP0_REGISTER_28
:
7256 tcg_gen_andi_tl(arg
, arg
, mask
);
7257 gen_mthc0_store64(arg
, offsetof(CPUMIPSState
, CP0_TagLo
));
7258 register_name
= "TagLo";
7261 goto cp0_unimplemented
;
7265 goto cp0_unimplemented
;
7267 trace_mips_translate_c0("mthc0", register_name
, reg
, sel
);
7270 qemu_log_mask(LOG_UNIMP
, "mthc0 %s (reg %d sel %d)\n",
7271 register_name
, reg
, sel
);
7274 static inline void gen_mfc0_unimplemented(DisasContext
*ctx
, TCGv arg
)
7276 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
7277 tcg_gen_movi_tl(arg
, 0);
7279 tcg_gen_movi_tl(arg
, ~0);
7283 static void gen_mfc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
7285 const char *register_name
= "invalid";
7288 check_insn(ctx
, ISA_MIPS_R1
);
7292 case CP0_REGISTER_00
:
7294 case CP0_REG00__INDEX
:
7295 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Index
));
7296 register_name
= "Index";
7298 case CP0_REG00__MVPCONTROL
:
7299 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7300 gen_helper_mfc0_mvpcontrol(arg
, cpu_env
);
7301 register_name
= "MVPControl";
7303 case CP0_REG00__MVPCONF0
:
7304 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7305 gen_helper_mfc0_mvpconf0(arg
, cpu_env
);
7306 register_name
= "MVPConf0";
7308 case CP0_REG00__MVPCONF1
:
7309 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7310 gen_helper_mfc0_mvpconf1(arg
, cpu_env
);
7311 register_name
= "MVPConf1";
7313 case CP0_REG00__VPCONTROL
:
7315 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPControl
));
7316 register_name
= "VPControl";
7319 goto cp0_unimplemented
;
7322 case CP0_REGISTER_01
:
7324 case CP0_REG01__RANDOM
:
7325 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS_R6
));
7326 gen_helper_mfc0_random(arg
, cpu_env
);
7327 register_name
= "Random";
7329 case CP0_REG01__VPECONTROL
:
7330 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7331 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEControl
));
7332 register_name
= "VPEControl";
7334 case CP0_REG01__VPECONF0
:
7335 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7336 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf0
));
7337 register_name
= "VPEConf0";
7339 case CP0_REG01__VPECONF1
:
7340 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7341 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf1
));
7342 register_name
= "VPEConf1";
7344 case CP0_REG01__YQMASK
:
7345 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7346 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_YQMask
));
7347 register_name
= "YQMask";
7349 case CP0_REG01__VPESCHEDULE
:
7350 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7351 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_VPESchedule
));
7352 register_name
= "VPESchedule";
7354 case CP0_REG01__VPESCHEFBACK
:
7355 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7356 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
7357 register_name
= "VPEScheFBack";
7359 case CP0_REG01__VPEOPT
:
7360 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7361 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEOpt
));
7362 register_name
= "VPEOpt";
7365 goto cp0_unimplemented
;
7368 case CP0_REGISTER_02
:
7370 case CP0_REG02__ENTRYLO0
:
7372 TCGv_i64 tmp
= tcg_temp_new_i64();
7373 tcg_gen_ld_i64(tmp
, cpu_env
,
7374 offsetof(CPUMIPSState
, CP0_EntryLo0
));
7375 #if defined(TARGET_MIPS64)
7377 /* Move RI/XI fields to bits 31:30 */
7378 tcg_gen_shri_tl(arg
, tmp
, CP0EnLo_XI
);
7379 tcg_gen_deposit_tl(tmp
, tmp
, arg
, 30, 2);
7382 gen_move_low32(arg
, tmp
);
7383 tcg_temp_free_i64(tmp
);
7385 register_name
= "EntryLo0";
7387 case CP0_REG02__TCSTATUS
:
7388 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7389 gen_helper_mfc0_tcstatus(arg
, cpu_env
);
7390 register_name
= "TCStatus";
7392 case CP0_REG02__TCBIND
:
7393 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7394 gen_helper_mfc0_tcbind(arg
, cpu_env
);
7395 register_name
= "TCBind";
7397 case CP0_REG02__TCRESTART
:
7398 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7399 gen_helper_mfc0_tcrestart(arg
, cpu_env
);
7400 register_name
= "TCRestart";
7402 case CP0_REG02__TCHALT
:
7403 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7404 gen_helper_mfc0_tchalt(arg
, cpu_env
);
7405 register_name
= "TCHalt";
7407 case CP0_REG02__TCCONTEXT
:
7408 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7409 gen_helper_mfc0_tccontext(arg
, cpu_env
);
7410 register_name
= "TCContext";
7412 case CP0_REG02__TCSCHEDULE
:
7413 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7414 gen_helper_mfc0_tcschedule(arg
, cpu_env
);
7415 register_name
= "TCSchedule";
7417 case CP0_REG02__TCSCHEFBACK
:
7418 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7419 gen_helper_mfc0_tcschefback(arg
, cpu_env
);
7420 register_name
= "TCScheFBack";
7423 goto cp0_unimplemented
;
7426 case CP0_REGISTER_03
:
7428 case CP0_REG03__ENTRYLO1
:
7430 TCGv_i64 tmp
= tcg_temp_new_i64();
7431 tcg_gen_ld_i64(tmp
, cpu_env
,
7432 offsetof(CPUMIPSState
, CP0_EntryLo1
));
7433 #if defined(TARGET_MIPS64)
7435 /* Move RI/XI fields to bits 31:30 */
7436 tcg_gen_shri_tl(arg
, tmp
, CP0EnLo_XI
);
7437 tcg_gen_deposit_tl(tmp
, tmp
, arg
, 30, 2);
7440 gen_move_low32(arg
, tmp
);
7441 tcg_temp_free_i64(tmp
);
7443 register_name
= "EntryLo1";
7445 case CP0_REG03__GLOBALNUM
:
7447 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_GlobalNumber
));
7448 register_name
= "GlobalNumber";
7451 goto cp0_unimplemented
;
7454 case CP0_REGISTER_04
:
7456 case CP0_REG04__CONTEXT
:
7457 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_Context
));
7458 tcg_gen_ext32s_tl(arg
, arg
);
7459 register_name
= "Context";
7461 case CP0_REG04__CONTEXTCONFIG
:
7463 /* gen_helper_mfc0_contextconfig(arg); */
7464 register_name
= "ContextConfig";
7465 goto cp0_unimplemented
;
7466 case CP0_REG04__USERLOCAL
:
7467 CP0_CHECK(ctx
->ulri
);
7468 tcg_gen_ld_tl(arg
, cpu_env
,
7469 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
7470 tcg_gen_ext32s_tl(arg
, arg
);
7471 register_name
= "UserLocal";
7473 case CP0_REG04__MMID
:
7475 gen_helper_mtc0_memorymapid(cpu_env
, arg
);
7476 register_name
= "MMID";
7479 goto cp0_unimplemented
;
7482 case CP0_REGISTER_05
:
7484 case CP0_REG05__PAGEMASK
:
7485 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageMask
));
7486 register_name
= "PageMask";
7488 case CP0_REG05__PAGEGRAIN
:
7489 check_insn(ctx
, ISA_MIPS_R2
);
7490 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageGrain
));
7491 register_name
= "PageGrain";
7493 case CP0_REG05__SEGCTL0
:
7495 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_SegCtl0
));
7496 tcg_gen_ext32s_tl(arg
, arg
);
7497 register_name
= "SegCtl0";
7499 case CP0_REG05__SEGCTL1
:
7501 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_SegCtl1
));
7502 tcg_gen_ext32s_tl(arg
, arg
);
7503 register_name
= "SegCtl1";
7505 case CP0_REG05__SEGCTL2
:
7507 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_SegCtl2
));
7508 tcg_gen_ext32s_tl(arg
, arg
);
7509 register_name
= "SegCtl2";
7511 case CP0_REG05__PWBASE
:
7513 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PWBase
));
7514 register_name
= "PWBase";
7516 case CP0_REG05__PWFIELD
:
7518 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PWField
));
7519 register_name
= "PWField";
7521 case CP0_REG05__PWSIZE
:
7523 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PWSize
));
7524 register_name
= "PWSize";
7527 goto cp0_unimplemented
;
7530 case CP0_REGISTER_06
:
7532 case CP0_REG06__WIRED
:
7533 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Wired
));
7534 register_name
= "Wired";
7536 case CP0_REG06__SRSCONF0
:
7537 check_insn(ctx
, ISA_MIPS_R2
);
7538 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf0
));
7539 register_name
= "SRSConf0";
7541 case CP0_REG06__SRSCONF1
:
7542 check_insn(ctx
, ISA_MIPS_R2
);
7543 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf1
));
7544 register_name
= "SRSConf1";
7546 case CP0_REG06__SRSCONF2
:
7547 check_insn(ctx
, ISA_MIPS_R2
);
7548 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf2
));
7549 register_name
= "SRSConf2";
7551 case CP0_REG06__SRSCONF3
:
7552 check_insn(ctx
, ISA_MIPS_R2
);
7553 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf3
));
7554 register_name
= "SRSConf3";
7556 case CP0_REG06__SRSCONF4
:
7557 check_insn(ctx
, ISA_MIPS_R2
);
7558 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf4
));
7559 register_name
= "SRSConf4";
7561 case CP0_REG06__PWCTL
:
7563 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PWCtl
));
7564 register_name
= "PWCtl";
7567 goto cp0_unimplemented
;
7570 case CP0_REGISTER_07
:
7572 case CP0_REG07__HWRENA
:
7573 check_insn(ctx
, ISA_MIPS_R2
);
7574 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_HWREna
));
7575 register_name
= "HWREna";
7578 goto cp0_unimplemented
;
7581 case CP0_REGISTER_08
:
7583 case CP0_REG08__BADVADDR
:
7584 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_BadVAddr
));
7585 tcg_gen_ext32s_tl(arg
, arg
);
7586 register_name
= "BadVAddr";
7588 case CP0_REG08__BADINSTR
:
7590 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstr
));
7591 register_name
= "BadInstr";
7593 case CP0_REG08__BADINSTRP
:
7595 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstrP
));
7596 register_name
= "BadInstrP";
7598 case CP0_REG08__BADINSTRX
:
7600 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstrX
));
7601 tcg_gen_andi_tl(arg
, arg
, ~0xffff);
7602 register_name
= "BadInstrX";
7605 goto cp0_unimplemented
;
7608 case CP0_REGISTER_09
:
7610 case CP0_REG09__COUNT
:
7611 /* Mark as an IO operation because we read the time. */
7612 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
7615 gen_helper_mfc0_count(arg
, cpu_env
);
7617 * Break the TB to be able to take timer interrupts immediately
7618 * after reading count. DISAS_STOP isn't sufficient, we need to
7619 * ensure we break completely out of translated code.
7621 gen_save_pc(ctx
->base
.pc_next
+ 4);
7622 ctx
->base
.is_jmp
= DISAS_EXIT
;
7623 register_name
= "Count";
7625 case CP0_REG09__SAARI
:
7626 CP0_CHECK(ctx
->saar
);
7627 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SAARI
));
7628 register_name
= "SAARI";
7630 case CP0_REG09__SAAR
:
7631 CP0_CHECK(ctx
->saar
);
7632 gen_helper_mfc0_saar(arg
, cpu_env
);
7633 register_name
= "SAAR";
7636 goto cp0_unimplemented
;
7639 case CP0_REGISTER_10
:
7641 case CP0_REG10__ENTRYHI
:
7642 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryHi
));
7643 tcg_gen_ext32s_tl(arg
, arg
);
7644 register_name
= "EntryHi";
7647 goto cp0_unimplemented
;
7650 case CP0_REGISTER_11
:
7652 case CP0_REG11__COMPARE
:
7653 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Compare
));
7654 register_name
= "Compare";
7656 /* 6,7 are implementation dependent */
7658 goto cp0_unimplemented
;
7661 case CP0_REGISTER_12
:
7663 case CP0_REG12__STATUS
:
7664 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Status
));
7665 register_name
= "Status";
7667 case CP0_REG12__INTCTL
:
7668 check_insn(ctx
, ISA_MIPS_R2
);
7669 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_IntCtl
));
7670 register_name
= "IntCtl";
7672 case CP0_REG12__SRSCTL
:
7673 check_insn(ctx
, ISA_MIPS_R2
);
7674 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
7675 register_name
= "SRSCtl";
7677 case CP0_REG12__SRSMAP
:
7678 check_insn(ctx
, ISA_MIPS_R2
);
7679 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
7680 register_name
= "SRSMap";
7683 goto cp0_unimplemented
;
7686 case CP0_REGISTER_13
:
7688 case CP0_REG13__CAUSE
:
7689 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Cause
));
7690 register_name
= "Cause";
7693 goto cp0_unimplemented
;
7696 case CP0_REGISTER_14
:
7698 case CP0_REG14__EPC
:
7699 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
7700 tcg_gen_ext32s_tl(arg
, arg
);
7701 register_name
= "EPC";
7704 goto cp0_unimplemented
;
7707 case CP0_REGISTER_15
:
7709 case CP0_REG15__PRID
:
7710 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PRid
));
7711 register_name
= "PRid";
7713 case CP0_REG15__EBASE
:
7714 check_insn(ctx
, ISA_MIPS_R2
);
7715 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EBase
));
7716 tcg_gen_ext32s_tl(arg
, arg
);
7717 register_name
= "EBase";
7719 case CP0_REG15__CMGCRBASE
:
7720 check_insn(ctx
, ISA_MIPS_R2
);
7721 CP0_CHECK(ctx
->cmgcr
);
7722 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_CMGCRBase
));
7723 tcg_gen_ext32s_tl(arg
, arg
);
7724 register_name
= "CMGCRBase";
7727 goto cp0_unimplemented
;
7730 case CP0_REGISTER_16
:
7732 case CP0_REG16__CONFIG
:
7733 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config0
));
7734 register_name
= "Config";
7736 case CP0_REG16__CONFIG1
:
7737 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config1
));
7738 register_name
= "Config1";
7740 case CP0_REG16__CONFIG2
:
7741 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config2
));
7742 register_name
= "Config2";
7744 case CP0_REG16__CONFIG3
:
7745 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config3
));
7746 register_name
= "Config3";
7748 case CP0_REG16__CONFIG4
:
7749 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config4
));
7750 register_name
= "Config4";
7752 case CP0_REG16__CONFIG5
:
7753 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config5
));
7754 register_name
= "Config5";
7756 /* 6,7 are implementation dependent */
7757 case CP0_REG16__CONFIG6
:
7758 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config6
));
7759 register_name
= "Config6";
7761 case CP0_REG16__CONFIG7
:
7762 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config7
));
7763 register_name
= "Config7";
7766 goto cp0_unimplemented
;
7769 case CP0_REGISTER_17
:
7771 case CP0_REG17__LLADDR
:
7772 gen_helper_mfc0_lladdr(arg
, cpu_env
);
7773 register_name
= "LLAddr";
7775 case CP0_REG17__MAAR
:
7776 CP0_CHECK(ctx
->mrp
);
7777 gen_helper_mfc0_maar(arg
, cpu_env
);
7778 register_name
= "MAAR";
7780 case CP0_REG17__MAARI
:
7781 CP0_CHECK(ctx
->mrp
);
7782 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_MAARI
));
7783 register_name
= "MAARI";
7786 goto cp0_unimplemented
;
7789 case CP0_REGISTER_18
:
7791 case CP0_REG18__WATCHLO0
:
7792 case CP0_REG18__WATCHLO1
:
7793 case CP0_REG18__WATCHLO2
:
7794 case CP0_REG18__WATCHLO3
:
7795 case CP0_REG18__WATCHLO4
:
7796 case CP0_REG18__WATCHLO5
:
7797 case CP0_REG18__WATCHLO6
:
7798 case CP0_REG18__WATCHLO7
:
7799 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
7800 gen_helper_1e0i(mfc0_watchlo
, arg
, sel
);
7801 register_name
= "WatchLo";
7804 goto cp0_unimplemented
;
7807 case CP0_REGISTER_19
:
7809 case CP0_REG19__WATCHHI0
:
7810 case CP0_REG19__WATCHHI1
:
7811 case CP0_REG19__WATCHHI2
:
7812 case CP0_REG19__WATCHHI3
:
7813 case CP0_REG19__WATCHHI4
:
7814 case CP0_REG19__WATCHHI5
:
7815 case CP0_REG19__WATCHHI6
:
7816 case CP0_REG19__WATCHHI7
:
7817 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
7818 gen_helper_1e0i(mfc0_watchhi
, arg
, sel
);
7819 register_name
= "WatchHi";
7822 goto cp0_unimplemented
;
7825 case CP0_REGISTER_20
:
7827 case CP0_REG20__XCONTEXT
:
7828 #if defined(TARGET_MIPS64)
7829 check_insn(ctx
, ISA_MIPS3
);
7830 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_XContext
));
7831 tcg_gen_ext32s_tl(arg
, arg
);
7832 register_name
= "XContext";
7836 goto cp0_unimplemented
;
7839 case CP0_REGISTER_21
:
7840 /* Officially reserved, but sel 0 is used for R1x000 framemask */
7841 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS_R6
));
7844 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Framemask
));
7845 register_name
= "Framemask";
7848 goto cp0_unimplemented
;
7851 case CP0_REGISTER_22
:
7852 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
7853 register_name
= "'Diagnostic"; /* implementation dependent */
7855 case CP0_REGISTER_23
:
7857 case CP0_REG23__DEBUG
:
7858 gen_helper_mfc0_debug(arg
, cpu_env
); /* EJTAG support */
7859 register_name
= "Debug";
7861 case CP0_REG23__TRACECONTROL
:
7862 /* PDtrace support */
7863 /* gen_helper_mfc0_tracecontrol(arg); */
7864 register_name
= "TraceControl";
7865 goto cp0_unimplemented
;
7866 case CP0_REG23__TRACECONTROL2
:
7867 /* PDtrace support */
7868 /* gen_helper_mfc0_tracecontrol2(arg); */
7869 register_name
= "TraceControl2";
7870 goto cp0_unimplemented
;
7871 case CP0_REG23__USERTRACEDATA1
:
7872 /* PDtrace support */
7873 /* gen_helper_mfc0_usertracedata1(arg);*/
7874 register_name
= "UserTraceData1";
7875 goto cp0_unimplemented
;
7876 case CP0_REG23__TRACEIBPC
:
7877 /* PDtrace support */
7878 /* gen_helper_mfc0_traceibpc(arg); */
7879 register_name
= "TraceIBPC";
7880 goto cp0_unimplemented
;
7881 case CP0_REG23__TRACEDBPC
:
7882 /* PDtrace support */
7883 /* gen_helper_mfc0_tracedbpc(arg); */
7884 register_name
= "TraceDBPC";
7885 goto cp0_unimplemented
;
7887 goto cp0_unimplemented
;
7890 case CP0_REGISTER_24
:
7892 case CP0_REG24__DEPC
:
7894 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
7895 tcg_gen_ext32s_tl(arg
, arg
);
7896 register_name
= "DEPC";
7899 goto cp0_unimplemented
;
7902 case CP0_REGISTER_25
:
7904 case CP0_REG25__PERFCTL0
:
7905 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Performance0
));
7906 register_name
= "Performance0";
7908 case CP0_REG25__PERFCNT0
:
7909 /* gen_helper_mfc0_performance1(arg); */
7910 register_name
= "Performance1";
7911 goto cp0_unimplemented
;
7912 case CP0_REG25__PERFCTL1
:
7913 /* gen_helper_mfc0_performance2(arg); */
7914 register_name
= "Performance2";
7915 goto cp0_unimplemented
;
7916 case CP0_REG25__PERFCNT1
:
7917 /* gen_helper_mfc0_performance3(arg); */
7918 register_name
= "Performance3";
7919 goto cp0_unimplemented
;
7920 case CP0_REG25__PERFCTL2
:
7921 /* gen_helper_mfc0_performance4(arg); */
7922 register_name
= "Performance4";
7923 goto cp0_unimplemented
;
7924 case CP0_REG25__PERFCNT2
:
7925 /* gen_helper_mfc0_performance5(arg); */
7926 register_name
= "Performance5";
7927 goto cp0_unimplemented
;
7928 case CP0_REG25__PERFCTL3
:
7929 /* gen_helper_mfc0_performance6(arg); */
7930 register_name
= "Performance6";
7931 goto cp0_unimplemented
;
7932 case CP0_REG25__PERFCNT3
:
7933 /* gen_helper_mfc0_performance7(arg); */
7934 register_name
= "Performance7";
7935 goto cp0_unimplemented
;
7937 goto cp0_unimplemented
;
7940 case CP0_REGISTER_26
:
7942 case CP0_REG26__ERRCTL
:
7943 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_ErrCtl
));
7944 register_name
= "ErrCtl";
7947 goto cp0_unimplemented
;
7950 case CP0_REGISTER_27
:
7952 case CP0_REG27__CACHERR
:
7953 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
7954 register_name
= "CacheErr";
7957 goto cp0_unimplemented
;
7960 case CP0_REGISTER_28
:
7962 case CP0_REG28__TAGLO
:
7963 case CP0_REG28__TAGLO1
:
7964 case CP0_REG28__TAGLO2
:
7965 case CP0_REG28__TAGLO3
:
7967 TCGv_i64 tmp
= tcg_temp_new_i64();
7968 tcg_gen_ld_i64(tmp
, cpu_env
, offsetof(CPUMIPSState
, CP0_TagLo
));
7969 gen_move_low32(arg
, tmp
);
7970 tcg_temp_free_i64(tmp
);
7972 register_name
= "TagLo";
7974 case CP0_REG28__DATALO
:
7975 case CP0_REG28__DATALO1
:
7976 case CP0_REG28__DATALO2
:
7977 case CP0_REG28__DATALO3
:
7978 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataLo
));
7979 register_name
= "DataLo";
7982 goto cp0_unimplemented
;
7985 case CP0_REGISTER_29
:
7987 case CP0_REG29__TAGHI
:
7988 case CP0_REG29__TAGHI1
:
7989 case CP0_REG29__TAGHI2
:
7990 case CP0_REG29__TAGHI3
:
7991 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagHi
));
7992 register_name
= "TagHi";
7994 case CP0_REG29__DATAHI
:
7995 case CP0_REG29__DATAHI1
:
7996 case CP0_REG29__DATAHI2
:
7997 case CP0_REG29__DATAHI3
:
7998 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataHi
));
7999 register_name
= "DataHi";
8002 goto cp0_unimplemented
;
8005 case CP0_REGISTER_30
:
8007 case CP0_REG30__ERROREPC
:
8008 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
8009 tcg_gen_ext32s_tl(arg
, arg
);
8010 register_name
= "ErrorEPC";
8013 goto cp0_unimplemented
;
8016 case CP0_REGISTER_31
:
8018 case CP0_REG31__DESAVE
:
8020 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
8021 register_name
= "DESAVE";
8023 case CP0_REG31__KSCRATCH1
:
8024 case CP0_REG31__KSCRATCH2
:
8025 case CP0_REG31__KSCRATCH3
:
8026 case CP0_REG31__KSCRATCH4
:
8027 case CP0_REG31__KSCRATCH5
:
8028 case CP0_REG31__KSCRATCH6
:
8029 CP0_CHECK(ctx
->kscrexist
& (1 << sel
));
8030 tcg_gen_ld_tl(arg
, cpu_env
,
8031 offsetof(CPUMIPSState
, CP0_KScratch
[sel
- 2]));
8032 tcg_gen_ext32s_tl(arg
, arg
);
8033 register_name
= "KScratch";
8036 goto cp0_unimplemented
;
8040 goto cp0_unimplemented
;
8042 trace_mips_translate_c0("mfc0", register_name
, reg
, sel
);
8046 qemu_log_mask(LOG_UNIMP
, "mfc0 %s (reg %d sel %d)\n",
8047 register_name
, reg
, sel
);
8048 gen_mfc0_unimplemented(ctx
, arg
);
8051 static void gen_mtc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
8053 const char *register_name
= "invalid";
8056 check_insn(ctx
, ISA_MIPS_R1
);
8059 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
8064 case CP0_REGISTER_00
:
8066 case CP0_REG00__INDEX
:
8067 gen_helper_mtc0_index(cpu_env
, arg
);
8068 register_name
= "Index";
8070 case CP0_REG00__MVPCONTROL
:
8071 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8072 gen_helper_mtc0_mvpcontrol(cpu_env
, arg
);
8073 register_name
= "MVPControl";
8075 case CP0_REG00__MVPCONF0
:
8076 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8078 register_name
= "MVPConf0";
8080 case CP0_REG00__MVPCONF1
:
8081 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8083 register_name
= "MVPConf1";
8085 case CP0_REG00__VPCONTROL
:
8088 register_name
= "VPControl";
8091 goto cp0_unimplemented
;
8094 case CP0_REGISTER_01
:
8096 case CP0_REG01__RANDOM
:
8098 register_name
= "Random";
8100 case CP0_REG01__VPECONTROL
:
8101 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8102 gen_helper_mtc0_vpecontrol(cpu_env
, arg
);
8103 register_name
= "VPEControl";
8105 case CP0_REG01__VPECONF0
:
8106 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8107 gen_helper_mtc0_vpeconf0(cpu_env
, arg
);
8108 register_name
= "VPEConf0";
8110 case CP0_REG01__VPECONF1
:
8111 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8112 gen_helper_mtc0_vpeconf1(cpu_env
, arg
);
8113 register_name
= "VPEConf1";
8115 case CP0_REG01__YQMASK
:
8116 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8117 gen_helper_mtc0_yqmask(cpu_env
, arg
);
8118 register_name
= "YQMask";
8120 case CP0_REG01__VPESCHEDULE
:
8121 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8122 tcg_gen_st_tl(arg
, cpu_env
,
8123 offsetof(CPUMIPSState
, CP0_VPESchedule
));
8124 register_name
= "VPESchedule";
8126 case CP0_REG01__VPESCHEFBACK
:
8127 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8128 tcg_gen_st_tl(arg
, cpu_env
,
8129 offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
8130 register_name
= "VPEScheFBack";
8132 case CP0_REG01__VPEOPT
:
8133 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8134 gen_helper_mtc0_vpeopt(cpu_env
, arg
);
8135 register_name
= "VPEOpt";
8138 goto cp0_unimplemented
;
8141 case CP0_REGISTER_02
:
8143 case CP0_REG02__ENTRYLO0
:
8144 gen_helper_mtc0_entrylo0(cpu_env
, arg
);
8145 register_name
= "EntryLo0";
8147 case CP0_REG02__TCSTATUS
:
8148 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8149 gen_helper_mtc0_tcstatus(cpu_env
, arg
);
8150 register_name
= "TCStatus";
8152 case CP0_REG02__TCBIND
:
8153 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8154 gen_helper_mtc0_tcbind(cpu_env
, arg
);
8155 register_name
= "TCBind";
8157 case CP0_REG02__TCRESTART
:
8158 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8159 gen_helper_mtc0_tcrestart(cpu_env
, arg
);
8160 register_name
= "TCRestart";
8162 case CP0_REG02__TCHALT
:
8163 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8164 gen_helper_mtc0_tchalt(cpu_env
, arg
);
8165 register_name
= "TCHalt";
8167 case CP0_REG02__TCCONTEXT
:
8168 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8169 gen_helper_mtc0_tccontext(cpu_env
, arg
);
8170 register_name
= "TCContext";
8172 case CP0_REG02__TCSCHEDULE
:
8173 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8174 gen_helper_mtc0_tcschedule(cpu_env
, arg
);
8175 register_name
= "TCSchedule";
8177 case CP0_REG02__TCSCHEFBACK
:
8178 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8179 gen_helper_mtc0_tcschefback(cpu_env
, arg
);
8180 register_name
= "TCScheFBack";
8183 goto cp0_unimplemented
;
8186 case CP0_REGISTER_03
:
8188 case CP0_REG03__ENTRYLO1
:
8189 gen_helper_mtc0_entrylo1(cpu_env
, arg
);
8190 register_name
= "EntryLo1";
8192 case CP0_REG03__GLOBALNUM
:
8195 register_name
= "GlobalNumber";
8198 goto cp0_unimplemented
;
8201 case CP0_REGISTER_04
:
8203 case CP0_REG04__CONTEXT
:
8204 gen_helper_mtc0_context(cpu_env
, arg
);
8205 register_name
= "Context";
8207 case CP0_REG04__CONTEXTCONFIG
:
8209 /* gen_helper_mtc0_contextconfig(arg); */
8210 register_name
= "ContextConfig";
8211 goto cp0_unimplemented
;
8212 case CP0_REG04__USERLOCAL
:
8213 CP0_CHECK(ctx
->ulri
);
8214 tcg_gen_st_tl(arg
, cpu_env
,
8215 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
8216 register_name
= "UserLocal";
8218 case CP0_REG04__MMID
:
8220 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_MemoryMapID
));
8221 register_name
= "MMID";
8224 goto cp0_unimplemented
;
8227 case CP0_REGISTER_05
:
8229 case CP0_REG05__PAGEMASK
:
8230 gen_helper_mtc0_pagemask(cpu_env
, arg
);
8231 register_name
= "PageMask";
8233 case CP0_REG05__PAGEGRAIN
:
8234 check_insn(ctx
, ISA_MIPS_R2
);
8235 gen_helper_mtc0_pagegrain(cpu_env
, arg
);
8236 register_name
= "PageGrain";
8237 ctx
->base
.is_jmp
= DISAS_STOP
;
8239 case CP0_REG05__SEGCTL0
:
8241 gen_helper_mtc0_segctl0(cpu_env
, arg
);
8242 register_name
= "SegCtl0";
8244 case CP0_REG05__SEGCTL1
:
8246 gen_helper_mtc0_segctl1(cpu_env
, arg
);
8247 register_name
= "SegCtl1";
8249 case CP0_REG05__SEGCTL2
:
8251 gen_helper_mtc0_segctl2(cpu_env
, arg
);
8252 register_name
= "SegCtl2";
8254 case CP0_REG05__PWBASE
:
8256 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_PWBase
));
8257 register_name
= "PWBase";
8259 case CP0_REG05__PWFIELD
:
8261 gen_helper_mtc0_pwfield(cpu_env
, arg
);
8262 register_name
= "PWField";
8264 case CP0_REG05__PWSIZE
:
8266 gen_helper_mtc0_pwsize(cpu_env
, arg
);
8267 register_name
= "PWSize";
8270 goto cp0_unimplemented
;
8273 case CP0_REGISTER_06
:
8275 case CP0_REG06__WIRED
:
8276 gen_helper_mtc0_wired(cpu_env
, arg
);
8277 register_name
= "Wired";
8279 case CP0_REG06__SRSCONF0
:
8280 check_insn(ctx
, ISA_MIPS_R2
);
8281 gen_helper_mtc0_srsconf0(cpu_env
, arg
);
8282 register_name
= "SRSConf0";
8284 case CP0_REG06__SRSCONF1
:
8285 check_insn(ctx
, ISA_MIPS_R2
);
8286 gen_helper_mtc0_srsconf1(cpu_env
, arg
);
8287 register_name
= "SRSConf1";
8289 case CP0_REG06__SRSCONF2
:
8290 check_insn(ctx
, ISA_MIPS_R2
);
8291 gen_helper_mtc0_srsconf2(cpu_env
, arg
);
8292 register_name
= "SRSConf2";
8294 case CP0_REG06__SRSCONF3
:
8295 check_insn(ctx
, ISA_MIPS_R2
);
8296 gen_helper_mtc0_srsconf3(cpu_env
, arg
);
8297 register_name
= "SRSConf3";
8299 case CP0_REG06__SRSCONF4
:
8300 check_insn(ctx
, ISA_MIPS_R2
);
8301 gen_helper_mtc0_srsconf4(cpu_env
, arg
);
8302 register_name
= "SRSConf4";
8304 case CP0_REG06__PWCTL
:
8306 gen_helper_mtc0_pwctl(cpu_env
, arg
);
8307 register_name
= "PWCtl";
8310 goto cp0_unimplemented
;
8313 case CP0_REGISTER_07
:
8315 case CP0_REG07__HWRENA
:
8316 check_insn(ctx
, ISA_MIPS_R2
);
8317 gen_helper_mtc0_hwrena(cpu_env
, arg
);
8318 ctx
->base
.is_jmp
= DISAS_STOP
;
8319 register_name
= "HWREna";
8322 goto cp0_unimplemented
;
8325 case CP0_REGISTER_08
:
8327 case CP0_REG08__BADVADDR
:
8329 register_name
= "BadVAddr";
8331 case CP0_REG08__BADINSTR
:
8333 register_name
= "BadInstr";
8335 case CP0_REG08__BADINSTRP
:
8337 register_name
= "BadInstrP";
8339 case CP0_REG08__BADINSTRX
:
8341 register_name
= "BadInstrX";
8344 goto cp0_unimplemented
;
8347 case CP0_REGISTER_09
:
8349 case CP0_REG09__COUNT
:
8350 gen_helper_mtc0_count(cpu_env
, arg
);
8351 register_name
= "Count";
8353 case CP0_REG09__SAARI
:
8354 CP0_CHECK(ctx
->saar
);
8355 gen_helper_mtc0_saari(cpu_env
, arg
);
8356 register_name
= "SAARI";
8358 case CP0_REG09__SAAR
:
8359 CP0_CHECK(ctx
->saar
);
8360 gen_helper_mtc0_saar(cpu_env
, arg
);
8361 register_name
= "SAAR";
8364 goto cp0_unimplemented
;
8367 case CP0_REGISTER_10
:
8369 case CP0_REG10__ENTRYHI
:
8370 gen_helper_mtc0_entryhi(cpu_env
, arg
);
8371 register_name
= "EntryHi";
8374 goto cp0_unimplemented
;
8377 case CP0_REGISTER_11
:
8379 case CP0_REG11__COMPARE
:
8380 gen_helper_mtc0_compare(cpu_env
, arg
);
8381 register_name
= "Compare";
8383 /* 6,7 are implementation dependent */
8385 goto cp0_unimplemented
;
8388 case CP0_REGISTER_12
:
8390 case CP0_REG12__STATUS
:
8391 save_cpu_state(ctx
, 1);
8392 gen_helper_mtc0_status(cpu_env
, arg
);
8393 /* DISAS_STOP isn't good enough here, hflags may have changed. */
8394 gen_save_pc(ctx
->base
.pc_next
+ 4);
8395 ctx
->base
.is_jmp
= DISAS_EXIT
;
8396 register_name
= "Status";
8398 case CP0_REG12__INTCTL
:
8399 check_insn(ctx
, ISA_MIPS_R2
);
8400 gen_helper_mtc0_intctl(cpu_env
, arg
);
8401 /* Stop translation as we may have switched the execution mode */
8402 ctx
->base
.is_jmp
= DISAS_STOP
;
8403 register_name
= "IntCtl";
8405 case CP0_REG12__SRSCTL
:
8406 check_insn(ctx
, ISA_MIPS_R2
);
8407 gen_helper_mtc0_srsctl(cpu_env
, arg
);
8408 /* Stop translation as we may have switched the execution mode */
8409 ctx
->base
.is_jmp
= DISAS_STOP
;
8410 register_name
= "SRSCtl";
8412 case CP0_REG12__SRSMAP
:
8413 check_insn(ctx
, ISA_MIPS_R2
);
8414 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
8415 /* Stop translation as we may have switched the execution mode */
8416 ctx
->base
.is_jmp
= DISAS_STOP
;
8417 register_name
= "SRSMap";
8420 goto cp0_unimplemented
;
8423 case CP0_REGISTER_13
:
8425 case CP0_REG13__CAUSE
:
8426 save_cpu_state(ctx
, 1);
8427 gen_helper_mtc0_cause(cpu_env
, arg
);
8429 * Stop translation as we may have triggered an interrupt.
8430 * DISAS_STOP isn't sufficient, we need to ensure we break out of
8431 * translated code to check for pending interrupts.
8433 gen_save_pc(ctx
->base
.pc_next
+ 4);
8434 ctx
->base
.is_jmp
= DISAS_EXIT
;
8435 register_name
= "Cause";
8438 goto cp0_unimplemented
;
8441 case CP0_REGISTER_14
:
8443 case CP0_REG14__EPC
:
8444 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
8445 register_name
= "EPC";
8448 goto cp0_unimplemented
;
8451 case CP0_REGISTER_15
:
8453 case CP0_REG15__PRID
:
8455 register_name
= "PRid";
8457 case CP0_REG15__EBASE
:
8458 check_insn(ctx
, ISA_MIPS_R2
);
8459 gen_helper_mtc0_ebase(cpu_env
, arg
);
8460 register_name
= "EBase";
8463 goto cp0_unimplemented
;
8466 case CP0_REGISTER_16
:
8468 case CP0_REG16__CONFIG
:
8469 gen_helper_mtc0_config0(cpu_env
, arg
);
8470 register_name
= "Config";
8471 /* Stop translation as we may have switched the execution mode */
8472 ctx
->base
.is_jmp
= DISAS_STOP
;
8474 case CP0_REG16__CONFIG1
:
8475 /* ignored, read only */
8476 register_name
= "Config1";
8478 case CP0_REG16__CONFIG2
:
8479 gen_helper_mtc0_config2(cpu_env
, arg
);
8480 register_name
= "Config2";
8481 /* Stop translation as we may have switched the execution mode */
8482 ctx
->base
.is_jmp
= DISAS_STOP
;
8484 case CP0_REG16__CONFIG3
:
8485 gen_helper_mtc0_config3(cpu_env
, arg
);
8486 register_name
= "Config3";
8487 /* Stop translation as we may have switched the execution mode */
8488 ctx
->base
.is_jmp
= DISAS_STOP
;
8490 case CP0_REG16__CONFIG4
:
8491 gen_helper_mtc0_config4(cpu_env
, arg
);
8492 register_name
= "Config4";
8493 ctx
->base
.is_jmp
= DISAS_STOP
;
8495 case CP0_REG16__CONFIG5
:
8496 gen_helper_mtc0_config5(cpu_env
, arg
);
8497 register_name
= "Config5";
8498 /* Stop translation as we may have switched the execution mode */
8499 ctx
->base
.is_jmp
= DISAS_STOP
;
8501 /* 6,7 are implementation dependent */
8502 case CP0_REG16__CONFIG6
:
8504 register_name
= "Config6";
8506 case CP0_REG16__CONFIG7
:
8508 register_name
= "Config7";
8511 register_name
= "Invalid config selector";
8512 goto cp0_unimplemented
;
8515 case CP0_REGISTER_17
:
8517 case CP0_REG17__LLADDR
:
8518 gen_helper_mtc0_lladdr(cpu_env
, arg
);
8519 register_name
= "LLAddr";
8521 case CP0_REG17__MAAR
:
8522 CP0_CHECK(ctx
->mrp
);
8523 gen_helper_mtc0_maar(cpu_env
, arg
);
8524 register_name
= "MAAR";
8526 case CP0_REG17__MAARI
:
8527 CP0_CHECK(ctx
->mrp
);
8528 gen_helper_mtc0_maari(cpu_env
, arg
);
8529 register_name
= "MAARI";
8532 goto cp0_unimplemented
;
8535 case CP0_REGISTER_18
:
8537 case CP0_REG18__WATCHLO0
:
8538 case CP0_REG18__WATCHLO1
:
8539 case CP0_REG18__WATCHLO2
:
8540 case CP0_REG18__WATCHLO3
:
8541 case CP0_REG18__WATCHLO4
:
8542 case CP0_REG18__WATCHLO5
:
8543 case CP0_REG18__WATCHLO6
:
8544 case CP0_REG18__WATCHLO7
:
8545 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
8546 gen_helper_0e1i(mtc0_watchlo
, arg
, sel
);
8547 register_name
= "WatchLo";
8550 goto cp0_unimplemented
;
8553 case CP0_REGISTER_19
:
8555 case CP0_REG19__WATCHHI0
:
8556 case CP0_REG19__WATCHHI1
:
8557 case CP0_REG19__WATCHHI2
:
8558 case CP0_REG19__WATCHHI3
:
8559 case CP0_REG19__WATCHHI4
:
8560 case CP0_REG19__WATCHHI5
:
8561 case CP0_REG19__WATCHHI6
:
8562 case CP0_REG19__WATCHHI7
:
8563 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
8564 gen_helper_0e1i(mtc0_watchhi
, arg
, sel
);
8565 register_name
= "WatchHi";
8568 goto cp0_unimplemented
;
8571 case CP0_REGISTER_20
:
8573 case CP0_REG20__XCONTEXT
:
8574 #if defined(TARGET_MIPS64)
8575 check_insn(ctx
, ISA_MIPS3
);
8576 gen_helper_mtc0_xcontext(cpu_env
, arg
);
8577 register_name
= "XContext";
8581 goto cp0_unimplemented
;
8584 case CP0_REGISTER_21
:
8585 /* Officially reserved, but sel 0 is used for R1x000 framemask */
8586 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS_R6
));
8589 gen_helper_mtc0_framemask(cpu_env
, arg
);
8590 register_name
= "Framemask";
8593 goto cp0_unimplemented
;
8596 case CP0_REGISTER_22
:
8598 register_name
= "Diagnostic"; /* implementation dependent */
8600 case CP0_REGISTER_23
:
8602 case CP0_REG23__DEBUG
:
8603 gen_helper_mtc0_debug(cpu_env
, arg
); /* EJTAG support */
8604 /* DISAS_STOP isn't good enough here, hflags may have changed. */
8605 gen_save_pc(ctx
->base
.pc_next
+ 4);
8606 ctx
->base
.is_jmp
= DISAS_EXIT
;
8607 register_name
= "Debug";
8609 case CP0_REG23__TRACECONTROL
:
8610 /* PDtrace support */
8611 /* gen_helper_mtc0_tracecontrol(cpu_env, arg); */
8612 register_name
= "TraceControl";
8613 /* Stop translation as we may have switched the execution mode */
8614 ctx
->base
.is_jmp
= DISAS_STOP
;
8615 goto cp0_unimplemented
;
8616 case CP0_REG23__TRACECONTROL2
:
8617 /* PDtrace support */
8618 /* gen_helper_mtc0_tracecontrol2(cpu_env, arg); */
8619 register_name
= "TraceControl2";
8620 /* Stop translation as we may have switched the execution mode */
8621 ctx
->base
.is_jmp
= DISAS_STOP
;
8622 goto cp0_unimplemented
;
8623 case CP0_REG23__USERTRACEDATA1
:
8624 /* Stop translation as we may have switched the execution mode */
8625 ctx
->base
.is_jmp
= DISAS_STOP
;
8626 /* PDtrace support */
8627 /* gen_helper_mtc0_usertracedata1(cpu_env, arg);*/
8628 register_name
= "UserTraceData";
8629 /* Stop translation as we may have switched the execution mode */
8630 ctx
->base
.is_jmp
= DISAS_STOP
;
8631 goto cp0_unimplemented
;
8632 case CP0_REG23__TRACEIBPC
:
8633 /* PDtrace support */
8634 /* gen_helper_mtc0_traceibpc(cpu_env, arg); */
8635 /* Stop translation as we may have switched the execution mode */
8636 ctx
->base
.is_jmp
= DISAS_STOP
;
8637 register_name
= "TraceIBPC";
8638 goto cp0_unimplemented
;
8639 case CP0_REG23__TRACEDBPC
:
8640 /* PDtrace support */
8641 /* gen_helper_mtc0_tracedbpc(cpu_env, arg); */
8642 /* Stop translation as we may have switched the execution mode */
8643 ctx
->base
.is_jmp
= DISAS_STOP
;
8644 register_name
= "TraceDBPC";
8645 goto cp0_unimplemented
;
8647 goto cp0_unimplemented
;
8650 case CP0_REGISTER_24
:
8652 case CP0_REG24__DEPC
:
8654 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
8655 register_name
= "DEPC";
8658 goto cp0_unimplemented
;
8661 case CP0_REGISTER_25
:
8663 case CP0_REG25__PERFCTL0
:
8664 gen_helper_mtc0_performance0(cpu_env
, arg
);
8665 register_name
= "Performance0";
8667 case CP0_REG25__PERFCNT0
:
8668 /* gen_helper_mtc0_performance1(arg); */
8669 register_name
= "Performance1";
8670 goto cp0_unimplemented
;
8671 case CP0_REG25__PERFCTL1
:
8672 /* gen_helper_mtc0_performance2(arg); */
8673 register_name
= "Performance2";
8674 goto cp0_unimplemented
;
8675 case CP0_REG25__PERFCNT1
:
8676 /* gen_helper_mtc0_performance3(arg); */
8677 register_name
= "Performance3";
8678 goto cp0_unimplemented
;
8679 case CP0_REG25__PERFCTL2
:
8680 /* gen_helper_mtc0_performance4(arg); */
8681 register_name
= "Performance4";
8682 goto cp0_unimplemented
;
8683 case CP0_REG25__PERFCNT2
:
8684 /* gen_helper_mtc0_performance5(arg); */
8685 register_name
= "Performance5";
8686 goto cp0_unimplemented
;
8687 case CP0_REG25__PERFCTL3
:
8688 /* gen_helper_mtc0_performance6(arg); */
8689 register_name
= "Performance6";
8690 goto cp0_unimplemented
;
8691 case CP0_REG25__PERFCNT3
:
8692 /* gen_helper_mtc0_performance7(arg); */
8693 register_name
= "Performance7";
8694 goto cp0_unimplemented
;
8696 goto cp0_unimplemented
;
8699 case CP0_REGISTER_26
:
8701 case CP0_REG26__ERRCTL
:
8702 gen_helper_mtc0_errctl(cpu_env
, arg
);
8703 ctx
->base
.is_jmp
= DISAS_STOP
;
8704 register_name
= "ErrCtl";
8707 goto cp0_unimplemented
;
8710 case CP0_REGISTER_27
:
8712 case CP0_REG27__CACHERR
:
8714 register_name
= "CacheErr";
8717 goto cp0_unimplemented
;
8720 case CP0_REGISTER_28
:
8722 case CP0_REG28__TAGLO
:
8723 case CP0_REG28__TAGLO1
:
8724 case CP0_REG28__TAGLO2
:
8725 case CP0_REG28__TAGLO3
:
8726 gen_helper_mtc0_taglo(cpu_env
, arg
);
8727 register_name
= "TagLo";
8729 case CP0_REG28__DATALO
:
8730 case CP0_REG28__DATALO1
:
8731 case CP0_REG28__DATALO2
:
8732 case CP0_REG28__DATALO3
:
8733 gen_helper_mtc0_datalo(cpu_env
, arg
);
8734 register_name
= "DataLo";
8737 goto cp0_unimplemented
;
8740 case CP0_REGISTER_29
:
8742 case CP0_REG29__TAGHI
:
8743 case CP0_REG29__TAGHI1
:
8744 case CP0_REG29__TAGHI2
:
8745 case CP0_REG29__TAGHI3
:
8746 gen_helper_mtc0_taghi(cpu_env
, arg
);
8747 register_name
= "TagHi";
8749 case CP0_REG29__DATAHI
:
8750 case CP0_REG29__DATAHI1
:
8751 case CP0_REG29__DATAHI2
:
8752 case CP0_REG29__DATAHI3
:
8753 gen_helper_mtc0_datahi(cpu_env
, arg
);
8754 register_name
= "DataHi";
8757 register_name
= "invalid sel";
8758 goto cp0_unimplemented
;
8761 case CP0_REGISTER_30
:
8763 case CP0_REG30__ERROREPC
:
8764 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
8765 register_name
= "ErrorEPC";
8768 goto cp0_unimplemented
;
8771 case CP0_REGISTER_31
:
8773 case CP0_REG31__DESAVE
:
8775 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
8776 register_name
= "DESAVE";
8778 case CP0_REG31__KSCRATCH1
:
8779 case CP0_REG31__KSCRATCH2
:
8780 case CP0_REG31__KSCRATCH3
:
8781 case CP0_REG31__KSCRATCH4
:
8782 case CP0_REG31__KSCRATCH5
:
8783 case CP0_REG31__KSCRATCH6
:
8784 CP0_CHECK(ctx
->kscrexist
& (1 << sel
));
8785 tcg_gen_st_tl(arg
, cpu_env
,
8786 offsetof(CPUMIPSState
, CP0_KScratch
[sel
- 2]));
8787 register_name
= "KScratch";
8790 goto cp0_unimplemented
;
8794 goto cp0_unimplemented
;
8796 trace_mips_translate_c0("mtc0", register_name
, reg
, sel
);
8798 /* For simplicity assume that all writes can cause interrupts. */
8799 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
8801 * DISAS_STOP isn't sufficient, we need to ensure we break out of
8802 * translated code to check for pending interrupts.
8804 gen_save_pc(ctx
->base
.pc_next
+ 4);
8805 ctx
->base
.is_jmp
= DISAS_EXIT
;
8810 qemu_log_mask(LOG_UNIMP
, "mtc0 %s (reg %d sel %d)\n",
8811 register_name
, reg
, sel
);
8814 #if defined(TARGET_MIPS64)
8815 static void gen_dmfc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
8817 const char *register_name
= "invalid";
8820 check_insn(ctx
, ISA_MIPS_R1
);
8824 case CP0_REGISTER_00
:
8826 case CP0_REG00__INDEX
:
8827 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Index
));
8828 register_name
= "Index";
8830 case CP0_REG00__MVPCONTROL
:
8831 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8832 gen_helper_mfc0_mvpcontrol(arg
, cpu_env
);
8833 register_name
= "MVPControl";
8835 case CP0_REG00__MVPCONF0
:
8836 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8837 gen_helper_mfc0_mvpconf0(arg
, cpu_env
);
8838 register_name
= "MVPConf0";
8840 case CP0_REG00__MVPCONF1
:
8841 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8842 gen_helper_mfc0_mvpconf1(arg
, cpu_env
);
8843 register_name
= "MVPConf1";
8845 case CP0_REG00__VPCONTROL
:
8847 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPControl
));
8848 register_name
= "VPControl";
8851 goto cp0_unimplemented
;
8854 case CP0_REGISTER_01
:
8856 case CP0_REG01__RANDOM
:
8857 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS_R6
));
8858 gen_helper_mfc0_random(arg
, cpu_env
);
8859 register_name
= "Random";
8861 case CP0_REG01__VPECONTROL
:
8862 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8863 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEControl
));
8864 register_name
= "VPEControl";
8866 case CP0_REG01__VPECONF0
:
8867 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8868 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf0
));
8869 register_name
= "VPEConf0";
8871 case CP0_REG01__VPECONF1
:
8872 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8873 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf1
));
8874 register_name
= "VPEConf1";
8876 case CP0_REG01__YQMASK
:
8877 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8878 tcg_gen_ld_tl(arg
, cpu_env
,
8879 offsetof(CPUMIPSState
, CP0_YQMask
));
8880 register_name
= "YQMask";
8882 case CP0_REG01__VPESCHEDULE
:
8883 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8884 tcg_gen_ld_tl(arg
, cpu_env
,
8885 offsetof(CPUMIPSState
, CP0_VPESchedule
));
8886 register_name
= "VPESchedule";
8888 case CP0_REG01__VPESCHEFBACK
:
8889 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8890 tcg_gen_ld_tl(arg
, cpu_env
,
8891 offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
8892 register_name
= "VPEScheFBack";
8894 case CP0_REG01__VPEOPT
:
8895 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8896 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEOpt
));
8897 register_name
= "VPEOpt";
8900 goto cp0_unimplemented
;
8903 case CP0_REGISTER_02
:
8905 case CP0_REG02__ENTRYLO0
:
8906 tcg_gen_ld_tl(arg
, cpu_env
,
8907 offsetof(CPUMIPSState
, CP0_EntryLo0
));
8908 register_name
= "EntryLo0";
8910 case CP0_REG02__TCSTATUS
:
8911 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8912 gen_helper_mfc0_tcstatus(arg
, cpu_env
);
8913 register_name
= "TCStatus";
8915 case CP0_REG02__TCBIND
:
8916 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8917 gen_helper_mfc0_tcbind(arg
, cpu_env
);
8918 register_name
= "TCBind";
8920 case CP0_REG02__TCRESTART
:
8921 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8922 gen_helper_dmfc0_tcrestart(arg
, cpu_env
);
8923 register_name
= "TCRestart";
8925 case CP0_REG02__TCHALT
:
8926 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8927 gen_helper_dmfc0_tchalt(arg
, cpu_env
);
8928 register_name
= "TCHalt";
8930 case CP0_REG02__TCCONTEXT
:
8931 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8932 gen_helper_dmfc0_tccontext(arg
, cpu_env
);
8933 register_name
= "TCContext";
8935 case CP0_REG02__TCSCHEDULE
:
8936 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8937 gen_helper_dmfc0_tcschedule(arg
, cpu_env
);
8938 register_name
= "TCSchedule";
8940 case CP0_REG02__TCSCHEFBACK
:
8941 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8942 gen_helper_dmfc0_tcschefback(arg
, cpu_env
);
8943 register_name
= "TCScheFBack";
8946 goto cp0_unimplemented
;
8949 case CP0_REGISTER_03
:
8951 case CP0_REG03__ENTRYLO1
:
8952 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryLo1
));
8953 register_name
= "EntryLo1";
8955 case CP0_REG03__GLOBALNUM
:
8957 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_GlobalNumber
));
8958 register_name
= "GlobalNumber";
8961 goto cp0_unimplemented
;
8964 case CP0_REGISTER_04
:
8966 case CP0_REG04__CONTEXT
:
8967 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_Context
));
8968 register_name
= "Context";
8970 case CP0_REG04__CONTEXTCONFIG
:
8972 /* gen_helper_dmfc0_contextconfig(arg); */
8973 register_name
= "ContextConfig";
8974 goto cp0_unimplemented
;
8975 case CP0_REG04__USERLOCAL
:
8976 CP0_CHECK(ctx
->ulri
);
8977 tcg_gen_ld_tl(arg
, cpu_env
,
8978 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
8979 register_name
= "UserLocal";
8981 case CP0_REG04__MMID
:
8983 gen_helper_mtc0_memorymapid(cpu_env
, arg
);
8984 register_name
= "MMID";
8987 goto cp0_unimplemented
;
8990 case CP0_REGISTER_05
:
8992 case CP0_REG05__PAGEMASK
:
8993 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageMask
));
8994 register_name
= "PageMask";
8996 case CP0_REG05__PAGEGRAIN
:
8997 check_insn(ctx
, ISA_MIPS_R2
);
8998 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageGrain
));
8999 register_name
= "PageGrain";
9001 case CP0_REG05__SEGCTL0
:
9003 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_SegCtl0
));
9004 register_name
= "SegCtl0";
9006 case CP0_REG05__SEGCTL1
:
9008 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_SegCtl1
));
9009 register_name
= "SegCtl1";
9011 case CP0_REG05__SEGCTL2
:
9013 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_SegCtl2
));
9014 register_name
= "SegCtl2";
9016 case CP0_REG05__PWBASE
:
9018 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_PWBase
));
9019 register_name
= "PWBase";
9021 case CP0_REG05__PWFIELD
:
9023 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_PWField
));
9024 register_name
= "PWField";
9026 case CP0_REG05__PWSIZE
:
9028 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_PWSize
));
9029 register_name
= "PWSize";
9032 goto cp0_unimplemented
;
9035 case CP0_REGISTER_06
:
9037 case CP0_REG06__WIRED
:
9038 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Wired
));
9039 register_name
= "Wired";
9041 case CP0_REG06__SRSCONF0
:
9042 check_insn(ctx
, ISA_MIPS_R2
);
9043 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf0
));
9044 register_name
= "SRSConf0";
9046 case CP0_REG06__SRSCONF1
:
9047 check_insn(ctx
, ISA_MIPS_R2
);
9048 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf1
));
9049 register_name
= "SRSConf1";
9051 case CP0_REG06__SRSCONF2
:
9052 check_insn(ctx
, ISA_MIPS_R2
);
9053 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf2
));
9054 register_name
= "SRSConf2";
9056 case CP0_REG06__SRSCONF3
:
9057 check_insn(ctx
, ISA_MIPS_R2
);
9058 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf3
));
9059 register_name
= "SRSConf3";
9061 case CP0_REG06__SRSCONF4
:
9062 check_insn(ctx
, ISA_MIPS_R2
);
9063 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf4
));
9064 register_name
= "SRSConf4";
9066 case CP0_REG06__PWCTL
:
9068 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PWCtl
));
9069 register_name
= "PWCtl";
9072 goto cp0_unimplemented
;
9075 case CP0_REGISTER_07
:
9077 case CP0_REG07__HWRENA
:
9078 check_insn(ctx
, ISA_MIPS_R2
);
9079 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_HWREna
));
9080 register_name
= "HWREna";
9083 goto cp0_unimplemented
;
9086 case CP0_REGISTER_08
:
9088 case CP0_REG08__BADVADDR
:
9089 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_BadVAddr
));
9090 register_name
= "BadVAddr";
9092 case CP0_REG08__BADINSTR
:
9094 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstr
));
9095 register_name
= "BadInstr";
9097 case CP0_REG08__BADINSTRP
:
9099 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstrP
));
9100 register_name
= "BadInstrP";
9102 case CP0_REG08__BADINSTRX
:
9104 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstrX
));
9105 tcg_gen_andi_tl(arg
, arg
, ~0xffff);
9106 register_name
= "BadInstrX";
9109 goto cp0_unimplemented
;
9112 case CP0_REGISTER_09
:
9114 case CP0_REG09__COUNT
:
9115 /* Mark as an IO operation because we read the time. */
9116 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
9119 gen_helper_mfc0_count(arg
, cpu_env
);
9121 * Break the TB to be able to take timer interrupts immediately
9122 * after reading count. DISAS_STOP isn't sufficient, we need to
9123 * ensure we break completely out of translated code.
9125 gen_save_pc(ctx
->base
.pc_next
+ 4);
9126 ctx
->base
.is_jmp
= DISAS_EXIT
;
9127 register_name
= "Count";
9129 case CP0_REG09__SAARI
:
9130 CP0_CHECK(ctx
->saar
);
9131 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SAARI
));
9132 register_name
= "SAARI";
9134 case CP0_REG09__SAAR
:
9135 CP0_CHECK(ctx
->saar
);
9136 gen_helper_dmfc0_saar(arg
, cpu_env
);
9137 register_name
= "SAAR";
9140 goto cp0_unimplemented
;
9143 case CP0_REGISTER_10
:
9145 case CP0_REG10__ENTRYHI
:
9146 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryHi
));
9147 register_name
= "EntryHi";
9150 goto cp0_unimplemented
;
9153 case CP0_REGISTER_11
:
9155 case CP0_REG11__COMPARE
:
9156 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Compare
));
9157 register_name
= "Compare";
9159 /* 6,7 are implementation dependent */
9161 goto cp0_unimplemented
;
9164 case CP0_REGISTER_12
:
9166 case CP0_REG12__STATUS
:
9167 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Status
));
9168 register_name
= "Status";
9170 case CP0_REG12__INTCTL
:
9171 check_insn(ctx
, ISA_MIPS_R2
);
9172 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_IntCtl
));
9173 register_name
= "IntCtl";
9175 case CP0_REG12__SRSCTL
:
9176 check_insn(ctx
, ISA_MIPS_R2
);
9177 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
9178 register_name
= "SRSCtl";
9180 case CP0_REG12__SRSMAP
:
9181 check_insn(ctx
, ISA_MIPS_R2
);
9182 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
9183 register_name
= "SRSMap";
9186 goto cp0_unimplemented
;
9189 case CP0_REGISTER_13
:
9191 case CP0_REG13__CAUSE
:
9192 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Cause
));
9193 register_name
= "Cause";
9196 goto cp0_unimplemented
;
9199 case CP0_REGISTER_14
:
9201 case CP0_REG14__EPC
:
9202 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
9203 register_name
= "EPC";
9206 goto cp0_unimplemented
;
9209 case CP0_REGISTER_15
:
9211 case CP0_REG15__PRID
:
9212 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PRid
));
9213 register_name
= "PRid";
9215 case CP0_REG15__EBASE
:
9216 check_insn(ctx
, ISA_MIPS_R2
);
9217 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EBase
));
9218 register_name
= "EBase";
9220 case CP0_REG15__CMGCRBASE
:
9221 check_insn(ctx
, ISA_MIPS_R2
);
9222 CP0_CHECK(ctx
->cmgcr
);
9223 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_CMGCRBase
));
9224 register_name
= "CMGCRBase";
9227 goto cp0_unimplemented
;
9230 case CP0_REGISTER_16
:
9232 case CP0_REG16__CONFIG
:
9233 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config0
));
9234 register_name
= "Config";
9236 case CP0_REG16__CONFIG1
:
9237 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config1
));
9238 register_name
= "Config1";
9240 case CP0_REG16__CONFIG2
:
9241 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config2
));
9242 register_name
= "Config2";
9244 case CP0_REG16__CONFIG3
:
9245 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config3
));
9246 register_name
= "Config3";
9248 case CP0_REG16__CONFIG4
:
9249 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config4
));
9250 register_name
= "Config4";
9252 case CP0_REG16__CONFIG5
:
9253 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config5
));
9254 register_name
= "Config5";
9256 /* 6,7 are implementation dependent */
9257 case CP0_REG16__CONFIG6
:
9258 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config6
));
9259 register_name
= "Config6";
9261 case CP0_REG16__CONFIG7
:
9262 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config7
));
9263 register_name
= "Config7";
9266 goto cp0_unimplemented
;
9269 case CP0_REGISTER_17
:
9271 case CP0_REG17__LLADDR
:
9272 gen_helper_dmfc0_lladdr(arg
, cpu_env
);
9273 register_name
= "LLAddr";
9275 case CP0_REG17__MAAR
:
9276 CP0_CHECK(ctx
->mrp
);
9277 gen_helper_dmfc0_maar(arg
, cpu_env
);
9278 register_name
= "MAAR";
9280 case CP0_REG17__MAARI
:
9281 CP0_CHECK(ctx
->mrp
);
9282 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_MAARI
));
9283 register_name
= "MAARI";
9286 goto cp0_unimplemented
;
9289 case CP0_REGISTER_18
:
9291 case CP0_REG18__WATCHLO0
:
9292 case CP0_REG18__WATCHLO1
:
9293 case CP0_REG18__WATCHLO2
:
9294 case CP0_REG18__WATCHLO3
:
9295 case CP0_REG18__WATCHLO4
:
9296 case CP0_REG18__WATCHLO5
:
9297 case CP0_REG18__WATCHLO6
:
9298 case CP0_REG18__WATCHLO7
:
9299 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
9300 gen_helper_1e0i(dmfc0_watchlo
, arg
, sel
);
9301 register_name
= "WatchLo";
9304 goto cp0_unimplemented
;
9307 case CP0_REGISTER_19
:
9309 case CP0_REG19__WATCHHI0
:
9310 case CP0_REG19__WATCHHI1
:
9311 case CP0_REG19__WATCHHI2
:
9312 case CP0_REG19__WATCHHI3
:
9313 case CP0_REG19__WATCHHI4
:
9314 case CP0_REG19__WATCHHI5
:
9315 case CP0_REG19__WATCHHI6
:
9316 case CP0_REG19__WATCHHI7
:
9317 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
9318 gen_helper_1e0i(dmfc0_watchhi
, arg
, sel
);
9319 register_name
= "WatchHi";
9322 goto cp0_unimplemented
;
9325 case CP0_REGISTER_20
:
9327 case CP0_REG20__XCONTEXT
:
9328 check_insn(ctx
, ISA_MIPS3
);
9329 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_XContext
));
9330 register_name
= "XContext";
9333 goto cp0_unimplemented
;
9336 case CP0_REGISTER_21
:
9337 /* Officially reserved, but sel 0 is used for R1x000 framemask */
9338 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS_R6
));
9341 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Framemask
));
9342 register_name
= "Framemask";
9345 goto cp0_unimplemented
;
9348 case CP0_REGISTER_22
:
9349 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
9350 register_name
= "'Diagnostic"; /* implementation dependent */
9352 case CP0_REGISTER_23
:
9354 case CP0_REG23__DEBUG
:
9355 gen_helper_mfc0_debug(arg
, cpu_env
); /* EJTAG support */
9356 register_name
= "Debug";
9358 case CP0_REG23__TRACECONTROL
:
9359 /* PDtrace support */
9360 /* gen_helper_dmfc0_tracecontrol(arg, cpu_env); */
9361 register_name
= "TraceControl";
9362 goto cp0_unimplemented
;
9363 case CP0_REG23__TRACECONTROL2
:
9364 /* PDtrace support */
9365 /* gen_helper_dmfc0_tracecontrol2(arg, cpu_env); */
9366 register_name
= "TraceControl2";
9367 goto cp0_unimplemented
;
9368 case CP0_REG23__USERTRACEDATA1
:
9369 /* PDtrace support */
9370 /* gen_helper_dmfc0_usertracedata1(arg, cpu_env);*/
9371 register_name
= "UserTraceData1";
9372 goto cp0_unimplemented
;
9373 case CP0_REG23__TRACEIBPC
:
9374 /* PDtrace support */
9375 /* gen_helper_dmfc0_traceibpc(arg, cpu_env); */
9376 register_name
= "TraceIBPC";
9377 goto cp0_unimplemented
;
9378 case CP0_REG23__TRACEDBPC
:
9379 /* PDtrace support */
9380 /* gen_helper_dmfc0_tracedbpc(arg, cpu_env); */
9381 register_name
= "TraceDBPC";
9382 goto cp0_unimplemented
;
9384 goto cp0_unimplemented
;
9387 case CP0_REGISTER_24
:
9389 case CP0_REG24__DEPC
:
9391 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
9392 register_name
= "DEPC";
9395 goto cp0_unimplemented
;
9398 case CP0_REGISTER_25
:
9400 case CP0_REG25__PERFCTL0
:
9401 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Performance0
));
9402 register_name
= "Performance0";
9404 case CP0_REG25__PERFCNT0
:
9405 /* gen_helper_dmfc0_performance1(arg); */
9406 register_name
= "Performance1";
9407 goto cp0_unimplemented
;
9408 case CP0_REG25__PERFCTL1
:
9409 /* gen_helper_dmfc0_performance2(arg); */
9410 register_name
= "Performance2";
9411 goto cp0_unimplemented
;
9412 case CP0_REG25__PERFCNT1
:
9413 /* gen_helper_dmfc0_performance3(arg); */
9414 register_name
= "Performance3";
9415 goto cp0_unimplemented
;
9416 case CP0_REG25__PERFCTL2
:
9417 /* gen_helper_dmfc0_performance4(arg); */
9418 register_name
= "Performance4";
9419 goto cp0_unimplemented
;
9420 case CP0_REG25__PERFCNT2
:
9421 /* gen_helper_dmfc0_performance5(arg); */
9422 register_name
= "Performance5";
9423 goto cp0_unimplemented
;
9424 case CP0_REG25__PERFCTL3
:
9425 /* gen_helper_dmfc0_performance6(arg); */
9426 register_name
= "Performance6";
9427 goto cp0_unimplemented
;
9428 case CP0_REG25__PERFCNT3
:
9429 /* gen_helper_dmfc0_performance7(arg); */
9430 register_name
= "Performance7";
9431 goto cp0_unimplemented
;
9433 goto cp0_unimplemented
;
9436 case CP0_REGISTER_26
:
9438 case CP0_REG26__ERRCTL
:
9439 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_ErrCtl
));
9440 register_name
= "ErrCtl";
9443 goto cp0_unimplemented
;
9446 case CP0_REGISTER_27
:
9449 case CP0_REG27__CACHERR
:
9450 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
9451 register_name
= "CacheErr";
9454 goto cp0_unimplemented
;
9457 case CP0_REGISTER_28
:
9459 case CP0_REG28__TAGLO
:
9460 case CP0_REG28__TAGLO1
:
9461 case CP0_REG28__TAGLO2
:
9462 case CP0_REG28__TAGLO3
:
9463 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagLo
));
9464 register_name
= "TagLo";
9466 case CP0_REG28__DATALO
:
9467 case CP0_REG28__DATALO1
:
9468 case CP0_REG28__DATALO2
:
9469 case CP0_REG28__DATALO3
:
9470 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataLo
));
9471 register_name
= "DataLo";
9474 goto cp0_unimplemented
;
9477 case CP0_REGISTER_29
:
9479 case CP0_REG29__TAGHI
:
9480 case CP0_REG29__TAGHI1
:
9481 case CP0_REG29__TAGHI2
:
9482 case CP0_REG29__TAGHI3
:
9483 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagHi
));
9484 register_name
= "TagHi";
9486 case CP0_REG29__DATAHI
:
9487 case CP0_REG29__DATAHI1
:
9488 case CP0_REG29__DATAHI2
:
9489 case CP0_REG29__DATAHI3
:
9490 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataHi
));
9491 register_name
= "DataHi";
9494 goto cp0_unimplemented
;
9497 case CP0_REGISTER_30
:
9499 case CP0_REG30__ERROREPC
:
9500 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
9501 register_name
= "ErrorEPC";
9504 goto cp0_unimplemented
;
9507 case CP0_REGISTER_31
:
9509 case CP0_REG31__DESAVE
:
9511 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
9512 register_name
= "DESAVE";
9514 case CP0_REG31__KSCRATCH1
:
9515 case CP0_REG31__KSCRATCH2
:
9516 case CP0_REG31__KSCRATCH3
:
9517 case CP0_REG31__KSCRATCH4
:
9518 case CP0_REG31__KSCRATCH5
:
9519 case CP0_REG31__KSCRATCH6
:
9520 CP0_CHECK(ctx
->kscrexist
& (1 << sel
));
9521 tcg_gen_ld_tl(arg
, cpu_env
,
9522 offsetof(CPUMIPSState
, CP0_KScratch
[sel
- 2]));
9523 register_name
= "KScratch";
9526 goto cp0_unimplemented
;
9530 goto cp0_unimplemented
;
9532 trace_mips_translate_c0("dmfc0", register_name
, reg
, sel
);
9536 qemu_log_mask(LOG_UNIMP
, "dmfc0 %s (reg %d sel %d)\n",
9537 register_name
, reg
, sel
);
9538 gen_mfc0_unimplemented(ctx
, arg
);
9541 static void gen_dmtc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
9543 const char *register_name
= "invalid";
9546 check_insn(ctx
, ISA_MIPS_R1
);
9549 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
9554 case CP0_REGISTER_00
:
9556 case CP0_REG00__INDEX
:
9557 gen_helper_mtc0_index(cpu_env
, arg
);
9558 register_name
= "Index";
9560 case CP0_REG00__MVPCONTROL
:
9561 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9562 gen_helper_mtc0_mvpcontrol(cpu_env
, arg
);
9563 register_name
= "MVPControl";
9565 case CP0_REG00__MVPCONF0
:
9566 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9568 register_name
= "MVPConf0";
9570 case CP0_REG00__MVPCONF1
:
9571 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9573 register_name
= "MVPConf1";
9575 case CP0_REG00__VPCONTROL
:
9578 register_name
= "VPControl";
9581 goto cp0_unimplemented
;
9584 case CP0_REGISTER_01
:
9586 case CP0_REG01__RANDOM
:
9588 register_name
= "Random";
9590 case CP0_REG01__VPECONTROL
:
9591 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9592 gen_helper_mtc0_vpecontrol(cpu_env
, arg
);
9593 register_name
= "VPEControl";
9595 case CP0_REG01__VPECONF0
:
9596 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9597 gen_helper_mtc0_vpeconf0(cpu_env
, arg
);
9598 register_name
= "VPEConf0";
9600 case CP0_REG01__VPECONF1
:
9601 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9602 gen_helper_mtc0_vpeconf1(cpu_env
, arg
);
9603 register_name
= "VPEConf1";
9605 case CP0_REG01__YQMASK
:
9606 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9607 gen_helper_mtc0_yqmask(cpu_env
, arg
);
9608 register_name
= "YQMask";
9610 case CP0_REG01__VPESCHEDULE
:
9611 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9612 tcg_gen_st_tl(arg
, cpu_env
,
9613 offsetof(CPUMIPSState
, CP0_VPESchedule
));
9614 register_name
= "VPESchedule";
9616 case CP0_REG01__VPESCHEFBACK
:
9617 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9618 tcg_gen_st_tl(arg
, cpu_env
,
9619 offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
9620 register_name
= "VPEScheFBack";
9622 case CP0_REG01__VPEOPT
:
9623 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9624 gen_helper_mtc0_vpeopt(cpu_env
, arg
);
9625 register_name
= "VPEOpt";
9628 goto cp0_unimplemented
;
9631 case CP0_REGISTER_02
:
9633 case CP0_REG02__ENTRYLO0
:
9634 gen_helper_dmtc0_entrylo0(cpu_env
, arg
);
9635 register_name
= "EntryLo0";
9637 case CP0_REG02__TCSTATUS
:
9638 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9639 gen_helper_mtc0_tcstatus(cpu_env
, arg
);
9640 register_name
= "TCStatus";
9642 case CP0_REG02__TCBIND
:
9643 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9644 gen_helper_mtc0_tcbind(cpu_env
, arg
);
9645 register_name
= "TCBind";
9647 case CP0_REG02__TCRESTART
:
9648 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9649 gen_helper_mtc0_tcrestart(cpu_env
, arg
);
9650 register_name
= "TCRestart";
9652 case CP0_REG02__TCHALT
:
9653 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9654 gen_helper_mtc0_tchalt(cpu_env
, arg
);
9655 register_name
= "TCHalt";
9657 case CP0_REG02__TCCONTEXT
:
9658 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9659 gen_helper_mtc0_tccontext(cpu_env
, arg
);
9660 register_name
= "TCContext";
9662 case CP0_REG02__TCSCHEDULE
:
9663 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9664 gen_helper_mtc0_tcschedule(cpu_env
, arg
);
9665 register_name
= "TCSchedule";
9667 case CP0_REG02__TCSCHEFBACK
:
9668 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9669 gen_helper_mtc0_tcschefback(cpu_env
, arg
);
9670 register_name
= "TCScheFBack";
9673 goto cp0_unimplemented
;
9676 case CP0_REGISTER_03
:
9678 case CP0_REG03__ENTRYLO1
:
9679 gen_helper_dmtc0_entrylo1(cpu_env
, arg
);
9680 register_name
= "EntryLo1";
9682 case CP0_REG03__GLOBALNUM
:
9685 register_name
= "GlobalNumber";
9688 goto cp0_unimplemented
;
9691 case CP0_REGISTER_04
:
9693 case CP0_REG04__CONTEXT
:
9694 gen_helper_mtc0_context(cpu_env
, arg
);
9695 register_name
= "Context";
9697 case CP0_REG04__CONTEXTCONFIG
:
9699 /* gen_helper_dmtc0_contextconfig(arg); */
9700 register_name
= "ContextConfig";
9701 goto cp0_unimplemented
;
9702 case CP0_REG04__USERLOCAL
:
9703 CP0_CHECK(ctx
->ulri
);
9704 tcg_gen_st_tl(arg
, cpu_env
,
9705 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
9706 register_name
= "UserLocal";
9708 case CP0_REG04__MMID
:
9710 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_MemoryMapID
));
9711 register_name
= "MMID";
9714 goto cp0_unimplemented
;
9717 case CP0_REGISTER_05
:
9719 case CP0_REG05__PAGEMASK
:
9720 gen_helper_mtc0_pagemask(cpu_env
, arg
);
9721 register_name
= "PageMask";
9723 case CP0_REG05__PAGEGRAIN
:
9724 check_insn(ctx
, ISA_MIPS_R2
);
9725 gen_helper_mtc0_pagegrain(cpu_env
, arg
);
9726 register_name
= "PageGrain";
9728 case CP0_REG05__SEGCTL0
:
9730 gen_helper_mtc0_segctl0(cpu_env
, arg
);
9731 register_name
= "SegCtl0";
9733 case CP0_REG05__SEGCTL1
:
9735 gen_helper_mtc0_segctl1(cpu_env
, arg
);
9736 register_name
= "SegCtl1";
9738 case CP0_REG05__SEGCTL2
:
9740 gen_helper_mtc0_segctl2(cpu_env
, arg
);
9741 register_name
= "SegCtl2";
9743 case CP0_REG05__PWBASE
:
9745 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_PWBase
));
9746 register_name
= "PWBase";
9748 case CP0_REG05__PWFIELD
:
9750 gen_helper_mtc0_pwfield(cpu_env
, arg
);
9751 register_name
= "PWField";
9753 case CP0_REG05__PWSIZE
:
9755 gen_helper_mtc0_pwsize(cpu_env
, arg
);
9756 register_name
= "PWSize";
9759 goto cp0_unimplemented
;
9762 case CP0_REGISTER_06
:
9764 case CP0_REG06__WIRED
:
9765 gen_helper_mtc0_wired(cpu_env
, arg
);
9766 register_name
= "Wired";
9768 case CP0_REG06__SRSCONF0
:
9769 check_insn(ctx
, ISA_MIPS_R2
);
9770 gen_helper_mtc0_srsconf0(cpu_env
, arg
);
9771 register_name
= "SRSConf0";
9773 case CP0_REG06__SRSCONF1
:
9774 check_insn(ctx
, ISA_MIPS_R2
);
9775 gen_helper_mtc0_srsconf1(cpu_env
, arg
);
9776 register_name
= "SRSConf1";
9778 case CP0_REG06__SRSCONF2
:
9779 check_insn(ctx
, ISA_MIPS_R2
);
9780 gen_helper_mtc0_srsconf2(cpu_env
, arg
);
9781 register_name
= "SRSConf2";
9783 case CP0_REG06__SRSCONF3
:
9784 check_insn(ctx
, ISA_MIPS_R2
);
9785 gen_helper_mtc0_srsconf3(cpu_env
, arg
);
9786 register_name
= "SRSConf3";
9788 case CP0_REG06__SRSCONF4
:
9789 check_insn(ctx
, ISA_MIPS_R2
);
9790 gen_helper_mtc0_srsconf4(cpu_env
, arg
);
9791 register_name
= "SRSConf4";
9793 case CP0_REG06__PWCTL
:
9795 gen_helper_mtc0_pwctl(cpu_env
, arg
);
9796 register_name
= "PWCtl";
9799 goto cp0_unimplemented
;
9802 case CP0_REGISTER_07
:
9804 case CP0_REG07__HWRENA
:
9805 check_insn(ctx
, ISA_MIPS_R2
);
9806 gen_helper_mtc0_hwrena(cpu_env
, arg
);
9807 ctx
->base
.is_jmp
= DISAS_STOP
;
9808 register_name
= "HWREna";
9811 goto cp0_unimplemented
;
9814 case CP0_REGISTER_08
:
9816 case CP0_REG08__BADVADDR
:
9818 register_name
= "BadVAddr";
9820 case CP0_REG08__BADINSTR
:
9822 register_name
= "BadInstr";
9824 case CP0_REG08__BADINSTRP
:
9826 register_name
= "BadInstrP";
9828 case CP0_REG08__BADINSTRX
:
9830 register_name
= "BadInstrX";
9833 goto cp0_unimplemented
;
9836 case CP0_REGISTER_09
:
9838 case CP0_REG09__COUNT
:
9839 gen_helper_mtc0_count(cpu_env
, arg
);
9840 register_name
= "Count";
9842 case CP0_REG09__SAARI
:
9843 CP0_CHECK(ctx
->saar
);
9844 gen_helper_mtc0_saari(cpu_env
, arg
);
9845 register_name
= "SAARI";
9847 case CP0_REG09__SAAR
:
9848 CP0_CHECK(ctx
->saar
);
9849 gen_helper_mtc0_saar(cpu_env
, arg
);
9850 register_name
= "SAAR";
9853 goto cp0_unimplemented
;
9855 /* Stop translation as we may have switched the execution mode */
9856 ctx
->base
.is_jmp
= DISAS_STOP
;
9858 case CP0_REGISTER_10
:
9860 case CP0_REG10__ENTRYHI
:
9861 gen_helper_mtc0_entryhi(cpu_env
, arg
);
9862 register_name
= "EntryHi";
9865 goto cp0_unimplemented
;
9868 case CP0_REGISTER_11
:
9870 case CP0_REG11__COMPARE
:
9871 gen_helper_mtc0_compare(cpu_env
, arg
);
9872 register_name
= "Compare";
9874 /* 6,7 are implementation dependent */
9876 goto cp0_unimplemented
;
9878 /* Stop translation as we may have switched the execution mode */
9879 ctx
->base
.is_jmp
= DISAS_STOP
;
9881 case CP0_REGISTER_12
:
9883 case CP0_REG12__STATUS
:
9884 save_cpu_state(ctx
, 1);
9885 gen_helper_mtc0_status(cpu_env
, arg
);
9886 /* DISAS_STOP isn't good enough here, hflags may have changed. */
9887 gen_save_pc(ctx
->base
.pc_next
+ 4);
9888 ctx
->base
.is_jmp
= DISAS_EXIT
;
9889 register_name
= "Status";
9891 case CP0_REG12__INTCTL
:
9892 check_insn(ctx
, ISA_MIPS_R2
);
9893 gen_helper_mtc0_intctl(cpu_env
, arg
);
9894 /* Stop translation as we may have switched the execution mode */
9895 ctx
->base
.is_jmp
= DISAS_STOP
;
9896 register_name
= "IntCtl";
9898 case CP0_REG12__SRSCTL
:
9899 check_insn(ctx
, ISA_MIPS_R2
);
9900 gen_helper_mtc0_srsctl(cpu_env
, arg
);
9901 /* Stop translation as we may have switched the execution mode */
9902 ctx
->base
.is_jmp
= DISAS_STOP
;
9903 register_name
= "SRSCtl";
9905 case CP0_REG12__SRSMAP
:
9906 check_insn(ctx
, ISA_MIPS_R2
);
9907 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
9908 /* Stop translation as we may have switched the execution mode */
9909 ctx
->base
.is_jmp
= DISAS_STOP
;
9910 register_name
= "SRSMap";
9913 goto cp0_unimplemented
;
9916 case CP0_REGISTER_13
:
9918 case CP0_REG13__CAUSE
:
9919 save_cpu_state(ctx
, 1);
9920 gen_helper_mtc0_cause(cpu_env
, arg
);
9922 * Stop translation as we may have triggered an interrupt.
9923 * DISAS_STOP isn't sufficient, we need to ensure we break out of
9924 * translated code to check for pending interrupts.
9926 gen_save_pc(ctx
->base
.pc_next
+ 4);
9927 ctx
->base
.is_jmp
= DISAS_EXIT
;
9928 register_name
= "Cause";
9931 goto cp0_unimplemented
;
9934 case CP0_REGISTER_14
:
9936 case CP0_REG14__EPC
:
9937 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
9938 register_name
= "EPC";
9941 goto cp0_unimplemented
;
9944 case CP0_REGISTER_15
:
9946 case CP0_REG15__PRID
:
9948 register_name
= "PRid";
9950 case CP0_REG15__EBASE
:
9951 check_insn(ctx
, ISA_MIPS_R2
);
9952 gen_helper_mtc0_ebase(cpu_env
, arg
);
9953 register_name
= "EBase";
9956 goto cp0_unimplemented
;
9959 case CP0_REGISTER_16
:
9961 case CP0_REG16__CONFIG
:
9962 gen_helper_mtc0_config0(cpu_env
, arg
);
9963 register_name
= "Config";
9964 /* Stop translation as we may have switched the execution mode */
9965 ctx
->base
.is_jmp
= DISAS_STOP
;
9967 case CP0_REG16__CONFIG1
:
9968 /* ignored, read only */
9969 register_name
= "Config1";
9971 case CP0_REG16__CONFIG2
:
9972 gen_helper_mtc0_config2(cpu_env
, arg
);
9973 register_name
= "Config2";
9974 /* Stop translation as we may have switched the execution mode */
9975 ctx
->base
.is_jmp
= DISAS_STOP
;
9977 case CP0_REG16__CONFIG3
:
9978 gen_helper_mtc0_config3(cpu_env
, arg
);
9979 register_name
= "Config3";
9980 /* Stop translation as we may have switched the execution mode */
9981 ctx
->base
.is_jmp
= DISAS_STOP
;
9983 case CP0_REG16__CONFIG4
:
9984 /* currently ignored */
9985 register_name
= "Config4";
9987 case CP0_REG16__CONFIG5
:
9988 gen_helper_mtc0_config5(cpu_env
, arg
);
9989 register_name
= "Config5";
9990 /* Stop translation as we may have switched the execution mode */
9991 ctx
->base
.is_jmp
= DISAS_STOP
;
9993 /* 6,7 are implementation dependent */
9995 register_name
= "Invalid config selector";
9996 goto cp0_unimplemented
;
9999 case CP0_REGISTER_17
:
10001 case CP0_REG17__LLADDR
:
10002 gen_helper_mtc0_lladdr(cpu_env
, arg
);
10003 register_name
= "LLAddr";
10005 case CP0_REG17__MAAR
:
10006 CP0_CHECK(ctx
->mrp
);
10007 gen_helper_mtc0_maar(cpu_env
, arg
);
10008 register_name
= "MAAR";
10010 case CP0_REG17__MAARI
:
10011 CP0_CHECK(ctx
->mrp
);
10012 gen_helper_mtc0_maari(cpu_env
, arg
);
10013 register_name
= "MAARI";
10016 goto cp0_unimplemented
;
10019 case CP0_REGISTER_18
:
10021 case CP0_REG18__WATCHLO0
:
10022 case CP0_REG18__WATCHLO1
:
10023 case CP0_REG18__WATCHLO2
:
10024 case CP0_REG18__WATCHLO3
:
10025 case CP0_REG18__WATCHLO4
:
10026 case CP0_REG18__WATCHLO5
:
10027 case CP0_REG18__WATCHLO6
:
10028 case CP0_REG18__WATCHLO7
:
10029 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
10030 gen_helper_0e1i(mtc0_watchlo
, arg
, sel
);
10031 register_name
= "WatchLo";
10034 goto cp0_unimplemented
;
10037 case CP0_REGISTER_19
:
10039 case CP0_REG19__WATCHHI0
:
10040 case CP0_REG19__WATCHHI1
:
10041 case CP0_REG19__WATCHHI2
:
10042 case CP0_REG19__WATCHHI3
:
10043 case CP0_REG19__WATCHHI4
:
10044 case CP0_REG19__WATCHHI5
:
10045 case CP0_REG19__WATCHHI6
:
10046 case CP0_REG19__WATCHHI7
:
10047 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
10048 gen_helper_0e1i(mtc0_watchhi
, arg
, sel
);
10049 register_name
= "WatchHi";
10052 goto cp0_unimplemented
;
10055 case CP0_REGISTER_20
:
10057 case CP0_REG20__XCONTEXT
:
10058 check_insn(ctx
, ISA_MIPS3
);
10059 gen_helper_mtc0_xcontext(cpu_env
, arg
);
10060 register_name
= "XContext";
10063 goto cp0_unimplemented
;
10066 case CP0_REGISTER_21
:
10067 /* Officially reserved, but sel 0 is used for R1x000 framemask */
10068 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS_R6
));
10071 gen_helper_mtc0_framemask(cpu_env
, arg
);
10072 register_name
= "Framemask";
10075 goto cp0_unimplemented
;
10078 case CP0_REGISTER_22
:
10080 register_name
= "Diagnostic"; /* implementation dependent */
10082 case CP0_REGISTER_23
:
10084 case CP0_REG23__DEBUG
:
10085 gen_helper_mtc0_debug(cpu_env
, arg
); /* EJTAG support */
10086 /* DISAS_STOP isn't good enough here, hflags may have changed. */
10087 gen_save_pc(ctx
->base
.pc_next
+ 4);
10088 ctx
->base
.is_jmp
= DISAS_EXIT
;
10089 register_name
= "Debug";
10091 case CP0_REG23__TRACECONTROL
:
10092 /* PDtrace support */
10093 /* gen_helper_mtc0_tracecontrol(cpu_env, arg); */
10094 /* Stop translation as we may have switched the execution mode */
10095 ctx
->base
.is_jmp
= DISAS_STOP
;
10096 register_name
= "TraceControl";
10097 goto cp0_unimplemented
;
10098 case CP0_REG23__TRACECONTROL2
:
10099 /* PDtrace support */
10100 /* gen_helper_mtc0_tracecontrol2(cpu_env, arg); */
10101 /* Stop translation as we may have switched the execution mode */
10102 ctx
->base
.is_jmp
= DISAS_STOP
;
10103 register_name
= "TraceControl2";
10104 goto cp0_unimplemented
;
10105 case CP0_REG23__USERTRACEDATA1
:
10106 /* PDtrace support */
10107 /* gen_helper_mtc0_usertracedata1(cpu_env, arg);*/
10108 /* Stop translation as we may have switched the execution mode */
10109 ctx
->base
.is_jmp
= DISAS_STOP
;
10110 register_name
= "UserTraceData1";
10111 goto cp0_unimplemented
;
10112 case CP0_REG23__TRACEIBPC
:
10113 /* PDtrace support */
10114 /* gen_helper_mtc0_traceibpc(cpu_env, arg); */
10115 /* Stop translation as we may have switched the execution mode */
10116 ctx
->base
.is_jmp
= DISAS_STOP
;
10117 register_name
= "TraceIBPC";
10118 goto cp0_unimplemented
;
10119 case CP0_REG23__TRACEDBPC
:
10120 /* PDtrace support */
10121 /* gen_helper_mtc0_tracedbpc(cpu_env, arg); */
10122 /* Stop translation as we may have switched the execution mode */
10123 ctx
->base
.is_jmp
= DISAS_STOP
;
10124 register_name
= "TraceDBPC";
10125 goto cp0_unimplemented
;
10127 goto cp0_unimplemented
;
10130 case CP0_REGISTER_24
:
10132 case CP0_REG24__DEPC
:
10133 /* EJTAG support */
10134 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
10135 register_name
= "DEPC";
10138 goto cp0_unimplemented
;
10141 case CP0_REGISTER_25
:
10143 case CP0_REG25__PERFCTL0
:
10144 gen_helper_mtc0_performance0(cpu_env
, arg
);
10145 register_name
= "Performance0";
10147 case CP0_REG25__PERFCNT0
:
10148 /* gen_helper_mtc0_performance1(cpu_env, arg); */
10149 register_name
= "Performance1";
10150 goto cp0_unimplemented
;
10151 case CP0_REG25__PERFCTL1
:
10152 /* gen_helper_mtc0_performance2(cpu_env, arg); */
10153 register_name
= "Performance2";
10154 goto cp0_unimplemented
;
10155 case CP0_REG25__PERFCNT1
:
10156 /* gen_helper_mtc0_performance3(cpu_env, arg); */
10157 register_name
= "Performance3";
10158 goto cp0_unimplemented
;
10159 case CP0_REG25__PERFCTL2
:
10160 /* gen_helper_mtc0_performance4(cpu_env, arg); */
10161 register_name
= "Performance4";
10162 goto cp0_unimplemented
;
10163 case CP0_REG25__PERFCNT2
:
10164 /* gen_helper_mtc0_performance5(cpu_env, arg); */
10165 register_name
= "Performance5";
10166 goto cp0_unimplemented
;
10167 case CP0_REG25__PERFCTL3
:
10168 /* gen_helper_mtc0_performance6(cpu_env, arg); */
10169 register_name
= "Performance6";
10170 goto cp0_unimplemented
;
10171 case CP0_REG25__PERFCNT3
:
10172 /* gen_helper_mtc0_performance7(cpu_env, arg); */
10173 register_name
= "Performance7";
10174 goto cp0_unimplemented
;
10176 goto cp0_unimplemented
;
10179 case CP0_REGISTER_26
:
10181 case CP0_REG26__ERRCTL
:
10182 gen_helper_mtc0_errctl(cpu_env
, arg
);
10183 ctx
->base
.is_jmp
= DISAS_STOP
;
10184 register_name
= "ErrCtl";
10187 goto cp0_unimplemented
;
10190 case CP0_REGISTER_27
:
10192 case CP0_REG27__CACHERR
:
10194 register_name
= "CacheErr";
10197 goto cp0_unimplemented
;
10200 case CP0_REGISTER_28
:
10202 case CP0_REG28__TAGLO
:
10203 case CP0_REG28__TAGLO1
:
10204 case CP0_REG28__TAGLO2
:
10205 case CP0_REG28__TAGLO3
:
10206 gen_helper_mtc0_taglo(cpu_env
, arg
);
10207 register_name
= "TagLo";
10209 case CP0_REG28__DATALO
:
10210 case CP0_REG28__DATALO1
:
10211 case CP0_REG28__DATALO2
:
10212 case CP0_REG28__DATALO3
:
10213 gen_helper_mtc0_datalo(cpu_env
, arg
);
10214 register_name
= "DataLo";
10217 goto cp0_unimplemented
;
10220 case CP0_REGISTER_29
:
10222 case CP0_REG29__TAGHI
:
10223 case CP0_REG29__TAGHI1
:
10224 case CP0_REG29__TAGHI2
:
10225 case CP0_REG29__TAGHI3
:
10226 gen_helper_mtc0_taghi(cpu_env
, arg
);
10227 register_name
= "TagHi";
10229 case CP0_REG29__DATAHI
:
10230 case CP0_REG29__DATAHI1
:
10231 case CP0_REG29__DATAHI2
:
10232 case CP0_REG29__DATAHI3
:
10233 gen_helper_mtc0_datahi(cpu_env
, arg
);
10234 register_name
= "DataHi";
10237 register_name
= "invalid sel";
10238 goto cp0_unimplemented
;
10241 case CP0_REGISTER_30
:
10243 case CP0_REG30__ERROREPC
:
10244 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
10245 register_name
= "ErrorEPC";
10248 goto cp0_unimplemented
;
10251 case CP0_REGISTER_31
:
10253 case CP0_REG31__DESAVE
:
10254 /* EJTAG support */
10255 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
10256 register_name
= "DESAVE";
10258 case CP0_REG31__KSCRATCH1
:
10259 case CP0_REG31__KSCRATCH2
:
10260 case CP0_REG31__KSCRATCH3
:
10261 case CP0_REG31__KSCRATCH4
:
10262 case CP0_REG31__KSCRATCH5
:
10263 case CP0_REG31__KSCRATCH6
:
10264 CP0_CHECK(ctx
->kscrexist
& (1 << sel
));
10265 tcg_gen_st_tl(arg
, cpu_env
,
10266 offsetof(CPUMIPSState
, CP0_KScratch
[sel
- 2]));
10267 register_name
= "KScratch";
10270 goto cp0_unimplemented
;
10274 goto cp0_unimplemented
;
10276 trace_mips_translate_c0("dmtc0", register_name
, reg
, sel
);
10278 /* For simplicity assume that all writes can cause interrupts. */
10279 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
10281 * DISAS_STOP isn't sufficient, we need to ensure we break out of
10282 * translated code to check for pending interrupts.
10284 gen_save_pc(ctx
->base
.pc_next
+ 4);
10285 ctx
->base
.is_jmp
= DISAS_EXIT
;
10290 qemu_log_mask(LOG_UNIMP
, "dmtc0 %s (reg %d sel %d)\n",
10291 register_name
, reg
, sel
);
10293 #endif /* TARGET_MIPS64 */
10295 static void gen_mftr(CPUMIPSState
*env
, DisasContext
*ctx
, int rt
, int rd
,
10296 int u
, int sel
, int h
)
10298 int other_tc
= env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
);
10299 TCGv t0
= tcg_temp_local_new();
10301 if ((env
->CP0_VPEConf0
& (1 << CP0VPEC0_MVP
)) == 0 &&
10302 ((env
->tcs
[other_tc
].CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)) !=
10303 (env
->active_tc
.CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)))) {
10304 tcg_gen_movi_tl(t0
, -1);
10305 } else if ((env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
)) >
10306 (env
->mvp
->CP0_MVPConf0
& (0xff << CP0MVPC0_PTC
))) {
10307 tcg_gen_movi_tl(t0
, -1);
10308 } else if (u
== 0) {
10313 gen_helper_mftc0_vpecontrol(t0
, cpu_env
);
10316 gen_helper_mftc0_vpeconf0(t0
, cpu_env
);
10326 gen_helper_mftc0_tcstatus(t0
, cpu_env
);
10329 gen_helper_mftc0_tcbind(t0
, cpu_env
);
10332 gen_helper_mftc0_tcrestart(t0
, cpu_env
);
10335 gen_helper_mftc0_tchalt(t0
, cpu_env
);
10338 gen_helper_mftc0_tccontext(t0
, cpu_env
);
10341 gen_helper_mftc0_tcschedule(t0
, cpu_env
);
10344 gen_helper_mftc0_tcschefback(t0
, cpu_env
);
10347 gen_mfc0(ctx
, t0
, rt
, sel
);
10354 gen_helper_mftc0_entryhi(t0
, cpu_env
);
10357 gen_mfc0(ctx
, t0
, rt
, sel
);
10364 gen_helper_mftc0_status(t0
, cpu_env
);
10367 gen_mfc0(ctx
, t0
, rt
, sel
);
10374 gen_helper_mftc0_cause(t0
, cpu_env
);
10384 gen_helper_mftc0_epc(t0
, cpu_env
);
10394 gen_helper_mftc0_ebase(t0
, cpu_env
);
10411 gen_helper_mftc0_configx(t0
, cpu_env
, tcg_const_tl(sel
));
10421 gen_helper_mftc0_debug(t0
, cpu_env
);
10424 gen_mfc0(ctx
, t0
, rt
, sel
);
10429 gen_mfc0(ctx
, t0
, rt
, sel
);
10433 /* GPR registers. */
10435 gen_helper_1e0i(mftgpr
, t0
, rt
);
10437 /* Auxiliary CPU registers */
10441 gen_helper_1e0i(mftlo
, t0
, 0);
10444 gen_helper_1e0i(mfthi
, t0
, 0);
10447 gen_helper_1e0i(mftacx
, t0
, 0);
10450 gen_helper_1e0i(mftlo
, t0
, 1);
10453 gen_helper_1e0i(mfthi
, t0
, 1);
10456 gen_helper_1e0i(mftacx
, t0
, 1);
10459 gen_helper_1e0i(mftlo
, t0
, 2);
10462 gen_helper_1e0i(mfthi
, t0
, 2);
10465 gen_helper_1e0i(mftacx
, t0
, 2);
10468 gen_helper_1e0i(mftlo
, t0
, 3);
10471 gen_helper_1e0i(mfthi
, t0
, 3);
10474 gen_helper_1e0i(mftacx
, t0
, 3);
10477 gen_helper_mftdsp(t0
, cpu_env
);
10483 /* Floating point (COP1). */
10485 /* XXX: For now we support only a single FPU context. */
10487 TCGv_i32 fp0
= tcg_temp_new_i32();
10489 gen_load_fpr32(ctx
, fp0
, rt
);
10490 tcg_gen_ext_i32_tl(t0
, fp0
);
10491 tcg_temp_free_i32(fp0
);
10493 TCGv_i32 fp0
= tcg_temp_new_i32();
10495 gen_load_fpr32h(ctx
, fp0
, rt
);
10496 tcg_gen_ext_i32_tl(t0
, fp0
);
10497 tcg_temp_free_i32(fp0
);
10501 /* XXX: For now we support only a single FPU context. */
10502 gen_helper_1e0i(cfc1
, t0
, rt
);
10504 /* COP2: Not implemented. */
10512 trace_mips_translate_tr("mftr", rt
, u
, sel
, h
);
10513 gen_store_gpr(t0
, rd
);
10519 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt
, u
, sel
, h
);
10520 gen_reserved_instruction(ctx
);
10523 static void gen_mttr(CPUMIPSState
*env
, DisasContext
*ctx
, int rd
, int rt
,
10524 int u
, int sel
, int h
)
10526 int other_tc
= env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
);
10527 TCGv t0
= tcg_temp_local_new();
10529 gen_load_gpr(t0
, rt
);
10530 if ((env
->CP0_VPEConf0
& (1 << CP0VPEC0_MVP
)) == 0 &&
10531 ((env
->tcs
[other_tc
].CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)) !=
10532 (env
->active_tc
.CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)))) {
10535 } else if ((env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
)) >
10536 (env
->mvp
->CP0_MVPConf0
& (0xff << CP0MVPC0_PTC
))) {
10539 } else if (u
== 0) {
10544 gen_helper_mttc0_vpecontrol(cpu_env
, t0
);
10547 gen_helper_mttc0_vpeconf0(cpu_env
, t0
);
10557 gen_helper_mttc0_tcstatus(cpu_env
, t0
);
10560 gen_helper_mttc0_tcbind(cpu_env
, t0
);
10563 gen_helper_mttc0_tcrestart(cpu_env
, t0
);
10566 gen_helper_mttc0_tchalt(cpu_env
, t0
);
10569 gen_helper_mttc0_tccontext(cpu_env
, t0
);
10572 gen_helper_mttc0_tcschedule(cpu_env
, t0
);
10575 gen_helper_mttc0_tcschefback(cpu_env
, t0
);
10578 gen_mtc0(ctx
, t0
, rd
, sel
);
10585 gen_helper_mttc0_entryhi(cpu_env
, t0
);
10588 gen_mtc0(ctx
, t0
, rd
, sel
);
10595 gen_helper_mttc0_status(cpu_env
, t0
);
10598 gen_mtc0(ctx
, t0
, rd
, sel
);
10605 gen_helper_mttc0_cause(cpu_env
, t0
);
10615 gen_helper_mttc0_ebase(cpu_env
, t0
);
10625 gen_helper_mttc0_debug(cpu_env
, t0
);
10628 gen_mtc0(ctx
, t0
, rd
, sel
);
10633 gen_mtc0(ctx
, t0
, rd
, sel
);
10637 /* GPR registers. */
10639 gen_helper_0e1i(mttgpr
, t0
, rd
);
10641 /* Auxiliary CPU registers */
10645 gen_helper_0e1i(mttlo
, t0
, 0);
10648 gen_helper_0e1i(mtthi
, t0
, 0);
10651 gen_helper_0e1i(mttacx
, t0
, 0);
10654 gen_helper_0e1i(mttlo
, t0
, 1);
10657 gen_helper_0e1i(mtthi
, t0
, 1);
10660 gen_helper_0e1i(mttacx
, t0
, 1);
10663 gen_helper_0e1i(mttlo
, t0
, 2);
10666 gen_helper_0e1i(mtthi
, t0
, 2);
10669 gen_helper_0e1i(mttacx
, t0
, 2);
10672 gen_helper_0e1i(mttlo
, t0
, 3);
10675 gen_helper_0e1i(mtthi
, t0
, 3);
10678 gen_helper_0e1i(mttacx
, t0
, 3);
10681 gen_helper_mttdsp(cpu_env
, t0
);
10687 /* Floating point (COP1). */
10689 /* XXX: For now we support only a single FPU context. */
10691 TCGv_i32 fp0
= tcg_temp_new_i32();
10693 tcg_gen_trunc_tl_i32(fp0
, t0
);
10694 gen_store_fpr32(ctx
, fp0
, rd
);
10695 tcg_temp_free_i32(fp0
);
10697 TCGv_i32 fp0
= tcg_temp_new_i32();
10699 tcg_gen_trunc_tl_i32(fp0
, t0
);
10700 gen_store_fpr32h(ctx
, fp0
, rd
);
10701 tcg_temp_free_i32(fp0
);
10705 /* XXX: For now we support only a single FPU context. */
10707 TCGv_i32 fs_tmp
= tcg_const_i32(rd
);
10709 gen_helper_0e2i(ctc1
, t0
, fs_tmp
, rt
);
10710 tcg_temp_free_i32(fs_tmp
);
10712 /* Stop translation as we may have changed hflags */
10713 ctx
->base
.is_jmp
= DISAS_STOP
;
10715 /* COP2: Not implemented. */
10723 trace_mips_translate_tr("mttr", rd
, u
, sel
, h
);
10729 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd
, u
, sel
, h
);
10730 gen_reserved_instruction(ctx
);
10733 static void gen_cp0(CPUMIPSState
*env
, DisasContext
*ctx
, uint32_t opc
,
10736 const char *opn
= "ldst";
10738 check_cp0_enabled(ctx
);
10742 /* Treat as NOP. */
10745 gen_mfc0(ctx
, cpu_gpr
[rt
], rd
, ctx
->opcode
& 0x7);
10750 TCGv t0
= tcg_temp_new();
10752 gen_load_gpr(t0
, rt
);
10753 gen_mtc0(ctx
, t0
, rd
, ctx
->opcode
& 0x7);
10758 #if defined(TARGET_MIPS64)
10760 check_insn(ctx
, ISA_MIPS3
);
10762 /* Treat as NOP. */
10765 gen_dmfc0(ctx
, cpu_gpr
[rt
], rd
, ctx
->opcode
& 0x7);
10769 check_insn(ctx
, ISA_MIPS3
);
10771 TCGv t0
= tcg_temp_new();
10773 gen_load_gpr(t0
, rt
);
10774 gen_dmtc0(ctx
, t0
, rd
, ctx
->opcode
& 0x7);
10783 /* Treat as NOP. */
10786 gen_mfhc0(ctx
, cpu_gpr
[rt
], rd
, ctx
->opcode
& 0x7);
10792 TCGv t0
= tcg_temp_new();
10793 gen_load_gpr(t0
, rt
);
10794 gen_mthc0(ctx
, t0
, rd
, ctx
->opcode
& 0x7);
10800 check_cp0_enabled(ctx
);
10802 /* Treat as NOP. */
10805 gen_mftr(env
, ctx
, rt
, rd
, (ctx
->opcode
>> 5) & 1,
10806 ctx
->opcode
& 0x7, (ctx
->opcode
>> 4) & 1);
10810 check_cp0_enabled(ctx
);
10811 gen_mttr(env
, ctx
, rd
, rt
, (ctx
->opcode
>> 5) & 1,
10812 ctx
->opcode
& 0x7, (ctx
->opcode
>> 4) & 1);
10817 if (!env
->tlb
->helper_tlbwi
) {
10820 gen_helper_tlbwi(cpu_env
);
10824 if (ctx
->ie
>= 2) {
10825 if (!env
->tlb
->helper_tlbinv
) {
10828 gen_helper_tlbinv(cpu_env
);
10829 } /* treat as nop if TLBINV not supported */
10833 if (ctx
->ie
>= 2) {
10834 if (!env
->tlb
->helper_tlbinvf
) {
10837 gen_helper_tlbinvf(cpu_env
);
10838 } /* treat as nop if TLBINV not supported */
10842 if (!env
->tlb
->helper_tlbwr
) {
10845 gen_helper_tlbwr(cpu_env
);
10849 if (!env
->tlb
->helper_tlbp
) {
10852 gen_helper_tlbp(cpu_env
);
10856 if (!env
->tlb
->helper_tlbr
) {
10859 gen_helper_tlbr(cpu_env
);
10861 case OPC_ERET
: /* OPC_ERETNC */
10862 if ((ctx
->insn_flags
& ISA_MIPS_R6
) &&
10863 (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
10866 int bit_shift
= (ctx
->hflags
& MIPS_HFLAG_M16
) ? 16 : 6;
10867 if (ctx
->opcode
& (1 << bit_shift
)) {
10870 check_insn(ctx
, ISA_MIPS_R5
);
10871 gen_helper_eretnc(cpu_env
);
10875 check_insn(ctx
, ISA_MIPS2
);
10876 gen_helper_eret(cpu_env
);
10878 ctx
->base
.is_jmp
= DISAS_EXIT
;
10883 check_insn(ctx
, ISA_MIPS_R1
);
10884 if ((ctx
->insn_flags
& ISA_MIPS_R6
) &&
10885 (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
10888 if (!(ctx
->hflags
& MIPS_HFLAG_DM
)) {
10890 gen_reserved_instruction(ctx
);
10892 gen_helper_deret(cpu_env
);
10893 ctx
->base
.is_jmp
= DISAS_EXIT
;
10898 check_insn(ctx
, ISA_MIPS3
| ISA_MIPS_R1
);
10899 if ((ctx
->insn_flags
& ISA_MIPS_R6
) &&
10900 (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
10903 /* If we get an exception, we want to restart at next instruction */
10904 ctx
->base
.pc_next
+= 4;
10905 save_cpu_state(ctx
, 1);
10906 ctx
->base
.pc_next
-= 4;
10907 gen_helper_wait(cpu_env
);
10908 ctx
->base
.is_jmp
= DISAS_NORETURN
;
10913 gen_reserved_instruction(ctx
);
10916 (void)opn
; /* avoid a compiler warning */
10918 #endif /* !CONFIG_USER_ONLY */
10920 /* CP1 Branches (before delay slot) */
10921 static void gen_compute_branch1(DisasContext
*ctx
, uint32_t op
,
10922 int32_t cc
, int32_t offset
)
10924 target_ulong btarget
;
10925 TCGv_i32 t0
= tcg_temp_new_i32();
10927 if ((ctx
->insn_flags
& ISA_MIPS_R6
) && (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
10928 gen_reserved_instruction(ctx
);
10933 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS_R1
);
10936 btarget
= ctx
->base
.pc_next
+ 4 + offset
;
10940 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
10941 tcg_gen_not_i32(t0
, t0
);
10942 tcg_gen_andi_i32(t0
, t0
, 1);
10943 tcg_gen_extu_i32_tl(bcond
, t0
);
10946 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
10947 tcg_gen_not_i32(t0
, t0
);
10948 tcg_gen_andi_i32(t0
, t0
, 1);
10949 tcg_gen_extu_i32_tl(bcond
, t0
);
10952 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
10953 tcg_gen_andi_i32(t0
, t0
, 1);
10954 tcg_gen_extu_i32_tl(bcond
, t0
);
10957 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
10958 tcg_gen_andi_i32(t0
, t0
, 1);
10959 tcg_gen_extu_i32_tl(bcond
, t0
);
10961 ctx
->hflags
|= MIPS_HFLAG_BL
;
10965 TCGv_i32 t1
= tcg_temp_new_i32();
10966 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
10967 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 1));
10968 tcg_gen_nand_i32(t0
, t0
, t1
);
10969 tcg_temp_free_i32(t1
);
10970 tcg_gen_andi_i32(t0
, t0
, 1);
10971 tcg_gen_extu_i32_tl(bcond
, t0
);
10976 TCGv_i32 t1
= tcg_temp_new_i32();
10977 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
10978 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 1));
10979 tcg_gen_or_i32(t0
, t0
, t1
);
10980 tcg_temp_free_i32(t1
);
10981 tcg_gen_andi_i32(t0
, t0
, 1);
10982 tcg_gen_extu_i32_tl(bcond
, t0
);
10987 TCGv_i32 t1
= tcg_temp_new_i32();
10988 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
10989 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 1));
10990 tcg_gen_and_i32(t0
, t0
, t1
);
10991 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 2));
10992 tcg_gen_and_i32(t0
, t0
, t1
);
10993 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 3));
10994 tcg_gen_nand_i32(t0
, t0
, t1
);
10995 tcg_temp_free_i32(t1
);
10996 tcg_gen_andi_i32(t0
, t0
, 1);
10997 tcg_gen_extu_i32_tl(bcond
, t0
);
11002 TCGv_i32 t1
= tcg_temp_new_i32();
11003 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
11004 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 1));
11005 tcg_gen_or_i32(t0
, t0
, t1
);
11006 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 2));
11007 tcg_gen_or_i32(t0
, t0
, t1
);
11008 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 3));
11009 tcg_gen_or_i32(t0
, t0
, t1
);
11010 tcg_temp_free_i32(t1
);
11011 tcg_gen_andi_i32(t0
, t0
, 1);
11012 tcg_gen_extu_i32_tl(bcond
, t0
);
11015 ctx
->hflags
|= MIPS_HFLAG_BC
;
11018 MIPS_INVAL("cp1 cond branch");
11019 gen_reserved_instruction(ctx
);
11022 ctx
->btarget
= btarget
;
11023 ctx
->hflags
|= MIPS_HFLAG_BDS32
;
11025 tcg_temp_free_i32(t0
);
11028 /* R6 CP1 Branches */
11029 static void gen_compute_branch1_r6(DisasContext
*ctx
, uint32_t op
,
11030 int32_t ft
, int32_t offset
,
11031 int delayslot_size
)
11033 target_ulong btarget
;
11034 TCGv_i64 t0
= tcg_temp_new_i64();
11036 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
11037 #ifdef MIPS_DEBUG_DISAS
11038 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
11039 "\n", ctx
->base
.pc_next
);
11041 gen_reserved_instruction(ctx
);
11045 gen_load_fpr64(ctx
, t0
, ft
);
11046 tcg_gen_andi_i64(t0
, t0
, 1);
11048 btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
11052 tcg_gen_xori_i64(t0
, t0
, 1);
11053 ctx
->hflags
|= MIPS_HFLAG_BC
;
11056 /* t0 already set */
11057 ctx
->hflags
|= MIPS_HFLAG_BC
;
11060 MIPS_INVAL("cp1 cond branch");
11061 gen_reserved_instruction(ctx
);
11065 tcg_gen_trunc_i64_tl(bcond
, t0
);
11067 ctx
->btarget
= btarget
;
11069 switch (delayslot_size
) {
11071 ctx
->hflags
|= MIPS_HFLAG_BDS16
;
11074 ctx
->hflags
|= MIPS_HFLAG_BDS32
;
11079 tcg_temp_free_i64(t0
);
11082 /* Coprocessor 1 (FPU) */
11084 #define FOP(func, fmt) (((fmt) << 21) | (func))
11087 OPC_ADD_S
= FOP(0, FMT_S
),
11088 OPC_SUB_S
= FOP(1, FMT_S
),
11089 OPC_MUL_S
= FOP(2, FMT_S
),
11090 OPC_DIV_S
= FOP(3, FMT_S
),
11091 OPC_SQRT_S
= FOP(4, FMT_S
),
11092 OPC_ABS_S
= FOP(5, FMT_S
),
11093 OPC_MOV_S
= FOP(6, FMT_S
),
11094 OPC_NEG_S
= FOP(7, FMT_S
),
11095 OPC_ROUND_L_S
= FOP(8, FMT_S
),
11096 OPC_TRUNC_L_S
= FOP(9, FMT_S
),
11097 OPC_CEIL_L_S
= FOP(10, FMT_S
),
11098 OPC_FLOOR_L_S
= FOP(11, FMT_S
),
11099 OPC_ROUND_W_S
= FOP(12, FMT_S
),
11100 OPC_TRUNC_W_S
= FOP(13, FMT_S
),
11101 OPC_CEIL_W_S
= FOP(14, FMT_S
),
11102 OPC_FLOOR_W_S
= FOP(15, FMT_S
),
11103 OPC_SEL_S
= FOP(16, FMT_S
),
11104 OPC_MOVCF_S
= FOP(17, FMT_S
),
11105 OPC_MOVZ_S
= FOP(18, FMT_S
),
11106 OPC_MOVN_S
= FOP(19, FMT_S
),
11107 OPC_SELEQZ_S
= FOP(20, FMT_S
),
11108 OPC_RECIP_S
= FOP(21, FMT_S
),
11109 OPC_RSQRT_S
= FOP(22, FMT_S
),
11110 OPC_SELNEZ_S
= FOP(23, FMT_S
),
11111 OPC_MADDF_S
= FOP(24, FMT_S
),
11112 OPC_MSUBF_S
= FOP(25, FMT_S
),
11113 OPC_RINT_S
= FOP(26, FMT_S
),
11114 OPC_CLASS_S
= FOP(27, FMT_S
),
11115 OPC_MIN_S
= FOP(28, FMT_S
),
11116 OPC_RECIP2_S
= FOP(28, FMT_S
),
11117 OPC_MINA_S
= FOP(29, FMT_S
),
11118 OPC_RECIP1_S
= FOP(29, FMT_S
),
11119 OPC_MAX_S
= FOP(30, FMT_S
),
11120 OPC_RSQRT1_S
= FOP(30, FMT_S
),
11121 OPC_MAXA_S
= FOP(31, FMT_S
),
11122 OPC_RSQRT2_S
= FOP(31, FMT_S
),
11123 OPC_CVT_D_S
= FOP(33, FMT_S
),
11124 OPC_CVT_W_S
= FOP(36, FMT_S
),
11125 OPC_CVT_L_S
= FOP(37, FMT_S
),
11126 OPC_CVT_PS_S
= FOP(38, FMT_S
),
11127 OPC_CMP_F_S
= FOP(48, FMT_S
),
11128 OPC_CMP_UN_S
= FOP(49, FMT_S
),
11129 OPC_CMP_EQ_S
= FOP(50, FMT_S
),
11130 OPC_CMP_UEQ_S
= FOP(51, FMT_S
),
11131 OPC_CMP_OLT_S
= FOP(52, FMT_S
),
11132 OPC_CMP_ULT_S
= FOP(53, FMT_S
),
11133 OPC_CMP_OLE_S
= FOP(54, FMT_S
),
11134 OPC_CMP_ULE_S
= FOP(55, FMT_S
),
11135 OPC_CMP_SF_S
= FOP(56, FMT_S
),
11136 OPC_CMP_NGLE_S
= FOP(57, FMT_S
),
11137 OPC_CMP_SEQ_S
= FOP(58, FMT_S
),
11138 OPC_CMP_NGL_S
= FOP(59, FMT_S
),
11139 OPC_CMP_LT_S
= FOP(60, FMT_S
),
11140 OPC_CMP_NGE_S
= FOP(61, FMT_S
),
11141 OPC_CMP_LE_S
= FOP(62, FMT_S
),
11142 OPC_CMP_NGT_S
= FOP(63, FMT_S
),
11144 OPC_ADD_D
= FOP(0, FMT_D
),
11145 OPC_SUB_D
= FOP(1, FMT_D
),
11146 OPC_MUL_D
= FOP(2, FMT_D
),
11147 OPC_DIV_D
= FOP(3, FMT_D
),
11148 OPC_SQRT_D
= FOP(4, FMT_D
),
11149 OPC_ABS_D
= FOP(5, FMT_D
),
11150 OPC_MOV_D
= FOP(6, FMT_D
),
11151 OPC_NEG_D
= FOP(7, FMT_D
),
11152 OPC_ROUND_L_D
= FOP(8, FMT_D
),
11153 OPC_TRUNC_L_D
= FOP(9, FMT_D
),
11154 OPC_CEIL_L_D
= FOP(10, FMT_D
),
11155 OPC_FLOOR_L_D
= FOP(11, FMT_D
),
11156 OPC_ROUND_W_D
= FOP(12, FMT_D
),
11157 OPC_TRUNC_W_D
= FOP(13, FMT_D
),
11158 OPC_CEIL_W_D
= FOP(14, FMT_D
),
11159 OPC_FLOOR_W_D
= FOP(15, FMT_D
),
11160 OPC_SEL_D
= FOP(16, FMT_D
),
11161 OPC_MOVCF_D
= FOP(17, FMT_D
),
11162 OPC_MOVZ_D
= FOP(18, FMT_D
),
11163 OPC_MOVN_D
= FOP(19, FMT_D
),
11164 OPC_SELEQZ_D
= FOP(20, FMT_D
),
11165 OPC_RECIP_D
= FOP(21, FMT_D
),
11166 OPC_RSQRT_D
= FOP(22, FMT_D
),
11167 OPC_SELNEZ_D
= FOP(23, FMT_D
),
11168 OPC_MADDF_D
= FOP(24, FMT_D
),
11169 OPC_MSUBF_D
= FOP(25, FMT_D
),
11170 OPC_RINT_D
= FOP(26, FMT_D
),
11171 OPC_CLASS_D
= FOP(27, FMT_D
),
11172 OPC_MIN_D
= FOP(28, FMT_D
),
11173 OPC_RECIP2_D
= FOP(28, FMT_D
),
11174 OPC_MINA_D
= FOP(29, FMT_D
),
11175 OPC_RECIP1_D
= FOP(29, FMT_D
),
11176 OPC_MAX_D
= FOP(30, FMT_D
),
11177 OPC_RSQRT1_D
= FOP(30, FMT_D
),
11178 OPC_MAXA_D
= FOP(31, FMT_D
),
11179 OPC_RSQRT2_D
= FOP(31, FMT_D
),
11180 OPC_CVT_S_D
= FOP(32, FMT_D
),
11181 OPC_CVT_W_D
= FOP(36, FMT_D
),
11182 OPC_CVT_L_D
= FOP(37, FMT_D
),
11183 OPC_CMP_F_D
= FOP(48, FMT_D
),
11184 OPC_CMP_UN_D
= FOP(49, FMT_D
),
11185 OPC_CMP_EQ_D
= FOP(50, FMT_D
),
11186 OPC_CMP_UEQ_D
= FOP(51, FMT_D
),
11187 OPC_CMP_OLT_D
= FOP(52, FMT_D
),
11188 OPC_CMP_ULT_D
= FOP(53, FMT_D
),
11189 OPC_CMP_OLE_D
= FOP(54, FMT_D
),
11190 OPC_CMP_ULE_D
= FOP(55, FMT_D
),
11191 OPC_CMP_SF_D
= FOP(56, FMT_D
),
11192 OPC_CMP_NGLE_D
= FOP(57, FMT_D
),
11193 OPC_CMP_SEQ_D
= FOP(58, FMT_D
),
11194 OPC_CMP_NGL_D
= FOP(59, FMT_D
),
11195 OPC_CMP_LT_D
= FOP(60, FMT_D
),
11196 OPC_CMP_NGE_D
= FOP(61, FMT_D
),
11197 OPC_CMP_LE_D
= FOP(62, FMT_D
),
11198 OPC_CMP_NGT_D
= FOP(63, FMT_D
),
11200 OPC_CVT_S_W
= FOP(32, FMT_W
),
11201 OPC_CVT_D_W
= FOP(33, FMT_W
),
11202 OPC_CVT_S_L
= FOP(32, FMT_L
),
11203 OPC_CVT_D_L
= FOP(33, FMT_L
),
11204 OPC_CVT_PS_PW
= FOP(38, FMT_W
),
11206 OPC_ADD_PS
= FOP(0, FMT_PS
),
11207 OPC_SUB_PS
= FOP(1, FMT_PS
),
11208 OPC_MUL_PS
= FOP(2, FMT_PS
),
11209 OPC_DIV_PS
= FOP(3, FMT_PS
),
11210 OPC_ABS_PS
= FOP(5, FMT_PS
),
11211 OPC_MOV_PS
= FOP(6, FMT_PS
),
11212 OPC_NEG_PS
= FOP(7, FMT_PS
),
11213 OPC_MOVCF_PS
= FOP(17, FMT_PS
),
11214 OPC_MOVZ_PS
= FOP(18, FMT_PS
),
11215 OPC_MOVN_PS
= FOP(19, FMT_PS
),
11216 OPC_ADDR_PS
= FOP(24, FMT_PS
),
11217 OPC_MULR_PS
= FOP(26, FMT_PS
),
11218 OPC_RECIP2_PS
= FOP(28, FMT_PS
),
11219 OPC_RECIP1_PS
= FOP(29, FMT_PS
),
11220 OPC_RSQRT1_PS
= FOP(30, FMT_PS
),
11221 OPC_RSQRT2_PS
= FOP(31, FMT_PS
),
11223 OPC_CVT_S_PU
= FOP(32, FMT_PS
),
11224 OPC_CVT_PW_PS
= FOP(36, FMT_PS
),
11225 OPC_CVT_S_PL
= FOP(40, FMT_PS
),
11226 OPC_PLL_PS
= FOP(44, FMT_PS
),
11227 OPC_PLU_PS
= FOP(45, FMT_PS
),
11228 OPC_PUL_PS
= FOP(46, FMT_PS
),
11229 OPC_PUU_PS
= FOP(47, FMT_PS
),
11230 OPC_CMP_F_PS
= FOP(48, FMT_PS
),
11231 OPC_CMP_UN_PS
= FOP(49, FMT_PS
),
11232 OPC_CMP_EQ_PS
= FOP(50, FMT_PS
),
11233 OPC_CMP_UEQ_PS
= FOP(51, FMT_PS
),
11234 OPC_CMP_OLT_PS
= FOP(52, FMT_PS
),
11235 OPC_CMP_ULT_PS
= FOP(53, FMT_PS
),
11236 OPC_CMP_OLE_PS
= FOP(54, FMT_PS
),
11237 OPC_CMP_ULE_PS
= FOP(55, FMT_PS
),
11238 OPC_CMP_SF_PS
= FOP(56, FMT_PS
),
11239 OPC_CMP_NGLE_PS
= FOP(57, FMT_PS
),
11240 OPC_CMP_SEQ_PS
= FOP(58, FMT_PS
),
11241 OPC_CMP_NGL_PS
= FOP(59, FMT_PS
),
11242 OPC_CMP_LT_PS
= FOP(60, FMT_PS
),
11243 OPC_CMP_NGE_PS
= FOP(61, FMT_PS
),
11244 OPC_CMP_LE_PS
= FOP(62, FMT_PS
),
11245 OPC_CMP_NGT_PS
= FOP(63, FMT_PS
),
11249 R6_OPC_CMP_AF_S
= FOP(0, FMT_W
),
11250 R6_OPC_CMP_UN_S
= FOP(1, FMT_W
),
11251 R6_OPC_CMP_EQ_S
= FOP(2, FMT_W
),
11252 R6_OPC_CMP_UEQ_S
= FOP(3, FMT_W
),
11253 R6_OPC_CMP_LT_S
= FOP(4, FMT_W
),
11254 R6_OPC_CMP_ULT_S
= FOP(5, FMT_W
),
11255 R6_OPC_CMP_LE_S
= FOP(6, FMT_W
),
11256 R6_OPC_CMP_ULE_S
= FOP(7, FMT_W
),
11257 R6_OPC_CMP_SAF_S
= FOP(8, FMT_W
),
11258 R6_OPC_CMP_SUN_S
= FOP(9, FMT_W
),
11259 R6_OPC_CMP_SEQ_S
= FOP(10, FMT_W
),
11260 R6_OPC_CMP_SEUQ_S
= FOP(11, FMT_W
),
11261 R6_OPC_CMP_SLT_S
= FOP(12, FMT_W
),
11262 R6_OPC_CMP_SULT_S
= FOP(13, FMT_W
),
11263 R6_OPC_CMP_SLE_S
= FOP(14, FMT_W
),
11264 R6_OPC_CMP_SULE_S
= FOP(15, FMT_W
),
11265 R6_OPC_CMP_OR_S
= FOP(17, FMT_W
),
11266 R6_OPC_CMP_UNE_S
= FOP(18, FMT_W
),
11267 R6_OPC_CMP_NE_S
= FOP(19, FMT_W
),
11268 R6_OPC_CMP_SOR_S
= FOP(25, FMT_W
),
11269 R6_OPC_CMP_SUNE_S
= FOP(26, FMT_W
),
11270 R6_OPC_CMP_SNE_S
= FOP(27, FMT_W
),
11272 R6_OPC_CMP_AF_D
= FOP(0, FMT_L
),
11273 R6_OPC_CMP_UN_D
= FOP(1, FMT_L
),
11274 R6_OPC_CMP_EQ_D
= FOP(2, FMT_L
),
11275 R6_OPC_CMP_UEQ_D
= FOP(3, FMT_L
),
11276 R6_OPC_CMP_LT_D
= FOP(4, FMT_L
),
11277 R6_OPC_CMP_ULT_D
= FOP(5, FMT_L
),
11278 R6_OPC_CMP_LE_D
= FOP(6, FMT_L
),
11279 R6_OPC_CMP_ULE_D
= FOP(7, FMT_L
),
11280 R6_OPC_CMP_SAF_D
= FOP(8, FMT_L
),
11281 R6_OPC_CMP_SUN_D
= FOP(9, FMT_L
),
11282 R6_OPC_CMP_SEQ_D
= FOP(10, FMT_L
),
11283 R6_OPC_CMP_SEUQ_D
= FOP(11, FMT_L
),
11284 R6_OPC_CMP_SLT_D
= FOP(12, FMT_L
),
11285 R6_OPC_CMP_SULT_D
= FOP(13, FMT_L
),
11286 R6_OPC_CMP_SLE_D
= FOP(14, FMT_L
),
11287 R6_OPC_CMP_SULE_D
= FOP(15, FMT_L
),
11288 R6_OPC_CMP_OR_D
= FOP(17, FMT_L
),
11289 R6_OPC_CMP_UNE_D
= FOP(18, FMT_L
),
11290 R6_OPC_CMP_NE_D
= FOP(19, FMT_L
),
11291 R6_OPC_CMP_SOR_D
= FOP(25, FMT_L
),
11292 R6_OPC_CMP_SUNE_D
= FOP(26, FMT_L
),
11293 R6_OPC_CMP_SNE_D
= FOP(27, FMT_L
),
11296 static void gen_cp1(DisasContext
*ctx
, uint32_t opc
, int rt
, int fs
)
11298 TCGv t0
= tcg_temp_new();
11303 TCGv_i32 fp0
= tcg_temp_new_i32();
11305 gen_load_fpr32(ctx
, fp0
, fs
);
11306 tcg_gen_ext_i32_tl(t0
, fp0
);
11307 tcg_temp_free_i32(fp0
);
11309 gen_store_gpr(t0
, rt
);
11312 gen_load_gpr(t0
, rt
);
11314 TCGv_i32 fp0
= tcg_temp_new_i32();
11316 tcg_gen_trunc_tl_i32(fp0
, t0
);
11317 gen_store_fpr32(ctx
, fp0
, fs
);
11318 tcg_temp_free_i32(fp0
);
11322 gen_helper_1e0i(cfc1
, t0
, fs
);
11323 gen_store_gpr(t0
, rt
);
11326 gen_load_gpr(t0
, rt
);
11327 save_cpu_state(ctx
, 0);
11329 TCGv_i32 fs_tmp
= tcg_const_i32(fs
);
11331 gen_helper_0e2i(ctc1
, t0
, fs_tmp
, rt
);
11332 tcg_temp_free_i32(fs_tmp
);
11334 /* Stop translation as we may have changed hflags */
11335 ctx
->base
.is_jmp
= DISAS_STOP
;
11337 #if defined(TARGET_MIPS64)
11339 gen_load_fpr64(ctx
, t0
, fs
);
11340 gen_store_gpr(t0
, rt
);
11343 gen_load_gpr(t0
, rt
);
11344 gen_store_fpr64(ctx
, t0
, fs
);
11349 TCGv_i32 fp0
= tcg_temp_new_i32();
11351 gen_load_fpr32h(ctx
, fp0
, fs
);
11352 tcg_gen_ext_i32_tl(t0
, fp0
);
11353 tcg_temp_free_i32(fp0
);
11355 gen_store_gpr(t0
, rt
);
11358 gen_load_gpr(t0
, rt
);
11360 TCGv_i32 fp0
= tcg_temp_new_i32();
11362 tcg_gen_trunc_tl_i32(fp0
, t0
);
11363 gen_store_fpr32h(ctx
, fp0
, fs
);
11364 tcg_temp_free_i32(fp0
);
11368 MIPS_INVAL("cp1 move");
11369 gen_reserved_instruction(ctx
);
11377 static void gen_movci(DisasContext
*ctx
, int rd
, int rs
, int cc
, int tf
)
11384 /* Treat as NOP. */
11389 cond
= TCG_COND_EQ
;
11391 cond
= TCG_COND_NE
;
11394 l1
= gen_new_label();
11395 t0
= tcg_temp_new_i32();
11396 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
11397 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
11398 tcg_temp_free_i32(t0
);
11400 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
11402 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
11407 static inline void gen_movcf_s(DisasContext
*ctx
, int fs
, int fd
, int cc
,
11411 TCGv_i32 t0
= tcg_temp_new_i32();
11412 TCGLabel
*l1
= gen_new_label();
11415 cond
= TCG_COND_EQ
;
11417 cond
= TCG_COND_NE
;
11420 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
11421 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
11422 gen_load_fpr32(ctx
, t0
, fs
);
11423 gen_store_fpr32(ctx
, t0
, fd
);
11425 tcg_temp_free_i32(t0
);
11428 static inline void gen_movcf_d(DisasContext
*ctx
, int fs
, int fd
, int cc
,
11432 TCGv_i32 t0
= tcg_temp_new_i32();
11434 TCGLabel
*l1
= gen_new_label();
11437 cond
= TCG_COND_EQ
;
11439 cond
= TCG_COND_NE
;
11442 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
11443 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
11444 tcg_temp_free_i32(t0
);
11445 fp0
= tcg_temp_new_i64();
11446 gen_load_fpr64(ctx
, fp0
, fs
);
11447 gen_store_fpr64(ctx
, fp0
, fd
);
11448 tcg_temp_free_i64(fp0
);
11452 static inline void gen_movcf_ps(DisasContext
*ctx
, int fs
, int fd
,
11456 TCGv_i32 t0
= tcg_temp_new_i32();
11457 TCGLabel
*l1
= gen_new_label();
11458 TCGLabel
*l2
= gen_new_label();
11461 cond
= TCG_COND_EQ
;
11463 cond
= TCG_COND_NE
;
11466 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
11467 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
11468 gen_load_fpr32(ctx
, t0
, fs
);
11469 gen_store_fpr32(ctx
, t0
, fd
);
11472 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
+ 1));
11473 tcg_gen_brcondi_i32(cond
, t0
, 0, l2
);
11474 gen_load_fpr32h(ctx
, t0
, fs
);
11475 gen_store_fpr32h(ctx
, t0
, fd
);
11476 tcg_temp_free_i32(t0
);
11480 static void gen_sel_s(DisasContext
*ctx
, enum fopcode op1
, int fd
, int ft
,
11483 TCGv_i32 t1
= tcg_const_i32(0);
11484 TCGv_i32 fp0
= tcg_temp_new_i32();
11485 TCGv_i32 fp1
= tcg_temp_new_i32();
11486 TCGv_i32 fp2
= tcg_temp_new_i32();
11487 gen_load_fpr32(ctx
, fp0
, fd
);
11488 gen_load_fpr32(ctx
, fp1
, ft
);
11489 gen_load_fpr32(ctx
, fp2
, fs
);
11493 tcg_gen_andi_i32(fp0
, fp0
, 1);
11494 tcg_gen_movcond_i32(TCG_COND_NE
, fp0
, fp0
, t1
, fp1
, fp2
);
11497 tcg_gen_andi_i32(fp1
, fp1
, 1);
11498 tcg_gen_movcond_i32(TCG_COND_EQ
, fp0
, fp1
, t1
, fp2
, t1
);
11501 tcg_gen_andi_i32(fp1
, fp1
, 1);
11502 tcg_gen_movcond_i32(TCG_COND_NE
, fp0
, fp1
, t1
, fp2
, t1
);
11505 MIPS_INVAL("gen_sel_s");
11506 gen_reserved_instruction(ctx
);
11510 gen_store_fpr32(ctx
, fp0
, fd
);
11511 tcg_temp_free_i32(fp2
);
11512 tcg_temp_free_i32(fp1
);
11513 tcg_temp_free_i32(fp0
);
11514 tcg_temp_free_i32(t1
);
11517 static void gen_sel_d(DisasContext
*ctx
, enum fopcode op1
, int fd
, int ft
,
11520 TCGv_i64 t1
= tcg_const_i64(0);
11521 TCGv_i64 fp0
= tcg_temp_new_i64();
11522 TCGv_i64 fp1
= tcg_temp_new_i64();
11523 TCGv_i64 fp2
= tcg_temp_new_i64();
11524 gen_load_fpr64(ctx
, fp0
, fd
);
11525 gen_load_fpr64(ctx
, fp1
, ft
);
11526 gen_load_fpr64(ctx
, fp2
, fs
);
11530 tcg_gen_andi_i64(fp0
, fp0
, 1);
11531 tcg_gen_movcond_i64(TCG_COND_NE
, fp0
, fp0
, t1
, fp1
, fp2
);
11534 tcg_gen_andi_i64(fp1
, fp1
, 1);
11535 tcg_gen_movcond_i64(TCG_COND_EQ
, fp0
, fp1
, t1
, fp2
, t1
);
11538 tcg_gen_andi_i64(fp1
, fp1
, 1);
11539 tcg_gen_movcond_i64(TCG_COND_NE
, fp0
, fp1
, t1
, fp2
, t1
);
11542 MIPS_INVAL("gen_sel_d");
11543 gen_reserved_instruction(ctx
);
11547 gen_store_fpr64(ctx
, fp0
, fd
);
11548 tcg_temp_free_i64(fp2
);
11549 tcg_temp_free_i64(fp1
);
11550 tcg_temp_free_i64(fp0
);
11551 tcg_temp_free_i64(t1
);
11554 static void gen_farith(DisasContext
*ctx
, enum fopcode op1
,
11555 int ft
, int fs
, int fd
, int cc
)
11557 uint32_t func
= ctx
->opcode
& 0x3f;
11561 TCGv_i32 fp0
= tcg_temp_new_i32();
11562 TCGv_i32 fp1
= tcg_temp_new_i32();
11564 gen_load_fpr32(ctx
, fp0
, fs
);
11565 gen_load_fpr32(ctx
, fp1
, ft
);
11566 gen_helper_float_add_s(fp0
, cpu_env
, fp0
, fp1
);
11567 tcg_temp_free_i32(fp1
);
11568 gen_store_fpr32(ctx
, fp0
, fd
);
11569 tcg_temp_free_i32(fp0
);
11574 TCGv_i32 fp0
= tcg_temp_new_i32();
11575 TCGv_i32 fp1
= tcg_temp_new_i32();
11577 gen_load_fpr32(ctx
, fp0
, fs
);
11578 gen_load_fpr32(ctx
, fp1
, ft
);
11579 gen_helper_float_sub_s(fp0
, cpu_env
, fp0
, fp1
);
11580 tcg_temp_free_i32(fp1
);
11581 gen_store_fpr32(ctx
, fp0
, fd
);
11582 tcg_temp_free_i32(fp0
);
11587 TCGv_i32 fp0
= tcg_temp_new_i32();
11588 TCGv_i32 fp1
= tcg_temp_new_i32();
11590 gen_load_fpr32(ctx
, fp0
, fs
);
11591 gen_load_fpr32(ctx
, fp1
, ft
);
11592 gen_helper_float_mul_s(fp0
, cpu_env
, fp0
, fp1
);
11593 tcg_temp_free_i32(fp1
);
11594 gen_store_fpr32(ctx
, fp0
, fd
);
11595 tcg_temp_free_i32(fp0
);
11600 TCGv_i32 fp0
= tcg_temp_new_i32();
11601 TCGv_i32 fp1
= tcg_temp_new_i32();
11603 gen_load_fpr32(ctx
, fp0
, fs
);
11604 gen_load_fpr32(ctx
, fp1
, ft
);
11605 gen_helper_float_div_s(fp0
, cpu_env
, fp0
, fp1
);
11606 tcg_temp_free_i32(fp1
);
11607 gen_store_fpr32(ctx
, fp0
, fd
);
11608 tcg_temp_free_i32(fp0
);
11613 TCGv_i32 fp0
= tcg_temp_new_i32();
11615 gen_load_fpr32(ctx
, fp0
, fs
);
11616 gen_helper_float_sqrt_s(fp0
, cpu_env
, fp0
);
11617 gen_store_fpr32(ctx
, fp0
, fd
);
11618 tcg_temp_free_i32(fp0
);
11623 TCGv_i32 fp0
= tcg_temp_new_i32();
11625 gen_load_fpr32(ctx
, fp0
, fs
);
11626 if (ctx
->abs2008
) {
11627 tcg_gen_andi_i32(fp0
, fp0
, 0x7fffffffUL
);
11629 gen_helper_float_abs_s(fp0
, fp0
);
11631 gen_store_fpr32(ctx
, fp0
, fd
);
11632 tcg_temp_free_i32(fp0
);
11637 TCGv_i32 fp0
= tcg_temp_new_i32();
11639 gen_load_fpr32(ctx
, fp0
, fs
);
11640 gen_store_fpr32(ctx
, fp0
, fd
);
11641 tcg_temp_free_i32(fp0
);
11646 TCGv_i32 fp0
= tcg_temp_new_i32();
11648 gen_load_fpr32(ctx
, fp0
, fs
);
11649 if (ctx
->abs2008
) {
11650 tcg_gen_xori_i32(fp0
, fp0
, 1UL << 31);
11652 gen_helper_float_chs_s(fp0
, fp0
);
11654 gen_store_fpr32(ctx
, fp0
, fd
);
11655 tcg_temp_free_i32(fp0
);
11658 case OPC_ROUND_L_S
:
11659 check_cp1_64bitmode(ctx
);
11661 TCGv_i32 fp32
= tcg_temp_new_i32();
11662 TCGv_i64 fp64
= tcg_temp_new_i64();
11664 gen_load_fpr32(ctx
, fp32
, fs
);
11665 if (ctx
->nan2008
) {
11666 gen_helper_float_round_2008_l_s(fp64
, cpu_env
, fp32
);
11668 gen_helper_float_round_l_s(fp64
, cpu_env
, fp32
);
11670 tcg_temp_free_i32(fp32
);
11671 gen_store_fpr64(ctx
, fp64
, fd
);
11672 tcg_temp_free_i64(fp64
);
11675 case OPC_TRUNC_L_S
:
11676 check_cp1_64bitmode(ctx
);
11678 TCGv_i32 fp32
= tcg_temp_new_i32();
11679 TCGv_i64 fp64
= tcg_temp_new_i64();
11681 gen_load_fpr32(ctx
, fp32
, fs
);
11682 if (ctx
->nan2008
) {
11683 gen_helper_float_trunc_2008_l_s(fp64
, cpu_env
, fp32
);
11685 gen_helper_float_trunc_l_s(fp64
, cpu_env
, fp32
);
11687 tcg_temp_free_i32(fp32
);
11688 gen_store_fpr64(ctx
, fp64
, fd
);
11689 tcg_temp_free_i64(fp64
);
11693 check_cp1_64bitmode(ctx
);
11695 TCGv_i32 fp32
= tcg_temp_new_i32();
11696 TCGv_i64 fp64
= tcg_temp_new_i64();
11698 gen_load_fpr32(ctx
, fp32
, fs
);
11699 if (ctx
->nan2008
) {
11700 gen_helper_float_ceil_2008_l_s(fp64
, cpu_env
, fp32
);
11702 gen_helper_float_ceil_l_s(fp64
, cpu_env
, fp32
);
11704 tcg_temp_free_i32(fp32
);
11705 gen_store_fpr64(ctx
, fp64
, fd
);
11706 tcg_temp_free_i64(fp64
);
11709 case OPC_FLOOR_L_S
:
11710 check_cp1_64bitmode(ctx
);
11712 TCGv_i32 fp32
= tcg_temp_new_i32();
11713 TCGv_i64 fp64
= tcg_temp_new_i64();
11715 gen_load_fpr32(ctx
, fp32
, fs
);
11716 if (ctx
->nan2008
) {
11717 gen_helper_float_floor_2008_l_s(fp64
, cpu_env
, fp32
);
11719 gen_helper_float_floor_l_s(fp64
, cpu_env
, fp32
);
11721 tcg_temp_free_i32(fp32
);
11722 gen_store_fpr64(ctx
, fp64
, fd
);
11723 tcg_temp_free_i64(fp64
);
11726 case OPC_ROUND_W_S
:
11728 TCGv_i32 fp0
= tcg_temp_new_i32();
11730 gen_load_fpr32(ctx
, fp0
, fs
);
11731 if (ctx
->nan2008
) {
11732 gen_helper_float_round_2008_w_s(fp0
, cpu_env
, fp0
);
11734 gen_helper_float_round_w_s(fp0
, cpu_env
, fp0
);
11736 gen_store_fpr32(ctx
, fp0
, fd
);
11737 tcg_temp_free_i32(fp0
);
11740 case OPC_TRUNC_W_S
:
11742 TCGv_i32 fp0
= tcg_temp_new_i32();
11744 gen_load_fpr32(ctx
, fp0
, fs
);
11745 if (ctx
->nan2008
) {
11746 gen_helper_float_trunc_2008_w_s(fp0
, cpu_env
, fp0
);
11748 gen_helper_float_trunc_w_s(fp0
, cpu_env
, fp0
);
11750 gen_store_fpr32(ctx
, fp0
, fd
);
11751 tcg_temp_free_i32(fp0
);
11756 TCGv_i32 fp0
= tcg_temp_new_i32();
11758 gen_load_fpr32(ctx
, fp0
, fs
);
11759 if (ctx
->nan2008
) {
11760 gen_helper_float_ceil_2008_w_s(fp0
, cpu_env
, fp0
);
11762 gen_helper_float_ceil_w_s(fp0
, cpu_env
, fp0
);
11764 gen_store_fpr32(ctx
, fp0
, fd
);
11765 tcg_temp_free_i32(fp0
);
11768 case OPC_FLOOR_W_S
:
11770 TCGv_i32 fp0
= tcg_temp_new_i32();
11772 gen_load_fpr32(ctx
, fp0
, fs
);
11773 if (ctx
->nan2008
) {
11774 gen_helper_float_floor_2008_w_s(fp0
, cpu_env
, fp0
);
11776 gen_helper_float_floor_w_s(fp0
, cpu_env
, fp0
);
11778 gen_store_fpr32(ctx
, fp0
, fd
);
11779 tcg_temp_free_i32(fp0
);
11783 check_insn(ctx
, ISA_MIPS_R6
);
11784 gen_sel_s(ctx
, op1
, fd
, ft
, fs
);
11787 check_insn(ctx
, ISA_MIPS_R6
);
11788 gen_sel_s(ctx
, op1
, fd
, ft
, fs
);
11791 check_insn(ctx
, ISA_MIPS_R6
);
11792 gen_sel_s(ctx
, op1
, fd
, ft
, fs
);
11795 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
11796 gen_movcf_s(ctx
, fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
11799 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
11801 TCGLabel
*l1
= gen_new_label();
11805 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
11807 fp0
= tcg_temp_new_i32();
11808 gen_load_fpr32(ctx
, fp0
, fs
);
11809 gen_store_fpr32(ctx
, fp0
, fd
);
11810 tcg_temp_free_i32(fp0
);
11815 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
11817 TCGLabel
*l1
= gen_new_label();
11821 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
11822 fp0
= tcg_temp_new_i32();
11823 gen_load_fpr32(ctx
, fp0
, fs
);
11824 gen_store_fpr32(ctx
, fp0
, fd
);
11825 tcg_temp_free_i32(fp0
);
11832 TCGv_i32 fp0
= tcg_temp_new_i32();
11834 gen_load_fpr32(ctx
, fp0
, fs
);
11835 gen_helper_float_recip_s(fp0
, cpu_env
, fp0
);
11836 gen_store_fpr32(ctx
, fp0
, fd
);
11837 tcg_temp_free_i32(fp0
);
11842 TCGv_i32 fp0
= tcg_temp_new_i32();
11844 gen_load_fpr32(ctx
, fp0
, fs
);
11845 gen_helper_float_rsqrt_s(fp0
, cpu_env
, fp0
);
11846 gen_store_fpr32(ctx
, fp0
, fd
);
11847 tcg_temp_free_i32(fp0
);
11851 check_insn(ctx
, ISA_MIPS_R6
);
11853 TCGv_i32 fp0
= tcg_temp_new_i32();
11854 TCGv_i32 fp1
= tcg_temp_new_i32();
11855 TCGv_i32 fp2
= tcg_temp_new_i32();
11856 gen_load_fpr32(ctx
, fp0
, fs
);
11857 gen_load_fpr32(ctx
, fp1
, ft
);
11858 gen_load_fpr32(ctx
, fp2
, fd
);
11859 gen_helper_float_maddf_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
11860 gen_store_fpr32(ctx
, fp2
, fd
);
11861 tcg_temp_free_i32(fp2
);
11862 tcg_temp_free_i32(fp1
);
11863 tcg_temp_free_i32(fp0
);
11867 check_insn(ctx
, ISA_MIPS_R6
);
11869 TCGv_i32 fp0
= tcg_temp_new_i32();
11870 TCGv_i32 fp1
= tcg_temp_new_i32();
11871 TCGv_i32 fp2
= tcg_temp_new_i32();
11872 gen_load_fpr32(ctx
, fp0
, fs
);
11873 gen_load_fpr32(ctx
, fp1
, ft
);
11874 gen_load_fpr32(ctx
, fp2
, fd
);
11875 gen_helper_float_msubf_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
11876 gen_store_fpr32(ctx
, fp2
, fd
);
11877 tcg_temp_free_i32(fp2
);
11878 tcg_temp_free_i32(fp1
);
11879 tcg_temp_free_i32(fp0
);
11883 check_insn(ctx
, ISA_MIPS_R6
);
11885 TCGv_i32 fp0
= tcg_temp_new_i32();
11886 gen_load_fpr32(ctx
, fp0
, fs
);
11887 gen_helper_float_rint_s(fp0
, cpu_env
, fp0
);
11888 gen_store_fpr32(ctx
, fp0
, fd
);
11889 tcg_temp_free_i32(fp0
);
11893 check_insn(ctx
, ISA_MIPS_R6
);
11895 TCGv_i32 fp0
= tcg_temp_new_i32();
11896 gen_load_fpr32(ctx
, fp0
, fs
);
11897 gen_helper_float_class_s(fp0
, cpu_env
, fp0
);
11898 gen_store_fpr32(ctx
, fp0
, fd
);
11899 tcg_temp_free_i32(fp0
);
11902 case OPC_MIN_S
: /* OPC_RECIP2_S */
11903 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
11905 TCGv_i32 fp0
= tcg_temp_new_i32();
11906 TCGv_i32 fp1
= tcg_temp_new_i32();
11907 TCGv_i32 fp2
= tcg_temp_new_i32();
11908 gen_load_fpr32(ctx
, fp0
, fs
);
11909 gen_load_fpr32(ctx
, fp1
, ft
);
11910 gen_helper_float_min_s(fp2
, cpu_env
, fp0
, fp1
);
11911 gen_store_fpr32(ctx
, fp2
, fd
);
11912 tcg_temp_free_i32(fp2
);
11913 tcg_temp_free_i32(fp1
);
11914 tcg_temp_free_i32(fp0
);
11917 check_cp1_64bitmode(ctx
);
11919 TCGv_i32 fp0
= tcg_temp_new_i32();
11920 TCGv_i32 fp1
= tcg_temp_new_i32();
11922 gen_load_fpr32(ctx
, fp0
, fs
);
11923 gen_load_fpr32(ctx
, fp1
, ft
);
11924 gen_helper_float_recip2_s(fp0
, cpu_env
, fp0
, fp1
);
11925 tcg_temp_free_i32(fp1
);
11926 gen_store_fpr32(ctx
, fp0
, fd
);
11927 tcg_temp_free_i32(fp0
);
11931 case OPC_MINA_S
: /* OPC_RECIP1_S */
11932 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
11934 TCGv_i32 fp0
= tcg_temp_new_i32();
11935 TCGv_i32 fp1
= tcg_temp_new_i32();
11936 TCGv_i32 fp2
= tcg_temp_new_i32();
11937 gen_load_fpr32(ctx
, fp0
, fs
);
11938 gen_load_fpr32(ctx
, fp1
, ft
);
11939 gen_helper_float_mina_s(fp2
, cpu_env
, fp0
, fp1
);
11940 gen_store_fpr32(ctx
, fp2
, fd
);
11941 tcg_temp_free_i32(fp2
);
11942 tcg_temp_free_i32(fp1
);
11943 tcg_temp_free_i32(fp0
);
11946 check_cp1_64bitmode(ctx
);
11948 TCGv_i32 fp0
= tcg_temp_new_i32();
11950 gen_load_fpr32(ctx
, fp0
, fs
);
11951 gen_helper_float_recip1_s(fp0
, cpu_env
, fp0
);
11952 gen_store_fpr32(ctx
, fp0
, fd
);
11953 tcg_temp_free_i32(fp0
);
11957 case OPC_MAX_S
: /* OPC_RSQRT1_S */
11958 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
11960 TCGv_i32 fp0
= tcg_temp_new_i32();
11961 TCGv_i32 fp1
= tcg_temp_new_i32();
11962 gen_load_fpr32(ctx
, fp0
, fs
);
11963 gen_load_fpr32(ctx
, fp1
, ft
);
11964 gen_helper_float_max_s(fp1
, cpu_env
, fp0
, fp1
);
11965 gen_store_fpr32(ctx
, fp1
, fd
);
11966 tcg_temp_free_i32(fp1
);
11967 tcg_temp_free_i32(fp0
);
11970 check_cp1_64bitmode(ctx
);
11972 TCGv_i32 fp0
= tcg_temp_new_i32();
11974 gen_load_fpr32(ctx
, fp0
, fs
);
11975 gen_helper_float_rsqrt1_s(fp0
, cpu_env
, fp0
);
11976 gen_store_fpr32(ctx
, fp0
, fd
);
11977 tcg_temp_free_i32(fp0
);
11981 case OPC_MAXA_S
: /* OPC_RSQRT2_S */
11982 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
11984 TCGv_i32 fp0
= tcg_temp_new_i32();
11985 TCGv_i32 fp1
= tcg_temp_new_i32();
11986 gen_load_fpr32(ctx
, fp0
, fs
);
11987 gen_load_fpr32(ctx
, fp1
, ft
);
11988 gen_helper_float_maxa_s(fp1
, cpu_env
, fp0
, fp1
);
11989 gen_store_fpr32(ctx
, fp1
, fd
);
11990 tcg_temp_free_i32(fp1
);
11991 tcg_temp_free_i32(fp0
);
11994 check_cp1_64bitmode(ctx
);
11996 TCGv_i32 fp0
= tcg_temp_new_i32();
11997 TCGv_i32 fp1
= tcg_temp_new_i32();
11999 gen_load_fpr32(ctx
, fp0
, fs
);
12000 gen_load_fpr32(ctx
, fp1
, ft
);
12001 gen_helper_float_rsqrt2_s(fp0
, cpu_env
, fp0
, fp1
);
12002 tcg_temp_free_i32(fp1
);
12003 gen_store_fpr32(ctx
, fp0
, fd
);
12004 tcg_temp_free_i32(fp0
);
12009 check_cp1_registers(ctx
, fd
);
12011 TCGv_i32 fp32
= tcg_temp_new_i32();
12012 TCGv_i64 fp64
= tcg_temp_new_i64();
12014 gen_load_fpr32(ctx
, fp32
, fs
);
12015 gen_helper_float_cvtd_s(fp64
, cpu_env
, fp32
);
12016 tcg_temp_free_i32(fp32
);
12017 gen_store_fpr64(ctx
, fp64
, fd
);
12018 tcg_temp_free_i64(fp64
);
12023 TCGv_i32 fp0
= tcg_temp_new_i32();
12025 gen_load_fpr32(ctx
, fp0
, fs
);
12026 if (ctx
->nan2008
) {
12027 gen_helper_float_cvt_2008_w_s(fp0
, cpu_env
, fp0
);
12029 gen_helper_float_cvt_w_s(fp0
, cpu_env
, fp0
);
12031 gen_store_fpr32(ctx
, fp0
, fd
);
12032 tcg_temp_free_i32(fp0
);
12036 check_cp1_64bitmode(ctx
);
12038 TCGv_i32 fp32
= tcg_temp_new_i32();
12039 TCGv_i64 fp64
= tcg_temp_new_i64();
12041 gen_load_fpr32(ctx
, fp32
, fs
);
12042 if (ctx
->nan2008
) {
12043 gen_helper_float_cvt_2008_l_s(fp64
, cpu_env
, fp32
);
12045 gen_helper_float_cvt_l_s(fp64
, cpu_env
, fp32
);
12047 tcg_temp_free_i32(fp32
);
12048 gen_store_fpr64(ctx
, fp64
, fd
);
12049 tcg_temp_free_i64(fp64
);
12055 TCGv_i64 fp64
= tcg_temp_new_i64();
12056 TCGv_i32 fp32_0
= tcg_temp_new_i32();
12057 TCGv_i32 fp32_1
= tcg_temp_new_i32();
12059 gen_load_fpr32(ctx
, fp32_0
, fs
);
12060 gen_load_fpr32(ctx
, fp32_1
, ft
);
12061 tcg_gen_concat_i32_i64(fp64
, fp32_1
, fp32_0
);
12062 tcg_temp_free_i32(fp32_1
);
12063 tcg_temp_free_i32(fp32_0
);
12064 gen_store_fpr64(ctx
, fp64
, fd
);
12065 tcg_temp_free_i64(fp64
);
12071 case OPC_CMP_UEQ_S
:
12072 case OPC_CMP_OLT_S
:
12073 case OPC_CMP_ULT_S
:
12074 case OPC_CMP_OLE_S
:
12075 case OPC_CMP_ULE_S
:
12077 case OPC_CMP_NGLE_S
:
12078 case OPC_CMP_SEQ_S
:
12079 case OPC_CMP_NGL_S
:
12081 case OPC_CMP_NGE_S
:
12083 case OPC_CMP_NGT_S
:
12084 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
12085 if (ctx
->opcode
& (1 << 6)) {
12086 gen_cmpabs_s(ctx
, func
- 48, ft
, fs
, cc
);
12088 gen_cmp_s(ctx
, func
- 48, ft
, fs
, cc
);
12092 check_cp1_registers(ctx
, fs
| ft
| fd
);
12094 TCGv_i64 fp0
= tcg_temp_new_i64();
12095 TCGv_i64 fp1
= tcg_temp_new_i64();
12097 gen_load_fpr64(ctx
, fp0
, fs
);
12098 gen_load_fpr64(ctx
, fp1
, ft
);
12099 gen_helper_float_add_d(fp0
, cpu_env
, fp0
, fp1
);
12100 tcg_temp_free_i64(fp1
);
12101 gen_store_fpr64(ctx
, fp0
, fd
);
12102 tcg_temp_free_i64(fp0
);
12106 check_cp1_registers(ctx
, fs
| ft
| fd
);
12108 TCGv_i64 fp0
= tcg_temp_new_i64();
12109 TCGv_i64 fp1
= tcg_temp_new_i64();
12111 gen_load_fpr64(ctx
, fp0
, fs
);
12112 gen_load_fpr64(ctx
, fp1
, ft
);
12113 gen_helper_float_sub_d(fp0
, cpu_env
, fp0
, fp1
);
12114 tcg_temp_free_i64(fp1
);
12115 gen_store_fpr64(ctx
, fp0
, fd
);
12116 tcg_temp_free_i64(fp0
);
12120 check_cp1_registers(ctx
, fs
| ft
| fd
);
12122 TCGv_i64 fp0
= tcg_temp_new_i64();
12123 TCGv_i64 fp1
= tcg_temp_new_i64();
12125 gen_load_fpr64(ctx
, fp0
, fs
);
12126 gen_load_fpr64(ctx
, fp1
, ft
);
12127 gen_helper_float_mul_d(fp0
, cpu_env
, fp0
, fp1
);
12128 tcg_temp_free_i64(fp1
);
12129 gen_store_fpr64(ctx
, fp0
, fd
);
12130 tcg_temp_free_i64(fp0
);
12134 check_cp1_registers(ctx
, fs
| ft
| fd
);
12136 TCGv_i64 fp0
= tcg_temp_new_i64();
12137 TCGv_i64 fp1
= tcg_temp_new_i64();
12139 gen_load_fpr64(ctx
, fp0
, fs
);
12140 gen_load_fpr64(ctx
, fp1
, ft
);
12141 gen_helper_float_div_d(fp0
, cpu_env
, fp0
, fp1
);
12142 tcg_temp_free_i64(fp1
);
12143 gen_store_fpr64(ctx
, fp0
, fd
);
12144 tcg_temp_free_i64(fp0
);
12148 check_cp1_registers(ctx
, fs
| fd
);
12150 TCGv_i64 fp0
= tcg_temp_new_i64();
12152 gen_load_fpr64(ctx
, fp0
, fs
);
12153 gen_helper_float_sqrt_d(fp0
, cpu_env
, fp0
);
12154 gen_store_fpr64(ctx
, fp0
, fd
);
12155 tcg_temp_free_i64(fp0
);
12159 check_cp1_registers(ctx
, fs
| fd
);
12161 TCGv_i64 fp0
= tcg_temp_new_i64();
12163 gen_load_fpr64(ctx
, fp0
, fs
);
12164 if (ctx
->abs2008
) {
12165 tcg_gen_andi_i64(fp0
, fp0
, 0x7fffffffffffffffULL
);
12167 gen_helper_float_abs_d(fp0
, fp0
);
12169 gen_store_fpr64(ctx
, fp0
, fd
);
12170 tcg_temp_free_i64(fp0
);
12174 check_cp1_registers(ctx
, fs
| fd
);
12176 TCGv_i64 fp0
= tcg_temp_new_i64();
12178 gen_load_fpr64(ctx
, fp0
, fs
);
12179 gen_store_fpr64(ctx
, fp0
, fd
);
12180 tcg_temp_free_i64(fp0
);
12184 check_cp1_registers(ctx
, fs
| fd
);
12186 TCGv_i64 fp0
= tcg_temp_new_i64();
12188 gen_load_fpr64(ctx
, fp0
, fs
);
12189 if (ctx
->abs2008
) {
12190 tcg_gen_xori_i64(fp0
, fp0
, 1ULL << 63);
12192 gen_helper_float_chs_d(fp0
, fp0
);
12194 gen_store_fpr64(ctx
, fp0
, fd
);
12195 tcg_temp_free_i64(fp0
);
12198 case OPC_ROUND_L_D
:
12199 check_cp1_64bitmode(ctx
);
12201 TCGv_i64 fp0
= tcg_temp_new_i64();
12203 gen_load_fpr64(ctx
, fp0
, fs
);
12204 if (ctx
->nan2008
) {
12205 gen_helper_float_round_2008_l_d(fp0
, cpu_env
, fp0
);
12207 gen_helper_float_round_l_d(fp0
, cpu_env
, fp0
);
12209 gen_store_fpr64(ctx
, fp0
, fd
);
12210 tcg_temp_free_i64(fp0
);
12213 case OPC_TRUNC_L_D
:
12214 check_cp1_64bitmode(ctx
);
12216 TCGv_i64 fp0
= tcg_temp_new_i64();
12218 gen_load_fpr64(ctx
, fp0
, fs
);
12219 if (ctx
->nan2008
) {
12220 gen_helper_float_trunc_2008_l_d(fp0
, cpu_env
, fp0
);
12222 gen_helper_float_trunc_l_d(fp0
, cpu_env
, fp0
);
12224 gen_store_fpr64(ctx
, fp0
, fd
);
12225 tcg_temp_free_i64(fp0
);
12229 check_cp1_64bitmode(ctx
);
12231 TCGv_i64 fp0
= tcg_temp_new_i64();
12233 gen_load_fpr64(ctx
, fp0
, fs
);
12234 if (ctx
->nan2008
) {
12235 gen_helper_float_ceil_2008_l_d(fp0
, cpu_env
, fp0
);
12237 gen_helper_float_ceil_l_d(fp0
, cpu_env
, fp0
);
12239 gen_store_fpr64(ctx
, fp0
, fd
);
12240 tcg_temp_free_i64(fp0
);
12243 case OPC_FLOOR_L_D
:
12244 check_cp1_64bitmode(ctx
);
12246 TCGv_i64 fp0
= tcg_temp_new_i64();
12248 gen_load_fpr64(ctx
, fp0
, fs
);
12249 if (ctx
->nan2008
) {
12250 gen_helper_float_floor_2008_l_d(fp0
, cpu_env
, fp0
);
12252 gen_helper_float_floor_l_d(fp0
, cpu_env
, fp0
);
12254 gen_store_fpr64(ctx
, fp0
, fd
);
12255 tcg_temp_free_i64(fp0
);
12258 case OPC_ROUND_W_D
:
12259 check_cp1_registers(ctx
, fs
);
12261 TCGv_i32 fp32
= tcg_temp_new_i32();
12262 TCGv_i64 fp64
= tcg_temp_new_i64();
12264 gen_load_fpr64(ctx
, fp64
, fs
);
12265 if (ctx
->nan2008
) {
12266 gen_helper_float_round_2008_w_d(fp32
, cpu_env
, fp64
);
12268 gen_helper_float_round_w_d(fp32
, cpu_env
, fp64
);
12270 tcg_temp_free_i64(fp64
);
12271 gen_store_fpr32(ctx
, fp32
, fd
);
12272 tcg_temp_free_i32(fp32
);
12275 case OPC_TRUNC_W_D
:
12276 check_cp1_registers(ctx
, fs
);
12278 TCGv_i32 fp32
= tcg_temp_new_i32();
12279 TCGv_i64 fp64
= tcg_temp_new_i64();
12281 gen_load_fpr64(ctx
, fp64
, fs
);
12282 if (ctx
->nan2008
) {
12283 gen_helper_float_trunc_2008_w_d(fp32
, cpu_env
, fp64
);
12285 gen_helper_float_trunc_w_d(fp32
, cpu_env
, fp64
);
12287 tcg_temp_free_i64(fp64
);
12288 gen_store_fpr32(ctx
, fp32
, fd
);
12289 tcg_temp_free_i32(fp32
);
12293 check_cp1_registers(ctx
, fs
);
12295 TCGv_i32 fp32
= tcg_temp_new_i32();
12296 TCGv_i64 fp64
= tcg_temp_new_i64();
12298 gen_load_fpr64(ctx
, fp64
, fs
);
12299 if (ctx
->nan2008
) {
12300 gen_helper_float_ceil_2008_w_d(fp32
, cpu_env
, fp64
);
12302 gen_helper_float_ceil_w_d(fp32
, cpu_env
, fp64
);
12304 tcg_temp_free_i64(fp64
);
12305 gen_store_fpr32(ctx
, fp32
, fd
);
12306 tcg_temp_free_i32(fp32
);
12309 case OPC_FLOOR_W_D
:
12310 check_cp1_registers(ctx
, fs
);
12312 TCGv_i32 fp32
= tcg_temp_new_i32();
12313 TCGv_i64 fp64
= tcg_temp_new_i64();
12315 gen_load_fpr64(ctx
, fp64
, fs
);
12316 if (ctx
->nan2008
) {
12317 gen_helper_float_floor_2008_w_d(fp32
, cpu_env
, fp64
);
12319 gen_helper_float_floor_w_d(fp32
, cpu_env
, fp64
);
12321 tcg_temp_free_i64(fp64
);
12322 gen_store_fpr32(ctx
, fp32
, fd
);
12323 tcg_temp_free_i32(fp32
);
12327 check_insn(ctx
, ISA_MIPS_R6
);
12328 gen_sel_d(ctx
, op1
, fd
, ft
, fs
);
12331 check_insn(ctx
, ISA_MIPS_R6
);
12332 gen_sel_d(ctx
, op1
, fd
, ft
, fs
);
12335 check_insn(ctx
, ISA_MIPS_R6
);
12336 gen_sel_d(ctx
, op1
, fd
, ft
, fs
);
12339 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
12340 gen_movcf_d(ctx
, fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
12343 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
12345 TCGLabel
*l1
= gen_new_label();
12349 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
12351 fp0
= tcg_temp_new_i64();
12352 gen_load_fpr64(ctx
, fp0
, fs
);
12353 gen_store_fpr64(ctx
, fp0
, fd
);
12354 tcg_temp_free_i64(fp0
);
12359 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
12361 TCGLabel
*l1
= gen_new_label();
12365 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
12366 fp0
= tcg_temp_new_i64();
12367 gen_load_fpr64(ctx
, fp0
, fs
);
12368 gen_store_fpr64(ctx
, fp0
, fd
);
12369 tcg_temp_free_i64(fp0
);
12375 check_cp1_registers(ctx
, fs
| fd
);
12377 TCGv_i64 fp0
= tcg_temp_new_i64();
12379 gen_load_fpr64(ctx
, fp0
, fs
);
12380 gen_helper_float_recip_d(fp0
, cpu_env
, fp0
);
12381 gen_store_fpr64(ctx
, fp0
, fd
);
12382 tcg_temp_free_i64(fp0
);
12386 check_cp1_registers(ctx
, fs
| fd
);
12388 TCGv_i64 fp0
= tcg_temp_new_i64();
12390 gen_load_fpr64(ctx
, fp0
, fs
);
12391 gen_helper_float_rsqrt_d(fp0
, cpu_env
, fp0
);
12392 gen_store_fpr64(ctx
, fp0
, fd
);
12393 tcg_temp_free_i64(fp0
);
12397 check_insn(ctx
, ISA_MIPS_R6
);
12399 TCGv_i64 fp0
= tcg_temp_new_i64();
12400 TCGv_i64 fp1
= tcg_temp_new_i64();
12401 TCGv_i64 fp2
= tcg_temp_new_i64();
12402 gen_load_fpr64(ctx
, fp0
, fs
);
12403 gen_load_fpr64(ctx
, fp1
, ft
);
12404 gen_load_fpr64(ctx
, fp2
, fd
);
12405 gen_helper_float_maddf_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12406 gen_store_fpr64(ctx
, fp2
, fd
);
12407 tcg_temp_free_i64(fp2
);
12408 tcg_temp_free_i64(fp1
);
12409 tcg_temp_free_i64(fp0
);
12413 check_insn(ctx
, ISA_MIPS_R6
);
12415 TCGv_i64 fp0
= tcg_temp_new_i64();
12416 TCGv_i64 fp1
= tcg_temp_new_i64();
12417 TCGv_i64 fp2
= tcg_temp_new_i64();
12418 gen_load_fpr64(ctx
, fp0
, fs
);
12419 gen_load_fpr64(ctx
, fp1
, ft
);
12420 gen_load_fpr64(ctx
, fp2
, fd
);
12421 gen_helper_float_msubf_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12422 gen_store_fpr64(ctx
, fp2
, fd
);
12423 tcg_temp_free_i64(fp2
);
12424 tcg_temp_free_i64(fp1
);
12425 tcg_temp_free_i64(fp0
);
12429 check_insn(ctx
, ISA_MIPS_R6
);
12431 TCGv_i64 fp0
= tcg_temp_new_i64();
12432 gen_load_fpr64(ctx
, fp0
, fs
);
12433 gen_helper_float_rint_d(fp0
, cpu_env
, fp0
);
12434 gen_store_fpr64(ctx
, fp0
, fd
);
12435 tcg_temp_free_i64(fp0
);
12439 check_insn(ctx
, ISA_MIPS_R6
);
12441 TCGv_i64 fp0
= tcg_temp_new_i64();
12442 gen_load_fpr64(ctx
, fp0
, fs
);
12443 gen_helper_float_class_d(fp0
, cpu_env
, fp0
);
12444 gen_store_fpr64(ctx
, fp0
, fd
);
12445 tcg_temp_free_i64(fp0
);
12448 case OPC_MIN_D
: /* OPC_RECIP2_D */
12449 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
12451 TCGv_i64 fp0
= tcg_temp_new_i64();
12452 TCGv_i64 fp1
= tcg_temp_new_i64();
12453 gen_load_fpr64(ctx
, fp0
, fs
);
12454 gen_load_fpr64(ctx
, fp1
, ft
);
12455 gen_helper_float_min_d(fp1
, cpu_env
, fp0
, fp1
);
12456 gen_store_fpr64(ctx
, fp1
, fd
);
12457 tcg_temp_free_i64(fp1
);
12458 tcg_temp_free_i64(fp0
);
12461 check_cp1_64bitmode(ctx
);
12463 TCGv_i64 fp0
= tcg_temp_new_i64();
12464 TCGv_i64 fp1
= tcg_temp_new_i64();
12466 gen_load_fpr64(ctx
, fp0
, fs
);
12467 gen_load_fpr64(ctx
, fp1
, ft
);
12468 gen_helper_float_recip2_d(fp0
, cpu_env
, fp0
, fp1
);
12469 tcg_temp_free_i64(fp1
);
12470 gen_store_fpr64(ctx
, fp0
, fd
);
12471 tcg_temp_free_i64(fp0
);
12475 case OPC_MINA_D
: /* OPC_RECIP1_D */
12476 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
12478 TCGv_i64 fp0
= tcg_temp_new_i64();
12479 TCGv_i64 fp1
= tcg_temp_new_i64();
12480 gen_load_fpr64(ctx
, fp0
, fs
);
12481 gen_load_fpr64(ctx
, fp1
, ft
);
12482 gen_helper_float_mina_d(fp1
, cpu_env
, fp0
, fp1
);
12483 gen_store_fpr64(ctx
, fp1
, fd
);
12484 tcg_temp_free_i64(fp1
);
12485 tcg_temp_free_i64(fp0
);
12488 check_cp1_64bitmode(ctx
);
12490 TCGv_i64 fp0
= tcg_temp_new_i64();
12492 gen_load_fpr64(ctx
, fp0
, fs
);
12493 gen_helper_float_recip1_d(fp0
, cpu_env
, fp0
);
12494 gen_store_fpr64(ctx
, fp0
, fd
);
12495 tcg_temp_free_i64(fp0
);
12499 case OPC_MAX_D
: /* OPC_RSQRT1_D */
12500 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
12502 TCGv_i64 fp0
= tcg_temp_new_i64();
12503 TCGv_i64 fp1
= tcg_temp_new_i64();
12504 gen_load_fpr64(ctx
, fp0
, fs
);
12505 gen_load_fpr64(ctx
, fp1
, ft
);
12506 gen_helper_float_max_d(fp1
, cpu_env
, fp0
, fp1
);
12507 gen_store_fpr64(ctx
, fp1
, fd
);
12508 tcg_temp_free_i64(fp1
);
12509 tcg_temp_free_i64(fp0
);
12512 check_cp1_64bitmode(ctx
);
12514 TCGv_i64 fp0
= tcg_temp_new_i64();
12516 gen_load_fpr64(ctx
, fp0
, fs
);
12517 gen_helper_float_rsqrt1_d(fp0
, cpu_env
, fp0
);
12518 gen_store_fpr64(ctx
, fp0
, fd
);
12519 tcg_temp_free_i64(fp0
);
12523 case OPC_MAXA_D
: /* OPC_RSQRT2_D */
12524 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
12526 TCGv_i64 fp0
= tcg_temp_new_i64();
12527 TCGv_i64 fp1
= tcg_temp_new_i64();
12528 gen_load_fpr64(ctx
, fp0
, fs
);
12529 gen_load_fpr64(ctx
, fp1
, ft
);
12530 gen_helper_float_maxa_d(fp1
, cpu_env
, fp0
, fp1
);
12531 gen_store_fpr64(ctx
, fp1
, fd
);
12532 tcg_temp_free_i64(fp1
);
12533 tcg_temp_free_i64(fp0
);
12536 check_cp1_64bitmode(ctx
);
12538 TCGv_i64 fp0
= tcg_temp_new_i64();
12539 TCGv_i64 fp1
= tcg_temp_new_i64();
12541 gen_load_fpr64(ctx
, fp0
, fs
);
12542 gen_load_fpr64(ctx
, fp1
, ft
);
12543 gen_helper_float_rsqrt2_d(fp0
, cpu_env
, fp0
, fp1
);
12544 tcg_temp_free_i64(fp1
);
12545 gen_store_fpr64(ctx
, fp0
, fd
);
12546 tcg_temp_free_i64(fp0
);
12553 case OPC_CMP_UEQ_D
:
12554 case OPC_CMP_OLT_D
:
12555 case OPC_CMP_ULT_D
:
12556 case OPC_CMP_OLE_D
:
12557 case OPC_CMP_ULE_D
:
12559 case OPC_CMP_NGLE_D
:
12560 case OPC_CMP_SEQ_D
:
12561 case OPC_CMP_NGL_D
:
12563 case OPC_CMP_NGE_D
:
12565 case OPC_CMP_NGT_D
:
12566 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
12567 if (ctx
->opcode
& (1 << 6)) {
12568 gen_cmpabs_d(ctx
, func
- 48, ft
, fs
, cc
);
12570 gen_cmp_d(ctx
, func
- 48, ft
, fs
, cc
);
12574 check_cp1_registers(ctx
, fs
);
12576 TCGv_i32 fp32
= tcg_temp_new_i32();
12577 TCGv_i64 fp64
= tcg_temp_new_i64();
12579 gen_load_fpr64(ctx
, fp64
, fs
);
12580 gen_helper_float_cvts_d(fp32
, cpu_env
, fp64
);
12581 tcg_temp_free_i64(fp64
);
12582 gen_store_fpr32(ctx
, fp32
, fd
);
12583 tcg_temp_free_i32(fp32
);
12587 check_cp1_registers(ctx
, fs
);
12589 TCGv_i32 fp32
= tcg_temp_new_i32();
12590 TCGv_i64 fp64
= tcg_temp_new_i64();
12592 gen_load_fpr64(ctx
, fp64
, fs
);
12593 if (ctx
->nan2008
) {
12594 gen_helper_float_cvt_2008_w_d(fp32
, cpu_env
, fp64
);
12596 gen_helper_float_cvt_w_d(fp32
, cpu_env
, fp64
);
12598 tcg_temp_free_i64(fp64
);
12599 gen_store_fpr32(ctx
, fp32
, fd
);
12600 tcg_temp_free_i32(fp32
);
12604 check_cp1_64bitmode(ctx
);
12606 TCGv_i64 fp0
= tcg_temp_new_i64();
12608 gen_load_fpr64(ctx
, fp0
, fs
);
12609 if (ctx
->nan2008
) {
12610 gen_helper_float_cvt_2008_l_d(fp0
, cpu_env
, fp0
);
12612 gen_helper_float_cvt_l_d(fp0
, cpu_env
, fp0
);
12614 gen_store_fpr64(ctx
, fp0
, fd
);
12615 tcg_temp_free_i64(fp0
);
12620 TCGv_i32 fp0
= tcg_temp_new_i32();
12622 gen_load_fpr32(ctx
, fp0
, fs
);
12623 gen_helper_float_cvts_w(fp0
, cpu_env
, fp0
);
12624 gen_store_fpr32(ctx
, fp0
, fd
);
12625 tcg_temp_free_i32(fp0
);
12629 check_cp1_registers(ctx
, fd
);
12631 TCGv_i32 fp32
= tcg_temp_new_i32();
12632 TCGv_i64 fp64
= tcg_temp_new_i64();
12634 gen_load_fpr32(ctx
, fp32
, fs
);
12635 gen_helper_float_cvtd_w(fp64
, cpu_env
, fp32
);
12636 tcg_temp_free_i32(fp32
);
12637 gen_store_fpr64(ctx
, fp64
, fd
);
12638 tcg_temp_free_i64(fp64
);
12642 check_cp1_64bitmode(ctx
);
12644 TCGv_i32 fp32
= tcg_temp_new_i32();
12645 TCGv_i64 fp64
= tcg_temp_new_i64();
12647 gen_load_fpr64(ctx
, fp64
, fs
);
12648 gen_helper_float_cvts_l(fp32
, cpu_env
, fp64
);
12649 tcg_temp_free_i64(fp64
);
12650 gen_store_fpr32(ctx
, fp32
, fd
);
12651 tcg_temp_free_i32(fp32
);
12655 check_cp1_64bitmode(ctx
);
12657 TCGv_i64 fp0
= tcg_temp_new_i64();
12659 gen_load_fpr64(ctx
, fp0
, fs
);
12660 gen_helper_float_cvtd_l(fp0
, cpu_env
, fp0
);
12661 gen_store_fpr64(ctx
, fp0
, fd
);
12662 tcg_temp_free_i64(fp0
);
12665 case OPC_CVT_PS_PW
:
12668 TCGv_i64 fp0
= tcg_temp_new_i64();
12670 gen_load_fpr64(ctx
, fp0
, fs
);
12671 gen_helper_float_cvtps_pw(fp0
, cpu_env
, fp0
);
12672 gen_store_fpr64(ctx
, fp0
, fd
);
12673 tcg_temp_free_i64(fp0
);
12679 TCGv_i64 fp0
= tcg_temp_new_i64();
12680 TCGv_i64 fp1
= tcg_temp_new_i64();
12682 gen_load_fpr64(ctx
, fp0
, fs
);
12683 gen_load_fpr64(ctx
, fp1
, ft
);
12684 gen_helper_float_add_ps(fp0
, cpu_env
, fp0
, fp1
);
12685 tcg_temp_free_i64(fp1
);
12686 gen_store_fpr64(ctx
, fp0
, fd
);
12687 tcg_temp_free_i64(fp0
);
12693 TCGv_i64 fp0
= tcg_temp_new_i64();
12694 TCGv_i64 fp1
= tcg_temp_new_i64();
12696 gen_load_fpr64(ctx
, fp0
, fs
);
12697 gen_load_fpr64(ctx
, fp1
, ft
);
12698 gen_helper_float_sub_ps(fp0
, cpu_env
, fp0
, fp1
);
12699 tcg_temp_free_i64(fp1
);
12700 gen_store_fpr64(ctx
, fp0
, fd
);
12701 tcg_temp_free_i64(fp0
);
12707 TCGv_i64 fp0
= tcg_temp_new_i64();
12708 TCGv_i64 fp1
= tcg_temp_new_i64();
12710 gen_load_fpr64(ctx
, fp0
, fs
);
12711 gen_load_fpr64(ctx
, fp1
, ft
);
12712 gen_helper_float_mul_ps(fp0
, cpu_env
, fp0
, fp1
);
12713 tcg_temp_free_i64(fp1
);
12714 gen_store_fpr64(ctx
, fp0
, fd
);
12715 tcg_temp_free_i64(fp0
);
12721 TCGv_i64 fp0
= tcg_temp_new_i64();
12723 gen_load_fpr64(ctx
, fp0
, fs
);
12724 gen_helper_float_abs_ps(fp0
, fp0
);
12725 gen_store_fpr64(ctx
, fp0
, fd
);
12726 tcg_temp_free_i64(fp0
);
12732 TCGv_i64 fp0
= tcg_temp_new_i64();
12734 gen_load_fpr64(ctx
, fp0
, fs
);
12735 gen_store_fpr64(ctx
, fp0
, fd
);
12736 tcg_temp_free_i64(fp0
);
12742 TCGv_i64 fp0
= tcg_temp_new_i64();
12744 gen_load_fpr64(ctx
, fp0
, fs
);
12745 gen_helper_float_chs_ps(fp0
, fp0
);
12746 gen_store_fpr64(ctx
, fp0
, fd
);
12747 tcg_temp_free_i64(fp0
);
12752 gen_movcf_ps(ctx
, fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
12757 TCGLabel
*l1
= gen_new_label();
12761 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
12763 fp0
= tcg_temp_new_i64();
12764 gen_load_fpr64(ctx
, fp0
, fs
);
12765 gen_store_fpr64(ctx
, fp0
, fd
);
12766 tcg_temp_free_i64(fp0
);
12773 TCGLabel
*l1
= gen_new_label();
12777 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
12778 fp0
= tcg_temp_new_i64();
12779 gen_load_fpr64(ctx
, fp0
, fs
);
12780 gen_store_fpr64(ctx
, fp0
, fd
);
12781 tcg_temp_free_i64(fp0
);
12789 TCGv_i64 fp0
= tcg_temp_new_i64();
12790 TCGv_i64 fp1
= tcg_temp_new_i64();
12792 gen_load_fpr64(ctx
, fp0
, ft
);
12793 gen_load_fpr64(ctx
, fp1
, fs
);
12794 gen_helper_float_addr_ps(fp0
, cpu_env
, fp0
, fp1
);
12795 tcg_temp_free_i64(fp1
);
12796 gen_store_fpr64(ctx
, fp0
, fd
);
12797 tcg_temp_free_i64(fp0
);
12803 TCGv_i64 fp0
= tcg_temp_new_i64();
12804 TCGv_i64 fp1
= tcg_temp_new_i64();
12806 gen_load_fpr64(ctx
, fp0
, ft
);
12807 gen_load_fpr64(ctx
, fp1
, fs
);
12808 gen_helper_float_mulr_ps(fp0
, cpu_env
, fp0
, fp1
);
12809 tcg_temp_free_i64(fp1
);
12810 gen_store_fpr64(ctx
, fp0
, fd
);
12811 tcg_temp_free_i64(fp0
);
12814 case OPC_RECIP2_PS
:
12817 TCGv_i64 fp0
= tcg_temp_new_i64();
12818 TCGv_i64 fp1
= tcg_temp_new_i64();
12820 gen_load_fpr64(ctx
, fp0
, fs
);
12821 gen_load_fpr64(ctx
, fp1
, ft
);
12822 gen_helper_float_recip2_ps(fp0
, cpu_env
, fp0
, fp1
);
12823 tcg_temp_free_i64(fp1
);
12824 gen_store_fpr64(ctx
, fp0
, fd
);
12825 tcg_temp_free_i64(fp0
);
12828 case OPC_RECIP1_PS
:
12831 TCGv_i64 fp0
= tcg_temp_new_i64();
12833 gen_load_fpr64(ctx
, fp0
, fs
);
12834 gen_helper_float_recip1_ps(fp0
, cpu_env
, fp0
);
12835 gen_store_fpr64(ctx
, fp0
, fd
);
12836 tcg_temp_free_i64(fp0
);
12839 case OPC_RSQRT1_PS
:
12842 TCGv_i64 fp0
= tcg_temp_new_i64();
12844 gen_load_fpr64(ctx
, fp0
, fs
);
12845 gen_helper_float_rsqrt1_ps(fp0
, cpu_env
, fp0
);
12846 gen_store_fpr64(ctx
, fp0
, fd
);
12847 tcg_temp_free_i64(fp0
);
12850 case OPC_RSQRT2_PS
:
12853 TCGv_i64 fp0
= tcg_temp_new_i64();
12854 TCGv_i64 fp1
= tcg_temp_new_i64();
12856 gen_load_fpr64(ctx
, fp0
, fs
);
12857 gen_load_fpr64(ctx
, fp1
, ft
);
12858 gen_helper_float_rsqrt2_ps(fp0
, cpu_env
, fp0
, fp1
);
12859 tcg_temp_free_i64(fp1
);
12860 gen_store_fpr64(ctx
, fp0
, fd
);
12861 tcg_temp_free_i64(fp0
);
12865 check_cp1_64bitmode(ctx
);
12867 TCGv_i32 fp0
= tcg_temp_new_i32();
12869 gen_load_fpr32h(ctx
, fp0
, fs
);
12870 gen_helper_float_cvts_pu(fp0
, cpu_env
, fp0
);
12871 gen_store_fpr32(ctx
, fp0
, fd
);
12872 tcg_temp_free_i32(fp0
);
12875 case OPC_CVT_PW_PS
:
12878 TCGv_i64 fp0
= tcg_temp_new_i64();
12880 gen_load_fpr64(ctx
, fp0
, fs
);
12881 gen_helper_float_cvtpw_ps(fp0
, cpu_env
, fp0
);
12882 gen_store_fpr64(ctx
, fp0
, fd
);
12883 tcg_temp_free_i64(fp0
);
12887 check_cp1_64bitmode(ctx
);
12889 TCGv_i32 fp0
= tcg_temp_new_i32();
12891 gen_load_fpr32(ctx
, fp0
, fs
);
12892 gen_helper_float_cvts_pl(fp0
, cpu_env
, fp0
);
12893 gen_store_fpr32(ctx
, fp0
, fd
);
12894 tcg_temp_free_i32(fp0
);
12900 TCGv_i32 fp0
= tcg_temp_new_i32();
12901 TCGv_i32 fp1
= tcg_temp_new_i32();
12903 gen_load_fpr32(ctx
, fp0
, fs
);
12904 gen_load_fpr32(ctx
, fp1
, ft
);
12905 gen_store_fpr32h(ctx
, fp0
, fd
);
12906 gen_store_fpr32(ctx
, fp1
, fd
);
12907 tcg_temp_free_i32(fp0
);
12908 tcg_temp_free_i32(fp1
);
12914 TCGv_i32 fp0
= tcg_temp_new_i32();
12915 TCGv_i32 fp1
= tcg_temp_new_i32();
12917 gen_load_fpr32(ctx
, fp0
, fs
);
12918 gen_load_fpr32h(ctx
, fp1
, ft
);
12919 gen_store_fpr32(ctx
, fp1
, fd
);
12920 gen_store_fpr32h(ctx
, fp0
, fd
);
12921 tcg_temp_free_i32(fp0
);
12922 tcg_temp_free_i32(fp1
);
12928 TCGv_i32 fp0
= tcg_temp_new_i32();
12929 TCGv_i32 fp1
= tcg_temp_new_i32();
12931 gen_load_fpr32h(ctx
, fp0
, fs
);
12932 gen_load_fpr32(ctx
, fp1
, ft
);
12933 gen_store_fpr32(ctx
, fp1
, fd
);
12934 gen_store_fpr32h(ctx
, fp0
, fd
);
12935 tcg_temp_free_i32(fp0
);
12936 tcg_temp_free_i32(fp1
);
12942 TCGv_i32 fp0
= tcg_temp_new_i32();
12943 TCGv_i32 fp1
= tcg_temp_new_i32();
12945 gen_load_fpr32h(ctx
, fp0
, fs
);
12946 gen_load_fpr32h(ctx
, fp1
, ft
);
12947 gen_store_fpr32(ctx
, fp1
, fd
);
12948 gen_store_fpr32h(ctx
, fp0
, fd
);
12949 tcg_temp_free_i32(fp0
);
12950 tcg_temp_free_i32(fp1
);
12954 case OPC_CMP_UN_PS
:
12955 case OPC_CMP_EQ_PS
:
12956 case OPC_CMP_UEQ_PS
:
12957 case OPC_CMP_OLT_PS
:
12958 case OPC_CMP_ULT_PS
:
12959 case OPC_CMP_OLE_PS
:
12960 case OPC_CMP_ULE_PS
:
12961 case OPC_CMP_SF_PS
:
12962 case OPC_CMP_NGLE_PS
:
12963 case OPC_CMP_SEQ_PS
:
12964 case OPC_CMP_NGL_PS
:
12965 case OPC_CMP_LT_PS
:
12966 case OPC_CMP_NGE_PS
:
12967 case OPC_CMP_LE_PS
:
12968 case OPC_CMP_NGT_PS
:
12969 if (ctx
->opcode
& (1 << 6)) {
12970 gen_cmpabs_ps(ctx
, func
- 48, ft
, fs
, cc
);
12972 gen_cmp_ps(ctx
, func
- 48, ft
, fs
, cc
);
12976 MIPS_INVAL("farith");
12977 gen_reserved_instruction(ctx
);
12982 /* Coprocessor 3 (FPU) */
12983 static void gen_flt3_ldst(DisasContext
*ctx
, uint32_t opc
,
12984 int fd
, int fs
, int base
, int index
)
12986 TCGv t0
= tcg_temp_new();
12989 gen_load_gpr(t0
, index
);
12990 } else if (index
== 0) {
12991 gen_load_gpr(t0
, base
);
12993 gen_op_addr_add(ctx
, t0
, cpu_gpr
[base
], cpu_gpr
[index
]);
12996 * Don't do NOP if destination is zero: we must perform the actual
13003 TCGv_i32 fp0
= tcg_temp_new_i32();
13005 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESL
);
13006 tcg_gen_trunc_tl_i32(fp0
, t0
);
13007 gen_store_fpr32(ctx
, fp0
, fd
);
13008 tcg_temp_free_i32(fp0
);
13013 check_cp1_registers(ctx
, fd
);
13015 TCGv_i64 fp0
= tcg_temp_new_i64();
13016 tcg_gen_qemu_ld_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
13017 gen_store_fpr64(ctx
, fp0
, fd
);
13018 tcg_temp_free_i64(fp0
);
13022 check_cp1_64bitmode(ctx
);
13023 tcg_gen_andi_tl(t0
, t0
, ~0x7);
13025 TCGv_i64 fp0
= tcg_temp_new_i64();
13027 tcg_gen_qemu_ld_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
13028 gen_store_fpr64(ctx
, fp0
, fd
);
13029 tcg_temp_free_i64(fp0
);
13035 TCGv_i32 fp0
= tcg_temp_new_i32();
13036 gen_load_fpr32(ctx
, fp0
, fs
);
13037 tcg_gen_qemu_st_i32(fp0
, t0
, ctx
->mem_idx
, MO_TEUL
);
13038 tcg_temp_free_i32(fp0
);
13043 check_cp1_registers(ctx
, fs
);
13045 TCGv_i64 fp0
= tcg_temp_new_i64();
13046 gen_load_fpr64(ctx
, fp0
, fs
);
13047 tcg_gen_qemu_st_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
13048 tcg_temp_free_i64(fp0
);
13052 check_cp1_64bitmode(ctx
);
13053 tcg_gen_andi_tl(t0
, t0
, ~0x7);
13055 TCGv_i64 fp0
= tcg_temp_new_i64();
13056 gen_load_fpr64(ctx
, fp0
, fs
);
13057 tcg_gen_qemu_st_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
13058 tcg_temp_free_i64(fp0
);
13065 static void gen_flt3_arith(DisasContext
*ctx
, uint32_t opc
,
13066 int fd
, int fr
, int fs
, int ft
)
13072 TCGv t0
= tcg_temp_local_new();
13073 TCGv_i32 fp
= tcg_temp_new_i32();
13074 TCGv_i32 fph
= tcg_temp_new_i32();
13075 TCGLabel
*l1
= gen_new_label();
13076 TCGLabel
*l2
= gen_new_label();
13078 gen_load_gpr(t0
, fr
);
13079 tcg_gen_andi_tl(t0
, t0
, 0x7);
13081 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, 0, l1
);
13082 gen_load_fpr32(ctx
, fp
, fs
);
13083 gen_load_fpr32h(ctx
, fph
, fs
);
13084 gen_store_fpr32(ctx
, fp
, fd
);
13085 gen_store_fpr32h(ctx
, fph
, fd
);
13088 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, 4, l2
);
13090 #ifdef TARGET_WORDS_BIGENDIAN
13091 gen_load_fpr32(ctx
, fp
, fs
);
13092 gen_load_fpr32h(ctx
, fph
, ft
);
13093 gen_store_fpr32h(ctx
, fp
, fd
);
13094 gen_store_fpr32(ctx
, fph
, fd
);
13096 gen_load_fpr32h(ctx
, fph
, fs
);
13097 gen_load_fpr32(ctx
, fp
, ft
);
13098 gen_store_fpr32(ctx
, fph
, fd
);
13099 gen_store_fpr32h(ctx
, fp
, fd
);
13102 tcg_temp_free_i32(fp
);
13103 tcg_temp_free_i32(fph
);
13109 TCGv_i32 fp0
= tcg_temp_new_i32();
13110 TCGv_i32 fp1
= tcg_temp_new_i32();
13111 TCGv_i32 fp2
= tcg_temp_new_i32();
13113 gen_load_fpr32(ctx
, fp0
, fs
);
13114 gen_load_fpr32(ctx
, fp1
, ft
);
13115 gen_load_fpr32(ctx
, fp2
, fr
);
13116 gen_helper_float_madd_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
13117 tcg_temp_free_i32(fp0
);
13118 tcg_temp_free_i32(fp1
);
13119 gen_store_fpr32(ctx
, fp2
, fd
);
13120 tcg_temp_free_i32(fp2
);
13125 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
13127 TCGv_i64 fp0
= tcg_temp_new_i64();
13128 TCGv_i64 fp1
= tcg_temp_new_i64();
13129 TCGv_i64 fp2
= tcg_temp_new_i64();
13131 gen_load_fpr64(ctx
, fp0
, fs
);
13132 gen_load_fpr64(ctx
, fp1
, ft
);
13133 gen_load_fpr64(ctx
, fp2
, fr
);
13134 gen_helper_float_madd_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
13135 tcg_temp_free_i64(fp0
);
13136 tcg_temp_free_i64(fp1
);
13137 gen_store_fpr64(ctx
, fp2
, fd
);
13138 tcg_temp_free_i64(fp2
);
13144 TCGv_i64 fp0
= tcg_temp_new_i64();
13145 TCGv_i64 fp1
= tcg_temp_new_i64();
13146 TCGv_i64 fp2
= tcg_temp_new_i64();
13148 gen_load_fpr64(ctx
, fp0
, fs
);
13149 gen_load_fpr64(ctx
, fp1
, ft
);
13150 gen_load_fpr64(ctx
, fp2
, fr
);
13151 gen_helper_float_madd_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
13152 tcg_temp_free_i64(fp0
);
13153 tcg_temp_free_i64(fp1
);
13154 gen_store_fpr64(ctx
, fp2
, fd
);
13155 tcg_temp_free_i64(fp2
);
13161 TCGv_i32 fp0
= tcg_temp_new_i32();
13162 TCGv_i32 fp1
= tcg_temp_new_i32();
13163 TCGv_i32 fp2
= tcg_temp_new_i32();
13165 gen_load_fpr32(ctx
, fp0
, fs
);
13166 gen_load_fpr32(ctx
, fp1
, ft
);
13167 gen_load_fpr32(ctx
, fp2
, fr
);
13168 gen_helper_float_msub_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
13169 tcg_temp_free_i32(fp0
);
13170 tcg_temp_free_i32(fp1
);
13171 gen_store_fpr32(ctx
, fp2
, fd
);
13172 tcg_temp_free_i32(fp2
);
13177 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
13179 TCGv_i64 fp0
= tcg_temp_new_i64();
13180 TCGv_i64 fp1
= tcg_temp_new_i64();
13181 TCGv_i64 fp2
= tcg_temp_new_i64();
13183 gen_load_fpr64(ctx
, fp0
, fs
);
13184 gen_load_fpr64(ctx
, fp1
, ft
);
13185 gen_load_fpr64(ctx
, fp2
, fr
);
13186 gen_helper_float_msub_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
13187 tcg_temp_free_i64(fp0
);
13188 tcg_temp_free_i64(fp1
);
13189 gen_store_fpr64(ctx
, fp2
, fd
);
13190 tcg_temp_free_i64(fp2
);
13196 TCGv_i64 fp0
= tcg_temp_new_i64();
13197 TCGv_i64 fp1
= tcg_temp_new_i64();
13198 TCGv_i64 fp2
= tcg_temp_new_i64();
13200 gen_load_fpr64(ctx
, fp0
, fs
);
13201 gen_load_fpr64(ctx
, fp1
, ft
);
13202 gen_load_fpr64(ctx
, fp2
, fr
);
13203 gen_helper_float_msub_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
13204 tcg_temp_free_i64(fp0
);
13205 tcg_temp_free_i64(fp1
);
13206 gen_store_fpr64(ctx
, fp2
, fd
);
13207 tcg_temp_free_i64(fp2
);
13213 TCGv_i32 fp0
= tcg_temp_new_i32();
13214 TCGv_i32 fp1
= tcg_temp_new_i32();
13215 TCGv_i32 fp2
= tcg_temp_new_i32();
13217 gen_load_fpr32(ctx
, fp0
, fs
);
13218 gen_load_fpr32(ctx
, fp1
, ft
);
13219 gen_load_fpr32(ctx
, fp2
, fr
);
13220 gen_helper_float_nmadd_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
13221 tcg_temp_free_i32(fp0
);
13222 tcg_temp_free_i32(fp1
);
13223 gen_store_fpr32(ctx
, fp2
, fd
);
13224 tcg_temp_free_i32(fp2
);
13229 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
13231 TCGv_i64 fp0
= tcg_temp_new_i64();
13232 TCGv_i64 fp1
= tcg_temp_new_i64();
13233 TCGv_i64 fp2
= tcg_temp_new_i64();
13235 gen_load_fpr64(ctx
, fp0
, fs
);
13236 gen_load_fpr64(ctx
, fp1
, ft
);
13237 gen_load_fpr64(ctx
, fp2
, fr
);
13238 gen_helper_float_nmadd_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
13239 tcg_temp_free_i64(fp0
);
13240 tcg_temp_free_i64(fp1
);
13241 gen_store_fpr64(ctx
, fp2
, fd
);
13242 tcg_temp_free_i64(fp2
);
13248 TCGv_i64 fp0
= tcg_temp_new_i64();
13249 TCGv_i64 fp1
= tcg_temp_new_i64();
13250 TCGv_i64 fp2
= tcg_temp_new_i64();
13252 gen_load_fpr64(ctx
, fp0
, fs
);
13253 gen_load_fpr64(ctx
, fp1
, ft
);
13254 gen_load_fpr64(ctx
, fp2
, fr
);
13255 gen_helper_float_nmadd_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
13256 tcg_temp_free_i64(fp0
);
13257 tcg_temp_free_i64(fp1
);
13258 gen_store_fpr64(ctx
, fp2
, fd
);
13259 tcg_temp_free_i64(fp2
);
13265 TCGv_i32 fp0
= tcg_temp_new_i32();
13266 TCGv_i32 fp1
= tcg_temp_new_i32();
13267 TCGv_i32 fp2
= tcg_temp_new_i32();
13269 gen_load_fpr32(ctx
, fp0
, fs
);
13270 gen_load_fpr32(ctx
, fp1
, ft
);
13271 gen_load_fpr32(ctx
, fp2
, fr
);
13272 gen_helper_float_nmsub_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
13273 tcg_temp_free_i32(fp0
);
13274 tcg_temp_free_i32(fp1
);
13275 gen_store_fpr32(ctx
, fp2
, fd
);
13276 tcg_temp_free_i32(fp2
);
13281 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
13283 TCGv_i64 fp0
= tcg_temp_new_i64();
13284 TCGv_i64 fp1
= tcg_temp_new_i64();
13285 TCGv_i64 fp2
= tcg_temp_new_i64();
13287 gen_load_fpr64(ctx
, fp0
, fs
);
13288 gen_load_fpr64(ctx
, fp1
, ft
);
13289 gen_load_fpr64(ctx
, fp2
, fr
);
13290 gen_helper_float_nmsub_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
13291 tcg_temp_free_i64(fp0
);
13292 tcg_temp_free_i64(fp1
);
13293 gen_store_fpr64(ctx
, fp2
, fd
);
13294 tcg_temp_free_i64(fp2
);
13300 TCGv_i64 fp0
= tcg_temp_new_i64();
13301 TCGv_i64 fp1
= tcg_temp_new_i64();
13302 TCGv_i64 fp2
= tcg_temp_new_i64();
13304 gen_load_fpr64(ctx
, fp0
, fs
);
13305 gen_load_fpr64(ctx
, fp1
, ft
);
13306 gen_load_fpr64(ctx
, fp2
, fr
);
13307 gen_helper_float_nmsub_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
13308 tcg_temp_free_i64(fp0
);
13309 tcg_temp_free_i64(fp1
);
13310 gen_store_fpr64(ctx
, fp2
, fd
);
13311 tcg_temp_free_i64(fp2
);
13315 MIPS_INVAL("flt3_arith");
13316 gen_reserved_instruction(ctx
);
13321 static void gen_rdhwr(DisasContext
*ctx
, int rt
, int rd
, int sel
)
13325 #if !defined(CONFIG_USER_ONLY)
13327 * The Linux kernel will emulate rdhwr if it's not supported natively.
13328 * Therefore only check the ISA in system mode.
13330 check_insn(ctx
, ISA_MIPS_R2
);
13332 t0
= tcg_temp_new();
13336 gen_helper_rdhwr_cpunum(t0
, cpu_env
);
13337 gen_store_gpr(t0
, rt
);
13340 gen_helper_rdhwr_synci_step(t0
, cpu_env
);
13341 gen_store_gpr(t0
, rt
);
13344 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
13347 gen_helper_rdhwr_cc(t0
, cpu_env
);
13348 gen_store_gpr(t0
, rt
);
13350 * Break the TB to be able to take timer interrupts immediately
13351 * after reading count. DISAS_STOP isn't sufficient, we need to ensure
13352 * we break completely out of translated code.
13354 gen_save_pc(ctx
->base
.pc_next
+ 4);
13355 ctx
->base
.is_jmp
= DISAS_EXIT
;
13358 gen_helper_rdhwr_ccres(t0
, cpu_env
);
13359 gen_store_gpr(t0
, rt
);
13362 check_insn(ctx
, ISA_MIPS_R6
);
13365 * Performance counter registers are not implemented other than
13366 * control register 0.
13368 generate_exception(ctx
, EXCP_RI
);
13370 gen_helper_rdhwr_performance(t0
, cpu_env
);
13371 gen_store_gpr(t0
, rt
);
13374 check_insn(ctx
, ISA_MIPS_R6
);
13375 gen_helper_rdhwr_xnp(t0
, cpu_env
);
13376 gen_store_gpr(t0
, rt
);
13379 #if defined(CONFIG_USER_ONLY)
13380 tcg_gen_ld_tl(t0
, cpu_env
,
13381 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
13382 gen_store_gpr(t0
, rt
);
13385 if ((ctx
->hflags
& MIPS_HFLAG_CP0
) ||
13386 (ctx
->hflags
& MIPS_HFLAG_HWRENA_ULR
)) {
13387 tcg_gen_ld_tl(t0
, cpu_env
,
13388 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
13389 gen_store_gpr(t0
, rt
);
13391 gen_reserved_instruction(ctx
);
13395 default: /* Invalid */
13396 MIPS_INVAL("rdhwr");
13397 gen_reserved_instruction(ctx
);
13403 static inline void clear_branch_hflags(DisasContext
*ctx
)
13405 ctx
->hflags
&= ~MIPS_HFLAG_BMASK
;
13406 if (ctx
->base
.is_jmp
== DISAS_NEXT
) {
13407 save_cpu_state(ctx
, 0);
13410 * It is not safe to save ctx->hflags as hflags may be changed
13411 * in execution time by the instruction in delay / forbidden slot.
13413 tcg_gen_andi_i32(hflags
, hflags
, ~MIPS_HFLAG_BMASK
);
13417 static void gen_branch(DisasContext
*ctx
, int insn_bytes
)
13419 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
13420 int proc_hflags
= ctx
->hflags
& MIPS_HFLAG_BMASK
;
13421 /* Branches completion */
13422 clear_branch_hflags(ctx
);
13423 ctx
->base
.is_jmp
= DISAS_NORETURN
;
13424 /* FIXME: Need to clear can_do_io. */
13425 switch (proc_hflags
& MIPS_HFLAG_BMASK_BASE
) {
13426 case MIPS_HFLAG_FBNSLOT
:
13427 gen_goto_tb(ctx
, 0, ctx
->base
.pc_next
+ insn_bytes
);
13430 /* unconditional branch */
13431 if (proc_hflags
& MIPS_HFLAG_BX
) {
13432 tcg_gen_xori_i32(hflags
, hflags
, MIPS_HFLAG_M16
);
13434 gen_goto_tb(ctx
, 0, ctx
->btarget
);
13436 case MIPS_HFLAG_BL
:
13437 /* blikely taken case */
13438 gen_goto_tb(ctx
, 0, ctx
->btarget
);
13440 case MIPS_HFLAG_BC
:
13441 /* Conditional branch */
13443 TCGLabel
*l1
= gen_new_label();
13445 tcg_gen_brcondi_tl(TCG_COND_NE
, bcond
, 0, l1
);
13446 gen_goto_tb(ctx
, 1, ctx
->base
.pc_next
+ insn_bytes
);
13448 gen_goto_tb(ctx
, 0, ctx
->btarget
);
13451 case MIPS_HFLAG_BR
:
13452 /* unconditional branch to register */
13453 if (ctx
->insn_flags
& (ASE_MIPS16
| ASE_MICROMIPS
)) {
13454 TCGv t0
= tcg_temp_new();
13455 TCGv_i32 t1
= tcg_temp_new_i32();
13457 tcg_gen_andi_tl(t0
, btarget
, 0x1);
13458 tcg_gen_trunc_tl_i32(t1
, t0
);
13460 tcg_gen_andi_i32(hflags
, hflags
, ~(uint32_t)MIPS_HFLAG_M16
);
13461 tcg_gen_shli_i32(t1
, t1
, MIPS_HFLAG_M16_SHIFT
);
13462 tcg_gen_or_i32(hflags
, hflags
, t1
);
13463 tcg_temp_free_i32(t1
);
13465 tcg_gen_andi_tl(cpu_PC
, btarget
, ~(target_ulong
)0x1);
13467 tcg_gen_mov_tl(cpu_PC
, btarget
);
13469 if (ctx
->base
.singlestep_enabled
) {
13470 save_cpu_state(ctx
, 0);
13471 gen_helper_raise_exception_debug(cpu_env
);
13473 tcg_gen_lookup_and_goto_ptr();
13476 fprintf(stderr
, "unknown branch 0x%x\n", proc_hflags
);
13482 /* Compact Branches */
13483 static void gen_compute_compact_branch(DisasContext
*ctx
, uint32_t opc
,
13484 int rs
, int rt
, int32_t offset
)
13486 int bcond_compute
= 0;
13487 TCGv t0
= tcg_temp_new();
13488 TCGv t1
= tcg_temp_new();
13489 int m16_lowbit
= (ctx
->hflags
& MIPS_HFLAG_M16
) != 0;
13491 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
13492 #ifdef MIPS_DEBUG_DISAS
13493 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
13494 "\n", ctx
->base
.pc_next
);
13496 gen_reserved_instruction(ctx
);
13500 /* Load needed operands and calculate btarget */
13502 /* compact branch */
13503 case OPC_BOVC
: /* OPC_BEQZALC, OPC_BEQC */
13504 case OPC_BNVC
: /* OPC_BNEZALC, OPC_BNEC */
13505 gen_load_gpr(t0
, rs
);
13506 gen_load_gpr(t1
, rt
);
13508 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
13509 if (rs
<= rt
&& rs
== 0) {
13510 /* OPC_BEQZALC, OPC_BNEZALC */
13511 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 4 + m16_lowbit
);
13514 case OPC_BLEZC
: /* OPC_BGEZC, OPC_BGEC */
13515 case OPC_BGTZC
: /* OPC_BLTZC, OPC_BLTC */
13516 gen_load_gpr(t0
, rs
);
13517 gen_load_gpr(t1
, rt
);
13519 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
13521 case OPC_BLEZALC
: /* OPC_BGEZALC, OPC_BGEUC */
13522 case OPC_BGTZALC
: /* OPC_BLTZALC, OPC_BLTUC */
13523 if (rs
== 0 || rs
== rt
) {
13524 /* OPC_BLEZALC, OPC_BGEZALC */
13525 /* OPC_BGTZALC, OPC_BLTZALC */
13526 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 4 + m16_lowbit
);
13528 gen_load_gpr(t0
, rs
);
13529 gen_load_gpr(t1
, rt
);
13531 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
13535 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
13540 /* OPC_BEQZC, OPC_BNEZC */
13541 gen_load_gpr(t0
, rs
);
13543 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
13545 /* OPC_JIC, OPC_JIALC */
13546 TCGv tbase
= tcg_temp_new();
13547 TCGv toffset
= tcg_temp_new();
13549 gen_load_gpr(tbase
, rt
);
13550 tcg_gen_movi_tl(toffset
, offset
);
13551 gen_op_addr_add(ctx
, btarget
, tbase
, toffset
);
13552 tcg_temp_free(tbase
);
13553 tcg_temp_free(toffset
);
13557 MIPS_INVAL("Compact branch/jump");
13558 gen_reserved_instruction(ctx
);
13562 if (bcond_compute
== 0) {
13563 /* Uncoditional compact branch */
13566 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 4 + m16_lowbit
);
13569 ctx
->hflags
|= MIPS_HFLAG_BR
;
13572 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 4 + m16_lowbit
);
13575 ctx
->hflags
|= MIPS_HFLAG_B
;
13578 MIPS_INVAL("Compact branch/jump");
13579 gen_reserved_instruction(ctx
);
13583 /* Generating branch here as compact branches don't have delay slot */
13584 gen_branch(ctx
, 4);
13586 /* Conditional compact branch */
13587 TCGLabel
*fs
= gen_new_label();
13588 save_cpu_state(ctx
, 0);
13591 case OPC_BLEZALC
: /* OPC_BGEZALC, OPC_BGEUC */
13592 if (rs
== 0 && rt
!= 0) {
13594 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE
), t1
, 0, fs
);
13595 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
13597 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE
), t1
, 0, fs
);
13600 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU
), t0
, t1
, fs
);
13603 case OPC_BGTZALC
: /* OPC_BLTZALC, OPC_BLTUC */
13604 if (rs
== 0 && rt
!= 0) {
13606 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT
), t1
, 0, fs
);
13607 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
13609 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT
), t1
, 0, fs
);
13612 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU
), t0
, t1
, fs
);
13615 case OPC_BLEZC
: /* OPC_BGEZC, OPC_BGEC */
13616 if (rs
== 0 && rt
!= 0) {
13618 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE
), t1
, 0, fs
);
13619 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
13621 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE
), t1
, 0, fs
);
13624 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE
), t0
, t1
, fs
);
13627 case OPC_BGTZC
: /* OPC_BLTZC, OPC_BLTC */
13628 if (rs
== 0 && rt
!= 0) {
13630 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT
), t1
, 0, fs
);
13631 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
13633 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT
), t1
, 0, fs
);
13636 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT
), t0
, t1
, fs
);
13639 case OPC_BOVC
: /* OPC_BEQZALC, OPC_BEQC */
13640 case OPC_BNVC
: /* OPC_BNEZALC, OPC_BNEC */
13642 /* OPC_BOVC, OPC_BNVC */
13643 TCGv t2
= tcg_temp_new();
13644 TCGv t3
= tcg_temp_new();
13645 TCGv t4
= tcg_temp_new();
13646 TCGv input_overflow
= tcg_temp_new();
13648 gen_load_gpr(t0
, rs
);
13649 gen_load_gpr(t1
, rt
);
13650 tcg_gen_ext32s_tl(t2
, t0
);
13651 tcg_gen_setcond_tl(TCG_COND_NE
, input_overflow
, t2
, t0
);
13652 tcg_gen_ext32s_tl(t3
, t1
);
13653 tcg_gen_setcond_tl(TCG_COND_NE
, t4
, t3
, t1
);
13654 tcg_gen_or_tl(input_overflow
, input_overflow
, t4
);
13656 tcg_gen_add_tl(t4
, t2
, t3
);
13657 tcg_gen_ext32s_tl(t4
, t4
);
13658 tcg_gen_xor_tl(t2
, t2
, t3
);
13659 tcg_gen_xor_tl(t3
, t4
, t3
);
13660 tcg_gen_andc_tl(t2
, t3
, t2
);
13661 tcg_gen_setcondi_tl(TCG_COND_LT
, t4
, t2
, 0);
13662 tcg_gen_or_tl(t4
, t4
, input_overflow
);
13663 if (opc
== OPC_BOVC
) {
13665 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE
), t4
, 0, fs
);
13668 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ
), t4
, 0, fs
);
13670 tcg_temp_free(input_overflow
);
13674 } else if (rs
< rt
&& rs
== 0) {
13675 /* OPC_BEQZALC, OPC_BNEZALC */
13676 if (opc
== OPC_BEQZALC
) {
13678 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ
), t1
, 0, fs
);
13681 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE
), t1
, 0, fs
);
13684 /* OPC_BEQC, OPC_BNEC */
13685 if (opc
== OPC_BEQC
) {
13687 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ
), t0
, t1
, fs
);
13690 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE
), t0
, t1
, fs
);
13695 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ
), t0
, 0, fs
);
13698 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE
), t0
, 0, fs
);
13701 MIPS_INVAL("Compact conditional branch/jump");
13702 gen_reserved_instruction(ctx
);
13706 /* Generating branch here as compact branches don't have delay slot */
13707 gen_goto_tb(ctx
, 1, ctx
->btarget
);
13710 ctx
->hflags
|= MIPS_HFLAG_FBNSLOT
;
13718 /* ISA extensions (ASEs) */
13719 /* MIPS16 extension to MIPS32 */
13721 /* MIPS16 major opcodes */
13723 M16_OPC_ADDIUSP
= 0x00,
13724 M16_OPC_ADDIUPC
= 0x01,
13726 M16_OPC_JAL
= 0x03,
13727 M16_OPC_BEQZ
= 0x04,
13728 M16_OPC_BNEQZ
= 0x05,
13729 M16_OPC_SHIFT
= 0x06,
13731 M16_OPC_RRIA
= 0x08,
13732 M16_OPC_ADDIU8
= 0x09,
13733 M16_OPC_SLTI
= 0x0a,
13734 M16_OPC_SLTIU
= 0x0b,
13737 M16_OPC_CMPI
= 0x0e,
13741 M16_OPC_LWSP
= 0x12,
13743 M16_OPC_LBU
= 0x14,
13744 M16_OPC_LHU
= 0x15,
13745 M16_OPC_LWPC
= 0x16,
13746 M16_OPC_LWU
= 0x17,
13749 M16_OPC_SWSP
= 0x1a,
13751 M16_OPC_RRR
= 0x1c,
13753 M16_OPC_EXTEND
= 0x1e,
13757 /* I8 funct field */
13776 /* RR funct field */
13810 /* I64 funct field */
13818 I64_DADDIUPC
= 0x6,
13822 /* RR ry field for CNVT */
13824 RR_RY_CNVT_ZEB
= 0x0,
13825 RR_RY_CNVT_ZEH
= 0x1,
13826 RR_RY_CNVT_ZEW
= 0x2,
13827 RR_RY_CNVT_SEB
= 0x4,
13828 RR_RY_CNVT_SEH
= 0x5,
13829 RR_RY_CNVT_SEW
= 0x6,
13832 static int xlat(int r
)
13834 static int map
[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
13839 static void gen_mips16_save(DisasContext
*ctx
,
13840 int xsregs
, int aregs
,
13841 int do_ra
, int do_s0
, int do_s1
,
13844 TCGv t0
= tcg_temp_new();
13845 TCGv t1
= tcg_temp_new();
13846 TCGv t2
= tcg_temp_new();
13876 gen_reserved_instruction(ctx
);
13882 gen_base_offset_addr(ctx
, t0
, 29, 12);
13883 gen_load_gpr(t1
, 7);
13884 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
13887 gen_base_offset_addr(ctx
, t0
, 29, 8);
13888 gen_load_gpr(t1
, 6);
13889 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
13892 gen_base_offset_addr(ctx
, t0
, 29, 4);
13893 gen_load_gpr(t1
, 5);
13894 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
13897 gen_base_offset_addr(ctx
, t0
, 29, 0);
13898 gen_load_gpr(t1
, 4);
13899 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
13902 gen_load_gpr(t0
, 29);
13904 #define DECR_AND_STORE(reg) do { \
13905 tcg_gen_movi_tl(t2, -4); \
13906 gen_op_addr_add(ctx, t0, t0, t2); \
13907 gen_load_gpr(t1, reg); \
13908 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \
13912 DECR_AND_STORE(31);
13917 DECR_AND_STORE(30);
13920 DECR_AND_STORE(23);
13923 DECR_AND_STORE(22);
13926 DECR_AND_STORE(21);
13929 DECR_AND_STORE(20);
13932 DECR_AND_STORE(19);
13935 DECR_AND_STORE(18);
13939 DECR_AND_STORE(17);
13942 DECR_AND_STORE(16);
13972 gen_reserved_instruction(ctx
);
13988 #undef DECR_AND_STORE
13990 tcg_gen_movi_tl(t2
, -framesize
);
13991 gen_op_addr_add(ctx
, cpu_gpr
[29], cpu_gpr
[29], t2
);
13997 static void gen_mips16_restore(DisasContext
*ctx
,
13998 int xsregs
, int aregs
,
13999 int do_ra
, int do_s0
, int do_s1
,
14003 TCGv t0
= tcg_temp_new();
14004 TCGv t1
= tcg_temp_new();
14005 TCGv t2
= tcg_temp_new();
14007 tcg_gen_movi_tl(t2
, framesize
);
14008 gen_op_addr_add(ctx
, t0
, cpu_gpr
[29], t2
);
14010 #define DECR_AND_LOAD(reg) do { \
14011 tcg_gen_movi_tl(t2, -4); \
14012 gen_op_addr_add(ctx, t0, t0, t2); \
14013 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \
14014 gen_store_gpr(t1, reg); \
14078 gen_reserved_instruction(ctx
);
14094 #undef DECR_AND_LOAD
14096 tcg_gen_movi_tl(t2
, framesize
);
14097 gen_op_addr_add(ctx
, cpu_gpr
[29], cpu_gpr
[29], t2
);
14103 static void gen_addiupc(DisasContext
*ctx
, int rx
, int imm
,
14104 int is_64_bit
, int extended
)
14108 if (extended
&& (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
14109 gen_reserved_instruction(ctx
);
14113 t0
= tcg_temp_new();
14115 tcg_gen_movi_tl(t0
, pc_relative_pc(ctx
));
14116 tcg_gen_addi_tl(cpu_gpr
[rx
], t0
, imm
);
14118 tcg_gen_ext32s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
14124 static void gen_cache_operation(DisasContext
*ctx
, uint32_t op
, int base
,
14127 TCGv_i32 t0
= tcg_const_i32(op
);
14128 TCGv t1
= tcg_temp_new();
14129 gen_base_offset_addr(ctx
, t1
, base
, offset
);
14130 gen_helper_cache(cpu_env
, t1
, t0
);
14133 #if defined(TARGET_MIPS64)
14134 static void decode_i64_mips16(DisasContext
*ctx
,
14135 int ry
, int funct
, int16_t offset
,
14140 check_insn(ctx
, ISA_MIPS3
);
14141 check_mips_64(ctx
);
14142 offset
= extended
? offset
: offset
<< 3;
14143 gen_ld(ctx
, OPC_LD
, ry
, 29, offset
);
14146 check_insn(ctx
, ISA_MIPS3
);
14147 check_mips_64(ctx
);
14148 offset
= extended
? offset
: offset
<< 3;
14149 gen_st(ctx
, OPC_SD
, ry
, 29, offset
);
14152 check_insn(ctx
, ISA_MIPS3
);
14153 check_mips_64(ctx
);
14154 offset
= extended
? offset
: (ctx
->opcode
& 0xff) << 3;
14155 gen_st(ctx
, OPC_SD
, 31, 29, offset
);
14158 check_insn(ctx
, ISA_MIPS3
);
14159 check_mips_64(ctx
);
14160 offset
= extended
? offset
: ((int8_t)ctx
->opcode
) << 3;
14161 gen_arith_imm(ctx
, OPC_DADDIU
, 29, 29, offset
);
14164 check_insn(ctx
, ISA_MIPS3
);
14165 check_mips_64(ctx
);
14166 if (extended
&& (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
14167 gen_reserved_instruction(ctx
);
14169 offset
= extended
? offset
: offset
<< 3;
14170 gen_ld(ctx
, OPC_LDPC
, ry
, 0, offset
);
14174 check_insn(ctx
, ISA_MIPS3
);
14175 check_mips_64(ctx
);
14176 offset
= extended
? offset
: ((int8_t)(offset
<< 3)) >> 3;
14177 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, ry
, offset
);
14180 check_insn(ctx
, ISA_MIPS3
);
14181 check_mips_64(ctx
);
14182 offset
= extended
? offset
: offset
<< 2;
14183 gen_addiupc(ctx
, ry
, offset
, 1, extended
);
14186 check_insn(ctx
, ISA_MIPS3
);
14187 check_mips_64(ctx
);
14188 offset
= extended
? offset
: offset
<< 2;
14189 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, 29, offset
);
14195 static int decode_extended_mips16_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
14197 int extend
= cpu_lduw_code(env
, ctx
->base
.pc_next
+ 2);
14198 int op
, rx
, ry
, funct
, sa
;
14199 int16_t imm
, offset
;
14201 ctx
->opcode
= (ctx
->opcode
<< 16) | extend
;
14202 op
= (ctx
->opcode
>> 11) & 0x1f;
14203 sa
= (ctx
->opcode
>> 22) & 0x1f;
14204 funct
= (ctx
->opcode
>> 8) & 0x7;
14205 rx
= xlat((ctx
->opcode
>> 8) & 0x7);
14206 ry
= xlat((ctx
->opcode
>> 5) & 0x7);
14207 offset
= imm
= (int16_t) (((ctx
->opcode
>> 16) & 0x1f) << 11
14208 | ((ctx
->opcode
>> 21) & 0x3f) << 5
14209 | (ctx
->opcode
& 0x1f));
14212 * The extended opcodes cleverly reuse the opcodes from their 16-bit
14216 case M16_OPC_ADDIUSP
:
14217 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 29, imm
);
14219 case M16_OPC_ADDIUPC
:
14220 gen_addiupc(ctx
, rx
, imm
, 0, 1);
14223 gen_compute_branch(ctx
, OPC_BEQ
, 4, 0, 0, offset
<< 1, 0);
14224 /* No delay slot, so just process as a normal instruction */
14227 gen_compute_branch(ctx
, OPC_BEQ
, 4, rx
, 0, offset
<< 1, 0);
14228 /* No delay slot, so just process as a normal instruction */
14230 case M16_OPC_BNEQZ
:
14231 gen_compute_branch(ctx
, OPC_BNE
, 4, rx
, 0, offset
<< 1, 0);
14232 /* No delay slot, so just process as a normal instruction */
14234 case M16_OPC_SHIFT
:
14235 switch (ctx
->opcode
& 0x3) {
14237 gen_shift_imm(ctx
, OPC_SLL
, rx
, ry
, sa
);
14240 #if defined(TARGET_MIPS64)
14241 check_mips_64(ctx
);
14242 gen_shift_imm(ctx
, OPC_DSLL
, rx
, ry
, sa
);
14244 gen_reserved_instruction(ctx
);
14248 gen_shift_imm(ctx
, OPC_SRL
, rx
, ry
, sa
);
14251 gen_shift_imm(ctx
, OPC_SRA
, rx
, ry
, sa
);
14255 #if defined(TARGET_MIPS64)
14257 check_insn(ctx
, ISA_MIPS3
);
14258 check_mips_64(ctx
);
14259 gen_ld(ctx
, OPC_LD
, ry
, rx
, offset
);
14263 imm
= ctx
->opcode
& 0xf;
14264 imm
= imm
| ((ctx
->opcode
>> 20) & 0x7f) << 4;
14265 imm
= imm
| ((ctx
->opcode
>> 16) & 0xf) << 11;
14266 imm
= (int16_t) (imm
<< 1) >> 1;
14267 if ((ctx
->opcode
>> 4) & 0x1) {
14268 #if defined(TARGET_MIPS64)
14269 check_mips_64(ctx
);
14270 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, rx
, imm
);
14272 gen_reserved_instruction(ctx
);
14275 gen_arith_imm(ctx
, OPC_ADDIU
, ry
, rx
, imm
);
14278 case M16_OPC_ADDIU8
:
14279 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, rx
, imm
);
14282 gen_slt_imm(ctx
, OPC_SLTI
, 24, rx
, imm
);
14284 case M16_OPC_SLTIU
:
14285 gen_slt_imm(ctx
, OPC_SLTIU
, 24, rx
, imm
);
14290 gen_compute_branch(ctx
, OPC_BEQ
, 4, 24, 0, offset
<< 1, 0);
14293 gen_compute_branch(ctx
, OPC_BNE
, 4, 24, 0, offset
<< 1, 0);
14296 gen_st(ctx
, OPC_SW
, 31, 29, imm
);
14299 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, imm
);
14302 check_insn(ctx
, ISA_MIPS_R1
);
14304 int xsregs
= (ctx
->opcode
>> 24) & 0x7;
14305 int aregs
= (ctx
->opcode
>> 16) & 0xf;
14306 int do_ra
= (ctx
->opcode
>> 6) & 0x1;
14307 int do_s0
= (ctx
->opcode
>> 5) & 0x1;
14308 int do_s1
= (ctx
->opcode
>> 4) & 0x1;
14309 int framesize
= (((ctx
->opcode
>> 20) & 0xf) << 4
14310 | (ctx
->opcode
& 0xf)) << 3;
14312 if (ctx
->opcode
& (1 << 7)) {
14313 gen_mips16_save(ctx
, xsregs
, aregs
,
14314 do_ra
, do_s0
, do_s1
,
14317 gen_mips16_restore(ctx
, xsregs
, aregs
,
14318 do_ra
, do_s0
, do_s1
,
14324 gen_reserved_instruction(ctx
);
14329 tcg_gen_movi_tl(cpu_gpr
[rx
], (uint16_t) imm
);
14332 tcg_gen_xori_tl(cpu_gpr
[24], cpu_gpr
[rx
], (uint16_t) imm
);
14334 #if defined(TARGET_MIPS64)
14336 check_insn(ctx
, ISA_MIPS3
);
14337 check_mips_64(ctx
);
14338 gen_st(ctx
, OPC_SD
, ry
, rx
, offset
);
14342 gen_ld(ctx
, OPC_LB
, ry
, rx
, offset
);
14345 gen_ld(ctx
, OPC_LH
, ry
, rx
, offset
);
14348 gen_ld(ctx
, OPC_LW
, rx
, 29, offset
);
14351 gen_ld(ctx
, OPC_LW
, ry
, rx
, offset
);
14354 gen_ld(ctx
, OPC_LBU
, ry
, rx
, offset
);
14357 gen_ld(ctx
, OPC_LHU
, ry
, rx
, offset
);
14360 gen_ld(ctx
, OPC_LWPC
, rx
, 0, offset
);
14362 #if defined(TARGET_MIPS64)
14364 check_insn(ctx
, ISA_MIPS3
);
14365 check_mips_64(ctx
);
14366 gen_ld(ctx
, OPC_LWU
, ry
, rx
, offset
);
14370 gen_st(ctx
, OPC_SB
, ry
, rx
, offset
);
14373 gen_st(ctx
, OPC_SH
, ry
, rx
, offset
);
14376 gen_st(ctx
, OPC_SW
, rx
, 29, offset
);
14379 gen_st(ctx
, OPC_SW
, ry
, rx
, offset
);
14381 #if defined(TARGET_MIPS64)
14383 decode_i64_mips16(ctx
, ry
, funct
, offset
, 1);
14387 gen_reserved_instruction(ctx
);
14394 static inline bool is_uhi(int sdbbp_code
)
14396 #ifdef CONFIG_USER_ONLY
14399 return semihosting_enabled() && sdbbp_code
== 1;
14403 #ifdef CONFIG_USER_ONLY
14404 /* The above should dead-code away any calls to this..*/
14405 static inline void gen_helper_do_semihosting(void *env
)
14407 g_assert_not_reached();
14411 static int decode_mips16_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
14415 int op
, cnvt_op
, op1
, offset
;
14419 op
= (ctx
->opcode
>> 11) & 0x1f;
14420 sa
= (ctx
->opcode
>> 2) & 0x7;
14421 sa
= sa
== 0 ? 8 : sa
;
14422 rx
= xlat((ctx
->opcode
>> 8) & 0x7);
14423 cnvt_op
= (ctx
->opcode
>> 5) & 0x7;
14424 ry
= xlat((ctx
->opcode
>> 5) & 0x7);
14425 op1
= offset
= ctx
->opcode
& 0x1f;
14430 case M16_OPC_ADDIUSP
:
14432 int16_t imm
= ((uint8_t) ctx
->opcode
) << 2;
14434 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 29, imm
);
14437 case M16_OPC_ADDIUPC
:
14438 gen_addiupc(ctx
, rx
, ((uint8_t) ctx
->opcode
) << 2, 0, 0);
14441 offset
= (ctx
->opcode
& 0x7ff) << 1;
14442 offset
= (int16_t)(offset
<< 4) >> 4;
14443 gen_compute_branch(ctx
, OPC_BEQ
, 2, 0, 0, offset
, 0);
14444 /* No delay slot, so just process as a normal instruction */
14447 offset
= cpu_lduw_code(env
, ctx
->base
.pc_next
+ 2);
14448 offset
= (((ctx
->opcode
& 0x1f) << 21)
14449 | ((ctx
->opcode
>> 5) & 0x1f) << 16
14451 op
= ((ctx
->opcode
>> 10) & 0x1) ? OPC_JALX
: OPC_JAL
;
14452 gen_compute_branch(ctx
, op
, 4, rx
, ry
, offset
, 2);
14456 gen_compute_branch(ctx
, OPC_BEQ
, 2, rx
, 0,
14457 ((int8_t)ctx
->opcode
) << 1, 0);
14458 /* No delay slot, so just process as a normal instruction */
14460 case M16_OPC_BNEQZ
:
14461 gen_compute_branch(ctx
, OPC_BNE
, 2, rx
, 0,
14462 ((int8_t)ctx
->opcode
) << 1, 0);
14463 /* No delay slot, so just process as a normal instruction */
14465 case M16_OPC_SHIFT
:
14466 switch (ctx
->opcode
& 0x3) {
14468 gen_shift_imm(ctx
, OPC_SLL
, rx
, ry
, sa
);
14471 #if defined(TARGET_MIPS64)
14472 check_insn(ctx
, ISA_MIPS3
);
14473 check_mips_64(ctx
);
14474 gen_shift_imm(ctx
, OPC_DSLL
, rx
, ry
, sa
);
14476 gen_reserved_instruction(ctx
);
14480 gen_shift_imm(ctx
, OPC_SRL
, rx
, ry
, sa
);
14483 gen_shift_imm(ctx
, OPC_SRA
, rx
, ry
, sa
);
14487 #if defined(TARGET_MIPS64)
14489 check_insn(ctx
, ISA_MIPS3
);
14490 check_mips_64(ctx
);
14491 gen_ld(ctx
, OPC_LD
, ry
, rx
, offset
<< 3);
14496 int16_t imm
= (int8_t)((ctx
->opcode
& 0xf) << 4) >> 4;
14498 if ((ctx
->opcode
>> 4) & 1) {
14499 #if defined(TARGET_MIPS64)
14500 check_insn(ctx
, ISA_MIPS3
);
14501 check_mips_64(ctx
);
14502 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, rx
, imm
);
14504 gen_reserved_instruction(ctx
);
14507 gen_arith_imm(ctx
, OPC_ADDIU
, ry
, rx
, imm
);
14511 case M16_OPC_ADDIU8
:
14513 int16_t imm
= (int8_t) ctx
->opcode
;
14515 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, rx
, imm
);
14520 int16_t imm
= (uint8_t) ctx
->opcode
;
14521 gen_slt_imm(ctx
, OPC_SLTI
, 24, rx
, imm
);
14524 case M16_OPC_SLTIU
:
14526 int16_t imm
= (uint8_t) ctx
->opcode
;
14527 gen_slt_imm(ctx
, OPC_SLTIU
, 24, rx
, imm
);
14534 funct
= (ctx
->opcode
>> 8) & 0x7;
14537 gen_compute_branch(ctx
, OPC_BEQ
, 2, 24, 0,
14538 ((int8_t)ctx
->opcode
) << 1, 0);
14541 gen_compute_branch(ctx
, OPC_BNE
, 2, 24, 0,
14542 ((int8_t)ctx
->opcode
) << 1, 0);
14545 gen_st(ctx
, OPC_SW
, 31, 29, (ctx
->opcode
& 0xff) << 2);
14548 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29,
14549 ((int8_t)ctx
->opcode
) << 3);
14552 check_insn(ctx
, ISA_MIPS_R1
);
14554 int do_ra
= ctx
->opcode
& (1 << 6);
14555 int do_s0
= ctx
->opcode
& (1 << 5);
14556 int do_s1
= ctx
->opcode
& (1 << 4);
14557 int framesize
= ctx
->opcode
& 0xf;
14559 if (framesize
== 0) {
14562 framesize
= framesize
<< 3;
14565 if (ctx
->opcode
& (1 << 7)) {
14566 gen_mips16_save(ctx
, 0, 0,
14567 do_ra
, do_s0
, do_s1
, framesize
);
14569 gen_mips16_restore(ctx
, 0, 0,
14570 do_ra
, do_s0
, do_s1
, framesize
);
14576 int rz
= xlat(ctx
->opcode
& 0x7);
14578 reg32
= (((ctx
->opcode
>> 3) & 0x3) << 3) |
14579 ((ctx
->opcode
>> 5) & 0x7);
14580 gen_arith(ctx
, OPC_ADDU
, reg32
, rz
, 0);
14584 reg32
= ctx
->opcode
& 0x1f;
14585 gen_arith(ctx
, OPC_ADDU
, ry
, reg32
, 0);
14588 gen_reserved_instruction(ctx
);
14595 int16_t imm
= (uint8_t) ctx
->opcode
;
14597 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 0, imm
);
14602 int16_t imm
= (uint8_t) ctx
->opcode
;
14603 gen_logic_imm(ctx
, OPC_XORI
, 24, rx
, imm
);
14606 #if defined(TARGET_MIPS64)
14608 check_insn(ctx
, ISA_MIPS3
);
14609 check_mips_64(ctx
);
14610 gen_st(ctx
, OPC_SD
, ry
, rx
, offset
<< 3);
14614 gen_ld(ctx
, OPC_LB
, ry
, rx
, offset
);
14617 gen_ld(ctx
, OPC_LH
, ry
, rx
, offset
<< 1);
14620 gen_ld(ctx
, OPC_LW
, rx
, 29, ((uint8_t)ctx
->opcode
) << 2);
14623 gen_ld(ctx
, OPC_LW
, ry
, rx
, offset
<< 2);
14626 gen_ld(ctx
, OPC_LBU
, ry
, rx
, offset
);
14629 gen_ld(ctx
, OPC_LHU
, ry
, rx
, offset
<< 1);
14632 gen_ld(ctx
, OPC_LWPC
, rx
, 0, ((uint8_t)ctx
->opcode
) << 2);
14634 #if defined(TARGET_MIPS64)
14636 check_insn(ctx
, ISA_MIPS3
);
14637 check_mips_64(ctx
);
14638 gen_ld(ctx
, OPC_LWU
, ry
, rx
, offset
<< 2);
14642 gen_st(ctx
, OPC_SB
, ry
, rx
, offset
);
14645 gen_st(ctx
, OPC_SH
, ry
, rx
, offset
<< 1);
14648 gen_st(ctx
, OPC_SW
, rx
, 29, ((uint8_t)ctx
->opcode
) << 2);
14651 gen_st(ctx
, OPC_SW
, ry
, rx
, offset
<< 2);
14655 int rz
= xlat((ctx
->opcode
>> 2) & 0x7);
14658 switch (ctx
->opcode
& 0x3) {
14660 mips32_op
= OPC_ADDU
;
14663 mips32_op
= OPC_SUBU
;
14665 #if defined(TARGET_MIPS64)
14667 mips32_op
= OPC_DADDU
;
14668 check_insn(ctx
, ISA_MIPS3
);
14669 check_mips_64(ctx
);
14672 mips32_op
= OPC_DSUBU
;
14673 check_insn(ctx
, ISA_MIPS3
);
14674 check_mips_64(ctx
);
14678 gen_reserved_instruction(ctx
);
14682 gen_arith(ctx
, mips32_op
, rz
, rx
, ry
);
14691 int nd
= (ctx
->opcode
>> 7) & 0x1;
14692 int link
= (ctx
->opcode
>> 6) & 0x1;
14693 int ra
= (ctx
->opcode
>> 5) & 0x1;
14696 check_insn(ctx
, ISA_MIPS_R1
);
14705 gen_compute_branch(ctx
, op
, 2, ra
? 31 : rx
, 31, 0,
14710 if (is_uhi(extract32(ctx
->opcode
, 5, 6))) {
14711 gen_helper_do_semihosting(cpu_env
);
14714 * XXX: not clear which exception should be raised
14715 * when in debug mode...
14717 check_insn(ctx
, ISA_MIPS_R1
);
14718 generate_exception_end(ctx
, EXCP_DBp
);
14722 gen_slt(ctx
, OPC_SLT
, 24, rx
, ry
);
14725 gen_slt(ctx
, OPC_SLTU
, 24, rx
, ry
);
14728 generate_exception_end(ctx
, EXCP_BREAK
);
14731 gen_shift(ctx
, OPC_SLLV
, ry
, rx
, ry
);
14734 gen_shift(ctx
, OPC_SRLV
, ry
, rx
, ry
);
14737 gen_shift(ctx
, OPC_SRAV
, ry
, rx
, ry
);
14739 #if defined(TARGET_MIPS64)
14741 check_insn(ctx
, ISA_MIPS3
);
14742 check_mips_64(ctx
);
14743 gen_shift_imm(ctx
, OPC_DSRL
, ry
, ry
, sa
);
14747 gen_logic(ctx
, OPC_XOR
, 24, rx
, ry
);
14750 gen_arith(ctx
, OPC_SUBU
, rx
, 0, ry
);
14753 gen_logic(ctx
, OPC_AND
, rx
, rx
, ry
);
14756 gen_logic(ctx
, OPC_OR
, rx
, rx
, ry
);
14759 gen_logic(ctx
, OPC_XOR
, rx
, rx
, ry
);
14762 gen_logic(ctx
, OPC_NOR
, rx
, ry
, 0);
14765 gen_HILO(ctx
, OPC_MFHI
, 0, rx
);
14768 check_insn(ctx
, ISA_MIPS_R1
);
14770 case RR_RY_CNVT_ZEB
:
14771 tcg_gen_ext8u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
14773 case RR_RY_CNVT_ZEH
:
14774 tcg_gen_ext16u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
14776 case RR_RY_CNVT_SEB
:
14777 tcg_gen_ext8s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
14779 case RR_RY_CNVT_SEH
:
14780 tcg_gen_ext16s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
14782 #if defined(TARGET_MIPS64)
14783 case RR_RY_CNVT_ZEW
:
14784 check_insn(ctx
, ISA_MIPS_R1
);
14785 check_mips_64(ctx
);
14786 tcg_gen_ext32u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
14788 case RR_RY_CNVT_SEW
:
14789 check_insn(ctx
, ISA_MIPS_R1
);
14790 check_mips_64(ctx
);
14791 tcg_gen_ext32s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
14795 gen_reserved_instruction(ctx
);
14800 gen_HILO(ctx
, OPC_MFLO
, 0, rx
);
14802 #if defined(TARGET_MIPS64)
14804 check_insn(ctx
, ISA_MIPS3
);
14805 check_mips_64(ctx
);
14806 gen_shift_imm(ctx
, OPC_DSRA
, ry
, ry
, sa
);
14809 check_insn(ctx
, ISA_MIPS3
);
14810 check_mips_64(ctx
);
14811 gen_shift(ctx
, OPC_DSLLV
, ry
, rx
, ry
);
14814 check_insn(ctx
, ISA_MIPS3
);
14815 check_mips_64(ctx
);
14816 gen_shift(ctx
, OPC_DSRLV
, ry
, rx
, ry
);
14819 check_insn(ctx
, ISA_MIPS3
);
14820 check_mips_64(ctx
);
14821 gen_shift(ctx
, OPC_DSRAV
, ry
, rx
, ry
);
14825 gen_muldiv(ctx
, OPC_MULT
, 0, rx
, ry
);
14828 gen_muldiv(ctx
, OPC_MULTU
, 0, rx
, ry
);
14831 gen_muldiv(ctx
, OPC_DIV
, 0, rx
, ry
);
14834 gen_muldiv(ctx
, OPC_DIVU
, 0, rx
, ry
);
14836 #if defined(TARGET_MIPS64)
14838 check_insn(ctx
, ISA_MIPS3
);
14839 check_mips_64(ctx
);
14840 gen_muldiv(ctx
, OPC_DMULT
, 0, rx
, ry
);
14843 check_insn(ctx
, ISA_MIPS3
);
14844 check_mips_64(ctx
);
14845 gen_muldiv(ctx
, OPC_DMULTU
, 0, rx
, ry
);
14848 check_insn(ctx
, ISA_MIPS3
);
14849 check_mips_64(ctx
);
14850 gen_muldiv(ctx
, OPC_DDIV
, 0, rx
, ry
);
14853 check_insn(ctx
, ISA_MIPS3
);
14854 check_mips_64(ctx
);
14855 gen_muldiv(ctx
, OPC_DDIVU
, 0, rx
, ry
);
14859 gen_reserved_instruction(ctx
);
14863 case M16_OPC_EXTEND
:
14864 decode_extended_mips16_opc(env
, ctx
);
14867 #if defined(TARGET_MIPS64)
14869 funct
= (ctx
->opcode
>> 8) & 0x7;
14870 decode_i64_mips16(ctx
, ry
, funct
, offset
, 0);
14874 gen_reserved_instruction(ctx
);
14881 /* microMIPS extension to MIPS32/MIPS64 */
14884 * microMIPS32/microMIPS64 major opcodes
14886 * 1. MIPS Architecture for Programmers Volume II-B:
14887 * The microMIPS32 Instruction Set (Revision 3.05)
14889 * Table 6.2 microMIPS32 Encoding of Major Opcode Field
14891 * 2. MIPS Architecture For Programmers Volume II-A:
14892 * The MIPS64 Instruction Set (Revision 3.51)
14922 POOL32S
= 0x16, /* MIPS64 */
14923 DADDIU32
= 0x17, /* MIPS64 */
14952 /* 0x29 is reserved */
14965 /* 0x31 is reserved */
14978 SD32
= 0x36, /* MIPS64 */
14979 LD32
= 0x37, /* MIPS64 */
14981 /* 0x39 is reserved */
14997 /* PCREL Instructions perform PC-Relative address calculation. bits 20..16 */
15019 /* POOL32A encoding of minor opcode field */
15023 * These opcodes are distinguished only by bits 9..6; those bits are
15024 * what are recorded below.
15062 /* The following can be distinguished by their lower 6 bits. */
15072 /* POOL32AXF encoding of minor opcode field extension */
15075 * 1. MIPS Architecture for Programmers Volume II-B:
15076 * The microMIPS32 Instruction Set (Revision 3.05)
15078 * Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
15080 * 2. MIPS Architecture for Programmers VolumeIV-e:
15081 * The MIPS DSP Application-Specific Extension
15082 * to the microMIPS32 Architecture (Revision 2.34)
15084 * Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
15099 /* begin of microMIPS32 DSP */
15101 /* bits 13..12 for 0x01 */
15107 /* bits 13..12 for 0x2a */
15113 /* bits 13..12 for 0x32 */
15117 /* end of microMIPS32 DSP */
15119 /* bits 15..12 for 0x2c */
15136 /* bits 15..12 for 0x34 */
15144 /* bits 15..12 for 0x3c */
15146 JR
= 0x0, /* alias */
15154 /* bits 15..12 for 0x05 */
15158 /* bits 15..12 for 0x0d */
15170 /* bits 15..12 for 0x15 */
15176 /* bits 15..12 for 0x1d */
15180 /* bits 15..12 for 0x2d */
15185 /* bits 15..12 for 0x35 */
15192 /* POOL32B encoding of minor opcode field (bits 15..12) */
15208 /* POOL32C encoding of minor opcode field (bits 15..12) */
15229 /* POOL32C LD-EVA encoding of minor opcode field (bits 11..9) */
15242 /* POOL32C ST-EVA encoding of minor opcode field (bits 11..9) */
15255 /* POOL32F encoding of minor opcode field (bits 5..0) */
15258 /* These are the bit 7..6 values */
15267 /* These are the bit 8..6 values */
15292 MOVZ_FMT_05
= 0x05,
15326 CABS_COND_FMT
= 0x1c, /* MIPS3D */
15333 /* POOL32Fxf encoding of minor opcode extension field */
15371 /* POOL32I encoding of minor opcode field (bits 25..21) */
15401 /* These overlap and are distinguished by bit16 of the instruction */
15410 /* POOL16A encoding of minor opcode field */
15417 /* POOL16B encoding of minor opcode field */
15424 /* POOL16C encoding of minor opcode field */
15444 /* R6 POOL16C encoding of minor opcode field (bits 0..5) */
15468 /* POOL16D encoding of minor opcode field */
15475 /* POOL16E encoding of minor opcode field */
15482 static int mmreg(int r
)
15484 static const int map
[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
15489 /* Used for 16-bit store instructions. */
15490 static int mmreg2(int r
)
15492 static const int map
[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
15497 #define uMIPS_RD(op) ((op >> 7) & 0x7)
15498 #define uMIPS_RS(op) ((op >> 4) & 0x7)
15499 #define uMIPS_RS2(op) uMIPS_RS(op)
15500 #define uMIPS_RS1(op) ((op >> 1) & 0x7)
15501 #define uMIPS_RD5(op) ((op >> 5) & 0x1f)
15502 #define uMIPS_RS5(op) (op & 0x1f)
15504 /* Signed immediate */
15505 #define SIMM(op, start, width) \
15506 ((int32_t)(((op >> start) & ((~0U) >> (32 - width))) \
15509 /* Zero-extended immediate */
15510 #define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32 - width)))
15512 static void gen_addiur1sp(DisasContext
*ctx
)
15514 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
15516 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, 29, ((ctx
->opcode
>> 1) & 0x3f) << 2);
15519 static void gen_addiur2(DisasContext
*ctx
)
15521 static const int decoded_imm
[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
15522 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
15523 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
15525 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, rs
, decoded_imm
[ZIMM(ctx
->opcode
, 1, 3)]);
15528 static void gen_addiusp(DisasContext
*ctx
)
15530 int encoded
= ZIMM(ctx
->opcode
, 1, 9);
15533 if (encoded
<= 1) {
15534 decoded
= 256 + encoded
;
15535 } else if (encoded
<= 255) {
15537 } else if (encoded
<= 509) {
15538 decoded
= encoded
- 512;
15540 decoded
= encoded
- 768;
15543 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, decoded
<< 2);
15546 static void gen_addius5(DisasContext
*ctx
)
15548 int imm
= SIMM(ctx
->opcode
, 1, 4);
15549 int rd
= (ctx
->opcode
>> 5) & 0x1f;
15551 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, rd
, imm
);
15554 static void gen_andi16(DisasContext
*ctx
)
15556 static const int decoded_imm
[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
15557 31, 32, 63, 64, 255, 32768, 65535 };
15558 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
15559 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
15560 int encoded
= ZIMM(ctx
->opcode
, 0, 4);
15562 gen_logic_imm(ctx
, OPC_ANDI
, rd
, rs
, decoded_imm
[encoded
]);
15565 static void gen_ldst_multiple(DisasContext
*ctx
, uint32_t opc
, int reglist
,
15566 int base
, int16_t offset
)
15571 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
15572 gen_reserved_instruction(ctx
);
15576 t0
= tcg_temp_new();
15578 gen_base_offset_addr(ctx
, t0
, base
, offset
);
15580 t1
= tcg_const_tl(reglist
);
15581 t2
= tcg_const_i32(ctx
->mem_idx
);
15583 save_cpu_state(ctx
, 1);
15586 gen_helper_lwm(cpu_env
, t0
, t1
, t2
);
15589 gen_helper_swm(cpu_env
, t0
, t1
, t2
);
15591 #ifdef TARGET_MIPS64
15593 gen_helper_ldm(cpu_env
, t0
, t1
, t2
);
15596 gen_helper_sdm(cpu_env
, t0
, t1
, t2
);
15602 tcg_temp_free_i32(t2
);
15606 static void gen_pool16c_insn(DisasContext
*ctx
)
15608 int rd
= mmreg((ctx
->opcode
>> 3) & 0x7);
15609 int rs
= mmreg(ctx
->opcode
& 0x7);
15611 switch (((ctx
->opcode
) >> 4) & 0x3f) {
15616 gen_logic(ctx
, OPC_NOR
, rd
, rs
, 0);
15622 gen_logic(ctx
, OPC_XOR
, rd
, rd
, rs
);
15628 gen_logic(ctx
, OPC_AND
, rd
, rd
, rs
);
15634 gen_logic(ctx
, OPC_OR
, rd
, rd
, rs
);
15641 static const int lwm_convert
[] = { 0x11, 0x12, 0x13, 0x14 };
15642 int offset
= ZIMM(ctx
->opcode
, 0, 4);
15644 gen_ldst_multiple(ctx
, LWM32
, lwm_convert
[(ctx
->opcode
>> 4) & 0x3],
15653 static const int swm_convert
[] = { 0x11, 0x12, 0x13, 0x14 };
15654 int offset
= ZIMM(ctx
->opcode
, 0, 4);
15656 gen_ldst_multiple(ctx
, SWM32
, swm_convert
[(ctx
->opcode
>> 4) & 0x3],
15663 int reg
= ctx
->opcode
& 0x1f;
15665 gen_compute_branch(ctx
, OPC_JR
, 2, reg
, 0, 0, 4);
15671 int reg
= ctx
->opcode
& 0x1f;
15672 gen_compute_branch(ctx
, OPC_JR
, 2, reg
, 0, 0, 0);
15674 * Let normal delay slot handling in our caller take us
15675 * to the branch target.
15681 gen_compute_branch(ctx
, OPC_JALR
, 2, ctx
->opcode
& 0x1f, 31, 0, 4);
15682 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
15686 gen_compute_branch(ctx
, OPC_JALR
, 2, ctx
->opcode
& 0x1f, 31, 0, 2);
15687 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
15691 gen_HILO(ctx
, OPC_MFHI
, 0, uMIPS_RS5(ctx
->opcode
));
15695 gen_HILO(ctx
, OPC_MFLO
, 0, uMIPS_RS5(ctx
->opcode
));
15698 generate_exception_end(ctx
, EXCP_BREAK
);
15701 if (is_uhi(extract32(ctx
->opcode
, 0, 4))) {
15702 gen_helper_do_semihosting(cpu_env
);
15705 * XXX: not clear which exception should be raised
15706 * when in debug mode...
15708 check_insn(ctx
, ISA_MIPS_R1
);
15709 generate_exception_end(ctx
, EXCP_DBp
);
15712 case JRADDIUSP
+ 0:
15713 case JRADDIUSP
+ 1:
15715 int imm
= ZIMM(ctx
->opcode
, 0, 5);
15716 gen_compute_branch(ctx
, OPC_JR
, 2, 31, 0, 0, 0);
15717 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, imm
<< 2);
15719 * Let normal delay slot handling in our caller take us
15720 * to the branch target.
15725 gen_reserved_instruction(ctx
);
15730 static inline void gen_movep(DisasContext
*ctx
, int enc_dest
, int enc_rt
,
15733 int rd
, rs
, re
, rt
;
15734 static const int rd_enc
[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
15735 static const int re_enc
[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
15736 static const int rs_rt_enc
[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
15737 rd
= rd_enc
[enc_dest
];
15738 re
= re_enc
[enc_dest
];
15739 rs
= rs_rt_enc
[enc_rs
];
15740 rt
= rs_rt_enc
[enc_rt
];
15742 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
15744 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
15747 tcg_gen_mov_tl(cpu_gpr
[re
], cpu_gpr
[rt
]);
15749 tcg_gen_movi_tl(cpu_gpr
[re
], 0);
15753 static void gen_pool16c_r6_insn(DisasContext
*ctx
)
15755 int rt
= mmreg((ctx
->opcode
>> 7) & 0x7);
15756 int rs
= mmreg((ctx
->opcode
>> 4) & 0x7);
15758 switch (ctx
->opcode
& 0xf) {
15760 gen_logic(ctx
, OPC_NOR
, rt
, rs
, 0);
15763 gen_logic(ctx
, OPC_AND
, rt
, rt
, rs
);
15767 int lwm_converted
= 0x11 + extract32(ctx
->opcode
, 8, 2);
15768 int offset
= extract32(ctx
->opcode
, 4, 4);
15769 gen_ldst_multiple(ctx
, LWM32
, lwm_converted
, 29, offset
<< 2);
15772 case R6_JRC16
: /* JRCADDIUSP */
15773 if ((ctx
->opcode
>> 4) & 1) {
15775 int imm
= extract32(ctx
->opcode
, 5, 5);
15776 gen_compute_branch(ctx
, OPC_JR
, 2, 31, 0, 0, 0);
15777 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, imm
<< 2);
15780 rs
= extract32(ctx
->opcode
, 5, 5);
15781 gen_compute_branch(ctx
, OPC_JR
, 2, rs
, 0, 0, 0);
15793 int enc_dest
= uMIPS_RD(ctx
->opcode
);
15794 int enc_rt
= uMIPS_RS2(ctx
->opcode
);
15795 int enc_rs
= (ctx
->opcode
& 3) | ((ctx
->opcode
>> 1) & 4);
15796 gen_movep(ctx
, enc_dest
, enc_rt
, enc_rs
);
15800 gen_logic(ctx
, OPC_XOR
, rt
, rt
, rs
);
15803 gen_logic(ctx
, OPC_OR
, rt
, rt
, rs
);
15807 int swm_converted
= 0x11 + extract32(ctx
->opcode
, 8, 2);
15808 int offset
= extract32(ctx
->opcode
, 4, 4);
15809 gen_ldst_multiple(ctx
, SWM32
, swm_converted
, 29, offset
<< 2);
15812 case JALRC16
: /* BREAK16, SDBBP16 */
15813 switch (ctx
->opcode
& 0x3f) {
15815 case JALRC16
+ 0x20:
15817 gen_compute_branch(ctx
, OPC_JALR
, 2, (ctx
->opcode
>> 5) & 0x1f,
15822 generate_exception(ctx
, EXCP_BREAK
);
15826 if (is_uhi(extract32(ctx
->opcode
, 6, 4))) {
15827 gen_helper_do_semihosting(cpu_env
);
15829 if (ctx
->hflags
& MIPS_HFLAG_SBRI
) {
15830 generate_exception(ctx
, EXCP_RI
);
15832 generate_exception(ctx
, EXCP_DBp
);
15839 generate_exception(ctx
, EXCP_RI
);
15844 static void gen_ldxs(DisasContext
*ctx
, int base
, int index
, int rd
)
15846 TCGv t0
= tcg_temp_new();
15847 TCGv t1
= tcg_temp_new();
15849 gen_load_gpr(t0
, base
);
15852 gen_load_gpr(t1
, index
);
15853 tcg_gen_shli_tl(t1
, t1
, 2);
15854 gen_op_addr_add(ctx
, t0
, t1
, t0
);
15857 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TESL
);
15858 gen_store_gpr(t1
, rd
);
15864 static void gen_ldst_pair(DisasContext
*ctx
, uint32_t opc
, int rd
,
15865 int base
, int16_t offset
)
15869 if (ctx
->hflags
& MIPS_HFLAG_BMASK
|| rd
== 31) {
15870 gen_reserved_instruction(ctx
);
15874 t0
= tcg_temp_new();
15875 t1
= tcg_temp_new();
15877 gen_base_offset_addr(ctx
, t0
, base
, offset
);
15882 gen_reserved_instruction(ctx
);
15885 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TESL
);
15886 gen_store_gpr(t1
, rd
);
15887 tcg_gen_movi_tl(t1
, 4);
15888 gen_op_addr_add(ctx
, t0
, t0
, t1
);
15889 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TESL
);
15890 gen_store_gpr(t1
, rd
+ 1);
15893 gen_load_gpr(t1
, rd
);
15894 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
15895 tcg_gen_movi_tl(t1
, 4);
15896 gen_op_addr_add(ctx
, t0
, t0
, t1
);
15897 gen_load_gpr(t1
, rd
+ 1);
15898 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
15900 #ifdef TARGET_MIPS64
15903 gen_reserved_instruction(ctx
);
15906 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
15907 gen_store_gpr(t1
, rd
);
15908 tcg_gen_movi_tl(t1
, 8);
15909 gen_op_addr_add(ctx
, t0
, t0
, t1
);
15910 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
15911 gen_store_gpr(t1
, rd
+ 1);
15914 gen_load_gpr(t1
, rd
);
15915 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
15916 tcg_gen_movi_tl(t1
, 8);
15917 gen_op_addr_add(ctx
, t0
, t0
, t1
);
15918 gen_load_gpr(t1
, rd
+ 1);
15919 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
15927 static void gen_sync(int stype
)
15929 TCGBar tcg_mo
= TCG_BAR_SC
;
15932 case 0x4: /* SYNC_WMB */
15933 tcg_mo
|= TCG_MO_ST_ST
;
15935 case 0x10: /* SYNC_MB */
15936 tcg_mo
|= TCG_MO_ALL
;
15938 case 0x11: /* SYNC_ACQUIRE */
15939 tcg_mo
|= TCG_MO_LD_LD
| TCG_MO_LD_ST
;
15941 case 0x12: /* SYNC_RELEASE */
15942 tcg_mo
|= TCG_MO_ST_ST
| TCG_MO_LD_ST
;
15944 case 0x13: /* SYNC_RMB */
15945 tcg_mo
|= TCG_MO_LD_LD
;
15948 tcg_mo
|= TCG_MO_ALL
;
15952 tcg_gen_mb(tcg_mo
);
15955 static void gen_pool32axf(CPUMIPSState
*env
, DisasContext
*ctx
, int rt
, int rs
)
15957 int extension
= (ctx
->opcode
>> 6) & 0x3f;
15958 int minor
= (ctx
->opcode
>> 12) & 0xf;
15959 uint32_t mips32_op
;
15961 switch (extension
) {
15963 mips32_op
= OPC_TEQ
;
15966 mips32_op
= OPC_TGE
;
15969 mips32_op
= OPC_TGEU
;
15972 mips32_op
= OPC_TLT
;
15975 mips32_op
= OPC_TLTU
;
15978 mips32_op
= OPC_TNE
;
15980 gen_trap(ctx
, mips32_op
, rs
, rt
, -1);
15982 #ifndef CONFIG_USER_ONLY
15985 check_cp0_enabled(ctx
);
15987 /* Treat as NOP. */
15990 gen_mfc0(ctx
, cpu_gpr
[rt
], rs
, (ctx
->opcode
>> 11) & 0x7);
15994 check_cp0_enabled(ctx
);
15996 TCGv t0
= tcg_temp_new();
15998 gen_load_gpr(t0
, rt
);
15999 gen_mtc0(ctx
, t0
, rs
, (ctx
->opcode
>> 11) & 0x7);
16005 switch (minor
& 3) {
16007 gen_muldiv(ctx
, OPC_MADD
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
16010 gen_muldiv(ctx
, OPC_MADDU
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
16013 gen_muldiv(ctx
, OPC_MSUB
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
16016 gen_muldiv(ctx
, OPC_MSUBU
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
16019 goto pool32axf_invalid
;
16023 switch (minor
& 3) {
16025 gen_muldiv(ctx
, OPC_MULT
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
16028 gen_muldiv(ctx
, OPC_MULTU
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
16031 goto pool32axf_invalid
;
16037 check_insn(ctx
, ISA_MIPS_R6
);
16038 gen_bitswap(ctx
, OPC_BITSWAP
, rs
, rt
);
16041 gen_bshfl(ctx
, OPC_SEB
, rs
, rt
);
16044 gen_bshfl(ctx
, OPC_SEH
, rs
, rt
);
16047 mips32_op
= OPC_CLO
;
16050 mips32_op
= OPC_CLZ
;
16052 check_insn(ctx
, ISA_MIPS_R1
);
16053 gen_cl(ctx
, mips32_op
, rt
, rs
);
16056 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16057 gen_rdhwr(ctx
, rt
, rs
, 0);
16060 gen_bshfl(ctx
, OPC_WSBH
, rs
, rt
);
16063 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16064 mips32_op
= OPC_MULT
;
16067 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16068 mips32_op
= OPC_MULTU
;
16071 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16072 mips32_op
= OPC_DIV
;
16075 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16076 mips32_op
= OPC_DIVU
;
16079 check_insn(ctx
, ISA_MIPS_R1
);
16080 gen_muldiv(ctx
, mips32_op
, 0, rs
, rt
);
16083 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16084 mips32_op
= OPC_MADD
;
16087 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16088 mips32_op
= OPC_MADDU
;
16091 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16092 mips32_op
= OPC_MSUB
;
16095 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16096 mips32_op
= OPC_MSUBU
;
16098 check_insn(ctx
, ISA_MIPS_R1
);
16099 gen_muldiv(ctx
, mips32_op
, 0, rs
, rt
);
16102 goto pool32axf_invalid
;
16113 generate_exception_err(ctx
, EXCP_CpU
, 2);
16116 goto pool32axf_invalid
;
16121 case JALR
: /* JALRC */
16122 case JALR_HB
: /* JALRC_HB */
16123 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16124 /* JALRC, JALRC_HB */
16125 gen_compute_branch(ctx
, OPC_JALR
, 4, rs
, rt
, 0, 0);
16127 /* JALR, JALR_HB */
16128 gen_compute_branch(ctx
, OPC_JALR
, 4, rs
, rt
, 0, 4);
16129 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
16134 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16135 gen_compute_branch(ctx
, OPC_JALR
, 4, rs
, rt
, 0, 2);
16136 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
16139 goto pool32axf_invalid
;
16145 check_cp0_enabled(ctx
);
16146 check_insn(ctx
, ISA_MIPS_R2
);
16147 gen_load_srsgpr(rs
, rt
);
16150 check_cp0_enabled(ctx
);
16151 check_insn(ctx
, ISA_MIPS_R2
);
16152 gen_store_srsgpr(rs
, rt
);
16155 goto pool32axf_invalid
;
16158 #ifndef CONFIG_USER_ONLY
16162 mips32_op
= OPC_TLBP
;
16165 mips32_op
= OPC_TLBR
;
16168 mips32_op
= OPC_TLBWI
;
16171 mips32_op
= OPC_TLBWR
;
16174 mips32_op
= OPC_TLBINV
;
16177 mips32_op
= OPC_TLBINVF
;
16180 mips32_op
= OPC_WAIT
;
16183 mips32_op
= OPC_DERET
;
16186 mips32_op
= OPC_ERET
;
16188 gen_cp0(env
, ctx
, mips32_op
, rt
, rs
);
16191 goto pool32axf_invalid
;
16197 check_cp0_enabled(ctx
);
16199 TCGv t0
= tcg_temp_new();
16201 save_cpu_state(ctx
, 1);
16202 gen_helper_di(t0
, cpu_env
);
16203 gen_store_gpr(t0
, rs
);
16205 * Stop translation as we may have switched the execution
16208 ctx
->base
.is_jmp
= DISAS_STOP
;
16213 check_cp0_enabled(ctx
);
16215 TCGv t0
= tcg_temp_new();
16217 save_cpu_state(ctx
, 1);
16218 gen_helper_ei(t0
, cpu_env
);
16219 gen_store_gpr(t0
, rs
);
16221 * DISAS_STOP isn't sufficient, we need to ensure we break out
16222 * of translated code to check for pending interrupts.
16224 gen_save_pc(ctx
->base
.pc_next
+ 4);
16225 ctx
->base
.is_jmp
= DISAS_EXIT
;
16230 goto pool32axf_invalid
;
16237 gen_sync(extract32(ctx
->opcode
, 16, 5));
16240 generate_exception_end(ctx
, EXCP_SYSCALL
);
16243 if (is_uhi(extract32(ctx
->opcode
, 16, 10))) {
16244 gen_helper_do_semihosting(cpu_env
);
16246 check_insn(ctx
, ISA_MIPS_R1
);
16247 if (ctx
->hflags
& MIPS_HFLAG_SBRI
) {
16248 gen_reserved_instruction(ctx
);
16250 generate_exception_end(ctx
, EXCP_DBp
);
16255 goto pool32axf_invalid
;
16259 switch (minor
& 3) {
16261 gen_HILO(ctx
, OPC_MFHI
, minor
>> 2, rs
);
16264 gen_HILO(ctx
, OPC_MFLO
, minor
>> 2, rs
);
16267 gen_HILO(ctx
, OPC_MTHI
, minor
>> 2, rs
);
16270 gen_HILO(ctx
, OPC_MTLO
, minor
>> 2, rs
);
16273 goto pool32axf_invalid
;
16277 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16280 gen_HILO(ctx
, OPC_MFHI
, 0, rs
);
16283 gen_HILO(ctx
, OPC_MFLO
, 0, rs
);
16286 gen_HILO(ctx
, OPC_MTHI
, 0, rs
);
16289 gen_HILO(ctx
, OPC_MTLO
, 0, rs
);
16292 goto pool32axf_invalid
;
16297 MIPS_INVAL("pool32axf");
16298 gen_reserved_instruction(ctx
);
16304 * Values for microMIPS fmt field. Variable-width, depending on which
16305 * formats the instruction supports.
16324 static void gen_pool32fxf(DisasContext
*ctx
, int rt
, int rs
)
16326 int extension
= (ctx
->opcode
>> 6) & 0x3ff;
16327 uint32_t mips32_op
;
16329 #define FLOAT_1BIT_FMT(opc, fmt) ((fmt << 8) | opc)
16330 #define FLOAT_2BIT_FMT(opc, fmt) ((fmt << 7) | opc)
16331 #define COND_FLOAT_MOV(opc, cond) ((cond << 7) | opc)
16333 switch (extension
) {
16334 case FLOAT_1BIT_FMT(CFC1
, 0):
16335 mips32_op
= OPC_CFC1
;
16337 case FLOAT_1BIT_FMT(CTC1
, 0):
16338 mips32_op
= OPC_CTC1
;
16340 case FLOAT_1BIT_FMT(MFC1
, 0):
16341 mips32_op
= OPC_MFC1
;
16343 case FLOAT_1BIT_FMT(MTC1
, 0):
16344 mips32_op
= OPC_MTC1
;
16346 case FLOAT_1BIT_FMT(MFHC1
, 0):
16347 mips32_op
= OPC_MFHC1
;
16349 case FLOAT_1BIT_FMT(MTHC1
, 0):
16350 mips32_op
= OPC_MTHC1
;
16352 gen_cp1(ctx
, mips32_op
, rt
, rs
);
16355 /* Reciprocal square root */
16356 case FLOAT_1BIT_FMT(RSQRT_FMT
, FMT_SD_S
):
16357 mips32_op
= OPC_RSQRT_S
;
16359 case FLOAT_1BIT_FMT(RSQRT_FMT
, FMT_SD_D
):
16360 mips32_op
= OPC_RSQRT_D
;
16364 case FLOAT_1BIT_FMT(SQRT_FMT
, FMT_SD_S
):
16365 mips32_op
= OPC_SQRT_S
;
16367 case FLOAT_1BIT_FMT(SQRT_FMT
, FMT_SD_D
):
16368 mips32_op
= OPC_SQRT_D
;
16372 case FLOAT_1BIT_FMT(RECIP_FMT
, FMT_SD_S
):
16373 mips32_op
= OPC_RECIP_S
;
16375 case FLOAT_1BIT_FMT(RECIP_FMT
, FMT_SD_D
):
16376 mips32_op
= OPC_RECIP_D
;
16380 case FLOAT_1BIT_FMT(FLOOR_L
, FMT_SD_S
):
16381 mips32_op
= OPC_FLOOR_L_S
;
16383 case FLOAT_1BIT_FMT(FLOOR_L
, FMT_SD_D
):
16384 mips32_op
= OPC_FLOOR_L_D
;
16386 case FLOAT_1BIT_FMT(FLOOR_W
, FMT_SD_S
):
16387 mips32_op
= OPC_FLOOR_W_S
;
16389 case FLOAT_1BIT_FMT(FLOOR_W
, FMT_SD_D
):
16390 mips32_op
= OPC_FLOOR_W_D
;
16394 case FLOAT_1BIT_FMT(CEIL_L
, FMT_SD_S
):
16395 mips32_op
= OPC_CEIL_L_S
;
16397 case FLOAT_1BIT_FMT(CEIL_L
, FMT_SD_D
):
16398 mips32_op
= OPC_CEIL_L_D
;
16400 case FLOAT_1BIT_FMT(CEIL_W
, FMT_SD_S
):
16401 mips32_op
= OPC_CEIL_W_S
;
16403 case FLOAT_1BIT_FMT(CEIL_W
, FMT_SD_D
):
16404 mips32_op
= OPC_CEIL_W_D
;
16408 case FLOAT_1BIT_FMT(TRUNC_L
, FMT_SD_S
):
16409 mips32_op
= OPC_TRUNC_L_S
;
16411 case FLOAT_1BIT_FMT(TRUNC_L
, FMT_SD_D
):
16412 mips32_op
= OPC_TRUNC_L_D
;
16414 case FLOAT_1BIT_FMT(TRUNC_W
, FMT_SD_S
):
16415 mips32_op
= OPC_TRUNC_W_S
;
16417 case FLOAT_1BIT_FMT(TRUNC_W
, FMT_SD_D
):
16418 mips32_op
= OPC_TRUNC_W_D
;
16422 case FLOAT_1BIT_FMT(ROUND_L
, FMT_SD_S
):
16423 mips32_op
= OPC_ROUND_L_S
;
16425 case FLOAT_1BIT_FMT(ROUND_L
, FMT_SD_D
):
16426 mips32_op
= OPC_ROUND_L_D
;
16428 case FLOAT_1BIT_FMT(ROUND_W
, FMT_SD_S
):
16429 mips32_op
= OPC_ROUND_W_S
;
16431 case FLOAT_1BIT_FMT(ROUND_W
, FMT_SD_D
):
16432 mips32_op
= OPC_ROUND_W_D
;
16435 /* Integer to floating-point conversion */
16436 case FLOAT_1BIT_FMT(CVT_L
, FMT_SD_S
):
16437 mips32_op
= OPC_CVT_L_S
;
16439 case FLOAT_1BIT_FMT(CVT_L
, FMT_SD_D
):
16440 mips32_op
= OPC_CVT_L_D
;
16442 case FLOAT_1BIT_FMT(CVT_W
, FMT_SD_S
):
16443 mips32_op
= OPC_CVT_W_S
;
16445 case FLOAT_1BIT_FMT(CVT_W
, FMT_SD_D
):
16446 mips32_op
= OPC_CVT_W_D
;
16449 /* Paired-foo conversions */
16450 case FLOAT_1BIT_FMT(CVT_S_PL
, 0):
16451 mips32_op
= OPC_CVT_S_PL
;
16453 case FLOAT_1BIT_FMT(CVT_S_PU
, 0):
16454 mips32_op
= OPC_CVT_S_PU
;
16456 case FLOAT_1BIT_FMT(CVT_PW_PS
, 0):
16457 mips32_op
= OPC_CVT_PW_PS
;
16459 case FLOAT_1BIT_FMT(CVT_PS_PW
, 0):
16460 mips32_op
= OPC_CVT_PS_PW
;
16463 /* Floating-point moves */
16464 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_S
):
16465 mips32_op
= OPC_MOV_S
;
16467 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_D
):
16468 mips32_op
= OPC_MOV_D
;
16470 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_PS
):
16471 mips32_op
= OPC_MOV_PS
;
16474 /* Absolute value */
16475 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_S
):
16476 mips32_op
= OPC_ABS_S
;
16478 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_D
):
16479 mips32_op
= OPC_ABS_D
;
16481 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_PS
):
16482 mips32_op
= OPC_ABS_PS
;
16486 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_S
):
16487 mips32_op
= OPC_NEG_S
;
16489 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_D
):
16490 mips32_op
= OPC_NEG_D
;
16492 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_PS
):
16493 mips32_op
= OPC_NEG_PS
;
16496 /* Reciprocal square root step */
16497 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_S
):
16498 mips32_op
= OPC_RSQRT1_S
;
16500 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_D
):
16501 mips32_op
= OPC_RSQRT1_D
;
16503 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_PS
):
16504 mips32_op
= OPC_RSQRT1_PS
;
16507 /* Reciprocal step */
16508 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_S
):
16509 mips32_op
= OPC_RECIP1_S
;
16511 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_D
):
16512 mips32_op
= OPC_RECIP1_S
;
16514 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_PS
):
16515 mips32_op
= OPC_RECIP1_PS
;
16518 /* Conversions from double */
16519 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_S
):
16520 mips32_op
= OPC_CVT_D_S
;
16522 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_W
):
16523 mips32_op
= OPC_CVT_D_W
;
16525 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_L
):
16526 mips32_op
= OPC_CVT_D_L
;
16529 /* Conversions from single */
16530 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_D
):
16531 mips32_op
= OPC_CVT_S_D
;
16533 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_W
):
16534 mips32_op
= OPC_CVT_S_W
;
16536 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_L
):
16537 mips32_op
= OPC_CVT_S_L
;
16539 gen_farith(ctx
, mips32_op
, -1, rs
, rt
, 0);
16542 /* Conditional moves on floating-point codes */
16543 case COND_FLOAT_MOV(MOVT
, 0):
16544 case COND_FLOAT_MOV(MOVT
, 1):
16545 case COND_FLOAT_MOV(MOVT
, 2):
16546 case COND_FLOAT_MOV(MOVT
, 3):
16547 case COND_FLOAT_MOV(MOVT
, 4):
16548 case COND_FLOAT_MOV(MOVT
, 5):
16549 case COND_FLOAT_MOV(MOVT
, 6):
16550 case COND_FLOAT_MOV(MOVT
, 7):
16551 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16552 gen_movci(ctx
, rt
, rs
, (ctx
->opcode
>> 13) & 0x7, 1);
16554 case COND_FLOAT_MOV(MOVF
, 0):
16555 case COND_FLOAT_MOV(MOVF
, 1):
16556 case COND_FLOAT_MOV(MOVF
, 2):
16557 case COND_FLOAT_MOV(MOVF
, 3):
16558 case COND_FLOAT_MOV(MOVF
, 4):
16559 case COND_FLOAT_MOV(MOVF
, 5):
16560 case COND_FLOAT_MOV(MOVF
, 6):
16561 case COND_FLOAT_MOV(MOVF
, 7):
16562 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16563 gen_movci(ctx
, rt
, rs
, (ctx
->opcode
>> 13) & 0x7, 0);
16566 MIPS_INVAL("pool32fxf");
16567 gen_reserved_instruction(ctx
);
16572 static void decode_micromips32_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
16576 int rt
, rs
, rd
, rr
;
16578 uint32_t op
, minor
, minor2
, mips32_op
;
16579 uint32_t cond
, fmt
, cc
;
16581 insn
= cpu_lduw_code(env
, ctx
->base
.pc_next
+ 2);
16582 ctx
->opcode
= (ctx
->opcode
<< 16) | insn
;
16584 rt
= (ctx
->opcode
>> 21) & 0x1f;
16585 rs
= (ctx
->opcode
>> 16) & 0x1f;
16586 rd
= (ctx
->opcode
>> 11) & 0x1f;
16587 rr
= (ctx
->opcode
>> 6) & 0x1f;
16588 imm
= (int16_t) ctx
->opcode
;
16590 op
= (ctx
->opcode
>> 26) & 0x3f;
16593 minor
= ctx
->opcode
& 0x3f;
16596 minor
= (ctx
->opcode
>> 6) & 0xf;
16599 mips32_op
= OPC_SLL
;
16602 mips32_op
= OPC_SRA
;
16605 mips32_op
= OPC_SRL
;
16608 mips32_op
= OPC_ROTR
;
16610 gen_shift_imm(ctx
, mips32_op
, rt
, rs
, rd
);
16613 check_insn(ctx
, ISA_MIPS_R6
);
16614 gen_cond_move(ctx
, OPC_SELEQZ
, rd
, rs
, rt
);
16617 check_insn(ctx
, ISA_MIPS_R6
);
16618 gen_cond_move(ctx
, OPC_SELNEZ
, rd
, rs
, rt
);
16621 check_insn(ctx
, ISA_MIPS_R6
);
16622 gen_rdhwr(ctx
, rt
, rs
, extract32(ctx
->opcode
, 11, 3));
16625 goto pool32a_invalid
;
16629 minor
= (ctx
->opcode
>> 6) & 0xf;
16633 mips32_op
= OPC_ADD
;
16636 mips32_op
= OPC_ADDU
;
16639 mips32_op
= OPC_SUB
;
16642 mips32_op
= OPC_SUBU
;
16645 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16646 mips32_op
= OPC_MUL
;
16648 gen_arith(ctx
, mips32_op
, rd
, rs
, rt
);
16652 mips32_op
= OPC_SLLV
;
16655 mips32_op
= OPC_SRLV
;
16658 mips32_op
= OPC_SRAV
;
16661 mips32_op
= OPC_ROTRV
;
16663 gen_shift(ctx
, mips32_op
, rd
, rs
, rt
);
16665 /* Logical operations */
16667 mips32_op
= OPC_AND
;
16670 mips32_op
= OPC_OR
;
16673 mips32_op
= OPC_NOR
;
16676 mips32_op
= OPC_XOR
;
16678 gen_logic(ctx
, mips32_op
, rd
, rs
, rt
);
16680 /* Set less than */
16682 mips32_op
= OPC_SLT
;
16685 mips32_op
= OPC_SLTU
;
16687 gen_slt(ctx
, mips32_op
, rd
, rs
, rt
);
16690 goto pool32a_invalid
;
16694 minor
= (ctx
->opcode
>> 6) & 0xf;
16696 /* Conditional moves */
16697 case MOVN
: /* MUL */
16698 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16700 gen_r6_muldiv(ctx
, R6_OPC_MUL
, rd
, rs
, rt
);
16703 gen_cond_move(ctx
, OPC_MOVN
, rd
, rs
, rt
);
16706 case MOVZ
: /* MUH */
16707 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16709 gen_r6_muldiv(ctx
, R6_OPC_MUH
, rd
, rs
, rt
);
16712 gen_cond_move(ctx
, OPC_MOVZ
, rd
, rs
, rt
);
16716 check_insn(ctx
, ISA_MIPS_R6
);
16717 gen_r6_muldiv(ctx
, R6_OPC_MULU
, rd
, rs
, rt
);
16720 check_insn(ctx
, ISA_MIPS_R6
);
16721 gen_r6_muldiv(ctx
, R6_OPC_MUHU
, rd
, rs
, rt
);
16723 case LWXS
: /* DIV */
16724 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16726 gen_r6_muldiv(ctx
, R6_OPC_DIV
, rd
, rs
, rt
);
16729 gen_ldxs(ctx
, rs
, rt
, rd
);
16733 check_insn(ctx
, ISA_MIPS_R6
);
16734 gen_r6_muldiv(ctx
, R6_OPC_MOD
, rd
, rs
, rt
);
16737 check_insn(ctx
, ISA_MIPS_R6
);
16738 gen_r6_muldiv(ctx
, R6_OPC_DIVU
, rd
, rs
, rt
);
16741 check_insn(ctx
, ISA_MIPS_R6
);
16742 gen_r6_muldiv(ctx
, R6_OPC_MODU
, rd
, rs
, rt
);
16745 goto pool32a_invalid
;
16749 gen_bitops(ctx
, OPC_INS
, rt
, rs
, rr
, rd
);
16752 check_insn(ctx
, ISA_MIPS_R6
);
16753 gen_lsa(ctx
, OPC_LSA
, rd
, rs
, rt
,
16754 extract32(ctx
->opcode
, 9, 2));
16757 check_insn(ctx
, ISA_MIPS_R6
);
16758 gen_align(ctx
, 32, rd
, rs
, rt
, extract32(ctx
->opcode
, 9, 2));
16761 gen_bitops(ctx
, OPC_EXT
, rt
, rs
, rr
, rd
);
16764 gen_pool32axf(env
, ctx
, rt
, rs
);
16767 generate_exception_end(ctx
, EXCP_BREAK
);
16770 check_insn(ctx
, ISA_MIPS_R6
);
16771 gen_reserved_instruction(ctx
);
16775 MIPS_INVAL("pool32a");
16776 gen_reserved_instruction(ctx
);
16781 minor
= (ctx
->opcode
>> 12) & 0xf;
16784 check_cp0_enabled(ctx
);
16785 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
16786 gen_cache_operation(ctx
, rt
, rs
, imm
);
16791 /* COP2: Not implemented. */
16792 generate_exception_err(ctx
, EXCP_CpU
, 2);
16794 #ifdef TARGET_MIPS64
16797 check_insn(ctx
, ISA_MIPS3
);
16798 check_mips_64(ctx
);
16803 gen_ldst_pair(ctx
, minor
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
16805 #ifdef TARGET_MIPS64
16808 check_insn(ctx
, ISA_MIPS3
);
16809 check_mips_64(ctx
);
16814 gen_ldst_multiple(ctx
, minor
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
16817 MIPS_INVAL("pool32b");
16818 gen_reserved_instruction(ctx
);
16823 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
16824 minor
= ctx
->opcode
& 0x3f;
16825 check_cp1_enabled(ctx
);
16828 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16829 mips32_op
= OPC_ALNV_PS
;
16832 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16833 mips32_op
= OPC_MADD_S
;
16836 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16837 mips32_op
= OPC_MADD_D
;
16840 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16841 mips32_op
= OPC_MADD_PS
;
16844 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16845 mips32_op
= OPC_MSUB_S
;
16848 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16849 mips32_op
= OPC_MSUB_D
;
16852 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16853 mips32_op
= OPC_MSUB_PS
;
16856 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16857 mips32_op
= OPC_NMADD_S
;
16860 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16861 mips32_op
= OPC_NMADD_D
;
16864 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16865 mips32_op
= OPC_NMADD_PS
;
16868 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16869 mips32_op
= OPC_NMSUB_S
;
16872 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16873 mips32_op
= OPC_NMSUB_D
;
16876 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16877 mips32_op
= OPC_NMSUB_PS
;
16879 gen_flt3_arith(ctx
, mips32_op
, rd
, rr
, rs
, rt
);
16881 case CABS_COND_FMT
:
16882 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16883 cond
= (ctx
->opcode
>> 6) & 0xf;
16884 cc
= (ctx
->opcode
>> 13) & 0x7;
16885 fmt
= (ctx
->opcode
>> 10) & 0x3;
16888 gen_cmpabs_s(ctx
, cond
, rt
, rs
, cc
);
16891 gen_cmpabs_d(ctx
, cond
, rt
, rs
, cc
);
16894 gen_cmpabs_ps(ctx
, cond
, rt
, rs
, cc
);
16897 goto pool32f_invalid
;
16901 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16902 cond
= (ctx
->opcode
>> 6) & 0xf;
16903 cc
= (ctx
->opcode
>> 13) & 0x7;
16904 fmt
= (ctx
->opcode
>> 10) & 0x3;
16907 gen_cmp_s(ctx
, cond
, rt
, rs
, cc
);
16910 gen_cmp_d(ctx
, cond
, rt
, rs
, cc
);
16913 gen_cmp_ps(ctx
, cond
, rt
, rs
, cc
);
16916 goto pool32f_invalid
;
16920 check_insn(ctx
, ISA_MIPS_R6
);
16921 gen_r6_cmp_s(ctx
, (ctx
->opcode
>> 6) & 0x1f, rt
, rs
, rd
);
16924 check_insn(ctx
, ISA_MIPS_R6
);
16925 gen_r6_cmp_d(ctx
, (ctx
->opcode
>> 6) & 0x1f, rt
, rs
, rd
);
16928 gen_pool32fxf(ctx
, rt
, rs
);
16932 switch ((ctx
->opcode
>> 6) & 0x7) {
16934 mips32_op
= OPC_PLL_PS
;
16937 mips32_op
= OPC_PLU_PS
;
16940 mips32_op
= OPC_PUL_PS
;
16943 mips32_op
= OPC_PUU_PS
;
16946 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16947 mips32_op
= OPC_CVT_PS_S
;
16949 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
16952 goto pool32f_invalid
;
16956 check_insn(ctx
, ISA_MIPS_R6
);
16957 switch ((ctx
->opcode
>> 9) & 0x3) {
16959 gen_farith(ctx
, OPC_MIN_S
, rt
, rs
, rd
, 0);
16962 gen_farith(ctx
, OPC_MIN_D
, rt
, rs
, rd
, 0);
16965 goto pool32f_invalid
;
16970 switch ((ctx
->opcode
>> 6) & 0x7) {
16972 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16973 mips32_op
= OPC_LWXC1
;
16976 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16977 mips32_op
= OPC_SWXC1
;
16980 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16981 mips32_op
= OPC_LDXC1
;
16984 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16985 mips32_op
= OPC_SDXC1
;
16988 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16989 mips32_op
= OPC_LUXC1
;
16992 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16993 mips32_op
= OPC_SUXC1
;
16995 gen_flt3_ldst(ctx
, mips32_op
, rd
, rd
, rt
, rs
);
16998 goto pool32f_invalid
;
17002 check_insn(ctx
, ISA_MIPS_R6
);
17003 switch ((ctx
->opcode
>> 9) & 0x3) {
17005 gen_farith(ctx
, OPC_MAX_S
, rt
, rs
, rd
, 0);
17008 gen_farith(ctx
, OPC_MAX_D
, rt
, rs
, rd
, 0);
17011 goto pool32f_invalid
;
17016 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17017 fmt
= (ctx
->opcode
>> 9) & 0x3;
17018 switch ((ctx
->opcode
>> 6) & 0x7) {
17022 mips32_op
= OPC_RSQRT2_S
;
17025 mips32_op
= OPC_RSQRT2_D
;
17028 mips32_op
= OPC_RSQRT2_PS
;
17031 goto pool32f_invalid
;
17037 mips32_op
= OPC_RECIP2_S
;
17040 mips32_op
= OPC_RECIP2_D
;
17043 mips32_op
= OPC_RECIP2_PS
;
17046 goto pool32f_invalid
;
17050 mips32_op
= OPC_ADDR_PS
;
17053 mips32_op
= OPC_MULR_PS
;
17055 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
17058 goto pool32f_invalid
;
17062 /* MOV[FT].fmt, PREFX, RINT.fmt, CLASS.fmt*/
17063 cc
= (ctx
->opcode
>> 13) & 0x7;
17064 fmt
= (ctx
->opcode
>> 9) & 0x3;
17065 switch ((ctx
->opcode
>> 6) & 0x7) {
17066 case MOVF_FMT
: /* RINT_FMT */
17067 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
17071 gen_farith(ctx
, OPC_RINT_S
, 0, rt
, rs
, 0);
17074 gen_farith(ctx
, OPC_RINT_D
, 0, rt
, rs
, 0);
17077 goto pool32f_invalid
;
17083 gen_movcf_s(ctx
, rs
, rt
, cc
, 0);
17086 gen_movcf_d(ctx
, rs
, rt
, cc
, 0);
17090 gen_movcf_ps(ctx
, rs
, rt
, cc
, 0);
17093 goto pool32f_invalid
;
17097 case MOVT_FMT
: /* CLASS_FMT */
17098 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
17102 gen_farith(ctx
, OPC_CLASS_S
, 0, rt
, rs
, 0);
17105 gen_farith(ctx
, OPC_CLASS_D
, 0, rt
, rs
, 0);
17108 goto pool32f_invalid
;
17114 gen_movcf_s(ctx
, rs
, rt
, cc
, 1);
17117 gen_movcf_d(ctx
, rs
, rt
, cc
, 1);
17121 gen_movcf_ps(ctx
, rs
, rt
, cc
, 1);
17124 goto pool32f_invalid
;
17129 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17132 goto pool32f_invalid
;
17135 #define FINSN_3ARG_SDPS(prfx) \
17136 switch ((ctx->opcode >> 8) & 0x3) { \
17138 mips32_op = OPC_##prfx##_S; \
17141 mips32_op = OPC_##prfx##_D; \
17143 case FMT_SDPS_PS: \
17145 mips32_op = OPC_##prfx##_PS; \
17148 goto pool32f_invalid; \
17151 check_insn(ctx
, ISA_MIPS_R6
);
17152 switch ((ctx
->opcode
>> 9) & 0x3) {
17154 gen_farith(ctx
, OPC_MINA_S
, rt
, rs
, rd
, 0);
17157 gen_farith(ctx
, OPC_MINA_D
, rt
, rs
, rd
, 0);
17160 goto pool32f_invalid
;
17164 check_insn(ctx
, ISA_MIPS_R6
);
17165 switch ((ctx
->opcode
>> 9) & 0x3) {
17167 gen_farith(ctx
, OPC_MAXA_S
, rt
, rs
, rd
, 0);
17170 gen_farith(ctx
, OPC_MAXA_D
, rt
, rs
, rd
, 0);
17173 goto pool32f_invalid
;
17177 /* regular FP ops */
17178 switch ((ctx
->opcode
>> 6) & 0x3) {
17180 FINSN_3ARG_SDPS(ADD
);
17183 FINSN_3ARG_SDPS(SUB
);
17186 FINSN_3ARG_SDPS(MUL
);
17189 fmt
= (ctx
->opcode
>> 8) & 0x3;
17191 mips32_op
= OPC_DIV_D
;
17192 } else if (fmt
== 0) {
17193 mips32_op
= OPC_DIV_S
;
17195 goto pool32f_invalid
;
17199 goto pool32f_invalid
;
17204 switch ((ctx
->opcode
>> 6) & 0x7) {
17205 case MOVN_FMT
: /* SELEQZ_FMT */
17206 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
17208 switch ((ctx
->opcode
>> 9) & 0x3) {
17210 gen_sel_s(ctx
, OPC_SELEQZ_S
, rd
, rt
, rs
);
17213 gen_sel_d(ctx
, OPC_SELEQZ_D
, rd
, rt
, rs
);
17216 goto pool32f_invalid
;
17220 FINSN_3ARG_SDPS(MOVN
);
17224 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17225 FINSN_3ARG_SDPS(MOVN
);
17227 case MOVZ_FMT
: /* SELNEZ_FMT */
17228 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
17230 switch ((ctx
->opcode
>> 9) & 0x3) {
17232 gen_sel_s(ctx
, OPC_SELNEZ_S
, rd
, rt
, rs
);
17235 gen_sel_d(ctx
, OPC_SELNEZ_D
, rd
, rt
, rs
);
17238 goto pool32f_invalid
;
17242 FINSN_3ARG_SDPS(MOVZ
);
17246 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17247 FINSN_3ARG_SDPS(MOVZ
);
17250 check_insn(ctx
, ISA_MIPS_R6
);
17251 switch ((ctx
->opcode
>> 9) & 0x3) {
17253 gen_sel_s(ctx
, OPC_SEL_S
, rd
, rt
, rs
);
17256 gen_sel_d(ctx
, OPC_SEL_D
, rd
, rt
, rs
);
17259 goto pool32f_invalid
;
17263 check_insn(ctx
, ISA_MIPS_R6
);
17264 switch ((ctx
->opcode
>> 9) & 0x3) {
17266 mips32_op
= OPC_MADDF_S
;
17269 mips32_op
= OPC_MADDF_D
;
17272 goto pool32f_invalid
;
17276 check_insn(ctx
, ISA_MIPS_R6
);
17277 switch ((ctx
->opcode
>> 9) & 0x3) {
17279 mips32_op
= OPC_MSUBF_S
;
17282 mips32_op
= OPC_MSUBF_D
;
17285 goto pool32f_invalid
;
17289 goto pool32f_invalid
;
17293 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
17297 MIPS_INVAL("pool32f");
17298 gen_reserved_instruction(ctx
);
17302 generate_exception_err(ctx
, EXCP_CpU
, 1);
17306 minor
= (ctx
->opcode
>> 21) & 0x1f;
17309 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17310 gen_compute_branch(ctx
, OPC_BLTZ
, 4, rs
, -1, imm
<< 1, 4);
17313 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17314 gen_compute_branch(ctx
, OPC_BLTZAL
, 4, rs
, -1, imm
<< 1, 4);
17315 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
17318 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17319 gen_compute_branch(ctx
, OPC_BLTZAL
, 4, rs
, -1, imm
<< 1, 2);
17320 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
17323 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17324 gen_compute_branch(ctx
, OPC_BGEZ
, 4, rs
, -1, imm
<< 1, 4);
17327 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17328 gen_compute_branch(ctx
, OPC_BGEZAL
, 4, rs
, -1, imm
<< 1, 4);
17329 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
17332 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17333 gen_compute_branch(ctx
, OPC_BGEZAL
, 4, rs
, -1, imm
<< 1, 2);
17334 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
17337 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17338 gen_compute_branch(ctx
, OPC_BLEZ
, 4, rs
, -1, imm
<< 1, 4);
17341 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17342 gen_compute_branch(ctx
, OPC_BGTZ
, 4, rs
, -1, imm
<< 1, 4);
17346 case TLTI
: /* BC1EQZC */
17347 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
17349 check_cp1_enabled(ctx
);
17350 gen_compute_branch1_r6(ctx
, OPC_BC1EQZ
, rs
, imm
<< 1, 0);
17353 mips32_op
= OPC_TLTI
;
17357 case TGEI
: /* BC1NEZC */
17358 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
17360 check_cp1_enabled(ctx
);
17361 gen_compute_branch1_r6(ctx
, OPC_BC1NEZ
, rs
, imm
<< 1, 0);
17364 mips32_op
= OPC_TGEI
;
17369 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17370 mips32_op
= OPC_TLTIU
;
17373 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17374 mips32_op
= OPC_TGEIU
;
17376 case TNEI
: /* SYNCI */
17377 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
17380 * Break the TB to be able to sync copied instructions
17383 ctx
->base
.is_jmp
= DISAS_STOP
;
17386 mips32_op
= OPC_TNEI
;
17391 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17392 mips32_op
= OPC_TEQI
;
17394 gen_trap(ctx
, mips32_op
, rs
, -1, imm
);
17399 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17400 gen_compute_branch(ctx
, minor
== BNEZC
? OPC_BNE
: OPC_BEQ
,
17401 4, rs
, 0, imm
<< 1, 0);
17403 * Compact branches don't have a delay slot, so just let
17404 * the normal delay slot handling take us to the branch
17409 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17410 gen_logic_imm(ctx
, OPC_LUI
, rs
, 0, imm
);
17413 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17415 * Break the TB to be able to sync copied instructions
17418 ctx
->base
.is_jmp
= DISAS_STOP
;
17422 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17423 /* COP2: Not implemented. */
17424 generate_exception_err(ctx
, EXCP_CpU
, 2);
17427 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17428 mips32_op
= (ctx
->opcode
& (1 << 16)) ? OPC_BC1FANY2
: OPC_BC1F
;
17431 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17432 mips32_op
= (ctx
->opcode
& (1 << 16)) ? OPC_BC1TANY2
: OPC_BC1T
;
17435 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17436 mips32_op
= OPC_BC1FANY4
;
17439 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17440 mips32_op
= OPC_BC1TANY4
;
17443 check_insn(ctx
, ASE_MIPS3D
);
17446 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
17447 check_cp1_enabled(ctx
);
17448 gen_compute_branch1(ctx
, mips32_op
,
17449 (ctx
->opcode
>> 18) & 0x7, imm
<< 1);
17451 generate_exception_err(ctx
, EXCP_CpU
, 1);
17456 /* MIPS DSP: not implemented */
17459 MIPS_INVAL("pool32i");
17460 gen_reserved_instruction(ctx
);
17465 minor
= (ctx
->opcode
>> 12) & 0xf;
17466 offset
= sextract32(ctx
->opcode
, 0,
17467 (ctx
->insn_flags
& ISA_MIPS_R6
) ? 9 : 12);
17470 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17471 mips32_op
= OPC_LWL
;
17474 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17475 mips32_op
= OPC_SWL
;
17478 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17479 mips32_op
= OPC_LWR
;
17482 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17483 mips32_op
= OPC_SWR
;
17485 #if defined(TARGET_MIPS64)
17487 check_insn(ctx
, ISA_MIPS3
);
17488 check_mips_64(ctx
);
17489 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17490 mips32_op
= OPC_LDL
;
17493 check_insn(ctx
, ISA_MIPS3
);
17494 check_mips_64(ctx
);
17495 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17496 mips32_op
= OPC_SDL
;
17499 check_insn(ctx
, ISA_MIPS3
);
17500 check_mips_64(ctx
);
17501 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17502 mips32_op
= OPC_LDR
;
17505 check_insn(ctx
, ISA_MIPS3
);
17506 check_mips_64(ctx
);
17507 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17508 mips32_op
= OPC_SDR
;
17511 check_insn(ctx
, ISA_MIPS3
);
17512 check_mips_64(ctx
);
17513 mips32_op
= OPC_LWU
;
17516 check_insn(ctx
, ISA_MIPS3
);
17517 check_mips_64(ctx
);
17518 mips32_op
= OPC_LLD
;
17522 mips32_op
= OPC_LL
;
17525 gen_ld(ctx
, mips32_op
, rt
, rs
, offset
);
17528 gen_st(ctx
, mips32_op
, rt
, rs
, offset
);
17531 gen_st_cond(ctx
, rt
, rs
, offset
, MO_TESL
, false);
17533 #if defined(TARGET_MIPS64)
17535 check_insn(ctx
, ISA_MIPS3
);
17536 check_mips_64(ctx
);
17537 gen_st_cond(ctx
, rt
, rs
, offset
, MO_TEQ
, false);
17542 MIPS_INVAL("pool32c ld-eva");
17543 gen_reserved_instruction(ctx
);
17546 check_cp0_enabled(ctx
);
17548 minor2
= (ctx
->opcode
>> 9) & 0x7;
17549 offset
= sextract32(ctx
->opcode
, 0, 9);
17552 mips32_op
= OPC_LBUE
;
17555 mips32_op
= OPC_LHUE
;
17558 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17559 mips32_op
= OPC_LWLE
;
17562 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17563 mips32_op
= OPC_LWRE
;
17566 mips32_op
= OPC_LBE
;
17569 mips32_op
= OPC_LHE
;
17572 mips32_op
= OPC_LLE
;
17575 mips32_op
= OPC_LWE
;
17581 MIPS_INVAL("pool32c st-eva");
17582 gen_reserved_instruction(ctx
);
17585 check_cp0_enabled(ctx
);
17587 minor2
= (ctx
->opcode
>> 9) & 0x7;
17588 offset
= sextract32(ctx
->opcode
, 0, 9);
17591 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17592 mips32_op
= OPC_SWLE
;
17595 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17596 mips32_op
= OPC_SWRE
;
17599 /* Treat as no-op */
17600 if ((ctx
->insn_flags
& ISA_MIPS_R6
) && (rt
>= 24)) {
17601 /* hint codes 24-31 are reserved and signal RI */
17602 generate_exception(ctx
, EXCP_RI
);
17606 /* Treat as no-op */
17607 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
17608 gen_cache_operation(ctx
, rt
, rs
, offset
);
17612 mips32_op
= OPC_SBE
;
17615 mips32_op
= OPC_SHE
;
17618 gen_st_cond(ctx
, rt
, rs
, offset
, MO_TESL
, true);
17621 mips32_op
= OPC_SWE
;
17626 /* Treat as no-op */
17627 if ((ctx
->insn_flags
& ISA_MIPS_R6
) && (rt
>= 24)) {
17628 /* hint codes 24-31 are reserved and signal RI */
17629 generate_exception(ctx
, EXCP_RI
);
17633 MIPS_INVAL("pool32c");
17634 gen_reserved_instruction(ctx
);
17638 case ADDI32
: /* AUI, LUI */
17639 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
17641 gen_logic_imm(ctx
, OPC_LUI
, rt
, rs
, imm
);
17644 mips32_op
= OPC_ADDI
;
17649 mips32_op
= OPC_ADDIU
;
17651 gen_arith_imm(ctx
, mips32_op
, rt
, rs
, imm
);
17654 /* Logical operations */
17656 mips32_op
= OPC_ORI
;
17659 mips32_op
= OPC_XORI
;
17662 mips32_op
= OPC_ANDI
;
17664 gen_logic_imm(ctx
, mips32_op
, rt
, rs
, imm
);
17667 /* Set less than immediate */
17669 mips32_op
= OPC_SLTI
;
17672 mips32_op
= OPC_SLTIU
;
17674 gen_slt_imm(ctx
, mips32_op
, rt
, rs
, imm
);
17677 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17678 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
17679 gen_compute_branch(ctx
, OPC_JALX
, 4, rt
, rs
, offset
, 4);
17680 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
17682 case JALS32
: /* BOVC, BEQC, BEQZALC */
17683 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
17686 mips32_op
= OPC_BOVC
;
17687 } else if (rs
< rt
&& rs
== 0) {
17689 mips32_op
= OPC_BEQZALC
;
17692 mips32_op
= OPC_BEQC
;
17694 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
17697 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1;
17698 gen_compute_branch(ctx
, OPC_JAL
, 4, rt
, rs
, offset
, 2);
17699 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
17702 case BEQ32
: /* BC */
17703 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
17705 gen_compute_compact_branch(ctx
, OPC_BC
, 0, 0,
17706 sextract32(ctx
->opcode
<< 1, 0, 27));
17709 gen_compute_branch(ctx
, OPC_BEQ
, 4, rt
, rs
, imm
<< 1, 4);
17712 case BNE32
: /* BALC */
17713 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
17715 gen_compute_compact_branch(ctx
, OPC_BALC
, 0, 0,
17716 sextract32(ctx
->opcode
<< 1, 0, 27));
17719 gen_compute_branch(ctx
, OPC_BNE
, 4, rt
, rs
, imm
<< 1, 4);
17722 case J32
: /* BGTZC, BLTZC, BLTC */
17723 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
17724 if (rs
== 0 && rt
!= 0) {
17726 mips32_op
= OPC_BGTZC
;
17727 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
17729 mips32_op
= OPC_BLTZC
;
17732 mips32_op
= OPC_BLTC
;
17734 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
17737 gen_compute_branch(ctx
, OPC_J
, 4, rt
, rs
,
17738 (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1, 4);
17741 case JAL32
: /* BLEZC, BGEZC, BGEC */
17742 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
17743 if (rs
== 0 && rt
!= 0) {
17745 mips32_op
= OPC_BLEZC
;
17746 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
17748 mips32_op
= OPC_BGEZC
;
17751 mips32_op
= OPC_BGEC
;
17753 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
17756 gen_compute_branch(ctx
, OPC_JAL
, 4, rt
, rs
,
17757 (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1, 4);
17758 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
17761 /* Floating point (COP1) */
17763 mips32_op
= OPC_LWC1
;
17766 mips32_op
= OPC_LDC1
;
17769 mips32_op
= OPC_SWC1
;
17772 mips32_op
= OPC_SDC1
;
17774 gen_cop1_ldst(ctx
, mips32_op
, rt
, rs
, imm
);
17776 case ADDIUPC
: /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
17777 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
17778 /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
17779 switch ((ctx
->opcode
>> 16) & 0x1f) {
17788 gen_pcrel(ctx
, OPC_ADDIUPC
, ctx
->base
.pc_next
& ~0x3, rt
);
17791 gen_pcrel(ctx
, OPC_AUIPC
, ctx
->base
.pc_next
, rt
);
17794 gen_pcrel(ctx
, OPC_ALUIPC
, ctx
->base
.pc_next
, rt
);
17804 gen_pcrel(ctx
, R6_OPC_LWPC
, ctx
->base
.pc_next
& ~0x3, rt
);
17807 generate_exception(ctx
, EXCP_RI
);
17812 int reg
= mmreg(ZIMM(ctx
->opcode
, 23, 3));
17813 offset
= SIMM(ctx
->opcode
, 0, 23) << 2;
17815 gen_addiupc(ctx
, reg
, offset
, 0, 0);
17818 case BNVC
: /* BNEC, BNEZALC */
17819 check_insn(ctx
, ISA_MIPS_R6
);
17822 mips32_op
= OPC_BNVC
;
17823 } else if (rs
< rt
&& rs
== 0) {
17825 mips32_op
= OPC_BNEZALC
;
17828 mips32_op
= OPC_BNEC
;
17830 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
17832 case R6_BNEZC
: /* JIALC */
17833 check_insn(ctx
, ISA_MIPS_R6
);
17836 gen_compute_compact_branch(ctx
, OPC_BNEZC
, rt
, 0,
17837 sextract32(ctx
->opcode
<< 1, 0, 22));
17840 gen_compute_compact_branch(ctx
, OPC_JIALC
, 0, rs
, imm
);
17843 case R6_BEQZC
: /* JIC */
17844 check_insn(ctx
, ISA_MIPS_R6
);
17847 gen_compute_compact_branch(ctx
, OPC_BEQZC
, rt
, 0,
17848 sextract32(ctx
->opcode
<< 1, 0, 22));
17851 gen_compute_compact_branch(ctx
, OPC_JIC
, 0, rs
, imm
);
17854 case BLEZALC
: /* BGEZALC, BGEUC */
17855 check_insn(ctx
, ISA_MIPS_R6
);
17856 if (rs
== 0 && rt
!= 0) {
17858 mips32_op
= OPC_BLEZALC
;
17859 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
17861 mips32_op
= OPC_BGEZALC
;
17864 mips32_op
= OPC_BGEUC
;
17866 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
17868 case BGTZALC
: /* BLTZALC, BLTUC */
17869 check_insn(ctx
, ISA_MIPS_R6
);
17870 if (rs
== 0 && rt
!= 0) {
17872 mips32_op
= OPC_BGTZALC
;
17873 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
17875 mips32_op
= OPC_BLTZALC
;
17878 mips32_op
= OPC_BLTUC
;
17880 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
17882 /* Loads and stores */
17884 mips32_op
= OPC_LB
;
17887 mips32_op
= OPC_LBU
;
17890 mips32_op
= OPC_LH
;
17893 mips32_op
= OPC_LHU
;
17896 mips32_op
= OPC_LW
;
17898 #ifdef TARGET_MIPS64
17900 check_insn(ctx
, ISA_MIPS3
);
17901 check_mips_64(ctx
);
17902 mips32_op
= OPC_LD
;
17905 check_insn(ctx
, ISA_MIPS3
);
17906 check_mips_64(ctx
);
17907 mips32_op
= OPC_SD
;
17911 mips32_op
= OPC_SB
;
17914 mips32_op
= OPC_SH
;
17917 mips32_op
= OPC_SW
;
17920 gen_ld(ctx
, mips32_op
, rt
, rs
, imm
);
17923 gen_st(ctx
, mips32_op
, rt
, rs
, imm
);
17926 gen_reserved_instruction(ctx
);
17931 static int decode_micromips_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
17935 /* make sure instructions are on a halfword boundary */
17936 if (ctx
->base
.pc_next
& 0x1) {
17937 env
->CP0_BadVAddr
= ctx
->base
.pc_next
;
17938 generate_exception_end(ctx
, EXCP_AdEL
);
17942 op
= (ctx
->opcode
>> 10) & 0x3f;
17943 /* Enforce properly-sized instructions in a delay slot */
17944 if (ctx
->hflags
& MIPS_HFLAG_BDS_STRICT
) {
17945 switch (op
& 0x7) { /* MSB-3..MSB-5 */
17947 /* POOL32A, POOL32B, POOL32I, POOL32C */
17949 /* ADDI32, ADDIU32, ORI32, XORI32, SLTI32, SLTIU32, ANDI32, JALX32 */
17951 /* LBU32, LHU32, POOL32F, JALS32, BEQ32, BNE32, J32, JAL32 */
17953 /* SB32, SH32, ADDIUPC, SWC132, SDC132, SW32 */
17955 /* LB32, LH32, LWC132, LDC132, LW32 */
17956 if (ctx
->hflags
& MIPS_HFLAG_BDS16
) {
17957 gen_reserved_instruction(ctx
);
17962 /* POOL16A, POOL16B, POOL16C, LWGP16, POOL16F */
17964 /* LBU16, LHU16, LWSP16, LW16, SB16, SH16, SWSP16, SW16 */
17966 /* MOVE16, ANDI16, POOL16D, POOL16E, BEQZ16, BNEZ16, B16, LI16 */
17967 if (ctx
->hflags
& MIPS_HFLAG_BDS32
) {
17968 gen_reserved_instruction(ctx
);
17978 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
17979 int rs1
= mmreg(uMIPS_RS1(ctx
->opcode
));
17980 int rs2
= mmreg(uMIPS_RS2(ctx
->opcode
));
17983 switch (ctx
->opcode
& 0x1) {
17991 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
17993 * In the Release 6, the register number location in
17994 * the instruction encoding has changed.
17996 gen_arith(ctx
, opc
, rs1
, rd
, rs2
);
17998 gen_arith(ctx
, opc
, rd
, rs1
, rs2
);
18004 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
18005 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
18006 int amount
= (ctx
->opcode
>> 1) & 0x7;
18008 amount
= amount
== 0 ? 8 : amount
;
18010 switch (ctx
->opcode
& 0x1) {
18019 gen_shift_imm(ctx
, opc
, rd
, rs
, amount
);
18023 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
18024 gen_pool16c_r6_insn(ctx
);
18026 gen_pool16c_insn(ctx
);
18031 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
18032 int rb
= 28; /* GP */
18033 int16_t offset
= SIMM(ctx
->opcode
, 0, 7) << 2;
18035 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
18039 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
18040 if (ctx
->opcode
& 1) {
18041 gen_reserved_instruction(ctx
);
18044 int enc_dest
= uMIPS_RD(ctx
->opcode
);
18045 int enc_rt
= uMIPS_RS2(ctx
->opcode
);
18046 int enc_rs
= uMIPS_RS1(ctx
->opcode
);
18047 gen_movep(ctx
, enc_dest
, enc_rt
, enc_rs
);
18052 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
18053 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
18054 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4);
18055 offset
= (offset
== 0xf ? -1 : offset
);
18057 gen_ld(ctx
, OPC_LBU
, rd
, rb
, offset
);
18062 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
18063 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
18064 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 1;
18066 gen_ld(ctx
, OPC_LHU
, rd
, rb
, offset
);
18071 int rd
= (ctx
->opcode
>> 5) & 0x1f;
18072 int rb
= 29; /* SP */
18073 int16_t offset
= ZIMM(ctx
->opcode
, 0, 5) << 2;
18075 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
18080 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
18081 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
18082 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 2;
18084 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
18089 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
18090 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
18091 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4);
18093 gen_st(ctx
, OPC_SB
, rd
, rb
, offset
);
18098 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
18099 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
18100 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 1;
18102 gen_st(ctx
, OPC_SH
, rd
, rb
, offset
);
18107 int rd
= (ctx
->opcode
>> 5) & 0x1f;
18108 int rb
= 29; /* SP */
18109 int16_t offset
= ZIMM(ctx
->opcode
, 0, 5) << 2;
18111 gen_st(ctx
, OPC_SW
, rd
, rb
, offset
);
18116 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
18117 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
18118 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 2;
18120 gen_st(ctx
, OPC_SW
, rd
, rb
, offset
);
18125 int rd
= uMIPS_RD5(ctx
->opcode
);
18126 int rs
= uMIPS_RS5(ctx
->opcode
);
18128 gen_arith(ctx
, OPC_ADDU
, rd
, rs
, 0);
18135 switch (ctx
->opcode
& 0x1) {
18145 switch (ctx
->opcode
& 0x1) {
18150 gen_addiur1sp(ctx
);
18154 case B16
: /* BC16 */
18155 gen_compute_branch(ctx
, OPC_BEQ
, 2, 0, 0,
18156 sextract32(ctx
->opcode
, 0, 10) << 1,
18157 (ctx
->insn_flags
& ISA_MIPS_R6
) ? 0 : 4);
18159 case BNEZ16
: /* BNEZC16 */
18160 case BEQZ16
: /* BEQZC16 */
18161 gen_compute_branch(ctx
, op
== BNEZ16
? OPC_BNE
: OPC_BEQ
, 2,
18162 mmreg(uMIPS_RD(ctx
->opcode
)),
18163 0, sextract32(ctx
->opcode
, 0, 7) << 1,
18164 (ctx
->insn_flags
& ISA_MIPS_R6
) ? 0 : 4);
18169 int reg
= mmreg(uMIPS_RD(ctx
->opcode
));
18170 int imm
= ZIMM(ctx
->opcode
, 0, 7);
18172 imm
= (imm
== 0x7f ? -1 : imm
);
18173 tcg_gen_movi_tl(cpu_gpr
[reg
], imm
);
18179 gen_reserved_instruction(ctx
);
18182 decode_micromips32_opc(env
, ctx
);
18195 /* MAJOR, P16, and P32 pools opcodes */
18199 NM_MOVE_BALC
= 0x02,
18207 NM_P16_SHIFT
= 0x0c,
18225 NM_P_LS_U12
= 0x21,
18235 NM_P16_ADDU
= 0x2c,
18249 NM_MOVEPREV
= 0x3f,
18252 /* POOL32A instruction pool */
18254 NM_POOL32A0
= 0x00,
18255 NM_SPECIAL2
= 0x01,
18258 NM_POOL32A5
= 0x05,
18259 NM_POOL32A7
= 0x07,
18262 /* P.GP.W instruction pool */
18264 NM_ADDIUGP_W
= 0x00,
18269 /* P48I instruction pool */
18273 NM_ADDIUGP48
= 0x02,
18274 NM_ADDIUPC48
= 0x03,
18279 /* P.U12 instruction pool */
18288 NM_ADDIUNEG
= 0x08,
18295 /* POOL32F instruction pool */
18297 NM_POOL32F_0
= 0x00,
18298 NM_POOL32F_3
= 0x03,
18299 NM_POOL32F_5
= 0x05,
18302 /* POOL32S instruction pool */
18304 NM_POOL32S_0
= 0x00,
18305 NM_POOL32S_4
= 0x04,
18308 /* P.LUI instruction pool */
18314 /* P.GP.BH instruction pool */
18319 NM_ADDIUGP_B
= 0x03,
18322 NM_P_GP_CP1
= 0x06,
18325 /* P.LS.U12 instruction pool */
18330 NM_P_PREFU12
= 0x03,
18343 /* P.LS.S9 instruction pool */
18349 NM_P_LS_UAWM
= 0x05,
18352 /* P.BAL instruction pool */
18358 /* P.J instruction pool */
18361 NM_JALRC_HB
= 0x01,
18362 NM_P_BALRSC
= 0x08,
18365 /* P.BR1 instruction pool */
18373 /* P.BR2 instruction pool */
18380 /* P.BRI instruction pool */
18392 /* P16.SHIFT instruction pool */
18398 /* POOL16C instruction pool */
18400 NM_POOL16C_0
= 0x00,
18404 /* P16.A1 instruction pool */
18406 NM_ADDIUR1SP
= 0x01,
18409 /* P16.A2 instruction pool */
18412 NM_P_ADDIURS5
= 0x01,
18415 /* P16.ADDU instruction pool */
18421 /* P16.SR instruction pool */
18424 NM_RESTORE_JRC16
= 0x01,
18427 /* P16.4X4 instruction pool */
18433 /* P16.LB instruction pool */
18440 /* P16.LH instruction pool */
18447 /* P.RI instruction pool */
18450 NM_P_SYSCALL
= 0x01,
18455 /* POOL32A0 instruction pool */
18490 NM_D_E_MT_VPE
= 0x56,
18498 /* CRC32 instruction pool */
18508 /* POOL32A5 instruction pool */
18510 NM_CMP_EQ_PH
= 0x00,
18511 NM_CMP_LT_PH
= 0x08,
18512 NM_CMP_LE_PH
= 0x10,
18513 NM_CMPGU_EQ_QB
= 0x18,
18514 NM_CMPGU_LT_QB
= 0x20,
18515 NM_CMPGU_LE_QB
= 0x28,
18516 NM_CMPGDU_EQ_QB
= 0x30,
18517 NM_CMPGDU_LT_QB
= 0x38,
18518 NM_CMPGDU_LE_QB
= 0x40,
18519 NM_CMPU_EQ_QB
= 0x48,
18520 NM_CMPU_LT_QB
= 0x50,
18521 NM_CMPU_LE_QB
= 0x58,
18522 NM_ADDQ_S_W
= 0x60,
18523 NM_SUBQ_S_W
= 0x68,
18527 NM_ADDQ_S_PH
= 0x01,
18528 NM_ADDQH_R_PH
= 0x09,
18529 NM_ADDQH_R_W
= 0x11,
18530 NM_ADDU_S_QB
= 0x19,
18531 NM_ADDU_S_PH
= 0x21,
18532 NM_ADDUH_R_QB
= 0x29,
18533 NM_SHRAV_R_PH
= 0x31,
18534 NM_SHRAV_R_QB
= 0x39,
18535 NM_SUBQ_S_PH
= 0x41,
18536 NM_SUBQH_R_PH
= 0x49,
18537 NM_SUBQH_R_W
= 0x51,
18538 NM_SUBU_S_QB
= 0x59,
18539 NM_SUBU_S_PH
= 0x61,
18540 NM_SUBUH_R_QB
= 0x69,
18541 NM_SHLLV_S_PH
= 0x71,
18542 NM_PRECR_SRA_R_PH_W
= 0x79,
18544 NM_MULEU_S_PH_QBL
= 0x12,
18545 NM_MULEU_S_PH_QBR
= 0x1a,
18546 NM_MULQ_RS_PH
= 0x22,
18547 NM_MULQ_S_PH
= 0x2a,
18548 NM_MULQ_RS_W
= 0x32,
18549 NM_MULQ_S_W
= 0x3a,
18552 NM_SHRAV_R_W
= 0x5a,
18553 NM_SHRLV_PH
= 0x62,
18554 NM_SHRLV_QB
= 0x6a,
18555 NM_SHLLV_QB
= 0x72,
18556 NM_SHLLV_S_W
= 0x7a,
18560 NM_MULEQ_S_W_PHL
= 0x04,
18561 NM_MULEQ_S_W_PHR
= 0x0c,
18563 NM_MUL_S_PH
= 0x05,
18564 NM_PRECR_QB_PH
= 0x0d,
18565 NM_PRECRQ_QB_PH
= 0x15,
18566 NM_PRECRQ_PH_W
= 0x1d,
18567 NM_PRECRQ_RS_PH_W
= 0x25,
18568 NM_PRECRQU_S_QB_PH
= 0x2d,
18569 NM_PACKRL_PH
= 0x35,
18573 NM_SHRA_R_W
= 0x5e,
18574 NM_SHRA_R_PH
= 0x66,
18575 NM_SHLL_S_PH
= 0x76,
18576 NM_SHLL_S_W
= 0x7e,
18581 /* POOL32A7 instruction pool */
18586 NM_POOL32AXF
= 0x07,
18589 /* P.SR instruction pool */
18595 /* P.SHIFT instruction pool */
18603 /* P.ROTX instruction pool */
18608 /* P.INS instruction pool */
18613 /* P.EXT instruction pool */
18618 /* POOL32F_0 (fmt) instruction pool */
18623 NM_SELEQZ_S
= 0x07,
18624 NM_SELEQZ_D
= 0x47,
18628 NM_SELNEZ_S
= 0x0f,
18629 NM_SELNEZ_D
= 0x4f,
18644 /* POOL32F_3 instruction pool */
18648 NM_MINA_FMT
= 0x04,
18649 NM_MAXA_FMT
= 0x05,
18650 NM_POOL32FXF
= 0x07,
18653 /* POOL32F_5 instruction pool */
18655 NM_CMP_CONDN_S
= 0x00,
18656 NM_CMP_CONDN_D
= 0x02,
18659 /* P.GP.LH instruction pool */
18665 /* P.GP.SH instruction pool */
18670 /* P.GP.CP1 instruction pool */
18678 /* P.LS.S0 instruction pool */
18695 NM_P_PREFS9
= 0x03,
18701 /* P.LS.S1 instruction pool */
18703 NM_ASET_ACLR
= 0x02,
18711 /* P.LS.E0 instruction pool */
18727 /* P.PREFE instruction pool */
18733 /* P.LLE instruction pool */
18739 /* P.SCE instruction pool */
18745 /* P.LS.WM instruction pool */
18751 /* P.LS.UAWM instruction pool */
18757 /* P.BR3A instruction pool */
18763 NM_BPOSGE32C
= 0x04,
18766 /* P16.RI instruction pool */
18768 NM_P16_SYSCALL
= 0x01,
18773 /* POOL16C_0 instruction pool */
18775 NM_POOL16C_00
= 0x00,
18778 /* P16.JRC instruction pool */
18784 /* P.SYSCALL instruction pool */
18790 /* P.TRAP instruction pool */
18796 /* P.CMOVE instruction pool */
18802 /* POOL32Axf instruction pool */
18804 NM_POOL32AXF_1
= 0x01,
18805 NM_POOL32AXF_2
= 0x02,
18806 NM_POOL32AXF_4
= 0x04,
18807 NM_POOL32AXF_5
= 0x05,
18808 NM_POOL32AXF_7
= 0x07,
18811 /* POOL32Axf_1 instruction pool */
18813 NM_POOL32AXF_1_0
= 0x00,
18814 NM_POOL32AXF_1_1
= 0x01,
18815 NM_POOL32AXF_1_3
= 0x03,
18816 NM_POOL32AXF_1_4
= 0x04,
18817 NM_POOL32AXF_1_5
= 0x05,
18818 NM_POOL32AXF_1_7
= 0x07,
18821 /* POOL32Axf_2 instruction pool */
18823 NM_POOL32AXF_2_0_7
= 0x00,
18824 NM_POOL32AXF_2_8_15
= 0x01,
18825 NM_POOL32AXF_2_16_23
= 0x02,
18826 NM_POOL32AXF_2_24_31
= 0x03,
18829 /* POOL32Axf_7 instruction pool */
18831 NM_SHRA_R_QB
= 0x0,
18836 /* POOL32Axf_1_0 instruction pool */
18844 /* POOL32Axf_1_1 instruction pool */
18850 /* POOL32Axf_1_3 instruction pool */
18858 /* POOL32Axf_1_4 instruction pool */
18864 /* POOL32Axf_1_5 instruction pool */
18866 NM_MAQ_S_W_PHR
= 0x0,
18867 NM_MAQ_S_W_PHL
= 0x1,
18868 NM_MAQ_SA_W_PHR
= 0x2,
18869 NM_MAQ_SA_W_PHL
= 0x3,
18872 /* POOL32Axf_1_7 instruction pool */
18876 NM_EXTR_RS_W
= 0x2,
18880 /* POOL32Axf_2_0_7 instruction pool */
18883 NM_DPAQ_S_W_PH
= 0x1,
18885 NM_DPSQ_S_W_PH
= 0x3,
18892 /* POOL32Axf_2_8_15 instruction pool */
18894 NM_DPAX_W_PH
= 0x0,
18895 NM_DPAQ_SA_L_W
= 0x1,
18896 NM_DPSX_W_PH
= 0x2,
18897 NM_DPSQ_SA_L_W
= 0x3,
18900 NM_EXTRV_R_W
= 0x7,
18903 /* POOL32Axf_2_16_23 instruction pool */
18905 NM_DPAU_H_QBL
= 0x0,
18906 NM_DPAQX_S_W_PH
= 0x1,
18907 NM_DPSU_H_QBL
= 0x2,
18908 NM_DPSQX_S_W_PH
= 0x3,
18911 NM_MULSA_W_PH
= 0x6,
18912 NM_EXTRV_RS_W
= 0x7,
18915 /* POOL32Axf_2_24_31 instruction pool */
18917 NM_DPAU_H_QBR
= 0x0,
18918 NM_DPAQX_SA_W_PH
= 0x1,
18919 NM_DPSU_H_QBR
= 0x2,
18920 NM_DPSQX_SA_W_PH
= 0x3,
18923 NM_MULSAQ_S_W_PH
= 0x6,
18924 NM_EXTRV_S_H
= 0x7,
18927 /* POOL32Axf_{4, 5} instruction pool */
18946 /* nanoMIPS DSP instructions */
18947 NM_ABSQ_S_QB
= 0x00,
18948 NM_ABSQ_S_PH
= 0x08,
18949 NM_ABSQ_S_W
= 0x10,
18950 NM_PRECEQ_W_PHL
= 0x28,
18951 NM_PRECEQ_W_PHR
= 0x30,
18952 NM_PRECEQU_PH_QBL
= 0x38,
18953 NM_PRECEQU_PH_QBR
= 0x48,
18954 NM_PRECEU_PH_QBL
= 0x58,
18955 NM_PRECEU_PH_QBR
= 0x68,
18956 NM_PRECEQU_PH_QBLA
= 0x39,
18957 NM_PRECEQU_PH_QBRA
= 0x49,
18958 NM_PRECEU_PH_QBLA
= 0x59,
18959 NM_PRECEU_PH_QBRA
= 0x69,
18960 NM_REPLV_PH
= 0x01,
18961 NM_REPLV_QB
= 0x09,
18964 NM_RADDU_W_QB
= 0x78,
18970 /* PP.SR instruction pool */
18974 NM_RESTORE_JRC
= 0x03,
18977 /* P.SR.F instruction pool */
18980 NM_RESTOREF
= 0x01,
18983 /* P16.SYSCALL instruction pool */
18985 NM_SYSCALL16
= 0x00,
18986 NM_HYPCALL16
= 0x01,
18989 /* POOL16C_00 instruction pool */
18997 /* PP.LSX and PP.LSXS instruction pool */
19035 /* ERETx instruction pool */
19041 /* POOL32FxF_{0, 1} insturction pool */
19050 NM_CVT_S_PL
= 0x84,
19051 NM_CVT_S_PU
= 0xa4,
19053 NM_CVT_L_S
= 0x004,
19054 NM_CVT_L_D
= 0x104,
19055 NM_CVT_W_S
= 0x024,
19056 NM_CVT_W_D
= 0x124,
19058 NM_RSQRT_S
= 0x008,
19059 NM_RSQRT_D
= 0x108,
19064 NM_RECIP_S
= 0x048,
19065 NM_RECIP_D
= 0x148,
19067 NM_FLOOR_L_S
= 0x00c,
19068 NM_FLOOR_L_D
= 0x10c,
19070 NM_FLOOR_W_S
= 0x02c,
19071 NM_FLOOR_W_D
= 0x12c,
19073 NM_CEIL_L_S
= 0x04c,
19074 NM_CEIL_L_D
= 0x14c,
19075 NM_CEIL_W_S
= 0x06c,
19076 NM_CEIL_W_D
= 0x16c,
19077 NM_TRUNC_L_S
= 0x08c,
19078 NM_TRUNC_L_D
= 0x18c,
19079 NM_TRUNC_W_S
= 0x0ac,
19080 NM_TRUNC_W_D
= 0x1ac,
19081 NM_ROUND_L_S
= 0x0cc,
19082 NM_ROUND_L_D
= 0x1cc,
19083 NM_ROUND_W_S
= 0x0ec,
19084 NM_ROUND_W_D
= 0x1ec,
19092 NM_CVT_D_S
= 0x04d,
19093 NM_CVT_D_W
= 0x0cd,
19094 NM_CVT_D_L
= 0x14d,
19095 NM_CVT_S_D
= 0x06d,
19096 NM_CVT_S_W
= 0x0ed,
19097 NM_CVT_S_L
= 0x16d,
19100 /* P.LL instruction pool */
19106 /* P.SC instruction pool */
19112 /* P.DVP instruction pool */
19121 * nanoMIPS decoding engine
19126 /* extraction utilities */
19128 #define NANOMIPS_EXTRACT_RT3(op) ((op >> 7) & 0x7)
19129 #define NANOMIPS_EXTRACT_RS3(op) ((op >> 4) & 0x7)
19130 #define NANOMIPS_EXTRACT_RD3(op) ((op >> 1) & 0x7)
19131 #define NANOMIPS_EXTRACT_RD5(op) ((op >> 5) & 0x1f)
19132 #define NANOMIPS_EXTRACT_RS5(op) (op & 0x1f)
19134 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3'). */
19135 static inline int decode_gpr_gpr3(int r
)
19137 static const int map
[] = { 16, 17, 18, 19, 4, 5, 6, 7 };
19139 return map
[r
& 0x7];
19142 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3.src.store'). */
19143 static inline int decode_gpr_gpr3_src_store(int r
)
19145 static const int map
[] = { 0, 17, 18, 19, 4, 5, 6, 7 };
19147 return map
[r
& 0x7];
19150 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4'). */
19151 static inline int decode_gpr_gpr4(int r
)
19153 static const int map
[] = { 8, 9, 10, 11, 4, 5, 6, 7,
19154 16, 17, 18, 19, 20, 21, 22, 23 };
19156 return map
[r
& 0xf];
19159 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4.zero'). */
19160 static inline int decode_gpr_gpr4_zero(int r
)
19162 static const int map
[] = { 8, 9, 10, 0, 4, 5, 6, 7,
19163 16, 17, 18, 19, 20, 21, 22, 23 };
19165 return map
[r
& 0xf];
19169 static void gen_adjust_sp(DisasContext
*ctx
, int u
)
19171 gen_op_addr_addi(ctx
, cpu_gpr
[29], cpu_gpr
[29], u
);
19174 static void gen_save(DisasContext
*ctx
, uint8_t rt
, uint8_t count
,
19175 uint8_t gp
, uint16_t u
)
19178 TCGv va
= tcg_temp_new();
19179 TCGv t0
= tcg_temp_new();
19181 while (counter
!= count
) {
19182 bool use_gp
= gp
&& (counter
== count
- 1);
19183 int this_rt
= use_gp
? 28 : (rt
& 0x10) | ((rt
+ counter
) & 0x1f);
19184 int this_offset
= -((counter
+ 1) << 2);
19185 gen_base_offset_addr(ctx
, va
, 29, this_offset
);
19186 gen_load_gpr(t0
, this_rt
);
19187 tcg_gen_qemu_st_tl(t0
, va
, ctx
->mem_idx
,
19188 (MO_TEUL
| ctx
->default_tcg_memop_mask
));
19192 /* adjust stack pointer */
19193 gen_adjust_sp(ctx
, -u
);
19199 static void gen_restore(DisasContext
*ctx
, uint8_t rt
, uint8_t count
,
19200 uint8_t gp
, uint16_t u
)
19203 TCGv va
= tcg_temp_new();
19204 TCGv t0
= tcg_temp_new();
19206 while (counter
!= count
) {
19207 bool use_gp
= gp
&& (counter
== count
- 1);
19208 int this_rt
= use_gp
? 28 : (rt
& 0x10) | ((rt
+ counter
) & 0x1f);
19209 int this_offset
= u
- ((counter
+ 1) << 2);
19210 gen_base_offset_addr(ctx
, va
, 29, this_offset
);
19211 tcg_gen_qemu_ld_tl(t0
, va
, ctx
->mem_idx
, MO_TESL
|
19212 ctx
->default_tcg_memop_mask
);
19213 tcg_gen_ext32s_tl(t0
, t0
);
19214 gen_store_gpr(t0
, this_rt
);
19218 /* adjust stack pointer */
19219 gen_adjust_sp(ctx
, u
);
19225 static void gen_pool16c_nanomips_insn(DisasContext
*ctx
)
19227 int rt
= decode_gpr_gpr3(NANOMIPS_EXTRACT_RT3(ctx
->opcode
));
19228 int rs
= decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx
->opcode
));
19230 switch (extract32(ctx
->opcode
, 2, 2)) {
19232 gen_logic(ctx
, OPC_NOR
, rt
, rs
, 0);
19235 gen_logic(ctx
, OPC_AND
, rt
, rt
, rs
);
19238 gen_logic(ctx
, OPC_XOR
, rt
, rt
, rs
);
19241 gen_logic(ctx
, OPC_OR
, rt
, rt
, rs
);
19246 static void gen_pool32a0_nanomips_insn(CPUMIPSState
*env
, DisasContext
*ctx
)
19248 int rt
= extract32(ctx
->opcode
, 21, 5);
19249 int rs
= extract32(ctx
->opcode
, 16, 5);
19250 int rd
= extract32(ctx
->opcode
, 11, 5);
19252 switch (extract32(ctx
->opcode
, 3, 7)) {
19254 switch (extract32(ctx
->opcode
, 10, 1)) {
19257 gen_trap(ctx
, OPC_TEQ
, rs
, rt
, -1);
19261 gen_trap(ctx
, OPC_TNE
, rs
, rt
, -1);
19267 gen_rdhwr(ctx
, rt
, rs
, extract32(ctx
->opcode
, 11, 3));
19271 gen_bshfl(ctx
, OPC_SEB
, rs
, rt
);
19274 gen_bshfl(ctx
, OPC_SEH
, rs
, rt
);
19277 gen_shift(ctx
, OPC_SLLV
, rd
, rt
, rs
);
19280 gen_shift(ctx
, OPC_SRLV
, rd
, rt
, rs
);
19283 gen_shift(ctx
, OPC_SRAV
, rd
, rt
, rs
);
19286 gen_shift(ctx
, OPC_ROTRV
, rd
, rt
, rs
);
19289 gen_arith(ctx
, OPC_ADD
, rd
, rs
, rt
);
19292 gen_arith(ctx
, OPC_ADDU
, rd
, rs
, rt
);
19296 gen_arith(ctx
, OPC_SUB
, rd
, rs
, rt
);
19299 gen_arith(ctx
, OPC_SUBU
, rd
, rs
, rt
);
19302 switch (extract32(ctx
->opcode
, 10, 1)) {
19304 gen_cond_move(ctx
, OPC_MOVZ
, rd
, rs
, rt
);
19307 gen_cond_move(ctx
, OPC_MOVN
, rd
, rs
, rt
);
19312 gen_logic(ctx
, OPC_AND
, rd
, rs
, rt
);
19315 gen_logic(ctx
, OPC_OR
, rd
, rs
, rt
);
19318 gen_logic(ctx
, OPC_NOR
, rd
, rs
, rt
);
19321 gen_logic(ctx
, OPC_XOR
, rd
, rs
, rt
);
19324 gen_slt(ctx
, OPC_SLT
, rd
, rs
, rt
);
19329 #ifndef CONFIG_USER_ONLY
19330 TCGv t0
= tcg_temp_new();
19331 switch (extract32(ctx
->opcode
, 10, 1)) {
19334 check_cp0_enabled(ctx
);
19335 gen_helper_dvp(t0
, cpu_env
);
19336 gen_store_gpr(t0
, rt
);
19341 check_cp0_enabled(ctx
);
19342 gen_helper_evp(t0
, cpu_env
);
19343 gen_store_gpr(t0
, rt
);
19350 gen_slt(ctx
, OPC_SLTU
, rd
, rs
, rt
);
19355 TCGv t0
= tcg_temp_new();
19356 TCGv t1
= tcg_temp_new();
19357 TCGv t2
= tcg_temp_new();
19359 gen_load_gpr(t1
, rs
);
19360 gen_load_gpr(t2
, rt
);
19361 tcg_gen_add_tl(t0
, t1
, t2
);
19362 tcg_gen_ext32s_tl(t0
, t0
);
19363 tcg_gen_xor_tl(t1
, t1
, t2
);
19364 tcg_gen_xor_tl(t2
, t0
, t2
);
19365 tcg_gen_andc_tl(t1
, t2
, t1
);
19367 /* operands of same sign, result different sign */
19368 tcg_gen_setcondi_tl(TCG_COND_LT
, t0
, t1
, 0);
19369 gen_store_gpr(t0
, rd
);
19377 gen_r6_muldiv(ctx
, R6_OPC_MUL
, rd
, rs
, rt
);
19380 gen_r6_muldiv(ctx
, R6_OPC_MUH
, rd
, rs
, rt
);
19383 gen_r6_muldiv(ctx
, R6_OPC_MULU
, rd
, rs
, rt
);
19386 gen_r6_muldiv(ctx
, R6_OPC_MUHU
, rd
, rs
, rt
);
19389 gen_r6_muldiv(ctx
, R6_OPC_DIV
, rd
, rs
, rt
);
19392 gen_r6_muldiv(ctx
, R6_OPC_MOD
, rd
, rs
, rt
);
19395 gen_r6_muldiv(ctx
, R6_OPC_DIVU
, rd
, rs
, rt
);
19398 gen_r6_muldiv(ctx
, R6_OPC_MODU
, rd
, rs
, rt
);
19400 #ifndef CONFIG_USER_ONLY
19402 check_cp0_enabled(ctx
);
19404 /* Treat as NOP. */
19407 gen_mfc0(ctx
, cpu_gpr
[rt
], rs
, extract32(ctx
->opcode
, 11, 3));
19410 check_cp0_enabled(ctx
);
19412 TCGv t0
= tcg_temp_new();
19414 gen_load_gpr(t0
, rt
);
19415 gen_mtc0(ctx
, t0
, rs
, extract32(ctx
->opcode
, 11, 3));
19419 case NM_D_E_MT_VPE
:
19421 uint8_t sc
= extract32(ctx
->opcode
, 10, 1);
19422 TCGv t0
= tcg_temp_new();
19429 gen_helper_dmt(t0
);
19430 gen_store_gpr(t0
, rt
);
19431 } else if (rs
== 0) {
19434 gen_helper_dvpe(t0
, cpu_env
);
19435 gen_store_gpr(t0
, rt
);
19437 gen_reserved_instruction(ctx
);
19444 gen_helper_emt(t0
);
19445 gen_store_gpr(t0
, rt
);
19446 } else if (rs
== 0) {
19449 gen_helper_evpe(t0
, cpu_env
);
19450 gen_store_gpr(t0
, rt
);
19452 gen_reserved_instruction(ctx
);
19463 TCGv t0
= tcg_temp_new();
19464 TCGv t1
= tcg_temp_new();
19466 gen_load_gpr(t0
, rt
);
19467 gen_load_gpr(t1
, rs
);
19468 gen_helper_fork(t0
, t1
);
19475 check_cp0_enabled(ctx
);
19477 /* Treat as NOP. */
19480 gen_mftr(env
, ctx
, rs
, rt
, extract32(ctx
->opcode
, 10, 1),
19481 extract32(ctx
->opcode
, 11, 5), extract32(ctx
->opcode
, 3, 1));
19485 check_cp0_enabled(ctx
);
19486 gen_mttr(env
, ctx
, rs
, rt
, extract32(ctx
->opcode
, 10, 1),
19487 extract32(ctx
->opcode
, 11, 5), extract32(ctx
->opcode
, 3, 1));
19492 TCGv t0
= tcg_temp_new();
19494 gen_load_gpr(t0
, rs
);
19495 gen_helper_yield(t0
, cpu_env
, t0
);
19496 gen_store_gpr(t0
, rt
);
19502 gen_reserved_instruction(ctx
);
19508 static void gen_pool32axf_1_5_nanomips_insn(DisasContext
*ctx
, uint32_t opc
,
19509 int ret
, int v1
, int v2
)
19515 t0
= tcg_temp_new_i32();
19517 v0_t
= tcg_temp_new();
19518 v1_t
= tcg_temp_new();
19520 tcg_gen_movi_i32(t0
, v2
>> 3);
19522 gen_load_gpr(v0_t
, ret
);
19523 gen_load_gpr(v1_t
, v1
);
19526 case NM_MAQ_S_W_PHR
:
19528 gen_helper_maq_s_w_phr(t0
, v1_t
, v0_t
, cpu_env
);
19530 case NM_MAQ_S_W_PHL
:
19532 gen_helper_maq_s_w_phl(t0
, v1_t
, v0_t
, cpu_env
);
19534 case NM_MAQ_SA_W_PHR
:
19536 gen_helper_maq_sa_w_phr(t0
, v1_t
, v0_t
, cpu_env
);
19538 case NM_MAQ_SA_W_PHL
:
19540 gen_helper_maq_sa_w_phl(t0
, v1_t
, v0_t
, cpu_env
);
19543 gen_reserved_instruction(ctx
);
19547 tcg_temp_free_i32(t0
);
19549 tcg_temp_free(v0_t
);
19550 tcg_temp_free(v1_t
);
19554 static void gen_pool32axf_1_nanomips_insn(DisasContext
*ctx
, uint32_t opc
,
19555 int ret
, int v1
, int v2
)
19558 TCGv t0
= tcg_temp_new();
19559 TCGv t1
= tcg_temp_new();
19560 TCGv v0_t
= tcg_temp_new();
19562 gen_load_gpr(v0_t
, v1
);
19565 case NM_POOL32AXF_1_0
:
19567 switch (extract32(ctx
->opcode
, 12, 2)) {
19569 gen_HILO(ctx
, OPC_MFHI
, v2
>> 3, ret
);
19572 gen_HILO(ctx
, OPC_MFLO
, v2
>> 3, ret
);
19575 gen_HILO(ctx
, OPC_MTHI
, v2
>> 3, v1
);
19578 gen_HILO(ctx
, OPC_MTLO
, v2
>> 3, v1
);
19582 case NM_POOL32AXF_1_1
:
19584 switch (extract32(ctx
->opcode
, 12, 2)) {
19586 tcg_gen_movi_tl(t0
, v2
);
19587 gen_helper_mthlip(t0
, v0_t
, cpu_env
);
19590 tcg_gen_movi_tl(t0
, v2
>> 3);
19591 gen_helper_shilo(t0
, v0_t
, cpu_env
);
19594 gen_reserved_instruction(ctx
);
19598 case NM_POOL32AXF_1_3
:
19600 imm
= extract32(ctx
->opcode
, 14, 7);
19601 switch (extract32(ctx
->opcode
, 12, 2)) {
19603 tcg_gen_movi_tl(t0
, imm
);
19604 gen_helper_rddsp(t0
, t0
, cpu_env
);
19605 gen_store_gpr(t0
, ret
);
19608 gen_load_gpr(t0
, ret
);
19609 tcg_gen_movi_tl(t1
, imm
);
19610 gen_helper_wrdsp(t0
, t1
, cpu_env
);
19613 tcg_gen_movi_tl(t0
, v2
>> 3);
19614 tcg_gen_movi_tl(t1
, v1
);
19615 gen_helper_extp(t0
, t0
, t1
, cpu_env
);
19616 gen_store_gpr(t0
, ret
);
19619 tcg_gen_movi_tl(t0
, v2
>> 3);
19620 tcg_gen_movi_tl(t1
, v1
);
19621 gen_helper_extpdp(t0
, t0
, t1
, cpu_env
);
19622 gen_store_gpr(t0
, ret
);
19626 case NM_POOL32AXF_1_4
:
19628 tcg_gen_movi_tl(t0
, v2
>> 2);
19629 switch (extract32(ctx
->opcode
, 12, 1)) {
19631 gen_helper_shll_qb(t0
, t0
, v0_t
, cpu_env
);
19632 gen_store_gpr(t0
, ret
);
19635 gen_helper_shrl_qb(t0
, t0
, v0_t
);
19636 gen_store_gpr(t0
, ret
);
19640 case NM_POOL32AXF_1_5
:
19641 opc
= extract32(ctx
->opcode
, 12, 2);
19642 gen_pool32axf_1_5_nanomips_insn(ctx
, opc
, ret
, v1
, v2
);
19644 case NM_POOL32AXF_1_7
:
19646 tcg_gen_movi_tl(t0
, v2
>> 3);
19647 tcg_gen_movi_tl(t1
, v1
);
19648 switch (extract32(ctx
->opcode
, 12, 2)) {
19650 gen_helper_extr_w(t0
, t0
, t1
, cpu_env
);
19651 gen_store_gpr(t0
, ret
);
19654 gen_helper_extr_r_w(t0
, t0
, t1
, cpu_env
);
19655 gen_store_gpr(t0
, ret
);
19658 gen_helper_extr_rs_w(t0
, t0
, t1
, cpu_env
);
19659 gen_store_gpr(t0
, ret
);
19662 gen_helper_extr_s_h(t0
, t0
, t1
, cpu_env
);
19663 gen_store_gpr(t0
, ret
);
19668 gen_reserved_instruction(ctx
);
19674 tcg_temp_free(v0_t
);
19677 static void gen_pool32axf_2_multiply(DisasContext
*ctx
, uint32_t opc
,
19678 TCGv v0
, TCGv v1
, int rd
)
19682 t0
= tcg_temp_new_i32();
19684 tcg_gen_movi_i32(t0
, rd
>> 3);
19687 case NM_POOL32AXF_2_0_7
:
19688 switch (extract32(ctx
->opcode
, 9, 3)) {
19691 gen_helper_dpa_w_ph(t0
, v1
, v0
, cpu_env
);
19693 case NM_DPAQ_S_W_PH
:
19695 gen_helper_dpaq_s_w_ph(t0
, v1
, v0
, cpu_env
);
19699 gen_helper_dps_w_ph(t0
, v1
, v0
, cpu_env
);
19701 case NM_DPSQ_S_W_PH
:
19703 gen_helper_dpsq_s_w_ph(t0
, v1
, v0
, cpu_env
);
19706 gen_reserved_instruction(ctx
);
19710 case NM_POOL32AXF_2_8_15
:
19711 switch (extract32(ctx
->opcode
, 9, 3)) {
19714 gen_helper_dpax_w_ph(t0
, v0
, v1
, cpu_env
);
19716 case NM_DPAQ_SA_L_W
:
19718 gen_helper_dpaq_sa_l_w(t0
, v0
, v1
, cpu_env
);
19722 gen_helper_dpsx_w_ph(t0
, v0
, v1
, cpu_env
);
19724 case NM_DPSQ_SA_L_W
:
19726 gen_helper_dpsq_sa_l_w(t0
, v0
, v1
, cpu_env
);
19729 gen_reserved_instruction(ctx
);
19733 case NM_POOL32AXF_2_16_23
:
19734 switch (extract32(ctx
->opcode
, 9, 3)) {
19735 case NM_DPAU_H_QBL
:
19737 gen_helper_dpau_h_qbl(t0
, v0
, v1
, cpu_env
);
19739 case NM_DPAQX_S_W_PH
:
19741 gen_helper_dpaqx_s_w_ph(t0
, v0
, v1
, cpu_env
);
19743 case NM_DPSU_H_QBL
:
19745 gen_helper_dpsu_h_qbl(t0
, v0
, v1
, cpu_env
);
19747 case NM_DPSQX_S_W_PH
:
19749 gen_helper_dpsqx_s_w_ph(t0
, v0
, v1
, cpu_env
);
19751 case NM_MULSA_W_PH
:
19753 gen_helper_mulsa_w_ph(t0
, v0
, v1
, cpu_env
);
19756 gen_reserved_instruction(ctx
);
19760 case NM_POOL32AXF_2_24_31
:
19761 switch (extract32(ctx
->opcode
, 9, 3)) {
19762 case NM_DPAU_H_QBR
:
19764 gen_helper_dpau_h_qbr(t0
, v1
, v0
, cpu_env
);
19766 case NM_DPAQX_SA_W_PH
:
19768 gen_helper_dpaqx_sa_w_ph(t0
, v1
, v0
, cpu_env
);
19770 case NM_DPSU_H_QBR
:
19772 gen_helper_dpsu_h_qbr(t0
, v1
, v0
, cpu_env
);
19774 case NM_DPSQX_SA_W_PH
:
19776 gen_helper_dpsqx_sa_w_ph(t0
, v1
, v0
, cpu_env
);
19778 case NM_MULSAQ_S_W_PH
:
19780 gen_helper_mulsaq_s_w_ph(t0
, v1
, v0
, cpu_env
);
19783 gen_reserved_instruction(ctx
);
19788 gen_reserved_instruction(ctx
);
19792 tcg_temp_free_i32(t0
);
19795 static void gen_pool32axf_2_nanomips_insn(DisasContext
*ctx
, uint32_t opc
,
19796 int rt
, int rs
, int rd
)
19799 TCGv t0
= tcg_temp_new();
19800 TCGv t1
= tcg_temp_new();
19801 TCGv v0_t
= tcg_temp_new();
19802 TCGv v1_t
= tcg_temp_new();
19804 gen_load_gpr(v0_t
, rt
);
19805 gen_load_gpr(v1_t
, rs
);
19808 case NM_POOL32AXF_2_0_7
:
19809 switch (extract32(ctx
->opcode
, 9, 3)) {
19811 case NM_DPAQ_S_W_PH
:
19813 case NM_DPSQ_S_W_PH
:
19814 gen_pool32axf_2_multiply(ctx
, opc
, v0_t
, v1_t
, rd
);
19819 gen_load_gpr(t0
, rs
);
19821 if (rd
!= 0 && rd
!= 2) {
19822 tcg_gen_shli_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], 8 * rd
);
19823 tcg_gen_ext32u_tl(t0
, t0
);
19824 tcg_gen_shri_tl(t0
, t0
, 8 * (4 - rd
));
19825 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
19827 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
19833 int acc
= extract32(ctx
->opcode
, 14, 2);
19834 TCGv_i64 t2
= tcg_temp_new_i64();
19835 TCGv_i64 t3
= tcg_temp_new_i64();
19837 gen_load_gpr(t0
, rt
);
19838 gen_load_gpr(t1
, rs
);
19839 tcg_gen_ext_tl_i64(t2
, t0
);
19840 tcg_gen_ext_tl_i64(t3
, t1
);
19841 tcg_gen_mul_i64(t2
, t2
, t3
);
19842 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
19843 tcg_gen_add_i64(t2
, t2
, t3
);
19844 tcg_temp_free_i64(t3
);
19845 gen_move_low32(cpu_LO
[acc
], t2
);
19846 gen_move_high32(cpu_HI
[acc
], t2
);
19847 tcg_temp_free_i64(t2
);
19853 int acc
= extract32(ctx
->opcode
, 14, 2);
19854 TCGv_i32 t2
= tcg_temp_new_i32();
19855 TCGv_i32 t3
= tcg_temp_new_i32();
19857 gen_load_gpr(t0
, rs
);
19858 gen_load_gpr(t1
, rt
);
19859 tcg_gen_trunc_tl_i32(t2
, t0
);
19860 tcg_gen_trunc_tl_i32(t3
, t1
);
19861 tcg_gen_muls2_i32(t2
, t3
, t2
, t3
);
19862 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
19863 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
19864 tcg_temp_free_i32(t2
);
19865 tcg_temp_free_i32(t3
);
19870 gen_load_gpr(v1_t
, rs
);
19871 tcg_gen_movi_tl(t0
, rd
>> 3);
19872 gen_helper_extr_w(t0
, t0
, v1_t
, cpu_env
);
19873 gen_store_gpr(t0
, ret
);
19877 case NM_POOL32AXF_2_8_15
:
19878 switch (extract32(ctx
->opcode
, 9, 3)) {
19880 case NM_DPAQ_SA_L_W
:
19882 case NM_DPSQ_SA_L_W
:
19883 gen_pool32axf_2_multiply(ctx
, opc
, v0_t
, v1_t
, rd
);
19888 int acc
= extract32(ctx
->opcode
, 14, 2);
19889 TCGv_i64 t2
= tcg_temp_new_i64();
19890 TCGv_i64 t3
= tcg_temp_new_i64();
19892 gen_load_gpr(t0
, rs
);
19893 gen_load_gpr(t1
, rt
);
19894 tcg_gen_ext32u_tl(t0
, t0
);
19895 tcg_gen_ext32u_tl(t1
, t1
);
19896 tcg_gen_extu_tl_i64(t2
, t0
);
19897 tcg_gen_extu_tl_i64(t3
, t1
);
19898 tcg_gen_mul_i64(t2
, t2
, t3
);
19899 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
19900 tcg_gen_add_i64(t2
, t2
, t3
);
19901 tcg_temp_free_i64(t3
);
19902 gen_move_low32(cpu_LO
[acc
], t2
);
19903 gen_move_high32(cpu_HI
[acc
], t2
);
19904 tcg_temp_free_i64(t2
);
19910 int acc
= extract32(ctx
->opcode
, 14, 2);
19911 TCGv_i32 t2
= tcg_temp_new_i32();
19912 TCGv_i32 t3
= tcg_temp_new_i32();
19914 gen_load_gpr(t0
, rs
);
19915 gen_load_gpr(t1
, rt
);
19916 tcg_gen_trunc_tl_i32(t2
, t0
);
19917 tcg_gen_trunc_tl_i32(t3
, t1
);
19918 tcg_gen_mulu2_i32(t2
, t3
, t2
, t3
);
19919 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
19920 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
19921 tcg_temp_free_i32(t2
);
19922 tcg_temp_free_i32(t3
);
19927 tcg_gen_movi_tl(t0
, rd
>> 3);
19928 gen_helper_extr_r_w(t0
, t0
, v1_t
, cpu_env
);
19929 gen_store_gpr(t0
, ret
);
19932 gen_reserved_instruction(ctx
);
19936 case NM_POOL32AXF_2_16_23
:
19937 switch (extract32(ctx
->opcode
, 9, 3)) {
19938 case NM_DPAU_H_QBL
:
19939 case NM_DPAQX_S_W_PH
:
19940 case NM_DPSU_H_QBL
:
19941 case NM_DPSQX_S_W_PH
:
19942 case NM_MULSA_W_PH
:
19943 gen_pool32axf_2_multiply(ctx
, opc
, v0_t
, v1_t
, rd
);
19947 tcg_gen_movi_tl(t0
, rd
>> 3);
19948 gen_helper_extp(t0
, t0
, v1_t
, cpu_env
);
19949 gen_store_gpr(t0
, ret
);
19954 int acc
= extract32(ctx
->opcode
, 14, 2);
19955 TCGv_i64 t2
= tcg_temp_new_i64();
19956 TCGv_i64 t3
= tcg_temp_new_i64();
19958 gen_load_gpr(t0
, rs
);
19959 gen_load_gpr(t1
, rt
);
19960 tcg_gen_ext_tl_i64(t2
, t0
);
19961 tcg_gen_ext_tl_i64(t3
, t1
);
19962 tcg_gen_mul_i64(t2
, t2
, t3
);
19963 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
19964 tcg_gen_sub_i64(t2
, t3
, t2
);
19965 tcg_temp_free_i64(t3
);
19966 gen_move_low32(cpu_LO
[acc
], t2
);
19967 gen_move_high32(cpu_HI
[acc
], t2
);
19968 tcg_temp_free_i64(t2
);
19971 case NM_EXTRV_RS_W
:
19973 tcg_gen_movi_tl(t0
, rd
>> 3);
19974 gen_helper_extr_rs_w(t0
, t0
, v1_t
, cpu_env
);
19975 gen_store_gpr(t0
, ret
);
19979 case NM_POOL32AXF_2_24_31
:
19980 switch (extract32(ctx
->opcode
, 9, 3)) {
19981 case NM_DPAU_H_QBR
:
19982 case NM_DPAQX_SA_W_PH
:
19983 case NM_DPSU_H_QBR
:
19984 case NM_DPSQX_SA_W_PH
:
19985 case NM_MULSAQ_S_W_PH
:
19986 gen_pool32axf_2_multiply(ctx
, opc
, v0_t
, v1_t
, rd
);
19990 tcg_gen_movi_tl(t0
, rd
>> 3);
19991 gen_helper_extpdp(t0
, t0
, v1_t
, cpu_env
);
19992 gen_store_gpr(t0
, ret
);
19997 int acc
= extract32(ctx
->opcode
, 14, 2);
19998 TCGv_i64 t2
= tcg_temp_new_i64();
19999 TCGv_i64 t3
= tcg_temp_new_i64();
20001 gen_load_gpr(t0
, rs
);
20002 gen_load_gpr(t1
, rt
);
20003 tcg_gen_ext32u_tl(t0
, t0
);
20004 tcg_gen_ext32u_tl(t1
, t1
);
20005 tcg_gen_extu_tl_i64(t2
, t0
);
20006 tcg_gen_extu_tl_i64(t3
, t1
);
20007 tcg_gen_mul_i64(t2
, t2
, t3
);
20008 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
20009 tcg_gen_sub_i64(t2
, t3
, t2
);
20010 tcg_temp_free_i64(t3
);
20011 gen_move_low32(cpu_LO
[acc
], t2
);
20012 gen_move_high32(cpu_HI
[acc
], t2
);
20013 tcg_temp_free_i64(t2
);
20018 tcg_gen_movi_tl(t0
, rd
>> 3);
20019 gen_helper_extr_s_h(t0
, t0
, v0_t
, cpu_env
);
20020 gen_store_gpr(t0
, ret
);
20025 gen_reserved_instruction(ctx
);
20032 tcg_temp_free(v0_t
);
20033 tcg_temp_free(v1_t
);
20036 static void gen_pool32axf_4_nanomips_insn(DisasContext
*ctx
, uint32_t opc
,
20040 TCGv t0
= tcg_temp_new();
20041 TCGv v0_t
= tcg_temp_new();
20043 gen_load_gpr(v0_t
, rs
);
20048 gen_helper_absq_s_qb(v0_t
, v0_t
, cpu_env
);
20049 gen_store_gpr(v0_t
, ret
);
20053 gen_helper_absq_s_ph(v0_t
, v0_t
, cpu_env
);
20054 gen_store_gpr(v0_t
, ret
);
20058 gen_helper_absq_s_w(v0_t
, v0_t
, cpu_env
);
20059 gen_store_gpr(v0_t
, ret
);
20061 case NM_PRECEQ_W_PHL
:
20063 tcg_gen_andi_tl(v0_t
, v0_t
, 0xFFFF0000);
20064 tcg_gen_ext32s_tl(v0_t
, v0_t
);
20065 gen_store_gpr(v0_t
, ret
);
20067 case NM_PRECEQ_W_PHR
:
20069 tcg_gen_andi_tl(v0_t
, v0_t
, 0x0000FFFF);
20070 tcg_gen_shli_tl(v0_t
, v0_t
, 16);
20071 tcg_gen_ext32s_tl(v0_t
, v0_t
);
20072 gen_store_gpr(v0_t
, ret
);
20074 case NM_PRECEQU_PH_QBL
:
20076 gen_helper_precequ_ph_qbl(v0_t
, v0_t
);
20077 gen_store_gpr(v0_t
, ret
);
20079 case NM_PRECEQU_PH_QBR
:
20081 gen_helper_precequ_ph_qbr(v0_t
, v0_t
);
20082 gen_store_gpr(v0_t
, ret
);
20084 case NM_PRECEQU_PH_QBLA
:
20086 gen_helper_precequ_ph_qbla(v0_t
, v0_t
);
20087 gen_store_gpr(v0_t
, ret
);
20089 case NM_PRECEQU_PH_QBRA
:
20091 gen_helper_precequ_ph_qbra(v0_t
, v0_t
);
20092 gen_store_gpr(v0_t
, ret
);
20094 case NM_PRECEU_PH_QBL
:
20096 gen_helper_preceu_ph_qbl(v0_t
, v0_t
);
20097 gen_store_gpr(v0_t
, ret
);
20099 case NM_PRECEU_PH_QBR
:
20101 gen_helper_preceu_ph_qbr(v0_t
, v0_t
);
20102 gen_store_gpr(v0_t
, ret
);
20104 case NM_PRECEU_PH_QBLA
:
20106 gen_helper_preceu_ph_qbla(v0_t
, v0_t
);
20107 gen_store_gpr(v0_t
, ret
);
20109 case NM_PRECEU_PH_QBRA
:
20111 gen_helper_preceu_ph_qbra(v0_t
, v0_t
);
20112 gen_store_gpr(v0_t
, ret
);
20116 tcg_gen_ext16u_tl(v0_t
, v0_t
);
20117 tcg_gen_shli_tl(t0
, v0_t
, 16);
20118 tcg_gen_or_tl(v0_t
, v0_t
, t0
);
20119 tcg_gen_ext32s_tl(v0_t
, v0_t
);
20120 gen_store_gpr(v0_t
, ret
);
20124 tcg_gen_ext8u_tl(v0_t
, v0_t
);
20125 tcg_gen_shli_tl(t0
, v0_t
, 8);
20126 tcg_gen_or_tl(v0_t
, v0_t
, t0
);
20127 tcg_gen_shli_tl(t0
, v0_t
, 16);
20128 tcg_gen_or_tl(v0_t
, v0_t
, t0
);
20129 tcg_gen_ext32s_tl(v0_t
, v0_t
);
20130 gen_store_gpr(v0_t
, ret
);
20134 gen_helper_bitrev(v0_t
, v0_t
);
20135 gen_store_gpr(v0_t
, ret
);
20140 TCGv tv0
= tcg_temp_new();
20142 gen_load_gpr(tv0
, rt
);
20143 gen_helper_insv(v0_t
, cpu_env
, v0_t
, tv0
);
20144 gen_store_gpr(v0_t
, ret
);
20145 tcg_temp_free(tv0
);
20148 case NM_RADDU_W_QB
:
20150 gen_helper_raddu_w_qb(v0_t
, v0_t
);
20151 gen_store_gpr(v0_t
, ret
);
20154 gen_bitswap(ctx
, OPC_BITSWAP
, ret
, rs
);
20158 gen_cl(ctx
, OPC_CLO
, ret
, rs
);
20162 gen_cl(ctx
, OPC_CLZ
, ret
, rs
);
20165 gen_bshfl(ctx
, OPC_WSBH
, ret
, rs
);
20168 gen_reserved_instruction(ctx
);
20172 tcg_temp_free(v0_t
);
20176 static void gen_pool32axf_7_nanomips_insn(DisasContext
*ctx
, uint32_t opc
,
20177 int rt
, int rs
, int rd
)
20179 TCGv t0
= tcg_temp_new();
20180 TCGv rs_t
= tcg_temp_new();
20182 gen_load_gpr(rs_t
, rs
);
20187 tcg_gen_movi_tl(t0
, rd
>> 2);
20188 switch (extract32(ctx
->opcode
, 12, 1)) {
20191 gen_helper_shra_qb(t0
, t0
, rs_t
);
20192 gen_store_gpr(t0
, rt
);
20196 gen_helper_shra_r_qb(t0
, t0
, rs_t
);
20197 gen_store_gpr(t0
, rt
);
20203 tcg_gen_movi_tl(t0
, rd
>> 1);
20204 gen_helper_shrl_ph(t0
, t0
, rs_t
);
20205 gen_store_gpr(t0
, rt
);
20211 target_long result
;
20212 imm
= extract32(ctx
->opcode
, 13, 8);
20213 result
= (uint32_t)imm
<< 24 |
20214 (uint32_t)imm
<< 16 |
20215 (uint32_t)imm
<< 8 |
20217 result
= (int32_t)result
;
20218 tcg_gen_movi_tl(t0
, result
);
20219 gen_store_gpr(t0
, rt
);
20223 gen_reserved_instruction(ctx
);
20227 tcg_temp_free(rs_t
);
20231 static void gen_pool32axf_nanomips_insn(CPUMIPSState
*env
, DisasContext
*ctx
)
20233 int rt
= extract32(ctx
->opcode
, 21, 5);
20234 int rs
= extract32(ctx
->opcode
, 16, 5);
20235 int rd
= extract32(ctx
->opcode
, 11, 5);
20237 switch (extract32(ctx
->opcode
, 6, 3)) {
20238 case NM_POOL32AXF_1
:
20240 int32_t op1
= extract32(ctx
->opcode
, 9, 3);
20241 gen_pool32axf_1_nanomips_insn(ctx
, op1
, rt
, rs
, rd
);
20244 case NM_POOL32AXF_2
:
20246 int32_t op1
= extract32(ctx
->opcode
, 12, 2);
20247 gen_pool32axf_2_nanomips_insn(ctx
, op1
, rt
, rs
, rd
);
20250 case NM_POOL32AXF_4
:
20252 int32_t op1
= extract32(ctx
->opcode
, 9, 7);
20253 gen_pool32axf_4_nanomips_insn(ctx
, op1
, rt
, rs
);
20256 case NM_POOL32AXF_5
:
20257 switch (extract32(ctx
->opcode
, 9, 7)) {
20258 #ifndef CONFIG_USER_ONLY
20260 gen_cp0(env
, ctx
, OPC_TLBP
, 0, 0);
20263 gen_cp0(env
, ctx
, OPC_TLBR
, 0, 0);
20266 gen_cp0(env
, ctx
, OPC_TLBWI
, 0, 0);
20269 gen_cp0(env
, ctx
, OPC_TLBWR
, 0, 0);
20272 gen_cp0(env
, ctx
, OPC_TLBINV
, 0, 0);
20275 gen_cp0(env
, ctx
, OPC_TLBINVF
, 0, 0);
20278 check_cp0_enabled(ctx
);
20280 TCGv t0
= tcg_temp_new();
20282 save_cpu_state(ctx
, 1);
20283 gen_helper_di(t0
, cpu_env
);
20284 gen_store_gpr(t0
, rt
);
20285 /* Stop translation as we may have switched the execution mode */
20286 ctx
->base
.is_jmp
= DISAS_STOP
;
20291 check_cp0_enabled(ctx
);
20293 TCGv t0
= tcg_temp_new();
20295 save_cpu_state(ctx
, 1);
20296 gen_helper_ei(t0
, cpu_env
);
20297 gen_store_gpr(t0
, rt
);
20298 /* Stop translation as we may have switched the execution mode */
20299 ctx
->base
.is_jmp
= DISAS_STOP
;
20304 gen_load_srsgpr(rs
, rt
);
20307 gen_store_srsgpr(rs
, rt
);
20310 gen_cp0(env
, ctx
, OPC_WAIT
, 0, 0);
20313 gen_cp0(env
, ctx
, OPC_DERET
, 0, 0);
20316 gen_cp0(env
, ctx
, OPC_ERET
, 0, 0);
20320 gen_reserved_instruction(ctx
);
20324 case NM_POOL32AXF_7
:
20326 int32_t op1
= extract32(ctx
->opcode
, 9, 3);
20327 gen_pool32axf_7_nanomips_insn(ctx
, op1
, rt
, rs
, rd
);
20331 gen_reserved_instruction(ctx
);
20336 /* Immediate Value Compact Branches */
20337 static void gen_compute_imm_branch(DisasContext
*ctx
, uint32_t opc
,
20338 int rt
, int32_t imm
, int32_t offset
)
20340 TCGCond cond
= TCG_COND_ALWAYS
;
20341 TCGv t0
= tcg_temp_new();
20342 TCGv t1
= tcg_temp_new();
20344 gen_load_gpr(t0
, rt
);
20345 tcg_gen_movi_tl(t1
, imm
);
20346 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
20348 /* Load needed operands and calculate btarget */
20351 if (rt
== 0 && imm
== 0) {
20352 /* Unconditional branch */
20353 } else if (rt
== 0 && imm
!= 0) {
20357 cond
= TCG_COND_EQ
;
20363 if (imm
>= 32 && !(ctx
->hflags
& MIPS_HFLAG_64
)) {
20364 gen_reserved_instruction(ctx
);
20366 } else if (rt
== 0 && opc
== NM_BBEQZC
) {
20367 /* Unconditional branch */
20368 } else if (rt
== 0 && opc
== NM_BBNEZC
) {
20372 tcg_gen_shri_tl(t0
, t0
, imm
);
20373 tcg_gen_andi_tl(t0
, t0
, 1);
20374 tcg_gen_movi_tl(t1
, 0);
20375 if (opc
== NM_BBEQZC
) {
20376 cond
= TCG_COND_EQ
;
20378 cond
= TCG_COND_NE
;
20383 if (rt
== 0 && imm
== 0) {
20386 } else if (rt
== 0 && imm
!= 0) {
20387 /* Unconditional branch */
20389 cond
= TCG_COND_NE
;
20393 if (rt
== 0 && imm
== 0) {
20394 /* Unconditional branch */
20396 cond
= TCG_COND_GE
;
20400 cond
= TCG_COND_LT
;
20403 if (rt
== 0 && imm
== 0) {
20404 /* Unconditional branch */
20406 cond
= TCG_COND_GEU
;
20410 cond
= TCG_COND_LTU
;
20413 MIPS_INVAL("Immediate Value Compact branch");
20414 gen_reserved_instruction(ctx
);
20418 /* branch completion */
20419 clear_branch_hflags(ctx
);
20420 ctx
->base
.is_jmp
= DISAS_NORETURN
;
20422 if (cond
== TCG_COND_ALWAYS
) {
20423 /* Uncoditional compact branch */
20424 gen_goto_tb(ctx
, 0, ctx
->btarget
);
20426 /* Conditional compact branch */
20427 TCGLabel
*fs
= gen_new_label();
20429 tcg_gen_brcond_tl(tcg_invert_cond(cond
), t0
, t1
, fs
);
20431 gen_goto_tb(ctx
, 1, ctx
->btarget
);
20434 gen_goto_tb(ctx
, 0, ctx
->base
.pc_next
+ 4);
20442 /* P.BALRSC type nanoMIPS R6 branches: BALRSC and BRSC */
20443 static void gen_compute_nanomips_pbalrsc_branch(DisasContext
*ctx
, int rs
,
20446 TCGv t0
= tcg_temp_new();
20447 TCGv t1
= tcg_temp_new();
20450 gen_load_gpr(t0
, rs
);
20454 tcg_gen_movi_tl(cpu_gpr
[rt
], ctx
->base
.pc_next
+ 4);
20457 /* calculate btarget */
20458 tcg_gen_shli_tl(t0
, t0
, 1);
20459 tcg_gen_movi_tl(t1
, ctx
->base
.pc_next
+ 4);
20460 gen_op_addr_add(ctx
, btarget
, t1
, t0
);
20462 /* branch completion */
20463 clear_branch_hflags(ctx
);
20464 ctx
->base
.is_jmp
= DISAS_NORETURN
;
20466 /* unconditional branch to register */
20467 tcg_gen_mov_tl(cpu_PC
, btarget
);
20468 tcg_gen_lookup_and_goto_ptr();
20474 /* nanoMIPS Branches */
20475 static void gen_compute_compact_branch_nm(DisasContext
*ctx
, uint32_t opc
,
20476 int rs
, int rt
, int32_t offset
)
20478 int bcond_compute
= 0;
20479 TCGv t0
= tcg_temp_new();
20480 TCGv t1
= tcg_temp_new();
20482 /* Load needed operands and calculate btarget */
20484 /* compact branch */
20487 gen_load_gpr(t0
, rs
);
20488 gen_load_gpr(t1
, rt
);
20490 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
20494 if (rs
== 0 || rs
== rt
) {
20495 /* OPC_BLEZALC, OPC_BGEZALC */
20496 /* OPC_BGTZALC, OPC_BLTZALC */
20497 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 4);
20499 gen_load_gpr(t0
, rs
);
20500 gen_load_gpr(t1
, rt
);
20502 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
20505 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
20509 /* OPC_BEQZC, OPC_BNEZC */
20510 gen_load_gpr(t0
, rs
);
20512 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
20514 /* OPC_JIC, OPC_JIALC */
20515 TCGv tbase
= tcg_temp_new();
20516 TCGv toffset
= tcg_temp_new();
20518 gen_load_gpr(tbase
, rt
);
20519 tcg_gen_movi_tl(toffset
, offset
);
20520 gen_op_addr_add(ctx
, btarget
, tbase
, toffset
);
20521 tcg_temp_free(tbase
);
20522 tcg_temp_free(toffset
);
20526 MIPS_INVAL("Compact branch/jump");
20527 gen_reserved_instruction(ctx
);
20531 if (bcond_compute
== 0) {
20532 /* Uncoditional compact branch */
20535 gen_goto_tb(ctx
, 0, ctx
->btarget
);
20538 MIPS_INVAL("Compact branch/jump");
20539 gen_reserved_instruction(ctx
);
20543 /* Conditional compact branch */
20544 TCGLabel
*fs
= gen_new_label();
20548 if (rs
== 0 && rt
!= 0) {
20550 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE
), t1
, 0, fs
);
20551 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
20553 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE
), t1
, 0, fs
);
20556 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU
), t0
, t1
, fs
);
20560 if (rs
== 0 && rt
!= 0) {
20562 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT
), t1
, 0, fs
);
20563 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
20565 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT
), t1
, 0, fs
);
20568 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU
), t0
, t1
, fs
);
20572 if (rs
== 0 && rt
!= 0) {
20574 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE
), t1
, 0, fs
);
20575 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
20577 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE
), t1
, 0, fs
);
20580 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE
), t0
, t1
, fs
);
20584 if (rs
== 0 && rt
!= 0) {
20586 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT
), t1
, 0, fs
);
20587 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
20589 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT
), t1
, 0, fs
);
20592 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT
), t0
, t1
, fs
);
20596 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ
), t0
, 0, fs
);
20599 MIPS_INVAL("Compact conditional branch/jump");
20600 gen_reserved_instruction(ctx
);
20604 /* branch completion */
20605 clear_branch_hflags(ctx
);
20606 ctx
->base
.is_jmp
= DISAS_NORETURN
;
20608 /* Generating branch here as compact branches don't have delay slot */
20609 gen_goto_tb(ctx
, 1, ctx
->btarget
);
20612 gen_goto_tb(ctx
, 0, ctx
->base
.pc_next
+ 4);
20621 /* nanoMIPS CP1 Branches */
20622 static void gen_compute_branch_cp1_nm(DisasContext
*ctx
, uint32_t op
,
20623 int32_t ft
, int32_t offset
)
20625 target_ulong btarget
;
20626 TCGv_i64 t0
= tcg_temp_new_i64();
20628 gen_load_fpr64(ctx
, t0
, ft
);
20629 tcg_gen_andi_i64(t0
, t0
, 1);
20631 btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
20635 tcg_gen_xori_i64(t0
, t0
, 1);
20636 ctx
->hflags
|= MIPS_HFLAG_BC
;
20639 /* t0 already set */
20640 ctx
->hflags
|= MIPS_HFLAG_BC
;
20643 MIPS_INVAL("cp1 cond branch");
20644 gen_reserved_instruction(ctx
);
20648 tcg_gen_trunc_i64_tl(bcond
, t0
);
20650 ctx
->btarget
= btarget
;
20653 tcg_temp_free_i64(t0
);
20657 static void gen_p_lsx(DisasContext
*ctx
, int rd
, int rs
, int rt
)
20660 t0
= tcg_temp_new();
20661 t1
= tcg_temp_new();
20663 gen_load_gpr(t0
, rs
);
20664 gen_load_gpr(t1
, rt
);
20666 if ((extract32(ctx
->opcode
, 6, 1)) == 1) {
20667 /* PP.LSXS instructions require shifting */
20668 switch (extract32(ctx
->opcode
, 7, 4)) {
20674 tcg_gen_shli_tl(t0
, t0
, 1);
20682 tcg_gen_shli_tl(t0
, t0
, 2);
20686 tcg_gen_shli_tl(t0
, t0
, 3);
20690 gen_op_addr_add(ctx
, t0
, t0
, t1
);
20692 switch (extract32(ctx
->opcode
, 7, 4)) {
20694 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
,
20696 gen_store_gpr(t0
, rd
);
20700 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
,
20702 gen_store_gpr(t0
, rd
);
20706 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
,
20708 gen_store_gpr(t0
, rd
);
20711 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
,
20713 gen_store_gpr(t0
, rd
);
20717 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
,
20719 gen_store_gpr(t0
, rd
);
20723 gen_load_gpr(t1
, rd
);
20724 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
,
20730 gen_load_gpr(t1
, rd
);
20731 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
,
20737 gen_load_gpr(t1
, rd
);
20738 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
,
20742 /*case NM_LWC1XS:*/
20744 /*case NM_LDC1XS:*/
20746 /*case NM_SWC1XS:*/
20748 /*case NM_SDC1XS:*/
20749 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
20750 check_cp1_enabled(ctx
);
20751 switch (extract32(ctx
->opcode
, 7, 4)) {
20753 /*case NM_LWC1XS:*/
20754 gen_flt_ldst(ctx
, OPC_LWC1
, rd
, t0
);
20757 /*case NM_LDC1XS:*/
20758 gen_flt_ldst(ctx
, OPC_LDC1
, rd
, t0
);
20761 /*case NM_SWC1XS:*/
20762 gen_flt_ldst(ctx
, OPC_SWC1
, rd
, t0
);
20765 /*case NM_SDC1XS:*/
20766 gen_flt_ldst(ctx
, OPC_SDC1
, rd
, t0
);
20770 generate_exception_err(ctx
, EXCP_CpU
, 1);
20774 gen_reserved_instruction(ctx
);
20782 static void gen_pool32f_nanomips_insn(DisasContext
*ctx
)
20786 rt
= extract32(ctx
->opcode
, 21, 5);
20787 rs
= extract32(ctx
->opcode
, 16, 5);
20788 rd
= extract32(ctx
->opcode
, 11, 5);
20790 if (!(ctx
->CP0_Config1
& (1 << CP0C1_FP
))) {
20791 gen_reserved_instruction(ctx
);
20794 check_cp1_enabled(ctx
);
20795 switch (extract32(ctx
->opcode
, 0, 3)) {
20797 switch (extract32(ctx
->opcode
, 3, 7)) {
20799 gen_farith(ctx
, OPC_RINT_S
, 0, rt
, rs
, 0);
20802 gen_farith(ctx
, OPC_RINT_D
, 0, rt
, rs
, 0);
20805 gen_farith(ctx
, OPC_CLASS_S
, 0, rt
, rs
, 0);
20808 gen_farith(ctx
, OPC_CLASS_D
, 0, rt
, rs
, 0);
20811 gen_farith(ctx
, OPC_ADD_S
, rt
, rs
, rd
, 0);
20814 gen_farith(ctx
, OPC_ADD_D
, rt
, rs
, rd
, 0);
20817 gen_farith(ctx
, OPC_SUB_S
, rt
, rs
, rd
, 0);
20820 gen_farith(ctx
, OPC_SUB_D
, rt
, rs
, rd
, 0);
20823 gen_farith(ctx
, OPC_MUL_S
, rt
, rs
, rd
, 0);
20826 gen_farith(ctx
, OPC_MUL_D
, rt
, rs
, rd
, 0);
20829 gen_farith(ctx
, OPC_DIV_S
, rt
, rs
, rd
, 0);
20832 gen_farith(ctx
, OPC_DIV_D
, rt
, rs
, rd
, 0);
20835 gen_sel_s(ctx
, OPC_SELEQZ_S
, rd
, rt
, rs
);
20838 gen_sel_d(ctx
, OPC_SELEQZ_D
, rd
, rt
, rs
);
20841 gen_sel_s(ctx
, OPC_SELNEZ_S
, rd
, rt
, rs
);
20844 gen_sel_d(ctx
, OPC_SELNEZ_D
, rd
, rt
, rs
);
20847 gen_sel_s(ctx
, OPC_SEL_S
, rd
, rt
, rs
);
20850 gen_sel_d(ctx
, OPC_SEL_D
, rd
, rt
, rs
);
20853 gen_farith(ctx
, OPC_MADDF_S
, rt
, rs
, rd
, 0);
20856 gen_farith(ctx
, OPC_MADDF_D
, rt
, rs
, rd
, 0);
20859 gen_farith(ctx
, OPC_MSUBF_S
, rt
, rs
, rd
, 0);
20862 gen_farith(ctx
, OPC_MSUBF_D
, rt
, rs
, rd
, 0);
20865 gen_reserved_instruction(ctx
);
20870 switch (extract32(ctx
->opcode
, 3, 3)) {
20872 switch (extract32(ctx
->opcode
, 9, 1)) {
20874 gen_farith(ctx
, OPC_MIN_S
, rt
, rs
, rd
, 0);
20877 gen_farith(ctx
, OPC_MIN_D
, rt
, rs
, rd
, 0);
20882 switch (extract32(ctx
->opcode
, 9, 1)) {
20884 gen_farith(ctx
, OPC_MAX_S
, rt
, rs
, rd
, 0);
20887 gen_farith(ctx
, OPC_MAX_D
, rt
, rs
, rd
, 0);
20892 switch (extract32(ctx
->opcode
, 9, 1)) {
20894 gen_farith(ctx
, OPC_MINA_S
, rt
, rs
, rd
, 0);
20897 gen_farith(ctx
, OPC_MINA_D
, rt
, rs
, rd
, 0);
20902 switch (extract32(ctx
->opcode
, 9, 1)) {
20904 gen_farith(ctx
, OPC_MAXA_S
, rt
, rs
, rd
, 0);
20907 gen_farith(ctx
, OPC_MAXA_D
, rt
, rs
, rd
, 0);
20912 switch (extract32(ctx
->opcode
, 6, 8)) {
20914 gen_cp1(ctx
, OPC_CFC1
, rt
, rs
);
20917 gen_cp1(ctx
, OPC_CTC1
, rt
, rs
);
20920 gen_cp1(ctx
, OPC_MFC1
, rt
, rs
);
20923 gen_cp1(ctx
, OPC_MTC1
, rt
, rs
);
20926 gen_cp1(ctx
, OPC_MFHC1
, rt
, rs
);
20929 gen_cp1(ctx
, OPC_MTHC1
, rt
, rs
);
20932 gen_farith(ctx
, OPC_CVT_S_PL
, -1, rs
, rt
, 0);
20935 gen_farith(ctx
, OPC_CVT_S_PU
, -1, rs
, rt
, 0);
20938 switch (extract32(ctx
->opcode
, 6, 9)) {
20940 gen_farith(ctx
, OPC_CVT_L_S
, -1, rs
, rt
, 0);
20943 gen_farith(ctx
, OPC_CVT_L_D
, -1, rs
, rt
, 0);
20946 gen_farith(ctx
, OPC_CVT_W_S
, -1, rs
, rt
, 0);
20949 gen_farith(ctx
, OPC_CVT_W_D
, -1, rs
, rt
, 0);
20952 gen_farith(ctx
, OPC_RSQRT_S
, -1, rs
, rt
, 0);
20955 gen_farith(ctx
, OPC_RSQRT_D
, -1, rs
, rt
, 0);
20958 gen_farith(ctx
, OPC_SQRT_S
, -1, rs
, rt
, 0);
20961 gen_farith(ctx
, OPC_SQRT_D
, -1, rs
, rt
, 0);
20964 gen_farith(ctx
, OPC_RECIP_S
, -1, rs
, rt
, 0);
20967 gen_farith(ctx
, OPC_RECIP_D
, -1, rs
, rt
, 0);
20970 gen_farith(ctx
, OPC_FLOOR_L_S
, -1, rs
, rt
, 0);
20973 gen_farith(ctx
, OPC_FLOOR_L_D
, -1, rs
, rt
, 0);
20976 gen_farith(ctx
, OPC_FLOOR_W_S
, -1, rs
, rt
, 0);
20979 gen_farith(ctx
, OPC_FLOOR_W_D
, -1, rs
, rt
, 0);
20982 gen_farith(ctx
, OPC_CEIL_L_S
, -1, rs
, rt
, 0);
20985 gen_farith(ctx
, OPC_CEIL_L_D
, -1, rs
, rt
, 0);
20988 gen_farith(ctx
, OPC_CEIL_W_S
, -1, rs
, rt
, 0);
20991 gen_farith(ctx
, OPC_CEIL_W_D
, -1, rs
, rt
, 0);
20994 gen_farith(ctx
, OPC_TRUNC_L_S
, -1, rs
, rt
, 0);
20997 gen_farith(ctx
, OPC_TRUNC_L_D
, -1, rs
, rt
, 0);
21000 gen_farith(ctx
, OPC_TRUNC_W_S
, -1, rs
, rt
, 0);
21003 gen_farith(ctx
, OPC_TRUNC_W_D
, -1, rs
, rt
, 0);
21006 gen_farith(ctx
, OPC_ROUND_L_S
, -1, rs
, rt
, 0);
21009 gen_farith(ctx
, OPC_ROUND_L_D
, -1, rs
, rt
, 0);
21012 gen_farith(ctx
, OPC_ROUND_W_S
, -1, rs
, rt
, 0);
21015 gen_farith(ctx
, OPC_ROUND_W_D
, -1, rs
, rt
, 0);
21018 gen_farith(ctx
, OPC_MOV_S
, -1, rs
, rt
, 0);
21021 gen_farith(ctx
, OPC_MOV_D
, -1, rs
, rt
, 0);
21024 gen_farith(ctx
, OPC_ABS_S
, -1, rs
, rt
, 0);
21027 gen_farith(ctx
, OPC_ABS_D
, -1, rs
, rt
, 0);
21030 gen_farith(ctx
, OPC_NEG_S
, -1, rs
, rt
, 0);
21033 gen_farith(ctx
, OPC_NEG_D
, -1, rs
, rt
, 0);
21036 gen_farith(ctx
, OPC_CVT_D_S
, -1, rs
, rt
, 0);
21039 gen_farith(ctx
, OPC_CVT_D_W
, -1, rs
, rt
, 0);
21042 gen_farith(ctx
, OPC_CVT_D_L
, -1, rs
, rt
, 0);
21045 gen_farith(ctx
, OPC_CVT_S_D
, -1, rs
, rt
, 0);
21048 gen_farith(ctx
, OPC_CVT_S_W
, -1, rs
, rt
, 0);
21051 gen_farith(ctx
, OPC_CVT_S_L
, -1, rs
, rt
, 0);
21054 gen_reserved_instruction(ctx
);
21063 switch (extract32(ctx
->opcode
, 3, 3)) {
21064 case NM_CMP_CONDN_S
:
21065 gen_r6_cmp_s(ctx
, extract32(ctx
->opcode
, 6, 5), rt
, rs
, rd
);
21067 case NM_CMP_CONDN_D
:
21068 gen_r6_cmp_d(ctx
, extract32(ctx
->opcode
, 6, 5), rt
, rs
, rd
);
21071 gen_reserved_instruction(ctx
);
21076 gen_reserved_instruction(ctx
);
21081 static void gen_pool32a5_nanomips_insn(DisasContext
*ctx
, int opc
,
21082 int rd
, int rs
, int rt
)
21085 TCGv t0
= tcg_temp_new();
21086 TCGv v1_t
= tcg_temp_new();
21087 TCGv v2_t
= tcg_temp_new();
21089 gen_load_gpr(v1_t
, rs
);
21090 gen_load_gpr(v2_t
, rt
);
21095 gen_helper_cmp_eq_ph(v1_t
, v2_t
, cpu_env
);
21099 gen_helper_cmp_lt_ph(v1_t
, v2_t
, cpu_env
);
21103 gen_helper_cmp_le_ph(v1_t
, v2_t
, cpu_env
);
21105 case NM_CMPU_EQ_QB
:
21107 gen_helper_cmpu_eq_qb(v1_t
, v2_t
, cpu_env
);
21109 case NM_CMPU_LT_QB
:
21111 gen_helper_cmpu_lt_qb(v1_t
, v2_t
, cpu_env
);
21113 case NM_CMPU_LE_QB
:
21115 gen_helper_cmpu_le_qb(v1_t
, v2_t
, cpu_env
);
21117 case NM_CMPGU_EQ_QB
:
21119 gen_helper_cmpgu_eq_qb(v1_t
, v1_t
, v2_t
);
21120 gen_store_gpr(v1_t
, ret
);
21122 case NM_CMPGU_LT_QB
:
21124 gen_helper_cmpgu_lt_qb(v1_t
, v1_t
, v2_t
);
21125 gen_store_gpr(v1_t
, ret
);
21127 case NM_CMPGU_LE_QB
:
21129 gen_helper_cmpgu_le_qb(v1_t
, v1_t
, v2_t
);
21130 gen_store_gpr(v1_t
, ret
);
21132 case NM_CMPGDU_EQ_QB
:
21134 gen_helper_cmpgu_eq_qb(v1_t
, v1_t
, v2_t
);
21135 tcg_gen_deposit_tl(cpu_dspctrl
, cpu_dspctrl
, v1_t
, 24, 4);
21136 gen_store_gpr(v1_t
, ret
);
21138 case NM_CMPGDU_LT_QB
:
21140 gen_helper_cmpgu_lt_qb(v1_t
, v1_t
, v2_t
);
21141 tcg_gen_deposit_tl(cpu_dspctrl
, cpu_dspctrl
, v1_t
, 24, 4);
21142 gen_store_gpr(v1_t
, ret
);
21144 case NM_CMPGDU_LE_QB
:
21146 gen_helper_cmpgu_le_qb(v1_t
, v1_t
, v2_t
);
21147 tcg_gen_deposit_tl(cpu_dspctrl
, cpu_dspctrl
, v1_t
, 24, 4);
21148 gen_store_gpr(v1_t
, ret
);
21152 gen_helper_packrl_ph(v1_t
, v1_t
, v2_t
);
21153 gen_store_gpr(v1_t
, ret
);
21157 gen_helper_pick_qb(v1_t
, v1_t
, v2_t
, cpu_env
);
21158 gen_store_gpr(v1_t
, ret
);
21162 gen_helper_pick_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21163 gen_store_gpr(v1_t
, ret
);
21167 gen_helper_addq_s_w(v1_t
, v1_t
, v2_t
, cpu_env
);
21168 gen_store_gpr(v1_t
, ret
);
21172 gen_helper_subq_s_w(v1_t
, v1_t
, v2_t
, cpu_env
);
21173 gen_store_gpr(v1_t
, ret
);
21177 gen_helper_addsc(v1_t
, v1_t
, v2_t
, cpu_env
);
21178 gen_store_gpr(v1_t
, ret
);
21182 gen_helper_addwc(v1_t
, v1_t
, v2_t
, cpu_env
);
21183 gen_store_gpr(v1_t
, ret
);
21187 switch (extract32(ctx
->opcode
, 10, 1)) {
21190 gen_helper_addq_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21191 gen_store_gpr(v1_t
, ret
);
21195 gen_helper_addq_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21196 gen_store_gpr(v1_t
, ret
);
21200 case NM_ADDQH_R_PH
:
21202 switch (extract32(ctx
->opcode
, 10, 1)) {
21205 gen_helper_addqh_ph(v1_t
, v1_t
, v2_t
);
21206 gen_store_gpr(v1_t
, ret
);
21210 gen_helper_addqh_r_ph(v1_t
, v1_t
, v2_t
);
21211 gen_store_gpr(v1_t
, ret
);
21217 switch (extract32(ctx
->opcode
, 10, 1)) {
21220 gen_helper_addqh_w(v1_t
, v1_t
, v2_t
);
21221 gen_store_gpr(v1_t
, ret
);
21225 gen_helper_addqh_r_w(v1_t
, v1_t
, v2_t
);
21226 gen_store_gpr(v1_t
, ret
);
21232 switch (extract32(ctx
->opcode
, 10, 1)) {
21235 gen_helper_addu_qb(v1_t
, v1_t
, v2_t
, cpu_env
);
21236 gen_store_gpr(v1_t
, ret
);
21240 gen_helper_addu_s_qb(v1_t
, v1_t
, v2_t
, cpu_env
);
21241 gen_store_gpr(v1_t
, ret
);
21247 switch (extract32(ctx
->opcode
, 10, 1)) {
21250 gen_helper_addu_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21251 gen_store_gpr(v1_t
, ret
);
21255 gen_helper_addu_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21256 gen_store_gpr(v1_t
, ret
);
21260 case NM_ADDUH_R_QB
:
21262 switch (extract32(ctx
->opcode
, 10, 1)) {
21265 gen_helper_adduh_qb(v1_t
, v1_t
, v2_t
);
21266 gen_store_gpr(v1_t
, ret
);
21270 gen_helper_adduh_r_qb(v1_t
, v1_t
, v2_t
);
21271 gen_store_gpr(v1_t
, ret
);
21275 case NM_SHRAV_R_PH
:
21277 switch (extract32(ctx
->opcode
, 10, 1)) {
21280 gen_helper_shra_ph(v1_t
, v1_t
, v2_t
);
21281 gen_store_gpr(v1_t
, ret
);
21285 gen_helper_shra_r_ph(v1_t
, v1_t
, v2_t
);
21286 gen_store_gpr(v1_t
, ret
);
21290 case NM_SHRAV_R_QB
:
21292 switch (extract32(ctx
->opcode
, 10, 1)) {
21295 gen_helper_shra_qb(v1_t
, v1_t
, v2_t
);
21296 gen_store_gpr(v1_t
, ret
);
21300 gen_helper_shra_r_qb(v1_t
, v1_t
, v2_t
);
21301 gen_store_gpr(v1_t
, ret
);
21307 switch (extract32(ctx
->opcode
, 10, 1)) {
21310 gen_helper_subq_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21311 gen_store_gpr(v1_t
, ret
);
21315 gen_helper_subq_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21316 gen_store_gpr(v1_t
, ret
);
21320 case NM_SUBQH_R_PH
:
21322 switch (extract32(ctx
->opcode
, 10, 1)) {
21325 gen_helper_subqh_ph(v1_t
, v1_t
, v2_t
);
21326 gen_store_gpr(v1_t
, ret
);
21330 gen_helper_subqh_r_ph(v1_t
, v1_t
, v2_t
);
21331 gen_store_gpr(v1_t
, ret
);
21337 switch (extract32(ctx
->opcode
, 10, 1)) {
21340 gen_helper_subqh_w(v1_t
, v1_t
, v2_t
);
21341 gen_store_gpr(v1_t
, ret
);
21345 gen_helper_subqh_r_w(v1_t
, v1_t
, v2_t
);
21346 gen_store_gpr(v1_t
, ret
);
21352 switch (extract32(ctx
->opcode
, 10, 1)) {
21355 gen_helper_subu_qb(v1_t
, v1_t
, v2_t
, cpu_env
);
21356 gen_store_gpr(v1_t
, ret
);
21360 gen_helper_subu_s_qb(v1_t
, v1_t
, v2_t
, cpu_env
);
21361 gen_store_gpr(v1_t
, ret
);
21367 switch (extract32(ctx
->opcode
, 10, 1)) {
21370 gen_helper_subu_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21371 gen_store_gpr(v1_t
, ret
);
21375 gen_helper_subu_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21376 gen_store_gpr(v1_t
, ret
);
21380 case NM_SUBUH_R_QB
:
21382 switch (extract32(ctx
->opcode
, 10, 1)) {
21385 gen_helper_subuh_qb(v1_t
, v1_t
, v2_t
);
21386 gen_store_gpr(v1_t
, ret
);
21390 gen_helper_subuh_r_qb(v1_t
, v1_t
, v2_t
);
21391 gen_store_gpr(v1_t
, ret
);
21395 case NM_SHLLV_S_PH
:
21397 switch (extract32(ctx
->opcode
, 10, 1)) {
21400 gen_helper_shll_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21401 gen_store_gpr(v1_t
, ret
);
21405 gen_helper_shll_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21406 gen_store_gpr(v1_t
, ret
);
21410 case NM_PRECR_SRA_R_PH_W
:
21412 switch (extract32(ctx
->opcode
, 10, 1)) {
21414 /* PRECR_SRA_PH_W */
21416 TCGv_i32 sa_t
= tcg_const_i32(rd
);
21417 gen_helper_precr_sra_ph_w(v1_t
, sa_t
, v1_t
,
21419 gen_store_gpr(v1_t
, rt
);
21420 tcg_temp_free_i32(sa_t
);
21424 /* PRECR_SRA_R_PH_W */
21426 TCGv_i32 sa_t
= tcg_const_i32(rd
);
21427 gen_helper_precr_sra_r_ph_w(v1_t
, sa_t
, v1_t
,
21429 gen_store_gpr(v1_t
, rt
);
21430 tcg_temp_free_i32(sa_t
);
21435 case NM_MULEU_S_PH_QBL
:
21437 gen_helper_muleu_s_ph_qbl(v1_t
, v1_t
, v2_t
, cpu_env
);
21438 gen_store_gpr(v1_t
, ret
);
21440 case NM_MULEU_S_PH_QBR
:
21442 gen_helper_muleu_s_ph_qbr(v1_t
, v1_t
, v2_t
, cpu_env
);
21443 gen_store_gpr(v1_t
, ret
);
21445 case NM_MULQ_RS_PH
:
21447 gen_helper_mulq_rs_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21448 gen_store_gpr(v1_t
, ret
);
21452 gen_helper_mulq_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21453 gen_store_gpr(v1_t
, ret
);
21457 gen_helper_mulq_rs_w(v1_t
, v1_t
, v2_t
, cpu_env
);
21458 gen_store_gpr(v1_t
, ret
);
21462 gen_helper_mulq_s_w(v1_t
, v1_t
, v2_t
, cpu_env
);
21463 gen_store_gpr(v1_t
, ret
);
21467 gen_load_gpr(t0
, rs
);
21469 tcg_gen_deposit_tl(cpu_gpr
[rt
], t0
, cpu_gpr
[rt
], rd
, 32 - rd
);
21471 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
21475 gen_helper_modsub(v1_t
, v1_t
, v2_t
);
21476 gen_store_gpr(v1_t
, ret
);
21480 gen_helper_shra_r_w(v1_t
, v1_t
, v2_t
);
21481 gen_store_gpr(v1_t
, ret
);
21485 gen_helper_shrl_ph(v1_t
, v1_t
, v2_t
);
21486 gen_store_gpr(v1_t
, ret
);
21490 gen_helper_shrl_qb(v1_t
, v1_t
, v2_t
);
21491 gen_store_gpr(v1_t
, ret
);
21495 gen_helper_shll_qb(v1_t
, v1_t
, v2_t
, cpu_env
);
21496 gen_store_gpr(v1_t
, ret
);
21500 gen_helper_shll_s_w(v1_t
, v1_t
, v2_t
, cpu_env
);
21501 gen_store_gpr(v1_t
, ret
);
21506 TCGv tv0
= tcg_temp_new();
21507 TCGv tv1
= tcg_temp_new();
21508 int16_t imm
= extract32(ctx
->opcode
, 16, 7);
21510 tcg_gen_movi_tl(tv0
, rd
>> 3);
21511 tcg_gen_movi_tl(tv1
, imm
);
21512 gen_helper_shilo(tv0
, tv1
, cpu_env
);
21515 case NM_MULEQ_S_W_PHL
:
21517 gen_helper_muleq_s_w_phl(v1_t
, v1_t
, v2_t
, cpu_env
);
21518 gen_store_gpr(v1_t
, ret
);
21520 case NM_MULEQ_S_W_PHR
:
21522 gen_helper_muleq_s_w_phr(v1_t
, v1_t
, v2_t
, cpu_env
);
21523 gen_store_gpr(v1_t
, ret
);
21527 switch (extract32(ctx
->opcode
, 10, 1)) {
21530 gen_helper_mul_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21531 gen_store_gpr(v1_t
, ret
);
21535 gen_helper_mul_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21536 gen_store_gpr(v1_t
, ret
);
21540 case NM_PRECR_QB_PH
:
21542 gen_helper_precr_qb_ph(v1_t
, v1_t
, v2_t
);
21543 gen_store_gpr(v1_t
, ret
);
21545 case NM_PRECRQ_QB_PH
:
21547 gen_helper_precrq_qb_ph(v1_t
, v1_t
, v2_t
);
21548 gen_store_gpr(v1_t
, ret
);
21550 case NM_PRECRQ_PH_W
:
21552 gen_helper_precrq_ph_w(v1_t
, v1_t
, v2_t
);
21553 gen_store_gpr(v1_t
, ret
);
21555 case NM_PRECRQ_RS_PH_W
:
21557 gen_helper_precrq_rs_ph_w(v1_t
, v1_t
, v2_t
, cpu_env
);
21558 gen_store_gpr(v1_t
, ret
);
21560 case NM_PRECRQU_S_QB_PH
:
21562 gen_helper_precrqu_s_qb_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21563 gen_store_gpr(v1_t
, ret
);
21567 tcg_gen_movi_tl(t0
, rd
);
21568 gen_helper_shra_r_w(v1_t
, t0
, v1_t
);
21569 gen_store_gpr(v1_t
, rt
);
21573 tcg_gen_movi_tl(t0
, rd
>> 1);
21574 switch (extract32(ctx
->opcode
, 10, 1)) {
21577 gen_helper_shra_ph(v1_t
, t0
, v1_t
);
21578 gen_store_gpr(v1_t
, rt
);
21582 gen_helper_shra_r_ph(v1_t
, t0
, v1_t
);
21583 gen_store_gpr(v1_t
, rt
);
21589 tcg_gen_movi_tl(t0
, rd
>> 1);
21590 switch (extract32(ctx
->opcode
, 10, 2)) {
21593 gen_helper_shll_ph(v1_t
, t0
, v1_t
, cpu_env
);
21594 gen_store_gpr(v1_t
, rt
);
21598 gen_helper_shll_s_ph(v1_t
, t0
, v1_t
, cpu_env
);
21599 gen_store_gpr(v1_t
, rt
);
21602 gen_reserved_instruction(ctx
);
21608 tcg_gen_movi_tl(t0
, rd
);
21609 gen_helper_shll_s_w(v1_t
, t0
, v1_t
, cpu_env
);
21610 gen_store_gpr(v1_t
, rt
);
21616 imm
= sextract32(ctx
->opcode
, 11, 11);
21617 imm
= (int16_t)(imm
<< 6) >> 6;
21619 tcg_gen_movi_tl(cpu_gpr
[rt
], dup_const(MO_16
, imm
));
21624 gen_reserved_instruction(ctx
);
21629 static int decode_nanomips_32_48_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
21637 insn
= cpu_lduw_code(env
, ctx
->base
.pc_next
+ 2);
21638 ctx
->opcode
= (ctx
->opcode
<< 16) | insn
;
21640 rt
= extract32(ctx
->opcode
, 21, 5);
21641 rs
= extract32(ctx
->opcode
, 16, 5);
21642 rd
= extract32(ctx
->opcode
, 11, 5);
21644 op
= extract32(ctx
->opcode
, 26, 6);
21649 switch (extract32(ctx
->opcode
, 19, 2)) {
21652 gen_reserved_instruction(ctx
);
21655 if ((extract32(ctx
->opcode
, 18, 1)) == NM_SYSCALL
) {
21656 generate_exception_end(ctx
, EXCP_SYSCALL
);
21658 gen_reserved_instruction(ctx
);
21662 generate_exception_end(ctx
, EXCP_BREAK
);
21665 if (is_uhi(extract32(ctx
->opcode
, 0, 19))) {
21666 gen_helper_do_semihosting(cpu_env
);
21668 if (ctx
->hflags
& MIPS_HFLAG_SBRI
) {
21669 gen_reserved_instruction(ctx
);
21671 generate_exception_end(ctx
, EXCP_DBp
);
21678 imm
= extract32(ctx
->opcode
, 0, 16);
21680 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], imm
);
21682 tcg_gen_movi_tl(cpu_gpr
[rt
], imm
);
21684 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
21689 offset
= sextract32(ctx
->opcode
, 0, 1) << 21 |
21690 extract32(ctx
->opcode
, 1, 20) << 1;
21691 target_long addr
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
21692 tcg_gen_movi_tl(cpu_gpr
[rt
], addr
);
21696 switch (ctx
->opcode
& 0x07) {
21698 gen_pool32a0_nanomips_insn(env
, ctx
);
21702 int32_t op1
= extract32(ctx
->opcode
, 3, 7);
21703 gen_pool32a5_nanomips_insn(ctx
, op1
, rd
, rs
, rt
);
21707 switch (extract32(ctx
->opcode
, 3, 3)) {
21709 gen_p_lsx(ctx
, rd
, rs
, rt
);
21713 * In nanoMIPS, the shift field directly encodes the shift
21714 * amount, meaning that the supported shift values are in
21715 * the range 0 to 3 (instead of 1 to 4 in MIPSR6).
21717 gen_lsa(ctx
, OPC_LSA
, rd
, rs
, rt
,
21718 extract32(ctx
->opcode
, 9, 2) - 1);
21721 gen_ext(ctx
, 32, rd
, rs
, rt
, extract32(ctx
->opcode
, 6, 5));
21724 gen_pool32axf_nanomips_insn(env
, ctx
);
21727 gen_reserved_instruction(ctx
);
21732 gen_reserved_instruction(ctx
);
21737 switch (ctx
->opcode
& 0x03) {
21740 offset
= extract32(ctx
->opcode
, 0, 21);
21741 gen_op_addr_addi(ctx
, cpu_gpr
[rt
], cpu_gpr
[28], offset
);
21745 gen_ld(ctx
, OPC_LW
, rt
, 28, extract32(ctx
->opcode
, 2, 19) << 2);
21748 gen_st(ctx
, OPC_SW
, rt
, 28, extract32(ctx
->opcode
, 2, 19) << 2);
21751 gen_reserved_instruction(ctx
);
21757 insn
= cpu_lduw_code(env
, ctx
->base
.pc_next
+ 4);
21758 target_long addr_off
= extract32(ctx
->opcode
, 0, 16) | insn
<< 16;
21759 switch (extract32(ctx
->opcode
, 16, 5)) {
21763 tcg_gen_movi_tl(cpu_gpr
[rt
], addr_off
);
21769 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], addr_off
);
21770 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
21776 gen_op_addr_addi(ctx
, cpu_gpr
[rt
], cpu_gpr
[28], addr_off
);
21782 target_long addr
= addr_add(ctx
, ctx
->base
.pc_next
+ 6,
21785 tcg_gen_movi_tl(cpu_gpr
[rt
], addr
);
21792 t0
= tcg_temp_new();
21794 target_long addr
= addr_add(ctx
, ctx
->base
.pc_next
+ 6,
21797 tcg_gen_movi_tl(t0
, addr
);
21798 tcg_gen_qemu_ld_tl(cpu_gpr
[rt
], t0
, ctx
->mem_idx
, MO_TESL
);
21806 t0
= tcg_temp_new();
21807 t1
= tcg_temp_new();
21809 target_long addr
= addr_add(ctx
, ctx
->base
.pc_next
+ 6,
21812 tcg_gen_movi_tl(t0
, addr
);
21813 gen_load_gpr(t1
, rt
);
21815 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
21822 gen_reserved_instruction(ctx
);
21828 switch (extract32(ctx
->opcode
, 12, 4)) {
21830 gen_logic_imm(ctx
, OPC_ORI
, rt
, rs
, extract32(ctx
->opcode
, 0, 12));
21833 gen_logic_imm(ctx
, OPC_XORI
, rt
, rs
, extract32(ctx
->opcode
, 0, 12));
21836 gen_logic_imm(ctx
, OPC_ANDI
, rt
, rs
, extract32(ctx
->opcode
, 0, 12));
21839 switch (extract32(ctx
->opcode
, 20, 1)) {
21841 switch (ctx
->opcode
& 3) {
21843 gen_save(ctx
, rt
, extract32(ctx
->opcode
, 16, 4),
21844 extract32(ctx
->opcode
, 2, 1),
21845 extract32(ctx
->opcode
, 3, 9) << 3);
21848 case NM_RESTORE_JRC
:
21849 gen_restore(ctx
, rt
, extract32(ctx
->opcode
, 16, 4),
21850 extract32(ctx
->opcode
, 2, 1),
21851 extract32(ctx
->opcode
, 3, 9) << 3);
21852 if ((ctx
->opcode
& 3) == NM_RESTORE_JRC
) {
21853 gen_compute_branch_nm(ctx
, OPC_JR
, 2, 31, 0, 0);
21857 gen_reserved_instruction(ctx
);
21862 gen_reserved_instruction(ctx
);
21867 gen_slt_imm(ctx
, OPC_SLTI
, rt
, rs
, extract32(ctx
->opcode
, 0, 12));
21870 gen_slt_imm(ctx
, OPC_SLTIU
, rt
, rs
, extract32(ctx
->opcode
, 0, 12));
21874 TCGv t0
= tcg_temp_new();
21876 imm
= extract32(ctx
->opcode
, 0, 12);
21877 gen_load_gpr(t0
, rs
);
21878 tcg_gen_setcondi_tl(TCG_COND_EQ
, t0
, t0
, imm
);
21879 gen_store_gpr(t0
, rt
);
21885 imm
= (int16_t) extract32(ctx
->opcode
, 0, 12);
21886 gen_arith_imm(ctx
, OPC_ADDIU
, rt
, rs
, -imm
);
21890 int shift
= extract32(ctx
->opcode
, 0, 5);
21891 switch (extract32(ctx
->opcode
, 5, 4)) {
21893 if (rt
== 0 && shift
== 0) {
21895 } else if (rt
== 0 && shift
== 3) {
21896 /* EHB - treat as NOP */
21897 } else if (rt
== 0 && shift
== 5) {
21898 /* PAUSE - treat as NOP */
21899 } else if (rt
== 0 && shift
== 6) {
21901 gen_sync(extract32(ctx
->opcode
, 16, 5));
21904 gen_shift_imm(ctx
, OPC_SLL
, rt
, rs
,
21905 extract32(ctx
->opcode
, 0, 5));
21909 gen_shift_imm(ctx
, OPC_SRL
, rt
, rs
,
21910 extract32(ctx
->opcode
, 0, 5));
21913 gen_shift_imm(ctx
, OPC_SRA
, rt
, rs
,
21914 extract32(ctx
->opcode
, 0, 5));
21917 gen_shift_imm(ctx
, OPC_ROTR
, rt
, rs
,
21918 extract32(ctx
->opcode
, 0, 5));
21926 TCGv t0
= tcg_temp_new();
21927 TCGv_i32 shift
= tcg_const_i32(extract32(ctx
->opcode
, 0, 5));
21928 TCGv_i32 shiftx
= tcg_const_i32(extract32(ctx
->opcode
, 7, 4)
21930 TCGv_i32 stripe
= tcg_const_i32(extract32(ctx
->opcode
, 6, 1));
21932 gen_load_gpr(t0
, rs
);
21933 gen_helper_rotx(cpu_gpr
[rt
], t0
, shift
, shiftx
, stripe
);
21936 tcg_temp_free_i32(shift
);
21937 tcg_temp_free_i32(shiftx
);
21938 tcg_temp_free_i32(stripe
);
21942 switch (((ctx
->opcode
>> 10) & 2) |
21943 (extract32(ctx
->opcode
, 5, 1))) {
21946 gen_bitops(ctx
, OPC_INS
, rt
, rs
, extract32(ctx
->opcode
, 0, 5),
21947 extract32(ctx
->opcode
, 6, 5));
21950 gen_reserved_instruction(ctx
);
21955 switch (((ctx
->opcode
>> 10) & 2) |
21956 (extract32(ctx
->opcode
, 5, 1))) {
21959 gen_bitops(ctx
, OPC_EXT
, rt
, rs
, extract32(ctx
->opcode
, 0, 5),
21960 extract32(ctx
->opcode
, 6, 5));
21963 gen_reserved_instruction(ctx
);
21968 gen_reserved_instruction(ctx
);
21973 gen_pool32f_nanomips_insn(ctx
);
21978 switch (extract32(ctx
->opcode
, 1, 1)) {
21981 tcg_gen_movi_tl(cpu_gpr
[rt
],
21982 sextract32(ctx
->opcode
, 0, 1) << 31 |
21983 extract32(ctx
->opcode
, 2, 10) << 21 |
21984 extract32(ctx
->opcode
, 12, 9) << 12);
21989 offset
= sextract32(ctx
->opcode
, 0, 1) << 31 |
21990 extract32(ctx
->opcode
, 2, 10) << 21 |
21991 extract32(ctx
->opcode
, 12, 9) << 12;
21993 addr
= ~0xFFF & addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
21994 tcg_gen_movi_tl(cpu_gpr
[rt
], addr
);
22001 uint32_t u
= extract32(ctx
->opcode
, 0, 18);
22003 switch (extract32(ctx
->opcode
, 18, 3)) {
22005 gen_ld(ctx
, OPC_LB
, rt
, 28, u
);
22008 gen_st(ctx
, OPC_SB
, rt
, 28, u
);
22011 gen_ld(ctx
, OPC_LBU
, rt
, 28, u
);
22015 gen_op_addr_addi(ctx
, cpu_gpr
[rt
], cpu_gpr
[28], u
);
22020 switch (ctx
->opcode
& 1) {
22022 gen_ld(ctx
, OPC_LH
, rt
, 28, u
);
22025 gen_ld(ctx
, OPC_LHU
, rt
, 28, u
);
22031 switch (ctx
->opcode
& 1) {
22033 gen_st(ctx
, OPC_SH
, rt
, 28, u
);
22036 gen_reserved_instruction(ctx
);
22042 switch (ctx
->opcode
& 0x3) {
22044 gen_cop1_ldst(ctx
, OPC_LWC1
, rt
, 28, u
);
22047 gen_cop1_ldst(ctx
, OPC_LDC1
, rt
, 28, u
);
22050 gen_cop1_ldst(ctx
, OPC_SWC1
, rt
, 28, u
);
22053 gen_cop1_ldst(ctx
, OPC_SDC1
, rt
, 28, u
);
22058 gen_reserved_instruction(ctx
);
22065 uint32_t u
= extract32(ctx
->opcode
, 0, 12);
22067 switch (extract32(ctx
->opcode
, 12, 4)) {
22072 * Break the TB to be able to sync copied instructions
22075 ctx
->base
.is_jmp
= DISAS_STOP
;
22078 /* Treat as NOP. */
22082 gen_ld(ctx
, OPC_LB
, rt
, rs
, u
);
22085 gen_ld(ctx
, OPC_LH
, rt
, rs
, u
);
22088 gen_ld(ctx
, OPC_LW
, rt
, rs
, u
);
22091 gen_ld(ctx
, OPC_LBU
, rt
, rs
, u
);
22094 gen_ld(ctx
, OPC_LHU
, rt
, rs
, u
);
22097 gen_st(ctx
, OPC_SB
, rt
, rs
, u
);
22100 gen_st(ctx
, OPC_SH
, rt
, rs
, u
);
22103 gen_st(ctx
, OPC_SW
, rt
, rs
, u
);
22106 gen_cop1_ldst(ctx
, OPC_LWC1
, rt
, rs
, u
);
22109 gen_cop1_ldst(ctx
, OPC_LDC1
, rt
, rs
, u
);
22112 gen_cop1_ldst(ctx
, OPC_SWC1
, rt
, rs
, u
);
22115 gen_cop1_ldst(ctx
, OPC_SDC1
, rt
, rs
, u
);
22118 gen_reserved_instruction(ctx
);
22125 int32_t s
= (sextract32(ctx
->opcode
, 15, 1) << 8) |
22126 extract32(ctx
->opcode
, 0, 8);
22128 switch (extract32(ctx
->opcode
, 8, 3)) {
22130 switch (extract32(ctx
->opcode
, 11, 4)) {
22132 gen_ld(ctx
, OPC_LB
, rt
, rs
, s
);
22135 gen_ld(ctx
, OPC_LH
, rt
, rs
, s
);
22138 gen_ld(ctx
, OPC_LW
, rt
, rs
, s
);
22141 gen_ld(ctx
, OPC_LBU
, rt
, rs
, s
);
22144 gen_ld(ctx
, OPC_LHU
, rt
, rs
, s
);
22147 gen_st(ctx
, OPC_SB
, rt
, rs
, s
);
22150 gen_st(ctx
, OPC_SH
, rt
, rs
, s
);
22153 gen_st(ctx
, OPC_SW
, rt
, rs
, s
);
22156 gen_cop1_ldst(ctx
, OPC_LWC1
, rt
, rs
, s
);
22159 gen_cop1_ldst(ctx
, OPC_LDC1
, rt
, rs
, s
);
22162 gen_cop1_ldst(ctx
, OPC_SWC1
, rt
, rs
, s
);
22165 gen_cop1_ldst(ctx
, OPC_SDC1
, rt
, rs
, s
);
22171 * Break the TB to be able to sync copied instructions
22174 ctx
->base
.is_jmp
= DISAS_STOP
;
22177 /* Treat as NOP. */
22181 gen_reserved_instruction(ctx
);
22186 switch (extract32(ctx
->opcode
, 11, 4)) {
22191 TCGv t0
= tcg_temp_new();
22192 TCGv t1
= tcg_temp_new();
22194 gen_base_offset_addr(ctx
, t0
, rs
, s
);
22196 switch (extract32(ctx
->opcode
, 11, 4)) {
22198 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESW
|
22200 gen_store_gpr(t0
, rt
);
22203 gen_load_gpr(t1
, rt
);
22204 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUW
|
22213 switch (ctx
->opcode
& 0x03) {
22215 gen_ld(ctx
, OPC_LL
, rt
, rs
, s
);
22219 gen_llwp(ctx
, rs
, 0, rt
, extract32(ctx
->opcode
, 3, 5));
22224 switch (ctx
->opcode
& 0x03) {
22226 gen_st_cond(ctx
, rt
, rs
, s
, MO_TESL
, false);
22230 gen_scwp(ctx
, rs
, 0, rt
, extract32(ctx
->opcode
, 3, 5),
22236 check_cp0_enabled(ctx
);
22237 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
22238 gen_cache_operation(ctx
, rt
, rs
, s
);
22244 switch (extract32(ctx
->opcode
, 11, 4)) {
22247 check_cp0_enabled(ctx
);
22248 gen_ld(ctx
, OPC_LBE
, rt
, rs
, s
);
22252 check_cp0_enabled(ctx
);
22253 gen_st(ctx
, OPC_SBE
, rt
, rs
, s
);
22257 check_cp0_enabled(ctx
);
22258 gen_ld(ctx
, OPC_LBUE
, rt
, rs
, s
);
22262 /* case NM_SYNCIE */
22264 check_cp0_enabled(ctx
);
22266 * Break the TB to be able to sync copied instructions
22269 ctx
->base
.is_jmp
= DISAS_STOP
;
22271 /* case NM_PREFE */
22273 check_cp0_enabled(ctx
);
22274 /* Treat as NOP. */
22279 check_cp0_enabled(ctx
);
22280 gen_ld(ctx
, OPC_LHE
, rt
, rs
, s
);
22284 check_cp0_enabled(ctx
);
22285 gen_st(ctx
, OPC_SHE
, rt
, rs
, s
);
22289 check_cp0_enabled(ctx
);
22290 gen_ld(ctx
, OPC_LHUE
, rt
, rs
, s
);
22293 check_nms_dl_il_sl_tl_l2c(ctx
);
22294 gen_cache_operation(ctx
, rt
, rs
, s
);
22298 check_cp0_enabled(ctx
);
22299 gen_ld(ctx
, OPC_LWE
, rt
, rs
, s
);
22303 check_cp0_enabled(ctx
);
22304 gen_st(ctx
, OPC_SWE
, rt
, rs
, s
);
22307 switch (extract32(ctx
->opcode
, 2, 2)) {
22311 check_cp0_enabled(ctx
);
22312 gen_ld(ctx
, OPC_LLE
, rt
, rs
, s
);
22317 check_cp0_enabled(ctx
);
22318 gen_llwp(ctx
, rs
, 0, rt
, extract32(ctx
->opcode
, 3, 5));
22321 gen_reserved_instruction(ctx
);
22326 switch (extract32(ctx
->opcode
, 2, 2)) {
22330 check_cp0_enabled(ctx
);
22331 gen_st_cond(ctx
, rt
, rs
, s
, MO_TESL
, true);
22336 check_cp0_enabled(ctx
);
22337 gen_scwp(ctx
, rs
, 0, rt
, extract32(ctx
->opcode
, 3, 5),
22341 gen_reserved_instruction(ctx
);
22351 int count
= extract32(ctx
->opcode
, 12, 3);
22354 offset
= sextract32(ctx
->opcode
, 15, 1) << 8 |
22355 extract32(ctx
->opcode
, 0, 8);
22356 TCGv va
= tcg_temp_new();
22357 TCGv t1
= tcg_temp_new();
22358 MemOp memop
= (extract32(ctx
->opcode
, 8, 3)) ==
22359 NM_P_LS_UAWM
? MO_UNALN
: 0;
22361 count
= (count
== 0) ? 8 : count
;
22362 while (counter
!= count
) {
22363 int this_rt
= ((rt
+ counter
) & 0x1f) | (rt
& 0x10);
22364 int this_offset
= offset
+ (counter
<< 2);
22366 gen_base_offset_addr(ctx
, va
, rs
, this_offset
);
22368 switch (extract32(ctx
->opcode
, 11, 1)) {
22370 tcg_gen_qemu_ld_tl(t1
, va
, ctx
->mem_idx
,
22372 gen_store_gpr(t1
, this_rt
);
22373 if ((this_rt
== rs
) &&
22374 (counter
!= (count
- 1))) {
22375 /* UNPREDICTABLE */
22379 this_rt
= (rt
== 0) ? 0 : this_rt
;
22380 gen_load_gpr(t1
, this_rt
);
22381 tcg_gen_qemu_st_tl(t1
, va
, ctx
->mem_idx
,
22392 gen_reserved_instruction(ctx
);
22400 TCGv t0
= tcg_temp_new();
22401 int32_t s
= sextract32(ctx
->opcode
, 0, 1) << 21 |
22402 extract32(ctx
->opcode
, 1, 20) << 1;
22403 rd
= (extract32(ctx
->opcode
, 24, 1)) == 0 ? 4 : 5;
22404 rt
= decode_gpr_gpr4_zero(extract32(ctx
->opcode
, 25, 1) << 3 |
22405 extract32(ctx
->opcode
, 21, 3));
22406 gen_load_gpr(t0
, rt
);
22407 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
22408 gen_compute_branch_nm(ctx
, OPC_BGEZAL
, 4, 0, 0, s
);
22414 int32_t s
= sextract32(ctx
->opcode
, 0, 1) << 25 |
22415 extract32(ctx
->opcode
, 1, 24) << 1;
22417 if ((extract32(ctx
->opcode
, 25, 1)) == 0) {
22419 gen_compute_branch_nm(ctx
, OPC_BEQ
, 4, 0, 0, s
);
22422 gen_compute_branch_nm(ctx
, OPC_BGEZAL
, 4, 0, 0, s
);
22427 switch (extract32(ctx
->opcode
, 12, 4)) {
22430 gen_compute_branch_nm(ctx
, OPC_JALR
, 4, rs
, rt
, 0);
22433 gen_compute_nanomips_pbalrsc_branch(ctx
, rs
, rt
);
22436 gen_reserved_instruction(ctx
);
22442 int32_t s
= sextract32(ctx
->opcode
, 0, 1) << 14 |
22443 extract32(ctx
->opcode
, 1, 13) << 1;
22444 switch (extract32(ctx
->opcode
, 14, 2)) {
22447 gen_compute_branch_nm(ctx
, OPC_BEQ
, 4, rs
, rt
, s
);
22450 s
= sextract32(ctx
->opcode
, 0, 1) << 14 |
22451 extract32(ctx
->opcode
, 1, 13) << 1;
22452 check_cp1_enabled(ctx
);
22453 switch (extract32(ctx
->opcode
, 16, 5)) {
22455 gen_compute_branch_cp1_nm(ctx
, OPC_BC1EQZ
, rt
, s
);
22458 gen_compute_branch_cp1_nm(ctx
, OPC_BC1NEZ
, rt
, s
);
22463 int32_t imm
= extract32(ctx
->opcode
, 1, 13) |
22464 extract32(ctx
->opcode
, 0, 1) << 13;
22466 gen_compute_branch_nm(ctx
, OPC_BPOSGE32
, 4, -1, -2,
22471 gen_reserved_instruction(ctx
);
22477 gen_compute_compact_branch_nm(ctx
, OPC_BC
, rs
, rt
, s
);
22479 gen_compute_compact_branch_nm(ctx
, OPC_BGEC
, rs
, rt
, s
);
22483 if (rs
== rt
|| rt
== 0) {
22484 gen_compute_compact_branch_nm(ctx
, OPC_BC
, 0, 0, s
);
22485 } else if (rs
== 0) {
22486 gen_compute_compact_branch_nm(ctx
, OPC_BEQZC
, rt
, 0, s
);
22488 gen_compute_compact_branch_nm(ctx
, OPC_BGEUC
, rs
, rt
, s
);
22496 int32_t s
= sextract32(ctx
->opcode
, 0, 1) << 14 |
22497 extract32(ctx
->opcode
, 1, 13) << 1;
22498 switch (extract32(ctx
->opcode
, 14, 2)) {
22501 gen_compute_branch_nm(ctx
, OPC_BNE
, 4, rs
, rt
, s
);
22504 if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
22506 ctx
->hflags
|= MIPS_HFLAG_FBNSLOT
;
22508 gen_compute_compact_branch_nm(ctx
, OPC_BLTC
, rs
, rt
, s
);
22512 if (rs
== 0 || rs
== rt
) {
22514 ctx
->hflags
|= MIPS_HFLAG_FBNSLOT
;
22516 gen_compute_compact_branch_nm(ctx
, OPC_BLTUC
, rs
, rt
, s
);
22520 gen_reserved_instruction(ctx
);
22527 int32_t s
= sextract32(ctx
->opcode
, 0, 1) << 11 |
22528 extract32(ctx
->opcode
, 1, 10) << 1;
22529 uint32_t u
= extract32(ctx
->opcode
, 11, 7);
22531 gen_compute_imm_branch(ctx
, extract32(ctx
->opcode
, 18, 3),
22536 gen_reserved_instruction(ctx
);
22542 static int decode_nanomips_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
22545 int rt
= decode_gpr_gpr3(NANOMIPS_EXTRACT_RT3(ctx
->opcode
));
22546 int rs
= decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx
->opcode
));
22547 int rd
= decode_gpr_gpr3(NANOMIPS_EXTRACT_RD3(ctx
->opcode
));
22551 /* make sure instructions are on a halfword boundary */
22552 if (ctx
->base
.pc_next
& 0x1) {
22553 TCGv tmp
= tcg_const_tl(ctx
->base
.pc_next
);
22554 tcg_gen_st_tl(tmp
, cpu_env
, offsetof(CPUMIPSState
, CP0_BadVAddr
));
22555 tcg_temp_free(tmp
);
22556 generate_exception_end(ctx
, EXCP_AdEL
);
22560 op
= extract32(ctx
->opcode
, 10, 6);
22563 rt
= NANOMIPS_EXTRACT_RD5(ctx
->opcode
);
22566 rs
= NANOMIPS_EXTRACT_RS5(ctx
->opcode
);
22567 gen_arith(ctx
, OPC_ADDU
, rt
, rs
, 0);
22570 switch (extract32(ctx
->opcode
, 3, 2)) {
22571 case NM_P16_SYSCALL
:
22572 if (extract32(ctx
->opcode
, 2, 1) == 0) {
22573 generate_exception_end(ctx
, EXCP_SYSCALL
);
22575 gen_reserved_instruction(ctx
);
22579 generate_exception_end(ctx
, EXCP_BREAK
);
22582 if (is_uhi(extract32(ctx
->opcode
, 0, 3))) {
22583 gen_helper_do_semihosting(cpu_env
);
22585 if (ctx
->hflags
& MIPS_HFLAG_SBRI
) {
22586 gen_reserved_instruction(ctx
);
22588 generate_exception_end(ctx
, EXCP_DBp
);
22593 gen_reserved_instruction(ctx
);
22600 int shift
= extract32(ctx
->opcode
, 0, 3);
22602 shift
= (shift
== 0) ? 8 : shift
;
22604 switch (extract32(ctx
->opcode
, 3, 1)) {
22612 gen_shift_imm(ctx
, opc
, rt
, rs
, shift
);
22616 switch (ctx
->opcode
& 1) {
22618 gen_pool16c_nanomips_insn(ctx
);
22621 gen_ldxs(ctx
, rt
, rs
, rd
);
22626 switch (extract32(ctx
->opcode
, 6, 1)) {
22628 imm
= extract32(ctx
->opcode
, 0, 6) << 2;
22629 gen_arith_imm(ctx
, OPC_ADDIU
, rt
, 29, imm
);
22632 gen_reserved_instruction(ctx
);
22637 switch (extract32(ctx
->opcode
, 3, 1)) {
22639 imm
= extract32(ctx
->opcode
, 0, 3) << 2;
22640 gen_arith_imm(ctx
, OPC_ADDIU
, rt
, rs
, imm
);
22642 case NM_P_ADDIURS5
:
22643 rt
= extract32(ctx
->opcode
, 5, 5);
22645 /* imm = sign_extend(s[3] . s[2:0] , from_nbits = 4) */
22646 imm
= (sextract32(ctx
->opcode
, 4, 1) << 3) |
22647 (extract32(ctx
->opcode
, 0, 3));
22648 gen_arith_imm(ctx
, OPC_ADDIU
, rt
, rt
, imm
);
22654 switch (ctx
->opcode
& 0x1) {
22656 gen_arith(ctx
, OPC_ADDU
, rd
, rs
, rt
);
22659 gen_arith(ctx
, OPC_SUBU
, rd
, rs
, rt
);
22664 rt
= (extract32(ctx
->opcode
, 9, 1) << 3) |
22665 extract32(ctx
->opcode
, 5, 3);
22666 rs
= (extract32(ctx
->opcode
, 4, 1) << 3) |
22667 extract32(ctx
->opcode
, 0, 3);
22668 rt
= decode_gpr_gpr4(rt
);
22669 rs
= decode_gpr_gpr4(rs
);
22670 switch ((extract32(ctx
->opcode
, 7, 2) & 0x2) |
22671 (extract32(ctx
->opcode
, 3, 1))) {
22674 gen_arith(ctx
, OPC_ADDU
, rt
, rs
, rt
);
22678 gen_r6_muldiv(ctx
, R6_OPC_MUL
, rt
, rs
, rt
);
22681 gen_reserved_instruction(ctx
);
22687 int imm
= extract32(ctx
->opcode
, 0, 7);
22688 imm
= (imm
== 0x7f ? -1 : imm
);
22690 tcg_gen_movi_tl(cpu_gpr
[rt
], imm
);
22696 uint32_t u
= extract32(ctx
->opcode
, 0, 4);
22697 u
= (u
== 12) ? 0xff :
22698 (u
== 13) ? 0xffff : u
;
22699 gen_logic_imm(ctx
, OPC_ANDI
, rt
, rs
, u
);
22703 offset
= extract32(ctx
->opcode
, 0, 2);
22704 switch (extract32(ctx
->opcode
, 2, 2)) {
22706 gen_ld(ctx
, OPC_LB
, rt
, rs
, offset
);
22709 rt
= decode_gpr_gpr3_src_store(
22710 NANOMIPS_EXTRACT_RT3(ctx
->opcode
));
22711 gen_st(ctx
, OPC_SB
, rt
, rs
, offset
);
22714 gen_ld(ctx
, OPC_LBU
, rt
, rs
, offset
);
22717 gen_reserved_instruction(ctx
);
22722 offset
= extract32(ctx
->opcode
, 1, 2) << 1;
22723 switch ((extract32(ctx
->opcode
, 3, 1) << 1) | (ctx
->opcode
& 1)) {
22725 gen_ld(ctx
, OPC_LH
, rt
, rs
, offset
);
22728 rt
= decode_gpr_gpr3_src_store(
22729 NANOMIPS_EXTRACT_RT3(ctx
->opcode
));
22730 gen_st(ctx
, OPC_SH
, rt
, rs
, offset
);
22733 gen_ld(ctx
, OPC_LHU
, rt
, rs
, offset
);
22736 gen_reserved_instruction(ctx
);
22741 offset
= extract32(ctx
->opcode
, 0, 4) << 2;
22742 gen_ld(ctx
, OPC_LW
, rt
, rs
, offset
);
22745 rt
= NANOMIPS_EXTRACT_RD5(ctx
->opcode
);
22746 offset
= extract32(ctx
->opcode
, 0, 5) << 2;
22747 gen_ld(ctx
, OPC_LW
, rt
, 29, offset
);
22751 rt
= (extract32(ctx
->opcode
, 9, 1) << 3) |
22752 extract32(ctx
->opcode
, 5, 3);
22753 rs
= (extract32(ctx
->opcode
, 4, 1) << 3) |
22754 extract32(ctx
->opcode
, 0, 3);
22755 offset
= (extract32(ctx
->opcode
, 3, 1) << 3) |
22756 (extract32(ctx
->opcode
, 8, 1) << 2);
22757 rt
= decode_gpr_gpr4(rt
);
22758 rs
= decode_gpr_gpr4(rs
);
22759 gen_ld(ctx
, OPC_LW
, rt
, rs
, offset
);
22763 rt
= (extract32(ctx
->opcode
, 9, 1) << 3) |
22764 extract32(ctx
->opcode
, 5, 3);
22765 rs
= (extract32(ctx
->opcode
, 4, 1) << 3) |
22766 extract32(ctx
->opcode
, 0, 3);
22767 offset
= (extract32(ctx
->opcode
, 3, 1) << 3) |
22768 (extract32(ctx
->opcode
, 8, 1) << 2);
22769 rt
= decode_gpr_gpr4_zero(rt
);
22770 rs
= decode_gpr_gpr4(rs
);
22771 gen_st(ctx
, OPC_SW
, rt
, rs
, offset
);
22774 offset
= extract32(ctx
->opcode
, 0, 7) << 2;
22775 gen_ld(ctx
, OPC_LW
, rt
, 28, offset
);
22778 rt
= NANOMIPS_EXTRACT_RD5(ctx
->opcode
);
22779 offset
= extract32(ctx
->opcode
, 0, 5) << 2;
22780 gen_st(ctx
, OPC_SW
, rt
, 29, offset
);
22783 rt
= decode_gpr_gpr3_src_store(
22784 NANOMIPS_EXTRACT_RT3(ctx
->opcode
));
22785 rs
= decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx
->opcode
));
22786 offset
= extract32(ctx
->opcode
, 0, 4) << 2;
22787 gen_st(ctx
, OPC_SW
, rt
, rs
, offset
);
22790 rt
= decode_gpr_gpr3_src_store(
22791 NANOMIPS_EXTRACT_RT3(ctx
->opcode
));
22792 offset
= extract32(ctx
->opcode
, 0, 7) << 2;
22793 gen_st(ctx
, OPC_SW
, rt
, 28, offset
);
22796 gen_compute_branch_nm(ctx
, OPC_BEQ
, 2, 0, 0,
22797 (sextract32(ctx
->opcode
, 0, 1) << 10) |
22798 (extract32(ctx
->opcode
, 1, 9) << 1));
22801 gen_compute_branch_nm(ctx
, OPC_BGEZAL
, 2, 0, 0,
22802 (sextract32(ctx
->opcode
, 0, 1) << 10) |
22803 (extract32(ctx
->opcode
, 1, 9) << 1));
22806 gen_compute_branch_nm(ctx
, OPC_BEQ
, 2, rt
, 0,
22807 (sextract32(ctx
->opcode
, 0, 1) << 7) |
22808 (extract32(ctx
->opcode
, 1, 6) << 1));
22811 gen_compute_branch_nm(ctx
, OPC_BNE
, 2, rt
, 0,
22812 (sextract32(ctx
->opcode
, 0, 1) << 7) |
22813 (extract32(ctx
->opcode
, 1, 6) << 1));
22816 switch (ctx
->opcode
& 0xf) {
22819 switch (extract32(ctx
->opcode
, 4, 1)) {
22821 gen_compute_branch_nm(ctx
, OPC_JR
, 2,
22822 extract32(ctx
->opcode
, 5, 5), 0, 0);
22825 gen_compute_branch_nm(ctx
, OPC_JALR
, 2,
22826 extract32(ctx
->opcode
, 5, 5), 31, 0);
22833 uint32_t opc
= extract32(ctx
->opcode
, 4, 3) <
22834 extract32(ctx
->opcode
, 7, 3) ? OPC_BEQ
: OPC_BNE
;
22835 gen_compute_branch_nm(ctx
, opc
, 2, rs
, rt
,
22836 extract32(ctx
->opcode
, 0, 4) << 1);
22843 int count
= extract32(ctx
->opcode
, 0, 4);
22844 int u
= extract32(ctx
->opcode
, 4, 4) << 4;
22846 rt
= 30 + extract32(ctx
->opcode
, 9, 1);
22847 switch (extract32(ctx
->opcode
, 8, 1)) {
22849 gen_save(ctx
, rt
, count
, 0, u
);
22851 case NM_RESTORE_JRC16
:
22852 gen_restore(ctx
, rt
, count
, 0, u
);
22853 gen_compute_branch_nm(ctx
, OPC_JR
, 2, 31, 0, 0);
22862 static const int gpr2reg1
[] = {4, 5, 6, 7};
22863 static const int gpr2reg2
[] = {5, 6, 7, 8};
22865 int rd2
= extract32(ctx
->opcode
, 3, 1) << 1 |
22866 extract32(ctx
->opcode
, 8, 1);
22867 int r1
= gpr2reg1
[rd2
];
22868 int r2
= gpr2reg2
[rd2
];
22869 int r3
= extract32(ctx
->opcode
, 4, 1) << 3 |
22870 extract32(ctx
->opcode
, 0, 3);
22871 int r4
= extract32(ctx
->opcode
, 9, 1) << 3 |
22872 extract32(ctx
->opcode
, 5, 3);
22873 TCGv t0
= tcg_temp_new();
22874 TCGv t1
= tcg_temp_new();
22875 if (op
== NM_MOVEP
) {
22878 rs
= decode_gpr_gpr4_zero(r3
);
22879 rt
= decode_gpr_gpr4_zero(r4
);
22881 rd
= decode_gpr_gpr4(r3
);
22882 re
= decode_gpr_gpr4(r4
);
22886 gen_load_gpr(t0
, rs
);
22887 gen_load_gpr(t1
, rt
);
22888 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
22889 tcg_gen_mov_tl(cpu_gpr
[re
], t1
);
22895 return decode_nanomips_32_48_opc(env
, ctx
);
22902 /* SmartMIPS extension to MIPS32 */
22904 #if defined(TARGET_MIPS64)
22906 /* MDMX extension to MIPS64 */
22910 /* MIPSDSP functions. */
22911 static void gen_mipsdsp_ld(DisasContext
*ctx
, uint32_t opc
,
22912 int rd
, int base
, int offset
)
22917 t0
= tcg_temp_new();
22920 gen_load_gpr(t0
, offset
);
22921 } else if (offset
== 0) {
22922 gen_load_gpr(t0
, base
);
22924 gen_op_addr_add(ctx
, t0
, cpu_gpr
[base
], cpu_gpr
[offset
]);
22929 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_UB
);
22930 gen_store_gpr(t0
, rd
);
22933 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESW
);
22934 gen_store_gpr(t0
, rd
);
22937 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESL
);
22938 gen_store_gpr(t0
, rd
);
22940 #if defined(TARGET_MIPS64)
22942 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
);
22943 gen_store_gpr(t0
, rd
);
22950 static void gen_mipsdsp_arith(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
22951 int ret
, int v1
, int v2
)
22957 /* Treat as NOP. */
22961 v1_t
= tcg_temp_new();
22962 v2_t
= tcg_temp_new();
22964 gen_load_gpr(v1_t
, v1
);
22965 gen_load_gpr(v2_t
, v2
);
22968 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
22969 case OPC_MULT_G_2E
:
22973 gen_helper_adduh_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
22975 case OPC_ADDUH_R_QB
:
22976 gen_helper_adduh_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
22979 gen_helper_addqh_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
22981 case OPC_ADDQH_R_PH
:
22982 gen_helper_addqh_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
22985 gen_helper_addqh_w(cpu_gpr
[ret
], v1_t
, v2_t
);
22987 case OPC_ADDQH_R_W
:
22988 gen_helper_addqh_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
22991 gen_helper_subuh_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
22993 case OPC_SUBUH_R_QB
:
22994 gen_helper_subuh_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
22997 gen_helper_subqh_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
22999 case OPC_SUBQH_R_PH
:
23000 gen_helper_subqh_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
23003 gen_helper_subqh_w(cpu_gpr
[ret
], v1_t
, v2_t
);
23005 case OPC_SUBQH_R_W
:
23006 gen_helper_subqh_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
23010 case OPC_ABSQ_S_PH_DSP
:
23012 case OPC_ABSQ_S_QB
:
23014 gen_helper_absq_s_qb(cpu_gpr
[ret
], v2_t
, cpu_env
);
23016 case OPC_ABSQ_S_PH
:
23018 gen_helper_absq_s_ph(cpu_gpr
[ret
], v2_t
, cpu_env
);
23022 gen_helper_absq_s_w(cpu_gpr
[ret
], v2_t
, cpu_env
);
23024 case OPC_PRECEQ_W_PHL
:
23026 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0xFFFF0000);
23027 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
23029 case OPC_PRECEQ_W_PHR
:
23031 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0x0000FFFF);
23032 tcg_gen_shli_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], 16);
23033 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
23035 case OPC_PRECEQU_PH_QBL
:
23037 gen_helper_precequ_ph_qbl(cpu_gpr
[ret
], v2_t
);
23039 case OPC_PRECEQU_PH_QBR
:
23041 gen_helper_precequ_ph_qbr(cpu_gpr
[ret
], v2_t
);
23043 case OPC_PRECEQU_PH_QBLA
:
23045 gen_helper_precequ_ph_qbla(cpu_gpr
[ret
], v2_t
);
23047 case OPC_PRECEQU_PH_QBRA
:
23049 gen_helper_precequ_ph_qbra(cpu_gpr
[ret
], v2_t
);
23051 case OPC_PRECEU_PH_QBL
:
23053 gen_helper_preceu_ph_qbl(cpu_gpr
[ret
], v2_t
);
23055 case OPC_PRECEU_PH_QBR
:
23057 gen_helper_preceu_ph_qbr(cpu_gpr
[ret
], v2_t
);
23059 case OPC_PRECEU_PH_QBLA
:
23061 gen_helper_preceu_ph_qbla(cpu_gpr
[ret
], v2_t
);
23063 case OPC_PRECEU_PH_QBRA
:
23065 gen_helper_preceu_ph_qbra(cpu_gpr
[ret
], v2_t
);
23069 case OPC_ADDU_QB_DSP
:
23073 gen_helper_addq_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23075 case OPC_ADDQ_S_PH
:
23077 gen_helper_addq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23081 gen_helper_addq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23085 gen_helper_addu_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23087 case OPC_ADDU_S_QB
:
23089 gen_helper_addu_s_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23093 gen_helper_addu_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23095 case OPC_ADDU_S_PH
:
23097 gen_helper_addu_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23101 gen_helper_subq_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23103 case OPC_SUBQ_S_PH
:
23105 gen_helper_subq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23109 gen_helper_subq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23113 gen_helper_subu_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23115 case OPC_SUBU_S_QB
:
23117 gen_helper_subu_s_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23121 gen_helper_subu_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23123 case OPC_SUBU_S_PH
:
23125 gen_helper_subu_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23129 gen_helper_addsc(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23133 gen_helper_addwc(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23137 gen_helper_modsub(cpu_gpr
[ret
], v1_t
, v2_t
);
23139 case OPC_RADDU_W_QB
:
23141 gen_helper_raddu_w_qb(cpu_gpr
[ret
], v1_t
);
23145 case OPC_CMPU_EQ_QB_DSP
:
23147 case OPC_PRECR_QB_PH
:
23149 gen_helper_precr_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
23151 case OPC_PRECRQ_QB_PH
:
23153 gen_helper_precrq_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
23155 case OPC_PRECR_SRA_PH_W
:
23158 TCGv_i32 sa_t
= tcg_const_i32(v2
);
23159 gen_helper_precr_sra_ph_w(cpu_gpr
[ret
], sa_t
, v1_t
,
23161 tcg_temp_free_i32(sa_t
);
23164 case OPC_PRECR_SRA_R_PH_W
:
23167 TCGv_i32 sa_t
= tcg_const_i32(v2
);
23168 gen_helper_precr_sra_r_ph_w(cpu_gpr
[ret
], sa_t
, v1_t
,
23170 tcg_temp_free_i32(sa_t
);
23173 case OPC_PRECRQ_PH_W
:
23175 gen_helper_precrq_ph_w(cpu_gpr
[ret
], v1_t
, v2_t
);
23177 case OPC_PRECRQ_RS_PH_W
:
23179 gen_helper_precrq_rs_ph_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23181 case OPC_PRECRQU_S_QB_PH
:
23183 gen_helper_precrqu_s_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23187 #ifdef TARGET_MIPS64
23188 case OPC_ABSQ_S_QH_DSP
:
23190 case OPC_PRECEQ_L_PWL
:
23192 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0xFFFFFFFF00000000ull
);
23194 case OPC_PRECEQ_L_PWR
:
23196 tcg_gen_shli_tl(cpu_gpr
[ret
], v2_t
, 32);
23198 case OPC_PRECEQ_PW_QHL
:
23200 gen_helper_preceq_pw_qhl(cpu_gpr
[ret
], v2_t
);
23202 case OPC_PRECEQ_PW_QHR
:
23204 gen_helper_preceq_pw_qhr(cpu_gpr
[ret
], v2_t
);
23206 case OPC_PRECEQ_PW_QHLA
:
23208 gen_helper_preceq_pw_qhla(cpu_gpr
[ret
], v2_t
);
23210 case OPC_PRECEQ_PW_QHRA
:
23212 gen_helper_preceq_pw_qhra(cpu_gpr
[ret
], v2_t
);
23214 case OPC_PRECEQU_QH_OBL
:
23216 gen_helper_precequ_qh_obl(cpu_gpr
[ret
], v2_t
);
23218 case OPC_PRECEQU_QH_OBR
:
23220 gen_helper_precequ_qh_obr(cpu_gpr
[ret
], v2_t
);
23222 case OPC_PRECEQU_QH_OBLA
:
23224 gen_helper_precequ_qh_obla(cpu_gpr
[ret
], v2_t
);
23226 case OPC_PRECEQU_QH_OBRA
:
23228 gen_helper_precequ_qh_obra(cpu_gpr
[ret
], v2_t
);
23230 case OPC_PRECEU_QH_OBL
:
23232 gen_helper_preceu_qh_obl(cpu_gpr
[ret
], v2_t
);
23234 case OPC_PRECEU_QH_OBR
:
23236 gen_helper_preceu_qh_obr(cpu_gpr
[ret
], v2_t
);
23238 case OPC_PRECEU_QH_OBLA
:
23240 gen_helper_preceu_qh_obla(cpu_gpr
[ret
], v2_t
);
23242 case OPC_PRECEU_QH_OBRA
:
23244 gen_helper_preceu_qh_obra(cpu_gpr
[ret
], v2_t
);
23246 case OPC_ABSQ_S_OB
:
23248 gen_helper_absq_s_ob(cpu_gpr
[ret
], v2_t
, cpu_env
);
23250 case OPC_ABSQ_S_PW
:
23252 gen_helper_absq_s_pw(cpu_gpr
[ret
], v2_t
, cpu_env
);
23254 case OPC_ABSQ_S_QH
:
23256 gen_helper_absq_s_qh(cpu_gpr
[ret
], v2_t
, cpu_env
);
23260 case OPC_ADDU_OB_DSP
:
23262 case OPC_RADDU_L_OB
:
23264 gen_helper_raddu_l_ob(cpu_gpr
[ret
], v1_t
);
23268 gen_helper_subq_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23270 case OPC_SUBQ_S_PW
:
23272 gen_helper_subq_s_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23276 gen_helper_subq_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23278 case OPC_SUBQ_S_QH
:
23280 gen_helper_subq_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23284 gen_helper_subu_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23286 case OPC_SUBU_S_OB
:
23288 gen_helper_subu_s_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23292 gen_helper_subu_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23294 case OPC_SUBU_S_QH
:
23296 gen_helper_subu_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23300 gen_helper_subuh_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
23302 case OPC_SUBUH_R_OB
:
23304 gen_helper_subuh_r_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
23308 gen_helper_addq_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23310 case OPC_ADDQ_S_PW
:
23312 gen_helper_addq_s_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23316 gen_helper_addq_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23318 case OPC_ADDQ_S_QH
:
23320 gen_helper_addq_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23324 gen_helper_addu_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23326 case OPC_ADDU_S_OB
:
23328 gen_helper_addu_s_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23332 gen_helper_addu_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23334 case OPC_ADDU_S_QH
:
23336 gen_helper_addu_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23340 gen_helper_adduh_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
23342 case OPC_ADDUH_R_OB
:
23344 gen_helper_adduh_r_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
23348 case OPC_CMPU_EQ_OB_DSP
:
23350 case OPC_PRECR_OB_QH
:
23352 gen_helper_precr_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
);
23354 case OPC_PRECR_SRA_QH_PW
:
23357 TCGv_i32 ret_t
= tcg_const_i32(ret
);
23358 gen_helper_precr_sra_qh_pw(v2_t
, v1_t
, v2_t
, ret_t
);
23359 tcg_temp_free_i32(ret_t
);
23362 case OPC_PRECR_SRA_R_QH_PW
:
23365 TCGv_i32 sa_v
= tcg_const_i32(ret
);
23366 gen_helper_precr_sra_r_qh_pw(v2_t
, v1_t
, v2_t
, sa_v
);
23367 tcg_temp_free_i32(sa_v
);
23370 case OPC_PRECRQ_OB_QH
:
23372 gen_helper_precrq_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
);
23374 case OPC_PRECRQ_PW_L
:
23376 gen_helper_precrq_pw_l(cpu_gpr
[ret
], v1_t
, v2_t
);
23378 case OPC_PRECRQ_QH_PW
:
23380 gen_helper_precrq_qh_pw(cpu_gpr
[ret
], v1_t
, v2_t
);
23382 case OPC_PRECRQ_RS_QH_PW
:
23384 gen_helper_precrq_rs_qh_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23386 case OPC_PRECRQU_S_OB_QH
:
23388 gen_helper_precrqu_s_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23395 tcg_temp_free(v1_t
);
23396 tcg_temp_free(v2_t
);
23399 static void gen_mipsdsp_shift(DisasContext
*ctx
, uint32_t opc
,
23400 int ret
, int v1
, int v2
)
23408 /* Treat as NOP. */
23412 t0
= tcg_temp_new();
23413 v1_t
= tcg_temp_new();
23414 v2_t
= tcg_temp_new();
23416 tcg_gen_movi_tl(t0
, v1
);
23417 gen_load_gpr(v1_t
, v1
);
23418 gen_load_gpr(v2_t
, v2
);
23421 case OPC_SHLL_QB_DSP
:
23423 op2
= MASK_SHLL_QB(ctx
->opcode
);
23427 gen_helper_shll_qb(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
23431 gen_helper_shll_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23435 gen_helper_shll_ph(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
23439 gen_helper_shll_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23441 case OPC_SHLL_S_PH
:
23443 gen_helper_shll_s_ph(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
23445 case OPC_SHLLV_S_PH
:
23447 gen_helper_shll_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23451 gen_helper_shll_s_w(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
23453 case OPC_SHLLV_S_W
:
23455 gen_helper_shll_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23459 gen_helper_shrl_qb(cpu_gpr
[ret
], t0
, v2_t
);
23463 gen_helper_shrl_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
23467 gen_helper_shrl_ph(cpu_gpr
[ret
], t0
, v2_t
);
23471 gen_helper_shrl_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
23475 gen_helper_shra_qb(cpu_gpr
[ret
], t0
, v2_t
);
23477 case OPC_SHRA_R_QB
:
23479 gen_helper_shra_r_qb(cpu_gpr
[ret
], t0
, v2_t
);
23483 gen_helper_shra_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
23485 case OPC_SHRAV_R_QB
:
23487 gen_helper_shra_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
23491 gen_helper_shra_ph(cpu_gpr
[ret
], t0
, v2_t
);
23493 case OPC_SHRA_R_PH
:
23495 gen_helper_shra_r_ph(cpu_gpr
[ret
], t0
, v2_t
);
23499 gen_helper_shra_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
23501 case OPC_SHRAV_R_PH
:
23503 gen_helper_shra_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
23507 gen_helper_shra_r_w(cpu_gpr
[ret
], t0
, v2_t
);
23509 case OPC_SHRAV_R_W
:
23511 gen_helper_shra_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
23513 default: /* Invalid */
23514 MIPS_INVAL("MASK SHLL.QB");
23515 gen_reserved_instruction(ctx
);
23520 #ifdef TARGET_MIPS64
23521 case OPC_SHLL_OB_DSP
:
23522 op2
= MASK_SHLL_OB(ctx
->opcode
);
23526 gen_helper_shll_pw(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
23530 gen_helper_shll_pw(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
23532 case OPC_SHLL_S_PW
:
23534 gen_helper_shll_s_pw(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
23536 case OPC_SHLLV_S_PW
:
23538 gen_helper_shll_s_pw(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
23542 gen_helper_shll_ob(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
23546 gen_helper_shll_ob(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
23550 gen_helper_shll_qh(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
23554 gen_helper_shll_qh(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
23556 case OPC_SHLL_S_QH
:
23558 gen_helper_shll_s_qh(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
23560 case OPC_SHLLV_S_QH
:
23562 gen_helper_shll_s_qh(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
23566 gen_helper_shra_ob(cpu_gpr
[ret
], v2_t
, t0
);
23570 gen_helper_shra_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
23572 case OPC_SHRA_R_OB
:
23574 gen_helper_shra_r_ob(cpu_gpr
[ret
], v2_t
, t0
);
23576 case OPC_SHRAV_R_OB
:
23578 gen_helper_shra_r_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
23582 gen_helper_shra_pw(cpu_gpr
[ret
], v2_t
, t0
);
23586 gen_helper_shra_pw(cpu_gpr
[ret
], v2_t
, v1_t
);
23588 case OPC_SHRA_R_PW
:
23590 gen_helper_shra_r_pw(cpu_gpr
[ret
], v2_t
, t0
);
23592 case OPC_SHRAV_R_PW
:
23594 gen_helper_shra_r_pw(cpu_gpr
[ret
], v2_t
, v1_t
);
23598 gen_helper_shra_qh(cpu_gpr
[ret
], v2_t
, t0
);
23602 gen_helper_shra_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
23604 case OPC_SHRA_R_QH
:
23606 gen_helper_shra_r_qh(cpu_gpr
[ret
], v2_t
, t0
);
23608 case OPC_SHRAV_R_QH
:
23610 gen_helper_shra_r_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
23614 gen_helper_shrl_ob(cpu_gpr
[ret
], v2_t
, t0
);
23618 gen_helper_shrl_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
23622 gen_helper_shrl_qh(cpu_gpr
[ret
], v2_t
, t0
);
23626 gen_helper_shrl_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
23628 default: /* Invalid */
23629 MIPS_INVAL("MASK SHLL.OB");
23630 gen_reserved_instruction(ctx
);
23638 tcg_temp_free(v1_t
);
23639 tcg_temp_free(v2_t
);
23642 static void gen_mipsdsp_multiply(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
23643 int ret
, int v1
, int v2
, int check_ret
)
23649 if ((ret
== 0) && (check_ret
== 1)) {
23650 /* Treat as NOP. */
23654 t0
= tcg_temp_new_i32();
23655 v1_t
= tcg_temp_new();
23656 v2_t
= tcg_temp_new();
23658 tcg_gen_movi_i32(t0
, ret
);
23659 gen_load_gpr(v1_t
, v1
);
23660 gen_load_gpr(v2_t
, v2
);
23664 * OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
23665 * the same mask and op1.
23667 case OPC_MULT_G_2E
:
23671 gen_helper_mul_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23674 gen_helper_mul_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23677 gen_helper_mulq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23679 case OPC_MULQ_RS_W
:
23680 gen_helper_mulq_rs_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23684 case OPC_DPA_W_PH_DSP
:
23686 case OPC_DPAU_H_QBL
:
23688 gen_helper_dpau_h_qbl(t0
, v1_t
, v2_t
, cpu_env
);
23690 case OPC_DPAU_H_QBR
:
23692 gen_helper_dpau_h_qbr(t0
, v1_t
, v2_t
, cpu_env
);
23694 case OPC_DPSU_H_QBL
:
23696 gen_helper_dpsu_h_qbl(t0
, v1_t
, v2_t
, cpu_env
);
23698 case OPC_DPSU_H_QBR
:
23700 gen_helper_dpsu_h_qbr(t0
, v1_t
, v2_t
, cpu_env
);
23704 gen_helper_dpa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23706 case OPC_DPAX_W_PH
:
23708 gen_helper_dpax_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23710 case OPC_DPAQ_S_W_PH
:
23712 gen_helper_dpaq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23714 case OPC_DPAQX_S_W_PH
:
23716 gen_helper_dpaqx_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23718 case OPC_DPAQX_SA_W_PH
:
23720 gen_helper_dpaqx_sa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23724 gen_helper_dps_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23726 case OPC_DPSX_W_PH
:
23728 gen_helper_dpsx_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23730 case OPC_DPSQ_S_W_PH
:
23732 gen_helper_dpsq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23734 case OPC_DPSQX_S_W_PH
:
23736 gen_helper_dpsqx_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23738 case OPC_DPSQX_SA_W_PH
:
23740 gen_helper_dpsqx_sa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23742 case OPC_MULSAQ_S_W_PH
:
23744 gen_helper_mulsaq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23746 case OPC_DPAQ_SA_L_W
:
23748 gen_helper_dpaq_sa_l_w(t0
, v1_t
, v2_t
, cpu_env
);
23750 case OPC_DPSQ_SA_L_W
:
23752 gen_helper_dpsq_sa_l_w(t0
, v1_t
, v2_t
, cpu_env
);
23754 case OPC_MAQ_S_W_PHL
:
23756 gen_helper_maq_s_w_phl(t0
, v1_t
, v2_t
, cpu_env
);
23758 case OPC_MAQ_S_W_PHR
:
23760 gen_helper_maq_s_w_phr(t0
, v1_t
, v2_t
, cpu_env
);
23762 case OPC_MAQ_SA_W_PHL
:
23764 gen_helper_maq_sa_w_phl(t0
, v1_t
, v2_t
, cpu_env
);
23766 case OPC_MAQ_SA_W_PHR
:
23768 gen_helper_maq_sa_w_phr(t0
, v1_t
, v2_t
, cpu_env
);
23770 case OPC_MULSA_W_PH
:
23772 gen_helper_mulsa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23776 #ifdef TARGET_MIPS64
23777 case OPC_DPAQ_W_QH_DSP
:
23779 int ac
= ret
& 0x03;
23780 tcg_gen_movi_i32(t0
, ac
);
23785 gen_helper_dmadd(v1_t
, v2_t
, t0
, cpu_env
);
23789 gen_helper_dmaddu(v1_t
, v2_t
, t0
, cpu_env
);
23793 gen_helper_dmsub(v1_t
, v2_t
, t0
, cpu_env
);
23797 gen_helper_dmsubu(v1_t
, v2_t
, t0
, cpu_env
);
23801 gen_helper_dpa_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
23803 case OPC_DPAQ_S_W_QH
:
23805 gen_helper_dpaq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
23807 case OPC_DPAQ_SA_L_PW
:
23809 gen_helper_dpaq_sa_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
23811 case OPC_DPAU_H_OBL
:
23813 gen_helper_dpau_h_obl(v1_t
, v2_t
, t0
, cpu_env
);
23815 case OPC_DPAU_H_OBR
:
23817 gen_helper_dpau_h_obr(v1_t
, v2_t
, t0
, cpu_env
);
23821 gen_helper_dps_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
23823 case OPC_DPSQ_S_W_QH
:
23825 gen_helper_dpsq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
23827 case OPC_DPSQ_SA_L_PW
:
23829 gen_helper_dpsq_sa_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
23831 case OPC_DPSU_H_OBL
:
23833 gen_helper_dpsu_h_obl(v1_t
, v2_t
, t0
, cpu_env
);
23835 case OPC_DPSU_H_OBR
:
23837 gen_helper_dpsu_h_obr(v1_t
, v2_t
, t0
, cpu_env
);
23839 case OPC_MAQ_S_L_PWL
:
23841 gen_helper_maq_s_l_pwl(v1_t
, v2_t
, t0
, cpu_env
);
23843 case OPC_MAQ_S_L_PWR
:
23845 gen_helper_maq_s_l_pwr(v1_t
, v2_t
, t0
, cpu_env
);
23847 case OPC_MAQ_S_W_QHLL
:
23849 gen_helper_maq_s_w_qhll(v1_t
, v2_t
, t0
, cpu_env
);
23851 case OPC_MAQ_SA_W_QHLL
:
23853 gen_helper_maq_sa_w_qhll(v1_t
, v2_t
, t0
, cpu_env
);
23855 case OPC_MAQ_S_W_QHLR
:
23857 gen_helper_maq_s_w_qhlr(v1_t
, v2_t
, t0
, cpu_env
);
23859 case OPC_MAQ_SA_W_QHLR
:
23861 gen_helper_maq_sa_w_qhlr(v1_t
, v2_t
, t0
, cpu_env
);
23863 case OPC_MAQ_S_W_QHRL
:
23865 gen_helper_maq_s_w_qhrl(v1_t
, v2_t
, t0
, cpu_env
);
23867 case OPC_MAQ_SA_W_QHRL
:
23869 gen_helper_maq_sa_w_qhrl(v1_t
, v2_t
, t0
, cpu_env
);
23871 case OPC_MAQ_S_W_QHRR
:
23873 gen_helper_maq_s_w_qhrr(v1_t
, v2_t
, t0
, cpu_env
);
23875 case OPC_MAQ_SA_W_QHRR
:
23877 gen_helper_maq_sa_w_qhrr(v1_t
, v2_t
, t0
, cpu_env
);
23879 case OPC_MULSAQ_S_L_PW
:
23881 gen_helper_mulsaq_s_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
23883 case OPC_MULSAQ_S_W_QH
:
23885 gen_helper_mulsaq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
23891 case OPC_ADDU_QB_DSP
:
23893 case OPC_MULEU_S_PH_QBL
:
23895 gen_helper_muleu_s_ph_qbl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23897 case OPC_MULEU_S_PH_QBR
:
23899 gen_helper_muleu_s_ph_qbr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23901 case OPC_MULQ_RS_PH
:
23903 gen_helper_mulq_rs_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23905 case OPC_MULEQ_S_W_PHL
:
23907 gen_helper_muleq_s_w_phl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23909 case OPC_MULEQ_S_W_PHR
:
23911 gen_helper_muleq_s_w_phr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23913 case OPC_MULQ_S_PH
:
23915 gen_helper_mulq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23919 #ifdef TARGET_MIPS64
23920 case OPC_ADDU_OB_DSP
:
23922 case OPC_MULEQ_S_PW_QHL
:
23924 gen_helper_muleq_s_pw_qhl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23926 case OPC_MULEQ_S_PW_QHR
:
23928 gen_helper_muleq_s_pw_qhr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23930 case OPC_MULEU_S_QH_OBL
:
23932 gen_helper_muleu_s_qh_obl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23934 case OPC_MULEU_S_QH_OBR
:
23936 gen_helper_muleu_s_qh_obr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23938 case OPC_MULQ_RS_QH
:
23940 gen_helper_mulq_rs_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23947 tcg_temp_free_i32(t0
);
23948 tcg_temp_free(v1_t
);
23949 tcg_temp_free(v2_t
);
23952 static void gen_mipsdsp_bitinsn(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
23960 /* Treat as NOP. */
23964 t0
= tcg_temp_new();
23965 val_t
= tcg_temp_new();
23966 gen_load_gpr(val_t
, val
);
23969 case OPC_ABSQ_S_PH_DSP
:
23973 gen_helper_bitrev(cpu_gpr
[ret
], val_t
);
23978 target_long result
;
23979 imm
= (ctx
->opcode
>> 16) & 0xFF;
23980 result
= (uint32_t)imm
<< 24 |
23981 (uint32_t)imm
<< 16 |
23982 (uint32_t)imm
<< 8 |
23984 result
= (int32_t)result
;
23985 tcg_gen_movi_tl(cpu_gpr
[ret
], result
);
23990 tcg_gen_ext8u_tl(cpu_gpr
[ret
], val_t
);
23991 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 8);
23992 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
23993 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
23994 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
23995 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
24000 imm
= (ctx
->opcode
>> 16) & 0x03FF;
24001 imm
= (int16_t)(imm
<< 6) >> 6;
24002 tcg_gen_movi_tl(cpu_gpr
[ret
], \
24003 (target_long
)((int32_t)imm
<< 16 | \
24009 tcg_gen_ext16u_tl(cpu_gpr
[ret
], val_t
);
24010 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
24011 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
24012 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
24016 #ifdef TARGET_MIPS64
24017 case OPC_ABSQ_S_QH_DSP
:
24024 imm
= (ctx
->opcode
>> 16) & 0xFF;
24025 temp
= ((uint64_t)imm
<< 8) | (uint64_t)imm
;
24026 temp
= (temp
<< 16) | temp
;
24027 temp
= (temp
<< 32) | temp
;
24028 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
24036 imm
= (ctx
->opcode
>> 16) & 0x03FF;
24037 imm
= (int16_t)(imm
<< 6) >> 6;
24038 temp
= ((target_long
)imm
<< 32) \
24039 | ((target_long
)imm
& 0xFFFFFFFF);
24040 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
24048 imm
= (ctx
->opcode
>> 16) & 0x03FF;
24049 imm
= (int16_t)(imm
<< 6) >> 6;
24051 temp
= ((uint64_t)(uint16_t)imm
<< 48) |
24052 ((uint64_t)(uint16_t)imm
<< 32) |
24053 ((uint64_t)(uint16_t)imm
<< 16) |
24054 (uint64_t)(uint16_t)imm
;
24055 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
24060 tcg_gen_ext8u_tl(cpu_gpr
[ret
], val_t
);
24061 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 8);
24062 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
24063 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
24064 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
24065 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
24066 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
24070 tcg_gen_ext32u_i64(cpu_gpr
[ret
], val_t
);
24071 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
24072 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
24076 tcg_gen_ext16u_tl(cpu_gpr
[ret
], val_t
);
24077 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
24078 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
24079 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
24080 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
24087 tcg_temp_free(val_t
);
24090 static void gen_mipsdsp_add_cmp_pick(DisasContext
*ctx
,
24091 uint32_t op1
, uint32_t op2
,
24092 int ret
, int v1
, int v2
, int check_ret
)
24098 if ((ret
== 0) && (check_ret
== 1)) {
24099 /* Treat as NOP. */
24103 t1
= tcg_temp_new();
24104 v1_t
= tcg_temp_new();
24105 v2_t
= tcg_temp_new();
24107 gen_load_gpr(v1_t
, v1
);
24108 gen_load_gpr(v2_t
, v2
);
24111 case OPC_CMPU_EQ_QB_DSP
:
24113 case OPC_CMPU_EQ_QB
:
24115 gen_helper_cmpu_eq_qb(v1_t
, v2_t
, cpu_env
);
24117 case OPC_CMPU_LT_QB
:
24119 gen_helper_cmpu_lt_qb(v1_t
, v2_t
, cpu_env
);
24121 case OPC_CMPU_LE_QB
:
24123 gen_helper_cmpu_le_qb(v1_t
, v2_t
, cpu_env
);
24125 case OPC_CMPGU_EQ_QB
:
24127 gen_helper_cmpgu_eq_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
24129 case OPC_CMPGU_LT_QB
:
24131 gen_helper_cmpgu_lt_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
24133 case OPC_CMPGU_LE_QB
:
24135 gen_helper_cmpgu_le_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
24137 case OPC_CMPGDU_EQ_QB
:
24139 gen_helper_cmpgu_eq_qb(t1
, v1_t
, v2_t
);
24140 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
24141 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
24142 tcg_gen_shli_tl(t1
, t1
, 24);
24143 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
24145 case OPC_CMPGDU_LT_QB
:
24147 gen_helper_cmpgu_lt_qb(t1
, v1_t
, v2_t
);
24148 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
24149 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
24150 tcg_gen_shli_tl(t1
, t1
, 24);
24151 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
24153 case OPC_CMPGDU_LE_QB
:
24155 gen_helper_cmpgu_le_qb(t1
, v1_t
, v2_t
);
24156 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
24157 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
24158 tcg_gen_shli_tl(t1
, t1
, 24);
24159 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
24161 case OPC_CMP_EQ_PH
:
24163 gen_helper_cmp_eq_ph(v1_t
, v2_t
, cpu_env
);
24165 case OPC_CMP_LT_PH
:
24167 gen_helper_cmp_lt_ph(v1_t
, v2_t
, cpu_env
);
24169 case OPC_CMP_LE_PH
:
24171 gen_helper_cmp_le_ph(v1_t
, v2_t
, cpu_env
);
24175 gen_helper_pick_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
24179 gen_helper_pick_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
24181 case OPC_PACKRL_PH
:
24183 gen_helper_packrl_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
24187 #ifdef TARGET_MIPS64
24188 case OPC_CMPU_EQ_OB_DSP
:
24190 case OPC_CMP_EQ_PW
:
24192 gen_helper_cmp_eq_pw(v1_t
, v2_t
, cpu_env
);
24194 case OPC_CMP_LT_PW
:
24196 gen_helper_cmp_lt_pw(v1_t
, v2_t
, cpu_env
);
24198 case OPC_CMP_LE_PW
:
24200 gen_helper_cmp_le_pw(v1_t
, v2_t
, cpu_env
);
24202 case OPC_CMP_EQ_QH
:
24204 gen_helper_cmp_eq_qh(v1_t
, v2_t
, cpu_env
);
24206 case OPC_CMP_LT_QH
:
24208 gen_helper_cmp_lt_qh(v1_t
, v2_t
, cpu_env
);
24210 case OPC_CMP_LE_QH
:
24212 gen_helper_cmp_le_qh(v1_t
, v2_t
, cpu_env
);
24214 case OPC_CMPGDU_EQ_OB
:
24216 gen_helper_cmpgdu_eq_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
24218 case OPC_CMPGDU_LT_OB
:
24220 gen_helper_cmpgdu_lt_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
24222 case OPC_CMPGDU_LE_OB
:
24224 gen_helper_cmpgdu_le_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
24226 case OPC_CMPGU_EQ_OB
:
24228 gen_helper_cmpgu_eq_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
24230 case OPC_CMPGU_LT_OB
:
24232 gen_helper_cmpgu_lt_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
24234 case OPC_CMPGU_LE_OB
:
24236 gen_helper_cmpgu_le_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
24238 case OPC_CMPU_EQ_OB
:
24240 gen_helper_cmpu_eq_ob(v1_t
, v2_t
, cpu_env
);
24242 case OPC_CMPU_LT_OB
:
24244 gen_helper_cmpu_lt_ob(v1_t
, v2_t
, cpu_env
);
24246 case OPC_CMPU_LE_OB
:
24248 gen_helper_cmpu_le_ob(v1_t
, v2_t
, cpu_env
);
24250 case OPC_PACKRL_PW
:
24252 gen_helper_packrl_pw(cpu_gpr
[ret
], v1_t
, v2_t
);
24256 gen_helper_pick_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
24260 gen_helper_pick_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
24264 gen_helper_pick_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
24272 tcg_temp_free(v1_t
);
24273 tcg_temp_free(v2_t
);
24276 static void gen_mipsdsp_append(CPUMIPSState
*env
, DisasContext
*ctx
,
24277 uint32_t op1
, int rt
, int rs
, int sa
)
24284 /* Treat as NOP. */
24288 t0
= tcg_temp_new();
24289 gen_load_gpr(t0
, rs
);
24292 case OPC_APPEND_DSP
:
24293 switch (MASK_APPEND(ctx
->opcode
)) {
24296 tcg_gen_deposit_tl(cpu_gpr
[rt
], t0
, cpu_gpr
[rt
], sa
, 32 - sa
);
24298 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
24302 tcg_gen_ext32u_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
24303 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], sa
);
24304 tcg_gen_shli_tl(t0
, t0
, 32 - sa
);
24305 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
24307 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
24311 if (sa
!= 0 && sa
!= 2) {
24312 tcg_gen_shli_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 8 * sa
);
24313 tcg_gen_ext32u_tl(t0
, t0
);
24314 tcg_gen_shri_tl(t0
, t0
, 8 * (4 - sa
));
24315 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
24317 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
24319 default: /* Invalid */
24320 MIPS_INVAL("MASK APPEND");
24321 gen_reserved_instruction(ctx
);
24325 #ifdef TARGET_MIPS64
24326 case OPC_DAPPEND_DSP
:
24327 switch (MASK_DAPPEND(ctx
->opcode
)) {
24330 tcg_gen_deposit_tl(cpu_gpr
[rt
], t0
, cpu_gpr
[rt
], sa
, 64 - sa
);
24334 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 0x20 | sa
);
24335 tcg_gen_shli_tl(t0
, t0
, 64 - (0x20 | sa
));
24336 tcg_gen_or_tl(cpu_gpr
[rt
], t0
, t0
);
24340 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], sa
);
24341 tcg_gen_shli_tl(t0
, t0
, 64 - sa
);
24342 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
24347 if (sa
!= 0 && sa
!= 2 && sa
!= 4) {
24348 tcg_gen_shli_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 8 * sa
);
24349 tcg_gen_shri_tl(t0
, t0
, 8 * (8 - sa
));
24350 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
24353 default: /* Invalid */
24354 MIPS_INVAL("MASK DAPPEND");
24355 gen_reserved_instruction(ctx
);
24364 static void gen_mipsdsp_accinsn(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
24365 int ret
, int v1
, int v2
, int check_ret
)
24374 if ((ret
== 0) && (check_ret
== 1)) {
24375 /* Treat as NOP. */
24379 t0
= tcg_temp_new();
24380 t1
= tcg_temp_new();
24381 v1_t
= tcg_temp_new();
24382 v2_t
= tcg_temp_new();
24384 gen_load_gpr(v1_t
, v1
);
24385 gen_load_gpr(v2_t
, v2
);
24388 case OPC_EXTR_W_DSP
:
24392 tcg_gen_movi_tl(t0
, v2
);
24393 tcg_gen_movi_tl(t1
, v1
);
24394 gen_helper_extr_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24397 tcg_gen_movi_tl(t0
, v2
);
24398 tcg_gen_movi_tl(t1
, v1
);
24399 gen_helper_extr_r_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24401 case OPC_EXTR_RS_W
:
24402 tcg_gen_movi_tl(t0
, v2
);
24403 tcg_gen_movi_tl(t1
, v1
);
24404 gen_helper_extr_rs_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24407 tcg_gen_movi_tl(t0
, v2
);
24408 tcg_gen_movi_tl(t1
, v1
);
24409 gen_helper_extr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24411 case OPC_EXTRV_S_H
:
24412 tcg_gen_movi_tl(t0
, v2
);
24413 gen_helper_extr_s_h(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24416 tcg_gen_movi_tl(t0
, v2
);
24417 gen_helper_extr_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24419 case OPC_EXTRV_R_W
:
24420 tcg_gen_movi_tl(t0
, v2
);
24421 gen_helper_extr_r_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24423 case OPC_EXTRV_RS_W
:
24424 tcg_gen_movi_tl(t0
, v2
);
24425 gen_helper_extr_rs_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24428 tcg_gen_movi_tl(t0
, v2
);
24429 tcg_gen_movi_tl(t1
, v1
);
24430 gen_helper_extp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24433 tcg_gen_movi_tl(t0
, v2
);
24434 gen_helper_extp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24437 tcg_gen_movi_tl(t0
, v2
);
24438 tcg_gen_movi_tl(t1
, v1
);
24439 gen_helper_extpdp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24442 tcg_gen_movi_tl(t0
, v2
);
24443 gen_helper_extpdp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24446 imm
= (ctx
->opcode
>> 20) & 0x3F;
24447 tcg_gen_movi_tl(t0
, ret
);
24448 tcg_gen_movi_tl(t1
, imm
);
24449 gen_helper_shilo(t0
, t1
, cpu_env
);
24452 tcg_gen_movi_tl(t0
, ret
);
24453 gen_helper_shilo(t0
, v1_t
, cpu_env
);
24456 tcg_gen_movi_tl(t0
, ret
);
24457 gen_helper_mthlip(t0
, v1_t
, cpu_env
);
24460 imm
= (ctx
->opcode
>> 11) & 0x3FF;
24461 tcg_gen_movi_tl(t0
, imm
);
24462 gen_helper_wrdsp(v1_t
, t0
, cpu_env
);
24465 imm
= (ctx
->opcode
>> 16) & 0x03FF;
24466 tcg_gen_movi_tl(t0
, imm
);
24467 gen_helper_rddsp(cpu_gpr
[ret
], t0
, cpu_env
);
24471 #ifdef TARGET_MIPS64
24472 case OPC_DEXTR_W_DSP
:
24476 tcg_gen_movi_tl(t0
, ret
);
24477 gen_helper_dmthlip(v1_t
, t0
, cpu_env
);
24481 int shift
= (ctx
->opcode
>> 19) & 0x7F;
24482 int ac
= (ctx
->opcode
>> 11) & 0x03;
24483 tcg_gen_movi_tl(t0
, shift
);
24484 tcg_gen_movi_tl(t1
, ac
);
24485 gen_helper_dshilo(t0
, t1
, cpu_env
);
24490 int ac
= (ctx
->opcode
>> 11) & 0x03;
24491 tcg_gen_movi_tl(t0
, ac
);
24492 gen_helper_dshilo(v1_t
, t0
, cpu_env
);
24496 tcg_gen_movi_tl(t0
, v2
);
24497 tcg_gen_movi_tl(t1
, v1
);
24499 gen_helper_dextp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24502 tcg_gen_movi_tl(t0
, v2
);
24503 gen_helper_dextp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24506 tcg_gen_movi_tl(t0
, v2
);
24507 tcg_gen_movi_tl(t1
, v1
);
24508 gen_helper_dextpdp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24511 tcg_gen_movi_tl(t0
, v2
);
24512 gen_helper_dextpdp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24515 tcg_gen_movi_tl(t0
, v2
);
24516 tcg_gen_movi_tl(t1
, v1
);
24517 gen_helper_dextr_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24519 case OPC_DEXTR_R_L
:
24520 tcg_gen_movi_tl(t0
, v2
);
24521 tcg_gen_movi_tl(t1
, v1
);
24522 gen_helper_dextr_r_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24524 case OPC_DEXTR_RS_L
:
24525 tcg_gen_movi_tl(t0
, v2
);
24526 tcg_gen_movi_tl(t1
, v1
);
24527 gen_helper_dextr_rs_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24530 tcg_gen_movi_tl(t0
, v2
);
24531 tcg_gen_movi_tl(t1
, v1
);
24532 gen_helper_dextr_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24534 case OPC_DEXTR_R_W
:
24535 tcg_gen_movi_tl(t0
, v2
);
24536 tcg_gen_movi_tl(t1
, v1
);
24537 gen_helper_dextr_r_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24539 case OPC_DEXTR_RS_W
:
24540 tcg_gen_movi_tl(t0
, v2
);
24541 tcg_gen_movi_tl(t1
, v1
);
24542 gen_helper_dextr_rs_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24544 case OPC_DEXTR_S_H
:
24545 tcg_gen_movi_tl(t0
, v2
);
24546 tcg_gen_movi_tl(t1
, v1
);
24547 gen_helper_dextr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24549 case OPC_DEXTRV_S_H
:
24550 tcg_gen_movi_tl(t0
, v2
);
24551 tcg_gen_movi_tl(t1
, v1
);
24552 gen_helper_dextr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24555 tcg_gen_movi_tl(t0
, v2
);
24556 gen_helper_dextr_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24558 case OPC_DEXTRV_R_L
:
24559 tcg_gen_movi_tl(t0
, v2
);
24560 gen_helper_dextr_r_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24562 case OPC_DEXTRV_RS_L
:
24563 tcg_gen_movi_tl(t0
, v2
);
24564 gen_helper_dextr_rs_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24567 tcg_gen_movi_tl(t0
, v2
);
24568 gen_helper_dextr_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24570 case OPC_DEXTRV_R_W
:
24571 tcg_gen_movi_tl(t0
, v2
);
24572 gen_helper_dextr_r_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24574 case OPC_DEXTRV_RS_W
:
24575 tcg_gen_movi_tl(t0
, v2
);
24576 gen_helper_dextr_rs_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24585 tcg_temp_free(v1_t
);
24586 tcg_temp_free(v2_t
);
24589 /* End MIPSDSP functions. */
24591 static void decode_opc_special_r6(CPUMIPSState
*env
, DisasContext
*ctx
)
24593 int rs
, rt
, rd
, sa
;
24596 rs
= (ctx
->opcode
>> 21) & 0x1f;
24597 rt
= (ctx
->opcode
>> 16) & 0x1f;
24598 rd
= (ctx
->opcode
>> 11) & 0x1f;
24599 sa
= (ctx
->opcode
>> 6) & 0x1f;
24601 op1
= MASK_SPECIAL(ctx
->opcode
);
24604 gen_lsa(ctx
, op1
, rd
, rs
, rt
, extract32(ctx
->opcode
, 6, 2));
24610 op2
= MASK_R6_MULDIV(ctx
->opcode
);
24620 gen_r6_muldiv(ctx
, op2
, rd
, rs
, rt
);
24623 MIPS_INVAL("special_r6 muldiv");
24624 gen_reserved_instruction(ctx
);
24630 gen_cond_move(ctx
, op1
, rd
, rs
, rt
);
24634 if (rt
== 0 && sa
== 1) {
24636 * Major opcode and function field is shared with preR6 MFHI/MTHI.
24637 * We need additionally to check other fields.
24639 gen_cl(ctx
, op1
, rd
, rs
);
24641 gen_reserved_instruction(ctx
);
24645 if (is_uhi(extract32(ctx
->opcode
, 6, 20))) {
24646 gen_helper_do_semihosting(cpu_env
);
24648 if (ctx
->hflags
& MIPS_HFLAG_SBRI
) {
24649 gen_reserved_instruction(ctx
);
24651 generate_exception_end(ctx
, EXCP_DBp
);
24655 #if defined(TARGET_MIPS64)
24657 check_mips_64(ctx
);
24658 gen_lsa(ctx
, op1
, rd
, rs
, rt
, extract32(ctx
->opcode
, 6, 2));
24662 if (rt
== 0 && sa
== 1) {
24664 * Major opcode and function field is shared with preR6 MFHI/MTHI.
24665 * We need additionally to check other fields.
24667 check_mips_64(ctx
);
24668 gen_cl(ctx
, op1
, rd
, rs
);
24670 gen_reserved_instruction(ctx
);
24678 op2
= MASK_R6_MULDIV(ctx
->opcode
);
24688 check_mips_64(ctx
);
24689 gen_r6_muldiv(ctx
, op2
, rd
, rs
, rt
);
24692 MIPS_INVAL("special_r6 muldiv");
24693 gen_reserved_instruction(ctx
);
24698 default: /* Invalid */
24699 MIPS_INVAL("special_r6");
24700 gen_reserved_instruction(ctx
);
24705 static void decode_opc_special_tx79(CPUMIPSState
*env
, DisasContext
*ctx
)
24707 int rs
= extract32(ctx
->opcode
, 21, 5);
24708 int rt
= extract32(ctx
->opcode
, 16, 5);
24709 int rd
= extract32(ctx
->opcode
, 11, 5);
24710 uint32_t op1
= MASK_SPECIAL(ctx
->opcode
);
24713 case OPC_MOVN
: /* Conditional move */
24715 gen_cond_move(ctx
, op1
, rd
, rs
, rt
);
24717 case OPC_MFHI
: /* Move from HI/LO */
24719 gen_HILO(ctx
, op1
, 0, rd
);
24722 case OPC_MTLO
: /* Move to HI/LO */
24723 gen_HILO(ctx
, op1
, 0, rs
);
24727 gen_mul_txx9(ctx
, op1
, rd
, rs
, rt
);
24731 gen_muldiv(ctx
, op1
, 0, rs
, rt
);
24733 #if defined(TARGET_MIPS64)
24738 check_insn_opc_user_only(ctx
, INSN_R5900
);
24739 gen_muldiv(ctx
, op1
, 0, rs
, rt
);
24743 gen_compute_branch(ctx
, op1
, 4, rs
, 0, 0, 4);
24745 default: /* Invalid */
24746 MIPS_INVAL("special_tx79");
24747 gen_reserved_instruction(ctx
);
24752 static void decode_opc_special_legacy(CPUMIPSState
*env
, DisasContext
*ctx
)
24754 int rs
, rt
, rd
, sa
;
24757 rs
= (ctx
->opcode
>> 21) & 0x1f;
24758 rt
= (ctx
->opcode
>> 16) & 0x1f;
24759 rd
= (ctx
->opcode
>> 11) & 0x1f;
24760 sa
= (ctx
->opcode
>> 6) & 0x1f;
24762 op1
= MASK_SPECIAL(ctx
->opcode
);
24764 case OPC_MOVN
: /* Conditional move */
24766 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS_R1
|
24767 INSN_LOONGSON2E
| INSN_LOONGSON2F
);
24768 gen_cond_move(ctx
, op1
, rd
, rs
, rt
);
24770 case OPC_MFHI
: /* Move from HI/LO */
24772 gen_HILO(ctx
, op1
, rs
& 3, rd
);
24775 case OPC_MTLO
: /* Move to HI/LO */
24776 gen_HILO(ctx
, op1
, rd
& 3, rs
);
24779 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS_R1
);
24780 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
24781 check_cp1_enabled(ctx
);
24782 gen_movci(ctx
, rd
, rs
, (ctx
->opcode
>> 18) & 0x7,
24783 (ctx
->opcode
>> 16) & 1);
24785 generate_exception_err(ctx
, EXCP_CpU
, 1);
24791 check_insn(ctx
, INSN_VR54XX
);
24792 op1
= MASK_MUL_VR54XX(ctx
->opcode
);
24793 gen_mul_vr54xx(ctx
, op1
, rd
, rs
, rt
);
24795 gen_muldiv(ctx
, op1
, rd
& 3, rs
, rt
);
24800 gen_muldiv(ctx
, op1
, 0, rs
, rt
);
24802 #if defined(TARGET_MIPS64)
24807 check_insn(ctx
, ISA_MIPS3
);
24808 check_mips_64(ctx
);
24809 gen_muldiv(ctx
, op1
, 0, rs
, rt
);
24813 gen_compute_branch(ctx
, op1
, 4, rs
, rd
, sa
, 4);
24816 #ifdef MIPS_STRICT_STANDARD
24817 MIPS_INVAL("SPIM");
24818 gen_reserved_instruction(ctx
);
24820 /* Implemented as RI exception for now. */
24821 MIPS_INVAL("spim (unofficial)");
24822 gen_reserved_instruction(ctx
);
24825 default: /* Invalid */
24826 MIPS_INVAL("special_legacy");
24827 gen_reserved_instruction(ctx
);
24832 static void decode_opc_special(CPUMIPSState
*env
, DisasContext
*ctx
)
24834 int rs
, rt
, rd
, sa
;
24837 rs
= (ctx
->opcode
>> 21) & 0x1f;
24838 rt
= (ctx
->opcode
>> 16) & 0x1f;
24839 rd
= (ctx
->opcode
>> 11) & 0x1f;
24840 sa
= (ctx
->opcode
>> 6) & 0x1f;
24842 op1
= MASK_SPECIAL(ctx
->opcode
);
24844 case OPC_SLL
: /* Shift with immediate */
24845 if (sa
== 5 && rd
== 0 &&
24846 rs
== 0 && rt
== 0) { /* PAUSE */
24847 if ((ctx
->insn_flags
& ISA_MIPS_R6
) &&
24848 (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
24849 gen_reserved_instruction(ctx
);
24855 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
24858 switch ((ctx
->opcode
>> 21) & 0x1f) {
24860 /* rotr is decoded as srl on non-R2 CPUs */
24861 if (ctx
->insn_flags
& ISA_MIPS_R2
) {
24866 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
24869 gen_reserved_instruction(ctx
);
24877 gen_arith(ctx
, op1
, rd
, rs
, rt
);
24879 case OPC_SLLV
: /* Shifts */
24881 gen_shift(ctx
, op1
, rd
, rs
, rt
);
24884 switch ((ctx
->opcode
>> 6) & 0x1f) {
24886 /* rotrv is decoded as srlv on non-R2 CPUs */
24887 if (ctx
->insn_flags
& ISA_MIPS_R2
) {
24892 gen_shift(ctx
, op1
, rd
, rs
, rt
);
24895 gen_reserved_instruction(ctx
);
24899 case OPC_SLT
: /* Set on less than */
24901 gen_slt(ctx
, op1
, rd
, rs
, rt
);
24903 case OPC_AND
: /* Logic*/
24907 gen_logic(ctx
, op1
, rd
, rs
, rt
);
24910 gen_compute_branch(ctx
, op1
, 4, rs
, rd
, sa
, 4);
24912 case OPC_TGE
: /* Traps */
24918 check_insn(ctx
, ISA_MIPS2
);
24919 gen_trap(ctx
, op1
, rs
, rt
, -1);
24921 case OPC_LSA
: /* OPC_PMON */
24922 if ((ctx
->insn_flags
& ISA_MIPS_R6
) || ase_msa_available(env
)) {
24923 decode_opc_special_r6(env
, ctx
);
24925 /* Pmon entry point, also R4010 selsl */
24926 #ifdef MIPS_STRICT_STANDARD
24927 MIPS_INVAL("PMON / selsl");
24928 gen_reserved_instruction(ctx
);
24930 gen_helper_0e0i(pmon
, sa
);
24935 generate_exception_end(ctx
, EXCP_SYSCALL
);
24938 generate_exception_end(ctx
, EXCP_BREAK
);
24941 check_insn(ctx
, ISA_MIPS2
);
24942 gen_sync(extract32(ctx
->opcode
, 6, 5));
24945 #if defined(TARGET_MIPS64)
24946 /* MIPS64 specific opcodes */
24951 check_insn(ctx
, ISA_MIPS3
);
24952 check_mips_64(ctx
);
24953 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
24956 switch ((ctx
->opcode
>> 21) & 0x1f) {
24958 /* drotr is decoded as dsrl on non-R2 CPUs */
24959 if (ctx
->insn_flags
& ISA_MIPS_R2
) {
24964 check_insn(ctx
, ISA_MIPS3
);
24965 check_mips_64(ctx
);
24966 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
24969 gen_reserved_instruction(ctx
);
24974 switch ((ctx
->opcode
>> 21) & 0x1f) {
24976 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
24977 if (ctx
->insn_flags
& ISA_MIPS_R2
) {
24982 check_insn(ctx
, ISA_MIPS3
);
24983 check_mips_64(ctx
);
24984 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
24987 gen_reserved_instruction(ctx
);
24995 check_insn(ctx
, ISA_MIPS3
);
24996 check_mips_64(ctx
);
24997 gen_arith(ctx
, op1
, rd
, rs
, rt
);
25001 check_insn(ctx
, ISA_MIPS3
);
25002 check_mips_64(ctx
);
25003 gen_shift(ctx
, op1
, rd
, rs
, rt
);
25006 switch ((ctx
->opcode
>> 6) & 0x1f) {
25008 /* drotrv is decoded as dsrlv on non-R2 CPUs */
25009 if (ctx
->insn_flags
& ISA_MIPS_R2
) {
25014 check_insn(ctx
, ISA_MIPS3
);
25015 check_mips_64(ctx
);
25016 gen_shift(ctx
, op1
, rd
, rs
, rt
);
25019 gen_reserved_instruction(ctx
);
25024 if ((ctx
->insn_flags
& ISA_MIPS_R6
) || ase_msa_available(env
)) {
25025 decode_opc_special_r6(env
, ctx
);
25030 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
25031 decode_opc_special_r6(env
, ctx
);
25032 } else if (ctx
->insn_flags
& INSN_R5900
) {
25033 decode_opc_special_tx79(env
, ctx
);
25035 decode_opc_special_legacy(env
, ctx
);
25041 #if defined(TARGET_MIPS64)
25045 * MMI (MultiMedia Interface) ASE instructions
25046 * ===========================================
25050 * MMI instructions category: data communication
25051 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
25053 * PCPYH PEXCH PEXTLB PINTH PPACB PEXT5 PREVH
25054 * PCPYLD PEXCW PEXTLH PINTEH PPACH PPAC5 PROT3W
25055 * PCPYUD PEXEH PEXTLW PPACW
25064 * Parallel Copy Halfword
25066 * 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
25067 * +-----------+---------+---------+---------+---------+-----------+
25068 * | MMI |0 0 0 0 0| rt | rd | PCPYH | MMI3 |
25069 * +-----------+---------+---------+---------+---------+-----------+
25071 static void gen_mmi_pcpyh(DisasContext
*ctx
)
25073 uint32_t pd
, rt
, rd
;
25076 opcode
= ctx
->opcode
;
25078 pd
= extract32(opcode
, 21, 5);
25079 rt
= extract32(opcode
, 16, 5);
25080 rd
= extract32(opcode
, 11, 5);
25082 if (unlikely(pd
!= 0)) {
25083 gen_reserved_instruction(ctx
);
25084 } else if (rd
== 0) {
25086 } else if (rt
== 0) {
25087 tcg_gen_movi_i64(cpu_gpr
[rd
], 0);
25088 tcg_gen_movi_i64(cpu_mmr
[rd
], 0);
25090 TCGv_i64 t0
= tcg_temp_new();
25091 TCGv_i64 t1
= tcg_temp_new();
25092 uint64_t mask
= (1ULL << 16) - 1;
25094 tcg_gen_andi_i64(t0
, cpu_gpr
[rt
], mask
);
25095 tcg_gen_movi_i64(t1
, 0);
25096 tcg_gen_or_i64(t1
, t0
, t1
);
25097 tcg_gen_shli_i64(t0
, t0
, 16);
25098 tcg_gen_or_i64(t1
, t0
, t1
);
25099 tcg_gen_shli_i64(t0
, t0
, 16);
25100 tcg_gen_or_i64(t1
, t0
, t1
);
25101 tcg_gen_shli_i64(t0
, t0
, 16);
25102 tcg_gen_or_i64(t1
, t0
, t1
);
25104 tcg_gen_mov_i64(cpu_gpr
[rd
], t1
);
25106 tcg_gen_andi_i64(t0
, cpu_mmr
[rt
], mask
);
25107 tcg_gen_movi_i64(t1
, 0);
25108 tcg_gen_or_i64(t1
, t0
, t1
);
25109 tcg_gen_shli_i64(t0
, t0
, 16);
25110 tcg_gen_or_i64(t1
, t0
, t1
);
25111 tcg_gen_shli_i64(t0
, t0
, 16);
25112 tcg_gen_or_i64(t1
, t0
, t1
);
25113 tcg_gen_shli_i64(t0
, t0
, 16);
25114 tcg_gen_or_i64(t1
, t0
, t1
);
25116 tcg_gen_mov_i64(cpu_mmr
[rd
], t1
);
25124 * PCPYLD rd, rs, rt
25126 * Parallel Copy Lower Doubleword
25128 * 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
25129 * +-----------+---------+---------+---------+---------+-----------+
25130 * | MMI | rs | rt | rd | PCPYLD | MMI2 |
25131 * +-----------+---------+---------+---------+---------+-----------+
25133 static void gen_mmi_pcpyld(DisasContext
*ctx
)
25135 uint32_t rs
, rt
, rd
;
25138 opcode
= ctx
->opcode
;
25140 rs
= extract32(opcode
, 21, 5);
25141 rt
= extract32(opcode
, 16, 5);
25142 rd
= extract32(opcode
, 11, 5);
25148 tcg_gen_movi_i64(cpu_mmr
[rd
], 0);
25150 tcg_gen_mov_i64(cpu_mmr
[rd
], cpu_gpr
[rs
]);
25153 tcg_gen_movi_i64(cpu_gpr
[rd
], 0);
25156 tcg_gen_mov_i64(cpu_gpr
[rd
], cpu_gpr
[rt
]);
25163 * PCPYUD rd, rs, rt
25165 * Parallel Copy Upper Doubleword
25167 * 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
25168 * +-----------+---------+---------+---------+---------+-----------+
25169 * | MMI | rs | rt | rd | PCPYUD | MMI3 |
25170 * +-----------+---------+---------+---------+---------+-----------+
25172 static void gen_mmi_pcpyud(DisasContext
*ctx
)
25174 uint32_t rs
, rt
, rd
;
25177 opcode
= ctx
->opcode
;
25179 rs
= extract32(opcode
, 21, 5);
25180 rt
= extract32(opcode
, 16, 5);
25181 rd
= extract32(opcode
, 11, 5);
25187 tcg_gen_movi_i64(cpu_gpr
[rd
], 0);
25189 tcg_gen_mov_i64(cpu_gpr
[rd
], cpu_mmr
[rs
]);
25192 tcg_gen_movi_i64(cpu_mmr
[rd
], 0);
25195 tcg_gen_mov_i64(cpu_mmr
[rd
], cpu_mmr
[rt
]);
25204 #if !defined(TARGET_MIPS64)
25206 /* MXU accumulate add/subtract 1-bit pattern 'aptn1' */
25207 #define MXU_APTN1_A 0
25208 #define MXU_APTN1_S 1
25210 /* MXU accumulate add/subtract 2-bit pattern 'aptn2' */
25211 #define MXU_APTN2_AA 0
25212 #define MXU_APTN2_AS 1
25213 #define MXU_APTN2_SA 2
25214 #define MXU_APTN2_SS 3
25216 /* MXU execute add/subtract 2-bit pattern 'eptn2' */
25217 #define MXU_EPTN2_AA 0
25218 #define MXU_EPTN2_AS 1
25219 #define MXU_EPTN2_SA 2
25220 #define MXU_EPTN2_SS 3
25222 /* MXU operand getting pattern 'optn2' */
25223 #define MXU_OPTN2_PTN0 0
25224 #define MXU_OPTN2_PTN1 1
25225 #define MXU_OPTN2_PTN2 2
25226 #define MXU_OPTN2_PTN3 3
25227 /* alternative naming scheme for 'optn2' */
25228 #define MXU_OPTN2_WW 0
25229 #define MXU_OPTN2_LW 1
25230 #define MXU_OPTN2_HW 2
25231 #define MXU_OPTN2_XW 3
25233 /* MXU operand getting pattern 'optn3' */
25234 #define MXU_OPTN3_PTN0 0
25235 #define MXU_OPTN3_PTN1 1
25236 #define MXU_OPTN3_PTN2 2
25237 #define MXU_OPTN3_PTN3 3
25238 #define MXU_OPTN3_PTN4 4
25239 #define MXU_OPTN3_PTN5 5
25240 #define MXU_OPTN3_PTN6 6
25241 #define MXU_OPTN3_PTN7 7
25245 * S32I2M XRa, rb - Register move from GRF to XRF
25247 static void gen_mxu_s32i2m(DisasContext
*ctx
)
25252 t0
= tcg_temp_new();
25254 XRa
= extract32(ctx
->opcode
, 6, 5);
25255 Rb
= extract32(ctx
->opcode
, 16, 5);
25257 gen_load_gpr(t0
, Rb
);
25259 gen_store_mxu_gpr(t0
, XRa
);
25260 } else if (XRa
== 16) {
25261 gen_store_mxu_cr(t0
);
25268 * S32M2I XRa, rb - Register move from XRF to GRF
25270 static void gen_mxu_s32m2i(DisasContext
*ctx
)
25275 t0
= tcg_temp_new();
25277 XRa
= extract32(ctx
->opcode
, 6, 5);
25278 Rb
= extract32(ctx
->opcode
, 16, 5);
25281 gen_load_mxu_gpr(t0
, XRa
);
25282 } else if (XRa
== 16) {
25283 gen_load_mxu_cr(t0
);
25286 gen_store_gpr(t0
, Rb
);
25292 * S8LDD XRa, Rb, s8, optn3 - Load a byte from memory to XRF
25294 static void gen_mxu_s8ldd(DisasContext
*ctx
)
25297 uint32_t XRa
, Rb
, s8
, optn3
;
25299 t0
= tcg_temp_new();
25300 t1
= tcg_temp_new();
25302 XRa
= extract32(ctx
->opcode
, 6, 4);
25303 s8
= extract32(ctx
->opcode
, 10, 8);
25304 optn3
= extract32(ctx
->opcode
, 18, 3);
25305 Rb
= extract32(ctx
->opcode
, 21, 5);
25307 gen_load_gpr(t0
, Rb
);
25308 tcg_gen_addi_tl(t0
, t0
, (int8_t)s8
);
25311 /* XRa[7:0] = tmp8 */
25312 case MXU_OPTN3_PTN0
:
25313 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
25314 gen_load_mxu_gpr(t0
, XRa
);
25315 tcg_gen_deposit_tl(t0
, t0
, t1
, 0, 8);
25317 /* XRa[15:8] = tmp8 */
25318 case MXU_OPTN3_PTN1
:
25319 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
25320 gen_load_mxu_gpr(t0
, XRa
);
25321 tcg_gen_deposit_tl(t0
, t0
, t1
, 8, 8);
25323 /* XRa[23:16] = tmp8 */
25324 case MXU_OPTN3_PTN2
:
25325 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
25326 gen_load_mxu_gpr(t0
, XRa
);
25327 tcg_gen_deposit_tl(t0
, t0
, t1
, 16, 8);
25329 /* XRa[31:24] = tmp8 */
25330 case MXU_OPTN3_PTN3
:
25331 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
25332 gen_load_mxu_gpr(t0
, XRa
);
25333 tcg_gen_deposit_tl(t0
, t0
, t1
, 24, 8);
25335 /* XRa = {8'b0, tmp8, 8'b0, tmp8} */
25336 case MXU_OPTN3_PTN4
:
25337 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
25338 tcg_gen_deposit_tl(t0
, t1
, t1
, 16, 16);
25340 /* XRa = {tmp8, 8'b0, tmp8, 8'b0} */
25341 case MXU_OPTN3_PTN5
:
25342 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
25343 tcg_gen_shli_tl(t1
, t1
, 8);
25344 tcg_gen_deposit_tl(t0
, t1
, t1
, 16, 16);
25346 /* XRa = {{8{sign of tmp8}}, tmp8, {8{sign of tmp8}}, tmp8} */
25347 case MXU_OPTN3_PTN6
:
25348 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_SB
);
25349 tcg_gen_mov_tl(t0
, t1
);
25350 tcg_gen_andi_tl(t0
, t0
, 0xFF00FFFF);
25351 tcg_gen_shli_tl(t1
, t1
, 16);
25352 tcg_gen_or_tl(t0
, t0
, t1
);
25354 /* XRa = {tmp8, tmp8, tmp8, tmp8} */
25355 case MXU_OPTN3_PTN7
:
25356 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
25357 tcg_gen_deposit_tl(t1
, t1
, t1
, 8, 8);
25358 tcg_gen_deposit_tl(t0
, t1
, t1
, 16, 16);
25362 gen_store_mxu_gpr(t0
, XRa
);
25369 * D16MUL XRa, XRb, XRc, XRd, optn2 - Signed 16 bit pattern multiplication
25371 static void gen_mxu_d16mul(DisasContext
*ctx
)
25373 TCGv t0
, t1
, t2
, t3
;
25374 uint32_t XRa
, XRb
, XRc
, XRd
, optn2
;
25376 t0
= tcg_temp_new();
25377 t1
= tcg_temp_new();
25378 t2
= tcg_temp_new();
25379 t3
= tcg_temp_new();
25381 XRa
= extract32(ctx
->opcode
, 6, 4);
25382 XRb
= extract32(ctx
->opcode
, 10, 4);
25383 XRc
= extract32(ctx
->opcode
, 14, 4);
25384 XRd
= extract32(ctx
->opcode
, 18, 4);
25385 optn2
= extract32(ctx
->opcode
, 22, 2);
25387 gen_load_mxu_gpr(t1
, XRb
);
25388 tcg_gen_sextract_tl(t0
, t1
, 0, 16);
25389 tcg_gen_sextract_tl(t1
, t1
, 16, 16);
25390 gen_load_mxu_gpr(t3
, XRc
);
25391 tcg_gen_sextract_tl(t2
, t3
, 0, 16);
25392 tcg_gen_sextract_tl(t3
, t3
, 16, 16);
25395 case MXU_OPTN2_WW
: /* XRB.H*XRC.H == lop, XRB.L*XRC.L == rop */
25396 tcg_gen_mul_tl(t3
, t1
, t3
);
25397 tcg_gen_mul_tl(t2
, t0
, t2
);
25399 case MXU_OPTN2_LW
: /* XRB.L*XRC.H == lop, XRB.L*XRC.L == rop */
25400 tcg_gen_mul_tl(t3
, t0
, t3
);
25401 tcg_gen_mul_tl(t2
, t0
, t2
);
25403 case MXU_OPTN2_HW
: /* XRB.H*XRC.H == lop, XRB.H*XRC.L == rop */
25404 tcg_gen_mul_tl(t3
, t1
, t3
);
25405 tcg_gen_mul_tl(t2
, t1
, t2
);
25407 case MXU_OPTN2_XW
: /* XRB.L*XRC.H == lop, XRB.H*XRC.L == rop */
25408 tcg_gen_mul_tl(t3
, t0
, t3
);
25409 tcg_gen_mul_tl(t2
, t1
, t2
);
25412 gen_store_mxu_gpr(t3
, XRa
);
25413 gen_store_mxu_gpr(t2
, XRd
);
25422 * D16MAC XRa, XRb, XRc, XRd, aptn2, optn2 - Signed 16 bit pattern multiply
25425 static void gen_mxu_d16mac(DisasContext
*ctx
)
25427 TCGv t0
, t1
, t2
, t3
;
25428 uint32_t XRa
, XRb
, XRc
, XRd
, optn2
, aptn2
;
25430 t0
= tcg_temp_new();
25431 t1
= tcg_temp_new();
25432 t2
= tcg_temp_new();
25433 t3
= tcg_temp_new();
25435 XRa
= extract32(ctx
->opcode
, 6, 4);
25436 XRb
= extract32(ctx
->opcode
, 10, 4);
25437 XRc
= extract32(ctx
->opcode
, 14, 4);
25438 XRd
= extract32(ctx
->opcode
, 18, 4);
25439 optn2
= extract32(ctx
->opcode
, 22, 2);
25440 aptn2
= extract32(ctx
->opcode
, 24, 2);
25442 gen_load_mxu_gpr(t1
, XRb
);
25443 tcg_gen_sextract_tl(t0
, t1
, 0, 16);
25444 tcg_gen_sextract_tl(t1
, t1
, 16, 16);
25446 gen_load_mxu_gpr(t3
, XRc
);
25447 tcg_gen_sextract_tl(t2
, t3
, 0, 16);
25448 tcg_gen_sextract_tl(t3
, t3
, 16, 16);
25451 case MXU_OPTN2_WW
: /* XRB.H*XRC.H == lop, XRB.L*XRC.L == rop */
25452 tcg_gen_mul_tl(t3
, t1
, t3
);
25453 tcg_gen_mul_tl(t2
, t0
, t2
);
25455 case MXU_OPTN2_LW
: /* XRB.L*XRC.H == lop, XRB.L*XRC.L == rop */
25456 tcg_gen_mul_tl(t3
, t0
, t3
);
25457 tcg_gen_mul_tl(t2
, t0
, t2
);
25459 case MXU_OPTN2_HW
: /* XRB.H*XRC.H == lop, XRB.H*XRC.L == rop */
25460 tcg_gen_mul_tl(t3
, t1
, t3
);
25461 tcg_gen_mul_tl(t2
, t1
, t2
);
25463 case MXU_OPTN2_XW
: /* XRB.L*XRC.H == lop, XRB.H*XRC.L == rop */
25464 tcg_gen_mul_tl(t3
, t0
, t3
);
25465 tcg_gen_mul_tl(t2
, t1
, t2
);
25468 gen_load_mxu_gpr(t0
, XRa
);
25469 gen_load_mxu_gpr(t1
, XRd
);
25473 tcg_gen_add_tl(t3
, t0
, t3
);
25474 tcg_gen_add_tl(t2
, t1
, t2
);
25477 tcg_gen_add_tl(t3
, t0
, t3
);
25478 tcg_gen_sub_tl(t2
, t1
, t2
);
25481 tcg_gen_sub_tl(t3
, t0
, t3
);
25482 tcg_gen_add_tl(t2
, t1
, t2
);
25485 tcg_gen_sub_tl(t3
, t0
, t3
);
25486 tcg_gen_sub_tl(t2
, t1
, t2
);
25489 gen_store_mxu_gpr(t3
, XRa
);
25490 gen_store_mxu_gpr(t2
, XRd
);
25499 * Q8MUL XRa, XRb, XRc, XRd - Parallel unsigned 8 bit pattern multiply
25500 * Q8MULSU XRa, XRb, XRc, XRd - Parallel signed 8 bit pattern multiply
25502 static void gen_mxu_q8mul_q8mulsu(DisasContext
*ctx
)
25504 TCGv t0
, t1
, t2
, t3
, t4
, t5
, t6
, t7
;
25505 uint32_t XRa
, XRb
, XRc
, XRd
, sel
;
25507 t0
= tcg_temp_new();
25508 t1
= tcg_temp_new();
25509 t2
= tcg_temp_new();
25510 t3
= tcg_temp_new();
25511 t4
= tcg_temp_new();
25512 t5
= tcg_temp_new();
25513 t6
= tcg_temp_new();
25514 t7
= tcg_temp_new();
25516 XRa
= extract32(ctx
->opcode
, 6, 4);
25517 XRb
= extract32(ctx
->opcode
, 10, 4);
25518 XRc
= extract32(ctx
->opcode
, 14, 4);
25519 XRd
= extract32(ctx
->opcode
, 18, 4);
25520 sel
= extract32(ctx
->opcode
, 22, 2);
25522 gen_load_mxu_gpr(t3
, XRb
);
25523 gen_load_mxu_gpr(t7
, XRc
);
25527 tcg_gen_ext8s_tl(t0
, t3
);
25528 tcg_gen_shri_tl(t3
, t3
, 8);
25529 tcg_gen_ext8s_tl(t1
, t3
);
25530 tcg_gen_shri_tl(t3
, t3
, 8);
25531 tcg_gen_ext8s_tl(t2
, t3
);
25532 tcg_gen_shri_tl(t3
, t3
, 8);
25533 tcg_gen_ext8s_tl(t3
, t3
);
25536 tcg_gen_ext8u_tl(t0
, t3
);
25537 tcg_gen_shri_tl(t3
, t3
, 8);
25538 tcg_gen_ext8u_tl(t1
, t3
);
25539 tcg_gen_shri_tl(t3
, t3
, 8);
25540 tcg_gen_ext8u_tl(t2
, t3
);
25541 tcg_gen_shri_tl(t3
, t3
, 8);
25542 tcg_gen_ext8u_tl(t3
, t3
);
25545 tcg_gen_ext8u_tl(t4
, t7
);
25546 tcg_gen_shri_tl(t7
, t7
, 8);
25547 tcg_gen_ext8u_tl(t5
, t7
);
25548 tcg_gen_shri_tl(t7
, t7
, 8);
25549 tcg_gen_ext8u_tl(t6
, t7
);
25550 tcg_gen_shri_tl(t7
, t7
, 8);
25551 tcg_gen_ext8u_tl(t7
, t7
);
25553 tcg_gen_mul_tl(t0
, t0
, t4
);
25554 tcg_gen_mul_tl(t1
, t1
, t5
);
25555 tcg_gen_mul_tl(t2
, t2
, t6
);
25556 tcg_gen_mul_tl(t3
, t3
, t7
);
25558 tcg_gen_andi_tl(t0
, t0
, 0xFFFF);
25559 tcg_gen_andi_tl(t1
, t1
, 0xFFFF);
25560 tcg_gen_andi_tl(t2
, t2
, 0xFFFF);
25561 tcg_gen_andi_tl(t3
, t3
, 0xFFFF);
25563 tcg_gen_shli_tl(t1
, t1
, 16);
25564 tcg_gen_shli_tl(t3
, t3
, 16);
25566 tcg_gen_or_tl(t0
, t0
, t1
);
25567 tcg_gen_or_tl(t1
, t2
, t3
);
25569 gen_store_mxu_gpr(t0
, XRd
);
25570 gen_store_mxu_gpr(t1
, XRa
);
25583 * S32LDD XRa, Rb, S12 - Load a word from memory to XRF
25584 * S32LDDR XRa, Rb, S12 - Load a word from memory to XRF, reversed byte seq.
25586 static void gen_mxu_s32ldd_s32lddr(DisasContext
*ctx
)
25589 uint32_t XRa
, Rb
, s12
, sel
;
25591 t0
= tcg_temp_new();
25592 t1
= tcg_temp_new();
25594 XRa
= extract32(ctx
->opcode
, 6, 4);
25595 s12
= extract32(ctx
->opcode
, 10, 10);
25596 sel
= extract32(ctx
->opcode
, 20, 1);
25597 Rb
= extract32(ctx
->opcode
, 21, 5);
25599 gen_load_gpr(t0
, Rb
);
25601 tcg_gen_movi_tl(t1
, s12
);
25602 tcg_gen_shli_tl(t1
, t1
, 2);
25604 tcg_gen_ori_tl(t1
, t1
, 0xFFFFF000);
25606 tcg_gen_add_tl(t1
, t0
, t1
);
25607 tcg_gen_qemu_ld_tl(t1
, t1
, ctx
->mem_idx
, MO_SL
);
25611 tcg_gen_bswap32_tl(t1
, t1
);
25613 gen_store_mxu_gpr(t1
, XRa
);
25621 * MXU instruction category: logic
25622 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
25624 * S32NOR S32AND S32OR S32XOR
25628 * S32NOR XRa, XRb, XRc
25629 * Update XRa with the result of logical bitwise 'nor' operation
25630 * applied to the content of XRb and XRc.
25632 * 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
25633 * +-----------+---------+-----+-------+-------+-------+-----------+
25634 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL16|
25635 * +-----------+---------+-----+-------+-------+-------+-----------+
25637 static void gen_mxu_S32NOR(DisasContext
*ctx
)
25639 uint32_t pad
, XRc
, XRb
, XRa
;
25641 pad
= extract32(ctx
->opcode
, 21, 5);
25642 XRc
= extract32(ctx
->opcode
, 14, 4);
25643 XRb
= extract32(ctx
->opcode
, 10, 4);
25644 XRa
= extract32(ctx
->opcode
, 6, 4);
25646 if (unlikely(pad
!= 0)) {
25647 /* opcode padding incorrect -> do nothing */
25648 } else if (unlikely(XRa
== 0)) {
25649 /* destination is zero register -> do nothing */
25650 } else if (unlikely((XRb
== 0) && (XRc
== 0))) {
25651 /* both operands zero registers -> just set destination to all 1s */
25652 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0xFFFFFFFF);
25653 } else if (unlikely(XRb
== 0)) {
25654 /* XRb zero register -> just set destination to the negation of XRc */
25655 tcg_gen_not_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRc
- 1]);
25656 } else if (unlikely(XRc
== 0)) {
25657 /* XRa zero register -> just set destination to the negation of XRb */
25658 tcg_gen_not_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25659 } else if (unlikely(XRb
== XRc
)) {
25660 /* both operands same -> just set destination to the negation of XRb */
25661 tcg_gen_not_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25663 /* the most general case */
25664 tcg_gen_nor_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1], mxu_gpr
[XRc
- 1]);
25669 * S32AND XRa, XRb, XRc
25670 * Update XRa with the result of logical bitwise 'and' operation
25671 * applied to the content of XRb and XRc.
25673 * 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
25674 * +-----------+---------+-----+-------+-------+-------+-----------+
25675 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL16|
25676 * +-----------+---------+-----+-------+-------+-------+-----------+
25678 static void gen_mxu_S32AND(DisasContext
*ctx
)
25680 uint32_t pad
, XRc
, XRb
, XRa
;
25682 pad
= extract32(ctx
->opcode
, 21, 5);
25683 XRc
= extract32(ctx
->opcode
, 14, 4);
25684 XRb
= extract32(ctx
->opcode
, 10, 4);
25685 XRa
= extract32(ctx
->opcode
, 6, 4);
25687 if (unlikely(pad
!= 0)) {
25688 /* opcode padding incorrect -> do nothing */
25689 } else if (unlikely(XRa
== 0)) {
25690 /* destination is zero register -> do nothing */
25691 } else if (unlikely((XRb
== 0) || (XRc
== 0))) {
25692 /* one of operands zero register -> just set destination to all 0s */
25693 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0);
25694 } else if (unlikely(XRb
== XRc
)) {
25695 /* both operands same -> just set destination to one of them */
25696 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25698 /* the most general case */
25699 tcg_gen_and_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1], mxu_gpr
[XRc
- 1]);
25704 * S32OR XRa, XRb, XRc
25705 * Update XRa with the result of logical bitwise 'or' operation
25706 * applied to the content of XRb and XRc.
25708 * 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
25709 * +-----------+---------+-----+-------+-------+-------+-----------+
25710 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL16|
25711 * +-----------+---------+-----+-------+-------+-------+-----------+
25713 static void gen_mxu_S32OR(DisasContext
*ctx
)
25715 uint32_t pad
, XRc
, XRb
, XRa
;
25717 pad
= extract32(ctx
->opcode
, 21, 5);
25718 XRc
= extract32(ctx
->opcode
, 14, 4);
25719 XRb
= extract32(ctx
->opcode
, 10, 4);
25720 XRa
= extract32(ctx
->opcode
, 6, 4);
25722 if (unlikely(pad
!= 0)) {
25723 /* opcode padding incorrect -> do nothing */
25724 } else if (unlikely(XRa
== 0)) {
25725 /* destination is zero register -> do nothing */
25726 } else if (unlikely((XRb
== 0) && (XRc
== 0))) {
25727 /* both operands zero registers -> just set destination to all 0s */
25728 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0);
25729 } else if (unlikely(XRb
== 0)) {
25730 /* XRb zero register -> just set destination to the content of XRc */
25731 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRc
- 1]);
25732 } else if (unlikely(XRc
== 0)) {
25733 /* XRc zero register -> just set destination to the content of XRb */
25734 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25735 } else if (unlikely(XRb
== XRc
)) {
25736 /* both operands same -> just set destination to one of them */
25737 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25739 /* the most general case */
25740 tcg_gen_or_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1], mxu_gpr
[XRc
- 1]);
25745 * S32XOR XRa, XRb, XRc
25746 * Update XRa with the result of logical bitwise 'xor' operation
25747 * applied to the content of XRb and XRc.
25749 * 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
25750 * +-----------+---------+-----+-------+-------+-------+-----------+
25751 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL16|
25752 * +-----------+---------+-----+-------+-------+-------+-----------+
25754 static void gen_mxu_S32XOR(DisasContext
*ctx
)
25756 uint32_t pad
, XRc
, XRb
, XRa
;
25758 pad
= extract32(ctx
->opcode
, 21, 5);
25759 XRc
= extract32(ctx
->opcode
, 14, 4);
25760 XRb
= extract32(ctx
->opcode
, 10, 4);
25761 XRa
= extract32(ctx
->opcode
, 6, 4);
25763 if (unlikely(pad
!= 0)) {
25764 /* opcode padding incorrect -> do nothing */
25765 } else if (unlikely(XRa
== 0)) {
25766 /* destination is zero register -> do nothing */
25767 } else if (unlikely((XRb
== 0) && (XRc
== 0))) {
25768 /* both operands zero registers -> just set destination to all 0s */
25769 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0);
25770 } else if (unlikely(XRb
== 0)) {
25771 /* XRb zero register -> just set destination to the content of XRc */
25772 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRc
- 1]);
25773 } else if (unlikely(XRc
== 0)) {
25774 /* XRc zero register -> just set destination to the content of XRb */
25775 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25776 } else if (unlikely(XRb
== XRc
)) {
25777 /* both operands same -> just set destination to all 0s */
25778 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0);
25780 /* the most general case */
25781 tcg_gen_xor_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1], mxu_gpr
[XRc
- 1]);
25787 * MXU instruction category max/min
25788 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
25790 * S32MAX D16MAX Q8MAX
25791 * S32MIN D16MIN Q8MIN
25795 * S32MAX XRa, XRb, XRc
25796 * Update XRa with the maximum of signed 32-bit integers contained
25799 * S32MIN XRa, XRb, XRc
25800 * Update XRa with the minimum of signed 32-bit integers contained
25803 * 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
25804 * +-----------+---------+-----+-------+-------+-------+-----------+
25805 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL00|
25806 * +-----------+---------+-----+-------+-------+-------+-----------+
25808 static void gen_mxu_S32MAX_S32MIN(DisasContext
*ctx
)
25810 uint32_t pad
, opc
, XRc
, XRb
, XRa
;
25812 pad
= extract32(ctx
->opcode
, 21, 5);
25813 opc
= extract32(ctx
->opcode
, 18, 3);
25814 XRc
= extract32(ctx
->opcode
, 14, 4);
25815 XRb
= extract32(ctx
->opcode
, 10, 4);
25816 XRa
= extract32(ctx
->opcode
, 6, 4);
25818 if (unlikely(pad
!= 0)) {
25819 /* opcode padding incorrect -> do nothing */
25820 } else if (unlikely(XRa
== 0)) {
25821 /* destination is zero register -> do nothing */
25822 } else if (unlikely((XRb
== 0) && (XRc
== 0))) {
25823 /* both operands zero registers -> just set destination to zero */
25824 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0);
25825 } else if (unlikely((XRb
== 0) || (XRc
== 0))) {
25826 /* exactly one operand is zero register - find which one is not...*/
25827 uint32_t XRx
= XRb
? XRb
: XRc
;
25828 /* ...and do max/min operation with one operand 0 */
25829 if (opc
== OPC_MXU_S32MAX
) {
25830 tcg_gen_smax_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRx
- 1], 0);
25832 tcg_gen_smin_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRx
- 1], 0);
25834 } else if (unlikely(XRb
== XRc
)) {
25835 /* both operands same -> just set destination to one of them */
25836 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25838 /* the most general case */
25839 if (opc
== OPC_MXU_S32MAX
) {
25840 tcg_gen_smax_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1],
25843 tcg_gen_smin_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1],
25851 * Update XRa with the 16-bit-wise maximums of signed integers
25852 * contained in XRb and XRc.
25855 * Update XRa with the 16-bit-wise minimums of signed integers
25856 * contained in XRb and XRc.
25858 * 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
25859 * +-----------+---------+-----+-------+-------+-------+-----------+
25860 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL00|
25861 * +-----------+---------+-----+-------+-------+-------+-----------+
25863 static void gen_mxu_D16MAX_D16MIN(DisasContext
*ctx
)
25865 uint32_t pad
, opc
, XRc
, XRb
, XRa
;
25867 pad
= extract32(ctx
->opcode
, 21, 5);
25868 opc
= extract32(ctx
->opcode
, 18, 3);
25869 XRc
= extract32(ctx
->opcode
, 14, 4);
25870 XRb
= extract32(ctx
->opcode
, 10, 4);
25871 XRa
= extract32(ctx
->opcode
, 6, 4);
25873 if (unlikely(pad
!= 0)) {
25874 /* opcode padding incorrect -> do nothing */
25875 } else if (unlikely(XRc
== 0)) {
25876 /* destination is zero register -> do nothing */
25877 } else if (unlikely((XRb
== 0) && (XRa
== 0))) {
25878 /* both operands zero registers -> just set destination to zero */
25879 tcg_gen_movi_i32(mxu_gpr
[XRc
- 1], 0);
25880 } else if (unlikely((XRb
== 0) || (XRa
== 0))) {
25881 /* exactly one operand is zero register - find which one is not...*/
25882 uint32_t XRx
= XRb
? XRb
: XRc
;
25883 /* ...and do half-word-wise max/min with one operand 0 */
25884 TCGv_i32 t0
= tcg_temp_new();
25885 TCGv_i32 t1
= tcg_const_i32(0);
25887 /* the left half-word first */
25888 tcg_gen_andi_i32(t0
, mxu_gpr
[XRx
- 1], 0xFFFF0000);
25889 if (opc
== OPC_MXU_D16MAX
) {
25890 tcg_gen_smax_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
25892 tcg_gen_smin_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
25895 /* the right half-word */
25896 tcg_gen_andi_i32(t0
, mxu_gpr
[XRx
- 1], 0x0000FFFF);
25897 /* move half-words to the leftmost position */
25898 tcg_gen_shli_i32(t0
, t0
, 16);
25899 /* t0 will be max/min of t0 and t1 */
25900 if (opc
== OPC_MXU_D16MAX
) {
25901 tcg_gen_smax_i32(t0
, t0
, t1
);
25903 tcg_gen_smin_i32(t0
, t0
, t1
);
25905 /* return resulting half-words to its original position */
25906 tcg_gen_shri_i32(t0
, t0
, 16);
25907 /* finally update the destination */
25908 tcg_gen_or_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRa
- 1], t0
);
25912 } else if (unlikely(XRb
== XRc
)) {
25913 /* both operands same -> just set destination to one of them */
25914 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25916 /* the most general case */
25917 TCGv_i32 t0
= tcg_temp_new();
25918 TCGv_i32 t1
= tcg_temp_new();
25920 /* the left half-word first */
25921 tcg_gen_andi_i32(t0
, mxu_gpr
[XRb
- 1], 0xFFFF0000);
25922 tcg_gen_andi_i32(t1
, mxu_gpr
[XRc
- 1], 0xFFFF0000);
25923 if (opc
== OPC_MXU_D16MAX
) {
25924 tcg_gen_smax_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
25926 tcg_gen_smin_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
25929 /* the right half-word */
25930 tcg_gen_andi_i32(t0
, mxu_gpr
[XRb
- 1], 0x0000FFFF);
25931 tcg_gen_andi_i32(t1
, mxu_gpr
[XRc
- 1], 0x0000FFFF);
25932 /* move half-words to the leftmost position */
25933 tcg_gen_shli_i32(t0
, t0
, 16);
25934 tcg_gen_shli_i32(t1
, t1
, 16);
25935 /* t0 will be max/min of t0 and t1 */
25936 if (opc
== OPC_MXU_D16MAX
) {
25937 tcg_gen_smax_i32(t0
, t0
, t1
);
25939 tcg_gen_smin_i32(t0
, t0
, t1
);
25941 /* return resulting half-words to its original position */
25942 tcg_gen_shri_i32(t0
, t0
, 16);
25943 /* finally update the destination */
25944 tcg_gen_or_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRa
- 1], t0
);
25953 * Update XRa with the 8-bit-wise maximums of signed integers
25954 * contained in XRb and XRc.
25957 * Update XRa with the 8-bit-wise minimums of signed integers
25958 * contained in XRb and XRc.
25960 * 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
25961 * +-----------+---------+-----+-------+-------+-------+-----------+
25962 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL00|
25963 * +-----------+---------+-----+-------+-------+-------+-----------+
25965 static void gen_mxu_Q8MAX_Q8MIN(DisasContext
*ctx
)
25967 uint32_t pad
, opc
, XRc
, XRb
, XRa
;
25969 pad
= extract32(ctx
->opcode
, 21, 5);
25970 opc
= extract32(ctx
->opcode
, 18, 3);
25971 XRc
= extract32(ctx
->opcode
, 14, 4);
25972 XRb
= extract32(ctx
->opcode
, 10, 4);
25973 XRa
= extract32(ctx
->opcode
, 6, 4);
25975 if (unlikely(pad
!= 0)) {
25976 /* opcode padding incorrect -> do nothing */
25977 } else if (unlikely(XRa
== 0)) {
25978 /* destination is zero register -> do nothing */
25979 } else if (unlikely((XRb
== 0) && (XRc
== 0))) {
25980 /* both operands zero registers -> just set destination to zero */
25981 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0);
25982 } else if (unlikely((XRb
== 0) || (XRc
== 0))) {
25983 /* exactly one operand is zero register - make it be the first...*/
25984 uint32_t XRx
= XRb
? XRb
: XRc
;
25985 /* ...and do byte-wise max/min with one operand 0 */
25986 TCGv_i32 t0
= tcg_temp_new();
25987 TCGv_i32 t1
= tcg_const_i32(0);
25990 /* the leftmost byte (byte 3) first */
25991 tcg_gen_andi_i32(t0
, mxu_gpr
[XRx
- 1], 0xFF000000);
25992 if (opc
== OPC_MXU_Q8MAX
) {
25993 tcg_gen_smax_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
25995 tcg_gen_smin_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
25998 /* bytes 2, 1, 0 */
25999 for (i
= 2; i
>= 0; i
--) {
26000 /* extract the byte */
26001 tcg_gen_andi_i32(t0
, mxu_gpr
[XRx
- 1], 0xFF << (8 * i
));
26002 /* move the byte to the leftmost position */
26003 tcg_gen_shli_i32(t0
, t0
, 8 * (3 - i
));
26004 /* t0 will be max/min of t0 and t1 */
26005 if (opc
== OPC_MXU_Q8MAX
) {
26006 tcg_gen_smax_i32(t0
, t0
, t1
);
26008 tcg_gen_smin_i32(t0
, t0
, t1
);
26010 /* return resulting byte to its original position */
26011 tcg_gen_shri_i32(t0
, t0
, 8 * (3 - i
));
26012 /* finally update the destination */
26013 tcg_gen_or_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRa
- 1], t0
);
26018 } else if (unlikely(XRb
== XRc
)) {
26019 /* both operands same -> just set destination to one of them */
26020 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
26022 /* the most general case */
26023 TCGv_i32 t0
= tcg_temp_new();
26024 TCGv_i32 t1
= tcg_temp_new();
26027 /* the leftmost bytes (bytes 3) first */
26028 tcg_gen_andi_i32(t0
, mxu_gpr
[XRb
- 1], 0xFF000000);
26029 tcg_gen_andi_i32(t1
, mxu_gpr
[XRc
- 1], 0xFF000000);
26030 if (opc
== OPC_MXU_Q8MAX
) {
26031 tcg_gen_smax_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
26033 tcg_gen_smin_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
26036 /* bytes 2, 1, 0 */
26037 for (i
= 2; i
>= 0; i
--) {
26038 /* extract corresponding bytes */
26039 tcg_gen_andi_i32(t0
, mxu_gpr
[XRb
- 1], 0xFF << (8 * i
));
26040 tcg_gen_andi_i32(t1
, mxu_gpr
[XRc
- 1], 0xFF << (8 * i
));
26041 /* move the bytes to the leftmost position */
26042 tcg_gen_shli_i32(t0
, t0
, 8 * (3 - i
));
26043 tcg_gen_shli_i32(t1
, t1
, 8 * (3 - i
));
26044 /* t0 will be max/min of t0 and t1 */
26045 if (opc
== OPC_MXU_Q8MAX
) {
26046 tcg_gen_smax_i32(t0
, t0
, t1
);
26048 tcg_gen_smin_i32(t0
, t0
, t1
);
26050 /* return resulting byte to its original position */
26051 tcg_gen_shri_i32(t0
, t0
, 8 * (3 - i
));
26052 /* finally update the destination */
26053 tcg_gen_or_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRa
- 1], t0
);
26063 * MXU instruction category: align
26064 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
26070 * S32ALNI XRc, XRb, XRa, optn3
26071 * Arrange bytes from XRb and XRc according to one of five sets of
26072 * rules determined by optn3, and place the result in XRa.
26074 * 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
26075 * +-----------+-----+---+-----+-------+-------+-------+-----------+
26076 * | SPECIAL2 |optn3|0 0|x x x| XRc | XRb | XRa |MXU__POOL16|
26077 * +-----------+-----+---+-----+-------+-------+-------+-----------+
26080 static void gen_mxu_S32ALNI(DisasContext
*ctx
)
26082 uint32_t optn3
, pad
, XRc
, XRb
, XRa
;
26084 optn3
= extract32(ctx
->opcode
, 23, 3);
26085 pad
= extract32(ctx
->opcode
, 21, 2);
26086 XRc
= extract32(ctx
->opcode
, 14, 4);
26087 XRb
= extract32(ctx
->opcode
, 10, 4);
26088 XRa
= extract32(ctx
->opcode
, 6, 4);
26090 if (unlikely(pad
!= 0)) {
26091 /* opcode padding incorrect -> do nothing */
26092 } else if (unlikely(XRa
== 0)) {
26093 /* destination is zero register -> do nothing */
26094 } else if (unlikely((XRb
== 0) && (XRc
== 0))) {
26095 /* both operands zero registers -> just set destination to all 0s */
26096 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0);
26097 } else if (unlikely(XRb
== 0)) {
26098 /* XRb zero register -> just appropriatelly shift XRc into XRa */
26100 case MXU_OPTN3_PTN0
:
26101 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0);
26103 case MXU_OPTN3_PTN1
:
26104 case MXU_OPTN3_PTN2
:
26105 case MXU_OPTN3_PTN3
:
26106 tcg_gen_shri_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRc
- 1],
26109 case MXU_OPTN3_PTN4
:
26110 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRc
- 1]);
26113 } else if (unlikely(XRc
== 0)) {
26114 /* XRc zero register -> just appropriatelly shift XRb into XRa */
26116 case MXU_OPTN3_PTN0
:
26117 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
26119 case MXU_OPTN3_PTN1
:
26120 case MXU_OPTN3_PTN2
:
26121 case MXU_OPTN3_PTN3
:
26122 tcg_gen_shri_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1], 8 * optn3
);
26124 case MXU_OPTN3_PTN4
:
26125 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0);
26128 } else if (unlikely(XRb
== XRc
)) {
26129 /* both operands same -> just rotation or moving from any of them */
26131 case MXU_OPTN3_PTN0
:
26132 case MXU_OPTN3_PTN4
:
26133 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
26135 case MXU_OPTN3_PTN1
:
26136 case MXU_OPTN3_PTN2
:
26137 case MXU_OPTN3_PTN3
:
26138 tcg_gen_rotli_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1], 8 * optn3
);
26142 /* the most general case */
26144 case MXU_OPTN3_PTN0
:
26148 /* +---------------+ */
26149 /* | A B C D | E F G H */
26150 /* +-------+-------+ */
26155 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
26158 case MXU_OPTN3_PTN1
:
26162 /* +-------------------+ */
26163 /* A | B C D E | F G H */
26164 /* +---------+---------+ */
26169 TCGv_i32 t0
= tcg_temp_new();
26170 TCGv_i32 t1
= tcg_temp_new();
26172 tcg_gen_andi_i32(t0
, mxu_gpr
[XRb
- 1], 0x00FFFFFF);
26173 tcg_gen_shli_i32(t0
, t0
, 8);
26175 tcg_gen_andi_i32(t1
, mxu_gpr
[XRc
- 1], 0xFF000000);
26176 tcg_gen_shri_i32(t1
, t1
, 24);
26178 tcg_gen_or_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
26184 case MXU_OPTN3_PTN2
:
26188 /* +-------------------+ */
26189 /* A B | C D E F | G H */
26190 /* +---------+---------+ */
26195 TCGv_i32 t0
= tcg_temp_new();
26196 TCGv_i32 t1
= tcg_temp_new();
26198 tcg_gen_andi_i32(t0
, mxu_gpr
[XRb
- 1], 0x0000FFFF);
26199 tcg_gen_shli_i32(t0
, t0
, 16);
26201 tcg_gen_andi_i32(t1
, mxu_gpr
[XRc
- 1], 0xFFFF0000);
26202 tcg_gen_shri_i32(t1
, t1
, 16);
26204 tcg_gen_or_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
26210 case MXU_OPTN3_PTN3
:
26214 /* +-------------------+ */
26215 /* A B C | D E F G | H */
26216 /* +---------+---------+ */
26221 TCGv_i32 t0
= tcg_temp_new();
26222 TCGv_i32 t1
= tcg_temp_new();
26224 tcg_gen_andi_i32(t0
, mxu_gpr
[XRb
- 1], 0x000000FF);
26225 tcg_gen_shli_i32(t0
, t0
, 24);
26227 tcg_gen_andi_i32(t1
, mxu_gpr
[XRc
- 1], 0xFFFFFF00);
26228 tcg_gen_shri_i32(t1
, t1
, 8);
26230 tcg_gen_or_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
26236 case MXU_OPTN3_PTN4
:
26240 /* +---------------+ */
26241 /* A B C D | E F G H | */
26242 /* +-------+-------+ */
26247 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRc
- 1]);
26256 * Decoding engine for MXU
26257 * =======================
26262 * Decode MXU pool00
26264 * 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
26265 * +-----------+---------+-----+-------+-------+-------+-----------+
26266 * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL00|
26267 * +-----------+---------+-----+-------+-------+-------+-----------+
26270 static void decode_opc_mxu__pool00(CPUMIPSState
*env
, DisasContext
*ctx
)
26272 uint32_t opcode
= extract32(ctx
->opcode
, 18, 3);
26275 case OPC_MXU_S32MAX
:
26276 case OPC_MXU_S32MIN
:
26277 gen_mxu_S32MAX_S32MIN(ctx
);
26279 case OPC_MXU_D16MAX
:
26280 case OPC_MXU_D16MIN
:
26281 gen_mxu_D16MAX_D16MIN(ctx
);
26283 case OPC_MXU_Q8MAX
:
26284 case OPC_MXU_Q8MIN
:
26285 gen_mxu_Q8MAX_Q8MIN(ctx
);
26287 case OPC_MXU_Q8SLT
:
26288 /* TODO: Implement emulation of Q8SLT instruction. */
26289 MIPS_INVAL("OPC_MXU_Q8SLT");
26290 gen_reserved_instruction(ctx
);
26292 case OPC_MXU_Q8SLTU
:
26293 /* TODO: Implement emulation of Q8SLTU instruction. */
26294 MIPS_INVAL("OPC_MXU_Q8SLTU");
26295 gen_reserved_instruction(ctx
);
26298 MIPS_INVAL("decode_opc_mxu");
26299 gen_reserved_instruction(ctx
);
26306 * Decode MXU pool01
26308 * S32SLT, D16SLT, D16AVG, D16AVGR, Q8AVG, Q8AVGR:
26309 * 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
26310 * +-----------+---------+-----+-------+-------+-------+-----------+
26311 * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL01|
26312 * +-----------+---------+-----+-------+-------+-------+-----------+
26315 * 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
26316 * +-----------+---+-----+-----+-------+-------+-------+-----------+
26317 * | SPECIAL2 |en2|0 0 0|x x x| XRc | XRb | XRa |MXU__POOL01|
26318 * +-----------+---+-----+-----+-------+-------+-------+-----------+
26321 static void decode_opc_mxu__pool01(CPUMIPSState
*env
, DisasContext
*ctx
)
26323 uint32_t opcode
= extract32(ctx
->opcode
, 18, 3);
26326 case OPC_MXU_S32SLT
:
26327 /* TODO: Implement emulation of S32SLT instruction. */
26328 MIPS_INVAL("OPC_MXU_S32SLT");
26329 gen_reserved_instruction(ctx
);
26331 case OPC_MXU_D16SLT
:
26332 /* TODO: Implement emulation of D16SLT instruction. */
26333 MIPS_INVAL("OPC_MXU_D16SLT");
26334 gen_reserved_instruction(ctx
);
26336 case OPC_MXU_D16AVG
:
26337 /* TODO: Implement emulation of D16AVG instruction. */
26338 MIPS_INVAL("OPC_MXU_D16AVG");
26339 gen_reserved_instruction(ctx
);
26341 case OPC_MXU_D16AVGR
:
26342 /* TODO: Implement emulation of D16AVGR instruction. */
26343 MIPS_INVAL("OPC_MXU_D16AVGR");
26344 gen_reserved_instruction(ctx
);
26346 case OPC_MXU_Q8AVG
:
26347 /* TODO: Implement emulation of Q8AVG instruction. */
26348 MIPS_INVAL("OPC_MXU_Q8AVG");
26349 gen_reserved_instruction(ctx
);
26351 case OPC_MXU_Q8AVGR
:
26352 /* TODO: Implement emulation of Q8AVGR instruction. */
26353 MIPS_INVAL("OPC_MXU_Q8AVGR");
26354 gen_reserved_instruction(ctx
);
26356 case OPC_MXU_Q8ADD
:
26357 /* TODO: Implement emulation of Q8ADD instruction. */
26358 MIPS_INVAL("OPC_MXU_Q8ADD");
26359 gen_reserved_instruction(ctx
);
26362 MIPS_INVAL("decode_opc_mxu");
26363 gen_reserved_instruction(ctx
);
26370 * Decode MXU pool02
26372 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26373 * +-----------+---------+-----+-------+-------+-------+-----------+
26374 * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL02|
26375 * +-----------+---------+-----+-------+-------+-------+-----------+
26378 static void decode_opc_mxu__pool02(CPUMIPSState
*env
, DisasContext
*ctx
)
26380 uint32_t opcode
= extract32(ctx
->opcode
, 18, 3);
26383 case OPC_MXU_S32CPS
:
26384 /* TODO: Implement emulation of S32CPS instruction. */
26385 MIPS_INVAL("OPC_MXU_S32CPS");
26386 gen_reserved_instruction(ctx
);
26388 case OPC_MXU_D16CPS
:
26389 /* TODO: Implement emulation of D16CPS instruction. */
26390 MIPS_INVAL("OPC_MXU_D16CPS");
26391 gen_reserved_instruction(ctx
);
26393 case OPC_MXU_Q8ABD
:
26394 /* TODO: Implement emulation of Q8ABD instruction. */
26395 MIPS_INVAL("OPC_MXU_Q8ABD");
26396 gen_reserved_instruction(ctx
);
26398 case OPC_MXU_Q16SAT
:
26399 /* TODO: Implement emulation of Q16SAT instruction. */
26400 MIPS_INVAL("OPC_MXU_Q16SAT");
26401 gen_reserved_instruction(ctx
);
26404 MIPS_INVAL("decode_opc_mxu");
26405 gen_reserved_instruction(ctx
);
26412 * Decode MXU pool03
26415 * 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
26416 * +-----------+---+---+-------+-------+-------+-------+-----------+
26417 * | SPECIAL2 |x x|on2|0 0 0 0| XRc | XRb | XRa |MXU__POOL03|
26418 * +-----------+---+---+-------+-------+-------+-------+-----------+
26421 * 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
26422 * +-----------+---+---+-------+-------+-------+-------+-----------+
26423 * | SPECIAL2 |x x|on2| Xd | XRc | XRb | XRa |MXU__POOL03|
26424 * +-----------+---+---+-------+-------+-------+-------+-----------+
26427 static void decode_opc_mxu__pool03(CPUMIPSState
*env
, DisasContext
*ctx
)
26429 uint32_t opcode
= extract32(ctx
->opcode
, 24, 2);
26432 case OPC_MXU_D16MULF
:
26433 /* TODO: Implement emulation of D16MULF instruction. */
26434 MIPS_INVAL("OPC_MXU_D16MULF");
26435 gen_reserved_instruction(ctx
);
26437 case OPC_MXU_D16MULE
:
26438 /* TODO: Implement emulation of D16MULE instruction. */
26439 MIPS_INVAL("OPC_MXU_D16MULE");
26440 gen_reserved_instruction(ctx
);
26443 MIPS_INVAL("decode_opc_mxu");
26444 gen_reserved_instruction(ctx
);
26451 * Decode MXU pool04
26453 * 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
26454 * +-----------+---------+-+-------------------+-------+-----------+
26455 * | SPECIAL2 | rb |x| s12 | XRa |MXU__POOL04|
26456 * +-----------+---------+-+-------------------+-------+-----------+
26459 static void decode_opc_mxu__pool04(CPUMIPSState
*env
, DisasContext
*ctx
)
26461 uint32_t opcode
= extract32(ctx
->opcode
, 20, 1);
26464 case OPC_MXU_S32LDD
:
26465 case OPC_MXU_S32LDDR
:
26466 gen_mxu_s32ldd_s32lddr(ctx
);
26469 MIPS_INVAL("decode_opc_mxu");
26470 gen_reserved_instruction(ctx
);
26477 * Decode MXU pool05
26479 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26480 * +-----------+---------+-+-------------------+-------+-----------+
26481 * | SPECIAL2 | rb |x| s12 | XRa |MXU__POOL05|
26482 * +-----------+---------+-+-------------------+-------+-----------+
26485 static void decode_opc_mxu__pool05(CPUMIPSState
*env
, DisasContext
*ctx
)
26487 uint32_t opcode
= extract32(ctx
->opcode
, 20, 1);
26490 case OPC_MXU_S32STD
:
26491 /* TODO: Implement emulation of S32STD instruction. */
26492 MIPS_INVAL("OPC_MXU_S32STD");
26493 gen_reserved_instruction(ctx
);
26495 case OPC_MXU_S32STDR
:
26496 /* TODO: Implement emulation of S32STDR instruction. */
26497 MIPS_INVAL("OPC_MXU_S32STDR");
26498 gen_reserved_instruction(ctx
);
26501 MIPS_INVAL("decode_opc_mxu");
26502 gen_reserved_instruction(ctx
);
26509 * Decode MXU pool06
26511 * 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
26512 * +-----------+---------+---------+---+-------+-------+-----------+
26513 * | SPECIAL2 | rb | rc |st2|x x x x| XRa |MXU__POOL06|
26514 * +-----------+---------+---------+---+-------+-------+-----------+
26517 static void decode_opc_mxu__pool06(CPUMIPSState
*env
, DisasContext
*ctx
)
26519 uint32_t opcode
= extract32(ctx
->opcode
, 10, 4);
26522 case OPC_MXU_S32LDDV
:
26523 /* TODO: Implement emulation of S32LDDV instruction. */
26524 MIPS_INVAL("OPC_MXU_S32LDDV");
26525 gen_reserved_instruction(ctx
);
26527 case OPC_MXU_S32LDDVR
:
26528 /* TODO: Implement emulation of S32LDDVR instruction. */
26529 MIPS_INVAL("OPC_MXU_S32LDDVR");
26530 gen_reserved_instruction(ctx
);
26533 MIPS_INVAL("decode_opc_mxu");
26534 gen_reserved_instruction(ctx
);
26541 * Decode MXU pool07
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 | rb | rc |st2|x x x x| XRa |MXU__POOL07|
26546 * +-----------+---------+---------+---+-------+-------+-----------+
26549 static void decode_opc_mxu__pool07(CPUMIPSState
*env
, DisasContext
*ctx
)
26551 uint32_t opcode
= extract32(ctx
->opcode
, 10, 4);
26554 case OPC_MXU_S32STDV
:
26555 /* TODO: Implement emulation of S32TDV instruction. */
26556 MIPS_INVAL("OPC_MXU_S32TDV");
26557 gen_reserved_instruction(ctx
);
26559 case OPC_MXU_S32STDVR
:
26560 /* TODO: Implement emulation of S32TDVR instruction. */
26561 MIPS_INVAL("OPC_MXU_S32TDVR");
26562 gen_reserved_instruction(ctx
);
26565 MIPS_INVAL("decode_opc_mxu");
26566 gen_reserved_instruction(ctx
);
26573 * Decode MXU pool08
26575 * 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
26576 * +-----------+---------+-+-------------------+-------+-----------+
26577 * | SPECIAL2 | rb |x| s12 | XRa |MXU__POOL08|
26578 * +-----------+---------+-+-------------------+-------+-----------+
26581 static void decode_opc_mxu__pool08(CPUMIPSState
*env
, DisasContext
*ctx
)
26583 uint32_t opcode
= extract32(ctx
->opcode
, 20, 1);
26586 case OPC_MXU_S32LDI
:
26587 /* TODO: Implement emulation of S32LDI instruction. */
26588 MIPS_INVAL("OPC_MXU_S32LDI");
26589 gen_reserved_instruction(ctx
);
26591 case OPC_MXU_S32LDIR
:
26592 /* TODO: Implement emulation of S32LDIR instruction. */
26593 MIPS_INVAL("OPC_MXU_S32LDIR");
26594 gen_reserved_instruction(ctx
);
26597 MIPS_INVAL("decode_opc_mxu");
26598 gen_reserved_instruction(ctx
);
26605 * Decode MXU pool09
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__POOL09|
26610 * +-----------+---------+-+-------------------+-------+-----------+
26613 static void decode_opc_mxu__pool09(CPUMIPSState
*env
, DisasContext
*ctx
)
26615 uint32_t opcode
= extract32(ctx
->opcode
, 5, 0);
26618 case OPC_MXU_S32SDI
:
26619 /* TODO: Implement emulation of S32SDI instruction. */
26620 MIPS_INVAL("OPC_MXU_S32SDI");
26621 gen_reserved_instruction(ctx
);
26623 case OPC_MXU_S32SDIR
:
26624 /* TODO: Implement emulation of S32SDIR instruction. */
26625 MIPS_INVAL("OPC_MXU_S32SDIR");
26626 gen_reserved_instruction(ctx
);
26629 MIPS_INVAL("decode_opc_mxu");
26630 gen_reserved_instruction(ctx
);
26637 * Decode MXU pool10
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__POOL10|
26642 * +-----------+---------+---------+---+-------+-------+-----------+
26645 static void decode_opc_mxu__pool10(CPUMIPSState
*env
, DisasContext
*ctx
)
26647 uint32_t opcode
= extract32(ctx
->opcode
, 5, 0);
26650 case OPC_MXU_S32LDIV
:
26651 /* TODO: Implement emulation of S32LDIV instruction. */
26652 MIPS_INVAL("OPC_MXU_S32LDIV");
26653 gen_reserved_instruction(ctx
);
26655 case OPC_MXU_S32LDIVR
:
26656 /* TODO: Implement emulation of S32LDIVR instruction. */
26657 MIPS_INVAL("OPC_MXU_S32LDIVR");
26658 gen_reserved_instruction(ctx
);
26661 MIPS_INVAL("decode_opc_mxu");
26662 gen_reserved_instruction(ctx
);
26669 * Decode MXU pool11
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__POOL11|
26674 * +-----------+---------+---------+---+-------+-------+-----------+
26677 static void decode_opc_mxu__pool11(CPUMIPSState
*env
, DisasContext
*ctx
)
26679 uint32_t opcode
= extract32(ctx
->opcode
, 10, 4);
26682 case OPC_MXU_S32SDIV
:
26683 /* TODO: Implement emulation of S32SDIV instruction. */
26684 MIPS_INVAL("OPC_MXU_S32SDIV");
26685 gen_reserved_instruction(ctx
);
26687 case OPC_MXU_S32SDIVR
:
26688 /* TODO: Implement emulation of S32SDIVR instruction. */
26689 MIPS_INVAL("OPC_MXU_S32SDIVR");
26690 gen_reserved_instruction(ctx
);
26693 MIPS_INVAL("decode_opc_mxu");
26694 gen_reserved_instruction(ctx
);
26701 * Decode MXU pool12
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 |an2|x x| Xd | XRc | XRb | XRa |MXU__POOL12|
26706 * +-----------+---+---+-------+-------+-------+-------+-----------+
26709 static void decode_opc_mxu__pool12(CPUMIPSState
*env
, DisasContext
*ctx
)
26711 uint32_t opcode
= extract32(ctx
->opcode
, 22, 2);
26714 case OPC_MXU_D32ACC
:
26715 /* TODO: Implement emulation of D32ACC instruction. */
26716 MIPS_INVAL("OPC_MXU_D32ACC");
26717 gen_reserved_instruction(ctx
);
26719 case OPC_MXU_D32ACCM
:
26720 /* TODO: Implement emulation of D32ACCM instruction. */
26721 MIPS_INVAL("OPC_MXU_D32ACCM");
26722 gen_reserved_instruction(ctx
);
26724 case OPC_MXU_D32ASUM
:
26725 /* TODO: Implement emulation of D32ASUM instruction. */
26726 MIPS_INVAL("OPC_MXU_D32ASUM");
26727 gen_reserved_instruction(ctx
);
26730 MIPS_INVAL("decode_opc_mxu");
26731 gen_reserved_instruction(ctx
);
26738 * Decode MXU pool13
26740 * 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
26741 * +-----------+---+---+-------+-------+-------+-------+-----------+
26742 * | SPECIAL2 |en2|x x|0 0 0 0| XRc | XRb | XRa |MXU__POOL13|
26743 * +-----------+---+---+-------+-------+-------+-------+-----------+
26746 static void decode_opc_mxu__pool13(CPUMIPSState
*env
, DisasContext
*ctx
)
26748 uint32_t opcode
= extract32(ctx
->opcode
, 22, 2);
26751 case OPC_MXU_Q16ACC
:
26752 /* TODO: Implement emulation of Q16ACC instruction. */
26753 MIPS_INVAL("OPC_MXU_Q16ACC");
26754 gen_reserved_instruction(ctx
);
26756 case OPC_MXU_Q16ACCM
:
26757 /* TODO: Implement emulation of Q16ACCM instruction. */
26758 MIPS_INVAL("OPC_MXU_Q16ACCM");
26759 gen_reserved_instruction(ctx
);
26761 case OPC_MXU_Q16ASUM
:
26762 /* TODO: Implement emulation of Q16ASUM instruction. */
26763 MIPS_INVAL("OPC_MXU_Q16ASUM");
26764 gen_reserved_instruction(ctx
);
26767 MIPS_INVAL("decode_opc_mxu");
26768 gen_reserved_instruction(ctx
);
26775 * Decode MXU pool14
26778 * 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
26779 * +-----------+---+---+-------+-------+-------+-------+-----------+
26780 * | SPECIAL2 |0 0|x x| XRd | XRc | XRb | XRa |MXU__POOL14|
26781 * +-----------+---+---+-------+-------+-------+-------+-----------+
26784 * 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
26785 * +-----------+---+---+-------+-------+-------+-------+-----------+
26786 * | SPECIAL2 |en2|x x|0 0 0 0| XRc | XRb | XRa |MXU__POOL14|
26787 * +-----------+---+---+-------+-------+-------+-------+-----------+
26790 static void decode_opc_mxu__pool14(CPUMIPSState
*env
, DisasContext
*ctx
)
26792 uint32_t opcode
= extract32(ctx
->opcode
, 22, 2);
26795 case OPC_MXU_Q8ADDE
:
26796 /* TODO: Implement emulation of Q8ADDE instruction. */
26797 MIPS_INVAL("OPC_MXU_Q8ADDE");
26798 gen_reserved_instruction(ctx
);
26800 case OPC_MXU_D8SUM
:
26801 /* TODO: Implement emulation of D8SUM instruction. */
26802 MIPS_INVAL("OPC_MXU_D8SUM");
26803 gen_reserved_instruction(ctx
);
26805 case OPC_MXU_D8SUMC
:
26806 /* TODO: Implement emulation of D8SUMC instruction. */
26807 MIPS_INVAL("OPC_MXU_D8SUMC");
26808 gen_reserved_instruction(ctx
);
26811 MIPS_INVAL("decode_opc_mxu");
26812 gen_reserved_instruction(ctx
);
26819 * Decode MXU pool15
26821 * S32MUL, S32MULU, S32EXTRV:
26822 * 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
26823 * +-----------+---------+---------+---+-------+-------+-----------+
26824 * | SPECIAL2 | rs | rt |x x| XRd | XRa |MXU__POOL15|
26825 * +-----------+---------+---------+---+-------+-------+-----------+
26828 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26829 * +-----------+---------+---------+---+-------+-------+-----------+
26830 * | SPECIAL2 | rb | sft5 |x x| XRd | XRa |MXU__POOL15|
26831 * +-----------+---------+---------+---+-------+-------+-----------+
26834 static void decode_opc_mxu__pool15(CPUMIPSState
*env
, DisasContext
*ctx
)
26836 uint32_t opcode
= extract32(ctx
->opcode
, 14, 2);
26839 case OPC_MXU_S32MUL
:
26840 /* TODO: Implement emulation of S32MUL instruction. */
26841 MIPS_INVAL("OPC_MXU_S32MUL");
26842 gen_reserved_instruction(ctx
);
26844 case OPC_MXU_S32MULU
:
26845 /* TODO: Implement emulation of S32MULU instruction. */
26846 MIPS_INVAL("OPC_MXU_S32MULU");
26847 gen_reserved_instruction(ctx
);
26849 case OPC_MXU_S32EXTR
:
26850 /* TODO: Implement emulation of S32EXTR instruction. */
26851 MIPS_INVAL("OPC_MXU_S32EXTR");
26852 gen_reserved_instruction(ctx
);
26854 case OPC_MXU_S32EXTRV
:
26855 /* TODO: Implement emulation of S32EXTRV instruction. */
26856 MIPS_INVAL("OPC_MXU_S32EXTRV");
26857 gen_reserved_instruction(ctx
);
26860 MIPS_INVAL("decode_opc_mxu");
26861 gen_reserved_instruction(ctx
);
26868 * Decode MXU pool16
26871 * 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
26872 * +-----------+---------+-----+-------+-------+-------+-----------+
26873 * | SPECIAL2 | rb |x x x| XRc | XRb | XRa |MXU__POOL16|
26874 * +-----------+---------+-----+-------+-------+-------+-----------+
26877 * 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
26878 * +-----------+---------+-----+-------+-------+-------+-----------+
26879 * | SPECIAL2 | rs |x x x| XRc | XRb | XRa |MXU__POOL16|
26880 * +-----------+---------+-----+-------+-------+-------+-----------+
26883 * 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
26884 * +-----------+-----+---+-----+-------+-------+-------+-----------+
26885 * | SPECIAL2 | s3 |0 0|x x x| XRc | XRb | XRa |MXU__POOL16|
26886 * +-----------+-----+---+-----+-------+-------+-------+-----------+
26889 * 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
26890 * +-----------+-----+---+-----+-------+---------------+-----------+
26891 * | SPECIAL2 |optn3|0 0|x x x| XRc | s8 |MXU__POOL16|
26892 * +-----------+-----+---+-----+-------+---------------+-----------+
26894 * S32NOR, S32AND, S32OR, S32XOR:
26895 * 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
26896 * +-----------+---------+-----+-------+-------+-------+-----------+
26897 * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL16|
26898 * +-----------+---------+-----+-------+-------+-------+-----------+
26901 static void decode_opc_mxu__pool16(CPUMIPSState
*env
, DisasContext
*ctx
)
26903 uint32_t opcode
= extract32(ctx
->opcode
, 18, 3);
26906 case OPC_MXU_D32SARW
:
26907 /* TODO: Implement emulation of D32SARW instruction. */
26908 MIPS_INVAL("OPC_MXU_D32SARW");
26909 gen_reserved_instruction(ctx
);
26911 case OPC_MXU_S32ALN
:
26912 /* TODO: Implement emulation of S32ALN instruction. */
26913 MIPS_INVAL("OPC_MXU_S32ALN");
26914 gen_reserved_instruction(ctx
);
26916 case OPC_MXU_S32ALNI
:
26917 gen_mxu_S32ALNI(ctx
);
26919 case OPC_MXU_S32LUI
:
26920 /* TODO: Implement emulation of S32LUI instruction. */
26921 MIPS_INVAL("OPC_MXU_S32LUI");
26922 gen_reserved_instruction(ctx
);
26924 case OPC_MXU_S32NOR
:
26925 gen_mxu_S32NOR(ctx
);
26927 case OPC_MXU_S32AND
:
26928 gen_mxu_S32AND(ctx
);
26930 case OPC_MXU_S32OR
:
26931 gen_mxu_S32OR(ctx
);
26933 case OPC_MXU_S32XOR
:
26934 gen_mxu_S32XOR(ctx
);
26937 MIPS_INVAL("decode_opc_mxu");
26938 gen_reserved_instruction(ctx
);
26945 * Decode MXU pool17
26947 * 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
26948 * +-----------+---------+---------+---+---------+-----+-----------+
26949 * | SPECIAL2 | rs | rt |0 0| rd |x x x|MXU__POOL15|
26950 * +-----------+---------+---------+---+---------+-----+-----------+
26953 static void decode_opc_mxu__pool17(CPUMIPSState
*env
, DisasContext
*ctx
)
26955 uint32_t opcode
= extract32(ctx
->opcode
, 6, 2);
26959 /* TODO: Implement emulation of LXW instruction. */
26960 MIPS_INVAL("OPC_MXU_LXW");
26961 gen_reserved_instruction(ctx
);
26964 /* TODO: Implement emulation of LXH instruction. */
26965 MIPS_INVAL("OPC_MXU_LXH");
26966 gen_reserved_instruction(ctx
);
26969 /* TODO: Implement emulation of LXHU instruction. */
26970 MIPS_INVAL("OPC_MXU_LXHU");
26971 gen_reserved_instruction(ctx
);
26974 /* TODO: Implement emulation of LXB instruction. */
26975 MIPS_INVAL("OPC_MXU_LXB");
26976 gen_reserved_instruction(ctx
);
26979 /* TODO: Implement emulation of LXBU instruction. */
26980 MIPS_INVAL("OPC_MXU_LXBU");
26981 gen_reserved_instruction(ctx
);
26984 MIPS_INVAL("decode_opc_mxu");
26985 gen_reserved_instruction(ctx
);
26991 * Decode MXU pool18
26993 * 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
26994 * +-----------+---------+-----+-------+-------+-------+-----------+
26995 * | SPECIAL2 | rb |x x x| XRd | XRa |0 0 0 0|MXU__POOL18|
26996 * +-----------+---------+-----+-------+-------+-------+-----------+
26999 static void decode_opc_mxu__pool18(CPUMIPSState
*env
, DisasContext
*ctx
)
27001 uint32_t opcode
= extract32(ctx
->opcode
, 18, 3);
27004 case OPC_MXU_D32SLLV
:
27005 /* TODO: Implement emulation of D32SLLV instruction. */
27006 MIPS_INVAL("OPC_MXU_D32SLLV");
27007 gen_reserved_instruction(ctx
);
27009 case OPC_MXU_D32SLRV
:
27010 /* TODO: Implement emulation of D32SLRV instruction. */
27011 MIPS_INVAL("OPC_MXU_D32SLRV");
27012 gen_reserved_instruction(ctx
);
27014 case OPC_MXU_D32SARV
:
27015 /* TODO: Implement emulation of D32SARV instruction. */
27016 MIPS_INVAL("OPC_MXU_D32SARV");
27017 gen_reserved_instruction(ctx
);
27019 case OPC_MXU_Q16SLLV
:
27020 /* TODO: Implement emulation of Q16SLLV instruction. */
27021 MIPS_INVAL("OPC_MXU_Q16SLLV");
27022 gen_reserved_instruction(ctx
);
27024 case OPC_MXU_Q16SLRV
:
27025 /* TODO: Implement emulation of Q16SLRV instruction. */
27026 MIPS_INVAL("OPC_MXU_Q16SLRV");
27027 gen_reserved_instruction(ctx
);
27029 case OPC_MXU_Q16SARV
:
27030 /* TODO: Implement emulation of Q16SARV instruction. */
27031 MIPS_INVAL("OPC_MXU_Q16SARV");
27032 gen_reserved_instruction(ctx
);
27035 MIPS_INVAL("decode_opc_mxu");
27036 gen_reserved_instruction(ctx
);
27043 * Decode MXU pool19
27045 * 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
27046 * +-----------+---+---+-------+-------+-------+-------+-----------+
27047 * | SPECIAL2 |0 0|x x| XRd | XRc | XRb | XRa |MXU__POOL19|
27048 * +-----------+---+---+-------+-------+-------+-------+-----------+
27051 static void decode_opc_mxu__pool19(CPUMIPSState
*env
, DisasContext
*ctx
)
27053 uint32_t opcode
= extract32(ctx
->opcode
, 22, 2);
27056 case OPC_MXU_Q8MUL
:
27057 case OPC_MXU_Q8MULSU
:
27058 gen_mxu_q8mul_q8mulsu(ctx
);
27061 MIPS_INVAL("decode_opc_mxu");
27062 gen_reserved_instruction(ctx
);
27069 * Decode MXU pool20
27071 * 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
27072 * +-----------+---------+-----+-------+-------+-------+-----------+
27073 * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL20|
27074 * +-----------+---------+-----+-------+-------+-------+-----------+
27077 static void decode_opc_mxu__pool20(CPUMIPSState
*env
, DisasContext
*ctx
)
27079 uint32_t opcode
= extract32(ctx
->opcode
, 18, 3);
27082 case OPC_MXU_Q8MOVZ
:
27083 /* TODO: Implement emulation of Q8MOVZ instruction. */
27084 MIPS_INVAL("OPC_MXU_Q8MOVZ");
27085 gen_reserved_instruction(ctx
);
27087 case OPC_MXU_Q8MOVN
:
27088 /* TODO: Implement emulation of Q8MOVN instruction. */
27089 MIPS_INVAL("OPC_MXU_Q8MOVN");
27090 gen_reserved_instruction(ctx
);
27092 case OPC_MXU_D16MOVZ
:
27093 /* TODO: Implement emulation of D16MOVZ instruction. */
27094 MIPS_INVAL("OPC_MXU_D16MOVZ");
27095 gen_reserved_instruction(ctx
);
27097 case OPC_MXU_D16MOVN
:
27098 /* TODO: Implement emulation of D16MOVN instruction. */
27099 MIPS_INVAL("OPC_MXU_D16MOVN");
27100 gen_reserved_instruction(ctx
);
27102 case OPC_MXU_S32MOVZ
:
27103 /* TODO: Implement emulation of S32MOVZ instruction. */
27104 MIPS_INVAL("OPC_MXU_S32MOVZ");
27105 gen_reserved_instruction(ctx
);
27107 case OPC_MXU_S32MOVN
:
27108 /* TODO: Implement emulation of S32MOVN instruction. */
27109 MIPS_INVAL("OPC_MXU_S32MOVN");
27110 gen_reserved_instruction(ctx
);
27113 MIPS_INVAL("decode_opc_mxu");
27114 gen_reserved_instruction(ctx
);
27121 * Decode MXU pool21
27123 * 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
27124 * +-----------+---+---+-------+-------+-------+-------+-----------+
27125 * | SPECIAL2 |an2|x x| XRd | XRc | XRb | XRa |MXU__POOL21|
27126 * +-----------+---+---+-------+-------+-------+-------+-----------+
27129 static void decode_opc_mxu__pool21(CPUMIPSState
*env
, DisasContext
*ctx
)
27131 uint32_t opcode
= extract32(ctx
->opcode
, 22, 2);
27134 case OPC_MXU_Q8MAC
:
27135 /* TODO: Implement emulation of Q8MAC instruction. */
27136 MIPS_INVAL("OPC_MXU_Q8MAC");
27137 gen_reserved_instruction(ctx
);
27139 case OPC_MXU_Q8MACSU
:
27140 /* TODO: Implement emulation of Q8MACSU instruction. */
27141 MIPS_INVAL("OPC_MXU_Q8MACSU");
27142 gen_reserved_instruction(ctx
);
27145 MIPS_INVAL("decode_opc_mxu");
27146 gen_reserved_instruction(ctx
);
27153 * Main MXU decoding function
27155 * 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
27156 * +-----------+---------------------------------------+-----------+
27157 * | SPECIAL2 | |x x x x x x|
27158 * +-----------+---------------------------------------+-----------+
27161 static void decode_opc_mxu(CPUMIPSState
*env
, DisasContext
*ctx
)
27164 * TODO: Investigate necessity of including handling of
27165 * CLZ, CLO, SDBB in this function, as they belong to
27166 * SPECIAL2 opcode space for regular pre-R6 MIPS ISAs.
27168 uint32_t opcode
= extract32(ctx
->opcode
, 0, 6);
27170 if (opcode
== OPC__MXU_MUL
) {
27171 uint32_t rs
, rt
, rd
, op1
;
27173 rs
= extract32(ctx
->opcode
, 21, 5);
27174 rt
= extract32(ctx
->opcode
, 16, 5);
27175 rd
= extract32(ctx
->opcode
, 11, 5);
27176 op1
= MASK_SPECIAL2(ctx
->opcode
);
27178 gen_arith(ctx
, op1
, rd
, rs
, rt
);
27183 if (opcode
== OPC_MXU_S32M2I
) {
27184 gen_mxu_s32m2i(ctx
);
27188 if (opcode
== OPC_MXU_S32I2M
) {
27189 gen_mxu_s32i2m(ctx
);
27194 TCGv t_mxu_cr
= tcg_temp_new();
27195 TCGLabel
*l_exit
= gen_new_label();
27197 gen_load_mxu_cr(t_mxu_cr
);
27198 tcg_gen_andi_tl(t_mxu_cr
, t_mxu_cr
, MXU_CR_MXU_EN
);
27199 tcg_gen_brcondi_tl(TCG_COND_NE
, t_mxu_cr
, MXU_CR_MXU_EN
, l_exit
);
27202 case OPC_MXU_S32MADD
:
27203 /* TODO: Implement emulation of S32MADD instruction. */
27204 MIPS_INVAL("OPC_MXU_S32MADD");
27205 gen_reserved_instruction(ctx
);
27207 case OPC_MXU_S32MADDU
:
27208 /* TODO: Implement emulation of S32MADDU instruction. */
27209 MIPS_INVAL("OPC_MXU_S32MADDU");
27210 gen_reserved_instruction(ctx
);
27212 case OPC_MXU__POOL00
:
27213 decode_opc_mxu__pool00(env
, ctx
);
27215 case OPC_MXU_S32MSUB
:
27216 /* TODO: Implement emulation of S32MSUB instruction. */
27217 MIPS_INVAL("OPC_MXU_S32MSUB");
27218 gen_reserved_instruction(ctx
);
27220 case OPC_MXU_S32MSUBU
:
27221 /* TODO: Implement emulation of S32MSUBU instruction. */
27222 MIPS_INVAL("OPC_MXU_S32MSUBU");
27223 gen_reserved_instruction(ctx
);
27225 case OPC_MXU__POOL01
:
27226 decode_opc_mxu__pool01(env
, ctx
);
27228 case OPC_MXU__POOL02
:
27229 decode_opc_mxu__pool02(env
, ctx
);
27231 case OPC_MXU_D16MUL
:
27232 gen_mxu_d16mul(ctx
);
27234 case OPC_MXU__POOL03
:
27235 decode_opc_mxu__pool03(env
, ctx
);
27237 case OPC_MXU_D16MAC
:
27238 gen_mxu_d16mac(ctx
);
27240 case OPC_MXU_D16MACF
:
27241 /* TODO: Implement emulation of D16MACF instruction. */
27242 MIPS_INVAL("OPC_MXU_D16MACF");
27243 gen_reserved_instruction(ctx
);
27245 case OPC_MXU_D16MADL
:
27246 /* TODO: Implement emulation of D16MADL instruction. */
27247 MIPS_INVAL("OPC_MXU_D16MADL");
27248 gen_reserved_instruction(ctx
);
27250 case OPC_MXU_S16MAD
:
27251 /* TODO: Implement emulation of S16MAD instruction. */
27252 MIPS_INVAL("OPC_MXU_S16MAD");
27253 gen_reserved_instruction(ctx
);
27255 case OPC_MXU_Q16ADD
:
27256 /* TODO: Implement emulation of Q16ADD instruction. */
27257 MIPS_INVAL("OPC_MXU_Q16ADD");
27258 gen_reserved_instruction(ctx
);
27260 case OPC_MXU_D16MACE
:
27261 /* TODO: Implement emulation of D16MACE instruction. */
27262 MIPS_INVAL("OPC_MXU_D16MACE");
27263 gen_reserved_instruction(ctx
);
27265 case OPC_MXU__POOL04
:
27266 decode_opc_mxu__pool04(env
, ctx
);
27268 case OPC_MXU__POOL05
:
27269 decode_opc_mxu__pool05(env
, ctx
);
27271 case OPC_MXU__POOL06
:
27272 decode_opc_mxu__pool06(env
, ctx
);
27274 case OPC_MXU__POOL07
:
27275 decode_opc_mxu__pool07(env
, ctx
);
27277 case OPC_MXU__POOL08
:
27278 decode_opc_mxu__pool08(env
, ctx
);
27280 case OPC_MXU__POOL09
:
27281 decode_opc_mxu__pool09(env
, ctx
);
27283 case OPC_MXU__POOL10
:
27284 decode_opc_mxu__pool10(env
, ctx
);
27286 case OPC_MXU__POOL11
:
27287 decode_opc_mxu__pool11(env
, ctx
);
27289 case OPC_MXU_D32ADD
:
27290 /* TODO: Implement emulation of D32ADD instruction. */
27291 MIPS_INVAL("OPC_MXU_D32ADD");
27292 gen_reserved_instruction(ctx
);
27294 case OPC_MXU__POOL12
:
27295 decode_opc_mxu__pool12(env
, ctx
);
27297 case OPC_MXU__POOL13
:
27298 decode_opc_mxu__pool13(env
, ctx
);
27300 case OPC_MXU__POOL14
:
27301 decode_opc_mxu__pool14(env
, ctx
);
27303 case OPC_MXU_Q8ACCE
:
27304 /* TODO: Implement emulation of Q8ACCE instruction. */
27305 MIPS_INVAL("OPC_MXU_Q8ACCE");
27306 gen_reserved_instruction(ctx
);
27308 case OPC_MXU_S8LDD
:
27309 gen_mxu_s8ldd(ctx
);
27311 case OPC_MXU_S8STD
:
27312 /* TODO: Implement emulation of S8STD instruction. */
27313 MIPS_INVAL("OPC_MXU_S8STD");
27314 gen_reserved_instruction(ctx
);
27316 case OPC_MXU_S8LDI
:
27317 /* TODO: Implement emulation of S8LDI instruction. */
27318 MIPS_INVAL("OPC_MXU_S8LDI");
27319 gen_reserved_instruction(ctx
);
27321 case OPC_MXU_S8SDI
:
27322 /* TODO: Implement emulation of S8SDI instruction. */
27323 MIPS_INVAL("OPC_MXU_S8SDI");
27324 gen_reserved_instruction(ctx
);
27326 case OPC_MXU__POOL15
:
27327 decode_opc_mxu__pool15(env
, ctx
);
27329 case OPC_MXU__POOL16
:
27330 decode_opc_mxu__pool16(env
, ctx
);
27332 case OPC_MXU__POOL17
:
27333 decode_opc_mxu__pool17(env
, ctx
);
27335 case OPC_MXU_S16LDD
:
27336 /* TODO: Implement emulation of S16LDD instruction. */
27337 MIPS_INVAL("OPC_MXU_S16LDD");
27338 gen_reserved_instruction(ctx
);
27340 case OPC_MXU_S16STD
:
27341 /* TODO: Implement emulation of S16STD instruction. */
27342 MIPS_INVAL("OPC_MXU_S16STD");
27343 gen_reserved_instruction(ctx
);
27345 case OPC_MXU_S16LDI
:
27346 /* TODO: Implement emulation of S16LDI instruction. */
27347 MIPS_INVAL("OPC_MXU_S16LDI");
27348 gen_reserved_instruction(ctx
);
27350 case OPC_MXU_S16SDI
:
27351 /* TODO: Implement emulation of S16SDI instruction. */
27352 MIPS_INVAL("OPC_MXU_S16SDI");
27353 gen_reserved_instruction(ctx
);
27355 case OPC_MXU_D32SLL
:
27356 /* TODO: Implement emulation of D32SLL instruction. */
27357 MIPS_INVAL("OPC_MXU_D32SLL");
27358 gen_reserved_instruction(ctx
);
27360 case OPC_MXU_D32SLR
:
27361 /* TODO: Implement emulation of D32SLR instruction. */
27362 MIPS_INVAL("OPC_MXU_D32SLR");
27363 gen_reserved_instruction(ctx
);
27365 case OPC_MXU_D32SARL
:
27366 /* TODO: Implement emulation of D32SARL instruction. */
27367 MIPS_INVAL("OPC_MXU_D32SARL");
27368 gen_reserved_instruction(ctx
);
27370 case OPC_MXU_D32SAR
:
27371 /* TODO: Implement emulation of D32SAR instruction. */
27372 MIPS_INVAL("OPC_MXU_D32SAR");
27373 gen_reserved_instruction(ctx
);
27375 case OPC_MXU_Q16SLL
:
27376 /* TODO: Implement emulation of Q16SLL instruction. */
27377 MIPS_INVAL("OPC_MXU_Q16SLL");
27378 gen_reserved_instruction(ctx
);
27380 case OPC_MXU_Q16SLR
:
27381 /* TODO: Implement emulation of Q16SLR instruction. */
27382 MIPS_INVAL("OPC_MXU_Q16SLR");
27383 gen_reserved_instruction(ctx
);
27385 case OPC_MXU__POOL18
:
27386 decode_opc_mxu__pool18(env
, ctx
);
27388 case OPC_MXU_Q16SAR
:
27389 /* TODO: Implement emulation of Q16SAR instruction. */
27390 MIPS_INVAL("OPC_MXU_Q16SAR");
27391 gen_reserved_instruction(ctx
);
27393 case OPC_MXU__POOL19
:
27394 decode_opc_mxu__pool19(env
, ctx
);
27396 case OPC_MXU__POOL20
:
27397 decode_opc_mxu__pool20(env
, ctx
);
27399 case OPC_MXU__POOL21
:
27400 decode_opc_mxu__pool21(env
, ctx
);
27402 case OPC_MXU_Q16SCOP
:
27403 /* TODO: Implement emulation of Q16SCOP instruction. */
27404 MIPS_INVAL("OPC_MXU_Q16SCOP");
27405 gen_reserved_instruction(ctx
);
27407 case OPC_MXU_Q8MADL
:
27408 /* TODO: Implement emulation of Q8MADL instruction. */
27409 MIPS_INVAL("OPC_MXU_Q8MADL");
27410 gen_reserved_instruction(ctx
);
27412 case OPC_MXU_S32SFL
:
27413 /* TODO: Implement emulation of S32SFL instruction. */
27414 MIPS_INVAL("OPC_MXU_S32SFL");
27415 gen_reserved_instruction(ctx
);
27417 case OPC_MXU_Q8SAD
:
27418 /* TODO: Implement emulation of Q8SAD instruction. */
27419 MIPS_INVAL("OPC_MXU_Q8SAD");
27420 gen_reserved_instruction(ctx
);
27423 MIPS_INVAL("decode_opc_mxu");
27424 gen_reserved_instruction(ctx
);
27427 gen_set_label(l_exit
);
27428 tcg_temp_free(t_mxu_cr
);
27432 #endif /* !defined(TARGET_MIPS64) */
27435 static void decode_opc_special2_legacy(CPUMIPSState
*env
, DisasContext
*ctx
)
27440 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
27442 rs
= (ctx
->opcode
>> 21) & 0x1f;
27443 rt
= (ctx
->opcode
>> 16) & 0x1f;
27444 rd
= (ctx
->opcode
>> 11) & 0x1f;
27446 op1
= MASK_SPECIAL2(ctx
->opcode
);
27448 case OPC_MADD
: /* Multiply and add/sub */
27452 check_insn(ctx
, ISA_MIPS_R1
);
27453 gen_muldiv(ctx
, op1
, rd
& 3, rs
, rt
);
27456 gen_arith(ctx
, op1
, rd
, rs
, rt
);
27459 case OPC_DIVU_G_2F
:
27460 case OPC_MULT_G_2F
:
27461 case OPC_MULTU_G_2F
:
27463 case OPC_MODU_G_2F
:
27464 check_insn(ctx
, INSN_LOONGSON2F
| ASE_LEXT
);
27465 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
27469 check_insn(ctx
, ISA_MIPS_R1
);
27470 gen_cl(ctx
, op1
, rd
, rs
);
27473 if (is_uhi(extract32(ctx
->opcode
, 6, 20))) {
27474 gen_helper_do_semihosting(cpu_env
);
27477 * XXX: not clear which exception should be raised
27478 * when in debug mode...
27480 check_insn(ctx
, ISA_MIPS_R1
);
27481 generate_exception_end(ctx
, EXCP_DBp
);
27484 #if defined(TARGET_MIPS64)
27487 check_insn(ctx
, ISA_MIPS_R1
);
27488 check_mips_64(ctx
);
27489 gen_cl(ctx
, op1
, rd
, rs
);
27491 case OPC_DMULT_G_2F
:
27492 case OPC_DMULTU_G_2F
:
27493 case OPC_DDIV_G_2F
:
27494 case OPC_DDIVU_G_2F
:
27495 case OPC_DMOD_G_2F
:
27496 case OPC_DMODU_G_2F
:
27497 check_insn(ctx
, INSN_LOONGSON2F
| ASE_LEXT
);
27498 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
27501 default: /* Invalid */
27502 MIPS_INVAL("special2_legacy");
27503 gen_reserved_instruction(ctx
);
27508 static void decode_opc_special3_r6(CPUMIPSState
*env
, DisasContext
*ctx
)
27510 int rs
, rt
, rd
, sa
;
27514 rs
= (ctx
->opcode
>> 21) & 0x1f;
27515 rt
= (ctx
->opcode
>> 16) & 0x1f;
27516 rd
= (ctx
->opcode
>> 11) & 0x1f;
27517 sa
= (ctx
->opcode
>> 6) & 0x1f;
27518 imm
= (int16_t)ctx
->opcode
>> 7;
27520 op1
= MASK_SPECIAL3(ctx
->opcode
);
27524 /* hint codes 24-31 are reserved and signal RI */
27525 gen_reserved_instruction(ctx
);
27527 /* Treat as NOP. */
27530 check_cp0_enabled(ctx
);
27531 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
27532 gen_cache_operation(ctx
, rt
, rs
, imm
);
27536 gen_st_cond(ctx
, rt
, rs
, imm
, MO_TESL
, false);
27539 gen_ld(ctx
, op1
, rt
, rs
, imm
);
27544 /* Treat as NOP. */
27547 op2
= MASK_BSHFL(ctx
->opcode
);
27553 gen_align(ctx
, 32, rd
, rs
, rt
, sa
& 3);
27556 gen_bitswap(ctx
, op2
, rd
, rt
);
27561 #ifndef CONFIG_USER_ONLY
27563 if (unlikely(ctx
->gi
<= 1)) {
27564 gen_reserved_instruction(ctx
);
27566 check_cp0_enabled(ctx
);
27567 switch ((ctx
->opcode
>> 6) & 3) {
27568 case 0: /* GINVI */
27569 /* Treat as NOP. */
27571 case 2: /* GINVT */
27572 gen_helper_0e1i(ginvt
, cpu_gpr
[rs
], extract32(ctx
->opcode
, 8, 2));
27575 gen_reserved_instruction(ctx
);
27580 #if defined(TARGET_MIPS64)
27582 gen_st_cond(ctx
, rt
, rs
, imm
, MO_TEQ
, false);
27585 gen_ld(ctx
, op1
, rt
, rs
, imm
);
27588 check_mips_64(ctx
);
27591 /* Treat as NOP. */
27594 op2
= MASK_DBSHFL(ctx
->opcode
);
27604 gen_align(ctx
, 64, rd
, rs
, rt
, sa
& 7);
27607 gen_bitswap(ctx
, op2
, rd
, rt
);
27614 default: /* Invalid */
27615 MIPS_INVAL("special3_r6");
27616 gen_reserved_instruction(ctx
);
27621 static void decode_opc_special3_legacy(CPUMIPSState
*env
, DisasContext
*ctx
)
27626 rs
= (ctx
->opcode
>> 21) & 0x1f;
27627 rt
= (ctx
->opcode
>> 16) & 0x1f;
27628 rd
= (ctx
->opcode
>> 11) & 0x1f;
27630 op1
= MASK_SPECIAL3(ctx
->opcode
);
27633 case OPC_DIVU_G_2E
:
27635 case OPC_MODU_G_2E
:
27636 case OPC_MULT_G_2E
:
27637 case OPC_MULTU_G_2E
:
27639 * OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
27640 * the same mask and op1.
27642 if ((ctx
->insn_flags
& ASE_DSP_R2
) && (op1
== OPC_MULT_G_2E
)) {
27643 op2
= MASK_ADDUH_QB(ctx
->opcode
);
27646 case OPC_ADDUH_R_QB
:
27648 case OPC_ADDQH_R_PH
:
27650 case OPC_ADDQH_R_W
:
27652 case OPC_SUBUH_R_QB
:
27654 case OPC_SUBQH_R_PH
:
27656 case OPC_SUBQH_R_W
:
27657 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
27662 case OPC_MULQ_RS_W
:
27663 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
27666 MIPS_INVAL("MASK ADDUH.QB");
27667 gen_reserved_instruction(ctx
);
27670 } else if (ctx
->insn_flags
& INSN_LOONGSON2E
) {
27671 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
27673 gen_reserved_instruction(ctx
);
27677 op2
= MASK_LX(ctx
->opcode
);
27679 #if defined(TARGET_MIPS64)
27685 gen_mipsdsp_ld(ctx
, op2
, rd
, rs
, rt
);
27687 default: /* Invalid */
27688 MIPS_INVAL("MASK LX");
27689 gen_reserved_instruction(ctx
);
27693 case OPC_ABSQ_S_PH_DSP
:
27694 op2
= MASK_ABSQ_S_PH(ctx
->opcode
);
27696 case OPC_ABSQ_S_QB
:
27697 case OPC_ABSQ_S_PH
:
27699 case OPC_PRECEQ_W_PHL
:
27700 case OPC_PRECEQ_W_PHR
:
27701 case OPC_PRECEQU_PH_QBL
:
27702 case OPC_PRECEQU_PH_QBR
:
27703 case OPC_PRECEQU_PH_QBLA
:
27704 case OPC_PRECEQU_PH_QBRA
:
27705 case OPC_PRECEU_PH_QBL
:
27706 case OPC_PRECEU_PH_QBR
:
27707 case OPC_PRECEU_PH_QBLA
:
27708 case OPC_PRECEU_PH_QBRA
:
27709 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
27716 gen_mipsdsp_bitinsn(ctx
, op1
, op2
, rd
, rt
);
27719 MIPS_INVAL("MASK ABSQ_S.PH");
27720 gen_reserved_instruction(ctx
);
27724 case OPC_ADDU_QB_DSP
:
27725 op2
= MASK_ADDU_QB(ctx
->opcode
);
27728 case OPC_ADDQ_S_PH
:
27731 case OPC_ADDU_S_QB
:
27733 case OPC_ADDU_S_PH
:
27735 case OPC_SUBQ_S_PH
:
27738 case OPC_SUBU_S_QB
:
27740 case OPC_SUBU_S_PH
:
27744 case OPC_RADDU_W_QB
:
27745 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
27747 case OPC_MULEU_S_PH_QBL
:
27748 case OPC_MULEU_S_PH_QBR
:
27749 case OPC_MULQ_RS_PH
:
27750 case OPC_MULEQ_S_W_PHL
:
27751 case OPC_MULEQ_S_W_PHR
:
27752 case OPC_MULQ_S_PH
:
27753 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
27755 default: /* Invalid */
27756 MIPS_INVAL("MASK ADDU.QB");
27757 gen_reserved_instruction(ctx
);
27762 case OPC_CMPU_EQ_QB_DSP
:
27763 op2
= MASK_CMPU_EQ_QB(ctx
->opcode
);
27765 case OPC_PRECR_SRA_PH_W
:
27766 case OPC_PRECR_SRA_R_PH_W
:
27767 gen_mipsdsp_arith(ctx
, op1
, op2
, rt
, rs
, rd
);
27769 case OPC_PRECR_QB_PH
:
27770 case OPC_PRECRQ_QB_PH
:
27771 case OPC_PRECRQ_PH_W
:
27772 case OPC_PRECRQ_RS_PH_W
:
27773 case OPC_PRECRQU_S_QB_PH
:
27774 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
27776 case OPC_CMPU_EQ_QB
:
27777 case OPC_CMPU_LT_QB
:
27778 case OPC_CMPU_LE_QB
:
27779 case OPC_CMP_EQ_PH
:
27780 case OPC_CMP_LT_PH
:
27781 case OPC_CMP_LE_PH
:
27782 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
27784 case OPC_CMPGU_EQ_QB
:
27785 case OPC_CMPGU_LT_QB
:
27786 case OPC_CMPGU_LE_QB
:
27787 case OPC_CMPGDU_EQ_QB
:
27788 case OPC_CMPGDU_LT_QB
:
27789 case OPC_CMPGDU_LE_QB
:
27792 case OPC_PACKRL_PH
:
27793 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
27795 default: /* Invalid */
27796 MIPS_INVAL("MASK CMPU.EQ.QB");
27797 gen_reserved_instruction(ctx
);
27801 case OPC_SHLL_QB_DSP
:
27802 gen_mipsdsp_shift(ctx
, op1
, rd
, rs
, rt
);
27804 case OPC_DPA_W_PH_DSP
:
27805 op2
= MASK_DPA_W_PH(ctx
->opcode
);
27807 case OPC_DPAU_H_QBL
:
27808 case OPC_DPAU_H_QBR
:
27809 case OPC_DPSU_H_QBL
:
27810 case OPC_DPSU_H_QBR
:
27812 case OPC_DPAX_W_PH
:
27813 case OPC_DPAQ_S_W_PH
:
27814 case OPC_DPAQX_S_W_PH
:
27815 case OPC_DPAQX_SA_W_PH
:
27817 case OPC_DPSX_W_PH
:
27818 case OPC_DPSQ_S_W_PH
:
27819 case OPC_DPSQX_S_W_PH
:
27820 case OPC_DPSQX_SA_W_PH
:
27821 case OPC_MULSAQ_S_W_PH
:
27822 case OPC_DPAQ_SA_L_W
:
27823 case OPC_DPSQ_SA_L_W
:
27824 case OPC_MAQ_S_W_PHL
:
27825 case OPC_MAQ_S_W_PHR
:
27826 case OPC_MAQ_SA_W_PHL
:
27827 case OPC_MAQ_SA_W_PHR
:
27828 case OPC_MULSA_W_PH
:
27829 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
27831 default: /* Invalid */
27832 MIPS_INVAL("MASK DPAW.PH");
27833 gen_reserved_instruction(ctx
);
27838 op2
= MASK_INSV(ctx
->opcode
);
27849 t0
= tcg_temp_new();
27850 t1
= tcg_temp_new();
27852 gen_load_gpr(t0
, rt
);
27853 gen_load_gpr(t1
, rs
);
27855 gen_helper_insv(cpu_gpr
[rt
], cpu_env
, t1
, t0
);
27861 default: /* Invalid */
27862 MIPS_INVAL("MASK INSV");
27863 gen_reserved_instruction(ctx
);
27867 case OPC_APPEND_DSP
:
27868 gen_mipsdsp_append(env
, ctx
, op1
, rt
, rs
, rd
);
27870 case OPC_EXTR_W_DSP
:
27871 op2
= MASK_EXTR_W(ctx
->opcode
);
27875 case OPC_EXTR_RS_W
:
27877 case OPC_EXTRV_S_H
:
27879 case OPC_EXTRV_R_W
:
27880 case OPC_EXTRV_RS_W
:
27885 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rt
, rs
, rd
, 1);
27888 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
27894 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
27896 default: /* Invalid */
27897 MIPS_INVAL("MASK EXTR.W");
27898 gen_reserved_instruction(ctx
);
27902 #if defined(TARGET_MIPS64)
27903 case OPC_DDIV_G_2E
:
27904 case OPC_DDIVU_G_2E
:
27905 case OPC_DMULT_G_2E
:
27906 case OPC_DMULTU_G_2E
:
27907 case OPC_DMOD_G_2E
:
27908 case OPC_DMODU_G_2E
:
27909 check_insn(ctx
, INSN_LOONGSON2E
);
27910 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
27912 case OPC_ABSQ_S_QH_DSP
:
27913 op2
= MASK_ABSQ_S_QH(ctx
->opcode
);
27915 case OPC_PRECEQ_L_PWL
:
27916 case OPC_PRECEQ_L_PWR
:
27917 case OPC_PRECEQ_PW_QHL
:
27918 case OPC_PRECEQ_PW_QHR
:
27919 case OPC_PRECEQ_PW_QHLA
:
27920 case OPC_PRECEQ_PW_QHRA
:
27921 case OPC_PRECEQU_QH_OBL
:
27922 case OPC_PRECEQU_QH_OBR
:
27923 case OPC_PRECEQU_QH_OBLA
:
27924 case OPC_PRECEQU_QH_OBRA
:
27925 case OPC_PRECEU_QH_OBL
:
27926 case OPC_PRECEU_QH_OBR
:
27927 case OPC_PRECEU_QH_OBLA
:
27928 case OPC_PRECEU_QH_OBRA
:
27929 case OPC_ABSQ_S_OB
:
27930 case OPC_ABSQ_S_PW
:
27931 case OPC_ABSQ_S_QH
:
27932 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
27940 gen_mipsdsp_bitinsn(ctx
, op1
, op2
, rd
, rt
);
27942 default: /* Invalid */
27943 MIPS_INVAL("MASK ABSQ_S.QH");
27944 gen_reserved_instruction(ctx
);
27948 case OPC_ADDU_OB_DSP
:
27949 op2
= MASK_ADDU_OB(ctx
->opcode
);
27951 case OPC_RADDU_L_OB
:
27953 case OPC_SUBQ_S_PW
:
27955 case OPC_SUBQ_S_QH
:
27957 case OPC_SUBU_S_OB
:
27959 case OPC_SUBU_S_QH
:
27961 case OPC_SUBUH_R_OB
:
27963 case OPC_ADDQ_S_PW
:
27965 case OPC_ADDQ_S_QH
:
27967 case OPC_ADDU_S_OB
:
27969 case OPC_ADDU_S_QH
:
27971 case OPC_ADDUH_R_OB
:
27972 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
27974 case OPC_MULEQ_S_PW_QHL
:
27975 case OPC_MULEQ_S_PW_QHR
:
27976 case OPC_MULEU_S_QH_OBL
:
27977 case OPC_MULEU_S_QH_OBR
:
27978 case OPC_MULQ_RS_QH
:
27979 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
27981 default: /* Invalid */
27982 MIPS_INVAL("MASK ADDU.OB");
27983 gen_reserved_instruction(ctx
);
27987 case OPC_CMPU_EQ_OB_DSP
:
27988 op2
= MASK_CMPU_EQ_OB(ctx
->opcode
);
27990 case OPC_PRECR_SRA_QH_PW
:
27991 case OPC_PRECR_SRA_R_QH_PW
:
27992 /* Return value is rt. */
27993 gen_mipsdsp_arith(ctx
, op1
, op2
, rt
, rs
, rd
);
27995 case OPC_PRECR_OB_QH
:
27996 case OPC_PRECRQ_OB_QH
:
27997 case OPC_PRECRQ_PW_L
:
27998 case OPC_PRECRQ_QH_PW
:
27999 case OPC_PRECRQ_RS_QH_PW
:
28000 case OPC_PRECRQU_S_OB_QH
:
28001 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
28003 case OPC_CMPU_EQ_OB
:
28004 case OPC_CMPU_LT_OB
:
28005 case OPC_CMPU_LE_OB
:
28006 case OPC_CMP_EQ_QH
:
28007 case OPC_CMP_LT_QH
:
28008 case OPC_CMP_LE_QH
:
28009 case OPC_CMP_EQ_PW
:
28010 case OPC_CMP_LT_PW
:
28011 case OPC_CMP_LE_PW
:
28012 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
28014 case OPC_CMPGDU_EQ_OB
:
28015 case OPC_CMPGDU_LT_OB
:
28016 case OPC_CMPGDU_LE_OB
:
28017 case OPC_CMPGU_EQ_OB
:
28018 case OPC_CMPGU_LT_OB
:
28019 case OPC_CMPGU_LE_OB
:
28020 case OPC_PACKRL_PW
:
28024 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
28026 default: /* Invalid */
28027 MIPS_INVAL("MASK CMPU_EQ.OB");
28028 gen_reserved_instruction(ctx
);
28032 case OPC_DAPPEND_DSP
:
28033 gen_mipsdsp_append(env
, ctx
, op1
, rt
, rs
, rd
);
28035 case OPC_DEXTR_W_DSP
:
28036 op2
= MASK_DEXTR_W(ctx
->opcode
);
28043 case OPC_DEXTR_R_L
:
28044 case OPC_DEXTR_RS_L
:
28046 case OPC_DEXTR_R_W
:
28047 case OPC_DEXTR_RS_W
:
28048 case OPC_DEXTR_S_H
:
28050 case OPC_DEXTRV_R_L
:
28051 case OPC_DEXTRV_RS_L
:
28052 case OPC_DEXTRV_S_H
:
28054 case OPC_DEXTRV_R_W
:
28055 case OPC_DEXTRV_RS_W
:
28056 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rt
, rs
, rd
, 1);
28061 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
28063 default: /* Invalid */
28064 MIPS_INVAL("MASK EXTR.W");
28065 gen_reserved_instruction(ctx
);
28069 case OPC_DPAQ_W_QH_DSP
:
28070 op2
= MASK_DPAQ_W_QH(ctx
->opcode
);
28072 case OPC_DPAU_H_OBL
:
28073 case OPC_DPAU_H_OBR
:
28074 case OPC_DPSU_H_OBL
:
28075 case OPC_DPSU_H_OBR
:
28077 case OPC_DPAQ_S_W_QH
:
28079 case OPC_DPSQ_S_W_QH
:
28080 case OPC_MULSAQ_S_W_QH
:
28081 case OPC_DPAQ_SA_L_PW
:
28082 case OPC_DPSQ_SA_L_PW
:
28083 case OPC_MULSAQ_S_L_PW
:
28084 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
28086 case OPC_MAQ_S_W_QHLL
:
28087 case OPC_MAQ_S_W_QHLR
:
28088 case OPC_MAQ_S_W_QHRL
:
28089 case OPC_MAQ_S_W_QHRR
:
28090 case OPC_MAQ_SA_W_QHLL
:
28091 case OPC_MAQ_SA_W_QHLR
:
28092 case OPC_MAQ_SA_W_QHRL
:
28093 case OPC_MAQ_SA_W_QHRR
:
28094 case OPC_MAQ_S_L_PWL
:
28095 case OPC_MAQ_S_L_PWR
:
28100 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
28102 default: /* Invalid */
28103 MIPS_INVAL("MASK DPAQ.W.QH");
28104 gen_reserved_instruction(ctx
);
28108 case OPC_DINSV_DSP
:
28109 op2
= MASK_INSV(ctx
->opcode
);
28120 t0
= tcg_temp_new();
28121 t1
= tcg_temp_new();
28123 gen_load_gpr(t0
, rt
);
28124 gen_load_gpr(t1
, rs
);
28126 gen_helper_dinsv(cpu_gpr
[rt
], cpu_env
, t1
, t0
);
28132 default: /* Invalid */
28133 MIPS_INVAL("MASK DINSV");
28134 gen_reserved_instruction(ctx
);
28138 case OPC_SHLL_OB_DSP
:
28139 gen_mipsdsp_shift(ctx
, op1
, rd
, rs
, rt
);
28142 default: /* Invalid */
28143 MIPS_INVAL("special3_legacy");
28144 gen_reserved_instruction(ctx
);
28150 #if defined(TARGET_MIPS64)
28152 static void decode_mmi0(CPUMIPSState
*env
, DisasContext
*ctx
)
28154 uint32_t opc
= MASK_MMI0(ctx
->opcode
);
28157 case MMI_OPC_0_PADDW
: /* TODO: MMI_OPC_0_PADDW */
28158 case MMI_OPC_0_PSUBW
: /* TODO: MMI_OPC_0_PSUBW */
28159 case MMI_OPC_0_PCGTW
: /* TODO: MMI_OPC_0_PCGTW */
28160 case MMI_OPC_0_PMAXW
: /* TODO: MMI_OPC_0_PMAXW */
28161 case MMI_OPC_0_PADDH
: /* TODO: MMI_OPC_0_PADDH */
28162 case MMI_OPC_0_PSUBH
: /* TODO: MMI_OPC_0_PSUBH */
28163 case MMI_OPC_0_PCGTH
: /* TODO: MMI_OPC_0_PCGTH */
28164 case MMI_OPC_0_PMAXH
: /* TODO: MMI_OPC_0_PMAXH */
28165 case MMI_OPC_0_PADDB
: /* TODO: MMI_OPC_0_PADDB */
28166 case MMI_OPC_0_PSUBB
: /* TODO: MMI_OPC_0_PSUBB */
28167 case MMI_OPC_0_PCGTB
: /* TODO: MMI_OPC_0_PCGTB */
28168 case MMI_OPC_0_PADDSW
: /* TODO: MMI_OPC_0_PADDSW */
28169 case MMI_OPC_0_PSUBSW
: /* TODO: MMI_OPC_0_PSUBSW */
28170 case MMI_OPC_0_PEXTLW
: /* TODO: MMI_OPC_0_PEXTLW */
28171 case MMI_OPC_0_PPACW
: /* TODO: MMI_OPC_0_PPACW */
28172 case MMI_OPC_0_PADDSH
: /* TODO: MMI_OPC_0_PADDSH */
28173 case MMI_OPC_0_PSUBSH
: /* TODO: MMI_OPC_0_PSUBSH */
28174 case MMI_OPC_0_PEXTLH
: /* TODO: MMI_OPC_0_PEXTLH */
28175 case MMI_OPC_0_PPACH
: /* TODO: MMI_OPC_0_PPACH */
28176 case MMI_OPC_0_PADDSB
: /* TODO: MMI_OPC_0_PADDSB */
28177 case MMI_OPC_0_PSUBSB
: /* TODO: MMI_OPC_0_PSUBSB */
28178 case MMI_OPC_0_PEXTLB
: /* TODO: MMI_OPC_0_PEXTLB */
28179 case MMI_OPC_0_PPACB
: /* TODO: MMI_OPC_0_PPACB */
28180 case MMI_OPC_0_PEXT5
: /* TODO: MMI_OPC_0_PEXT5 */
28181 case MMI_OPC_0_PPAC5
: /* TODO: MMI_OPC_0_PPAC5 */
28182 gen_reserved_instruction(ctx
); /* TODO: MMI_OPC_CLASS_MMI0 */
28185 MIPS_INVAL("TX79 MMI class MMI0");
28186 gen_reserved_instruction(ctx
);
28191 static void decode_mmi1(CPUMIPSState
*env
, DisasContext
*ctx
)
28193 uint32_t opc
= MASK_MMI1(ctx
->opcode
);
28196 case MMI_OPC_1_PABSW
: /* TODO: MMI_OPC_1_PABSW */
28197 case MMI_OPC_1_PCEQW
: /* TODO: MMI_OPC_1_PCEQW */
28198 case MMI_OPC_1_PMINW
: /* TODO: MMI_OPC_1_PMINW */
28199 case MMI_OPC_1_PADSBH
: /* TODO: MMI_OPC_1_PADSBH */
28200 case MMI_OPC_1_PABSH
: /* TODO: MMI_OPC_1_PABSH */
28201 case MMI_OPC_1_PCEQH
: /* TODO: MMI_OPC_1_PCEQH */
28202 case MMI_OPC_1_PMINH
: /* TODO: MMI_OPC_1_PMINH */
28203 case MMI_OPC_1_PCEQB
: /* TODO: MMI_OPC_1_PCEQB */
28204 case MMI_OPC_1_PADDUW
: /* TODO: MMI_OPC_1_PADDUW */
28205 case MMI_OPC_1_PSUBUW
: /* TODO: MMI_OPC_1_PSUBUW */
28206 case MMI_OPC_1_PEXTUW
: /* TODO: MMI_OPC_1_PEXTUW */
28207 case MMI_OPC_1_PADDUH
: /* TODO: MMI_OPC_1_PADDUH */
28208 case MMI_OPC_1_PSUBUH
: /* TODO: MMI_OPC_1_PSUBUH */
28209 case MMI_OPC_1_PEXTUH
: /* TODO: MMI_OPC_1_PEXTUH */
28210 case MMI_OPC_1_PADDUB
: /* TODO: MMI_OPC_1_PADDUB */
28211 case MMI_OPC_1_PSUBUB
: /* TODO: MMI_OPC_1_PSUBUB */
28212 case MMI_OPC_1_PEXTUB
: /* TODO: MMI_OPC_1_PEXTUB */
28213 case MMI_OPC_1_QFSRV
: /* TODO: MMI_OPC_1_QFSRV */
28214 gen_reserved_instruction(ctx
); /* TODO: MMI_OPC_CLASS_MMI1 */
28217 MIPS_INVAL("TX79 MMI class MMI1");
28218 gen_reserved_instruction(ctx
);
28223 static void decode_mmi2(CPUMIPSState
*env
, DisasContext
*ctx
)
28225 uint32_t opc
= MASK_MMI2(ctx
->opcode
);
28228 case MMI_OPC_2_PMADDW
: /* TODO: MMI_OPC_2_PMADDW */
28229 case MMI_OPC_2_PSLLVW
: /* TODO: MMI_OPC_2_PSLLVW */
28230 case MMI_OPC_2_PSRLVW
: /* TODO: MMI_OPC_2_PSRLVW */
28231 case MMI_OPC_2_PMSUBW
: /* TODO: MMI_OPC_2_PMSUBW */
28232 case MMI_OPC_2_PMFHI
: /* TODO: MMI_OPC_2_PMFHI */
28233 case MMI_OPC_2_PMFLO
: /* TODO: MMI_OPC_2_PMFLO */
28234 case MMI_OPC_2_PINTH
: /* TODO: MMI_OPC_2_PINTH */
28235 case MMI_OPC_2_PMULTW
: /* TODO: MMI_OPC_2_PMULTW */
28236 case MMI_OPC_2_PDIVW
: /* TODO: MMI_OPC_2_PDIVW */
28237 case MMI_OPC_2_PMADDH
: /* TODO: MMI_OPC_2_PMADDH */
28238 case MMI_OPC_2_PHMADH
: /* TODO: MMI_OPC_2_PHMADH */
28239 case MMI_OPC_2_PAND
: /* TODO: MMI_OPC_2_PAND */
28240 case MMI_OPC_2_PXOR
: /* TODO: MMI_OPC_2_PXOR */
28241 case MMI_OPC_2_PMSUBH
: /* TODO: MMI_OPC_2_PMSUBH */
28242 case MMI_OPC_2_PHMSBH
: /* TODO: MMI_OPC_2_PHMSBH */
28243 case MMI_OPC_2_PEXEH
: /* TODO: MMI_OPC_2_PEXEH */
28244 case MMI_OPC_2_PREVH
: /* TODO: MMI_OPC_2_PREVH */
28245 case MMI_OPC_2_PMULTH
: /* TODO: MMI_OPC_2_PMULTH */
28246 case MMI_OPC_2_PDIVBW
: /* TODO: MMI_OPC_2_PDIVBW */
28247 case MMI_OPC_2_PEXEW
: /* TODO: MMI_OPC_2_PEXEW */
28248 case MMI_OPC_2_PROT3W
: /* TODO: MMI_OPC_2_PROT3W */
28249 gen_reserved_instruction(ctx
); /* TODO: MMI_OPC_CLASS_MMI2 */
28251 case MMI_OPC_2_PCPYLD
:
28252 gen_mmi_pcpyld(ctx
);
28255 MIPS_INVAL("TX79 MMI class MMI2");
28256 gen_reserved_instruction(ctx
);
28261 static void decode_mmi3(CPUMIPSState
*env
, DisasContext
*ctx
)
28263 uint32_t opc
= MASK_MMI3(ctx
->opcode
);
28266 case MMI_OPC_3_PMADDUW
: /* TODO: MMI_OPC_3_PMADDUW */
28267 case MMI_OPC_3_PSRAVW
: /* TODO: MMI_OPC_3_PSRAVW */
28268 case MMI_OPC_3_PMTHI
: /* TODO: MMI_OPC_3_PMTHI */
28269 case MMI_OPC_3_PMTLO
: /* TODO: MMI_OPC_3_PMTLO */
28270 case MMI_OPC_3_PINTEH
: /* TODO: MMI_OPC_3_PINTEH */
28271 case MMI_OPC_3_PMULTUW
: /* TODO: MMI_OPC_3_PMULTUW */
28272 case MMI_OPC_3_PDIVUW
: /* TODO: MMI_OPC_3_PDIVUW */
28273 case MMI_OPC_3_POR
: /* TODO: MMI_OPC_3_POR */
28274 case MMI_OPC_3_PNOR
: /* TODO: MMI_OPC_3_PNOR */
28275 case MMI_OPC_3_PEXCH
: /* TODO: MMI_OPC_3_PEXCH */
28276 case MMI_OPC_3_PEXCW
: /* TODO: MMI_OPC_3_PEXCW */
28277 gen_reserved_instruction(ctx
); /* TODO: MMI_OPC_CLASS_MMI3 */
28279 case MMI_OPC_3_PCPYH
:
28280 gen_mmi_pcpyh(ctx
);
28282 case MMI_OPC_3_PCPYUD
:
28283 gen_mmi_pcpyud(ctx
);
28286 MIPS_INVAL("TX79 MMI class MMI3");
28287 gen_reserved_instruction(ctx
);
28292 static void decode_mmi(CPUMIPSState
*env
, DisasContext
*ctx
)
28294 uint32_t opc
= MASK_MMI(ctx
->opcode
);
28295 int rs
= extract32(ctx
->opcode
, 21, 5);
28296 int rt
= extract32(ctx
->opcode
, 16, 5);
28297 int rd
= extract32(ctx
->opcode
, 11, 5);
28300 case MMI_OPC_CLASS_MMI0
:
28301 decode_mmi0(env
, ctx
);
28303 case MMI_OPC_CLASS_MMI1
:
28304 decode_mmi1(env
, ctx
);
28306 case MMI_OPC_CLASS_MMI2
:
28307 decode_mmi2(env
, ctx
);
28309 case MMI_OPC_CLASS_MMI3
:
28310 decode_mmi3(env
, ctx
);
28312 case MMI_OPC_MULT1
:
28313 case MMI_OPC_MULTU1
:
28315 case MMI_OPC_MADDU
:
28316 case MMI_OPC_MADD1
:
28317 case MMI_OPC_MADDU1
:
28318 gen_mul_txx9(ctx
, opc
, rd
, rs
, rt
);
28321 case MMI_OPC_DIVU1
:
28322 gen_div1_tx79(ctx
, opc
, rs
, rt
);
28324 case MMI_OPC_MTLO1
:
28325 case MMI_OPC_MTHI1
:
28326 gen_HILO1_tx79(ctx
, opc
, rs
);
28328 case MMI_OPC_MFLO1
:
28329 case MMI_OPC_MFHI1
:
28330 gen_HILO1_tx79(ctx
, opc
, rd
);
28332 case MMI_OPC_PLZCW
: /* TODO: MMI_OPC_PLZCW */
28333 case MMI_OPC_PMFHL
: /* TODO: MMI_OPC_PMFHL */
28334 case MMI_OPC_PMTHL
: /* TODO: MMI_OPC_PMTHL */
28335 case MMI_OPC_PSLLH
: /* TODO: MMI_OPC_PSLLH */
28336 case MMI_OPC_PSRLH
: /* TODO: MMI_OPC_PSRLH */
28337 case MMI_OPC_PSRAH
: /* TODO: MMI_OPC_PSRAH */
28338 case MMI_OPC_PSLLW
: /* TODO: MMI_OPC_PSLLW */
28339 case MMI_OPC_PSRLW
: /* TODO: MMI_OPC_PSRLW */
28340 case MMI_OPC_PSRAW
: /* TODO: MMI_OPC_PSRAW */
28341 gen_reserved_instruction(ctx
); /* TODO: MMI_OPC_CLASS_MMI */
28344 MIPS_INVAL("TX79 MMI class");
28345 gen_reserved_instruction(ctx
);
28350 static void gen_mmi_lq(CPUMIPSState
*env
, DisasContext
*ctx
)
28352 gen_reserved_instruction(ctx
); /* TODO: MMI_OPC_LQ */
28355 static void gen_mmi_sq(DisasContext
*ctx
, int base
, int rt
, int offset
)
28357 gen_reserved_instruction(ctx
); /* TODO: MMI_OPC_SQ */
28361 * The TX79-specific instruction Store Quadword
28363 * +--------+-------+-------+------------------------+
28364 * | 011111 | base | rt | offset | SQ
28365 * +--------+-------+-------+------------------------+
28368 * has the same opcode as the Read Hardware Register instruction
28370 * +--------+-------+-------+-------+-------+--------+
28371 * | 011111 | 00000 | rt | rd | 00000 | 111011 | RDHWR
28372 * +--------+-------+-------+-------+-------+--------+
28375 * that is required, trapped and emulated by the Linux kernel. However, all
28376 * RDHWR encodings yield address error exceptions on the TX79 since the SQ
28377 * offset is odd. Therefore all valid SQ instructions can execute normally.
28378 * In user mode, QEMU must verify the upper and lower 11 bits to distinguish
28379 * between SQ and RDHWR, as the Linux kernel does.
28381 static void decode_mmi_sq(CPUMIPSState
*env
, DisasContext
*ctx
)
28383 int base
= extract32(ctx
->opcode
, 21, 5);
28384 int rt
= extract32(ctx
->opcode
, 16, 5);
28385 int offset
= extract32(ctx
->opcode
, 0, 16);
28387 #ifdef CONFIG_USER_ONLY
28388 uint32_t op1
= MASK_SPECIAL3(ctx
->opcode
);
28389 uint32_t op2
= extract32(ctx
->opcode
, 6, 5);
28391 if (base
== 0 && op2
== 0 && op1
== OPC_RDHWR
) {
28392 int rd
= extract32(ctx
->opcode
, 11, 5);
28394 gen_rdhwr(ctx
, rt
, rd
, 0);
28399 gen_mmi_sq(ctx
, base
, rt
, offset
);
28404 static void decode_opc_special3(CPUMIPSState
*env
, DisasContext
*ctx
)
28406 int rs
, rt
, rd
, sa
;
28410 rs
= (ctx
->opcode
>> 21) & 0x1f;
28411 rt
= (ctx
->opcode
>> 16) & 0x1f;
28412 rd
= (ctx
->opcode
>> 11) & 0x1f;
28413 sa
= (ctx
->opcode
>> 6) & 0x1f;
28414 imm
= sextract32(ctx
->opcode
, 7, 9);
28416 op1
= MASK_SPECIAL3(ctx
->opcode
);
28419 * EVA loads and stores overlap Loongson 2E instructions decoded by
28420 * decode_opc_special3_legacy(), so be careful to allow their decoding when
28427 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
28435 check_cp0_enabled(ctx
);
28436 gen_ld(ctx
, op1
, rt
, rs
, imm
);
28440 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
28445 check_cp0_enabled(ctx
);
28446 gen_st(ctx
, op1
, rt
, rs
, imm
);
28449 check_cp0_enabled(ctx
);
28450 gen_st_cond(ctx
, rt
, rs
, imm
, MO_TESL
, true);
28453 check_cp0_enabled(ctx
);
28454 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
28455 gen_cache_operation(ctx
, rt
, rs
, imm
);
28457 /* Treat as NOP. */
28460 check_cp0_enabled(ctx
);
28461 /* Treat as NOP. */
28469 check_insn(ctx
, ISA_MIPS_R2
);
28470 gen_bitops(ctx
, op1
, rt
, rs
, sa
, rd
);
28473 op2
= MASK_BSHFL(ctx
->opcode
);
28480 check_insn(ctx
, ISA_MIPS_R6
);
28481 decode_opc_special3_r6(env
, ctx
);
28484 check_insn(ctx
, ISA_MIPS_R2
);
28485 gen_bshfl(ctx
, op2
, rt
, rd
);
28489 #if defined(TARGET_MIPS64)
28496 check_insn(ctx
, ISA_MIPS_R2
);
28497 check_mips_64(ctx
);
28498 gen_bitops(ctx
, op1
, rt
, rs
, sa
, rd
);
28501 op2
= MASK_DBSHFL(ctx
->opcode
);
28512 check_insn(ctx
, ISA_MIPS_R6
);
28513 decode_opc_special3_r6(env
, ctx
);
28516 check_insn(ctx
, ISA_MIPS_R2
);
28517 check_mips_64(ctx
);
28518 op2
= MASK_DBSHFL(ctx
->opcode
);
28519 gen_bshfl(ctx
, op2
, rt
, rd
);
28525 gen_rdhwr(ctx
, rt
, rd
, extract32(ctx
->opcode
, 6, 3));
28530 TCGv t0
= tcg_temp_new();
28531 TCGv t1
= tcg_temp_new();
28533 gen_load_gpr(t0
, rt
);
28534 gen_load_gpr(t1
, rs
);
28535 gen_helper_fork(t0
, t1
);
28543 TCGv t0
= tcg_temp_new();
28545 gen_load_gpr(t0
, rs
);
28546 gen_helper_yield(t0
, cpu_env
, t0
);
28547 gen_store_gpr(t0
, rd
);
28552 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
28553 decode_opc_special3_r6(env
, ctx
);
28555 decode_opc_special3_legacy(env
, ctx
);
28560 /* MIPS SIMD Architecture (MSA) */
28561 static inline int check_msa_access(DisasContext
*ctx
)
28563 if (unlikely((ctx
->hflags
& MIPS_HFLAG_FPU
) &&
28564 !(ctx
->hflags
& MIPS_HFLAG_F64
))) {
28565 gen_reserved_instruction(ctx
);
28569 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_MSA
))) {
28570 if (ctx
->insn_flags
& ASE_MSA
) {
28571 generate_exception_end(ctx
, EXCP_MSADIS
);
28574 gen_reserved_instruction(ctx
);
28581 static void gen_check_zero_element(TCGv tresult
, uint8_t df
, uint8_t wt
)
28583 /* generates tcg ops to check if any element is 0 */
28584 /* Note this function only works with MSA_WRLEN = 128 */
28585 uint64_t eval_zero_or_big
= 0;
28586 uint64_t eval_big
= 0;
28587 TCGv_i64 t0
= tcg_temp_new_i64();
28588 TCGv_i64 t1
= tcg_temp_new_i64();
28591 eval_zero_or_big
= 0x0101010101010101ULL
;
28592 eval_big
= 0x8080808080808080ULL
;
28595 eval_zero_or_big
= 0x0001000100010001ULL
;
28596 eval_big
= 0x8000800080008000ULL
;
28599 eval_zero_or_big
= 0x0000000100000001ULL
;
28600 eval_big
= 0x8000000080000000ULL
;
28603 eval_zero_or_big
= 0x0000000000000001ULL
;
28604 eval_big
= 0x8000000000000000ULL
;
28607 tcg_gen_subi_i64(t0
, msa_wr_d
[wt
<< 1], eval_zero_or_big
);
28608 tcg_gen_andc_i64(t0
, t0
, msa_wr_d
[wt
<< 1]);
28609 tcg_gen_andi_i64(t0
, t0
, eval_big
);
28610 tcg_gen_subi_i64(t1
, msa_wr_d
[(wt
<< 1) + 1], eval_zero_or_big
);
28611 tcg_gen_andc_i64(t1
, t1
, msa_wr_d
[(wt
<< 1) + 1]);
28612 tcg_gen_andi_i64(t1
, t1
, eval_big
);
28613 tcg_gen_or_i64(t0
, t0
, t1
);
28614 /* if all bits are zero then all elements are not zero */
28615 /* if some bit is non-zero then some element is zero */
28616 tcg_gen_setcondi_i64(TCG_COND_NE
, t0
, t0
, 0);
28617 tcg_gen_trunc_i64_tl(tresult
, t0
);
28618 tcg_temp_free_i64(t0
);
28619 tcg_temp_free_i64(t1
);
28622 static void gen_msa_branch(CPUMIPSState
*env
, DisasContext
*ctx
, uint32_t op1
)
28624 uint8_t df
= (ctx
->opcode
>> 21) & 0x3;
28625 uint8_t wt
= (ctx
->opcode
>> 16) & 0x1f;
28626 int64_t s16
= (int16_t)ctx
->opcode
;
28628 check_msa_access(ctx
);
28630 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
28631 gen_reserved_instruction(ctx
);
28638 TCGv_i64 t0
= tcg_temp_new_i64();
28639 tcg_gen_or_i64(t0
, msa_wr_d
[wt
<< 1], msa_wr_d
[(wt
<< 1) + 1]);
28640 tcg_gen_setcondi_i64((op1
== OPC_BZ_V
) ?
28641 TCG_COND_EQ
: TCG_COND_NE
, t0
, t0
, 0);
28642 tcg_gen_trunc_i64_tl(bcond
, t0
);
28643 tcg_temp_free_i64(t0
);
28650 gen_check_zero_element(bcond
, df
, wt
);
28656 gen_check_zero_element(bcond
, df
, wt
);
28657 tcg_gen_setcondi_tl(TCG_COND_EQ
, bcond
, bcond
, 0);
28661 ctx
->btarget
= ctx
->base
.pc_next
+ (s16
<< 2) + 4;
28663 ctx
->hflags
|= MIPS_HFLAG_BC
;
28664 ctx
->hflags
|= MIPS_HFLAG_BDS32
;
28667 static void gen_msa_i8(CPUMIPSState
*env
, DisasContext
*ctx
)
28669 #define MASK_MSA_I8(op) (MASK_MSA_MINOR(op) | (op & (0x03 << 24)))
28670 uint8_t i8
= (ctx
->opcode
>> 16) & 0xff;
28671 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
28672 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
28674 TCGv_i32 twd
= tcg_const_i32(wd
);
28675 TCGv_i32 tws
= tcg_const_i32(ws
);
28676 TCGv_i32 ti8
= tcg_const_i32(i8
);
28678 switch (MASK_MSA_I8(ctx
->opcode
)) {
28680 gen_helper_msa_andi_b(cpu_env
, twd
, tws
, ti8
);
28683 gen_helper_msa_ori_b(cpu_env
, twd
, tws
, ti8
);
28686 gen_helper_msa_nori_b(cpu_env
, twd
, tws
, ti8
);
28689 gen_helper_msa_xori_b(cpu_env
, twd
, tws
, ti8
);
28692 gen_helper_msa_bmnzi_b(cpu_env
, twd
, tws
, ti8
);
28695 gen_helper_msa_bmzi_b(cpu_env
, twd
, tws
, ti8
);
28698 gen_helper_msa_bseli_b(cpu_env
, twd
, tws
, ti8
);
28704 uint8_t df
= (ctx
->opcode
>> 24) & 0x3;
28705 if (df
== DF_DOUBLE
) {
28706 gen_reserved_instruction(ctx
);
28708 TCGv_i32 tdf
= tcg_const_i32(df
);
28709 gen_helper_msa_shf_df(cpu_env
, tdf
, twd
, tws
, ti8
);
28710 tcg_temp_free_i32(tdf
);
28715 MIPS_INVAL("MSA instruction");
28716 gen_reserved_instruction(ctx
);
28720 tcg_temp_free_i32(twd
);
28721 tcg_temp_free_i32(tws
);
28722 tcg_temp_free_i32(ti8
);
28725 static void gen_msa_i5(CPUMIPSState
*env
, DisasContext
*ctx
)
28727 #define MASK_MSA_I5(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
28728 uint8_t df
= (ctx
->opcode
>> 21) & 0x3;
28729 int8_t s5
= (int8_t) sextract32(ctx
->opcode
, 16, 5);
28730 uint8_t u5
= (ctx
->opcode
>> 16) & 0x1f;
28731 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
28732 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
28734 TCGv_i32 tdf
= tcg_const_i32(df
);
28735 TCGv_i32 twd
= tcg_const_i32(wd
);
28736 TCGv_i32 tws
= tcg_const_i32(ws
);
28737 TCGv_i32 timm
= tcg_temp_new_i32();
28738 tcg_gen_movi_i32(timm
, u5
);
28740 switch (MASK_MSA_I5(ctx
->opcode
)) {
28742 gen_helper_msa_addvi_df(cpu_env
, tdf
, twd
, tws
, timm
);
28745 gen_helper_msa_subvi_df(cpu_env
, tdf
, twd
, tws
, timm
);
28747 case OPC_MAXI_S_df
:
28748 tcg_gen_movi_i32(timm
, s5
);
28749 gen_helper_msa_maxi_s_df(cpu_env
, tdf
, twd
, tws
, timm
);
28751 case OPC_MAXI_U_df
:
28752 gen_helper_msa_maxi_u_df(cpu_env
, tdf
, twd
, tws
, timm
);
28754 case OPC_MINI_S_df
:
28755 tcg_gen_movi_i32(timm
, s5
);
28756 gen_helper_msa_mini_s_df(cpu_env
, tdf
, twd
, tws
, timm
);
28758 case OPC_MINI_U_df
:
28759 gen_helper_msa_mini_u_df(cpu_env
, tdf
, twd
, tws
, timm
);
28762 tcg_gen_movi_i32(timm
, s5
);
28763 gen_helper_msa_ceqi_df(cpu_env
, tdf
, twd
, tws
, timm
);
28765 case OPC_CLTI_S_df
:
28766 tcg_gen_movi_i32(timm
, s5
);
28767 gen_helper_msa_clti_s_df(cpu_env
, tdf
, twd
, tws
, timm
);
28769 case OPC_CLTI_U_df
:
28770 gen_helper_msa_clti_u_df(cpu_env
, tdf
, twd
, tws
, timm
);
28772 case OPC_CLEI_S_df
:
28773 tcg_gen_movi_i32(timm
, s5
);
28774 gen_helper_msa_clei_s_df(cpu_env
, tdf
, twd
, tws
, timm
);
28776 case OPC_CLEI_U_df
:
28777 gen_helper_msa_clei_u_df(cpu_env
, tdf
, twd
, tws
, timm
);
28781 int32_t s10
= sextract32(ctx
->opcode
, 11, 10);
28782 tcg_gen_movi_i32(timm
, s10
);
28783 gen_helper_msa_ldi_df(cpu_env
, tdf
, twd
, timm
);
28787 MIPS_INVAL("MSA instruction");
28788 gen_reserved_instruction(ctx
);
28792 tcg_temp_free_i32(tdf
);
28793 tcg_temp_free_i32(twd
);
28794 tcg_temp_free_i32(tws
);
28795 tcg_temp_free_i32(timm
);
28798 static void gen_msa_bit(CPUMIPSState
*env
, DisasContext
*ctx
)
28800 #define MASK_MSA_BIT(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
28801 uint8_t dfm
= (ctx
->opcode
>> 16) & 0x7f;
28802 uint32_t df
= 0, m
= 0;
28803 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
28804 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
28811 if ((dfm
& 0x40) == 0x00) {
28814 } else if ((dfm
& 0x60) == 0x40) {
28817 } else if ((dfm
& 0x70) == 0x60) {
28820 } else if ((dfm
& 0x78) == 0x70) {
28824 gen_reserved_instruction(ctx
);
28828 tdf
= tcg_const_i32(df
);
28829 tm
= tcg_const_i32(m
);
28830 twd
= tcg_const_i32(wd
);
28831 tws
= tcg_const_i32(ws
);
28833 switch (MASK_MSA_BIT(ctx
->opcode
)) {
28835 gen_helper_msa_slli_df(cpu_env
, tdf
, twd
, tws
, tm
);
28838 gen_helper_msa_srai_df(cpu_env
, tdf
, twd
, tws
, tm
);
28841 gen_helper_msa_srli_df(cpu_env
, tdf
, twd
, tws
, tm
);
28844 gen_helper_msa_bclri_df(cpu_env
, tdf
, twd
, tws
, tm
);
28847 gen_helper_msa_bseti_df(cpu_env
, tdf
, twd
, tws
, tm
);
28850 gen_helper_msa_bnegi_df(cpu_env
, tdf
, twd
, tws
, tm
);
28852 case OPC_BINSLI_df
:
28853 gen_helper_msa_binsli_df(cpu_env
, tdf
, twd
, tws
, tm
);
28855 case OPC_BINSRI_df
:
28856 gen_helper_msa_binsri_df(cpu_env
, tdf
, twd
, tws
, tm
);
28859 gen_helper_msa_sat_s_df(cpu_env
, tdf
, twd
, tws
, tm
);
28862 gen_helper_msa_sat_u_df(cpu_env
, tdf
, twd
, tws
, tm
);
28865 gen_helper_msa_srari_df(cpu_env
, tdf
, twd
, tws
, tm
);
28868 gen_helper_msa_srlri_df(cpu_env
, tdf
, twd
, tws
, tm
);
28871 MIPS_INVAL("MSA instruction");
28872 gen_reserved_instruction(ctx
);
28876 tcg_temp_free_i32(tdf
);
28877 tcg_temp_free_i32(tm
);
28878 tcg_temp_free_i32(twd
);
28879 tcg_temp_free_i32(tws
);
28882 static void gen_msa_3r(CPUMIPSState
*env
, DisasContext
*ctx
)
28884 #define MASK_MSA_3R(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
28885 uint8_t df
= (ctx
->opcode
>> 21) & 0x3;
28886 uint8_t wt
= (ctx
->opcode
>> 16) & 0x1f;
28887 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
28888 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
28890 TCGv_i32 tdf
= tcg_const_i32(df
);
28891 TCGv_i32 twd
= tcg_const_i32(wd
);
28892 TCGv_i32 tws
= tcg_const_i32(ws
);
28893 TCGv_i32 twt
= tcg_const_i32(wt
);
28895 switch (MASK_MSA_3R(ctx
->opcode
)) {
28899 gen_helper_msa_binsl_b(cpu_env
, twd
, tws
, twt
);
28902 gen_helper_msa_binsl_h(cpu_env
, twd
, tws
, twt
);
28905 gen_helper_msa_binsl_w(cpu_env
, twd
, tws
, twt
);
28908 gen_helper_msa_binsl_d(cpu_env
, twd
, tws
, twt
);
28915 gen_helper_msa_binsr_b(cpu_env
, twd
, tws
, twt
);
28918 gen_helper_msa_binsr_h(cpu_env
, twd
, tws
, twt
);
28921 gen_helper_msa_binsr_w(cpu_env
, twd
, tws
, twt
);
28924 gen_helper_msa_binsr_d(cpu_env
, twd
, tws
, twt
);
28931 gen_helper_msa_bclr_b(cpu_env
, twd
, tws
, twt
);
28934 gen_helper_msa_bclr_h(cpu_env
, twd
, tws
, twt
);
28937 gen_helper_msa_bclr_w(cpu_env
, twd
, tws
, twt
);
28940 gen_helper_msa_bclr_d(cpu_env
, twd
, tws
, twt
);
28947 gen_helper_msa_bneg_b(cpu_env
, twd
, tws
, twt
);
28950 gen_helper_msa_bneg_h(cpu_env
, twd
, tws
, twt
);
28953 gen_helper_msa_bneg_w(cpu_env
, twd
, tws
, twt
);
28956 gen_helper_msa_bneg_d(cpu_env
, twd
, tws
, twt
);
28963 gen_helper_msa_bset_b(cpu_env
, twd
, tws
, twt
);
28966 gen_helper_msa_bset_h(cpu_env
, twd
, tws
, twt
);
28969 gen_helper_msa_bset_w(cpu_env
, twd
, tws
, twt
);
28972 gen_helper_msa_bset_d(cpu_env
, twd
, tws
, twt
);
28979 gen_helper_msa_add_a_b(cpu_env
, twd
, tws
, twt
);
28982 gen_helper_msa_add_a_h(cpu_env
, twd
, tws
, twt
);
28985 gen_helper_msa_add_a_w(cpu_env
, twd
, tws
, twt
);
28988 gen_helper_msa_add_a_d(cpu_env
, twd
, tws
, twt
);
28992 case OPC_ADDS_A_df
:
28995 gen_helper_msa_adds_a_b(cpu_env
, twd
, tws
, twt
);
28998 gen_helper_msa_adds_a_h(cpu_env
, twd
, tws
, twt
);
29001 gen_helper_msa_adds_a_w(cpu_env
, twd
, tws
, twt
);
29004 gen_helper_msa_adds_a_d(cpu_env
, twd
, tws
, twt
);
29008 case OPC_ADDS_S_df
:
29011 gen_helper_msa_adds_s_b(cpu_env
, twd
, tws
, twt
);
29014 gen_helper_msa_adds_s_h(cpu_env
, twd
, tws
, twt
);
29017 gen_helper_msa_adds_s_w(cpu_env
, twd
, tws
, twt
);
29020 gen_helper_msa_adds_s_d(cpu_env
, twd
, tws
, twt
);
29024 case OPC_ADDS_U_df
:
29027 gen_helper_msa_adds_u_b(cpu_env
, twd
, tws
, twt
);
29030 gen_helper_msa_adds_u_h(cpu_env
, twd
, tws
, twt
);
29033 gen_helper_msa_adds_u_w(cpu_env
, twd
, tws
, twt
);
29036 gen_helper_msa_adds_u_d(cpu_env
, twd
, tws
, twt
);
29043 gen_helper_msa_addv_b(cpu_env
, twd
, tws
, twt
);
29046 gen_helper_msa_addv_h(cpu_env
, twd
, tws
, twt
);
29049 gen_helper_msa_addv_w(cpu_env
, twd
, tws
, twt
);
29052 gen_helper_msa_addv_d(cpu_env
, twd
, tws
, twt
);
29059 gen_helper_msa_ave_s_b(cpu_env
, twd
, tws
, twt
);
29062 gen_helper_msa_ave_s_h(cpu_env
, twd
, tws
, twt
);
29065 gen_helper_msa_ave_s_w(cpu_env
, twd
, tws
, twt
);
29068 gen_helper_msa_ave_s_d(cpu_env
, twd
, tws
, twt
);
29075 gen_helper_msa_ave_u_b(cpu_env
, twd
, tws
, twt
);
29078 gen_helper_msa_ave_u_h(cpu_env
, twd
, tws
, twt
);
29081 gen_helper_msa_ave_u_w(cpu_env
, twd
, tws
, twt
);
29084 gen_helper_msa_ave_u_d(cpu_env
, twd
, tws
, twt
);
29088 case OPC_AVER_S_df
:
29091 gen_helper_msa_aver_s_b(cpu_env
, twd
, tws
, twt
);
29094 gen_helper_msa_aver_s_h(cpu_env
, twd
, tws
, twt
);
29097 gen_helper_msa_aver_s_w(cpu_env
, twd
, tws
, twt
);
29100 gen_helper_msa_aver_s_d(cpu_env
, twd
, tws
, twt
);
29104 case OPC_AVER_U_df
:
29107 gen_helper_msa_aver_u_b(cpu_env
, twd
, tws
, twt
);
29110 gen_helper_msa_aver_u_h(cpu_env
, twd
, tws
, twt
);
29113 gen_helper_msa_aver_u_w(cpu_env
, twd
, tws
, twt
);
29116 gen_helper_msa_aver_u_d(cpu_env
, twd
, tws
, twt
);
29123 gen_helper_msa_ceq_b(cpu_env
, twd
, tws
, twt
);
29126 gen_helper_msa_ceq_h(cpu_env
, twd
, tws
, twt
);
29129 gen_helper_msa_ceq_w(cpu_env
, twd
, tws
, twt
);
29132 gen_helper_msa_ceq_d(cpu_env
, twd
, tws
, twt
);
29139 gen_helper_msa_cle_s_b(cpu_env
, twd
, tws
, twt
);
29142 gen_helper_msa_cle_s_h(cpu_env
, twd
, tws
, twt
);
29145 gen_helper_msa_cle_s_w(cpu_env
, twd
, tws
, twt
);
29148 gen_helper_msa_cle_s_d(cpu_env
, twd
, tws
, twt
);
29155 gen_helper_msa_cle_u_b(cpu_env
, twd
, tws
, twt
);
29158 gen_helper_msa_cle_u_h(cpu_env
, twd
, tws
, twt
);
29161 gen_helper_msa_cle_u_w(cpu_env
, twd
, tws
, twt
);
29164 gen_helper_msa_cle_u_d(cpu_env
, twd
, tws
, twt
);
29171 gen_helper_msa_clt_s_b(cpu_env
, twd
, tws
, twt
);
29174 gen_helper_msa_clt_s_h(cpu_env
, twd
, tws
, twt
);
29177 gen_helper_msa_clt_s_w(cpu_env
, twd
, tws
, twt
);
29180 gen_helper_msa_clt_s_d(cpu_env
, twd
, tws
, twt
);
29187 gen_helper_msa_clt_u_b(cpu_env
, twd
, tws
, twt
);
29190 gen_helper_msa_clt_u_h(cpu_env
, twd
, tws
, twt
);
29193 gen_helper_msa_clt_u_w(cpu_env
, twd
, tws
, twt
);
29196 gen_helper_msa_clt_u_d(cpu_env
, twd
, tws
, twt
);
29203 gen_helper_msa_div_s_b(cpu_env
, twd
, tws
, twt
);
29206 gen_helper_msa_div_s_h(cpu_env
, twd
, tws
, twt
);
29209 gen_helper_msa_div_s_w(cpu_env
, twd
, tws
, twt
);
29212 gen_helper_msa_div_s_d(cpu_env
, twd
, tws
, twt
);
29219 gen_helper_msa_div_u_b(cpu_env
, twd
, tws
, twt
);
29222 gen_helper_msa_div_u_h(cpu_env
, twd
, tws
, twt
);
29225 gen_helper_msa_div_u_w(cpu_env
, twd
, tws
, twt
);
29228 gen_helper_msa_div_u_d(cpu_env
, twd
, tws
, twt
);
29235 gen_helper_msa_max_a_b(cpu_env
, twd
, tws
, twt
);
29238 gen_helper_msa_max_a_h(cpu_env
, twd
, tws
, twt
);
29241 gen_helper_msa_max_a_w(cpu_env
, twd
, tws
, twt
);
29244 gen_helper_msa_max_a_d(cpu_env
, twd
, tws
, twt
);
29251 gen_helper_msa_max_s_b(cpu_env
, twd
, tws
, twt
);
29254 gen_helper_msa_max_s_h(cpu_env
, twd
, tws
, twt
);
29257 gen_helper_msa_max_s_w(cpu_env
, twd
, tws
, twt
);
29260 gen_helper_msa_max_s_d(cpu_env
, twd
, tws
, twt
);
29267 gen_helper_msa_max_u_b(cpu_env
, twd
, tws
, twt
);
29270 gen_helper_msa_max_u_h(cpu_env
, twd
, tws
, twt
);
29273 gen_helper_msa_max_u_w(cpu_env
, twd
, tws
, twt
);
29276 gen_helper_msa_max_u_d(cpu_env
, twd
, tws
, twt
);
29283 gen_helper_msa_min_a_b(cpu_env
, twd
, tws
, twt
);
29286 gen_helper_msa_min_a_h(cpu_env
, twd
, tws
, twt
);
29289 gen_helper_msa_min_a_w(cpu_env
, twd
, tws
, twt
);
29292 gen_helper_msa_min_a_d(cpu_env
, twd
, tws
, twt
);
29299 gen_helper_msa_min_s_b(cpu_env
, twd
, tws
, twt
);
29302 gen_helper_msa_min_s_h(cpu_env
, twd
, tws
, twt
);
29305 gen_helper_msa_min_s_w(cpu_env
, twd
, tws
, twt
);
29308 gen_helper_msa_min_s_d(cpu_env
, twd
, tws
, twt
);
29315 gen_helper_msa_min_u_b(cpu_env
, twd
, tws
, twt
);
29318 gen_helper_msa_min_u_h(cpu_env
, twd
, tws
, twt
);
29321 gen_helper_msa_min_u_w(cpu_env
, twd
, tws
, twt
);
29324 gen_helper_msa_min_u_d(cpu_env
, twd
, tws
, twt
);
29331 gen_helper_msa_mod_s_b(cpu_env
, twd
, tws
, twt
);
29334 gen_helper_msa_mod_s_h(cpu_env
, twd
, tws
, twt
);
29337 gen_helper_msa_mod_s_w(cpu_env
, twd
, tws
, twt
);
29340 gen_helper_msa_mod_s_d(cpu_env
, twd
, tws
, twt
);
29347 gen_helper_msa_mod_u_b(cpu_env
, twd
, tws
, twt
);
29350 gen_helper_msa_mod_u_h(cpu_env
, twd
, tws
, twt
);
29353 gen_helper_msa_mod_u_w(cpu_env
, twd
, tws
, twt
);
29356 gen_helper_msa_mod_u_d(cpu_env
, twd
, tws
, twt
);
29363 gen_helper_msa_maddv_b(cpu_env
, twd
, tws
, twt
);
29366 gen_helper_msa_maddv_h(cpu_env
, twd
, tws
, twt
);
29369 gen_helper_msa_maddv_w(cpu_env
, twd
, tws
, twt
);
29372 gen_helper_msa_maddv_d(cpu_env
, twd
, tws
, twt
);
29379 gen_helper_msa_msubv_b(cpu_env
, twd
, tws
, twt
);
29382 gen_helper_msa_msubv_h(cpu_env
, twd
, tws
, twt
);
29385 gen_helper_msa_msubv_w(cpu_env
, twd
, tws
, twt
);
29388 gen_helper_msa_msubv_d(cpu_env
, twd
, tws
, twt
);
29392 case OPC_ASUB_S_df
:
29395 gen_helper_msa_asub_s_b(cpu_env
, twd
, tws
, twt
);
29398 gen_helper_msa_asub_s_h(cpu_env
, twd
, tws
, twt
);
29401 gen_helper_msa_asub_s_w(cpu_env
, twd
, tws
, twt
);
29404 gen_helper_msa_asub_s_d(cpu_env
, twd
, tws
, twt
);
29408 case OPC_ASUB_U_df
:
29411 gen_helper_msa_asub_u_b(cpu_env
, twd
, tws
, twt
);
29414 gen_helper_msa_asub_u_h(cpu_env
, twd
, tws
, twt
);
29417 gen_helper_msa_asub_u_w(cpu_env
, twd
, tws
, twt
);
29420 gen_helper_msa_asub_u_d(cpu_env
, twd
, tws
, twt
);
29427 gen_helper_msa_ilvev_b(cpu_env
, twd
, tws
, twt
);
29430 gen_helper_msa_ilvev_h(cpu_env
, twd
, tws
, twt
);
29433 gen_helper_msa_ilvev_w(cpu_env
, twd
, tws
, twt
);
29436 gen_helper_msa_ilvev_d(cpu_env
, twd
, tws
, twt
);
29443 gen_helper_msa_ilvod_b(cpu_env
, twd
, tws
, twt
);
29446 gen_helper_msa_ilvod_h(cpu_env
, twd
, tws
, twt
);
29449 gen_helper_msa_ilvod_w(cpu_env
, twd
, tws
, twt
);
29452 gen_helper_msa_ilvod_d(cpu_env
, twd
, tws
, twt
);
29459 gen_helper_msa_ilvl_b(cpu_env
, twd
, tws
, twt
);
29462 gen_helper_msa_ilvl_h(cpu_env
, twd
, tws
, twt
);
29465 gen_helper_msa_ilvl_w(cpu_env
, twd
, tws
, twt
);
29468 gen_helper_msa_ilvl_d(cpu_env
, twd
, tws
, twt
);
29475 gen_helper_msa_ilvr_b(cpu_env
, twd
, tws
, twt
);
29478 gen_helper_msa_ilvr_h(cpu_env
, twd
, tws
, twt
);
29481 gen_helper_msa_ilvr_w(cpu_env
, twd
, tws
, twt
);
29484 gen_helper_msa_ilvr_d(cpu_env
, twd
, tws
, twt
);
29491 gen_helper_msa_pckev_b(cpu_env
, twd
, tws
, twt
);
29494 gen_helper_msa_pckev_h(cpu_env
, twd
, tws
, twt
);
29497 gen_helper_msa_pckev_w(cpu_env
, twd
, tws
, twt
);
29500 gen_helper_msa_pckev_d(cpu_env
, twd
, tws
, twt
);
29507 gen_helper_msa_pckod_b(cpu_env
, twd
, tws
, twt
);
29510 gen_helper_msa_pckod_h(cpu_env
, twd
, tws
, twt
);
29513 gen_helper_msa_pckod_w(cpu_env
, twd
, tws
, twt
);
29516 gen_helper_msa_pckod_d(cpu_env
, twd
, tws
, twt
);
29523 gen_helper_msa_sll_b(cpu_env
, twd
, tws
, twt
);
29526 gen_helper_msa_sll_h(cpu_env
, twd
, tws
, twt
);
29529 gen_helper_msa_sll_w(cpu_env
, twd
, tws
, twt
);
29532 gen_helper_msa_sll_d(cpu_env
, twd
, tws
, twt
);
29539 gen_helper_msa_sra_b(cpu_env
, twd
, tws
, twt
);
29542 gen_helper_msa_sra_h(cpu_env
, twd
, tws
, twt
);
29545 gen_helper_msa_sra_w(cpu_env
, twd
, tws
, twt
);
29548 gen_helper_msa_sra_d(cpu_env
, twd
, tws
, twt
);
29555 gen_helper_msa_srar_b(cpu_env
, twd
, tws
, twt
);
29558 gen_helper_msa_srar_h(cpu_env
, twd
, tws
, twt
);
29561 gen_helper_msa_srar_w(cpu_env
, twd
, tws
, twt
);
29564 gen_helper_msa_srar_d(cpu_env
, twd
, tws
, twt
);
29571 gen_helper_msa_srl_b(cpu_env
, twd
, tws
, twt
);
29574 gen_helper_msa_srl_h(cpu_env
, twd
, tws
, twt
);
29577 gen_helper_msa_srl_w(cpu_env
, twd
, tws
, twt
);
29580 gen_helper_msa_srl_d(cpu_env
, twd
, tws
, twt
);
29587 gen_helper_msa_srlr_b(cpu_env
, twd
, tws
, twt
);
29590 gen_helper_msa_srlr_h(cpu_env
, twd
, tws
, twt
);
29593 gen_helper_msa_srlr_w(cpu_env
, twd
, tws
, twt
);
29596 gen_helper_msa_srlr_d(cpu_env
, twd
, tws
, twt
);
29600 case OPC_SUBS_S_df
:
29603 gen_helper_msa_subs_s_b(cpu_env
, twd
, tws
, twt
);
29606 gen_helper_msa_subs_s_h(cpu_env
, twd
, tws
, twt
);
29609 gen_helper_msa_subs_s_w(cpu_env
, twd
, tws
, twt
);
29612 gen_helper_msa_subs_s_d(cpu_env
, twd
, tws
, twt
);
29619 gen_helper_msa_mulv_b(cpu_env
, twd
, tws
, twt
);
29622 gen_helper_msa_mulv_h(cpu_env
, twd
, tws
, twt
);
29625 gen_helper_msa_mulv_w(cpu_env
, twd
, tws
, twt
);
29628 gen_helper_msa_mulv_d(cpu_env
, twd
, tws
, twt
);
29633 gen_helper_msa_sld_df(cpu_env
, tdf
, twd
, tws
, twt
);
29636 gen_helper_msa_vshf_df(cpu_env
, tdf
, twd
, tws
, twt
);
29641 gen_helper_msa_subv_b(cpu_env
, twd
, tws
, twt
);
29644 gen_helper_msa_subv_h(cpu_env
, twd
, tws
, twt
);
29647 gen_helper_msa_subv_w(cpu_env
, twd
, tws
, twt
);
29650 gen_helper_msa_subv_d(cpu_env
, twd
, tws
, twt
);
29654 case OPC_SUBS_U_df
:
29657 gen_helper_msa_subs_u_b(cpu_env
, twd
, tws
, twt
);
29660 gen_helper_msa_subs_u_h(cpu_env
, twd
, tws
, twt
);
29663 gen_helper_msa_subs_u_w(cpu_env
, twd
, tws
, twt
);
29666 gen_helper_msa_subs_u_d(cpu_env
, twd
, tws
, twt
);
29671 gen_helper_msa_splat_df(cpu_env
, tdf
, twd
, tws
, twt
);
29673 case OPC_SUBSUS_U_df
:
29676 gen_helper_msa_subsus_u_b(cpu_env
, twd
, tws
, twt
);
29679 gen_helper_msa_subsus_u_h(cpu_env
, twd
, tws
, twt
);
29682 gen_helper_msa_subsus_u_w(cpu_env
, twd
, tws
, twt
);
29685 gen_helper_msa_subsus_u_d(cpu_env
, twd
, tws
, twt
);
29689 case OPC_SUBSUU_S_df
:
29692 gen_helper_msa_subsuu_s_b(cpu_env
, twd
, tws
, twt
);
29695 gen_helper_msa_subsuu_s_h(cpu_env
, twd
, tws
, twt
);
29698 gen_helper_msa_subsuu_s_w(cpu_env
, twd
, tws
, twt
);
29701 gen_helper_msa_subsuu_s_d(cpu_env
, twd
, tws
, twt
);
29706 case OPC_DOTP_S_df
:
29707 case OPC_DOTP_U_df
:
29708 case OPC_DPADD_S_df
:
29709 case OPC_DPADD_U_df
:
29710 case OPC_DPSUB_S_df
:
29711 case OPC_HADD_S_df
:
29712 case OPC_DPSUB_U_df
:
29713 case OPC_HADD_U_df
:
29714 case OPC_HSUB_S_df
:
29715 case OPC_HSUB_U_df
:
29716 if (df
== DF_BYTE
) {
29717 gen_reserved_instruction(ctx
);
29720 switch (MASK_MSA_3R(ctx
->opcode
)) {
29721 case OPC_HADD_S_df
:
29724 gen_helper_msa_hadd_s_h(cpu_env
, twd
, tws
, twt
);
29727 gen_helper_msa_hadd_s_w(cpu_env
, twd
, tws
, twt
);
29730 gen_helper_msa_hadd_s_d(cpu_env
, twd
, tws
, twt
);
29734 case OPC_HADD_U_df
:
29737 gen_helper_msa_hadd_u_h(cpu_env
, twd
, tws
, twt
);
29740 gen_helper_msa_hadd_u_w(cpu_env
, twd
, tws
, twt
);
29743 gen_helper_msa_hadd_u_d(cpu_env
, twd
, tws
, twt
);
29747 case OPC_HSUB_S_df
:
29750 gen_helper_msa_hsub_s_h(cpu_env
, twd
, tws
, twt
);
29753 gen_helper_msa_hsub_s_w(cpu_env
, twd
, tws
, twt
);
29756 gen_helper_msa_hsub_s_d(cpu_env
, twd
, tws
, twt
);
29760 case OPC_HSUB_U_df
:
29763 gen_helper_msa_hsub_u_h(cpu_env
, twd
, tws
, twt
);
29766 gen_helper_msa_hsub_u_w(cpu_env
, twd
, tws
, twt
);
29769 gen_helper_msa_hsub_u_d(cpu_env
, twd
, tws
, twt
);
29773 case OPC_DOTP_S_df
:
29776 gen_helper_msa_dotp_s_h(cpu_env
, twd
, tws
, twt
);
29779 gen_helper_msa_dotp_s_w(cpu_env
, twd
, tws
, twt
);
29782 gen_helper_msa_dotp_s_d(cpu_env
, twd
, tws
, twt
);
29786 case OPC_DOTP_U_df
:
29789 gen_helper_msa_dotp_u_h(cpu_env
, twd
, tws
, twt
);
29792 gen_helper_msa_dotp_u_w(cpu_env
, twd
, tws
, twt
);
29795 gen_helper_msa_dotp_u_d(cpu_env
, twd
, tws
, twt
);
29799 case OPC_DPADD_S_df
:
29802 gen_helper_msa_dpadd_s_h(cpu_env
, twd
, tws
, twt
);
29805 gen_helper_msa_dpadd_s_w(cpu_env
, twd
, tws
, twt
);
29808 gen_helper_msa_dpadd_s_d(cpu_env
, twd
, tws
, twt
);
29812 case OPC_DPADD_U_df
:
29815 gen_helper_msa_dpadd_u_h(cpu_env
, twd
, tws
, twt
);
29818 gen_helper_msa_dpadd_u_w(cpu_env
, twd
, tws
, twt
);
29821 gen_helper_msa_dpadd_u_d(cpu_env
, twd
, tws
, twt
);
29825 case OPC_DPSUB_S_df
:
29828 gen_helper_msa_dpsub_s_h(cpu_env
, twd
, tws
, twt
);
29831 gen_helper_msa_dpsub_s_w(cpu_env
, twd
, tws
, twt
);
29834 gen_helper_msa_dpsub_s_d(cpu_env
, twd
, tws
, twt
);
29838 case OPC_DPSUB_U_df
:
29841 gen_helper_msa_dpsub_u_h(cpu_env
, twd
, tws
, twt
);
29844 gen_helper_msa_dpsub_u_w(cpu_env
, twd
, tws
, twt
);
29847 gen_helper_msa_dpsub_u_d(cpu_env
, twd
, tws
, twt
);
29854 MIPS_INVAL("MSA instruction");
29855 gen_reserved_instruction(ctx
);
29858 tcg_temp_free_i32(twd
);
29859 tcg_temp_free_i32(tws
);
29860 tcg_temp_free_i32(twt
);
29861 tcg_temp_free_i32(tdf
);
29864 static void gen_msa_elm_3e(CPUMIPSState
*env
, DisasContext
*ctx
)
29866 #define MASK_MSA_ELM_DF3E(op) (MASK_MSA_MINOR(op) | (op & (0x3FF << 16)))
29867 uint8_t source
= (ctx
->opcode
>> 11) & 0x1f;
29868 uint8_t dest
= (ctx
->opcode
>> 6) & 0x1f;
29869 TCGv telm
= tcg_temp_new();
29870 TCGv_i32 tsr
= tcg_const_i32(source
);
29871 TCGv_i32 tdt
= tcg_const_i32(dest
);
29873 switch (MASK_MSA_ELM_DF3E(ctx
->opcode
)) {
29875 gen_load_gpr(telm
, source
);
29876 gen_helper_msa_ctcmsa(cpu_env
, telm
, tdt
);
29879 gen_helper_msa_cfcmsa(telm
, cpu_env
, tsr
);
29880 gen_store_gpr(telm
, dest
);
29883 gen_helper_msa_move_v(cpu_env
, tdt
, tsr
);
29886 MIPS_INVAL("MSA instruction");
29887 gen_reserved_instruction(ctx
);
29891 tcg_temp_free(telm
);
29892 tcg_temp_free_i32(tdt
);
29893 tcg_temp_free_i32(tsr
);
29896 static void gen_msa_elm_df(CPUMIPSState
*env
, DisasContext
*ctx
, uint32_t df
,
29899 #define MASK_MSA_ELM(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
29900 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
29901 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
29903 TCGv_i32 tws
= tcg_const_i32(ws
);
29904 TCGv_i32 twd
= tcg_const_i32(wd
);
29905 TCGv_i32 tn
= tcg_const_i32(n
);
29906 TCGv_i32 tdf
= tcg_const_i32(df
);
29908 switch (MASK_MSA_ELM(ctx
->opcode
)) {
29910 gen_helper_msa_sldi_df(cpu_env
, tdf
, twd
, tws
, tn
);
29912 case OPC_SPLATI_df
:
29913 gen_helper_msa_splati_df(cpu_env
, tdf
, twd
, tws
, tn
);
29916 gen_helper_msa_insve_df(cpu_env
, tdf
, twd
, tws
, tn
);
29918 case OPC_COPY_S_df
:
29919 case OPC_COPY_U_df
:
29920 case OPC_INSERT_df
:
29921 #if !defined(TARGET_MIPS64)
29922 /* Double format valid only for MIPS64 */
29923 if (df
== DF_DOUBLE
) {
29924 gen_reserved_instruction(ctx
);
29927 if ((MASK_MSA_ELM(ctx
->opcode
) == OPC_COPY_U_df
) &&
29929 gen_reserved_instruction(ctx
);
29933 switch (MASK_MSA_ELM(ctx
->opcode
)) {
29934 case OPC_COPY_S_df
:
29935 if (likely(wd
!= 0)) {
29938 gen_helper_msa_copy_s_b(cpu_env
, twd
, tws
, tn
);
29941 gen_helper_msa_copy_s_h(cpu_env
, twd
, tws
, tn
);
29944 gen_helper_msa_copy_s_w(cpu_env
, twd
, tws
, tn
);
29946 #if defined(TARGET_MIPS64)
29948 gen_helper_msa_copy_s_d(cpu_env
, twd
, tws
, tn
);
29956 case OPC_COPY_U_df
:
29957 if (likely(wd
!= 0)) {
29960 gen_helper_msa_copy_u_b(cpu_env
, twd
, tws
, tn
);
29963 gen_helper_msa_copy_u_h(cpu_env
, twd
, tws
, tn
);
29965 #if defined(TARGET_MIPS64)
29967 gen_helper_msa_copy_u_w(cpu_env
, twd
, tws
, tn
);
29975 case OPC_INSERT_df
:
29978 gen_helper_msa_insert_b(cpu_env
, twd
, tws
, tn
);
29981 gen_helper_msa_insert_h(cpu_env
, twd
, tws
, tn
);
29984 gen_helper_msa_insert_w(cpu_env
, twd
, tws
, tn
);
29986 #if defined(TARGET_MIPS64)
29988 gen_helper_msa_insert_d(cpu_env
, twd
, tws
, tn
);
29998 MIPS_INVAL("MSA instruction");
29999 gen_reserved_instruction(ctx
);
30001 tcg_temp_free_i32(twd
);
30002 tcg_temp_free_i32(tws
);
30003 tcg_temp_free_i32(tn
);
30004 tcg_temp_free_i32(tdf
);
30007 static void gen_msa_elm(CPUMIPSState
*env
, DisasContext
*ctx
)
30009 uint8_t dfn
= (ctx
->opcode
>> 16) & 0x3f;
30010 uint32_t df
= 0, n
= 0;
30012 if ((dfn
& 0x30) == 0x00) {
30015 } else if ((dfn
& 0x38) == 0x20) {
30018 } else if ((dfn
& 0x3c) == 0x30) {
30021 } else if ((dfn
& 0x3e) == 0x38) {
30024 } else if (dfn
== 0x3E) {
30025 /* CTCMSA, CFCMSA, MOVE.V */
30026 gen_msa_elm_3e(env
, ctx
);
30029 gen_reserved_instruction(ctx
);
30033 gen_msa_elm_df(env
, ctx
, df
, n
);
30036 static void gen_msa_3rf(CPUMIPSState
*env
, DisasContext
*ctx
)
30038 #define MASK_MSA_3RF(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
30039 uint8_t df
= (ctx
->opcode
>> 21) & 0x1;
30040 uint8_t wt
= (ctx
->opcode
>> 16) & 0x1f;
30041 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
30042 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
30044 TCGv_i32 twd
= tcg_const_i32(wd
);
30045 TCGv_i32 tws
= tcg_const_i32(ws
);
30046 TCGv_i32 twt
= tcg_const_i32(wt
);
30047 TCGv_i32 tdf
= tcg_temp_new_i32();
30049 /* adjust df value for floating-point instruction */
30050 tcg_gen_movi_i32(tdf
, df
+ 2);
30052 switch (MASK_MSA_3RF(ctx
->opcode
)) {
30054 gen_helper_msa_fcaf_df(cpu_env
, tdf
, twd
, tws
, twt
);
30057 gen_helper_msa_fadd_df(cpu_env
, tdf
, twd
, tws
, twt
);
30060 gen_helper_msa_fcun_df(cpu_env
, tdf
, twd
, tws
, twt
);
30063 gen_helper_msa_fsub_df(cpu_env
, tdf
, twd
, tws
, twt
);
30066 gen_helper_msa_fcor_df(cpu_env
, tdf
, twd
, tws
, twt
);
30069 gen_helper_msa_fceq_df(cpu_env
, tdf
, twd
, tws
, twt
);
30072 gen_helper_msa_fmul_df(cpu_env
, tdf
, twd
, tws
, twt
);
30075 gen_helper_msa_fcune_df(cpu_env
, tdf
, twd
, tws
, twt
);
30078 gen_helper_msa_fcueq_df(cpu_env
, tdf
, twd
, tws
, twt
);
30081 gen_helper_msa_fdiv_df(cpu_env
, tdf
, twd
, tws
, twt
);
30084 gen_helper_msa_fcne_df(cpu_env
, tdf
, twd
, tws
, twt
);
30087 gen_helper_msa_fclt_df(cpu_env
, tdf
, twd
, tws
, twt
);
30090 gen_helper_msa_fmadd_df(cpu_env
, tdf
, twd
, tws
, twt
);
30093 tcg_gen_movi_i32(tdf
, df
+ 1);
30094 gen_helper_msa_mul_q_df(cpu_env
, tdf
, twd
, tws
, twt
);
30097 gen_helper_msa_fcult_df(cpu_env
, tdf
, twd
, tws
, twt
);
30100 gen_helper_msa_fmsub_df(cpu_env
, tdf
, twd
, tws
, twt
);
30102 case OPC_MADD_Q_df
:
30103 tcg_gen_movi_i32(tdf
, df
+ 1);
30104 gen_helper_msa_madd_q_df(cpu_env
, tdf
, twd
, tws
, twt
);
30107 gen_helper_msa_fcle_df(cpu_env
, tdf
, twd
, tws
, twt
);
30109 case OPC_MSUB_Q_df
:
30110 tcg_gen_movi_i32(tdf
, df
+ 1);
30111 gen_helper_msa_msub_q_df(cpu_env
, tdf
, twd
, tws
, twt
);
30114 gen_helper_msa_fcule_df(cpu_env
, tdf
, twd
, tws
, twt
);
30117 gen_helper_msa_fexp2_df(cpu_env
, tdf
, twd
, tws
, twt
);
30120 gen_helper_msa_fsaf_df(cpu_env
, tdf
, twd
, tws
, twt
);
30123 gen_helper_msa_fexdo_df(cpu_env
, tdf
, twd
, tws
, twt
);
30126 gen_helper_msa_fsun_df(cpu_env
, tdf
, twd
, tws
, twt
);
30129 gen_helper_msa_fsor_df(cpu_env
, tdf
, twd
, tws
, twt
);
30132 gen_helper_msa_fseq_df(cpu_env
, tdf
, twd
, tws
, twt
);
30135 gen_helper_msa_ftq_df(cpu_env
, tdf
, twd
, tws
, twt
);
30138 gen_helper_msa_fsune_df(cpu_env
, tdf
, twd
, tws
, twt
);
30141 gen_helper_msa_fsueq_df(cpu_env
, tdf
, twd
, tws
, twt
);
30144 gen_helper_msa_fsne_df(cpu_env
, tdf
, twd
, tws
, twt
);
30147 gen_helper_msa_fslt_df(cpu_env
, tdf
, twd
, tws
, twt
);
30150 gen_helper_msa_fmin_df(cpu_env
, tdf
, twd
, tws
, twt
);
30152 case OPC_MULR_Q_df
:
30153 tcg_gen_movi_i32(tdf
, df
+ 1);
30154 gen_helper_msa_mulr_q_df(cpu_env
, tdf
, twd
, tws
, twt
);
30157 gen_helper_msa_fsult_df(cpu_env
, tdf
, twd
, tws
, twt
);
30159 case OPC_FMIN_A_df
:
30160 gen_helper_msa_fmin_a_df(cpu_env
, tdf
, twd
, tws
, twt
);
30162 case OPC_MADDR_Q_df
:
30163 tcg_gen_movi_i32(tdf
, df
+ 1);
30164 gen_helper_msa_maddr_q_df(cpu_env
, tdf
, twd
, tws
, twt
);
30167 gen_helper_msa_fsle_df(cpu_env
, tdf
, twd
, tws
, twt
);
30170 gen_helper_msa_fmax_df(cpu_env
, tdf
, twd
, tws
, twt
);
30172 case OPC_MSUBR_Q_df
:
30173 tcg_gen_movi_i32(tdf
, df
+ 1);
30174 gen_helper_msa_msubr_q_df(cpu_env
, tdf
, twd
, tws
, twt
);
30177 gen_helper_msa_fsule_df(cpu_env
, tdf
, twd
, tws
, twt
);
30179 case OPC_FMAX_A_df
:
30180 gen_helper_msa_fmax_a_df(cpu_env
, tdf
, twd
, tws
, twt
);
30183 MIPS_INVAL("MSA instruction");
30184 gen_reserved_instruction(ctx
);
30188 tcg_temp_free_i32(twd
);
30189 tcg_temp_free_i32(tws
);
30190 tcg_temp_free_i32(twt
);
30191 tcg_temp_free_i32(tdf
);
30194 static void gen_msa_2r(CPUMIPSState
*env
, DisasContext
*ctx
)
30196 #define MASK_MSA_2R(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
30197 (op & (0x7 << 18)))
30198 uint8_t wt
= (ctx
->opcode
>> 16) & 0x1f;
30199 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
30200 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
30201 uint8_t df
= (ctx
->opcode
>> 16) & 0x3;
30202 TCGv_i32 twd
= tcg_const_i32(wd
);
30203 TCGv_i32 tws
= tcg_const_i32(ws
);
30204 TCGv_i32 twt
= tcg_const_i32(wt
);
30205 TCGv_i32 tdf
= tcg_const_i32(df
);
30207 switch (MASK_MSA_2R(ctx
->opcode
)) {
30209 #if !defined(TARGET_MIPS64)
30210 /* Double format valid only for MIPS64 */
30211 if (df
== DF_DOUBLE
) {
30212 gen_reserved_instruction(ctx
);
30216 gen_helper_msa_fill_df(cpu_env
, tdf
, twd
, tws
); /* trs */
30221 gen_helper_msa_nloc_b(cpu_env
, twd
, tws
);
30224 gen_helper_msa_nloc_h(cpu_env
, twd
, tws
);
30227 gen_helper_msa_nloc_w(cpu_env
, twd
, tws
);
30230 gen_helper_msa_nloc_d(cpu_env
, twd
, tws
);
30237 gen_helper_msa_nlzc_b(cpu_env
, twd
, tws
);
30240 gen_helper_msa_nlzc_h(cpu_env
, twd
, tws
);
30243 gen_helper_msa_nlzc_w(cpu_env
, twd
, tws
);
30246 gen_helper_msa_nlzc_d(cpu_env
, twd
, tws
);
30253 gen_helper_msa_pcnt_b(cpu_env
, twd
, tws
);
30256 gen_helper_msa_pcnt_h(cpu_env
, twd
, tws
);
30259 gen_helper_msa_pcnt_w(cpu_env
, twd
, tws
);
30262 gen_helper_msa_pcnt_d(cpu_env
, twd
, tws
);
30267 MIPS_INVAL("MSA instruction");
30268 gen_reserved_instruction(ctx
);
30272 tcg_temp_free_i32(twd
);
30273 tcg_temp_free_i32(tws
);
30274 tcg_temp_free_i32(twt
);
30275 tcg_temp_free_i32(tdf
);
30278 static void gen_msa_2rf(CPUMIPSState
*env
, DisasContext
*ctx
)
30280 #define MASK_MSA_2RF(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
30281 (op & (0xf << 17)))
30282 uint8_t wt
= (ctx
->opcode
>> 16) & 0x1f;
30283 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
30284 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
30285 uint8_t df
= (ctx
->opcode
>> 16) & 0x1;
30286 TCGv_i32 twd
= tcg_const_i32(wd
);
30287 TCGv_i32 tws
= tcg_const_i32(ws
);
30288 TCGv_i32 twt
= tcg_const_i32(wt
);
30289 /* adjust df value for floating-point instruction */
30290 TCGv_i32 tdf
= tcg_const_i32(df
+ 2);
30292 switch (MASK_MSA_2RF(ctx
->opcode
)) {
30293 case OPC_FCLASS_df
:
30294 gen_helper_msa_fclass_df(cpu_env
, tdf
, twd
, tws
);
30296 case OPC_FTRUNC_S_df
:
30297 gen_helper_msa_ftrunc_s_df(cpu_env
, tdf
, twd
, tws
);
30299 case OPC_FTRUNC_U_df
:
30300 gen_helper_msa_ftrunc_u_df(cpu_env
, tdf
, twd
, tws
);
30303 gen_helper_msa_fsqrt_df(cpu_env
, tdf
, twd
, tws
);
30305 case OPC_FRSQRT_df
:
30306 gen_helper_msa_frsqrt_df(cpu_env
, tdf
, twd
, tws
);
30309 gen_helper_msa_frcp_df(cpu_env
, tdf
, twd
, tws
);
30312 gen_helper_msa_frint_df(cpu_env
, tdf
, twd
, tws
);
30315 gen_helper_msa_flog2_df(cpu_env
, tdf
, twd
, tws
);
30317 case OPC_FEXUPL_df
:
30318 gen_helper_msa_fexupl_df(cpu_env
, tdf
, twd
, tws
);
30320 case OPC_FEXUPR_df
:
30321 gen_helper_msa_fexupr_df(cpu_env
, tdf
, twd
, tws
);
30324 gen_helper_msa_ffql_df(cpu_env
, tdf
, twd
, tws
);
30327 gen_helper_msa_ffqr_df(cpu_env
, tdf
, twd
, tws
);
30329 case OPC_FTINT_S_df
:
30330 gen_helper_msa_ftint_s_df(cpu_env
, tdf
, twd
, tws
);
30332 case OPC_FTINT_U_df
:
30333 gen_helper_msa_ftint_u_df(cpu_env
, tdf
, twd
, tws
);
30335 case OPC_FFINT_S_df
:
30336 gen_helper_msa_ffint_s_df(cpu_env
, tdf
, twd
, tws
);
30338 case OPC_FFINT_U_df
:
30339 gen_helper_msa_ffint_u_df(cpu_env
, tdf
, twd
, tws
);
30343 tcg_temp_free_i32(twd
);
30344 tcg_temp_free_i32(tws
);
30345 tcg_temp_free_i32(twt
);
30346 tcg_temp_free_i32(tdf
);
30349 static void gen_msa_vec_v(CPUMIPSState
*env
, DisasContext
*ctx
)
30351 #define MASK_MSA_VEC(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)))
30352 uint8_t wt
= (ctx
->opcode
>> 16) & 0x1f;
30353 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
30354 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
30355 TCGv_i32 twd
= tcg_const_i32(wd
);
30356 TCGv_i32 tws
= tcg_const_i32(ws
);
30357 TCGv_i32 twt
= tcg_const_i32(wt
);
30359 switch (MASK_MSA_VEC(ctx
->opcode
)) {
30361 gen_helper_msa_and_v(cpu_env
, twd
, tws
, twt
);
30364 gen_helper_msa_or_v(cpu_env
, twd
, tws
, twt
);
30367 gen_helper_msa_nor_v(cpu_env
, twd
, tws
, twt
);
30370 gen_helper_msa_xor_v(cpu_env
, twd
, tws
, twt
);
30373 gen_helper_msa_bmnz_v(cpu_env
, twd
, tws
, twt
);
30376 gen_helper_msa_bmz_v(cpu_env
, twd
, tws
, twt
);
30379 gen_helper_msa_bsel_v(cpu_env
, twd
, tws
, twt
);
30382 MIPS_INVAL("MSA instruction");
30383 gen_reserved_instruction(ctx
);
30387 tcg_temp_free_i32(twd
);
30388 tcg_temp_free_i32(tws
);
30389 tcg_temp_free_i32(twt
);
30392 static void gen_msa_vec(CPUMIPSState
*env
, DisasContext
*ctx
)
30394 switch (MASK_MSA_VEC(ctx
->opcode
)) {
30402 gen_msa_vec_v(env
, ctx
);
30405 gen_msa_2r(env
, ctx
);
30408 gen_msa_2rf(env
, ctx
);
30411 MIPS_INVAL("MSA instruction");
30412 gen_reserved_instruction(ctx
);
30417 static void gen_msa(CPUMIPSState
*env
, DisasContext
*ctx
)
30419 uint32_t opcode
= ctx
->opcode
;
30420 check_insn(ctx
, ASE_MSA
);
30421 check_msa_access(ctx
);
30423 switch (MASK_MSA_MINOR(opcode
)) {
30424 case OPC_MSA_I8_00
:
30425 case OPC_MSA_I8_01
:
30426 case OPC_MSA_I8_02
:
30427 gen_msa_i8(env
, ctx
);
30429 case OPC_MSA_I5_06
:
30430 case OPC_MSA_I5_07
:
30431 gen_msa_i5(env
, ctx
);
30433 case OPC_MSA_BIT_09
:
30434 case OPC_MSA_BIT_0A
:
30435 gen_msa_bit(env
, ctx
);
30437 case OPC_MSA_3R_0D
:
30438 case OPC_MSA_3R_0E
:
30439 case OPC_MSA_3R_0F
:
30440 case OPC_MSA_3R_10
:
30441 case OPC_MSA_3R_11
:
30442 case OPC_MSA_3R_12
:
30443 case OPC_MSA_3R_13
:
30444 case OPC_MSA_3R_14
:
30445 case OPC_MSA_3R_15
:
30446 gen_msa_3r(env
, ctx
);
30449 gen_msa_elm(env
, ctx
);
30451 case OPC_MSA_3RF_1A
:
30452 case OPC_MSA_3RF_1B
:
30453 case OPC_MSA_3RF_1C
:
30454 gen_msa_3rf(env
, ctx
);
30457 gen_msa_vec(env
, ctx
);
30468 int32_t s10
= sextract32(ctx
->opcode
, 16, 10);
30469 uint8_t rs
= (ctx
->opcode
>> 11) & 0x1f;
30470 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
30471 uint8_t df
= (ctx
->opcode
>> 0) & 0x3;
30473 TCGv_i32 twd
= tcg_const_i32(wd
);
30474 TCGv taddr
= tcg_temp_new();
30475 gen_base_offset_addr(ctx
, taddr
, rs
, s10
<< df
);
30477 switch (MASK_MSA_MINOR(opcode
)) {
30479 gen_helper_msa_ld_b(cpu_env
, twd
, taddr
);
30482 gen_helper_msa_ld_h(cpu_env
, twd
, taddr
);
30485 gen_helper_msa_ld_w(cpu_env
, twd
, taddr
);
30488 gen_helper_msa_ld_d(cpu_env
, twd
, taddr
);
30491 gen_helper_msa_st_b(cpu_env
, twd
, taddr
);
30494 gen_helper_msa_st_h(cpu_env
, twd
, taddr
);
30497 gen_helper_msa_st_w(cpu_env
, twd
, taddr
);
30500 gen_helper_msa_st_d(cpu_env
, twd
, taddr
);
30504 tcg_temp_free_i32(twd
);
30505 tcg_temp_free(taddr
);
30509 MIPS_INVAL("MSA instruction");
30510 gen_reserved_instruction(ctx
);
30516 static bool decode_opc_legacy(CPUMIPSState
*env
, DisasContext
*ctx
)
30519 int rs
, rt
, rd
, sa
;
30523 op
= MASK_OP_MAJOR(ctx
->opcode
);
30524 rs
= (ctx
->opcode
>> 21) & 0x1f;
30525 rt
= (ctx
->opcode
>> 16) & 0x1f;
30526 rd
= (ctx
->opcode
>> 11) & 0x1f;
30527 sa
= (ctx
->opcode
>> 6) & 0x1f;
30528 imm
= (int16_t)ctx
->opcode
;
30531 decode_opc_special(env
, ctx
);
30534 #if defined(TARGET_MIPS64)
30535 if ((ctx
->insn_flags
& INSN_R5900
) && (ctx
->insn_flags
& ASE_MMI
)) {
30536 decode_mmi(env
, ctx
);
30538 if (ctx
->insn_flags
& ASE_MXU
) {
30539 decode_opc_mxu(env
, ctx
);
30542 decode_opc_special2_legacy(env
, ctx
);
30546 #if defined(TARGET_MIPS64)
30547 if (ctx
->insn_flags
& INSN_R5900
) {
30548 decode_mmi_sq(env
, ctx
); /* MMI_OPC_SQ */
30550 decode_opc_special3(env
, ctx
);
30553 decode_opc_special3(env
, ctx
);
30557 op1
= MASK_REGIMM(ctx
->opcode
);
30559 case OPC_BLTZL
: /* REGIMM branches */
30563 check_insn(ctx
, ISA_MIPS2
);
30564 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
30568 gen_compute_branch(ctx
, op1
, 4, rs
, -1, imm
<< 2, 4);
30572 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
30574 /* OPC_NAL, OPC_BAL */
30575 gen_compute_branch(ctx
, op1
, 4, 0, -1, imm
<< 2, 4);
30577 gen_reserved_instruction(ctx
);
30580 gen_compute_branch(ctx
, op1
, 4, rs
, -1, imm
<< 2, 4);
30583 case OPC_TGEI
: /* REGIMM traps */
30590 check_insn(ctx
, ISA_MIPS2
);
30591 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
30592 gen_trap(ctx
, op1
, rs
, -1, imm
);
30595 check_insn(ctx
, ISA_MIPS_R6
);
30596 gen_reserved_instruction(ctx
);
30599 check_insn(ctx
, ISA_MIPS_R2
);
30601 * Break the TB to be able to sync copied instructions
30604 ctx
->base
.is_jmp
= DISAS_STOP
;
30606 case OPC_BPOSGE32
: /* MIPS DSP branch */
30607 #if defined(TARGET_MIPS64)
30611 gen_compute_branch(ctx
, op1
, 4, -1, -2, (int32_t)imm
<< 2, 4);
30613 #if defined(TARGET_MIPS64)
30615 check_insn(ctx
, ISA_MIPS_R6
);
30616 check_mips_64(ctx
);
30618 tcg_gen_addi_tl(cpu_gpr
[rs
], cpu_gpr
[rs
], (int64_t)imm
<< 32);
30622 check_insn(ctx
, ISA_MIPS_R6
);
30623 check_mips_64(ctx
);
30625 tcg_gen_addi_tl(cpu_gpr
[rs
], cpu_gpr
[rs
], (int64_t)imm
<< 48);
30629 default: /* Invalid */
30630 MIPS_INVAL("regimm");
30631 gen_reserved_instruction(ctx
);
30636 check_cp0_enabled(ctx
);
30637 op1
= MASK_CP0(ctx
->opcode
);
30645 #if defined(TARGET_MIPS64)
30649 #ifndef CONFIG_USER_ONLY
30650 gen_cp0(env
, ctx
, op1
, rt
, rd
);
30651 #endif /* !CONFIG_USER_ONLY */
30669 #ifndef CONFIG_USER_ONLY
30670 gen_cp0(env
, ctx
, MASK_C0(ctx
->opcode
), rt
, rd
);
30671 #endif /* !CONFIG_USER_ONLY */
30674 #ifndef CONFIG_USER_ONLY
30677 TCGv t0
= tcg_temp_new();
30679 op2
= MASK_MFMC0(ctx
->opcode
);
30683 gen_helper_dmt(t0
);
30684 gen_store_gpr(t0
, rt
);
30688 gen_helper_emt(t0
);
30689 gen_store_gpr(t0
, rt
);
30693 gen_helper_dvpe(t0
, cpu_env
);
30694 gen_store_gpr(t0
, rt
);
30698 gen_helper_evpe(t0
, cpu_env
);
30699 gen_store_gpr(t0
, rt
);
30702 check_insn(ctx
, ISA_MIPS_R6
);
30704 gen_helper_dvp(t0
, cpu_env
);
30705 gen_store_gpr(t0
, rt
);
30709 check_insn(ctx
, ISA_MIPS_R6
);
30711 gen_helper_evp(t0
, cpu_env
);
30712 gen_store_gpr(t0
, rt
);
30716 check_insn(ctx
, ISA_MIPS_R2
);
30717 save_cpu_state(ctx
, 1);
30718 gen_helper_di(t0
, cpu_env
);
30719 gen_store_gpr(t0
, rt
);
30721 * Stop translation as we may have switched
30722 * the execution mode.
30724 ctx
->base
.is_jmp
= DISAS_STOP
;
30727 check_insn(ctx
, ISA_MIPS_R2
);
30728 save_cpu_state(ctx
, 1);
30729 gen_helper_ei(t0
, cpu_env
);
30730 gen_store_gpr(t0
, rt
);
30732 * DISAS_STOP isn't sufficient, we need to ensure we break
30733 * out of translated code to check for pending interrupts.
30735 gen_save_pc(ctx
->base
.pc_next
+ 4);
30736 ctx
->base
.is_jmp
= DISAS_EXIT
;
30738 default: /* Invalid */
30739 MIPS_INVAL("mfmc0");
30740 gen_reserved_instruction(ctx
);
30745 #endif /* !CONFIG_USER_ONLY */
30748 check_insn(ctx
, ISA_MIPS_R2
);
30749 gen_load_srsgpr(rt
, rd
);
30752 check_insn(ctx
, ISA_MIPS_R2
);
30753 gen_store_srsgpr(rt
, rd
);
30757 gen_reserved_instruction(ctx
);
30761 case OPC_BOVC
: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */
30762 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
30763 /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */
30764 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
30767 /* Arithmetic with immediate opcode */
30768 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
30772 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
30774 case OPC_SLTI
: /* Set on less than with immediate opcode */
30776 gen_slt_imm(ctx
, op
, rt
, rs
, imm
);
30778 case OPC_ANDI
: /* Arithmetic with immediate opcode */
30779 case OPC_LUI
: /* OPC_AUI */
30782 gen_logic_imm(ctx
, op
, rt
, rs
, imm
);
30784 case OPC_J
: /* Jump */
30786 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
30787 gen_compute_branch(ctx
, op
, 4, rs
, rt
, offset
, 4);
30790 case OPC_BLEZC
: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */
30791 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
30793 gen_reserved_instruction(ctx
);
30796 /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */
30797 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
30800 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
30803 case OPC_BGTZC
: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */
30804 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
30806 gen_reserved_instruction(ctx
);
30809 /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */
30810 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
30813 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
30816 case OPC_BLEZALC
: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */
30819 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
30821 check_insn(ctx
, ISA_MIPS_R6
);
30822 /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */
30823 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
30826 case OPC_BGTZALC
: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */
30829 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
30831 check_insn(ctx
, ISA_MIPS_R6
);
30832 /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */
30833 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
30838 check_insn(ctx
, ISA_MIPS2
);
30839 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
30843 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
30845 case OPC_LL
: /* Load and stores */
30846 check_insn(ctx
, ISA_MIPS2
);
30847 if (ctx
->insn_flags
& INSN_R5900
) {
30848 check_insn_opc_user_only(ctx
, INSN_R5900
);
30853 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
30861 gen_ld(ctx
, op
, rt
, rs
, imm
);
30865 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
30870 gen_st(ctx
, op
, rt
, rs
, imm
);
30873 check_insn(ctx
, ISA_MIPS2
);
30874 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
30875 if (ctx
->insn_flags
& INSN_R5900
) {
30876 check_insn_opc_user_only(ctx
, INSN_R5900
);
30878 gen_st_cond(ctx
, rt
, rs
, imm
, MO_TESL
, false);
30881 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
30882 check_cp0_enabled(ctx
);
30883 check_insn(ctx
, ISA_MIPS3
| ISA_MIPS_R1
);
30884 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
30885 gen_cache_operation(ctx
, rt
, rs
, imm
);
30887 /* Treat as NOP. */
30890 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
30891 if (ctx
->insn_flags
& INSN_R5900
) {
30892 /* Treat as NOP. */
30894 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS_R1
);
30895 /* Treat as NOP. */
30899 /* Floating point (COP1). */
30904 gen_cop1_ldst(ctx
, op
, rt
, rs
, imm
);
30908 op1
= MASK_CP1(ctx
->opcode
);
30913 check_cp1_enabled(ctx
);
30914 check_insn(ctx
, ISA_MIPS_R2
);
30920 check_cp1_enabled(ctx
);
30921 gen_cp1(ctx
, op1
, rt
, rd
);
30923 #if defined(TARGET_MIPS64)
30926 check_cp1_enabled(ctx
);
30927 check_insn(ctx
, ISA_MIPS3
);
30928 check_mips_64(ctx
);
30929 gen_cp1(ctx
, op1
, rt
, rd
);
30932 case OPC_BC1EQZ
: /* OPC_BC1ANY2 */
30933 check_cp1_enabled(ctx
);
30934 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
30936 gen_compute_branch1_r6(ctx
, MASK_CP1(ctx
->opcode
),
30941 check_insn(ctx
, ASE_MIPS3D
);
30942 gen_compute_branch1(ctx
, MASK_BC1(ctx
->opcode
),
30943 (rt
>> 2) & 0x7, imm
<< 2);
30947 check_cp1_enabled(ctx
);
30948 check_insn(ctx
, ISA_MIPS_R6
);
30949 gen_compute_branch1_r6(ctx
, MASK_CP1(ctx
->opcode
),
30953 check_cp1_enabled(ctx
);
30954 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
30956 check_insn(ctx
, ASE_MIPS3D
);
30959 check_cp1_enabled(ctx
);
30960 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
30961 gen_compute_branch1(ctx
, MASK_BC1(ctx
->opcode
),
30962 (rt
>> 2) & 0x7, imm
<< 2);
30969 check_cp1_enabled(ctx
);
30970 gen_farith(ctx
, ctx
->opcode
& FOP(0x3f, 0x1f), rt
, rd
, sa
,
30976 int r6_op
= ctx
->opcode
& FOP(0x3f, 0x1f);
30977 check_cp1_enabled(ctx
);
30978 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
30980 case R6_OPC_CMP_AF_S
:
30981 case R6_OPC_CMP_UN_S
:
30982 case R6_OPC_CMP_EQ_S
:
30983 case R6_OPC_CMP_UEQ_S
:
30984 case R6_OPC_CMP_LT_S
:
30985 case R6_OPC_CMP_ULT_S
:
30986 case R6_OPC_CMP_LE_S
:
30987 case R6_OPC_CMP_ULE_S
:
30988 case R6_OPC_CMP_SAF_S
:
30989 case R6_OPC_CMP_SUN_S
:
30990 case R6_OPC_CMP_SEQ_S
:
30991 case R6_OPC_CMP_SEUQ_S
:
30992 case R6_OPC_CMP_SLT_S
:
30993 case R6_OPC_CMP_SULT_S
:
30994 case R6_OPC_CMP_SLE_S
:
30995 case R6_OPC_CMP_SULE_S
:
30996 case R6_OPC_CMP_OR_S
:
30997 case R6_OPC_CMP_UNE_S
:
30998 case R6_OPC_CMP_NE_S
:
30999 case R6_OPC_CMP_SOR_S
:
31000 case R6_OPC_CMP_SUNE_S
:
31001 case R6_OPC_CMP_SNE_S
:
31002 gen_r6_cmp_s(ctx
, ctx
->opcode
& 0x1f, rt
, rd
, sa
);
31004 case R6_OPC_CMP_AF_D
:
31005 case R6_OPC_CMP_UN_D
:
31006 case R6_OPC_CMP_EQ_D
:
31007 case R6_OPC_CMP_UEQ_D
:
31008 case R6_OPC_CMP_LT_D
:
31009 case R6_OPC_CMP_ULT_D
:
31010 case R6_OPC_CMP_LE_D
:
31011 case R6_OPC_CMP_ULE_D
:
31012 case R6_OPC_CMP_SAF_D
:
31013 case R6_OPC_CMP_SUN_D
:
31014 case R6_OPC_CMP_SEQ_D
:
31015 case R6_OPC_CMP_SEUQ_D
:
31016 case R6_OPC_CMP_SLT_D
:
31017 case R6_OPC_CMP_SULT_D
:
31018 case R6_OPC_CMP_SLE_D
:
31019 case R6_OPC_CMP_SULE_D
:
31020 case R6_OPC_CMP_OR_D
:
31021 case R6_OPC_CMP_UNE_D
:
31022 case R6_OPC_CMP_NE_D
:
31023 case R6_OPC_CMP_SOR_D
:
31024 case R6_OPC_CMP_SUNE_D
:
31025 case R6_OPC_CMP_SNE_D
:
31026 gen_r6_cmp_d(ctx
, ctx
->opcode
& 0x1f, rt
, rd
, sa
);
31029 gen_farith(ctx
, ctx
->opcode
& FOP(0x3f, 0x1f),
31030 rt
, rd
, sa
, (imm
>> 8) & 0x7);
31035 gen_farith(ctx
, ctx
->opcode
& FOP(0x3f, 0x1f), rt
, rd
, sa
,
31050 check_insn(ctx
, ASE_MSA
);
31051 gen_msa_branch(env
, ctx
, op1
);
31055 gen_reserved_instruction(ctx
);
31060 /* Compact branches [R6] and COP2 [non-R6] */
31061 case OPC_BC
: /* OPC_LWC2 */
31062 case OPC_BALC
: /* OPC_SWC2 */
31063 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
31064 /* OPC_BC, OPC_BALC */
31065 gen_compute_compact_branch(ctx
, op
, 0, 0,
31066 sextract32(ctx
->opcode
<< 2, 0, 28));
31067 } else if (ctx
->insn_flags
& ASE_LEXT
) {
31068 gen_loongson_lswc2(ctx
, rt
, rs
, rd
);
31070 /* OPC_LWC2, OPC_SWC2 */
31071 /* COP2: Not implemented. */
31072 generate_exception_err(ctx
, EXCP_CpU
, 2);
31075 case OPC_BEQZC
: /* OPC_JIC, OPC_LDC2 */
31076 case OPC_BNEZC
: /* OPC_JIALC, OPC_SDC2 */
31077 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
31079 /* OPC_BEQZC, OPC_BNEZC */
31080 gen_compute_compact_branch(ctx
, op
, rs
, 0,
31081 sextract32(ctx
->opcode
<< 2, 0, 23));
31083 /* OPC_JIC, OPC_JIALC */
31084 gen_compute_compact_branch(ctx
, op
, 0, rt
, imm
);
31086 } else if (ctx
->insn_flags
& ASE_LEXT
) {
31087 gen_loongson_lsdc2(ctx
, rt
, rs
, rd
);
31089 /* OPC_LWC2, OPC_SWC2 */
31090 /* COP2: Not implemented. */
31091 generate_exception_err(ctx
, EXCP_CpU
, 2);
31095 check_insn(ctx
, ASE_LMMI
);
31096 /* Note that these instructions use different fields. */
31097 gen_loongson_multimedia(ctx
, sa
, rd
, rt
);
31101 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
31102 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
31103 check_cp1_enabled(ctx
);
31104 op1
= MASK_CP3(ctx
->opcode
);
31108 check_insn(ctx
, ISA_MIPS5
| ISA_MIPS_R2
);
31114 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS_R2
);
31115 gen_flt3_ldst(ctx
, op1
, sa
, rd
, rs
, rt
);
31118 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS_R2
);
31119 /* Treat as NOP. */
31122 check_insn(ctx
, ISA_MIPS5
| ISA_MIPS_R2
);
31136 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS_R2
);
31137 gen_flt3_arith(ctx
, op1
, sa
, rs
, rd
, rt
);
31141 gen_reserved_instruction(ctx
);
31145 generate_exception_err(ctx
, EXCP_CpU
, 1);
31149 #if defined(TARGET_MIPS64)
31150 /* MIPS64 opcodes */
31152 if (ctx
->insn_flags
& INSN_R5900
) {
31153 check_insn_opc_user_only(ctx
, INSN_R5900
);
31158 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
31162 check_insn(ctx
, ISA_MIPS3
);
31163 check_mips_64(ctx
);
31164 gen_ld(ctx
, op
, rt
, rs
, imm
);
31168 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
31171 check_insn(ctx
, ISA_MIPS3
);
31172 check_mips_64(ctx
);
31173 gen_st(ctx
, op
, rt
, rs
, imm
);
31176 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
31177 check_insn(ctx
, ISA_MIPS3
);
31178 if (ctx
->insn_flags
& INSN_R5900
) {
31179 check_insn_opc_user_only(ctx
, INSN_R5900
);
31181 check_mips_64(ctx
);
31182 gen_st_cond(ctx
, rt
, rs
, imm
, MO_TEQ
, false);
31184 case OPC_BNVC
: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */
31185 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
31186 /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */
31187 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
31190 check_insn(ctx
, ISA_MIPS3
);
31191 check_mips_64(ctx
);
31192 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
31196 check_insn(ctx
, ISA_MIPS3
);
31197 check_mips_64(ctx
);
31198 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
31201 case OPC_BNVC
: /* OPC_BNEZALC, OPC_BNEC */
31202 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
31203 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
31205 MIPS_INVAL("major opcode");
31206 gen_reserved_instruction(ctx
);
31210 case OPC_DAUI
: /* OPC_JALX */
31211 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
31212 #if defined(TARGET_MIPS64)
31214 check_mips_64(ctx
);
31216 generate_exception(ctx
, EXCP_RI
);
31217 } else if (rt
!= 0) {
31218 TCGv t0
= tcg_temp_new();
31219 gen_load_gpr(t0
, rs
);
31220 tcg_gen_addi_tl(cpu_gpr
[rt
], t0
, imm
<< 16);
31224 gen_reserved_instruction(ctx
);
31225 MIPS_INVAL("major opcode");
31229 check_insn(ctx
, ASE_MIPS16
| ASE_MICROMIPS
);
31230 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
31231 gen_compute_branch(ctx
, op
, 4, rs
, rt
, offset
, 4);
31234 case OPC_MSA
: /* OPC_MDMX */
31235 if (ctx
->insn_flags
& INSN_R5900
) {
31236 #if defined(TARGET_MIPS64)
31237 gen_mmi_lq(env
, ctx
); /* MMI_OPC_LQ */
31240 /* MDMX: Not implemented. */
31245 check_insn(ctx
, ISA_MIPS_R6
);
31246 gen_pcrel(ctx
, ctx
->opcode
, ctx
->base
.pc_next
, rs
);
31248 default: /* Invalid */
31249 MIPS_INVAL("major opcode");
31255 static void decode_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
31257 /* make sure instructions are on a word boundary */
31258 if (ctx
->base
.pc_next
& 0x3) {
31259 env
->CP0_BadVAddr
= ctx
->base
.pc_next
;
31260 generate_exception_err(ctx
, EXCP_AdEL
, EXCP_INST_NOTAVAIL
);
31264 /* Handle blikely not taken case */
31265 if ((ctx
->hflags
& MIPS_HFLAG_BMASK_BASE
) == MIPS_HFLAG_BL
) {
31266 TCGLabel
*l1
= gen_new_label();
31268 tcg_gen_brcondi_tl(TCG_COND_NE
, bcond
, 0, l1
);
31269 tcg_gen_movi_i32(hflags
, ctx
->hflags
& ~MIPS_HFLAG_BMASK
);
31270 gen_goto_tb(ctx
, 1, ctx
->base
.pc_next
+ 4);
31274 if (decode_opc_legacy(env
, ctx
)) {
31278 gen_reserved_instruction(ctx
);
31281 static void mips_tr_init_disas_context(DisasContextBase
*dcbase
, CPUState
*cs
)
31283 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
31284 CPUMIPSState
*env
= cs
->env_ptr
;
31286 ctx
->page_start
= ctx
->base
.pc_first
& TARGET_PAGE_MASK
;
31287 ctx
->saved_pc
= -1;
31288 ctx
->insn_flags
= env
->insn_flags
;
31289 ctx
->CP0_Config1
= env
->CP0_Config1
;
31290 ctx
->CP0_Config2
= env
->CP0_Config2
;
31291 ctx
->CP0_Config3
= env
->CP0_Config3
;
31292 ctx
->CP0_Config5
= env
->CP0_Config5
;
31294 ctx
->kscrexist
= (env
->CP0_Config4
>> CP0C4_KScrExist
) & 0xff;
31295 ctx
->rxi
= (env
->CP0_Config3
>> CP0C3_RXI
) & 1;
31296 ctx
->ie
= (env
->CP0_Config4
>> CP0C4_IE
) & 3;
31297 ctx
->bi
= (env
->CP0_Config3
>> CP0C3_BI
) & 1;
31298 ctx
->bp
= (env
->CP0_Config3
>> CP0C3_BP
) & 1;
31299 ctx
->PAMask
= env
->PAMask
;
31300 ctx
->mvh
= (env
->CP0_Config5
>> CP0C5_MVH
) & 1;
31301 ctx
->eva
= (env
->CP0_Config5
>> CP0C5_EVA
) & 1;
31302 ctx
->sc
= (env
->CP0_Config3
>> CP0C3_SC
) & 1;
31303 ctx
->CP0_LLAddr_shift
= env
->CP0_LLAddr_shift
;
31304 ctx
->cmgcr
= (env
->CP0_Config3
>> CP0C3_CMGCR
) & 1;
31305 /* Restore delay slot state from the tb context. */
31306 ctx
->hflags
= (uint32_t)ctx
->base
.tb
->flags
; /* FIXME: maybe use 64 bits? */
31307 ctx
->ulri
= (env
->CP0_Config3
>> CP0C3_ULRI
) & 1;
31308 ctx
->ps
= ((env
->active_fpu
.fcr0
>> FCR0_PS
) & 1) ||
31309 (env
->insn_flags
& (INSN_LOONGSON2E
| INSN_LOONGSON2F
));
31310 ctx
->vp
= (env
->CP0_Config5
>> CP0C5_VP
) & 1;
31311 ctx
->mrp
= (env
->CP0_Config5
>> CP0C5_MRP
) & 1;
31312 ctx
->nan2008
= (env
->active_fpu
.fcr31
>> FCR31_NAN2008
) & 1;
31313 ctx
->abs2008
= (env
->active_fpu
.fcr31
>> FCR31_ABS2008
) & 1;
31314 ctx
->mi
= (env
->CP0_Config5
>> CP0C5_MI
) & 1;
31315 ctx
->gi
= (env
->CP0_Config5
>> CP0C5_GI
) & 3;
31316 restore_cpu_state(env
, ctx
);
31317 #ifdef CONFIG_USER_ONLY
31318 ctx
->mem_idx
= MIPS_HFLAG_UM
;
31320 ctx
->mem_idx
= hflags_mmu_index(ctx
->hflags
);
31322 ctx
->default_tcg_memop_mask
= (ctx
->insn_flags
& (ISA_MIPS_R6
|
31323 INSN_LOONGSON3A
)) ? MO_UNALN
: MO_ALIGN
;
31325 LOG_DISAS("\ntb %p idx %d hflags %04x\n", ctx
->base
.tb
, ctx
->mem_idx
,
31329 static void mips_tr_tb_start(DisasContextBase
*dcbase
, CPUState
*cs
)
31333 static void mips_tr_insn_start(DisasContextBase
*dcbase
, CPUState
*cs
)
31335 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
31337 tcg_gen_insn_start(ctx
->base
.pc_next
, ctx
->hflags
& MIPS_HFLAG_BMASK
,
31341 static bool mips_tr_breakpoint_check(DisasContextBase
*dcbase
, CPUState
*cs
,
31342 const CPUBreakpoint
*bp
)
31344 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
31346 save_cpu_state(ctx
, 1);
31347 ctx
->base
.is_jmp
= DISAS_NORETURN
;
31348 gen_helper_raise_exception_debug(cpu_env
);
31350 * The address covered by the breakpoint must be included in
31351 * [tb->pc, tb->pc + tb->size) in order to for it to be
31352 * properly cleared -- thus we increment the PC here so that
31353 * the logic setting tb->size below does the right thing.
31355 ctx
->base
.pc_next
+= 4;
31359 static void mips_tr_translate_insn(DisasContextBase
*dcbase
, CPUState
*cs
)
31361 CPUMIPSState
*env
= cs
->env_ptr
;
31362 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
31366 is_slot
= ctx
->hflags
& MIPS_HFLAG_BMASK
;
31367 if (ctx
->insn_flags
& ISA_NANOMIPS32
) {
31368 ctx
->opcode
= cpu_lduw_code(env
, ctx
->base
.pc_next
);
31369 insn_bytes
= decode_nanomips_opc(env
, ctx
);
31370 } else if (!(ctx
->hflags
& MIPS_HFLAG_M16
)) {
31371 ctx
->opcode
= cpu_ldl_code(env
, ctx
->base
.pc_next
);
31373 decode_opc(env
, ctx
);
31374 } else if (ctx
->insn_flags
& ASE_MICROMIPS
) {
31375 ctx
->opcode
= cpu_lduw_code(env
, ctx
->base
.pc_next
);
31376 insn_bytes
= decode_micromips_opc(env
, ctx
);
31377 } else if (ctx
->insn_flags
& ASE_MIPS16
) {
31378 ctx
->opcode
= cpu_lduw_code(env
, ctx
->base
.pc_next
);
31379 insn_bytes
= decode_mips16_opc(env
, ctx
);
31381 gen_reserved_instruction(ctx
);
31382 g_assert(ctx
->base
.is_jmp
== DISAS_NORETURN
);
31386 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
31387 if (!(ctx
->hflags
& (MIPS_HFLAG_BDS16
| MIPS_HFLAG_BDS32
|
31388 MIPS_HFLAG_FBNSLOT
))) {
31390 * Force to generate branch as there is neither delay nor
31395 if ((ctx
->hflags
& MIPS_HFLAG_M16
) &&
31396 (ctx
->hflags
& MIPS_HFLAG_FBNSLOT
)) {
31398 * Force to generate branch as microMIPS R6 doesn't restrict
31399 * branches in the forbidden slot.
31405 gen_branch(ctx
, insn_bytes
);
31407 ctx
->base
.pc_next
+= insn_bytes
;
31409 if (ctx
->base
.is_jmp
!= DISAS_NEXT
) {
31413 * Execute a branch and its delay slot as a single instruction.
31414 * This is what GDB expects and is consistent with what the
31415 * hardware does (e.g. if a delay slot instruction faults, the
31416 * reported PC is the PC of the branch).
31418 if (ctx
->base
.singlestep_enabled
&&
31419 (ctx
->hflags
& MIPS_HFLAG_BMASK
) == 0) {
31420 ctx
->base
.is_jmp
= DISAS_TOO_MANY
;
31422 if (ctx
->base
.pc_next
- ctx
->page_start
>= TARGET_PAGE_SIZE
) {
31423 ctx
->base
.is_jmp
= DISAS_TOO_MANY
;
31427 static void mips_tr_tb_stop(DisasContextBase
*dcbase
, CPUState
*cs
)
31429 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
31431 if (ctx
->base
.singlestep_enabled
&& ctx
->base
.is_jmp
!= DISAS_NORETURN
) {
31432 save_cpu_state(ctx
, ctx
->base
.is_jmp
!= DISAS_EXIT
);
31433 gen_helper_raise_exception_debug(cpu_env
);
31435 switch (ctx
->base
.is_jmp
) {
31437 gen_save_pc(ctx
->base
.pc_next
);
31438 tcg_gen_lookup_and_goto_ptr();
31441 case DISAS_TOO_MANY
:
31442 save_cpu_state(ctx
, 0);
31443 gen_goto_tb(ctx
, 0, ctx
->base
.pc_next
);
31446 tcg_gen_exit_tb(NULL
, 0);
31448 case DISAS_NORETURN
:
31451 g_assert_not_reached();
31456 static void mips_tr_disas_log(const DisasContextBase
*dcbase
, CPUState
*cs
)
31458 qemu_log("IN: %s\n", lookup_symbol(dcbase
->pc_first
));
31459 log_target_disas(cs
, dcbase
->pc_first
, dcbase
->tb
->size
);
31462 static const TranslatorOps mips_tr_ops
= {
31463 .init_disas_context
= mips_tr_init_disas_context
,
31464 .tb_start
= mips_tr_tb_start
,
31465 .insn_start
= mips_tr_insn_start
,
31466 .breakpoint_check
= mips_tr_breakpoint_check
,
31467 .translate_insn
= mips_tr_translate_insn
,
31468 .tb_stop
= mips_tr_tb_stop
,
31469 .disas_log
= mips_tr_disas_log
,
31472 void gen_intermediate_code(CPUState
*cs
, TranslationBlock
*tb
, int max_insns
)
31476 translator_loop(&mips_tr_ops
, &ctx
.base
, cs
, tb
, max_insns
);
31479 static void fpu_dump_state(CPUMIPSState
*env
, FILE * f
, int flags
)
31482 int is_fpu64
= !!(env
->hflags
& MIPS_HFLAG_F64
);
31484 #define printfpr(fp) \
31487 qemu_fprintf(f, "w:%08x d:%016" PRIx64 \
31488 " fd:%13g fs:%13g psu: %13g\n", \
31489 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
31490 (double)(fp)->fd, \
31491 (double)(fp)->fs[FP_ENDIAN_IDX], \
31492 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
31495 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
31496 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
31497 qemu_fprintf(f, "w:%08x d:%016" PRIx64 \
31498 " fd:%13g fs:%13g psu:%13g\n", \
31499 tmp.w[FP_ENDIAN_IDX], tmp.d, \
31501 (double)tmp.fs[FP_ENDIAN_IDX], \
31502 (double)tmp.fs[!FP_ENDIAN_IDX]); \
31508 "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
31509 env
->active_fpu
.fcr0
, env
->active_fpu
.fcr31
, is_fpu64
,
31510 get_float_exception_flags(&env
->active_fpu
.fp_status
));
31511 for (i
= 0; i
< 32; (is_fpu64
) ? i
++ : (i
+= 2)) {
31512 qemu_fprintf(f
, "%3s: ", fregnames
[i
]);
31513 printfpr(&env
->active_fpu
.fpr
[i
]);
31519 void mips_cpu_dump_state(CPUState
*cs
, FILE *f
, int flags
)
31521 MIPSCPU
*cpu
= MIPS_CPU(cs
);
31522 CPUMIPSState
*env
= &cpu
->env
;
31525 qemu_fprintf(f
, "pc=0x" TARGET_FMT_lx
" HI=0x" TARGET_FMT_lx
31526 " LO=0x" TARGET_FMT_lx
" ds %04x "
31527 TARGET_FMT_lx
" " TARGET_FMT_ld
"\n",
31528 env
->active_tc
.PC
, env
->active_tc
.HI
[0], env
->active_tc
.LO
[0],
31529 env
->hflags
, env
->btarget
, env
->bcond
);
31530 for (i
= 0; i
< 32; i
++) {
31531 if ((i
& 3) == 0) {
31532 qemu_fprintf(f
, "GPR%02d:", i
);
31534 qemu_fprintf(f
, " %s " TARGET_FMT_lx
,
31535 regnames
[i
], env
->active_tc
.gpr
[i
]);
31536 if ((i
& 3) == 3) {
31537 qemu_fprintf(f
, "\n");
31541 qemu_fprintf(f
, "CP0 Status 0x%08x Cause 0x%08x EPC 0x"
31542 TARGET_FMT_lx
"\n",
31543 env
->CP0_Status
, env
->CP0_Cause
, env
->CP0_EPC
);
31544 qemu_fprintf(f
, " Config0 0x%08x Config1 0x%08x LLAddr 0x%016"
31546 env
->CP0_Config0
, env
->CP0_Config1
, env
->CP0_LLAddr
);
31547 qemu_fprintf(f
, " Config2 0x%08x Config3 0x%08x\n",
31548 env
->CP0_Config2
, env
->CP0_Config3
);
31549 qemu_fprintf(f
, " Config4 0x%08x Config5 0x%08x\n",
31550 env
->CP0_Config4
, env
->CP0_Config5
);
31551 if ((flags
& CPU_DUMP_FPU
) && (env
->hflags
& MIPS_HFLAG_FPU
)) {
31552 fpu_dump_state(env
, f
, flags
);
31556 void mips_tcg_init(void)
31561 for (i
= 1; i
< 32; i
++)
31562 cpu_gpr
[i
] = tcg_global_mem_new(cpu_env
,
31563 offsetof(CPUMIPSState
,
31567 for (i
= 0; i
< 32; i
++) {
31568 int off
= offsetof(CPUMIPSState
, active_fpu
.fpr
[i
].wr
.d
[0]);
31570 tcg_global_mem_new_i64(cpu_env
, off
, msaregnames
[i
* 2]);
31572 * The scalar floating-point unit (FPU) registers are mapped on
31573 * the MSA vector registers.
31575 fpu_f64
[i
] = msa_wr_d
[i
* 2];
31576 off
= offsetof(CPUMIPSState
, active_fpu
.fpr
[i
].wr
.d
[1]);
31577 msa_wr_d
[i
* 2 + 1] =
31578 tcg_global_mem_new_i64(cpu_env
, off
, msaregnames
[i
* 2 + 1]);
31581 cpu_PC
= tcg_global_mem_new(cpu_env
,
31582 offsetof(CPUMIPSState
, active_tc
.PC
), "PC");
31583 for (i
= 0; i
< MIPS_DSP_ACC
; i
++) {
31584 cpu_HI
[i
] = tcg_global_mem_new(cpu_env
,
31585 offsetof(CPUMIPSState
, active_tc
.HI
[i
]),
31587 cpu_LO
[i
] = tcg_global_mem_new(cpu_env
,
31588 offsetof(CPUMIPSState
, active_tc
.LO
[i
]),
31591 cpu_dspctrl
= tcg_global_mem_new(cpu_env
,
31592 offsetof(CPUMIPSState
,
31593 active_tc
.DSPControl
),
31595 bcond
= tcg_global_mem_new(cpu_env
,
31596 offsetof(CPUMIPSState
, bcond
), "bcond");
31597 btarget
= tcg_global_mem_new(cpu_env
,
31598 offsetof(CPUMIPSState
, btarget
), "btarget");
31599 hflags
= tcg_global_mem_new_i32(cpu_env
,
31600 offsetof(CPUMIPSState
, hflags
), "hflags");
31602 fpu_fcr0
= tcg_global_mem_new_i32(cpu_env
,
31603 offsetof(CPUMIPSState
, active_fpu
.fcr0
),
31605 fpu_fcr31
= tcg_global_mem_new_i32(cpu_env
,
31606 offsetof(CPUMIPSState
, active_fpu
.fcr31
),
31608 cpu_lladdr
= tcg_global_mem_new(cpu_env
, offsetof(CPUMIPSState
, lladdr
),
31610 cpu_llval
= tcg_global_mem_new(cpu_env
, offsetof(CPUMIPSState
, llval
),
31613 #if defined(TARGET_MIPS64)
31615 for (i
= 1; i
< 32; i
++) {
31616 cpu_mmr
[i
] = tcg_global_mem_new_i64(cpu_env
,
31617 offsetof(CPUMIPSState
,
31623 #if !defined(TARGET_MIPS64)
31624 for (i
= 0; i
< NUMBER_OF_MXU_REGISTERS
- 1; i
++) {
31625 mxu_gpr
[i
] = tcg_global_mem_new(cpu_env
,
31626 offsetof(CPUMIPSState
,
31627 active_tc
.mxu_gpr
[i
]),
31631 mxu_CR
= tcg_global_mem_new(cpu_env
,
31632 offsetof(CPUMIPSState
, active_tc
.mxu_cr
),
31633 mxuregnames
[NUMBER_OF_MXU_REGISTERS
- 1]);
31637 void restore_state_to_opc(CPUMIPSState
*env
, TranslationBlock
*tb
,
31638 target_ulong
*data
)
31640 env
->active_tc
.PC
= data
[0];
31641 env
->hflags
&= ~MIPS_HFLAG_BMASK
;
31642 env
->hflags
|= data
[1];
31643 switch (env
->hflags
& MIPS_HFLAG_BMASK_BASE
) {
31644 case MIPS_HFLAG_BR
:
31646 case MIPS_HFLAG_BC
:
31647 case MIPS_HFLAG_BL
:
31649 env
->btarget
= data
[2];