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
);
2974 #ifdef TARGET_MIPS64
2976 * This code generates a "reserved instruction" exception if 64-bit
2977 * instructions are not enabled.
2979 void check_mips_64(DisasContext
*ctx
)
2981 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_64
))) {
2982 gen_reserved_instruction(ctx
);
2987 #ifndef CONFIG_USER_ONLY
2988 static inline void check_mvh(DisasContext
*ctx
)
2990 if (unlikely(!ctx
->mvh
)) {
2991 generate_exception(ctx
, EXCP_RI
);
2997 * This code generates a "reserved instruction" exception if the
2998 * Config5 XNP bit is set.
3000 static inline void check_xnp(DisasContext
*ctx
)
3002 if (unlikely(ctx
->CP0_Config5
& (1 << CP0C5_XNP
))) {
3003 gen_reserved_instruction(ctx
);
3007 #ifndef CONFIG_USER_ONLY
3009 * This code generates a "reserved instruction" exception if the
3010 * Config3 PW bit is NOT set.
3012 static inline void check_pw(DisasContext
*ctx
)
3014 if (unlikely(!(ctx
->CP0_Config3
& (1 << CP0C3_PW
)))) {
3015 gen_reserved_instruction(ctx
);
3021 * This code generates a "reserved instruction" exception if the
3022 * Config3 MT bit is NOT set.
3024 static inline void check_mt(DisasContext
*ctx
)
3026 if (unlikely(!(ctx
->CP0_Config3
& (1 << CP0C3_MT
)))) {
3027 gen_reserved_instruction(ctx
);
3031 #ifndef CONFIG_USER_ONLY
3033 * This code generates a "coprocessor unusable" exception if CP0 is not
3034 * available, and, if that is not the case, generates a "reserved instruction"
3035 * exception if the Config5 MT bit is NOT set. This is needed for availability
3036 * control of some of MT ASE instructions.
3038 static inline void check_cp0_mt(DisasContext
*ctx
)
3040 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_CP0
))) {
3041 generate_exception_end(ctx
, EXCP_CpU
);
3043 if (unlikely(!(ctx
->CP0_Config3
& (1 << CP0C3_MT
)))) {
3044 gen_reserved_instruction(ctx
);
3051 * This code generates a "reserved instruction" exception if the
3052 * Config5 NMS bit is set.
3054 static inline void check_nms(DisasContext
*ctx
)
3056 if (unlikely(ctx
->CP0_Config5
& (1 << CP0C5_NMS
))) {
3057 gen_reserved_instruction(ctx
);
3062 * This code generates a "reserved instruction" exception if the
3063 * Config5 NMS bit is set, and Config1 DL, Config1 IL, Config2 SL,
3064 * Config2 TL, and Config5 L2C are unset.
3066 static inline void check_nms_dl_il_sl_tl_l2c(DisasContext
*ctx
)
3068 if (unlikely((ctx
->CP0_Config5
& (1 << CP0C5_NMS
)) &&
3069 !(ctx
->CP0_Config1
& (1 << CP0C1_DL
)) &&
3070 !(ctx
->CP0_Config1
& (1 << CP0C1_IL
)) &&
3071 !(ctx
->CP0_Config2
& (1 << CP0C2_SL
)) &&
3072 !(ctx
->CP0_Config2
& (1 << CP0C2_TL
)) &&
3073 !(ctx
->CP0_Config5
& (1 << CP0C5_L2C
)))) {
3074 gen_reserved_instruction(ctx
);
3079 * This code generates a "reserved instruction" exception if the
3080 * Config5 EVA bit is NOT set.
3082 static inline void check_eva(DisasContext
*ctx
)
3084 if (unlikely(!(ctx
->CP0_Config5
& (1 << CP0C5_EVA
)))) {
3085 gen_reserved_instruction(ctx
);
3091 * Define small wrappers for gen_load_fpr* so that we have a uniform
3092 * calling interface for 32 and 64-bit FPRs. No sense in changing
3093 * all callers for gen_load_fpr32 when we need the CTX parameter for
3096 #define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(ctx, x, y)
3097 #define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
3098 #define FOP_CONDS(type, abs, fmt, ifmt, bits) \
3099 static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
3100 int ft, int fs, int cc) \
3102 TCGv_i##bits fp0 = tcg_temp_new_i##bits(); \
3103 TCGv_i##bits fp1 = tcg_temp_new_i##bits(); \
3112 check_cp1_registers(ctx, fs | ft); \
3120 gen_ldcmp_fpr##bits(ctx, fp0, fs); \
3121 gen_ldcmp_fpr##bits(ctx, fp1, ft); \
3124 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); \
3127 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); \
3130 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); \
3133 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); \
3136 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); \
3139 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); \
3142 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); \
3145 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); \
3148 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); \
3151 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); \
3154 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); \
3157 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); \
3160 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); \
3163 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); \
3166 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); \
3169 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); \
3174 tcg_temp_free_i##bits(fp0); \
3175 tcg_temp_free_i##bits(fp1); \
3178 FOP_CONDS(, 0, d
, FMT_D
, 64)
3179 FOP_CONDS(abs
, 1, d
, FMT_D
, 64)
3180 FOP_CONDS(, 0, s
, FMT_S
, 32)
3181 FOP_CONDS(abs
, 1, s
, FMT_S
, 32)
3182 FOP_CONDS(, 0, ps
, FMT_PS
, 64)
3183 FOP_CONDS(abs
, 1, ps
, FMT_PS
, 64)
3186 #define FOP_CONDNS(fmt, ifmt, bits, STORE) \
3187 static inline void gen_r6_cmp_ ## fmt(DisasContext *ctx, int n, \
3188 int ft, int fs, int fd) \
3190 TCGv_i ## bits fp0 = tcg_temp_new_i ## bits(); \
3191 TCGv_i ## bits fp1 = tcg_temp_new_i ## bits(); \
3192 if (ifmt == FMT_D) { \
3193 check_cp1_registers(ctx, fs | ft | fd); \
3195 gen_ldcmp_fpr ## bits(ctx, fp0, fs); \
3196 gen_ldcmp_fpr ## bits(ctx, fp1, ft); \
3199 gen_helper_r6_cmp_ ## fmt ## _af(fp0, cpu_env, fp0, fp1); \
3202 gen_helper_r6_cmp_ ## fmt ## _un(fp0, cpu_env, fp0, fp1); \
3205 gen_helper_r6_cmp_ ## fmt ## _eq(fp0, cpu_env, fp0, fp1); \
3208 gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, cpu_env, fp0, fp1); \
3211 gen_helper_r6_cmp_ ## fmt ## _lt(fp0, cpu_env, fp0, fp1); \
3214 gen_helper_r6_cmp_ ## fmt ## _ult(fp0, cpu_env, fp0, fp1); \
3217 gen_helper_r6_cmp_ ## fmt ## _le(fp0, cpu_env, fp0, fp1); \
3220 gen_helper_r6_cmp_ ## fmt ## _ule(fp0, cpu_env, fp0, fp1); \
3223 gen_helper_r6_cmp_ ## fmt ## _saf(fp0, cpu_env, fp0, fp1); \
3226 gen_helper_r6_cmp_ ## fmt ## _sun(fp0, cpu_env, fp0, fp1); \
3229 gen_helper_r6_cmp_ ## fmt ## _seq(fp0, cpu_env, fp0, fp1); \
3232 gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, cpu_env, fp0, fp1); \
3235 gen_helper_r6_cmp_ ## fmt ## _slt(fp0, cpu_env, fp0, fp1); \
3238 gen_helper_r6_cmp_ ## fmt ## _sult(fp0, cpu_env, fp0, fp1); \
3241 gen_helper_r6_cmp_ ## fmt ## _sle(fp0, cpu_env, fp0, fp1); \
3244 gen_helper_r6_cmp_ ## fmt ## _sule(fp0, cpu_env, fp0, fp1); \
3247 gen_helper_r6_cmp_ ## fmt ## _or(fp0, cpu_env, fp0, fp1); \
3250 gen_helper_r6_cmp_ ## fmt ## _une(fp0, cpu_env, fp0, fp1); \
3253 gen_helper_r6_cmp_ ## fmt ## _ne(fp0, cpu_env, fp0, fp1); \
3256 gen_helper_r6_cmp_ ## fmt ## _sor(fp0, cpu_env, fp0, fp1); \
3259 gen_helper_r6_cmp_ ## fmt ## _sune(fp0, cpu_env, fp0, fp1); \
3262 gen_helper_r6_cmp_ ## fmt ## _sne(fp0, cpu_env, fp0, fp1); \
3268 tcg_temp_free_i ## bits(fp0); \
3269 tcg_temp_free_i ## bits(fp1); \
3272 FOP_CONDNS(d
, FMT_D
, 64, gen_store_fpr64(ctx
, fp0
, fd
))
3273 FOP_CONDNS(s
, FMT_S
, 32, gen_store_fpr32(ctx
, fp0
, fd
))
3275 #undef gen_ldcmp_fpr32
3276 #undef gen_ldcmp_fpr64
3278 /* load/store instructions. */
3279 #ifdef CONFIG_USER_ONLY
3280 #define OP_LD_ATOMIC(insn, fname) \
3281 static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \
3282 DisasContext *ctx) \
3284 TCGv t0 = tcg_temp_new(); \
3285 tcg_gen_mov_tl(t0, arg1); \
3286 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
3287 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
3288 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
3289 tcg_temp_free(t0); \
3292 #define OP_LD_ATOMIC(insn, fname) \
3293 static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \
3294 DisasContext *ctx) \
3296 gen_helper_1e1i(insn, ret, arg1, mem_idx); \
3299 OP_LD_ATOMIC(ll
, ld32s
);
3300 #if defined(TARGET_MIPS64)
3301 OP_LD_ATOMIC(lld
, ld64
);
3305 void gen_base_offset_addr(DisasContext
*ctx
, TCGv addr
, int base
, int offset
)
3308 tcg_gen_movi_tl(addr
, offset
);
3309 } else if (offset
== 0) {
3310 gen_load_gpr(addr
, base
);
3312 tcg_gen_movi_tl(addr
, offset
);
3313 gen_op_addr_add(ctx
, addr
, cpu_gpr
[base
], addr
);
3317 static target_ulong
pc_relative_pc(DisasContext
*ctx
)
3319 target_ulong pc
= ctx
->base
.pc_next
;
3321 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
3322 int branch_bytes
= ctx
->hflags
& MIPS_HFLAG_BDS16
? 2 : 4;
3327 pc
&= ~(target_ulong
)3;
3332 static void gen_ld(DisasContext
*ctx
, uint32_t opc
,
3333 int rt
, int base
, int offset
)
3336 int mem_idx
= ctx
->mem_idx
;
3338 if (rt
== 0 && ctx
->insn_flags
& (INSN_LOONGSON2E
| INSN_LOONGSON2F
|
3341 * Loongson CPU uses a load to zero register for prefetch.
3342 * We emulate it as a NOP. On other CPU we must perform the
3343 * actual memory access.
3348 t0
= tcg_temp_new();
3349 gen_base_offset_addr(ctx
, t0
, base
, offset
);
3352 #if defined(TARGET_MIPS64)
3354 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEUL
|
3355 ctx
->default_tcg_memop_mask
);
3356 gen_store_gpr(t0
, rt
);
3359 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEQ
|
3360 ctx
->default_tcg_memop_mask
);
3361 gen_store_gpr(t0
, rt
);
3365 op_ld_lld(t0
, t0
, mem_idx
, ctx
);
3366 gen_store_gpr(t0
, rt
);
3369 t1
= tcg_temp_new();
3371 * Do a byte access to possibly trigger a page
3372 * fault with the unaligned address.
3374 tcg_gen_qemu_ld_tl(t1
, t0
, mem_idx
, MO_UB
);
3375 tcg_gen_andi_tl(t1
, t0
, 7);
3376 #ifndef TARGET_WORDS_BIGENDIAN
3377 tcg_gen_xori_tl(t1
, t1
, 7);
3379 tcg_gen_shli_tl(t1
, t1
, 3);
3380 tcg_gen_andi_tl(t0
, t0
, ~7);
3381 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEQ
);
3382 tcg_gen_shl_tl(t0
, t0
, t1
);
3383 t2
= tcg_const_tl(-1);
3384 tcg_gen_shl_tl(t2
, t2
, t1
);
3385 gen_load_gpr(t1
, rt
);
3386 tcg_gen_andc_tl(t1
, t1
, t2
);
3388 tcg_gen_or_tl(t0
, t0
, t1
);
3390 gen_store_gpr(t0
, rt
);
3393 t1
= tcg_temp_new();
3395 * Do a byte access to possibly trigger a page
3396 * fault with the unaligned address.
3398 tcg_gen_qemu_ld_tl(t1
, t0
, mem_idx
, MO_UB
);
3399 tcg_gen_andi_tl(t1
, t0
, 7);
3400 #ifdef TARGET_WORDS_BIGENDIAN
3401 tcg_gen_xori_tl(t1
, t1
, 7);
3403 tcg_gen_shli_tl(t1
, t1
, 3);
3404 tcg_gen_andi_tl(t0
, t0
, ~7);
3405 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEQ
);
3406 tcg_gen_shr_tl(t0
, t0
, t1
);
3407 tcg_gen_xori_tl(t1
, t1
, 63);
3408 t2
= tcg_const_tl(0xfffffffffffffffeull
);
3409 tcg_gen_shl_tl(t2
, t2
, t1
);
3410 gen_load_gpr(t1
, rt
);
3411 tcg_gen_and_tl(t1
, t1
, t2
);
3413 tcg_gen_or_tl(t0
, t0
, t1
);
3415 gen_store_gpr(t0
, rt
);
3418 t1
= tcg_const_tl(pc_relative_pc(ctx
));
3419 gen_op_addr_add(ctx
, t0
, t0
, t1
);
3421 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEQ
);
3422 gen_store_gpr(t0
, rt
);
3426 t1
= tcg_const_tl(pc_relative_pc(ctx
));
3427 gen_op_addr_add(ctx
, t0
, t0
, t1
);
3429 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TESL
);
3430 gen_store_gpr(t0
, rt
);
3433 mem_idx
= MIPS_HFLAG_UM
;
3436 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TESL
|
3437 ctx
->default_tcg_memop_mask
);
3438 gen_store_gpr(t0
, rt
);
3441 mem_idx
= MIPS_HFLAG_UM
;
3444 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TESW
|
3445 ctx
->default_tcg_memop_mask
);
3446 gen_store_gpr(t0
, rt
);
3449 mem_idx
= MIPS_HFLAG_UM
;
3452 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEUW
|
3453 ctx
->default_tcg_memop_mask
);
3454 gen_store_gpr(t0
, rt
);
3457 mem_idx
= MIPS_HFLAG_UM
;
3460 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_SB
);
3461 gen_store_gpr(t0
, rt
);
3464 mem_idx
= MIPS_HFLAG_UM
;
3467 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_UB
);
3468 gen_store_gpr(t0
, rt
);
3471 mem_idx
= MIPS_HFLAG_UM
;
3474 t1
= tcg_temp_new();
3476 * Do a byte access to possibly trigger a page
3477 * fault with the unaligned address.
3479 tcg_gen_qemu_ld_tl(t1
, t0
, mem_idx
, MO_UB
);
3480 tcg_gen_andi_tl(t1
, t0
, 3);
3481 #ifndef TARGET_WORDS_BIGENDIAN
3482 tcg_gen_xori_tl(t1
, t1
, 3);
3484 tcg_gen_shli_tl(t1
, t1
, 3);
3485 tcg_gen_andi_tl(t0
, t0
, ~3);
3486 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEUL
);
3487 tcg_gen_shl_tl(t0
, t0
, t1
);
3488 t2
= tcg_const_tl(-1);
3489 tcg_gen_shl_tl(t2
, t2
, t1
);
3490 gen_load_gpr(t1
, rt
);
3491 tcg_gen_andc_tl(t1
, t1
, t2
);
3493 tcg_gen_or_tl(t0
, t0
, t1
);
3495 tcg_gen_ext32s_tl(t0
, t0
);
3496 gen_store_gpr(t0
, rt
);
3499 mem_idx
= MIPS_HFLAG_UM
;
3502 t1
= tcg_temp_new();
3504 * Do a byte access to possibly trigger a page
3505 * fault with the unaligned address.
3507 tcg_gen_qemu_ld_tl(t1
, t0
, mem_idx
, MO_UB
);
3508 tcg_gen_andi_tl(t1
, t0
, 3);
3509 #ifdef TARGET_WORDS_BIGENDIAN
3510 tcg_gen_xori_tl(t1
, t1
, 3);
3512 tcg_gen_shli_tl(t1
, t1
, 3);
3513 tcg_gen_andi_tl(t0
, t0
, ~3);
3514 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEUL
);
3515 tcg_gen_shr_tl(t0
, t0
, t1
);
3516 tcg_gen_xori_tl(t1
, t1
, 31);
3517 t2
= tcg_const_tl(0xfffffffeull
);
3518 tcg_gen_shl_tl(t2
, t2
, t1
);
3519 gen_load_gpr(t1
, rt
);
3520 tcg_gen_and_tl(t1
, t1
, t2
);
3522 tcg_gen_or_tl(t0
, t0
, t1
);
3524 tcg_gen_ext32s_tl(t0
, t0
);
3525 gen_store_gpr(t0
, rt
);
3528 mem_idx
= MIPS_HFLAG_UM
;
3532 op_ld_ll(t0
, t0
, mem_idx
, ctx
);
3533 gen_store_gpr(t0
, rt
);
3539 static void gen_llwp(DisasContext
*ctx
, uint32_t base
, int16_t offset
,
3540 uint32_t reg1
, uint32_t reg2
)
3542 TCGv taddr
= tcg_temp_new();
3543 TCGv_i64 tval
= tcg_temp_new_i64();
3544 TCGv tmp1
= tcg_temp_new();
3545 TCGv tmp2
= tcg_temp_new();
3547 gen_base_offset_addr(ctx
, taddr
, base
, offset
);
3548 tcg_gen_qemu_ld64(tval
, taddr
, ctx
->mem_idx
);
3549 #ifdef TARGET_WORDS_BIGENDIAN
3550 tcg_gen_extr_i64_tl(tmp2
, tmp1
, tval
);
3552 tcg_gen_extr_i64_tl(tmp1
, tmp2
, tval
);
3554 gen_store_gpr(tmp1
, reg1
);
3555 tcg_temp_free(tmp1
);
3556 gen_store_gpr(tmp2
, reg2
);
3557 tcg_temp_free(tmp2
);
3558 tcg_gen_st_i64(tval
, cpu_env
, offsetof(CPUMIPSState
, llval_wp
));
3559 tcg_temp_free_i64(tval
);
3560 tcg_gen_st_tl(taddr
, cpu_env
, offsetof(CPUMIPSState
, lladdr
));
3561 tcg_temp_free(taddr
);
3565 static void gen_st(DisasContext
*ctx
, uint32_t opc
, int rt
,
3566 int base
, int offset
)
3568 TCGv t0
= tcg_temp_new();
3569 TCGv t1
= tcg_temp_new();
3570 int mem_idx
= ctx
->mem_idx
;
3572 gen_base_offset_addr(ctx
, t0
, base
, offset
);
3573 gen_load_gpr(t1
, rt
);
3575 #if defined(TARGET_MIPS64)
3577 tcg_gen_qemu_st_tl(t1
, t0
, mem_idx
, MO_TEQ
|
3578 ctx
->default_tcg_memop_mask
);
3581 gen_helper_0e2i(sdl
, t1
, t0
, mem_idx
);
3584 gen_helper_0e2i(sdr
, t1
, t0
, mem_idx
);
3588 mem_idx
= MIPS_HFLAG_UM
;
3591 tcg_gen_qemu_st_tl(t1
, t0
, mem_idx
, MO_TEUL
|
3592 ctx
->default_tcg_memop_mask
);
3595 mem_idx
= MIPS_HFLAG_UM
;
3598 tcg_gen_qemu_st_tl(t1
, t0
, mem_idx
, MO_TEUW
|
3599 ctx
->default_tcg_memop_mask
);
3602 mem_idx
= MIPS_HFLAG_UM
;
3605 tcg_gen_qemu_st_tl(t1
, t0
, mem_idx
, MO_8
);
3608 mem_idx
= MIPS_HFLAG_UM
;
3611 gen_helper_0e2i(swl
, t1
, t0
, mem_idx
);
3614 mem_idx
= MIPS_HFLAG_UM
;
3617 gen_helper_0e2i(swr
, t1
, t0
, mem_idx
);
3625 /* Store conditional */
3626 static void gen_st_cond(DisasContext
*ctx
, int rt
, int base
, int offset
,
3627 MemOp tcg_mo
, bool eva
)
3630 TCGLabel
*l1
= gen_new_label();
3631 TCGLabel
*done
= gen_new_label();
3633 t0
= tcg_temp_new();
3634 addr
= tcg_temp_new();
3635 /* compare the address against that of the preceding LL */
3636 gen_base_offset_addr(ctx
, addr
, base
, offset
);
3637 tcg_gen_brcond_tl(TCG_COND_EQ
, addr
, cpu_lladdr
, l1
);
3638 tcg_temp_free(addr
);
3639 tcg_gen_movi_tl(t0
, 0);
3640 gen_store_gpr(t0
, rt
);
3644 /* generate cmpxchg */
3645 val
= tcg_temp_new();
3646 gen_load_gpr(val
, rt
);
3647 tcg_gen_atomic_cmpxchg_tl(t0
, cpu_lladdr
, cpu_llval
, val
,
3648 eva
? MIPS_HFLAG_UM
: ctx
->mem_idx
, tcg_mo
);
3649 tcg_gen_setcond_tl(TCG_COND_EQ
, t0
, t0
, cpu_llval
);
3650 gen_store_gpr(t0
, rt
);
3653 gen_set_label(done
);
3658 static void gen_scwp(DisasContext
*ctx
, uint32_t base
, int16_t offset
,
3659 uint32_t reg1
, uint32_t reg2
, bool eva
)
3661 TCGv taddr
= tcg_temp_local_new();
3662 TCGv lladdr
= tcg_temp_local_new();
3663 TCGv_i64 tval
= tcg_temp_new_i64();
3664 TCGv_i64 llval
= tcg_temp_new_i64();
3665 TCGv_i64 val
= tcg_temp_new_i64();
3666 TCGv tmp1
= tcg_temp_new();
3667 TCGv tmp2
= tcg_temp_new();
3668 TCGLabel
*lab_fail
= gen_new_label();
3669 TCGLabel
*lab_done
= gen_new_label();
3671 gen_base_offset_addr(ctx
, taddr
, base
, offset
);
3673 tcg_gen_ld_tl(lladdr
, cpu_env
, offsetof(CPUMIPSState
, lladdr
));
3674 tcg_gen_brcond_tl(TCG_COND_NE
, taddr
, lladdr
, lab_fail
);
3676 gen_load_gpr(tmp1
, reg1
);
3677 gen_load_gpr(tmp2
, reg2
);
3679 #ifdef TARGET_WORDS_BIGENDIAN
3680 tcg_gen_concat_tl_i64(tval
, tmp2
, tmp1
);
3682 tcg_gen_concat_tl_i64(tval
, tmp1
, tmp2
);
3685 tcg_gen_ld_i64(llval
, cpu_env
, offsetof(CPUMIPSState
, llval_wp
));
3686 tcg_gen_atomic_cmpxchg_i64(val
, taddr
, llval
, tval
,
3687 eva
? MIPS_HFLAG_UM
: ctx
->mem_idx
, MO_64
);
3689 tcg_gen_movi_tl(cpu_gpr
[reg1
], 1);
3691 tcg_gen_brcond_i64(TCG_COND_EQ
, val
, llval
, lab_done
);
3693 gen_set_label(lab_fail
);
3696 tcg_gen_movi_tl(cpu_gpr
[reg1
], 0);
3698 gen_set_label(lab_done
);
3699 tcg_gen_movi_tl(lladdr
, -1);
3700 tcg_gen_st_tl(lladdr
, cpu_env
, offsetof(CPUMIPSState
, lladdr
));
3703 /* Load and store */
3704 static void gen_flt_ldst(DisasContext
*ctx
, uint32_t opc
, int ft
,
3708 * Don't do NOP if destination is zero: we must perform the actual
3714 TCGv_i32 fp0
= tcg_temp_new_i32();
3715 tcg_gen_qemu_ld_i32(fp0
, t0
, ctx
->mem_idx
, MO_TESL
|
3716 ctx
->default_tcg_memop_mask
);
3717 gen_store_fpr32(ctx
, fp0
, ft
);
3718 tcg_temp_free_i32(fp0
);
3723 TCGv_i32 fp0
= tcg_temp_new_i32();
3724 gen_load_fpr32(ctx
, fp0
, ft
);
3725 tcg_gen_qemu_st_i32(fp0
, t0
, ctx
->mem_idx
, MO_TEUL
|
3726 ctx
->default_tcg_memop_mask
);
3727 tcg_temp_free_i32(fp0
);
3732 TCGv_i64 fp0
= tcg_temp_new_i64();
3733 tcg_gen_qemu_ld_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
|
3734 ctx
->default_tcg_memop_mask
);
3735 gen_store_fpr64(ctx
, fp0
, ft
);
3736 tcg_temp_free_i64(fp0
);
3741 TCGv_i64 fp0
= tcg_temp_new_i64();
3742 gen_load_fpr64(ctx
, fp0
, ft
);
3743 tcg_gen_qemu_st_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
|
3744 ctx
->default_tcg_memop_mask
);
3745 tcg_temp_free_i64(fp0
);
3749 MIPS_INVAL("flt_ldst");
3750 gen_reserved_instruction(ctx
);
3755 static void gen_cop1_ldst(DisasContext
*ctx
, uint32_t op
, int rt
,
3756 int rs
, int16_t imm
)
3758 TCGv t0
= tcg_temp_new();
3760 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
3761 check_cp1_enabled(ctx
);
3765 check_insn(ctx
, ISA_MIPS2
);
3768 gen_base_offset_addr(ctx
, t0
, rs
, imm
);
3769 gen_flt_ldst(ctx
, op
, rt
, t0
);
3772 generate_exception_err(ctx
, EXCP_CpU
, 1);
3777 /* Arithmetic with immediate operand */
3778 static void gen_arith_imm(DisasContext
*ctx
, uint32_t opc
,
3779 int rt
, int rs
, int imm
)
3781 target_ulong uimm
= (target_long
)imm
; /* Sign extend to 32/64 bits */
3783 if (rt
== 0 && opc
!= OPC_ADDI
&& opc
!= OPC_DADDI
) {
3785 * If no destination, treat it as a NOP.
3786 * For addi, we must generate the overflow exception when needed.
3793 TCGv t0
= tcg_temp_local_new();
3794 TCGv t1
= tcg_temp_new();
3795 TCGv t2
= tcg_temp_new();
3796 TCGLabel
*l1
= gen_new_label();
3798 gen_load_gpr(t1
, rs
);
3799 tcg_gen_addi_tl(t0
, t1
, uimm
);
3800 tcg_gen_ext32s_tl(t0
, t0
);
3802 tcg_gen_xori_tl(t1
, t1
, ~uimm
);
3803 tcg_gen_xori_tl(t2
, t0
, uimm
);
3804 tcg_gen_and_tl(t1
, t1
, t2
);
3806 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
3808 /* operands of same sign, result different sign */
3809 generate_exception(ctx
, EXCP_OVERFLOW
);
3811 tcg_gen_ext32s_tl(t0
, t0
);
3812 gen_store_gpr(t0
, rt
);
3818 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
3819 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
3821 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
3824 #if defined(TARGET_MIPS64)
3827 TCGv t0
= tcg_temp_local_new();
3828 TCGv t1
= tcg_temp_new();
3829 TCGv t2
= tcg_temp_new();
3830 TCGLabel
*l1
= gen_new_label();
3832 gen_load_gpr(t1
, rs
);
3833 tcg_gen_addi_tl(t0
, t1
, uimm
);
3835 tcg_gen_xori_tl(t1
, t1
, ~uimm
);
3836 tcg_gen_xori_tl(t2
, t0
, uimm
);
3837 tcg_gen_and_tl(t1
, t1
, t2
);
3839 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
3841 /* operands of same sign, result different sign */
3842 generate_exception(ctx
, EXCP_OVERFLOW
);
3844 gen_store_gpr(t0
, rt
);
3850 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
3852 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
3859 /* Logic with immediate operand */
3860 static void gen_logic_imm(DisasContext
*ctx
, uint32_t opc
,
3861 int rt
, int rs
, int16_t imm
)
3866 /* If no destination, treat it as a NOP. */
3869 uimm
= (uint16_t)imm
;
3872 if (likely(rs
!= 0)) {
3873 tcg_gen_andi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
3875 tcg_gen_movi_tl(cpu_gpr
[rt
], 0);
3880 tcg_gen_ori_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
3882 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
3886 if (likely(rs
!= 0)) {
3887 tcg_gen_xori_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
3889 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
3893 if (rs
!= 0 && (ctx
->insn_flags
& ISA_MIPS_R6
)) {
3895 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], imm
<< 16);
3896 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
3898 tcg_gen_movi_tl(cpu_gpr
[rt
], imm
<< 16);
3907 /* Set on less than with immediate operand */
3908 static void gen_slt_imm(DisasContext
*ctx
, uint32_t opc
,
3909 int rt
, int rs
, int16_t imm
)
3911 target_ulong uimm
= (target_long
)imm
; /* Sign extend to 32/64 bits */
3915 /* If no destination, treat it as a NOP. */
3918 t0
= tcg_temp_new();
3919 gen_load_gpr(t0
, rs
);
3922 tcg_gen_setcondi_tl(TCG_COND_LT
, cpu_gpr
[rt
], t0
, uimm
);
3925 tcg_gen_setcondi_tl(TCG_COND_LTU
, cpu_gpr
[rt
], t0
, uimm
);
3931 /* Shifts with immediate operand */
3932 static void gen_shift_imm(DisasContext
*ctx
, uint32_t opc
,
3933 int rt
, int rs
, int16_t imm
)
3935 target_ulong uimm
= ((uint16_t)imm
) & 0x1f;
3939 /* If no destination, treat it as a NOP. */
3943 t0
= tcg_temp_new();
3944 gen_load_gpr(t0
, rs
);
3947 tcg_gen_shli_tl(t0
, t0
, uimm
);
3948 tcg_gen_ext32s_tl(cpu_gpr
[rt
], t0
);
3951 tcg_gen_sari_tl(cpu_gpr
[rt
], t0
, uimm
);
3955 tcg_gen_ext32u_tl(t0
, t0
);
3956 tcg_gen_shri_tl(cpu_gpr
[rt
], t0
, uimm
);
3958 tcg_gen_ext32s_tl(cpu_gpr
[rt
], t0
);
3963 TCGv_i32 t1
= tcg_temp_new_i32();
3965 tcg_gen_trunc_tl_i32(t1
, t0
);
3966 tcg_gen_rotri_i32(t1
, t1
, uimm
);
3967 tcg_gen_ext_i32_tl(cpu_gpr
[rt
], t1
);
3968 tcg_temp_free_i32(t1
);
3970 tcg_gen_ext32s_tl(cpu_gpr
[rt
], t0
);
3973 #if defined(TARGET_MIPS64)
3975 tcg_gen_shli_tl(cpu_gpr
[rt
], t0
, uimm
);
3978 tcg_gen_sari_tl(cpu_gpr
[rt
], t0
, uimm
);
3981 tcg_gen_shri_tl(cpu_gpr
[rt
], t0
, uimm
);
3985 tcg_gen_rotri_tl(cpu_gpr
[rt
], t0
, uimm
);
3987 tcg_gen_mov_tl(cpu_gpr
[rt
], t0
);
3991 tcg_gen_shli_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
3994 tcg_gen_sari_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
3997 tcg_gen_shri_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
4000 tcg_gen_rotri_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
4008 static void gen_arith(DisasContext
*ctx
, uint32_t opc
,
4009 int rd
, int rs
, int rt
)
4011 if (rd
== 0 && opc
!= OPC_ADD
&& opc
!= OPC_SUB
4012 && opc
!= OPC_DADD
&& opc
!= OPC_DSUB
) {
4014 * If no destination, treat it as a NOP.
4015 * For add & sub, we must generate the overflow exception when needed.
4023 TCGv t0
= tcg_temp_local_new();
4024 TCGv t1
= tcg_temp_new();
4025 TCGv t2
= tcg_temp_new();
4026 TCGLabel
*l1
= gen_new_label();
4028 gen_load_gpr(t1
, rs
);
4029 gen_load_gpr(t2
, rt
);
4030 tcg_gen_add_tl(t0
, t1
, t2
);
4031 tcg_gen_ext32s_tl(t0
, t0
);
4032 tcg_gen_xor_tl(t1
, t1
, t2
);
4033 tcg_gen_xor_tl(t2
, t0
, t2
);
4034 tcg_gen_andc_tl(t1
, t2
, t1
);
4036 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
4038 /* operands of same sign, result different sign */
4039 generate_exception(ctx
, EXCP_OVERFLOW
);
4041 gen_store_gpr(t0
, rd
);
4046 if (rs
!= 0 && rt
!= 0) {
4047 tcg_gen_add_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
4048 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
4049 } else if (rs
== 0 && rt
!= 0) {
4050 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
4051 } else if (rs
!= 0 && rt
== 0) {
4052 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
4054 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4059 TCGv t0
= tcg_temp_local_new();
4060 TCGv t1
= tcg_temp_new();
4061 TCGv t2
= tcg_temp_new();
4062 TCGLabel
*l1
= gen_new_label();
4064 gen_load_gpr(t1
, rs
);
4065 gen_load_gpr(t2
, rt
);
4066 tcg_gen_sub_tl(t0
, t1
, t2
);
4067 tcg_gen_ext32s_tl(t0
, t0
);
4068 tcg_gen_xor_tl(t2
, t1
, t2
);
4069 tcg_gen_xor_tl(t1
, t0
, t1
);
4070 tcg_gen_and_tl(t1
, t1
, t2
);
4072 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
4075 * operands of different sign, first operand and the result
4078 generate_exception(ctx
, EXCP_OVERFLOW
);
4080 gen_store_gpr(t0
, rd
);
4085 if (rs
!= 0 && rt
!= 0) {
4086 tcg_gen_sub_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
4087 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
4088 } else if (rs
== 0 && rt
!= 0) {
4089 tcg_gen_neg_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
4090 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
4091 } else if (rs
!= 0 && rt
== 0) {
4092 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
4094 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4097 #if defined(TARGET_MIPS64)
4100 TCGv t0
= tcg_temp_local_new();
4101 TCGv t1
= tcg_temp_new();
4102 TCGv t2
= tcg_temp_new();
4103 TCGLabel
*l1
= gen_new_label();
4105 gen_load_gpr(t1
, rs
);
4106 gen_load_gpr(t2
, rt
);
4107 tcg_gen_add_tl(t0
, t1
, t2
);
4108 tcg_gen_xor_tl(t1
, t1
, t2
);
4109 tcg_gen_xor_tl(t2
, t0
, t2
);
4110 tcg_gen_andc_tl(t1
, t2
, t1
);
4112 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
4114 /* operands of same sign, result different sign */
4115 generate_exception(ctx
, EXCP_OVERFLOW
);
4117 gen_store_gpr(t0
, rd
);
4122 if (rs
!= 0 && rt
!= 0) {
4123 tcg_gen_add_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
4124 } else if (rs
== 0 && rt
!= 0) {
4125 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
4126 } else if (rs
!= 0 && rt
== 0) {
4127 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
4129 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4134 TCGv t0
= tcg_temp_local_new();
4135 TCGv t1
= tcg_temp_new();
4136 TCGv t2
= tcg_temp_new();
4137 TCGLabel
*l1
= gen_new_label();
4139 gen_load_gpr(t1
, rs
);
4140 gen_load_gpr(t2
, rt
);
4141 tcg_gen_sub_tl(t0
, t1
, t2
);
4142 tcg_gen_xor_tl(t2
, t1
, t2
);
4143 tcg_gen_xor_tl(t1
, t0
, t1
);
4144 tcg_gen_and_tl(t1
, t1
, t2
);
4146 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
4149 * Operands of different sign, first operand and result different
4152 generate_exception(ctx
, EXCP_OVERFLOW
);
4154 gen_store_gpr(t0
, rd
);
4159 if (rs
!= 0 && rt
!= 0) {
4160 tcg_gen_sub_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
4161 } else if (rs
== 0 && rt
!= 0) {
4162 tcg_gen_neg_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
4163 } else if (rs
!= 0 && rt
== 0) {
4164 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
4166 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4171 if (likely(rs
!= 0 && rt
!= 0)) {
4172 tcg_gen_mul_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
4173 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
4175 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4181 /* Conditional move */
4182 static void gen_cond_move(DisasContext
*ctx
, uint32_t opc
,
4183 int rd
, int rs
, int rt
)
4188 /* If no destination, treat it as a NOP. */
4192 t0
= tcg_temp_new();
4193 gen_load_gpr(t0
, rt
);
4194 t1
= tcg_const_tl(0);
4195 t2
= tcg_temp_new();
4196 gen_load_gpr(t2
, rs
);
4199 tcg_gen_movcond_tl(TCG_COND_NE
, cpu_gpr
[rd
], t0
, t1
, t2
, cpu_gpr
[rd
]);
4202 tcg_gen_movcond_tl(TCG_COND_EQ
, cpu_gpr
[rd
], t0
, t1
, t2
, cpu_gpr
[rd
]);
4205 tcg_gen_movcond_tl(TCG_COND_NE
, cpu_gpr
[rd
], t0
, t1
, t2
, t1
);
4208 tcg_gen_movcond_tl(TCG_COND_EQ
, cpu_gpr
[rd
], t0
, t1
, t2
, t1
);
4217 static void gen_logic(DisasContext
*ctx
, uint32_t opc
,
4218 int rd
, int rs
, int rt
)
4221 /* If no destination, treat it as a NOP. */
4227 if (likely(rs
!= 0 && rt
!= 0)) {
4228 tcg_gen_and_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
4230 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4234 if (rs
!= 0 && rt
!= 0) {
4235 tcg_gen_nor_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
4236 } else if (rs
== 0 && rt
!= 0) {
4237 tcg_gen_not_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
4238 } else if (rs
!= 0 && rt
== 0) {
4239 tcg_gen_not_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
4241 tcg_gen_movi_tl(cpu_gpr
[rd
], ~((target_ulong
)0));
4245 if (likely(rs
!= 0 && rt
!= 0)) {
4246 tcg_gen_or_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
4247 } else if (rs
== 0 && rt
!= 0) {
4248 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
4249 } else if (rs
!= 0 && rt
== 0) {
4250 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
4252 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4256 if (likely(rs
!= 0 && rt
!= 0)) {
4257 tcg_gen_xor_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
4258 } else if (rs
== 0 && rt
!= 0) {
4259 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
4260 } else if (rs
!= 0 && rt
== 0) {
4261 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
4263 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4269 /* Set on lower than */
4270 static void gen_slt(DisasContext
*ctx
, uint32_t opc
,
4271 int rd
, int rs
, int rt
)
4276 /* If no destination, treat it as a NOP. */
4280 t0
= tcg_temp_new();
4281 t1
= tcg_temp_new();
4282 gen_load_gpr(t0
, rs
);
4283 gen_load_gpr(t1
, rt
);
4286 tcg_gen_setcond_tl(TCG_COND_LT
, cpu_gpr
[rd
], t0
, t1
);
4289 tcg_gen_setcond_tl(TCG_COND_LTU
, cpu_gpr
[rd
], t0
, t1
);
4297 static void gen_shift(DisasContext
*ctx
, uint32_t opc
,
4298 int rd
, int rs
, int rt
)
4304 * If no destination, treat it as a NOP.
4305 * For add & sub, we must generate the overflow exception when needed.
4310 t0
= tcg_temp_new();
4311 t1
= tcg_temp_new();
4312 gen_load_gpr(t0
, rs
);
4313 gen_load_gpr(t1
, rt
);
4316 tcg_gen_andi_tl(t0
, t0
, 0x1f);
4317 tcg_gen_shl_tl(t0
, t1
, t0
);
4318 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
4321 tcg_gen_andi_tl(t0
, t0
, 0x1f);
4322 tcg_gen_sar_tl(cpu_gpr
[rd
], t1
, t0
);
4325 tcg_gen_ext32u_tl(t1
, t1
);
4326 tcg_gen_andi_tl(t0
, t0
, 0x1f);
4327 tcg_gen_shr_tl(t0
, t1
, t0
);
4328 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
4332 TCGv_i32 t2
= tcg_temp_new_i32();
4333 TCGv_i32 t3
= tcg_temp_new_i32();
4335 tcg_gen_trunc_tl_i32(t2
, t0
);
4336 tcg_gen_trunc_tl_i32(t3
, t1
);
4337 tcg_gen_andi_i32(t2
, t2
, 0x1f);
4338 tcg_gen_rotr_i32(t2
, t3
, t2
);
4339 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
4340 tcg_temp_free_i32(t2
);
4341 tcg_temp_free_i32(t3
);
4344 #if defined(TARGET_MIPS64)
4346 tcg_gen_andi_tl(t0
, t0
, 0x3f);
4347 tcg_gen_shl_tl(cpu_gpr
[rd
], t1
, t0
);
4350 tcg_gen_andi_tl(t0
, t0
, 0x3f);
4351 tcg_gen_sar_tl(cpu_gpr
[rd
], t1
, t0
);
4354 tcg_gen_andi_tl(t0
, t0
, 0x3f);
4355 tcg_gen_shr_tl(cpu_gpr
[rd
], t1
, t0
);
4358 tcg_gen_andi_tl(t0
, t0
, 0x3f);
4359 tcg_gen_rotr_tl(cpu_gpr
[rd
], t1
, t0
);
4367 #if defined(TARGET_MIPS64)
4368 /* Copy GPR to and from TX79 HI1/LO1 register. */
4369 static void gen_HILO1_tx79(DisasContext
*ctx
, uint32_t opc
, int reg
)
4371 if (reg
== 0 && (opc
== MMI_OPC_MFHI1
|| opc
== MMI_OPC_MFLO1
)) {
4378 tcg_gen_mov_tl(cpu_gpr
[reg
], cpu_HI
[1]);
4381 tcg_gen_mov_tl(cpu_gpr
[reg
], cpu_LO
[1]);
4385 tcg_gen_mov_tl(cpu_HI
[1], cpu_gpr
[reg
]);
4387 tcg_gen_movi_tl(cpu_HI
[1], 0);
4392 tcg_gen_mov_tl(cpu_LO
[1], cpu_gpr
[reg
]);
4394 tcg_gen_movi_tl(cpu_LO
[1], 0);
4398 MIPS_INVAL("mfthilo1 TX79");
4399 gen_reserved_instruction(ctx
);
4405 /* Arithmetic on HI/LO registers */
4406 static void gen_HILO(DisasContext
*ctx
, uint32_t opc
, int acc
, int reg
)
4408 if (reg
== 0 && (opc
== OPC_MFHI
|| opc
== OPC_MFLO
)) {
4419 #if defined(TARGET_MIPS64)
4421 tcg_gen_ext32s_tl(cpu_gpr
[reg
], cpu_HI
[acc
]);
4425 tcg_gen_mov_tl(cpu_gpr
[reg
], cpu_HI
[acc
]);
4429 #if defined(TARGET_MIPS64)
4431 tcg_gen_ext32s_tl(cpu_gpr
[reg
], cpu_LO
[acc
]);
4435 tcg_gen_mov_tl(cpu_gpr
[reg
], cpu_LO
[acc
]);
4440 #if defined(TARGET_MIPS64)
4442 tcg_gen_ext32s_tl(cpu_HI
[acc
], cpu_gpr
[reg
]);
4446 tcg_gen_mov_tl(cpu_HI
[acc
], cpu_gpr
[reg
]);
4449 tcg_gen_movi_tl(cpu_HI
[acc
], 0);
4454 #if defined(TARGET_MIPS64)
4456 tcg_gen_ext32s_tl(cpu_LO
[acc
], cpu_gpr
[reg
]);
4460 tcg_gen_mov_tl(cpu_LO
[acc
], cpu_gpr
[reg
]);
4463 tcg_gen_movi_tl(cpu_LO
[acc
], 0);
4469 static inline void gen_r6_ld(target_long addr
, int reg
, int memidx
,
4472 TCGv t0
= tcg_const_tl(addr
);
4473 tcg_gen_qemu_ld_tl(t0
, t0
, memidx
, memop
);
4474 gen_store_gpr(t0
, reg
);
4478 static inline void gen_pcrel(DisasContext
*ctx
, int opc
, target_ulong pc
,
4484 switch (MASK_OPC_PCREL_TOP2BITS(opc
)) {
4487 offset
= sextract32(ctx
->opcode
<< 2, 0, 21);
4488 addr
= addr_add(ctx
, pc
, offset
);
4489 tcg_gen_movi_tl(cpu_gpr
[rs
], addr
);
4493 offset
= sextract32(ctx
->opcode
<< 2, 0, 21);
4494 addr
= addr_add(ctx
, pc
, offset
);
4495 gen_r6_ld(addr
, rs
, ctx
->mem_idx
, MO_TESL
);
4497 #if defined(TARGET_MIPS64)
4500 offset
= sextract32(ctx
->opcode
<< 2, 0, 21);
4501 addr
= addr_add(ctx
, pc
, offset
);
4502 gen_r6_ld(addr
, rs
, ctx
->mem_idx
, MO_TEUL
);
4506 switch (MASK_OPC_PCREL_TOP5BITS(opc
)) {
4509 offset
= sextract32(ctx
->opcode
, 0, 16) << 16;
4510 addr
= addr_add(ctx
, pc
, offset
);
4511 tcg_gen_movi_tl(cpu_gpr
[rs
], addr
);
4516 offset
= sextract32(ctx
->opcode
, 0, 16) << 16;
4517 addr
= ~0xFFFF & addr_add(ctx
, pc
, offset
);
4518 tcg_gen_movi_tl(cpu_gpr
[rs
], addr
);
4521 #if defined(TARGET_MIPS64)
4522 case R6_OPC_LDPC
: /* bits 16 and 17 are part of immediate */
4523 case R6_OPC_LDPC
+ (1 << 16):
4524 case R6_OPC_LDPC
+ (2 << 16):
4525 case R6_OPC_LDPC
+ (3 << 16):
4527 offset
= sextract32(ctx
->opcode
<< 3, 0, 21);
4528 addr
= addr_add(ctx
, (pc
& ~0x7), offset
);
4529 gen_r6_ld(addr
, rs
, ctx
->mem_idx
, MO_TEQ
);
4533 MIPS_INVAL("OPC_PCREL");
4534 gen_reserved_instruction(ctx
);
4541 static void gen_r6_muldiv(DisasContext
*ctx
, int opc
, int rd
, int rs
, int rt
)
4550 t0
= tcg_temp_new();
4551 t1
= tcg_temp_new();
4553 gen_load_gpr(t0
, rs
);
4554 gen_load_gpr(t1
, rt
);
4559 TCGv t2
= tcg_temp_new();
4560 TCGv t3
= tcg_temp_new();
4561 tcg_gen_ext32s_tl(t0
, t0
);
4562 tcg_gen_ext32s_tl(t1
, t1
);
4563 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, INT_MIN
);
4564 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1);
4565 tcg_gen_and_tl(t2
, t2
, t3
);
4566 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
4567 tcg_gen_or_tl(t2
, t2
, t3
);
4568 tcg_gen_movi_tl(t3
, 0);
4569 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
4570 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
4571 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
4578 TCGv t2
= tcg_temp_new();
4579 TCGv t3
= tcg_temp_new();
4580 tcg_gen_ext32s_tl(t0
, t0
);
4581 tcg_gen_ext32s_tl(t1
, t1
);
4582 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, INT_MIN
);
4583 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1);
4584 tcg_gen_and_tl(t2
, t2
, t3
);
4585 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
4586 tcg_gen_or_tl(t2
, t2
, t3
);
4587 tcg_gen_movi_tl(t3
, 0);
4588 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
4589 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
4590 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
4597 TCGv t2
= tcg_const_tl(0);
4598 TCGv t3
= tcg_const_tl(1);
4599 tcg_gen_ext32u_tl(t0
, t0
);
4600 tcg_gen_ext32u_tl(t1
, t1
);
4601 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
4602 tcg_gen_divu_tl(cpu_gpr
[rd
], t0
, t1
);
4603 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
4610 TCGv t2
= tcg_const_tl(0);
4611 TCGv t3
= tcg_const_tl(1);
4612 tcg_gen_ext32u_tl(t0
, t0
);
4613 tcg_gen_ext32u_tl(t1
, t1
);
4614 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
4615 tcg_gen_remu_tl(cpu_gpr
[rd
], t0
, t1
);
4616 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
4623 TCGv_i32 t2
= tcg_temp_new_i32();
4624 TCGv_i32 t3
= tcg_temp_new_i32();
4625 tcg_gen_trunc_tl_i32(t2
, t0
);
4626 tcg_gen_trunc_tl_i32(t3
, t1
);
4627 tcg_gen_mul_i32(t2
, t2
, t3
);
4628 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
4629 tcg_temp_free_i32(t2
);
4630 tcg_temp_free_i32(t3
);
4635 TCGv_i32 t2
= tcg_temp_new_i32();
4636 TCGv_i32 t3
= tcg_temp_new_i32();
4637 tcg_gen_trunc_tl_i32(t2
, t0
);
4638 tcg_gen_trunc_tl_i32(t3
, t1
);
4639 tcg_gen_muls2_i32(t2
, t3
, t2
, t3
);
4640 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t3
);
4641 tcg_temp_free_i32(t2
);
4642 tcg_temp_free_i32(t3
);
4647 TCGv_i32 t2
= tcg_temp_new_i32();
4648 TCGv_i32 t3
= tcg_temp_new_i32();
4649 tcg_gen_trunc_tl_i32(t2
, t0
);
4650 tcg_gen_trunc_tl_i32(t3
, t1
);
4651 tcg_gen_mul_i32(t2
, t2
, t3
);
4652 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
4653 tcg_temp_free_i32(t2
);
4654 tcg_temp_free_i32(t3
);
4659 TCGv_i32 t2
= tcg_temp_new_i32();
4660 TCGv_i32 t3
= tcg_temp_new_i32();
4661 tcg_gen_trunc_tl_i32(t2
, t0
);
4662 tcg_gen_trunc_tl_i32(t3
, t1
);
4663 tcg_gen_mulu2_i32(t2
, t3
, t2
, t3
);
4664 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t3
);
4665 tcg_temp_free_i32(t2
);
4666 tcg_temp_free_i32(t3
);
4669 #if defined(TARGET_MIPS64)
4672 TCGv t2
= tcg_temp_new();
4673 TCGv t3
= tcg_temp_new();
4674 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, -1LL << 63);
4675 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1LL);
4676 tcg_gen_and_tl(t2
, t2
, t3
);
4677 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
4678 tcg_gen_or_tl(t2
, t2
, t3
);
4679 tcg_gen_movi_tl(t3
, 0);
4680 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
4681 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
4688 TCGv t2
= tcg_temp_new();
4689 TCGv t3
= tcg_temp_new();
4690 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, -1LL << 63);
4691 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1LL);
4692 tcg_gen_and_tl(t2
, t2
, t3
);
4693 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
4694 tcg_gen_or_tl(t2
, t2
, t3
);
4695 tcg_gen_movi_tl(t3
, 0);
4696 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
4697 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
4704 TCGv t2
= tcg_const_tl(0);
4705 TCGv t3
= tcg_const_tl(1);
4706 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
4707 tcg_gen_divu_i64(cpu_gpr
[rd
], t0
, t1
);
4714 TCGv t2
= tcg_const_tl(0);
4715 TCGv t3
= tcg_const_tl(1);
4716 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
4717 tcg_gen_remu_i64(cpu_gpr
[rd
], t0
, t1
);
4723 tcg_gen_mul_i64(cpu_gpr
[rd
], t0
, t1
);
4727 TCGv t2
= tcg_temp_new();
4728 tcg_gen_muls2_i64(t2
, cpu_gpr
[rd
], t0
, t1
);
4733 tcg_gen_mul_i64(cpu_gpr
[rd
], t0
, t1
);
4737 TCGv t2
= tcg_temp_new();
4738 tcg_gen_mulu2_i64(t2
, cpu_gpr
[rd
], t0
, t1
);
4744 MIPS_INVAL("r6 mul/div");
4745 gen_reserved_instruction(ctx
);
4753 #if defined(TARGET_MIPS64)
4754 static void gen_div1_tx79(DisasContext
*ctx
, uint32_t opc
, int rs
, int rt
)
4758 t0
= tcg_temp_new();
4759 t1
= tcg_temp_new();
4761 gen_load_gpr(t0
, rs
);
4762 gen_load_gpr(t1
, rt
);
4767 TCGv t2
= tcg_temp_new();
4768 TCGv t3
= tcg_temp_new();
4769 tcg_gen_ext32s_tl(t0
, t0
);
4770 tcg_gen_ext32s_tl(t1
, t1
);
4771 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, INT_MIN
);
4772 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1);
4773 tcg_gen_and_tl(t2
, t2
, t3
);
4774 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
4775 tcg_gen_or_tl(t2
, t2
, t3
);
4776 tcg_gen_movi_tl(t3
, 0);
4777 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
4778 tcg_gen_div_tl(cpu_LO
[1], t0
, t1
);
4779 tcg_gen_rem_tl(cpu_HI
[1], t0
, t1
);
4780 tcg_gen_ext32s_tl(cpu_LO
[1], cpu_LO
[1]);
4781 tcg_gen_ext32s_tl(cpu_HI
[1], cpu_HI
[1]);
4788 TCGv t2
= tcg_const_tl(0);
4789 TCGv t3
= tcg_const_tl(1);
4790 tcg_gen_ext32u_tl(t0
, t0
);
4791 tcg_gen_ext32u_tl(t1
, t1
);
4792 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
4793 tcg_gen_divu_tl(cpu_LO
[1], t0
, t1
);
4794 tcg_gen_remu_tl(cpu_HI
[1], t0
, t1
);
4795 tcg_gen_ext32s_tl(cpu_LO
[1], cpu_LO
[1]);
4796 tcg_gen_ext32s_tl(cpu_HI
[1], cpu_HI
[1]);
4802 MIPS_INVAL("div1 TX79");
4803 gen_reserved_instruction(ctx
);
4812 static void gen_muldiv(DisasContext
*ctx
, uint32_t opc
,
4813 int acc
, int rs
, int rt
)
4817 t0
= tcg_temp_new();
4818 t1
= tcg_temp_new();
4820 gen_load_gpr(t0
, rs
);
4821 gen_load_gpr(t1
, rt
);
4830 TCGv t2
= tcg_temp_new();
4831 TCGv t3
= tcg_temp_new();
4832 tcg_gen_ext32s_tl(t0
, t0
);
4833 tcg_gen_ext32s_tl(t1
, t1
);
4834 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, INT_MIN
);
4835 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1);
4836 tcg_gen_and_tl(t2
, t2
, t3
);
4837 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
4838 tcg_gen_or_tl(t2
, t2
, t3
);
4839 tcg_gen_movi_tl(t3
, 0);
4840 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
4841 tcg_gen_div_tl(cpu_LO
[acc
], t0
, t1
);
4842 tcg_gen_rem_tl(cpu_HI
[acc
], t0
, t1
);
4843 tcg_gen_ext32s_tl(cpu_LO
[acc
], cpu_LO
[acc
]);
4844 tcg_gen_ext32s_tl(cpu_HI
[acc
], cpu_HI
[acc
]);
4851 TCGv t2
= tcg_const_tl(0);
4852 TCGv t3
= tcg_const_tl(1);
4853 tcg_gen_ext32u_tl(t0
, t0
);
4854 tcg_gen_ext32u_tl(t1
, t1
);
4855 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
4856 tcg_gen_divu_tl(cpu_LO
[acc
], t0
, t1
);
4857 tcg_gen_remu_tl(cpu_HI
[acc
], t0
, t1
);
4858 tcg_gen_ext32s_tl(cpu_LO
[acc
], cpu_LO
[acc
]);
4859 tcg_gen_ext32s_tl(cpu_HI
[acc
], cpu_HI
[acc
]);
4866 TCGv_i32 t2
= tcg_temp_new_i32();
4867 TCGv_i32 t3
= tcg_temp_new_i32();
4868 tcg_gen_trunc_tl_i32(t2
, t0
);
4869 tcg_gen_trunc_tl_i32(t3
, t1
);
4870 tcg_gen_muls2_i32(t2
, t3
, t2
, t3
);
4871 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
4872 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
4873 tcg_temp_free_i32(t2
);
4874 tcg_temp_free_i32(t3
);
4879 TCGv_i32 t2
= tcg_temp_new_i32();
4880 TCGv_i32 t3
= tcg_temp_new_i32();
4881 tcg_gen_trunc_tl_i32(t2
, t0
);
4882 tcg_gen_trunc_tl_i32(t3
, t1
);
4883 tcg_gen_mulu2_i32(t2
, t3
, t2
, t3
);
4884 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
4885 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
4886 tcg_temp_free_i32(t2
);
4887 tcg_temp_free_i32(t3
);
4890 #if defined(TARGET_MIPS64)
4893 TCGv t2
= tcg_temp_new();
4894 TCGv t3
= tcg_temp_new();
4895 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, -1LL << 63);
4896 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1LL);
4897 tcg_gen_and_tl(t2
, t2
, t3
);
4898 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
4899 tcg_gen_or_tl(t2
, t2
, t3
);
4900 tcg_gen_movi_tl(t3
, 0);
4901 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
4902 tcg_gen_div_tl(cpu_LO
[acc
], t0
, t1
);
4903 tcg_gen_rem_tl(cpu_HI
[acc
], t0
, t1
);
4910 TCGv t2
= tcg_const_tl(0);
4911 TCGv t3
= tcg_const_tl(1);
4912 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
4913 tcg_gen_divu_i64(cpu_LO
[acc
], t0
, t1
);
4914 tcg_gen_remu_i64(cpu_HI
[acc
], t0
, t1
);
4920 tcg_gen_muls2_i64(cpu_LO
[acc
], cpu_HI
[acc
], t0
, t1
);
4923 tcg_gen_mulu2_i64(cpu_LO
[acc
], cpu_HI
[acc
], t0
, t1
);
4928 TCGv_i64 t2
= tcg_temp_new_i64();
4929 TCGv_i64 t3
= tcg_temp_new_i64();
4931 tcg_gen_ext_tl_i64(t2
, t0
);
4932 tcg_gen_ext_tl_i64(t3
, t1
);
4933 tcg_gen_mul_i64(t2
, t2
, t3
);
4934 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
4935 tcg_gen_add_i64(t2
, t2
, t3
);
4936 tcg_temp_free_i64(t3
);
4937 gen_move_low32(cpu_LO
[acc
], t2
);
4938 gen_move_high32(cpu_HI
[acc
], t2
);
4939 tcg_temp_free_i64(t2
);
4944 TCGv_i64 t2
= tcg_temp_new_i64();
4945 TCGv_i64 t3
= tcg_temp_new_i64();
4947 tcg_gen_ext32u_tl(t0
, t0
);
4948 tcg_gen_ext32u_tl(t1
, t1
);
4949 tcg_gen_extu_tl_i64(t2
, t0
);
4950 tcg_gen_extu_tl_i64(t3
, t1
);
4951 tcg_gen_mul_i64(t2
, t2
, t3
);
4952 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
4953 tcg_gen_add_i64(t2
, t2
, t3
);
4954 tcg_temp_free_i64(t3
);
4955 gen_move_low32(cpu_LO
[acc
], t2
);
4956 gen_move_high32(cpu_HI
[acc
], t2
);
4957 tcg_temp_free_i64(t2
);
4962 TCGv_i64 t2
= tcg_temp_new_i64();
4963 TCGv_i64 t3
= tcg_temp_new_i64();
4965 tcg_gen_ext_tl_i64(t2
, t0
);
4966 tcg_gen_ext_tl_i64(t3
, t1
);
4967 tcg_gen_mul_i64(t2
, t2
, t3
);
4968 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
4969 tcg_gen_sub_i64(t2
, t3
, t2
);
4970 tcg_temp_free_i64(t3
);
4971 gen_move_low32(cpu_LO
[acc
], t2
);
4972 gen_move_high32(cpu_HI
[acc
], t2
);
4973 tcg_temp_free_i64(t2
);
4978 TCGv_i64 t2
= tcg_temp_new_i64();
4979 TCGv_i64 t3
= tcg_temp_new_i64();
4981 tcg_gen_ext32u_tl(t0
, t0
);
4982 tcg_gen_ext32u_tl(t1
, t1
);
4983 tcg_gen_extu_tl_i64(t2
, t0
);
4984 tcg_gen_extu_tl_i64(t3
, t1
);
4985 tcg_gen_mul_i64(t2
, t2
, t3
);
4986 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
4987 tcg_gen_sub_i64(t2
, t3
, t2
);
4988 tcg_temp_free_i64(t3
);
4989 gen_move_low32(cpu_LO
[acc
], t2
);
4990 gen_move_high32(cpu_HI
[acc
], t2
);
4991 tcg_temp_free_i64(t2
);
4995 MIPS_INVAL("mul/div");
4996 gen_reserved_instruction(ctx
);
5005 * These MULT[U] and MADD[U] instructions implemented in for example
5006 * the Toshiba/Sony R5900 and the Toshiba TX19, TX39 and TX79 core
5007 * architectures are special three-operand variants with the syntax
5009 * MULT[U][1] rd, rs, rt
5013 * (rd, LO, HI) <- rs * rt
5017 * MADD[U][1] rd, rs, rt
5021 * (rd, LO, HI) <- (LO, HI) + rs * rt
5023 * where the low-order 32-bits of the result is placed into both the
5024 * GPR rd and the special register LO. The high-order 32-bits of the
5025 * result is placed into the special register HI.
5027 * If the GPR rd is omitted in assembly language, it is taken to be 0,
5028 * which is the zero register that always reads as 0.
5030 static void gen_mul_txx9(DisasContext
*ctx
, uint32_t opc
,
5031 int rd
, int rs
, int rt
)
5033 TCGv t0
= tcg_temp_new();
5034 TCGv t1
= tcg_temp_new();
5037 gen_load_gpr(t0
, rs
);
5038 gen_load_gpr(t1
, rt
);
5046 TCGv_i32 t2
= tcg_temp_new_i32();
5047 TCGv_i32 t3
= tcg_temp_new_i32();
5048 tcg_gen_trunc_tl_i32(t2
, t0
);
5049 tcg_gen_trunc_tl_i32(t3
, t1
);
5050 tcg_gen_muls2_i32(t2
, t3
, t2
, t3
);
5052 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
5054 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
5055 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
5056 tcg_temp_free_i32(t2
);
5057 tcg_temp_free_i32(t3
);
5060 case MMI_OPC_MULTU1
:
5065 TCGv_i32 t2
= tcg_temp_new_i32();
5066 TCGv_i32 t3
= tcg_temp_new_i32();
5067 tcg_gen_trunc_tl_i32(t2
, t0
);
5068 tcg_gen_trunc_tl_i32(t3
, t1
);
5069 tcg_gen_mulu2_i32(t2
, t3
, t2
, t3
);
5071 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
5073 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
5074 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
5075 tcg_temp_free_i32(t2
);
5076 tcg_temp_free_i32(t3
);
5084 TCGv_i64 t2
= tcg_temp_new_i64();
5085 TCGv_i64 t3
= tcg_temp_new_i64();
5087 tcg_gen_ext_tl_i64(t2
, t0
);
5088 tcg_gen_ext_tl_i64(t3
, t1
);
5089 tcg_gen_mul_i64(t2
, t2
, t3
);
5090 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
5091 tcg_gen_add_i64(t2
, t2
, t3
);
5092 tcg_temp_free_i64(t3
);
5093 gen_move_low32(cpu_LO
[acc
], t2
);
5094 gen_move_high32(cpu_HI
[acc
], t2
);
5096 gen_move_low32(cpu_gpr
[rd
], t2
);
5098 tcg_temp_free_i64(t2
);
5101 case MMI_OPC_MADDU1
:
5106 TCGv_i64 t2
= tcg_temp_new_i64();
5107 TCGv_i64 t3
= tcg_temp_new_i64();
5109 tcg_gen_ext32u_tl(t0
, t0
);
5110 tcg_gen_ext32u_tl(t1
, t1
);
5111 tcg_gen_extu_tl_i64(t2
, t0
);
5112 tcg_gen_extu_tl_i64(t3
, t1
);
5113 tcg_gen_mul_i64(t2
, t2
, t3
);
5114 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
5115 tcg_gen_add_i64(t2
, t2
, t3
);
5116 tcg_temp_free_i64(t3
);
5117 gen_move_low32(cpu_LO
[acc
], t2
);
5118 gen_move_high32(cpu_HI
[acc
], t2
);
5120 gen_move_low32(cpu_gpr
[rd
], t2
);
5122 tcg_temp_free_i64(t2
);
5126 MIPS_INVAL("mul/madd TXx9");
5127 gen_reserved_instruction(ctx
);
5136 static void gen_mul_vr54xx(DisasContext
*ctx
, uint32_t opc
,
5137 int rd
, int rs
, int rt
)
5139 TCGv t0
= tcg_temp_new();
5140 TCGv t1
= tcg_temp_new();
5142 gen_load_gpr(t0
, rs
);
5143 gen_load_gpr(t1
, rt
);
5146 case OPC_VR54XX_MULS
:
5147 gen_helper_muls(t0
, cpu_env
, t0
, t1
);
5149 case OPC_VR54XX_MULSU
:
5150 gen_helper_mulsu(t0
, cpu_env
, t0
, t1
);
5152 case OPC_VR54XX_MACC
:
5153 gen_helper_macc(t0
, cpu_env
, t0
, t1
);
5155 case OPC_VR54XX_MACCU
:
5156 gen_helper_maccu(t0
, cpu_env
, t0
, t1
);
5158 case OPC_VR54XX_MSAC
:
5159 gen_helper_msac(t0
, cpu_env
, t0
, t1
);
5161 case OPC_VR54XX_MSACU
:
5162 gen_helper_msacu(t0
, cpu_env
, t0
, t1
);
5164 case OPC_VR54XX_MULHI
:
5165 gen_helper_mulhi(t0
, cpu_env
, t0
, t1
);
5167 case OPC_VR54XX_MULHIU
:
5168 gen_helper_mulhiu(t0
, cpu_env
, t0
, t1
);
5170 case OPC_VR54XX_MULSHI
:
5171 gen_helper_mulshi(t0
, cpu_env
, t0
, t1
);
5173 case OPC_VR54XX_MULSHIU
:
5174 gen_helper_mulshiu(t0
, cpu_env
, t0
, t1
);
5176 case OPC_VR54XX_MACCHI
:
5177 gen_helper_macchi(t0
, cpu_env
, t0
, t1
);
5179 case OPC_VR54XX_MACCHIU
:
5180 gen_helper_macchiu(t0
, cpu_env
, t0
, t1
);
5182 case OPC_VR54XX_MSACHI
:
5183 gen_helper_msachi(t0
, cpu_env
, t0
, t1
);
5185 case OPC_VR54XX_MSACHIU
:
5186 gen_helper_msachiu(t0
, cpu_env
, t0
, t1
);
5189 MIPS_INVAL("mul vr54xx");
5190 gen_reserved_instruction(ctx
);
5193 gen_store_gpr(t0
, rd
);
5200 static void gen_cl(DisasContext
*ctx
, uint32_t opc
,
5210 gen_load_gpr(t0
, rs
);
5215 #if defined(TARGET_MIPS64)
5219 tcg_gen_not_tl(t0
, t0
);
5228 tcg_gen_ext32u_tl(t0
, t0
);
5229 tcg_gen_clzi_tl(t0
, t0
, TARGET_LONG_BITS
);
5230 tcg_gen_subi_tl(t0
, t0
, TARGET_LONG_BITS
- 32);
5232 #if defined(TARGET_MIPS64)
5237 tcg_gen_clzi_i64(t0
, t0
, 64);
5243 /* Godson integer instructions */
5244 static void gen_loongson_integer(DisasContext
*ctx
, uint32_t opc
,
5245 int rd
, int rs
, int rt
)
5257 case OPC_MULTU_G_2E
:
5258 case OPC_MULTU_G_2F
:
5259 #if defined(TARGET_MIPS64)
5260 case OPC_DMULT_G_2E
:
5261 case OPC_DMULT_G_2F
:
5262 case OPC_DMULTU_G_2E
:
5263 case OPC_DMULTU_G_2F
:
5265 t0
= tcg_temp_new();
5266 t1
= tcg_temp_new();
5269 t0
= tcg_temp_local_new();
5270 t1
= tcg_temp_local_new();
5274 gen_load_gpr(t0
, rs
);
5275 gen_load_gpr(t1
, rt
);
5280 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
5281 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
5283 case OPC_MULTU_G_2E
:
5284 case OPC_MULTU_G_2F
:
5285 tcg_gen_ext32u_tl(t0
, t0
);
5286 tcg_gen_ext32u_tl(t1
, t1
);
5287 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
5288 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
5293 TCGLabel
*l1
= gen_new_label();
5294 TCGLabel
*l2
= gen_new_label();
5295 TCGLabel
*l3
= gen_new_label();
5296 tcg_gen_ext32s_tl(t0
, t0
);
5297 tcg_gen_ext32s_tl(t1
, t1
);
5298 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
5299 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
5302 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, INT_MIN
, l2
);
5303 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1, l2
);
5304 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
5307 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
5308 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
5315 TCGLabel
*l1
= gen_new_label();
5316 TCGLabel
*l2
= gen_new_label();
5317 tcg_gen_ext32u_tl(t0
, t0
);
5318 tcg_gen_ext32u_tl(t1
, t1
);
5319 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
5320 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
5323 tcg_gen_divu_tl(cpu_gpr
[rd
], t0
, t1
);
5324 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
5331 TCGLabel
*l1
= gen_new_label();
5332 TCGLabel
*l2
= gen_new_label();
5333 TCGLabel
*l3
= gen_new_label();
5334 tcg_gen_ext32u_tl(t0
, t0
);
5335 tcg_gen_ext32u_tl(t1
, t1
);
5336 tcg_gen_brcondi_tl(TCG_COND_EQ
, t1
, 0, l1
);
5337 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, INT_MIN
, l2
);
5338 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1, l2
);
5340 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
5343 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
5344 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
5351 TCGLabel
*l1
= gen_new_label();
5352 TCGLabel
*l2
= gen_new_label();
5353 tcg_gen_ext32u_tl(t0
, t0
);
5354 tcg_gen_ext32u_tl(t1
, t1
);
5355 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
5356 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
5359 tcg_gen_remu_tl(cpu_gpr
[rd
], t0
, t1
);
5360 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
5364 #if defined(TARGET_MIPS64)
5365 case OPC_DMULT_G_2E
:
5366 case OPC_DMULT_G_2F
:
5367 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
5369 case OPC_DMULTU_G_2E
:
5370 case OPC_DMULTU_G_2F
:
5371 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
5376 TCGLabel
*l1
= gen_new_label();
5377 TCGLabel
*l2
= gen_new_label();
5378 TCGLabel
*l3
= gen_new_label();
5379 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
5380 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
5383 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, -1LL << 63, l2
);
5384 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1LL, l2
);
5385 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
5388 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
5392 case OPC_DDIVU_G_2E
:
5393 case OPC_DDIVU_G_2F
:
5395 TCGLabel
*l1
= gen_new_label();
5396 TCGLabel
*l2
= gen_new_label();
5397 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
5398 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
5401 tcg_gen_divu_tl(cpu_gpr
[rd
], t0
, t1
);
5408 TCGLabel
*l1
= gen_new_label();
5409 TCGLabel
*l2
= gen_new_label();
5410 TCGLabel
*l3
= gen_new_label();
5411 tcg_gen_brcondi_tl(TCG_COND_EQ
, t1
, 0, l1
);
5412 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, -1LL << 63, l2
);
5413 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1LL, l2
);
5415 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
5418 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
5422 case OPC_DMODU_G_2E
:
5423 case OPC_DMODU_G_2F
:
5425 TCGLabel
*l1
= gen_new_label();
5426 TCGLabel
*l2
= gen_new_label();
5427 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
5428 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
5431 tcg_gen_remu_tl(cpu_gpr
[rd
], t0
, t1
);
5442 /* Loongson multimedia instructions */
5443 static void gen_loongson_multimedia(DisasContext
*ctx
, int rd
, int rs
, int rt
)
5445 uint32_t opc
, shift_max
;
5449 opc
= MASK_LMMI(ctx
->opcode
);
5455 t0
= tcg_temp_local_new_i64();
5456 t1
= tcg_temp_local_new_i64();
5459 t0
= tcg_temp_new_i64();
5460 t1
= tcg_temp_new_i64();
5464 check_cp1_enabled(ctx
);
5465 gen_load_fpr64(ctx
, t0
, rs
);
5466 gen_load_fpr64(ctx
, t1
, rt
);
5470 gen_helper_paddsh(t0
, t0
, t1
);
5473 gen_helper_paddush(t0
, t0
, t1
);
5476 gen_helper_paddh(t0
, t0
, t1
);
5479 gen_helper_paddw(t0
, t0
, t1
);
5482 gen_helper_paddsb(t0
, t0
, t1
);
5485 gen_helper_paddusb(t0
, t0
, t1
);
5488 gen_helper_paddb(t0
, t0
, t1
);
5492 gen_helper_psubsh(t0
, t0
, t1
);
5495 gen_helper_psubush(t0
, t0
, t1
);
5498 gen_helper_psubh(t0
, t0
, t1
);
5501 gen_helper_psubw(t0
, t0
, t1
);
5504 gen_helper_psubsb(t0
, t0
, t1
);
5507 gen_helper_psubusb(t0
, t0
, t1
);
5510 gen_helper_psubb(t0
, t0
, t1
);
5514 gen_helper_pshufh(t0
, t0
, t1
);
5517 gen_helper_packsswh(t0
, t0
, t1
);
5520 gen_helper_packsshb(t0
, t0
, t1
);
5523 gen_helper_packushb(t0
, t0
, t1
);
5527 gen_helper_punpcklhw(t0
, t0
, t1
);
5530 gen_helper_punpckhhw(t0
, t0
, t1
);
5533 gen_helper_punpcklbh(t0
, t0
, t1
);
5536 gen_helper_punpckhbh(t0
, t0
, t1
);
5539 gen_helper_punpcklwd(t0
, t0
, t1
);
5542 gen_helper_punpckhwd(t0
, t0
, t1
);
5546 gen_helper_pavgh(t0
, t0
, t1
);
5549 gen_helper_pavgb(t0
, t0
, t1
);
5552 gen_helper_pmaxsh(t0
, t0
, t1
);
5555 gen_helper_pminsh(t0
, t0
, t1
);
5558 gen_helper_pmaxub(t0
, t0
, t1
);
5561 gen_helper_pminub(t0
, t0
, t1
);
5565 gen_helper_pcmpeqw(t0
, t0
, t1
);
5568 gen_helper_pcmpgtw(t0
, t0
, t1
);
5571 gen_helper_pcmpeqh(t0
, t0
, t1
);
5574 gen_helper_pcmpgth(t0
, t0
, t1
);
5577 gen_helper_pcmpeqb(t0
, t0
, t1
);
5580 gen_helper_pcmpgtb(t0
, t0
, t1
);
5584 gen_helper_psllw(t0
, t0
, t1
);
5587 gen_helper_psllh(t0
, t0
, t1
);
5590 gen_helper_psrlw(t0
, t0
, t1
);
5593 gen_helper_psrlh(t0
, t0
, t1
);
5596 gen_helper_psraw(t0
, t0
, t1
);
5599 gen_helper_psrah(t0
, t0
, t1
);
5603 gen_helper_pmullh(t0
, t0
, t1
);
5606 gen_helper_pmulhh(t0
, t0
, t1
);
5609 gen_helper_pmulhuh(t0
, t0
, t1
);
5612 gen_helper_pmaddhw(t0
, t0
, t1
);
5616 gen_helper_pasubub(t0
, t0
, t1
);
5619 gen_helper_biadd(t0
, t0
);
5622 gen_helper_pmovmskb(t0
, t0
);
5626 tcg_gen_add_i64(t0
, t0
, t1
);
5629 tcg_gen_sub_i64(t0
, t0
, t1
);
5632 tcg_gen_xor_i64(t0
, t0
, t1
);
5635 tcg_gen_nor_i64(t0
, t0
, t1
);
5638 tcg_gen_and_i64(t0
, t0
, t1
);
5641 tcg_gen_or_i64(t0
, t0
, t1
);
5645 tcg_gen_andc_i64(t0
, t1
, t0
);
5649 tcg_gen_deposit_i64(t0
, t0
, t1
, 0, 16);
5652 tcg_gen_deposit_i64(t0
, t0
, t1
, 16, 16);
5655 tcg_gen_deposit_i64(t0
, t0
, t1
, 32, 16);
5658 tcg_gen_deposit_i64(t0
, t0
, t1
, 48, 16);
5662 tcg_gen_andi_i64(t1
, t1
, 3);
5663 tcg_gen_shli_i64(t1
, t1
, 4);
5664 tcg_gen_shr_i64(t0
, t0
, t1
);
5665 tcg_gen_ext16u_i64(t0
, t0
);
5669 tcg_gen_add_i64(t0
, t0
, t1
);
5670 tcg_gen_ext32s_i64(t0
, t0
);
5673 tcg_gen_sub_i64(t0
, t0
, t1
);
5674 tcg_gen_ext32s_i64(t0
, t0
);
5696 /* Make sure shift count isn't TCG undefined behaviour. */
5697 tcg_gen_andi_i64(t1
, t1
, shift_max
- 1);
5702 tcg_gen_shl_i64(t0
, t0
, t1
);
5707 * Since SRA is UndefinedResult without sign-extended inputs,
5708 * we can treat SRA and DSRA the same.
5710 tcg_gen_sar_i64(t0
, t0
, t1
);
5713 /* We want to shift in zeros for SRL; zero-extend first. */
5714 tcg_gen_ext32u_i64(t0
, t0
);
5717 tcg_gen_shr_i64(t0
, t0
, t1
);
5721 if (shift_max
== 32) {
5722 tcg_gen_ext32s_i64(t0
, t0
);
5725 /* Shifts larger than MAX produce zero. */
5726 tcg_gen_setcondi_i64(TCG_COND_LTU
, t1
, t1
, shift_max
);
5727 tcg_gen_neg_i64(t1
, t1
);
5728 tcg_gen_and_i64(t0
, t0
, t1
);
5734 TCGv_i64 t2
= tcg_temp_new_i64();
5735 TCGLabel
*lab
= gen_new_label();
5737 tcg_gen_mov_i64(t2
, t0
);
5738 tcg_gen_add_i64(t0
, t1
, t2
);
5739 if (opc
== OPC_ADD_CP2
) {
5740 tcg_gen_ext32s_i64(t0
, t0
);
5742 tcg_gen_xor_i64(t1
, t1
, t2
);
5743 tcg_gen_xor_i64(t2
, t2
, t0
);
5744 tcg_gen_andc_i64(t1
, t2
, t1
);
5745 tcg_temp_free_i64(t2
);
5746 tcg_gen_brcondi_i64(TCG_COND_GE
, t1
, 0, lab
);
5747 generate_exception(ctx
, EXCP_OVERFLOW
);
5755 TCGv_i64 t2
= tcg_temp_new_i64();
5756 TCGLabel
*lab
= gen_new_label();
5758 tcg_gen_mov_i64(t2
, t0
);
5759 tcg_gen_sub_i64(t0
, t1
, t2
);
5760 if (opc
== OPC_SUB_CP2
) {
5761 tcg_gen_ext32s_i64(t0
, t0
);
5763 tcg_gen_xor_i64(t1
, t1
, t2
);
5764 tcg_gen_xor_i64(t2
, t2
, t0
);
5765 tcg_gen_and_i64(t1
, t1
, t2
);
5766 tcg_temp_free_i64(t2
);
5767 tcg_gen_brcondi_i64(TCG_COND_GE
, t1
, 0, lab
);
5768 generate_exception(ctx
, EXCP_OVERFLOW
);
5774 tcg_gen_ext32u_i64(t0
, t0
);
5775 tcg_gen_ext32u_i64(t1
, t1
);
5776 tcg_gen_mul_i64(t0
, t0
, t1
);
5785 cond
= TCG_COND_LTU
;
5793 cond
= TCG_COND_LEU
;
5800 int cc
= (ctx
->opcode
>> 8) & 0x7;
5801 TCGv_i64 t64
= tcg_temp_new_i64();
5802 TCGv_i32 t32
= tcg_temp_new_i32();
5804 tcg_gen_setcond_i64(cond
, t64
, t0
, t1
);
5805 tcg_gen_extrl_i64_i32(t32
, t64
);
5806 tcg_gen_deposit_i32(fpu_fcr31
, fpu_fcr31
, t32
,
5809 tcg_temp_free_i32(t32
);
5810 tcg_temp_free_i64(t64
);
5815 MIPS_INVAL("loongson_cp2");
5816 gen_reserved_instruction(ctx
);
5820 gen_store_fpr64(ctx
, t0
, rd
);
5823 tcg_temp_free_i64(t0
);
5824 tcg_temp_free_i64(t1
);
5827 static void gen_loongson_lswc2(DisasContext
*ctx
, int rt
,
5832 #if defined(TARGET_MIPS64)
5833 int lsq_rt1
= ctx
->opcode
& 0x1f;
5834 int lsq_offset
= sextract32(ctx
->opcode
, 6, 9) << 4;
5836 int shf_offset
= sextract32(ctx
->opcode
, 6, 8);
5838 t0
= tcg_temp_new();
5840 switch (MASK_LOONGSON_GSLSQ(ctx
->opcode
)) {
5841 #if defined(TARGET_MIPS64)
5843 t1
= tcg_temp_new();
5844 gen_base_offset_addr(ctx
, t0
, rs
, lsq_offset
);
5845 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
|
5846 ctx
->default_tcg_memop_mask
);
5847 gen_base_offset_addr(ctx
, t0
, rs
, lsq_offset
+ 8);
5848 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
|
5849 ctx
->default_tcg_memop_mask
);
5850 gen_store_gpr(t1
, rt
);
5851 gen_store_gpr(t0
, lsq_rt1
);
5855 check_cp1_enabled(ctx
);
5856 t1
= tcg_temp_new();
5857 gen_base_offset_addr(ctx
, t0
, rs
, lsq_offset
);
5858 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
|
5859 ctx
->default_tcg_memop_mask
);
5860 gen_base_offset_addr(ctx
, t0
, rs
, lsq_offset
+ 8);
5861 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
|
5862 ctx
->default_tcg_memop_mask
);
5863 gen_store_fpr64(ctx
, t1
, rt
);
5864 gen_store_fpr64(ctx
, t0
, lsq_rt1
);
5868 t1
= tcg_temp_new();
5869 gen_base_offset_addr(ctx
, t0
, rs
, lsq_offset
);
5870 gen_load_gpr(t1
, rt
);
5871 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
|
5872 ctx
->default_tcg_memop_mask
);
5873 gen_base_offset_addr(ctx
, t0
, rs
, lsq_offset
+ 8);
5874 gen_load_gpr(t1
, lsq_rt1
);
5875 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
|
5876 ctx
->default_tcg_memop_mask
);
5880 check_cp1_enabled(ctx
);
5881 t1
= tcg_temp_new();
5882 gen_base_offset_addr(ctx
, t0
, rs
, lsq_offset
);
5883 gen_load_fpr64(ctx
, t1
, rt
);
5884 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
|
5885 ctx
->default_tcg_memop_mask
);
5886 gen_base_offset_addr(ctx
, t0
, rs
, lsq_offset
+ 8);
5887 gen_load_fpr64(ctx
, t1
, lsq_rt1
);
5888 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
|
5889 ctx
->default_tcg_memop_mask
);
5894 switch (MASK_LOONGSON_GSSHFLS(ctx
->opcode
)) {
5896 check_cp1_enabled(ctx
);
5897 gen_base_offset_addr(ctx
, t0
, rs
, shf_offset
);
5898 t1
= tcg_temp_new();
5899 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
5900 tcg_gen_andi_tl(t1
, t0
, 3);
5901 #ifndef TARGET_WORDS_BIGENDIAN
5902 tcg_gen_xori_tl(t1
, t1
, 3);
5904 tcg_gen_shli_tl(t1
, t1
, 3);
5905 tcg_gen_andi_tl(t0
, t0
, ~3);
5906 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEUL
);
5907 tcg_gen_shl_tl(t0
, t0
, t1
);
5908 t2
= tcg_const_tl(-1);
5909 tcg_gen_shl_tl(t2
, t2
, t1
);
5910 fp0
= tcg_temp_new_i32();
5911 gen_load_fpr32(ctx
, fp0
, rt
);
5912 tcg_gen_ext_i32_tl(t1
, fp0
);
5913 tcg_gen_andc_tl(t1
, t1
, t2
);
5915 tcg_gen_or_tl(t0
, t0
, t1
);
5917 #if defined(TARGET_MIPS64)
5918 tcg_gen_extrl_i64_i32(fp0
, t0
);
5920 tcg_gen_ext32s_tl(fp0
, t0
);
5922 gen_store_fpr32(ctx
, fp0
, rt
);
5923 tcg_temp_free_i32(fp0
);
5926 check_cp1_enabled(ctx
);
5927 gen_base_offset_addr(ctx
, t0
, rs
, shf_offset
);
5928 t1
= tcg_temp_new();
5929 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
5930 tcg_gen_andi_tl(t1
, t0
, 3);
5931 #ifdef TARGET_WORDS_BIGENDIAN
5932 tcg_gen_xori_tl(t1
, t1
, 3);
5934 tcg_gen_shli_tl(t1
, t1
, 3);
5935 tcg_gen_andi_tl(t0
, t0
, ~3);
5936 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEUL
);
5937 tcg_gen_shr_tl(t0
, t0
, t1
);
5938 tcg_gen_xori_tl(t1
, t1
, 31);
5939 t2
= tcg_const_tl(0xfffffffeull
);
5940 tcg_gen_shl_tl(t2
, t2
, t1
);
5941 fp0
= tcg_temp_new_i32();
5942 gen_load_fpr32(ctx
, fp0
, rt
);
5943 tcg_gen_ext_i32_tl(t1
, fp0
);
5944 tcg_gen_and_tl(t1
, t1
, t2
);
5946 tcg_gen_or_tl(t0
, t0
, t1
);
5948 #if defined(TARGET_MIPS64)
5949 tcg_gen_extrl_i64_i32(fp0
, t0
);
5951 tcg_gen_ext32s_tl(fp0
, t0
);
5953 gen_store_fpr32(ctx
, fp0
, rt
);
5954 tcg_temp_free_i32(fp0
);
5956 #if defined(TARGET_MIPS64)
5958 check_cp1_enabled(ctx
);
5959 gen_base_offset_addr(ctx
, t0
, rs
, shf_offset
);
5960 t1
= tcg_temp_new();
5961 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
5962 tcg_gen_andi_tl(t1
, t0
, 7);
5963 #ifndef TARGET_WORDS_BIGENDIAN
5964 tcg_gen_xori_tl(t1
, t1
, 7);
5966 tcg_gen_shli_tl(t1
, t1
, 3);
5967 tcg_gen_andi_tl(t0
, t0
, ~7);
5968 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
);
5969 tcg_gen_shl_tl(t0
, t0
, t1
);
5970 t2
= tcg_const_tl(-1);
5971 tcg_gen_shl_tl(t2
, t2
, t1
);
5972 gen_load_fpr64(ctx
, t1
, rt
);
5973 tcg_gen_andc_tl(t1
, t1
, t2
);
5975 tcg_gen_or_tl(t0
, t0
, t1
);
5977 gen_store_fpr64(ctx
, t0
, rt
);
5980 check_cp1_enabled(ctx
);
5981 gen_base_offset_addr(ctx
, t0
, rs
, shf_offset
);
5982 t1
= tcg_temp_new();
5983 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
5984 tcg_gen_andi_tl(t1
, t0
, 7);
5985 #ifdef TARGET_WORDS_BIGENDIAN
5986 tcg_gen_xori_tl(t1
, t1
, 7);
5988 tcg_gen_shli_tl(t1
, t1
, 3);
5989 tcg_gen_andi_tl(t0
, t0
, ~7);
5990 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
);
5991 tcg_gen_shr_tl(t0
, t0
, t1
);
5992 tcg_gen_xori_tl(t1
, t1
, 63);
5993 t2
= tcg_const_tl(0xfffffffffffffffeull
);
5994 tcg_gen_shl_tl(t2
, t2
, t1
);
5995 gen_load_fpr64(ctx
, t1
, rt
);
5996 tcg_gen_and_tl(t1
, t1
, t2
);
5998 tcg_gen_or_tl(t0
, t0
, t1
);
6000 gen_store_fpr64(ctx
, t0
, rt
);
6004 MIPS_INVAL("loongson_gsshfl");
6005 gen_reserved_instruction(ctx
);
6010 switch (MASK_LOONGSON_GSSHFLS(ctx
->opcode
)) {
6012 check_cp1_enabled(ctx
);
6013 t1
= tcg_temp_new();
6014 gen_base_offset_addr(ctx
, t0
, rs
, shf_offset
);
6015 fp0
= tcg_temp_new_i32();
6016 gen_load_fpr32(ctx
, fp0
, rt
);
6017 tcg_gen_ext_i32_tl(t1
, fp0
);
6018 gen_helper_0e2i(swl
, t1
, t0
, ctx
->mem_idx
);
6019 tcg_temp_free_i32(fp0
);
6023 check_cp1_enabled(ctx
);
6024 t1
= tcg_temp_new();
6025 gen_base_offset_addr(ctx
, t0
, rs
, shf_offset
);
6026 fp0
= tcg_temp_new_i32();
6027 gen_load_fpr32(ctx
, fp0
, rt
);
6028 tcg_gen_ext_i32_tl(t1
, fp0
);
6029 gen_helper_0e2i(swr
, t1
, t0
, ctx
->mem_idx
);
6030 tcg_temp_free_i32(fp0
);
6033 #if defined(TARGET_MIPS64)
6035 check_cp1_enabled(ctx
);
6036 t1
= tcg_temp_new();
6037 gen_base_offset_addr(ctx
, t0
, rs
, shf_offset
);
6038 gen_load_fpr64(ctx
, t1
, rt
);
6039 gen_helper_0e2i(sdl
, t1
, t0
, ctx
->mem_idx
);
6043 check_cp1_enabled(ctx
);
6044 t1
= tcg_temp_new();
6045 gen_base_offset_addr(ctx
, t0
, rs
, shf_offset
);
6046 gen_load_fpr64(ctx
, t1
, rt
);
6047 gen_helper_0e2i(sdr
, t1
, t0
, ctx
->mem_idx
);
6052 MIPS_INVAL("loongson_gsshfs");
6053 gen_reserved_instruction(ctx
);
6058 MIPS_INVAL("loongson_gslsq");
6059 gen_reserved_instruction(ctx
);
6065 /* Loongson EXT LDC2/SDC2 */
6066 static void gen_loongson_lsdc2(DisasContext
*ctx
, int rt
,
6069 int offset
= sextract32(ctx
->opcode
, 3, 8);
6070 uint32_t opc
= MASK_LOONGSON_LSDC2(ctx
->opcode
);
6074 /* Pre-conditions */
6080 /* prefetch, implement as NOP */
6091 #if defined(TARGET_MIPS64)
6094 check_cp1_enabled(ctx
);
6095 /* prefetch, implement as NOP */
6101 #if defined(TARGET_MIPS64)
6104 check_cp1_enabled(ctx
);
6107 MIPS_INVAL("loongson_lsdc2");
6108 gen_reserved_instruction(ctx
);
6113 t0
= tcg_temp_new();
6115 gen_base_offset_addr(ctx
, t0
, rs
, offset
);
6116 gen_op_addr_add(ctx
, t0
, cpu_gpr
[rd
], t0
);
6120 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_SB
);
6121 gen_store_gpr(t0
, rt
);
6124 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESW
|
6125 ctx
->default_tcg_memop_mask
);
6126 gen_store_gpr(t0
, rt
);
6129 gen_base_offset_addr(ctx
, t0
, rs
, offset
);
6131 gen_op_addr_add(ctx
, t0
, cpu_gpr
[rd
], t0
);
6133 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESL
|
6134 ctx
->default_tcg_memop_mask
);
6135 gen_store_gpr(t0
, rt
);
6137 #if defined(TARGET_MIPS64)
6139 gen_base_offset_addr(ctx
, t0
, rs
, offset
);
6141 gen_op_addr_add(ctx
, t0
, cpu_gpr
[rd
], t0
);
6143 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
|
6144 ctx
->default_tcg_memop_mask
);
6145 gen_store_gpr(t0
, rt
);
6149 check_cp1_enabled(ctx
);
6150 gen_base_offset_addr(ctx
, t0
, rs
, offset
);
6152 gen_op_addr_add(ctx
, t0
, cpu_gpr
[rd
], t0
);
6154 fp0
= tcg_temp_new_i32();
6155 tcg_gen_qemu_ld_i32(fp0
, t0
, ctx
->mem_idx
, MO_TESL
|
6156 ctx
->default_tcg_memop_mask
);
6157 gen_store_fpr32(ctx
, fp0
, rt
);
6158 tcg_temp_free_i32(fp0
);
6160 #if defined(TARGET_MIPS64)
6162 check_cp1_enabled(ctx
);
6163 gen_base_offset_addr(ctx
, t0
, rs
, offset
);
6165 gen_op_addr_add(ctx
, t0
, cpu_gpr
[rd
], t0
);
6167 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
|
6168 ctx
->default_tcg_memop_mask
);
6169 gen_store_fpr64(ctx
, t0
, rt
);
6173 t1
= tcg_temp_new();
6174 gen_load_gpr(t1
, rt
);
6175 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_SB
);
6179 t1
= tcg_temp_new();
6180 gen_load_gpr(t1
, rt
);
6181 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUW
|
6182 ctx
->default_tcg_memop_mask
);
6186 t1
= tcg_temp_new();
6187 gen_load_gpr(t1
, rt
);
6188 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
|
6189 ctx
->default_tcg_memop_mask
);
6192 #if defined(TARGET_MIPS64)
6194 t1
= tcg_temp_new();
6195 gen_load_gpr(t1
, rt
);
6196 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
|
6197 ctx
->default_tcg_memop_mask
);
6202 fp0
= tcg_temp_new_i32();
6203 gen_load_fpr32(ctx
, fp0
, rt
);
6204 tcg_gen_qemu_st_i32(fp0
, t0
, ctx
->mem_idx
, MO_TEUL
|
6205 ctx
->default_tcg_memop_mask
);
6206 tcg_temp_free_i32(fp0
);
6208 #if defined(TARGET_MIPS64)
6210 t1
= tcg_temp_new();
6211 gen_load_fpr64(ctx
, t1
, rt
);
6212 tcg_gen_qemu_st_i64(t1
, t0
, ctx
->mem_idx
, MO_TEQ
|
6213 ctx
->default_tcg_memop_mask
);
6225 static void gen_trap(DisasContext
*ctx
, uint32_t opc
,
6226 int rs
, int rt
, int16_t imm
)
6229 TCGv t0
= tcg_temp_new();
6230 TCGv t1
= tcg_temp_new();
6233 /* Load needed operands */
6241 /* Compare two registers */
6243 gen_load_gpr(t0
, rs
);
6244 gen_load_gpr(t1
, rt
);
6254 /* Compare register to immediate */
6255 if (rs
!= 0 || imm
!= 0) {
6256 gen_load_gpr(t0
, rs
);
6257 tcg_gen_movi_tl(t1
, (int32_t)imm
);
6264 case OPC_TEQ
: /* rs == rs */
6265 case OPC_TEQI
: /* r0 == 0 */
6266 case OPC_TGE
: /* rs >= rs */
6267 case OPC_TGEI
: /* r0 >= 0 */
6268 case OPC_TGEU
: /* rs >= rs unsigned */
6269 case OPC_TGEIU
: /* r0 >= 0 unsigned */
6271 generate_exception_end(ctx
, EXCP_TRAP
);
6273 case OPC_TLT
: /* rs < rs */
6274 case OPC_TLTI
: /* r0 < 0 */
6275 case OPC_TLTU
: /* rs < rs unsigned */
6276 case OPC_TLTIU
: /* r0 < 0 unsigned */
6277 case OPC_TNE
: /* rs != rs */
6278 case OPC_TNEI
: /* r0 != 0 */
6279 /* Never trap: treat as NOP. */
6283 TCGLabel
*l1
= gen_new_label();
6288 tcg_gen_brcond_tl(TCG_COND_NE
, t0
, t1
, l1
);
6292 tcg_gen_brcond_tl(TCG_COND_LT
, t0
, t1
, l1
);
6296 tcg_gen_brcond_tl(TCG_COND_LTU
, t0
, t1
, l1
);
6300 tcg_gen_brcond_tl(TCG_COND_GE
, t0
, t1
, l1
);
6304 tcg_gen_brcond_tl(TCG_COND_GEU
, t0
, t1
, l1
);
6308 tcg_gen_brcond_tl(TCG_COND_EQ
, t0
, t1
, l1
);
6311 generate_exception(ctx
, EXCP_TRAP
);
6318 static inline bool use_goto_tb(DisasContext
*ctx
, target_ulong dest
)
6320 if (unlikely(ctx
->base
.singlestep_enabled
)) {
6324 #ifndef CONFIG_USER_ONLY
6325 return (ctx
->base
.tb
->pc
& TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
);
6331 static inline void gen_goto_tb(DisasContext
*ctx
, int n
, target_ulong dest
)
6333 if (use_goto_tb(ctx
, dest
)) {
6336 tcg_gen_exit_tb(ctx
->base
.tb
, n
);
6339 if (ctx
->base
.singlestep_enabled
) {
6340 save_cpu_state(ctx
, 0);
6341 gen_helper_raise_exception_debug(cpu_env
);
6343 tcg_gen_lookup_and_goto_ptr();
6347 /* Branches (before delay slot) */
6348 static void gen_compute_branch(DisasContext
*ctx
, uint32_t opc
,
6350 int rs
, int rt
, int32_t offset
,
6353 target_ulong btgt
= -1;
6355 int bcond_compute
= 0;
6356 TCGv t0
= tcg_temp_new();
6357 TCGv t1
= tcg_temp_new();
6359 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
6360 #ifdef MIPS_DEBUG_DISAS
6361 LOG_DISAS("Branch in delay / forbidden slot at PC 0x"
6362 TARGET_FMT_lx
"\n", ctx
->base
.pc_next
);
6364 gen_reserved_instruction(ctx
);
6368 /* Load needed operands */
6374 /* Compare two registers */
6376 gen_load_gpr(t0
, rs
);
6377 gen_load_gpr(t1
, rt
);
6380 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ offset
;
6394 /* Compare to zero */
6396 gen_load_gpr(t0
, rs
);
6399 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ offset
;
6402 #if defined(TARGET_MIPS64)
6404 tcg_gen_andi_tl(t0
, cpu_dspctrl
, 0x7F);
6406 tcg_gen_andi_tl(t0
, cpu_dspctrl
, 0x3F);
6409 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ offset
;
6414 /* Jump to immediate */
6415 btgt
= ((ctx
->base
.pc_next
+ insn_bytes
) & (int32_t)0xF0000000) |
6420 /* Jump to register */
6421 if (offset
!= 0 && offset
!= 16) {
6423 * Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
6424 * others are reserved.
6426 MIPS_INVAL("jump hint");
6427 gen_reserved_instruction(ctx
);
6430 gen_load_gpr(btarget
, rs
);
6433 MIPS_INVAL("branch/jump");
6434 gen_reserved_instruction(ctx
);
6437 if (bcond_compute
== 0) {
6438 /* No condition to be computed */
6440 case OPC_BEQ
: /* rx == rx */
6441 case OPC_BEQL
: /* rx == rx likely */
6442 case OPC_BGEZ
: /* 0 >= 0 */
6443 case OPC_BGEZL
: /* 0 >= 0 likely */
6444 case OPC_BLEZ
: /* 0 <= 0 */
6445 case OPC_BLEZL
: /* 0 <= 0 likely */
6447 ctx
->hflags
|= MIPS_HFLAG_B
;
6449 case OPC_BGEZAL
: /* 0 >= 0 */
6450 case OPC_BGEZALL
: /* 0 >= 0 likely */
6451 /* Always take and link */
6453 ctx
->hflags
|= MIPS_HFLAG_B
;
6455 case OPC_BNE
: /* rx != rx */
6456 case OPC_BGTZ
: /* 0 > 0 */
6457 case OPC_BLTZ
: /* 0 < 0 */
6460 case OPC_BLTZAL
: /* 0 < 0 */
6462 * Handle as an unconditional branch to get correct delay
6466 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ delayslot_size
;
6467 ctx
->hflags
|= MIPS_HFLAG_B
;
6469 case OPC_BLTZALL
: /* 0 < 0 likely */
6470 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 8);
6471 /* Skip the instruction in the delay slot */
6472 ctx
->base
.pc_next
+= 4;
6474 case OPC_BNEL
: /* rx != rx likely */
6475 case OPC_BGTZL
: /* 0 > 0 likely */
6476 case OPC_BLTZL
: /* 0 < 0 likely */
6477 /* Skip the instruction in the delay slot */
6478 ctx
->base
.pc_next
+= 4;
6481 ctx
->hflags
|= MIPS_HFLAG_B
;
6484 ctx
->hflags
|= MIPS_HFLAG_BX
;
6488 ctx
->hflags
|= MIPS_HFLAG_B
;
6491 ctx
->hflags
|= MIPS_HFLAG_BR
;
6495 ctx
->hflags
|= MIPS_HFLAG_BR
;
6498 MIPS_INVAL("branch/jump");
6499 gen_reserved_instruction(ctx
);
6505 tcg_gen_setcond_tl(TCG_COND_EQ
, bcond
, t0
, t1
);
6508 tcg_gen_setcond_tl(TCG_COND_EQ
, bcond
, t0
, t1
);
6511 tcg_gen_setcond_tl(TCG_COND_NE
, bcond
, t0
, t1
);
6514 tcg_gen_setcond_tl(TCG_COND_NE
, bcond
, t0
, t1
);
6517 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
6520 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
6523 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
6527 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
6531 tcg_gen_setcondi_tl(TCG_COND_GT
, bcond
, t0
, 0);
6534 tcg_gen_setcondi_tl(TCG_COND_GT
, bcond
, t0
, 0);
6537 tcg_gen_setcondi_tl(TCG_COND_LE
, bcond
, t0
, 0);
6540 tcg_gen_setcondi_tl(TCG_COND_LE
, bcond
, t0
, 0);
6543 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
6546 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
6549 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 32);
6551 #if defined(TARGET_MIPS64)
6553 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 64);
6557 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
6560 ctx
->hflags
|= MIPS_HFLAG_BC
;
6563 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
6566 ctx
->hflags
|= MIPS_HFLAG_BL
;
6569 MIPS_INVAL("conditional branch/jump");
6570 gen_reserved_instruction(ctx
);
6575 ctx
->btarget
= btgt
;
6577 switch (delayslot_size
) {
6579 ctx
->hflags
|= MIPS_HFLAG_BDS16
;
6582 ctx
->hflags
|= MIPS_HFLAG_BDS32
;
6587 int post_delay
= insn_bytes
+ delayslot_size
;
6588 int lowbit
= !!(ctx
->hflags
& MIPS_HFLAG_M16
);
6590 tcg_gen_movi_tl(cpu_gpr
[blink
],
6591 ctx
->base
.pc_next
+ post_delay
+ lowbit
);
6595 if (insn_bytes
== 2) {
6596 ctx
->hflags
|= MIPS_HFLAG_B16
;
6603 /* nanoMIPS Branches */
6604 static void gen_compute_branch_nm(DisasContext
*ctx
, uint32_t opc
,
6606 int rs
, int rt
, int32_t offset
)
6608 target_ulong btgt
= -1;
6609 int bcond_compute
= 0;
6610 TCGv t0
= tcg_temp_new();
6611 TCGv t1
= tcg_temp_new();
6613 /* Load needed operands */
6617 /* Compare two registers */
6619 gen_load_gpr(t0
, rs
);
6620 gen_load_gpr(t1
, rt
);
6623 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ offset
;
6626 /* Compare to zero */
6628 gen_load_gpr(t0
, rs
);
6631 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ offset
;
6634 tcg_gen_andi_tl(t0
, cpu_dspctrl
, 0x3F);
6636 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ offset
;
6640 /* Jump to register */
6641 if (offset
!= 0 && offset
!= 16) {
6643 * Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
6644 * others are reserved.
6646 MIPS_INVAL("jump hint");
6647 gen_reserved_instruction(ctx
);
6650 gen_load_gpr(btarget
, rs
);
6653 MIPS_INVAL("branch/jump");
6654 gen_reserved_instruction(ctx
);
6657 if (bcond_compute
== 0) {
6658 /* No condition to be computed */
6660 case OPC_BEQ
: /* rx == rx */
6662 ctx
->hflags
|= MIPS_HFLAG_B
;
6664 case OPC_BGEZAL
: /* 0 >= 0 */
6665 /* Always take and link */
6666 tcg_gen_movi_tl(cpu_gpr
[31],
6667 ctx
->base
.pc_next
+ insn_bytes
);
6668 ctx
->hflags
|= MIPS_HFLAG_B
;
6670 case OPC_BNE
: /* rx != rx */
6671 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 8);
6672 /* Skip the instruction in the delay slot */
6673 ctx
->base
.pc_next
+= 4;
6676 ctx
->hflags
|= MIPS_HFLAG_BR
;
6680 tcg_gen_movi_tl(cpu_gpr
[rt
],
6681 ctx
->base
.pc_next
+ insn_bytes
);
6683 ctx
->hflags
|= MIPS_HFLAG_BR
;
6686 MIPS_INVAL("branch/jump");
6687 gen_reserved_instruction(ctx
);
6693 tcg_gen_setcond_tl(TCG_COND_EQ
, bcond
, t0
, t1
);
6696 tcg_gen_setcond_tl(TCG_COND_NE
, bcond
, t0
, t1
);
6699 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
6700 tcg_gen_movi_tl(cpu_gpr
[31],
6701 ctx
->base
.pc_next
+ insn_bytes
);
6704 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 32);
6706 ctx
->hflags
|= MIPS_HFLAG_BC
;
6709 MIPS_INVAL("conditional branch/jump");
6710 gen_reserved_instruction(ctx
);
6715 ctx
->btarget
= btgt
;
6718 if (insn_bytes
== 2) {
6719 ctx
->hflags
|= MIPS_HFLAG_B16
;
6726 /* special3 bitfield operations */
6727 static void gen_bitops(DisasContext
*ctx
, uint32_t opc
, int rt
,
6728 int rs
, int lsb
, int msb
)
6730 TCGv t0
= tcg_temp_new();
6731 TCGv t1
= tcg_temp_new();
6733 gen_load_gpr(t1
, rs
);
6736 if (lsb
+ msb
> 31) {
6740 tcg_gen_extract_tl(t0
, t1
, lsb
, msb
+ 1);
6743 * The two checks together imply that lsb == 0,
6744 * so this is a simple sign-extension.
6746 tcg_gen_ext32s_tl(t0
, t1
);
6749 #if defined(TARGET_MIPS64)
6758 if (lsb
+ msb
> 63) {
6761 tcg_gen_extract_tl(t0
, t1
, lsb
, msb
+ 1);
6768 gen_load_gpr(t0
, rt
);
6769 tcg_gen_deposit_tl(t0
, t0
, t1
, lsb
, msb
- lsb
+ 1);
6770 tcg_gen_ext32s_tl(t0
, t0
);
6772 #if defined(TARGET_MIPS64)
6783 gen_load_gpr(t0
, rt
);
6784 tcg_gen_deposit_tl(t0
, t0
, t1
, lsb
, msb
- lsb
+ 1);
6789 MIPS_INVAL("bitops");
6790 gen_reserved_instruction(ctx
);
6795 gen_store_gpr(t0
, rt
);
6800 static void gen_bshfl(DisasContext
*ctx
, uint32_t op2
, int rt
, int rd
)
6805 /* If no destination, treat it as a NOP. */
6809 t0
= tcg_temp_new();
6810 gen_load_gpr(t0
, rt
);
6814 TCGv t1
= tcg_temp_new();
6815 TCGv t2
= tcg_const_tl(0x00FF00FF);
6817 tcg_gen_shri_tl(t1
, t0
, 8);
6818 tcg_gen_and_tl(t1
, t1
, t2
);
6819 tcg_gen_and_tl(t0
, t0
, t2
);
6820 tcg_gen_shli_tl(t0
, t0
, 8);
6821 tcg_gen_or_tl(t0
, t0
, t1
);
6824 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
6828 tcg_gen_ext8s_tl(cpu_gpr
[rd
], t0
);
6831 tcg_gen_ext16s_tl(cpu_gpr
[rd
], t0
);
6833 #if defined(TARGET_MIPS64)
6836 TCGv t1
= tcg_temp_new();
6837 TCGv t2
= tcg_const_tl(0x00FF00FF00FF00FFULL
);
6839 tcg_gen_shri_tl(t1
, t0
, 8);
6840 tcg_gen_and_tl(t1
, t1
, t2
);
6841 tcg_gen_and_tl(t0
, t0
, t2
);
6842 tcg_gen_shli_tl(t0
, t0
, 8);
6843 tcg_gen_or_tl(cpu_gpr
[rd
], t0
, t1
);
6850 TCGv t1
= tcg_temp_new();
6851 TCGv t2
= tcg_const_tl(0x0000FFFF0000FFFFULL
);
6853 tcg_gen_shri_tl(t1
, t0
, 16);
6854 tcg_gen_and_tl(t1
, t1
, t2
);
6855 tcg_gen_and_tl(t0
, t0
, t2
);
6856 tcg_gen_shli_tl(t0
, t0
, 16);
6857 tcg_gen_or_tl(t0
, t0
, t1
);
6858 tcg_gen_shri_tl(t1
, t0
, 32);
6859 tcg_gen_shli_tl(t0
, t0
, 32);
6860 tcg_gen_or_tl(cpu_gpr
[rd
], t0
, t1
);
6867 MIPS_INVAL("bsfhl");
6868 gen_reserved_instruction(ctx
);
6875 static void gen_lsa(DisasContext
*ctx
, int opc
, int rd
, int rs
, int rt
,
6884 t0
= tcg_temp_new();
6885 t1
= tcg_temp_new();
6886 gen_load_gpr(t0
, rs
);
6887 gen_load_gpr(t1
, rt
);
6888 tcg_gen_shli_tl(t0
, t0
, imm2
+ 1);
6889 tcg_gen_add_tl(cpu_gpr
[rd
], t0
, t1
);
6890 if (opc
== OPC_LSA
) {
6891 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
6900 static void gen_align_bits(DisasContext
*ctx
, int wordsz
, int rd
, int rs
,
6908 t0
= tcg_temp_new();
6909 if (bits
== 0 || bits
== wordsz
) {
6911 gen_load_gpr(t0
, rt
);
6913 gen_load_gpr(t0
, rs
);
6917 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
6919 #if defined(TARGET_MIPS64)
6921 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
6926 TCGv t1
= tcg_temp_new();
6927 gen_load_gpr(t0
, rt
);
6928 gen_load_gpr(t1
, rs
);
6932 TCGv_i64 t2
= tcg_temp_new_i64();
6933 tcg_gen_concat_tl_i64(t2
, t1
, t0
);
6934 tcg_gen_shri_i64(t2
, t2
, 32 - bits
);
6935 gen_move_low32(cpu_gpr
[rd
], t2
);
6936 tcg_temp_free_i64(t2
);
6939 #if defined(TARGET_MIPS64)
6941 tcg_gen_shli_tl(t0
, t0
, bits
);
6942 tcg_gen_shri_tl(t1
, t1
, 64 - bits
);
6943 tcg_gen_or_tl(cpu_gpr
[rd
], t1
, t0
);
6953 static void gen_align(DisasContext
*ctx
, int wordsz
, int rd
, int rs
, int rt
,
6956 gen_align_bits(ctx
, wordsz
, rd
, rs
, rt
, bp
* 8);
6959 static void gen_ext(DisasContext
*ctx
, int wordsz
, int rd
, int rs
, int rt
,
6962 gen_align_bits(ctx
, wordsz
, rd
, rs
, rt
, wordsz
- shift
);
6965 static void gen_bitswap(DisasContext
*ctx
, int opc
, int rd
, int rt
)
6972 t0
= tcg_temp_new();
6973 gen_load_gpr(t0
, rt
);
6976 gen_helper_bitswap(cpu_gpr
[rd
], t0
);
6978 #if defined(TARGET_MIPS64)
6980 gen_helper_dbitswap(cpu_gpr
[rd
], t0
);
6987 #ifndef CONFIG_USER_ONLY
6988 /* CP0 (MMU and control) */
6989 static inline void gen_mthc0_entrylo(TCGv arg
, target_ulong off
)
6991 TCGv_i64 t0
= tcg_temp_new_i64();
6992 TCGv_i64 t1
= tcg_temp_new_i64();
6994 tcg_gen_ext_tl_i64(t0
, arg
);
6995 tcg_gen_ld_i64(t1
, cpu_env
, off
);
6996 #if defined(TARGET_MIPS64)
6997 tcg_gen_deposit_i64(t1
, t1
, t0
, 30, 32);
6999 tcg_gen_concat32_i64(t1
, t1
, t0
);
7001 tcg_gen_st_i64(t1
, cpu_env
, off
);
7002 tcg_temp_free_i64(t1
);
7003 tcg_temp_free_i64(t0
);
7006 static inline void gen_mthc0_store64(TCGv arg
, target_ulong off
)
7008 TCGv_i64 t0
= tcg_temp_new_i64();
7009 TCGv_i64 t1
= tcg_temp_new_i64();
7011 tcg_gen_ext_tl_i64(t0
, arg
);
7012 tcg_gen_ld_i64(t1
, cpu_env
, off
);
7013 tcg_gen_concat32_i64(t1
, t1
, t0
);
7014 tcg_gen_st_i64(t1
, cpu_env
, off
);
7015 tcg_temp_free_i64(t1
);
7016 tcg_temp_free_i64(t0
);
7019 static inline void gen_mfhc0_entrylo(TCGv arg
, target_ulong off
)
7021 TCGv_i64 t0
= tcg_temp_new_i64();
7023 tcg_gen_ld_i64(t0
, cpu_env
, off
);
7024 #if defined(TARGET_MIPS64)
7025 tcg_gen_shri_i64(t0
, t0
, 30);
7027 tcg_gen_shri_i64(t0
, t0
, 32);
7029 gen_move_low32(arg
, t0
);
7030 tcg_temp_free_i64(t0
);
7033 static inline void gen_mfhc0_load64(TCGv arg
, target_ulong off
, int shift
)
7035 TCGv_i64 t0
= tcg_temp_new_i64();
7037 tcg_gen_ld_i64(t0
, cpu_env
, off
);
7038 tcg_gen_shri_i64(t0
, t0
, 32 + shift
);
7039 gen_move_low32(arg
, t0
);
7040 tcg_temp_free_i64(t0
);
7043 static inline void gen_mfc0_load32(TCGv arg
, target_ulong off
)
7045 TCGv_i32 t0
= tcg_temp_new_i32();
7047 tcg_gen_ld_i32(t0
, cpu_env
, off
);
7048 tcg_gen_ext_i32_tl(arg
, t0
);
7049 tcg_temp_free_i32(t0
);
7052 static inline void gen_mfc0_load64(TCGv arg
, target_ulong off
)
7054 tcg_gen_ld_tl(arg
, cpu_env
, off
);
7055 tcg_gen_ext32s_tl(arg
, arg
);
7058 static inline void gen_mtc0_store32(TCGv arg
, target_ulong off
)
7060 TCGv_i32 t0
= tcg_temp_new_i32();
7062 tcg_gen_trunc_tl_i32(t0
, arg
);
7063 tcg_gen_st_i32(t0
, cpu_env
, off
);
7064 tcg_temp_free_i32(t0
);
7067 #define CP0_CHECK(c) \
7070 goto cp0_unimplemented; \
7074 static void gen_mfhc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
7076 const char *register_name
= "invalid";
7079 case CP0_REGISTER_02
:
7082 CP0_CHECK(ctx
->hflags
& MIPS_HFLAG_ELPA
);
7083 gen_mfhc0_entrylo(arg
, offsetof(CPUMIPSState
, CP0_EntryLo0
));
7084 register_name
= "EntryLo0";
7087 goto cp0_unimplemented
;
7090 case CP0_REGISTER_03
:
7092 case CP0_REG03__ENTRYLO1
:
7093 CP0_CHECK(ctx
->hflags
& MIPS_HFLAG_ELPA
);
7094 gen_mfhc0_entrylo(arg
, offsetof(CPUMIPSState
, CP0_EntryLo1
));
7095 register_name
= "EntryLo1";
7098 goto cp0_unimplemented
;
7101 case CP0_REGISTER_09
:
7103 case CP0_REG09__SAAR
:
7104 CP0_CHECK(ctx
->saar
);
7105 gen_helper_mfhc0_saar(arg
, cpu_env
);
7106 register_name
= "SAAR";
7109 goto cp0_unimplemented
;
7112 case CP0_REGISTER_17
:
7114 case CP0_REG17__LLADDR
:
7115 gen_mfhc0_load64(arg
, offsetof(CPUMIPSState
, CP0_LLAddr
),
7116 ctx
->CP0_LLAddr_shift
);
7117 register_name
= "LLAddr";
7119 case CP0_REG17__MAAR
:
7120 CP0_CHECK(ctx
->mrp
);
7121 gen_helper_mfhc0_maar(arg
, cpu_env
);
7122 register_name
= "MAAR";
7125 goto cp0_unimplemented
;
7128 case CP0_REGISTER_19
:
7130 case CP0_REG19__WATCHHI0
:
7131 case CP0_REG19__WATCHHI1
:
7132 case CP0_REG19__WATCHHI2
:
7133 case CP0_REG19__WATCHHI3
:
7134 case CP0_REG19__WATCHHI4
:
7135 case CP0_REG19__WATCHHI5
:
7136 case CP0_REG19__WATCHHI6
:
7137 case CP0_REG19__WATCHHI7
:
7138 /* upper 32 bits are only available when Config5MI != 0 */
7140 gen_mfhc0_load64(arg
, offsetof(CPUMIPSState
, CP0_WatchHi
[sel
]), 0);
7141 register_name
= "WatchHi";
7144 goto cp0_unimplemented
;
7147 case CP0_REGISTER_28
:
7153 gen_mfhc0_load64(arg
, offsetof(CPUMIPSState
, CP0_TagLo
), 0);
7154 register_name
= "TagLo";
7157 goto cp0_unimplemented
;
7161 goto cp0_unimplemented
;
7163 trace_mips_translate_c0("mfhc0", register_name
, reg
, sel
);
7167 qemu_log_mask(LOG_UNIMP
, "mfhc0 %s (reg %d sel %d)\n",
7168 register_name
, reg
, sel
);
7169 tcg_gen_movi_tl(arg
, 0);
7172 static void gen_mthc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
7174 const char *register_name
= "invalid";
7175 uint64_t mask
= ctx
->PAMask
>> 36;
7178 case CP0_REGISTER_02
:
7181 CP0_CHECK(ctx
->hflags
& MIPS_HFLAG_ELPA
);
7182 tcg_gen_andi_tl(arg
, arg
, mask
);
7183 gen_mthc0_entrylo(arg
, offsetof(CPUMIPSState
, CP0_EntryLo0
));
7184 register_name
= "EntryLo0";
7187 goto cp0_unimplemented
;
7190 case CP0_REGISTER_03
:
7192 case CP0_REG03__ENTRYLO1
:
7193 CP0_CHECK(ctx
->hflags
& MIPS_HFLAG_ELPA
);
7194 tcg_gen_andi_tl(arg
, arg
, mask
);
7195 gen_mthc0_entrylo(arg
, offsetof(CPUMIPSState
, CP0_EntryLo1
));
7196 register_name
= "EntryLo1";
7199 goto cp0_unimplemented
;
7202 case CP0_REGISTER_09
:
7204 case CP0_REG09__SAAR
:
7205 CP0_CHECK(ctx
->saar
);
7206 gen_helper_mthc0_saar(cpu_env
, arg
);
7207 register_name
= "SAAR";
7210 goto cp0_unimplemented
;
7213 case CP0_REGISTER_17
:
7215 case CP0_REG17__LLADDR
:
7217 * LLAddr is read-only (the only exception is bit 0 if LLB is
7218 * supported); the CP0_LLAddr_rw_bitmask does not seem to be
7219 * relevant for modern MIPS cores supporting MTHC0, therefore
7220 * treating MTHC0 to LLAddr as NOP.
7222 register_name
= "LLAddr";
7224 case CP0_REG17__MAAR
:
7225 CP0_CHECK(ctx
->mrp
);
7226 gen_helper_mthc0_maar(cpu_env
, arg
);
7227 register_name
= "MAAR";
7230 goto cp0_unimplemented
;
7233 case CP0_REGISTER_19
:
7235 case CP0_REG19__WATCHHI0
:
7236 case CP0_REG19__WATCHHI1
:
7237 case CP0_REG19__WATCHHI2
:
7238 case CP0_REG19__WATCHHI3
:
7239 case CP0_REG19__WATCHHI4
:
7240 case CP0_REG19__WATCHHI5
:
7241 case CP0_REG19__WATCHHI6
:
7242 case CP0_REG19__WATCHHI7
:
7243 /* upper 32 bits are only available when Config5MI != 0 */
7245 gen_helper_0e1i(mthc0_watchhi
, arg
, sel
);
7246 register_name
= "WatchHi";
7249 goto cp0_unimplemented
;
7252 case CP0_REGISTER_28
:
7258 tcg_gen_andi_tl(arg
, arg
, mask
);
7259 gen_mthc0_store64(arg
, offsetof(CPUMIPSState
, CP0_TagLo
));
7260 register_name
= "TagLo";
7263 goto cp0_unimplemented
;
7267 goto cp0_unimplemented
;
7269 trace_mips_translate_c0("mthc0", register_name
, reg
, sel
);
7272 qemu_log_mask(LOG_UNIMP
, "mthc0 %s (reg %d sel %d)\n",
7273 register_name
, reg
, sel
);
7276 static inline void gen_mfc0_unimplemented(DisasContext
*ctx
, TCGv arg
)
7278 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
7279 tcg_gen_movi_tl(arg
, 0);
7281 tcg_gen_movi_tl(arg
, ~0);
7285 static void gen_mfc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
7287 const char *register_name
= "invalid";
7290 check_insn(ctx
, ISA_MIPS_R1
);
7294 case CP0_REGISTER_00
:
7296 case CP0_REG00__INDEX
:
7297 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Index
));
7298 register_name
= "Index";
7300 case CP0_REG00__MVPCONTROL
:
7301 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7302 gen_helper_mfc0_mvpcontrol(arg
, cpu_env
);
7303 register_name
= "MVPControl";
7305 case CP0_REG00__MVPCONF0
:
7306 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7307 gen_helper_mfc0_mvpconf0(arg
, cpu_env
);
7308 register_name
= "MVPConf0";
7310 case CP0_REG00__MVPCONF1
:
7311 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7312 gen_helper_mfc0_mvpconf1(arg
, cpu_env
);
7313 register_name
= "MVPConf1";
7315 case CP0_REG00__VPCONTROL
:
7317 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPControl
));
7318 register_name
= "VPControl";
7321 goto cp0_unimplemented
;
7324 case CP0_REGISTER_01
:
7326 case CP0_REG01__RANDOM
:
7327 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS_R6
));
7328 gen_helper_mfc0_random(arg
, cpu_env
);
7329 register_name
= "Random";
7331 case CP0_REG01__VPECONTROL
:
7332 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7333 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEControl
));
7334 register_name
= "VPEControl";
7336 case CP0_REG01__VPECONF0
:
7337 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7338 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf0
));
7339 register_name
= "VPEConf0";
7341 case CP0_REG01__VPECONF1
:
7342 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7343 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf1
));
7344 register_name
= "VPEConf1";
7346 case CP0_REG01__YQMASK
:
7347 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7348 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_YQMask
));
7349 register_name
= "YQMask";
7351 case CP0_REG01__VPESCHEDULE
:
7352 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7353 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_VPESchedule
));
7354 register_name
= "VPESchedule";
7356 case CP0_REG01__VPESCHEFBACK
:
7357 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7358 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
7359 register_name
= "VPEScheFBack";
7361 case CP0_REG01__VPEOPT
:
7362 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7363 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEOpt
));
7364 register_name
= "VPEOpt";
7367 goto cp0_unimplemented
;
7370 case CP0_REGISTER_02
:
7372 case CP0_REG02__ENTRYLO0
:
7374 TCGv_i64 tmp
= tcg_temp_new_i64();
7375 tcg_gen_ld_i64(tmp
, cpu_env
,
7376 offsetof(CPUMIPSState
, CP0_EntryLo0
));
7377 #if defined(TARGET_MIPS64)
7379 /* Move RI/XI fields to bits 31:30 */
7380 tcg_gen_shri_tl(arg
, tmp
, CP0EnLo_XI
);
7381 tcg_gen_deposit_tl(tmp
, tmp
, arg
, 30, 2);
7384 gen_move_low32(arg
, tmp
);
7385 tcg_temp_free_i64(tmp
);
7387 register_name
= "EntryLo0";
7389 case CP0_REG02__TCSTATUS
:
7390 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7391 gen_helper_mfc0_tcstatus(arg
, cpu_env
);
7392 register_name
= "TCStatus";
7394 case CP0_REG02__TCBIND
:
7395 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7396 gen_helper_mfc0_tcbind(arg
, cpu_env
);
7397 register_name
= "TCBind";
7399 case CP0_REG02__TCRESTART
:
7400 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7401 gen_helper_mfc0_tcrestart(arg
, cpu_env
);
7402 register_name
= "TCRestart";
7404 case CP0_REG02__TCHALT
:
7405 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7406 gen_helper_mfc0_tchalt(arg
, cpu_env
);
7407 register_name
= "TCHalt";
7409 case CP0_REG02__TCCONTEXT
:
7410 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7411 gen_helper_mfc0_tccontext(arg
, cpu_env
);
7412 register_name
= "TCContext";
7414 case CP0_REG02__TCSCHEDULE
:
7415 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7416 gen_helper_mfc0_tcschedule(arg
, cpu_env
);
7417 register_name
= "TCSchedule";
7419 case CP0_REG02__TCSCHEFBACK
:
7420 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7421 gen_helper_mfc0_tcschefback(arg
, cpu_env
);
7422 register_name
= "TCScheFBack";
7425 goto cp0_unimplemented
;
7428 case CP0_REGISTER_03
:
7430 case CP0_REG03__ENTRYLO1
:
7432 TCGv_i64 tmp
= tcg_temp_new_i64();
7433 tcg_gen_ld_i64(tmp
, cpu_env
,
7434 offsetof(CPUMIPSState
, CP0_EntryLo1
));
7435 #if defined(TARGET_MIPS64)
7437 /* Move RI/XI fields to bits 31:30 */
7438 tcg_gen_shri_tl(arg
, tmp
, CP0EnLo_XI
);
7439 tcg_gen_deposit_tl(tmp
, tmp
, arg
, 30, 2);
7442 gen_move_low32(arg
, tmp
);
7443 tcg_temp_free_i64(tmp
);
7445 register_name
= "EntryLo1";
7447 case CP0_REG03__GLOBALNUM
:
7449 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_GlobalNumber
));
7450 register_name
= "GlobalNumber";
7453 goto cp0_unimplemented
;
7456 case CP0_REGISTER_04
:
7458 case CP0_REG04__CONTEXT
:
7459 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_Context
));
7460 tcg_gen_ext32s_tl(arg
, arg
);
7461 register_name
= "Context";
7463 case CP0_REG04__CONTEXTCONFIG
:
7465 /* gen_helper_mfc0_contextconfig(arg); */
7466 register_name
= "ContextConfig";
7467 goto cp0_unimplemented
;
7468 case CP0_REG04__USERLOCAL
:
7469 CP0_CHECK(ctx
->ulri
);
7470 tcg_gen_ld_tl(arg
, cpu_env
,
7471 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
7472 tcg_gen_ext32s_tl(arg
, arg
);
7473 register_name
= "UserLocal";
7475 case CP0_REG04__MMID
:
7477 gen_helper_mtc0_memorymapid(cpu_env
, arg
);
7478 register_name
= "MMID";
7481 goto cp0_unimplemented
;
7484 case CP0_REGISTER_05
:
7486 case CP0_REG05__PAGEMASK
:
7487 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageMask
));
7488 register_name
= "PageMask";
7490 case CP0_REG05__PAGEGRAIN
:
7491 check_insn(ctx
, ISA_MIPS_R2
);
7492 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageGrain
));
7493 register_name
= "PageGrain";
7495 case CP0_REG05__SEGCTL0
:
7497 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_SegCtl0
));
7498 tcg_gen_ext32s_tl(arg
, arg
);
7499 register_name
= "SegCtl0";
7501 case CP0_REG05__SEGCTL1
:
7503 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_SegCtl1
));
7504 tcg_gen_ext32s_tl(arg
, arg
);
7505 register_name
= "SegCtl1";
7507 case CP0_REG05__SEGCTL2
:
7509 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_SegCtl2
));
7510 tcg_gen_ext32s_tl(arg
, arg
);
7511 register_name
= "SegCtl2";
7513 case CP0_REG05__PWBASE
:
7515 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PWBase
));
7516 register_name
= "PWBase";
7518 case CP0_REG05__PWFIELD
:
7520 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PWField
));
7521 register_name
= "PWField";
7523 case CP0_REG05__PWSIZE
:
7525 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PWSize
));
7526 register_name
= "PWSize";
7529 goto cp0_unimplemented
;
7532 case CP0_REGISTER_06
:
7534 case CP0_REG06__WIRED
:
7535 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Wired
));
7536 register_name
= "Wired";
7538 case CP0_REG06__SRSCONF0
:
7539 check_insn(ctx
, ISA_MIPS_R2
);
7540 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf0
));
7541 register_name
= "SRSConf0";
7543 case CP0_REG06__SRSCONF1
:
7544 check_insn(ctx
, ISA_MIPS_R2
);
7545 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf1
));
7546 register_name
= "SRSConf1";
7548 case CP0_REG06__SRSCONF2
:
7549 check_insn(ctx
, ISA_MIPS_R2
);
7550 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf2
));
7551 register_name
= "SRSConf2";
7553 case CP0_REG06__SRSCONF3
:
7554 check_insn(ctx
, ISA_MIPS_R2
);
7555 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf3
));
7556 register_name
= "SRSConf3";
7558 case CP0_REG06__SRSCONF4
:
7559 check_insn(ctx
, ISA_MIPS_R2
);
7560 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf4
));
7561 register_name
= "SRSConf4";
7563 case CP0_REG06__PWCTL
:
7565 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PWCtl
));
7566 register_name
= "PWCtl";
7569 goto cp0_unimplemented
;
7572 case CP0_REGISTER_07
:
7574 case CP0_REG07__HWRENA
:
7575 check_insn(ctx
, ISA_MIPS_R2
);
7576 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_HWREna
));
7577 register_name
= "HWREna";
7580 goto cp0_unimplemented
;
7583 case CP0_REGISTER_08
:
7585 case CP0_REG08__BADVADDR
:
7586 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_BadVAddr
));
7587 tcg_gen_ext32s_tl(arg
, arg
);
7588 register_name
= "BadVAddr";
7590 case CP0_REG08__BADINSTR
:
7592 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstr
));
7593 register_name
= "BadInstr";
7595 case CP0_REG08__BADINSTRP
:
7597 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstrP
));
7598 register_name
= "BadInstrP";
7600 case CP0_REG08__BADINSTRX
:
7602 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstrX
));
7603 tcg_gen_andi_tl(arg
, arg
, ~0xffff);
7604 register_name
= "BadInstrX";
7607 goto cp0_unimplemented
;
7610 case CP0_REGISTER_09
:
7612 case CP0_REG09__COUNT
:
7613 /* Mark as an IO operation because we read the time. */
7614 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
7617 gen_helper_mfc0_count(arg
, cpu_env
);
7619 * Break the TB to be able to take timer interrupts immediately
7620 * after reading count. DISAS_STOP isn't sufficient, we need to
7621 * ensure we break completely out of translated code.
7623 gen_save_pc(ctx
->base
.pc_next
+ 4);
7624 ctx
->base
.is_jmp
= DISAS_EXIT
;
7625 register_name
= "Count";
7627 case CP0_REG09__SAARI
:
7628 CP0_CHECK(ctx
->saar
);
7629 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SAARI
));
7630 register_name
= "SAARI";
7632 case CP0_REG09__SAAR
:
7633 CP0_CHECK(ctx
->saar
);
7634 gen_helper_mfc0_saar(arg
, cpu_env
);
7635 register_name
= "SAAR";
7638 goto cp0_unimplemented
;
7641 case CP0_REGISTER_10
:
7643 case CP0_REG10__ENTRYHI
:
7644 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryHi
));
7645 tcg_gen_ext32s_tl(arg
, arg
);
7646 register_name
= "EntryHi";
7649 goto cp0_unimplemented
;
7652 case CP0_REGISTER_11
:
7654 case CP0_REG11__COMPARE
:
7655 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Compare
));
7656 register_name
= "Compare";
7658 /* 6,7 are implementation dependent */
7660 goto cp0_unimplemented
;
7663 case CP0_REGISTER_12
:
7665 case CP0_REG12__STATUS
:
7666 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Status
));
7667 register_name
= "Status";
7669 case CP0_REG12__INTCTL
:
7670 check_insn(ctx
, ISA_MIPS_R2
);
7671 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_IntCtl
));
7672 register_name
= "IntCtl";
7674 case CP0_REG12__SRSCTL
:
7675 check_insn(ctx
, ISA_MIPS_R2
);
7676 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
7677 register_name
= "SRSCtl";
7679 case CP0_REG12__SRSMAP
:
7680 check_insn(ctx
, ISA_MIPS_R2
);
7681 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
7682 register_name
= "SRSMap";
7685 goto cp0_unimplemented
;
7688 case CP0_REGISTER_13
:
7690 case CP0_REG13__CAUSE
:
7691 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Cause
));
7692 register_name
= "Cause";
7695 goto cp0_unimplemented
;
7698 case CP0_REGISTER_14
:
7700 case CP0_REG14__EPC
:
7701 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
7702 tcg_gen_ext32s_tl(arg
, arg
);
7703 register_name
= "EPC";
7706 goto cp0_unimplemented
;
7709 case CP0_REGISTER_15
:
7711 case CP0_REG15__PRID
:
7712 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PRid
));
7713 register_name
= "PRid";
7715 case CP0_REG15__EBASE
:
7716 check_insn(ctx
, ISA_MIPS_R2
);
7717 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EBase
));
7718 tcg_gen_ext32s_tl(arg
, arg
);
7719 register_name
= "EBase";
7721 case CP0_REG15__CMGCRBASE
:
7722 check_insn(ctx
, ISA_MIPS_R2
);
7723 CP0_CHECK(ctx
->cmgcr
);
7724 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_CMGCRBase
));
7725 tcg_gen_ext32s_tl(arg
, arg
);
7726 register_name
= "CMGCRBase";
7729 goto cp0_unimplemented
;
7732 case CP0_REGISTER_16
:
7734 case CP0_REG16__CONFIG
:
7735 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config0
));
7736 register_name
= "Config";
7738 case CP0_REG16__CONFIG1
:
7739 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config1
));
7740 register_name
= "Config1";
7742 case CP0_REG16__CONFIG2
:
7743 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config2
));
7744 register_name
= "Config2";
7746 case CP0_REG16__CONFIG3
:
7747 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config3
));
7748 register_name
= "Config3";
7750 case CP0_REG16__CONFIG4
:
7751 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config4
));
7752 register_name
= "Config4";
7754 case CP0_REG16__CONFIG5
:
7755 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config5
));
7756 register_name
= "Config5";
7758 /* 6,7 are implementation dependent */
7759 case CP0_REG16__CONFIG6
:
7760 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config6
));
7761 register_name
= "Config6";
7763 case CP0_REG16__CONFIG7
:
7764 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config7
));
7765 register_name
= "Config7";
7768 goto cp0_unimplemented
;
7771 case CP0_REGISTER_17
:
7773 case CP0_REG17__LLADDR
:
7774 gen_helper_mfc0_lladdr(arg
, cpu_env
);
7775 register_name
= "LLAddr";
7777 case CP0_REG17__MAAR
:
7778 CP0_CHECK(ctx
->mrp
);
7779 gen_helper_mfc0_maar(arg
, cpu_env
);
7780 register_name
= "MAAR";
7782 case CP0_REG17__MAARI
:
7783 CP0_CHECK(ctx
->mrp
);
7784 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_MAARI
));
7785 register_name
= "MAARI";
7788 goto cp0_unimplemented
;
7791 case CP0_REGISTER_18
:
7793 case CP0_REG18__WATCHLO0
:
7794 case CP0_REG18__WATCHLO1
:
7795 case CP0_REG18__WATCHLO2
:
7796 case CP0_REG18__WATCHLO3
:
7797 case CP0_REG18__WATCHLO4
:
7798 case CP0_REG18__WATCHLO5
:
7799 case CP0_REG18__WATCHLO6
:
7800 case CP0_REG18__WATCHLO7
:
7801 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
7802 gen_helper_1e0i(mfc0_watchlo
, arg
, sel
);
7803 register_name
= "WatchLo";
7806 goto cp0_unimplemented
;
7809 case CP0_REGISTER_19
:
7811 case CP0_REG19__WATCHHI0
:
7812 case CP0_REG19__WATCHHI1
:
7813 case CP0_REG19__WATCHHI2
:
7814 case CP0_REG19__WATCHHI3
:
7815 case CP0_REG19__WATCHHI4
:
7816 case CP0_REG19__WATCHHI5
:
7817 case CP0_REG19__WATCHHI6
:
7818 case CP0_REG19__WATCHHI7
:
7819 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
7820 gen_helper_1e0i(mfc0_watchhi
, arg
, sel
);
7821 register_name
= "WatchHi";
7824 goto cp0_unimplemented
;
7827 case CP0_REGISTER_20
:
7829 case CP0_REG20__XCONTEXT
:
7830 #if defined(TARGET_MIPS64)
7831 check_insn(ctx
, ISA_MIPS3
);
7832 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_XContext
));
7833 tcg_gen_ext32s_tl(arg
, arg
);
7834 register_name
= "XContext";
7838 goto cp0_unimplemented
;
7841 case CP0_REGISTER_21
:
7842 /* Officially reserved, but sel 0 is used for R1x000 framemask */
7843 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS_R6
));
7846 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Framemask
));
7847 register_name
= "Framemask";
7850 goto cp0_unimplemented
;
7853 case CP0_REGISTER_22
:
7854 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
7855 register_name
= "'Diagnostic"; /* implementation dependent */
7857 case CP0_REGISTER_23
:
7859 case CP0_REG23__DEBUG
:
7860 gen_helper_mfc0_debug(arg
, cpu_env
); /* EJTAG support */
7861 register_name
= "Debug";
7863 case CP0_REG23__TRACECONTROL
:
7864 /* PDtrace support */
7865 /* gen_helper_mfc0_tracecontrol(arg); */
7866 register_name
= "TraceControl";
7867 goto cp0_unimplemented
;
7868 case CP0_REG23__TRACECONTROL2
:
7869 /* PDtrace support */
7870 /* gen_helper_mfc0_tracecontrol2(arg); */
7871 register_name
= "TraceControl2";
7872 goto cp0_unimplemented
;
7873 case CP0_REG23__USERTRACEDATA1
:
7874 /* PDtrace support */
7875 /* gen_helper_mfc0_usertracedata1(arg);*/
7876 register_name
= "UserTraceData1";
7877 goto cp0_unimplemented
;
7878 case CP0_REG23__TRACEIBPC
:
7879 /* PDtrace support */
7880 /* gen_helper_mfc0_traceibpc(arg); */
7881 register_name
= "TraceIBPC";
7882 goto cp0_unimplemented
;
7883 case CP0_REG23__TRACEDBPC
:
7884 /* PDtrace support */
7885 /* gen_helper_mfc0_tracedbpc(arg); */
7886 register_name
= "TraceDBPC";
7887 goto cp0_unimplemented
;
7889 goto cp0_unimplemented
;
7892 case CP0_REGISTER_24
:
7894 case CP0_REG24__DEPC
:
7896 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
7897 tcg_gen_ext32s_tl(arg
, arg
);
7898 register_name
= "DEPC";
7901 goto cp0_unimplemented
;
7904 case CP0_REGISTER_25
:
7906 case CP0_REG25__PERFCTL0
:
7907 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Performance0
));
7908 register_name
= "Performance0";
7910 case CP0_REG25__PERFCNT0
:
7911 /* gen_helper_mfc0_performance1(arg); */
7912 register_name
= "Performance1";
7913 goto cp0_unimplemented
;
7914 case CP0_REG25__PERFCTL1
:
7915 /* gen_helper_mfc0_performance2(arg); */
7916 register_name
= "Performance2";
7917 goto cp0_unimplemented
;
7918 case CP0_REG25__PERFCNT1
:
7919 /* gen_helper_mfc0_performance3(arg); */
7920 register_name
= "Performance3";
7921 goto cp0_unimplemented
;
7922 case CP0_REG25__PERFCTL2
:
7923 /* gen_helper_mfc0_performance4(arg); */
7924 register_name
= "Performance4";
7925 goto cp0_unimplemented
;
7926 case CP0_REG25__PERFCNT2
:
7927 /* gen_helper_mfc0_performance5(arg); */
7928 register_name
= "Performance5";
7929 goto cp0_unimplemented
;
7930 case CP0_REG25__PERFCTL3
:
7931 /* gen_helper_mfc0_performance6(arg); */
7932 register_name
= "Performance6";
7933 goto cp0_unimplemented
;
7934 case CP0_REG25__PERFCNT3
:
7935 /* gen_helper_mfc0_performance7(arg); */
7936 register_name
= "Performance7";
7937 goto cp0_unimplemented
;
7939 goto cp0_unimplemented
;
7942 case CP0_REGISTER_26
:
7944 case CP0_REG26__ERRCTL
:
7945 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_ErrCtl
));
7946 register_name
= "ErrCtl";
7949 goto cp0_unimplemented
;
7952 case CP0_REGISTER_27
:
7954 case CP0_REG27__CACHERR
:
7955 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
7956 register_name
= "CacheErr";
7959 goto cp0_unimplemented
;
7962 case CP0_REGISTER_28
:
7964 case CP0_REG28__TAGLO
:
7965 case CP0_REG28__TAGLO1
:
7966 case CP0_REG28__TAGLO2
:
7967 case CP0_REG28__TAGLO3
:
7969 TCGv_i64 tmp
= tcg_temp_new_i64();
7970 tcg_gen_ld_i64(tmp
, cpu_env
, offsetof(CPUMIPSState
, CP0_TagLo
));
7971 gen_move_low32(arg
, tmp
);
7972 tcg_temp_free_i64(tmp
);
7974 register_name
= "TagLo";
7976 case CP0_REG28__DATALO
:
7977 case CP0_REG28__DATALO1
:
7978 case CP0_REG28__DATALO2
:
7979 case CP0_REG28__DATALO3
:
7980 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataLo
));
7981 register_name
= "DataLo";
7984 goto cp0_unimplemented
;
7987 case CP0_REGISTER_29
:
7989 case CP0_REG29__TAGHI
:
7990 case CP0_REG29__TAGHI1
:
7991 case CP0_REG29__TAGHI2
:
7992 case CP0_REG29__TAGHI3
:
7993 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagHi
));
7994 register_name
= "TagHi";
7996 case CP0_REG29__DATAHI
:
7997 case CP0_REG29__DATAHI1
:
7998 case CP0_REG29__DATAHI2
:
7999 case CP0_REG29__DATAHI3
:
8000 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataHi
));
8001 register_name
= "DataHi";
8004 goto cp0_unimplemented
;
8007 case CP0_REGISTER_30
:
8009 case CP0_REG30__ERROREPC
:
8010 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
8011 tcg_gen_ext32s_tl(arg
, arg
);
8012 register_name
= "ErrorEPC";
8015 goto cp0_unimplemented
;
8018 case CP0_REGISTER_31
:
8020 case CP0_REG31__DESAVE
:
8022 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
8023 register_name
= "DESAVE";
8025 case CP0_REG31__KSCRATCH1
:
8026 case CP0_REG31__KSCRATCH2
:
8027 case CP0_REG31__KSCRATCH3
:
8028 case CP0_REG31__KSCRATCH4
:
8029 case CP0_REG31__KSCRATCH5
:
8030 case CP0_REG31__KSCRATCH6
:
8031 CP0_CHECK(ctx
->kscrexist
& (1 << sel
));
8032 tcg_gen_ld_tl(arg
, cpu_env
,
8033 offsetof(CPUMIPSState
, CP0_KScratch
[sel
- 2]));
8034 tcg_gen_ext32s_tl(arg
, arg
);
8035 register_name
= "KScratch";
8038 goto cp0_unimplemented
;
8042 goto cp0_unimplemented
;
8044 trace_mips_translate_c0("mfc0", register_name
, reg
, sel
);
8048 qemu_log_mask(LOG_UNIMP
, "mfc0 %s (reg %d sel %d)\n",
8049 register_name
, reg
, sel
);
8050 gen_mfc0_unimplemented(ctx
, arg
);
8053 static void gen_mtc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
8055 const char *register_name
= "invalid";
8058 check_insn(ctx
, ISA_MIPS_R1
);
8061 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
8066 case CP0_REGISTER_00
:
8068 case CP0_REG00__INDEX
:
8069 gen_helper_mtc0_index(cpu_env
, arg
);
8070 register_name
= "Index";
8072 case CP0_REG00__MVPCONTROL
:
8073 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8074 gen_helper_mtc0_mvpcontrol(cpu_env
, arg
);
8075 register_name
= "MVPControl";
8077 case CP0_REG00__MVPCONF0
:
8078 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8080 register_name
= "MVPConf0";
8082 case CP0_REG00__MVPCONF1
:
8083 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8085 register_name
= "MVPConf1";
8087 case CP0_REG00__VPCONTROL
:
8090 register_name
= "VPControl";
8093 goto cp0_unimplemented
;
8096 case CP0_REGISTER_01
:
8098 case CP0_REG01__RANDOM
:
8100 register_name
= "Random";
8102 case CP0_REG01__VPECONTROL
:
8103 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8104 gen_helper_mtc0_vpecontrol(cpu_env
, arg
);
8105 register_name
= "VPEControl";
8107 case CP0_REG01__VPECONF0
:
8108 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8109 gen_helper_mtc0_vpeconf0(cpu_env
, arg
);
8110 register_name
= "VPEConf0";
8112 case CP0_REG01__VPECONF1
:
8113 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8114 gen_helper_mtc0_vpeconf1(cpu_env
, arg
);
8115 register_name
= "VPEConf1";
8117 case CP0_REG01__YQMASK
:
8118 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8119 gen_helper_mtc0_yqmask(cpu_env
, arg
);
8120 register_name
= "YQMask";
8122 case CP0_REG01__VPESCHEDULE
:
8123 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8124 tcg_gen_st_tl(arg
, cpu_env
,
8125 offsetof(CPUMIPSState
, CP0_VPESchedule
));
8126 register_name
= "VPESchedule";
8128 case CP0_REG01__VPESCHEFBACK
:
8129 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8130 tcg_gen_st_tl(arg
, cpu_env
,
8131 offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
8132 register_name
= "VPEScheFBack";
8134 case CP0_REG01__VPEOPT
:
8135 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8136 gen_helper_mtc0_vpeopt(cpu_env
, arg
);
8137 register_name
= "VPEOpt";
8140 goto cp0_unimplemented
;
8143 case CP0_REGISTER_02
:
8145 case CP0_REG02__ENTRYLO0
:
8146 gen_helper_mtc0_entrylo0(cpu_env
, arg
);
8147 register_name
= "EntryLo0";
8149 case CP0_REG02__TCSTATUS
:
8150 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8151 gen_helper_mtc0_tcstatus(cpu_env
, arg
);
8152 register_name
= "TCStatus";
8154 case CP0_REG02__TCBIND
:
8155 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8156 gen_helper_mtc0_tcbind(cpu_env
, arg
);
8157 register_name
= "TCBind";
8159 case CP0_REG02__TCRESTART
:
8160 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8161 gen_helper_mtc0_tcrestart(cpu_env
, arg
);
8162 register_name
= "TCRestart";
8164 case CP0_REG02__TCHALT
:
8165 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8166 gen_helper_mtc0_tchalt(cpu_env
, arg
);
8167 register_name
= "TCHalt";
8169 case CP0_REG02__TCCONTEXT
:
8170 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8171 gen_helper_mtc0_tccontext(cpu_env
, arg
);
8172 register_name
= "TCContext";
8174 case CP0_REG02__TCSCHEDULE
:
8175 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8176 gen_helper_mtc0_tcschedule(cpu_env
, arg
);
8177 register_name
= "TCSchedule";
8179 case CP0_REG02__TCSCHEFBACK
:
8180 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8181 gen_helper_mtc0_tcschefback(cpu_env
, arg
);
8182 register_name
= "TCScheFBack";
8185 goto cp0_unimplemented
;
8188 case CP0_REGISTER_03
:
8190 case CP0_REG03__ENTRYLO1
:
8191 gen_helper_mtc0_entrylo1(cpu_env
, arg
);
8192 register_name
= "EntryLo1";
8194 case CP0_REG03__GLOBALNUM
:
8197 register_name
= "GlobalNumber";
8200 goto cp0_unimplemented
;
8203 case CP0_REGISTER_04
:
8205 case CP0_REG04__CONTEXT
:
8206 gen_helper_mtc0_context(cpu_env
, arg
);
8207 register_name
= "Context";
8209 case CP0_REG04__CONTEXTCONFIG
:
8211 /* gen_helper_mtc0_contextconfig(arg); */
8212 register_name
= "ContextConfig";
8213 goto cp0_unimplemented
;
8214 case CP0_REG04__USERLOCAL
:
8215 CP0_CHECK(ctx
->ulri
);
8216 tcg_gen_st_tl(arg
, cpu_env
,
8217 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
8218 register_name
= "UserLocal";
8220 case CP0_REG04__MMID
:
8222 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_MemoryMapID
));
8223 register_name
= "MMID";
8226 goto cp0_unimplemented
;
8229 case CP0_REGISTER_05
:
8231 case CP0_REG05__PAGEMASK
:
8232 gen_helper_mtc0_pagemask(cpu_env
, arg
);
8233 register_name
= "PageMask";
8235 case CP0_REG05__PAGEGRAIN
:
8236 check_insn(ctx
, ISA_MIPS_R2
);
8237 gen_helper_mtc0_pagegrain(cpu_env
, arg
);
8238 register_name
= "PageGrain";
8239 ctx
->base
.is_jmp
= DISAS_STOP
;
8241 case CP0_REG05__SEGCTL0
:
8243 gen_helper_mtc0_segctl0(cpu_env
, arg
);
8244 register_name
= "SegCtl0";
8246 case CP0_REG05__SEGCTL1
:
8248 gen_helper_mtc0_segctl1(cpu_env
, arg
);
8249 register_name
= "SegCtl1";
8251 case CP0_REG05__SEGCTL2
:
8253 gen_helper_mtc0_segctl2(cpu_env
, arg
);
8254 register_name
= "SegCtl2";
8256 case CP0_REG05__PWBASE
:
8258 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_PWBase
));
8259 register_name
= "PWBase";
8261 case CP0_REG05__PWFIELD
:
8263 gen_helper_mtc0_pwfield(cpu_env
, arg
);
8264 register_name
= "PWField";
8266 case CP0_REG05__PWSIZE
:
8268 gen_helper_mtc0_pwsize(cpu_env
, arg
);
8269 register_name
= "PWSize";
8272 goto cp0_unimplemented
;
8275 case CP0_REGISTER_06
:
8277 case CP0_REG06__WIRED
:
8278 gen_helper_mtc0_wired(cpu_env
, arg
);
8279 register_name
= "Wired";
8281 case CP0_REG06__SRSCONF0
:
8282 check_insn(ctx
, ISA_MIPS_R2
);
8283 gen_helper_mtc0_srsconf0(cpu_env
, arg
);
8284 register_name
= "SRSConf0";
8286 case CP0_REG06__SRSCONF1
:
8287 check_insn(ctx
, ISA_MIPS_R2
);
8288 gen_helper_mtc0_srsconf1(cpu_env
, arg
);
8289 register_name
= "SRSConf1";
8291 case CP0_REG06__SRSCONF2
:
8292 check_insn(ctx
, ISA_MIPS_R2
);
8293 gen_helper_mtc0_srsconf2(cpu_env
, arg
);
8294 register_name
= "SRSConf2";
8296 case CP0_REG06__SRSCONF3
:
8297 check_insn(ctx
, ISA_MIPS_R2
);
8298 gen_helper_mtc0_srsconf3(cpu_env
, arg
);
8299 register_name
= "SRSConf3";
8301 case CP0_REG06__SRSCONF4
:
8302 check_insn(ctx
, ISA_MIPS_R2
);
8303 gen_helper_mtc0_srsconf4(cpu_env
, arg
);
8304 register_name
= "SRSConf4";
8306 case CP0_REG06__PWCTL
:
8308 gen_helper_mtc0_pwctl(cpu_env
, arg
);
8309 register_name
= "PWCtl";
8312 goto cp0_unimplemented
;
8315 case CP0_REGISTER_07
:
8317 case CP0_REG07__HWRENA
:
8318 check_insn(ctx
, ISA_MIPS_R2
);
8319 gen_helper_mtc0_hwrena(cpu_env
, arg
);
8320 ctx
->base
.is_jmp
= DISAS_STOP
;
8321 register_name
= "HWREna";
8324 goto cp0_unimplemented
;
8327 case CP0_REGISTER_08
:
8329 case CP0_REG08__BADVADDR
:
8331 register_name
= "BadVAddr";
8333 case CP0_REG08__BADINSTR
:
8335 register_name
= "BadInstr";
8337 case CP0_REG08__BADINSTRP
:
8339 register_name
= "BadInstrP";
8341 case CP0_REG08__BADINSTRX
:
8343 register_name
= "BadInstrX";
8346 goto cp0_unimplemented
;
8349 case CP0_REGISTER_09
:
8351 case CP0_REG09__COUNT
:
8352 gen_helper_mtc0_count(cpu_env
, arg
);
8353 register_name
= "Count";
8355 case CP0_REG09__SAARI
:
8356 CP0_CHECK(ctx
->saar
);
8357 gen_helper_mtc0_saari(cpu_env
, arg
);
8358 register_name
= "SAARI";
8360 case CP0_REG09__SAAR
:
8361 CP0_CHECK(ctx
->saar
);
8362 gen_helper_mtc0_saar(cpu_env
, arg
);
8363 register_name
= "SAAR";
8366 goto cp0_unimplemented
;
8369 case CP0_REGISTER_10
:
8371 case CP0_REG10__ENTRYHI
:
8372 gen_helper_mtc0_entryhi(cpu_env
, arg
);
8373 register_name
= "EntryHi";
8376 goto cp0_unimplemented
;
8379 case CP0_REGISTER_11
:
8381 case CP0_REG11__COMPARE
:
8382 gen_helper_mtc0_compare(cpu_env
, arg
);
8383 register_name
= "Compare";
8385 /* 6,7 are implementation dependent */
8387 goto cp0_unimplemented
;
8390 case CP0_REGISTER_12
:
8392 case CP0_REG12__STATUS
:
8393 save_cpu_state(ctx
, 1);
8394 gen_helper_mtc0_status(cpu_env
, arg
);
8395 /* DISAS_STOP isn't good enough here, hflags may have changed. */
8396 gen_save_pc(ctx
->base
.pc_next
+ 4);
8397 ctx
->base
.is_jmp
= DISAS_EXIT
;
8398 register_name
= "Status";
8400 case CP0_REG12__INTCTL
:
8401 check_insn(ctx
, ISA_MIPS_R2
);
8402 gen_helper_mtc0_intctl(cpu_env
, arg
);
8403 /* Stop translation as we may have switched the execution mode */
8404 ctx
->base
.is_jmp
= DISAS_STOP
;
8405 register_name
= "IntCtl";
8407 case CP0_REG12__SRSCTL
:
8408 check_insn(ctx
, ISA_MIPS_R2
);
8409 gen_helper_mtc0_srsctl(cpu_env
, arg
);
8410 /* Stop translation as we may have switched the execution mode */
8411 ctx
->base
.is_jmp
= DISAS_STOP
;
8412 register_name
= "SRSCtl";
8414 case CP0_REG12__SRSMAP
:
8415 check_insn(ctx
, ISA_MIPS_R2
);
8416 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
8417 /* Stop translation as we may have switched the execution mode */
8418 ctx
->base
.is_jmp
= DISAS_STOP
;
8419 register_name
= "SRSMap";
8422 goto cp0_unimplemented
;
8425 case CP0_REGISTER_13
:
8427 case CP0_REG13__CAUSE
:
8428 save_cpu_state(ctx
, 1);
8429 gen_helper_mtc0_cause(cpu_env
, arg
);
8431 * Stop translation as we may have triggered an interrupt.
8432 * DISAS_STOP isn't sufficient, we need to ensure we break out of
8433 * translated code to check for pending interrupts.
8435 gen_save_pc(ctx
->base
.pc_next
+ 4);
8436 ctx
->base
.is_jmp
= DISAS_EXIT
;
8437 register_name
= "Cause";
8440 goto cp0_unimplemented
;
8443 case CP0_REGISTER_14
:
8445 case CP0_REG14__EPC
:
8446 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
8447 register_name
= "EPC";
8450 goto cp0_unimplemented
;
8453 case CP0_REGISTER_15
:
8455 case CP0_REG15__PRID
:
8457 register_name
= "PRid";
8459 case CP0_REG15__EBASE
:
8460 check_insn(ctx
, ISA_MIPS_R2
);
8461 gen_helper_mtc0_ebase(cpu_env
, arg
);
8462 register_name
= "EBase";
8465 goto cp0_unimplemented
;
8468 case CP0_REGISTER_16
:
8470 case CP0_REG16__CONFIG
:
8471 gen_helper_mtc0_config0(cpu_env
, arg
);
8472 register_name
= "Config";
8473 /* Stop translation as we may have switched the execution mode */
8474 ctx
->base
.is_jmp
= DISAS_STOP
;
8476 case CP0_REG16__CONFIG1
:
8477 /* ignored, read only */
8478 register_name
= "Config1";
8480 case CP0_REG16__CONFIG2
:
8481 gen_helper_mtc0_config2(cpu_env
, arg
);
8482 register_name
= "Config2";
8483 /* Stop translation as we may have switched the execution mode */
8484 ctx
->base
.is_jmp
= DISAS_STOP
;
8486 case CP0_REG16__CONFIG3
:
8487 gen_helper_mtc0_config3(cpu_env
, arg
);
8488 register_name
= "Config3";
8489 /* Stop translation as we may have switched the execution mode */
8490 ctx
->base
.is_jmp
= DISAS_STOP
;
8492 case CP0_REG16__CONFIG4
:
8493 gen_helper_mtc0_config4(cpu_env
, arg
);
8494 register_name
= "Config4";
8495 ctx
->base
.is_jmp
= DISAS_STOP
;
8497 case CP0_REG16__CONFIG5
:
8498 gen_helper_mtc0_config5(cpu_env
, arg
);
8499 register_name
= "Config5";
8500 /* Stop translation as we may have switched the execution mode */
8501 ctx
->base
.is_jmp
= DISAS_STOP
;
8503 /* 6,7 are implementation dependent */
8504 case CP0_REG16__CONFIG6
:
8506 register_name
= "Config6";
8508 case CP0_REG16__CONFIG7
:
8510 register_name
= "Config7";
8513 register_name
= "Invalid config selector";
8514 goto cp0_unimplemented
;
8517 case CP0_REGISTER_17
:
8519 case CP0_REG17__LLADDR
:
8520 gen_helper_mtc0_lladdr(cpu_env
, arg
);
8521 register_name
= "LLAddr";
8523 case CP0_REG17__MAAR
:
8524 CP0_CHECK(ctx
->mrp
);
8525 gen_helper_mtc0_maar(cpu_env
, arg
);
8526 register_name
= "MAAR";
8528 case CP0_REG17__MAARI
:
8529 CP0_CHECK(ctx
->mrp
);
8530 gen_helper_mtc0_maari(cpu_env
, arg
);
8531 register_name
= "MAARI";
8534 goto cp0_unimplemented
;
8537 case CP0_REGISTER_18
:
8539 case CP0_REG18__WATCHLO0
:
8540 case CP0_REG18__WATCHLO1
:
8541 case CP0_REG18__WATCHLO2
:
8542 case CP0_REG18__WATCHLO3
:
8543 case CP0_REG18__WATCHLO4
:
8544 case CP0_REG18__WATCHLO5
:
8545 case CP0_REG18__WATCHLO6
:
8546 case CP0_REG18__WATCHLO7
:
8547 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
8548 gen_helper_0e1i(mtc0_watchlo
, arg
, sel
);
8549 register_name
= "WatchLo";
8552 goto cp0_unimplemented
;
8555 case CP0_REGISTER_19
:
8557 case CP0_REG19__WATCHHI0
:
8558 case CP0_REG19__WATCHHI1
:
8559 case CP0_REG19__WATCHHI2
:
8560 case CP0_REG19__WATCHHI3
:
8561 case CP0_REG19__WATCHHI4
:
8562 case CP0_REG19__WATCHHI5
:
8563 case CP0_REG19__WATCHHI6
:
8564 case CP0_REG19__WATCHHI7
:
8565 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
8566 gen_helper_0e1i(mtc0_watchhi
, arg
, sel
);
8567 register_name
= "WatchHi";
8570 goto cp0_unimplemented
;
8573 case CP0_REGISTER_20
:
8575 case CP0_REG20__XCONTEXT
:
8576 #if defined(TARGET_MIPS64)
8577 check_insn(ctx
, ISA_MIPS3
);
8578 gen_helper_mtc0_xcontext(cpu_env
, arg
);
8579 register_name
= "XContext";
8583 goto cp0_unimplemented
;
8586 case CP0_REGISTER_21
:
8587 /* Officially reserved, but sel 0 is used for R1x000 framemask */
8588 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS_R6
));
8591 gen_helper_mtc0_framemask(cpu_env
, arg
);
8592 register_name
= "Framemask";
8595 goto cp0_unimplemented
;
8598 case CP0_REGISTER_22
:
8600 register_name
= "Diagnostic"; /* implementation dependent */
8602 case CP0_REGISTER_23
:
8604 case CP0_REG23__DEBUG
:
8605 gen_helper_mtc0_debug(cpu_env
, arg
); /* EJTAG support */
8606 /* DISAS_STOP isn't good enough here, hflags may have changed. */
8607 gen_save_pc(ctx
->base
.pc_next
+ 4);
8608 ctx
->base
.is_jmp
= DISAS_EXIT
;
8609 register_name
= "Debug";
8611 case CP0_REG23__TRACECONTROL
:
8612 /* PDtrace support */
8613 /* gen_helper_mtc0_tracecontrol(cpu_env, arg); */
8614 register_name
= "TraceControl";
8615 /* Stop translation as we may have switched the execution mode */
8616 ctx
->base
.is_jmp
= DISAS_STOP
;
8617 goto cp0_unimplemented
;
8618 case CP0_REG23__TRACECONTROL2
:
8619 /* PDtrace support */
8620 /* gen_helper_mtc0_tracecontrol2(cpu_env, arg); */
8621 register_name
= "TraceControl2";
8622 /* Stop translation as we may have switched the execution mode */
8623 ctx
->base
.is_jmp
= DISAS_STOP
;
8624 goto cp0_unimplemented
;
8625 case CP0_REG23__USERTRACEDATA1
:
8626 /* Stop translation as we may have switched the execution mode */
8627 ctx
->base
.is_jmp
= DISAS_STOP
;
8628 /* PDtrace support */
8629 /* gen_helper_mtc0_usertracedata1(cpu_env, arg);*/
8630 register_name
= "UserTraceData";
8631 /* Stop translation as we may have switched the execution mode */
8632 ctx
->base
.is_jmp
= DISAS_STOP
;
8633 goto cp0_unimplemented
;
8634 case CP0_REG23__TRACEIBPC
:
8635 /* PDtrace support */
8636 /* gen_helper_mtc0_traceibpc(cpu_env, arg); */
8637 /* Stop translation as we may have switched the execution mode */
8638 ctx
->base
.is_jmp
= DISAS_STOP
;
8639 register_name
= "TraceIBPC";
8640 goto cp0_unimplemented
;
8641 case CP0_REG23__TRACEDBPC
:
8642 /* PDtrace support */
8643 /* gen_helper_mtc0_tracedbpc(cpu_env, arg); */
8644 /* Stop translation as we may have switched the execution mode */
8645 ctx
->base
.is_jmp
= DISAS_STOP
;
8646 register_name
= "TraceDBPC";
8647 goto cp0_unimplemented
;
8649 goto cp0_unimplemented
;
8652 case CP0_REGISTER_24
:
8654 case CP0_REG24__DEPC
:
8656 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
8657 register_name
= "DEPC";
8660 goto cp0_unimplemented
;
8663 case CP0_REGISTER_25
:
8665 case CP0_REG25__PERFCTL0
:
8666 gen_helper_mtc0_performance0(cpu_env
, arg
);
8667 register_name
= "Performance0";
8669 case CP0_REG25__PERFCNT0
:
8670 /* gen_helper_mtc0_performance1(arg); */
8671 register_name
= "Performance1";
8672 goto cp0_unimplemented
;
8673 case CP0_REG25__PERFCTL1
:
8674 /* gen_helper_mtc0_performance2(arg); */
8675 register_name
= "Performance2";
8676 goto cp0_unimplemented
;
8677 case CP0_REG25__PERFCNT1
:
8678 /* gen_helper_mtc0_performance3(arg); */
8679 register_name
= "Performance3";
8680 goto cp0_unimplemented
;
8681 case CP0_REG25__PERFCTL2
:
8682 /* gen_helper_mtc0_performance4(arg); */
8683 register_name
= "Performance4";
8684 goto cp0_unimplemented
;
8685 case CP0_REG25__PERFCNT2
:
8686 /* gen_helper_mtc0_performance5(arg); */
8687 register_name
= "Performance5";
8688 goto cp0_unimplemented
;
8689 case CP0_REG25__PERFCTL3
:
8690 /* gen_helper_mtc0_performance6(arg); */
8691 register_name
= "Performance6";
8692 goto cp0_unimplemented
;
8693 case CP0_REG25__PERFCNT3
:
8694 /* gen_helper_mtc0_performance7(arg); */
8695 register_name
= "Performance7";
8696 goto cp0_unimplemented
;
8698 goto cp0_unimplemented
;
8701 case CP0_REGISTER_26
:
8703 case CP0_REG26__ERRCTL
:
8704 gen_helper_mtc0_errctl(cpu_env
, arg
);
8705 ctx
->base
.is_jmp
= DISAS_STOP
;
8706 register_name
= "ErrCtl";
8709 goto cp0_unimplemented
;
8712 case CP0_REGISTER_27
:
8714 case CP0_REG27__CACHERR
:
8716 register_name
= "CacheErr";
8719 goto cp0_unimplemented
;
8722 case CP0_REGISTER_28
:
8724 case CP0_REG28__TAGLO
:
8725 case CP0_REG28__TAGLO1
:
8726 case CP0_REG28__TAGLO2
:
8727 case CP0_REG28__TAGLO3
:
8728 gen_helper_mtc0_taglo(cpu_env
, arg
);
8729 register_name
= "TagLo";
8731 case CP0_REG28__DATALO
:
8732 case CP0_REG28__DATALO1
:
8733 case CP0_REG28__DATALO2
:
8734 case CP0_REG28__DATALO3
:
8735 gen_helper_mtc0_datalo(cpu_env
, arg
);
8736 register_name
= "DataLo";
8739 goto cp0_unimplemented
;
8742 case CP0_REGISTER_29
:
8744 case CP0_REG29__TAGHI
:
8745 case CP0_REG29__TAGHI1
:
8746 case CP0_REG29__TAGHI2
:
8747 case CP0_REG29__TAGHI3
:
8748 gen_helper_mtc0_taghi(cpu_env
, arg
);
8749 register_name
= "TagHi";
8751 case CP0_REG29__DATAHI
:
8752 case CP0_REG29__DATAHI1
:
8753 case CP0_REG29__DATAHI2
:
8754 case CP0_REG29__DATAHI3
:
8755 gen_helper_mtc0_datahi(cpu_env
, arg
);
8756 register_name
= "DataHi";
8759 register_name
= "invalid sel";
8760 goto cp0_unimplemented
;
8763 case CP0_REGISTER_30
:
8765 case CP0_REG30__ERROREPC
:
8766 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
8767 register_name
= "ErrorEPC";
8770 goto cp0_unimplemented
;
8773 case CP0_REGISTER_31
:
8775 case CP0_REG31__DESAVE
:
8777 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
8778 register_name
= "DESAVE";
8780 case CP0_REG31__KSCRATCH1
:
8781 case CP0_REG31__KSCRATCH2
:
8782 case CP0_REG31__KSCRATCH3
:
8783 case CP0_REG31__KSCRATCH4
:
8784 case CP0_REG31__KSCRATCH5
:
8785 case CP0_REG31__KSCRATCH6
:
8786 CP0_CHECK(ctx
->kscrexist
& (1 << sel
));
8787 tcg_gen_st_tl(arg
, cpu_env
,
8788 offsetof(CPUMIPSState
, CP0_KScratch
[sel
- 2]));
8789 register_name
= "KScratch";
8792 goto cp0_unimplemented
;
8796 goto cp0_unimplemented
;
8798 trace_mips_translate_c0("mtc0", register_name
, reg
, sel
);
8800 /* For simplicity assume that all writes can cause interrupts. */
8801 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
8803 * DISAS_STOP isn't sufficient, we need to ensure we break out of
8804 * translated code to check for pending interrupts.
8806 gen_save_pc(ctx
->base
.pc_next
+ 4);
8807 ctx
->base
.is_jmp
= DISAS_EXIT
;
8812 qemu_log_mask(LOG_UNIMP
, "mtc0 %s (reg %d sel %d)\n",
8813 register_name
, reg
, sel
);
8816 #if defined(TARGET_MIPS64)
8817 static void gen_dmfc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
8819 const char *register_name
= "invalid";
8822 check_insn(ctx
, ISA_MIPS_R1
);
8826 case CP0_REGISTER_00
:
8828 case CP0_REG00__INDEX
:
8829 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Index
));
8830 register_name
= "Index";
8832 case CP0_REG00__MVPCONTROL
:
8833 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8834 gen_helper_mfc0_mvpcontrol(arg
, cpu_env
);
8835 register_name
= "MVPControl";
8837 case CP0_REG00__MVPCONF0
:
8838 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8839 gen_helper_mfc0_mvpconf0(arg
, cpu_env
);
8840 register_name
= "MVPConf0";
8842 case CP0_REG00__MVPCONF1
:
8843 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8844 gen_helper_mfc0_mvpconf1(arg
, cpu_env
);
8845 register_name
= "MVPConf1";
8847 case CP0_REG00__VPCONTROL
:
8849 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPControl
));
8850 register_name
= "VPControl";
8853 goto cp0_unimplemented
;
8856 case CP0_REGISTER_01
:
8858 case CP0_REG01__RANDOM
:
8859 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS_R6
));
8860 gen_helper_mfc0_random(arg
, cpu_env
);
8861 register_name
= "Random";
8863 case CP0_REG01__VPECONTROL
:
8864 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8865 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEControl
));
8866 register_name
= "VPEControl";
8868 case CP0_REG01__VPECONF0
:
8869 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8870 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf0
));
8871 register_name
= "VPEConf0";
8873 case CP0_REG01__VPECONF1
:
8874 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8875 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf1
));
8876 register_name
= "VPEConf1";
8878 case CP0_REG01__YQMASK
:
8879 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8880 tcg_gen_ld_tl(arg
, cpu_env
,
8881 offsetof(CPUMIPSState
, CP0_YQMask
));
8882 register_name
= "YQMask";
8884 case CP0_REG01__VPESCHEDULE
:
8885 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8886 tcg_gen_ld_tl(arg
, cpu_env
,
8887 offsetof(CPUMIPSState
, CP0_VPESchedule
));
8888 register_name
= "VPESchedule";
8890 case CP0_REG01__VPESCHEFBACK
:
8891 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8892 tcg_gen_ld_tl(arg
, cpu_env
,
8893 offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
8894 register_name
= "VPEScheFBack";
8896 case CP0_REG01__VPEOPT
:
8897 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8898 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEOpt
));
8899 register_name
= "VPEOpt";
8902 goto cp0_unimplemented
;
8905 case CP0_REGISTER_02
:
8907 case CP0_REG02__ENTRYLO0
:
8908 tcg_gen_ld_tl(arg
, cpu_env
,
8909 offsetof(CPUMIPSState
, CP0_EntryLo0
));
8910 register_name
= "EntryLo0";
8912 case CP0_REG02__TCSTATUS
:
8913 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8914 gen_helper_mfc0_tcstatus(arg
, cpu_env
);
8915 register_name
= "TCStatus";
8917 case CP0_REG02__TCBIND
:
8918 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8919 gen_helper_mfc0_tcbind(arg
, cpu_env
);
8920 register_name
= "TCBind";
8922 case CP0_REG02__TCRESTART
:
8923 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8924 gen_helper_dmfc0_tcrestart(arg
, cpu_env
);
8925 register_name
= "TCRestart";
8927 case CP0_REG02__TCHALT
:
8928 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8929 gen_helper_dmfc0_tchalt(arg
, cpu_env
);
8930 register_name
= "TCHalt";
8932 case CP0_REG02__TCCONTEXT
:
8933 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8934 gen_helper_dmfc0_tccontext(arg
, cpu_env
);
8935 register_name
= "TCContext";
8937 case CP0_REG02__TCSCHEDULE
:
8938 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8939 gen_helper_dmfc0_tcschedule(arg
, cpu_env
);
8940 register_name
= "TCSchedule";
8942 case CP0_REG02__TCSCHEFBACK
:
8943 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8944 gen_helper_dmfc0_tcschefback(arg
, cpu_env
);
8945 register_name
= "TCScheFBack";
8948 goto cp0_unimplemented
;
8951 case CP0_REGISTER_03
:
8953 case CP0_REG03__ENTRYLO1
:
8954 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryLo1
));
8955 register_name
= "EntryLo1";
8957 case CP0_REG03__GLOBALNUM
:
8959 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_GlobalNumber
));
8960 register_name
= "GlobalNumber";
8963 goto cp0_unimplemented
;
8966 case CP0_REGISTER_04
:
8968 case CP0_REG04__CONTEXT
:
8969 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_Context
));
8970 register_name
= "Context";
8972 case CP0_REG04__CONTEXTCONFIG
:
8974 /* gen_helper_dmfc0_contextconfig(arg); */
8975 register_name
= "ContextConfig";
8976 goto cp0_unimplemented
;
8977 case CP0_REG04__USERLOCAL
:
8978 CP0_CHECK(ctx
->ulri
);
8979 tcg_gen_ld_tl(arg
, cpu_env
,
8980 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
8981 register_name
= "UserLocal";
8983 case CP0_REG04__MMID
:
8985 gen_helper_mtc0_memorymapid(cpu_env
, arg
);
8986 register_name
= "MMID";
8989 goto cp0_unimplemented
;
8992 case CP0_REGISTER_05
:
8994 case CP0_REG05__PAGEMASK
:
8995 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageMask
));
8996 register_name
= "PageMask";
8998 case CP0_REG05__PAGEGRAIN
:
8999 check_insn(ctx
, ISA_MIPS_R2
);
9000 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageGrain
));
9001 register_name
= "PageGrain";
9003 case CP0_REG05__SEGCTL0
:
9005 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_SegCtl0
));
9006 register_name
= "SegCtl0";
9008 case CP0_REG05__SEGCTL1
:
9010 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_SegCtl1
));
9011 register_name
= "SegCtl1";
9013 case CP0_REG05__SEGCTL2
:
9015 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_SegCtl2
));
9016 register_name
= "SegCtl2";
9018 case CP0_REG05__PWBASE
:
9020 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_PWBase
));
9021 register_name
= "PWBase";
9023 case CP0_REG05__PWFIELD
:
9025 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_PWField
));
9026 register_name
= "PWField";
9028 case CP0_REG05__PWSIZE
:
9030 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_PWSize
));
9031 register_name
= "PWSize";
9034 goto cp0_unimplemented
;
9037 case CP0_REGISTER_06
:
9039 case CP0_REG06__WIRED
:
9040 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Wired
));
9041 register_name
= "Wired";
9043 case CP0_REG06__SRSCONF0
:
9044 check_insn(ctx
, ISA_MIPS_R2
);
9045 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf0
));
9046 register_name
= "SRSConf0";
9048 case CP0_REG06__SRSCONF1
:
9049 check_insn(ctx
, ISA_MIPS_R2
);
9050 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf1
));
9051 register_name
= "SRSConf1";
9053 case CP0_REG06__SRSCONF2
:
9054 check_insn(ctx
, ISA_MIPS_R2
);
9055 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf2
));
9056 register_name
= "SRSConf2";
9058 case CP0_REG06__SRSCONF3
:
9059 check_insn(ctx
, ISA_MIPS_R2
);
9060 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf3
));
9061 register_name
= "SRSConf3";
9063 case CP0_REG06__SRSCONF4
:
9064 check_insn(ctx
, ISA_MIPS_R2
);
9065 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf4
));
9066 register_name
= "SRSConf4";
9068 case CP0_REG06__PWCTL
:
9070 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PWCtl
));
9071 register_name
= "PWCtl";
9074 goto cp0_unimplemented
;
9077 case CP0_REGISTER_07
:
9079 case CP0_REG07__HWRENA
:
9080 check_insn(ctx
, ISA_MIPS_R2
);
9081 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_HWREna
));
9082 register_name
= "HWREna";
9085 goto cp0_unimplemented
;
9088 case CP0_REGISTER_08
:
9090 case CP0_REG08__BADVADDR
:
9091 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_BadVAddr
));
9092 register_name
= "BadVAddr";
9094 case CP0_REG08__BADINSTR
:
9096 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstr
));
9097 register_name
= "BadInstr";
9099 case CP0_REG08__BADINSTRP
:
9101 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstrP
));
9102 register_name
= "BadInstrP";
9104 case CP0_REG08__BADINSTRX
:
9106 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstrX
));
9107 tcg_gen_andi_tl(arg
, arg
, ~0xffff);
9108 register_name
= "BadInstrX";
9111 goto cp0_unimplemented
;
9114 case CP0_REGISTER_09
:
9116 case CP0_REG09__COUNT
:
9117 /* Mark as an IO operation because we read the time. */
9118 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
9121 gen_helper_mfc0_count(arg
, cpu_env
);
9123 * Break the TB to be able to take timer interrupts immediately
9124 * after reading count. DISAS_STOP isn't sufficient, we need to
9125 * ensure we break completely out of translated code.
9127 gen_save_pc(ctx
->base
.pc_next
+ 4);
9128 ctx
->base
.is_jmp
= DISAS_EXIT
;
9129 register_name
= "Count";
9131 case CP0_REG09__SAARI
:
9132 CP0_CHECK(ctx
->saar
);
9133 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SAARI
));
9134 register_name
= "SAARI";
9136 case CP0_REG09__SAAR
:
9137 CP0_CHECK(ctx
->saar
);
9138 gen_helper_dmfc0_saar(arg
, cpu_env
);
9139 register_name
= "SAAR";
9142 goto cp0_unimplemented
;
9145 case CP0_REGISTER_10
:
9147 case CP0_REG10__ENTRYHI
:
9148 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryHi
));
9149 register_name
= "EntryHi";
9152 goto cp0_unimplemented
;
9155 case CP0_REGISTER_11
:
9157 case CP0_REG11__COMPARE
:
9158 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Compare
));
9159 register_name
= "Compare";
9161 /* 6,7 are implementation dependent */
9163 goto cp0_unimplemented
;
9166 case CP0_REGISTER_12
:
9168 case CP0_REG12__STATUS
:
9169 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Status
));
9170 register_name
= "Status";
9172 case CP0_REG12__INTCTL
:
9173 check_insn(ctx
, ISA_MIPS_R2
);
9174 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_IntCtl
));
9175 register_name
= "IntCtl";
9177 case CP0_REG12__SRSCTL
:
9178 check_insn(ctx
, ISA_MIPS_R2
);
9179 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
9180 register_name
= "SRSCtl";
9182 case CP0_REG12__SRSMAP
:
9183 check_insn(ctx
, ISA_MIPS_R2
);
9184 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
9185 register_name
= "SRSMap";
9188 goto cp0_unimplemented
;
9191 case CP0_REGISTER_13
:
9193 case CP0_REG13__CAUSE
:
9194 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Cause
));
9195 register_name
= "Cause";
9198 goto cp0_unimplemented
;
9201 case CP0_REGISTER_14
:
9203 case CP0_REG14__EPC
:
9204 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
9205 register_name
= "EPC";
9208 goto cp0_unimplemented
;
9211 case CP0_REGISTER_15
:
9213 case CP0_REG15__PRID
:
9214 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PRid
));
9215 register_name
= "PRid";
9217 case CP0_REG15__EBASE
:
9218 check_insn(ctx
, ISA_MIPS_R2
);
9219 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EBase
));
9220 register_name
= "EBase";
9222 case CP0_REG15__CMGCRBASE
:
9223 check_insn(ctx
, ISA_MIPS_R2
);
9224 CP0_CHECK(ctx
->cmgcr
);
9225 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_CMGCRBase
));
9226 register_name
= "CMGCRBase";
9229 goto cp0_unimplemented
;
9232 case CP0_REGISTER_16
:
9234 case CP0_REG16__CONFIG
:
9235 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config0
));
9236 register_name
= "Config";
9238 case CP0_REG16__CONFIG1
:
9239 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config1
));
9240 register_name
= "Config1";
9242 case CP0_REG16__CONFIG2
:
9243 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config2
));
9244 register_name
= "Config2";
9246 case CP0_REG16__CONFIG3
:
9247 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config3
));
9248 register_name
= "Config3";
9250 case CP0_REG16__CONFIG4
:
9251 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config4
));
9252 register_name
= "Config4";
9254 case CP0_REG16__CONFIG5
:
9255 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config5
));
9256 register_name
= "Config5";
9258 /* 6,7 are implementation dependent */
9259 case CP0_REG16__CONFIG6
:
9260 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config6
));
9261 register_name
= "Config6";
9263 case CP0_REG16__CONFIG7
:
9264 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config7
));
9265 register_name
= "Config7";
9268 goto cp0_unimplemented
;
9271 case CP0_REGISTER_17
:
9273 case CP0_REG17__LLADDR
:
9274 gen_helper_dmfc0_lladdr(arg
, cpu_env
);
9275 register_name
= "LLAddr";
9277 case CP0_REG17__MAAR
:
9278 CP0_CHECK(ctx
->mrp
);
9279 gen_helper_dmfc0_maar(arg
, cpu_env
);
9280 register_name
= "MAAR";
9282 case CP0_REG17__MAARI
:
9283 CP0_CHECK(ctx
->mrp
);
9284 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_MAARI
));
9285 register_name
= "MAARI";
9288 goto cp0_unimplemented
;
9291 case CP0_REGISTER_18
:
9293 case CP0_REG18__WATCHLO0
:
9294 case CP0_REG18__WATCHLO1
:
9295 case CP0_REG18__WATCHLO2
:
9296 case CP0_REG18__WATCHLO3
:
9297 case CP0_REG18__WATCHLO4
:
9298 case CP0_REG18__WATCHLO5
:
9299 case CP0_REG18__WATCHLO6
:
9300 case CP0_REG18__WATCHLO7
:
9301 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
9302 gen_helper_1e0i(dmfc0_watchlo
, arg
, sel
);
9303 register_name
= "WatchLo";
9306 goto cp0_unimplemented
;
9309 case CP0_REGISTER_19
:
9311 case CP0_REG19__WATCHHI0
:
9312 case CP0_REG19__WATCHHI1
:
9313 case CP0_REG19__WATCHHI2
:
9314 case CP0_REG19__WATCHHI3
:
9315 case CP0_REG19__WATCHHI4
:
9316 case CP0_REG19__WATCHHI5
:
9317 case CP0_REG19__WATCHHI6
:
9318 case CP0_REG19__WATCHHI7
:
9319 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
9320 gen_helper_1e0i(dmfc0_watchhi
, arg
, sel
);
9321 register_name
= "WatchHi";
9324 goto cp0_unimplemented
;
9327 case CP0_REGISTER_20
:
9329 case CP0_REG20__XCONTEXT
:
9330 check_insn(ctx
, ISA_MIPS3
);
9331 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_XContext
));
9332 register_name
= "XContext";
9335 goto cp0_unimplemented
;
9338 case CP0_REGISTER_21
:
9339 /* Officially reserved, but sel 0 is used for R1x000 framemask */
9340 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS_R6
));
9343 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Framemask
));
9344 register_name
= "Framemask";
9347 goto cp0_unimplemented
;
9350 case CP0_REGISTER_22
:
9351 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
9352 register_name
= "'Diagnostic"; /* implementation dependent */
9354 case CP0_REGISTER_23
:
9356 case CP0_REG23__DEBUG
:
9357 gen_helper_mfc0_debug(arg
, cpu_env
); /* EJTAG support */
9358 register_name
= "Debug";
9360 case CP0_REG23__TRACECONTROL
:
9361 /* PDtrace support */
9362 /* gen_helper_dmfc0_tracecontrol(arg, cpu_env); */
9363 register_name
= "TraceControl";
9364 goto cp0_unimplemented
;
9365 case CP0_REG23__TRACECONTROL2
:
9366 /* PDtrace support */
9367 /* gen_helper_dmfc0_tracecontrol2(arg, cpu_env); */
9368 register_name
= "TraceControl2";
9369 goto cp0_unimplemented
;
9370 case CP0_REG23__USERTRACEDATA1
:
9371 /* PDtrace support */
9372 /* gen_helper_dmfc0_usertracedata1(arg, cpu_env);*/
9373 register_name
= "UserTraceData1";
9374 goto cp0_unimplemented
;
9375 case CP0_REG23__TRACEIBPC
:
9376 /* PDtrace support */
9377 /* gen_helper_dmfc0_traceibpc(arg, cpu_env); */
9378 register_name
= "TraceIBPC";
9379 goto cp0_unimplemented
;
9380 case CP0_REG23__TRACEDBPC
:
9381 /* PDtrace support */
9382 /* gen_helper_dmfc0_tracedbpc(arg, cpu_env); */
9383 register_name
= "TraceDBPC";
9384 goto cp0_unimplemented
;
9386 goto cp0_unimplemented
;
9389 case CP0_REGISTER_24
:
9391 case CP0_REG24__DEPC
:
9393 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
9394 register_name
= "DEPC";
9397 goto cp0_unimplemented
;
9400 case CP0_REGISTER_25
:
9402 case CP0_REG25__PERFCTL0
:
9403 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Performance0
));
9404 register_name
= "Performance0";
9406 case CP0_REG25__PERFCNT0
:
9407 /* gen_helper_dmfc0_performance1(arg); */
9408 register_name
= "Performance1";
9409 goto cp0_unimplemented
;
9410 case CP0_REG25__PERFCTL1
:
9411 /* gen_helper_dmfc0_performance2(arg); */
9412 register_name
= "Performance2";
9413 goto cp0_unimplemented
;
9414 case CP0_REG25__PERFCNT1
:
9415 /* gen_helper_dmfc0_performance3(arg); */
9416 register_name
= "Performance3";
9417 goto cp0_unimplemented
;
9418 case CP0_REG25__PERFCTL2
:
9419 /* gen_helper_dmfc0_performance4(arg); */
9420 register_name
= "Performance4";
9421 goto cp0_unimplemented
;
9422 case CP0_REG25__PERFCNT2
:
9423 /* gen_helper_dmfc0_performance5(arg); */
9424 register_name
= "Performance5";
9425 goto cp0_unimplemented
;
9426 case CP0_REG25__PERFCTL3
:
9427 /* gen_helper_dmfc0_performance6(arg); */
9428 register_name
= "Performance6";
9429 goto cp0_unimplemented
;
9430 case CP0_REG25__PERFCNT3
:
9431 /* gen_helper_dmfc0_performance7(arg); */
9432 register_name
= "Performance7";
9433 goto cp0_unimplemented
;
9435 goto cp0_unimplemented
;
9438 case CP0_REGISTER_26
:
9440 case CP0_REG26__ERRCTL
:
9441 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_ErrCtl
));
9442 register_name
= "ErrCtl";
9445 goto cp0_unimplemented
;
9448 case CP0_REGISTER_27
:
9451 case CP0_REG27__CACHERR
:
9452 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
9453 register_name
= "CacheErr";
9456 goto cp0_unimplemented
;
9459 case CP0_REGISTER_28
:
9461 case CP0_REG28__TAGLO
:
9462 case CP0_REG28__TAGLO1
:
9463 case CP0_REG28__TAGLO2
:
9464 case CP0_REG28__TAGLO3
:
9465 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagLo
));
9466 register_name
= "TagLo";
9468 case CP0_REG28__DATALO
:
9469 case CP0_REG28__DATALO1
:
9470 case CP0_REG28__DATALO2
:
9471 case CP0_REG28__DATALO3
:
9472 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataLo
));
9473 register_name
= "DataLo";
9476 goto cp0_unimplemented
;
9479 case CP0_REGISTER_29
:
9481 case CP0_REG29__TAGHI
:
9482 case CP0_REG29__TAGHI1
:
9483 case CP0_REG29__TAGHI2
:
9484 case CP0_REG29__TAGHI3
:
9485 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagHi
));
9486 register_name
= "TagHi";
9488 case CP0_REG29__DATAHI
:
9489 case CP0_REG29__DATAHI1
:
9490 case CP0_REG29__DATAHI2
:
9491 case CP0_REG29__DATAHI3
:
9492 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataHi
));
9493 register_name
= "DataHi";
9496 goto cp0_unimplemented
;
9499 case CP0_REGISTER_30
:
9501 case CP0_REG30__ERROREPC
:
9502 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
9503 register_name
= "ErrorEPC";
9506 goto cp0_unimplemented
;
9509 case CP0_REGISTER_31
:
9511 case CP0_REG31__DESAVE
:
9513 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
9514 register_name
= "DESAVE";
9516 case CP0_REG31__KSCRATCH1
:
9517 case CP0_REG31__KSCRATCH2
:
9518 case CP0_REG31__KSCRATCH3
:
9519 case CP0_REG31__KSCRATCH4
:
9520 case CP0_REG31__KSCRATCH5
:
9521 case CP0_REG31__KSCRATCH6
:
9522 CP0_CHECK(ctx
->kscrexist
& (1 << sel
));
9523 tcg_gen_ld_tl(arg
, cpu_env
,
9524 offsetof(CPUMIPSState
, CP0_KScratch
[sel
- 2]));
9525 register_name
= "KScratch";
9528 goto cp0_unimplemented
;
9532 goto cp0_unimplemented
;
9534 trace_mips_translate_c0("dmfc0", register_name
, reg
, sel
);
9538 qemu_log_mask(LOG_UNIMP
, "dmfc0 %s (reg %d sel %d)\n",
9539 register_name
, reg
, sel
);
9540 gen_mfc0_unimplemented(ctx
, arg
);
9543 static void gen_dmtc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
9545 const char *register_name
= "invalid";
9548 check_insn(ctx
, ISA_MIPS_R1
);
9551 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
9556 case CP0_REGISTER_00
:
9558 case CP0_REG00__INDEX
:
9559 gen_helper_mtc0_index(cpu_env
, arg
);
9560 register_name
= "Index";
9562 case CP0_REG00__MVPCONTROL
:
9563 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9564 gen_helper_mtc0_mvpcontrol(cpu_env
, arg
);
9565 register_name
= "MVPControl";
9567 case CP0_REG00__MVPCONF0
:
9568 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9570 register_name
= "MVPConf0";
9572 case CP0_REG00__MVPCONF1
:
9573 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9575 register_name
= "MVPConf1";
9577 case CP0_REG00__VPCONTROL
:
9580 register_name
= "VPControl";
9583 goto cp0_unimplemented
;
9586 case CP0_REGISTER_01
:
9588 case CP0_REG01__RANDOM
:
9590 register_name
= "Random";
9592 case CP0_REG01__VPECONTROL
:
9593 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9594 gen_helper_mtc0_vpecontrol(cpu_env
, arg
);
9595 register_name
= "VPEControl";
9597 case CP0_REG01__VPECONF0
:
9598 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9599 gen_helper_mtc0_vpeconf0(cpu_env
, arg
);
9600 register_name
= "VPEConf0";
9602 case CP0_REG01__VPECONF1
:
9603 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9604 gen_helper_mtc0_vpeconf1(cpu_env
, arg
);
9605 register_name
= "VPEConf1";
9607 case CP0_REG01__YQMASK
:
9608 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9609 gen_helper_mtc0_yqmask(cpu_env
, arg
);
9610 register_name
= "YQMask";
9612 case CP0_REG01__VPESCHEDULE
:
9613 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9614 tcg_gen_st_tl(arg
, cpu_env
,
9615 offsetof(CPUMIPSState
, CP0_VPESchedule
));
9616 register_name
= "VPESchedule";
9618 case CP0_REG01__VPESCHEFBACK
:
9619 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9620 tcg_gen_st_tl(arg
, cpu_env
,
9621 offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
9622 register_name
= "VPEScheFBack";
9624 case CP0_REG01__VPEOPT
:
9625 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9626 gen_helper_mtc0_vpeopt(cpu_env
, arg
);
9627 register_name
= "VPEOpt";
9630 goto cp0_unimplemented
;
9633 case CP0_REGISTER_02
:
9635 case CP0_REG02__ENTRYLO0
:
9636 gen_helper_dmtc0_entrylo0(cpu_env
, arg
);
9637 register_name
= "EntryLo0";
9639 case CP0_REG02__TCSTATUS
:
9640 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9641 gen_helper_mtc0_tcstatus(cpu_env
, arg
);
9642 register_name
= "TCStatus";
9644 case CP0_REG02__TCBIND
:
9645 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9646 gen_helper_mtc0_tcbind(cpu_env
, arg
);
9647 register_name
= "TCBind";
9649 case CP0_REG02__TCRESTART
:
9650 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9651 gen_helper_mtc0_tcrestart(cpu_env
, arg
);
9652 register_name
= "TCRestart";
9654 case CP0_REG02__TCHALT
:
9655 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9656 gen_helper_mtc0_tchalt(cpu_env
, arg
);
9657 register_name
= "TCHalt";
9659 case CP0_REG02__TCCONTEXT
:
9660 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9661 gen_helper_mtc0_tccontext(cpu_env
, arg
);
9662 register_name
= "TCContext";
9664 case CP0_REG02__TCSCHEDULE
:
9665 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9666 gen_helper_mtc0_tcschedule(cpu_env
, arg
);
9667 register_name
= "TCSchedule";
9669 case CP0_REG02__TCSCHEFBACK
:
9670 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9671 gen_helper_mtc0_tcschefback(cpu_env
, arg
);
9672 register_name
= "TCScheFBack";
9675 goto cp0_unimplemented
;
9678 case CP0_REGISTER_03
:
9680 case CP0_REG03__ENTRYLO1
:
9681 gen_helper_dmtc0_entrylo1(cpu_env
, arg
);
9682 register_name
= "EntryLo1";
9684 case CP0_REG03__GLOBALNUM
:
9687 register_name
= "GlobalNumber";
9690 goto cp0_unimplemented
;
9693 case CP0_REGISTER_04
:
9695 case CP0_REG04__CONTEXT
:
9696 gen_helper_mtc0_context(cpu_env
, arg
);
9697 register_name
= "Context";
9699 case CP0_REG04__CONTEXTCONFIG
:
9701 /* gen_helper_dmtc0_contextconfig(arg); */
9702 register_name
= "ContextConfig";
9703 goto cp0_unimplemented
;
9704 case CP0_REG04__USERLOCAL
:
9705 CP0_CHECK(ctx
->ulri
);
9706 tcg_gen_st_tl(arg
, cpu_env
,
9707 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
9708 register_name
= "UserLocal";
9710 case CP0_REG04__MMID
:
9712 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_MemoryMapID
));
9713 register_name
= "MMID";
9716 goto cp0_unimplemented
;
9719 case CP0_REGISTER_05
:
9721 case CP0_REG05__PAGEMASK
:
9722 gen_helper_mtc0_pagemask(cpu_env
, arg
);
9723 register_name
= "PageMask";
9725 case CP0_REG05__PAGEGRAIN
:
9726 check_insn(ctx
, ISA_MIPS_R2
);
9727 gen_helper_mtc0_pagegrain(cpu_env
, arg
);
9728 register_name
= "PageGrain";
9730 case CP0_REG05__SEGCTL0
:
9732 gen_helper_mtc0_segctl0(cpu_env
, arg
);
9733 register_name
= "SegCtl0";
9735 case CP0_REG05__SEGCTL1
:
9737 gen_helper_mtc0_segctl1(cpu_env
, arg
);
9738 register_name
= "SegCtl1";
9740 case CP0_REG05__SEGCTL2
:
9742 gen_helper_mtc0_segctl2(cpu_env
, arg
);
9743 register_name
= "SegCtl2";
9745 case CP0_REG05__PWBASE
:
9747 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_PWBase
));
9748 register_name
= "PWBase";
9750 case CP0_REG05__PWFIELD
:
9752 gen_helper_mtc0_pwfield(cpu_env
, arg
);
9753 register_name
= "PWField";
9755 case CP0_REG05__PWSIZE
:
9757 gen_helper_mtc0_pwsize(cpu_env
, arg
);
9758 register_name
= "PWSize";
9761 goto cp0_unimplemented
;
9764 case CP0_REGISTER_06
:
9766 case CP0_REG06__WIRED
:
9767 gen_helper_mtc0_wired(cpu_env
, arg
);
9768 register_name
= "Wired";
9770 case CP0_REG06__SRSCONF0
:
9771 check_insn(ctx
, ISA_MIPS_R2
);
9772 gen_helper_mtc0_srsconf0(cpu_env
, arg
);
9773 register_name
= "SRSConf0";
9775 case CP0_REG06__SRSCONF1
:
9776 check_insn(ctx
, ISA_MIPS_R2
);
9777 gen_helper_mtc0_srsconf1(cpu_env
, arg
);
9778 register_name
= "SRSConf1";
9780 case CP0_REG06__SRSCONF2
:
9781 check_insn(ctx
, ISA_MIPS_R2
);
9782 gen_helper_mtc0_srsconf2(cpu_env
, arg
);
9783 register_name
= "SRSConf2";
9785 case CP0_REG06__SRSCONF3
:
9786 check_insn(ctx
, ISA_MIPS_R2
);
9787 gen_helper_mtc0_srsconf3(cpu_env
, arg
);
9788 register_name
= "SRSConf3";
9790 case CP0_REG06__SRSCONF4
:
9791 check_insn(ctx
, ISA_MIPS_R2
);
9792 gen_helper_mtc0_srsconf4(cpu_env
, arg
);
9793 register_name
= "SRSConf4";
9795 case CP0_REG06__PWCTL
:
9797 gen_helper_mtc0_pwctl(cpu_env
, arg
);
9798 register_name
= "PWCtl";
9801 goto cp0_unimplemented
;
9804 case CP0_REGISTER_07
:
9806 case CP0_REG07__HWRENA
:
9807 check_insn(ctx
, ISA_MIPS_R2
);
9808 gen_helper_mtc0_hwrena(cpu_env
, arg
);
9809 ctx
->base
.is_jmp
= DISAS_STOP
;
9810 register_name
= "HWREna";
9813 goto cp0_unimplemented
;
9816 case CP0_REGISTER_08
:
9818 case CP0_REG08__BADVADDR
:
9820 register_name
= "BadVAddr";
9822 case CP0_REG08__BADINSTR
:
9824 register_name
= "BadInstr";
9826 case CP0_REG08__BADINSTRP
:
9828 register_name
= "BadInstrP";
9830 case CP0_REG08__BADINSTRX
:
9832 register_name
= "BadInstrX";
9835 goto cp0_unimplemented
;
9838 case CP0_REGISTER_09
:
9840 case CP0_REG09__COUNT
:
9841 gen_helper_mtc0_count(cpu_env
, arg
);
9842 register_name
= "Count";
9844 case CP0_REG09__SAARI
:
9845 CP0_CHECK(ctx
->saar
);
9846 gen_helper_mtc0_saari(cpu_env
, arg
);
9847 register_name
= "SAARI";
9849 case CP0_REG09__SAAR
:
9850 CP0_CHECK(ctx
->saar
);
9851 gen_helper_mtc0_saar(cpu_env
, arg
);
9852 register_name
= "SAAR";
9855 goto cp0_unimplemented
;
9857 /* Stop translation as we may have switched the execution mode */
9858 ctx
->base
.is_jmp
= DISAS_STOP
;
9860 case CP0_REGISTER_10
:
9862 case CP0_REG10__ENTRYHI
:
9863 gen_helper_mtc0_entryhi(cpu_env
, arg
);
9864 register_name
= "EntryHi";
9867 goto cp0_unimplemented
;
9870 case CP0_REGISTER_11
:
9872 case CP0_REG11__COMPARE
:
9873 gen_helper_mtc0_compare(cpu_env
, arg
);
9874 register_name
= "Compare";
9876 /* 6,7 are implementation dependent */
9878 goto cp0_unimplemented
;
9880 /* Stop translation as we may have switched the execution mode */
9881 ctx
->base
.is_jmp
= DISAS_STOP
;
9883 case CP0_REGISTER_12
:
9885 case CP0_REG12__STATUS
:
9886 save_cpu_state(ctx
, 1);
9887 gen_helper_mtc0_status(cpu_env
, arg
);
9888 /* DISAS_STOP isn't good enough here, hflags may have changed. */
9889 gen_save_pc(ctx
->base
.pc_next
+ 4);
9890 ctx
->base
.is_jmp
= DISAS_EXIT
;
9891 register_name
= "Status";
9893 case CP0_REG12__INTCTL
:
9894 check_insn(ctx
, ISA_MIPS_R2
);
9895 gen_helper_mtc0_intctl(cpu_env
, arg
);
9896 /* Stop translation as we may have switched the execution mode */
9897 ctx
->base
.is_jmp
= DISAS_STOP
;
9898 register_name
= "IntCtl";
9900 case CP0_REG12__SRSCTL
:
9901 check_insn(ctx
, ISA_MIPS_R2
);
9902 gen_helper_mtc0_srsctl(cpu_env
, arg
);
9903 /* Stop translation as we may have switched the execution mode */
9904 ctx
->base
.is_jmp
= DISAS_STOP
;
9905 register_name
= "SRSCtl";
9907 case CP0_REG12__SRSMAP
:
9908 check_insn(ctx
, ISA_MIPS_R2
);
9909 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
9910 /* Stop translation as we may have switched the execution mode */
9911 ctx
->base
.is_jmp
= DISAS_STOP
;
9912 register_name
= "SRSMap";
9915 goto cp0_unimplemented
;
9918 case CP0_REGISTER_13
:
9920 case CP0_REG13__CAUSE
:
9921 save_cpu_state(ctx
, 1);
9922 gen_helper_mtc0_cause(cpu_env
, arg
);
9924 * Stop translation as we may have triggered an interrupt.
9925 * DISAS_STOP isn't sufficient, we need to ensure we break out of
9926 * translated code to check for pending interrupts.
9928 gen_save_pc(ctx
->base
.pc_next
+ 4);
9929 ctx
->base
.is_jmp
= DISAS_EXIT
;
9930 register_name
= "Cause";
9933 goto cp0_unimplemented
;
9936 case CP0_REGISTER_14
:
9938 case CP0_REG14__EPC
:
9939 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
9940 register_name
= "EPC";
9943 goto cp0_unimplemented
;
9946 case CP0_REGISTER_15
:
9948 case CP0_REG15__PRID
:
9950 register_name
= "PRid";
9952 case CP0_REG15__EBASE
:
9953 check_insn(ctx
, ISA_MIPS_R2
);
9954 gen_helper_mtc0_ebase(cpu_env
, arg
);
9955 register_name
= "EBase";
9958 goto cp0_unimplemented
;
9961 case CP0_REGISTER_16
:
9963 case CP0_REG16__CONFIG
:
9964 gen_helper_mtc0_config0(cpu_env
, arg
);
9965 register_name
= "Config";
9966 /* Stop translation as we may have switched the execution mode */
9967 ctx
->base
.is_jmp
= DISAS_STOP
;
9969 case CP0_REG16__CONFIG1
:
9970 /* ignored, read only */
9971 register_name
= "Config1";
9973 case CP0_REG16__CONFIG2
:
9974 gen_helper_mtc0_config2(cpu_env
, arg
);
9975 register_name
= "Config2";
9976 /* Stop translation as we may have switched the execution mode */
9977 ctx
->base
.is_jmp
= DISAS_STOP
;
9979 case CP0_REG16__CONFIG3
:
9980 gen_helper_mtc0_config3(cpu_env
, arg
);
9981 register_name
= "Config3";
9982 /* Stop translation as we may have switched the execution mode */
9983 ctx
->base
.is_jmp
= DISAS_STOP
;
9985 case CP0_REG16__CONFIG4
:
9986 /* currently ignored */
9987 register_name
= "Config4";
9989 case CP0_REG16__CONFIG5
:
9990 gen_helper_mtc0_config5(cpu_env
, arg
);
9991 register_name
= "Config5";
9992 /* Stop translation as we may have switched the execution mode */
9993 ctx
->base
.is_jmp
= DISAS_STOP
;
9995 /* 6,7 are implementation dependent */
9997 register_name
= "Invalid config selector";
9998 goto cp0_unimplemented
;
10001 case CP0_REGISTER_17
:
10003 case CP0_REG17__LLADDR
:
10004 gen_helper_mtc0_lladdr(cpu_env
, arg
);
10005 register_name
= "LLAddr";
10007 case CP0_REG17__MAAR
:
10008 CP0_CHECK(ctx
->mrp
);
10009 gen_helper_mtc0_maar(cpu_env
, arg
);
10010 register_name
= "MAAR";
10012 case CP0_REG17__MAARI
:
10013 CP0_CHECK(ctx
->mrp
);
10014 gen_helper_mtc0_maari(cpu_env
, arg
);
10015 register_name
= "MAARI";
10018 goto cp0_unimplemented
;
10021 case CP0_REGISTER_18
:
10023 case CP0_REG18__WATCHLO0
:
10024 case CP0_REG18__WATCHLO1
:
10025 case CP0_REG18__WATCHLO2
:
10026 case CP0_REG18__WATCHLO3
:
10027 case CP0_REG18__WATCHLO4
:
10028 case CP0_REG18__WATCHLO5
:
10029 case CP0_REG18__WATCHLO6
:
10030 case CP0_REG18__WATCHLO7
:
10031 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
10032 gen_helper_0e1i(mtc0_watchlo
, arg
, sel
);
10033 register_name
= "WatchLo";
10036 goto cp0_unimplemented
;
10039 case CP0_REGISTER_19
:
10041 case CP0_REG19__WATCHHI0
:
10042 case CP0_REG19__WATCHHI1
:
10043 case CP0_REG19__WATCHHI2
:
10044 case CP0_REG19__WATCHHI3
:
10045 case CP0_REG19__WATCHHI4
:
10046 case CP0_REG19__WATCHHI5
:
10047 case CP0_REG19__WATCHHI6
:
10048 case CP0_REG19__WATCHHI7
:
10049 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
10050 gen_helper_0e1i(mtc0_watchhi
, arg
, sel
);
10051 register_name
= "WatchHi";
10054 goto cp0_unimplemented
;
10057 case CP0_REGISTER_20
:
10059 case CP0_REG20__XCONTEXT
:
10060 check_insn(ctx
, ISA_MIPS3
);
10061 gen_helper_mtc0_xcontext(cpu_env
, arg
);
10062 register_name
= "XContext";
10065 goto cp0_unimplemented
;
10068 case CP0_REGISTER_21
:
10069 /* Officially reserved, but sel 0 is used for R1x000 framemask */
10070 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS_R6
));
10073 gen_helper_mtc0_framemask(cpu_env
, arg
);
10074 register_name
= "Framemask";
10077 goto cp0_unimplemented
;
10080 case CP0_REGISTER_22
:
10082 register_name
= "Diagnostic"; /* implementation dependent */
10084 case CP0_REGISTER_23
:
10086 case CP0_REG23__DEBUG
:
10087 gen_helper_mtc0_debug(cpu_env
, arg
); /* EJTAG support */
10088 /* DISAS_STOP isn't good enough here, hflags may have changed. */
10089 gen_save_pc(ctx
->base
.pc_next
+ 4);
10090 ctx
->base
.is_jmp
= DISAS_EXIT
;
10091 register_name
= "Debug";
10093 case CP0_REG23__TRACECONTROL
:
10094 /* PDtrace support */
10095 /* gen_helper_mtc0_tracecontrol(cpu_env, arg); */
10096 /* Stop translation as we may have switched the execution mode */
10097 ctx
->base
.is_jmp
= DISAS_STOP
;
10098 register_name
= "TraceControl";
10099 goto cp0_unimplemented
;
10100 case CP0_REG23__TRACECONTROL2
:
10101 /* PDtrace support */
10102 /* gen_helper_mtc0_tracecontrol2(cpu_env, arg); */
10103 /* Stop translation as we may have switched the execution mode */
10104 ctx
->base
.is_jmp
= DISAS_STOP
;
10105 register_name
= "TraceControl2";
10106 goto cp0_unimplemented
;
10107 case CP0_REG23__USERTRACEDATA1
:
10108 /* PDtrace support */
10109 /* gen_helper_mtc0_usertracedata1(cpu_env, arg);*/
10110 /* Stop translation as we may have switched the execution mode */
10111 ctx
->base
.is_jmp
= DISAS_STOP
;
10112 register_name
= "UserTraceData1";
10113 goto cp0_unimplemented
;
10114 case CP0_REG23__TRACEIBPC
:
10115 /* PDtrace support */
10116 /* gen_helper_mtc0_traceibpc(cpu_env, arg); */
10117 /* Stop translation as we may have switched the execution mode */
10118 ctx
->base
.is_jmp
= DISAS_STOP
;
10119 register_name
= "TraceIBPC";
10120 goto cp0_unimplemented
;
10121 case CP0_REG23__TRACEDBPC
:
10122 /* PDtrace support */
10123 /* gen_helper_mtc0_tracedbpc(cpu_env, arg); */
10124 /* Stop translation as we may have switched the execution mode */
10125 ctx
->base
.is_jmp
= DISAS_STOP
;
10126 register_name
= "TraceDBPC";
10127 goto cp0_unimplemented
;
10129 goto cp0_unimplemented
;
10132 case CP0_REGISTER_24
:
10134 case CP0_REG24__DEPC
:
10135 /* EJTAG support */
10136 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
10137 register_name
= "DEPC";
10140 goto cp0_unimplemented
;
10143 case CP0_REGISTER_25
:
10145 case CP0_REG25__PERFCTL0
:
10146 gen_helper_mtc0_performance0(cpu_env
, arg
);
10147 register_name
= "Performance0";
10149 case CP0_REG25__PERFCNT0
:
10150 /* gen_helper_mtc0_performance1(cpu_env, arg); */
10151 register_name
= "Performance1";
10152 goto cp0_unimplemented
;
10153 case CP0_REG25__PERFCTL1
:
10154 /* gen_helper_mtc0_performance2(cpu_env, arg); */
10155 register_name
= "Performance2";
10156 goto cp0_unimplemented
;
10157 case CP0_REG25__PERFCNT1
:
10158 /* gen_helper_mtc0_performance3(cpu_env, arg); */
10159 register_name
= "Performance3";
10160 goto cp0_unimplemented
;
10161 case CP0_REG25__PERFCTL2
:
10162 /* gen_helper_mtc0_performance4(cpu_env, arg); */
10163 register_name
= "Performance4";
10164 goto cp0_unimplemented
;
10165 case CP0_REG25__PERFCNT2
:
10166 /* gen_helper_mtc0_performance5(cpu_env, arg); */
10167 register_name
= "Performance5";
10168 goto cp0_unimplemented
;
10169 case CP0_REG25__PERFCTL3
:
10170 /* gen_helper_mtc0_performance6(cpu_env, arg); */
10171 register_name
= "Performance6";
10172 goto cp0_unimplemented
;
10173 case CP0_REG25__PERFCNT3
:
10174 /* gen_helper_mtc0_performance7(cpu_env, arg); */
10175 register_name
= "Performance7";
10176 goto cp0_unimplemented
;
10178 goto cp0_unimplemented
;
10181 case CP0_REGISTER_26
:
10183 case CP0_REG26__ERRCTL
:
10184 gen_helper_mtc0_errctl(cpu_env
, arg
);
10185 ctx
->base
.is_jmp
= DISAS_STOP
;
10186 register_name
= "ErrCtl";
10189 goto cp0_unimplemented
;
10192 case CP0_REGISTER_27
:
10194 case CP0_REG27__CACHERR
:
10196 register_name
= "CacheErr";
10199 goto cp0_unimplemented
;
10202 case CP0_REGISTER_28
:
10204 case CP0_REG28__TAGLO
:
10205 case CP0_REG28__TAGLO1
:
10206 case CP0_REG28__TAGLO2
:
10207 case CP0_REG28__TAGLO3
:
10208 gen_helper_mtc0_taglo(cpu_env
, arg
);
10209 register_name
= "TagLo";
10211 case CP0_REG28__DATALO
:
10212 case CP0_REG28__DATALO1
:
10213 case CP0_REG28__DATALO2
:
10214 case CP0_REG28__DATALO3
:
10215 gen_helper_mtc0_datalo(cpu_env
, arg
);
10216 register_name
= "DataLo";
10219 goto cp0_unimplemented
;
10222 case CP0_REGISTER_29
:
10224 case CP0_REG29__TAGHI
:
10225 case CP0_REG29__TAGHI1
:
10226 case CP0_REG29__TAGHI2
:
10227 case CP0_REG29__TAGHI3
:
10228 gen_helper_mtc0_taghi(cpu_env
, arg
);
10229 register_name
= "TagHi";
10231 case CP0_REG29__DATAHI
:
10232 case CP0_REG29__DATAHI1
:
10233 case CP0_REG29__DATAHI2
:
10234 case CP0_REG29__DATAHI3
:
10235 gen_helper_mtc0_datahi(cpu_env
, arg
);
10236 register_name
= "DataHi";
10239 register_name
= "invalid sel";
10240 goto cp0_unimplemented
;
10243 case CP0_REGISTER_30
:
10245 case CP0_REG30__ERROREPC
:
10246 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
10247 register_name
= "ErrorEPC";
10250 goto cp0_unimplemented
;
10253 case CP0_REGISTER_31
:
10255 case CP0_REG31__DESAVE
:
10256 /* EJTAG support */
10257 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
10258 register_name
= "DESAVE";
10260 case CP0_REG31__KSCRATCH1
:
10261 case CP0_REG31__KSCRATCH2
:
10262 case CP0_REG31__KSCRATCH3
:
10263 case CP0_REG31__KSCRATCH4
:
10264 case CP0_REG31__KSCRATCH5
:
10265 case CP0_REG31__KSCRATCH6
:
10266 CP0_CHECK(ctx
->kscrexist
& (1 << sel
));
10267 tcg_gen_st_tl(arg
, cpu_env
,
10268 offsetof(CPUMIPSState
, CP0_KScratch
[sel
- 2]));
10269 register_name
= "KScratch";
10272 goto cp0_unimplemented
;
10276 goto cp0_unimplemented
;
10278 trace_mips_translate_c0("dmtc0", register_name
, reg
, sel
);
10280 /* For simplicity assume that all writes can cause interrupts. */
10281 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
10283 * DISAS_STOP isn't sufficient, we need to ensure we break out of
10284 * translated code to check for pending interrupts.
10286 gen_save_pc(ctx
->base
.pc_next
+ 4);
10287 ctx
->base
.is_jmp
= DISAS_EXIT
;
10292 qemu_log_mask(LOG_UNIMP
, "dmtc0 %s (reg %d sel %d)\n",
10293 register_name
, reg
, sel
);
10295 #endif /* TARGET_MIPS64 */
10297 static void gen_mftr(CPUMIPSState
*env
, DisasContext
*ctx
, int rt
, int rd
,
10298 int u
, int sel
, int h
)
10300 int other_tc
= env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
);
10301 TCGv t0
= tcg_temp_local_new();
10303 if ((env
->CP0_VPEConf0
& (1 << CP0VPEC0_MVP
)) == 0 &&
10304 ((env
->tcs
[other_tc
].CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)) !=
10305 (env
->active_tc
.CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)))) {
10306 tcg_gen_movi_tl(t0
, -1);
10307 } else if ((env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
)) >
10308 (env
->mvp
->CP0_MVPConf0
& (0xff << CP0MVPC0_PTC
))) {
10309 tcg_gen_movi_tl(t0
, -1);
10310 } else if (u
== 0) {
10315 gen_helper_mftc0_vpecontrol(t0
, cpu_env
);
10318 gen_helper_mftc0_vpeconf0(t0
, cpu_env
);
10328 gen_helper_mftc0_tcstatus(t0
, cpu_env
);
10331 gen_helper_mftc0_tcbind(t0
, cpu_env
);
10334 gen_helper_mftc0_tcrestart(t0
, cpu_env
);
10337 gen_helper_mftc0_tchalt(t0
, cpu_env
);
10340 gen_helper_mftc0_tccontext(t0
, cpu_env
);
10343 gen_helper_mftc0_tcschedule(t0
, cpu_env
);
10346 gen_helper_mftc0_tcschefback(t0
, cpu_env
);
10349 gen_mfc0(ctx
, t0
, rt
, sel
);
10356 gen_helper_mftc0_entryhi(t0
, cpu_env
);
10359 gen_mfc0(ctx
, t0
, rt
, sel
);
10366 gen_helper_mftc0_status(t0
, cpu_env
);
10369 gen_mfc0(ctx
, t0
, rt
, sel
);
10376 gen_helper_mftc0_cause(t0
, cpu_env
);
10386 gen_helper_mftc0_epc(t0
, cpu_env
);
10396 gen_helper_mftc0_ebase(t0
, cpu_env
);
10413 gen_helper_mftc0_configx(t0
, cpu_env
, tcg_const_tl(sel
));
10423 gen_helper_mftc0_debug(t0
, cpu_env
);
10426 gen_mfc0(ctx
, t0
, rt
, sel
);
10431 gen_mfc0(ctx
, t0
, rt
, sel
);
10435 /* GPR registers. */
10437 gen_helper_1e0i(mftgpr
, t0
, rt
);
10439 /* Auxiliary CPU registers */
10443 gen_helper_1e0i(mftlo
, t0
, 0);
10446 gen_helper_1e0i(mfthi
, t0
, 0);
10449 gen_helper_1e0i(mftacx
, t0
, 0);
10452 gen_helper_1e0i(mftlo
, t0
, 1);
10455 gen_helper_1e0i(mfthi
, t0
, 1);
10458 gen_helper_1e0i(mftacx
, t0
, 1);
10461 gen_helper_1e0i(mftlo
, t0
, 2);
10464 gen_helper_1e0i(mfthi
, t0
, 2);
10467 gen_helper_1e0i(mftacx
, t0
, 2);
10470 gen_helper_1e0i(mftlo
, t0
, 3);
10473 gen_helper_1e0i(mfthi
, t0
, 3);
10476 gen_helper_1e0i(mftacx
, t0
, 3);
10479 gen_helper_mftdsp(t0
, cpu_env
);
10485 /* Floating point (COP1). */
10487 /* XXX: For now we support only a single FPU context. */
10489 TCGv_i32 fp0
= tcg_temp_new_i32();
10491 gen_load_fpr32(ctx
, fp0
, rt
);
10492 tcg_gen_ext_i32_tl(t0
, fp0
);
10493 tcg_temp_free_i32(fp0
);
10495 TCGv_i32 fp0
= tcg_temp_new_i32();
10497 gen_load_fpr32h(ctx
, fp0
, rt
);
10498 tcg_gen_ext_i32_tl(t0
, fp0
);
10499 tcg_temp_free_i32(fp0
);
10503 /* XXX: For now we support only a single FPU context. */
10504 gen_helper_1e0i(cfc1
, t0
, rt
);
10506 /* COP2: Not implemented. */
10514 trace_mips_translate_tr("mftr", rt
, u
, sel
, h
);
10515 gen_store_gpr(t0
, rd
);
10521 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt
, u
, sel
, h
);
10522 gen_reserved_instruction(ctx
);
10525 static void gen_mttr(CPUMIPSState
*env
, DisasContext
*ctx
, int rd
, int rt
,
10526 int u
, int sel
, int h
)
10528 int other_tc
= env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
);
10529 TCGv t0
= tcg_temp_local_new();
10531 gen_load_gpr(t0
, rt
);
10532 if ((env
->CP0_VPEConf0
& (1 << CP0VPEC0_MVP
)) == 0 &&
10533 ((env
->tcs
[other_tc
].CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)) !=
10534 (env
->active_tc
.CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)))) {
10537 } else if ((env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
)) >
10538 (env
->mvp
->CP0_MVPConf0
& (0xff << CP0MVPC0_PTC
))) {
10541 } else if (u
== 0) {
10546 gen_helper_mttc0_vpecontrol(cpu_env
, t0
);
10549 gen_helper_mttc0_vpeconf0(cpu_env
, t0
);
10559 gen_helper_mttc0_tcstatus(cpu_env
, t0
);
10562 gen_helper_mttc0_tcbind(cpu_env
, t0
);
10565 gen_helper_mttc0_tcrestart(cpu_env
, t0
);
10568 gen_helper_mttc0_tchalt(cpu_env
, t0
);
10571 gen_helper_mttc0_tccontext(cpu_env
, t0
);
10574 gen_helper_mttc0_tcschedule(cpu_env
, t0
);
10577 gen_helper_mttc0_tcschefback(cpu_env
, t0
);
10580 gen_mtc0(ctx
, t0
, rd
, sel
);
10587 gen_helper_mttc0_entryhi(cpu_env
, t0
);
10590 gen_mtc0(ctx
, t0
, rd
, sel
);
10597 gen_helper_mttc0_status(cpu_env
, t0
);
10600 gen_mtc0(ctx
, t0
, rd
, sel
);
10607 gen_helper_mttc0_cause(cpu_env
, t0
);
10617 gen_helper_mttc0_ebase(cpu_env
, t0
);
10627 gen_helper_mttc0_debug(cpu_env
, t0
);
10630 gen_mtc0(ctx
, t0
, rd
, sel
);
10635 gen_mtc0(ctx
, t0
, rd
, sel
);
10639 /* GPR registers. */
10641 gen_helper_0e1i(mttgpr
, t0
, rd
);
10643 /* Auxiliary CPU registers */
10647 gen_helper_0e1i(mttlo
, t0
, 0);
10650 gen_helper_0e1i(mtthi
, t0
, 0);
10653 gen_helper_0e1i(mttacx
, t0
, 0);
10656 gen_helper_0e1i(mttlo
, t0
, 1);
10659 gen_helper_0e1i(mtthi
, t0
, 1);
10662 gen_helper_0e1i(mttacx
, t0
, 1);
10665 gen_helper_0e1i(mttlo
, t0
, 2);
10668 gen_helper_0e1i(mtthi
, t0
, 2);
10671 gen_helper_0e1i(mttacx
, t0
, 2);
10674 gen_helper_0e1i(mttlo
, t0
, 3);
10677 gen_helper_0e1i(mtthi
, t0
, 3);
10680 gen_helper_0e1i(mttacx
, t0
, 3);
10683 gen_helper_mttdsp(cpu_env
, t0
);
10689 /* Floating point (COP1). */
10691 /* XXX: For now we support only a single FPU context. */
10693 TCGv_i32 fp0
= tcg_temp_new_i32();
10695 tcg_gen_trunc_tl_i32(fp0
, t0
);
10696 gen_store_fpr32(ctx
, fp0
, rd
);
10697 tcg_temp_free_i32(fp0
);
10699 TCGv_i32 fp0
= tcg_temp_new_i32();
10701 tcg_gen_trunc_tl_i32(fp0
, t0
);
10702 gen_store_fpr32h(ctx
, fp0
, rd
);
10703 tcg_temp_free_i32(fp0
);
10707 /* XXX: For now we support only a single FPU context. */
10709 TCGv_i32 fs_tmp
= tcg_const_i32(rd
);
10711 gen_helper_0e2i(ctc1
, t0
, fs_tmp
, rt
);
10712 tcg_temp_free_i32(fs_tmp
);
10714 /* Stop translation as we may have changed hflags */
10715 ctx
->base
.is_jmp
= DISAS_STOP
;
10717 /* COP2: Not implemented. */
10725 trace_mips_translate_tr("mttr", rd
, u
, sel
, h
);
10731 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd
, u
, sel
, h
);
10732 gen_reserved_instruction(ctx
);
10735 static void gen_cp0(CPUMIPSState
*env
, DisasContext
*ctx
, uint32_t opc
,
10738 const char *opn
= "ldst";
10740 check_cp0_enabled(ctx
);
10744 /* Treat as NOP. */
10747 gen_mfc0(ctx
, cpu_gpr
[rt
], rd
, ctx
->opcode
& 0x7);
10752 TCGv t0
= tcg_temp_new();
10754 gen_load_gpr(t0
, rt
);
10755 gen_mtc0(ctx
, t0
, rd
, ctx
->opcode
& 0x7);
10760 #if defined(TARGET_MIPS64)
10762 check_insn(ctx
, ISA_MIPS3
);
10764 /* Treat as NOP. */
10767 gen_dmfc0(ctx
, cpu_gpr
[rt
], rd
, ctx
->opcode
& 0x7);
10771 check_insn(ctx
, ISA_MIPS3
);
10773 TCGv t0
= tcg_temp_new();
10775 gen_load_gpr(t0
, rt
);
10776 gen_dmtc0(ctx
, t0
, rd
, ctx
->opcode
& 0x7);
10785 /* Treat as NOP. */
10788 gen_mfhc0(ctx
, cpu_gpr
[rt
], rd
, ctx
->opcode
& 0x7);
10794 TCGv t0
= tcg_temp_new();
10795 gen_load_gpr(t0
, rt
);
10796 gen_mthc0(ctx
, t0
, rd
, ctx
->opcode
& 0x7);
10802 check_cp0_enabled(ctx
);
10804 /* Treat as NOP. */
10807 gen_mftr(env
, ctx
, rt
, rd
, (ctx
->opcode
>> 5) & 1,
10808 ctx
->opcode
& 0x7, (ctx
->opcode
>> 4) & 1);
10812 check_cp0_enabled(ctx
);
10813 gen_mttr(env
, ctx
, rd
, rt
, (ctx
->opcode
>> 5) & 1,
10814 ctx
->opcode
& 0x7, (ctx
->opcode
>> 4) & 1);
10819 if (!env
->tlb
->helper_tlbwi
) {
10822 gen_helper_tlbwi(cpu_env
);
10826 if (ctx
->ie
>= 2) {
10827 if (!env
->tlb
->helper_tlbinv
) {
10830 gen_helper_tlbinv(cpu_env
);
10831 } /* treat as nop if TLBINV not supported */
10835 if (ctx
->ie
>= 2) {
10836 if (!env
->tlb
->helper_tlbinvf
) {
10839 gen_helper_tlbinvf(cpu_env
);
10840 } /* treat as nop if TLBINV not supported */
10844 if (!env
->tlb
->helper_tlbwr
) {
10847 gen_helper_tlbwr(cpu_env
);
10851 if (!env
->tlb
->helper_tlbp
) {
10854 gen_helper_tlbp(cpu_env
);
10858 if (!env
->tlb
->helper_tlbr
) {
10861 gen_helper_tlbr(cpu_env
);
10863 case OPC_ERET
: /* OPC_ERETNC */
10864 if ((ctx
->insn_flags
& ISA_MIPS_R6
) &&
10865 (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
10868 int bit_shift
= (ctx
->hflags
& MIPS_HFLAG_M16
) ? 16 : 6;
10869 if (ctx
->opcode
& (1 << bit_shift
)) {
10872 check_insn(ctx
, ISA_MIPS_R5
);
10873 gen_helper_eretnc(cpu_env
);
10877 check_insn(ctx
, ISA_MIPS2
);
10878 gen_helper_eret(cpu_env
);
10880 ctx
->base
.is_jmp
= DISAS_EXIT
;
10885 check_insn(ctx
, ISA_MIPS_R1
);
10886 if ((ctx
->insn_flags
& ISA_MIPS_R6
) &&
10887 (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
10890 if (!(ctx
->hflags
& MIPS_HFLAG_DM
)) {
10892 gen_reserved_instruction(ctx
);
10894 gen_helper_deret(cpu_env
);
10895 ctx
->base
.is_jmp
= DISAS_EXIT
;
10900 check_insn(ctx
, ISA_MIPS3
| ISA_MIPS_R1
);
10901 if ((ctx
->insn_flags
& ISA_MIPS_R6
) &&
10902 (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
10905 /* If we get an exception, we want to restart at next instruction */
10906 ctx
->base
.pc_next
+= 4;
10907 save_cpu_state(ctx
, 1);
10908 ctx
->base
.pc_next
-= 4;
10909 gen_helper_wait(cpu_env
);
10910 ctx
->base
.is_jmp
= DISAS_NORETURN
;
10915 gen_reserved_instruction(ctx
);
10918 (void)opn
; /* avoid a compiler warning */
10920 #endif /* !CONFIG_USER_ONLY */
10922 /* CP1 Branches (before delay slot) */
10923 static void gen_compute_branch1(DisasContext
*ctx
, uint32_t op
,
10924 int32_t cc
, int32_t offset
)
10926 target_ulong btarget
;
10927 TCGv_i32 t0
= tcg_temp_new_i32();
10929 if ((ctx
->insn_flags
& ISA_MIPS_R6
) && (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
10930 gen_reserved_instruction(ctx
);
10935 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS_R1
);
10938 btarget
= ctx
->base
.pc_next
+ 4 + offset
;
10942 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
10943 tcg_gen_not_i32(t0
, t0
);
10944 tcg_gen_andi_i32(t0
, t0
, 1);
10945 tcg_gen_extu_i32_tl(bcond
, t0
);
10948 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
10949 tcg_gen_not_i32(t0
, t0
);
10950 tcg_gen_andi_i32(t0
, t0
, 1);
10951 tcg_gen_extu_i32_tl(bcond
, t0
);
10954 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
10955 tcg_gen_andi_i32(t0
, t0
, 1);
10956 tcg_gen_extu_i32_tl(bcond
, t0
);
10959 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
10960 tcg_gen_andi_i32(t0
, t0
, 1);
10961 tcg_gen_extu_i32_tl(bcond
, t0
);
10963 ctx
->hflags
|= MIPS_HFLAG_BL
;
10967 TCGv_i32 t1
= tcg_temp_new_i32();
10968 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
10969 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 1));
10970 tcg_gen_nand_i32(t0
, t0
, t1
);
10971 tcg_temp_free_i32(t1
);
10972 tcg_gen_andi_i32(t0
, t0
, 1);
10973 tcg_gen_extu_i32_tl(bcond
, t0
);
10978 TCGv_i32 t1
= tcg_temp_new_i32();
10979 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
10980 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 1));
10981 tcg_gen_or_i32(t0
, t0
, t1
);
10982 tcg_temp_free_i32(t1
);
10983 tcg_gen_andi_i32(t0
, t0
, 1);
10984 tcg_gen_extu_i32_tl(bcond
, t0
);
10989 TCGv_i32 t1
= tcg_temp_new_i32();
10990 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
10991 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 1));
10992 tcg_gen_and_i32(t0
, t0
, t1
);
10993 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 2));
10994 tcg_gen_and_i32(t0
, t0
, t1
);
10995 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 3));
10996 tcg_gen_nand_i32(t0
, t0
, t1
);
10997 tcg_temp_free_i32(t1
);
10998 tcg_gen_andi_i32(t0
, t0
, 1);
10999 tcg_gen_extu_i32_tl(bcond
, t0
);
11004 TCGv_i32 t1
= tcg_temp_new_i32();
11005 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
11006 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 1));
11007 tcg_gen_or_i32(t0
, t0
, t1
);
11008 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 2));
11009 tcg_gen_or_i32(t0
, t0
, t1
);
11010 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 3));
11011 tcg_gen_or_i32(t0
, t0
, t1
);
11012 tcg_temp_free_i32(t1
);
11013 tcg_gen_andi_i32(t0
, t0
, 1);
11014 tcg_gen_extu_i32_tl(bcond
, t0
);
11017 ctx
->hflags
|= MIPS_HFLAG_BC
;
11020 MIPS_INVAL("cp1 cond branch");
11021 gen_reserved_instruction(ctx
);
11024 ctx
->btarget
= btarget
;
11025 ctx
->hflags
|= MIPS_HFLAG_BDS32
;
11027 tcg_temp_free_i32(t0
);
11030 /* R6 CP1 Branches */
11031 static void gen_compute_branch1_r6(DisasContext
*ctx
, uint32_t op
,
11032 int32_t ft
, int32_t offset
,
11033 int delayslot_size
)
11035 target_ulong btarget
;
11036 TCGv_i64 t0
= tcg_temp_new_i64();
11038 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
11039 #ifdef MIPS_DEBUG_DISAS
11040 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
11041 "\n", ctx
->base
.pc_next
);
11043 gen_reserved_instruction(ctx
);
11047 gen_load_fpr64(ctx
, t0
, ft
);
11048 tcg_gen_andi_i64(t0
, t0
, 1);
11050 btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
11054 tcg_gen_xori_i64(t0
, t0
, 1);
11055 ctx
->hflags
|= MIPS_HFLAG_BC
;
11058 /* t0 already set */
11059 ctx
->hflags
|= MIPS_HFLAG_BC
;
11062 MIPS_INVAL("cp1 cond branch");
11063 gen_reserved_instruction(ctx
);
11067 tcg_gen_trunc_i64_tl(bcond
, t0
);
11069 ctx
->btarget
= btarget
;
11071 switch (delayslot_size
) {
11073 ctx
->hflags
|= MIPS_HFLAG_BDS16
;
11076 ctx
->hflags
|= MIPS_HFLAG_BDS32
;
11081 tcg_temp_free_i64(t0
);
11084 /* Coprocessor 1 (FPU) */
11086 #define FOP(func, fmt) (((fmt) << 21) | (func))
11089 OPC_ADD_S
= FOP(0, FMT_S
),
11090 OPC_SUB_S
= FOP(1, FMT_S
),
11091 OPC_MUL_S
= FOP(2, FMT_S
),
11092 OPC_DIV_S
= FOP(3, FMT_S
),
11093 OPC_SQRT_S
= FOP(4, FMT_S
),
11094 OPC_ABS_S
= FOP(5, FMT_S
),
11095 OPC_MOV_S
= FOP(6, FMT_S
),
11096 OPC_NEG_S
= FOP(7, FMT_S
),
11097 OPC_ROUND_L_S
= FOP(8, FMT_S
),
11098 OPC_TRUNC_L_S
= FOP(9, FMT_S
),
11099 OPC_CEIL_L_S
= FOP(10, FMT_S
),
11100 OPC_FLOOR_L_S
= FOP(11, FMT_S
),
11101 OPC_ROUND_W_S
= FOP(12, FMT_S
),
11102 OPC_TRUNC_W_S
= FOP(13, FMT_S
),
11103 OPC_CEIL_W_S
= FOP(14, FMT_S
),
11104 OPC_FLOOR_W_S
= FOP(15, FMT_S
),
11105 OPC_SEL_S
= FOP(16, FMT_S
),
11106 OPC_MOVCF_S
= FOP(17, FMT_S
),
11107 OPC_MOVZ_S
= FOP(18, FMT_S
),
11108 OPC_MOVN_S
= FOP(19, FMT_S
),
11109 OPC_SELEQZ_S
= FOP(20, FMT_S
),
11110 OPC_RECIP_S
= FOP(21, FMT_S
),
11111 OPC_RSQRT_S
= FOP(22, FMT_S
),
11112 OPC_SELNEZ_S
= FOP(23, FMT_S
),
11113 OPC_MADDF_S
= FOP(24, FMT_S
),
11114 OPC_MSUBF_S
= FOP(25, FMT_S
),
11115 OPC_RINT_S
= FOP(26, FMT_S
),
11116 OPC_CLASS_S
= FOP(27, FMT_S
),
11117 OPC_MIN_S
= FOP(28, FMT_S
),
11118 OPC_RECIP2_S
= FOP(28, FMT_S
),
11119 OPC_MINA_S
= FOP(29, FMT_S
),
11120 OPC_RECIP1_S
= FOP(29, FMT_S
),
11121 OPC_MAX_S
= FOP(30, FMT_S
),
11122 OPC_RSQRT1_S
= FOP(30, FMT_S
),
11123 OPC_MAXA_S
= FOP(31, FMT_S
),
11124 OPC_RSQRT2_S
= FOP(31, FMT_S
),
11125 OPC_CVT_D_S
= FOP(33, FMT_S
),
11126 OPC_CVT_W_S
= FOP(36, FMT_S
),
11127 OPC_CVT_L_S
= FOP(37, FMT_S
),
11128 OPC_CVT_PS_S
= FOP(38, FMT_S
),
11129 OPC_CMP_F_S
= FOP(48, FMT_S
),
11130 OPC_CMP_UN_S
= FOP(49, FMT_S
),
11131 OPC_CMP_EQ_S
= FOP(50, FMT_S
),
11132 OPC_CMP_UEQ_S
= FOP(51, FMT_S
),
11133 OPC_CMP_OLT_S
= FOP(52, FMT_S
),
11134 OPC_CMP_ULT_S
= FOP(53, FMT_S
),
11135 OPC_CMP_OLE_S
= FOP(54, FMT_S
),
11136 OPC_CMP_ULE_S
= FOP(55, FMT_S
),
11137 OPC_CMP_SF_S
= FOP(56, FMT_S
),
11138 OPC_CMP_NGLE_S
= FOP(57, FMT_S
),
11139 OPC_CMP_SEQ_S
= FOP(58, FMT_S
),
11140 OPC_CMP_NGL_S
= FOP(59, FMT_S
),
11141 OPC_CMP_LT_S
= FOP(60, FMT_S
),
11142 OPC_CMP_NGE_S
= FOP(61, FMT_S
),
11143 OPC_CMP_LE_S
= FOP(62, FMT_S
),
11144 OPC_CMP_NGT_S
= FOP(63, FMT_S
),
11146 OPC_ADD_D
= FOP(0, FMT_D
),
11147 OPC_SUB_D
= FOP(1, FMT_D
),
11148 OPC_MUL_D
= FOP(2, FMT_D
),
11149 OPC_DIV_D
= FOP(3, FMT_D
),
11150 OPC_SQRT_D
= FOP(4, FMT_D
),
11151 OPC_ABS_D
= FOP(5, FMT_D
),
11152 OPC_MOV_D
= FOP(6, FMT_D
),
11153 OPC_NEG_D
= FOP(7, FMT_D
),
11154 OPC_ROUND_L_D
= FOP(8, FMT_D
),
11155 OPC_TRUNC_L_D
= FOP(9, FMT_D
),
11156 OPC_CEIL_L_D
= FOP(10, FMT_D
),
11157 OPC_FLOOR_L_D
= FOP(11, FMT_D
),
11158 OPC_ROUND_W_D
= FOP(12, FMT_D
),
11159 OPC_TRUNC_W_D
= FOP(13, FMT_D
),
11160 OPC_CEIL_W_D
= FOP(14, FMT_D
),
11161 OPC_FLOOR_W_D
= FOP(15, FMT_D
),
11162 OPC_SEL_D
= FOP(16, FMT_D
),
11163 OPC_MOVCF_D
= FOP(17, FMT_D
),
11164 OPC_MOVZ_D
= FOP(18, FMT_D
),
11165 OPC_MOVN_D
= FOP(19, FMT_D
),
11166 OPC_SELEQZ_D
= FOP(20, FMT_D
),
11167 OPC_RECIP_D
= FOP(21, FMT_D
),
11168 OPC_RSQRT_D
= FOP(22, FMT_D
),
11169 OPC_SELNEZ_D
= FOP(23, FMT_D
),
11170 OPC_MADDF_D
= FOP(24, FMT_D
),
11171 OPC_MSUBF_D
= FOP(25, FMT_D
),
11172 OPC_RINT_D
= FOP(26, FMT_D
),
11173 OPC_CLASS_D
= FOP(27, FMT_D
),
11174 OPC_MIN_D
= FOP(28, FMT_D
),
11175 OPC_RECIP2_D
= FOP(28, FMT_D
),
11176 OPC_MINA_D
= FOP(29, FMT_D
),
11177 OPC_RECIP1_D
= FOP(29, FMT_D
),
11178 OPC_MAX_D
= FOP(30, FMT_D
),
11179 OPC_RSQRT1_D
= FOP(30, FMT_D
),
11180 OPC_MAXA_D
= FOP(31, FMT_D
),
11181 OPC_RSQRT2_D
= FOP(31, FMT_D
),
11182 OPC_CVT_S_D
= FOP(32, FMT_D
),
11183 OPC_CVT_W_D
= FOP(36, FMT_D
),
11184 OPC_CVT_L_D
= FOP(37, FMT_D
),
11185 OPC_CMP_F_D
= FOP(48, FMT_D
),
11186 OPC_CMP_UN_D
= FOP(49, FMT_D
),
11187 OPC_CMP_EQ_D
= FOP(50, FMT_D
),
11188 OPC_CMP_UEQ_D
= FOP(51, FMT_D
),
11189 OPC_CMP_OLT_D
= FOP(52, FMT_D
),
11190 OPC_CMP_ULT_D
= FOP(53, FMT_D
),
11191 OPC_CMP_OLE_D
= FOP(54, FMT_D
),
11192 OPC_CMP_ULE_D
= FOP(55, FMT_D
),
11193 OPC_CMP_SF_D
= FOP(56, FMT_D
),
11194 OPC_CMP_NGLE_D
= FOP(57, FMT_D
),
11195 OPC_CMP_SEQ_D
= FOP(58, FMT_D
),
11196 OPC_CMP_NGL_D
= FOP(59, FMT_D
),
11197 OPC_CMP_LT_D
= FOP(60, FMT_D
),
11198 OPC_CMP_NGE_D
= FOP(61, FMT_D
),
11199 OPC_CMP_LE_D
= FOP(62, FMT_D
),
11200 OPC_CMP_NGT_D
= FOP(63, FMT_D
),
11202 OPC_CVT_S_W
= FOP(32, FMT_W
),
11203 OPC_CVT_D_W
= FOP(33, FMT_W
),
11204 OPC_CVT_S_L
= FOP(32, FMT_L
),
11205 OPC_CVT_D_L
= FOP(33, FMT_L
),
11206 OPC_CVT_PS_PW
= FOP(38, FMT_W
),
11208 OPC_ADD_PS
= FOP(0, FMT_PS
),
11209 OPC_SUB_PS
= FOP(1, FMT_PS
),
11210 OPC_MUL_PS
= FOP(2, FMT_PS
),
11211 OPC_DIV_PS
= FOP(3, FMT_PS
),
11212 OPC_ABS_PS
= FOP(5, FMT_PS
),
11213 OPC_MOV_PS
= FOP(6, FMT_PS
),
11214 OPC_NEG_PS
= FOP(7, FMT_PS
),
11215 OPC_MOVCF_PS
= FOP(17, FMT_PS
),
11216 OPC_MOVZ_PS
= FOP(18, FMT_PS
),
11217 OPC_MOVN_PS
= FOP(19, FMT_PS
),
11218 OPC_ADDR_PS
= FOP(24, FMT_PS
),
11219 OPC_MULR_PS
= FOP(26, FMT_PS
),
11220 OPC_RECIP2_PS
= FOP(28, FMT_PS
),
11221 OPC_RECIP1_PS
= FOP(29, FMT_PS
),
11222 OPC_RSQRT1_PS
= FOP(30, FMT_PS
),
11223 OPC_RSQRT2_PS
= FOP(31, FMT_PS
),
11225 OPC_CVT_S_PU
= FOP(32, FMT_PS
),
11226 OPC_CVT_PW_PS
= FOP(36, FMT_PS
),
11227 OPC_CVT_S_PL
= FOP(40, FMT_PS
),
11228 OPC_PLL_PS
= FOP(44, FMT_PS
),
11229 OPC_PLU_PS
= FOP(45, FMT_PS
),
11230 OPC_PUL_PS
= FOP(46, FMT_PS
),
11231 OPC_PUU_PS
= FOP(47, FMT_PS
),
11232 OPC_CMP_F_PS
= FOP(48, FMT_PS
),
11233 OPC_CMP_UN_PS
= FOP(49, FMT_PS
),
11234 OPC_CMP_EQ_PS
= FOP(50, FMT_PS
),
11235 OPC_CMP_UEQ_PS
= FOP(51, FMT_PS
),
11236 OPC_CMP_OLT_PS
= FOP(52, FMT_PS
),
11237 OPC_CMP_ULT_PS
= FOP(53, FMT_PS
),
11238 OPC_CMP_OLE_PS
= FOP(54, FMT_PS
),
11239 OPC_CMP_ULE_PS
= FOP(55, FMT_PS
),
11240 OPC_CMP_SF_PS
= FOP(56, FMT_PS
),
11241 OPC_CMP_NGLE_PS
= FOP(57, FMT_PS
),
11242 OPC_CMP_SEQ_PS
= FOP(58, FMT_PS
),
11243 OPC_CMP_NGL_PS
= FOP(59, FMT_PS
),
11244 OPC_CMP_LT_PS
= FOP(60, FMT_PS
),
11245 OPC_CMP_NGE_PS
= FOP(61, FMT_PS
),
11246 OPC_CMP_LE_PS
= FOP(62, FMT_PS
),
11247 OPC_CMP_NGT_PS
= FOP(63, FMT_PS
),
11251 R6_OPC_CMP_AF_S
= FOP(0, FMT_W
),
11252 R6_OPC_CMP_UN_S
= FOP(1, FMT_W
),
11253 R6_OPC_CMP_EQ_S
= FOP(2, FMT_W
),
11254 R6_OPC_CMP_UEQ_S
= FOP(3, FMT_W
),
11255 R6_OPC_CMP_LT_S
= FOP(4, FMT_W
),
11256 R6_OPC_CMP_ULT_S
= FOP(5, FMT_W
),
11257 R6_OPC_CMP_LE_S
= FOP(6, FMT_W
),
11258 R6_OPC_CMP_ULE_S
= FOP(7, FMT_W
),
11259 R6_OPC_CMP_SAF_S
= FOP(8, FMT_W
),
11260 R6_OPC_CMP_SUN_S
= FOP(9, FMT_W
),
11261 R6_OPC_CMP_SEQ_S
= FOP(10, FMT_W
),
11262 R6_OPC_CMP_SEUQ_S
= FOP(11, FMT_W
),
11263 R6_OPC_CMP_SLT_S
= FOP(12, FMT_W
),
11264 R6_OPC_CMP_SULT_S
= FOP(13, FMT_W
),
11265 R6_OPC_CMP_SLE_S
= FOP(14, FMT_W
),
11266 R6_OPC_CMP_SULE_S
= FOP(15, FMT_W
),
11267 R6_OPC_CMP_OR_S
= FOP(17, FMT_W
),
11268 R6_OPC_CMP_UNE_S
= FOP(18, FMT_W
),
11269 R6_OPC_CMP_NE_S
= FOP(19, FMT_W
),
11270 R6_OPC_CMP_SOR_S
= FOP(25, FMT_W
),
11271 R6_OPC_CMP_SUNE_S
= FOP(26, FMT_W
),
11272 R6_OPC_CMP_SNE_S
= FOP(27, FMT_W
),
11274 R6_OPC_CMP_AF_D
= FOP(0, FMT_L
),
11275 R6_OPC_CMP_UN_D
= FOP(1, FMT_L
),
11276 R6_OPC_CMP_EQ_D
= FOP(2, FMT_L
),
11277 R6_OPC_CMP_UEQ_D
= FOP(3, FMT_L
),
11278 R6_OPC_CMP_LT_D
= FOP(4, FMT_L
),
11279 R6_OPC_CMP_ULT_D
= FOP(5, FMT_L
),
11280 R6_OPC_CMP_LE_D
= FOP(6, FMT_L
),
11281 R6_OPC_CMP_ULE_D
= FOP(7, FMT_L
),
11282 R6_OPC_CMP_SAF_D
= FOP(8, FMT_L
),
11283 R6_OPC_CMP_SUN_D
= FOP(9, FMT_L
),
11284 R6_OPC_CMP_SEQ_D
= FOP(10, FMT_L
),
11285 R6_OPC_CMP_SEUQ_D
= FOP(11, FMT_L
),
11286 R6_OPC_CMP_SLT_D
= FOP(12, FMT_L
),
11287 R6_OPC_CMP_SULT_D
= FOP(13, FMT_L
),
11288 R6_OPC_CMP_SLE_D
= FOP(14, FMT_L
),
11289 R6_OPC_CMP_SULE_D
= FOP(15, FMT_L
),
11290 R6_OPC_CMP_OR_D
= FOP(17, FMT_L
),
11291 R6_OPC_CMP_UNE_D
= FOP(18, FMT_L
),
11292 R6_OPC_CMP_NE_D
= FOP(19, FMT_L
),
11293 R6_OPC_CMP_SOR_D
= FOP(25, FMT_L
),
11294 R6_OPC_CMP_SUNE_D
= FOP(26, FMT_L
),
11295 R6_OPC_CMP_SNE_D
= FOP(27, FMT_L
),
11298 static void gen_cp1(DisasContext
*ctx
, uint32_t opc
, int rt
, int fs
)
11300 TCGv t0
= tcg_temp_new();
11305 TCGv_i32 fp0
= tcg_temp_new_i32();
11307 gen_load_fpr32(ctx
, fp0
, fs
);
11308 tcg_gen_ext_i32_tl(t0
, fp0
);
11309 tcg_temp_free_i32(fp0
);
11311 gen_store_gpr(t0
, rt
);
11314 gen_load_gpr(t0
, rt
);
11316 TCGv_i32 fp0
= tcg_temp_new_i32();
11318 tcg_gen_trunc_tl_i32(fp0
, t0
);
11319 gen_store_fpr32(ctx
, fp0
, fs
);
11320 tcg_temp_free_i32(fp0
);
11324 gen_helper_1e0i(cfc1
, t0
, fs
);
11325 gen_store_gpr(t0
, rt
);
11328 gen_load_gpr(t0
, rt
);
11329 save_cpu_state(ctx
, 0);
11331 TCGv_i32 fs_tmp
= tcg_const_i32(fs
);
11333 gen_helper_0e2i(ctc1
, t0
, fs_tmp
, rt
);
11334 tcg_temp_free_i32(fs_tmp
);
11336 /* Stop translation as we may have changed hflags */
11337 ctx
->base
.is_jmp
= DISAS_STOP
;
11339 #if defined(TARGET_MIPS64)
11341 gen_load_fpr64(ctx
, t0
, fs
);
11342 gen_store_gpr(t0
, rt
);
11345 gen_load_gpr(t0
, rt
);
11346 gen_store_fpr64(ctx
, t0
, fs
);
11351 TCGv_i32 fp0
= tcg_temp_new_i32();
11353 gen_load_fpr32h(ctx
, fp0
, fs
);
11354 tcg_gen_ext_i32_tl(t0
, fp0
);
11355 tcg_temp_free_i32(fp0
);
11357 gen_store_gpr(t0
, rt
);
11360 gen_load_gpr(t0
, rt
);
11362 TCGv_i32 fp0
= tcg_temp_new_i32();
11364 tcg_gen_trunc_tl_i32(fp0
, t0
);
11365 gen_store_fpr32h(ctx
, fp0
, fs
);
11366 tcg_temp_free_i32(fp0
);
11370 MIPS_INVAL("cp1 move");
11371 gen_reserved_instruction(ctx
);
11379 static void gen_movci(DisasContext
*ctx
, int rd
, int rs
, int cc
, int tf
)
11386 /* Treat as NOP. */
11391 cond
= TCG_COND_EQ
;
11393 cond
= TCG_COND_NE
;
11396 l1
= gen_new_label();
11397 t0
= tcg_temp_new_i32();
11398 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
11399 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
11400 tcg_temp_free_i32(t0
);
11402 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
11404 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
11409 static inline void gen_movcf_s(DisasContext
*ctx
, int fs
, int fd
, int cc
,
11413 TCGv_i32 t0
= tcg_temp_new_i32();
11414 TCGLabel
*l1
= gen_new_label();
11417 cond
= TCG_COND_EQ
;
11419 cond
= TCG_COND_NE
;
11422 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
11423 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
11424 gen_load_fpr32(ctx
, t0
, fs
);
11425 gen_store_fpr32(ctx
, t0
, fd
);
11427 tcg_temp_free_i32(t0
);
11430 static inline void gen_movcf_d(DisasContext
*ctx
, int fs
, int fd
, int cc
,
11434 TCGv_i32 t0
= tcg_temp_new_i32();
11436 TCGLabel
*l1
= gen_new_label();
11439 cond
= TCG_COND_EQ
;
11441 cond
= TCG_COND_NE
;
11444 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
11445 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
11446 tcg_temp_free_i32(t0
);
11447 fp0
= tcg_temp_new_i64();
11448 gen_load_fpr64(ctx
, fp0
, fs
);
11449 gen_store_fpr64(ctx
, fp0
, fd
);
11450 tcg_temp_free_i64(fp0
);
11454 static inline void gen_movcf_ps(DisasContext
*ctx
, int fs
, int fd
,
11458 TCGv_i32 t0
= tcg_temp_new_i32();
11459 TCGLabel
*l1
= gen_new_label();
11460 TCGLabel
*l2
= gen_new_label();
11463 cond
= TCG_COND_EQ
;
11465 cond
= TCG_COND_NE
;
11468 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
11469 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
11470 gen_load_fpr32(ctx
, t0
, fs
);
11471 gen_store_fpr32(ctx
, t0
, fd
);
11474 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
+ 1));
11475 tcg_gen_brcondi_i32(cond
, t0
, 0, l2
);
11476 gen_load_fpr32h(ctx
, t0
, fs
);
11477 gen_store_fpr32h(ctx
, t0
, fd
);
11478 tcg_temp_free_i32(t0
);
11482 static void gen_sel_s(DisasContext
*ctx
, enum fopcode op1
, int fd
, int ft
,
11485 TCGv_i32 t1
= tcg_const_i32(0);
11486 TCGv_i32 fp0
= tcg_temp_new_i32();
11487 TCGv_i32 fp1
= tcg_temp_new_i32();
11488 TCGv_i32 fp2
= tcg_temp_new_i32();
11489 gen_load_fpr32(ctx
, fp0
, fd
);
11490 gen_load_fpr32(ctx
, fp1
, ft
);
11491 gen_load_fpr32(ctx
, fp2
, fs
);
11495 tcg_gen_andi_i32(fp0
, fp0
, 1);
11496 tcg_gen_movcond_i32(TCG_COND_NE
, fp0
, fp0
, t1
, fp1
, fp2
);
11499 tcg_gen_andi_i32(fp1
, fp1
, 1);
11500 tcg_gen_movcond_i32(TCG_COND_EQ
, fp0
, fp1
, t1
, fp2
, t1
);
11503 tcg_gen_andi_i32(fp1
, fp1
, 1);
11504 tcg_gen_movcond_i32(TCG_COND_NE
, fp0
, fp1
, t1
, fp2
, t1
);
11507 MIPS_INVAL("gen_sel_s");
11508 gen_reserved_instruction(ctx
);
11512 gen_store_fpr32(ctx
, fp0
, fd
);
11513 tcg_temp_free_i32(fp2
);
11514 tcg_temp_free_i32(fp1
);
11515 tcg_temp_free_i32(fp0
);
11516 tcg_temp_free_i32(t1
);
11519 static void gen_sel_d(DisasContext
*ctx
, enum fopcode op1
, int fd
, int ft
,
11522 TCGv_i64 t1
= tcg_const_i64(0);
11523 TCGv_i64 fp0
= tcg_temp_new_i64();
11524 TCGv_i64 fp1
= tcg_temp_new_i64();
11525 TCGv_i64 fp2
= tcg_temp_new_i64();
11526 gen_load_fpr64(ctx
, fp0
, fd
);
11527 gen_load_fpr64(ctx
, fp1
, ft
);
11528 gen_load_fpr64(ctx
, fp2
, fs
);
11532 tcg_gen_andi_i64(fp0
, fp0
, 1);
11533 tcg_gen_movcond_i64(TCG_COND_NE
, fp0
, fp0
, t1
, fp1
, fp2
);
11536 tcg_gen_andi_i64(fp1
, fp1
, 1);
11537 tcg_gen_movcond_i64(TCG_COND_EQ
, fp0
, fp1
, t1
, fp2
, t1
);
11540 tcg_gen_andi_i64(fp1
, fp1
, 1);
11541 tcg_gen_movcond_i64(TCG_COND_NE
, fp0
, fp1
, t1
, fp2
, t1
);
11544 MIPS_INVAL("gen_sel_d");
11545 gen_reserved_instruction(ctx
);
11549 gen_store_fpr64(ctx
, fp0
, fd
);
11550 tcg_temp_free_i64(fp2
);
11551 tcg_temp_free_i64(fp1
);
11552 tcg_temp_free_i64(fp0
);
11553 tcg_temp_free_i64(t1
);
11556 static void gen_farith(DisasContext
*ctx
, enum fopcode op1
,
11557 int ft
, int fs
, int fd
, int cc
)
11559 uint32_t func
= ctx
->opcode
& 0x3f;
11563 TCGv_i32 fp0
= tcg_temp_new_i32();
11564 TCGv_i32 fp1
= tcg_temp_new_i32();
11566 gen_load_fpr32(ctx
, fp0
, fs
);
11567 gen_load_fpr32(ctx
, fp1
, ft
);
11568 gen_helper_float_add_s(fp0
, cpu_env
, fp0
, fp1
);
11569 tcg_temp_free_i32(fp1
);
11570 gen_store_fpr32(ctx
, fp0
, fd
);
11571 tcg_temp_free_i32(fp0
);
11576 TCGv_i32 fp0
= tcg_temp_new_i32();
11577 TCGv_i32 fp1
= tcg_temp_new_i32();
11579 gen_load_fpr32(ctx
, fp0
, fs
);
11580 gen_load_fpr32(ctx
, fp1
, ft
);
11581 gen_helper_float_sub_s(fp0
, cpu_env
, fp0
, fp1
);
11582 tcg_temp_free_i32(fp1
);
11583 gen_store_fpr32(ctx
, fp0
, fd
);
11584 tcg_temp_free_i32(fp0
);
11589 TCGv_i32 fp0
= tcg_temp_new_i32();
11590 TCGv_i32 fp1
= tcg_temp_new_i32();
11592 gen_load_fpr32(ctx
, fp0
, fs
);
11593 gen_load_fpr32(ctx
, fp1
, ft
);
11594 gen_helper_float_mul_s(fp0
, cpu_env
, fp0
, fp1
);
11595 tcg_temp_free_i32(fp1
);
11596 gen_store_fpr32(ctx
, fp0
, fd
);
11597 tcg_temp_free_i32(fp0
);
11602 TCGv_i32 fp0
= tcg_temp_new_i32();
11603 TCGv_i32 fp1
= tcg_temp_new_i32();
11605 gen_load_fpr32(ctx
, fp0
, fs
);
11606 gen_load_fpr32(ctx
, fp1
, ft
);
11607 gen_helper_float_div_s(fp0
, cpu_env
, fp0
, fp1
);
11608 tcg_temp_free_i32(fp1
);
11609 gen_store_fpr32(ctx
, fp0
, fd
);
11610 tcg_temp_free_i32(fp0
);
11615 TCGv_i32 fp0
= tcg_temp_new_i32();
11617 gen_load_fpr32(ctx
, fp0
, fs
);
11618 gen_helper_float_sqrt_s(fp0
, cpu_env
, fp0
);
11619 gen_store_fpr32(ctx
, fp0
, fd
);
11620 tcg_temp_free_i32(fp0
);
11625 TCGv_i32 fp0
= tcg_temp_new_i32();
11627 gen_load_fpr32(ctx
, fp0
, fs
);
11628 if (ctx
->abs2008
) {
11629 tcg_gen_andi_i32(fp0
, fp0
, 0x7fffffffUL
);
11631 gen_helper_float_abs_s(fp0
, fp0
);
11633 gen_store_fpr32(ctx
, fp0
, fd
);
11634 tcg_temp_free_i32(fp0
);
11639 TCGv_i32 fp0
= tcg_temp_new_i32();
11641 gen_load_fpr32(ctx
, fp0
, fs
);
11642 gen_store_fpr32(ctx
, fp0
, fd
);
11643 tcg_temp_free_i32(fp0
);
11648 TCGv_i32 fp0
= tcg_temp_new_i32();
11650 gen_load_fpr32(ctx
, fp0
, fs
);
11651 if (ctx
->abs2008
) {
11652 tcg_gen_xori_i32(fp0
, fp0
, 1UL << 31);
11654 gen_helper_float_chs_s(fp0
, fp0
);
11656 gen_store_fpr32(ctx
, fp0
, fd
);
11657 tcg_temp_free_i32(fp0
);
11660 case OPC_ROUND_L_S
:
11661 check_cp1_64bitmode(ctx
);
11663 TCGv_i32 fp32
= tcg_temp_new_i32();
11664 TCGv_i64 fp64
= tcg_temp_new_i64();
11666 gen_load_fpr32(ctx
, fp32
, fs
);
11667 if (ctx
->nan2008
) {
11668 gen_helper_float_round_2008_l_s(fp64
, cpu_env
, fp32
);
11670 gen_helper_float_round_l_s(fp64
, cpu_env
, fp32
);
11672 tcg_temp_free_i32(fp32
);
11673 gen_store_fpr64(ctx
, fp64
, fd
);
11674 tcg_temp_free_i64(fp64
);
11677 case OPC_TRUNC_L_S
:
11678 check_cp1_64bitmode(ctx
);
11680 TCGv_i32 fp32
= tcg_temp_new_i32();
11681 TCGv_i64 fp64
= tcg_temp_new_i64();
11683 gen_load_fpr32(ctx
, fp32
, fs
);
11684 if (ctx
->nan2008
) {
11685 gen_helper_float_trunc_2008_l_s(fp64
, cpu_env
, fp32
);
11687 gen_helper_float_trunc_l_s(fp64
, cpu_env
, fp32
);
11689 tcg_temp_free_i32(fp32
);
11690 gen_store_fpr64(ctx
, fp64
, fd
);
11691 tcg_temp_free_i64(fp64
);
11695 check_cp1_64bitmode(ctx
);
11697 TCGv_i32 fp32
= tcg_temp_new_i32();
11698 TCGv_i64 fp64
= tcg_temp_new_i64();
11700 gen_load_fpr32(ctx
, fp32
, fs
);
11701 if (ctx
->nan2008
) {
11702 gen_helper_float_ceil_2008_l_s(fp64
, cpu_env
, fp32
);
11704 gen_helper_float_ceil_l_s(fp64
, cpu_env
, fp32
);
11706 tcg_temp_free_i32(fp32
);
11707 gen_store_fpr64(ctx
, fp64
, fd
);
11708 tcg_temp_free_i64(fp64
);
11711 case OPC_FLOOR_L_S
:
11712 check_cp1_64bitmode(ctx
);
11714 TCGv_i32 fp32
= tcg_temp_new_i32();
11715 TCGv_i64 fp64
= tcg_temp_new_i64();
11717 gen_load_fpr32(ctx
, fp32
, fs
);
11718 if (ctx
->nan2008
) {
11719 gen_helper_float_floor_2008_l_s(fp64
, cpu_env
, fp32
);
11721 gen_helper_float_floor_l_s(fp64
, cpu_env
, fp32
);
11723 tcg_temp_free_i32(fp32
);
11724 gen_store_fpr64(ctx
, fp64
, fd
);
11725 tcg_temp_free_i64(fp64
);
11728 case OPC_ROUND_W_S
:
11730 TCGv_i32 fp0
= tcg_temp_new_i32();
11732 gen_load_fpr32(ctx
, fp0
, fs
);
11733 if (ctx
->nan2008
) {
11734 gen_helper_float_round_2008_w_s(fp0
, cpu_env
, fp0
);
11736 gen_helper_float_round_w_s(fp0
, cpu_env
, fp0
);
11738 gen_store_fpr32(ctx
, fp0
, fd
);
11739 tcg_temp_free_i32(fp0
);
11742 case OPC_TRUNC_W_S
:
11744 TCGv_i32 fp0
= tcg_temp_new_i32();
11746 gen_load_fpr32(ctx
, fp0
, fs
);
11747 if (ctx
->nan2008
) {
11748 gen_helper_float_trunc_2008_w_s(fp0
, cpu_env
, fp0
);
11750 gen_helper_float_trunc_w_s(fp0
, cpu_env
, fp0
);
11752 gen_store_fpr32(ctx
, fp0
, fd
);
11753 tcg_temp_free_i32(fp0
);
11758 TCGv_i32 fp0
= tcg_temp_new_i32();
11760 gen_load_fpr32(ctx
, fp0
, fs
);
11761 if (ctx
->nan2008
) {
11762 gen_helper_float_ceil_2008_w_s(fp0
, cpu_env
, fp0
);
11764 gen_helper_float_ceil_w_s(fp0
, cpu_env
, fp0
);
11766 gen_store_fpr32(ctx
, fp0
, fd
);
11767 tcg_temp_free_i32(fp0
);
11770 case OPC_FLOOR_W_S
:
11772 TCGv_i32 fp0
= tcg_temp_new_i32();
11774 gen_load_fpr32(ctx
, fp0
, fs
);
11775 if (ctx
->nan2008
) {
11776 gen_helper_float_floor_2008_w_s(fp0
, cpu_env
, fp0
);
11778 gen_helper_float_floor_w_s(fp0
, cpu_env
, fp0
);
11780 gen_store_fpr32(ctx
, fp0
, fd
);
11781 tcg_temp_free_i32(fp0
);
11785 check_insn(ctx
, ISA_MIPS_R6
);
11786 gen_sel_s(ctx
, op1
, fd
, ft
, fs
);
11789 check_insn(ctx
, ISA_MIPS_R6
);
11790 gen_sel_s(ctx
, op1
, fd
, ft
, fs
);
11793 check_insn(ctx
, ISA_MIPS_R6
);
11794 gen_sel_s(ctx
, op1
, fd
, ft
, fs
);
11797 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
11798 gen_movcf_s(ctx
, fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
11801 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
11803 TCGLabel
*l1
= gen_new_label();
11807 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
11809 fp0
= tcg_temp_new_i32();
11810 gen_load_fpr32(ctx
, fp0
, fs
);
11811 gen_store_fpr32(ctx
, fp0
, fd
);
11812 tcg_temp_free_i32(fp0
);
11817 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
11819 TCGLabel
*l1
= gen_new_label();
11823 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
11824 fp0
= tcg_temp_new_i32();
11825 gen_load_fpr32(ctx
, fp0
, fs
);
11826 gen_store_fpr32(ctx
, fp0
, fd
);
11827 tcg_temp_free_i32(fp0
);
11834 TCGv_i32 fp0
= tcg_temp_new_i32();
11836 gen_load_fpr32(ctx
, fp0
, fs
);
11837 gen_helper_float_recip_s(fp0
, cpu_env
, fp0
);
11838 gen_store_fpr32(ctx
, fp0
, fd
);
11839 tcg_temp_free_i32(fp0
);
11844 TCGv_i32 fp0
= tcg_temp_new_i32();
11846 gen_load_fpr32(ctx
, fp0
, fs
);
11847 gen_helper_float_rsqrt_s(fp0
, cpu_env
, fp0
);
11848 gen_store_fpr32(ctx
, fp0
, fd
);
11849 tcg_temp_free_i32(fp0
);
11853 check_insn(ctx
, ISA_MIPS_R6
);
11855 TCGv_i32 fp0
= tcg_temp_new_i32();
11856 TCGv_i32 fp1
= tcg_temp_new_i32();
11857 TCGv_i32 fp2
= tcg_temp_new_i32();
11858 gen_load_fpr32(ctx
, fp0
, fs
);
11859 gen_load_fpr32(ctx
, fp1
, ft
);
11860 gen_load_fpr32(ctx
, fp2
, fd
);
11861 gen_helper_float_maddf_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
11862 gen_store_fpr32(ctx
, fp2
, fd
);
11863 tcg_temp_free_i32(fp2
);
11864 tcg_temp_free_i32(fp1
);
11865 tcg_temp_free_i32(fp0
);
11869 check_insn(ctx
, ISA_MIPS_R6
);
11871 TCGv_i32 fp0
= tcg_temp_new_i32();
11872 TCGv_i32 fp1
= tcg_temp_new_i32();
11873 TCGv_i32 fp2
= tcg_temp_new_i32();
11874 gen_load_fpr32(ctx
, fp0
, fs
);
11875 gen_load_fpr32(ctx
, fp1
, ft
);
11876 gen_load_fpr32(ctx
, fp2
, fd
);
11877 gen_helper_float_msubf_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
11878 gen_store_fpr32(ctx
, fp2
, fd
);
11879 tcg_temp_free_i32(fp2
);
11880 tcg_temp_free_i32(fp1
);
11881 tcg_temp_free_i32(fp0
);
11885 check_insn(ctx
, ISA_MIPS_R6
);
11887 TCGv_i32 fp0
= tcg_temp_new_i32();
11888 gen_load_fpr32(ctx
, fp0
, fs
);
11889 gen_helper_float_rint_s(fp0
, cpu_env
, fp0
);
11890 gen_store_fpr32(ctx
, fp0
, fd
);
11891 tcg_temp_free_i32(fp0
);
11895 check_insn(ctx
, ISA_MIPS_R6
);
11897 TCGv_i32 fp0
= tcg_temp_new_i32();
11898 gen_load_fpr32(ctx
, fp0
, fs
);
11899 gen_helper_float_class_s(fp0
, cpu_env
, fp0
);
11900 gen_store_fpr32(ctx
, fp0
, fd
);
11901 tcg_temp_free_i32(fp0
);
11904 case OPC_MIN_S
: /* OPC_RECIP2_S */
11905 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
11907 TCGv_i32 fp0
= tcg_temp_new_i32();
11908 TCGv_i32 fp1
= tcg_temp_new_i32();
11909 TCGv_i32 fp2
= tcg_temp_new_i32();
11910 gen_load_fpr32(ctx
, fp0
, fs
);
11911 gen_load_fpr32(ctx
, fp1
, ft
);
11912 gen_helper_float_min_s(fp2
, cpu_env
, fp0
, fp1
);
11913 gen_store_fpr32(ctx
, fp2
, fd
);
11914 tcg_temp_free_i32(fp2
);
11915 tcg_temp_free_i32(fp1
);
11916 tcg_temp_free_i32(fp0
);
11919 check_cp1_64bitmode(ctx
);
11921 TCGv_i32 fp0
= tcg_temp_new_i32();
11922 TCGv_i32 fp1
= tcg_temp_new_i32();
11924 gen_load_fpr32(ctx
, fp0
, fs
);
11925 gen_load_fpr32(ctx
, fp1
, ft
);
11926 gen_helper_float_recip2_s(fp0
, cpu_env
, fp0
, fp1
);
11927 tcg_temp_free_i32(fp1
);
11928 gen_store_fpr32(ctx
, fp0
, fd
);
11929 tcg_temp_free_i32(fp0
);
11933 case OPC_MINA_S
: /* OPC_RECIP1_S */
11934 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
11936 TCGv_i32 fp0
= tcg_temp_new_i32();
11937 TCGv_i32 fp1
= tcg_temp_new_i32();
11938 TCGv_i32 fp2
= tcg_temp_new_i32();
11939 gen_load_fpr32(ctx
, fp0
, fs
);
11940 gen_load_fpr32(ctx
, fp1
, ft
);
11941 gen_helper_float_mina_s(fp2
, cpu_env
, fp0
, fp1
);
11942 gen_store_fpr32(ctx
, fp2
, fd
);
11943 tcg_temp_free_i32(fp2
);
11944 tcg_temp_free_i32(fp1
);
11945 tcg_temp_free_i32(fp0
);
11948 check_cp1_64bitmode(ctx
);
11950 TCGv_i32 fp0
= tcg_temp_new_i32();
11952 gen_load_fpr32(ctx
, fp0
, fs
);
11953 gen_helper_float_recip1_s(fp0
, cpu_env
, fp0
);
11954 gen_store_fpr32(ctx
, fp0
, fd
);
11955 tcg_temp_free_i32(fp0
);
11959 case OPC_MAX_S
: /* OPC_RSQRT1_S */
11960 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
11962 TCGv_i32 fp0
= tcg_temp_new_i32();
11963 TCGv_i32 fp1
= tcg_temp_new_i32();
11964 gen_load_fpr32(ctx
, fp0
, fs
);
11965 gen_load_fpr32(ctx
, fp1
, ft
);
11966 gen_helper_float_max_s(fp1
, cpu_env
, fp0
, fp1
);
11967 gen_store_fpr32(ctx
, fp1
, fd
);
11968 tcg_temp_free_i32(fp1
);
11969 tcg_temp_free_i32(fp0
);
11972 check_cp1_64bitmode(ctx
);
11974 TCGv_i32 fp0
= tcg_temp_new_i32();
11976 gen_load_fpr32(ctx
, fp0
, fs
);
11977 gen_helper_float_rsqrt1_s(fp0
, cpu_env
, fp0
);
11978 gen_store_fpr32(ctx
, fp0
, fd
);
11979 tcg_temp_free_i32(fp0
);
11983 case OPC_MAXA_S
: /* OPC_RSQRT2_S */
11984 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
11986 TCGv_i32 fp0
= tcg_temp_new_i32();
11987 TCGv_i32 fp1
= tcg_temp_new_i32();
11988 gen_load_fpr32(ctx
, fp0
, fs
);
11989 gen_load_fpr32(ctx
, fp1
, ft
);
11990 gen_helper_float_maxa_s(fp1
, cpu_env
, fp0
, fp1
);
11991 gen_store_fpr32(ctx
, fp1
, fd
);
11992 tcg_temp_free_i32(fp1
);
11993 tcg_temp_free_i32(fp0
);
11996 check_cp1_64bitmode(ctx
);
11998 TCGv_i32 fp0
= tcg_temp_new_i32();
11999 TCGv_i32 fp1
= tcg_temp_new_i32();
12001 gen_load_fpr32(ctx
, fp0
, fs
);
12002 gen_load_fpr32(ctx
, fp1
, ft
);
12003 gen_helper_float_rsqrt2_s(fp0
, cpu_env
, fp0
, fp1
);
12004 tcg_temp_free_i32(fp1
);
12005 gen_store_fpr32(ctx
, fp0
, fd
);
12006 tcg_temp_free_i32(fp0
);
12011 check_cp1_registers(ctx
, fd
);
12013 TCGv_i32 fp32
= tcg_temp_new_i32();
12014 TCGv_i64 fp64
= tcg_temp_new_i64();
12016 gen_load_fpr32(ctx
, fp32
, fs
);
12017 gen_helper_float_cvtd_s(fp64
, cpu_env
, fp32
);
12018 tcg_temp_free_i32(fp32
);
12019 gen_store_fpr64(ctx
, fp64
, fd
);
12020 tcg_temp_free_i64(fp64
);
12025 TCGv_i32 fp0
= tcg_temp_new_i32();
12027 gen_load_fpr32(ctx
, fp0
, fs
);
12028 if (ctx
->nan2008
) {
12029 gen_helper_float_cvt_2008_w_s(fp0
, cpu_env
, fp0
);
12031 gen_helper_float_cvt_w_s(fp0
, cpu_env
, fp0
);
12033 gen_store_fpr32(ctx
, fp0
, fd
);
12034 tcg_temp_free_i32(fp0
);
12038 check_cp1_64bitmode(ctx
);
12040 TCGv_i32 fp32
= tcg_temp_new_i32();
12041 TCGv_i64 fp64
= tcg_temp_new_i64();
12043 gen_load_fpr32(ctx
, fp32
, fs
);
12044 if (ctx
->nan2008
) {
12045 gen_helper_float_cvt_2008_l_s(fp64
, cpu_env
, fp32
);
12047 gen_helper_float_cvt_l_s(fp64
, cpu_env
, fp32
);
12049 tcg_temp_free_i32(fp32
);
12050 gen_store_fpr64(ctx
, fp64
, fd
);
12051 tcg_temp_free_i64(fp64
);
12057 TCGv_i64 fp64
= tcg_temp_new_i64();
12058 TCGv_i32 fp32_0
= tcg_temp_new_i32();
12059 TCGv_i32 fp32_1
= tcg_temp_new_i32();
12061 gen_load_fpr32(ctx
, fp32_0
, fs
);
12062 gen_load_fpr32(ctx
, fp32_1
, ft
);
12063 tcg_gen_concat_i32_i64(fp64
, fp32_1
, fp32_0
);
12064 tcg_temp_free_i32(fp32_1
);
12065 tcg_temp_free_i32(fp32_0
);
12066 gen_store_fpr64(ctx
, fp64
, fd
);
12067 tcg_temp_free_i64(fp64
);
12073 case OPC_CMP_UEQ_S
:
12074 case OPC_CMP_OLT_S
:
12075 case OPC_CMP_ULT_S
:
12076 case OPC_CMP_OLE_S
:
12077 case OPC_CMP_ULE_S
:
12079 case OPC_CMP_NGLE_S
:
12080 case OPC_CMP_SEQ_S
:
12081 case OPC_CMP_NGL_S
:
12083 case OPC_CMP_NGE_S
:
12085 case OPC_CMP_NGT_S
:
12086 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
12087 if (ctx
->opcode
& (1 << 6)) {
12088 gen_cmpabs_s(ctx
, func
- 48, ft
, fs
, cc
);
12090 gen_cmp_s(ctx
, func
- 48, ft
, fs
, cc
);
12094 check_cp1_registers(ctx
, fs
| ft
| fd
);
12096 TCGv_i64 fp0
= tcg_temp_new_i64();
12097 TCGv_i64 fp1
= tcg_temp_new_i64();
12099 gen_load_fpr64(ctx
, fp0
, fs
);
12100 gen_load_fpr64(ctx
, fp1
, ft
);
12101 gen_helper_float_add_d(fp0
, cpu_env
, fp0
, fp1
);
12102 tcg_temp_free_i64(fp1
);
12103 gen_store_fpr64(ctx
, fp0
, fd
);
12104 tcg_temp_free_i64(fp0
);
12108 check_cp1_registers(ctx
, fs
| ft
| fd
);
12110 TCGv_i64 fp0
= tcg_temp_new_i64();
12111 TCGv_i64 fp1
= tcg_temp_new_i64();
12113 gen_load_fpr64(ctx
, fp0
, fs
);
12114 gen_load_fpr64(ctx
, fp1
, ft
);
12115 gen_helper_float_sub_d(fp0
, cpu_env
, fp0
, fp1
);
12116 tcg_temp_free_i64(fp1
);
12117 gen_store_fpr64(ctx
, fp0
, fd
);
12118 tcg_temp_free_i64(fp0
);
12122 check_cp1_registers(ctx
, fs
| ft
| fd
);
12124 TCGv_i64 fp0
= tcg_temp_new_i64();
12125 TCGv_i64 fp1
= tcg_temp_new_i64();
12127 gen_load_fpr64(ctx
, fp0
, fs
);
12128 gen_load_fpr64(ctx
, fp1
, ft
);
12129 gen_helper_float_mul_d(fp0
, cpu_env
, fp0
, fp1
);
12130 tcg_temp_free_i64(fp1
);
12131 gen_store_fpr64(ctx
, fp0
, fd
);
12132 tcg_temp_free_i64(fp0
);
12136 check_cp1_registers(ctx
, fs
| ft
| fd
);
12138 TCGv_i64 fp0
= tcg_temp_new_i64();
12139 TCGv_i64 fp1
= tcg_temp_new_i64();
12141 gen_load_fpr64(ctx
, fp0
, fs
);
12142 gen_load_fpr64(ctx
, fp1
, ft
);
12143 gen_helper_float_div_d(fp0
, cpu_env
, fp0
, fp1
);
12144 tcg_temp_free_i64(fp1
);
12145 gen_store_fpr64(ctx
, fp0
, fd
);
12146 tcg_temp_free_i64(fp0
);
12150 check_cp1_registers(ctx
, fs
| fd
);
12152 TCGv_i64 fp0
= tcg_temp_new_i64();
12154 gen_load_fpr64(ctx
, fp0
, fs
);
12155 gen_helper_float_sqrt_d(fp0
, cpu_env
, fp0
);
12156 gen_store_fpr64(ctx
, fp0
, fd
);
12157 tcg_temp_free_i64(fp0
);
12161 check_cp1_registers(ctx
, fs
| fd
);
12163 TCGv_i64 fp0
= tcg_temp_new_i64();
12165 gen_load_fpr64(ctx
, fp0
, fs
);
12166 if (ctx
->abs2008
) {
12167 tcg_gen_andi_i64(fp0
, fp0
, 0x7fffffffffffffffULL
);
12169 gen_helper_float_abs_d(fp0
, fp0
);
12171 gen_store_fpr64(ctx
, fp0
, fd
);
12172 tcg_temp_free_i64(fp0
);
12176 check_cp1_registers(ctx
, fs
| fd
);
12178 TCGv_i64 fp0
= tcg_temp_new_i64();
12180 gen_load_fpr64(ctx
, fp0
, fs
);
12181 gen_store_fpr64(ctx
, fp0
, fd
);
12182 tcg_temp_free_i64(fp0
);
12186 check_cp1_registers(ctx
, fs
| fd
);
12188 TCGv_i64 fp0
= tcg_temp_new_i64();
12190 gen_load_fpr64(ctx
, fp0
, fs
);
12191 if (ctx
->abs2008
) {
12192 tcg_gen_xori_i64(fp0
, fp0
, 1ULL << 63);
12194 gen_helper_float_chs_d(fp0
, fp0
);
12196 gen_store_fpr64(ctx
, fp0
, fd
);
12197 tcg_temp_free_i64(fp0
);
12200 case OPC_ROUND_L_D
:
12201 check_cp1_64bitmode(ctx
);
12203 TCGv_i64 fp0
= tcg_temp_new_i64();
12205 gen_load_fpr64(ctx
, fp0
, fs
);
12206 if (ctx
->nan2008
) {
12207 gen_helper_float_round_2008_l_d(fp0
, cpu_env
, fp0
);
12209 gen_helper_float_round_l_d(fp0
, cpu_env
, fp0
);
12211 gen_store_fpr64(ctx
, fp0
, fd
);
12212 tcg_temp_free_i64(fp0
);
12215 case OPC_TRUNC_L_D
:
12216 check_cp1_64bitmode(ctx
);
12218 TCGv_i64 fp0
= tcg_temp_new_i64();
12220 gen_load_fpr64(ctx
, fp0
, fs
);
12221 if (ctx
->nan2008
) {
12222 gen_helper_float_trunc_2008_l_d(fp0
, cpu_env
, fp0
);
12224 gen_helper_float_trunc_l_d(fp0
, cpu_env
, fp0
);
12226 gen_store_fpr64(ctx
, fp0
, fd
);
12227 tcg_temp_free_i64(fp0
);
12231 check_cp1_64bitmode(ctx
);
12233 TCGv_i64 fp0
= tcg_temp_new_i64();
12235 gen_load_fpr64(ctx
, fp0
, fs
);
12236 if (ctx
->nan2008
) {
12237 gen_helper_float_ceil_2008_l_d(fp0
, cpu_env
, fp0
);
12239 gen_helper_float_ceil_l_d(fp0
, cpu_env
, fp0
);
12241 gen_store_fpr64(ctx
, fp0
, fd
);
12242 tcg_temp_free_i64(fp0
);
12245 case OPC_FLOOR_L_D
:
12246 check_cp1_64bitmode(ctx
);
12248 TCGv_i64 fp0
= tcg_temp_new_i64();
12250 gen_load_fpr64(ctx
, fp0
, fs
);
12251 if (ctx
->nan2008
) {
12252 gen_helper_float_floor_2008_l_d(fp0
, cpu_env
, fp0
);
12254 gen_helper_float_floor_l_d(fp0
, cpu_env
, fp0
);
12256 gen_store_fpr64(ctx
, fp0
, fd
);
12257 tcg_temp_free_i64(fp0
);
12260 case OPC_ROUND_W_D
:
12261 check_cp1_registers(ctx
, fs
);
12263 TCGv_i32 fp32
= tcg_temp_new_i32();
12264 TCGv_i64 fp64
= tcg_temp_new_i64();
12266 gen_load_fpr64(ctx
, fp64
, fs
);
12267 if (ctx
->nan2008
) {
12268 gen_helper_float_round_2008_w_d(fp32
, cpu_env
, fp64
);
12270 gen_helper_float_round_w_d(fp32
, cpu_env
, fp64
);
12272 tcg_temp_free_i64(fp64
);
12273 gen_store_fpr32(ctx
, fp32
, fd
);
12274 tcg_temp_free_i32(fp32
);
12277 case OPC_TRUNC_W_D
:
12278 check_cp1_registers(ctx
, fs
);
12280 TCGv_i32 fp32
= tcg_temp_new_i32();
12281 TCGv_i64 fp64
= tcg_temp_new_i64();
12283 gen_load_fpr64(ctx
, fp64
, fs
);
12284 if (ctx
->nan2008
) {
12285 gen_helper_float_trunc_2008_w_d(fp32
, cpu_env
, fp64
);
12287 gen_helper_float_trunc_w_d(fp32
, cpu_env
, fp64
);
12289 tcg_temp_free_i64(fp64
);
12290 gen_store_fpr32(ctx
, fp32
, fd
);
12291 tcg_temp_free_i32(fp32
);
12295 check_cp1_registers(ctx
, fs
);
12297 TCGv_i32 fp32
= tcg_temp_new_i32();
12298 TCGv_i64 fp64
= tcg_temp_new_i64();
12300 gen_load_fpr64(ctx
, fp64
, fs
);
12301 if (ctx
->nan2008
) {
12302 gen_helper_float_ceil_2008_w_d(fp32
, cpu_env
, fp64
);
12304 gen_helper_float_ceil_w_d(fp32
, cpu_env
, fp64
);
12306 tcg_temp_free_i64(fp64
);
12307 gen_store_fpr32(ctx
, fp32
, fd
);
12308 tcg_temp_free_i32(fp32
);
12311 case OPC_FLOOR_W_D
:
12312 check_cp1_registers(ctx
, fs
);
12314 TCGv_i32 fp32
= tcg_temp_new_i32();
12315 TCGv_i64 fp64
= tcg_temp_new_i64();
12317 gen_load_fpr64(ctx
, fp64
, fs
);
12318 if (ctx
->nan2008
) {
12319 gen_helper_float_floor_2008_w_d(fp32
, cpu_env
, fp64
);
12321 gen_helper_float_floor_w_d(fp32
, cpu_env
, fp64
);
12323 tcg_temp_free_i64(fp64
);
12324 gen_store_fpr32(ctx
, fp32
, fd
);
12325 tcg_temp_free_i32(fp32
);
12329 check_insn(ctx
, ISA_MIPS_R6
);
12330 gen_sel_d(ctx
, op1
, fd
, ft
, fs
);
12333 check_insn(ctx
, ISA_MIPS_R6
);
12334 gen_sel_d(ctx
, op1
, fd
, ft
, fs
);
12337 check_insn(ctx
, ISA_MIPS_R6
);
12338 gen_sel_d(ctx
, op1
, fd
, ft
, fs
);
12341 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
12342 gen_movcf_d(ctx
, fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
12345 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
12347 TCGLabel
*l1
= gen_new_label();
12351 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
12353 fp0
= tcg_temp_new_i64();
12354 gen_load_fpr64(ctx
, fp0
, fs
);
12355 gen_store_fpr64(ctx
, fp0
, fd
);
12356 tcg_temp_free_i64(fp0
);
12361 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
12363 TCGLabel
*l1
= gen_new_label();
12367 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
12368 fp0
= tcg_temp_new_i64();
12369 gen_load_fpr64(ctx
, fp0
, fs
);
12370 gen_store_fpr64(ctx
, fp0
, fd
);
12371 tcg_temp_free_i64(fp0
);
12377 check_cp1_registers(ctx
, fs
| fd
);
12379 TCGv_i64 fp0
= tcg_temp_new_i64();
12381 gen_load_fpr64(ctx
, fp0
, fs
);
12382 gen_helper_float_recip_d(fp0
, cpu_env
, fp0
);
12383 gen_store_fpr64(ctx
, fp0
, fd
);
12384 tcg_temp_free_i64(fp0
);
12388 check_cp1_registers(ctx
, fs
| fd
);
12390 TCGv_i64 fp0
= tcg_temp_new_i64();
12392 gen_load_fpr64(ctx
, fp0
, fs
);
12393 gen_helper_float_rsqrt_d(fp0
, cpu_env
, fp0
);
12394 gen_store_fpr64(ctx
, fp0
, fd
);
12395 tcg_temp_free_i64(fp0
);
12399 check_insn(ctx
, ISA_MIPS_R6
);
12401 TCGv_i64 fp0
= tcg_temp_new_i64();
12402 TCGv_i64 fp1
= tcg_temp_new_i64();
12403 TCGv_i64 fp2
= tcg_temp_new_i64();
12404 gen_load_fpr64(ctx
, fp0
, fs
);
12405 gen_load_fpr64(ctx
, fp1
, ft
);
12406 gen_load_fpr64(ctx
, fp2
, fd
);
12407 gen_helper_float_maddf_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12408 gen_store_fpr64(ctx
, fp2
, fd
);
12409 tcg_temp_free_i64(fp2
);
12410 tcg_temp_free_i64(fp1
);
12411 tcg_temp_free_i64(fp0
);
12415 check_insn(ctx
, ISA_MIPS_R6
);
12417 TCGv_i64 fp0
= tcg_temp_new_i64();
12418 TCGv_i64 fp1
= tcg_temp_new_i64();
12419 TCGv_i64 fp2
= tcg_temp_new_i64();
12420 gen_load_fpr64(ctx
, fp0
, fs
);
12421 gen_load_fpr64(ctx
, fp1
, ft
);
12422 gen_load_fpr64(ctx
, fp2
, fd
);
12423 gen_helper_float_msubf_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12424 gen_store_fpr64(ctx
, fp2
, fd
);
12425 tcg_temp_free_i64(fp2
);
12426 tcg_temp_free_i64(fp1
);
12427 tcg_temp_free_i64(fp0
);
12431 check_insn(ctx
, ISA_MIPS_R6
);
12433 TCGv_i64 fp0
= tcg_temp_new_i64();
12434 gen_load_fpr64(ctx
, fp0
, fs
);
12435 gen_helper_float_rint_d(fp0
, cpu_env
, fp0
);
12436 gen_store_fpr64(ctx
, fp0
, fd
);
12437 tcg_temp_free_i64(fp0
);
12441 check_insn(ctx
, ISA_MIPS_R6
);
12443 TCGv_i64 fp0
= tcg_temp_new_i64();
12444 gen_load_fpr64(ctx
, fp0
, fs
);
12445 gen_helper_float_class_d(fp0
, cpu_env
, fp0
);
12446 gen_store_fpr64(ctx
, fp0
, fd
);
12447 tcg_temp_free_i64(fp0
);
12450 case OPC_MIN_D
: /* OPC_RECIP2_D */
12451 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
12453 TCGv_i64 fp0
= tcg_temp_new_i64();
12454 TCGv_i64 fp1
= tcg_temp_new_i64();
12455 gen_load_fpr64(ctx
, fp0
, fs
);
12456 gen_load_fpr64(ctx
, fp1
, ft
);
12457 gen_helper_float_min_d(fp1
, cpu_env
, fp0
, fp1
);
12458 gen_store_fpr64(ctx
, fp1
, fd
);
12459 tcg_temp_free_i64(fp1
);
12460 tcg_temp_free_i64(fp0
);
12463 check_cp1_64bitmode(ctx
);
12465 TCGv_i64 fp0
= tcg_temp_new_i64();
12466 TCGv_i64 fp1
= tcg_temp_new_i64();
12468 gen_load_fpr64(ctx
, fp0
, fs
);
12469 gen_load_fpr64(ctx
, fp1
, ft
);
12470 gen_helper_float_recip2_d(fp0
, cpu_env
, fp0
, fp1
);
12471 tcg_temp_free_i64(fp1
);
12472 gen_store_fpr64(ctx
, fp0
, fd
);
12473 tcg_temp_free_i64(fp0
);
12477 case OPC_MINA_D
: /* OPC_RECIP1_D */
12478 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
12480 TCGv_i64 fp0
= tcg_temp_new_i64();
12481 TCGv_i64 fp1
= tcg_temp_new_i64();
12482 gen_load_fpr64(ctx
, fp0
, fs
);
12483 gen_load_fpr64(ctx
, fp1
, ft
);
12484 gen_helper_float_mina_d(fp1
, cpu_env
, fp0
, fp1
);
12485 gen_store_fpr64(ctx
, fp1
, fd
);
12486 tcg_temp_free_i64(fp1
);
12487 tcg_temp_free_i64(fp0
);
12490 check_cp1_64bitmode(ctx
);
12492 TCGv_i64 fp0
= tcg_temp_new_i64();
12494 gen_load_fpr64(ctx
, fp0
, fs
);
12495 gen_helper_float_recip1_d(fp0
, cpu_env
, fp0
);
12496 gen_store_fpr64(ctx
, fp0
, fd
);
12497 tcg_temp_free_i64(fp0
);
12501 case OPC_MAX_D
: /* OPC_RSQRT1_D */
12502 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
12504 TCGv_i64 fp0
= tcg_temp_new_i64();
12505 TCGv_i64 fp1
= tcg_temp_new_i64();
12506 gen_load_fpr64(ctx
, fp0
, fs
);
12507 gen_load_fpr64(ctx
, fp1
, ft
);
12508 gen_helper_float_max_d(fp1
, cpu_env
, fp0
, fp1
);
12509 gen_store_fpr64(ctx
, fp1
, fd
);
12510 tcg_temp_free_i64(fp1
);
12511 tcg_temp_free_i64(fp0
);
12514 check_cp1_64bitmode(ctx
);
12516 TCGv_i64 fp0
= tcg_temp_new_i64();
12518 gen_load_fpr64(ctx
, fp0
, fs
);
12519 gen_helper_float_rsqrt1_d(fp0
, cpu_env
, fp0
);
12520 gen_store_fpr64(ctx
, fp0
, fd
);
12521 tcg_temp_free_i64(fp0
);
12525 case OPC_MAXA_D
: /* OPC_RSQRT2_D */
12526 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
12528 TCGv_i64 fp0
= tcg_temp_new_i64();
12529 TCGv_i64 fp1
= tcg_temp_new_i64();
12530 gen_load_fpr64(ctx
, fp0
, fs
);
12531 gen_load_fpr64(ctx
, fp1
, ft
);
12532 gen_helper_float_maxa_d(fp1
, cpu_env
, fp0
, fp1
);
12533 gen_store_fpr64(ctx
, fp1
, fd
);
12534 tcg_temp_free_i64(fp1
);
12535 tcg_temp_free_i64(fp0
);
12538 check_cp1_64bitmode(ctx
);
12540 TCGv_i64 fp0
= tcg_temp_new_i64();
12541 TCGv_i64 fp1
= tcg_temp_new_i64();
12543 gen_load_fpr64(ctx
, fp0
, fs
);
12544 gen_load_fpr64(ctx
, fp1
, ft
);
12545 gen_helper_float_rsqrt2_d(fp0
, cpu_env
, fp0
, fp1
);
12546 tcg_temp_free_i64(fp1
);
12547 gen_store_fpr64(ctx
, fp0
, fd
);
12548 tcg_temp_free_i64(fp0
);
12555 case OPC_CMP_UEQ_D
:
12556 case OPC_CMP_OLT_D
:
12557 case OPC_CMP_ULT_D
:
12558 case OPC_CMP_OLE_D
:
12559 case OPC_CMP_ULE_D
:
12561 case OPC_CMP_NGLE_D
:
12562 case OPC_CMP_SEQ_D
:
12563 case OPC_CMP_NGL_D
:
12565 case OPC_CMP_NGE_D
:
12567 case OPC_CMP_NGT_D
:
12568 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
12569 if (ctx
->opcode
& (1 << 6)) {
12570 gen_cmpabs_d(ctx
, func
- 48, ft
, fs
, cc
);
12572 gen_cmp_d(ctx
, func
- 48, ft
, fs
, cc
);
12576 check_cp1_registers(ctx
, fs
);
12578 TCGv_i32 fp32
= tcg_temp_new_i32();
12579 TCGv_i64 fp64
= tcg_temp_new_i64();
12581 gen_load_fpr64(ctx
, fp64
, fs
);
12582 gen_helper_float_cvts_d(fp32
, cpu_env
, fp64
);
12583 tcg_temp_free_i64(fp64
);
12584 gen_store_fpr32(ctx
, fp32
, fd
);
12585 tcg_temp_free_i32(fp32
);
12589 check_cp1_registers(ctx
, fs
);
12591 TCGv_i32 fp32
= tcg_temp_new_i32();
12592 TCGv_i64 fp64
= tcg_temp_new_i64();
12594 gen_load_fpr64(ctx
, fp64
, fs
);
12595 if (ctx
->nan2008
) {
12596 gen_helper_float_cvt_2008_w_d(fp32
, cpu_env
, fp64
);
12598 gen_helper_float_cvt_w_d(fp32
, cpu_env
, fp64
);
12600 tcg_temp_free_i64(fp64
);
12601 gen_store_fpr32(ctx
, fp32
, fd
);
12602 tcg_temp_free_i32(fp32
);
12606 check_cp1_64bitmode(ctx
);
12608 TCGv_i64 fp0
= tcg_temp_new_i64();
12610 gen_load_fpr64(ctx
, fp0
, fs
);
12611 if (ctx
->nan2008
) {
12612 gen_helper_float_cvt_2008_l_d(fp0
, cpu_env
, fp0
);
12614 gen_helper_float_cvt_l_d(fp0
, cpu_env
, fp0
);
12616 gen_store_fpr64(ctx
, fp0
, fd
);
12617 tcg_temp_free_i64(fp0
);
12622 TCGv_i32 fp0
= tcg_temp_new_i32();
12624 gen_load_fpr32(ctx
, fp0
, fs
);
12625 gen_helper_float_cvts_w(fp0
, cpu_env
, fp0
);
12626 gen_store_fpr32(ctx
, fp0
, fd
);
12627 tcg_temp_free_i32(fp0
);
12631 check_cp1_registers(ctx
, fd
);
12633 TCGv_i32 fp32
= tcg_temp_new_i32();
12634 TCGv_i64 fp64
= tcg_temp_new_i64();
12636 gen_load_fpr32(ctx
, fp32
, fs
);
12637 gen_helper_float_cvtd_w(fp64
, cpu_env
, fp32
);
12638 tcg_temp_free_i32(fp32
);
12639 gen_store_fpr64(ctx
, fp64
, fd
);
12640 tcg_temp_free_i64(fp64
);
12644 check_cp1_64bitmode(ctx
);
12646 TCGv_i32 fp32
= tcg_temp_new_i32();
12647 TCGv_i64 fp64
= tcg_temp_new_i64();
12649 gen_load_fpr64(ctx
, fp64
, fs
);
12650 gen_helper_float_cvts_l(fp32
, cpu_env
, fp64
);
12651 tcg_temp_free_i64(fp64
);
12652 gen_store_fpr32(ctx
, fp32
, fd
);
12653 tcg_temp_free_i32(fp32
);
12657 check_cp1_64bitmode(ctx
);
12659 TCGv_i64 fp0
= tcg_temp_new_i64();
12661 gen_load_fpr64(ctx
, fp0
, fs
);
12662 gen_helper_float_cvtd_l(fp0
, cpu_env
, fp0
);
12663 gen_store_fpr64(ctx
, fp0
, fd
);
12664 tcg_temp_free_i64(fp0
);
12667 case OPC_CVT_PS_PW
:
12670 TCGv_i64 fp0
= tcg_temp_new_i64();
12672 gen_load_fpr64(ctx
, fp0
, fs
);
12673 gen_helper_float_cvtps_pw(fp0
, cpu_env
, fp0
);
12674 gen_store_fpr64(ctx
, fp0
, fd
);
12675 tcg_temp_free_i64(fp0
);
12681 TCGv_i64 fp0
= tcg_temp_new_i64();
12682 TCGv_i64 fp1
= tcg_temp_new_i64();
12684 gen_load_fpr64(ctx
, fp0
, fs
);
12685 gen_load_fpr64(ctx
, fp1
, ft
);
12686 gen_helper_float_add_ps(fp0
, cpu_env
, fp0
, fp1
);
12687 tcg_temp_free_i64(fp1
);
12688 gen_store_fpr64(ctx
, fp0
, fd
);
12689 tcg_temp_free_i64(fp0
);
12695 TCGv_i64 fp0
= tcg_temp_new_i64();
12696 TCGv_i64 fp1
= tcg_temp_new_i64();
12698 gen_load_fpr64(ctx
, fp0
, fs
);
12699 gen_load_fpr64(ctx
, fp1
, ft
);
12700 gen_helper_float_sub_ps(fp0
, cpu_env
, fp0
, fp1
);
12701 tcg_temp_free_i64(fp1
);
12702 gen_store_fpr64(ctx
, fp0
, fd
);
12703 tcg_temp_free_i64(fp0
);
12709 TCGv_i64 fp0
= tcg_temp_new_i64();
12710 TCGv_i64 fp1
= tcg_temp_new_i64();
12712 gen_load_fpr64(ctx
, fp0
, fs
);
12713 gen_load_fpr64(ctx
, fp1
, ft
);
12714 gen_helper_float_mul_ps(fp0
, cpu_env
, fp0
, fp1
);
12715 tcg_temp_free_i64(fp1
);
12716 gen_store_fpr64(ctx
, fp0
, fd
);
12717 tcg_temp_free_i64(fp0
);
12723 TCGv_i64 fp0
= tcg_temp_new_i64();
12725 gen_load_fpr64(ctx
, fp0
, fs
);
12726 gen_helper_float_abs_ps(fp0
, fp0
);
12727 gen_store_fpr64(ctx
, fp0
, fd
);
12728 tcg_temp_free_i64(fp0
);
12734 TCGv_i64 fp0
= tcg_temp_new_i64();
12736 gen_load_fpr64(ctx
, fp0
, fs
);
12737 gen_store_fpr64(ctx
, fp0
, fd
);
12738 tcg_temp_free_i64(fp0
);
12744 TCGv_i64 fp0
= tcg_temp_new_i64();
12746 gen_load_fpr64(ctx
, fp0
, fs
);
12747 gen_helper_float_chs_ps(fp0
, fp0
);
12748 gen_store_fpr64(ctx
, fp0
, fd
);
12749 tcg_temp_free_i64(fp0
);
12754 gen_movcf_ps(ctx
, fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
12759 TCGLabel
*l1
= gen_new_label();
12763 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
12765 fp0
= tcg_temp_new_i64();
12766 gen_load_fpr64(ctx
, fp0
, fs
);
12767 gen_store_fpr64(ctx
, fp0
, fd
);
12768 tcg_temp_free_i64(fp0
);
12775 TCGLabel
*l1
= gen_new_label();
12779 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
12780 fp0
= tcg_temp_new_i64();
12781 gen_load_fpr64(ctx
, fp0
, fs
);
12782 gen_store_fpr64(ctx
, fp0
, fd
);
12783 tcg_temp_free_i64(fp0
);
12791 TCGv_i64 fp0
= tcg_temp_new_i64();
12792 TCGv_i64 fp1
= tcg_temp_new_i64();
12794 gen_load_fpr64(ctx
, fp0
, ft
);
12795 gen_load_fpr64(ctx
, fp1
, fs
);
12796 gen_helper_float_addr_ps(fp0
, cpu_env
, fp0
, fp1
);
12797 tcg_temp_free_i64(fp1
);
12798 gen_store_fpr64(ctx
, fp0
, fd
);
12799 tcg_temp_free_i64(fp0
);
12805 TCGv_i64 fp0
= tcg_temp_new_i64();
12806 TCGv_i64 fp1
= tcg_temp_new_i64();
12808 gen_load_fpr64(ctx
, fp0
, ft
);
12809 gen_load_fpr64(ctx
, fp1
, fs
);
12810 gen_helper_float_mulr_ps(fp0
, cpu_env
, fp0
, fp1
);
12811 tcg_temp_free_i64(fp1
);
12812 gen_store_fpr64(ctx
, fp0
, fd
);
12813 tcg_temp_free_i64(fp0
);
12816 case OPC_RECIP2_PS
:
12819 TCGv_i64 fp0
= tcg_temp_new_i64();
12820 TCGv_i64 fp1
= tcg_temp_new_i64();
12822 gen_load_fpr64(ctx
, fp0
, fs
);
12823 gen_load_fpr64(ctx
, fp1
, ft
);
12824 gen_helper_float_recip2_ps(fp0
, cpu_env
, fp0
, fp1
);
12825 tcg_temp_free_i64(fp1
);
12826 gen_store_fpr64(ctx
, fp0
, fd
);
12827 tcg_temp_free_i64(fp0
);
12830 case OPC_RECIP1_PS
:
12833 TCGv_i64 fp0
= tcg_temp_new_i64();
12835 gen_load_fpr64(ctx
, fp0
, fs
);
12836 gen_helper_float_recip1_ps(fp0
, cpu_env
, fp0
);
12837 gen_store_fpr64(ctx
, fp0
, fd
);
12838 tcg_temp_free_i64(fp0
);
12841 case OPC_RSQRT1_PS
:
12844 TCGv_i64 fp0
= tcg_temp_new_i64();
12846 gen_load_fpr64(ctx
, fp0
, fs
);
12847 gen_helper_float_rsqrt1_ps(fp0
, cpu_env
, fp0
);
12848 gen_store_fpr64(ctx
, fp0
, fd
);
12849 tcg_temp_free_i64(fp0
);
12852 case OPC_RSQRT2_PS
:
12855 TCGv_i64 fp0
= tcg_temp_new_i64();
12856 TCGv_i64 fp1
= tcg_temp_new_i64();
12858 gen_load_fpr64(ctx
, fp0
, fs
);
12859 gen_load_fpr64(ctx
, fp1
, ft
);
12860 gen_helper_float_rsqrt2_ps(fp0
, cpu_env
, fp0
, fp1
);
12861 tcg_temp_free_i64(fp1
);
12862 gen_store_fpr64(ctx
, fp0
, fd
);
12863 tcg_temp_free_i64(fp0
);
12867 check_cp1_64bitmode(ctx
);
12869 TCGv_i32 fp0
= tcg_temp_new_i32();
12871 gen_load_fpr32h(ctx
, fp0
, fs
);
12872 gen_helper_float_cvts_pu(fp0
, cpu_env
, fp0
);
12873 gen_store_fpr32(ctx
, fp0
, fd
);
12874 tcg_temp_free_i32(fp0
);
12877 case OPC_CVT_PW_PS
:
12880 TCGv_i64 fp0
= tcg_temp_new_i64();
12882 gen_load_fpr64(ctx
, fp0
, fs
);
12883 gen_helper_float_cvtpw_ps(fp0
, cpu_env
, fp0
);
12884 gen_store_fpr64(ctx
, fp0
, fd
);
12885 tcg_temp_free_i64(fp0
);
12889 check_cp1_64bitmode(ctx
);
12891 TCGv_i32 fp0
= tcg_temp_new_i32();
12893 gen_load_fpr32(ctx
, fp0
, fs
);
12894 gen_helper_float_cvts_pl(fp0
, cpu_env
, fp0
);
12895 gen_store_fpr32(ctx
, fp0
, fd
);
12896 tcg_temp_free_i32(fp0
);
12902 TCGv_i32 fp0
= tcg_temp_new_i32();
12903 TCGv_i32 fp1
= tcg_temp_new_i32();
12905 gen_load_fpr32(ctx
, fp0
, fs
);
12906 gen_load_fpr32(ctx
, fp1
, ft
);
12907 gen_store_fpr32h(ctx
, fp0
, fd
);
12908 gen_store_fpr32(ctx
, fp1
, fd
);
12909 tcg_temp_free_i32(fp0
);
12910 tcg_temp_free_i32(fp1
);
12916 TCGv_i32 fp0
= tcg_temp_new_i32();
12917 TCGv_i32 fp1
= tcg_temp_new_i32();
12919 gen_load_fpr32(ctx
, fp0
, fs
);
12920 gen_load_fpr32h(ctx
, fp1
, ft
);
12921 gen_store_fpr32(ctx
, fp1
, fd
);
12922 gen_store_fpr32h(ctx
, fp0
, fd
);
12923 tcg_temp_free_i32(fp0
);
12924 tcg_temp_free_i32(fp1
);
12930 TCGv_i32 fp0
= tcg_temp_new_i32();
12931 TCGv_i32 fp1
= tcg_temp_new_i32();
12933 gen_load_fpr32h(ctx
, fp0
, fs
);
12934 gen_load_fpr32(ctx
, fp1
, ft
);
12935 gen_store_fpr32(ctx
, fp1
, fd
);
12936 gen_store_fpr32h(ctx
, fp0
, fd
);
12937 tcg_temp_free_i32(fp0
);
12938 tcg_temp_free_i32(fp1
);
12944 TCGv_i32 fp0
= tcg_temp_new_i32();
12945 TCGv_i32 fp1
= tcg_temp_new_i32();
12947 gen_load_fpr32h(ctx
, fp0
, fs
);
12948 gen_load_fpr32h(ctx
, fp1
, ft
);
12949 gen_store_fpr32(ctx
, fp1
, fd
);
12950 gen_store_fpr32h(ctx
, fp0
, fd
);
12951 tcg_temp_free_i32(fp0
);
12952 tcg_temp_free_i32(fp1
);
12956 case OPC_CMP_UN_PS
:
12957 case OPC_CMP_EQ_PS
:
12958 case OPC_CMP_UEQ_PS
:
12959 case OPC_CMP_OLT_PS
:
12960 case OPC_CMP_ULT_PS
:
12961 case OPC_CMP_OLE_PS
:
12962 case OPC_CMP_ULE_PS
:
12963 case OPC_CMP_SF_PS
:
12964 case OPC_CMP_NGLE_PS
:
12965 case OPC_CMP_SEQ_PS
:
12966 case OPC_CMP_NGL_PS
:
12967 case OPC_CMP_LT_PS
:
12968 case OPC_CMP_NGE_PS
:
12969 case OPC_CMP_LE_PS
:
12970 case OPC_CMP_NGT_PS
:
12971 if (ctx
->opcode
& (1 << 6)) {
12972 gen_cmpabs_ps(ctx
, func
- 48, ft
, fs
, cc
);
12974 gen_cmp_ps(ctx
, func
- 48, ft
, fs
, cc
);
12978 MIPS_INVAL("farith");
12979 gen_reserved_instruction(ctx
);
12984 /* Coprocessor 3 (FPU) */
12985 static void gen_flt3_ldst(DisasContext
*ctx
, uint32_t opc
,
12986 int fd
, int fs
, int base
, int index
)
12988 TCGv t0
= tcg_temp_new();
12991 gen_load_gpr(t0
, index
);
12992 } else if (index
== 0) {
12993 gen_load_gpr(t0
, base
);
12995 gen_op_addr_add(ctx
, t0
, cpu_gpr
[base
], cpu_gpr
[index
]);
12998 * Don't do NOP if destination is zero: we must perform the actual
13005 TCGv_i32 fp0
= tcg_temp_new_i32();
13007 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESL
);
13008 tcg_gen_trunc_tl_i32(fp0
, t0
);
13009 gen_store_fpr32(ctx
, fp0
, fd
);
13010 tcg_temp_free_i32(fp0
);
13015 check_cp1_registers(ctx
, fd
);
13017 TCGv_i64 fp0
= tcg_temp_new_i64();
13018 tcg_gen_qemu_ld_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
13019 gen_store_fpr64(ctx
, fp0
, fd
);
13020 tcg_temp_free_i64(fp0
);
13024 check_cp1_64bitmode(ctx
);
13025 tcg_gen_andi_tl(t0
, t0
, ~0x7);
13027 TCGv_i64 fp0
= tcg_temp_new_i64();
13029 tcg_gen_qemu_ld_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
13030 gen_store_fpr64(ctx
, fp0
, fd
);
13031 tcg_temp_free_i64(fp0
);
13037 TCGv_i32 fp0
= tcg_temp_new_i32();
13038 gen_load_fpr32(ctx
, fp0
, fs
);
13039 tcg_gen_qemu_st_i32(fp0
, t0
, ctx
->mem_idx
, MO_TEUL
);
13040 tcg_temp_free_i32(fp0
);
13045 check_cp1_registers(ctx
, fs
);
13047 TCGv_i64 fp0
= tcg_temp_new_i64();
13048 gen_load_fpr64(ctx
, fp0
, fs
);
13049 tcg_gen_qemu_st_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
13050 tcg_temp_free_i64(fp0
);
13054 check_cp1_64bitmode(ctx
);
13055 tcg_gen_andi_tl(t0
, t0
, ~0x7);
13057 TCGv_i64 fp0
= tcg_temp_new_i64();
13058 gen_load_fpr64(ctx
, fp0
, fs
);
13059 tcg_gen_qemu_st_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
13060 tcg_temp_free_i64(fp0
);
13067 static void gen_flt3_arith(DisasContext
*ctx
, uint32_t opc
,
13068 int fd
, int fr
, int fs
, int ft
)
13074 TCGv t0
= tcg_temp_local_new();
13075 TCGv_i32 fp
= tcg_temp_new_i32();
13076 TCGv_i32 fph
= tcg_temp_new_i32();
13077 TCGLabel
*l1
= gen_new_label();
13078 TCGLabel
*l2
= gen_new_label();
13080 gen_load_gpr(t0
, fr
);
13081 tcg_gen_andi_tl(t0
, t0
, 0x7);
13083 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, 0, l1
);
13084 gen_load_fpr32(ctx
, fp
, fs
);
13085 gen_load_fpr32h(ctx
, fph
, fs
);
13086 gen_store_fpr32(ctx
, fp
, fd
);
13087 gen_store_fpr32h(ctx
, fph
, fd
);
13090 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, 4, l2
);
13092 #ifdef TARGET_WORDS_BIGENDIAN
13093 gen_load_fpr32(ctx
, fp
, fs
);
13094 gen_load_fpr32h(ctx
, fph
, ft
);
13095 gen_store_fpr32h(ctx
, fp
, fd
);
13096 gen_store_fpr32(ctx
, fph
, fd
);
13098 gen_load_fpr32h(ctx
, fph
, fs
);
13099 gen_load_fpr32(ctx
, fp
, ft
);
13100 gen_store_fpr32(ctx
, fph
, fd
);
13101 gen_store_fpr32h(ctx
, fp
, fd
);
13104 tcg_temp_free_i32(fp
);
13105 tcg_temp_free_i32(fph
);
13111 TCGv_i32 fp0
= tcg_temp_new_i32();
13112 TCGv_i32 fp1
= tcg_temp_new_i32();
13113 TCGv_i32 fp2
= tcg_temp_new_i32();
13115 gen_load_fpr32(ctx
, fp0
, fs
);
13116 gen_load_fpr32(ctx
, fp1
, ft
);
13117 gen_load_fpr32(ctx
, fp2
, fr
);
13118 gen_helper_float_madd_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
13119 tcg_temp_free_i32(fp0
);
13120 tcg_temp_free_i32(fp1
);
13121 gen_store_fpr32(ctx
, fp2
, fd
);
13122 tcg_temp_free_i32(fp2
);
13127 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
13129 TCGv_i64 fp0
= tcg_temp_new_i64();
13130 TCGv_i64 fp1
= tcg_temp_new_i64();
13131 TCGv_i64 fp2
= tcg_temp_new_i64();
13133 gen_load_fpr64(ctx
, fp0
, fs
);
13134 gen_load_fpr64(ctx
, fp1
, ft
);
13135 gen_load_fpr64(ctx
, fp2
, fr
);
13136 gen_helper_float_madd_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
13137 tcg_temp_free_i64(fp0
);
13138 tcg_temp_free_i64(fp1
);
13139 gen_store_fpr64(ctx
, fp2
, fd
);
13140 tcg_temp_free_i64(fp2
);
13146 TCGv_i64 fp0
= tcg_temp_new_i64();
13147 TCGv_i64 fp1
= tcg_temp_new_i64();
13148 TCGv_i64 fp2
= tcg_temp_new_i64();
13150 gen_load_fpr64(ctx
, fp0
, fs
);
13151 gen_load_fpr64(ctx
, fp1
, ft
);
13152 gen_load_fpr64(ctx
, fp2
, fr
);
13153 gen_helper_float_madd_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
13154 tcg_temp_free_i64(fp0
);
13155 tcg_temp_free_i64(fp1
);
13156 gen_store_fpr64(ctx
, fp2
, fd
);
13157 tcg_temp_free_i64(fp2
);
13163 TCGv_i32 fp0
= tcg_temp_new_i32();
13164 TCGv_i32 fp1
= tcg_temp_new_i32();
13165 TCGv_i32 fp2
= tcg_temp_new_i32();
13167 gen_load_fpr32(ctx
, fp0
, fs
);
13168 gen_load_fpr32(ctx
, fp1
, ft
);
13169 gen_load_fpr32(ctx
, fp2
, fr
);
13170 gen_helper_float_msub_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
13171 tcg_temp_free_i32(fp0
);
13172 tcg_temp_free_i32(fp1
);
13173 gen_store_fpr32(ctx
, fp2
, fd
);
13174 tcg_temp_free_i32(fp2
);
13179 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
13181 TCGv_i64 fp0
= tcg_temp_new_i64();
13182 TCGv_i64 fp1
= tcg_temp_new_i64();
13183 TCGv_i64 fp2
= tcg_temp_new_i64();
13185 gen_load_fpr64(ctx
, fp0
, fs
);
13186 gen_load_fpr64(ctx
, fp1
, ft
);
13187 gen_load_fpr64(ctx
, fp2
, fr
);
13188 gen_helper_float_msub_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
13189 tcg_temp_free_i64(fp0
);
13190 tcg_temp_free_i64(fp1
);
13191 gen_store_fpr64(ctx
, fp2
, fd
);
13192 tcg_temp_free_i64(fp2
);
13198 TCGv_i64 fp0
= tcg_temp_new_i64();
13199 TCGv_i64 fp1
= tcg_temp_new_i64();
13200 TCGv_i64 fp2
= tcg_temp_new_i64();
13202 gen_load_fpr64(ctx
, fp0
, fs
);
13203 gen_load_fpr64(ctx
, fp1
, ft
);
13204 gen_load_fpr64(ctx
, fp2
, fr
);
13205 gen_helper_float_msub_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
13206 tcg_temp_free_i64(fp0
);
13207 tcg_temp_free_i64(fp1
);
13208 gen_store_fpr64(ctx
, fp2
, fd
);
13209 tcg_temp_free_i64(fp2
);
13215 TCGv_i32 fp0
= tcg_temp_new_i32();
13216 TCGv_i32 fp1
= tcg_temp_new_i32();
13217 TCGv_i32 fp2
= tcg_temp_new_i32();
13219 gen_load_fpr32(ctx
, fp0
, fs
);
13220 gen_load_fpr32(ctx
, fp1
, ft
);
13221 gen_load_fpr32(ctx
, fp2
, fr
);
13222 gen_helper_float_nmadd_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
13223 tcg_temp_free_i32(fp0
);
13224 tcg_temp_free_i32(fp1
);
13225 gen_store_fpr32(ctx
, fp2
, fd
);
13226 tcg_temp_free_i32(fp2
);
13231 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
13233 TCGv_i64 fp0
= tcg_temp_new_i64();
13234 TCGv_i64 fp1
= tcg_temp_new_i64();
13235 TCGv_i64 fp2
= tcg_temp_new_i64();
13237 gen_load_fpr64(ctx
, fp0
, fs
);
13238 gen_load_fpr64(ctx
, fp1
, ft
);
13239 gen_load_fpr64(ctx
, fp2
, fr
);
13240 gen_helper_float_nmadd_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
13241 tcg_temp_free_i64(fp0
);
13242 tcg_temp_free_i64(fp1
);
13243 gen_store_fpr64(ctx
, fp2
, fd
);
13244 tcg_temp_free_i64(fp2
);
13250 TCGv_i64 fp0
= tcg_temp_new_i64();
13251 TCGv_i64 fp1
= tcg_temp_new_i64();
13252 TCGv_i64 fp2
= tcg_temp_new_i64();
13254 gen_load_fpr64(ctx
, fp0
, fs
);
13255 gen_load_fpr64(ctx
, fp1
, ft
);
13256 gen_load_fpr64(ctx
, fp2
, fr
);
13257 gen_helper_float_nmadd_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
13258 tcg_temp_free_i64(fp0
);
13259 tcg_temp_free_i64(fp1
);
13260 gen_store_fpr64(ctx
, fp2
, fd
);
13261 tcg_temp_free_i64(fp2
);
13267 TCGv_i32 fp0
= tcg_temp_new_i32();
13268 TCGv_i32 fp1
= tcg_temp_new_i32();
13269 TCGv_i32 fp2
= tcg_temp_new_i32();
13271 gen_load_fpr32(ctx
, fp0
, fs
);
13272 gen_load_fpr32(ctx
, fp1
, ft
);
13273 gen_load_fpr32(ctx
, fp2
, fr
);
13274 gen_helper_float_nmsub_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
13275 tcg_temp_free_i32(fp0
);
13276 tcg_temp_free_i32(fp1
);
13277 gen_store_fpr32(ctx
, fp2
, fd
);
13278 tcg_temp_free_i32(fp2
);
13283 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
13285 TCGv_i64 fp0
= tcg_temp_new_i64();
13286 TCGv_i64 fp1
= tcg_temp_new_i64();
13287 TCGv_i64 fp2
= tcg_temp_new_i64();
13289 gen_load_fpr64(ctx
, fp0
, fs
);
13290 gen_load_fpr64(ctx
, fp1
, ft
);
13291 gen_load_fpr64(ctx
, fp2
, fr
);
13292 gen_helper_float_nmsub_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
13293 tcg_temp_free_i64(fp0
);
13294 tcg_temp_free_i64(fp1
);
13295 gen_store_fpr64(ctx
, fp2
, fd
);
13296 tcg_temp_free_i64(fp2
);
13302 TCGv_i64 fp0
= tcg_temp_new_i64();
13303 TCGv_i64 fp1
= tcg_temp_new_i64();
13304 TCGv_i64 fp2
= tcg_temp_new_i64();
13306 gen_load_fpr64(ctx
, fp0
, fs
);
13307 gen_load_fpr64(ctx
, fp1
, ft
);
13308 gen_load_fpr64(ctx
, fp2
, fr
);
13309 gen_helper_float_nmsub_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
13310 tcg_temp_free_i64(fp0
);
13311 tcg_temp_free_i64(fp1
);
13312 gen_store_fpr64(ctx
, fp2
, fd
);
13313 tcg_temp_free_i64(fp2
);
13317 MIPS_INVAL("flt3_arith");
13318 gen_reserved_instruction(ctx
);
13323 static void gen_rdhwr(DisasContext
*ctx
, int rt
, int rd
, int sel
)
13327 #if !defined(CONFIG_USER_ONLY)
13329 * The Linux kernel will emulate rdhwr if it's not supported natively.
13330 * Therefore only check the ISA in system mode.
13332 check_insn(ctx
, ISA_MIPS_R2
);
13334 t0
= tcg_temp_new();
13338 gen_helper_rdhwr_cpunum(t0
, cpu_env
);
13339 gen_store_gpr(t0
, rt
);
13342 gen_helper_rdhwr_synci_step(t0
, cpu_env
);
13343 gen_store_gpr(t0
, rt
);
13346 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
13349 gen_helper_rdhwr_cc(t0
, cpu_env
);
13350 gen_store_gpr(t0
, rt
);
13352 * Break the TB to be able to take timer interrupts immediately
13353 * after reading count. DISAS_STOP isn't sufficient, we need to ensure
13354 * we break completely out of translated code.
13356 gen_save_pc(ctx
->base
.pc_next
+ 4);
13357 ctx
->base
.is_jmp
= DISAS_EXIT
;
13360 gen_helper_rdhwr_ccres(t0
, cpu_env
);
13361 gen_store_gpr(t0
, rt
);
13364 check_insn(ctx
, ISA_MIPS_R6
);
13367 * Performance counter registers are not implemented other than
13368 * control register 0.
13370 generate_exception(ctx
, EXCP_RI
);
13372 gen_helper_rdhwr_performance(t0
, cpu_env
);
13373 gen_store_gpr(t0
, rt
);
13376 check_insn(ctx
, ISA_MIPS_R6
);
13377 gen_helper_rdhwr_xnp(t0
, cpu_env
);
13378 gen_store_gpr(t0
, rt
);
13381 #if defined(CONFIG_USER_ONLY)
13382 tcg_gen_ld_tl(t0
, cpu_env
,
13383 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
13384 gen_store_gpr(t0
, rt
);
13387 if ((ctx
->hflags
& MIPS_HFLAG_CP0
) ||
13388 (ctx
->hflags
& MIPS_HFLAG_HWRENA_ULR
)) {
13389 tcg_gen_ld_tl(t0
, cpu_env
,
13390 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
13391 gen_store_gpr(t0
, rt
);
13393 gen_reserved_instruction(ctx
);
13397 default: /* Invalid */
13398 MIPS_INVAL("rdhwr");
13399 gen_reserved_instruction(ctx
);
13405 static inline void clear_branch_hflags(DisasContext
*ctx
)
13407 ctx
->hflags
&= ~MIPS_HFLAG_BMASK
;
13408 if (ctx
->base
.is_jmp
== DISAS_NEXT
) {
13409 save_cpu_state(ctx
, 0);
13412 * It is not safe to save ctx->hflags as hflags may be changed
13413 * in execution time by the instruction in delay / forbidden slot.
13415 tcg_gen_andi_i32(hflags
, hflags
, ~MIPS_HFLAG_BMASK
);
13419 static void gen_branch(DisasContext
*ctx
, int insn_bytes
)
13421 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
13422 int proc_hflags
= ctx
->hflags
& MIPS_HFLAG_BMASK
;
13423 /* Branches completion */
13424 clear_branch_hflags(ctx
);
13425 ctx
->base
.is_jmp
= DISAS_NORETURN
;
13426 /* FIXME: Need to clear can_do_io. */
13427 switch (proc_hflags
& MIPS_HFLAG_BMASK_BASE
) {
13428 case MIPS_HFLAG_FBNSLOT
:
13429 gen_goto_tb(ctx
, 0, ctx
->base
.pc_next
+ insn_bytes
);
13432 /* unconditional branch */
13433 if (proc_hflags
& MIPS_HFLAG_BX
) {
13434 tcg_gen_xori_i32(hflags
, hflags
, MIPS_HFLAG_M16
);
13436 gen_goto_tb(ctx
, 0, ctx
->btarget
);
13438 case MIPS_HFLAG_BL
:
13439 /* blikely taken case */
13440 gen_goto_tb(ctx
, 0, ctx
->btarget
);
13442 case MIPS_HFLAG_BC
:
13443 /* Conditional branch */
13445 TCGLabel
*l1
= gen_new_label();
13447 tcg_gen_brcondi_tl(TCG_COND_NE
, bcond
, 0, l1
);
13448 gen_goto_tb(ctx
, 1, ctx
->base
.pc_next
+ insn_bytes
);
13450 gen_goto_tb(ctx
, 0, ctx
->btarget
);
13453 case MIPS_HFLAG_BR
:
13454 /* unconditional branch to register */
13455 if (ctx
->insn_flags
& (ASE_MIPS16
| ASE_MICROMIPS
)) {
13456 TCGv t0
= tcg_temp_new();
13457 TCGv_i32 t1
= tcg_temp_new_i32();
13459 tcg_gen_andi_tl(t0
, btarget
, 0x1);
13460 tcg_gen_trunc_tl_i32(t1
, t0
);
13462 tcg_gen_andi_i32(hflags
, hflags
, ~(uint32_t)MIPS_HFLAG_M16
);
13463 tcg_gen_shli_i32(t1
, t1
, MIPS_HFLAG_M16_SHIFT
);
13464 tcg_gen_or_i32(hflags
, hflags
, t1
);
13465 tcg_temp_free_i32(t1
);
13467 tcg_gen_andi_tl(cpu_PC
, btarget
, ~(target_ulong
)0x1);
13469 tcg_gen_mov_tl(cpu_PC
, btarget
);
13471 if (ctx
->base
.singlestep_enabled
) {
13472 save_cpu_state(ctx
, 0);
13473 gen_helper_raise_exception_debug(cpu_env
);
13475 tcg_gen_lookup_and_goto_ptr();
13478 fprintf(stderr
, "unknown branch 0x%x\n", proc_hflags
);
13484 /* Compact Branches */
13485 static void gen_compute_compact_branch(DisasContext
*ctx
, uint32_t opc
,
13486 int rs
, int rt
, int32_t offset
)
13488 int bcond_compute
= 0;
13489 TCGv t0
= tcg_temp_new();
13490 TCGv t1
= tcg_temp_new();
13491 int m16_lowbit
= (ctx
->hflags
& MIPS_HFLAG_M16
) != 0;
13493 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
13494 #ifdef MIPS_DEBUG_DISAS
13495 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
13496 "\n", ctx
->base
.pc_next
);
13498 gen_reserved_instruction(ctx
);
13502 /* Load needed operands and calculate btarget */
13504 /* compact branch */
13505 case OPC_BOVC
: /* OPC_BEQZALC, OPC_BEQC */
13506 case OPC_BNVC
: /* OPC_BNEZALC, OPC_BNEC */
13507 gen_load_gpr(t0
, rs
);
13508 gen_load_gpr(t1
, rt
);
13510 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
13511 if (rs
<= rt
&& rs
== 0) {
13512 /* OPC_BEQZALC, OPC_BNEZALC */
13513 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 4 + m16_lowbit
);
13516 case OPC_BLEZC
: /* OPC_BGEZC, OPC_BGEC */
13517 case OPC_BGTZC
: /* OPC_BLTZC, OPC_BLTC */
13518 gen_load_gpr(t0
, rs
);
13519 gen_load_gpr(t1
, rt
);
13521 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
13523 case OPC_BLEZALC
: /* OPC_BGEZALC, OPC_BGEUC */
13524 case OPC_BGTZALC
: /* OPC_BLTZALC, OPC_BLTUC */
13525 if (rs
== 0 || rs
== rt
) {
13526 /* OPC_BLEZALC, OPC_BGEZALC */
13527 /* OPC_BGTZALC, OPC_BLTZALC */
13528 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 4 + m16_lowbit
);
13530 gen_load_gpr(t0
, rs
);
13531 gen_load_gpr(t1
, rt
);
13533 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
13537 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
13542 /* OPC_BEQZC, OPC_BNEZC */
13543 gen_load_gpr(t0
, rs
);
13545 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
13547 /* OPC_JIC, OPC_JIALC */
13548 TCGv tbase
= tcg_temp_new();
13549 TCGv toffset
= tcg_temp_new();
13551 gen_load_gpr(tbase
, rt
);
13552 tcg_gen_movi_tl(toffset
, offset
);
13553 gen_op_addr_add(ctx
, btarget
, tbase
, toffset
);
13554 tcg_temp_free(tbase
);
13555 tcg_temp_free(toffset
);
13559 MIPS_INVAL("Compact branch/jump");
13560 gen_reserved_instruction(ctx
);
13564 if (bcond_compute
== 0) {
13565 /* Uncoditional compact branch */
13568 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 4 + m16_lowbit
);
13571 ctx
->hflags
|= MIPS_HFLAG_BR
;
13574 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 4 + m16_lowbit
);
13577 ctx
->hflags
|= MIPS_HFLAG_B
;
13580 MIPS_INVAL("Compact branch/jump");
13581 gen_reserved_instruction(ctx
);
13585 /* Generating branch here as compact branches don't have delay slot */
13586 gen_branch(ctx
, 4);
13588 /* Conditional compact branch */
13589 TCGLabel
*fs
= gen_new_label();
13590 save_cpu_state(ctx
, 0);
13593 case OPC_BLEZALC
: /* OPC_BGEZALC, OPC_BGEUC */
13594 if (rs
== 0 && rt
!= 0) {
13596 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE
), t1
, 0, fs
);
13597 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
13599 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE
), t1
, 0, fs
);
13602 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU
), t0
, t1
, fs
);
13605 case OPC_BGTZALC
: /* OPC_BLTZALC, OPC_BLTUC */
13606 if (rs
== 0 && rt
!= 0) {
13608 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT
), t1
, 0, fs
);
13609 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
13611 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT
), t1
, 0, fs
);
13614 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU
), t0
, t1
, fs
);
13617 case OPC_BLEZC
: /* OPC_BGEZC, OPC_BGEC */
13618 if (rs
== 0 && rt
!= 0) {
13620 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE
), t1
, 0, fs
);
13621 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
13623 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE
), t1
, 0, fs
);
13626 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE
), t0
, t1
, fs
);
13629 case OPC_BGTZC
: /* OPC_BLTZC, OPC_BLTC */
13630 if (rs
== 0 && rt
!= 0) {
13632 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT
), t1
, 0, fs
);
13633 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
13635 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT
), t1
, 0, fs
);
13638 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT
), t0
, t1
, fs
);
13641 case OPC_BOVC
: /* OPC_BEQZALC, OPC_BEQC */
13642 case OPC_BNVC
: /* OPC_BNEZALC, OPC_BNEC */
13644 /* OPC_BOVC, OPC_BNVC */
13645 TCGv t2
= tcg_temp_new();
13646 TCGv t3
= tcg_temp_new();
13647 TCGv t4
= tcg_temp_new();
13648 TCGv input_overflow
= tcg_temp_new();
13650 gen_load_gpr(t0
, rs
);
13651 gen_load_gpr(t1
, rt
);
13652 tcg_gen_ext32s_tl(t2
, t0
);
13653 tcg_gen_setcond_tl(TCG_COND_NE
, input_overflow
, t2
, t0
);
13654 tcg_gen_ext32s_tl(t3
, t1
);
13655 tcg_gen_setcond_tl(TCG_COND_NE
, t4
, t3
, t1
);
13656 tcg_gen_or_tl(input_overflow
, input_overflow
, t4
);
13658 tcg_gen_add_tl(t4
, t2
, t3
);
13659 tcg_gen_ext32s_tl(t4
, t4
);
13660 tcg_gen_xor_tl(t2
, t2
, t3
);
13661 tcg_gen_xor_tl(t3
, t4
, t3
);
13662 tcg_gen_andc_tl(t2
, t3
, t2
);
13663 tcg_gen_setcondi_tl(TCG_COND_LT
, t4
, t2
, 0);
13664 tcg_gen_or_tl(t4
, t4
, input_overflow
);
13665 if (opc
== OPC_BOVC
) {
13667 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE
), t4
, 0, fs
);
13670 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ
), t4
, 0, fs
);
13672 tcg_temp_free(input_overflow
);
13676 } else if (rs
< rt
&& rs
== 0) {
13677 /* OPC_BEQZALC, OPC_BNEZALC */
13678 if (opc
== OPC_BEQZALC
) {
13680 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ
), t1
, 0, fs
);
13683 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE
), t1
, 0, fs
);
13686 /* OPC_BEQC, OPC_BNEC */
13687 if (opc
== OPC_BEQC
) {
13689 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ
), t0
, t1
, fs
);
13692 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE
), t0
, t1
, fs
);
13697 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ
), t0
, 0, fs
);
13700 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE
), t0
, 0, fs
);
13703 MIPS_INVAL("Compact conditional branch/jump");
13704 gen_reserved_instruction(ctx
);
13708 /* Generating branch here as compact branches don't have delay slot */
13709 gen_goto_tb(ctx
, 1, ctx
->btarget
);
13712 ctx
->hflags
|= MIPS_HFLAG_FBNSLOT
;
13720 /* ISA extensions (ASEs) */
13721 /* MIPS16 extension to MIPS32 */
13723 /* MIPS16 major opcodes */
13725 M16_OPC_ADDIUSP
= 0x00,
13726 M16_OPC_ADDIUPC
= 0x01,
13728 M16_OPC_JAL
= 0x03,
13729 M16_OPC_BEQZ
= 0x04,
13730 M16_OPC_BNEQZ
= 0x05,
13731 M16_OPC_SHIFT
= 0x06,
13733 M16_OPC_RRIA
= 0x08,
13734 M16_OPC_ADDIU8
= 0x09,
13735 M16_OPC_SLTI
= 0x0a,
13736 M16_OPC_SLTIU
= 0x0b,
13739 M16_OPC_CMPI
= 0x0e,
13743 M16_OPC_LWSP
= 0x12,
13745 M16_OPC_LBU
= 0x14,
13746 M16_OPC_LHU
= 0x15,
13747 M16_OPC_LWPC
= 0x16,
13748 M16_OPC_LWU
= 0x17,
13751 M16_OPC_SWSP
= 0x1a,
13753 M16_OPC_RRR
= 0x1c,
13755 M16_OPC_EXTEND
= 0x1e,
13759 /* I8 funct field */
13778 /* RR funct field */
13812 /* I64 funct field */
13820 I64_DADDIUPC
= 0x6,
13824 /* RR ry field for CNVT */
13826 RR_RY_CNVT_ZEB
= 0x0,
13827 RR_RY_CNVT_ZEH
= 0x1,
13828 RR_RY_CNVT_ZEW
= 0x2,
13829 RR_RY_CNVT_SEB
= 0x4,
13830 RR_RY_CNVT_SEH
= 0x5,
13831 RR_RY_CNVT_SEW
= 0x6,
13834 static int xlat(int r
)
13836 static int map
[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
13841 static void gen_mips16_save(DisasContext
*ctx
,
13842 int xsregs
, int aregs
,
13843 int do_ra
, int do_s0
, int do_s1
,
13846 TCGv t0
= tcg_temp_new();
13847 TCGv t1
= tcg_temp_new();
13848 TCGv t2
= tcg_temp_new();
13878 gen_reserved_instruction(ctx
);
13884 gen_base_offset_addr(ctx
, t0
, 29, 12);
13885 gen_load_gpr(t1
, 7);
13886 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
13889 gen_base_offset_addr(ctx
, t0
, 29, 8);
13890 gen_load_gpr(t1
, 6);
13891 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
13894 gen_base_offset_addr(ctx
, t0
, 29, 4);
13895 gen_load_gpr(t1
, 5);
13896 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
13899 gen_base_offset_addr(ctx
, t0
, 29, 0);
13900 gen_load_gpr(t1
, 4);
13901 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
13904 gen_load_gpr(t0
, 29);
13906 #define DECR_AND_STORE(reg) do { \
13907 tcg_gen_movi_tl(t2, -4); \
13908 gen_op_addr_add(ctx, t0, t0, t2); \
13909 gen_load_gpr(t1, reg); \
13910 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \
13914 DECR_AND_STORE(31);
13919 DECR_AND_STORE(30);
13922 DECR_AND_STORE(23);
13925 DECR_AND_STORE(22);
13928 DECR_AND_STORE(21);
13931 DECR_AND_STORE(20);
13934 DECR_AND_STORE(19);
13937 DECR_AND_STORE(18);
13941 DECR_AND_STORE(17);
13944 DECR_AND_STORE(16);
13974 gen_reserved_instruction(ctx
);
13990 #undef DECR_AND_STORE
13992 tcg_gen_movi_tl(t2
, -framesize
);
13993 gen_op_addr_add(ctx
, cpu_gpr
[29], cpu_gpr
[29], t2
);
13999 static void gen_mips16_restore(DisasContext
*ctx
,
14000 int xsregs
, int aregs
,
14001 int do_ra
, int do_s0
, int do_s1
,
14005 TCGv t0
= tcg_temp_new();
14006 TCGv t1
= tcg_temp_new();
14007 TCGv t2
= tcg_temp_new();
14009 tcg_gen_movi_tl(t2
, framesize
);
14010 gen_op_addr_add(ctx
, t0
, cpu_gpr
[29], t2
);
14012 #define DECR_AND_LOAD(reg) do { \
14013 tcg_gen_movi_tl(t2, -4); \
14014 gen_op_addr_add(ctx, t0, t0, t2); \
14015 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \
14016 gen_store_gpr(t1, reg); \
14080 gen_reserved_instruction(ctx
);
14096 #undef DECR_AND_LOAD
14098 tcg_gen_movi_tl(t2
, framesize
);
14099 gen_op_addr_add(ctx
, cpu_gpr
[29], cpu_gpr
[29], t2
);
14105 static void gen_addiupc(DisasContext
*ctx
, int rx
, int imm
,
14106 int is_64_bit
, int extended
)
14110 if (extended
&& (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
14111 gen_reserved_instruction(ctx
);
14115 t0
= tcg_temp_new();
14117 tcg_gen_movi_tl(t0
, pc_relative_pc(ctx
));
14118 tcg_gen_addi_tl(cpu_gpr
[rx
], t0
, imm
);
14120 tcg_gen_ext32s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
14126 static void gen_cache_operation(DisasContext
*ctx
, uint32_t op
, int base
,
14129 TCGv_i32 t0
= tcg_const_i32(op
);
14130 TCGv t1
= tcg_temp_new();
14131 gen_base_offset_addr(ctx
, t1
, base
, offset
);
14132 gen_helper_cache(cpu_env
, t1
, t0
);
14135 #if defined(TARGET_MIPS64)
14136 static void decode_i64_mips16(DisasContext
*ctx
,
14137 int ry
, int funct
, int16_t offset
,
14142 check_insn(ctx
, ISA_MIPS3
);
14143 check_mips_64(ctx
);
14144 offset
= extended
? offset
: offset
<< 3;
14145 gen_ld(ctx
, OPC_LD
, ry
, 29, offset
);
14148 check_insn(ctx
, ISA_MIPS3
);
14149 check_mips_64(ctx
);
14150 offset
= extended
? offset
: offset
<< 3;
14151 gen_st(ctx
, OPC_SD
, ry
, 29, offset
);
14154 check_insn(ctx
, ISA_MIPS3
);
14155 check_mips_64(ctx
);
14156 offset
= extended
? offset
: (ctx
->opcode
& 0xff) << 3;
14157 gen_st(ctx
, OPC_SD
, 31, 29, offset
);
14160 check_insn(ctx
, ISA_MIPS3
);
14161 check_mips_64(ctx
);
14162 offset
= extended
? offset
: ((int8_t)ctx
->opcode
) << 3;
14163 gen_arith_imm(ctx
, OPC_DADDIU
, 29, 29, offset
);
14166 check_insn(ctx
, ISA_MIPS3
);
14167 check_mips_64(ctx
);
14168 if (extended
&& (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
14169 gen_reserved_instruction(ctx
);
14171 offset
= extended
? offset
: offset
<< 3;
14172 gen_ld(ctx
, OPC_LDPC
, ry
, 0, offset
);
14176 check_insn(ctx
, ISA_MIPS3
);
14177 check_mips_64(ctx
);
14178 offset
= extended
? offset
: ((int8_t)(offset
<< 3)) >> 3;
14179 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, ry
, offset
);
14182 check_insn(ctx
, ISA_MIPS3
);
14183 check_mips_64(ctx
);
14184 offset
= extended
? offset
: offset
<< 2;
14185 gen_addiupc(ctx
, ry
, offset
, 1, extended
);
14188 check_insn(ctx
, ISA_MIPS3
);
14189 check_mips_64(ctx
);
14190 offset
= extended
? offset
: offset
<< 2;
14191 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, 29, offset
);
14197 static int decode_extended_mips16_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
14199 int extend
= cpu_lduw_code(env
, ctx
->base
.pc_next
+ 2);
14200 int op
, rx
, ry
, funct
, sa
;
14201 int16_t imm
, offset
;
14203 ctx
->opcode
= (ctx
->opcode
<< 16) | extend
;
14204 op
= (ctx
->opcode
>> 11) & 0x1f;
14205 sa
= (ctx
->opcode
>> 22) & 0x1f;
14206 funct
= (ctx
->opcode
>> 8) & 0x7;
14207 rx
= xlat((ctx
->opcode
>> 8) & 0x7);
14208 ry
= xlat((ctx
->opcode
>> 5) & 0x7);
14209 offset
= imm
= (int16_t) (((ctx
->opcode
>> 16) & 0x1f) << 11
14210 | ((ctx
->opcode
>> 21) & 0x3f) << 5
14211 | (ctx
->opcode
& 0x1f));
14214 * The extended opcodes cleverly reuse the opcodes from their 16-bit
14218 case M16_OPC_ADDIUSP
:
14219 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 29, imm
);
14221 case M16_OPC_ADDIUPC
:
14222 gen_addiupc(ctx
, rx
, imm
, 0, 1);
14225 gen_compute_branch(ctx
, OPC_BEQ
, 4, 0, 0, offset
<< 1, 0);
14226 /* No delay slot, so just process as a normal instruction */
14229 gen_compute_branch(ctx
, OPC_BEQ
, 4, rx
, 0, offset
<< 1, 0);
14230 /* No delay slot, so just process as a normal instruction */
14232 case M16_OPC_BNEQZ
:
14233 gen_compute_branch(ctx
, OPC_BNE
, 4, rx
, 0, offset
<< 1, 0);
14234 /* No delay slot, so just process as a normal instruction */
14236 case M16_OPC_SHIFT
:
14237 switch (ctx
->opcode
& 0x3) {
14239 gen_shift_imm(ctx
, OPC_SLL
, rx
, ry
, sa
);
14242 #if defined(TARGET_MIPS64)
14243 check_mips_64(ctx
);
14244 gen_shift_imm(ctx
, OPC_DSLL
, rx
, ry
, sa
);
14246 gen_reserved_instruction(ctx
);
14250 gen_shift_imm(ctx
, OPC_SRL
, rx
, ry
, sa
);
14253 gen_shift_imm(ctx
, OPC_SRA
, rx
, ry
, sa
);
14257 #if defined(TARGET_MIPS64)
14259 check_insn(ctx
, ISA_MIPS3
);
14260 check_mips_64(ctx
);
14261 gen_ld(ctx
, OPC_LD
, ry
, rx
, offset
);
14265 imm
= ctx
->opcode
& 0xf;
14266 imm
= imm
| ((ctx
->opcode
>> 20) & 0x7f) << 4;
14267 imm
= imm
| ((ctx
->opcode
>> 16) & 0xf) << 11;
14268 imm
= (int16_t) (imm
<< 1) >> 1;
14269 if ((ctx
->opcode
>> 4) & 0x1) {
14270 #if defined(TARGET_MIPS64)
14271 check_mips_64(ctx
);
14272 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, rx
, imm
);
14274 gen_reserved_instruction(ctx
);
14277 gen_arith_imm(ctx
, OPC_ADDIU
, ry
, rx
, imm
);
14280 case M16_OPC_ADDIU8
:
14281 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, rx
, imm
);
14284 gen_slt_imm(ctx
, OPC_SLTI
, 24, rx
, imm
);
14286 case M16_OPC_SLTIU
:
14287 gen_slt_imm(ctx
, OPC_SLTIU
, 24, rx
, imm
);
14292 gen_compute_branch(ctx
, OPC_BEQ
, 4, 24, 0, offset
<< 1, 0);
14295 gen_compute_branch(ctx
, OPC_BNE
, 4, 24, 0, offset
<< 1, 0);
14298 gen_st(ctx
, OPC_SW
, 31, 29, imm
);
14301 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, imm
);
14304 check_insn(ctx
, ISA_MIPS_R1
);
14306 int xsregs
= (ctx
->opcode
>> 24) & 0x7;
14307 int aregs
= (ctx
->opcode
>> 16) & 0xf;
14308 int do_ra
= (ctx
->opcode
>> 6) & 0x1;
14309 int do_s0
= (ctx
->opcode
>> 5) & 0x1;
14310 int do_s1
= (ctx
->opcode
>> 4) & 0x1;
14311 int framesize
= (((ctx
->opcode
>> 20) & 0xf) << 4
14312 | (ctx
->opcode
& 0xf)) << 3;
14314 if (ctx
->opcode
& (1 << 7)) {
14315 gen_mips16_save(ctx
, xsregs
, aregs
,
14316 do_ra
, do_s0
, do_s1
,
14319 gen_mips16_restore(ctx
, xsregs
, aregs
,
14320 do_ra
, do_s0
, do_s1
,
14326 gen_reserved_instruction(ctx
);
14331 tcg_gen_movi_tl(cpu_gpr
[rx
], (uint16_t) imm
);
14334 tcg_gen_xori_tl(cpu_gpr
[24], cpu_gpr
[rx
], (uint16_t) imm
);
14336 #if defined(TARGET_MIPS64)
14338 check_insn(ctx
, ISA_MIPS3
);
14339 check_mips_64(ctx
);
14340 gen_st(ctx
, OPC_SD
, ry
, rx
, offset
);
14344 gen_ld(ctx
, OPC_LB
, ry
, rx
, offset
);
14347 gen_ld(ctx
, OPC_LH
, ry
, rx
, offset
);
14350 gen_ld(ctx
, OPC_LW
, rx
, 29, offset
);
14353 gen_ld(ctx
, OPC_LW
, ry
, rx
, offset
);
14356 gen_ld(ctx
, OPC_LBU
, ry
, rx
, offset
);
14359 gen_ld(ctx
, OPC_LHU
, ry
, rx
, offset
);
14362 gen_ld(ctx
, OPC_LWPC
, rx
, 0, offset
);
14364 #if defined(TARGET_MIPS64)
14366 check_insn(ctx
, ISA_MIPS3
);
14367 check_mips_64(ctx
);
14368 gen_ld(ctx
, OPC_LWU
, ry
, rx
, offset
);
14372 gen_st(ctx
, OPC_SB
, ry
, rx
, offset
);
14375 gen_st(ctx
, OPC_SH
, ry
, rx
, offset
);
14378 gen_st(ctx
, OPC_SW
, rx
, 29, offset
);
14381 gen_st(ctx
, OPC_SW
, ry
, rx
, offset
);
14383 #if defined(TARGET_MIPS64)
14385 decode_i64_mips16(ctx
, ry
, funct
, offset
, 1);
14389 gen_reserved_instruction(ctx
);
14396 static inline bool is_uhi(int sdbbp_code
)
14398 #ifdef CONFIG_USER_ONLY
14401 return semihosting_enabled() && sdbbp_code
== 1;
14405 #ifdef CONFIG_USER_ONLY
14406 /* The above should dead-code away any calls to this..*/
14407 static inline void gen_helper_do_semihosting(void *env
)
14409 g_assert_not_reached();
14413 static int decode_mips16_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
14417 int op
, cnvt_op
, op1
, offset
;
14421 op
= (ctx
->opcode
>> 11) & 0x1f;
14422 sa
= (ctx
->opcode
>> 2) & 0x7;
14423 sa
= sa
== 0 ? 8 : sa
;
14424 rx
= xlat((ctx
->opcode
>> 8) & 0x7);
14425 cnvt_op
= (ctx
->opcode
>> 5) & 0x7;
14426 ry
= xlat((ctx
->opcode
>> 5) & 0x7);
14427 op1
= offset
= ctx
->opcode
& 0x1f;
14432 case M16_OPC_ADDIUSP
:
14434 int16_t imm
= ((uint8_t) ctx
->opcode
) << 2;
14436 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 29, imm
);
14439 case M16_OPC_ADDIUPC
:
14440 gen_addiupc(ctx
, rx
, ((uint8_t) ctx
->opcode
) << 2, 0, 0);
14443 offset
= (ctx
->opcode
& 0x7ff) << 1;
14444 offset
= (int16_t)(offset
<< 4) >> 4;
14445 gen_compute_branch(ctx
, OPC_BEQ
, 2, 0, 0, offset
, 0);
14446 /* No delay slot, so just process as a normal instruction */
14449 offset
= cpu_lduw_code(env
, ctx
->base
.pc_next
+ 2);
14450 offset
= (((ctx
->opcode
& 0x1f) << 21)
14451 | ((ctx
->opcode
>> 5) & 0x1f) << 16
14453 op
= ((ctx
->opcode
>> 10) & 0x1) ? OPC_JALX
: OPC_JAL
;
14454 gen_compute_branch(ctx
, op
, 4, rx
, ry
, offset
, 2);
14458 gen_compute_branch(ctx
, OPC_BEQ
, 2, rx
, 0,
14459 ((int8_t)ctx
->opcode
) << 1, 0);
14460 /* No delay slot, so just process as a normal instruction */
14462 case M16_OPC_BNEQZ
:
14463 gen_compute_branch(ctx
, OPC_BNE
, 2, rx
, 0,
14464 ((int8_t)ctx
->opcode
) << 1, 0);
14465 /* No delay slot, so just process as a normal instruction */
14467 case M16_OPC_SHIFT
:
14468 switch (ctx
->opcode
& 0x3) {
14470 gen_shift_imm(ctx
, OPC_SLL
, rx
, ry
, sa
);
14473 #if defined(TARGET_MIPS64)
14474 check_insn(ctx
, ISA_MIPS3
);
14475 check_mips_64(ctx
);
14476 gen_shift_imm(ctx
, OPC_DSLL
, rx
, ry
, sa
);
14478 gen_reserved_instruction(ctx
);
14482 gen_shift_imm(ctx
, OPC_SRL
, rx
, ry
, sa
);
14485 gen_shift_imm(ctx
, OPC_SRA
, rx
, ry
, sa
);
14489 #if defined(TARGET_MIPS64)
14491 check_insn(ctx
, ISA_MIPS3
);
14492 check_mips_64(ctx
);
14493 gen_ld(ctx
, OPC_LD
, ry
, rx
, offset
<< 3);
14498 int16_t imm
= (int8_t)((ctx
->opcode
& 0xf) << 4) >> 4;
14500 if ((ctx
->opcode
>> 4) & 1) {
14501 #if defined(TARGET_MIPS64)
14502 check_insn(ctx
, ISA_MIPS3
);
14503 check_mips_64(ctx
);
14504 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, rx
, imm
);
14506 gen_reserved_instruction(ctx
);
14509 gen_arith_imm(ctx
, OPC_ADDIU
, ry
, rx
, imm
);
14513 case M16_OPC_ADDIU8
:
14515 int16_t imm
= (int8_t) ctx
->opcode
;
14517 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, rx
, imm
);
14522 int16_t imm
= (uint8_t) ctx
->opcode
;
14523 gen_slt_imm(ctx
, OPC_SLTI
, 24, rx
, imm
);
14526 case M16_OPC_SLTIU
:
14528 int16_t imm
= (uint8_t) ctx
->opcode
;
14529 gen_slt_imm(ctx
, OPC_SLTIU
, 24, rx
, imm
);
14536 funct
= (ctx
->opcode
>> 8) & 0x7;
14539 gen_compute_branch(ctx
, OPC_BEQ
, 2, 24, 0,
14540 ((int8_t)ctx
->opcode
) << 1, 0);
14543 gen_compute_branch(ctx
, OPC_BNE
, 2, 24, 0,
14544 ((int8_t)ctx
->opcode
) << 1, 0);
14547 gen_st(ctx
, OPC_SW
, 31, 29, (ctx
->opcode
& 0xff) << 2);
14550 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29,
14551 ((int8_t)ctx
->opcode
) << 3);
14554 check_insn(ctx
, ISA_MIPS_R1
);
14556 int do_ra
= ctx
->opcode
& (1 << 6);
14557 int do_s0
= ctx
->opcode
& (1 << 5);
14558 int do_s1
= ctx
->opcode
& (1 << 4);
14559 int framesize
= ctx
->opcode
& 0xf;
14561 if (framesize
== 0) {
14564 framesize
= framesize
<< 3;
14567 if (ctx
->opcode
& (1 << 7)) {
14568 gen_mips16_save(ctx
, 0, 0,
14569 do_ra
, do_s0
, do_s1
, framesize
);
14571 gen_mips16_restore(ctx
, 0, 0,
14572 do_ra
, do_s0
, do_s1
, framesize
);
14578 int rz
= xlat(ctx
->opcode
& 0x7);
14580 reg32
= (((ctx
->opcode
>> 3) & 0x3) << 3) |
14581 ((ctx
->opcode
>> 5) & 0x7);
14582 gen_arith(ctx
, OPC_ADDU
, reg32
, rz
, 0);
14586 reg32
= ctx
->opcode
& 0x1f;
14587 gen_arith(ctx
, OPC_ADDU
, ry
, reg32
, 0);
14590 gen_reserved_instruction(ctx
);
14597 int16_t imm
= (uint8_t) ctx
->opcode
;
14599 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 0, imm
);
14604 int16_t imm
= (uint8_t) ctx
->opcode
;
14605 gen_logic_imm(ctx
, OPC_XORI
, 24, rx
, imm
);
14608 #if defined(TARGET_MIPS64)
14610 check_insn(ctx
, ISA_MIPS3
);
14611 check_mips_64(ctx
);
14612 gen_st(ctx
, OPC_SD
, ry
, rx
, offset
<< 3);
14616 gen_ld(ctx
, OPC_LB
, ry
, rx
, offset
);
14619 gen_ld(ctx
, OPC_LH
, ry
, rx
, offset
<< 1);
14622 gen_ld(ctx
, OPC_LW
, rx
, 29, ((uint8_t)ctx
->opcode
) << 2);
14625 gen_ld(ctx
, OPC_LW
, ry
, rx
, offset
<< 2);
14628 gen_ld(ctx
, OPC_LBU
, ry
, rx
, offset
);
14631 gen_ld(ctx
, OPC_LHU
, ry
, rx
, offset
<< 1);
14634 gen_ld(ctx
, OPC_LWPC
, rx
, 0, ((uint8_t)ctx
->opcode
) << 2);
14636 #if defined(TARGET_MIPS64)
14638 check_insn(ctx
, ISA_MIPS3
);
14639 check_mips_64(ctx
);
14640 gen_ld(ctx
, OPC_LWU
, ry
, rx
, offset
<< 2);
14644 gen_st(ctx
, OPC_SB
, ry
, rx
, offset
);
14647 gen_st(ctx
, OPC_SH
, ry
, rx
, offset
<< 1);
14650 gen_st(ctx
, OPC_SW
, rx
, 29, ((uint8_t)ctx
->opcode
) << 2);
14653 gen_st(ctx
, OPC_SW
, ry
, rx
, offset
<< 2);
14657 int rz
= xlat((ctx
->opcode
>> 2) & 0x7);
14660 switch (ctx
->opcode
& 0x3) {
14662 mips32_op
= OPC_ADDU
;
14665 mips32_op
= OPC_SUBU
;
14667 #if defined(TARGET_MIPS64)
14669 mips32_op
= OPC_DADDU
;
14670 check_insn(ctx
, ISA_MIPS3
);
14671 check_mips_64(ctx
);
14674 mips32_op
= OPC_DSUBU
;
14675 check_insn(ctx
, ISA_MIPS3
);
14676 check_mips_64(ctx
);
14680 gen_reserved_instruction(ctx
);
14684 gen_arith(ctx
, mips32_op
, rz
, rx
, ry
);
14693 int nd
= (ctx
->opcode
>> 7) & 0x1;
14694 int link
= (ctx
->opcode
>> 6) & 0x1;
14695 int ra
= (ctx
->opcode
>> 5) & 0x1;
14698 check_insn(ctx
, ISA_MIPS_R1
);
14707 gen_compute_branch(ctx
, op
, 2, ra
? 31 : rx
, 31, 0,
14712 if (is_uhi(extract32(ctx
->opcode
, 5, 6))) {
14713 gen_helper_do_semihosting(cpu_env
);
14716 * XXX: not clear which exception should be raised
14717 * when in debug mode...
14719 check_insn(ctx
, ISA_MIPS_R1
);
14720 generate_exception_end(ctx
, EXCP_DBp
);
14724 gen_slt(ctx
, OPC_SLT
, 24, rx
, ry
);
14727 gen_slt(ctx
, OPC_SLTU
, 24, rx
, ry
);
14730 generate_exception_end(ctx
, EXCP_BREAK
);
14733 gen_shift(ctx
, OPC_SLLV
, ry
, rx
, ry
);
14736 gen_shift(ctx
, OPC_SRLV
, ry
, rx
, ry
);
14739 gen_shift(ctx
, OPC_SRAV
, ry
, rx
, ry
);
14741 #if defined(TARGET_MIPS64)
14743 check_insn(ctx
, ISA_MIPS3
);
14744 check_mips_64(ctx
);
14745 gen_shift_imm(ctx
, OPC_DSRL
, ry
, ry
, sa
);
14749 gen_logic(ctx
, OPC_XOR
, 24, rx
, ry
);
14752 gen_arith(ctx
, OPC_SUBU
, rx
, 0, ry
);
14755 gen_logic(ctx
, OPC_AND
, rx
, rx
, ry
);
14758 gen_logic(ctx
, OPC_OR
, rx
, rx
, ry
);
14761 gen_logic(ctx
, OPC_XOR
, rx
, rx
, ry
);
14764 gen_logic(ctx
, OPC_NOR
, rx
, ry
, 0);
14767 gen_HILO(ctx
, OPC_MFHI
, 0, rx
);
14770 check_insn(ctx
, ISA_MIPS_R1
);
14772 case RR_RY_CNVT_ZEB
:
14773 tcg_gen_ext8u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
14775 case RR_RY_CNVT_ZEH
:
14776 tcg_gen_ext16u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
14778 case RR_RY_CNVT_SEB
:
14779 tcg_gen_ext8s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
14781 case RR_RY_CNVT_SEH
:
14782 tcg_gen_ext16s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
14784 #if defined(TARGET_MIPS64)
14785 case RR_RY_CNVT_ZEW
:
14786 check_insn(ctx
, ISA_MIPS_R1
);
14787 check_mips_64(ctx
);
14788 tcg_gen_ext32u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
14790 case RR_RY_CNVT_SEW
:
14791 check_insn(ctx
, ISA_MIPS_R1
);
14792 check_mips_64(ctx
);
14793 tcg_gen_ext32s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
14797 gen_reserved_instruction(ctx
);
14802 gen_HILO(ctx
, OPC_MFLO
, 0, rx
);
14804 #if defined(TARGET_MIPS64)
14806 check_insn(ctx
, ISA_MIPS3
);
14807 check_mips_64(ctx
);
14808 gen_shift_imm(ctx
, OPC_DSRA
, ry
, ry
, sa
);
14811 check_insn(ctx
, ISA_MIPS3
);
14812 check_mips_64(ctx
);
14813 gen_shift(ctx
, OPC_DSLLV
, ry
, rx
, ry
);
14816 check_insn(ctx
, ISA_MIPS3
);
14817 check_mips_64(ctx
);
14818 gen_shift(ctx
, OPC_DSRLV
, ry
, rx
, ry
);
14821 check_insn(ctx
, ISA_MIPS3
);
14822 check_mips_64(ctx
);
14823 gen_shift(ctx
, OPC_DSRAV
, ry
, rx
, ry
);
14827 gen_muldiv(ctx
, OPC_MULT
, 0, rx
, ry
);
14830 gen_muldiv(ctx
, OPC_MULTU
, 0, rx
, ry
);
14833 gen_muldiv(ctx
, OPC_DIV
, 0, rx
, ry
);
14836 gen_muldiv(ctx
, OPC_DIVU
, 0, rx
, ry
);
14838 #if defined(TARGET_MIPS64)
14840 check_insn(ctx
, ISA_MIPS3
);
14841 check_mips_64(ctx
);
14842 gen_muldiv(ctx
, OPC_DMULT
, 0, rx
, ry
);
14845 check_insn(ctx
, ISA_MIPS3
);
14846 check_mips_64(ctx
);
14847 gen_muldiv(ctx
, OPC_DMULTU
, 0, rx
, ry
);
14850 check_insn(ctx
, ISA_MIPS3
);
14851 check_mips_64(ctx
);
14852 gen_muldiv(ctx
, OPC_DDIV
, 0, rx
, ry
);
14855 check_insn(ctx
, ISA_MIPS3
);
14856 check_mips_64(ctx
);
14857 gen_muldiv(ctx
, OPC_DDIVU
, 0, rx
, ry
);
14861 gen_reserved_instruction(ctx
);
14865 case M16_OPC_EXTEND
:
14866 decode_extended_mips16_opc(env
, ctx
);
14869 #if defined(TARGET_MIPS64)
14871 funct
= (ctx
->opcode
>> 8) & 0x7;
14872 decode_i64_mips16(ctx
, ry
, funct
, offset
, 0);
14876 gen_reserved_instruction(ctx
);
14883 /* microMIPS extension to MIPS32/MIPS64 */
14886 * microMIPS32/microMIPS64 major opcodes
14888 * 1. MIPS Architecture for Programmers Volume II-B:
14889 * The microMIPS32 Instruction Set (Revision 3.05)
14891 * Table 6.2 microMIPS32 Encoding of Major Opcode Field
14893 * 2. MIPS Architecture For Programmers Volume II-A:
14894 * The MIPS64 Instruction Set (Revision 3.51)
14924 POOL32S
= 0x16, /* MIPS64 */
14925 DADDIU32
= 0x17, /* MIPS64 */
14954 /* 0x29 is reserved */
14967 /* 0x31 is reserved */
14980 SD32
= 0x36, /* MIPS64 */
14981 LD32
= 0x37, /* MIPS64 */
14983 /* 0x39 is reserved */
14999 /* PCREL Instructions perform PC-Relative address calculation. bits 20..16 */
15021 /* POOL32A encoding of minor opcode field */
15025 * These opcodes are distinguished only by bits 9..6; those bits are
15026 * what are recorded below.
15064 /* The following can be distinguished by their lower 6 bits. */
15074 /* POOL32AXF encoding of minor opcode field extension */
15077 * 1. MIPS Architecture for Programmers Volume II-B:
15078 * The microMIPS32 Instruction Set (Revision 3.05)
15080 * Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
15082 * 2. MIPS Architecture for Programmers VolumeIV-e:
15083 * The MIPS DSP Application-Specific Extension
15084 * to the microMIPS32 Architecture (Revision 2.34)
15086 * Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
15101 /* begin of microMIPS32 DSP */
15103 /* bits 13..12 for 0x01 */
15109 /* bits 13..12 for 0x2a */
15115 /* bits 13..12 for 0x32 */
15119 /* end of microMIPS32 DSP */
15121 /* bits 15..12 for 0x2c */
15138 /* bits 15..12 for 0x34 */
15146 /* bits 15..12 for 0x3c */
15148 JR
= 0x0, /* alias */
15156 /* bits 15..12 for 0x05 */
15160 /* bits 15..12 for 0x0d */
15172 /* bits 15..12 for 0x15 */
15178 /* bits 15..12 for 0x1d */
15182 /* bits 15..12 for 0x2d */
15187 /* bits 15..12 for 0x35 */
15194 /* POOL32B encoding of minor opcode field (bits 15..12) */
15210 /* POOL32C encoding of minor opcode field (bits 15..12) */
15231 /* POOL32C LD-EVA encoding of minor opcode field (bits 11..9) */
15244 /* POOL32C ST-EVA encoding of minor opcode field (bits 11..9) */
15257 /* POOL32F encoding of minor opcode field (bits 5..0) */
15260 /* These are the bit 7..6 values */
15269 /* These are the bit 8..6 values */
15294 MOVZ_FMT_05
= 0x05,
15328 CABS_COND_FMT
= 0x1c, /* MIPS3D */
15335 /* POOL32Fxf encoding of minor opcode extension field */
15373 /* POOL32I encoding of minor opcode field (bits 25..21) */
15403 /* These overlap and are distinguished by bit16 of the instruction */
15412 /* POOL16A encoding of minor opcode field */
15419 /* POOL16B encoding of minor opcode field */
15426 /* POOL16C encoding of minor opcode field */
15446 /* R6 POOL16C encoding of minor opcode field (bits 0..5) */
15470 /* POOL16D encoding of minor opcode field */
15477 /* POOL16E encoding of minor opcode field */
15484 static int mmreg(int r
)
15486 static const int map
[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
15491 /* Used for 16-bit store instructions. */
15492 static int mmreg2(int r
)
15494 static const int map
[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
15499 #define uMIPS_RD(op) ((op >> 7) & 0x7)
15500 #define uMIPS_RS(op) ((op >> 4) & 0x7)
15501 #define uMIPS_RS2(op) uMIPS_RS(op)
15502 #define uMIPS_RS1(op) ((op >> 1) & 0x7)
15503 #define uMIPS_RD5(op) ((op >> 5) & 0x1f)
15504 #define uMIPS_RS5(op) (op & 0x1f)
15506 /* Signed immediate */
15507 #define SIMM(op, start, width) \
15508 ((int32_t)(((op >> start) & ((~0U) >> (32 - width))) \
15511 /* Zero-extended immediate */
15512 #define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32 - width)))
15514 static void gen_addiur1sp(DisasContext
*ctx
)
15516 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
15518 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, 29, ((ctx
->opcode
>> 1) & 0x3f) << 2);
15521 static void gen_addiur2(DisasContext
*ctx
)
15523 static const int decoded_imm
[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
15524 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
15525 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
15527 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, rs
, decoded_imm
[ZIMM(ctx
->opcode
, 1, 3)]);
15530 static void gen_addiusp(DisasContext
*ctx
)
15532 int encoded
= ZIMM(ctx
->opcode
, 1, 9);
15535 if (encoded
<= 1) {
15536 decoded
= 256 + encoded
;
15537 } else if (encoded
<= 255) {
15539 } else if (encoded
<= 509) {
15540 decoded
= encoded
- 512;
15542 decoded
= encoded
- 768;
15545 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, decoded
<< 2);
15548 static void gen_addius5(DisasContext
*ctx
)
15550 int imm
= SIMM(ctx
->opcode
, 1, 4);
15551 int rd
= (ctx
->opcode
>> 5) & 0x1f;
15553 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, rd
, imm
);
15556 static void gen_andi16(DisasContext
*ctx
)
15558 static const int decoded_imm
[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
15559 31, 32, 63, 64, 255, 32768, 65535 };
15560 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
15561 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
15562 int encoded
= ZIMM(ctx
->opcode
, 0, 4);
15564 gen_logic_imm(ctx
, OPC_ANDI
, rd
, rs
, decoded_imm
[encoded
]);
15567 static void gen_ldst_multiple(DisasContext
*ctx
, uint32_t opc
, int reglist
,
15568 int base
, int16_t offset
)
15573 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
15574 gen_reserved_instruction(ctx
);
15578 t0
= tcg_temp_new();
15580 gen_base_offset_addr(ctx
, t0
, base
, offset
);
15582 t1
= tcg_const_tl(reglist
);
15583 t2
= tcg_const_i32(ctx
->mem_idx
);
15585 save_cpu_state(ctx
, 1);
15588 gen_helper_lwm(cpu_env
, t0
, t1
, t2
);
15591 gen_helper_swm(cpu_env
, t0
, t1
, t2
);
15593 #ifdef TARGET_MIPS64
15595 gen_helper_ldm(cpu_env
, t0
, t1
, t2
);
15598 gen_helper_sdm(cpu_env
, t0
, t1
, t2
);
15604 tcg_temp_free_i32(t2
);
15608 static void gen_pool16c_insn(DisasContext
*ctx
)
15610 int rd
= mmreg((ctx
->opcode
>> 3) & 0x7);
15611 int rs
= mmreg(ctx
->opcode
& 0x7);
15613 switch (((ctx
->opcode
) >> 4) & 0x3f) {
15618 gen_logic(ctx
, OPC_NOR
, rd
, rs
, 0);
15624 gen_logic(ctx
, OPC_XOR
, rd
, rd
, rs
);
15630 gen_logic(ctx
, OPC_AND
, rd
, rd
, rs
);
15636 gen_logic(ctx
, OPC_OR
, rd
, rd
, rs
);
15643 static const int lwm_convert
[] = { 0x11, 0x12, 0x13, 0x14 };
15644 int offset
= ZIMM(ctx
->opcode
, 0, 4);
15646 gen_ldst_multiple(ctx
, LWM32
, lwm_convert
[(ctx
->opcode
>> 4) & 0x3],
15655 static const int swm_convert
[] = { 0x11, 0x12, 0x13, 0x14 };
15656 int offset
= ZIMM(ctx
->opcode
, 0, 4);
15658 gen_ldst_multiple(ctx
, SWM32
, swm_convert
[(ctx
->opcode
>> 4) & 0x3],
15665 int reg
= ctx
->opcode
& 0x1f;
15667 gen_compute_branch(ctx
, OPC_JR
, 2, reg
, 0, 0, 4);
15673 int reg
= ctx
->opcode
& 0x1f;
15674 gen_compute_branch(ctx
, OPC_JR
, 2, reg
, 0, 0, 0);
15676 * Let normal delay slot handling in our caller take us
15677 * to the branch target.
15683 gen_compute_branch(ctx
, OPC_JALR
, 2, ctx
->opcode
& 0x1f, 31, 0, 4);
15684 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
15688 gen_compute_branch(ctx
, OPC_JALR
, 2, ctx
->opcode
& 0x1f, 31, 0, 2);
15689 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
15693 gen_HILO(ctx
, OPC_MFHI
, 0, uMIPS_RS5(ctx
->opcode
));
15697 gen_HILO(ctx
, OPC_MFLO
, 0, uMIPS_RS5(ctx
->opcode
));
15700 generate_exception_end(ctx
, EXCP_BREAK
);
15703 if (is_uhi(extract32(ctx
->opcode
, 0, 4))) {
15704 gen_helper_do_semihosting(cpu_env
);
15707 * XXX: not clear which exception should be raised
15708 * when in debug mode...
15710 check_insn(ctx
, ISA_MIPS_R1
);
15711 generate_exception_end(ctx
, EXCP_DBp
);
15714 case JRADDIUSP
+ 0:
15715 case JRADDIUSP
+ 1:
15717 int imm
= ZIMM(ctx
->opcode
, 0, 5);
15718 gen_compute_branch(ctx
, OPC_JR
, 2, 31, 0, 0, 0);
15719 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, imm
<< 2);
15721 * Let normal delay slot handling in our caller take us
15722 * to the branch target.
15727 gen_reserved_instruction(ctx
);
15732 static inline void gen_movep(DisasContext
*ctx
, int enc_dest
, int enc_rt
,
15735 int rd
, rs
, re
, rt
;
15736 static const int rd_enc
[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
15737 static const int re_enc
[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
15738 static const int rs_rt_enc
[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
15739 rd
= rd_enc
[enc_dest
];
15740 re
= re_enc
[enc_dest
];
15741 rs
= rs_rt_enc
[enc_rs
];
15742 rt
= rs_rt_enc
[enc_rt
];
15744 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
15746 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
15749 tcg_gen_mov_tl(cpu_gpr
[re
], cpu_gpr
[rt
]);
15751 tcg_gen_movi_tl(cpu_gpr
[re
], 0);
15755 static void gen_pool16c_r6_insn(DisasContext
*ctx
)
15757 int rt
= mmreg((ctx
->opcode
>> 7) & 0x7);
15758 int rs
= mmreg((ctx
->opcode
>> 4) & 0x7);
15760 switch (ctx
->opcode
& 0xf) {
15762 gen_logic(ctx
, OPC_NOR
, rt
, rs
, 0);
15765 gen_logic(ctx
, OPC_AND
, rt
, rt
, rs
);
15769 int lwm_converted
= 0x11 + extract32(ctx
->opcode
, 8, 2);
15770 int offset
= extract32(ctx
->opcode
, 4, 4);
15771 gen_ldst_multiple(ctx
, LWM32
, lwm_converted
, 29, offset
<< 2);
15774 case R6_JRC16
: /* JRCADDIUSP */
15775 if ((ctx
->opcode
>> 4) & 1) {
15777 int imm
= extract32(ctx
->opcode
, 5, 5);
15778 gen_compute_branch(ctx
, OPC_JR
, 2, 31, 0, 0, 0);
15779 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, imm
<< 2);
15782 rs
= extract32(ctx
->opcode
, 5, 5);
15783 gen_compute_branch(ctx
, OPC_JR
, 2, rs
, 0, 0, 0);
15795 int enc_dest
= uMIPS_RD(ctx
->opcode
);
15796 int enc_rt
= uMIPS_RS2(ctx
->opcode
);
15797 int enc_rs
= (ctx
->opcode
& 3) | ((ctx
->opcode
>> 1) & 4);
15798 gen_movep(ctx
, enc_dest
, enc_rt
, enc_rs
);
15802 gen_logic(ctx
, OPC_XOR
, rt
, rt
, rs
);
15805 gen_logic(ctx
, OPC_OR
, rt
, rt
, rs
);
15809 int swm_converted
= 0x11 + extract32(ctx
->opcode
, 8, 2);
15810 int offset
= extract32(ctx
->opcode
, 4, 4);
15811 gen_ldst_multiple(ctx
, SWM32
, swm_converted
, 29, offset
<< 2);
15814 case JALRC16
: /* BREAK16, SDBBP16 */
15815 switch (ctx
->opcode
& 0x3f) {
15817 case JALRC16
+ 0x20:
15819 gen_compute_branch(ctx
, OPC_JALR
, 2, (ctx
->opcode
>> 5) & 0x1f,
15824 generate_exception(ctx
, EXCP_BREAK
);
15828 if (is_uhi(extract32(ctx
->opcode
, 6, 4))) {
15829 gen_helper_do_semihosting(cpu_env
);
15831 if (ctx
->hflags
& MIPS_HFLAG_SBRI
) {
15832 generate_exception(ctx
, EXCP_RI
);
15834 generate_exception(ctx
, EXCP_DBp
);
15841 generate_exception(ctx
, EXCP_RI
);
15846 static void gen_ldxs(DisasContext
*ctx
, int base
, int index
, int rd
)
15848 TCGv t0
= tcg_temp_new();
15849 TCGv t1
= tcg_temp_new();
15851 gen_load_gpr(t0
, base
);
15854 gen_load_gpr(t1
, index
);
15855 tcg_gen_shli_tl(t1
, t1
, 2);
15856 gen_op_addr_add(ctx
, t0
, t1
, t0
);
15859 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TESL
);
15860 gen_store_gpr(t1
, rd
);
15866 static void gen_ldst_pair(DisasContext
*ctx
, uint32_t opc
, int rd
,
15867 int base
, int16_t offset
)
15871 if (ctx
->hflags
& MIPS_HFLAG_BMASK
|| rd
== 31) {
15872 gen_reserved_instruction(ctx
);
15876 t0
= tcg_temp_new();
15877 t1
= tcg_temp_new();
15879 gen_base_offset_addr(ctx
, t0
, base
, offset
);
15884 gen_reserved_instruction(ctx
);
15887 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TESL
);
15888 gen_store_gpr(t1
, rd
);
15889 tcg_gen_movi_tl(t1
, 4);
15890 gen_op_addr_add(ctx
, t0
, t0
, t1
);
15891 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TESL
);
15892 gen_store_gpr(t1
, rd
+ 1);
15895 gen_load_gpr(t1
, rd
);
15896 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
15897 tcg_gen_movi_tl(t1
, 4);
15898 gen_op_addr_add(ctx
, t0
, t0
, t1
);
15899 gen_load_gpr(t1
, rd
+ 1);
15900 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
15902 #ifdef TARGET_MIPS64
15905 gen_reserved_instruction(ctx
);
15908 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
15909 gen_store_gpr(t1
, rd
);
15910 tcg_gen_movi_tl(t1
, 8);
15911 gen_op_addr_add(ctx
, t0
, t0
, t1
);
15912 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
15913 gen_store_gpr(t1
, rd
+ 1);
15916 gen_load_gpr(t1
, rd
);
15917 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
15918 tcg_gen_movi_tl(t1
, 8);
15919 gen_op_addr_add(ctx
, t0
, t0
, t1
);
15920 gen_load_gpr(t1
, rd
+ 1);
15921 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
15929 static void gen_sync(int stype
)
15931 TCGBar tcg_mo
= TCG_BAR_SC
;
15934 case 0x4: /* SYNC_WMB */
15935 tcg_mo
|= TCG_MO_ST_ST
;
15937 case 0x10: /* SYNC_MB */
15938 tcg_mo
|= TCG_MO_ALL
;
15940 case 0x11: /* SYNC_ACQUIRE */
15941 tcg_mo
|= TCG_MO_LD_LD
| TCG_MO_LD_ST
;
15943 case 0x12: /* SYNC_RELEASE */
15944 tcg_mo
|= TCG_MO_ST_ST
| TCG_MO_LD_ST
;
15946 case 0x13: /* SYNC_RMB */
15947 tcg_mo
|= TCG_MO_LD_LD
;
15950 tcg_mo
|= TCG_MO_ALL
;
15954 tcg_gen_mb(tcg_mo
);
15957 static void gen_pool32axf(CPUMIPSState
*env
, DisasContext
*ctx
, int rt
, int rs
)
15959 int extension
= (ctx
->opcode
>> 6) & 0x3f;
15960 int minor
= (ctx
->opcode
>> 12) & 0xf;
15961 uint32_t mips32_op
;
15963 switch (extension
) {
15965 mips32_op
= OPC_TEQ
;
15968 mips32_op
= OPC_TGE
;
15971 mips32_op
= OPC_TGEU
;
15974 mips32_op
= OPC_TLT
;
15977 mips32_op
= OPC_TLTU
;
15980 mips32_op
= OPC_TNE
;
15982 gen_trap(ctx
, mips32_op
, rs
, rt
, -1);
15984 #ifndef CONFIG_USER_ONLY
15987 check_cp0_enabled(ctx
);
15989 /* Treat as NOP. */
15992 gen_mfc0(ctx
, cpu_gpr
[rt
], rs
, (ctx
->opcode
>> 11) & 0x7);
15996 check_cp0_enabled(ctx
);
15998 TCGv t0
= tcg_temp_new();
16000 gen_load_gpr(t0
, rt
);
16001 gen_mtc0(ctx
, t0
, rs
, (ctx
->opcode
>> 11) & 0x7);
16007 switch (minor
& 3) {
16009 gen_muldiv(ctx
, OPC_MADD
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
16012 gen_muldiv(ctx
, OPC_MADDU
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
16015 gen_muldiv(ctx
, OPC_MSUB
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
16018 gen_muldiv(ctx
, OPC_MSUBU
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
16021 goto pool32axf_invalid
;
16025 switch (minor
& 3) {
16027 gen_muldiv(ctx
, OPC_MULT
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
16030 gen_muldiv(ctx
, OPC_MULTU
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
16033 goto pool32axf_invalid
;
16039 check_insn(ctx
, ISA_MIPS_R6
);
16040 gen_bitswap(ctx
, OPC_BITSWAP
, rs
, rt
);
16043 gen_bshfl(ctx
, OPC_SEB
, rs
, rt
);
16046 gen_bshfl(ctx
, OPC_SEH
, rs
, rt
);
16049 mips32_op
= OPC_CLO
;
16052 mips32_op
= OPC_CLZ
;
16054 check_insn(ctx
, ISA_MIPS_R1
);
16055 gen_cl(ctx
, mips32_op
, rt
, rs
);
16058 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16059 gen_rdhwr(ctx
, rt
, rs
, 0);
16062 gen_bshfl(ctx
, OPC_WSBH
, rs
, rt
);
16065 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16066 mips32_op
= OPC_MULT
;
16069 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16070 mips32_op
= OPC_MULTU
;
16073 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16074 mips32_op
= OPC_DIV
;
16077 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16078 mips32_op
= OPC_DIVU
;
16081 check_insn(ctx
, ISA_MIPS_R1
);
16082 gen_muldiv(ctx
, mips32_op
, 0, rs
, rt
);
16085 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16086 mips32_op
= OPC_MADD
;
16089 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16090 mips32_op
= OPC_MADDU
;
16093 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16094 mips32_op
= OPC_MSUB
;
16097 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16098 mips32_op
= OPC_MSUBU
;
16100 check_insn(ctx
, ISA_MIPS_R1
);
16101 gen_muldiv(ctx
, mips32_op
, 0, rs
, rt
);
16104 goto pool32axf_invalid
;
16115 generate_exception_err(ctx
, EXCP_CpU
, 2);
16118 goto pool32axf_invalid
;
16123 case JALR
: /* JALRC */
16124 case JALR_HB
: /* JALRC_HB */
16125 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16126 /* JALRC, JALRC_HB */
16127 gen_compute_branch(ctx
, OPC_JALR
, 4, rs
, rt
, 0, 0);
16129 /* JALR, JALR_HB */
16130 gen_compute_branch(ctx
, OPC_JALR
, 4, rs
, rt
, 0, 4);
16131 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
16136 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16137 gen_compute_branch(ctx
, OPC_JALR
, 4, rs
, rt
, 0, 2);
16138 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
16141 goto pool32axf_invalid
;
16147 check_cp0_enabled(ctx
);
16148 check_insn(ctx
, ISA_MIPS_R2
);
16149 gen_load_srsgpr(rs
, rt
);
16152 check_cp0_enabled(ctx
);
16153 check_insn(ctx
, ISA_MIPS_R2
);
16154 gen_store_srsgpr(rs
, rt
);
16157 goto pool32axf_invalid
;
16160 #ifndef CONFIG_USER_ONLY
16164 mips32_op
= OPC_TLBP
;
16167 mips32_op
= OPC_TLBR
;
16170 mips32_op
= OPC_TLBWI
;
16173 mips32_op
= OPC_TLBWR
;
16176 mips32_op
= OPC_TLBINV
;
16179 mips32_op
= OPC_TLBINVF
;
16182 mips32_op
= OPC_WAIT
;
16185 mips32_op
= OPC_DERET
;
16188 mips32_op
= OPC_ERET
;
16190 gen_cp0(env
, ctx
, mips32_op
, rt
, rs
);
16193 goto pool32axf_invalid
;
16199 check_cp0_enabled(ctx
);
16201 TCGv t0
= tcg_temp_new();
16203 save_cpu_state(ctx
, 1);
16204 gen_helper_di(t0
, cpu_env
);
16205 gen_store_gpr(t0
, rs
);
16207 * Stop translation as we may have switched the execution
16210 ctx
->base
.is_jmp
= DISAS_STOP
;
16215 check_cp0_enabled(ctx
);
16217 TCGv t0
= tcg_temp_new();
16219 save_cpu_state(ctx
, 1);
16220 gen_helper_ei(t0
, cpu_env
);
16221 gen_store_gpr(t0
, rs
);
16223 * DISAS_STOP isn't sufficient, we need to ensure we break out
16224 * of translated code to check for pending interrupts.
16226 gen_save_pc(ctx
->base
.pc_next
+ 4);
16227 ctx
->base
.is_jmp
= DISAS_EXIT
;
16232 goto pool32axf_invalid
;
16239 gen_sync(extract32(ctx
->opcode
, 16, 5));
16242 generate_exception_end(ctx
, EXCP_SYSCALL
);
16245 if (is_uhi(extract32(ctx
->opcode
, 16, 10))) {
16246 gen_helper_do_semihosting(cpu_env
);
16248 check_insn(ctx
, ISA_MIPS_R1
);
16249 if (ctx
->hflags
& MIPS_HFLAG_SBRI
) {
16250 gen_reserved_instruction(ctx
);
16252 generate_exception_end(ctx
, EXCP_DBp
);
16257 goto pool32axf_invalid
;
16261 switch (minor
& 3) {
16263 gen_HILO(ctx
, OPC_MFHI
, minor
>> 2, rs
);
16266 gen_HILO(ctx
, OPC_MFLO
, minor
>> 2, rs
);
16269 gen_HILO(ctx
, OPC_MTHI
, minor
>> 2, rs
);
16272 gen_HILO(ctx
, OPC_MTLO
, minor
>> 2, rs
);
16275 goto pool32axf_invalid
;
16279 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16282 gen_HILO(ctx
, OPC_MFHI
, 0, rs
);
16285 gen_HILO(ctx
, OPC_MFLO
, 0, rs
);
16288 gen_HILO(ctx
, OPC_MTHI
, 0, rs
);
16291 gen_HILO(ctx
, OPC_MTLO
, 0, rs
);
16294 goto pool32axf_invalid
;
16299 MIPS_INVAL("pool32axf");
16300 gen_reserved_instruction(ctx
);
16306 * Values for microMIPS fmt field. Variable-width, depending on which
16307 * formats the instruction supports.
16326 static void gen_pool32fxf(DisasContext
*ctx
, int rt
, int rs
)
16328 int extension
= (ctx
->opcode
>> 6) & 0x3ff;
16329 uint32_t mips32_op
;
16331 #define FLOAT_1BIT_FMT(opc, fmt) ((fmt << 8) | opc)
16332 #define FLOAT_2BIT_FMT(opc, fmt) ((fmt << 7) | opc)
16333 #define COND_FLOAT_MOV(opc, cond) ((cond << 7) | opc)
16335 switch (extension
) {
16336 case FLOAT_1BIT_FMT(CFC1
, 0):
16337 mips32_op
= OPC_CFC1
;
16339 case FLOAT_1BIT_FMT(CTC1
, 0):
16340 mips32_op
= OPC_CTC1
;
16342 case FLOAT_1BIT_FMT(MFC1
, 0):
16343 mips32_op
= OPC_MFC1
;
16345 case FLOAT_1BIT_FMT(MTC1
, 0):
16346 mips32_op
= OPC_MTC1
;
16348 case FLOAT_1BIT_FMT(MFHC1
, 0):
16349 mips32_op
= OPC_MFHC1
;
16351 case FLOAT_1BIT_FMT(MTHC1
, 0):
16352 mips32_op
= OPC_MTHC1
;
16354 gen_cp1(ctx
, mips32_op
, rt
, rs
);
16357 /* Reciprocal square root */
16358 case FLOAT_1BIT_FMT(RSQRT_FMT
, FMT_SD_S
):
16359 mips32_op
= OPC_RSQRT_S
;
16361 case FLOAT_1BIT_FMT(RSQRT_FMT
, FMT_SD_D
):
16362 mips32_op
= OPC_RSQRT_D
;
16366 case FLOAT_1BIT_FMT(SQRT_FMT
, FMT_SD_S
):
16367 mips32_op
= OPC_SQRT_S
;
16369 case FLOAT_1BIT_FMT(SQRT_FMT
, FMT_SD_D
):
16370 mips32_op
= OPC_SQRT_D
;
16374 case FLOAT_1BIT_FMT(RECIP_FMT
, FMT_SD_S
):
16375 mips32_op
= OPC_RECIP_S
;
16377 case FLOAT_1BIT_FMT(RECIP_FMT
, FMT_SD_D
):
16378 mips32_op
= OPC_RECIP_D
;
16382 case FLOAT_1BIT_FMT(FLOOR_L
, FMT_SD_S
):
16383 mips32_op
= OPC_FLOOR_L_S
;
16385 case FLOAT_1BIT_FMT(FLOOR_L
, FMT_SD_D
):
16386 mips32_op
= OPC_FLOOR_L_D
;
16388 case FLOAT_1BIT_FMT(FLOOR_W
, FMT_SD_S
):
16389 mips32_op
= OPC_FLOOR_W_S
;
16391 case FLOAT_1BIT_FMT(FLOOR_W
, FMT_SD_D
):
16392 mips32_op
= OPC_FLOOR_W_D
;
16396 case FLOAT_1BIT_FMT(CEIL_L
, FMT_SD_S
):
16397 mips32_op
= OPC_CEIL_L_S
;
16399 case FLOAT_1BIT_FMT(CEIL_L
, FMT_SD_D
):
16400 mips32_op
= OPC_CEIL_L_D
;
16402 case FLOAT_1BIT_FMT(CEIL_W
, FMT_SD_S
):
16403 mips32_op
= OPC_CEIL_W_S
;
16405 case FLOAT_1BIT_FMT(CEIL_W
, FMT_SD_D
):
16406 mips32_op
= OPC_CEIL_W_D
;
16410 case FLOAT_1BIT_FMT(TRUNC_L
, FMT_SD_S
):
16411 mips32_op
= OPC_TRUNC_L_S
;
16413 case FLOAT_1BIT_FMT(TRUNC_L
, FMT_SD_D
):
16414 mips32_op
= OPC_TRUNC_L_D
;
16416 case FLOAT_1BIT_FMT(TRUNC_W
, FMT_SD_S
):
16417 mips32_op
= OPC_TRUNC_W_S
;
16419 case FLOAT_1BIT_FMT(TRUNC_W
, FMT_SD_D
):
16420 mips32_op
= OPC_TRUNC_W_D
;
16424 case FLOAT_1BIT_FMT(ROUND_L
, FMT_SD_S
):
16425 mips32_op
= OPC_ROUND_L_S
;
16427 case FLOAT_1BIT_FMT(ROUND_L
, FMT_SD_D
):
16428 mips32_op
= OPC_ROUND_L_D
;
16430 case FLOAT_1BIT_FMT(ROUND_W
, FMT_SD_S
):
16431 mips32_op
= OPC_ROUND_W_S
;
16433 case FLOAT_1BIT_FMT(ROUND_W
, FMT_SD_D
):
16434 mips32_op
= OPC_ROUND_W_D
;
16437 /* Integer to floating-point conversion */
16438 case FLOAT_1BIT_FMT(CVT_L
, FMT_SD_S
):
16439 mips32_op
= OPC_CVT_L_S
;
16441 case FLOAT_1BIT_FMT(CVT_L
, FMT_SD_D
):
16442 mips32_op
= OPC_CVT_L_D
;
16444 case FLOAT_1BIT_FMT(CVT_W
, FMT_SD_S
):
16445 mips32_op
= OPC_CVT_W_S
;
16447 case FLOAT_1BIT_FMT(CVT_W
, FMT_SD_D
):
16448 mips32_op
= OPC_CVT_W_D
;
16451 /* Paired-foo conversions */
16452 case FLOAT_1BIT_FMT(CVT_S_PL
, 0):
16453 mips32_op
= OPC_CVT_S_PL
;
16455 case FLOAT_1BIT_FMT(CVT_S_PU
, 0):
16456 mips32_op
= OPC_CVT_S_PU
;
16458 case FLOAT_1BIT_FMT(CVT_PW_PS
, 0):
16459 mips32_op
= OPC_CVT_PW_PS
;
16461 case FLOAT_1BIT_FMT(CVT_PS_PW
, 0):
16462 mips32_op
= OPC_CVT_PS_PW
;
16465 /* Floating-point moves */
16466 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_S
):
16467 mips32_op
= OPC_MOV_S
;
16469 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_D
):
16470 mips32_op
= OPC_MOV_D
;
16472 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_PS
):
16473 mips32_op
= OPC_MOV_PS
;
16476 /* Absolute value */
16477 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_S
):
16478 mips32_op
= OPC_ABS_S
;
16480 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_D
):
16481 mips32_op
= OPC_ABS_D
;
16483 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_PS
):
16484 mips32_op
= OPC_ABS_PS
;
16488 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_S
):
16489 mips32_op
= OPC_NEG_S
;
16491 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_D
):
16492 mips32_op
= OPC_NEG_D
;
16494 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_PS
):
16495 mips32_op
= OPC_NEG_PS
;
16498 /* Reciprocal square root step */
16499 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_S
):
16500 mips32_op
= OPC_RSQRT1_S
;
16502 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_D
):
16503 mips32_op
= OPC_RSQRT1_D
;
16505 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_PS
):
16506 mips32_op
= OPC_RSQRT1_PS
;
16509 /* Reciprocal step */
16510 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_S
):
16511 mips32_op
= OPC_RECIP1_S
;
16513 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_D
):
16514 mips32_op
= OPC_RECIP1_S
;
16516 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_PS
):
16517 mips32_op
= OPC_RECIP1_PS
;
16520 /* Conversions from double */
16521 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_S
):
16522 mips32_op
= OPC_CVT_D_S
;
16524 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_W
):
16525 mips32_op
= OPC_CVT_D_W
;
16527 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_L
):
16528 mips32_op
= OPC_CVT_D_L
;
16531 /* Conversions from single */
16532 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_D
):
16533 mips32_op
= OPC_CVT_S_D
;
16535 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_W
):
16536 mips32_op
= OPC_CVT_S_W
;
16538 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_L
):
16539 mips32_op
= OPC_CVT_S_L
;
16541 gen_farith(ctx
, mips32_op
, -1, rs
, rt
, 0);
16544 /* Conditional moves on floating-point codes */
16545 case COND_FLOAT_MOV(MOVT
, 0):
16546 case COND_FLOAT_MOV(MOVT
, 1):
16547 case COND_FLOAT_MOV(MOVT
, 2):
16548 case COND_FLOAT_MOV(MOVT
, 3):
16549 case COND_FLOAT_MOV(MOVT
, 4):
16550 case COND_FLOAT_MOV(MOVT
, 5):
16551 case COND_FLOAT_MOV(MOVT
, 6):
16552 case COND_FLOAT_MOV(MOVT
, 7):
16553 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16554 gen_movci(ctx
, rt
, rs
, (ctx
->opcode
>> 13) & 0x7, 1);
16556 case COND_FLOAT_MOV(MOVF
, 0):
16557 case COND_FLOAT_MOV(MOVF
, 1):
16558 case COND_FLOAT_MOV(MOVF
, 2):
16559 case COND_FLOAT_MOV(MOVF
, 3):
16560 case COND_FLOAT_MOV(MOVF
, 4):
16561 case COND_FLOAT_MOV(MOVF
, 5):
16562 case COND_FLOAT_MOV(MOVF
, 6):
16563 case COND_FLOAT_MOV(MOVF
, 7):
16564 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16565 gen_movci(ctx
, rt
, rs
, (ctx
->opcode
>> 13) & 0x7, 0);
16568 MIPS_INVAL("pool32fxf");
16569 gen_reserved_instruction(ctx
);
16574 static void decode_micromips32_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
16578 int rt
, rs
, rd
, rr
;
16580 uint32_t op
, minor
, minor2
, mips32_op
;
16581 uint32_t cond
, fmt
, cc
;
16583 insn
= cpu_lduw_code(env
, ctx
->base
.pc_next
+ 2);
16584 ctx
->opcode
= (ctx
->opcode
<< 16) | insn
;
16586 rt
= (ctx
->opcode
>> 21) & 0x1f;
16587 rs
= (ctx
->opcode
>> 16) & 0x1f;
16588 rd
= (ctx
->opcode
>> 11) & 0x1f;
16589 rr
= (ctx
->opcode
>> 6) & 0x1f;
16590 imm
= (int16_t) ctx
->opcode
;
16592 op
= (ctx
->opcode
>> 26) & 0x3f;
16595 minor
= ctx
->opcode
& 0x3f;
16598 minor
= (ctx
->opcode
>> 6) & 0xf;
16601 mips32_op
= OPC_SLL
;
16604 mips32_op
= OPC_SRA
;
16607 mips32_op
= OPC_SRL
;
16610 mips32_op
= OPC_ROTR
;
16612 gen_shift_imm(ctx
, mips32_op
, rt
, rs
, rd
);
16615 check_insn(ctx
, ISA_MIPS_R6
);
16616 gen_cond_move(ctx
, OPC_SELEQZ
, rd
, rs
, rt
);
16619 check_insn(ctx
, ISA_MIPS_R6
);
16620 gen_cond_move(ctx
, OPC_SELNEZ
, rd
, rs
, rt
);
16623 check_insn(ctx
, ISA_MIPS_R6
);
16624 gen_rdhwr(ctx
, rt
, rs
, extract32(ctx
->opcode
, 11, 3));
16627 goto pool32a_invalid
;
16631 minor
= (ctx
->opcode
>> 6) & 0xf;
16635 mips32_op
= OPC_ADD
;
16638 mips32_op
= OPC_ADDU
;
16641 mips32_op
= OPC_SUB
;
16644 mips32_op
= OPC_SUBU
;
16647 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16648 mips32_op
= OPC_MUL
;
16650 gen_arith(ctx
, mips32_op
, rd
, rs
, rt
);
16654 mips32_op
= OPC_SLLV
;
16657 mips32_op
= OPC_SRLV
;
16660 mips32_op
= OPC_SRAV
;
16663 mips32_op
= OPC_ROTRV
;
16665 gen_shift(ctx
, mips32_op
, rd
, rs
, rt
);
16667 /* Logical operations */
16669 mips32_op
= OPC_AND
;
16672 mips32_op
= OPC_OR
;
16675 mips32_op
= OPC_NOR
;
16678 mips32_op
= OPC_XOR
;
16680 gen_logic(ctx
, mips32_op
, rd
, rs
, rt
);
16682 /* Set less than */
16684 mips32_op
= OPC_SLT
;
16687 mips32_op
= OPC_SLTU
;
16689 gen_slt(ctx
, mips32_op
, rd
, rs
, rt
);
16692 goto pool32a_invalid
;
16696 minor
= (ctx
->opcode
>> 6) & 0xf;
16698 /* Conditional moves */
16699 case MOVN
: /* MUL */
16700 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16702 gen_r6_muldiv(ctx
, R6_OPC_MUL
, rd
, rs
, rt
);
16705 gen_cond_move(ctx
, OPC_MOVN
, rd
, rs
, rt
);
16708 case MOVZ
: /* MUH */
16709 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16711 gen_r6_muldiv(ctx
, R6_OPC_MUH
, rd
, rs
, rt
);
16714 gen_cond_move(ctx
, OPC_MOVZ
, rd
, rs
, rt
);
16718 check_insn(ctx
, ISA_MIPS_R6
);
16719 gen_r6_muldiv(ctx
, R6_OPC_MULU
, rd
, rs
, rt
);
16722 check_insn(ctx
, ISA_MIPS_R6
);
16723 gen_r6_muldiv(ctx
, R6_OPC_MUHU
, rd
, rs
, rt
);
16725 case LWXS
: /* DIV */
16726 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16728 gen_r6_muldiv(ctx
, R6_OPC_DIV
, rd
, rs
, rt
);
16731 gen_ldxs(ctx
, rs
, rt
, rd
);
16735 check_insn(ctx
, ISA_MIPS_R6
);
16736 gen_r6_muldiv(ctx
, R6_OPC_MOD
, rd
, rs
, rt
);
16739 check_insn(ctx
, ISA_MIPS_R6
);
16740 gen_r6_muldiv(ctx
, R6_OPC_DIVU
, rd
, rs
, rt
);
16743 check_insn(ctx
, ISA_MIPS_R6
);
16744 gen_r6_muldiv(ctx
, R6_OPC_MODU
, rd
, rs
, rt
);
16747 goto pool32a_invalid
;
16751 gen_bitops(ctx
, OPC_INS
, rt
, rs
, rr
, rd
);
16754 check_insn(ctx
, ISA_MIPS_R6
);
16755 gen_lsa(ctx
, OPC_LSA
, rd
, rs
, rt
,
16756 extract32(ctx
->opcode
, 9, 2));
16759 check_insn(ctx
, ISA_MIPS_R6
);
16760 gen_align(ctx
, 32, rd
, rs
, rt
, extract32(ctx
->opcode
, 9, 2));
16763 gen_bitops(ctx
, OPC_EXT
, rt
, rs
, rr
, rd
);
16766 gen_pool32axf(env
, ctx
, rt
, rs
);
16769 generate_exception_end(ctx
, EXCP_BREAK
);
16772 check_insn(ctx
, ISA_MIPS_R6
);
16773 gen_reserved_instruction(ctx
);
16777 MIPS_INVAL("pool32a");
16778 gen_reserved_instruction(ctx
);
16783 minor
= (ctx
->opcode
>> 12) & 0xf;
16786 check_cp0_enabled(ctx
);
16787 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
16788 gen_cache_operation(ctx
, rt
, rs
, imm
);
16793 /* COP2: Not implemented. */
16794 generate_exception_err(ctx
, EXCP_CpU
, 2);
16796 #ifdef TARGET_MIPS64
16799 check_insn(ctx
, ISA_MIPS3
);
16800 check_mips_64(ctx
);
16805 gen_ldst_pair(ctx
, minor
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
16807 #ifdef TARGET_MIPS64
16810 check_insn(ctx
, ISA_MIPS3
);
16811 check_mips_64(ctx
);
16816 gen_ldst_multiple(ctx
, minor
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
16819 MIPS_INVAL("pool32b");
16820 gen_reserved_instruction(ctx
);
16825 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
16826 minor
= ctx
->opcode
& 0x3f;
16827 check_cp1_enabled(ctx
);
16830 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16831 mips32_op
= OPC_ALNV_PS
;
16834 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16835 mips32_op
= OPC_MADD_S
;
16838 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16839 mips32_op
= OPC_MADD_D
;
16842 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16843 mips32_op
= OPC_MADD_PS
;
16846 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16847 mips32_op
= OPC_MSUB_S
;
16850 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16851 mips32_op
= OPC_MSUB_D
;
16854 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16855 mips32_op
= OPC_MSUB_PS
;
16858 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16859 mips32_op
= OPC_NMADD_S
;
16862 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16863 mips32_op
= OPC_NMADD_D
;
16866 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16867 mips32_op
= OPC_NMADD_PS
;
16870 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16871 mips32_op
= OPC_NMSUB_S
;
16874 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16875 mips32_op
= OPC_NMSUB_D
;
16878 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16879 mips32_op
= OPC_NMSUB_PS
;
16881 gen_flt3_arith(ctx
, mips32_op
, rd
, rr
, rs
, rt
);
16883 case CABS_COND_FMT
:
16884 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16885 cond
= (ctx
->opcode
>> 6) & 0xf;
16886 cc
= (ctx
->opcode
>> 13) & 0x7;
16887 fmt
= (ctx
->opcode
>> 10) & 0x3;
16890 gen_cmpabs_s(ctx
, cond
, rt
, rs
, cc
);
16893 gen_cmpabs_d(ctx
, cond
, rt
, rs
, cc
);
16896 gen_cmpabs_ps(ctx
, cond
, rt
, rs
, cc
);
16899 goto pool32f_invalid
;
16903 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16904 cond
= (ctx
->opcode
>> 6) & 0xf;
16905 cc
= (ctx
->opcode
>> 13) & 0x7;
16906 fmt
= (ctx
->opcode
>> 10) & 0x3;
16909 gen_cmp_s(ctx
, cond
, rt
, rs
, cc
);
16912 gen_cmp_d(ctx
, cond
, rt
, rs
, cc
);
16915 gen_cmp_ps(ctx
, cond
, rt
, rs
, cc
);
16918 goto pool32f_invalid
;
16922 check_insn(ctx
, ISA_MIPS_R6
);
16923 gen_r6_cmp_s(ctx
, (ctx
->opcode
>> 6) & 0x1f, rt
, rs
, rd
);
16926 check_insn(ctx
, ISA_MIPS_R6
);
16927 gen_r6_cmp_d(ctx
, (ctx
->opcode
>> 6) & 0x1f, rt
, rs
, rd
);
16930 gen_pool32fxf(ctx
, rt
, rs
);
16934 switch ((ctx
->opcode
>> 6) & 0x7) {
16936 mips32_op
= OPC_PLL_PS
;
16939 mips32_op
= OPC_PLU_PS
;
16942 mips32_op
= OPC_PUL_PS
;
16945 mips32_op
= OPC_PUU_PS
;
16948 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16949 mips32_op
= OPC_CVT_PS_S
;
16951 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
16954 goto pool32f_invalid
;
16958 check_insn(ctx
, ISA_MIPS_R6
);
16959 switch ((ctx
->opcode
>> 9) & 0x3) {
16961 gen_farith(ctx
, OPC_MIN_S
, rt
, rs
, rd
, 0);
16964 gen_farith(ctx
, OPC_MIN_D
, rt
, rs
, rd
, 0);
16967 goto pool32f_invalid
;
16972 switch ((ctx
->opcode
>> 6) & 0x7) {
16974 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16975 mips32_op
= OPC_LWXC1
;
16978 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16979 mips32_op
= OPC_SWXC1
;
16982 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16983 mips32_op
= OPC_LDXC1
;
16986 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16987 mips32_op
= OPC_SDXC1
;
16990 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16991 mips32_op
= OPC_LUXC1
;
16994 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16995 mips32_op
= OPC_SUXC1
;
16997 gen_flt3_ldst(ctx
, mips32_op
, rd
, rd
, rt
, rs
);
17000 goto pool32f_invalid
;
17004 check_insn(ctx
, ISA_MIPS_R6
);
17005 switch ((ctx
->opcode
>> 9) & 0x3) {
17007 gen_farith(ctx
, OPC_MAX_S
, rt
, rs
, rd
, 0);
17010 gen_farith(ctx
, OPC_MAX_D
, rt
, rs
, rd
, 0);
17013 goto pool32f_invalid
;
17018 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17019 fmt
= (ctx
->opcode
>> 9) & 0x3;
17020 switch ((ctx
->opcode
>> 6) & 0x7) {
17024 mips32_op
= OPC_RSQRT2_S
;
17027 mips32_op
= OPC_RSQRT2_D
;
17030 mips32_op
= OPC_RSQRT2_PS
;
17033 goto pool32f_invalid
;
17039 mips32_op
= OPC_RECIP2_S
;
17042 mips32_op
= OPC_RECIP2_D
;
17045 mips32_op
= OPC_RECIP2_PS
;
17048 goto pool32f_invalid
;
17052 mips32_op
= OPC_ADDR_PS
;
17055 mips32_op
= OPC_MULR_PS
;
17057 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
17060 goto pool32f_invalid
;
17064 /* MOV[FT].fmt, PREFX, RINT.fmt, CLASS.fmt*/
17065 cc
= (ctx
->opcode
>> 13) & 0x7;
17066 fmt
= (ctx
->opcode
>> 9) & 0x3;
17067 switch ((ctx
->opcode
>> 6) & 0x7) {
17068 case MOVF_FMT
: /* RINT_FMT */
17069 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
17073 gen_farith(ctx
, OPC_RINT_S
, 0, rt
, rs
, 0);
17076 gen_farith(ctx
, OPC_RINT_D
, 0, rt
, rs
, 0);
17079 goto pool32f_invalid
;
17085 gen_movcf_s(ctx
, rs
, rt
, cc
, 0);
17088 gen_movcf_d(ctx
, rs
, rt
, cc
, 0);
17092 gen_movcf_ps(ctx
, rs
, rt
, cc
, 0);
17095 goto pool32f_invalid
;
17099 case MOVT_FMT
: /* CLASS_FMT */
17100 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
17104 gen_farith(ctx
, OPC_CLASS_S
, 0, rt
, rs
, 0);
17107 gen_farith(ctx
, OPC_CLASS_D
, 0, rt
, rs
, 0);
17110 goto pool32f_invalid
;
17116 gen_movcf_s(ctx
, rs
, rt
, cc
, 1);
17119 gen_movcf_d(ctx
, rs
, rt
, cc
, 1);
17123 gen_movcf_ps(ctx
, rs
, rt
, cc
, 1);
17126 goto pool32f_invalid
;
17131 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17134 goto pool32f_invalid
;
17137 #define FINSN_3ARG_SDPS(prfx) \
17138 switch ((ctx->opcode >> 8) & 0x3) { \
17140 mips32_op = OPC_##prfx##_S; \
17143 mips32_op = OPC_##prfx##_D; \
17145 case FMT_SDPS_PS: \
17147 mips32_op = OPC_##prfx##_PS; \
17150 goto pool32f_invalid; \
17153 check_insn(ctx
, ISA_MIPS_R6
);
17154 switch ((ctx
->opcode
>> 9) & 0x3) {
17156 gen_farith(ctx
, OPC_MINA_S
, rt
, rs
, rd
, 0);
17159 gen_farith(ctx
, OPC_MINA_D
, rt
, rs
, rd
, 0);
17162 goto pool32f_invalid
;
17166 check_insn(ctx
, ISA_MIPS_R6
);
17167 switch ((ctx
->opcode
>> 9) & 0x3) {
17169 gen_farith(ctx
, OPC_MAXA_S
, rt
, rs
, rd
, 0);
17172 gen_farith(ctx
, OPC_MAXA_D
, rt
, rs
, rd
, 0);
17175 goto pool32f_invalid
;
17179 /* regular FP ops */
17180 switch ((ctx
->opcode
>> 6) & 0x3) {
17182 FINSN_3ARG_SDPS(ADD
);
17185 FINSN_3ARG_SDPS(SUB
);
17188 FINSN_3ARG_SDPS(MUL
);
17191 fmt
= (ctx
->opcode
>> 8) & 0x3;
17193 mips32_op
= OPC_DIV_D
;
17194 } else if (fmt
== 0) {
17195 mips32_op
= OPC_DIV_S
;
17197 goto pool32f_invalid
;
17201 goto pool32f_invalid
;
17206 switch ((ctx
->opcode
>> 6) & 0x7) {
17207 case MOVN_FMT
: /* SELEQZ_FMT */
17208 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
17210 switch ((ctx
->opcode
>> 9) & 0x3) {
17212 gen_sel_s(ctx
, OPC_SELEQZ_S
, rd
, rt
, rs
);
17215 gen_sel_d(ctx
, OPC_SELEQZ_D
, rd
, rt
, rs
);
17218 goto pool32f_invalid
;
17222 FINSN_3ARG_SDPS(MOVN
);
17226 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17227 FINSN_3ARG_SDPS(MOVN
);
17229 case MOVZ_FMT
: /* SELNEZ_FMT */
17230 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
17232 switch ((ctx
->opcode
>> 9) & 0x3) {
17234 gen_sel_s(ctx
, OPC_SELNEZ_S
, rd
, rt
, rs
);
17237 gen_sel_d(ctx
, OPC_SELNEZ_D
, rd
, rt
, rs
);
17240 goto pool32f_invalid
;
17244 FINSN_3ARG_SDPS(MOVZ
);
17248 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17249 FINSN_3ARG_SDPS(MOVZ
);
17252 check_insn(ctx
, ISA_MIPS_R6
);
17253 switch ((ctx
->opcode
>> 9) & 0x3) {
17255 gen_sel_s(ctx
, OPC_SEL_S
, rd
, rt
, rs
);
17258 gen_sel_d(ctx
, OPC_SEL_D
, rd
, rt
, rs
);
17261 goto pool32f_invalid
;
17265 check_insn(ctx
, ISA_MIPS_R6
);
17266 switch ((ctx
->opcode
>> 9) & 0x3) {
17268 mips32_op
= OPC_MADDF_S
;
17271 mips32_op
= OPC_MADDF_D
;
17274 goto pool32f_invalid
;
17278 check_insn(ctx
, ISA_MIPS_R6
);
17279 switch ((ctx
->opcode
>> 9) & 0x3) {
17281 mips32_op
= OPC_MSUBF_S
;
17284 mips32_op
= OPC_MSUBF_D
;
17287 goto pool32f_invalid
;
17291 goto pool32f_invalid
;
17295 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
17299 MIPS_INVAL("pool32f");
17300 gen_reserved_instruction(ctx
);
17304 generate_exception_err(ctx
, EXCP_CpU
, 1);
17308 minor
= (ctx
->opcode
>> 21) & 0x1f;
17311 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17312 gen_compute_branch(ctx
, OPC_BLTZ
, 4, rs
, -1, imm
<< 1, 4);
17315 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17316 gen_compute_branch(ctx
, OPC_BLTZAL
, 4, rs
, -1, imm
<< 1, 4);
17317 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
17320 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17321 gen_compute_branch(ctx
, OPC_BLTZAL
, 4, rs
, -1, imm
<< 1, 2);
17322 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
17325 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17326 gen_compute_branch(ctx
, OPC_BGEZ
, 4, rs
, -1, imm
<< 1, 4);
17329 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17330 gen_compute_branch(ctx
, OPC_BGEZAL
, 4, rs
, -1, imm
<< 1, 4);
17331 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
17334 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17335 gen_compute_branch(ctx
, OPC_BGEZAL
, 4, rs
, -1, imm
<< 1, 2);
17336 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
17339 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17340 gen_compute_branch(ctx
, OPC_BLEZ
, 4, rs
, -1, imm
<< 1, 4);
17343 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17344 gen_compute_branch(ctx
, OPC_BGTZ
, 4, rs
, -1, imm
<< 1, 4);
17348 case TLTI
: /* BC1EQZC */
17349 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
17351 check_cp1_enabled(ctx
);
17352 gen_compute_branch1_r6(ctx
, OPC_BC1EQZ
, rs
, imm
<< 1, 0);
17355 mips32_op
= OPC_TLTI
;
17359 case TGEI
: /* BC1NEZC */
17360 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
17362 check_cp1_enabled(ctx
);
17363 gen_compute_branch1_r6(ctx
, OPC_BC1NEZ
, rs
, imm
<< 1, 0);
17366 mips32_op
= OPC_TGEI
;
17371 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17372 mips32_op
= OPC_TLTIU
;
17375 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17376 mips32_op
= OPC_TGEIU
;
17378 case TNEI
: /* SYNCI */
17379 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
17382 * Break the TB to be able to sync copied instructions
17385 ctx
->base
.is_jmp
= DISAS_STOP
;
17388 mips32_op
= OPC_TNEI
;
17393 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17394 mips32_op
= OPC_TEQI
;
17396 gen_trap(ctx
, mips32_op
, rs
, -1, imm
);
17401 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17402 gen_compute_branch(ctx
, minor
== BNEZC
? OPC_BNE
: OPC_BEQ
,
17403 4, rs
, 0, imm
<< 1, 0);
17405 * Compact branches don't have a delay slot, so just let
17406 * the normal delay slot handling take us to the branch
17411 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17412 gen_logic_imm(ctx
, OPC_LUI
, rs
, 0, imm
);
17415 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17417 * Break the TB to be able to sync copied instructions
17420 ctx
->base
.is_jmp
= DISAS_STOP
;
17424 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17425 /* COP2: Not implemented. */
17426 generate_exception_err(ctx
, EXCP_CpU
, 2);
17429 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17430 mips32_op
= (ctx
->opcode
& (1 << 16)) ? OPC_BC1FANY2
: OPC_BC1F
;
17433 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17434 mips32_op
= (ctx
->opcode
& (1 << 16)) ? OPC_BC1TANY2
: OPC_BC1T
;
17437 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17438 mips32_op
= OPC_BC1FANY4
;
17441 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17442 mips32_op
= OPC_BC1TANY4
;
17445 check_insn(ctx
, ASE_MIPS3D
);
17448 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
17449 check_cp1_enabled(ctx
);
17450 gen_compute_branch1(ctx
, mips32_op
,
17451 (ctx
->opcode
>> 18) & 0x7, imm
<< 1);
17453 generate_exception_err(ctx
, EXCP_CpU
, 1);
17458 /* MIPS DSP: not implemented */
17461 MIPS_INVAL("pool32i");
17462 gen_reserved_instruction(ctx
);
17467 minor
= (ctx
->opcode
>> 12) & 0xf;
17468 offset
= sextract32(ctx
->opcode
, 0,
17469 (ctx
->insn_flags
& ISA_MIPS_R6
) ? 9 : 12);
17472 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17473 mips32_op
= OPC_LWL
;
17476 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17477 mips32_op
= OPC_SWL
;
17480 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17481 mips32_op
= OPC_LWR
;
17484 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17485 mips32_op
= OPC_SWR
;
17487 #if defined(TARGET_MIPS64)
17489 check_insn(ctx
, ISA_MIPS3
);
17490 check_mips_64(ctx
);
17491 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17492 mips32_op
= OPC_LDL
;
17495 check_insn(ctx
, ISA_MIPS3
);
17496 check_mips_64(ctx
);
17497 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17498 mips32_op
= OPC_SDL
;
17501 check_insn(ctx
, ISA_MIPS3
);
17502 check_mips_64(ctx
);
17503 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17504 mips32_op
= OPC_LDR
;
17507 check_insn(ctx
, ISA_MIPS3
);
17508 check_mips_64(ctx
);
17509 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17510 mips32_op
= OPC_SDR
;
17513 check_insn(ctx
, ISA_MIPS3
);
17514 check_mips_64(ctx
);
17515 mips32_op
= OPC_LWU
;
17518 check_insn(ctx
, ISA_MIPS3
);
17519 check_mips_64(ctx
);
17520 mips32_op
= OPC_LLD
;
17524 mips32_op
= OPC_LL
;
17527 gen_ld(ctx
, mips32_op
, rt
, rs
, offset
);
17530 gen_st(ctx
, mips32_op
, rt
, rs
, offset
);
17533 gen_st_cond(ctx
, rt
, rs
, offset
, MO_TESL
, false);
17535 #if defined(TARGET_MIPS64)
17537 check_insn(ctx
, ISA_MIPS3
);
17538 check_mips_64(ctx
);
17539 gen_st_cond(ctx
, rt
, rs
, offset
, MO_TEQ
, false);
17544 MIPS_INVAL("pool32c ld-eva");
17545 gen_reserved_instruction(ctx
);
17548 check_cp0_enabled(ctx
);
17550 minor2
= (ctx
->opcode
>> 9) & 0x7;
17551 offset
= sextract32(ctx
->opcode
, 0, 9);
17554 mips32_op
= OPC_LBUE
;
17557 mips32_op
= OPC_LHUE
;
17560 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17561 mips32_op
= OPC_LWLE
;
17564 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17565 mips32_op
= OPC_LWRE
;
17568 mips32_op
= OPC_LBE
;
17571 mips32_op
= OPC_LHE
;
17574 mips32_op
= OPC_LLE
;
17577 mips32_op
= OPC_LWE
;
17583 MIPS_INVAL("pool32c st-eva");
17584 gen_reserved_instruction(ctx
);
17587 check_cp0_enabled(ctx
);
17589 minor2
= (ctx
->opcode
>> 9) & 0x7;
17590 offset
= sextract32(ctx
->opcode
, 0, 9);
17593 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17594 mips32_op
= OPC_SWLE
;
17597 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17598 mips32_op
= OPC_SWRE
;
17601 /* Treat as no-op */
17602 if ((ctx
->insn_flags
& ISA_MIPS_R6
) && (rt
>= 24)) {
17603 /* hint codes 24-31 are reserved and signal RI */
17604 generate_exception(ctx
, EXCP_RI
);
17608 /* Treat as no-op */
17609 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
17610 gen_cache_operation(ctx
, rt
, rs
, offset
);
17614 mips32_op
= OPC_SBE
;
17617 mips32_op
= OPC_SHE
;
17620 gen_st_cond(ctx
, rt
, rs
, offset
, MO_TESL
, true);
17623 mips32_op
= OPC_SWE
;
17628 /* Treat as no-op */
17629 if ((ctx
->insn_flags
& ISA_MIPS_R6
) && (rt
>= 24)) {
17630 /* hint codes 24-31 are reserved and signal RI */
17631 generate_exception(ctx
, EXCP_RI
);
17635 MIPS_INVAL("pool32c");
17636 gen_reserved_instruction(ctx
);
17640 case ADDI32
: /* AUI, LUI */
17641 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
17643 gen_logic_imm(ctx
, OPC_LUI
, rt
, rs
, imm
);
17646 mips32_op
= OPC_ADDI
;
17651 mips32_op
= OPC_ADDIU
;
17653 gen_arith_imm(ctx
, mips32_op
, rt
, rs
, imm
);
17656 /* Logical operations */
17658 mips32_op
= OPC_ORI
;
17661 mips32_op
= OPC_XORI
;
17664 mips32_op
= OPC_ANDI
;
17666 gen_logic_imm(ctx
, mips32_op
, rt
, rs
, imm
);
17669 /* Set less than immediate */
17671 mips32_op
= OPC_SLTI
;
17674 mips32_op
= OPC_SLTIU
;
17676 gen_slt_imm(ctx
, mips32_op
, rt
, rs
, imm
);
17679 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17680 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
17681 gen_compute_branch(ctx
, OPC_JALX
, 4, rt
, rs
, offset
, 4);
17682 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
17684 case JALS32
: /* BOVC, BEQC, BEQZALC */
17685 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
17688 mips32_op
= OPC_BOVC
;
17689 } else if (rs
< rt
&& rs
== 0) {
17691 mips32_op
= OPC_BEQZALC
;
17694 mips32_op
= OPC_BEQC
;
17696 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
17699 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1;
17700 gen_compute_branch(ctx
, OPC_JAL
, 4, rt
, rs
, offset
, 2);
17701 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
17704 case BEQ32
: /* BC */
17705 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
17707 gen_compute_compact_branch(ctx
, OPC_BC
, 0, 0,
17708 sextract32(ctx
->opcode
<< 1, 0, 27));
17711 gen_compute_branch(ctx
, OPC_BEQ
, 4, rt
, rs
, imm
<< 1, 4);
17714 case BNE32
: /* BALC */
17715 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
17717 gen_compute_compact_branch(ctx
, OPC_BALC
, 0, 0,
17718 sextract32(ctx
->opcode
<< 1, 0, 27));
17721 gen_compute_branch(ctx
, OPC_BNE
, 4, rt
, rs
, imm
<< 1, 4);
17724 case J32
: /* BGTZC, BLTZC, BLTC */
17725 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
17726 if (rs
== 0 && rt
!= 0) {
17728 mips32_op
= OPC_BGTZC
;
17729 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
17731 mips32_op
= OPC_BLTZC
;
17734 mips32_op
= OPC_BLTC
;
17736 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
17739 gen_compute_branch(ctx
, OPC_J
, 4, rt
, rs
,
17740 (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1, 4);
17743 case JAL32
: /* BLEZC, BGEZC, BGEC */
17744 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
17745 if (rs
== 0 && rt
!= 0) {
17747 mips32_op
= OPC_BLEZC
;
17748 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
17750 mips32_op
= OPC_BGEZC
;
17753 mips32_op
= OPC_BGEC
;
17755 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
17758 gen_compute_branch(ctx
, OPC_JAL
, 4, rt
, rs
,
17759 (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1, 4);
17760 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
17763 /* Floating point (COP1) */
17765 mips32_op
= OPC_LWC1
;
17768 mips32_op
= OPC_LDC1
;
17771 mips32_op
= OPC_SWC1
;
17774 mips32_op
= OPC_SDC1
;
17776 gen_cop1_ldst(ctx
, mips32_op
, rt
, rs
, imm
);
17778 case ADDIUPC
: /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
17779 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
17780 /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
17781 switch ((ctx
->opcode
>> 16) & 0x1f) {
17790 gen_pcrel(ctx
, OPC_ADDIUPC
, ctx
->base
.pc_next
& ~0x3, rt
);
17793 gen_pcrel(ctx
, OPC_AUIPC
, ctx
->base
.pc_next
, rt
);
17796 gen_pcrel(ctx
, OPC_ALUIPC
, ctx
->base
.pc_next
, rt
);
17806 gen_pcrel(ctx
, R6_OPC_LWPC
, ctx
->base
.pc_next
& ~0x3, rt
);
17809 generate_exception(ctx
, EXCP_RI
);
17814 int reg
= mmreg(ZIMM(ctx
->opcode
, 23, 3));
17815 offset
= SIMM(ctx
->opcode
, 0, 23) << 2;
17817 gen_addiupc(ctx
, reg
, offset
, 0, 0);
17820 case BNVC
: /* BNEC, BNEZALC */
17821 check_insn(ctx
, ISA_MIPS_R6
);
17824 mips32_op
= OPC_BNVC
;
17825 } else if (rs
< rt
&& rs
== 0) {
17827 mips32_op
= OPC_BNEZALC
;
17830 mips32_op
= OPC_BNEC
;
17832 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
17834 case R6_BNEZC
: /* JIALC */
17835 check_insn(ctx
, ISA_MIPS_R6
);
17838 gen_compute_compact_branch(ctx
, OPC_BNEZC
, rt
, 0,
17839 sextract32(ctx
->opcode
<< 1, 0, 22));
17842 gen_compute_compact_branch(ctx
, OPC_JIALC
, 0, rs
, imm
);
17845 case R6_BEQZC
: /* JIC */
17846 check_insn(ctx
, ISA_MIPS_R6
);
17849 gen_compute_compact_branch(ctx
, OPC_BEQZC
, rt
, 0,
17850 sextract32(ctx
->opcode
<< 1, 0, 22));
17853 gen_compute_compact_branch(ctx
, OPC_JIC
, 0, rs
, imm
);
17856 case BLEZALC
: /* BGEZALC, BGEUC */
17857 check_insn(ctx
, ISA_MIPS_R6
);
17858 if (rs
== 0 && rt
!= 0) {
17860 mips32_op
= OPC_BLEZALC
;
17861 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
17863 mips32_op
= OPC_BGEZALC
;
17866 mips32_op
= OPC_BGEUC
;
17868 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
17870 case BGTZALC
: /* BLTZALC, BLTUC */
17871 check_insn(ctx
, ISA_MIPS_R6
);
17872 if (rs
== 0 && rt
!= 0) {
17874 mips32_op
= OPC_BGTZALC
;
17875 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
17877 mips32_op
= OPC_BLTZALC
;
17880 mips32_op
= OPC_BLTUC
;
17882 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
17884 /* Loads and stores */
17886 mips32_op
= OPC_LB
;
17889 mips32_op
= OPC_LBU
;
17892 mips32_op
= OPC_LH
;
17895 mips32_op
= OPC_LHU
;
17898 mips32_op
= OPC_LW
;
17900 #ifdef TARGET_MIPS64
17902 check_insn(ctx
, ISA_MIPS3
);
17903 check_mips_64(ctx
);
17904 mips32_op
= OPC_LD
;
17907 check_insn(ctx
, ISA_MIPS3
);
17908 check_mips_64(ctx
);
17909 mips32_op
= OPC_SD
;
17913 mips32_op
= OPC_SB
;
17916 mips32_op
= OPC_SH
;
17919 mips32_op
= OPC_SW
;
17922 gen_ld(ctx
, mips32_op
, rt
, rs
, imm
);
17925 gen_st(ctx
, mips32_op
, rt
, rs
, imm
);
17928 gen_reserved_instruction(ctx
);
17933 static int decode_micromips_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
17937 /* make sure instructions are on a halfword boundary */
17938 if (ctx
->base
.pc_next
& 0x1) {
17939 env
->CP0_BadVAddr
= ctx
->base
.pc_next
;
17940 generate_exception_end(ctx
, EXCP_AdEL
);
17944 op
= (ctx
->opcode
>> 10) & 0x3f;
17945 /* Enforce properly-sized instructions in a delay slot */
17946 if (ctx
->hflags
& MIPS_HFLAG_BDS_STRICT
) {
17947 switch (op
& 0x7) { /* MSB-3..MSB-5 */
17949 /* POOL32A, POOL32B, POOL32I, POOL32C */
17951 /* ADDI32, ADDIU32, ORI32, XORI32, SLTI32, SLTIU32, ANDI32, JALX32 */
17953 /* LBU32, LHU32, POOL32F, JALS32, BEQ32, BNE32, J32, JAL32 */
17955 /* SB32, SH32, ADDIUPC, SWC132, SDC132, SW32 */
17957 /* LB32, LH32, LWC132, LDC132, LW32 */
17958 if (ctx
->hflags
& MIPS_HFLAG_BDS16
) {
17959 gen_reserved_instruction(ctx
);
17964 /* POOL16A, POOL16B, POOL16C, LWGP16, POOL16F */
17966 /* LBU16, LHU16, LWSP16, LW16, SB16, SH16, SWSP16, SW16 */
17968 /* MOVE16, ANDI16, POOL16D, POOL16E, BEQZ16, BNEZ16, B16, LI16 */
17969 if (ctx
->hflags
& MIPS_HFLAG_BDS32
) {
17970 gen_reserved_instruction(ctx
);
17980 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
17981 int rs1
= mmreg(uMIPS_RS1(ctx
->opcode
));
17982 int rs2
= mmreg(uMIPS_RS2(ctx
->opcode
));
17985 switch (ctx
->opcode
& 0x1) {
17993 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
17995 * In the Release 6, the register number location in
17996 * the instruction encoding has changed.
17998 gen_arith(ctx
, opc
, rs1
, rd
, rs2
);
18000 gen_arith(ctx
, opc
, rd
, rs1
, rs2
);
18006 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
18007 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
18008 int amount
= (ctx
->opcode
>> 1) & 0x7;
18010 amount
= amount
== 0 ? 8 : amount
;
18012 switch (ctx
->opcode
& 0x1) {
18021 gen_shift_imm(ctx
, opc
, rd
, rs
, amount
);
18025 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
18026 gen_pool16c_r6_insn(ctx
);
18028 gen_pool16c_insn(ctx
);
18033 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
18034 int rb
= 28; /* GP */
18035 int16_t offset
= SIMM(ctx
->opcode
, 0, 7) << 2;
18037 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
18041 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
18042 if (ctx
->opcode
& 1) {
18043 gen_reserved_instruction(ctx
);
18046 int enc_dest
= uMIPS_RD(ctx
->opcode
);
18047 int enc_rt
= uMIPS_RS2(ctx
->opcode
);
18048 int enc_rs
= uMIPS_RS1(ctx
->opcode
);
18049 gen_movep(ctx
, enc_dest
, enc_rt
, enc_rs
);
18054 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
18055 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
18056 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4);
18057 offset
= (offset
== 0xf ? -1 : offset
);
18059 gen_ld(ctx
, OPC_LBU
, rd
, rb
, offset
);
18064 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
18065 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
18066 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 1;
18068 gen_ld(ctx
, OPC_LHU
, rd
, rb
, offset
);
18073 int rd
= (ctx
->opcode
>> 5) & 0x1f;
18074 int rb
= 29; /* SP */
18075 int16_t offset
= ZIMM(ctx
->opcode
, 0, 5) << 2;
18077 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
18082 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
18083 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
18084 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 2;
18086 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
18091 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
18092 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
18093 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4);
18095 gen_st(ctx
, OPC_SB
, rd
, rb
, offset
);
18100 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
18101 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
18102 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 1;
18104 gen_st(ctx
, OPC_SH
, rd
, rb
, offset
);
18109 int rd
= (ctx
->opcode
>> 5) & 0x1f;
18110 int rb
= 29; /* SP */
18111 int16_t offset
= ZIMM(ctx
->opcode
, 0, 5) << 2;
18113 gen_st(ctx
, OPC_SW
, rd
, rb
, offset
);
18118 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
18119 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
18120 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 2;
18122 gen_st(ctx
, OPC_SW
, rd
, rb
, offset
);
18127 int rd
= uMIPS_RD5(ctx
->opcode
);
18128 int rs
= uMIPS_RS5(ctx
->opcode
);
18130 gen_arith(ctx
, OPC_ADDU
, rd
, rs
, 0);
18137 switch (ctx
->opcode
& 0x1) {
18147 switch (ctx
->opcode
& 0x1) {
18152 gen_addiur1sp(ctx
);
18156 case B16
: /* BC16 */
18157 gen_compute_branch(ctx
, OPC_BEQ
, 2, 0, 0,
18158 sextract32(ctx
->opcode
, 0, 10) << 1,
18159 (ctx
->insn_flags
& ISA_MIPS_R6
) ? 0 : 4);
18161 case BNEZ16
: /* BNEZC16 */
18162 case BEQZ16
: /* BEQZC16 */
18163 gen_compute_branch(ctx
, op
== BNEZ16
? OPC_BNE
: OPC_BEQ
, 2,
18164 mmreg(uMIPS_RD(ctx
->opcode
)),
18165 0, sextract32(ctx
->opcode
, 0, 7) << 1,
18166 (ctx
->insn_flags
& ISA_MIPS_R6
) ? 0 : 4);
18171 int reg
= mmreg(uMIPS_RD(ctx
->opcode
));
18172 int imm
= ZIMM(ctx
->opcode
, 0, 7);
18174 imm
= (imm
== 0x7f ? -1 : imm
);
18175 tcg_gen_movi_tl(cpu_gpr
[reg
], imm
);
18181 gen_reserved_instruction(ctx
);
18184 decode_micromips32_opc(env
, ctx
);
18197 /* MAJOR, P16, and P32 pools opcodes */
18201 NM_MOVE_BALC
= 0x02,
18209 NM_P16_SHIFT
= 0x0c,
18227 NM_P_LS_U12
= 0x21,
18237 NM_P16_ADDU
= 0x2c,
18251 NM_MOVEPREV
= 0x3f,
18254 /* POOL32A instruction pool */
18256 NM_POOL32A0
= 0x00,
18257 NM_SPECIAL2
= 0x01,
18260 NM_POOL32A5
= 0x05,
18261 NM_POOL32A7
= 0x07,
18264 /* P.GP.W instruction pool */
18266 NM_ADDIUGP_W
= 0x00,
18271 /* P48I instruction pool */
18275 NM_ADDIUGP48
= 0x02,
18276 NM_ADDIUPC48
= 0x03,
18281 /* P.U12 instruction pool */
18290 NM_ADDIUNEG
= 0x08,
18297 /* POOL32F instruction pool */
18299 NM_POOL32F_0
= 0x00,
18300 NM_POOL32F_3
= 0x03,
18301 NM_POOL32F_5
= 0x05,
18304 /* POOL32S instruction pool */
18306 NM_POOL32S_0
= 0x00,
18307 NM_POOL32S_4
= 0x04,
18310 /* P.LUI instruction pool */
18316 /* P.GP.BH instruction pool */
18321 NM_ADDIUGP_B
= 0x03,
18324 NM_P_GP_CP1
= 0x06,
18327 /* P.LS.U12 instruction pool */
18332 NM_P_PREFU12
= 0x03,
18345 /* P.LS.S9 instruction pool */
18351 NM_P_LS_UAWM
= 0x05,
18354 /* P.BAL instruction pool */
18360 /* P.J instruction pool */
18363 NM_JALRC_HB
= 0x01,
18364 NM_P_BALRSC
= 0x08,
18367 /* P.BR1 instruction pool */
18375 /* P.BR2 instruction pool */
18382 /* P.BRI instruction pool */
18394 /* P16.SHIFT instruction pool */
18400 /* POOL16C instruction pool */
18402 NM_POOL16C_0
= 0x00,
18406 /* P16.A1 instruction pool */
18408 NM_ADDIUR1SP
= 0x01,
18411 /* P16.A2 instruction pool */
18414 NM_P_ADDIURS5
= 0x01,
18417 /* P16.ADDU instruction pool */
18423 /* P16.SR instruction pool */
18426 NM_RESTORE_JRC16
= 0x01,
18429 /* P16.4X4 instruction pool */
18435 /* P16.LB instruction pool */
18442 /* P16.LH instruction pool */
18449 /* P.RI instruction pool */
18452 NM_P_SYSCALL
= 0x01,
18457 /* POOL32A0 instruction pool */
18492 NM_D_E_MT_VPE
= 0x56,
18500 /* CRC32 instruction pool */
18510 /* POOL32A5 instruction pool */
18512 NM_CMP_EQ_PH
= 0x00,
18513 NM_CMP_LT_PH
= 0x08,
18514 NM_CMP_LE_PH
= 0x10,
18515 NM_CMPGU_EQ_QB
= 0x18,
18516 NM_CMPGU_LT_QB
= 0x20,
18517 NM_CMPGU_LE_QB
= 0x28,
18518 NM_CMPGDU_EQ_QB
= 0x30,
18519 NM_CMPGDU_LT_QB
= 0x38,
18520 NM_CMPGDU_LE_QB
= 0x40,
18521 NM_CMPU_EQ_QB
= 0x48,
18522 NM_CMPU_LT_QB
= 0x50,
18523 NM_CMPU_LE_QB
= 0x58,
18524 NM_ADDQ_S_W
= 0x60,
18525 NM_SUBQ_S_W
= 0x68,
18529 NM_ADDQ_S_PH
= 0x01,
18530 NM_ADDQH_R_PH
= 0x09,
18531 NM_ADDQH_R_W
= 0x11,
18532 NM_ADDU_S_QB
= 0x19,
18533 NM_ADDU_S_PH
= 0x21,
18534 NM_ADDUH_R_QB
= 0x29,
18535 NM_SHRAV_R_PH
= 0x31,
18536 NM_SHRAV_R_QB
= 0x39,
18537 NM_SUBQ_S_PH
= 0x41,
18538 NM_SUBQH_R_PH
= 0x49,
18539 NM_SUBQH_R_W
= 0x51,
18540 NM_SUBU_S_QB
= 0x59,
18541 NM_SUBU_S_PH
= 0x61,
18542 NM_SUBUH_R_QB
= 0x69,
18543 NM_SHLLV_S_PH
= 0x71,
18544 NM_PRECR_SRA_R_PH_W
= 0x79,
18546 NM_MULEU_S_PH_QBL
= 0x12,
18547 NM_MULEU_S_PH_QBR
= 0x1a,
18548 NM_MULQ_RS_PH
= 0x22,
18549 NM_MULQ_S_PH
= 0x2a,
18550 NM_MULQ_RS_W
= 0x32,
18551 NM_MULQ_S_W
= 0x3a,
18554 NM_SHRAV_R_W
= 0x5a,
18555 NM_SHRLV_PH
= 0x62,
18556 NM_SHRLV_QB
= 0x6a,
18557 NM_SHLLV_QB
= 0x72,
18558 NM_SHLLV_S_W
= 0x7a,
18562 NM_MULEQ_S_W_PHL
= 0x04,
18563 NM_MULEQ_S_W_PHR
= 0x0c,
18565 NM_MUL_S_PH
= 0x05,
18566 NM_PRECR_QB_PH
= 0x0d,
18567 NM_PRECRQ_QB_PH
= 0x15,
18568 NM_PRECRQ_PH_W
= 0x1d,
18569 NM_PRECRQ_RS_PH_W
= 0x25,
18570 NM_PRECRQU_S_QB_PH
= 0x2d,
18571 NM_PACKRL_PH
= 0x35,
18575 NM_SHRA_R_W
= 0x5e,
18576 NM_SHRA_R_PH
= 0x66,
18577 NM_SHLL_S_PH
= 0x76,
18578 NM_SHLL_S_W
= 0x7e,
18583 /* POOL32A7 instruction pool */
18588 NM_POOL32AXF
= 0x07,
18591 /* P.SR instruction pool */
18597 /* P.SHIFT instruction pool */
18605 /* P.ROTX instruction pool */
18610 /* P.INS instruction pool */
18615 /* P.EXT instruction pool */
18620 /* POOL32F_0 (fmt) instruction pool */
18625 NM_SELEQZ_S
= 0x07,
18626 NM_SELEQZ_D
= 0x47,
18630 NM_SELNEZ_S
= 0x0f,
18631 NM_SELNEZ_D
= 0x4f,
18646 /* POOL32F_3 instruction pool */
18650 NM_MINA_FMT
= 0x04,
18651 NM_MAXA_FMT
= 0x05,
18652 NM_POOL32FXF
= 0x07,
18655 /* POOL32F_5 instruction pool */
18657 NM_CMP_CONDN_S
= 0x00,
18658 NM_CMP_CONDN_D
= 0x02,
18661 /* P.GP.LH instruction pool */
18667 /* P.GP.SH instruction pool */
18672 /* P.GP.CP1 instruction pool */
18680 /* P.LS.S0 instruction pool */
18697 NM_P_PREFS9
= 0x03,
18703 /* P.LS.S1 instruction pool */
18705 NM_ASET_ACLR
= 0x02,
18713 /* P.LS.E0 instruction pool */
18729 /* P.PREFE instruction pool */
18735 /* P.LLE instruction pool */
18741 /* P.SCE instruction pool */
18747 /* P.LS.WM instruction pool */
18753 /* P.LS.UAWM instruction pool */
18759 /* P.BR3A instruction pool */
18765 NM_BPOSGE32C
= 0x04,
18768 /* P16.RI instruction pool */
18770 NM_P16_SYSCALL
= 0x01,
18775 /* POOL16C_0 instruction pool */
18777 NM_POOL16C_00
= 0x00,
18780 /* P16.JRC instruction pool */
18786 /* P.SYSCALL instruction pool */
18792 /* P.TRAP instruction pool */
18798 /* P.CMOVE instruction pool */
18804 /* POOL32Axf instruction pool */
18806 NM_POOL32AXF_1
= 0x01,
18807 NM_POOL32AXF_2
= 0x02,
18808 NM_POOL32AXF_4
= 0x04,
18809 NM_POOL32AXF_5
= 0x05,
18810 NM_POOL32AXF_7
= 0x07,
18813 /* POOL32Axf_1 instruction pool */
18815 NM_POOL32AXF_1_0
= 0x00,
18816 NM_POOL32AXF_1_1
= 0x01,
18817 NM_POOL32AXF_1_3
= 0x03,
18818 NM_POOL32AXF_1_4
= 0x04,
18819 NM_POOL32AXF_1_5
= 0x05,
18820 NM_POOL32AXF_1_7
= 0x07,
18823 /* POOL32Axf_2 instruction pool */
18825 NM_POOL32AXF_2_0_7
= 0x00,
18826 NM_POOL32AXF_2_8_15
= 0x01,
18827 NM_POOL32AXF_2_16_23
= 0x02,
18828 NM_POOL32AXF_2_24_31
= 0x03,
18831 /* POOL32Axf_7 instruction pool */
18833 NM_SHRA_R_QB
= 0x0,
18838 /* POOL32Axf_1_0 instruction pool */
18846 /* POOL32Axf_1_1 instruction pool */
18852 /* POOL32Axf_1_3 instruction pool */
18860 /* POOL32Axf_1_4 instruction pool */
18866 /* POOL32Axf_1_5 instruction pool */
18868 NM_MAQ_S_W_PHR
= 0x0,
18869 NM_MAQ_S_W_PHL
= 0x1,
18870 NM_MAQ_SA_W_PHR
= 0x2,
18871 NM_MAQ_SA_W_PHL
= 0x3,
18874 /* POOL32Axf_1_7 instruction pool */
18878 NM_EXTR_RS_W
= 0x2,
18882 /* POOL32Axf_2_0_7 instruction pool */
18885 NM_DPAQ_S_W_PH
= 0x1,
18887 NM_DPSQ_S_W_PH
= 0x3,
18894 /* POOL32Axf_2_8_15 instruction pool */
18896 NM_DPAX_W_PH
= 0x0,
18897 NM_DPAQ_SA_L_W
= 0x1,
18898 NM_DPSX_W_PH
= 0x2,
18899 NM_DPSQ_SA_L_W
= 0x3,
18902 NM_EXTRV_R_W
= 0x7,
18905 /* POOL32Axf_2_16_23 instruction pool */
18907 NM_DPAU_H_QBL
= 0x0,
18908 NM_DPAQX_S_W_PH
= 0x1,
18909 NM_DPSU_H_QBL
= 0x2,
18910 NM_DPSQX_S_W_PH
= 0x3,
18913 NM_MULSA_W_PH
= 0x6,
18914 NM_EXTRV_RS_W
= 0x7,
18917 /* POOL32Axf_2_24_31 instruction pool */
18919 NM_DPAU_H_QBR
= 0x0,
18920 NM_DPAQX_SA_W_PH
= 0x1,
18921 NM_DPSU_H_QBR
= 0x2,
18922 NM_DPSQX_SA_W_PH
= 0x3,
18925 NM_MULSAQ_S_W_PH
= 0x6,
18926 NM_EXTRV_S_H
= 0x7,
18929 /* POOL32Axf_{4, 5} instruction pool */
18948 /* nanoMIPS DSP instructions */
18949 NM_ABSQ_S_QB
= 0x00,
18950 NM_ABSQ_S_PH
= 0x08,
18951 NM_ABSQ_S_W
= 0x10,
18952 NM_PRECEQ_W_PHL
= 0x28,
18953 NM_PRECEQ_W_PHR
= 0x30,
18954 NM_PRECEQU_PH_QBL
= 0x38,
18955 NM_PRECEQU_PH_QBR
= 0x48,
18956 NM_PRECEU_PH_QBL
= 0x58,
18957 NM_PRECEU_PH_QBR
= 0x68,
18958 NM_PRECEQU_PH_QBLA
= 0x39,
18959 NM_PRECEQU_PH_QBRA
= 0x49,
18960 NM_PRECEU_PH_QBLA
= 0x59,
18961 NM_PRECEU_PH_QBRA
= 0x69,
18962 NM_REPLV_PH
= 0x01,
18963 NM_REPLV_QB
= 0x09,
18966 NM_RADDU_W_QB
= 0x78,
18972 /* PP.SR instruction pool */
18976 NM_RESTORE_JRC
= 0x03,
18979 /* P.SR.F instruction pool */
18982 NM_RESTOREF
= 0x01,
18985 /* P16.SYSCALL instruction pool */
18987 NM_SYSCALL16
= 0x00,
18988 NM_HYPCALL16
= 0x01,
18991 /* POOL16C_00 instruction pool */
18999 /* PP.LSX and PP.LSXS instruction pool */
19037 /* ERETx instruction pool */
19043 /* POOL32FxF_{0, 1} insturction pool */
19052 NM_CVT_S_PL
= 0x84,
19053 NM_CVT_S_PU
= 0xa4,
19055 NM_CVT_L_S
= 0x004,
19056 NM_CVT_L_D
= 0x104,
19057 NM_CVT_W_S
= 0x024,
19058 NM_CVT_W_D
= 0x124,
19060 NM_RSQRT_S
= 0x008,
19061 NM_RSQRT_D
= 0x108,
19066 NM_RECIP_S
= 0x048,
19067 NM_RECIP_D
= 0x148,
19069 NM_FLOOR_L_S
= 0x00c,
19070 NM_FLOOR_L_D
= 0x10c,
19072 NM_FLOOR_W_S
= 0x02c,
19073 NM_FLOOR_W_D
= 0x12c,
19075 NM_CEIL_L_S
= 0x04c,
19076 NM_CEIL_L_D
= 0x14c,
19077 NM_CEIL_W_S
= 0x06c,
19078 NM_CEIL_W_D
= 0x16c,
19079 NM_TRUNC_L_S
= 0x08c,
19080 NM_TRUNC_L_D
= 0x18c,
19081 NM_TRUNC_W_S
= 0x0ac,
19082 NM_TRUNC_W_D
= 0x1ac,
19083 NM_ROUND_L_S
= 0x0cc,
19084 NM_ROUND_L_D
= 0x1cc,
19085 NM_ROUND_W_S
= 0x0ec,
19086 NM_ROUND_W_D
= 0x1ec,
19094 NM_CVT_D_S
= 0x04d,
19095 NM_CVT_D_W
= 0x0cd,
19096 NM_CVT_D_L
= 0x14d,
19097 NM_CVT_S_D
= 0x06d,
19098 NM_CVT_S_W
= 0x0ed,
19099 NM_CVT_S_L
= 0x16d,
19102 /* P.LL instruction pool */
19108 /* P.SC instruction pool */
19114 /* P.DVP instruction pool */
19123 * nanoMIPS decoding engine
19128 /* extraction utilities */
19130 #define NANOMIPS_EXTRACT_RT3(op) ((op >> 7) & 0x7)
19131 #define NANOMIPS_EXTRACT_RS3(op) ((op >> 4) & 0x7)
19132 #define NANOMIPS_EXTRACT_RD3(op) ((op >> 1) & 0x7)
19133 #define NANOMIPS_EXTRACT_RD5(op) ((op >> 5) & 0x1f)
19134 #define NANOMIPS_EXTRACT_RS5(op) (op & 0x1f)
19136 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3'). */
19137 static inline int decode_gpr_gpr3(int r
)
19139 static const int map
[] = { 16, 17, 18, 19, 4, 5, 6, 7 };
19141 return map
[r
& 0x7];
19144 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3.src.store'). */
19145 static inline int decode_gpr_gpr3_src_store(int r
)
19147 static const int map
[] = { 0, 17, 18, 19, 4, 5, 6, 7 };
19149 return map
[r
& 0x7];
19152 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4'). */
19153 static inline int decode_gpr_gpr4(int r
)
19155 static const int map
[] = { 8, 9, 10, 11, 4, 5, 6, 7,
19156 16, 17, 18, 19, 20, 21, 22, 23 };
19158 return map
[r
& 0xf];
19161 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4.zero'). */
19162 static inline int decode_gpr_gpr4_zero(int r
)
19164 static const int map
[] = { 8, 9, 10, 0, 4, 5, 6, 7,
19165 16, 17, 18, 19, 20, 21, 22, 23 };
19167 return map
[r
& 0xf];
19171 static void gen_adjust_sp(DisasContext
*ctx
, int u
)
19173 gen_op_addr_addi(ctx
, cpu_gpr
[29], cpu_gpr
[29], u
);
19176 static void gen_save(DisasContext
*ctx
, uint8_t rt
, uint8_t count
,
19177 uint8_t gp
, uint16_t u
)
19180 TCGv va
= tcg_temp_new();
19181 TCGv t0
= tcg_temp_new();
19183 while (counter
!= count
) {
19184 bool use_gp
= gp
&& (counter
== count
- 1);
19185 int this_rt
= use_gp
? 28 : (rt
& 0x10) | ((rt
+ counter
) & 0x1f);
19186 int this_offset
= -((counter
+ 1) << 2);
19187 gen_base_offset_addr(ctx
, va
, 29, this_offset
);
19188 gen_load_gpr(t0
, this_rt
);
19189 tcg_gen_qemu_st_tl(t0
, va
, ctx
->mem_idx
,
19190 (MO_TEUL
| ctx
->default_tcg_memop_mask
));
19194 /* adjust stack pointer */
19195 gen_adjust_sp(ctx
, -u
);
19201 static void gen_restore(DisasContext
*ctx
, uint8_t rt
, uint8_t count
,
19202 uint8_t gp
, uint16_t u
)
19205 TCGv va
= tcg_temp_new();
19206 TCGv t0
= tcg_temp_new();
19208 while (counter
!= count
) {
19209 bool use_gp
= gp
&& (counter
== count
- 1);
19210 int this_rt
= use_gp
? 28 : (rt
& 0x10) | ((rt
+ counter
) & 0x1f);
19211 int this_offset
= u
- ((counter
+ 1) << 2);
19212 gen_base_offset_addr(ctx
, va
, 29, this_offset
);
19213 tcg_gen_qemu_ld_tl(t0
, va
, ctx
->mem_idx
, MO_TESL
|
19214 ctx
->default_tcg_memop_mask
);
19215 tcg_gen_ext32s_tl(t0
, t0
);
19216 gen_store_gpr(t0
, this_rt
);
19220 /* adjust stack pointer */
19221 gen_adjust_sp(ctx
, u
);
19227 static void gen_pool16c_nanomips_insn(DisasContext
*ctx
)
19229 int rt
= decode_gpr_gpr3(NANOMIPS_EXTRACT_RT3(ctx
->opcode
));
19230 int rs
= decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx
->opcode
));
19232 switch (extract32(ctx
->opcode
, 2, 2)) {
19234 gen_logic(ctx
, OPC_NOR
, rt
, rs
, 0);
19237 gen_logic(ctx
, OPC_AND
, rt
, rt
, rs
);
19240 gen_logic(ctx
, OPC_XOR
, rt
, rt
, rs
);
19243 gen_logic(ctx
, OPC_OR
, rt
, rt
, rs
);
19248 static void gen_pool32a0_nanomips_insn(CPUMIPSState
*env
, DisasContext
*ctx
)
19250 int rt
= extract32(ctx
->opcode
, 21, 5);
19251 int rs
= extract32(ctx
->opcode
, 16, 5);
19252 int rd
= extract32(ctx
->opcode
, 11, 5);
19254 switch (extract32(ctx
->opcode
, 3, 7)) {
19256 switch (extract32(ctx
->opcode
, 10, 1)) {
19259 gen_trap(ctx
, OPC_TEQ
, rs
, rt
, -1);
19263 gen_trap(ctx
, OPC_TNE
, rs
, rt
, -1);
19269 gen_rdhwr(ctx
, rt
, rs
, extract32(ctx
->opcode
, 11, 3));
19273 gen_bshfl(ctx
, OPC_SEB
, rs
, rt
);
19276 gen_bshfl(ctx
, OPC_SEH
, rs
, rt
);
19279 gen_shift(ctx
, OPC_SLLV
, rd
, rt
, rs
);
19282 gen_shift(ctx
, OPC_SRLV
, rd
, rt
, rs
);
19285 gen_shift(ctx
, OPC_SRAV
, rd
, rt
, rs
);
19288 gen_shift(ctx
, OPC_ROTRV
, rd
, rt
, rs
);
19291 gen_arith(ctx
, OPC_ADD
, rd
, rs
, rt
);
19294 gen_arith(ctx
, OPC_ADDU
, rd
, rs
, rt
);
19298 gen_arith(ctx
, OPC_SUB
, rd
, rs
, rt
);
19301 gen_arith(ctx
, OPC_SUBU
, rd
, rs
, rt
);
19304 switch (extract32(ctx
->opcode
, 10, 1)) {
19306 gen_cond_move(ctx
, OPC_MOVZ
, rd
, rs
, rt
);
19309 gen_cond_move(ctx
, OPC_MOVN
, rd
, rs
, rt
);
19314 gen_logic(ctx
, OPC_AND
, rd
, rs
, rt
);
19317 gen_logic(ctx
, OPC_OR
, rd
, rs
, rt
);
19320 gen_logic(ctx
, OPC_NOR
, rd
, rs
, rt
);
19323 gen_logic(ctx
, OPC_XOR
, rd
, rs
, rt
);
19326 gen_slt(ctx
, OPC_SLT
, rd
, rs
, rt
);
19331 #ifndef CONFIG_USER_ONLY
19332 TCGv t0
= tcg_temp_new();
19333 switch (extract32(ctx
->opcode
, 10, 1)) {
19336 check_cp0_enabled(ctx
);
19337 gen_helper_dvp(t0
, cpu_env
);
19338 gen_store_gpr(t0
, rt
);
19343 check_cp0_enabled(ctx
);
19344 gen_helper_evp(t0
, cpu_env
);
19345 gen_store_gpr(t0
, rt
);
19352 gen_slt(ctx
, OPC_SLTU
, rd
, rs
, rt
);
19357 TCGv t0
= tcg_temp_new();
19358 TCGv t1
= tcg_temp_new();
19359 TCGv t2
= tcg_temp_new();
19361 gen_load_gpr(t1
, rs
);
19362 gen_load_gpr(t2
, rt
);
19363 tcg_gen_add_tl(t0
, t1
, t2
);
19364 tcg_gen_ext32s_tl(t0
, t0
);
19365 tcg_gen_xor_tl(t1
, t1
, t2
);
19366 tcg_gen_xor_tl(t2
, t0
, t2
);
19367 tcg_gen_andc_tl(t1
, t2
, t1
);
19369 /* operands of same sign, result different sign */
19370 tcg_gen_setcondi_tl(TCG_COND_LT
, t0
, t1
, 0);
19371 gen_store_gpr(t0
, rd
);
19379 gen_r6_muldiv(ctx
, R6_OPC_MUL
, rd
, rs
, rt
);
19382 gen_r6_muldiv(ctx
, R6_OPC_MUH
, rd
, rs
, rt
);
19385 gen_r6_muldiv(ctx
, R6_OPC_MULU
, rd
, rs
, rt
);
19388 gen_r6_muldiv(ctx
, R6_OPC_MUHU
, rd
, rs
, rt
);
19391 gen_r6_muldiv(ctx
, R6_OPC_DIV
, rd
, rs
, rt
);
19394 gen_r6_muldiv(ctx
, R6_OPC_MOD
, rd
, rs
, rt
);
19397 gen_r6_muldiv(ctx
, R6_OPC_DIVU
, rd
, rs
, rt
);
19400 gen_r6_muldiv(ctx
, R6_OPC_MODU
, rd
, rs
, rt
);
19402 #ifndef CONFIG_USER_ONLY
19404 check_cp0_enabled(ctx
);
19406 /* Treat as NOP. */
19409 gen_mfc0(ctx
, cpu_gpr
[rt
], rs
, extract32(ctx
->opcode
, 11, 3));
19412 check_cp0_enabled(ctx
);
19414 TCGv t0
= tcg_temp_new();
19416 gen_load_gpr(t0
, rt
);
19417 gen_mtc0(ctx
, t0
, rs
, extract32(ctx
->opcode
, 11, 3));
19421 case NM_D_E_MT_VPE
:
19423 uint8_t sc
= extract32(ctx
->opcode
, 10, 1);
19424 TCGv t0
= tcg_temp_new();
19431 gen_helper_dmt(t0
);
19432 gen_store_gpr(t0
, rt
);
19433 } else if (rs
== 0) {
19436 gen_helper_dvpe(t0
, cpu_env
);
19437 gen_store_gpr(t0
, rt
);
19439 gen_reserved_instruction(ctx
);
19446 gen_helper_emt(t0
);
19447 gen_store_gpr(t0
, rt
);
19448 } else if (rs
== 0) {
19451 gen_helper_evpe(t0
, cpu_env
);
19452 gen_store_gpr(t0
, rt
);
19454 gen_reserved_instruction(ctx
);
19465 TCGv t0
= tcg_temp_new();
19466 TCGv t1
= tcg_temp_new();
19468 gen_load_gpr(t0
, rt
);
19469 gen_load_gpr(t1
, rs
);
19470 gen_helper_fork(t0
, t1
);
19477 check_cp0_enabled(ctx
);
19479 /* Treat as NOP. */
19482 gen_mftr(env
, ctx
, rs
, rt
, extract32(ctx
->opcode
, 10, 1),
19483 extract32(ctx
->opcode
, 11, 5), extract32(ctx
->opcode
, 3, 1));
19487 check_cp0_enabled(ctx
);
19488 gen_mttr(env
, ctx
, rs
, rt
, extract32(ctx
->opcode
, 10, 1),
19489 extract32(ctx
->opcode
, 11, 5), extract32(ctx
->opcode
, 3, 1));
19494 TCGv t0
= tcg_temp_new();
19496 gen_load_gpr(t0
, rs
);
19497 gen_helper_yield(t0
, cpu_env
, t0
);
19498 gen_store_gpr(t0
, rt
);
19504 gen_reserved_instruction(ctx
);
19510 static void gen_pool32axf_1_5_nanomips_insn(DisasContext
*ctx
, uint32_t opc
,
19511 int ret
, int v1
, int v2
)
19517 t0
= tcg_temp_new_i32();
19519 v0_t
= tcg_temp_new();
19520 v1_t
= tcg_temp_new();
19522 tcg_gen_movi_i32(t0
, v2
>> 3);
19524 gen_load_gpr(v0_t
, ret
);
19525 gen_load_gpr(v1_t
, v1
);
19528 case NM_MAQ_S_W_PHR
:
19530 gen_helper_maq_s_w_phr(t0
, v1_t
, v0_t
, cpu_env
);
19532 case NM_MAQ_S_W_PHL
:
19534 gen_helper_maq_s_w_phl(t0
, v1_t
, v0_t
, cpu_env
);
19536 case NM_MAQ_SA_W_PHR
:
19538 gen_helper_maq_sa_w_phr(t0
, v1_t
, v0_t
, cpu_env
);
19540 case NM_MAQ_SA_W_PHL
:
19542 gen_helper_maq_sa_w_phl(t0
, v1_t
, v0_t
, cpu_env
);
19545 gen_reserved_instruction(ctx
);
19549 tcg_temp_free_i32(t0
);
19551 tcg_temp_free(v0_t
);
19552 tcg_temp_free(v1_t
);
19556 static void gen_pool32axf_1_nanomips_insn(DisasContext
*ctx
, uint32_t opc
,
19557 int ret
, int v1
, int v2
)
19560 TCGv t0
= tcg_temp_new();
19561 TCGv t1
= tcg_temp_new();
19562 TCGv v0_t
= tcg_temp_new();
19564 gen_load_gpr(v0_t
, v1
);
19567 case NM_POOL32AXF_1_0
:
19569 switch (extract32(ctx
->opcode
, 12, 2)) {
19571 gen_HILO(ctx
, OPC_MFHI
, v2
>> 3, ret
);
19574 gen_HILO(ctx
, OPC_MFLO
, v2
>> 3, ret
);
19577 gen_HILO(ctx
, OPC_MTHI
, v2
>> 3, v1
);
19580 gen_HILO(ctx
, OPC_MTLO
, v2
>> 3, v1
);
19584 case NM_POOL32AXF_1_1
:
19586 switch (extract32(ctx
->opcode
, 12, 2)) {
19588 tcg_gen_movi_tl(t0
, v2
);
19589 gen_helper_mthlip(t0
, v0_t
, cpu_env
);
19592 tcg_gen_movi_tl(t0
, v2
>> 3);
19593 gen_helper_shilo(t0
, v0_t
, cpu_env
);
19596 gen_reserved_instruction(ctx
);
19600 case NM_POOL32AXF_1_3
:
19602 imm
= extract32(ctx
->opcode
, 14, 7);
19603 switch (extract32(ctx
->opcode
, 12, 2)) {
19605 tcg_gen_movi_tl(t0
, imm
);
19606 gen_helper_rddsp(t0
, t0
, cpu_env
);
19607 gen_store_gpr(t0
, ret
);
19610 gen_load_gpr(t0
, ret
);
19611 tcg_gen_movi_tl(t1
, imm
);
19612 gen_helper_wrdsp(t0
, t1
, cpu_env
);
19615 tcg_gen_movi_tl(t0
, v2
>> 3);
19616 tcg_gen_movi_tl(t1
, v1
);
19617 gen_helper_extp(t0
, t0
, t1
, cpu_env
);
19618 gen_store_gpr(t0
, ret
);
19621 tcg_gen_movi_tl(t0
, v2
>> 3);
19622 tcg_gen_movi_tl(t1
, v1
);
19623 gen_helper_extpdp(t0
, t0
, t1
, cpu_env
);
19624 gen_store_gpr(t0
, ret
);
19628 case NM_POOL32AXF_1_4
:
19630 tcg_gen_movi_tl(t0
, v2
>> 2);
19631 switch (extract32(ctx
->opcode
, 12, 1)) {
19633 gen_helper_shll_qb(t0
, t0
, v0_t
, cpu_env
);
19634 gen_store_gpr(t0
, ret
);
19637 gen_helper_shrl_qb(t0
, t0
, v0_t
);
19638 gen_store_gpr(t0
, ret
);
19642 case NM_POOL32AXF_1_5
:
19643 opc
= extract32(ctx
->opcode
, 12, 2);
19644 gen_pool32axf_1_5_nanomips_insn(ctx
, opc
, ret
, v1
, v2
);
19646 case NM_POOL32AXF_1_7
:
19648 tcg_gen_movi_tl(t0
, v2
>> 3);
19649 tcg_gen_movi_tl(t1
, v1
);
19650 switch (extract32(ctx
->opcode
, 12, 2)) {
19652 gen_helper_extr_w(t0
, t0
, t1
, cpu_env
);
19653 gen_store_gpr(t0
, ret
);
19656 gen_helper_extr_r_w(t0
, t0
, t1
, cpu_env
);
19657 gen_store_gpr(t0
, ret
);
19660 gen_helper_extr_rs_w(t0
, t0
, t1
, cpu_env
);
19661 gen_store_gpr(t0
, ret
);
19664 gen_helper_extr_s_h(t0
, t0
, t1
, cpu_env
);
19665 gen_store_gpr(t0
, ret
);
19670 gen_reserved_instruction(ctx
);
19676 tcg_temp_free(v0_t
);
19679 static void gen_pool32axf_2_multiply(DisasContext
*ctx
, uint32_t opc
,
19680 TCGv v0
, TCGv v1
, int rd
)
19684 t0
= tcg_temp_new_i32();
19686 tcg_gen_movi_i32(t0
, rd
>> 3);
19689 case NM_POOL32AXF_2_0_7
:
19690 switch (extract32(ctx
->opcode
, 9, 3)) {
19693 gen_helper_dpa_w_ph(t0
, v1
, v0
, cpu_env
);
19695 case NM_DPAQ_S_W_PH
:
19697 gen_helper_dpaq_s_w_ph(t0
, v1
, v0
, cpu_env
);
19701 gen_helper_dps_w_ph(t0
, v1
, v0
, cpu_env
);
19703 case NM_DPSQ_S_W_PH
:
19705 gen_helper_dpsq_s_w_ph(t0
, v1
, v0
, cpu_env
);
19708 gen_reserved_instruction(ctx
);
19712 case NM_POOL32AXF_2_8_15
:
19713 switch (extract32(ctx
->opcode
, 9, 3)) {
19716 gen_helper_dpax_w_ph(t0
, v0
, v1
, cpu_env
);
19718 case NM_DPAQ_SA_L_W
:
19720 gen_helper_dpaq_sa_l_w(t0
, v0
, v1
, cpu_env
);
19724 gen_helper_dpsx_w_ph(t0
, v0
, v1
, cpu_env
);
19726 case NM_DPSQ_SA_L_W
:
19728 gen_helper_dpsq_sa_l_w(t0
, v0
, v1
, cpu_env
);
19731 gen_reserved_instruction(ctx
);
19735 case NM_POOL32AXF_2_16_23
:
19736 switch (extract32(ctx
->opcode
, 9, 3)) {
19737 case NM_DPAU_H_QBL
:
19739 gen_helper_dpau_h_qbl(t0
, v0
, v1
, cpu_env
);
19741 case NM_DPAQX_S_W_PH
:
19743 gen_helper_dpaqx_s_w_ph(t0
, v0
, v1
, cpu_env
);
19745 case NM_DPSU_H_QBL
:
19747 gen_helper_dpsu_h_qbl(t0
, v0
, v1
, cpu_env
);
19749 case NM_DPSQX_S_W_PH
:
19751 gen_helper_dpsqx_s_w_ph(t0
, v0
, v1
, cpu_env
);
19753 case NM_MULSA_W_PH
:
19755 gen_helper_mulsa_w_ph(t0
, v0
, v1
, cpu_env
);
19758 gen_reserved_instruction(ctx
);
19762 case NM_POOL32AXF_2_24_31
:
19763 switch (extract32(ctx
->opcode
, 9, 3)) {
19764 case NM_DPAU_H_QBR
:
19766 gen_helper_dpau_h_qbr(t0
, v1
, v0
, cpu_env
);
19768 case NM_DPAQX_SA_W_PH
:
19770 gen_helper_dpaqx_sa_w_ph(t0
, v1
, v0
, cpu_env
);
19772 case NM_DPSU_H_QBR
:
19774 gen_helper_dpsu_h_qbr(t0
, v1
, v0
, cpu_env
);
19776 case NM_DPSQX_SA_W_PH
:
19778 gen_helper_dpsqx_sa_w_ph(t0
, v1
, v0
, cpu_env
);
19780 case NM_MULSAQ_S_W_PH
:
19782 gen_helper_mulsaq_s_w_ph(t0
, v1
, v0
, cpu_env
);
19785 gen_reserved_instruction(ctx
);
19790 gen_reserved_instruction(ctx
);
19794 tcg_temp_free_i32(t0
);
19797 static void gen_pool32axf_2_nanomips_insn(DisasContext
*ctx
, uint32_t opc
,
19798 int rt
, int rs
, int rd
)
19801 TCGv t0
= tcg_temp_new();
19802 TCGv t1
= tcg_temp_new();
19803 TCGv v0_t
= tcg_temp_new();
19804 TCGv v1_t
= tcg_temp_new();
19806 gen_load_gpr(v0_t
, rt
);
19807 gen_load_gpr(v1_t
, rs
);
19810 case NM_POOL32AXF_2_0_7
:
19811 switch (extract32(ctx
->opcode
, 9, 3)) {
19813 case NM_DPAQ_S_W_PH
:
19815 case NM_DPSQ_S_W_PH
:
19816 gen_pool32axf_2_multiply(ctx
, opc
, v0_t
, v1_t
, rd
);
19821 gen_load_gpr(t0
, rs
);
19823 if (rd
!= 0 && rd
!= 2) {
19824 tcg_gen_shli_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], 8 * rd
);
19825 tcg_gen_ext32u_tl(t0
, t0
);
19826 tcg_gen_shri_tl(t0
, t0
, 8 * (4 - rd
));
19827 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
19829 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
19835 int acc
= extract32(ctx
->opcode
, 14, 2);
19836 TCGv_i64 t2
= tcg_temp_new_i64();
19837 TCGv_i64 t3
= tcg_temp_new_i64();
19839 gen_load_gpr(t0
, rt
);
19840 gen_load_gpr(t1
, rs
);
19841 tcg_gen_ext_tl_i64(t2
, t0
);
19842 tcg_gen_ext_tl_i64(t3
, t1
);
19843 tcg_gen_mul_i64(t2
, t2
, t3
);
19844 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
19845 tcg_gen_add_i64(t2
, t2
, t3
);
19846 tcg_temp_free_i64(t3
);
19847 gen_move_low32(cpu_LO
[acc
], t2
);
19848 gen_move_high32(cpu_HI
[acc
], t2
);
19849 tcg_temp_free_i64(t2
);
19855 int acc
= extract32(ctx
->opcode
, 14, 2);
19856 TCGv_i32 t2
= tcg_temp_new_i32();
19857 TCGv_i32 t3
= tcg_temp_new_i32();
19859 gen_load_gpr(t0
, rs
);
19860 gen_load_gpr(t1
, rt
);
19861 tcg_gen_trunc_tl_i32(t2
, t0
);
19862 tcg_gen_trunc_tl_i32(t3
, t1
);
19863 tcg_gen_muls2_i32(t2
, t3
, t2
, t3
);
19864 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
19865 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
19866 tcg_temp_free_i32(t2
);
19867 tcg_temp_free_i32(t3
);
19872 gen_load_gpr(v1_t
, rs
);
19873 tcg_gen_movi_tl(t0
, rd
>> 3);
19874 gen_helper_extr_w(t0
, t0
, v1_t
, cpu_env
);
19875 gen_store_gpr(t0
, ret
);
19879 case NM_POOL32AXF_2_8_15
:
19880 switch (extract32(ctx
->opcode
, 9, 3)) {
19882 case NM_DPAQ_SA_L_W
:
19884 case NM_DPSQ_SA_L_W
:
19885 gen_pool32axf_2_multiply(ctx
, opc
, v0_t
, v1_t
, rd
);
19890 int acc
= extract32(ctx
->opcode
, 14, 2);
19891 TCGv_i64 t2
= tcg_temp_new_i64();
19892 TCGv_i64 t3
= tcg_temp_new_i64();
19894 gen_load_gpr(t0
, rs
);
19895 gen_load_gpr(t1
, rt
);
19896 tcg_gen_ext32u_tl(t0
, t0
);
19897 tcg_gen_ext32u_tl(t1
, t1
);
19898 tcg_gen_extu_tl_i64(t2
, t0
);
19899 tcg_gen_extu_tl_i64(t3
, t1
);
19900 tcg_gen_mul_i64(t2
, t2
, t3
);
19901 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
19902 tcg_gen_add_i64(t2
, t2
, t3
);
19903 tcg_temp_free_i64(t3
);
19904 gen_move_low32(cpu_LO
[acc
], t2
);
19905 gen_move_high32(cpu_HI
[acc
], t2
);
19906 tcg_temp_free_i64(t2
);
19912 int acc
= extract32(ctx
->opcode
, 14, 2);
19913 TCGv_i32 t2
= tcg_temp_new_i32();
19914 TCGv_i32 t3
= tcg_temp_new_i32();
19916 gen_load_gpr(t0
, rs
);
19917 gen_load_gpr(t1
, rt
);
19918 tcg_gen_trunc_tl_i32(t2
, t0
);
19919 tcg_gen_trunc_tl_i32(t3
, t1
);
19920 tcg_gen_mulu2_i32(t2
, t3
, t2
, t3
);
19921 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
19922 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
19923 tcg_temp_free_i32(t2
);
19924 tcg_temp_free_i32(t3
);
19929 tcg_gen_movi_tl(t0
, rd
>> 3);
19930 gen_helper_extr_r_w(t0
, t0
, v1_t
, cpu_env
);
19931 gen_store_gpr(t0
, ret
);
19934 gen_reserved_instruction(ctx
);
19938 case NM_POOL32AXF_2_16_23
:
19939 switch (extract32(ctx
->opcode
, 9, 3)) {
19940 case NM_DPAU_H_QBL
:
19941 case NM_DPAQX_S_W_PH
:
19942 case NM_DPSU_H_QBL
:
19943 case NM_DPSQX_S_W_PH
:
19944 case NM_MULSA_W_PH
:
19945 gen_pool32axf_2_multiply(ctx
, opc
, v0_t
, v1_t
, rd
);
19949 tcg_gen_movi_tl(t0
, rd
>> 3);
19950 gen_helper_extp(t0
, t0
, v1_t
, cpu_env
);
19951 gen_store_gpr(t0
, ret
);
19956 int acc
= extract32(ctx
->opcode
, 14, 2);
19957 TCGv_i64 t2
= tcg_temp_new_i64();
19958 TCGv_i64 t3
= tcg_temp_new_i64();
19960 gen_load_gpr(t0
, rs
);
19961 gen_load_gpr(t1
, rt
);
19962 tcg_gen_ext_tl_i64(t2
, t0
);
19963 tcg_gen_ext_tl_i64(t3
, t1
);
19964 tcg_gen_mul_i64(t2
, t2
, t3
);
19965 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
19966 tcg_gen_sub_i64(t2
, t3
, t2
);
19967 tcg_temp_free_i64(t3
);
19968 gen_move_low32(cpu_LO
[acc
], t2
);
19969 gen_move_high32(cpu_HI
[acc
], t2
);
19970 tcg_temp_free_i64(t2
);
19973 case NM_EXTRV_RS_W
:
19975 tcg_gen_movi_tl(t0
, rd
>> 3);
19976 gen_helper_extr_rs_w(t0
, t0
, v1_t
, cpu_env
);
19977 gen_store_gpr(t0
, ret
);
19981 case NM_POOL32AXF_2_24_31
:
19982 switch (extract32(ctx
->opcode
, 9, 3)) {
19983 case NM_DPAU_H_QBR
:
19984 case NM_DPAQX_SA_W_PH
:
19985 case NM_DPSU_H_QBR
:
19986 case NM_DPSQX_SA_W_PH
:
19987 case NM_MULSAQ_S_W_PH
:
19988 gen_pool32axf_2_multiply(ctx
, opc
, v0_t
, v1_t
, rd
);
19992 tcg_gen_movi_tl(t0
, rd
>> 3);
19993 gen_helper_extpdp(t0
, t0
, v1_t
, cpu_env
);
19994 gen_store_gpr(t0
, ret
);
19999 int acc
= extract32(ctx
->opcode
, 14, 2);
20000 TCGv_i64 t2
= tcg_temp_new_i64();
20001 TCGv_i64 t3
= tcg_temp_new_i64();
20003 gen_load_gpr(t0
, rs
);
20004 gen_load_gpr(t1
, rt
);
20005 tcg_gen_ext32u_tl(t0
, t0
);
20006 tcg_gen_ext32u_tl(t1
, t1
);
20007 tcg_gen_extu_tl_i64(t2
, t0
);
20008 tcg_gen_extu_tl_i64(t3
, t1
);
20009 tcg_gen_mul_i64(t2
, t2
, t3
);
20010 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
20011 tcg_gen_sub_i64(t2
, t3
, t2
);
20012 tcg_temp_free_i64(t3
);
20013 gen_move_low32(cpu_LO
[acc
], t2
);
20014 gen_move_high32(cpu_HI
[acc
], t2
);
20015 tcg_temp_free_i64(t2
);
20020 tcg_gen_movi_tl(t0
, rd
>> 3);
20021 gen_helper_extr_s_h(t0
, t0
, v0_t
, cpu_env
);
20022 gen_store_gpr(t0
, ret
);
20027 gen_reserved_instruction(ctx
);
20034 tcg_temp_free(v0_t
);
20035 tcg_temp_free(v1_t
);
20038 static void gen_pool32axf_4_nanomips_insn(DisasContext
*ctx
, uint32_t opc
,
20042 TCGv t0
= tcg_temp_new();
20043 TCGv v0_t
= tcg_temp_new();
20045 gen_load_gpr(v0_t
, rs
);
20050 gen_helper_absq_s_qb(v0_t
, v0_t
, cpu_env
);
20051 gen_store_gpr(v0_t
, ret
);
20055 gen_helper_absq_s_ph(v0_t
, v0_t
, cpu_env
);
20056 gen_store_gpr(v0_t
, ret
);
20060 gen_helper_absq_s_w(v0_t
, v0_t
, cpu_env
);
20061 gen_store_gpr(v0_t
, ret
);
20063 case NM_PRECEQ_W_PHL
:
20065 tcg_gen_andi_tl(v0_t
, v0_t
, 0xFFFF0000);
20066 tcg_gen_ext32s_tl(v0_t
, v0_t
);
20067 gen_store_gpr(v0_t
, ret
);
20069 case NM_PRECEQ_W_PHR
:
20071 tcg_gen_andi_tl(v0_t
, v0_t
, 0x0000FFFF);
20072 tcg_gen_shli_tl(v0_t
, v0_t
, 16);
20073 tcg_gen_ext32s_tl(v0_t
, v0_t
);
20074 gen_store_gpr(v0_t
, ret
);
20076 case NM_PRECEQU_PH_QBL
:
20078 gen_helper_precequ_ph_qbl(v0_t
, v0_t
);
20079 gen_store_gpr(v0_t
, ret
);
20081 case NM_PRECEQU_PH_QBR
:
20083 gen_helper_precequ_ph_qbr(v0_t
, v0_t
);
20084 gen_store_gpr(v0_t
, ret
);
20086 case NM_PRECEQU_PH_QBLA
:
20088 gen_helper_precequ_ph_qbla(v0_t
, v0_t
);
20089 gen_store_gpr(v0_t
, ret
);
20091 case NM_PRECEQU_PH_QBRA
:
20093 gen_helper_precequ_ph_qbra(v0_t
, v0_t
);
20094 gen_store_gpr(v0_t
, ret
);
20096 case NM_PRECEU_PH_QBL
:
20098 gen_helper_preceu_ph_qbl(v0_t
, v0_t
);
20099 gen_store_gpr(v0_t
, ret
);
20101 case NM_PRECEU_PH_QBR
:
20103 gen_helper_preceu_ph_qbr(v0_t
, v0_t
);
20104 gen_store_gpr(v0_t
, ret
);
20106 case NM_PRECEU_PH_QBLA
:
20108 gen_helper_preceu_ph_qbla(v0_t
, v0_t
);
20109 gen_store_gpr(v0_t
, ret
);
20111 case NM_PRECEU_PH_QBRA
:
20113 gen_helper_preceu_ph_qbra(v0_t
, v0_t
);
20114 gen_store_gpr(v0_t
, ret
);
20118 tcg_gen_ext16u_tl(v0_t
, v0_t
);
20119 tcg_gen_shli_tl(t0
, v0_t
, 16);
20120 tcg_gen_or_tl(v0_t
, v0_t
, t0
);
20121 tcg_gen_ext32s_tl(v0_t
, v0_t
);
20122 gen_store_gpr(v0_t
, ret
);
20126 tcg_gen_ext8u_tl(v0_t
, v0_t
);
20127 tcg_gen_shli_tl(t0
, v0_t
, 8);
20128 tcg_gen_or_tl(v0_t
, v0_t
, t0
);
20129 tcg_gen_shli_tl(t0
, v0_t
, 16);
20130 tcg_gen_or_tl(v0_t
, v0_t
, t0
);
20131 tcg_gen_ext32s_tl(v0_t
, v0_t
);
20132 gen_store_gpr(v0_t
, ret
);
20136 gen_helper_bitrev(v0_t
, v0_t
);
20137 gen_store_gpr(v0_t
, ret
);
20142 TCGv tv0
= tcg_temp_new();
20144 gen_load_gpr(tv0
, rt
);
20145 gen_helper_insv(v0_t
, cpu_env
, v0_t
, tv0
);
20146 gen_store_gpr(v0_t
, ret
);
20147 tcg_temp_free(tv0
);
20150 case NM_RADDU_W_QB
:
20152 gen_helper_raddu_w_qb(v0_t
, v0_t
);
20153 gen_store_gpr(v0_t
, ret
);
20156 gen_bitswap(ctx
, OPC_BITSWAP
, ret
, rs
);
20160 gen_cl(ctx
, OPC_CLO
, ret
, rs
);
20164 gen_cl(ctx
, OPC_CLZ
, ret
, rs
);
20167 gen_bshfl(ctx
, OPC_WSBH
, ret
, rs
);
20170 gen_reserved_instruction(ctx
);
20174 tcg_temp_free(v0_t
);
20178 static void gen_pool32axf_7_nanomips_insn(DisasContext
*ctx
, uint32_t opc
,
20179 int rt
, int rs
, int rd
)
20181 TCGv t0
= tcg_temp_new();
20182 TCGv rs_t
= tcg_temp_new();
20184 gen_load_gpr(rs_t
, rs
);
20189 tcg_gen_movi_tl(t0
, rd
>> 2);
20190 switch (extract32(ctx
->opcode
, 12, 1)) {
20193 gen_helper_shra_qb(t0
, t0
, rs_t
);
20194 gen_store_gpr(t0
, rt
);
20198 gen_helper_shra_r_qb(t0
, t0
, rs_t
);
20199 gen_store_gpr(t0
, rt
);
20205 tcg_gen_movi_tl(t0
, rd
>> 1);
20206 gen_helper_shrl_ph(t0
, t0
, rs_t
);
20207 gen_store_gpr(t0
, rt
);
20213 target_long result
;
20214 imm
= extract32(ctx
->opcode
, 13, 8);
20215 result
= (uint32_t)imm
<< 24 |
20216 (uint32_t)imm
<< 16 |
20217 (uint32_t)imm
<< 8 |
20219 result
= (int32_t)result
;
20220 tcg_gen_movi_tl(t0
, result
);
20221 gen_store_gpr(t0
, rt
);
20225 gen_reserved_instruction(ctx
);
20229 tcg_temp_free(rs_t
);
20233 static void gen_pool32axf_nanomips_insn(CPUMIPSState
*env
, DisasContext
*ctx
)
20235 int rt
= extract32(ctx
->opcode
, 21, 5);
20236 int rs
= extract32(ctx
->opcode
, 16, 5);
20237 int rd
= extract32(ctx
->opcode
, 11, 5);
20239 switch (extract32(ctx
->opcode
, 6, 3)) {
20240 case NM_POOL32AXF_1
:
20242 int32_t op1
= extract32(ctx
->opcode
, 9, 3);
20243 gen_pool32axf_1_nanomips_insn(ctx
, op1
, rt
, rs
, rd
);
20246 case NM_POOL32AXF_2
:
20248 int32_t op1
= extract32(ctx
->opcode
, 12, 2);
20249 gen_pool32axf_2_nanomips_insn(ctx
, op1
, rt
, rs
, rd
);
20252 case NM_POOL32AXF_4
:
20254 int32_t op1
= extract32(ctx
->opcode
, 9, 7);
20255 gen_pool32axf_4_nanomips_insn(ctx
, op1
, rt
, rs
);
20258 case NM_POOL32AXF_5
:
20259 switch (extract32(ctx
->opcode
, 9, 7)) {
20260 #ifndef CONFIG_USER_ONLY
20262 gen_cp0(env
, ctx
, OPC_TLBP
, 0, 0);
20265 gen_cp0(env
, ctx
, OPC_TLBR
, 0, 0);
20268 gen_cp0(env
, ctx
, OPC_TLBWI
, 0, 0);
20271 gen_cp0(env
, ctx
, OPC_TLBWR
, 0, 0);
20274 gen_cp0(env
, ctx
, OPC_TLBINV
, 0, 0);
20277 gen_cp0(env
, ctx
, OPC_TLBINVF
, 0, 0);
20280 check_cp0_enabled(ctx
);
20282 TCGv t0
= tcg_temp_new();
20284 save_cpu_state(ctx
, 1);
20285 gen_helper_di(t0
, cpu_env
);
20286 gen_store_gpr(t0
, rt
);
20287 /* Stop translation as we may have switched the execution mode */
20288 ctx
->base
.is_jmp
= DISAS_STOP
;
20293 check_cp0_enabled(ctx
);
20295 TCGv t0
= tcg_temp_new();
20297 save_cpu_state(ctx
, 1);
20298 gen_helper_ei(t0
, cpu_env
);
20299 gen_store_gpr(t0
, rt
);
20300 /* Stop translation as we may have switched the execution mode */
20301 ctx
->base
.is_jmp
= DISAS_STOP
;
20306 gen_load_srsgpr(rs
, rt
);
20309 gen_store_srsgpr(rs
, rt
);
20312 gen_cp0(env
, ctx
, OPC_WAIT
, 0, 0);
20315 gen_cp0(env
, ctx
, OPC_DERET
, 0, 0);
20318 gen_cp0(env
, ctx
, OPC_ERET
, 0, 0);
20322 gen_reserved_instruction(ctx
);
20326 case NM_POOL32AXF_7
:
20328 int32_t op1
= extract32(ctx
->opcode
, 9, 3);
20329 gen_pool32axf_7_nanomips_insn(ctx
, op1
, rt
, rs
, rd
);
20333 gen_reserved_instruction(ctx
);
20338 /* Immediate Value Compact Branches */
20339 static void gen_compute_imm_branch(DisasContext
*ctx
, uint32_t opc
,
20340 int rt
, int32_t imm
, int32_t offset
)
20342 TCGCond cond
= TCG_COND_ALWAYS
;
20343 TCGv t0
= tcg_temp_new();
20344 TCGv t1
= tcg_temp_new();
20346 gen_load_gpr(t0
, rt
);
20347 tcg_gen_movi_tl(t1
, imm
);
20348 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
20350 /* Load needed operands and calculate btarget */
20353 if (rt
== 0 && imm
== 0) {
20354 /* Unconditional branch */
20355 } else if (rt
== 0 && imm
!= 0) {
20359 cond
= TCG_COND_EQ
;
20365 if (imm
>= 32 && !(ctx
->hflags
& MIPS_HFLAG_64
)) {
20366 gen_reserved_instruction(ctx
);
20368 } else if (rt
== 0 && opc
== NM_BBEQZC
) {
20369 /* Unconditional branch */
20370 } else if (rt
== 0 && opc
== NM_BBNEZC
) {
20374 tcg_gen_shri_tl(t0
, t0
, imm
);
20375 tcg_gen_andi_tl(t0
, t0
, 1);
20376 tcg_gen_movi_tl(t1
, 0);
20377 if (opc
== NM_BBEQZC
) {
20378 cond
= TCG_COND_EQ
;
20380 cond
= TCG_COND_NE
;
20385 if (rt
== 0 && imm
== 0) {
20388 } else if (rt
== 0 && imm
!= 0) {
20389 /* Unconditional branch */
20391 cond
= TCG_COND_NE
;
20395 if (rt
== 0 && imm
== 0) {
20396 /* Unconditional branch */
20398 cond
= TCG_COND_GE
;
20402 cond
= TCG_COND_LT
;
20405 if (rt
== 0 && imm
== 0) {
20406 /* Unconditional branch */
20408 cond
= TCG_COND_GEU
;
20412 cond
= TCG_COND_LTU
;
20415 MIPS_INVAL("Immediate Value Compact branch");
20416 gen_reserved_instruction(ctx
);
20420 /* branch completion */
20421 clear_branch_hflags(ctx
);
20422 ctx
->base
.is_jmp
= DISAS_NORETURN
;
20424 if (cond
== TCG_COND_ALWAYS
) {
20425 /* Uncoditional compact branch */
20426 gen_goto_tb(ctx
, 0, ctx
->btarget
);
20428 /* Conditional compact branch */
20429 TCGLabel
*fs
= gen_new_label();
20431 tcg_gen_brcond_tl(tcg_invert_cond(cond
), t0
, t1
, fs
);
20433 gen_goto_tb(ctx
, 1, ctx
->btarget
);
20436 gen_goto_tb(ctx
, 0, ctx
->base
.pc_next
+ 4);
20444 /* P.BALRSC type nanoMIPS R6 branches: BALRSC and BRSC */
20445 static void gen_compute_nanomips_pbalrsc_branch(DisasContext
*ctx
, int rs
,
20448 TCGv t0
= tcg_temp_new();
20449 TCGv t1
= tcg_temp_new();
20452 gen_load_gpr(t0
, rs
);
20456 tcg_gen_movi_tl(cpu_gpr
[rt
], ctx
->base
.pc_next
+ 4);
20459 /* calculate btarget */
20460 tcg_gen_shli_tl(t0
, t0
, 1);
20461 tcg_gen_movi_tl(t1
, ctx
->base
.pc_next
+ 4);
20462 gen_op_addr_add(ctx
, btarget
, t1
, t0
);
20464 /* branch completion */
20465 clear_branch_hflags(ctx
);
20466 ctx
->base
.is_jmp
= DISAS_NORETURN
;
20468 /* unconditional branch to register */
20469 tcg_gen_mov_tl(cpu_PC
, btarget
);
20470 tcg_gen_lookup_and_goto_ptr();
20476 /* nanoMIPS Branches */
20477 static void gen_compute_compact_branch_nm(DisasContext
*ctx
, uint32_t opc
,
20478 int rs
, int rt
, int32_t offset
)
20480 int bcond_compute
= 0;
20481 TCGv t0
= tcg_temp_new();
20482 TCGv t1
= tcg_temp_new();
20484 /* Load needed operands and calculate btarget */
20486 /* compact branch */
20489 gen_load_gpr(t0
, rs
);
20490 gen_load_gpr(t1
, rt
);
20492 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
20496 if (rs
== 0 || rs
== rt
) {
20497 /* OPC_BLEZALC, OPC_BGEZALC */
20498 /* OPC_BGTZALC, OPC_BLTZALC */
20499 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 4);
20501 gen_load_gpr(t0
, rs
);
20502 gen_load_gpr(t1
, rt
);
20504 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
20507 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
20511 /* OPC_BEQZC, OPC_BNEZC */
20512 gen_load_gpr(t0
, rs
);
20514 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
20516 /* OPC_JIC, OPC_JIALC */
20517 TCGv tbase
= tcg_temp_new();
20518 TCGv toffset
= tcg_temp_new();
20520 gen_load_gpr(tbase
, rt
);
20521 tcg_gen_movi_tl(toffset
, offset
);
20522 gen_op_addr_add(ctx
, btarget
, tbase
, toffset
);
20523 tcg_temp_free(tbase
);
20524 tcg_temp_free(toffset
);
20528 MIPS_INVAL("Compact branch/jump");
20529 gen_reserved_instruction(ctx
);
20533 if (bcond_compute
== 0) {
20534 /* Uncoditional compact branch */
20537 gen_goto_tb(ctx
, 0, ctx
->btarget
);
20540 MIPS_INVAL("Compact branch/jump");
20541 gen_reserved_instruction(ctx
);
20545 /* Conditional compact branch */
20546 TCGLabel
*fs
= gen_new_label();
20550 if (rs
== 0 && rt
!= 0) {
20552 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE
), t1
, 0, fs
);
20553 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
20555 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE
), t1
, 0, fs
);
20558 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU
), t0
, t1
, fs
);
20562 if (rs
== 0 && rt
!= 0) {
20564 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT
), t1
, 0, fs
);
20565 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
20567 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT
), t1
, 0, fs
);
20570 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU
), t0
, t1
, fs
);
20574 if (rs
== 0 && rt
!= 0) {
20576 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE
), t1
, 0, fs
);
20577 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
20579 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE
), t1
, 0, fs
);
20582 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE
), t0
, t1
, fs
);
20586 if (rs
== 0 && rt
!= 0) {
20588 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT
), t1
, 0, fs
);
20589 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
20591 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT
), t1
, 0, fs
);
20594 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT
), t0
, t1
, fs
);
20598 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ
), t0
, 0, fs
);
20601 MIPS_INVAL("Compact conditional branch/jump");
20602 gen_reserved_instruction(ctx
);
20606 /* branch completion */
20607 clear_branch_hflags(ctx
);
20608 ctx
->base
.is_jmp
= DISAS_NORETURN
;
20610 /* Generating branch here as compact branches don't have delay slot */
20611 gen_goto_tb(ctx
, 1, ctx
->btarget
);
20614 gen_goto_tb(ctx
, 0, ctx
->base
.pc_next
+ 4);
20623 /* nanoMIPS CP1 Branches */
20624 static void gen_compute_branch_cp1_nm(DisasContext
*ctx
, uint32_t op
,
20625 int32_t ft
, int32_t offset
)
20627 target_ulong btarget
;
20628 TCGv_i64 t0
= tcg_temp_new_i64();
20630 gen_load_fpr64(ctx
, t0
, ft
);
20631 tcg_gen_andi_i64(t0
, t0
, 1);
20633 btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
20637 tcg_gen_xori_i64(t0
, t0
, 1);
20638 ctx
->hflags
|= MIPS_HFLAG_BC
;
20641 /* t0 already set */
20642 ctx
->hflags
|= MIPS_HFLAG_BC
;
20645 MIPS_INVAL("cp1 cond branch");
20646 gen_reserved_instruction(ctx
);
20650 tcg_gen_trunc_i64_tl(bcond
, t0
);
20652 ctx
->btarget
= btarget
;
20655 tcg_temp_free_i64(t0
);
20659 static void gen_p_lsx(DisasContext
*ctx
, int rd
, int rs
, int rt
)
20662 t0
= tcg_temp_new();
20663 t1
= tcg_temp_new();
20665 gen_load_gpr(t0
, rs
);
20666 gen_load_gpr(t1
, rt
);
20668 if ((extract32(ctx
->opcode
, 6, 1)) == 1) {
20669 /* PP.LSXS instructions require shifting */
20670 switch (extract32(ctx
->opcode
, 7, 4)) {
20676 tcg_gen_shli_tl(t0
, t0
, 1);
20684 tcg_gen_shli_tl(t0
, t0
, 2);
20688 tcg_gen_shli_tl(t0
, t0
, 3);
20692 gen_op_addr_add(ctx
, t0
, t0
, t1
);
20694 switch (extract32(ctx
->opcode
, 7, 4)) {
20696 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
,
20698 gen_store_gpr(t0
, rd
);
20702 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
,
20704 gen_store_gpr(t0
, rd
);
20708 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
,
20710 gen_store_gpr(t0
, rd
);
20713 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
,
20715 gen_store_gpr(t0
, rd
);
20719 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
,
20721 gen_store_gpr(t0
, rd
);
20725 gen_load_gpr(t1
, rd
);
20726 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
,
20732 gen_load_gpr(t1
, rd
);
20733 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
,
20739 gen_load_gpr(t1
, rd
);
20740 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
,
20744 /*case NM_LWC1XS:*/
20746 /*case NM_LDC1XS:*/
20748 /*case NM_SWC1XS:*/
20750 /*case NM_SDC1XS:*/
20751 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
20752 check_cp1_enabled(ctx
);
20753 switch (extract32(ctx
->opcode
, 7, 4)) {
20755 /*case NM_LWC1XS:*/
20756 gen_flt_ldst(ctx
, OPC_LWC1
, rd
, t0
);
20759 /*case NM_LDC1XS:*/
20760 gen_flt_ldst(ctx
, OPC_LDC1
, rd
, t0
);
20763 /*case NM_SWC1XS:*/
20764 gen_flt_ldst(ctx
, OPC_SWC1
, rd
, t0
);
20767 /*case NM_SDC1XS:*/
20768 gen_flt_ldst(ctx
, OPC_SDC1
, rd
, t0
);
20772 generate_exception_err(ctx
, EXCP_CpU
, 1);
20776 gen_reserved_instruction(ctx
);
20784 static void gen_pool32f_nanomips_insn(DisasContext
*ctx
)
20788 rt
= extract32(ctx
->opcode
, 21, 5);
20789 rs
= extract32(ctx
->opcode
, 16, 5);
20790 rd
= extract32(ctx
->opcode
, 11, 5);
20792 if (!(ctx
->CP0_Config1
& (1 << CP0C1_FP
))) {
20793 gen_reserved_instruction(ctx
);
20796 check_cp1_enabled(ctx
);
20797 switch (extract32(ctx
->opcode
, 0, 3)) {
20799 switch (extract32(ctx
->opcode
, 3, 7)) {
20801 gen_farith(ctx
, OPC_RINT_S
, 0, rt
, rs
, 0);
20804 gen_farith(ctx
, OPC_RINT_D
, 0, rt
, rs
, 0);
20807 gen_farith(ctx
, OPC_CLASS_S
, 0, rt
, rs
, 0);
20810 gen_farith(ctx
, OPC_CLASS_D
, 0, rt
, rs
, 0);
20813 gen_farith(ctx
, OPC_ADD_S
, rt
, rs
, rd
, 0);
20816 gen_farith(ctx
, OPC_ADD_D
, rt
, rs
, rd
, 0);
20819 gen_farith(ctx
, OPC_SUB_S
, rt
, rs
, rd
, 0);
20822 gen_farith(ctx
, OPC_SUB_D
, rt
, rs
, rd
, 0);
20825 gen_farith(ctx
, OPC_MUL_S
, rt
, rs
, rd
, 0);
20828 gen_farith(ctx
, OPC_MUL_D
, rt
, rs
, rd
, 0);
20831 gen_farith(ctx
, OPC_DIV_S
, rt
, rs
, rd
, 0);
20834 gen_farith(ctx
, OPC_DIV_D
, rt
, rs
, rd
, 0);
20837 gen_sel_s(ctx
, OPC_SELEQZ_S
, rd
, rt
, rs
);
20840 gen_sel_d(ctx
, OPC_SELEQZ_D
, rd
, rt
, rs
);
20843 gen_sel_s(ctx
, OPC_SELNEZ_S
, rd
, rt
, rs
);
20846 gen_sel_d(ctx
, OPC_SELNEZ_D
, rd
, rt
, rs
);
20849 gen_sel_s(ctx
, OPC_SEL_S
, rd
, rt
, rs
);
20852 gen_sel_d(ctx
, OPC_SEL_D
, rd
, rt
, rs
);
20855 gen_farith(ctx
, OPC_MADDF_S
, rt
, rs
, rd
, 0);
20858 gen_farith(ctx
, OPC_MADDF_D
, rt
, rs
, rd
, 0);
20861 gen_farith(ctx
, OPC_MSUBF_S
, rt
, rs
, rd
, 0);
20864 gen_farith(ctx
, OPC_MSUBF_D
, rt
, rs
, rd
, 0);
20867 gen_reserved_instruction(ctx
);
20872 switch (extract32(ctx
->opcode
, 3, 3)) {
20874 switch (extract32(ctx
->opcode
, 9, 1)) {
20876 gen_farith(ctx
, OPC_MIN_S
, rt
, rs
, rd
, 0);
20879 gen_farith(ctx
, OPC_MIN_D
, rt
, rs
, rd
, 0);
20884 switch (extract32(ctx
->opcode
, 9, 1)) {
20886 gen_farith(ctx
, OPC_MAX_S
, rt
, rs
, rd
, 0);
20889 gen_farith(ctx
, OPC_MAX_D
, rt
, rs
, rd
, 0);
20894 switch (extract32(ctx
->opcode
, 9, 1)) {
20896 gen_farith(ctx
, OPC_MINA_S
, rt
, rs
, rd
, 0);
20899 gen_farith(ctx
, OPC_MINA_D
, rt
, rs
, rd
, 0);
20904 switch (extract32(ctx
->opcode
, 9, 1)) {
20906 gen_farith(ctx
, OPC_MAXA_S
, rt
, rs
, rd
, 0);
20909 gen_farith(ctx
, OPC_MAXA_D
, rt
, rs
, rd
, 0);
20914 switch (extract32(ctx
->opcode
, 6, 8)) {
20916 gen_cp1(ctx
, OPC_CFC1
, rt
, rs
);
20919 gen_cp1(ctx
, OPC_CTC1
, rt
, rs
);
20922 gen_cp1(ctx
, OPC_MFC1
, rt
, rs
);
20925 gen_cp1(ctx
, OPC_MTC1
, rt
, rs
);
20928 gen_cp1(ctx
, OPC_MFHC1
, rt
, rs
);
20931 gen_cp1(ctx
, OPC_MTHC1
, rt
, rs
);
20934 gen_farith(ctx
, OPC_CVT_S_PL
, -1, rs
, rt
, 0);
20937 gen_farith(ctx
, OPC_CVT_S_PU
, -1, rs
, rt
, 0);
20940 switch (extract32(ctx
->opcode
, 6, 9)) {
20942 gen_farith(ctx
, OPC_CVT_L_S
, -1, rs
, rt
, 0);
20945 gen_farith(ctx
, OPC_CVT_L_D
, -1, rs
, rt
, 0);
20948 gen_farith(ctx
, OPC_CVT_W_S
, -1, rs
, rt
, 0);
20951 gen_farith(ctx
, OPC_CVT_W_D
, -1, rs
, rt
, 0);
20954 gen_farith(ctx
, OPC_RSQRT_S
, -1, rs
, rt
, 0);
20957 gen_farith(ctx
, OPC_RSQRT_D
, -1, rs
, rt
, 0);
20960 gen_farith(ctx
, OPC_SQRT_S
, -1, rs
, rt
, 0);
20963 gen_farith(ctx
, OPC_SQRT_D
, -1, rs
, rt
, 0);
20966 gen_farith(ctx
, OPC_RECIP_S
, -1, rs
, rt
, 0);
20969 gen_farith(ctx
, OPC_RECIP_D
, -1, rs
, rt
, 0);
20972 gen_farith(ctx
, OPC_FLOOR_L_S
, -1, rs
, rt
, 0);
20975 gen_farith(ctx
, OPC_FLOOR_L_D
, -1, rs
, rt
, 0);
20978 gen_farith(ctx
, OPC_FLOOR_W_S
, -1, rs
, rt
, 0);
20981 gen_farith(ctx
, OPC_FLOOR_W_D
, -1, rs
, rt
, 0);
20984 gen_farith(ctx
, OPC_CEIL_L_S
, -1, rs
, rt
, 0);
20987 gen_farith(ctx
, OPC_CEIL_L_D
, -1, rs
, rt
, 0);
20990 gen_farith(ctx
, OPC_CEIL_W_S
, -1, rs
, rt
, 0);
20993 gen_farith(ctx
, OPC_CEIL_W_D
, -1, rs
, rt
, 0);
20996 gen_farith(ctx
, OPC_TRUNC_L_S
, -1, rs
, rt
, 0);
20999 gen_farith(ctx
, OPC_TRUNC_L_D
, -1, rs
, rt
, 0);
21002 gen_farith(ctx
, OPC_TRUNC_W_S
, -1, rs
, rt
, 0);
21005 gen_farith(ctx
, OPC_TRUNC_W_D
, -1, rs
, rt
, 0);
21008 gen_farith(ctx
, OPC_ROUND_L_S
, -1, rs
, rt
, 0);
21011 gen_farith(ctx
, OPC_ROUND_L_D
, -1, rs
, rt
, 0);
21014 gen_farith(ctx
, OPC_ROUND_W_S
, -1, rs
, rt
, 0);
21017 gen_farith(ctx
, OPC_ROUND_W_D
, -1, rs
, rt
, 0);
21020 gen_farith(ctx
, OPC_MOV_S
, -1, rs
, rt
, 0);
21023 gen_farith(ctx
, OPC_MOV_D
, -1, rs
, rt
, 0);
21026 gen_farith(ctx
, OPC_ABS_S
, -1, rs
, rt
, 0);
21029 gen_farith(ctx
, OPC_ABS_D
, -1, rs
, rt
, 0);
21032 gen_farith(ctx
, OPC_NEG_S
, -1, rs
, rt
, 0);
21035 gen_farith(ctx
, OPC_NEG_D
, -1, rs
, rt
, 0);
21038 gen_farith(ctx
, OPC_CVT_D_S
, -1, rs
, rt
, 0);
21041 gen_farith(ctx
, OPC_CVT_D_W
, -1, rs
, rt
, 0);
21044 gen_farith(ctx
, OPC_CVT_D_L
, -1, rs
, rt
, 0);
21047 gen_farith(ctx
, OPC_CVT_S_D
, -1, rs
, rt
, 0);
21050 gen_farith(ctx
, OPC_CVT_S_W
, -1, rs
, rt
, 0);
21053 gen_farith(ctx
, OPC_CVT_S_L
, -1, rs
, rt
, 0);
21056 gen_reserved_instruction(ctx
);
21065 switch (extract32(ctx
->opcode
, 3, 3)) {
21066 case NM_CMP_CONDN_S
:
21067 gen_r6_cmp_s(ctx
, extract32(ctx
->opcode
, 6, 5), rt
, rs
, rd
);
21069 case NM_CMP_CONDN_D
:
21070 gen_r6_cmp_d(ctx
, extract32(ctx
->opcode
, 6, 5), rt
, rs
, rd
);
21073 gen_reserved_instruction(ctx
);
21078 gen_reserved_instruction(ctx
);
21083 static void gen_pool32a5_nanomips_insn(DisasContext
*ctx
, int opc
,
21084 int rd
, int rs
, int rt
)
21087 TCGv t0
= tcg_temp_new();
21088 TCGv v1_t
= tcg_temp_new();
21089 TCGv v2_t
= tcg_temp_new();
21091 gen_load_gpr(v1_t
, rs
);
21092 gen_load_gpr(v2_t
, rt
);
21097 gen_helper_cmp_eq_ph(v1_t
, v2_t
, cpu_env
);
21101 gen_helper_cmp_lt_ph(v1_t
, v2_t
, cpu_env
);
21105 gen_helper_cmp_le_ph(v1_t
, v2_t
, cpu_env
);
21107 case NM_CMPU_EQ_QB
:
21109 gen_helper_cmpu_eq_qb(v1_t
, v2_t
, cpu_env
);
21111 case NM_CMPU_LT_QB
:
21113 gen_helper_cmpu_lt_qb(v1_t
, v2_t
, cpu_env
);
21115 case NM_CMPU_LE_QB
:
21117 gen_helper_cmpu_le_qb(v1_t
, v2_t
, cpu_env
);
21119 case NM_CMPGU_EQ_QB
:
21121 gen_helper_cmpgu_eq_qb(v1_t
, v1_t
, v2_t
);
21122 gen_store_gpr(v1_t
, ret
);
21124 case NM_CMPGU_LT_QB
:
21126 gen_helper_cmpgu_lt_qb(v1_t
, v1_t
, v2_t
);
21127 gen_store_gpr(v1_t
, ret
);
21129 case NM_CMPGU_LE_QB
:
21131 gen_helper_cmpgu_le_qb(v1_t
, v1_t
, v2_t
);
21132 gen_store_gpr(v1_t
, ret
);
21134 case NM_CMPGDU_EQ_QB
:
21136 gen_helper_cmpgu_eq_qb(v1_t
, v1_t
, v2_t
);
21137 tcg_gen_deposit_tl(cpu_dspctrl
, cpu_dspctrl
, v1_t
, 24, 4);
21138 gen_store_gpr(v1_t
, ret
);
21140 case NM_CMPGDU_LT_QB
:
21142 gen_helper_cmpgu_lt_qb(v1_t
, v1_t
, v2_t
);
21143 tcg_gen_deposit_tl(cpu_dspctrl
, cpu_dspctrl
, v1_t
, 24, 4);
21144 gen_store_gpr(v1_t
, ret
);
21146 case NM_CMPGDU_LE_QB
:
21148 gen_helper_cmpgu_le_qb(v1_t
, v1_t
, v2_t
);
21149 tcg_gen_deposit_tl(cpu_dspctrl
, cpu_dspctrl
, v1_t
, 24, 4);
21150 gen_store_gpr(v1_t
, ret
);
21154 gen_helper_packrl_ph(v1_t
, v1_t
, v2_t
);
21155 gen_store_gpr(v1_t
, ret
);
21159 gen_helper_pick_qb(v1_t
, v1_t
, v2_t
, cpu_env
);
21160 gen_store_gpr(v1_t
, ret
);
21164 gen_helper_pick_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21165 gen_store_gpr(v1_t
, ret
);
21169 gen_helper_addq_s_w(v1_t
, v1_t
, v2_t
, cpu_env
);
21170 gen_store_gpr(v1_t
, ret
);
21174 gen_helper_subq_s_w(v1_t
, v1_t
, v2_t
, cpu_env
);
21175 gen_store_gpr(v1_t
, ret
);
21179 gen_helper_addsc(v1_t
, v1_t
, v2_t
, cpu_env
);
21180 gen_store_gpr(v1_t
, ret
);
21184 gen_helper_addwc(v1_t
, v1_t
, v2_t
, cpu_env
);
21185 gen_store_gpr(v1_t
, ret
);
21189 switch (extract32(ctx
->opcode
, 10, 1)) {
21192 gen_helper_addq_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21193 gen_store_gpr(v1_t
, ret
);
21197 gen_helper_addq_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21198 gen_store_gpr(v1_t
, ret
);
21202 case NM_ADDQH_R_PH
:
21204 switch (extract32(ctx
->opcode
, 10, 1)) {
21207 gen_helper_addqh_ph(v1_t
, v1_t
, v2_t
);
21208 gen_store_gpr(v1_t
, ret
);
21212 gen_helper_addqh_r_ph(v1_t
, v1_t
, v2_t
);
21213 gen_store_gpr(v1_t
, ret
);
21219 switch (extract32(ctx
->opcode
, 10, 1)) {
21222 gen_helper_addqh_w(v1_t
, v1_t
, v2_t
);
21223 gen_store_gpr(v1_t
, ret
);
21227 gen_helper_addqh_r_w(v1_t
, v1_t
, v2_t
);
21228 gen_store_gpr(v1_t
, ret
);
21234 switch (extract32(ctx
->opcode
, 10, 1)) {
21237 gen_helper_addu_qb(v1_t
, v1_t
, v2_t
, cpu_env
);
21238 gen_store_gpr(v1_t
, ret
);
21242 gen_helper_addu_s_qb(v1_t
, v1_t
, v2_t
, cpu_env
);
21243 gen_store_gpr(v1_t
, ret
);
21249 switch (extract32(ctx
->opcode
, 10, 1)) {
21252 gen_helper_addu_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21253 gen_store_gpr(v1_t
, ret
);
21257 gen_helper_addu_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21258 gen_store_gpr(v1_t
, ret
);
21262 case NM_ADDUH_R_QB
:
21264 switch (extract32(ctx
->opcode
, 10, 1)) {
21267 gen_helper_adduh_qb(v1_t
, v1_t
, v2_t
);
21268 gen_store_gpr(v1_t
, ret
);
21272 gen_helper_adduh_r_qb(v1_t
, v1_t
, v2_t
);
21273 gen_store_gpr(v1_t
, ret
);
21277 case NM_SHRAV_R_PH
:
21279 switch (extract32(ctx
->opcode
, 10, 1)) {
21282 gen_helper_shra_ph(v1_t
, v1_t
, v2_t
);
21283 gen_store_gpr(v1_t
, ret
);
21287 gen_helper_shra_r_ph(v1_t
, v1_t
, v2_t
);
21288 gen_store_gpr(v1_t
, ret
);
21292 case NM_SHRAV_R_QB
:
21294 switch (extract32(ctx
->opcode
, 10, 1)) {
21297 gen_helper_shra_qb(v1_t
, v1_t
, v2_t
);
21298 gen_store_gpr(v1_t
, ret
);
21302 gen_helper_shra_r_qb(v1_t
, v1_t
, v2_t
);
21303 gen_store_gpr(v1_t
, ret
);
21309 switch (extract32(ctx
->opcode
, 10, 1)) {
21312 gen_helper_subq_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21313 gen_store_gpr(v1_t
, ret
);
21317 gen_helper_subq_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21318 gen_store_gpr(v1_t
, ret
);
21322 case NM_SUBQH_R_PH
:
21324 switch (extract32(ctx
->opcode
, 10, 1)) {
21327 gen_helper_subqh_ph(v1_t
, v1_t
, v2_t
);
21328 gen_store_gpr(v1_t
, ret
);
21332 gen_helper_subqh_r_ph(v1_t
, v1_t
, v2_t
);
21333 gen_store_gpr(v1_t
, ret
);
21339 switch (extract32(ctx
->opcode
, 10, 1)) {
21342 gen_helper_subqh_w(v1_t
, v1_t
, v2_t
);
21343 gen_store_gpr(v1_t
, ret
);
21347 gen_helper_subqh_r_w(v1_t
, v1_t
, v2_t
);
21348 gen_store_gpr(v1_t
, ret
);
21354 switch (extract32(ctx
->opcode
, 10, 1)) {
21357 gen_helper_subu_qb(v1_t
, v1_t
, v2_t
, cpu_env
);
21358 gen_store_gpr(v1_t
, ret
);
21362 gen_helper_subu_s_qb(v1_t
, v1_t
, v2_t
, cpu_env
);
21363 gen_store_gpr(v1_t
, ret
);
21369 switch (extract32(ctx
->opcode
, 10, 1)) {
21372 gen_helper_subu_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21373 gen_store_gpr(v1_t
, ret
);
21377 gen_helper_subu_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21378 gen_store_gpr(v1_t
, ret
);
21382 case NM_SUBUH_R_QB
:
21384 switch (extract32(ctx
->opcode
, 10, 1)) {
21387 gen_helper_subuh_qb(v1_t
, v1_t
, v2_t
);
21388 gen_store_gpr(v1_t
, ret
);
21392 gen_helper_subuh_r_qb(v1_t
, v1_t
, v2_t
);
21393 gen_store_gpr(v1_t
, ret
);
21397 case NM_SHLLV_S_PH
:
21399 switch (extract32(ctx
->opcode
, 10, 1)) {
21402 gen_helper_shll_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21403 gen_store_gpr(v1_t
, ret
);
21407 gen_helper_shll_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21408 gen_store_gpr(v1_t
, ret
);
21412 case NM_PRECR_SRA_R_PH_W
:
21414 switch (extract32(ctx
->opcode
, 10, 1)) {
21416 /* PRECR_SRA_PH_W */
21418 TCGv_i32 sa_t
= tcg_const_i32(rd
);
21419 gen_helper_precr_sra_ph_w(v1_t
, sa_t
, v1_t
,
21421 gen_store_gpr(v1_t
, rt
);
21422 tcg_temp_free_i32(sa_t
);
21426 /* PRECR_SRA_R_PH_W */
21428 TCGv_i32 sa_t
= tcg_const_i32(rd
);
21429 gen_helper_precr_sra_r_ph_w(v1_t
, sa_t
, v1_t
,
21431 gen_store_gpr(v1_t
, rt
);
21432 tcg_temp_free_i32(sa_t
);
21437 case NM_MULEU_S_PH_QBL
:
21439 gen_helper_muleu_s_ph_qbl(v1_t
, v1_t
, v2_t
, cpu_env
);
21440 gen_store_gpr(v1_t
, ret
);
21442 case NM_MULEU_S_PH_QBR
:
21444 gen_helper_muleu_s_ph_qbr(v1_t
, v1_t
, v2_t
, cpu_env
);
21445 gen_store_gpr(v1_t
, ret
);
21447 case NM_MULQ_RS_PH
:
21449 gen_helper_mulq_rs_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21450 gen_store_gpr(v1_t
, ret
);
21454 gen_helper_mulq_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21455 gen_store_gpr(v1_t
, ret
);
21459 gen_helper_mulq_rs_w(v1_t
, v1_t
, v2_t
, cpu_env
);
21460 gen_store_gpr(v1_t
, ret
);
21464 gen_helper_mulq_s_w(v1_t
, v1_t
, v2_t
, cpu_env
);
21465 gen_store_gpr(v1_t
, ret
);
21469 gen_load_gpr(t0
, rs
);
21471 tcg_gen_deposit_tl(cpu_gpr
[rt
], t0
, cpu_gpr
[rt
], rd
, 32 - rd
);
21473 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
21477 gen_helper_modsub(v1_t
, v1_t
, v2_t
);
21478 gen_store_gpr(v1_t
, ret
);
21482 gen_helper_shra_r_w(v1_t
, v1_t
, v2_t
);
21483 gen_store_gpr(v1_t
, ret
);
21487 gen_helper_shrl_ph(v1_t
, v1_t
, v2_t
);
21488 gen_store_gpr(v1_t
, ret
);
21492 gen_helper_shrl_qb(v1_t
, v1_t
, v2_t
);
21493 gen_store_gpr(v1_t
, ret
);
21497 gen_helper_shll_qb(v1_t
, v1_t
, v2_t
, cpu_env
);
21498 gen_store_gpr(v1_t
, ret
);
21502 gen_helper_shll_s_w(v1_t
, v1_t
, v2_t
, cpu_env
);
21503 gen_store_gpr(v1_t
, ret
);
21508 TCGv tv0
= tcg_temp_new();
21509 TCGv tv1
= tcg_temp_new();
21510 int16_t imm
= extract32(ctx
->opcode
, 16, 7);
21512 tcg_gen_movi_tl(tv0
, rd
>> 3);
21513 tcg_gen_movi_tl(tv1
, imm
);
21514 gen_helper_shilo(tv0
, tv1
, cpu_env
);
21517 case NM_MULEQ_S_W_PHL
:
21519 gen_helper_muleq_s_w_phl(v1_t
, v1_t
, v2_t
, cpu_env
);
21520 gen_store_gpr(v1_t
, ret
);
21522 case NM_MULEQ_S_W_PHR
:
21524 gen_helper_muleq_s_w_phr(v1_t
, v1_t
, v2_t
, cpu_env
);
21525 gen_store_gpr(v1_t
, ret
);
21529 switch (extract32(ctx
->opcode
, 10, 1)) {
21532 gen_helper_mul_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21533 gen_store_gpr(v1_t
, ret
);
21537 gen_helper_mul_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21538 gen_store_gpr(v1_t
, ret
);
21542 case NM_PRECR_QB_PH
:
21544 gen_helper_precr_qb_ph(v1_t
, v1_t
, v2_t
);
21545 gen_store_gpr(v1_t
, ret
);
21547 case NM_PRECRQ_QB_PH
:
21549 gen_helper_precrq_qb_ph(v1_t
, v1_t
, v2_t
);
21550 gen_store_gpr(v1_t
, ret
);
21552 case NM_PRECRQ_PH_W
:
21554 gen_helper_precrq_ph_w(v1_t
, v1_t
, v2_t
);
21555 gen_store_gpr(v1_t
, ret
);
21557 case NM_PRECRQ_RS_PH_W
:
21559 gen_helper_precrq_rs_ph_w(v1_t
, v1_t
, v2_t
, cpu_env
);
21560 gen_store_gpr(v1_t
, ret
);
21562 case NM_PRECRQU_S_QB_PH
:
21564 gen_helper_precrqu_s_qb_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21565 gen_store_gpr(v1_t
, ret
);
21569 tcg_gen_movi_tl(t0
, rd
);
21570 gen_helper_shra_r_w(v1_t
, t0
, v1_t
);
21571 gen_store_gpr(v1_t
, rt
);
21575 tcg_gen_movi_tl(t0
, rd
>> 1);
21576 switch (extract32(ctx
->opcode
, 10, 1)) {
21579 gen_helper_shra_ph(v1_t
, t0
, v1_t
);
21580 gen_store_gpr(v1_t
, rt
);
21584 gen_helper_shra_r_ph(v1_t
, t0
, v1_t
);
21585 gen_store_gpr(v1_t
, rt
);
21591 tcg_gen_movi_tl(t0
, rd
>> 1);
21592 switch (extract32(ctx
->opcode
, 10, 2)) {
21595 gen_helper_shll_ph(v1_t
, t0
, v1_t
, cpu_env
);
21596 gen_store_gpr(v1_t
, rt
);
21600 gen_helper_shll_s_ph(v1_t
, t0
, v1_t
, cpu_env
);
21601 gen_store_gpr(v1_t
, rt
);
21604 gen_reserved_instruction(ctx
);
21610 tcg_gen_movi_tl(t0
, rd
);
21611 gen_helper_shll_s_w(v1_t
, t0
, v1_t
, cpu_env
);
21612 gen_store_gpr(v1_t
, rt
);
21618 imm
= sextract32(ctx
->opcode
, 11, 11);
21619 imm
= (int16_t)(imm
<< 6) >> 6;
21621 tcg_gen_movi_tl(cpu_gpr
[rt
], dup_const(MO_16
, imm
));
21626 gen_reserved_instruction(ctx
);
21631 static int decode_nanomips_32_48_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
21639 insn
= cpu_lduw_code(env
, ctx
->base
.pc_next
+ 2);
21640 ctx
->opcode
= (ctx
->opcode
<< 16) | insn
;
21642 rt
= extract32(ctx
->opcode
, 21, 5);
21643 rs
= extract32(ctx
->opcode
, 16, 5);
21644 rd
= extract32(ctx
->opcode
, 11, 5);
21646 op
= extract32(ctx
->opcode
, 26, 6);
21651 switch (extract32(ctx
->opcode
, 19, 2)) {
21654 gen_reserved_instruction(ctx
);
21657 if ((extract32(ctx
->opcode
, 18, 1)) == NM_SYSCALL
) {
21658 generate_exception_end(ctx
, EXCP_SYSCALL
);
21660 gen_reserved_instruction(ctx
);
21664 generate_exception_end(ctx
, EXCP_BREAK
);
21667 if (is_uhi(extract32(ctx
->opcode
, 0, 19))) {
21668 gen_helper_do_semihosting(cpu_env
);
21670 if (ctx
->hflags
& MIPS_HFLAG_SBRI
) {
21671 gen_reserved_instruction(ctx
);
21673 generate_exception_end(ctx
, EXCP_DBp
);
21680 imm
= extract32(ctx
->opcode
, 0, 16);
21682 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], imm
);
21684 tcg_gen_movi_tl(cpu_gpr
[rt
], imm
);
21686 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
21691 offset
= sextract32(ctx
->opcode
, 0, 1) << 21 |
21692 extract32(ctx
->opcode
, 1, 20) << 1;
21693 target_long addr
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
21694 tcg_gen_movi_tl(cpu_gpr
[rt
], addr
);
21698 switch (ctx
->opcode
& 0x07) {
21700 gen_pool32a0_nanomips_insn(env
, ctx
);
21704 int32_t op1
= extract32(ctx
->opcode
, 3, 7);
21705 gen_pool32a5_nanomips_insn(ctx
, op1
, rd
, rs
, rt
);
21709 switch (extract32(ctx
->opcode
, 3, 3)) {
21711 gen_p_lsx(ctx
, rd
, rs
, rt
);
21715 * In nanoMIPS, the shift field directly encodes the shift
21716 * amount, meaning that the supported shift values are in
21717 * the range 0 to 3 (instead of 1 to 4 in MIPSR6).
21719 gen_lsa(ctx
, OPC_LSA
, rd
, rs
, rt
,
21720 extract32(ctx
->opcode
, 9, 2) - 1);
21723 gen_ext(ctx
, 32, rd
, rs
, rt
, extract32(ctx
->opcode
, 6, 5));
21726 gen_pool32axf_nanomips_insn(env
, ctx
);
21729 gen_reserved_instruction(ctx
);
21734 gen_reserved_instruction(ctx
);
21739 switch (ctx
->opcode
& 0x03) {
21742 offset
= extract32(ctx
->opcode
, 0, 21);
21743 gen_op_addr_addi(ctx
, cpu_gpr
[rt
], cpu_gpr
[28], offset
);
21747 gen_ld(ctx
, OPC_LW
, rt
, 28, extract32(ctx
->opcode
, 2, 19) << 2);
21750 gen_st(ctx
, OPC_SW
, rt
, 28, extract32(ctx
->opcode
, 2, 19) << 2);
21753 gen_reserved_instruction(ctx
);
21759 insn
= cpu_lduw_code(env
, ctx
->base
.pc_next
+ 4);
21760 target_long addr_off
= extract32(ctx
->opcode
, 0, 16) | insn
<< 16;
21761 switch (extract32(ctx
->opcode
, 16, 5)) {
21765 tcg_gen_movi_tl(cpu_gpr
[rt
], addr_off
);
21771 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], addr_off
);
21772 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
21778 gen_op_addr_addi(ctx
, cpu_gpr
[rt
], cpu_gpr
[28], addr_off
);
21784 target_long addr
= addr_add(ctx
, ctx
->base
.pc_next
+ 6,
21787 tcg_gen_movi_tl(cpu_gpr
[rt
], addr
);
21794 t0
= tcg_temp_new();
21796 target_long addr
= addr_add(ctx
, ctx
->base
.pc_next
+ 6,
21799 tcg_gen_movi_tl(t0
, addr
);
21800 tcg_gen_qemu_ld_tl(cpu_gpr
[rt
], t0
, ctx
->mem_idx
, MO_TESL
);
21808 t0
= tcg_temp_new();
21809 t1
= tcg_temp_new();
21811 target_long addr
= addr_add(ctx
, ctx
->base
.pc_next
+ 6,
21814 tcg_gen_movi_tl(t0
, addr
);
21815 gen_load_gpr(t1
, rt
);
21817 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
21824 gen_reserved_instruction(ctx
);
21830 switch (extract32(ctx
->opcode
, 12, 4)) {
21832 gen_logic_imm(ctx
, OPC_ORI
, rt
, rs
, extract32(ctx
->opcode
, 0, 12));
21835 gen_logic_imm(ctx
, OPC_XORI
, rt
, rs
, extract32(ctx
->opcode
, 0, 12));
21838 gen_logic_imm(ctx
, OPC_ANDI
, rt
, rs
, extract32(ctx
->opcode
, 0, 12));
21841 switch (extract32(ctx
->opcode
, 20, 1)) {
21843 switch (ctx
->opcode
& 3) {
21845 gen_save(ctx
, rt
, extract32(ctx
->opcode
, 16, 4),
21846 extract32(ctx
->opcode
, 2, 1),
21847 extract32(ctx
->opcode
, 3, 9) << 3);
21850 case NM_RESTORE_JRC
:
21851 gen_restore(ctx
, rt
, extract32(ctx
->opcode
, 16, 4),
21852 extract32(ctx
->opcode
, 2, 1),
21853 extract32(ctx
->opcode
, 3, 9) << 3);
21854 if ((ctx
->opcode
& 3) == NM_RESTORE_JRC
) {
21855 gen_compute_branch_nm(ctx
, OPC_JR
, 2, 31, 0, 0);
21859 gen_reserved_instruction(ctx
);
21864 gen_reserved_instruction(ctx
);
21869 gen_slt_imm(ctx
, OPC_SLTI
, rt
, rs
, extract32(ctx
->opcode
, 0, 12));
21872 gen_slt_imm(ctx
, OPC_SLTIU
, rt
, rs
, extract32(ctx
->opcode
, 0, 12));
21876 TCGv t0
= tcg_temp_new();
21878 imm
= extract32(ctx
->opcode
, 0, 12);
21879 gen_load_gpr(t0
, rs
);
21880 tcg_gen_setcondi_tl(TCG_COND_EQ
, t0
, t0
, imm
);
21881 gen_store_gpr(t0
, rt
);
21887 imm
= (int16_t) extract32(ctx
->opcode
, 0, 12);
21888 gen_arith_imm(ctx
, OPC_ADDIU
, rt
, rs
, -imm
);
21892 int shift
= extract32(ctx
->opcode
, 0, 5);
21893 switch (extract32(ctx
->opcode
, 5, 4)) {
21895 if (rt
== 0 && shift
== 0) {
21897 } else if (rt
== 0 && shift
== 3) {
21898 /* EHB - treat as NOP */
21899 } else if (rt
== 0 && shift
== 5) {
21900 /* PAUSE - treat as NOP */
21901 } else if (rt
== 0 && shift
== 6) {
21903 gen_sync(extract32(ctx
->opcode
, 16, 5));
21906 gen_shift_imm(ctx
, OPC_SLL
, rt
, rs
,
21907 extract32(ctx
->opcode
, 0, 5));
21911 gen_shift_imm(ctx
, OPC_SRL
, rt
, rs
,
21912 extract32(ctx
->opcode
, 0, 5));
21915 gen_shift_imm(ctx
, OPC_SRA
, rt
, rs
,
21916 extract32(ctx
->opcode
, 0, 5));
21919 gen_shift_imm(ctx
, OPC_ROTR
, rt
, rs
,
21920 extract32(ctx
->opcode
, 0, 5));
21928 TCGv t0
= tcg_temp_new();
21929 TCGv_i32 shift
= tcg_const_i32(extract32(ctx
->opcode
, 0, 5));
21930 TCGv_i32 shiftx
= tcg_const_i32(extract32(ctx
->opcode
, 7, 4)
21932 TCGv_i32 stripe
= tcg_const_i32(extract32(ctx
->opcode
, 6, 1));
21934 gen_load_gpr(t0
, rs
);
21935 gen_helper_rotx(cpu_gpr
[rt
], t0
, shift
, shiftx
, stripe
);
21938 tcg_temp_free_i32(shift
);
21939 tcg_temp_free_i32(shiftx
);
21940 tcg_temp_free_i32(stripe
);
21944 switch (((ctx
->opcode
>> 10) & 2) |
21945 (extract32(ctx
->opcode
, 5, 1))) {
21948 gen_bitops(ctx
, OPC_INS
, rt
, rs
, extract32(ctx
->opcode
, 0, 5),
21949 extract32(ctx
->opcode
, 6, 5));
21952 gen_reserved_instruction(ctx
);
21957 switch (((ctx
->opcode
>> 10) & 2) |
21958 (extract32(ctx
->opcode
, 5, 1))) {
21961 gen_bitops(ctx
, OPC_EXT
, rt
, rs
, extract32(ctx
->opcode
, 0, 5),
21962 extract32(ctx
->opcode
, 6, 5));
21965 gen_reserved_instruction(ctx
);
21970 gen_reserved_instruction(ctx
);
21975 gen_pool32f_nanomips_insn(ctx
);
21980 switch (extract32(ctx
->opcode
, 1, 1)) {
21983 tcg_gen_movi_tl(cpu_gpr
[rt
],
21984 sextract32(ctx
->opcode
, 0, 1) << 31 |
21985 extract32(ctx
->opcode
, 2, 10) << 21 |
21986 extract32(ctx
->opcode
, 12, 9) << 12);
21991 offset
= sextract32(ctx
->opcode
, 0, 1) << 31 |
21992 extract32(ctx
->opcode
, 2, 10) << 21 |
21993 extract32(ctx
->opcode
, 12, 9) << 12;
21995 addr
= ~0xFFF & addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
21996 tcg_gen_movi_tl(cpu_gpr
[rt
], addr
);
22003 uint32_t u
= extract32(ctx
->opcode
, 0, 18);
22005 switch (extract32(ctx
->opcode
, 18, 3)) {
22007 gen_ld(ctx
, OPC_LB
, rt
, 28, u
);
22010 gen_st(ctx
, OPC_SB
, rt
, 28, u
);
22013 gen_ld(ctx
, OPC_LBU
, rt
, 28, u
);
22017 gen_op_addr_addi(ctx
, cpu_gpr
[rt
], cpu_gpr
[28], u
);
22022 switch (ctx
->opcode
& 1) {
22024 gen_ld(ctx
, OPC_LH
, rt
, 28, u
);
22027 gen_ld(ctx
, OPC_LHU
, rt
, 28, u
);
22033 switch (ctx
->opcode
& 1) {
22035 gen_st(ctx
, OPC_SH
, rt
, 28, u
);
22038 gen_reserved_instruction(ctx
);
22044 switch (ctx
->opcode
& 0x3) {
22046 gen_cop1_ldst(ctx
, OPC_LWC1
, rt
, 28, u
);
22049 gen_cop1_ldst(ctx
, OPC_LDC1
, rt
, 28, u
);
22052 gen_cop1_ldst(ctx
, OPC_SWC1
, rt
, 28, u
);
22055 gen_cop1_ldst(ctx
, OPC_SDC1
, rt
, 28, u
);
22060 gen_reserved_instruction(ctx
);
22067 uint32_t u
= extract32(ctx
->opcode
, 0, 12);
22069 switch (extract32(ctx
->opcode
, 12, 4)) {
22074 * Break the TB to be able to sync copied instructions
22077 ctx
->base
.is_jmp
= DISAS_STOP
;
22080 /* Treat as NOP. */
22084 gen_ld(ctx
, OPC_LB
, rt
, rs
, u
);
22087 gen_ld(ctx
, OPC_LH
, rt
, rs
, u
);
22090 gen_ld(ctx
, OPC_LW
, rt
, rs
, u
);
22093 gen_ld(ctx
, OPC_LBU
, rt
, rs
, u
);
22096 gen_ld(ctx
, OPC_LHU
, rt
, rs
, u
);
22099 gen_st(ctx
, OPC_SB
, rt
, rs
, u
);
22102 gen_st(ctx
, OPC_SH
, rt
, rs
, u
);
22105 gen_st(ctx
, OPC_SW
, rt
, rs
, u
);
22108 gen_cop1_ldst(ctx
, OPC_LWC1
, rt
, rs
, u
);
22111 gen_cop1_ldst(ctx
, OPC_LDC1
, rt
, rs
, u
);
22114 gen_cop1_ldst(ctx
, OPC_SWC1
, rt
, rs
, u
);
22117 gen_cop1_ldst(ctx
, OPC_SDC1
, rt
, rs
, u
);
22120 gen_reserved_instruction(ctx
);
22127 int32_t s
= (sextract32(ctx
->opcode
, 15, 1) << 8) |
22128 extract32(ctx
->opcode
, 0, 8);
22130 switch (extract32(ctx
->opcode
, 8, 3)) {
22132 switch (extract32(ctx
->opcode
, 11, 4)) {
22134 gen_ld(ctx
, OPC_LB
, rt
, rs
, s
);
22137 gen_ld(ctx
, OPC_LH
, rt
, rs
, s
);
22140 gen_ld(ctx
, OPC_LW
, rt
, rs
, s
);
22143 gen_ld(ctx
, OPC_LBU
, rt
, rs
, s
);
22146 gen_ld(ctx
, OPC_LHU
, rt
, rs
, s
);
22149 gen_st(ctx
, OPC_SB
, rt
, rs
, s
);
22152 gen_st(ctx
, OPC_SH
, rt
, rs
, s
);
22155 gen_st(ctx
, OPC_SW
, rt
, rs
, s
);
22158 gen_cop1_ldst(ctx
, OPC_LWC1
, rt
, rs
, s
);
22161 gen_cop1_ldst(ctx
, OPC_LDC1
, rt
, rs
, s
);
22164 gen_cop1_ldst(ctx
, OPC_SWC1
, rt
, rs
, s
);
22167 gen_cop1_ldst(ctx
, OPC_SDC1
, rt
, rs
, s
);
22173 * Break the TB to be able to sync copied instructions
22176 ctx
->base
.is_jmp
= DISAS_STOP
;
22179 /* Treat as NOP. */
22183 gen_reserved_instruction(ctx
);
22188 switch (extract32(ctx
->opcode
, 11, 4)) {
22193 TCGv t0
= tcg_temp_new();
22194 TCGv t1
= tcg_temp_new();
22196 gen_base_offset_addr(ctx
, t0
, rs
, s
);
22198 switch (extract32(ctx
->opcode
, 11, 4)) {
22200 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESW
|
22202 gen_store_gpr(t0
, rt
);
22205 gen_load_gpr(t1
, rt
);
22206 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUW
|
22215 switch (ctx
->opcode
& 0x03) {
22217 gen_ld(ctx
, OPC_LL
, rt
, rs
, s
);
22221 gen_llwp(ctx
, rs
, 0, rt
, extract32(ctx
->opcode
, 3, 5));
22226 switch (ctx
->opcode
& 0x03) {
22228 gen_st_cond(ctx
, rt
, rs
, s
, MO_TESL
, false);
22232 gen_scwp(ctx
, rs
, 0, rt
, extract32(ctx
->opcode
, 3, 5),
22238 check_cp0_enabled(ctx
);
22239 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
22240 gen_cache_operation(ctx
, rt
, rs
, s
);
22246 switch (extract32(ctx
->opcode
, 11, 4)) {
22249 check_cp0_enabled(ctx
);
22250 gen_ld(ctx
, OPC_LBE
, rt
, rs
, s
);
22254 check_cp0_enabled(ctx
);
22255 gen_st(ctx
, OPC_SBE
, rt
, rs
, s
);
22259 check_cp0_enabled(ctx
);
22260 gen_ld(ctx
, OPC_LBUE
, rt
, rs
, s
);
22264 /* case NM_SYNCIE */
22266 check_cp0_enabled(ctx
);
22268 * Break the TB to be able to sync copied instructions
22271 ctx
->base
.is_jmp
= DISAS_STOP
;
22273 /* case NM_PREFE */
22275 check_cp0_enabled(ctx
);
22276 /* Treat as NOP. */
22281 check_cp0_enabled(ctx
);
22282 gen_ld(ctx
, OPC_LHE
, rt
, rs
, s
);
22286 check_cp0_enabled(ctx
);
22287 gen_st(ctx
, OPC_SHE
, rt
, rs
, s
);
22291 check_cp0_enabled(ctx
);
22292 gen_ld(ctx
, OPC_LHUE
, rt
, rs
, s
);
22295 check_nms_dl_il_sl_tl_l2c(ctx
);
22296 gen_cache_operation(ctx
, rt
, rs
, s
);
22300 check_cp0_enabled(ctx
);
22301 gen_ld(ctx
, OPC_LWE
, rt
, rs
, s
);
22305 check_cp0_enabled(ctx
);
22306 gen_st(ctx
, OPC_SWE
, rt
, rs
, s
);
22309 switch (extract32(ctx
->opcode
, 2, 2)) {
22313 check_cp0_enabled(ctx
);
22314 gen_ld(ctx
, OPC_LLE
, rt
, rs
, s
);
22319 check_cp0_enabled(ctx
);
22320 gen_llwp(ctx
, rs
, 0, rt
, extract32(ctx
->opcode
, 3, 5));
22323 gen_reserved_instruction(ctx
);
22328 switch (extract32(ctx
->opcode
, 2, 2)) {
22332 check_cp0_enabled(ctx
);
22333 gen_st_cond(ctx
, rt
, rs
, s
, MO_TESL
, true);
22338 check_cp0_enabled(ctx
);
22339 gen_scwp(ctx
, rs
, 0, rt
, extract32(ctx
->opcode
, 3, 5),
22343 gen_reserved_instruction(ctx
);
22353 int count
= extract32(ctx
->opcode
, 12, 3);
22356 offset
= sextract32(ctx
->opcode
, 15, 1) << 8 |
22357 extract32(ctx
->opcode
, 0, 8);
22358 TCGv va
= tcg_temp_new();
22359 TCGv t1
= tcg_temp_new();
22360 MemOp memop
= (extract32(ctx
->opcode
, 8, 3)) ==
22361 NM_P_LS_UAWM
? MO_UNALN
: 0;
22363 count
= (count
== 0) ? 8 : count
;
22364 while (counter
!= count
) {
22365 int this_rt
= ((rt
+ counter
) & 0x1f) | (rt
& 0x10);
22366 int this_offset
= offset
+ (counter
<< 2);
22368 gen_base_offset_addr(ctx
, va
, rs
, this_offset
);
22370 switch (extract32(ctx
->opcode
, 11, 1)) {
22372 tcg_gen_qemu_ld_tl(t1
, va
, ctx
->mem_idx
,
22374 gen_store_gpr(t1
, this_rt
);
22375 if ((this_rt
== rs
) &&
22376 (counter
!= (count
- 1))) {
22377 /* UNPREDICTABLE */
22381 this_rt
= (rt
== 0) ? 0 : this_rt
;
22382 gen_load_gpr(t1
, this_rt
);
22383 tcg_gen_qemu_st_tl(t1
, va
, ctx
->mem_idx
,
22394 gen_reserved_instruction(ctx
);
22402 TCGv t0
= tcg_temp_new();
22403 int32_t s
= sextract32(ctx
->opcode
, 0, 1) << 21 |
22404 extract32(ctx
->opcode
, 1, 20) << 1;
22405 rd
= (extract32(ctx
->opcode
, 24, 1)) == 0 ? 4 : 5;
22406 rt
= decode_gpr_gpr4_zero(extract32(ctx
->opcode
, 25, 1) << 3 |
22407 extract32(ctx
->opcode
, 21, 3));
22408 gen_load_gpr(t0
, rt
);
22409 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
22410 gen_compute_branch_nm(ctx
, OPC_BGEZAL
, 4, 0, 0, s
);
22416 int32_t s
= sextract32(ctx
->opcode
, 0, 1) << 25 |
22417 extract32(ctx
->opcode
, 1, 24) << 1;
22419 if ((extract32(ctx
->opcode
, 25, 1)) == 0) {
22421 gen_compute_branch_nm(ctx
, OPC_BEQ
, 4, 0, 0, s
);
22424 gen_compute_branch_nm(ctx
, OPC_BGEZAL
, 4, 0, 0, s
);
22429 switch (extract32(ctx
->opcode
, 12, 4)) {
22432 gen_compute_branch_nm(ctx
, OPC_JALR
, 4, rs
, rt
, 0);
22435 gen_compute_nanomips_pbalrsc_branch(ctx
, rs
, rt
);
22438 gen_reserved_instruction(ctx
);
22444 int32_t s
= sextract32(ctx
->opcode
, 0, 1) << 14 |
22445 extract32(ctx
->opcode
, 1, 13) << 1;
22446 switch (extract32(ctx
->opcode
, 14, 2)) {
22449 gen_compute_branch_nm(ctx
, OPC_BEQ
, 4, rs
, rt
, s
);
22452 s
= sextract32(ctx
->opcode
, 0, 1) << 14 |
22453 extract32(ctx
->opcode
, 1, 13) << 1;
22454 check_cp1_enabled(ctx
);
22455 switch (extract32(ctx
->opcode
, 16, 5)) {
22457 gen_compute_branch_cp1_nm(ctx
, OPC_BC1EQZ
, rt
, s
);
22460 gen_compute_branch_cp1_nm(ctx
, OPC_BC1NEZ
, rt
, s
);
22465 int32_t imm
= extract32(ctx
->opcode
, 1, 13) |
22466 extract32(ctx
->opcode
, 0, 1) << 13;
22468 gen_compute_branch_nm(ctx
, OPC_BPOSGE32
, 4, -1, -2,
22473 gen_reserved_instruction(ctx
);
22479 gen_compute_compact_branch_nm(ctx
, OPC_BC
, rs
, rt
, s
);
22481 gen_compute_compact_branch_nm(ctx
, OPC_BGEC
, rs
, rt
, s
);
22485 if (rs
== rt
|| rt
== 0) {
22486 gen_compute_compact_branch_nm(ctx
, OPC_BC
, 0, 0, s
);
22487 } else if (rs
== 0) {
22488 gen_compute_compact_branch_nm(ctx
, OPC_BEQZC
, rt
, 0, s
);
22490 gen_compute_compact_branch_nm(ctx
, OPC_BGEUC
, rs
, rt
, s
);
22498 int32_t s
= sextract32(ctx
->opcode
, 0, 1) << 14 |
22499 extract32(ctx
->opcode
, 1, 13) << 1;
22500 switch (extract32(ctx
->opcode
, 14, 2)) {
22503 gen_compute_branch_nm(ctx
, OPC_BNE
, 4, rs
, rt
, s
);
22506 if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
22508 ctx
->hflags
|= MIPS_HFLAG_FBNSLOT
;
22510 gen_compute_compact_branch_nm(ctx
, OPC_BLTC
, rs
, rt
, s
);
22514 if (rs
== 0 || rs
== rt
) {
22516 ctx
->hflags
|= MIPS_HFLAG_FBNSLOT
;
22518 gen_compute_compact_branch_nm(ctx
, OPC_BLTUC
, rs
, rt
, s
);
22522 gen_reserved_instruction(ctx
);
22529 int32_t s
= sextract32(ctx
->opcode
, 0, 1) << 11 |
22530 extract32(ctx
->opcode
, 1, 10) << 1;
22531 uint32_t u
= extract32(ctx
->opcode
, 11, 7);
22533 gen_compute_imm_branch(ctx
, extract32(ctx
->opcode
, 18, 3),
22538 gen_reserved_instruction(ctx
);
22544 static int decode_nanomips_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
22547 int rt
= decode_gpr_gpr3(NANOMIPS_EXTRACT_RT3(ctx
->opcode
));
22548 int rs
= decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx
->opcode
));
22549 int rd
= decode_gpr_gpr3(NANOMIPS_EXTRACT_RD3(ctx
->opcode
));
22553 /* make sure instructions are on a halfword boundary */
22554 if (ctx
->base
.pc_next
& 0x1) {
22555 TCGv tmp
= tcg_const_tl(ctx
->base
.pc_next
);
22556 tcg_gen_st_tl(tmp
, cpu_env
, offsetof(CPUMIPSState
, CP0_BadVAddr
));
22557 tcg_temp_free(tmp
);
22558 generate_exception_end(ctx
, EXCP_AdEL
);
22562 op
= extract32(ctx
->opcode
, 10, 6);
22565 rt
= NANOMIPS_EXTRACT_RD5(ctx
->opcode
);
22568 rs
= NANOMIPS_EXTRACT_RS5(ctx
->opcode
);
22569 gen_arith(ctx
, OPC_ADDU
, rt
, rs
, 0);
22572 switch (extract32(ctx
->opcode
, 3, 2)) {
22573 case NM_P16_SYSCALL
:
22574 if (extract32(ctx
->opcode
, 2, 1) == 0) {
22575 generate_exception_end(ctx
, EXCP_SYSCALL
);
22577 gen_reserved_instruction(ctx
);
22581 generate_exception_end(ctx
, EXCP_BREAK
);
22584 if (is_uhi(extract32(ctx
->opcode
, 0, 3))) {
22585 gen_helper_do_semihosting(cpu_env
);
22587 if (ctx
->hflags
& MIPS_HFLAG_SBRI
) {
22588 gen_reserved_instruction(ctx
);
22590 generate_exception_end(ctx
, EXCP_DBp
);
22595 gen_reserved_instruction(ctx
);
22602 int shift
= extract32(ctx
->opcode
, 0, 3);
22604 shift
= (shift
== 0) ? 8 : shift
;
22606 switch (extract32(ctx
->opcode
, 3, 1)) {
22614 gen_shift_imm(ctx
, opc
, rt
, rs
, shift
);
22618 switch (ctx
->opcode
& 1) {
22620 gen_pool16c_nanomips_insn(ctx
);
22623 gen_ldxs(ctx
, rt
, rs
, rd
);
22628 switch (extract32(ctx
->opcode
, 6, 1)) {
22630 imm
= extract32(ctx
->opcode
, 0, 6) << 2;
22631 gen_arith_imm(ctx
, OPC_ADDIU
, rt
, 29, imm
);
22634 gen_reserved_instruction(ctx
);
22639 switch (extract32(ctx
->opcode
, 3, 1)) {
22641 imm
= extract32(ctx
->opcode
, 0, 3) << 2;
22642 gen_arith_imm(ctx
, OPC_ADDIU
, rt
, rs
, imm
);
22644 case NM_P_ADDIURS5
:
22645 rt
= extract32(ctx
->opcode
, 5, 5);
22647 /* imm = sign_extend(s[3] . s[2:0] , from_nbits = 4) */
22648 imm
= (sextract32(ctx
->opcode
, 4, 1) << 3) |
22649 (extract32(ctx
->opcode
, 0, 3));
22650 gen_arith_imm(ctx
, OPC_ADDIU
, rt
, rt
, imm
);
22656 switch (ctx
->opcode
& 0x1) {
22658 gen_arith(ctx
, OPC_ADDU
, rd
, rs
, rt
);
22661 gen_arith(ctx
, OPC_SUBU
, rd
, rs
, rt
);
22666 rt
= (extract32(ctx
->opcode
, 9, 1) << 3) |
22667 extract32(ctx
->opcode
, 5, 3);
22668 rs
= (extract32(ctx
->opcode
, 4, 1) << 3) |
22669 extract32(ctx
->opcode
, 0, 3);
22670 rt
= decode_gpr_gpr4(rt
);
22671 rs
= decode_gpr_gpr4(rs
);
22672 switch ((extract32(ctx
->opcode
, 7, 2) & 0x2) |
22673 (extract32(ctx
->opcode
, 3, 1))) {
22676 gen_arith(ctx
, OPC_ADDU
, rt
, rs
, rt
);
22680 gen_r6_muldiv(ctx
, R6_OPC_MUL
, rt
, rs
, rt
);
22683 gen_reserved_instruction(ctx
);
22689 int imm
= extract32(ctx
->opcode
, 0, 7);
22690 imm
= (imm
== 0x7f ? -1 : imm
);
22692 tcg_gen_movi_tl(cpu_gpr
[rt
], imm
);
22698 uint32_t u
= extract32(ctx
->opcode
, 0, 4);
22699 u
= (u
== 12) ? 0xff :
22700 (u
== 13) ? 0xffff : u
;
22701 gen_logic_imm(ctx
, OPC_ANDI
, rt
, rs
, u
);
22705 offset
= extract32(ctx
->opcode
, 0, 2);
22706 switch (extract32(ctx
->opcode
, 2, 2)) {
22708 gen_ld(ctx
, OPC_LB
, rt
, rs
, offset
);
22711 rt
= decode_gpr_gpr3_src_store(
22712 NANOMIPS_EXTRACT_RT3(ctx
->opcode
));
22713 gen_st(ctx
, OPC_SB
, rt
, rs
, offset
);
22716 gen_ld(ctx
, OPC_LBU
, rt
, rs
, offset
);
22719 gen_reserved_instruction(ctx
);
22724 offset
= extract32(ctx
->opcode
, 1, 2) << 1;
22725 switch ((extract32(ctx
->opcode
, 3, 1) << 1) | (ctx
->opcode
& 1)) {
22727 gen_ld(ctx
, OPC_LH
, rt
, rs
, offset
);
22730 rt
= decode_gpr_gpr3_src_store(
22731 NANOMIPS_EXTRACT_RT3(ctx
->opcode
));
22732 gen_st(ctx
, OPC_SH
, rt
, rs
, offset
);
22735 gen_ld(ctx
, OPC_LHU
, rt
, rs
, offset
);
22738 gen_reserved_instruction(ctx
);
22743 offset
= extract32(ctx
->opcode
, 0, 4) << 2;
22744 gen_ld(ctx
, OPC_LW
, rt
, rs
, offset
);
22747 rt
= NANOMIPS_EXTRACT_RD5(ctx
->opcode
);
22748 offset
= extract32(ctx
->opcode
, 0, 5) << 2;
22749 gen_ld(ctx
, OPC_LW
, rt
, 29, offset
);
22753 rt
= (extract32(ctx
->opcode
, 9, 1) << 3) |
22754 extract32(ctx
->opcode
, 5, 3);
22755 rs
= (extract32(ctx
->opcode
, 4, 1) << 3) |
22756 extract32(ctx
->opcode
, 0, 3);
22757 offset
= (extract32(ctx
->opcode
, 3, 1) << 3) |
22758 (extract32(ctx
->opcode
, 8, 1) << 2);
22759 rt
= decode_gpr_gpr4(rt
);
22760 rs
= decode_gpr_gpr4(rs
);
22761 gen_ld(ctx
, OPC_LW
, rt
, rs
, offset
);
22765 rt
= (extract32(ctx
->opcode
, 9, 1) << 3) |
22766 extract32(ctx
->opcode
, 5, 3);
22767 rs
= (extract32(ctx
->opcode
, 4, 1) << 3) |
22768 extract32(ctx
->opcode
, 0, 3);
22769 offset
= (extract32(ctx
->opcode
, 3, 1) << 3) |
22770 (extract32(ctx
->opcode
, 8, 1) << 2);
22771 rt
= decode_gpr_gpr4_zero(rt
);
22772 rs
= decode_gpr_gpr4(rs
);
22773 gen_st(ctx
, OPC_SW
, rt
, rs
, offset
);
22776 offset
= extract32(ctx
->opcode
, 0, 7) << 2;
22777 gen_ld(ctx
, OPC_LW
, rt
, 28, offset
);
22780 rt
= NANOMIPS_EXTRACT_RD5(ctx
->opcode
);
22781 offset
= extract32(ctx
->opcode
, 0, 5) << 2;
22782 gen_st(ctx
, OPC_SW
, rt
, 29, offset
);
22785 rt
= decode_gpr_gpr3_src_store(
22786 NANOMIPS_EXTRACT_RT3(ctx
->opcode
));
22787 rs
= decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx
->opcode
));
22788 offset
= extract32(ctx
->opcode
, 0, 4) << 2;
22789 gen_st(ctx
, OPC_SW
, rt
, rs
, offset
);
22792 rt
= decode_gpr_gpr3_src_store(
22793 NANOMIPS_EXTRACT_RT3(ctx
->opcode
));
22794 offset
= extract32(ctx
->opcode
, 0, 7) << 2;
22795 gen_st(ctx
, OPC_SW
, rt
, 28, offset
);
22798 gen_compute_branch_nm(ctx
, OPC_BEQ
, 2, 0, 0,
22799 (sextract32(ctx
->opcode
, 0, 1) << 10) |
22800 (extract32(ctx
->opcode
, 1, 9) << 1));
22803 gen_compute_branch_nm(ctx
, OPC_BGEZAL
, 2, 0, 0,
22804 (sextract32(ctx
->opcode
, 0, 1) << 10) |
22805 (extract32(ctx
->opcode
, 1, 9) << 1));
22808 gen_compute_branch_nm(ctx
, OPC_BEQ
, 2, rt
, 0,
22809 (sextract32(ctx
->opcode
, 0, 1) << 7) |
22810 (extract32(ctx
->opcode
, 1, 6) << 1));
22813 gen_compute_branch_nm(ctx
, OPC_BNE
, 2, rt
, 0,
22814 (sextract32(ctx
->opcode
, 0, 1) << 7) |
22815 (extract32(ctx
->opcode
, 1, 6) << 1));
22818 switch (ctx
->opcode
& 0xf) {
22821 switch (extract32(ctx
->opcode
, 4, 1)) {
22823 gen_compute_branch_nm(ctx
, OPC_JR
, 2,
22824 extract32(ctx
->opcode
, 5, 5), 0, 0);
22827 gen_compute_branch_nm(ctx
, OPC_JALR
, 2,
22828 extract32(ctx
->opcode
, 5, 5), 31, 0);
22835 uint32_t opc
= extract32(ctx
->opcode
, 4, 3) <
22836 extract32(ctx
->opcode
, 7, 3) ? OPC_BEQ
: OPC_BNE
;
22837 gen_compute_branch_nm(ctx
, opc
, 2, rs
, rt
,
22838 extract32(ctx
->opcode
, 0, 4) << 1);
22845 int count
= extract32(ctx
->opcode
, 0, 4);
22846 int u
= extract32(ctx
->opcode
, 4, 4) << 4;
22848 rt
= 30 + extract32(ctx
->opcode
, 9, 1);
22849 switch (extract32(ctx
->opcode
, 8, 1)) {
22851 gen_save(ctx
, rt
, count
, 0, u
);
22853 case NM_RESTORE_JRC16
:
22854 gen_restore(ctx
, rt
, count
, 0, u
);
22855 gen_compute_branch_nm(ctx
, OPC_JR
, 2, 31, 0, 0);
22864 static const int gpr2reg1
[] = {4, 5, 6, 7};
22865 static const int gpr2reg2
[] = {5, 6, 7, 8};
22867 int rd2
= extract32(ctx
->opcode
, 3, 1) << 1 |
22868 extract32(ctx
->opcode
, 8, 1);
22869 int r1
= gpr2reg1
[rd2
];
22870 int r2
= gpr2reg2
[rd2
];
22871 int r3
= extract32(ctx
->opcode
, 4, 1) << 3 |
22872 extract32(ctx
->opcode
, 0, 3);
22873 int r4
= extract32(ctx
->opcode
, 9, 1) << 3 |
22874 extract32(ctx
->opcode
, 5, 3);
22875 TCGv t0
= tcg_temp_new();
22876 TCGv t1
= tcg_temp_new();
22877 if (op
== NM_MOVEP
) {
22880 rs
= decode_gpr_gpr4_zero(r3
);
22881 rt
= decode_gpr_gpr4_zero(r4
);
22883 rd
= decode_gpr_gpr4(r3
);
22884 re
= decode_gpr_gpr4(r4
);
22888 gen_load_gpr(t0
, rs
);
22889 gen_load_gpr(t1
, rt
);
22890 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
22891 tcg_gen_mov_tl(cpu_gpr
[re
], t1
);
22897 return decode_nanomips_32_48_opc(env
, ctx
);
22904 /* SmartMIPS extension to MIPS32 */
22906 #if defined(TARGET_MIPS64)
22908 /* MDMX extension to MIPS64 */
22912 /* MIPSDSP functions. */
22913 static void gen_mipsdsp_ld(DisasContext
*ctx
, uint32_t opc
,
22914 int rd
, int base
, int offset
)
22919 t0
= tcg_temp_new();
22922 gen_load_gpr(t0
, offset
);
22923 } else if (offset
== 0) {
22924 gen_load_gpr(t0
, base
);
22926 gen_op_addr_add(ctx
, t0
, cpu_gpr
[base
], cpu_gpr
[offset
]);
22931 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_UB
);
22932 gen_store_gpr(t0
, rd
);
22935 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESW
);
22936 gen_store_gpr(t0
, rd
);
22939 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESL
);
22940 gen_store_gpr(t0
, rd
);
22942 #if defined(TARGET_MIPS64)
22944 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
);
22945 gen_store_gpr(t0
, rd
);
22952 static void gen_mipsdsp_arith(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
22953 int ret
, int v1
, int v2
)
22959 /* Treat as NOP. */
22963 v1_t
= tcg_temp_new();
22964 v2_t
= tcg_temp_new();
22966 gen_load_gpr(v1_t
, v1
);
22967 gen_load_gpr(v2_t
, v2
);
22970 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
22971 case OPC_MULT_G_2E
:
22975 gen_helper_adduh_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
22977 case OPC_ADDUH_R_QB
:
22978 gen_helper_adduh_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
22981 gen_helper_addqh_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
22983 case OPC_ADDQH_R_PH
:
22984 gen_helper_addqh_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
22987 gen_helper_addqh_w(cpu_gpr
[ret
], v1_t
, v2_t
);
22989 case OPC_ADDQH_R_W
:
22990 gen_helper_addqh_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
22993 gen_helper_subuh_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
22995 case OPC_SUBUH_R_QB
:
22996 gen_helper_subuh_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
22999 gen_helper_subqh_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
23001 case OPC_SUBQH_R_PH
:
23002 gen_helper_subqh_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
23005 gen_helper_subqh_w(cpu_gpr
[ret
], v1_t
, v2_t
);
23007 case OPC_SUBQH_R_W
:
23008 gen_helper_subqh_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
23012 case OPC_ABSQ_S_PH_DSP
:
23014 case OPC_ABSQ_S_QB
:
23016 gen_helper_absq_s_qb(cpu_gpr
[ret
], v2_t
, cpu_env
);
23018 case OPC_ABSQ_S_PH
:
23020 gen_helper_absq_s_ph(cpu_gpr
[ret
], v2_t
, cpu_env
);
23024 gen_helper_absq_s_w(cpu_gpr
[ret
], v2_t
, cpu_env
);
23026 case OPC_PRECEQ_W_PHL
:
23028 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0xFFFF0000);
23029 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
23031 case OPC_PRECEQ_W_PHR
:
23033 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0x0000FFFF);
23034 tcg_gen_shli_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], 16);
23035 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
23037 case OPC_PRECEQU_PH_QBL
:
23039 gen_helper_precequ_ph_qbl(cpu_gpr
[ret
], v2_t
);
23041 case OPC_PRECEQU_PH_QBR
:
23043 gen_helper_precequ_ph_qbr(cpu_gpr
[ret
], v2_t
);
23045 case OPC_PRECEQU_PH_QBLA
:
23047 gen_helper_precequ_ph_qbla(cpu_gpr
[ret
], v2_t
);
23049 case OPC_PRECEQU_PH_QBRA
:
23051 gen_helper_precequ_ph_qbra(cpu_gpr
[ret
], v2_t
);
23053 case OPC_PRECEU_PH_QBL
:
23055 gen_helper_preceu_ph_qbl(cpu_gpr
[ret
], v2_t
);
23057 case OPC_PRECEU_PH_QBR
:
23059 gen_helper_preceu_ph_qbr(cpu_gpr
[ret
], v2_t
);
23061 case OPC_PRECEU_PH_QBLA
:
23063 gen_helper_preceu_ph_qbla(cpu_gpr
[ret
], v2_t
);
23065 case OPC_PRECEU_PH_QBRA
:
23067 gen_helper_preceu_ph_qbra(cpu_gpr
[ret
], v2_t
);
23071 case OPC_ADDU_QB_DSP
:
23075 gen_helper_addq_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23077 case OPC_ADDQ_S_PH
:
23079 gen_helper_addq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23083 gen_helper_addq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23087 gen_helper_addu_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23089 case OPC_ADDU_S_QB
:
23091 gen_helper_addu_s_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23095 gen_helper_addu_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23097 case OPC_ADDU_S_PH
:
23099 gen_helper_addu_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23103 gen_helper_subq_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23105 case OPC_SUBQ_S_PH
:
23107 gen_helper_subq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23111 gen_helper_subq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23115 gen_helper_subu_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23117 case OPC_SUBU_S_QB
:
23119 gen_helper_subu_s_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23123 gen_helper_subu_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23125 case OPC_SUBU_S_PH
:
23127 gen_helper_subu_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23131 gen_helper_addsc(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23135 gen_helper_addwc(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23139 gen_helper_modsub(cpu_gpr
[ret
], v1_t
, v2_t
);
23141 case OPC_RADDU_W_QB
:
23143 gen_helper_raddu_w_qb(cpu_gpr
[ret
], v1_t
);
23147 case OPC_CMPU_EQ_QB_DSP
:
23149 case OPC_PRECR_QB_PH
:
23151 gen_helper_precr_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
23153 case OPC_PRECRQ_QB_PH
:
23155 gen_helper_precrq_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
23157 case OPC_PRECR_SRA_PH_W
:
23160 TCGv_i32 sa_t
= tcg_const_i32(v2
);
23161 gen_helper_precr_sra_ph_w(cpu_gpr
[ret
], sa_t
, v1_t
,
23163 tcg_temp_free_i32(sa_t
);
23166 case OPC_PRECR_SRA_R_PH_W
:
23169 TCGv_i32 sa_t
= tcg_const_i32(v2
);
23170 gen_helper_precr_sra_r_ph_w(cpu_gpr
[ret
], sa_t
, v1_t
,
23172 tcg_temp_free_i32(sa_t
);
23175 case OPC_PRECRQ_PH_W
:
23177 gen_helper_precrq_ph_w(cpu_gpr
[ret
], v1_t
, v2_t
);
23179 case OPC_PRECRQ_RS_PH_W
:
23181 gen_helper_precrq_rs_ph_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23183 case OPC_PRECRQU_S_QB_PH
:
23185 gen_helper_precrqu_s_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23189 #ifdef TARGET_MIPS64
23190 case OPC_ABSQ_S_QH_DSP
:
23192 case OPC_PRECEQ_L_PWL
:
23194 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0xFFFFFFFF00000000ull
);
23196 case OPC_PRECEQ_L_PWR
:
23198 tcg_gen_shli_tl(cpu_gpr
[ret
], v2_t
, 32);
23200 case OPC_PRECEQ_PW_QHL
:
23202 gen_helper_preceq_pw_qhl(cpu_gpr
[ret
], v2_t
);
23204 case OPC_PRECEQ_PW_QHR
:
23206 gen_helper_preceq_pw_qhr(cpu_gpr
[ret
], v2_t
);
23208 case OPC_PRECEQ_PW_QHLA
:
23210 gen_helper_preceq_pw_qhla(cpu_gpr
[ret
], v2_t
);
23212 case OPC_PRECEQ_PW_QHRA
:
23214 gen_helper_preceq_pw_qhra(cpu_gpr
[ret
], v2_t
);
23216 case OPC_PRECEQU_QH_OBL
:
23218 gen_helper_precequ_qh_obl(cpu_gpr
[ret
], v2_t
);
23220 case OPC_PRECEQU_QH_OBR
:
23222 gen_helper_precequ_qh_obr(cpu_gpr
[ret
], v2_t
);
23224 case OPC_PRECEQU_QH_OBLA
:
23226 gen_helper_precequ_qh_obla(cpu_gpr
[ret
], v2_t
);
23228 case OPC_PRECEQU_QH_OBRA
:
23230 gen_helper_precequ_qh_obra(cpu_gpr
[ret
], v2_t
);
23232 case OPC_PRECEU_QH_OBL
:
23234 gen_helper_preceu_qh_obl(cpu_gpr
[ret
], v2_t
);
23236 case OPC_PRECEU_QH_OBR
:
23238 gen_helper_preceu_qh_obr(cpu_gpr
[ret
], v2_t
);
23240 case OPC_PRECEU_QH_OBLA
:
23242 gen_helper_preceu_qh_obla(cpu_gpr
[ret
], v2_t
);
23244 case OPC_PRECEU_QH_OBRA
:
23246 gen_helper_preceu_qh_obra(cpu_gpr
[ret
], v2_t
);
23248 case OPC_ABSQ_S_OB
:
23250 gen_helper_absq_s_ob(cpu_gpr
[ret
], v2_t
, cpu_env
);
23252 case OPC_ABSQ_S_PW
:
23254 gen_helper_absq_s_pw(cpu_gpr
[ret
], v2_t
, cpu_env
);
23256 case OPC_ABSQ_S_QH
:
23258 gen_helper_absq_s_qh(cpu_gpr
[ret
], v2_t
, cpu_env
);
23262 case OPC_ADDU_OB_DSP
:
23264 case OPC_RADDU_L_OB
:
23266 gen_helper_raddu_l_ob(cpu_gpr
[ret
], v1_t
);
23270 gen_helper_subq_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23272 case OPC_SUBQ_S_PW
:
23274 gen_helper_subq_s_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23278 gen_helper_subq_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23280 case OPC_SUBQ_S_QH
:
23282 gen_helper_subq_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23286 gen_helper_subu_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23288 case OPC_SUBU_S_OB
:
23290 gen_helper_subu_s_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23294 gen_helper_subu_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23296 case OPC_SUBU_S_QH
:
23298 gen_helper_subu_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23302 gen_helper_subuh_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
23304 case OPC_SUBUH_R_OB
:
23306 gen_helper_subuh_r_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
23310 gen_helper_addq_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23312 case OPC_ADDQ_S_PW
:
23314 gen_helper_addq_s_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23318 gen_helper_addq_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23320 case OPC_ADDQ_S_QH
:
23322 gen_helper_addq_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23326 gen_helper_addu_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23328 case OPC_ADDU_S_OB
:
23330 gen_helper_addu_s_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23334 gen_helper_addu_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23336 case OPC_ADDU_S_QH
:
23338 gen_helper_addu_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23342 gen_helper_adduh_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
23344 case OPC_ADDUH_R_OB
:
23346 gen_helper_adduh_r_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
23350 case OPC_CMPU_EQ_OB_DSP
:
23352 case OPC_PRECR_OB_QH
:
23354 gen_helper_precr_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
);
23356 case OPC_PRECR_SRA_QH_PW
:
23359 TCGv_i32 ret_t
= tcg_const_i32(ret
);
23360 gen_helper_precr_sra_qh_pw(v2_t
, v1_t
, v2_t
, ret_t
);
23361 tcg_temp_free_i32(ret_t
);
23364 case OPC_PRECR_SRA_R_QH_PW
:
23367 TCGv_i32 sa_v
= tcg_const_i32(ret
);
23368 gen_helper_precr_sra_r_qh_pw(v2_t
, v1_t
, v2_t
, sa_v
);
23369 tcg_temp_free_i32(sa_v
);
23372 case OPC_PRECRQ_OB_QH
:
23374 gen_helper_precrq_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
);
23376 case OPC_PRECRQ_PW_L
:
23378 gen_helper_precrq_pw_l(cpu_gpr
[ret
], v1_t
, v2_t
);
23380 case OPC_PRECRQ_QH_PW
:
23382 gen_helper_precrq_qh_pw(cpu_gpr
[ret
], v1_t
, v2_t
);
23384 case OPC_PRECRQ_RS_QH_PW
:
23386 gen_helper_precrq_rs_qh_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23388 case OPC_PRECRQU_S_OB_QH
:
23390 gen_helper_precrqu_s_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23397 tcg_temp_free(v1_t
);
23398 tcg_temp_free(v2_t
);
23401 static void gen_mipsdsp_shift(DisasContext
*ctx
, uint32_t opc
,
23402 int ret
, int v1
, int v2
)
23410 /* Treat as NOP. */
23414 t0
= tcg_temp_new();
23415 v1_t
= tcg_temp_new();
23416 v2_t
= tcg_temp_new();
23418 tcg_gen_movi_tl(t0
, v1
);
23419 gen_load_gpr(v1_t
, v1
);
23420 gen_load_gpr(v2_t
, v2
);
23423 case OPC_SHLL_QB_DSP
:
23425 op2
= MASK_SHLL_QB(ctx
->opcode
);
23429 gen_helper_shll_qb(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
23433 gen_helper_shll_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23437 gen_helper_shll_ph(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
23441 gen_helper_shll_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23443 case OPC_SHLL_S_PH
:
23445 gen_helper_shll_s_ph(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
23447 case OPC_SHLLV_S_PH
:
23449 gen_helper_shll_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23453 gen_helper_shll_s_w(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
23455 case OPC_SHLLV_S_W
:
23457 gen_helper_shll_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23461 gen_helper_shrl_qb(cpu_gpr
[ret
], t0
, v2_t
);
23465 gen_helper_shrl_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
23469 gen_helper_shrl_ph(cpu_gpr
[ret
], t0
, v2_t
);
23473 gen_helper_shrl_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
23477 gen_helper_shra_qb(cpu_gpr
[ret
], t0
, v2_t
);
23479 case OPC_SHRA_R_QB
:
23481 gen_helper_shra_r_qb(cpu_gpr
[ret
], t0
, v2_t
);
23485 gen_helper_shra_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
23487 case OPC_SHRAV_R_QB
:
23489 gen_helper_shra_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
23493 gen_helper_shra_ph(cpu_gpr
[ret
], t0
, v2_t
);
23495 case OPC_SHRA_R_PH
:
23497 gen_helper_shra_r_ph(cpu_gpr
[ret
], t0
, v2_t
);
23501 gen_helper_shra_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
23503 case OPC_SHRAV_R_PH
:
23505 gen_helper_shra_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
23509 gen_helper_shra_r_w(cpu_gpr
[ret
], t0
, v2_t
);
23511 case OPC_SHRAV_R_W
:
23513 gen_helper_shra_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
23515 default: /* Invalid */
23516 MIPS_INVAL("MASK SHLL.QB");
23517 gen_reserved_instruction(ctx
);
23522 #ifdef TARGET_MIPS64
23523 case OPC_SHLL_OB_DSP
:
23524 op2
= MASK_SHLL_OB(ctx
->opcode
);
23528 gen_helper_shll_pw(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
23532 gen_helper_shll_pw(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
23534 case OPC_SHLL_S_PW
:
23536 gen_helper_shll_s_pw(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
23538 case OPC_SHLLV_S_PW
:
23540 gen_helper_shll_s_pw(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
23544 gen_helper_shll_ob(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
23548 gen_helper_shll_ob(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
23552 gen_helper_shll_qh(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
23556 gen_helper_shll_qh(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
23558 case OPC_SHLL_S_QH
:
23560 gen_helper_shll_s_qh(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
23562 case OPC_SHLLV_S_QH
:
23564 gen_helper_shll_s_qh(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
23568 gen_helper_shra_ob(cpu_gpr
[ret
], v2_t
, t0
);
23572 gen_helper_shra_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
23574 case OPC_SHRA_R_OB
:
23576 gen_helper_shra_r_ob(cpu_gpr
[ret
], v2_t
, t0
);
23578 case OPC_SHRAV_R_OB
:
23580 gen_helper_shra_r_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
23584 gen_helper_shra_pw(cpu_gpr
[ret
], v2_t
, t0
);
23588 gen_helper_shra_pw(cpu_gpr
[ret
], v2_t
, v1_t
);
23590 case OPC_SHRA_R_PW
:
23592 gen_helper_shra_r_pw(cpu_gpr
[ret
], v2_t
, t0
);
23594 case OPC_SHRAV_R_PW
:
23596 gen_helper_shra_r_pw(cpu_gpr
[ret
], v2_t
, v1_t
);
23600 gen_helper_shra_qh(cpu_gpr
[ret
], v2_t
, t0
);
23604 gen_helper_shra_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
23606 case OPC_SHRA_R_QH
:
23608 gen_helper_shra_r_qh(cpu_gpr
[ret
], v2_t
, t0
);
23610 case OPC_SHRAV_R_QH
:
23612 gen_helper_shra_r_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
23616 gen_helper_shrl_ob(cpu_gpr
[ret
], v2_t
, t0
);
23620 gen_helper_shrl_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
23624 gen_helper_shrl_qh(cpu_gpr
[ret
], v2_t
, t0
);
23628 gen_helper_shrl_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
23630 default: /* Invalid */
23631 MIPS_INVAL("MASK SHLL.OB");
23632 gen_reserved_instruction(ctx
);
23640 tcg_temp_free(v1_t
);
23641 tcg_temp_free(v2_t
);
23644 static void gen_mipsdsp_multiply(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
23645 int ret
, int v1
, int v2
, int check_ret
)
23651 if ((ret
== 0) && (check_ret
== 1)) {
23652 /* Treat as NOP. */
23656 t0
= tcg_temp_new_i32();
23657 v1_t
= tcg_temp_new();
23658 v2_t
= tcg_temp_new();
23660 tcg_gen_movi_i32(t0
, ret
);
23661 gen_load_gpr(v1_t
, v1
);
23662 gen_load_gpr(v2_t
, v2
);
23666 * OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
23667 * the same mask and op1.
23669 case OPC_MULT_G_2E
:
23673 gen_helper_mul_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23676 gen_helper_mul_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23679 gen_helper_mulq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23681 case OPC_MULQ_RS_W
:
23682 gen_helper_mulq_rs_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23686 case OPC_DPA_W_PH_DSP
:
23688 case OPC_DPAU_H_QBL
:
23690 gen_helper_dpau_h_qbl(t0
, v1_t
, v2_t
, cpu_env
);
23692 case OPC_DPAU_H_QBR
:
23694 gen_helper_dpau_h_qbr(t0
, v1_t
, v2_t
, cpu_env
);
23696 case OPC_DPSU_H_QBL
:
23698 gen_helper_dpsu_h_qbl(t0
, v1_t
, v2_t
, cpu_env
);
23700 case OPC_DPSU_H_QBR
:
23702 gen_helper_dpsu_h_qbr(t0
, v1_t
, v2_t
, cpu_env
);
23706 gen_helper_dpa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23708 case OPC_DPAX_W_PH
:
23710 gen_helper_dpax_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23712 case OPC_DPAQ_S_W_PH
:
23714 gen_helper_dpaq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23716 case OPC_DPAQX_S_W_PH
:
23718 gen_helper_dpaqx_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23720 case OPC_DPAQX_SA_W_PH
:
23722 gen_helper_dpaqx_sa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23726 gen_helper_dps_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23728 case OPC_DPSX_W_PH
:
23730 gen_helper_dpsx_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23732 case OPC_DPSQ_S_W_PH
:
23734 gen_helper_dpsq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23736 case OPC_DPSQX_S_W_PH
:
23738 gen_helper_dpsqx_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23740 case OPC_DPSQX_SA_W_PH
:
23742 gen_helper_dpsqx_sa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23744 case OPC_MULSAQ_S_W_PH
:
23746 gen_helper_mulsaq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23748 case OPC_DPAQ_SA_L_W
:
23750 gen_helper_dpaq_sa_l_w(t0
, v1_t
, v2_t
, cpu_env
);
23752 case OPC_DPSQ_SA_L_W
:
23754 gen_helper_dpsq_sa_l_w(t0
, v1_t
, v2_t
, cpu_env
);
23756 case OPC_MAQ_S_W_PHL
:
23758 gen_helper_maq_s_w_phl(t0
, v1_t
, v2_t
, cpu_env
);
23760 case OPC_MAQ_S_W_PHR
:
23762 gen_helper_maq_s_w_phr(t0
, v1_t
, v2_t
, cpu_env
);
23764 case OPC_MAQ_SA_W_PHL
:
23766 gen_helper_maq_sa_w_phl(t0
, v1_t
, v2_t
, cpu_env
);
23768 case OPC_MAQ_SA_W_PHR
:
23770 gen_helper_maq_sa_w_phr(t0
, v1_t
, v2_t
, cpu_env
);
23772 case OPC_MULSA_W_PH
:
23774 gen_helper_mulsa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23778 #ifdef TARGET_MIPS64
23779 case OPC_DPAQ_W_QH_DSP
:
23781 int ac
= ret
& 0x03;
23782 tcg_gen_movi_i32(t0
, ac
);
23787 gen_helper_dmadd(v1_t
, v2_t
, t0
, cpu_env
);
23791 gen_helper_dmaddu(v1_t
, v2_t
, t0
, cpu_env
);
23795 gen_helper_dmsub(v1_t
, v2_t
, t0
, cpu_env
);
23799 gen_helper_dmsubu(v1_t
, v2_t
, t0
, cpu_env
);
23803 gen_helper_dpa_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
23805 case OPC_DPAQ_S_W_QH
:
23807 gen_helper_dpaq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
23809 case OPC_DPAQ_SA_L_PW
:
23811 gen_helper_dpaq_sa_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
23813 case OPC_DPAU_H_OBL
:
23815 gen_helper_dpau_h_obl(v1_t
, v2_t
, t0
, cpu_env
);
23817 case OPC_DPAU_H_OBR
:
23819 gen_helper_dpau_h_obr(v1_t
, v2_t
, t0
, cpu_env
);
23823 gen_helper_dps_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
23825 case OPC_DPSQ_S_W_QH
:
23827 gen_helper_dpsq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
23829 case OPC_DPSQ_SA_L_PW
:
23831 gen_helper_dpsq_sa_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
23833 case OPC_DPSU_H_OBL
:
23835 gen_helper_dpsu_h_obl(v1_t
, v2_t
, t0
, cpu_env
);
23837 case OPC_DPSU_H_OBR
:
23839 gen_helper_dpsu_h_obr(v1_t
, v2_t
, t0
, cpu_env
);
23841 case OPC_MAQ_S_L_PWL
:
23843 gen_helper_maq_s_l_pwl(v1_t
, v2_t
, t0
, cpu_env
);
23845 case OPC_MAQ_S_L_PWR
:
23847 gen_helper_maq_s_l_pwr(v1_t
, v2_t
, t0
, cpu_env
);
23849 case OPC_MAQ_S_W_QHLL
:
23851 gen_helper_maq_s_w_qhll(v1_t
, v2_t
, t0
, cpu_env
);
23853 case OPC_MAQ_SA_W_QHLL
:
23855 gen_helper_maq_sa_w_qhll(v1_t
, v2_t
, t0
, cpu_env
);
23857 case OPC_MAQ_S_W_QHLR
:
23859 gen_helper_maq_s_w_qhlr(v1_t
, v2_t
, t0
, cpu_env
);
23861 case OPC_MAQ_SA_W_QHLR
:
23863 gen_helper_maq_sa_w_qhlr(v1_t
, v2_t
, t0
, cpu_env
);
23865 case OPC_MAQ_S_W_QHRL
:
23867 gen_helper_maq_s_w_qhrl(v1_t
, v2_t
, t0
, cpu_env
);
23869 case OPC_MAQ_SA_W_QHRL
:
23871 gen_helper_maq_sa_w_qhrl(v1_t
, v2_t
, t0
, cpu_env
);
23873 case OPC_MAQ_S_W_QHRR
:
23875 gen_helper_maq_s_w_qhrr(v1_t
, v2_t
, t0
, cpu_env
);
23877 case OPC_MAQ_SA_W_QHRR
:
23879 gen_helper_maq_sa_w_qhrr(v1_t
, v2_t
, t0
, cpu_env
);
23881 case OPC_MULSAQ_S_L_PW
:
23883 gen_helper_mulsaq_s_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
23885 case OPC_MULSAQ_S_W_QH
:
23887 gen_helper_mulsaq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
23893 case OPC_ADDU_QB_DSP
:
23895 case OPC_MULEU_S_PH_QBL
:
23897 gen_helper_muleu_s_ph_qbl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23899 case OPC_MULEU_S_PH_QBR
:
23901 gen_helper_muleu_s_ph_qbr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23903 case OPC_MULQ_RS_PH
:
23905 gen_helper_mulq_rs_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23907 case OPC_MULEQ_S_W_PHL
:
23909 gen_helper_muleq_s_w_phl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23911 case OPC_MULEQ_S_W_PHR
:
23913 gen_helper_muleq_s_w_phr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23915 case OPC_MULQ_S_PH
:
23917 gen_helper_mulq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23921 #ifdef TARGET_MIPS64
23922 case OPC_ADDU_OB_DSP
:
23924 case OPC_MULEQ_S_PW_QHL
:
23926 gen_helper_muleq_s_pw_qhl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23928 case OPC_MULEQ_S_PW_QHR
:
23930 gen_helper_muleq_s_pw_qhr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23932 case OPC_MULEU_S_QH_OBL
:
23934 gen_helper_muleu_s_qh_obl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23936 case OPC_MULEU_S_QH_OBR
:
23938 gen_helper_muleu_s_qh_obr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23940 case OPC_MULQ_RS_QH
:
23942 gen_helper_mulq_rs_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23949 tcg_temp_free_i32(t0
);
23950 tcg_temp_free(v1_t
);
23951 tcg_temp_free(v2_t
);
23954 static void gen_mipsdsp_bitinsn(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
23962 /* Treat as NOP. */
23966 t0
= tcg_temp_new();
23967 val_t
= tcg_temp_new();
23968 gen_load_gpr(val_t
, val
);
23971 case OPC_ABSQ_S_PH_DSP
:
23975 gen_helper_bitrev(cpu_gpr
[ret
], val_t
);
23980 target_long result
;
23981 imm
= (ctx
->opcode
>> 16) & 0xFF;
23982 result
= (uint32_t)imm
<< 24 |
23983 (uint32_t)imm
<< 16 |
23984 (uint32_t)imm
<< 8 |
23986 result
= (int32_t)result
;
23987 tcg_gen_movi_tl(cpu_gpr
[ret
], result
);
23992 tcg_gen_ext8u_tl(cpu_gpr
[ret
], val_t
);
23993 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 8);
23994 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
23995 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
23996 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
23997 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
24002 imm
= (ctx
->opcode
>> 16) & 0x03FF;
24003 imm
= (int16_t)(imm
<< 6) >> 6;
24004 tcg_gen_movi_tl(cpu_gpr
[ret
], \
24005 (target_long
)((int32_t)imm
<< 16 | \
24011 tcg_gen_ext16u_tl(cpu_gpr
[ret
], val_t
);
24012 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
24013 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
24014 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
24018 #ifdef TARGET_MIPS64
24019 case OPC_ABSQ_S_QH_DSP
:
24026 imm
= (ctx
->opcode
>> 16) & 0xFF;
24027 temp
= ((uint64_t)imm
<< 8) | (uint64_t)imm
;
24028 temp
= (temp
<< 16) | temp
;
24029 temp
= (temp
<< 32) | temp
;
24030 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
24038 imm
= (ctx
->opcode
>> 16) & 0x03FF;
24039 imm
= (int16_t)(imm
<< 6) >> 6;
24040 temp
= ((target_long
)imm
<< 32) \
24041 | ((target_long
)imm
& 0xFFFFFFFF);
24042 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
24050 imm
= (ctx
->opcode
>> 16) & 0x03FF;
24051 imm
= (int16_t)(imm
<< 6) >> 6;
24053 temp
= ((uint64_t)(uint16_t)imm
<< 48) |
24054 ((uint64_t)(uint16_t)imm
<< 32) |
24055 ((uint64_t)(uint16_t)imm
<< 16) |
24056 (uint64_t)(uint16_t)imm
;
24057 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
24062 tcg_gen_ext8u_tl(cpu_gpr
[ret
], val_t
);
24063 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 8);
24064 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
24065 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
24066 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
24067 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
24068 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
24072 tcg_gen_ext32u_i64(cpu_gpr
[ret
], val_t
);
24073 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
24074 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
24078 tcg_gen_ext16u_tl(cpu_gpr
[ret
], val_t
);
24079 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
24080 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
24081 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
24082 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
24089 tcg_temp_free(val_t
);
24092 static void gen_mipsdsp_add_cmp_pick(DisasContext
*ctx
,
24093 uint32_t op1
, uint32_t op2
,
24094 int ret
, int v1
, int v2
, int check_ret
)
24100 if ((ret
== 0) && (check_ret
== 1)) {
24101 /* Treat as NOP. */
24105 t1
= tcg_temp_new();
24106 v1_t
= tcg_temp_new();
24107 v2_t
= tcg_temp_new();
24109 gen_load_gpr(v1_t
, v1
);
24110 gen_load_gpr(v2_t
, v2
);
24113 case OPC_CMPU_EQ_QB_DSP
:
24115 case OPC_CMPU_EQ_QB
:
24117 gen_helper_cmpu_eq_qb(v1_t
, v2_t
, cpu_env
);
24119 case OPC_CMPU_LT_QB
:
24121 gen_helper_cmpu_lt_qb(v1_t
, v2_t
, cpu_env
);
24123 case OPC_CMPU_LE_QB
:
24125 gen_helper_cmpu_le_qb(v1_t
, v2_t
, cpu_env
);
24127 case OPC_CMPGU_EQ_QB
:
24129 gen_helper_cmpgu_eq_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
24131 case OPC_CMPGU_LT_QB
:
24133 gen_helper_cmpgu_lt_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
24135 case OPC_CMPGU_LE_QB
:
24137 gen_helper_cmpgu_le_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
24139 case OPC_CMPGDU_EQ_QB
:
24141 gen_helper_cmpgu_eq_qb(t1
, v1_t
, v2_t
);
24142 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
24143 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
24144 tcg_gen_shli_tl(t1
, t1
, 24);
24145 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
24147 case OPC_CMPGDU_LT_QB
:
24149 gen_helper_cmpgu_lt_qb(t1
, v1_t
, v2_t
);
24150 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
24151 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
24152 tcg_gen_shli_tl(t1
, t1
, 24);
24153 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
24155 case OPC_CMPGDU_LE_QB
:
24157 gen_helper_cmpgu_le_qb(t1
, v1_t
, v2_t
);
24158 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
24159 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
24160 tcg_gen_shli_tl(t1
, t1
, 24);
24161 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
24163 case OPC_CMP_EQ_PH
:
24165 gen_helper_cmp_eq_ph(v1_t
, v2_t
, cpu_env
);
24167 case OPC_CMP_LT_PH
:
24169 gen_helper_cmp_lt_ph(v1_t
, v2_t
, cpu_env
);
24171 case OPC_CMP_LE_PH
:
24173 gen_helper_cmp_le_ph(v1_t
, v2_t
, cpu_env
);
24177 gen_helper_pick_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
24181 gen_helper_pick_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
24183 case OPC_PACKRL_PH
:
24185 gen_helper_packrl_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
24189 #ifdef TARGET_MIPS64
24190 case OPC_CMPU_EQ_OB_DSP
:
24192 case OPC_CMP_EQ_PW
:
24194 gen_helper_cmp_eq_pw(v1_t
, v2_t
, cpu_env
);
24196 case OPC_CMP_LT_PW
:
24198 gen_helper_cmp_lt_pw(v1_t
, v2_t
, cpu_env
);
24200 case OPC_CMP_LE_PW
:
24202 gen_helper_cmp_le_pw(v1_t
, v2_t
, cpu_env
);
24204 case OPC_CMP_EQ_QH
:
24206 gen_helper_cmp_eq_qh(v1_t
, v2_t
, cpu_env
);
24208 case OPC_CMP_LT_QH
:
24210 gen_helper_cmp_lt_qh(v1_t
, v2_t
, cpu_env
);
24212 case OPC_CMP_LE_QH
:
24214 gen_helper_cmp_le_qh(v1_t
, v2_t
, cpu_env
);
24216 case OPC_CMPGDU_EQ_OB
:
24218 gen_helper_cmpgdu_eq_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
24220 case OPC_CMPGDU_LT_OB
:
24222 gen_helper_cmpgdu_lt_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
24224 case OPC_CMPGDU_LE_OB
:
24226 gen_helper_cmpgdu_le_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
24228 case OPC_CMPGU_EQ_OB
:
24230 gen_helper_cmpgu_eq_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
24232 case OPC_CMPGU_LT_OB
:
24234 gen_helper_cmpgu_lt_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
24236 case OPC_CMPGU_LE_OB
:
24238 gen_helper_cmpgu_le_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
24240 case OPC_CMPU_EQ_OB
:
24242 gen_helper_cmpu_eq_ob(v1_t
, v2_t
, cpu_env
);
24244 case OPC_CMPU_LT_OB
:
24246 gen_helper_cmpu_lt_ob(v1_t
, v2_t
, cpu_env
);
24248 case OPC_CMPU_LE_OB
:
24250 gen_helper_cmpu_le_ob(v1_t
, v2_t
, cpu_env
);
24252 case OPC_PACKRL_PW
:
24254 gen_helper_packrl_pw(cpu_gpr
[ret
], v1_t
, v2_t
);
24258 gen_helper_pick_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
24262 gen_helper_pick_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
24266 gen_helper_pick_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
24274 tcg_temp_free(v1_t
);
24275 tcg_temp_free(v2_t
);
24278 static void gen_mipsdsp_append(CPUMIPSState
*env
, DisasContext
*ctx
,
24279 uint32_t op1
, int rt
, int rs
, int sa
)
24286 /* Treat as NOP. */
24290 t0
= tcg_temp_new();
24291 gen_load_gpr(t0
, rs
);
24294 case OPC_APPEND_DSP
:
24295 switch (MASK_APPEND(ctx
->opcode
)) {
24298 tcg_gen_deposit_tl(cpu_gpr
[rt
], t0
, cpu_gpr
[rt
], sa
, 32 - sa
);
24300 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
24304 tcg_gen_ext32u_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
24305 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], sa
);
24306 tcg_gen_shli_tl(t0
, t0
, 32 - sa
);
24307 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
24309 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
24313 if (sa
!= 0 && sa
!= 2) {
24314 tcg_gen_shli_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 8 * sa
);
24315 tcg_gen_ext32u_tl(t0
, t0
);
24316 tcg_gen_shri_tl(t0
, t0
, 8 * (4 - sa
));
24317 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
24319 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
24321 default: /* Invalid */
24322 MIPS_INVAL("MASK APPEND");
24323 gen_reserved_instruction(ctx
);
24327 #ifdef TARGET_MIPS64
24328 case OPC_DAPPEND_DSP
:
24329 switch (MASK_DAPPEND(ctx
->opcode
)) {
24332 tcg_gen_deposit_tl(cpu_gpr
[rt
], t0
, cpu_gpr
[rt
], sa
, 64 - sa
);
24336 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 0x20 | sa
);
24337 tcg_gen_shli_tl(t0
, t0
, 64 - (0x20 | sa
));
24338 tcg_gen_or_tl(cpu_gpr
[rt
], t0
, t0
);
24342 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], sa
);
24343 tcg_gen_shli_tl(t0
, t0
, 64 - sa
);
24344 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
24349 if (sa
!= 0 && sa
!= 2 && sa
!= 4) {
24350 tcg_gen_shli_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 8 * sa
);
24351 tcg_gen_shri_tl(t0
, t0
, 8 * (8 - sa
));
24352 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
24355 default: /* Invalid */
24356 MIPS_INVAL("MASK DAPPEND");
24357 gen_reserved_instruction(ctx
);
24366 static void gen_mipsdsp_accinsn(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
24367 int ret
, int v1
, int v2
, int check_ret
)
24376 if ((ret
== 0) && (check_ret
== 1)) {
24377 /* Treat as NOP. */
24381 t0
= tcg_temp_new();
24382 t1
= tcg_temp_new();
24383 v1_t
= tcg_temp_new();
24384 v2_t
= tcg_temp_new();
24386 gen_load_gpr(v1_t
, v1
);
24387 gen_load_gpr(v2_t
, v2
);
24390 case OPC_EXTR_W_DSP
:
24394 tcg_gen_movi_tl(t0
, v2
);
24395 tcg_gen_movi_tl(t1
, v1
);
24396 gen_helper_extr_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24399 tcg_gen_movi_tl(t0
, v2
);
24400 tcg_gen_movi_tl(t1
, v1
);
24401 gen_helper_extr_r_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24403 case OPC_EXTR_RS_W
:
24404 tcg_gen_movi_tl(t0
, v2
);
24405 tcg_gen_movi_tl(t1
, v1
);
24406 gen_helper_extr_rs_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24409 tcg_gen_movi_tl(t0
, v2
);
24410 tcg_gen_movi_tl(t1
, v1
);
24411 gen_helper_extr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24413 case OPC_EXTRV_S_H
:
24414 tcg_gen_movi_tl(t0
, v2
);
24415 gen_helper_extr_s_h(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24418 tcg_gen_movi_tl(t0
, v2
);
24419 gen_helper_extr_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24421 case OPC_EXTRV_R_W
:
24422 tcg_gen_movi_tl(t0
, v2
);
24423 gen_helper_extr_r_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24425 case OPC_EXTRV_RS_W
:
24426 tcg_gen_movi_tl(t0
, v2
);
24427 gen_helper_extr_rs_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24430 tcg_gen_movi_tl(t0
, v2
);
24431 tcg_gen_movi_tl(t1
, v1
);
24432 gen_helper_extp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24435 tcg_gen_movi_tl(t0
, v2
);
24436 gen_helper_extp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24439 tcg_gen_movi_tl(t0
, v2
);
24440 tcg_gen_movi_tl(t1
, v1
);
24441 gen_helper_extpdp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24444 tcg_gen_movi_tl(t0
, v2
);
24445 gen_helper_extpdp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24448 imm
= (ctx
->opcode
>> 20) & 0x3F;
24449 tcg_gen_movi_tl(t0
, ret
);
24450 tcg_gen_movi_tl(t1
, imm
);
24451 gen_helper_shilo(t0
, t1
, cpu_env
);
24454 tcg_gen_movi_tl(t0
, ret
);
24455 gen_helper_shilo(t0
, v1_t
, cpu_env
);
24458 tcg_gen_movi_tl(t0
, ret
);
24459 gen_helper_mthlip(t0
, v1_t
, cpu_env
);
24462 imm
= (ctx
->opcode
>> 11) & 0x3FF;
24463 tcg_gen_movi_tl(t0
, imm
);
24464 gen_helper_wrdsp(v1_t
, t0
, cpu_env
);
24467 imm
= (ctx
->opcode
>> 16) & 0x03FF;
24468 tcg_gen_movi_tl(t0
, imm
);
24469 gen_helper_rddsp(cpu_gpr
[ret
], t0
, cpu_env
);
24473 #ifdef TARGET_MIPS64
24474 case OPC_DEXTR_W_DSP
:
24478 tcg_gen_movi_tl(t0
, ret
);
24479 gen_helper_dmthlip(v1_t
, t0
, cpu_env
);
24483 int shift
= (ctx
->opcode
>> 19) & 0x7F;
24484 int ac
= (ctx
->opcode
>> 11) & 0x03;
24485 tcg_gen_movi_tl(t0
, shift
);
24486 tcg_gen_movi_tl(t1
, ac
);
24487 gen_helper_dshilo(t0
, t1
, cpu_env
);
24492 int ac
= (ctx
->opcode
>> 11) & 0x03;
24493 tcg_gen_movi_tl(t0
, ac
);
24494 gen_helper_dshilo(v1_t
, t0
, cpu_env
);
24498 tcg_gen_movi_tl(t0
, v2
);
24499 tcg_gen_movi_tl(t1
, v1
);
24501 gen_helper_dextp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24504 tcg_gen_movi_tl(t0
, v2
);
24505 gen_helper_dextp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24508 tcg_gen_movi_tl(t0
, v2
);
24509 tcg_gen_movi_tl(t1
, v1
);
24510 gen_helper_dextpdp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24513 tcg_gen_movi_tl(t0
, v2
);
24514 gen_helper_dextpdp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24517 tcg_gen_movi_tl(t0
, v2
);
24518 tcg_gen_movi_tl(t1
, v1
);
24519 gen_helper_dextr_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24521 case OPC_DEXTR_R_L
:
24522 tcg_gen_movi_tl(t0
, v2
);
24523 tcg_gen_movi_tl(t1
, v1
);
24524 gen_helper_dextr_r_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24526 case OPC_DEXTR_RS_L
:
24527 tcg_gen_movi_tl(t0
, v2
);
24528 tcg_gen_movi_tl(t1
, v1
);
24529 gen_helper_dextr_rs_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24532 tcg_gen_movi_tl(t0
, v2
);
24533 tcg_gen_movi_tl(t1
, v1
);
24534 gen_helper_dextr_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24536 case OPC_DEXTR_R_W
:
24537 tcg_gen_movi_tl(t0
, v2
);
24538 tcg_gen_movi_tl(t1
, v1
);
24539 gen_helper_dextr_r_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24541 case OPC_DEXTR_RS_W
:
24542 tcg_gen_movi_tl(t0
, v2
);
24543 tcg_gen_movi_tl(t1
, v1
);
24544 gen_helper_dextr_rs_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24546 case OPC_DEXTR_S_H
:
24547 tcg_gen_movi_tl(t0
, v2
);
24548 tcg_gen_movi_tl(t1
, v1
);
24549 gen_helper_dextr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24551 case OPC_DEXTRV_S_H
:
24552 tcg_gen_movi_tl(t0
, v2
);
24553 tcg_gen_movi_tl(t1
, v1
);
24554 gen_helper_dextr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24557 tcg_gen_movi_tl(t0
, v2
);
24558 gen_helper_dextr_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24560 case OPC_DEXTRV_R_L
:
24561 tcg_gen_movi_tl(t0
, v2
);
24562 gen_helper_dextr_r_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24564 case OPC_DEXTRV_RS_L
:
24565 tcg_gen_movi_tl(t0
, v2
);
24566 gen_helper_dextr_rs_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24569 tcg_gen_movi_tl(t0
, v2
);
24570 gen_helper_dextr_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24572 case OPC_DEXTRV_R_W
:
24573 tcg_gen_movi_tl(t0
, v2
);
24574 gen_helper_dextr_r_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24576 case OPC_DEXTRV_RS_W
:
24577 tcg_gen_movi_tl(t0
, v2
);
24578 gen_helper_dextr_rs_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24587 tcg_temp_free(v1_t
);
24588 tcg_temp_free(v2_t
);
24591 /* End MIPSDSP functions. */
24593 static void decode_opc_special_r6(CPUMIPSState
*env
, DisasContext
*ctx
)
24595 int rs
, rt
, rd
, sa
;
24598 rs
= (ctx
->opcode
>> 21) & 0x1f;
24599 rt
= (ctx
->opcode
>> 16) & 0x1f;
24600 rd
= (ctx
->opcode
>> 11) & 0x1f;
24601 sa
= (ctx
->opcode
>> 6) & 0x1f;
24603 op1
= MASK_SPECIAL(ctx
->opcode
);
24606 gen_lsa(ctx
, op1
, rd
, rs
, rt
, extract32(ctx
->opcode
, 6, 2));
24612 op2
= MASK_R6_MULDIV(ctx
->opcode
);
24622 gen_r6_muldiv(ctx
, op2
, rd
, rs
, rt
);
24625 MIPS_INVAL("special_r6 muldiv");
24626 gen_reserved_instruction(ctx
);
24632 gen_cond_move(ctx
, op1
, rd
, rs
, rt
);
24636 if (rt
== 0 && sa
== 1) {
24638 * Major opcode and function field is shared with preR6 MFHI/MTHI.
24639 * We need additionally to check other fields.
24641 gen_cl(ctx
, op1
, rd
, rs
);
24643 gen_reserved_instruction(ctx
);
24647 if (is_uhi(extract32(ctx
->opcode
, 6, 20))) {
24648 gen_helper_do_semihosting(cpu_env
);
24650 if (ctx
->hflags
& MIPS_HFLAG_SBRI
) {
24651 gen_reserved_instruction(ctx
);
24653 generate_exception_end(ctx
, EXCP_DBp
);
24657 #if defined(TARGET_MIPS64)
24659 check_mips_64(ctx
);
24660 gen_lsa(ctx
, op1
, rd
, rs
, rt
, extract32(ctx
->opcode
, 6, 2));
24664 if (rt
== 0 && sa
== 1) {
24666 * Major opcode and function field is shared with preR6 MFHI/MTHI.
24667 * We need additionally to check other fields.
24669 check_mips_64(ctx
);
24670 gen_cl(ctx
, op1
, rd
, rs
);
24672 gen_reserved_instruction(ctx
);
24680 op2
= MASK_R6_MULDIV(ctx
->opcode
);
24690 check_mips_64(ctx
);
24691 gen_r6_muldiv(ctx
, op2
, rd
, rs
, rt
);
24694 MIPS_INVAL("special_r6 muldiv");
24695 gen_reserved_instruction(ctx
);
24700 default: /* Invalid */
24701 MIPS_INVAL("special_r6");
24702 gen_reserved_instruction(ctx
);
24707 static void decode_opc_special_tx79(CPUMIPSState
*env
, DisasContext
*ctx
)
24709 int rs
= extract32(ctx
->opcode
, 21, 5);
24710 int rt
= extract32(ctx
->opcode
, 16, 5);
24711 int rd
= extract32(ctx
->opcode
, 11, 5);
24712 uint32_t op1
= MASK_SPECIAL(ctx
->opcode
);
24715 case OPC_MOVN
: /* Conditional move */
24717 gen_cond_move(ctx
, op1
, rd
, rs
, rt
);
24719 case OPC_MFHI
: /* Move from HI/LO */
24721 gen_HILO(ctx
, op1
, 0, rd
);
24724 case OPC_MTLO
: /* Move to HI/LO */
24725 gen_HILO(ctx
, op1
, 0, rs
);
24729 gen_mul_txx9(ctx
, op1
, rd
, rs
, rt
);
24733 gen_muldiv(ctx
, op1
, 0, rs
, rt
);
24735 #if defined(TARGET_MIPS64)
24740 check_insn_opc_user_only(ctx
, INSN_R5900
);
24741 gen_muldiv(ctx
, op1
, 0, rs
, rt
);
24745 gen_compute_branch(ctx
, op1
, 4, rs
, 0, 0, 4);
24747 default: /* Invalid */
24748 MIPS_INVAL("special_tx79");
24749 gen_reserved_instruction(ctx
);
24754 static void decode_opc_special_legacy(CPUMIPSState
*env
, DisasContext
*ctx
)
24756 int rs
, rt
, rd
, sa
;
24759 rs
= (ctx
->opcode
>> 21) & 0x1f;
24760 rt
= (ctx
->opcode
>> 16) & 0x1f;
24761 rd
= (ctx
->opcode
>> 11) & 0x1f;
24762 sa
= (ctx
->opcode
>> 6) & 0x1f;
24764 op1
= MASK_SPECIAL(ctx
->opcode
);
24766 case OPC_MOVN
: /* Conditional move */
24768 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS_R1
|
24769 INSN_LOONGSON2E
| INSN_LOONGSON2F
);
24770 gen_cond_move(ctx
, op1
, rd
, rs
, rt
);
24772 case OPC_MFHI
: /* Move from HI/LO */
24774 gen_HILO(ctx
, op1
, rs
& 3, rd
);
24777 case OPC_MTLO
: /* Move to HI/LO */
24778 gen_HILO(ctx
, op1
, rd
& 3, rs
);
24781 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS_R1
);
24782 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
24783 check_cp1_enabled(ctx
);
24784 gen_movci(ctx
, rd
, rs
, (ctx
->opcode
>> 18) & 0x7,
24785 (ctx
->opcode
>> 16) & 1);
24787 generate_exception_err(ctx
, EXCP_CpU
, 1);
24793 check_insn(ctx
, INSN_VR54XX
);
24794 op1
= MASK_MUL_VR54XX(ctx
->opcode
);
24795 gen_mul_vr54xx(ctx
, op1
, rd
, rs
, rt
);
24797 gen_muldiv(ctx
, op1
, rd
& 3, rs
, rt
);
24802 gen_muldiv(ctx
, op1
, 0, rs
, rt
);
24804 #if defined(TARGET_MIPS64)
24809 check_insn(ctx
, ISA_MIPS3
);
24810 check_mips_64(ctx
);
24811 gen_muldiv(ctx
, op1
, 0, rs
, rt
);
24815 gen_compute_branch(ctx
, op1
, 4, rs
, rd
, sa
, 4);
24818 #ifdef MIPS_STRICT_STANDARD
24819 MIPS_INVAL("SPIM");
24820 gen_reserved_instruction(ctx
);
24822 /* Implemented as RI exception for now. */
24823 MIPS_INVAL("spim (unofficial)");
24824 gen_reserved_instruction(ctx
);
24827 default: /* Invalid */
24828 MIPS_INVAL("special_legacy");
24829 gen_reserved_instruction(ctx
);
24834 static void decode_opc_special(CPUMIPSState
*env
, DisasContext
*ctx
)
24836 int rs
, rt
, rd
, sa
;
24839 rs
= (ctx
->opcode
>> 21) & 0x1f;
24840 rt
= (ctx
->opcode
>> 16) & 0x1f;
24841 rd
= (ctx
->opcode
>> 11) & 0x1f;
24842 sa
= (ctx
->opcode
>> 6) & 0x1f;
24844 op1
= MASK_SPECIAL(ctx
->opcode
);
24846 case OPC_SLL
: /* Shift with immediate */
24847 if (sa
== 5 && rd
== 0 &&
24848 rs
== 0 && rt
== 0) { /* PAUSE */
24849 if ((ctx
->insn_flags
& ISA_MIPS_R6
) &&
24850 (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
24851 gen_reserved_instruction(ctx
);
24857 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
24860 switch ((ctx
->opcode
>> 21) & 0x1f) {
24862 /* rotr is decoded as srl on non-R2 CPUs */
24863 if (ctx
->insn_flags
& ISA_MIPS_R2
) {
24868 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
24871 gen_reserved_instruction(ctx
);
24879 gen_arith(ctx
, op1
, rd
, rs
, rt
);
24881 case OPC_SLLV
: /* Shifts */
24883 gen_shift(ctx
, op1
, rd
, rs
, rt
);
24886 switch ((ctx
->opcode
>> 6) & 0x1f) {
24888 /* rotrv is decoded as srlv on non-R2 CPUs */
24889 if (ctx
->insn_flags
& ISA_MIPS_R2
) {
24894 gen_shift(ctx
, op1
, rd
, rs
, rt
);
24897 gen_reserved_instruction(ctx
);
24901 case OPC_SLT
: /* Set on less than */
24903 gen_slt(ctx
, op1
, rd
, rs
, rt
);
24905 case OPC_AND
: /* Logic*/
24909 gen_logic(ctx
, op1
, rd
, rs
, rt
);
24912 gen_compute_branch(ctx
, op1
, 4, rs
, rd
, sa
, 4);
24914 case OPC_TGE
: /* Traps */
24920 check_insn(ctx
, ISA_MIPS2
);
24921 gen_trap(ctx
, op1
, rs
, rt
, -1);
24923 case OPC_LSA
: /* OPC_PMON */
24924 if ((ctx
->insn_flags
& ISA_MIPS_R6
) ||
24925 (env
->CP0_Config3
& (1 << CP0C3_MSAP
))) {
24926 decode_opc_special_r6(env
, ctx
);
24928 /* Pmon entry point, also R4010 selsl */
24929 #ifdef MIPS_STRICT_STANDARD
24930 MIPS_INVAL("PMON / selsl");
24931 gen_reserved_instruction(ctx
);
24933 gen_helper_0e0i(pmon
, sa
);
24938 generate_exception_end(ctx
, EXCP_SYSCALL
);
24941 generate_exception_end(ctx
, EXCP_BREAK
);
24944 check_insn(ctx
, ISA_MIPS2
);
24945 gen_sync(extract32(ctx
->opcode
, 6, 5));
24948 #if defined(TARGET_MIPS64)
24949 /* MIPS64 specific opcodes */
24954 check_insn(ctx
, ISA_MIPS3
);
24955 check_mips_64(ctx
);
24956 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
24959 switch ((ctx
->opcode
>> 21) & 0x1f) {
24961 /* drotr is decoded as dsrl on non-R2 CPUs */
24962 if (ctx
->insn_flags
& ISA_MIPS_R2
) {
24967 check_insn(ctx
, ISA_MIPS3
);
24968 check_mips_64(ctx
);
24969 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
24972 gen_reserved_instruction(ctx
);
24977 switch ((ctx
->opcode
>> 21) & 0x1f) {
24979 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
24980 if (ctx
->insn_flags
& ISA_MIPS_R2
) {
24985 check_insn(ctx
, ISA_MIPS3
);
24986 check_mips_64(ctx
);
24987 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
24990 gen_reserved_instruction(ctx
);
24998 check_insn(ctx
, ISA_MIPS3
);
24999 check_mips_64(ctx
);
25000 gen_arith(ctx
, op1
, rd
, rs
, rt
);
25004 check_insn(ctx
, ISA_MIPS3
);
25005 check_mips_64(ctx
);
25006 gen_shift(ctx
, op1
, rd
, rs
, rt
);
25009 switch ((ctx
->opcode
>> 6) & 0x1f) {
25011 /* drotrv is decoded as dsrlv on non-R2 CPUs */
25012 if (ctx
->insn_flags
& ISA_MIPS_R2
) {
25017 check_insn(ctx
, ISA_MIPS3
);
25018 check_mips_64(ctx
);
25019 gen_shift(ctx
, op1
, rd
, rs
, rt
);
25022 gen_reserved_instruction(ctx
);
25027 if ((ctx
->insn_flags
& ISA_MIPS_R6
) ||
25028 (env
->CP0_Config3
& (1 << CP0C3_MSAP
))) {
25029 decode_opc_special_r6(env
, ctx
);
25034 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
25035 decode_opc_special_r6(env
, ctx
);
25036 } else if (ctx
->insn_flags
& INSN_R5900
) {
25037 decode_opc_special_tx79(env
, ctx
);
25039 decode_opc_special_legacy(env
, ctx
);
25045 #if defined(TARGET_MIPS64)
25049 * MMI (MultiMedia Interface) ASE instructions
25050 * ===========================================
25054 * MMI instructions category: data communication
25055 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
25057 * PCPYH PEXCH PEXTLB PINTH PPACB PEXT5 PREVH
25058 * PCPYLD PEXCW PEXTLH PINTEH PPACH PPAC5 PROT3W
25059 * PCPYUD PEXEH PEXTLW PPACW
25068 * Parallel Copy Halfword
25070 * 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
25071 * +-----------+---------+---------+---------+---------+-----------+
25072 * | MMI |0 0 0 0 0| rt | rd | PCPYH | MMI3 |
25073 * +-----------+---------+---------+---------+---------+-----------+
25075 static void gen_mmi_pcpyh(DisasContext
*ctx
)
25077 uint32_t pd
, rt
, rd
;
25080 opcode
= ctx
->opcode
;
25082 pd
= extract32(opcode
, 21, 5);
25083 rt
= extract32(opcode
, 16, 5);
25084 rd
= extract32(opcode
, 11, 5);
25086 if (unlikely(pd
!= 0)) {
25087 gen_reserved_instruction(ctx
);
25088 } else if (rd
== 0) {
25090 } else if (rt
== 0) {
25091 tcg_gen_movi_i64(cpu_gpr
[rd
], 0);
25092 tcg_gen_movi_i64(cpu_mmr
[rd
], 0);
25094 TCGv_i64 t0
= tcg_temp_new();
25095 TCGv_i64 t1
= tcg_temp_new();
25096 uint64_t mask
= (1ULL << 16) - 1;
25098 tcg_gen_andi_i64(t0
, cpu_gpr
[rt
], mask
);
25099 tcg_gen_movi_i64(t1
, 0);
25100 tcg_gen_or_i64(t1
, t0
, t1
);
25101 tcg_gen_shli_i64(t0
, t0
, 16);
25102 tcg_gen_or_i64(t1
, t0
, t1
);
25103 tcg_gen_shli_i64(t0
, t0
, 16);
25104 tcg_gen_or_i64(t1
, t0
, t1
);
25105 tcg_gen_shli_i64(t0
, t0
, 16);
25106 tcg_gen_or_i64(t1
, t0
, t1
);
25108 tcg_gen_mov_i64(cpu_gpr
[rd
], t1
);
25110 tcg_gen_andi_i64(t0
, cpu_mmr
[rt
], mask
);
25111 tcg_gen_movi_i64(t1
, 0);
25112 tcg_gen_or_i64(t1
, t0
, t1
);
25113 tcg_gen_shli_i64(t0
, t0
, 16);
25114 tcg_gen_or_i64(t1
, t0
, t1
);
25115 tcg_gen_shli_i64(t0
, t0
, 16);
25116 tcg_gen_or_i64(t1
, t0
, t1
);
25117 tcg_gen_shli_i64(t0
, t0
, 16);
25118 tcg_gen_or_i64(t1
, t0
, t1
);
25120 tcg_gen_mov_i64(cpu_mmr
[rd
], t1
);
25128 * PCPYLD rd, rs, rt
25130 * Parallel Copy Lower Doubleword
25132 * 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
25133 * +-----------+---------+---------+---------+---------+-----------+
25134 * | MMI | rs | rt | rd | PCPYLD | MMI2 |
25135 * +-----------+---------+---------+---------+---------+-----------+
25137 static void gen_mmi_pcpyld(DisasContext
*ctx
)
25139 uint32_t rs
, rt
, rd
;
25142 opcode
= ctx
->opcode
;
25144 rs
= extract32(opcode
, 21, 5);
25145 rt
= extract32(opcode
, 16, 5);
25146 rd
= extract32(opcode
, 11, 5);
25152 tcg_gen_movi_i64(cpu_mmr
[rd
], 0);
25154 tcg_gen_mov_i64(cpu_mmr
[rd
], cpu_gpr
[rs
]);
25157 tcg_gen_movi_i64(cpu_gpr
[rd
], 0);
25160 tcg_gen_mov_i64(cpu_gpr
[rd
], cpu_gpr
[rt
]);
25167 * PCPYUD rd, rs, rt
25169 * Parallel Copy Upper Doubleword
25171 * 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
25172 * +-----------+---------+---------+---------+---------+-----------+
25173 * | MMI | rs | rt | rd | PCPYUD | MMI3 |
25174 * +-----------+---------+---------+---------+---------+-----------+
25176 static void gen_mmi_pcpyud(DisasContext
*ctx
)
25178 uint32_t rs
, rt
, rd
;
25181 opcode
= ctx
->opcode
;
25183 rs
= extract32(opcode
, 21, 5);
25184 rt
= extract32(opcode
, 16, 5);
25185 rd
= extract32(opcode
, 11, 5);
25191 tcg_gen_movi_i64(cpu_gpr
[rd
], 0);
25193 tcg_gen_mov_i64(cpu_gpr
[rd
], cpu_mmr
[rs
]);
25196 tcg_gen_movi_i64(cpu_mmr
[rd
], 0);
25199 tcg_gen_mov_i64(cpu_mmr
[rd
], cpu_mmr
[rt
]);
25208 #if !defined(TARGET_MIPS64)
25210 /* MXU accumulate add/subtract 1-bit pattern 'aptn1' */
25211 #define MXU_APTN1_A 0
25212 #define MXU_APTN1_S 1
25214 /* MXU accumulate add/subtract 2-bit pattern 'aptn2' */
25215 #define MXU_APTN2_AA 0
25216 #define MXU_APTN2_AS 1
25217 #define MXU_APTN2_SA 2
25218 #define MXU_APTN2_SS 3
25220 /* MXU execute add/subtract 2-bit pattern 'eptn2' */
25221 #define MXU_EPTN2_AA 0
25222 #define MXU_EPTN2_AS 1
25223 #define MXU_EPTN2_SA 2
25224 #define MXU_EPTN2_SS 3
25226 /* MXU operand getting pattern 'optn2' */
25227 #define MXU_OPTN2_PTN0 0
25228 #define MXU_OPTN2_PTN1 1
25229 #define MXU_OPTN2_PTN2 2
25230 #define MXU_OPTN2_PTN3 3
25231 /* alternative naming scheme for 'optn2' */
25232 #define MXU_OPTN2_WW 0
25233 #define MXU_OPTN2_LW 1
25234 #define MXU_OPTN2_HW 2
25235 #define MXU_OPTN2_XW 3
25237 /* MXU operand getting pattern 'optn3' */
25238 #define MXU_OPTN3_PTN0 0
25239 #define MXU_OPTN3_PTN1 1
25240 #define MXU_OPTN3_PTN2 2
25241 #define MXU_OPTN3_PTN3 3
25242 #define MXU_OPTN3_PTN4 4
25243 #define MXU_OPTN3_PTN5 5
25244 #define MXU_OPTN3_PTN6 6
25245 #define MXU_OPTN3_PTN7 7
25249 * S32I2M XRa, rb - Register move from GRF to XRF
25251 static void gen_mxu_s32i2m(DisasContext
*ctx
)
25256 t0
= tcg_temp_new();
25258 XRa
= extract32(ctx
->opcode
, 6, 5);
25259 Rb
= extract32(ctx
->opcode
, 16, 5);
25261 gen_load_gpr(t0
, Rb
);
25263 gen_store_mxu_gpr(t0
, XRa
);
25264 } else if (XRa
== 16) {
25265 gen_store_mxu_cr(t0
);
25272 * S32M2I XRa, rb - Register move from XRF to GRF
25274 static void gen_mxu_s32m2i(DisasContext
*ctx
)
25279 t0
= tcg_temp_new();
25281 XRa
= extract32(ctx
->opcode
, 6, 5);
25282 Rb
= extract32(ctx
->opcode
, 16, 5);
25285 gen_load_mxu_gpr(t0
, XRa
);
25286 } else if (XRa
== 16) {
25287 gen_load_mxu_cr(t0
);
25290 gen_store_gpr(t0
, Rb
);
25296 * S8LDD XRa, Rb, s8, optn3 - Load a byte from memory to XRF
25298 static void gen_mxu_s8ldd(DisasContext
*ctx
)
25301 uint32_t XRa
, Rb
, s8
, optn3
;
25303 t0
= tcg_temp_new();
25304 t1
= tcg_temp_new();
25306 XRa
= extract32(ctx
->opcode
, 6, 4);
25307 s8
= extract32(ctx
->opcode
, 10, 8);
25308 optn3
= extract32(ctx
->opcode
, 18, 3);
25309 Rb
= extract32(ctx
->opcode
, 21, 5);
25311 gen_load_gpr(t0
, Rb
);
25312 tcg_gen_addi_tl(t0
, t0
, (int8_t)s8
);
25315 /* XRa[7:0] = tmp8 */
25316 case MXU_OPTN3_PTN0
:
25317 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
25318 gen_load_mxu_gpr(t0
, XRa
);
25319 tcg_gen_deposit_tl(t0
, t0
, t1
, 0, 8);
25321 /* XRa[15:8] = tmp8 */
25322 case MXU_OPTN3_PTN1
:
25323 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
25324 gen_load_mxu_gpr(t0
, XRa
);
25325 tcg_gen_deposit_tl(t0
, t0
, t1
, 8, 8);
25327 /* XRa[23:16] = tmp8 */
25328 case MXU_OPTN3_PTN2
:
25329 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
25330 gen_load_mxu_gpr(t0
, XRa
);
25331 tcg_gen_deposit_tl(t0
, t0
, t1
, 16, 8);
25333 /* XRa[31:24] = tmp8 */
25334 case MXU_OPTN3_PTN3
:
25335 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
25336 gen_load_mxu_gpr(t0
, XRa
);
25337 tcg_gen_deposit_tl(t0
, t0
, t1
, 24, 8);
25339 /* XRa = {8'b0, tmp8, 8'b0, tmp8} */
25340 case MXU_OPTN3_PTN4
:
25341 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
25342 tcg_gen_deposit_tl(t0
, t1
, t1
, 16, 16);
25344 /* XRa = {tmp8, 8'b0, tmp8, 8'b0} */
25345 case MXU_OPTN3_PTN5
:
25346 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
25347 tcg_gen_shli_tl(t1
, t1
, 8);
25348 tcg_gen_deposit_tl(t0
, t1
, t1
, 16, 16);
25350 /* XRa = {{8{sign of tmp8}}, tmp8, {8{sign of tmp8}}, tmp8} */
25351 case MXU_OPTN3_PTN6
:
25352 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_SB
);
25353 tcg_gen_mov_tl(t0
, t1
);
25354 tcg_gen_andi_tl(t0
, t0
, 0xFF00FFFF);
25355 tcg_gen_shli_tl(t1
, t1
, 16);
25356 tcg_gen_or_tl(t0
, t0
, t1
);
25358 /* XRa = {tmp8, tmp8, tmp8, tmp8} */
25359 case MXU_OPTN3_PTN7
:
25360 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
25361 tcg_gen_deposit_tl(t1
, t1
, t1
, 8, 8);
25362 tcg_gen_deposit_tl(t0
, t1
, t1
, 16, 16);
25366 gen_store_mxu_gpr(t0
, XRa
);
25373 * D16MUL XRa, XRb, XRc, XRd, optn2 - Signed 16 bit pattern multiplication
25375 static void gen_mxu_d16mul(DisasContext
*ctx
)
25377 TCGv t0
, t1
, t2
, t3
;
25378 uint32_t XRa
, XRb
, XRc
, XRd
, optn2
;
25380 t0
= tcg_temp_new();
25381 t1
= tcg_temp_new();
25382 t2
= tcg_temp_new();
25383 t3
= tcg_temp_new();
25385 XRa
= extract32(ctx
->opcode
, 6, 4);
25386 XRb
= extract32(ctx
->opcode
, 10, 4);
25387 XRc
= extract32(ctx
->opcode
, 14, 4);
25388 XRd
= extract32(ctx
->opcode
, 18, 4);
25389 optn2
= extract32(ctx
->opcode
, 22, 2);
25391 gen_load_mxu_gpr(t1
, XRb
);
25392 tcg_gen_sextract_tl(t0
, t1
, 0, 16);
25393 tcg_gen_sextract_tl(t1
, t1
, 16, 16);
25394 gen_load_mxu_gpr(t3
, XRc
);
25395 tcg_gen_sextract_tl(t2
, t3
, 0, 16);
25396 tcg_gen_sextract_tl(t3
, t3
, 16, 16);
25399 case MXU_OPTN2_WW
: /* XRB.H*XRC.H == lop, XRB.L*XRC.L == rop */
25400 tcg_gen_mul_tl(t3
, t1
, t3
);
25401 tcg_gen_mul_tl(t2
, t0
, t2
);
25403 case MXU_OPTN2_LW
: /* XRB.L*XRC.H == lop, XRB.L*XRC.L == rop */
25404 tcg_gen_mul_tl(t3
, t0
, t3
);
25405 tcg_gen_mul_tl(t2
, t0
, t2
);
25407 case MXU_OPTN2_HW
: /* XRB.H*XRC.H == lop, XRB.H*XRC.L == rop */
25408 tcg_gen_mul_tl(t3
, t1
, t3
);
25409 tcg_gen_mul_tl(t2
, t1
, t2
);
25411 case MXU_OPTN2_XW
: /* XRB.L*XRC.H == lop, XRB.H*XRC.L == rop */
25412 tcg_gen_mul_tl(t3
, t0
, t3
);
25413 tcg_gen_mul_tl(t2
, t1
, t2
);
25416 gen_store_mxu_gpr(t3
, XRa
);
25417 gen_store_mxu_gpr(t2
, XRd
);
25426 * D16MAC XRa, XRb, XRc, XRd, aptn2, optn2 - Signed 16 bit pattern multiply
25429 static void gen_mxu_d16mac(DisasContext
*ctx
)
25431 TCGv t0
, t1
, t2
, t3
;
25432 uint32_t XRa
, XRb
, XRc
, XRd
, optn2
, aptn2
;
25434 t0
= tcg_temp_new();
25435 t1
= tcg_temp_new();
25436 t2
= tcg_temp_new();
25437 t3
= tcg_temp_new();
25439 XRa
= extract32(ctx
->opcode
, 6, 4);
25440 XRb
= extract32(ctx
->opcode
, 10, 4);
25441 XRc
= extract32(ctx
->opcode
, 14, 4);
25442 XRd
= extract32(ctx
->opcode
, 18, 4);
25443 optn2
= extract32(ctx
->opcode
, 22, 2);
25444 aptn2
= extract32(ctx
->opcode
, 24, 2);
25446 gen_load_mxu_gpr(t1
, XRb
);
25447 tcg_gen_sextract_tl(t0
, t1
, 0, 16);
25448 tcg_gen_sextract_tl(t1
, t1
, 16, 16);
25450 gen_load_mxu_gpr(t3
, XRc
);
25451 tcg_gen_sextract_tl(t2
, t3
, 0, 16);
25452 tcg_gen_sextract_tl(t3
, t3
, 16, 16);
25455 case MXU_OPTN2_WW
: /* XRB.H*XRC.H == lop, XRB.L*XRC.L == rop */
25456 tcg_gen_mul_tl(t3
, t1
, t3
);
25457 tcg_gen_mul_tl(t2
, t0
, t2
);
25459 case MXU_OPTN2_LW
: /* XRB.L*XRC.H == lop, XRB.L*XRC.L == rop */
25460 tcg_gen_mul_tl(t3
, t0
, t3
);
25461 tcg_gen_mul_tl(t2
, t0
, t2
);
25463 case MXU_OPTN2_HW
: /* XRB.H*XRC.H == lop, XRB.H*XRC.L == rop */
25464 tcg_gen_mul_tl(t3
, t1
, t3
);
25465 tcg_gen_mul_tl(t2
, t1
, t2
);
25467 case MXU_OPTN2_XW
: /* XRB.L*XRC.H == lop, XRB.H*XRC.L == rop */
25468 tcg_gen_mul_tl(t3
, t0
, t3
);
25469 tcg_gen_mul_tl(t2
, t1
, t2
);
25472 gen_load_mxu_gpr(t0
, XRa
);
25473 gen_load_mxu_gpr(t1
, XRd
);
25477 tcg_gen_add_tl(t3
, t0
, t3
);
25478 tcg_gen_add_tl(t2
, t1
, t2
);
25481 tcg_gen_add_tl(t3
, t0
, t3
);
25482 tcg_gen_sub_tl(t2
, t1
, t2
);
25485 tcg_gen_sub_tl(t3
, t0
, t3
);
25486 tcg_gen_add_tl(t2
, t1
, t2
);
25489 tcg_gen_sub_tl(t3
, t0
, t3
);
25490 tcg_gen_sub_tl(t2
, t1
, t2
);
25493 gen_store_mxu_gpr(t3
, XRa
);
25494 gen_store_mxu_gpr(t2
, XRd
);
25503 * Q8MUL XRa, XRb, XRc, XRd - Parallel unsigned 8 bit pattern multiply
25504 * Q8MULSU XRa, XRb, XRc, XRd - Parallel signed 8 bit pattern multiply
25506 static void gen_mxu_q8mul_q8mulsu(DisasContext
*ctx
)
25508 TCGv t0
, t1
, t2
, t3
, t4
, t5
, t6
, t7
;
25509 uint32_t XRa
, XRb
, XRc
, XRd
, sel
;
25511 t0
= tcg_temp_new();
25512 t1
= tcg_temp_new();
25513 t2
= tcg_temp_new();
25514 t3
= tcg_temp_new();
25515 t4
= tcg_temp_new();
25516 t5
= tcg_temp_new();
25517 t6
= tcg_temp_new();
25518 t7
= tcg_temp_new();
25520 XRa
= extract32(ctx
->opcode
, 6, 4);
25521 XRb
= extract32(ctx
->opcode
, 10, 4);
25522 XRc
= extract32(ctx
->opcode
, 14, 4);
25523 XRd
= extract32(ctx
->opcode
, 18, 4);
25524 sel
= extract32(ctx
->opcode
, 22, 2);
25526 gen_load_mxu_gpr(t3
, XRb
);
25527 gen_load_mxu_gpr(t7
, XRc
);
25531 tcg_gen_ext8s_tl(t0
, t3
);
25532 tcg_gen_shri_tl(t3
, t3
, 8);
25533 tcg_gen_ext8s_tl(t1
, t3
);
25534 tcg_gen_shri_tl(t3
, t3
, 8);
25535 tcg_gen_ext8s_tl(t2
, t3
);
25536 tcg_gen_shri_tl(t3
, t3
, 8);
25537 tcg_gen_ext8s_tl(t3
, t3
);
25540 tcg_gen_ext8u_tl(t0
, t3
);
25541 tcg_gen_shri_tl(t3
, t3
, 8);
25542 tcg_gen_ext8u_tl(t1
, t3
);
25543 tcg_gen_shri_tl(t3
, t3
, 8);
25544 tcg_gen_ext8u_tl(t2
, t3
);
25545 tcg_gen_shri_tl(t3
, t3
, 8);
25546 tcg_gen_ext8u_tl(t3
, t3
);
25549 tcg_gen_ext8u_tl(t4
, t7
);
25550 tcg_gen_shri_tl(t7
, t7
, 8);
25551 tcg_gen_ext8u_tl(t5
, t7
);
25552 tcg_gen_shri_tl(t7
, t7
, 8);
25553 tcg_gen_ext8u_tl(t6
, t7
);
25554 tcg_gen_shri_tl(t7
, t7
, 8);
25555 tcg_gen_ext8u_tl(t7
, t7
);
25557 tcg_gen_mul_tl(t0
, t0
, t4
);
25558 tcg_gen_mul_tl(t1
, t1
, t5
);
25559 tcg_gen_mul_tl(t2
, t2
, t6
);
25560 tcg_gen_mul_tl(t3
, t3
, t7
);
25562 tcg_gen_andi_tl(t0
, t0
, 0xFFFF);
25563 tcg_gen_andi_tl(t1
, t1
, 0xFFFF);
25564 tcg_gen_andi_tl(t2
, t2
, 0xFFFF);
25565 tcg_gen_andi_tl(t3
, t3
, 0xFFFF);
25567 tcg_gen_shli_tl(t1
, t1
, 16);
25568 tcg_gen_shli_tl(t3
, t3
, 16);
25570 tcg_gen_or_tl(t0
, t0
, t1
);
25571 tcg_gen_or_tl(t1
, t2
, t3
);
25573 gen_store_mxu_gpr(t0
, XRd
);
25574 gen_store_mxu_gpr(t1
, XRa
);
25587 * S32LDD XRa, Rb, S12 - Load a word from memory to XRF
25588 * S32LDDR XRa, Rb, S12 - Load a word from memory to XRF, reversed byte seq.
25590 static void gen_mxu_s32ldd_s32lddr(DisasContext
*ctx
)
25593 uint32_t XRa
, Rb
, s12
, sel
;
25595 t0
= tcg_temp_new();
25596 t1
= tcg_temp_new();
25598 XRa
= extract32(ctx
->opcode
, 6, 4);
25599 s12
= extract32(ctx
->opcode
, 10, 10);
25600 sel
= extract32(ctx
->opcode
, 20, 1);
25601 Rb
= extract32(ctx
->opcode
, 21, 5);
25603 gen_load_gpr(t0
, Rb
);
25605 tcg_gen_movi_tl(t1
, s12
);
25606 tcg_gen_shli_tl(t1
, t1
, 2);
25608 tcg_gen_ori_tl(t1
, t1
, 0xFFFFF000);
25610 tcg_gen_add_tl(t1
, t0
, t1
);
25611 tcg_gen_qemu_ld_tl(t1
, t1
, ctx
->mem_idx
, MO_SL
);
25615 tcg_gen_bswap32_tl(t1
, t1
);
25617 gen_store_mxu_gpr(t1
, XRa
);
25625 * MXU instruction category: logic
25626 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
25628 * S32NOR S32AND S32OR S32XOR
25632 * S32NOR XRa, XRb, XRc
25633 * Update XRa with the result of logical bitwise 'nor' operation
25634 * applied to the content of XRb and XRc.
25636 * 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
25637 * +-----------+---------+-----+-------+-------+-------+-----------+
25638 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL16|
25639 * +-----------+---------+-----+-------+-------+-------+-----------+
25641 static void gen_mxu_S32NOR(DisasContext
*ctx
)
25643 uint32_t pad
, XRc
, XRb
, XRa
;
25645 pad
= extract32(ctx
->opcode
, 21, 5);
25646 XRc
= extract32(ctx
->opcode
, 14, 4);
25647 XRb
= extract32(ctx
->opcode
, 10, 4);
25648 XRa
= extract32(ctx
->opcode
, 6, 4);
25650 if (unlikely(pad
!= 0)) {
25651 /* opcode padding incorrect -> do nothing */
25652 } else if (unlikely(XRa
== 0)) {
25653 /* destination is zero register -> do nothing */
25654 } else if (unlikely((XRb
== 0) && (XRc
== 0))) {
25655 /* both operands zero registers -> just set destination to all 1s */
25656 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0xFFFFFFFF);
25657 } else if (unlikely(XRb
== 0)) {
25658 /* XRb zero register -> just set destination to the negation of XRc */
25659 tcg_gen_not_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRc
- 1]);
25660 } else if (unlikely(XRc
== 0)) {
25661 /* XRa zero register -> just set destination to the negation of XRb */
25662 tcg_gen_not_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25663 } else if (unlikely(XRb
== XRc
)) {
25664 /* both operands same -> just set destination to the negation of XRb */
25665 tcg_gen_not_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25667 /* the most general case */
25668 tcg_gen_nor_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1], mxu_gpr
[XRc
- 1]);
25673 * S32AND XRa, XRb, XRc
25674 * Update XRa with the result of logical bitwise 'and' operation
25675 * applied to the content of XRb and XRc.
25677 * 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
25678 * +-----------+---------+-----+-------+-------+-------+-----------+
25679 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL16|
25680 * +-----------+---------+-----+-------+-------+-------+-----------+
25682 static void gen_mxu_S32AND(DisasContext
*ctx
)
25684 uint32_t pad
, XRc
, XRb
, XRa
;
25686 pad
= extract32(ctx
->opcode
, 21, 5);
25687 XRc
= extract32(ctx
->opcode
, 14, 4);
25688 XRb
= extract32(ctx
->opcode
, 10, 4);
25689 XRa
= extract32(ctx
->opcode
, 6, 4);
25691 if (unlikely(pad
!= 0)) {
25692 /* opcode padding incorrect -> do nothing */
25693 } else if (unlikely(XRa
== 0)) {
25694 /* destination is zero register -> do nothing */
25695 } else if (unlikely((XRb
== 0) || (XRc
== 0))) {
25696 /* one of operands zero register -> just set destination to all 0s */
25697 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0);
25698 } else if (unlikely(XRb
== XRc
)) {
25699 /* both operands same -> just set destination to one of them */
25700 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25702 /* the most general case */
25703 tcg_gen_and_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1], mxu_gpr
[XRc
- 1]);
25708 * S32OR XRa, XRb, XRc
25709 * Update XRa with the result of logical bitwise 'or' operation
25710 * applied to the content of XRb and XRc.
25712 * 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
25713 * +-----------+---------+-----+-------+-------+-------+-----------+
25714 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL16|
25715 * +-----------+---------+-----+-------+-------+-------+-----------+
25717 static void gen_mxu_S32OR(DisasContext
*ctx
)
25719 uint32_t pad
, XRc
, XRb
, XRa
;
25721 pad
= extract32(ctx
->opcode
, 21, 5);
25722 XRc
= extract32(ctx
->opcode
, 14, 4);
25723 XRb
= extract32(ctx
->opcode
, 10, 4);
25724 XRa
= extract32(ctx
->opcode
, 6, 4);
25726 if (unlikely(pad
!= 0)) {
25727 /* opcode padding incorrect -> do nothing */
25728 } else if (unlikely(XRa
== 0)) {
25729 /* destination is zero register -> do nothing */
25730 } else if (unlikely((XRb
== 0) && (XRc
== 0))) {
25731 /* both operands zero registers -> just set destination to all 0s */
25732 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0);
25733 } else if (unlikely(XRb
== 0)) {
25734 /* XRb zero register -> just set destination to the content of XRc */
25735 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRc
- 1]);
25736 } else if (unlikely(XRc
== 0)) {
25737 /* XRc zero register -> just set destination to the content of XRb */
25738 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25739 } else if (unlikely(XRb
== XRc
)) {
25740 /* both operands same -> just set destination to one of them */
25741 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25743 /* the most general case */
25744 tcg_gen_or_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1], mxu_gpr
[XRc
- 1]);
25749 * S32XOR XRa, XRb, XRc
25750 * Update XRa with the result of logical bitwise 'xor' operation
25751 * applied to the content of XRb and XRc.
25753 * 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
25754 * +-----------+---------+-----+-------+-------+-------+-----------+
25755 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL16|
25756 * +-----------+---------+-----+-------+-------+-------+-----------+
25758 static void gen_mxu_S32XOR(DisasContext
*ctx
)
25760 uint32_t pad
, XRc
, XRb
, XRa
;
25762 pad
= extract32(ctx
->opcode
, 21, 5);
25763 XRc
= extract32(ctx
->opcode
, 14, 4);
25764 XRb
= extract32(ctx
->opcode
, 10, 4);
25765 XRa
= extract32(ctx
->opcode
, 6, 4);
25767 if (unlikely(pad
!= 0)) {
25768 /* opcode padding incorrect -> do nothing */
25769 } else if (unlikely(XRa
== 0)) {
25770 /* destination is zero register -> do nothing */
25771 } else if (unlikely((XRb
== 0) && (XRc
== 0))) {
25772 /* both operands zero registers -> just set destination to all 0s */
25773 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0);
25774 } else if (unlikely(XRb
== 0)) {
25775 /* XRb zero register -> just set destination to the content of XRc */
25776 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRc
- 1]);
25777 } else if (unlikely(XRc
== 0)) {
25778 /* XRc zero register -> just set destination to the content of XRb */
25779 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25780 } else if (unlikely(XRb
== XRc
)) {
25781 /* both operands same -> just set destination to all 0s */
25782 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0);
25784 /* the most general case */
25785 tcg_gen_xor_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1], mxu_gpr
[XRc
- 1]);
25791 * MXU instruction category max/min
25792 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
25794 * S32MAX D16MAX Q8MAX
25795 * S32MIN D16MIN Q8MIN
25799 * S32MAX XRa, XRb, XRc
25800 * Update XRa with the maximum of signed 32-bit integers contained
25803 * S32MIN XRa, XRb, XRc
25804 * Update XRa with the minimum of signed 32-bit integers contained
25807 * 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
25808 * +-----------+---------+-----+-------+-------+-------+-----------+
25809 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL00|
25810 * +-----------+---------+-----+-------+-------+-------+-----------+
25812 static void gen_mxu_S32MAX_S32MIN(DisasContext
*ctx
)
25814 uint32_t pad
, opc
, XRc
, XRb
, XRa
;
25816 pad
= extract32(ctx
->opcode
, 21, 5);
25817 opc
= extract32(ctx
->opcode
, 18, 3);
25818 XRc
= extract32(ctx
->opcode
, 14, 4);
25819 XRb
= extract32(ctx
->opcode
, 10, 4);
25820 XRa
= extract32(ctx
->opcode
, 6, 4);
25822 if (unlikely(pad
!= 0)) {
25823 /* opcode padding incorrect -> do nothing */
25824 } else if (unlikely(XRa
== 0)) {
25825 /* destination is zero register -> do nothing */
25826 } else if (unlikely((XRb
== 0) && (XRc
== 0))) {
25827 /* both operands zero registers -> just set destination to zero */
25828 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0);
25829 } else if (unlikely((XRb
== 0) || (XRc
== 0))) {
25830 /* exactly one operand is zero register - find which one is not...*/
25831 uint32_t XRx
= XRb
? XRb
: XRc
;
25832 /* ...and do max/min operation with one operand 0 */
25833 if (opc
== OPC_MXU_S32MAX
) {
25834 tcg_gen_smax_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRx
- 1], 0);
25836 tcg_gen_smin_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRx
- 1], 0);
25838 } else if (unlikely(XRb
== XRc
)) {
25839 /* both operands same -> just set destination to one of them */
25840 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25842 /* the most general case */
25843 if (opc
== OPC_MXU_S32MAX
) {
25844 tcg_gen_smax_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1],
25847 tcg_gen_smin_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1],
25855 * Update XRa with the 16-bit-wise maximums of signed integers
25856 * contained in XRb and XRc.
25859 * Update XRa with the 16-bit-wise minimums of signed integers
25860 * contained in XRb and XRc.
25862 * 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
25863 * +-----------+---------+-----+-------+-------+-------+-----------+
25864 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL00|
25865 * +-----------+---------+-----+-------+-------+-------+-----------+
25867 static void gen_mxu_D16MAX_D16MIN(DisasContext
*ctx
)
25869 uint32_t pad
, opc
, XRc
, XRb
, XRa
;
25871 pad
= extract32(ctx
->opcode
, 21, 5);
25872 opc
= extract32(ctx
->opcode
, 18, 3);
25873 XRc
= extract32(ctx
->opcode
, 14, 4);
25874 XRb
= extract32(ctx
->opcode
, 10, 4);
25875 XRa
= extract32(ctx
->opcode
, 6, 4);
25877 if (unlikely(pad
!= 0)) {
25878 /* opcode padding incorrect -> do nothing */
25879 } else if (unlikely(XRc
== 0)) {
25880 /* destination is zero register -> do nothing */
25881 } else if (unlikely((XRb
== 0) && (XRa
== 0))) {
25882 /* both operands zero registers -> just set destination to zero */
25883 tcg_gen_movi_i32(mxu_gpr
[XRc
- 1], 0);
25884 } else if (unlikely((XRb
== 0) || (XRa
== 0))) {
25885 /* exactly one operand is zero register - find which one is not...*/
25886 uint32_t XRx
= XRb
? XRb
: XRc
;
25887 /* ...and do half-word-wise max/min with one operand 0 */
25888 TCGv_i32 t0
= tcg_temp_new();
25889 TCGv_i32 t1
= tcg_const_i32(0);
25891 /* the left half-word first */
25892 tcg_gen_andi_i32(t0
, mxu_gpr
[XRx
- 1], 0xFFFF0000);
25893 if (opc
== OPC_MXU_D16MAX
) {
25894 tcg_gen_smax_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
25896 tcg_gen_smin_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
25899 /* the right half-word */
25900 tcg_gen_andi_i32(t0
, mxu_gpr
[XRx
- 1], 0x0000FFFF);
25901 /* move half-words to the leftmost position */
25902 tcg_gen_shli_i32(t0
, t0
, 16);
25903 /* t0 will be max/min of t0 and t1 */
25904 if (opc
== OPC_MXU_D16MAX
) {
25905 tcg_gen_smax_i32(t0
, t0
, t1
);
25907 tcg_gen_smin_i32(t0
, t0
, t1
);
25909 /* return resulting half-words to its original position */
25910 tcg_gen_shri_i32(t0
, t0
, 16);
25911 /* finally update the destination */
25912 tcg_gen_or_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRa
- 1], t0
);
25916 } else if (unlikely(XRb
== XRc
)) {
25917 /* both operands same -> just set destination to one of them */
25918 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25920 /* the most general case */
25921 TCGv_i32 t0
= tcg_temp_new();
25922 TCGv_i32 t1
= tcg_temp_new();
25924 /* the left half-word first */
25925 tcg_gen_andi_i32(t0
, mxu_gpr
[XRb
- 1], 0xFFFF0000);
25926 tcg_gen_andi_i32(t1
, mxu_gpr
[XRc
- 1], 0xFFFF0000);
25927 if (opc
== OPC_MXU_D16MAX
) {
25928 tcg_gen_smax_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
25930 tcg_gen_smin_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
25933 /* the right half-word */
25934 tcg_gen_andi_i32(t0
, mxu_gpr
[XRb
- 1], 0x0000FFFF);
25935 tcg_gen_andi_i32(t1
, mxu_gpr
[XRc
- 1], 0x0000FFFF);
25936 /* move half-words to the leftmost position */
25937 tcg_gen_shli_i32(t0
, t0
, 16);
25938 tcg_gen_shli_i32(t1
, t1
, 16);
25939 /* t0 will be max/min of t0 and t1 */
25940 if (opc
== OPC_MXU_D16MAX
) {
25941 tcg_gen_smax_i32(t0
, t0
, t1
);
25943 tcg_gen_smin_i32(t0
, t0
, t1
);
25945 /* return resulting half-words to its original position */
25946 tcg_gen_shri_i32(t0
, t0
, 16);
25947 /* finally update the destination */
25948 tcg_gen_or_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRa
- 1], t0
);
25957 * Update XRa with the 8-bit-wise maximums of signed integers
25958 * contained in XRb and XRc.
25961 * Update XRa with the 8-bit-wise minimums of signed integers
25962 * contained in XRb and XRc.
25964 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
25965 * +-----------+---------+-----+-------+-------+-------+-----------+
25966 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL00|
25967 * +-----------+---------+-----+-------+-------+-------+-----------+
25969 static void gen_mxu_Q8MAX_Q8MIN(DisasContext
*ctx
)
25971 uint32_t pad
, opc
, XRc
, XRb
, XRa
;
25973 pad
= extract32(ctx
->opcode
, 21, 5);
25974 opc
= extract32(ctx
->opcode
, 18, 3);
25975 XRc
= extract32(ctx
->opcode
, 14, 4);
25976 XRb
= extract32(ctx
->opcode
, 10, 4);
25977 XRa
= extract32(ctx
->opcode
, 6, 4);
25979 if (unlikely(pad
!= 0)) {
25980 /* opcode padding incorrect -> do nothing */
25981 } else if (unlikely(XRa
== 0)) {
25982 /* destination is zero register -> do nothing */
25983 } else if (unlikely((XRb
== 0) && (XRc
== 0))) {
25984 /* both operands zero registers -> just set destination to zero */
25985 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0);
25986 } else if (unlikely((XRb
== 0) || (XRc
== 0))) {
25987 /* exactly one operand is zero register - make it be the first...*/
25988 uint32_t XRx
= XRb
? XRb
: XRc
;
25989 /* ...and do byte-wise max/min with one operand 0 */
25990 TCGv_i32 t0
= tcg_temp_new();
25991 TCGv_i32 t1
= tcg_const_i32(0);
25994 /* the leftmost byte (byte 3) first */
25995 tcg_gen_andi_i32(t0
, mxu_gpr
[XRx
- 1], 0xFF000000);
25996 if (opc
== OPC_MXU_Q8MAX
) {
25997 tcg_gen_smax_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
25999 tcg_gen_smin_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
26002 /* bytes 2, 1, 0 */
26003 for (i
= 2; i
>= 0; i
--) {
26004 /* extract the byte */
26005 tcg_gen_andi_i32(t0
, mxu_gpr
[XRx
- 1], 0xFF << (8 * i
));
26006 /* move the byte to the leftmost position */
26007 tcg_gen_shli_i32(t0
, t0
, 8 * (3 - i
));
26008 /* t0 will be max/min of t0 and t1 */
26009 if (opc
== OPC_MXU_Q8MAX
) {
26010 tcg_gen_smax_i32(t0
, t0
, t1
);
26012 tcg_gen_smin_i32(t0
, t0
, t1
);
26014 /* return resulting byte to its original position */
26015 tcg_gen_shri_i32(t0
, t0
, 8 * (3 - i
));
26016 /* finally update the destination */
26017 tcg_gen_or_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRa
- 1], t0
);
26022 } else if (unlikely(XRb
== XRc
)) {
26023 /* both operands same -> just set destination to one of them */
26024 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
26026 /* the most general case */
26027 TCGv_i32 t0
= tcg_temp_new();
26028 TCGv_i32 t1
= tcg_temp_new();
26031 /* the leftmost bytes (bytes 3) first */
26032 tcg_gen_andi_i32(t0
, mxu_gpr
[XRb
- 1], 0xFF000000);
26033 tcg_gen_andi_i32(t1
, mxu_gpr
[XRc
- 1], 0xFF000000);
26034 if (opc
== OPC_MXU_Q8MAX
) {
26035 tcg_gen_smax_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
26037 tcg_gen_smin_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
26040 /* bytes 2, 1, 0 */
26041 for (i
= 2; i
>= 0; i
--) {
26042 /* extract corresponding bytes */
26043 tcg_gen_andi_i32(t0
, mxu_gpr
[XRb
- 1], 0xFF << (8 * i
));
26044 tcg_gen_andi_i32(t1
, mxu_gpr
[XRc
- 1], 0xFF << (8 * i
));
26045 /* move the bytes to the leftmost position */
26046 tcg_gen_shli_i32(t0
, t0
, 8 * (3 - i
));
26047 tcg_gen_shli_i32(t1
, t1
, 8 * (3 - i
));
26048 /* t0 will be max/min of t0 and t1 */
26049 if (opc
== OPC_MXU_Q8MAX
) {
26050 tcg_gen_smax_i32(t0
, t0
, t1
);
26052 tcg_gen_smin_i32(t0
, t0
, t1
);
26054 /* return resulting byte to its original position */
26055 tcg_gen_shri_i32(t0
, t0
, 8 * (3 - i
));
26056 /* finally update the destination */
26057 tcg_gen_or_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRa
- 1], t0
);
26067 * MXU instruction category: align
26068 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
26074 * S32ALNI XRc, XRb, XRa, optn3
26075 * Arrange bytes from XRb and XRc according to one of five sets of
26076 * rules determined by optn3, and place the result in XRa.
26078 * 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
26079 * +-----------+-----+---+-----+-------+-------+-------+-----------+
26080 * | SPECIAL2 |optn3|0 0|x x x| XRc | XRb | XRa |MXU__POOL16|
26081 * +-----------+-----+---+-----+-------+-------+-------+-----------+
26084 static void gen_mxu_S32ALNI(DisasContext
*ctx
)
26086 uint32_t optn3
, pad
, XRc
, XRb
, XRa
;
26088 optn3
= extract32(ctx
->opcode
, 23, 3);
26089 pad
= extract32(ctx
->opcode
, 21, 2);
26090 XRc
= extract32(ctx
->opcode
, 14, 4);
26091 XRb
= extract32(ctx
->opcode
, 10, 4);
26092 XRa
= extract32(ctx
->opcode
, 6, 4);
26094 if (unlikely(pad
!= 0)) {
26095 /* opcode padding incorrect -> do nothing */
26096 } else if (unlikely(XRa
== 0)) {
26097 /* destination is zero register -> do nothing */
26098 } else if (unlikely((XRb
== 0) && (XRc
== 0))) {
26099 /* both operands zero registers -> just set destination to all 0s */
26100 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0);
26101 } else if (unlikely(XRb
== 0)) {
26102 /* XRb zero register -> just appropriatelly shift XRc into XRa */
26104 case MXU_OPTN3_PTN0
:
26105 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0);
26107 case MXU_OPTN3_PTN1
:
26108 case MXU_OPTN3_PTN2
:
26109 case MXU_OPTN3_PTN3
:
26110 tcg_gen_shri_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRc
- 1],
26113 case MXU_OPTN3_PTN4
:
26114 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRc
- 1]);
26117 } else if (unlikely(XRc
== 0)) {
26118 /* XRc zero register -> just appropriatelly shift XRb into XRa */
26120 case MXU_OPTN3_PTN0
:
26121 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
26123 case MXU_OPTN3_PTN1
:
26124 case MXU_OPTN3_PTN2
:
26125 case MXU_OPTN3_PTN3
:
26126 tcg_gen_shri_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1], 8 * optn3
);
26128 case MXU_OPTN3_PTN4
:
26129 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0);
26132 } else if (unlikely(XRb
== XRc
)) {
26133 /* both operands same -> just rotation or moving from any of them */
26135 case MXU_OPTN3_PTN0
:
26136 case MXU_OPTN3_PTN4
:
26137 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
26139 case MXU_OPTN3_PTN1
:
26140 case MXU_OPTN3_PTN2
:
26141 case MXU_OPTN3_PTN3
:
26142 tcg_gen_rotli_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1], 8 * optn3
);
26146 /* the most general case */
26148 case MXU_OPTN3_PTN0
:
26152 /* +---------------+ */
26153 /* | A B C D | E F G H */
26154 /* +-------+-------+ */
26159 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
26162 case MXU_OPTN3_PTN1
:
26166 /* +-------------------+ */
26167 /* A | B C D E | F G H */
26168 /* +---------+---------+ */
26173 TCGv_i32 t0
= tcg_temp_new();
26174 TCGv_i32 t1
= tcg_temp_new();
26176 tcg_gen_andi_i32(t0
, mxu_gpr
[XRb
- 1], 0x00FFFFFF);
26177 tcg_gen_shli_i32(t0
, t0
, 8);
26179 tcg_gen_andi_i32(t1
, mxu_gpr
[XRc
- 1], 0xFF000000);
26180 tcg_gen_shri_i32(t1
, t1
, 24);
26182 tcg_gen_or_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
26188 case MXU_OPTN3_PTN2
:
26192 /* +-------------------+ */
26193 /* A B | C D E F | G H */
26194 /* +---------+---------+ */
26199 TCGv_i32 t0
= tcg_temp_new();
26200 TCGv_i32 t1
= tcg_temp_new();
26202 tcg_gen_andi_i32(t0
, mxu_gpr
[XRb
- 1], 0x0000FFFF);
26203 tcg_gen_shli_i32(t0
, t0
, 16);
26205 tcg_gen_andi_i32(t1
, mxu_gpr
[XRc
- 1], 0xFFFF0000);
26206 tcg_gen_shri_i32(t1
, t1
, 16);
26208 tcg_gen_or_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
26214 case MXU_OPTN3_PTN3
:
26218 /* +-------------------+ */
26219 /* A B C | D E F G | H */
26220 /* +---------+---------+ */
26225 TCGv_i32 t0
= tcg_temp_new();
26226 TCGv_i32 t1
= tcg_temp_new();
26228 tcg_gen_andi_i32(t0
, mxu_gpr
[XRb
- 1], 0x000000FF);
26229 tcg_gen_shli_i32(t0
, t0
, 24);
26231 tcg_gen_andi_i32(t1
, mxu_gpr
[XRc
- 1], 0xFFFFFF00);
26232 tcg_gen_shri_i32(t1
, t1
, 8);
26234 tcg_gen_or_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
26240 case MXU_OPTN3_PTN4
:
26244 /* +---------------+ */
26245 /* A B C D | E F G H | */
26246 /* +-------+-------+ */
26251 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRc
- 1]);
26260 * Decoding engine for MXU
26261 * =======================
26266 * Decode MXU pool00
26268 * 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
26269 * +-----------+---------+-----+-------+-------+-------+-----------+
26270 * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL00|
26271 * +-----------+---------+-----+-------+-------+-------+-----------+
26274 static void decode_opc_mxu__pool00(CPUMIPSState
*env
, DisasContext
*ctx
)
26276 uint32_t opcode
= extract32(ctx
->opcode
, 18, 3);
26279 case OPC_MXU_S32MAX
:
26280 case OPC_MXU_S32MIN
:
26281 gen_mxu_S32MAX_S32MIN(ctx
);
26283 case OPC_MXU_D16MAX
:
26284 case OPC_MXU_D16MIN
:
26285 gen_mxu_D16MAX_D16MIN(ctx
);
26287 case OPC_MXU_Q8MAX
:
26288 case OPC_MXU_Q8MIN
:
26289 gen_mxu_Q8MAX_Q8MIN(ctx
);
26291 case OPC_MXU_Q8SLT
:
26292 /* TODO: Implement emulation of Q8SLT instruction. */
26293 MIPS_INVAL("OPC_MXU_Q8SLT");
26294 gen_reserved_instruction(ctx
);
26296 case OPC_MXU_Q8SLTU
:
26297 /* TODO: Implement emulation of Q8SLTU instruction. */
26298 MIPS_INVAL("OPC_MXU_Q8SLTU");
26299 gen_reserved_instruction(ctx
);
26302 MIPS_INVAL("decode_opc_mxu");
26303 gen_reserved_instruction(ctx
);
26310 * Decode MXU pool01
26312 * S32SLT, D16SLT, D16AVG, D16AVGR, Q8AVG, Q8AVGR:
26313 * 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
26314 * +-----------+---------+-----+-------+-------+-------+-----------+
26315 * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL01|
26316 * +-----------+---------+-----+-------+-------+-------+-----------+
26319 * 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
26320 * +-----------+---+-----+-----+-------+-------+-------+-----------+
26321 * | SPECIAL2 |en2|0 0 0|x x x| XRc | XRb | XRa |MXU__POOL01|
26322 * +-----------+---+-----+-----+-------+-------+-------+-----------+
26325 static void decode_opc_mxu__pool01(CPUMIPSState
*env
, DisasContext
*ctx
)
26327 uint32_t opcode
= extract32(ctx
->opcode
, 18, 3);
26330 case OPC_MXU_S32SLT
:
26331 /* TODO: Implement emulation of S32SLT instruction. */
26332 MIPS_INVAL("OPC_MXU_S32SLT");
26333 gen_reserved_instruction(ctx
);
26335 case OPC_MXU_D16SLT
:
26336 /* TODO: Implement emulation of D16SLT instruction. */
26337 MIPS_INVAL("OPC_MXU_D16SLT");
26338 gen_reserved_instruction(ctx
);
26340 case OPC_MXU_D16AVG
:
26341 /* TODO: Implement emulation of D16AVG instruction. */
26342 MIPS_INVAL("OPC_MXU_D16AVG");
26343 gen_reserved_instruction(ctx
);
26345 case OPC_MXU_D16AVGR
:
26346 /* TODO: Implement emulation of D16AVGR instruction. */
26347 MIPS_INVAL("OPC_MXU_D16AVGR");
26348 gen_reserved_instruction(ctx
);
26350 case OPC_MXU_Q8AVG
:
26351 /* TODO: Implement emulation of Q8AVG instruction. */
26352 MIPS_INVAL("OPC_MXU_Q8AVG");
26353 gen_reserved_instruction(ctx
);
26355 case OPC_MXU_Q8AVGR
:
26356 /* TODO: Implement emulation of Q8AVGR instruction. */
26357 MIPS_INVAL("OPC_MXU_Q8AVGR");
26358 gen_reserved_instruction(ctx
);
26360 case OPC_MXU_Q8ADD
:
26361 /* TODO: Implement emulation of Q8ADD instruction. */
26362 MIPS_INVAL("OPC_MXU_Q8ADD");
26363 gen_reserved_instruction(ctx
);
26366 MIPS_INVAL("decode_opc_mxu");
26367 gen_reserved_instruction(ctx
);
26374 * Decode MXU pool02
26376 * 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
26377 * +-----------+---------+-----+-------+-------+-------+-----------+
26378 * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL02|
26379 * +-----------+---------+-----+-------+-------+-------+-----------+
26382 static void decode_opc_mxu__pool02(CPUMIPSState
*env
, DisasContext
*ctx
)
26384 uint32_t opcode
= extract32(ctx
->opcode
, 18, 3);
26387 case OPC_MXU_S32CPS
:
26388 /* TODO: Implement emulation of S32CPS instruction. */
26389 MIPS_INVAL("OPC_MXU_S32CPS");
26390 gen_reserved_instruction(ctx
);
26392 case OPC_MXU_D16CPS
:
26393 /* TODO: Implement emulation of D16CPS instruction. */
26394 MIPS_INVAL("OPC_MXU_D16CPS");
26395 gen_reserved_instruction(ctx
);
26397 case OPC_MXU_Q8ABD
:
26398 /* TODO: Implement emulation of Q8ABD instruction. */
26399 MIPS_INVAL("OPC_MXU_Q8ABD");
26400 gen_reserved_instruction(ctx
);
26402 case OPC_MXU_Q16SAT
:
26403 /* TODO: Implement emulation of Q16SAT instruction. */
26404 MIPS_INVAL("OPC_MXU_Q16SAT");
26405 gen_reserved_instruction(ctx
);
26408 MIPS_INVAL("decode_opc_mxu");
26409 gen_reserved_instruction(ctx
);
26416 * Decode MXU pool03
26419 * 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
26420 * +-----------+---+---+-------+-------+-------+-------+-----------+
26421 * | SPECIAL2 |x x|on2|0 0 0 0| XRc | XRb | XRa |MXU__POOL03|
26422 * +-----------+---+---+-------+-------+-------+-------+-----------+
26425 * 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
26426 * +-----------+---+---+-------+-------+-------+-------+-----------+
26427 * | SPECIAL2 |x x|on2| Xd | XRc | XRb | XRa |MXU__POOL03|
26428 * +-----------+---+---+-------+-------+-------+-------+-----------+
26431 static void decode_opc_mxu__pool03(CPUMIPSState
*env
, DisasContext
*ctx
)
26433 uint32_t opcode
= extract32(ctx
->opcode
, 24, 2);
26436 case OPC_MXU_D16MULF
:
26437 /* TODO: Implement emulation of D16MULF instruction. */
26438 MIPS_INVAL("OPC_MXU_D16MULF");
26439 gen_reserved_instruction(ctx
);
26441 case OPC_MXU_D16MULE
:
26442 /* TODO: Implement emulation of D16MULE instruction. */
26443 MIPS_INVAL("OPC_MXU_D16MULE");
26444 gen_reserved_instruction(ctx
);
26447 MIPS_INVAL("decode_opc_mxu");
26448 gen_reserved_instruction(ctx
);
26455 * Decode MXU pool04
26457 * 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
26458 * +-----------+---------+-+-------------------+-------+-----------+
26459 * | SPECIAL2 | rb |x| s12 | XRa |MXU__POOL04|
26460 * +-----------+---------+-+-------------------+-------+-----------+
26463 static void decode_opc_mxu__pool04(CPUMIPSState
*env
, DisasContext
*ctx
)
26465 uint32_t opcode
= extract32(ctx
->opcode
, 20, 1);
26468 case OPC_MXU_S32LDD
:
26469 case OPC_MXU_S32LDDR
:
26470 gen_mxu_s32ldd_s32lddr(ctx
);
26473 MIPS_INVAL("decode_opc_mxu");
26474 gen_reserved_instruction(ctx
);
26481 * Decode MXU pool05
26483 * 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
26484 * +-----------+---------+-+-------------------+-------+-----------+
26485 * | SPECIAL2 | rb |x| s12 | XRa |MXU__POOL05|
26486 * +-----------+---------+-+-------------------+-------+-----------+
26489 static void decode_opc_mxu__pool05(CPUMIPSState
*env
, DisasContext
*ctx
)
26491 uint32_t opcode
= extract32(ctx
->opcode
, 20, 1);
26494 case OPC_MXU_S32STD
:
26495 /* TODO: Implement emulation of S32STD instruction. */
26496 MIPS_INVAL("OPC_MXU_S32STD");
26497 gen_reserved_instruction(ctx
);
26499 case OPC_MXU_S32STDR
:
26500 /* TODO: Implement emulation of S32STDR instruction. */
26501 MIPS_INVAL("OPC_MXU_S32STDR");
26502 gen_reserved_instruction(ctx
);
26505 MIPS_INVAL("decode_opc_mxu");
26506 gen_reserved_instruction(ctx
);
26513 * Decode MXU pool06
26515 * 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
26516 * +-----------+---------+---------+---+-------+-------+-----------+
26517 * | SPECIAL2 | rb | rc |st2|x x x x| XRa |MXU__POOL06|
26518 * +-----------+---------+---------+---+-------+-------+-----------+
26521 static void decode_opc_mxu__pool06(CPUMIPSState
*env
, DisasContext
*ctx
)
26523 uint32_t opcode
= extract32(ctx
->opcode
, 10, 4);
26526 case OPC_MXU_S32LDDV
:
26527 /* TODO: Implement emulation of S32LDDV instruction. */
26528 MIPS_INVAL("OPC_MXU_S32LDDV");
26529 gen_reserved_instruction(ctx
);
26531 case OPC_MXU_S32LDDVR
:
26532 /* TODO: Implement emulation of S32LDDVR instruction. */
26533 MIPS_INVAL("OPC_MXU_S32LDDVR");
26534 gen_reserved_instruction(ctx
);
26537 MIPS_INVAL("decode_opc_mxu");
26538 gen_reserved_instruction(ctx
);
26545 * Decode MXU pool07
26547 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26548 * +-----------+---------+---------+---+-------+-------+-----------+
26549 * | SPECIAL2 | rb | rc |st2|x x x x| XRa |MXU__POOL07|
26550 * +-----------+---------+---------+---+-------+-------+-----------+
26553 static void decode_opc_mxu__pool07(CPUMIPSState
*env
, DisasContext
*ctx
)
26555 uint32_t opcode
= extract32(ctx
->opcode
, 10, 4);
26558 case OPC_MXU_S32STDV
:
26559 /* TODO: Implement emulation of S32TDV instruction. */
26560 MIPS_INVAL("OPC_MXU_S32TDV");
26561 gen_reserved_instruction(ctx
);
26563 case OPC_MXU_S32STDVR
:
26564 /* TODO: Implement emulation of S32TDVR instruction. */
26565 MIPS_INVAL("OPC_MXU_S32TDVR");
26566 gen_reserved_instruction(ctx
);
26569 MIPS_INVAL("decode_opc_mxu");
26570 gen_reserved_instruction(ctx
);
26577 * Decode MXU pool08
26579 * 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
26580 * +-----------+---------+-+-------------------+-------+-----------+
26581 * | SPECIAL2 | rb |x| s12 | XRa |MXU__POOL08|
26582 * +-----------+---------+-+-------------------+-------+-----------+
26585 static void decode_opc_mxu__pool08(CPUMIPSState
*env
, DisasContext
*ctx
)
26587 uint32_t opcode
= extract32(ctx
->opcode
, 20, 1);
26590 case OPC_MXU_S32LDI
:
26591 /* TODO: Implement emulation of S32LDI instruction. */
26592 MIPS_INVAL("OPC_MXU_S32LDI");
26593 gen_reserved_instruction(ctx
);
26595 case OPC_MXU_S32LDIR
:
26596 /* TODO: Implement emulation of S32LDIR instruction. */
26597 MIPS_INVAL("OPC_MXU_S32LDIR");
26598 gen_reserved_instruction(ctx
);
26601 MIPS_INVAL("decode_opc_mxu");
26602 gen_reserved_instruction(ctx
);
26609 * Decode MXU pool09
26611 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26612 * +-----------+---------+-+-------------------+-------+-----------+
26613 * | SPECIAL2 | rb |x| s12 | XRa |MXU__POOL09|
26614 * +-----------+---------+-+-------------------+-------+-----------+
26617 static void decode_opc_mxu__pool09(CPUMIPSState
*env
, DisasContext
*ctx
)
26619 uint32_t opcode
= extract32(ctx
->opcode
, 5, 0);
26622 case OPC_MXU_S32SDI
:
26623 /* TODO: Implement emulation of S32SDI instruction. */
26624 MIPS_INVAL("OPC_MXU_S32SDI");
26625 gen_reserved_instruction(ctx
);
26627 case OPC_MXU_S32SDIR
:
26628 /* TODO: Implement emulation of S32SDIR instruction. */
26629 MIPS_INVAL("OPC_MXU_S32SDIR");
26630 gen_reserved_instruction(ctx
);
26633 MIPS_INVAL("decode_opc_mxu");
26634 gen_reserved_instruction(ctx
);
26641 * Decode MXU pool10
26643 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26644 * +-----------+---------+---------+---+-------+-------+-----------+
26645 * | SPECIAL2 | rb | rc |st2|x x x x| XRa |MXU__POOL10|
26646 * +-----------+---------+---------+---+-------+-------+-----------+
26649 static void decode_opc_mxu__pool10(CPUMIPSState
*env
, DisasContext
*ctx
)
26651 uint32_t opcode
= extract32(ctx
->opcode
, 5, 0);
26654 case OPC_MXU_S32LDIV
:
26655 /* TODO: Implement emulation of S32LDIV instruction. */
26656 MIPS_INVAL("OPC_MXU_S32LDIV");
26657 gen_reserved_instruction(ctx
);
26659 case OPC_MXU_S32LDIVR
:
26660 /* TODO: Implement emulation of S32LDIVR instruction. */
26661 MIPS_INVAL("OPC_MXU_S32LDIVR");
26662 gen_reserved_instruction(ctx
);
26665 MIPS_INVAL("decode_opc_mxu");
26666 gen_reserved_instruction(ctx
);
26673 * Decode MXU pool11
26675 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26676 * +-----------+---------+---------+---+-------+-------+-----------+
26677 * | SPECIAL2 | rb | rc |st2|x x x x| XRa |MXU__POOL11|
26678 * +-----------+---------+---------+---+-------+-------+-----------+
26681 static void decode_opc_mxu__pool11(CPUMIPSState
*env
, DisasContext
*ctx
)
26683 uint32_t opcode
= extract32(ctx
->opcode
, 10, 4);
26686 case OPC_MXU_S32SDIV
:
26687 /* TODO: Implement emulation of S32SDIV instruction. */
26688 MIPS_INVAL("OPC_MXU_S32SDIV");
26689 gen_reserved_instruction(ctx
);
26691 case OPC_MXU_S32SDIVR
:
26692 /* TODO: Implement emulation of S32SDIVR instruction. */
26693 MIPS_INVAL("OPC_MXU_S32SDIVR");
26694 gen_reserved_instruction(ctx
);
26697 MIPS_INVAL("decode_opc_mxu");
26698 gen_reserved_instruction(ctx
);
26705 * Decode MXU pool12
26707 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26708 * +-----------+---+---+-------+-------+-------+-------+-----------+
26709 * | SPECIAL2 |an2|x x| Xd | XRc | XRb | XRa |MXU__POOL12|
26710 * +-----------+---+---+-------+-------+-------+-------+-----------+
26713 static void decode_opc_mxu__pool12(CPUMIPSState
*env
, DisasContext
*ctx
)
26715 uint32_t opcode
= extract32(ctx
->opcode
, 22, 2);
26718 case OPC_MXU_D32ACC
:
26719 /* TODO: Implement emulation of D32ACC instruction. */
26720 MIPS_INVAL("OPC_MXU_D32ACC");
26721 gen_reserved_instruction(ctx
);
26723 case OPC_MXU_D32ACCM
:
26724 /* TODO: Implement emulation of D32ACCM instruction. */
26725 MIPS_INVAL("OPC_MXU_D32ACCM");
26726 gen_reserved_instruction(ctx
);
26728 case OPC_MXU_D32ASUM
:
26729 /* TODO: Implement emulation of D32ASUM instruction. */
26730 MIPS_INVAL("OPC_MXU_D32ASUM");
26731 gen_reserved_instruction(ctx
);
26734 MIPS_INVAL("decode_opc_mxu");
26735 gen_reserved_instruction(ctx
);
26742 * Decode MXU pool13
26744 * 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
26745 * +-----------+---+---+-------+-------+-------+-------+-----------+
26746 * | SPECIAL2 |en2|x x|0 0 0 0| XRc | XRb | XRa |MXU__POOL13|
26747 * +-----------+---+---+-------+-------+-------+-------+-----------+
26750 static void decode_opc_mxu__pool13(CPUMIPSState
*env
, DisasContext
*ctx
)
26752 uint32_t opcode
= extract32(ctx
->opcode
, 22, 2);
26755 case OPC_MXU_Q16ACC
:
26756 /* TODO: Implement emulation of Q16ACC instruction. */
26757 MIPS_INVAL("OPC_MXU_Q16ACC");
26758 gen_reserved_instruction(ctx
);
26760 case OPC_MXU_Q16ACCM
:
26761 /* TODO: Implement emulation of Q16ACCM instruction. */
26762 MIPS_INVAL("OPC_MXU_Q16ACCM");
26763 gen_reserved_instruction(ctx
);
26765 case OPC_MXU_Q16ASUM
:
26766 /* TODO: Implement emulation of Q16ASUM instruction. */
26767 MIPS_INVAL("OPC_MXU_Q16ASUM");
26768 gen_reserved_instruction(ctx
);
26771 MIPS_INVAL("decode_opc_mxu");
26772 gen_reserved_instruction(ctx
);
26779 * Decode MXU pool14
26782 * 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
26783 * +-----------+---+---+-------+-------+-------+-------+-----------+
26784 * | SPECIAL2 |0 0|x x| XRd | XRc | XRb | XRa |MXU__POOL14|
26785 * +-----------+---+---+-------+-------+-------+-------+-----------+
26788 * 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
26789 * +-----------+---+---+-------+-------+-------+-------+-----------+
26790 * | SPECIAL2 |en2|x x|0 0 0 0| XRc | XRb | XRa |MXU__POOL14|
26791 * +-----------+---+---+-------+-------+-------+-------+-----------+
26794 static void decode_opc_mxu__pool14(CPUMIPSState
*env
, DisasContext
*ctx
)
26796 uint32_t opcode
= extract32(ctx
->opcode
, 22, 2);
26799 case OPC_MXU_Q8ADDE
:
26800 /* TODO: Implement emulation of Q8ADDE instruction. */
26801 MIPS_INVAL("OPC_MXU_Q8ADDE");
26802 gen_reserved_instruction(ctx
);
26804 case OPC_MXU_D8SUM
:
26805 /* TODO: Implement emulation of D8SUM instruction. */
26806 MIPS_INVAL("OPC_MXU_D8SUM");
26807 gen_reserved_instruction(ctx
);
26809 case OPC_MXU_D8SUMC
:
26810 /* TODO: Implement emulation of D8SUMC instruction. */
26811 MIPS_INVAL("OPC_MXU_D8SUMC");
26812 gen_reserved_instruction(ctx
);
26815 MIPS_INVAL("decode_opc_mxu");
26816 gen_reserved_instruction(ctx
);
26823 * Decode MXU pool15
26825 * S32MUL, S32MULU, S32EXTRV:
26826 * 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
26827 * +-----------+---------+---------+---+-------+-------+-----------+
26828 * | SPECIAL2 | rs | rt |x x| XRd | XRa |MXU__POOL15|
26829 * +-----------+---------+---------+---+-------+-------+-----------+
26832 * 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
26833 * +-----------+---------+---------+---+-------+-------+-----------+
26834 * | SPECIAL2 | rb | sft5 |x x| XRd | XRa |MXU__POOL15|
26835 * +-----------+---------+---------+---+-------+-------+-----------+
26838 static void decode_opc_mxu__pool15(CPUMIPSState
*env
, DisasContext
*ctx
)
26840 uint32_t opcode
= extract32(ctx
->opcode
, 14, 2);
26843 case OPC_MXU_S32MUL
:
26844 /* TODO: Implement emulation of S32MUL instruction. */
26845 MIPS_INVAL("OPC_MXU_S32MUL");
26846 gen_reserved_instruction(ctx
);
26848 case OPC_MXU_S32MULU
:
26849 /* TODO: Implement emulation of S32MULU instruction. */
26850 MIPS_INVAL("OPC_MXU_S32MULU");
26851 gen_reserved_instruction(ctx
);
26853 case OPC_MXU_S32EXTR
:
26854 /* TODO: Implement emulation of S32EXTR instruction. */
26855 MIPS_INVAL("OPC_MXU_S32EXTR");
26856 gen_reserved_instruction(ctx
);
26858 case OPC_MXU_S32EXTRV
:
26859 /* TODO: Implement emulation of S32EXTRV instruction. */
26860 MIPS_INVAL("OPC_MXU_S32EXTRV");
26861 gen_reserved_instruction(ctx
);
26864 MIPS_INVAL("decode_opc_mxu");
26865 gen_reserved_instruction(ctx
);
26872 * Decode MXU pool16
26875 * 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
26876 * +-----------+---------+-----+-------+-------+-------+-----------+
26877 * | SPECIAL2 | rb |x x x| XRc | XRb | XRa |MXU__POOL16|
26878 * +-----------+---------+-----+-------+-------+-------+-----------+
26881 * 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
26882 * +-----------+---------+-----+-------+-------+-------+-----------+
26883 * | SPECIAL2 | rs |x x x| XRc | XRb | XRa |MXU__POOL16|
26884 * +-----------+---------+-----+-------+-------+-------+-----------+
26887 * 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
26888 * +-----------+-----+---+-----+-------+-------+-------+-----------+
26889 * | SPECIAL2 | s3 |0 0|x x x| XRc | XRb | XRa |MXU__POOL16|
26890 * +-----------+-----+---+-----+-------+-------+-------+-----------+
26893 * 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
26894 * +-----------+-----+---+-----+-------+---------------+-----------+
26895 * | SPECIAL2 |optn3|0 0|x x x| XRc | s8 |MXU__POOL16|
26896 * +-----------+-----+---+-----+-------+---------------+-----------+
26898 * S32NOR, S32AND, S32OR, S32XOR:
26899 * 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
26900 * +-----------+---------+-----+-------+-------+-------+-----------+
26901 * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL16|
26902 * +-----------+---------+-----+-------+-------+-------+-----------+
26905 static void decode_opc_mxu__pool16(CPUMIPSState
*env
, DisasContext
*ctx
)
26907 uint32_t opcode
= extract32(ctx
->opcode
, 18, 3);
26910 case OPC_MXU_D32SARW
:
26911 /* TODO: Implement emulation of D32SARW instruction. */
26912 MIPS_INVAL("OPC_MXU_D32SARW");
26913 gen_reserved_instruction(ctx
);
26915 case OPC_MXU_S32ALN
:
26916 /* TODO: Implement emulation of S32ALN instruction. */
26917 MIPS_INVAL("OPC_MXU_S32ALN");
26918 gen_reserved_instruction(ctx
);
26920 case OPC_MXU_S32ALNI
:
26921 gen_mxu_S32ALNI(ctx
);
26923 case OPC_MXU_S32LUI
:
26924 /* TODO: Implement emulation of S32LUI instruction. */
26925 MIPS_INVAL("OPC_MXU_S32LUI");
26926 gen_reserved_instruction(ctx
);
26928 case OPC_MXU_S32NOR
:
26929 gen_mxu_S32NOR(ctx
);
26931 case OPC_MXU_S32AND
:
26932 gen_mxu_S32AND(ctx
);
26934 case OPC_MXU_S32OR
:
26935 gen_mxu_S32OR(ctx
);
26937 case OPC_MXU_S32XOR
:
26938 gen_mxu_S32XOR(ctx
);
26941 MIPS_INVAL("decode_opc_mxu");
26942 gen_reserved_instruction(ctx
);
26949 * Decode MXU pool17
26951 * 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
26952 * +-----------+---------+---------+---+---------+-----+-----------+
26953 * | SPECIAL2 | rs | rt |0 0| rd |x x x|MXU__POOL15|
26954 * +-----------+---------+---------+---+---------+-----+-----------+
26957 static void decode_opc_mxu__pool17(CPUMIPSState
*env
, DisasContext
*ctx
)
26959 uint32_t opcode
= extract32(ctx
->opcode
, 6, 2);
26963 /* TODO: Implement emulation of LXW instruction. */
26964 MIPS_INVAL("OPC_MXU_LXW");
26965 gen_reserved_instruction(ctx
);
26968 /* TODO: Implement emulation of LXH instruction. */
26969 MIPS_INVAL("OPC_MXU_LXH");
26970 gen_reserved_instruction(ctx
);
26973 /* TODO: Implement emulation of LXHU instruction. */
26974 MIPS_INVAL("OPC_MXU_LXHU");
26975 gen_reserved_instruction(ctx
);
26978 /* TODO: Implement emulation of LXB instruction. */
26979 MIPS_INVAL("OPC_MXU_LXB");
26980 gen_reserved_instruction(ctx
);
26983 /* TODO: Implement emulation of LXBU instruction. */
26984 MIPS_INVAL("OPC_MXU_LXBU");
26985 gen_reserved_instruction(ctx
);
26988 MIPS_INVAL("decode_opc_mxu");
26989 gen_reserved_instruction(ctx
);
26995 * Decode MXU pool18
26997 * 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
26998 * +-----------+---------+-----+-------+-------+-------+-----------+
26999 * | SPECIAL2 | rb |x x x| XRd | XRa |0 0 0 0|MXU__POOL18|
27000 * +-----------+---------+-----+-------+-------+-------+-----------+
27003 static void decode_opc_mxu__pool18(CPUMIPSState
*env
, DisasContext
*ctx
)
27005 uint32_t opcode
= extract32(ctx
->opcode
, 18, 3);
27008 case OPC_MXU_D32SLLV
:
27009 /* TODO: Implement emulation of D32SLLV instruction. */
27010 MIPS_INVAL("OPC_MXU_D32SLLV");
27011 gen_reserved_instruction(ctx
);
27013 case OPC_MXU_D32SLRV
:
27014 /* TODO: Implement emulation of D32SLRV instruction. */
27015 MIPS_INVAL("OPC_MXU_D32SLRV");
27016 gen_reserved_instruction(ctx
);
27018 case OPC_MXU_D32SARV
:
27019 /* TODO: Implement emulation of D32SARV instruction. */
27020 MIPS_INVAL("OPC_MXU_D32SARV");
27021 gen_reserved_instruction(ctx
);
27023 case OPC_MXU_Q16SLLV
:
27024 /* TODO: Implement emulation of Q16SLLV instruction. */
27025 MIPS_INVAL("OPC_MXU_Q16SLLV");
27026 gen_reserved_instruction(ctx
);
27028 case OPC_MXU_Q16SLRV
:
27029 /* TODO: Implement emulation of Q16SLRV instruction. */
27030 MIPS_INVAL("OPC_MXU_Q16SLRV");
27031 gen_reserved_instruction(ctx
);
27033 case OPC_MXU_Q16SARV
:
27034 /* TODO: Implement emulation of Q16SARV instruction. */
27035 MIPS_INVAL("OPC_MXU_Q16SARV");
27036 gen_reserved_instruction(ctx
);
27039 MIPS_INVAL("decode_opc_mxu");
27040 gen_reserved_instruction(ctx
);
27047 * Decode MXU pool19
27049 * 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
27050 * +-----------+---+---+-------+-------+-------+-------+-----------+
27051 * | SPECIAL2 |0 0|x x| XRd | XRc | XRb | XRa |MXU__POOL19|
27052 * +-----------+---+---+-------+-------+-------+-------+-----------+
27055 static void decode_opc_mxu__pool19(CPUMIPSState
*env
, DisasContext
*ctx
)
27057 uint32_t opcode
= extract32(ctx
->opcode
, 22, 2);
27060 case OPC_MXU_Q8MUL
:
27061 case OPC_MXU_Q8MULSU
:
27062 gen_mxu_q8mul_q8mulsu(ctx
);
27065 MIPS_INVAL("decode_opc_mxu");
27066 gen_reserved_instruction(ctx
);
27073 * Decode MXU pool20
27075 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
27076 * +-----------+---------+-----+-------+-------+-------+-----------+
27077 * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL20|
27078 * +-----------+---------+-----+-------+-------+-------+-----------+
27081 static void decode_opc_mxu__pool20(CPUMIPSState
*env
, DisasContext
*ctx
)
27083 uint32_t opcode
= extract32(ctx
->opcode
, 18, 3);
27086 case OPC_MXU_Q8MOVZ
:
27087 /* TODO: Implement emulation of Q8MOVZ instruction. */
27088 MIPS_INVAL("OPC_MXU_Q8MOVZ");
27089 gen_reserved_instruction(ctx
);
27091 case OPC_MXU_Q8MOVN
:
27092 /* TODO: Implement emulation of Q8MOVN instruction. */
27093 MIPS_INVAL("OPC_MXU_Q8MOVN");
27094 gen_reserved_instruction(ctx
);
27096 case OPC_MXU_D16MOVZ
:
27097 /* TODO: Implement emulation of D16MOVZ instruction. */
27098 MIPS_INVAL("OPC_MXU_D16MOVZ");
27099 gen_reserved_instruction(ctx
);
27101 case OPC_MXU_D16MOVN
:
27102 /* TODO: Implement emulation of D16MOVN instruction. */
27103 MIPS_INVAL("OPC_MXU_D16MOVN");
27104 gen_reserved_instruction(ctx
);
27106 case OPC_MXU_S32MOVZ
:
27107 /* TODO: Implement emulation of S32MOVZ instruction. */
27108 MIPS_INVAL("OPC_MXU_S32MOVZ");
27109 gen_reserved_instruction(ctx
);
27111 case OPC_MXU_S32MOVN
:
27112 /* TODO: Implement emulation of S32MOVN instruction. */
27113 MIPS_INVAL("OPC_MXU_S32MOVN");
27114 gen_reserved_instruction(ctx
);
27117 MIPS_INVAL("decode_opc_mxu");
27118 gen_reserved_instruction(ctx
);
27125 * Decode MXU pool21
27127 * 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
27128 * +-----------+---+---+-------+-------+-------+-------+-----------+
27129 * | SPECIAL2 |an2|x x| XRd | XRc | XRb | XRa |MXU__POOL21|
27130 * +-----------+---+---+-------+-------+-------+-------+-----------+
27133 static void decode_opc_mxu__pool21(CPUMIPSState
*env
, DisasContext
*ctx
)
27135 uint32_t opcode
= extract32(ctx
->opcode
, 22, 2);
27138 case OPC_MXU_Q8MAC
:
27139 /* TODO: Implement emulation of Q8MAC instruction. */
27140 MIPS_INVAL("OPC_MXU_Q8MAC");
27141 gen_reserved_instruction(ctx
);
27143 case OPC_MXU_Q8MACSU
:
27144 /* TODO: Implement emulation of Q8MACSU instruction. */
27145 MIPS_INVAL("OPC_MXU_Q8MACSU");
27146 gen_reserved_instruction(ctx
);
27149 MIPS_INVAL("decode_opc_mxu");
27150 gen_reserved_instruction(ctx
);
27157 * Main MXU decoding function
27159 * 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
27160 * +-----------+---------------------------------------+-----------+
27161 * | SPECIAL2 | |x x x x x x|
27162 * +-----------+---------------------------------------+-----------+
27165 static void decode_opc_mxu(CPUMIPSState
*env
, DisasContext
*ctx
)
27168 * TODO: Investigate necessity of including handling of
27169 * CLZ, CLO, SDBB in this function, as they belong to
27170 * SPECIAL2 opcode space for regular pre-R6 MIPS ISAs.
27172 uint32_t opcode
= extract32(ctx
->opcode
, 0, 6);
27174 if (opcode
== OPC__MXU_MUL
) {
27175 uint32_t rs
, rt
, rd
, op1
;
27177 rs
= extract32(ctx
->opcode
, 21, 5);
27178 rt
= extract32(ctx
->opcode
, 16, 5);
27179 rd
= extract32(ctx
->opcode
, 11, 5);
27180 op1
= MASK_SPECIAL2(ctx
->opcode
);
27182 gen_arith(ctx
, op1
, rd
, rs
, rt
);
27187 if (opcode
== OPC_MXU_S32M2I
) {
27188 gen_mxu_s32m2i(ctx
);
27192 if (opcode
== OPC_MXU_S32I2M
) {
27193 gen_mxu_s32i2m(ctx
);
27198 TCGv t_mxu_cr
= tcg_temp_new();
27199 TCGLabel
*l_exit
= gen_new_label();
27201 gen_load_mxu_cr(t_mxu_cr
);
27202 tcg_gen_andi_tl(t_mxu_cr
, t_mxu_cr
, MXU_CR_MXU_EN
);
27203 tcg_gen_brcondi_tl(TCG_COND_NE
, t_mxu_cr
, MXU_CR_MXU_EN
, l_exit
);
27206 case OPC_MXU_S32MADD
:
27207 /* TODO: Implement emulation of S32MADD instruction. */
27208 MIPS_INVAL("OPC_MXU_S32MADD");
27209 gen_reserved_instruction(ctx
);
27211 case OPC_MXU_S32MADDU
:
27212 /* TODO: Implement emulation of S32MADDU instruction. */
27213 MIPS_INVAL("OPC_MXU_S32MADDU");
27214 gen_reserved_instruction(ctx
);
27216 case OPC_MXU__POOL00
:
27217 decode_opc_mxu__pool00(env
, ctx
);
27219 case OPC_MXU_S32MSUB
:
27220 /* TODO: Implement emulation of S32MSUB instruction. */
27221 MIPS_INVAL("OPC_MXU_S32MSUB");
27222 gen_reserved_instruction(ctx
);
27224 case OPC_MXU_S32MSUBU
:
27225 /* TODO: Implement emulation of S32MSUBU instruction. */
27226 MIPS_INVAL("OPC_MXU_S32MSUBU");
27227 gen_reserved_instruction(ctx
);
27229 case OPC_MXU__POOL01
:
27230 decode_opc_mxu__pool01(env
, ctx
);
27232 case OPC_MXU__POOL02
:
27233 decode_opc_mxu__pool02(env
, ctx
);
27235 case OPC_MXU_D16MUL
:
27236 gen_mxu_d16mul(ctx
);
27238 case OPC_MXU__POOL03
:
27239 decode_opc_mxu__pool03(env
, ctx
);
27241 case OPC_MXU_D16MAC
:
27242 gen_mxu_d16mac(ctx
);
27244 case OPC_MXU_D16MACF
:
27245 /* TODO: Implement emulation of D16MACF instruction. */
27246 MIPS_INVAL("OPC_MXU_D16MACF");
27247 gen_reserved_instruction(ctx
);
27249 case OPC_MXU_D16MADL
:
27250 /* TODO: Implement emulation of D16MADL instruction. */
27251 MIPS_INVAL("OPC_MXU_D16MADL");
27252 gen_reserved_instruction(ctx
);
27254 case OPC_MXU_S16MAD
:
27255 /* TODO: Implement emulation of S16MAD instruction. */
27256 MIPS_INVAL("OPC_MXU_S16MAD");
27257 gen_reserved_instruction(ctx
);
27259 case OPC_MXU_Q16ADD
:
27260 /* TODO: Implement emulation of Q16ADD instruction. */
27261 MIPS_INVAL("OPC_MXU_Q16ADD");
27262 gen_reserved_instruction(ctx
);
27264 case OPC_MXU_D16MACE
:
27265 /* TODO: Implement emulation of D16MACE instruction. */
27266 MIPS_INVAL("OPC_MXU_D16MACE");
27267 gen_reserved_instruction(ctx
);
27269 case OPC_MXU__POOL04
:
27270 decode_opc_mxu__pool04(env
, ctx
);
27272 case OPC_MXU__POOL05
:
27273 decode_opc_mxu__pool05(env
, ctx
);
27275 case OPC_MXU__POOL06
:
27276 decode_opc_mxu__pool06(env
, ctx
);
27278 case OPC_MXU__POOL07
:
27279 decode_opc_mxu__pool07(env
, ctx
);
27281 case OPC_MXU__POOL08
:
27282 decode_opc_mxu__pool08(env
, ctx
);
27284 case OPC_MXU__POOL09
:
27285 decode_opc_mxu__pool09(env
, ctx
);
27287 case OPC_MXU__POOL10
:
27288 decode_opc_mxu__pool10(env
, ctx
);
27290 case OPC_MXU__POOL11
:
27291 decode_opc_mxu__pool11(env
, ctx
);
27293 case OPC_MXU_D32ADD
:
27294 /* TODO: Implement emulation of D32ADD instruction. */
27295 MIPS_INVAL("OPC_MXU_D32ADD");
27296 gen_reserved_instruction(ctx
);
27298 case OPC_MXU__POOL12
:
27299 decode_opc_mxu__pool12(env
, ctx
);
27301 case OPC_MXU__POOL13
:
27302 decode_opc_mxu__pool13(env
, ctx
);
27304 case OPC_MXU__POOL14
:
27305 decode_opc_mxu__pool14(env
, ctx
);
27307 case OPC_MXU_Q8ACCE
:
27308 /* TODO: Implement emulation of Q8ACCE instruction. */
27309 MIPS_INVAL("OPC_MXU_Q8ACCE");
27310 gen_reserved_instruction(ctx
);
27312 case OPC_MXU_S8LDD
:
27313 gen_mxu_s8ldd(ctx
);
27315 case OPC_MXU_S8STD
:
27316 /* TODO: Implement emulation of S8STD instruction. */
27317 MIPS_INVAL("OPC_MXU_S8STD");
27318 gen_reserved_instruction(ctx
);
27320 case OPC_MXU_S8LDI
:
27321 /* TODO: Implement emulation of S8LDI instruction. */
27322 MIPS_INVAL("OPC_MXU_S8LDI");
27323 gen_reserved_instruction(ctx
);
27325 case OPC_MXU_S8SDI
:
27326 /* TODO: Implement emulation of S8SDI instruction. */
27327 MIPS_INVAL("OPC_MXU_S8SDI");
27328 gen_reserved_instruction(ctx
);
27330 case OPC_MXU__POOL15
:
27331 decode_opc_mxu__pool15(env
, ctx
);
27333 case OPC_MXU__POOL16
:
27334 decode_opc_mxu__pool16(env
, ctx
);
27336 case OPC_MXU__POOL17
:
27337 decode_opc_mxu__pool17(env
, ctx
);
27339 case OPC_MXU_S16LDD
:
27340 /* TODO: Implement emulation of S16LDD instruction. */
27341 MIPS_INVAL("OPC_MXU_S16LDD");
27342 gen_reserved_instruction(ctx
);
27344 case OPC_MXU_S16STD
:
27345 /* TODO: Implement emulation of S16STD instruction. */
27346 MIPS_INVAL("OPC_MXU_S16STD");
27347 gen_reserved_instruction(ctx
);
27349 case OPC_MXU_S16LDI
:
27350 /* TODO: Implement emulation of S16LDI instruction. */
27351 MIPS_INVAL("OPC_MXU_S16LDI");
27352 gen_reserved_instruction(ctx
);
27354 case OPC_MXU_S16SDI
:
27355 /* TODO: Implement emulation of S16SDI instruction. */
27356 MIPS_INVAL("OPC_MXU_S16SDI");
27357 gen_reserved_instruction(ctx
);
27359 case OPC_MXU_D32SLL
:
27360 /* TODO: Implement emulation of D32SLL instruction. */
27361 MIPS_INVAL("OPC_MXU_D32SLL");
27362 gen_reserved_instruction(ctx
);
27364 case OPC_MXU_D32SLR
:
27365 /* TODO: Implement emulation of D32SLR instruction. */
27366 MIPS_INVAL("OPC_MXU_D32SLR");
27367 gen_reserved_instruction(ctx
);
27369 case OPC_MXU_D32SARL
:
27370 /* TODO: Implement emulation of D32SARL instruction. */
27371 MIPS_INVAL("OPC_MXU_D32SARL");
27372 gen_reserved_instruction(ctx
);
27374 case OPC_MXU_D32SAR
:
27375 /* TODO: Implement emulation of D32SAR instruction. */
27376 MIPS_INVAL("OPC_MXU_D32SAR");
27377 gen_reserved_instruction(ctx
);
27379 case OPC_MXU_Q16SLL
:
27380 /* TODO: Implement emulation of Q16SLL instruction. */
27381 MIPS_INVAL("OPC_MXU_Q16SLL");
27382 gen_reserved_instruction(ctx
);
27384 case OPC_MXU_Q16SLR
:
27385 /* TODO: Implement emulation of Q16SLR instruction. */
27386 MIPS_INVAL("OPC_MXU_Q16SLR");
27387 gen_reserved_instruction(ctx
);
27389 case OPC_MXU__POOL18
:
27390 decode_opc_mxu__pool18(env
, ctx
);
27392 case OPC_MXU_Q16SAR
:
27393 /* TODO: Implement emulation of Q16SAR instruction. */
27394 MIPS_INVAL("OPC_MXU_Q16SAR");
27395 gen_reserved_instruction(ctx
);
27397 case OPC_MXU__POOL19
:
27398 decode_opc_mxu__pool19(env
, ctx
);
27400 case OPC_MXU__POOL20
:
27401 decode_opc_mxu__pool20(env
, ctx
);
27403 case OPC_MXU__POOL21
:
27404 decode_opc_mxu__pool21(env
, ctx
);
27406 case OPC_MXU_Q16SCOP
:
27407 /* TODO: Implement emulation of Q16SCOP instruction. */
27408 MIPS_INVAL("OPC_MXU_Q16SCOP");
27409 gen_reserved_instruction(ctx
);
27411 case OPC_MXU_Q8MADL
:
27412 /* TODO: Implement emulation of Q8MADL instruction. */
27413 MIPS_INVAL("OPC_MXU_Q8MADL");
27414 gen_reserved_instruction(ctx
);
27416 case OPC_MXU_S32SFL
:
27417 /* TODO: Implement emulation of S32SFL instruction. */
27418 MIPS_INVAL("OPC_MXU_S32SFL");
27419 gen_reserved_instruction(ctx
);
27421 case OPC_MXU_Q8SAD
:
27422 /* TODO: Implement emulation of Q8SAD instruction. */
27423 MIPS_INVAL("OPC_MXU_Q8SAD");
27424 gen_reserved_instruction(ctx
);
27427 MIPS_INVAL("decode_opc_mxu");
27428 gen_reserved_instruction(ctx
);
27431 gen_set_label(l_exit
);
27432 tcg_temp_free(t_mxu_cr
);
27436 #endif /* !defined(TARGET_MIPS64) */
27439 static void decode_opc_special2_legacy(CPUMIPSState
*env
, DisasContext
*ctx
)
27444 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
27446 rs
= (ctx
->opcode
>> 21) & 0x1f;
27447 rt
= (ctx
->opcode
>> 16) & 0x1f;
27448 rd
= (ctx
->opcode
>> 11) & 0x1f;
27450 op1
= MASK_SPECIAL2(ctx
->opcode
);
27452 case OPC_MADD
: /* Multiply and add/sub */
27456 check_insn(ctx
, ISA_MIPS_R1
);
27457 gen_muldiv(ctx
, op1
, rd
& 3, rs
, rt
);
27460 gen_arith(ctx
, op1
, rd
, rs
, rt
);
27463 case OPC_DIVU_G_2F
:
27464 case OPC_MULT_G_2F
:
27465 case OPC_MULTU_G_2F
:
27467 case OPC_MODU_G_2F
:
27468 check_insn(ctx
, INSN_LOONGSON2F
| ASE_LEXT
);
27469 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
27473 check_insn(ctx
, ISA_MIPS_R1
);
27474 gen_cl(ctx
, op1
, rd
, rs
);
27477 if (is_uhi(extract32(ctx
->opcode
, 6, 20))) {
27478 gen_helper_do_semihosting(cpu_env
);
27481 * XXX: not clear which exception should be raised
27482 * when in debug mode...
27484 check_insn(ctx
, ISA_MIPS_R1
);
27485 generate_exception_end(ctx
, EXCP_DBp
);
27488 #if defined(TARGET_MIPS64)
27491 check_insn(ctx
, ISA_MIPS_R1
);
27492 check_mips_64(ctx
);
27493 gen_cl(ctx
, op1
, rd
, rs
);
27495 case OPC_DMULT_G_2F
:
27496 case OPC_DMULTU_G_2F
:
27497 case OPC_DDIV_G_2F
:
27498 case OPC_DDIVU_G_2F
:
27499 case OPC_DMOD_G_2F
:
27500 case OPC_DMODU_G_2F
:
27501 check_insn(ctx
, INSN_LOONGSON2F
| ASE_LEXT
);
27502 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
27505 default: /* Invalid */
27506 MIPS_INVAL("special2_legacy");
27507 gen_reserved_instruction(ctx
);
27512 static void decode_opc_special3_r6(CPUMIPSState
*env
, DisasContext
*ctx
)
27514 int rs
, rt
, rd
, sa
;
27518 rs
= (ctx
->opcode
>> 21) & 0x1f;
27519 rt
= (ctx
->opcode
>> 16) & 0x1f;
27520 rd
= (ctx
->opcode
>> 11) & 0x1f;
27521 sa
= (ctx
->opcode
>> 6) & 0x1f;
27522 imm
= (int16_t)ctx
->opcode
>> 7;
27524 op1
= MASK_SPECIAL3(ctx
->opcode
);
27528 /* hint codes 24-31 are reserved and signal RI */
27529 gen_reserved_instruction(ctx
);
27531 /* Treat as NOP. */
27534 check_cp0_enabled(ctx
);
27535 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
27536 gen_cache_operation(ctx
, rt
, rs
, imm
);
27540 gen_st_cond(ctx
, rt
, rs
, imm
, MO_TESL
, false);
27543 gen_ld(ctx
, op1
, rt
, rs
, imm
);
27548 /* Treat as NOP. */
27551 op2
= MASK_BSHFL(ctx
->opcode
);
27557 gen_align(ctx
, 32, rd
, rs
, rt
, sa
& 3);
27560 gen_bitswap(ctx
, op2
, rd
, rt
);
27565 #ifndef CONFIG_USER_ONLY
27567 if (unlikely(ctx
->gi
<= 1)) {
27568 gen_reserved_instruction(ctx
);
27570 check_cp0_enabled(ctx
);
27571 switch ((ctx
->opcode
>> 6) & 3) {
27572 case 0: /* GINVI */
27573 /* Treat as NOP. */
27575 case 2: /* GINVT */
27576 gen_helper_0e1i(ginvt
, cpu_gpr
[rs
], extract32(ctx
->opcode
, 8, 2));
27579 gen_reserved_instruction(ctx
);
27584 #if defined(TARGET_MIPS64)
27586 gen_st_cond(ctx
, rt
, rs
, imm
, MO_TEQ
, false);
27589 gen_ld(ctx
, op1
, rt
, rs
, imm
);
27592 check_mips_64(ctx
);
27595 /* Treat as NOP. */
27598 op2
= MASK_DBSHFL(ctx
->opcode
);
27608 gen_align(ctx
, 64, rd
, rs
, rt
, sa
& 7);
27611 gen_bitswap(ctx
, op2
, rd
, rt
);
27618 default: /* Invalid */
27619 MIPS_INVAL("special3_r6");
27620 gen_reserved_instruction(ctx
);
27625 static void decode_opc_special3_legacy(CPUMIPSState
*env
, DisasContext
*ctx
)
27630 rs
= (ctx
->opcode
>> 21) & 0x1f;
27631 rt
= (ctx
->opcode
>> 16) & 0x1f;
27632 rd
= (ctx
->opcode
>> 11) & 0x1f;
27634 op1
= MASK_SPECIAL3(ctx
->opcode
);
27637 case OPC_DIVU_G_2E
:
27639 case OPC_MODU_G_2E
:
27640 case OPC_MULT_G_2E
:
27641 case OPC_MULTU_G_2E
:
27643 * OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
27644 * the same mask and op1.
27646 if ((ctx
->insn_flags
& ASE_DSP_R2
) && (op1
== OPC_MULT_G_2E
)) {
27647 op2
= MASK_ADDUH_QB(ctx
->opcode
);
27650 case OPC_ADDUH_R_QB
:
27652 case OPC_ADDQH_R_PH
:
27654 case OPC_ADDQH_R_W
:
27656 case OPC_SUBUH_R_QB
:
27658 case OPC_SUBQH_R_PH
:
27660 case OPC_SUBQH_R_W
:
27661 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
27666 case OPC_MULQ_RS_W
:
27667 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
27670 MIPS_INVAL("MASK ADDUH.QB");
27671 gen_reserved_instruction(ctx
);
27674 } else if (ctx
->insn_flags
& INSN_LOONGSON2E
) {
27675 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
27677 gen_reserved_instruction(ctx
);
27681 op2
= MASK_LX(ctx
->opcode
);
27683 #if defined(TARGET_MIPS64)
27689 gen_mipsdsp_ld(ctx
, op2
, rd
, rs
, rt
);
27691 default: /* Invalid */
27692 MIPS_INVAL("MASK LX");
27693 gen_reserved_instruction(ctx
);
27697 case OPC_ABSQ_S_PH_DSP
:
27698 op2
= MASK_ABSQ_S_PH(ctx
->opcode
);
27700 case OPC_ABSQ_S_QB
:
27701 case OPC_ABSQ_S_PH
:
27703 case OPC_PRECEQ_W_PHL
:
27704 case OPC_PRECEQ_W_PHR
:
27705 case OPC_PRECEQU_PH_QBL
:
27706 case OPC_PRECEQU_PH_QBR
:
27707 case OPC_PRECEQU_PH_QBLA
:
27708 case OPC_PRECEQU_PH_QBRA
:
27709 case OPC_PRECEU_PH_QBL
:
27710 case OPC_PRECEU_PH_QBR
:
27711 case OPC_PRECEU_PH_QBLA
:
27712 case OPC_PRECEU_PH_QBRA
:
27713 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
27720 gen_mipsdsp_bitinsn(ctx
, op1
, op2
, rd
, rt
);
27723 MIPS_INVAL("MASK ABSQ_S.PH");
27724 gen_reserved_instruction(ctx
);
27728 case OPC_ADDU_QB_DSP
:
27729 op2
= MASK_ADDU_QB(ctx
->opcode
);
27732 case OPC_ADDQ_S_PH
:
27735 case OPC_ADDU_S_QB
:
27737 case OPC_ADDU_S_PH
:
27739 case OPC_SUBQ_S_PH
:
27742 case OPC_SUBU_S_QB
:
27744 case OPC_SUBU_S_PH
:
27748 case OPC_RADDU_W_QB
:
27749 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
27751 case OPC_MULEU_S_PH_QBL
:
27752 case OPC_MULEU_S_PH_QBR
:
27753 case OPC_MULQ_RS_PH
:
27754 case OPC_MULEQ_S_W_PHL
:
27755 case OPC_MULEQ_S_W_PHR
:
27756 case OPC_MULQ_S_PH
:
27757 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
27759 default: /* Invalid */
27760 MIPS_INVAL("MASK ADDU.QB");
27761 gen_reserved_instruction(ctx
);
27766 case OPC_CMPU_EQ_QB_DSP
:
27767 op2
= MASK_CMPU_EQ_QB(ctx
->opcode
);
27769 case OPC_PRECR_SRA_PH_W
:
27770 case OPC_PRECR_SRA_R_PH_W
:
27771 gen_mipsdsp_arith(ctx
, op1
, op2
, rt
, rs
, rd
);
27773 case OPC_PRECR_QB_PH
:
27774 case OPC_PRECRQ_QB_PH
:
27775 case OPC_PRECRQ_PH_W
:
27776 case OPC_PRECRQ_RS_PH_W
:
27777 case OPC_PRECRQU_S_QB_PH
:
27778 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
27780 case OPC_CMPU_EQ_QB
:
27781 case OPC_CMPU_LT_QB
:
27782 case OPC_CMPU_LE_QB
:
27783 case OPC_CMP_EQ_PH
:
27784 case OPC_CMP_LT_PH
:
27785 case OPC_CMP_LE_PH
:
27786 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
27788 case OPC_CMPGU_EQ_QB
:
27789 case OPC_CMPGU_LT_QB
:
27790 case OPC_CMPGU_LE_QB
:
27791 case OPC_CMPGDU_EQ_QB
:
27792 case OPC_CMPGDU_LT_QB
:
27793 case OPC_CMPGDU_LE_QB
:
27796 case OPC_PACKRL_PH
:
27797 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
27799 default: /* Invalid */
27800 MIPS_INVAL("MASK CMPU.EQ.QB");
27801 gen_reserved_instruction(ctx
);
27805 case OPC_SHLL_QB_DSP
:
27806 gen_mipsdsp_shift(ctx
, op1
, rd
, rs
, rt
);
27808 case OPC_DPA_W_PH_DSP
:
27809 op2
= MASK_DPA_W_PH(ctx
->opcode
);
27811 case OPC_DPAU_H_QBL
:
27812 case OPC_DPAU_H_QBR
:
27813 case OPC_DPSU_H_QBL
:
27814 case OPC_DPSU_H_QBR
:
27816 case OPC_DPAX_W_PH
:
27817 case OPC_DPAQ_S_W_PH
:
27818 case OPC_DPAQX_S_W_PH
:
27819 case OPC_DPAQX_SA_W_PH
:
27821 case OPC_DPSX_W_PH
:
27822 case OPC_DPSQ_S_W_PH
:
27823 case OPC_DPSQX_S_W_PH
:
27824 case OPC_DPSQX_SA_W_PH
:
27825 case OPC_MULSAQ_S_W_PH
:
27826 case OPC_DPAQ_SA_L_W
:
27827 case OPC_DPSQ_SA_L_W
:
27828 case OPC_MAQ_S_W_PHL
:
27829 case OPC_MAQ_S_W_PHR
:
27830 case OPC_MAQ_SA_W_PHL
:
27831 case OPC_MAQ_SA_W_PHR
:
27832 case OPC_MULSA_W_PH
:
27833 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
27835 default: /* Invalid */
27836 MIPS_INVAL("MASK DPAW.PH");
27837 gen_reserved_instruction(ctx
);
27842 op2
= MASK_INSV(ctx
->opcode
);
27853 t0
= tcg_temp_new();
27854 t1
= tcg_temp_new();
27856 gen_load_gpr(t0
, rt
);
27857 gen_load_gpr(t1
, rs
);
27859 gen_helper_insv(cpu_gpr
[rt
], cpu_env
, t1
, t0
);
27865 default: /* Invalid */
27866 MIPS_INVAL("MASK INSV");
27867 gen_reserved_instruction(ctx
);
27871 case OPC_APPEND_DSP
:
27872 gen_mipsdsp_append(env
, ctx
, op1
, rt
, rs
, rd
);
27874 case OPC_EXTR_W_DSP
:
27875 op2
= MASK_EXTR_W(ctx
->opcode
);
27879 case OPC_EXTR_RS_W
:
27881 case OPC_EXTRV_S_H
:
27883 case OPC_EXTRV_R_W
:
27884 case OPC_EXTRV_RS_W
:
27889 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rt
, rs
, rd
, 1);
27892 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
27898 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
27900 default: /* Invalid */
27901 MIPS_INVAL("MASK EXTR.W");
27902 gen_reserved_instruction(ctx
);
27906 #if defined(TARGET_MIPS64)
27907 case OPC_DDIV_G_2E
:
27908 case OPC_DDIVU_G_2E
:
27909 case OPC_DMULT_G_2E
:
27910 case OPC_DMULTU_G_2E
:
27911 case OPC_DMOD_G_2E
:
27912 case OPC_DMODU_G_2E
:
27913 check_insn(ctx
, INSN_LOONGSON2E
);
27914 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
27916 case OPC_ABSQ_S_QH_DSP
:
27917 op2
= MASK_ABSQ_S_QH(ctx
->opcode
);
27919 case OPC_PRECEQ_L_PWL
:
27920 case OPC_PRECEQ_L_PWR
:
27921 case OPC_PRECEQ_PW_QHL
:
27922 case OPC_PRECEQ_PW_QHR
:
27923 case OPC_PRECEQ_PW_QHLA
:
27924 case OPC_PRECEQ_PW_QHRA
:
27925 case OPC_PRECEQU_QH_OBL
:
27926 case OPC_PRECEQU_QH_OBR
:
27927 case OPC_PRECEQU_QH_OBLA
:
27928 case OPC_PRECEQU_QH_OBRA
:
27929 case OPC_PRECEU_QH_OBL
:
27930 case OPC_PRECEU_QH_OBR
:
27931 case OPC_PRECEU_QH_OBLA
:
27932 case OPC_PRECEU_QH_OBRA
:
27933 case OPC_ABSQ_S_OB
:
27934 case OPC_ABSQ_S_PW
:
27935 case OPC_ABSQ_S_QH
:
27936 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
27944 gen_mipsdsp_bitinsn(ctx
, op1
, op2
, rd
, rt
);
27946 default: /* Invalid */
27947 MIPS_INVAL("MASK ABSQ_S.QH");
27948 gen_reserved_instruction(ctx
);
27952 case OPC_ADDU_OB_DSP
:
27953 op2
= MASK_ADDU_OB(ctx
->opcode
);
27955 case OPC_RADDU_L_OB
:
27957 case OPC_SUBQ_S_PW
:
27959 case OPC_SUBQ_S_QH
:
27961 case OPC_SUBU_S_OB
:
27963 case OPC_SUBU_S_QH
:
27965 case OPC_SUBUH_R_OB
:
27967 case OPC_ADDQ_S_PW
:
27969 case OPC_ADDQ_S_QH
:
27971 case OPC_ADDU_S_OB
:
27973 case OPC_ADDU_S_QH
:
27975 case OPC_ADDUH_R_OB
:
27976 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
27978 case OPC_MULEQ_S_PW_QHL
:
27979 case OPC_MULEQ_S_PW_QHR
:
27980 case OPC_MULEU_S_QH_OBL
:
27981 case OPC_MULEU_S_QH_OBR
:
27982 case OPC_MULQ_RS_QH
:
27983 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
27985 default: /* Invalid */
27986 MIPS_INVAL("MASK ADDU.OB");
27987 gen_reserved_instruction(ctx
);
27991 case OPC_CMPU_EQ_OB_DSP
:
27992 op2
= MASK_CMPU_EQ_OB(ctx
->opcode
);
27994 case OPC_PRECR_SRA_QH_PW
:
27995 case OPC_PRECR_SRA_R_QH_PW
:
27996 /* Return value is rt. */
27997 gen_mipsdsp_arith(ctx
, op1
, op2
, rt
, rs
, rd
);
27999 case OPC_PRECR_OB_QH
:
28000 case OPC_PRECRQ_OB_QH
:
28001 case OPC_PRECRQ_PW_L
:
28002 case OPC_PRECRQ_QH_PW
:
28003 case OPC_PRECRQ_RS_QH_PW
:
28004 case OPC_PRECRQU_S_OB_QH
:
28005 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
28007 case OPC_CMPU_EQ_OB
:
28008 case OPC_CMPU_LT_OB
:
28009 case OPC_CMPU_LE_OB
:
28010 case OPC_CMP_EQ_QH
:
28011 case OPC_CMP_LT_QH
:
28012 case OPC_CMP_LE_QH
:
28013 case OPC_CMP_EQ_PW
:
28014 case OPC_CMP_LT_PW
:
28015 case OPC_CMP_LE_PW
:
28016 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
28018 case OPC_CMPGDU_EQ_OB
:
28019 case OPC_CMPGDU_LT_OB
:
28020 case OPC_CMPGDU_LE_OB
:
28021 case OPC_CMPGU_EQ_OB
:
28022 case OPC_CMPGU_LT_OB
:
28023 case OPC_CMPGU_LE_OB
:
28024 case OPC_PACKRL_PW
:
28028 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
28030 default: /* Invalid */
28031 MIPS_INVAL("MASK CMPU_EQ.OB");
28032 gen_reserved_instruction(ctx
);
28036 case OPC_DAPPEND_DSP
:
28037 gen_mipsdsp_append(env
, ctx
, op1
, rt
, rs
, rd
);
28039 case OPC_DEXTR_W_DSP
:
28040 op2
= MASK_DEXTR_W(ctx
->opcode
);
28047 case OPC_DEXTR_R_L
:
28048 case OPC_DEXTR_RS_L
:
28050 case OPC_DEXTR_R_W
:
28051 case OPC_DEXTR_RS_W
:
28052 case OPC_DEXTR_S_H
:
28054 case OPC_DEXTRV_R_L
:
28055 case OPC_DEXTRV_RS_L
:
28056 case OPC_DEXTRV_S_H
:
28058 case OPC_DEXTRV_R_W
:
28059 case OPC_DEXTRV_RS_W
:
28060 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rt
, rs
, rd
, 1);
28065 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
28067 default: /* Invalid */
28068 MIPS_INVAL("MASK EXTR.W");
28069 gen_reserved_instruction(ctx
);
28073 case OPC_DPAQ_W_QH_DSP
:
28074 op2
= MASK_DPAQ_W_QH(ctx
->opcode
);
28076 case OPC_DPAU_H_OBL
:
28077 case OPC_DPAU_H_OBR
:
28078 case OPC_DPSU_H_OBL
:
28079 case OPC_DPSU_H_OBR
:
28081 case OPC_DPAQ_S_W_QH
:
28083 case OPC_DPSQ_S_W_QH
:
28084 case OPC_MULSAQ_S_W_QH
:
28085 case OPC_DPAQ_SA_L_PW
:
28086 case OPC_DPSQ_SA_L_PW
:
28087 case OPC_MULSAQ_S_L_PW
:
28088 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
28090 case OPC_MAQ_S_W_QHLL
:
28091 case OPC_MAQ_S_W_QHLR
:
28092 case OPC_MAQ_S_W_QHRL
:
28093 case OPC_MAQ_S_W_QHRR
:
28094 case OPC_MAQ_SA_W_QHLL
:
28095 case OPC_MAQ_SA_W_QHLR
:
28096 case OPC_MAQ_SA_W_QHRL
:
28097 case OPC_MAQ_SA_W_QHRR
:
28098 case OPC_MAQ_S_L_PWL
:
28099 case OPC_MAQ_S_L_PWR
:
28104 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
28106 default: /* Invalid */
28107 MIPS_INVAL("MASK DPAQ.W.QH");
28108 gen_reserved_instruction(ctx
);
28112 case OPC_DINSV_DSP
:
28113 op2
= MASK_INSV(ctx
->opcode
);
28124 t0
= tcg_temp_new();
28125 t1
= tcg_temp_new();
28127 gen_load_gpr(t0
, rt
);
28128 gen_load_gpr(t1
, rs
);
28130 gen_helper_dinsv(cpu_gpr
[rt
], cpu_env
, t1
, t0
);
28136 default: /* Invalid */
28137 MIPS_INVAL("MASK DINSV");
28138 gen_reserved_instruction(ctx
);
28142 case OPC_SHLL_OB_DSP
:
28143 gen_mipsdsp_shift(ctx
, op1
, rd
, rs
, rt
);
28146 default: /* Invalid */
28147 MIPS_INVAL("special3_legacy");
28148 gen_reserved_instruction(ctx
);
28154 #if defined(TARGET_MIPS64)
28156 static void decode_mmi0(CPUMIPSState
*env
, DisasContext
*ctx
)
28158 uint32_t opc
= MASK_MMI0(ctx
->opcode
);
28161 case MMI_OPC_0_PADDW
: /* TODO: MMI_OPC_0_PADDW */
28162 case MMI_OPC_0_PSUBW
: /* TODO: MMI_OPC_0_PSUBW */
28163 case MMI_OPC_0_PCGTW
: /* TODO: MMI_OPC_0_PCGTW */
28164 case MMI_OPC_0_PMAXW
: /* TODO: MMI_OPC_0_PMAXW */
28165 case MMI_OPC_0_PADDH
: /* TODO: MMI_OPC_0_PADDH */
28166 case MMI_OPC_0_PSUBH
: /* TODO: MMI_OPC_0_PSUBH */
28167 case MMI_OPC_0_PCGTH
: /* TODO: MMI_OPC_0_PCGTH */
28168 case MMI_OPC_0_PMAXH
: /* TODO: MMI_OPC_0_PMAXH */
28169 case MMI_OPC_0_PADDB
: /* TODO: MMI_OPC_0_PADDB */
28170 case MMI_OPC_0_PSUBB
: /* TODO: MMI_OPC_0_PSUBB */
28171 case MMI_OPC_0_PCGTB
: /* TODO: MMI_OPC_0_PCGTB */
28172 case MMI_OPC_0_PADDSW
: /* TODO: MMI_OPC_0_PADDSW */
28173 case MMI_OPC_0_PSUBSW
: /* TODO: MMI_OPC_0_PSUBSW */
28174 case MMI_OPC_0_PEXTLW
: /* TODO: MMI_OPC_0_PEXTLW */
28175 case MMI_OPC_0_PPACW
: /* TODO: MMI_OPC_0_PPACW */
28176 case MMI_OPC_0_PADDSH
: /* TODO: MMI_OPC_0_PADDSH */
28177 case MMI_OPC_0_PSUBSH
: /* TODO: MMI_OPC_0_PSUBSH */
28178 case MMI_OPC_0_PEXTLH
: /* TODO: MMI_OPC_0_PEXTLH */
28179 case MMI_OPC_0_PPACH
: /* TODO: MMI_OPC_0_PPACH */
28180 case MMI_OPC_0_PADDSB
: /* TODO: MMI_OPC_0_PADDSB */
28181 case MMI_OPC_0_PSUBSB
: /* TODO: MMI_OPC_0_PSUBSB */
28182 case MMI_OPC_0_PEXTLB
: /* TODO: MMI_OPC_0_PEXTLB */
28183 case MMI_OPC_0_PPACB
: /* TODO: MMI_OPC_0_PPACB */
28184 case MMI_OPC_0_PEXT5
: /* TODO: MMI_OPC_0_PEXT5 */
28185 case MMI_OPC_0_PPAC5
: /* TODO: MMI_OPC_0_PPAC5 */
28186 gen_reserved_instruction(ctx
); /* TODO: MMI_OPC_CLASS_MMI0 */
28189 MIPS_INVAL("TX79 MMI class MMI0");
28190 gen_reserved_instruction(ctx
);
28195 static void decode_mmi1(CPUMIPSState
*env
, DisasContext
*ctx
)
28197 uint32_t opc
= MASK_MMI1(ctx
->opcode
);
28200 case MMI_OPC_1_PABSW
: /* TODO: MMI_OPC_1_PABSW */
28201 case MMI_OPC_1_PCEQW
: /* TODO: MMI_OPC_1_PCEQW */
28202 case MMI_OPC_1_PMINW
: /* TODO: MMI_OPC_1_PMINW */
28203 case MMI_OPC_1_PADSBH
: /* TODO: MMI_OPC_1_PADSBH */
28204 case MMI_OPC_1_PABSH
: /* TODO: MMI_OPC_1_PABSH */
28205 case MMI_OPC_1_PCEQH
: /* TODO: MMI_OPC_1_PCEQH */
28206 case MMI_OPC_1_PMINH
: /* TODO: MMI_OPC_1_PMINH */
28207 case MMI_OPC_1_PCEQB
: /* TODO: MMI_OPC_1_PCEQB */
28208 case MMI_OPC_1_PADDUW
: /* TODO: MMI_OPC_1_PADDUW */
28209 case MMI_OPC_1_PSUBUW
: /* TODO: MMI_OPC_1_PSUBUW */
28210 case MMI_OPC_1_PEXTUW
: /* TODO: MMI_OPC_1_PEXTUW */
28211 case MMI_OPC_1_PADDUH
: /* TODO: MMI_OPC_1_PADDUH */
28212 case MMI_OPC_1_PSUBUH
: /* TODO: MMI_OPC_1_PSUBUH */
28213 case MMI_OPC_1_PEXTUH
: /* TODO: MMI_OPC_1_PEXTUH */
28214 case MMI_OPC_1_PADDUB
: /* TODO: MMI_OPC_1_PADDUB */
28215 case MMI_OPC_1_PSUBUB
: /* TODO: MMI_OPC_1_PSUBUB */
28216 case MMI_OPC_1_PEXTUB
: /* TODO: MMI_OPC_1_PEXTUB */
28217 case MMI_OPC_1_QFSRV
: /* TODO: MMI_OPC_1_QFSRV */
28218 gen_reserved_instruction(ctx
); /* TODO: MMI_OPC_CLASS_MMI1 */
28221 MIPS_INVAL("TX79 MMI class MMI1");
28222 gen_reserved_instruction(ctx
);
28227 static void decode_mmi2(CPUMIPSState
*env
, DisasContext
*ctx
)
28229 uint32_t opc
= MASK_MMI2(ctx
->opcode
);
28232 case MMI_OPC_2_PMADDW
: /* TODO: MMI_OPC_2_PMADDW */
28233 case MMI_OPC_2_PSLLVW
: /* TODO: MMI_OPC_2_PSLLVW */
28234 case MMI_OPC_2_PSRLVW
: /* TODO: MMI_OPC_2_PSRLVW */
28235 case MMI_OPC_2_PMSUBW
: /* TODO: MMI_OPC_2_PMSUBW */
28236 case MMI_OPC_2_PMFHI
: /* TODO: MMI_OPC_2_PMFHI */
28237 case MMI_OPC_2_PMFLO
: /* TODO: MMI_OPC_2_PMFLO */
28238 case MMI_OPC_2_PINTH
: /* TODO: MMI_OPC_2_PINTH */
28239 case MMI_OPC_2_PMULTW
: /* TODO: MMI_OPC_2_PMULTW */
28240 case MMI_OPC_2_PDIVW
: /* TODO: MMI_OPC_2_PDIVW */
28241 case MMI_OPC_2_PMADDH
: /* TODO: MMI_OPC_2_PMADDH */
28242 case MMI_OPC_2_PHMADH
: /* TODO: MMI_OPC_2_PHMADH */
28243 case MMI_OPC_2_PAND
: /* TODO: MMI_OPC_2_PAND */
28244 case MMI_OPC_2_PXOR
: /* TODO: MMI_OPC_2_PXOR */
28245 case MMI_OPC_2_PMSUBH
: /* TODO: MMI_OPC_2_PMSUBH */
28246 case MMI_OPC_2_PHMSBH
: /* TODO: MMI_OPC_2_PHMSBH */
28247 case MMI_OPC_2_PEXEH
: /* TODO: MMI_OPC_2_PEXEH */
28248 case MMI_OPC_2_PREVH
: /* TODO: MMI_OPC_2_PREVH */
28249 case MMI_OPC_2_PMULTH
: /* TODO: MMI_OPC_2_PMULTH */
28250 case MMI_OPC_2_PDIVBW
: /* TODO: MMI_OPC_2_PDIVBW */
28251 case MMI_OPC_2_PEXEW
: /* TODO: MMI_OPC_2_PEXEW */
28252 case MMI_OPC_2_PROT3W
: /* TODO: MMI_OPC_2_PROT3W */
28253 gen_reserved_instruction(ctx
); /* TODO: MMI_OPC_CLASS_MMI2 */
28255 case MMI_OPC_2_PCPYLD
:
28256 gen_mmi_pcpyld(ctx
);
28259 MIPS_INVAL("TX79 MMI class MMI2");
28260 gen_reserved_instruction(ctx
);
28265 static void decode_mmi3(CPUMIPSState
*env
, DisasContext
*ctx
)
28267 uint32_t opc
= MASK_MMI3(ctx
->opcode
);
28270 case MMI_OPC_3_PMADDUW
: /* TODO: MMI_OPC_3_PMADDUW */
28271 case MMI_OPC_3_PSRAVW
: /* TODO: MMI_OPC_3_PSRAVW */
28272 case MMI_OPC_3_PMTHI
: /* TODO: MMI_OPC_3_PMTHI */
28273 case MMI_OPC_3_PMTLO
: /* TODO: MMI_OPC_3_PMTLO */
28274 case MMI_OPC_3_PINTEH
: /* TODO: MMI_OPC_3_PINTEH */
28275 case MMI_OPC_3_PMULTUW
: /* TODO: MMI_OPC_3_PMULTUW */
28276 case MMI_OPC_3_PDIVUW
: /* TODO: MMI_OPC_3_PDIVUW */
28277 case MMI_OPC_3_POR
: /* TODO: MMI_OPC_3_POR */
28278 case MMI_OPC_3_PNOR
: /* TODO: MMI_OPC_3_PNOR */
28279 case MMI_OPC_3_PEXCH
: /* TODO: MMI_OPC_3_PEXCH */
28280 case MMI_OPC_3_PEXCW
: /* TODO: MMI_OPC_3_PEXCW */
28281 gen_reserved_instruction(ctx
); /* TODO: MMI_OPC_CLASS_MMI3 */
28283 case MMI_OPC_3_PCPYH
:
28284 gen_mmi_pcpyh(ctx
);
28286 case MMI_OPC_3_PCPYUD
:
28287 gen_mmi_pcpyud(ctx
);
28290 MIPS_INVAL("TX79 MMI class MMI3");
28291 gen_reserved_instruction(ctx
);
28296 static void decode_mmi(CPUMIPSState
*env
, DisasContext
*ctx
)
28298 uint32_t opc
= MASK_MMI(ctx
->opcode
);
28299 int rs
= extract32(ctx
->opcode
, 21, 5);
28300 int rt
= extract32(ctx
->opcode
, 16, 5);
28301 int rd
= extract32(ctx
->opcode
, 11, 5);
28304 case MMI_OPC_CLASS_MMI0
:
28305 decode_mmi0(env
, ctx
);
28307 case MMI_OPC_CLASS_MMI1
:
28308 decode_mmi1(env
, ctx
);
28310 case MMI_OPC_CLASS_MMI2
:
28311 decode_mmi2(env
, ctx
);
28313 case MMI_OPC_CLASS_MMI3
:
28314 decode_mmi3(env
, ctx
);
28316 case MMI_OPC_MULT1
:
28317 case MMI_OPC_MULTU1
:
28319 case MMI_OPC_MADDU
:
28320 case MMI_OPC_MADD1
:
28321 case MMI_OPC_MADDU1
:
28322 gen_mul_txx9(ctx
, opc
, rd
, rs
, rt
);
28325 case MMI_OPC_DIVU1
:
28326 gen_div1_tx79(ctx
, opc
, rs
, rt
);
28328 case MMI_OPC_MTLO1
:
28329 case MMI_OPC_MTHI1
:
28330 gen_HILO1_tx79(ctx
, opc
, rs
);
28332 case MMI_OPC_MFLO1
:
28333 case MMI_OPC_MFHI1
:
28334 gen_HILO1_tx79(ctx
, opc
, rd
);
28336 case MMI_OPC_PLZCW
: /* TODO: MMI_OPC_PLZCW */
28337 case MMI_OPC_PMFHL
: /* TODO: MMI_OPC_PMFHL */
28338 case MMI_OPC_PMTHL
: /* TODO: MMI_OPC_PMTHL */
28339 case MMI_OPC_PSLLH
: /* TODO: MMI_OPC_PSLLH */
28340 case MMI_OPC_PSRLH
: /* TODO: MMI_OPC_PSRLH */
28341 case MMI_OPC_PSRAH
: /* TODO: MMI_OPC_PSRAH */
28342 case MMI_OPC_PSLLW
: /* TODO: MMI_OPC_PSLLW */
28343 case MMI_OPC_PSRLW
: /* TODO: MMI_OPC_PSRLW */
28344 case MMI_OPC_PSRAW
: /* TODO: MMI_OPC_PSRAW */
28345 gen_reserved_instruction(ctx
); /* TODO: MMI_OPC_CLASS_MMI */
28348 MIPS_INVAL("TX79 MMI class");
28349 gen_reserved_instruction(ctx
);
28354 static void gen_mmi_lq(CPUMIPSState
*env
, DisasContext
*ctx
)
28356 gen_reserved_instruction(ctx
); /* TODO: MMI_OPC_LQ */
28359 static void gen_mmi_sq(DisasContext
*ctx
, int base
, int rt
, int offset
)
28361 gen_reserved_instruction(ctx
); /* TODO: MMI_OPC_SQ */
28365 * The TX79-specific instruction Store Quadword
28367 * +--------+-------+-------+------------------------+
28368 * | 011111 | base | rt | offset | SQ
28369 * +--------+-------+-------+------------------------+
28372 * has the same opcode as the Read Hardware Register instruction
28374 * +--------+-------+-------+-------+-------+--------+
28375 * | 011111 | 00000 | rt | rd | 00000 | 111011 | RDHWR
28376 * +--------+-------+-------+-------+-------+--------+
28379 * that is required, trapped and emulated by the Linux kernel. However, all
28380 * RDHWR encodings yield address error exceptions on the TX79 since the SQ
28381 * offset is odd. Therefore all valid SQ instructions can execute normally.
28382 * In user mode, QEMU must verify the upper and lower 11 bits to distinguish
28383 * between SQ and RDHWR, as the Linux kernel does.
28385 static void decode_mmi_sq(CPUMIPSState
*env
, DisasContext
*ctx
)
28387 int base
= extract32(ctx
->opcode
, 21, 5);
28388 int rt
= extract32(ctx
->opcode
, 16, 5);
28389 int offset
= extract32(ctx
->opcode
, 0, 16);
28391 #ifdef CONFIG_USER_ONLY
28392 uint32_t op1
= MASK_SPECIAL3(ctx
->opcode
);
28393 uint32_t op2
= extract32(ctx
->opcode
, 6, 5);
28395 if (base
== 0 && op2
== 0 && op1
== OPC_RDHWR
) {
28396 int rd
= extract32(ctx
->opcode
, 11, 5);
28398 gen_rdhwr(ctx
, rt
, rd
, 0);
28403 gen_mmi_sq(ctx
, base
, rt
, offset
);
28408 static void decode_opc_special3(CPUMIPSState
*env
, DisasContext
*ctx
)
28410 int rs
, rt
, rd
, sa
;
28414 rs
= (ctx
->opcode
>> 21) & 0x1f;
28415 rt
= (ctx
->opcode
>> 16) & 0x1f;
28416 rd
= (ctx
->opcode
>> 11) & 0x1f;
28417 sa
= (ctx
->opcode
>> 6) & 0x1f;
28418 imm
= sextract32(ctx
->opcode
, 7, 9);
28420 op1
= MASK_SPECIAL3(ctx
->opcode
);
28423 * EVA loads and stores overlap Loongson 2E instructions decoded by
28424 * decode_opc_special3_legacy(), so be careful to allow their decoding when
28431 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
28439 check_cp0_enabled(ctx
);
28440 gen_ld(ctx
, op1
, rt
, rs
, imm
);
28444 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
28449 check_cp0_enabled(ctx
);
28450 gen_st(ctx
, op1
, rt
, rs
, imm
);
28453 check_cp0_enabled(ctx
);
28454 gen_st_cond(ctx
, rt
, rs
, imm
, MO_TESL
, true);
28457 check_cp0_enabled(ctx
);
28458 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
28459 gen_cache_operation(ctx
, rt
, rs
, imm
);
28461 /* Treat as NOP. */
28464 check_cp0_enabled(ctx
);
28465 /* Treat as NOP. */
28473 check_insn(ctx
, ISA_MIPS_R2
);
28474 gen_bitops(ctx
, op1
, rt
, rs
, sa
, rd
);
28477 op2
= MASK_BSHFL(ctx
->opcode
);
28484 check_insn(ctx
, ISA_MIPS_R6
);
28485 decode_opc_special3_r6(env
, ctx
);
28488 check_insn(ctx
, ISA_MIPS_R2
);
28489 gen_bshfl(ctx
, op2
, rt
, rd
);
28493 #if defined(TARGET_MIPS64)
28500 check_insn(ctx
, ISA_MIPS_R2
);
28501 check_mips_64(ctx
);
28502 gen_bitops(ctx
, op1
, rt
, rs
, sa
, rd
);
28505 op2
= MASK_DBSHFL(ctx
->opcode
);
28516 check_insn(ctx
, ISA_MIPS_R6
);
28517 decode_opc_special3_r6(env
, ctx
);
28520 check_insn(ctx
, ISA_MIPS_R2
);
28521 check_mips_64(ctx
);
28522 op2
= MASK_DBSHFL(ctx
->opcode
);
28523 gen_bshfl(ctx
, op2
, rt
, rd
);
28529 gen_rdhwr(ctx
, rt
, rd
, extract32(ctx
->opcode
, 6, 3));
28534 TCGv t0
= tcg_temp_new();
28535 TCGv t1
= tcg_temp_new();
28537 gen_load_gpr(t0
, rt
);
28538 gen_load_gpr(t1
, rs
);
28539 gen_helper_fork(t0
, t1
);
28547 TCGv t0
= tcg_temp_new();
28549 gen_load_gpr(t0
, rs
);
28550 gen_helper_yield(t0
, cpu_env
, t0
);
28551 gen_store_gpr(t0
, rd
);
28556 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
28557 decode_opc_special3_r6(env
, ctx
);
28559 decode_opc_special3_legacy(env
, ctx
);
28564 /* MIPS SIMD Architecture (MSA) */
28565 static inline int check_msa_access(DisasContext
*ctx
)
28567 if (unlikely((ctx
->hflags
& MIPS_HFLAG_FPU
) &&
28568 !(ctx
->hflags
& MIPS_HFLAG_F64
))) {
28569 gen_reserved_instruction(ctx
);
28573 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_MSA
))) {
28574 if (ctx
->insn_flags
& ASE_MSA
) {
28575 generate_exception_end(ctx
, EXCP_MSADIS
);
28578 gen_reserved_instruction(ctx
);
28585 static void gen_check_zero_element(TCGv tresult
, uint8_t df
, uint8_t wt
)
28587 /* generates tcg ops to check if any element is 0 */
28588 /* Note this function only works with MSA_WRLEN = 128 */
28589 uint64_t eval_zero_or_big
= 0;
28590 uint64_t eval_big
= 0;
28591 TCGv_i64 t0
= tcg_temp_new_i64();
28592 TCGv_i64 t1
= tcg_temp_new_i64();
28595 eval_zero_or_big
= 0x0101010101010101ULL
;
28596 eval_big
= 0x8080808080808080ULL
;
28599 eval_zero_or_big
= 0x0001000100010001ULL
;
28600 eval_big
= 0x8000800080008000ULL
;
28603 eval_zero_or_big
= 0x0000000100000001ULL
;
28604 eval_big
= 0x8000000080000000ULL
;
28607 eval_zero_or_big
= 0x0000000000000001ULL
;
28608 eval_big
= 0x8000000000000000ULL
;
28611 tcg_gen_subi_i64(t0
, msa_wr_d
[wt
<< 1], eval_zero_or_big
);
28612 tcg_gen_andc_i64(t0
, t0
, msa_wr_d
[wt
<< 1]);
28613 tcg_gen_andi_i64(t0
, t0
, eval_big
);
28614 tcg_gen_subi_i64(t1
, msa_wr_d
[(wt
<< 1) + 1], eval_zero_or_big
);
28615 tcg_gen_andc_i64(t1
, t1
, msa_wr_d
[(wt
<< 1) + 1]);
28616 tcg_gen_andi_i64(t1
, t1
, eval_big
);
28617 tcg_gen_or_i64(t0
, t0
, t1
);
28618 /* if all bits are zero then all elements are not zero */
28619 /* if some bit is non-zero then some element is zero */
28620 tcg_gen_setcondi_i64(TCG_COND_NE
, t0
, t0
, 0);
28621 tcg_gen_trunc_i64_tl(tresult
, t0
);
28622 tcg_temp_free_i64(t0
);
28623 tcg_temp_free_i64(t1
);
28626 static void gen_msa_branch(CPUMIPSState
*env
, DisasContext
*ctx
, uint32_t op1
)
28628 uint8_t df
= (ctx
->opcode
>> 21) & 0x3;
28629 uint8_t wt
= (ctx
->opcode
>> 16) & 0x1f;
28630 int64_t s16
= (int16_t)ctx
->opcode
;
28632 check_msa_access(ctx
);
28634 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
28635 gen_reserved_instruction(ctx
);
28642 TCGv_i64 t0
= tcg_temp_new_i64();
28643 tcg_gen_or_i64(t0
, msa_wr_d
[wt
<< 1], msa_wr_d
[(wt
<< 1) + 1]);
28644 tcg_gen_setcondi_i64((op1
== OPC_BZ_V
) ?
28645 TCG_COND_EQ
: TCG_COND_NE
, t0
, t0
, 0);
28646 tcg_gen_trunc_i64_tl(bcond
, t0
);
28647 tcg_temp_free_i64(t0
);
28654 gen_check_zero_element(bcond
, df
, wt
);
28660 gen_check_zero_element(bcond
, df
, wt
);
28661 tcg_gen_setcondi_tl(TCG_COND_EQ
, bcond
, bcond
, 0);
28665 ctx
->btarget
= ctx
->base
.pc_next
+ (s16
<< 2) + 4;
28667 ctx
->hflags
|= MIPS_HFLAG_BC
;
28668 ctx
->hflags
|= MIPS_HFLAG_BDS32
;
28671 static void gen_msa_i8(CPUMIPSState
*env
, DisasContext
*ctx
)
28673 #define MASK_MSA_I8(op) (MASK_MSA_MINOR(op) | (op & (0x03 << 24)))
28674 uint8_t i8
= (ctx
->opcode
>> 16) & 0xff;
28675 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
28676 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
28678 TCGv_i32 twd
= tcg_const_i32(wd
);
28679 TCGv_i32 tws
= tcg_const_i32(ws
);
28680 TCGv_i32 ti8
= tcg_const_i32(i8
);
28682 switch (MASK_MSA_I8(ctx
->opcode
)) {
28684 gen_helper_msa_andi_b(cpu_env
, twd
, tws
, ti8
);
28687 gen_helper_msa_ori_b(cpu_env
, twd
, tws
, ti8
);
28690 gen_helper_msa_nori_b(cpu_env
, twd
, tws
, ti8
);
28693 gen_helper_msa_xori_b(cpu_env
, twd
, tws
, ti8
);
28696 gen_helper_msa_bmnzi_b(cpu_env
, twd
, tws
, ti8
);
28699 gen_helper_msa_bmzi_b(cpu_env
, twd
, tws
, ti8
);
28702 gen_helper_msa_bseli_b(cpu_env
, twd
, tws
, ti8
);
28708 uint8_t df
= (ctx
->opcode
>> 24) & 0x3;
28709 if (df
== DF_DOUBLE
) {
28710 gen_reserved_instruction(ctx
);
28712 TCGv_i32 tdf
= tcg_const_i32(df
);
28713 gen_helper_msa_shf_df(cpu_env
, tdf
, twd
, tws
, ti8
);
28714 tcg_temp_free_i32(tdf
);
28719 MIPS_INVAL("MSA instruction");
28720 gen_reserved_instruction(ctx
);
28724 tcg_temp_free_i32(twd
);
28725 tcg_temp_free_i32(tws
);
28726 tcg_temp_free_i32(ti8
);
28729 static void gen_msa_i5(CPUMIPSState
*env
, DisasContext
*ctx
)
28731 #define MASK_MSA_I5(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
28732 uint8_t df
= (ctx
->opcode
>> 21) & 0x3;
28733 int8_t s5
= (int8_t) sextract32(ctx
->opcode
, 16, 5);
28734 uint8_t u5
= (ctx
->opcode
>> 16) & 0x1f;
28735 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
28736 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
28738 TCGv_i32 tdf
= tcg_const_i32(df
);
28739 TCGv_i32 twd
= tcg_const_i32(wd
);
28740 TCGv_i32 tws
= tcg_const_i32(ws
);
28741 TCGv_i32 timm
= tcg_temp_new_i32();
28742 tcg_gen_movi_i32(timm
, u5
);
28744 switch (MASK_MSA_I5(ctx
->opcode
)) {
28746 gen_helper_msa_addvi_df(cpu_env
, tdf
, twd
, tws
, timm
);
28749 gen_helper_msa_subvi_df(cpu_env
, tdf
, twd
, tws
, timm
);
28751 case OPC_MAXI_S_df
:
28752 tcg_gen_movi_i32(timm
, s5
);
28753 gen_helper_msa_maxi_s_df(cpu_env
, tdf
, twd
, tws
, timm
);
28755 case OPC_MAXI_U_df
:
28756 gen_helper_msa_maxi_u_df(cpu_env
, tdf
, twd
, tws
, timm
);
28758 case OPC_MINI_S_df
:
28759 tcg_gen_movi_i32(timm
, s5
);
28760 gen_helper_msa_mini_s_df(cpu_env
, tdf
, twd
, tws
, timm
);
28762 case OPC_MINI_U_df
:
28763 gen_helper_msa_mini_u_df(cpu_env
, tdf
, twd
, tws
, timm
);
28766 tcg_gen_movi_i32(timm
, s5
);
28767 gen_helper_msa_ceqi_df(cpu_env
, tdf
, twd
, tws
, timm
);
28769 case OPC_CLTI_S_df
:
28770 tcg_gen_movi_i32(timm
, s5
);
28771 gen_helper_msa_clti_s_df(cpu_env
, tdf
, twd
, tws
, timm
);
28773 case OPC_CLTI_U_df
:
28774 gen_helper_msa_clti_u_df(cpu_env
, tdf
, twd
, tws
, timm
);
28776 case OPC_CLEI_S_df
:
28777 tcg_gen_movi_i32(timm
, s5
);
28778 gen_helper_msa_clei_s_df(cpu_env
, tdf
, twd
, tws
, timm
);
28780 case OPC_CLEI_U_df
:
28781 gen_helper_msa_clei_u_df(cpu_env
, tdf
, twd
, tws
, timm
);
28785 int32_t s10
= sextract32(ctx
->opcode
, 11, 10);
28786 tcg_gen_movi_i32(timm
, s10
);
28787 gen_helper_msa_ldi_df(cpu_env
, tdf
, twd
, timm
);
28791 MIPS_INVAL("MSA instruction");
28792 gen_reserved_instruction(ctx
);
28796 tcg_temp_free_i32(tdf
);
28797 tcg_temp_free_i32(twd
);
28798 tcg_temp_free_i32(tws
);
28799 tcg_temp_free_i32(timm
);
28802 static void gen_msa_bit(CPUMIPSState
*env
, DisasContext
*ctx
)
28804 #define MASK_MSA_BIT(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
28805 uint8_t dfm
= (ctx
->opcode
>> 16) & 0x7f;
28806 uint32_t df
= 0, m
= 0;
28807 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
28808 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
28815 if ((dfm
& 0x40) == 0x00) {
28818 } else if ((dfm
& 0x60) == 0x40) {
28821 } else if ((dfm
& 0x70) == 0x60) {
28824 } else if ((dfm
& 0x78) == 0x70) {
28828 gen_reserved_instruction(ctx
);
28832 tdf
= tcg_const_i32(df
);
28833 tm
= tcg_const_i32(m
);
28834 twd
= tcg_const_i32(wd
);
28835 tws
= tcg_const_i32(ws
);
28837 switch (MASK_MSA_BIT(ctx
->opcode
)) {
28839 gen_helper_msa_slli_df(cpu_env
, tdf
, twd
, tws
, tm
);
28842 gen_helper_msa_srai_df(cpu_env
, tdf
, twd
, tws
, tm
);
28845 gen_helper_msa_srli_df(cpu_env
, tdf
, twd
, tws
, tm
);
28848 gen_helper_msa_bclri_df(cpu_env
, tdf
, twd
, tws
, tm
);
28851 gen_helper_msa_bseti_df(cpu_env
, tdf
, twd
, tws
, tm
);
28854 gen_helper_msa_bnegi_df(cpu_env
, tdf
, twd
, tws
, tm
);
28856 case OPC_BINSLI_df
:
28857 gen_helper_msa_binsli_df(cpu_env
, tdf
, twd
, tws
, tm
);
28859 case OPC_BINSRI_df
:
28860 gen_helper_msa_binsri_df(cpu_env
, tdf
, twd
, tws
, tm
);
28863 gen_helper_msa_sat_s_df(cpu_env
, tdf
, twd
, tws
, tm
);
28866 gen_helper_msa_sat_u_df(cpu_env
, tdf
, twd
, tws
, tm
);
28869 gen_helper_msa_srari_df(cpu_env
, tdf
, twd
, tws
, tm
);
28872 gen_helper_msa_srlri_df(cpu_env
, tdf
, twd
, tws
, tm
);
28875 MIPS_INVAL("MSA instruction");
28876 gen_reserved_instruction(ctx
);
28880 tcg_temp_free_i32(tdf
);
28881 tcg_temp_free_i32(tm
);
28882 tcg_temp_free_i32(twd
);
28883 tcg_temp_free_i32(tws
);
28886 static void gen_msa_3r(CPUMIPSState
*env
, DisasContext
*ctx
)
28888 #define MASK_MSA_3R(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
28889 uint8_t df
= (ctx
->opcode
>> 21) & 0x3;
28890 uint8_t wt
= (ctx
->opcode
>> 16) & 0x1f;
28891 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
28892 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
28894 TCGv_i32 tdf
= tcg_const_i32(df
);
28895 TCGv_i32 twd
= tcg_const_i32(wd
);
28896 TCGv_i32 tws
= tcg_const_i32(ws
);
28897 TCGv_i32 twt
= tcg_const_i32(wt
);
28899 switch (MASK_MSA_3R(ctx
->opcode
)) {
28903 gen_helper_msa_binsl_b(cpu_env
, twd
, tws
, twt
);
28906 gen_helper_msa_binsl_h(cpu_env
, twd
, tws
, twt
);
28909 gen_helper_msa_binsl_w(cpu_env
, twd
, tws
, twt
);
28912 gen_helper_msa_binsl_d(cpu_env
, twd
, tws
, twt
);
28919 gen_helper_msa_binsr_b(cpu_env
, twd
, tws
, twt
);
28922 gen_helper_msa_binsr_h(cpu_env
, twd
, tws
, twt
);
28925 gen_helper_msa_binsr_w(cpu_env
, twd
, tws
, twt
);
28928 gen_helper_msa_binsr_d(cpu_env
, twd
, tws
, twt
);
28935 gen_helper_msa_bclr_b(cpu_env
, twd
, tws
, twt
);
28938 gen_helper_msa_bclr_h(cpu_env
, twd
, tws
, twt
);
28941 gen_helper_msa_bclr_w(cpu_env
, twd
, tws
, twt
);
28944 gen_helper_msa_bclr_d(cpu_env
, twd
, tws
, twt
);
28951 gen_helper_msa_bneg_b(cpu_env
, twd
, tws
, twt
);
28954 gen_helper_msa_bneg_h(cpu_env
, twd
, tws
, twt
);
28957 gen_helper_msa_bneg_w(cpu_env
, twd
, tws
, twt
);
28960 gen_helper_msa_bneg_d(cpu_env
, twd
, tws
, twt
);
28967 gen_helper_msa_bset_b(cpu_env
, twd
, tws
, twt
);
28970 gen_helper_msa_bset_h(cpu_env
, twd
, tws
, twt
);
28973 gen_helper_msa_bset_w(cpu_env
, twd
, tws
, twt
);
28976 gen_helper_msa_bset_d(cpu_env
, twd
, tws
, twt
);
28983 gen_helper_msa_add_a_b(cpu_env
, twd
, tws
, twt
);
28986 gen_helper_msa_add_a_h(cpu_env
, twd
, tws
, twt
);
28989 gen_helper_msa_add_a_w(cpu_env
, twd
, tws
, twt
);
28992 gen_helper_msa_add_a_d(cpu_env
, twd
, tws
, twt
);
28996 case OPC_ADDS_A_df
:
28999 gen_helper_msa_adds_a_b(cpu_env
, twd
, tws
, twt
);
29002 gen_helper_msa_adds_a_h(cpu_env
, twd
, tws
, twt
);
29005 gen_helper_msa_adds_a_w(cpu_env
, twd
, tws
, twt
);
29008 gen_helper_msa_adds_a_d(cpu_env
, twd
, tws
, twt
);
29012 case OPC_ADDS_S_df
:
29015 gen_helper_msa_adds_s_b(cpu_env
, twd
, tws
, twt
);
29018 gen_helper_msa_adds_s_h(cpu_env
, twd
, tws
, twt
);
29021 gen_helper_msa_adds_s_w(cpu_env
, twd
, tws
, twt
);
29024 gen_helper_msa_adds_s_d(cpu_env
, twd
, tws
, twt
);
29028 case OPC_ADDS_U_df
:
29031 gen_helper_msa_adds_u_b(cpu_env
, twd
, tws
, twt
);
29034 gen_helper_msa_adds_u_h(cpu_env
, twd
, tws
, twt
);
29037 gen_helper_msa_adds_u_w(cpu_env
, twd
, tws
, twt
);
29040 gen_helper_msa_adds_u_d(cpu_env
, twd
, tws
, twt
);
29047 gen_helper_msa_addv_b(cpu_env
, twd
, tws
, twt
);
29050 gen_helper_msa_addv_h(cpu_env
, twd
, tws
, twt
);
29053 gen_helper_msa_addv_w(cpu_env
, twd
, tws
, twt
);
29056 gen_helper_msa_addv_d(cpu_env
, twd
, tws
, twt
);
29063 gen_helper_msa_ave_s_b(cpu_env
, twd
, tws
, twt
);
29066 gen_helper_msa_ave_s_h(cpu_env
, twd
, tws
, twt
);
29069 gen_helper_msa_ave_s_w(cpu_env
, twd
, tws
, twt
);
29072 gen_helper_msa_ave_s_d(cpu_env
, twd
, tws
, twt
);
29079 gen_helper_msa_ave_u_b(cpu_env
, twd
, tws
, twt
);
29082 gen_helper_msa_ave_u_h(cpu_env
, twd
, tws
, twt
);
29085 gen_helper_msa_ave_u_w(cpu_env
, twd
, tws
, twt
);
29088 gen_helper_msa_ave_u_d(cpu_env
, twd
, tws
, twt
);
29092 case OPC_AVER_S_df
:
29095 gen_helper_msa_aver_s_b(cpu_env
, twd
, tws
, twt
);
29098 gen_helper_msa_aver_s_h(cpu_env
, twd
, tws
, twt
);
29101 gen_helper_msa_aver_s_w(cpu_env
, twd
, tws
, twt
);
29104 gen_helper_msa_aver_s_d(cpu_env
, twd
, tws
, twt
);
29108 case OPC_AVER_U_df
:
29111 gen_helper_msa_aver_u_b(cpu_env
, twd
, tws
, twt
);
29114 gen_helper_msa_aver_u_h(cpu_env
, twd
, tws
, twt
);
29117 gen_helper_msa_aver_u_w(cpu_env
, twd
, tws
, twt
);
29120 gen_helper_msa_aver_u_d(cpu_env
, twd
, tws
, twt
);
29127 gen_helper_msa_ceq_b(cpu_env
, twd
, tws
, twt
);
29130 gen_helper_msa_ceq_h(cpu_env
, twd
, tws
, twt
);
29133 gen_helper_msa_ceq_w(cpu_env
, twd
, tws
, twt
);
29136 gen_helper_msa_ceq_d(cpu_env
, twd
, tws
, twt
);
29143 gen_helper_msa_cle_s_b(cpu_env
, twd
, tws
, twt
);
29146 gen_helper_msa_cle_s_h(cpu_env
, twd
, tws
, twt
);
29149 gen_helper_msa_cle_s_w(cpu_env
, twd
, tws
, twt
);
29152 gen_helper_msa_cle_s_d(cpu_env
, twd
, tws
, twt
);
29159 gen_helper_msa_cle_u_b(cpu_env
, twd
, tws
, twt
);
29162 gen_helper_msa_cle_u_h(cpu_env
, twd
, tws
, twt
);
29165 gen_helper_msa_cle_u_w(cpu_env
, twd
, tws
, twt
);
29168 gen_helper_msa_cle_u_d(cpu_env
, twd
, tws
, twt
);
29175 gen_helper_msa_clt_s_b(cpu_env
, twd
, tws
, twt
);
29178 gen_helper_msa_clt_s_h(cpu_env
, twd
, tws
, twt
);
29181 gen_helper_msa_clt_s_w(cpu_env
, twd
, tws
, twt
);
29184 gen_helper_msa_clt_s_d(cpu_env
, twd
, tws
, twt
);
29191 gen_helper_msa_clt_u_b(cpu_env
, twd
, tws
, twt
);
29194 gen_helper_msa_clt_u_h(cpu_env
, twd
, tws
, twt
);
29197 gen_helper_msa_clt_u_w(cpu_env
, twd
, tws
, twt
);
29200 gen_helper_msa_clt_u_d(cpu_env
, twd
, tws
, twt
);
29207 gen_helper_msa_div_s_b(cpu_env
, twd
, tws
, twt
);
29210 gen_helper_msa_div_s_h(cpu_env
, twd
, tws
, twt
);
29213 gen_helper_msa_div_s_w(cpu_env
, twd
, tws
, twt
);
29216 gen_helper_msa_div_s_d(cpu_env
, twd
, tws
, twt
);
29223 gen_helper_msa_div_u_b(cpu_env
, twd
, tws
, twt
);
29226 gen_helper_msa_div_u_h(cpu_env
, twd
, tws
, twt
);
29229 gen_helper_msa_div_u_w(cpu_env
, twd
, tws
, twt
);
29232 gen_helper_msa_div_u_d(cpu_env
, twd
, tws
, twt
);
29239 gen_helper_msa_max_a_b(cpu_env
, twd
, tws
, twt
);
29242 gen_helper_msa_max_a_h(cpu_env
, twd
, tws
, twt
);
29245 gen_helper_msa_max_a_w(cpu_env
, twd
, tws
, twt
);
29248 gen_helper_msa_max_a_d(cpu_env
, twd
, tws
, twt
);
29255 gen_helper_msa_max_s_b(cpu_env
, twd
, tws
, twt
);
29258 gen_helper_msa_max_s_h(cpu_env
, twd
, tws
, twt
);
29261 gen_helper_msa_max_s_w(cpu_env
, twd
, tws
, twt
);
29264 gen_helper_msa_max_s_d(cpu_env
, twd
, tws
, twt
);
29271 gen_helper_msa_max_u_b(cpu_env
, twd
, tws
, twt
);
29274 gen_helper_msa_max_u_h(cpu_env
, twd
, tws
, twt
);
29277 gen_helper_msa_max_u_w(cpu_env
, twd
, tws
, twt
);
29280 gen_helper_msa_max_u_d(cpu_env
, twd
, tws
, twt
);
29287 gen_helper_msa_min_a_b(cpu_env
, twd
, tws
, twt
);
29290 gen_helper_msa_min_a_h(cpu_env
, twd
, tws
, twt
);
29293 gen_helper_msa_min_a_w(cpu_env
, twd
, tws
, twt
);
29296 gen_helper_msa_min_a_d(cpu_env
, twd
, tws
, twt
);
29303 gen_helper_msa_min_s_b(cpu_env
, twd
, tws
, twt
);
29306 gen_helper_msa_min_s_h(cpu_env
, twd
, tws
, twt
);
29309 gen_helper_msa_min_s_w(cpu_env
, twd
, tws
, twt
);
29312 gen_helper_msa_min_s_d(cpu_env
, twd
, tws
, twt
);
29319 gen_helper_msa_min_u_b(cpu_env
, twd
, tws
, twt
);
29322 gen_helper_msa_min_u_h(cpu_env
, twd
, tws
, twt
);
29325 gen_helper_msa_min_u_w(cpu_env
, twd
, tws
, twt
);
29328 gen_helper_msa_min_u_d(cpu_env
, twd
, tws
, twt
);
29335 gen_helper_msa_mod_s_b(cpu_env
, twd
, tws
, twt
);
29338 gen_helper_msa_mod_s_h(cpu_env
, twd
, tws
, twt
);
29341 gen_helper_msa_mod_s_w(cpu_env
, twd
, tws
, twt
);
29344 gen_helper_msa_mod_s_d(cpu_env
, twd
, tws
, twt
);
29351 gen_helper_msa_mod_u_b(cpu_env
, twd
, tws
, twt
);
29354 gen_helper_msa_mod_u_h(cpu_env
, twd
, tws
, twt
);
29357 gen_helper_msa_mod_u_w(cpu_env
, twd
, tws
, twt
);
29360 gen_helper_msa_mod_u_d(cpu_env
, twd
, tws
, twt
);
29367 gen_helper_msa_maddv_b(cpu_env
, twd
, tws
, twt
);
29370 gen_helper_msa_maddv_h(cpu_env
, twd
, tws
, twt
);
29373 gen_helper_msa_maddv_w(cpu_env
, twd
, tws
, twt
);
29376 gen_helper_msa_maddv_d(cpu_env
, twd
, tws
, twt
);
29383 gen_helper_msa_msubv_b(cpu_env
, twd
, tws
, twt
);
29386 gen_helper_msa_msubv_h(cpu_env
, twd
, tws
, twt
);
29389 gen_helper_msa_msubv_w(cpu_env
, twd
, tws
, twt
);
29392 gen_helper_msa_msubv_d(cpu_env
, twd
, tws
, twt
);
29396 case OPC_ASUB_S_df
:
29399 gen_helper_msa_asub_s_b(cpu_env
, twd
, tws
, twt
);
29402 gen_helper_msa_asub_s_h(cpu_env
, twd
, tws
, twt
);
29405 gen_helper_msa_asub_s_w(cpu_env
, twd
, tws
, twt
);
29408 gen_helper_msa_asub_s_d(cpu_env
, twd
, tws
, twt
);
29412 case OPC_ASUB_U_df
:
29415 gen_helper_msa_asub_u_b(cpu_env
, twd
, tws
, twt
);
29418 gen_helper_msa_asub_u_h(cpu_env
, twd
, tws
, twt
);
29421 gen_helper_msa_asub_u_w(cpu_env
, twd
, tws
, twt
);
29424 gen_helper_msa_asub_u_d(cpu_env
, twd
, tws
, twt
);
29431 gen_helper_msa_ilvev_b(cpu_env
, twd
, tws
, twt
);
29434 gen_helper_msa_ilvev_h(cpu_env
, twd
, tws
, twt
);
29437 gen_helper_msa_ilvev_w(cpu_env
, twd
, tws
, twt
);
29440 gen_helper_msa_ilvev_d(cpu_env
, twd
, tws
, twt
);
29447 gen_helper_msa_ilvod_b(cpu_env
, twd
, tws
, twt
);
29450 gen_helper_msa_ilvod_h(cpu_env
, twd
, tws
, twt
);
29453 gen_helper_msa_ilvod_w(cpu_env
, twd
, tws
, twt
);
29456 gen_helper_msa_ilvod_d(cpu_env
, twd
, tws
, twt
);
29463 gen_helper_msa_ilvl_b(cpu_env
, twd
, tws
, twt
);
29466 gen_helper_msa_ilvl_h(cpu_env
, twd
, tws
, twt
);
29469 gen_helper_msa_ilvl_w(cpu_env
, twd
, tws
, twt
);
29472 gen_helper_msa_ilvl_d(cpu_env
, twd
, tws
, twt
);
29479 gen_helper_msa_ilvr_b(cpu_env
, twd
, tws
, twt
);
29482 gen_helper_msa_ilvr_h(cpu_env
, twd
, tws
, twt
);
29485 gen_helper_msa_ilvr_w(cpu_env
, twd
, tws
, twt
);
29488 gen_helper_msa_ilvr_d(cpu_env
, twd
, tws
, twt
);
29495 gen_helper_msa_pckev_b(cpu_env
, twd
, tws
, twt
);
29498 gen_helper_msa_pckev_h(cpu_env
, twd
, tws
, twt
);
29501 gen_helper_msa_pckev_w(cpu_env
, twd
, tws
, twt
);
29504 gen_helper_msa_pckev_d(cpu_env
, twd
, tws
, twt
);
29511 gen_helper_msa_pckod_b(cpu_env
, twd
, tws
, twt
);
29514 gen_helper_msa_pckod_h(cpu_env
, twd
, tws
, twt
);
29517 gen_helper_msa_pckod_w(cpu_env
, twd
, tws
, twt
);
29520 gen_helper_msa_pckod_d(cpu_env
, twd
, tws
, twt
);
29527 gen_helper_msa_sll_b(cpu_env
, twd
, tws
, twt
);
29530 gen_helper_msa_sll_h(cpu_env
, twd
, tws
, twt
);
29533 gen_helper_msa_sll_w(cpu_env
, twd
, tws
, twt
);
29536 gen_helper_msa_sll_d(cpu_env
, twd
, tws
, twt
);
29543 gen_helper_msa_sra_b(cpu_env
, twd
, tws
, twt
);
29546 gen_helper_msa_sra_h(cpu_env
, twd
, tws
, twt
);
29549 gen_helper_msa_sra_w(cpu_env
, twd
, tws
, twt
);
29552 gen_helper_msa_sra_d(cpu_env
, twd
, tws
, twt
);
29559 gen_helper_msa_srar_b(cpu_env
, twd
, tws
, twt
);
29562 gen_helper_msa_srar_h(cpu_env
, twd
, tws
, twt
);
29565 gen_helper_msa_srar_w(cpu_env
, twd
, tws
, twt
);
29568 gen_helper_msa_srar_d(cpu_env
, twd
, tws
, twt
);
29575 gen_helper_msa_srl_b(cpu_env
, twd
, tws
, twt
);
29578 gen_helper_msa_srl_h(cpu_env
, twd
, tws
, twt
);
29581 gen_helper_msa_srl_w(cpu_env
, twd
, tws
, twt
);
29584 gen_helper_msa_srl_d(cpu_env
, twd
, tws
, twt
);
29591 gen_helper_msa_srlr_b(cpu_env
, twd
, tws
, twt
);
29594 gen_helper_msa_srlr_h(cpu_env
, twd
, tws
, twt
);
29597 gen_helper_msa_srlr_w(cpu_env
, twd
, tws
, twt
);
29600 gen_helper_msa_srlr_d(cpu_env
, twd
, tws
, twt
);
29604 case OPC_SUBS_S_df
:
29607 gen_helper_msa_subs_s_b(cpu_env
, twd
, tws
, twt
);
29610 gen_helper_msa_subs_s_h(cpu_env
, twd
, tws
, twt
);
29613 gen_helper_msa_subs_s_w(cpu_env
, twd
, tws
, twt
);
29616 gen_helper_msa_subs_s_d(cpu_env
, twd
, tws
, twt
);
29623 gen_helper_msa_mulv_b(cpu_env
, twd
, tws
, twt
);
29626 gen_helper_msa_mulv_h(cpu_env
, twd
, tws
, twt
);
29629 gen_helper_msa_mulv_w(cpu_env
, twd
, tws
, twt
);
29632 gen_helper_msa_mulv_d(cpu_env
, twd
, tws
, twt
);
29637 gen_helper_msa_sld_df(cpu_env
, tdf
, twd
, tws
, twt
);
29640 gen_helper_msa_vshf_df(cpu_env
, tdf
, twd
, tws
, twt
);
29645 gen_helper_msa_subv_b(cpu_env
, twd
, tws
, twt
);
29648 gen_helper_msa_subv_h(cpu_env
, twd
, tws
, twt
);
29651 gen_helper_msa_subv_w(cpu_env
, twd
, tws
, twt
);
29654 gen_helper_msa_subv_d(cpu_env
, twd
, tws
, twt
);
29658 case OPC_SUBS_U_df
:
29661 gen_helper_msa_subs_u_b(cpu_env
, twd
, tws
, twt
);
29664 gen_helper_msa_subs_u_h(cpu_env
, twd
, tws
, twt
);
29667 gen_helper_msa_subs_u_w(cpu_env
, twd
, tws
, twt
);
29670 gen_helper_msa_subs_u_d(cpu_env
, twd
, tws
, twt
);
29675 gen_helper_msa_splat_df(cpu_env
, tdf
, twd
, tws
, twt
);
29677 case OPC_SUBSUS_U_df
:
29680 gen_helper_msa_subsus_u_b(cpu_env
, twd
, tws
, twt
);
29683 gen_helper_msa_subsus_u_h(cpu_env
, twd
, tws
, twt
);
29686 gen_helper_msa_subsus_u_w(cpu_env
, twd
, tws
, twt
);
29689 gen_helper_msa_subsus_u_d(cpu_env
, twd
, tws
, twt
);
29693 case OPC_SUBSUU_S_df
:
29696 gen_helper_msa_subsuu_s_b(cpu_env
, twd
, tws
, twt
);
29699 gen_helper_msa_subsuu_s_h(cpu_env
, twd
, tws
, twt
);
29702 gen_helper_msa_subsuu_s_w(cpu_env
, twd
, tws
, twt
);
29705 gen_helper_msa_subsuu_s_d(cpu_env
, twd
, tws
, twt
);
29710 case OPC_DOTP_S_df
:
29711 case OPC_DOTP_U_df
:
29712 case OPC_DPADD_S_df
:
29713 case OPC_DPADD_U_df
:
29714 case OPC_DPSUB_S_df
:
29715 case OPC_HADD_S_df
:
29716 case OPC_DPSUB_U_df
:
29717 case OPC_HADD_U_df
:
29718 case OPC_HSUB_S_df
:
29719 case OPC_HSUB_U_df
:
29720 if (df
== DF_BYTE
) {
29721 gen_reserved_instruction(ctx
);
29724 switch (MASK_MSA_3R(ctx
->opcode
)) {
29725 case OPC_HADD_S_df
:
29728 gen_helper_msa_hadd_s_h(cpu_env
, twd
, tws
, twt
);
29731 gen_helper_msa_hadd_s_w(cpu_env
, twd
, tws
, twt
);
29734 gen_helper_msa_hadd_s_d(cpu_env
, twd
, tws
, twt
);
29738 case OPC_HADD_U_df
:
29741 gen_helper_msa_hadd_u_h(cpu_env
, twd
, tws
, twt
);
29744 gen_helper_msa_hadd_u_w(cpu_env
, twd
, tws
, twt
);
29747 gen_helper_msa_hadd_u_d(cpu_env
, twd
, tws
, twt
);
29751 case OPC_HSUB_S_df
:
29754 gen_helper_msa_hsub_s_h(cpu_env
, twd
, tws
, twt
);
29757 gen_helper_msa_hsub_s_w(cpu_env
, twd
, tws
, twt
);
29760 gen_helper_msa_hsub_s_d(cpu_env
, twd
, tws
, twt
);
29764 case OPC_HSUB_U_df
:
29767 gen_helper_msa_hsub_u_h(cpu_env
, twd
, tws
, twt
);
29770 gen_helper_msa_hsub_u_w(cpu_env
, twd
, tws
, twt
);
29773 gen_helper_msa_hsub_u_d(cpu_env
, twd
, tws
, twt
);
29777 case OPC_DOTP_S_df
:
29780 gen_helper_msa_dotp_s_h(cpu_env
, twd
, tws
, twt
);
29783 gen_helper_msa_dotp_s_w(cpu_env
, twd
, tws
, twt
);
29786 gen_helper_msa_dotp_s_d(cpu_env
, twd
, tws
, twt
);
29790 case OPC_DOTP_U_df
:
29793 gen_helper_msa_dotp_u_h(cpu_env
, twd
, tws
, twt
);
29796 gen_helper_msa_dotp_u_w(cpu_env
, twd
, tws
, twt
);
29799 gen_helper_msa_dotp_u_d(cpu_env
, twd
, tws
, twt
);
29803 case OPC_DPADD_S_df
:
29806 gen_helper_msa_dpadd_s_h(cpu_env
, twd
, tws
, twt
);
29809 gen_helper_msa_dpadd_s_w(cpu_env
, twd
, tws
, twt
);
29812 gen_helper_msa_dpadd_s_d(cpu_env
, twd
, tws
, twt
);
29816 case OPC_DPADD_U_df
:
29819 gen_helper_msa_dpadd_u_h(cpu_env
, twd
, tws
, twt
);
29822 gen_helper_msa_dpadd_u_w(cpu_env
, twd
, tws
, twt
);
29825 gen_helper_msa_dpadd_u_d(cpu_env
, twd
, tws
, twt
);
29829 case OPC_DPSUB_S_df
:
29832 gen_helper_msa_dpsub_s_h(cpu_env
, twd
, tws
, twt
);
29835 gen_helper_msa_dpsub_s_w(cpu_env
, twd
, tws
, twt
);
29838 gen_helper_msa_dpsub_s_d(cpu_env
, twd
, tws
, twt
);
29842 case OPC_DPSUB_U_df
:
29845 gen_helper_msa_dpsub_u_h(cpu_env
, twd
, tws
, twt
);
29848 gen_helper_msa_dpsub_u_w(cpu_env
, twd
, tws
, twt
);
29851 gen_helper_msa_dpsub_u_d(cpu_env
, twd
, tws
, twt
);
29858 MIPS_INVAL("MSA instruction");
29859 gen_reserved_instruction(ctx
);
29862 tcg_temp_free_i32(twd
);
29863 tcg_temp_free_i32(tws
);
29864 tcg_temp_free_i32(twt
);
29865 tcg_temp_free_i32(tdf
);
29868 static void gen_msa_elm_3e(CPUMIPSState
*env
, DisasContext
*ctx
)
29870 #define MASK_MSA_ELM_DF3E(op) (MASK_MSA_MINOR(op) | (op & (0x3FF << 16)))
29871 uint8_t source
= (ctx
->opcode
>> 11) & 0x1f;
29872 uint8_t dest
= (ctx
->opcode
>> 6) & 0x1f;
29873 TCGv telm
= tcg_temp_new();
29874 TCGv_i32 tsr
= tcg_const_i32(source
);
29875 TCGv_i32 tdt
= tcg_const_i32(dest
);
29877 switch (MASK_MSA_ELM_DF3E(ctx
->opcode
)) {
29879 gen_load_gpr(telm
, source
);
29880 gen_helper_msa_ctcmsa(cpu_env
, telm
, tdt
);
29883 gen_helper_msa_cfcmsa(telm
, cpu_env
, tsr
);
29884 gen_store_gpr(telm
, dest
);
29887 gen_helper_msa_move_v(cpu_env
, tdt
, tsr
);
29890 MIPS_INVAL("MSA instruction");
29891 gen_reserved_instruction(ctx
);
29895 tcg_temp_free(telm
);
29896 tcg_temp_free_i32(tdt
);
29897 tcg_temp_free_i32(tsr
);
29900 static void gen_msa_elm_df(CPUMIPSState
*env
, DisasContext
*ctx
, uint32_t df
,
29903 #define MASK_MSA_ELM(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
29904 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
29905 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
29907 TCGv_i32 tws
= tcg_const_i32(ws
);
29908 TCGv_i32 twd
= tcg_const_i32(wd
);
29909 TCGv_i32 tn
= tcg_const_i32(n
);
29910 TCGv_i32 tdf
= tcg_const_i32(df
);
29912 switch (MASK_MSA_ELM(ctx
->opcode
)) {
29914 gen_helper_msa_sldi_df(cpu_env
, tdf
, twd
, tws
, tn
);
29916 case OPC_SPLATI_df
:
29917 gen_helper_msa_splati_df(cpu_env
, tdf
, twd
, tws
, tn
);
29920 gen_helper_msa_insve_df(cpu_env
, tdf
, twd
, tws
, tn
);
29922 case OPC_COPY_S_df
:
29923 case OPC_COPY_U_df
:
29924 case OPC_INSERT_df
:
29925 #if !defined(TARGET_MIPS64)
29926 /* Double format valid only for MIPS64 */
29927 if (df
== DF_DOUBLE
) {
29928 gen_reserved_instruction(ctx
);
29931 if ((MASK_MSA_ELM(ctx
->opcode
) == OPC_COPY_U_df
) &&
29933 gen_reserved_instruction(ctx
);
29937 switch (MASK_MSA_ELM(ctx
->opcode
)) {
29938 case OPC_COPY_S_df
:
29939 if (likely(wd
!= 0)) {
29942 gen_helper_msa_copy_s_b(cpu_env
, twd
, tws
, tn
);
29945 gen_helper_msa_copy_s_h(cpu_env
, twd
, tws
, tn
);
29948 gen_helper_msa_copy_s_w(cpu_env
, twd
, tws
, tn
);
29950 #if defined(TARGET_MIPS64)
29952 gen_helper_msa_copy_s_d(cpu_env
, twd
, tws
, tn
);
29960 case OPC_COPY_U_df
:
29961 if (likely(wd
!= 0)) {
29964 gen_helper_msa_copy_u_b(cpu_env
, twd
, tws
, tn
);
29967 gen_helper_msa_copy_u_h(cpu_env
, twd
, tws
, tn
);
29969 #if defined(TARGET_MIPS64)
29971 gen_helper_msa_copy_u_w(cpu_env
, twd
, tws
, tn
);
29979 case OPC_INSERT_df
:
29982 gen_helper_msa_insert_b(cpu_env
, twd
, tws
, tn
);
29985 gen_helper_msa_insert_h(cpu_env
, twd
, tws
, tn
);
29988 gen_helper_msa_insert_w(cpu_env
, twd
, tws
, tn
);
29990 #if defined(TARGET_MIPS64)
29992 gen_helper_msa_insert_d(cpu_env
, twd
, tws
, tn
);
30002 MIPS_INVAL("MSA instruction");
30003 gen_reserved_instruction(ctx
);
30005 tcg_temp_free_i32(twd
);
30006 tcg_temp_free_i32(tws
);
30007 tcg_temp_free_i32(tn
);
30008 tcg_temp_free_i32(tdf
);
30011 static void gen_msa_elm(CPUMIPSState
*env
, DisasContext
*ctx
)
30013 uint8_t dfn
= (ctx
->opcode
>> 16) & 0x3f;
30014 uint32_t df
= 0, n
= 0;
30016 if ((dfn
& 0x30) == 0x00) {
30019 } else if ((dfn
& 0x38) == 0x20) {
30022 } else if ((dfn
& 0x3c) == 0x30) {
30025 } else if ((dfn
& 0x3e) == 0x38) {
30028 } else if (dfn
== 0x3E) {
30029 /* CTCMSA, CFCMSA, MOVE.V */
30030 gen_msa_elm_3e(env
, ctx
);
30033 gen_reserved_instruction(ctx
);
30037 gen_msa_elm_df(env
, ctx
, df
, n
);
30040 static void gen_msa_3rf(CPUMIPSState
*env
, DisasContext
*ctx
)
30042 #define MASK_MSA_3RF(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
30043 uint8_t df
= (ctx
->opcode
>> 21) & 0x1;
30044 uint8_t wt
= (ctx
->opcode
>> 16) & 0x1f;
30045 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
30046 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
30048 TCGv_i32 twd
= tcg_const_i32(wd
);
30049 TCGv_i32 tws
= tcg_const_i32(ws
);
30050 TCGv_i32 twt
= tcg_const_i32(wt
);
30051 TCGv_i32 tdf
= tcg_temp_new_i32();
30053 /* adjust df value for floating-point instruction */
30054 tcg_gen_movi_i32(tdf
, df
+ 2);
30056 switch (MASK_MSA_3RF(ctx
->opcode
)) {
30058 gen_helper_msa_fcaf_df(cpu_env
, tdf
, twd
, tws
, twt
);
30061 gen_helper_msa_fadd_df(cpu_env
, tdf
, twd
, tws
, twt
);
30064 gen_helper_msa_fcun_df(cpu_env
, tdf
, twd
, tws
, twt
);
30067 gen_helper_msa_fsub_df(cpu_env
, tdf
, twd
, tws
, twt
);
30070 gen_helper_msa_fcor_df(cpu_env
, tdf
, twd
, tws
, twt
);
30073 gen_helper_msa_fceq_df(cpu_env
, tdf
, twd
, tws
, twt
);
30076 gen_helper_msa_fmul_df(cpu_env
, tdf
, twd
, tws
, twt
);
30079 gen_helper_msa_fcune_df(cpu_env
, tdf
, twd
, tws
, twt
);
30082 gen_helper_msa_fcueq_df(cpu_env
, tdf
, twd
, tws
, twt
);
30085 gen_helper_msa_fdiv_df(cpu_env
, tdf
, twd
, tws
, twt
);
30088 gen_helper_msa_fcne_df(cpu_env
, tdf
, twd
, tws
, twt
);
30091 gen_helper_msa_fclt_df(cpu_env
, tdf
, twd
, tws
, twt
);
30094 gen_helper_msa_fmadd_df(cpu_env
, tdf
, twd
, tws
, twt
);
30097 tcg_gen_movi_i32(tdf
, df
+ 1);
30098 gen_helper_msa_mul_q_df(cpu_env
, tdf
, twd
, tws
, twt
);
30101 gen_helper_msa_fcult_df(cpu_env
, tdf
, twd
, tws
, twt
);
30104 gen_helper_msa_fmsub_df(cpu_env
, tdf
, twd
, tws
, twt
);
30106 case OPC_MADD_Q_df
:
30107 tcg_gen_movi_i32(tdf
, df
+ 1);
30108 gen_helper_msa_madd_q_df(cpu_env
, tdf
, twd
, tws
, twt
);
30111 gen_helper_msa_fcle_df(cpu_env
, tdf
, twd
, tws
, twt
);
30113 case OPC_MSUB_Q_df
:
30114 tcg_gen_movi_i32(tdf
, df
+ 1);
30115 gen_helper_msa_msub_q_df(cpu_env
, tdf
, twd
, tws
, twt
);
30118 gen_helper_msa_fcule_df(cpu_env
, tdf
, twd
, tws
, twt
);
30121 gen_helper_msa_fexp2_df(cpu_env
, tdf
, twd
, tws
, twt
);
30124 gen_helper_msa_fsaf_df(cpu_env
, tdf
, twd
, tws
, twt
);
30127 gen_helper_msa_fexdo_df(cpu_env
, tdf
, twd
, tws
, twt
);
30130 gen_helper_msa_fsun_df(cpu_env
, tdf
, twd
, tws
, twt
);
30133 gen_helper_msa_fsor_df(cpu_env
, tdf
, twd
, tws
, twt
);
30136 gen_helper_msa_fseq_df(cpu_env
, tdf
, twd
, tws
, twt
);
30139 gen_helper_msa_ftq_df(cpu_env
, tdf
, twd
, tws
, twt
);
30142 gen_helper_msa_fsune_df(cpu_env
, tdf
, twd
, tws
, twt
);
30145 gen_helper_msa_fsueq_df(cpu_env
, tdf
, twd
, tws
, twt
);
30148 gen_helper_msa_fsne_df(cpu_env
, tdf
, twd
, tws
, twt
);
30151 gen_helper_msa_fslt_df(cpu_env
, tdf
, twd
, tws
, twt
);
30154 gen_helper_msa_fmin_df(cpu_env
, tdf
, twd
, tws
, twt
);
30156 case OPC_MULR_Q_df
:
30157 tcg_gen_movi_i32(tdf
, df
+ 1);
30158 gen_helper_msa_mulr_q_df(cpu_env
, tdf
, twd
, tws
, twt
);
30161 gen_helper_msa_fsult_df(cpu_env
, tdf
, twd
, tws
, twt
);
30163 case OPC_FMIN_A_df
:
30164 gen_helper_msa_fmin_a_df(cpu_env
, tdf
, twd
, tws
, twt
);
30166 case OPC_MADDR_Q_df
:
30167 tcg_gen_movi_i32(tdf
, df
+ 1);
30168 gen_helper_msa_maddr_q_df(cpu_env
, tdf
, twd
, tws
, twt
);
30171 gen_helper_msa_fsle_df(cpu_env
, tdf
, twd
, tws
, twt
);
30174 gen_helper_msa_fmax_df(cpu_env
, tdf
, twd
, tws
, twt
);
30176 case OPC_MSUBR_Q_df
:
30177 tcg_gen_movi_i32(tdf
, df
+ 1);
30178 gen_helper_msa_msubr_q_df(cpu_env
, tdf
, twd
, tws
, twt
);
30181 gen_helper_msa_fsule_df(cpu_env
, tdf
, twd
, tws
, twt
);
30183 case OPC_FMAX_A_df
:
30184 gen_helper_msa_fmax_a_df(cpu_env
, tdf
, twd
, tws
, twt
);
30187 MIPS_INVAL("MSA instruction");
30188 gen_reserved_instruction(ctx
);
30192 tcg_temp_free_i32(twd
);
30193 tcg_temp_free_i32(tws
);
30194 tcg_temp_free_i32(twt
);
30195 tcg_temp_free_i32(tdf
);
30198 static void gen_msa_2r(CPUMIPSState
*env
, DisasContext
*ctx
)
30200 #define MASK_MSA_2R(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
30201 (op & (0x7 << 18)))
30202 uint8_t wt
= (ctx
->opcode
>> 16) & 0x1f;
30203 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
30204 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
30205 uint8_t df
= (ctx
->opcode
>> 16) & 0x3;
30206 TCGv_i32 twd
= tcg_const_i32(wd
);
30207 TCGv_i32 tws
= tcg_const_i32(ws
);
30208 TCGv_i32 twt
= tcg_const_i32(wt
);
30209 TCGv_i32 tdf
= tcg_const_i32(df
);
30211 switch (MASK_MSA_2R(ctx
->opcode
)) {
30213 #if !defined(TARGET_MIPS64)
30214 /* Double format valid only for MIPS64 */
30215 if (df
== DF_DOUBLE
) {
30216 gen_reserved_instruction(ctx
);
30220 gen_helper_msa_fill_df(cpu_env
, tdf
, twd
, tws
); /* trs */
30225 gen_helper_msa_nloc_b(cpu_env
, twd
, tws
);
30228 gen_helper_msa_nloc_h(cpu_env
, twd
, tws
);
30231 gen_helper_msa_nloc_w(cpu_env
, twd
, tws
);
30234 gen_helper_msa_nloc_d(cpu_env
, twd
, tws
);
30241 gen_helper_msa_nlzc_b(cpu_env
, twd
, tws
);
30244 gen_helper_msa_nlzc_h(cpu_env
, twd
, tws
);
30247 gen_helper_msa_nlzc_w(cpu_env
, twd
, tws
);
30250 gen_helper_msa_nlzc_d(cpu_env
, twd
, tws
);
30257 gen_helper_msa_pcnt_b(cpu_env
, twd
, tws
);
30260 gen_helper_msa_pcnt_h(cpu_env
, twd
, tws
);
30263 gen_helper_msa_pcnt_w(cpu_env
, twd
, tws
);
30266 gen_helper_msa_pcnt_d(cpu_env
, twd
, tws
);
30271 MIPS_INVAL("MSA instruction");
30272 gen_reserved_instruction(ctx
);
30276 tcg_temp_free_i32(twd
);
30277 tcg_temp_free_i32(tws
);
30278 tcg_temp_free_i32(twt
);
30279 tcg_temp_free_i32(tdf
);
30282 static void gen_msa_2rf(CPUMIPSState
*env
, DisasContext
*ctx
)
30284 #define MASK_MSA_2RF(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
30285 (op & (0xf << 17)))
30286 uint8_t wt
= (ctx
->opcode
>> 16) & 0x1f;
30287 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
30288 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
30289 uint8_t df
= (ctx
->opcode
>> 16) & 0x1;
30290 TCGv_i32 twd
= tcg_const_i32(wd
);
30291 TCGv_i32 tws
= tcg_const_i32(ws
);
30292 TCGv_i32 twt
= tcg_const_i32(wt
);
30293 /* adjust df value for floating-point instruction */
30294 TCGv_i32 tdf
= tcg_const_i32(df
+ 2);
30296 switch (MASK_MSA_2RF(ctx
->opcode
)) {
30297 case OPC_FCLASS_df
:
30298 gen_helper_msa_fclass_df(cpu_env
, tdf
, twd
, tws
);
30300 case OPC_FTRUNC_S_df
:
30301 gen_helper_msa_ftrunc_s_df(cpu_env
, tdf
, twd
, tws
);
30303 case OPC_FTRUNC_U_df
:
30304 gen_helper_msa_ftrunc_u_df(cpu_env
, tdf
, twd
, tws
);
30307 gen_helper_msa_fsqrt_df(cpu_env
, tdf
, twd
, tws
);
30309 case OPC_FRSQRT_df
:
30310 gen_helper_msa_frsqrt_df(cpu_env
, tdf
, twd
, tws
);
30313 gen_helper_msa_frcp_df(cpu_env
, tdf
, twd
, tws
);
30316 gen_helper_msa_frint_df(cpu_env
, tdf
, twd
, tws
);
30319 gen_helper_msa_flog2_df(cpu_env
, tdf
, twd
, tws
);
30321 case OPC_FEXUPL_df
:
30322 gen_helper_msa_fexupl_df(cpu_env
, tdf
, twd
, tws
);
30324 case OPC_FEXUPR_df
:
30325 gen_helper_msa_fexupr_df(cpu_env
, tdf
, twd
, tws
);
30328 gen_helper_msa_ffql_df(cpu_env
, tdf
, twd
, tws
);
30331 gen_helper_msa_ffqr_df(cpu_env
, tdf
, twd
, tws
);
30333 case OPC_FTINT_S_df
:
30334 gen_helper_msa_ftint_s_df(cpu_env
, tdf
, twd
, tws
);
30336 case OPC_FTINT_U_df
:
30337 gen_helper_msa_ftint_u_df(cpu_env
, tdf
, twd
, tws
);
30339 case OPC_FFINT_S_df
:
30340 gen_helper_msa_ffint_s_df(cpu_env
, tdf
, twd
, tws
);
30342 case OPC_FFINT_U_df
:
30343 gen_helper_msa_ffint_u_df(cpu_env
, tdf
, twd
, tws
);
30347 tcg_temp_free_i32(twd
);
30348 tcg_temp_free_i32(tws
);
30349 tcg_temp_free_i32(twt
);
30350 tcg_temp_free_i32(tdf
);
30353 static void gen_msa_vec_v(CPUMIPSState
*env
, DisasContext
*ctx
)
30355 #define MASK_MSA_VEC(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)))
30356 uint8_t wt
= (ctx
->opcode
>> 16) & 0x1f;
30357 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
30358 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
30359 TCGv_i32 twd
= tcg_const_i32(wd
);
30360 TCGv_i32 tws
= tcg_const_i32(ws
);
30361 TCGv_i32 twt
= tcg_const_i32(wt
);
30363 switch (MASK_MSA_VEC(ctx
->opcode
)) {
30365 gen_helper_msa_and_v(cpu_env
, twd
, tws
, twt
);
30368 gen_helper_msa_or_v(cpu_env
, twd
, tws
, twt
);
30371 gen_helper_msa_nor_v(cpu_env
, twd
, tws
, twt
);
30374 gen_helper_msa_xor_v(cpu_env
, twd
, tws
, twt
);
30377 gen_helper_msa_bmnz_v(cpu_env
, twd
, tws
, twt
);
30380 gen_helper_msa_bmz_v(cpu_env
, twd
, tws
, twt
);
30383 gen_helper_msa_bsel_v(cpu_env
, twd
, tws
, twt
);
30386 MIPS_INVAL("MSA instruction");
30387 gen_reserved_instruction(ctx
);
30391 tcg_temp_free_i32(twd
);
30392 tcg_temp_free_i32(tws
);
30393 tcg_temp_free_i32(twt
);
30396 static void gen_msa_vec(CPUMIPSState
*env
, DisasContext
*ctx
)
30398 switch (MASK_MSA_VEC(ctx
->opcode
)) {
30406 gen_msa_vec_v(env
, ctx
);
30409 gen_msa_2r(env
, ctx
);
30412 gen_msa_2rf(env
, ctx
);
30415 MIPS_INVAL("MSA instruction");
30416 gen_reserved_instruction(ctx
);
30421 static void gen_msa(CPUMIPSState
*env
, DisasContext
*ctx
)
30423 uint32_t opcode
= ctx
->opcode
;
30424 check_insn(ctx
, ASE_MSA
);
30425 check_msa_access(ctx
);
30427 switch (MASK_MSA_MINOR(opcode
)) {
30428 case OPC_MSA_I8_00
:
30429 case OPC_MSA_I8_01
:
30430 case OPC_MSA_I8_02
:
30431 gen_msa_i8(env
, ctx
);
30433 case OPC_MSA_I5_06
:
30434 case OPC_MSA_I5_07
:
30435 gen_msa_i5(env
, ctx
);
30437 case OPC_MSA_BIT_09
:
30438 case OPC_MSA_BIT_0A
:
30439 gen_msa_bit(env
, ctx
);
30441 case OPC_MSA_3R_0D
:
30442 case OPC_MSA_3R_0E
:
30443 case OPC_MSA_3R_0F
:
30444 case OPC_MSA_3R_10
:
30445 case OPC_MSA_3R_11
:
30446 case OPC_MSA_3R_12
:
30447 case OPC_MSA_3R_13
:
30448 case OPC_MSA_3R_14
:
30449 case OPC_MSA_3R_15
:
30450 gen_msa_3r(env
, ctx
);
30453 gen_msa_elm(env
, ctx
);
30455 case OPC_MSA_3RF_1A
:
30456 case OPC_MSA_3RF_1B
:
30457 case OPC_MSA_3RF_1C
:
30458 gen_msa_3rf(env
, ctx
);
30461 gen_msa_vec(env
, ctx
);
30472 int32_t s10
= sextract32(ctx
->opcode
, 16, 10);
30473 uint8_t rs
= (ctx
->opcode
>> 11) & 0x1f;
30474 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
30475 uint8_t df
= (ctx
->opcode
>> 0) & 0x3;
30477 TCGv_i32 twd
= tcg_const_i32(wd
);
30478 TCGv taddr
= tcg_temp_new();
30479 gen_base_offset_addr(ctx
, taddr
, rs
, s10
<< df
);
30481 switch (MASK_MSA_MINOR(opcode
)) {
30483 gen_helper_msa_ld_b(cpu_env
, twd
, taddr
);
30486 gen_helper_msa_ld_h(cpu_env
, twd
, taddr
);
30489 gen_helper_msa_ld_w(cpu_env
, twd
, taddr
);
30492 gen_helper_msa_ld_d(cpu_env
, twd
, taddr
);
30495 gen_helper_msa_st_b(cpu_env
, twd
, taddr
);
30498 gen_helper_msa_st_h(cpu_env
, twd
, taddr
);
30501 gen_helper_msa_st_w(cpu_env
, twd
, taddr
);
30504 gen_helper_msa_st_d(cpu_env
, twd
, taddr
);
30508 tcg_temp_free_i32(twd
);
30509 tcg_temp_free(taddr
);
30513 MIPS_INVAL("MSA instruction");
30514 gen_reserved_instruction(ctx
);
30520 static void decode_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
30523 int rs
, rt
, rd
, sa
;
30527 /* make sure instructions are on a word boundary */
30528 if (ctx
->base
.pc_next
& 0x3) {
30529 env
->CP0_BadVAddr
= ctx
->base
.pc_next
;
30530 generate_exception_err(ctx
, EXCP_AdEL
, EXCP_INST_NOTAVAIL
);
30534 /* Handle blikely not taken case */
30535 if ((ctx
->hflags
& MIPS_HFLAG_BMASK_BASE
) == MIPS_HFLAG_BL
) {
30536 TCGLabel
*l1
= gen_new_label();
30538 tcg_gen_brcondi_tl(TCG_COND_NE
, bcond
, 0, l1
);
30539 tcg_gen_movi_i32(hflags
, ctx
->hflags
& ~MIPS_HFLAG_BMASK
);
30540 gen_goto_tb(ctx
, 1, ctx
->base
.pc_next
+ 4);
30544 op
= MASK_OP_MAJOR(ctx
->opcode
);
30545 rs
= (ctx
->opcode
>> 21) & 0x1f;
30546 rt
= (ctx
->opcode
>> 16) & 0x1f;
30547 rd
= (ctx
->opcode
>> 11) & 0x1f;
30548 sa
= (ctx
->opcode
>> 6) & 0x1f;
30549 imm
= (int16_t)ctx
->opcode
;
30552 decode_opc_special(env
, ctx
);
30555 #if defined(TARGET_MIPS64)
30556 if ((ctx
->insn_flags
& INSN_R5900
) && (ctx
->insn_flags
& ASE_MMI
)) {
30557 decode_mmi(env
, ctx
);
30559 if (ctx
->insn_flags
& ASE_MXU
) {
30560 decode_opc_mxu(env
, ctx
);
30563 decode_opc_special2_legacy(env
, ctx
);
30567 #if defined(TARGET_MIPS64)
30568 if (ctx
->insn_flags
& INSN_R5900
) {
30569 decode_mmi_sq(env
, ctx
); /* MMI_OPC_SQ */
30571 decode_opc_special3(env
, ctx
);
30574 decode_opc_special3(env
, ctx
);
30578 op1
= MASK_REGIMM(ctx
->opcode
);
30580 case OPC_BLTZL
: /* REGIMM branches */
30584 check_insn(ctx
, ISA_MIPS2
);
30585 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
30589 gen_compute_branch(ctx
, op1
, 4, rs
, -1, imm
<< 2, 4);
30593 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
30595 /* OPC_NAL, OPC_BAL */
30596 gen_compute_branch(ctx
, op1
, 4, 0, -1, imm
<< 2, 4);
30598 gen_reserved_instruction(ctx
);
30601 gen_compute_branch(ctx
, op1
, 4, rs
, -1, imm
<< 2, 4);
30604 case OPC_TGEI
: /* REGIMM traps */
30611 check_insn(ctx
, ISA_MIPS2
);
30612 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
30613 gen_trap(ctx
, op1
, rs
, -1, imm
);
30616 check_insn(ctx
, ISA_MIPS_R6
);
30617 gen_reserved_instruction(ctx
);
30620 check_insn(ctx
, ISA_MIPS_R2
);
30622 * Break the TB to be able to sync copied instructions
30625 ctx
->base
.is_jmp
= DISAS_STOP
;
30627 case OPC_BPOSGE32
: /* MIPS DSP branch */
30628 #if defined(TARGET_MIPS64)
30632 gen_compute_branch(ctx
, op1
, 4, -1, -2, (int32_t)imm
<< 2, 4);
30634 #if defined(TARGET_MIPS64)
30636 check_insn(ctx
, ISA_MIPS_R6
);
30637 check_mips_64(ctx
);
30639 tcg_gen_addi_tl(cpu_gpr
[rs
], cpu_gpr
[rs
], (int64_t)imm
<< 32);
30643 check_insn(ctx
, ISA_MIPS_R6
);
30644 check_mips_64(ctx
);
30646 tcg_gen_addi_tl(cpu_gpr
[rs
], cpu_gpr
[rs
], (int64_t)imm
<< 48);
30650 default: /* Invalid */
30651 MIPS_INVAL("regimm");
30652 gen_reserved_instruction(ctx
);
30657 check_cp0_enabled(ctx
);
30658 op1
= MASK_CP0(ctx
->opcode
);
30666 #if defined(TARGET_MIPS64)
30670 #ifndef CONFIG_USER_ONLY
30671 gen_cp0(env
, ctx
, op1
, rt
, rd
);
30672 #endif /* !CONFIG_USER_ONLY */
30690 #ifndef CONFIG_USER_ONLY
30691 gen_cp0(env
, ctx
, MASK_C0(ctx
->opcode
), rt
, rd
);
30692 #endif /* !CONFIG_USER_ONLY */
30695 #ifndef CONFIG_USER_ONLY
30698 TCGv t0
= tcg_temp_new();
30700 op2
= MASK_MFMC0(ctx
->opcode
);
30704 gen_helper_dmt(t0
);
30705 gen_store_gpr(t0
, rt
);
30709 gen_helper_emt(t0
);
30710 gen_store_gpr(t0
, rt
);
30714 gen_helper_dvpe(t0
, cpu_env
);
30715 gen_store_gpr(t0
, rt
);
30719 gen_helper_evpe(t0
, cpu_env
);
30720 gen_store_gpr(t0
, rt
);
30723 check_insn(ctx
, ISA_MIPS_R6
);
30725 gen_helper_dvp(t0
, cpu_env
);
30726 gen_store_gpr(t0
, rt
);
30730 check_insn(ctx
, ISA_MIPS_R6
);
30732 gen_helper_evp(t0
, cpu_env
);
30733 gen_store_gpr(t0
, rt
);
30737 check_insn(ctx
, ISA_MIPS_R2
);
30738 save_cpu_state(ctx
, 1);
30739 gen_helper_di(t0
, cpu_env
);
30740 gen_store_gpr(t0
, rt
);
30742 * Stop translation as we may have switched
30743 * the execution mode.
30745 ctx
->base
.is_jmp
= DISAS_STOP
;
30748 check_insn(ctx
, ISA_MIPS_R2
);
30749 save_cpu_state(ctx
, 1);
30750 gen_helper_ei(t0
, cpu_env
);
30751 gen_store_gpr(t0
, rt
);
30753 * DISAS_STOP isn't sufficient, we need to ensure we break
30754 * out of translated code to check for pending interrupts.
30756 gen_save_pc(ctx
->base
.pc_next
+ 4);
30757 ctx
->base
.is_jmp
= DISAS_EXIT
;
30759 default: /* Invalid */
30760 MIPS_INVAL("mfmc0");
30761 gen_reserved_instruction(ctx
);
30766 #endif /* !CONFIG_USER_ONLY */
30769 check_insn(ctx
, ISA_MIPS_R2
);
30770 gen_load_srsgpr(rt
, rd
);
30773 check_insn(ctx
, ISA_MIPS_R2
);
30774 gen_store_srsgpr(rt
, rd
);
30778 gen_reserved_instruction(ctx
);
30782 case OPC_BOVC
: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */
30783 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
30784 /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */
30785 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
30788 /* Arithmetic with immediate opcode */
30789 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
30793 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
30795 case OPC_SLTI
: /* Set on less than with immediate opcode */
30797 gen_slt_imm(ctx
, op
, rt
, rs
, imm
);
30799 case OPC_ANDI
: /* Arithmetic with immediate opcode */
30800 case OPC_LUI
: /* OPC_AUI */
30803 gen_logic_imm(ctx
, op
, rt
, rs
, imm
);
30805 case OPC_J
: /* Jump */
30807 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
30808 gen_compute_branch(ctx
, op
, 4, rs
, rt
, offset
, 4);
30811 case OPC_BLEZC
: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */
30812 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
30814 gen_reserved_instruction(ctx
);
30817 /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */
30818 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
30821 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
30824 case OPC_BGTZC
: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */
30825 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
30827 gen_reserved_instruction(ctx
);
30830 /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */
30831 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
30834 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
30837 case OPC_BLEZALC
: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */
30840 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
30842 check_insn(ctx
, ISA_MIPS_R6
);
30843 /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */
30844 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
30847 case OPC_BGTZALC
: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */
30850 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
30852 check_insn(ctx
, ISA_MIPS_R6
);
30853 /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */
30854 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
30859 check_insn(ctx
, ISA_MIPS2
);
30860 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
30864 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
30866 case OPC_LL
: /* Load and stores */
30867 check_insn(ctx
, ISA_MIPS2
);
30868 if (ctx
->insn_flags
& INSN_R5900
) {
30869 check_insn_opc_user_only(ctx
, INSN_R5900
);
30874 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
30882 gen_ld(ctx
, op
, rt
, rs
, imm
);
30886 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
30891 gen_st(ctx
, op
, rt
, rs
, imm
);
30894 check_insn(ctx
, ISA_MIPS2
);
30895 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
30896 if (ctx
->insn_flags
& INSN_R5900
) {
30897 check_insn_opc_user_only(ctx
, INSN_R5900
);
30899 gen_st_cond(ctx
, rt
, rs
, imm
, MO_TESL
, false);
30902 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
30903 check_cp0_enabled(ctx
);
30904 check_insn(ctx
, ISA_MIPS3
| ISA_MIPS_R1
);
30905 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
30906 gen_cache_operation(ctx
, rt
, rs
, imm
);
30908 /* Treat as NOP. */
30911 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
30912 if (ctx
->insn_flags
& INSN_R5900
) {
30913 /* Treat as NOP. */
30915 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS_R1
);
30916 /* Treat as NOP. */
30920 /* Floating point (COP1). */
30925 gen_cop1_ldst(ctx
, op
, rt
, rs
, imm
);
30929 op1
= MASK_CP1(ctx
->opcode
);
30934 check_cp1_enabled(ctx
);
30935 check_insn(ctx
, ISA_MIPS_R2
);
30941 check_cp1_enabled(ctx
);
30942 gen_cp1(ctx
, op1
, rt
, rd
);
30944 #if defined(TARGET_MIPS64)
30947 check_cp1_enabled(ctx
);
30948 check_insn(ctx
, ISA_MIPS3
);
30949 check_mips_64(ctx
);
30950 gen_cp1(ctx
, op1
, rt
, rd
);
30953 case OPC_BC1EQZ
: /* OPC_BC1ANY2 */
30954 check_cp1_enabled(ctx
);
30955 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
30957 gen_compute_branch1_r6(ctx
, MASK_CP1(ctx
->opcode
),
30962 check_insn(ctx
, ASE_MIPS3D
);
30963 gen_compute_branch1(ctx
, MASK_BC1(ctx
->opcode
),
30964 (rt
>> 2) & 0x7, imm
<< 2);
30968 check_cp1_enabled(ctx
);
30969 check_insn(ctx
, ISA_MIPS_R6
);
30970 gen_compute_branch1_r6(ctx
, MASK_CP1(ctx
->opcode
),
30974 check_cp1_enabled(ctx
);
30975 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
30977 check_insn(ctx
, ASE_MIPS3D
);
30980 check_cp1_enabled(ctx
);
30981 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
30982 gen_compute_branch1(ctx
, MASK_BC1(ctx
->opcode
),
30983 (rt
>> 2) & 0x7, imm
<< 2);
30990 check_cp1_enabled(ctx
);
30991 gen_farith(ctx
, ctx
->opcode
& FOP(0x3f, 0x1f), rt
, rd
, sa
,
30997 int r6_op
= ctx
->opcode
& FOP(0x3f, 0x1f);
30998 check_cp1_enabled(ctx
);
30999 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
31001 case R6_OPC_CMP_AF_S
:
31002 case R6_OPC_CMP_UN_S
:
31003 case R6_OPC_CMP_EQ_S
:
31004 case R6_OPC_CMP_UEQ_S
:
31005 case R6_OPC_CMP_LT_S
:
31006 case R6_OPC_CMP_ULT_S
:
31007 case R6_OPC_CMP_LE_S
:
31008 case R6_OPC_CMP_ULE_S
:
31009 case R6_OPC_CMP_SAF_S
:
31010 case R6_OPC_CMP_SUN_S
:
31011 case R6_OPC_CMP_SEQ_S
:
31012 case R6_OPC_CMP_SEUQ_S
:
31013 case R6_OPC_CMP_SLT_S
:
31014 case R6_OPC_CMP_SULT_S
:
31015 case R6_OPC_CMP_SLE_S
:
31016 case R6_OPC_CMP_SULE_S
:
31017 case R6_OPC_CMP_OR_S
:
31018 case R6_OPC_CMP_UNE_S
:
31019 case R6_OPC_CMP_NE_S
:
31020 case R6_OPC_CMP_SOR_S
:
31021 case R6_OPC_CMP_SUNE_S
:
31022 case R6_OPC_CMP_SNE_S
:
31023 gen_r6_cmp_s(ctx
, ctx
->opcode
& 0x1f, rt
, rd
, sa
);
31025 case R6_OPC_CMP_AF_D
:
31026 case R6_OPC_CMP_UN_D
:
31027 case R6_OPC_CMP_EQ_D
:
31028 case R6_OPC_CMP_UEQ_D
:
31029 case R6_OPC_CMP_LT_D
:
31030 case R6_OPC_CMP_ULT_D
:
31031 case R6_OPC_CMP_LE_D
:
31032 case R6_OPC_CMP_ULE_D
:
31033 case R6_OPC_CMP_SAF_D
:
31034 case R6_OPC_CMP_SUN_D
:
31035 case R6_OPC_CMP_SEQ_D
:
31036 case R6_OPC_CMP_SEUQ_D
:
31037 case R6_OPC_CMP_SLT_D
:
31038 case R6_OPC_CMP_SULT_D
:
31039 case R6_OPC_CMP_SLE_D
:
31040 case R6_OPC_CMP_SULE_D
:
31041 case R6_OPC_CMP_OR_D
:
31042 case R6_OPC_CMP_UNE_D
:
31043 case R6_OPC_CMP_NE_D
:
31044 case R6_OPC_CMP_SOR_D
:
31045 case R6_OPC_CMP_SUNE_D
:
31046 case R6_OPC_CMP_SNE_D
:
31047 gen_r6_cmp_d(ctx
, ctx
->opcode
& 0x1f, rt
, rd
, sa
);
31050 gen_farith(ctx
, ctx
->opcode
& FOP(0x3f, 0x1f),
31051 rt
, rd
, sa
, (imm
>> 8) & 0x7);
31056 gen_farith(ctx
, ctx
->opcode
& FOP(0x3f, 0x1f), rt
, rd
, sa
,
31071 check_insn(ctx
, ASE_MSA
);
31072 gen_msa_branch(env
, ctx
, op1
);
31076 gen_reserved_instruction(ctx
);
31081 /* Compact branches [R6] and COP2 [non-R6] */
31082 case OPC_BC
: /* OPC_LWC2 */
31083 case OPC_BALC
: /* OPC_SWC2 */
31084 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
31085 /* OPC_BC, OPC_BALC */
31086 gen_compute_compact_branch(ctx
, op
, 0, 0,
31087 sextract32(ctx
->opcode
<< 2, 0, 28));
31088 } else if (ctx
->insn_flags
& ASE_LEXT
) {
31089 gen_loongson_lswc2(ctx
, rt
, rs
, rd
);
31091 /* OPC_LWC2, OPC_SWC2 */
31092 /* COP2: Not implemented. */
31093 generate_exception_err(ctx
, EXCP_CpU
, 2);
31096 case OPC_BEQZC
: /* OPC_JIC, OPC_LDC2 */
31097 case OPC_BNEZC
: /* OPC_JIALC, OPC_SDC2 */
31098 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
31100 /* OPC_BEQZC, OPC_BNEZC */
31101 gen_compute_compact_branch(ctx
, op
, rs
, 0,
31102 sextract32(ctx
->opcode
<< 2, 0, 23));
31104 /* OPC_JIC, OPC_JIALC */
31105 gen_compute_compact_branch(ctx
, op
, 0, rt
, imm
);
31107 } else if (ctx
->insn_flags
& ASE_LEXT
) {
31108 gen_loongson_lsdc2(ctx
, rt
, rs
, rd
);
31110 /* OPC_LWC2, OPC_SWC2 */
31111 /* COP2: Not implemented. */
31112 generate_exception_err(ctx
, EXCP_CpU
, 2);
31116 check_insn(ctx
, ASE_LMMI
);
31117 /* Note that these instructions use different fields. */
31118 gen_loongson_multimedia(ctx
, sa
, rd
, rt
);
31122 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
31123 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
31124 check_cp1_enabled(ctx
);
31125 op1
= MASK_CP3(ctx
->opcode
);
31129 check_insn(ctx
, ISA_MIPS5
| ISA_MIPS_R2
);
31135 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS_R2
);
31136 gen_flt3_ldst(ctx
, op1
, sa
, rd
, rs
, rt
);
31139 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS_R2
);
31140 /* Treat as NOP. */
31143 check_insn(ctx
, ISA_MIPS5
| ISA_MIPS_R2
);
31157 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS_R2
);
31158 gen_flt3_arith(ctx
, op1
, sa
, rs
, rd
, rt
);
31162 gen_reserved_instruction(ctx
);
31166 generate_exception_err(ctx
, EXCP_CpU
, 1);
31170 #if defined(TARGET_MIPS64)
31171 /* MIPS64 opcodes */
31173 if (ctx
->insn_flags
& INSN_R5900
) {
31174 check_insn_opc_user_only(ctx
, INSN_R5900
);
31179 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
31183 check_insn(ctx
, ISA_MIPS3
);
31184 check_mips_64(ctx
);
31185 gen_ld(ctx
, op
, rt
, rs
, imm
);
31189 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
31192 check_insn(ctx
, ISA_MIPS3
);
31193 check_mips_64(ctx
);
31194 gen_st(ctx
, op
, rt
, rs
, imm
);
31197 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
31198 check_insn(ctx
, ISA_MIPS3
);
31199 if (ctx
->insn_flags
& INSN_R5900
) {
31200 check_insn_opc_user_only(ctx
, INSN_R5900
);
31202 check_mips_64(ctx
);
31203 gen_st_cond(ctx
, rt
, rs
, imm
, MO_TEQ
, false);
31205 case OPC_BNVC
: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */
31206 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
31207 /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */
31208 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
31211 check_insn(ctx
, ISA_MIPS3
);
31212 check_mips_64(ctx
);
31213 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
31217 check_insn(ctx
, ISA_MIPS3
);
31218 check_mips_64(ctx
);
31219 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
31222 case OPC_BNVC
: /* OPC_BNEZALC, OPC_BNEC */
31223 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
31224 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
31226 MIPS_INVAL("major opcode");
31227 gen_reserved_instruction(ctx
);
31231 case OPC_DAUI
: /* OPC_JALX */
31232 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
31233 #if defined(TARGET_MIPS64)
31235 check_mips_64(ctx
);
31237 generate_exception(ctx
, EXCP_RI
);
31238 } else if (rt
!= 0) {
31239 TCGv t0
= tcg_temp_new();
31240 gen_load_gpr(t0
, rs
);
31241 tcg_gen_addi_tl(cpu_gpr
[rt
], t0
, imm
<< 16);
31245 gen_reserved_instruction(ctx
);
31246 MIPS_INVAL("major opcode");
31250 check_insn(ctx
, ASE_MIPS16
| ASE_MICROMIPS
);
31251 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
31252 gen_compute_branch(ctx
, op
, 4, rs
, rt
, offset
, 4);
31255 case OPC_MSA
: /* OPC_MDMX */
31256 if (ctx
->insn_flags
& INSN_R5900
) {
31257 #if defined(TARGET_MIPS64)
31258 gen_mmi_lq(env
, ctx
); /* MMI_OPC_LQ */
31261 /* MDMX: Not implemented. */
31266 check_insn(ctx
, ISA_MIPS_R6
);
31267 gen_pcrel(ctx
, ctx
->opcode
, ctx
->base
.pc_next
, rs
);
31269 default: /* Invalid */
31270 MIPS_INVAL("major opcode");
31271 gen_reserved_instruction(ctx
);
31276 static void mips_tr_init_disas_context(DisasContextBase
*dcbase
, CPUState
*cs
)
31278 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
31279 CPUMIPSState
*env
= cs
->env_ptr
;
31281 ctx
->page_start
= ctx
->base
.pc_first
& TARGET_PAGE_MASK
;
31282 ctx
->saved_pc
= -1;
31283 ctx
->insn_flags
= env
->insn_flags
;
31284 ctx
->CP0_Config1
= env
->CP0_Config1
;
31285 ctx
->CP0_Config2
= env
->CP0_Config2
;
31286 ctx
->CP0_Config3
= env
->CP0_Config3
;
31287 ctx
->CP0_Config5
= env
->CP0_Config5
;
31289 ctx
->kscrexist
= (env
->CP0_Config4
>> CP0C4_KScrExist
) & 0xff;
31290 ctx
->rxi
= (env
->CP0_Config3
>> CP0C3_RXI
) & 1;
31291 ctx
->ie
= (env
->CP0_Config4
>> CP0C4_IE
) & 3;
31292 ctx
->bi
= (env
->CP0_Config3
>> CP0C3_BI
) & 1;
31293 ctx
->bp
= (env
->CP0_Config3
>> CP0C3_BP
) & 1;
31294 ctx
->PAMask
= env
->PAMask
;
31295 ctx
->mvh
= (env
->CP0_Config5
>> CP0C5_MVH
) & 1;
31296 ctx
->eva
= (env
->CP0_Config5
>> CP0C5_EVA
) & 1;
31297 ctx
->sc
= (env
->CP0_Config3
>> CP0C3_SC
) & 1;
31298 ctx
->CP0_LLAddr_shift
= env
->CP0_LLAddr_shift
;
31299 ctx
->cmgcr
= (env
->CP0_Config3
>> CP0C3_CMGCR
) & 1;
31300 /* Restore delay slot state from the tb context. */
31301 ctx
->hflags
= (uint32_t)ctx
->base
.tb
->flags
; /* FIXME: maybe use 64 bits? */
31302 ctx
->ulri
= (env
->CP0_Config3
>> CP0C3_ULRI
) & 1;
31303 ctx
->ps
= ((env
->active_fpu
.fcr0
>> FCR0_PS
) & 1) ||
31304 (env
->insn_flags
& (INSN_LOONGSON2E
| INSN_LOONGSON2F
));
31305 ctx
->vp
= (env
->CP0_Config5
>> CP0C5_VP
) & 1;
31306 ctx
->mrp
= (env
->CP0_Config5
>> CP0C5_MRP
) & 1;
31307 ctx
->nan2008
= (env
->active_fpu
.fcr31
>> FCR31_NAN2008
) & 1;
31308 ctx
->abs2008
= (env
->active_fpu
.fcr31
>> FCR31_ABS2008
) & 1;
31309 ctx
->mi
= (env
->CP0_Config5
>> CP0C5_MI
) & 1;
31310 ctx
->gi
= (env
->CP0_Config5
>> CP0C5_GI
) & 3;
31311 restore_cpu_state(env
, ctx
);
31312 #ifdef CONFIG_USER_ONLY
31313 ctx
->mem_idx
= MIPS_HFLAG_UM
;
31315 ctx
->mem_idx
= hflags_mmu_index(ctx
->hflags
);
31317 ctx
->default_tcg_memop_mask
= (ctx
->insn_flags
& (ISA_MIPS_R6
|
31318 INSN_LOONGSON3A
)) ? MO_UNALN
: MO_ALIGN
;
31320 LOG_DISAS("\ntb %p idx %d hflags %04x\n", ctx
->base
.tb
, ctx
->mem_idx
,
31324 static void mips_tr_tb_start(DisasContextBase
*dcbase
, CPUState
*cs
)
31328 static void mips_tr_insn_start(DisasContextBase
*dcbase
, CPUState
*cs
)
31330 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
31332 tcg_gen_insn_start(ctx
->base
.pc_next
, ctx
->hflags
& MIPS_HFLAG_BMASK
,
31336 static bool mips_tr_breakpoint_check(DisasContextBase
*dcbase
, CPUState
*cs
,
31337 const CPUBreakpoint
*bp
)
31339 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
31341 save_cpu_state(ctx
, 1);
31342 ctx
->base
.is_jmp
= DISAS_NORETURN
;
31343 gen_helper_raise_exception_debug(cpu_env
);
31345 * The address covered by the breakpoint must be included in
31346 * [tb->pc, tb->pc + tb->size) in order to for it to be
31347 * properly cleared -- thus we increment the PC here so that
31348 * the logic setting tb->size below does the right thing.
31350 ctx
->base
.pc_next
+= 4;
31354 static void mips_tr_translate_insn(DisasContextBase
*dcbase
, CPUState
*cs
)
31356 CPUMIPSState
*env
= cs
->env_ptr
;
31357 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
31361 is_slot
= ctx
->hflags
& MIPS_HFLAG_BMASK
;
31362 if (ctx
->insn_flags
& ISA_NANOMIPS32
) {
31363 ctx
->opcode
= cpu_lduw_code(env
, ctx
->base
.pc_next
);
31364 insn_bytes
= decode_nanomips_opc(env
, ctx
);
31365 } else if (!(ctx
->hflags
& MIPS_HFLAG_M16
)) {
31366 ctx
->opcode
= cpu_ldl_code(env
, ctx
->base
.pc_next
);
31368 decode_opc(env
, ctx
);
31369 } else if (ctx
->insn_flags
& ASE_MICROMIPS
) {
31370 ctx
->opcode
= cpu_lduw_code(env
, ctx
->base
.pc_next
);
31371 insn_bytes
= decode_micromips_opc(env
, ctx
);
31372 } else if (ctx
->insn_flags
& ASE_MIPS16
) {
31373 ctx
->opcode
= cpu_lduw_code(env
, ctx
->base
.pc_next
);
31374 insn_bytes
= decode_mips16_opc(env
, ctx
);
31376 gen_reserved_instruction(ctx
);
31377 g_assert(ctx
->base
.is_jmp
== DISAS_NORETURN
);
31381 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
31382 if (!(ctx
->hflags
& (MIPS_HFLAG_BDS16
| MIPS_HFLAG_BDS32
|
31383 MIPS_HFLAG_FBNSLOT
))) {
31385 * Force to generate branch as there is neither delay nor
31390 if ((ctx
->hflags
& MIPS_HFLAG_M16
) &&
31391 (ctx
->hflags
& MIPS_HFLAG_FBNSLOT
)) {
31393 * Force to generate branch as microMIPS R6 doesn't restrict
31394 * branches in the forbidden slot.
31400 gen_branch(ctx
, insn_bytes
);
31402 ctx
->base
.pc_next
+= insn_bytes
;
31404 if (ctx
->base
.is_jmp
!= DISAS_NEXT
) {
31408 * Execute a branch and its delay slot as a single instruction.
31409 * This is what GDB expects and is consistent with what the
31410 * hardware does (e.g. if a delay slot instruction faults, the
31411 * reported PC is the PC of the branch).
31413 if (ctx
->base
.singlestep_enabled
&&
31414 (ctx
->hflags
& MIPS_HFLAG_BMASK
) == 0) {
31415 ctx
->base
.is_jmp
= DISAS_TOO_MANY
;
31417 if (ctx
->base
.pc_next
- ctx
->page_start
>= TARGET_PAGE_SIZE
) {
31418 ctx
->base
.is_jmp
= DISAS_TOO_MANY
;
31422 static void mips_tr_tb_stop(DisasContextBase
*dcbase
, CPUState
*cs
)
31424 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
31426 if (ctx
->base
.singlestep_enabled
&& ctx
->base
.is_jmp
!= DISAS_NORETURN
) {
31427 save_cpu_state(ctx
, ctx
->base
.is_jmp
!= DISAS_EXIT
);
31428 gen_helper_raise_exception_debug(cpu_env
);
31430 switch (ctx
->base
.is_jmp
) {
31432 gen_save_pc(ctx
->base
.pc_next
);
31433 tcg_gen_lookup_and_goto_ptr();
31436 case DISAS_TOO_MANY
:
31437 save_cpu_state(ctx
, 0);
31438 gen_goto_tb(ctx
, 0, ctx
->base
.pc_next
);
31441 tcg_gen_exit_tb(NULL
, 0);
31443 case DISAS_NORETURN
:
31446 g_assert_not_reached();
31451 static void mips_tr_disas_log(const DisasContextBase
*dcbase
, CPUState
*cs
)
31453 qemu_log("IN: %s\n", lookup_symbol(dcbase
->pc_first
));
31454 log_target_disas(cs
, dcbase
->pc_first
, dcbase
->tb
->size
);
31457 static const TranslatorOps mips_tr_ops
= {
31458 .init_disas_context
= mips_tr_init_disas_context
,
31459 .tb_start
= mips_tr_tb_start
,
31460 .insn_start
= mips_tr_insn_start
,
31461 .breakpoint_check
= mips_tr_breakpoint_check
,
31462 .translate_insn
= mips_tr_translate_insn
,
31463 .tb_stop
= mips_tr_tb_stop
,
31464 .disas_log
= mips_tr_disas_log
,
31467 void gen_intermediate_code(CPUState
*cs
, TranslationBlock
*tb
, int max_insns
)
31471 translator_loop(&mips_tr_ops
, &ctx
.base
, cs
, tb
, max_insns
);
31474 static void fpu_dump_state(CPUMIPSState
*env
, FILE * f
, int flags
)
31477 int is_fpu64
= !!(env
->hflags
& MIPS_HFLAG_F64
);
31479 #define printfpr(fp) \
31482 qemu_fprintf(f, "w:%08x d:%016" PRIx64 \
31483 " fd:%13g fs:%13g psu: %13g\n", \
31484 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
31485 (double)(fp)->fd, \
31486 (double)(fp)->fs[FP_ENDIAN_IDX], \
31487 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
31490 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
31491 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
31492 qemu_fprintf(f, "w:%08x d:%016" PRIx64 \
31493 " fd:%13g fs:%13g psu:%13g\n", \
31494 tmp.w[FP_ENDIAN_IDX], tmp.d, \
31496 (double)tmp.fs[FP_ENDIAN_IDX], \
31497 (double)tmp.fs[!FP_ENDIAN_IDX]); \
31503 "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
31504 env
->active_fpu
.fcr0
, env
->active_fpu
.fcr31
, is_fpu64
,
31505 get_float_exception_flags(&env
->active_fpu
.fp_status
));
31506 for (i
= 0; i
< 32; (is_fpu64
) ? i
++ : (i
+= 2)) {
31507 qemu_fprintf(f
, "%3s: ", fregnames
[i
]);
31508 printfpr(&env
->active_fpu
.fpr
[i
]);
31514 void mips_cpu_dump_state(CPUState
*cs
, FILE *f
, int flags
)
31516 MIPSCPU
*cpu
= MIPS_CPU(cs
);
31517 CPUMIPSState
*env
= &cpu
->env
;
31520 qemu_fprintf(f
, "pc=0x" TARGET_FMT_lx
" HI=0x" TARGET_FMT_lx
31521 " LO=0x" TARGET_FMT_lx
" ds %04x "
31522 TARGET_FMT_lx
" " TARGET_FMT_ld
"\n",
31523 env
->active_tc
.PC
, env
->active_tc
.HI
[0], env
->active_tc
.LO
[0],
31524 env
->hflags
, env
->btarget
, env
->bcond
);
31525 for (i
= 0; i
< 32; i
++) {
31526 if ((i
& 3) == 0) {
31527 qemu_fprintf(f
, "GPR%02d:", i
);
31529 qemu_fprintf(f
, " %s " TARGET_FMT_lx
,
31530 regnames
[i
], env
->active_tc
.gpr
[i
]);
31531 if ((i
& 3) == 3) {
31532 qemu_fprintf(f
, "\n");
31536 qemu_fprintf(f
, "CP0 Status 0x%08x Cause 0x%08x EPC 0x"
31537 TARGET_FMT_lx
"\n",
31538 env
->CP0_Status
, env
->CP0_Cause
, env
->CP0_EPC
);
31539 qemu_fprintf(f
, " Config0 0x%08x Config1 0x%08x LLAddr 0x%016"
31541 env
->CP0_Config0
, env
->CP0_Config1
, env
->CP0_LLAddr
);
31542 qemu_fprintf(f
, " Config2 0x%08x Config3 0x%08x\n",
31543 env
->CP0_Config2
, env
->CP0_Config3
);
31544 qemu_fprintf(f
, " Config4 0x%08x Config5 0x%08x\n",
31545 env
->CP0_Config4
, env
->CP0_Config5
);
31546 if ((flags
& CPU_DUMP_FPU
) && (env
->hflags
& MIPS_HFLAG_FPU
)) {
31547 fpu_dump_state(env
, f
, flags
);
31551 void mips_tcg_init(void)
31556 for (i
= 1; i
< 32; i
++)
31557 cpu_gpr
[i
] = tcg_global_mem_new(cpu_env
,
31558 offsetof(CPUMIPSState
,
31562 for (i
= 0; i
< 32; i
++) {
31563 int off
= offsetof(CPUMIPSState
, active_fpu
.fpr
[i
].wr
.d
[0]);
31565 tcg_global_mem_new_i64(cpu_env
, off
, msaregnames
[i
* 2]);
31567 * The scalar floating-point unit (FPU) registers are mapped on
31568 * the MSA vector registers.
31570 fpu_f64
[i
] = msa_wr_d
[i
* 2];
31571 off
= offsetof(CPUMIPSState
, active_fpu
.fpr
[i
].wr
.d
[1]);
31572 msa_wr_d
[i
* 2 + 1] =
31573 tcg_global_mem_new_i64(cpu_env
, off
, msaregnames
[i
* 2 + 1]);
31576 cpu_PC
= tcg_global_mem_new(cpu_env
,
31577 offsetof(CPUMIPSState
, active_tc
.PC
), "PC");
31578 for (i
= 0; i
< MIPS_DSP_ACC
; i
++) {
31579 cpu_HI
[i
] = tcg_global_mem_new(cpu_env
,
31580 offsetof(CPUMIPSState
, active_tc
.HI
[i
]),
31582 cpu_LO
[i
] = tcg_global_mem_new(cpu_env
,
31583 offsetof(CPUMIPSState
, active_tc
.LO
[i
]),
31586 cpu_dspctrl
= tcg_global_mem_new(cpu_env
,
31587 offsetof(CPUMIPSState
,
31588 active_tc
.DSPControl
),
31590 bcond
= tcg_global_mem_new(cpu_env
,
31591 offsetof(CPUMIPSState
, bcond
), "bcond");
31592 btarget
= tcg_global_mem_new(cpu_env
,
31593 offsetof(CPUMIPSState
, btarget
), "btarget");
31594 hflags
= tcg_global_mem_new_i32(cpu_env
,
31595 offsetof(CPUMIPSState
, hflags
), "hflags");
31597 fpu_fcr0
= tcg_global_mem_new_i32(cpu_env
,
31598 offsetof(CPUMIPSState
, active_fpu
.fcr0
),
31600 fpu_fcr31
= tcg_global_mem_new_i32(cpu_env
,
31601 offsetof(CPUMIPSState
, active_fpu
.fcr31
),
31603 cpu_lladdr
= tcg_global_mem_new(cpu_env
, offsetof(CPUMIPSState
, lladdr
),
31605 cpu_llval
= tcg_global_mem_new(cpu_env
, offsetof(CPUMIPSState
, llval
),
31608 #if defined(TARGET_MIPS64)
31610 for (i
= 1; i
< 32; i
++) {
31611 cpu_mmr
[i
] = tcg_global_mem_new_i64(cpu_env
,
31612 offsetof(CPUMIPSState
,
31618 #if !defined(TARGET_MIPS64)
31619 for (i
= 0; i
< NUMBER_OF_MXU_REGISTERS
- 1; i
++) {
31620 mxu_gpr
[i
] = tcg_global_mem_new(cpu_env
,
31621 offsetof(CPUMIPSState
,
31622 active_tc
.mxu_gpr
[i
]),
31626 mxu_CR
= tcg_global_mem_new(cpu_env
,
31627 offsetof(CPUMIPSState
, active_tc
.mxu_cr
),
31628 mxuregnames
[NUMBER_OF_MXU_REGISTERS
- 1]);
31632 void restore_state_to_opc(CPUMIPSState
*env
, TranslationBlock
*tb
,
31633 target_ulong
*data
)
31635 env
->active_tc
.PC
= data
[0];
31636 env
->hflags
&= ~MIPS_HFLAG_BMASK
;
31637 env
->hflags
|= data
[1];
31638 switch (env
->hflags
& MIPS_HFLAG_BMASK_BASE
) {
31639 case MIPS_HFLAG_BR
:
31641 case MIPS_HFLAG_BC
:
31642 case MIPS_HFLAG_BL
:
31644 env
->btarget
= data
[2];