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)
9 * Copyright (c) 2020 Philippe Mathieu-Daudé
11 * This library is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public
13 * License as published by the Free Software Foundation; either
14 * version 2.1 of the License, or (at your option) any later version.
16 * This library is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
25 #include "qemu/osdep.h"
28 #include "tcg/tcg-op.h"
29 #include "exec/cpu_ldst.h"
30 #include "exec/helper-proto.h"
31 #include "exec/helper-gen.h"
32 #include "hw/semihosting/semihost.h"
34 #include "target/mips/trace.h"
35 #include "trace-tcg.h"
36 #include "exec/translator.h"
38 #include "qemu/qemu-print.h"
39 #include "fpu_helper.h"
40 #include "translate.h"
43 /* indirect opcode tables */
44 OPC_SPECIAL
= (0x00 << 26),
45 OPC_REGIMM
= (0x01 << 26),
46 OPC_CP0
= (0x10 << 26),
47 OPC_CP2
= (0x12 << 26),
48 OPC_CP3
= (0x13 << 26),
49 OPC_SPECIAL2
= (0x1C << 26),
50 OPC_SPECIAL3
= (0x1F << 26),
51 /* arithmetic with immediate */
52 OPC_ADDI
= (0x08 << 26),
53 OPC_ADDIU
= (0x09 << 26),
54 OPC_SLTI
= (0x0A << 26),
55 OPC_SLTIU
= (0x0B << 26),
56 /* logic with immediate */
57 OPC_ANDI
= (0x0C << 26),
58 OPC_ORI
= (0x0D << 26),
59 OPC_XORI
= (0x0E << 26),
60 OPC_LUI
= (0x0F << 26),
61 /* arithmetic with immediate */
62 OPC_DADDI
= (0x18 << 26),
63 OPC_DADDIU
= (0x19 << 26),
64 /* Jump and branches */
66 OPC_JAL
= (0x03 << 26),
67 OPC_BEQ
= (0x04 << 26), /* Unconditional if rs = rt = 0 (B) */
68 OPC_BEQL
= (0x14 << 26),
69 OPC_BNE
= (0x05 << 26),
70 OPC_BNEL
= (0x15 << 26),
71 OPC_BLEZ
= (0x06 << 26),
72 OPC_BLEZL
= (0x16 << 26),
73 OPC_BGTZ
= (0x07 << 26),
74 OPC_BGTZL
= (0x17 << 26),
75 OPC_JALX
= (0x1D << 26),
76 OPC_DAUI
= (0x1D << 26),
78 OPC_LDL
= (0x1A << 26),
79 OPC_LDR
= (0x1B << 26),
80 OPC_LB
= (0x20 << 26),
81 OPC_LH
= (0x21 << 26),
82 OPC_LWL
= (0x22 << 26),
83 OPC_LW
= (0x23 << 26),
84 OPC_LWPC
= OPC_LW
| 0x5,
85 OPC_LBU
= (0x24 << 26),
86 OPC_LHU
= (0x25 << 26),
87 OPC_LWR
= (0x26 << 26),
88 OPC_LWU
= (0x27 << 26),
89 OPC_SB
= (0x28 << 26),
90 OPC_SH
= (0x29 << 26),
91 OPC_SWL
= (0x2A << 26),
92 OPC_SW
= (0x2B << 26),
93 OPC_SDL
= (0x2C << 26),
94 OPC_SDR
= (0x2D << 26),
95 OPC_SWR
= (0x2E << 26),
96 OPC_LL
= (0x30 << 26),
97 OPC_LLD
= (0x34 << 26),
98 OPC_LD
= (0x37 << 26),
99 OPC_LDPC
= OPC_LD
| 0x5,
100 OPC_SC
= (0x38 << 26),
101 OPC_SCD
= (0x3C << 26),
102 OPC_SD
= (0x3F << 26),
103 /* Floating point load/store */
104 OPC_LWC1
= (0x31 << 26),
105 OPC_LWC2
= (0x32 << 26),
106 OPC_LDC1
= (0x35 << 26),
107 OPC_LDC2
= (0x36 << 26),
108 OPC_SWC1
= (0x39 << 26),
109 OPC_SWC2
= (0x3A << 26),
110 OPC_SDC1
= (0x3D << 26),
111 OPC_SDC2
= (0x3E << 26),
112 /* Compact Branches */
113 OPC_BLEZALC
= (0x06 << 26),
114 OPC_BGEZALC
= (0x06 << 26),
115 OPC_BGEUC
= (0x06 << 26),
116 OPC_BGTZALC
= (0x07 << 26),
117 OPC_BLTZALC
= (0x07 << 26),
118 OPC_BLTUC
= (0x07 << 26),
119 OPC_BOVC
= (0x08 << 26),
120 OPC_BEQZALC
= (0x08 << 26),
121 OPC_BEQC
= (0x08 << 26),
122 OPC_BLEZC
= (0x16 << 26),
123 OPC_BGEZC
= (0x16 << 26),
124 OPC_BGEC
= (0x16 << 26),
125 OPC_BGTZC
= (0x17 << 26),
126 OPC_BLTZC
= (0x17 << 26),
127 OPC_BLTC
= (0x17 << 26),
128 OPC_BNVC
= (0x18 << 26),
129 OPC_BNEZALC
= (0x18 << 26),
130 OPC_BNEC
= (0x18 << 26),
131 OPC_BC
= (0x32 << 26),
132 OPC_BEQZC
= (0x36 << 26),
133 OPC_JIC
= (0x36 << 26),
134 OPC_BALC
= (0x3A << 26),
135 OPC_BNEZC
= (0x3E << 26),
136 OPC_JIALC
= (0x3E << 26),
137 /* MDMX ASE specific */
138 OPC_MDMX
= (0x1E << 26),
139 /* Cache and prefetch */
140 OPC_CACHE
= (0x2F << 26),
141 OPC_PREF
= (0x33 << 26),
142 /* PC-relative address computation / loads */
143 OPC_PCREL
= (0x3B << 26),
146 /* PC-relative address computation / loads */
147 #define MASK_OPC_PCREL_TOP2BITS(op) (MASK_OP_MAJOR(op) | (op & (3 << 19)))
148 #define MASK_OPC_PCREL_TOP5BITS(op) (MASK_OP_MAJOR(op) | (op & (0x1f << 16)))
150 /* Instructions determined by bits 19 and 20 */
151 OPC_ADDIUPC
= OPC_PCREL
| (0 << 19),
152 R6_OPC_LWPC
= OPC_PCREL
| (1 << 19),
153 OPC_LWUPC
= OPC_PCREL
| (2 << 19),
155 /* Instructions determined by bits 16 ... 20 */
156 OPC_AUIPC
= OPC_PCREL
| (0x1e << 16),
157 OPC_ALUIPC
= OPC_PCREL
| (0x1f << 16),
160 R6_OPC_LDPC
= OPC_PCREL
| (6 << 18),
163 /* MIPS special opcodes */
164 #define MASK_SPECIAL(op) (MASK_OP_MAJOR(op) | (op & 0x3F))
168 OPC_SLL
= 0x00 | OPC_SPECIAL
,
169 /* NOP is SLL r0, r0, 0 */
170 /* SSNOP is SLL r0, r0, 1 */
171 /* EHB is SLL r0, r0, 3 */
172 OPC_SRL
= 0x02 | OPC_SPECIAL
, /* also ROTR */
173 OPC_ROTR
= OPC_SRL
| (1 << 21),
174 OPC_SRA
= 0x03 | OPC_SPECIAL
,
175 OPC_SLLV
= 0x04 | OPC_SPECIAL
,
176 OPC_SRLV
= 0x06 | OPC_SPECIAL
, /* also ROTRV */
177 OPC_ROTRV
= OPC_SRLV
| (1 << 6),
178 OPC_SRAV
= 0x07 | OPC_SPECIAL
,
179 OPC_DSLLV
= 0x14 | OPC_SPECIAL
,
180 OPC_DSRLV
= 0x16 | OPC_SPECIAL
, /* also DROTRV */
181 OPC_DROTRV
= OPC_DSRLV
| (1 << 6),
182 OPC_DSRAV
= 0x17 | OPC_SPECIAL
,
183 OPC_DSLL
= 0x38 | OPC_SPECIAL
,
184 OPC_DSRL
= 0x3A | OPC_SPECIAL
, /* also DROTR */
185 OPC_DROTR
= OPC_DSRL
| (1 << 21),
186 OPC_DSRA
= 0x3B | OPC_SPECIAL
,
187 OPC_DSLL32
= 0x3C | OPC_SPECIAL
,
188 OPC_DSRL32
= 0x3E | OPC_SPECIAL
, /* also DROTR32 */
189 OPC_DROTR32
= OPC_DSRL32
| (1 << 21),
190 OPC_DSRA32
= 0x3F | OPC_SPECIAL
,
191 /* Multiplication / division */
192 OPC_MULT
= 0x18 | OPC_SPECIAL
,
193 OPC_MULTU
= 0x19 | OPC_SPECIAL
,
194 OPC_DIV
= 0x1A | OPC_SPECIAL
,
195 OPC_DIVU
= 0x1B | OPC_SPECIAL
,
196 OPC_DMULT
= 0x1C | OPC_SPECIAL
,
197 OPC_DMULTU
= 0x1D | OPC_SPECIAL
,
198 OPC_DDIV
= 0x1E | OPC_SPECIAL
,
199 OPC_DDIVU
= 0x1F | OPC_SPECIAL
,
201 /* 2 registers arithmetic / logic */
202 OPC_ADD
= 0x20 | OPC_SPECIAL
,
203 OPC_ADDU
= 0x21 | OPC_SPECIAL
,
204 OPC_SUB
= 0x22 | OPC_SPECIAL
,
205 OPC_SUBU
= 0x23 | OPC_SPECIAL
,
206 OPC_AND
= 0x24 | OPC_SPECIAL
,
207 OPC_OR
= 0x25 | OPC_SPECIAL
,
208 OPC_XOR
= 0x26 | OPC_SPECIAL
,
209 OPC_NOR
= 0x27 | OPC_SPECIAL
,
210 OPC_SLT
= 0x2A | OPC_SPECIAL
,
211 OPC_SLTU
= 0x2B | OPC_SPECIAL
,
212 OPC_DADD
= 0x2C | OPC_SPECIAL
,
213 OPC_DADDU
= 0x2D | OPC_SPECIAL
,
214 OPC_DSUB
= 0x2E | OPC_SPECIAL
,
215 OPC_DSUBU
= 0x2F | OPC_SPECIAL
,
217 OPC_JR
= 0x08 | OPC_SPECIAL
, /* Also JR.HB */
218 OPC_JALR
= 0x09 | OPC_SPECIAL
, /* Also JALR.HB */
220 OPC_TGE
= 0x30 | OPC_SPECIAL
,
221 OPC_TGEU
= 0x31 | OPC_SPECIAL
,
222 OPC_TLT
= 0x32 | OPC_SPECIAL
,
223 OPC_TLTU
= 0x33 | OPC_SPECIAL
,
224 OPC_TEQ
= 0x34 | OPC_SPECIAL
,
225 OPC_TNE
= 0x36 | OPC_SPECIAL
,
226 /* HI / LO registers load & stores */
227 OPC_MFHI
= 0x10 | OPC_SPECIAL
,
228 OPC_MTHI
= 0x11 | OPC_SPECIAL
,
229 OPC_MFLO
= 0x12 | OPC_SPECIAL
,
230 OPC_MTLO
= 0x13 | OPC_SPECIAL
,
231 /* Conditional moves */
232 OPC_MOVZ
= 0x0A | OPC_SPECIAL
,
233 OPC_MOVN
= 0x0B | OPC_SPECIAL
,
235 OPC_SELEQZ
= 0x35 | OPC_SPECIAL
,
236 OPC_SELNEZ
= 0x37 | OPC_SPECIAL
,
238 OPC_MOVCI
= 0x01 | OPC_SPECIAL
,
241 OPC_PMON
= 0x05 | OPC_SPECIAL
, /* unofficial */
242 OPC_SYSCALL
= 0x0C | OPC_SPECIAL
,
243 OPC_BREAK
= 0x0D | OPC_SPECIAL
,
244 OPC_SPIM
= 0x0E | OPC_SPECIAL
, /* unofficial */
245 OPC_SYNC
= 0x0F | OPC_SPECIAL
,
247 OPC_SPECIAL28_RESERVED
= 0x28 | OPC_SPECIAL
,
248 OPC_SPECIAL29_RESERVED
= 0x29 | OPC_SPECIAL
,
249 OPC_SPECIAL39_RESERVED
= 0x39 | OPC_SPECIAL
,
250 OPC_SPECIAL3D_RESERVED
= 0x3D | OPC_SPECIAL
,
254 * R6 Multiply and Divide instructions have the same opcode
255 * and function field as legacy OPC_MULT[U]/OPC_DIV[U]
257 #define MASK_R6_MULDIV(op) (MASK_SPECIAL(op) | (op & (0x7ff)))
260 R6_OPC_MUL
= OPC_MULT
| (2 << 6),
261 R6_OPC_MUH
= OPC_MULT
| (3 << 6),
262 R6_OPC_MULU
= OPC_MULTU
| (2 << 6),
263 R6_OPC_MUHU
= OPC_MULTU
| (3 << 6),
264 R6_OPC_DIV
= OPC_DIV
| (2 << 6),
265 R6_OPC_MOD
= OPC_DIV
| (3 << 6),
266 R6_OPC_DIVU
= OPC_DIVU
| (2 << 6),
267 R6_OPC_MODU
= OPC_DIVU
| (3 << 6),
269 R6_OPC_DMUL
= OPC_DMULT
| (2 << 6),
270 R6_OPC_DMUH
= OPC_DMULT
| (3 << 6),
271 R6_OPC_DMULU
= OPC_DMULTU
| (2 << 6),
272 R6_OPC_DMUHU
= OPC_DMULTU
| (3 << 6),
273 R6_OPC_DDIV
= OPC_DDIV
| (2 << 6),
274 R6_OPC_DMOD
= OPC_DDIV
| (3 << 6),
275 R6_OPC_DDIVU
= OPC_DDIVU
| (2 << 6),
276 R6_OPC_DMODU
= OPC_DDIVU
| (3 << 6),
278 R6_OPC_CLZ
= 0x10 | OPC_SPECIAL
,
279 R6_OPC_CLO
= 0x11 | OPC_SPECIAL
,
280 R6_OPC_DCLZ
= 0x12 | OPC_SPECIAL
,
281 R6_OPC_DCLO
= 0x13 | OPC_SPECIAL
,
282 R6_OPC_SDBBP
= 0x0e | OPC_SPECIAL
,
285 /* Multiplication variants of the vr54xx. */
286 #define MASK_MUL_VR54XX(op) (MASK_SPECIAL(op) | (op & (0x1F << 6)))
289 OPC_VR54XX_MULS
= (0x03 << 6) | OPC_MULT
,
290 OPC_VR54XX_MULSU
= (0x03 << 6) | OPC_MULTU
,
291 OPC_VR54XX_MACC
= (0x05 << 6) | OPC_MULT
,
292 OPC_VR54XX_MACCU
= (0x05 << 6) | OPC_MULTU
,
293 OPC_VR54XX_MSAC
= (0x07 << 6) | OPC_MULT
,
294 OPC_VR54XX_MSACU
= (0x07 << 6) | OPC_MULTU
,
295 OPC_VR54XX_MULHI
= (0x09 << 6) | OPC_MULT
,
296 OPC_VR54XX_MULHIU
= (0x09 << 6) | OPC_MULTU
,
297 OPC_VR54XX_MULSHI
= (0x0B << 6) | OPC_MULT
,
298 OPC_VR54XX_MULSHIU
= (0x0B << 6) | OPC_MULTU
,
299 OPC_VR54XX_MACCHI
= (0x0D << 6) | OPC_MULT
,
300 OPC_VR54XX_MACCHIU
= (0x0D << 6) | OPC_MULTU
,
301 OPC_VR54XX_MSACHI
= (0x0F << 6) | OPC_MULT
,
302 OPC_VR54XX_MSACHIU
= (0x0F << 6) | OPC_MULTU
,
305 /* REGIMM (rt field) opcodes */
306 #define MASK_REGIMM(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 16)))
309 OPC_BLTZ
= (0x00 << 16) | OPC_REGIMM
,
310 OPC_BLTZL
= (0x02 << 16) | OPC_REGIMM
,
311 OPC_BGEZ
= (0x01 << 16) | OPC_REGIMM
,
312 OPC_BGEZL
= (0x03 << 16) | OPC_REGIMM
,
313 OPC_BLTZAL
= (0x10 << 16) | OPC_REGIMM
,
314 OPC_BLTZALL
= (0x12 << 16) | OPC_REGIMM
,
315 OPC_BGEZAL
= (0x11 << 16) | OPC_REGIMM
,
316 OPC_BGEZALL
= (0x13 << 16) | OPC_REGIMM
,
317 OPC_TGEI
= (0x08 << 16) | OPC_REGIMM
,
318 OPC_TGEIU
= (0x09 << 16) | OPC_REGIMM
,
319 OPC_TLTI
= (0x0A << 16) | OPC_REGIMM
,
320 OPC_TLTIU
= (0x0B << 16) | OPC_REGIMM
,
321 OPC_TEQI
= (0x0C << 16) | OPC_REGIMM
,
322 OPC_TNEI
= (0x0E << 16) | OPC_REGIMM
,
323 OPC_SIGRIE
= (0x17 << 16) | OPC_REGIMM
,
324 OPC_SYNCI
= (0x1F << 16) | OPC_REGIMM
,
326 OPC_DAHI
= (0x06 << 16) | OPC_REGIMM
,
327 OPC_DATI
= (0x1e << 16) | OPC_REGIMM
,
330 /* Special2 opcodes */
331 #define MASK_SPECIAL2(op) (MASK_OP_MAJOR(op) | (op & 0x3F))
334 /* Multiply & xxx operations */
335 OPC_MADD
= 0x00 | OPC_SPECIAL2
,
336 OPC_MADDU
= 0x01 | OPC_SPECIAL2
,
337 OPC_MUL
= 0x02 | OPC_SPECIAL2
,
338 OPC_MSUB
= 0x04 | OPC_SPECIAL2
,
339 OPC_MSUBU
= 0x05 | OPC_SPECIAL2
,
341 OPC_MULT_G_2F
= 0x10 | OPC_SPECIAL2
,
342 OPC_DMULT_G_2F
= 0x11 | OPC_SPECIAL2
,
343 OPC_MULTU_G_2F
= 0x12 | OPC_SPECIAL2
,
344 OPC_DMULTU_G_2F
= 0x13 | OPC_SPECIAL2
,
345 OPC_DIV_G_2F
= 0x14 | OPC_SPECIAL2
,
346 OPC_DDIV_G_2F
= 0x15 | OPC_SPECIAL2
,
347 OPC_DIVU_G_2F
= 0x16 | OPC_SPECIAL2
,
348 OPC_DDIVU_G_2F
= 0x17 | OPC_SPECIAL2
,
349 OPC_MOD_G_2F
= 0x1c | OPC_SPECIAL2
,
350 OPC_DMOD_G_2F
= 0x1d | OPC_SPECIAL2
,
351 OPC_MODU_G_2F
= 0x1e | OPC_SPECIAL2
,
352 OPC_DMODU_G_2F
= 0x1f | OPC_SPECIAL2
,
354 OPC_CLZ
= 0x20 | OPC_SPECIAL2
,
355 OPC_CLO
= 0x21 | OPC_SPECIAL2
,
356 OPC_DCLZ
= 0x24 | OPC_SPECIAL2
,
357 OPC_DCLO
= 0x25 | OPC_SPECIAL2
,
359 OPC_SDBBP
= 0x3F | OPC_SPECIAL2
,
362 /* Special3 opcodes */
363 #define MASK_SPECIAL3(op) (MASK_OP_MAJOR(op) | (op & 0x3F))
366 OPC_EXT
= 0x00 | OPC_SPECIAL3
,
367 OPC_DEXTM
= 0x01 | OPC_SPECIAL3
,
368 OPC_DEXTU
= 0x02 | OPC_SPECIAL3
,
369 OPC_DEXT
= 0x03 | OPC_SPECIAL3
,
370 OPC_INS
= 0x04 | OPC_SPECIAL3
,
371 OPC_DINSM
= 0x05 | OPC_SPECIAL3
,
372 OPC_DINSU
= 0x06 | OPC_SPECIAL3
,
373 OPC_DINS
= 0x07 | OPC_SPECIAL3
,
374 OPC_FORK
= 0x08 | OPC_SPECIAL3
,
375 OPC_YIELD
= 0x09 | OPC_SPECIAL3
,
376 OPC_BSHFL
= 0x20 | OPC_SPECIAL3
,
377 OPC_DBSHFL
= 0x24 | OPC_SPECIAL3
,
378 OPC_RDHWR
= 0x3B | OPC_SPECIAL3
,
379 OPC_GINV
= 0x3D | OPC_SPECIAL3
,
382 OPC_MULT_G_2E
= 0x18 | OPC_SPECIAL3
,
383 OPC_MULTU_G_2E
= 0x19 | OPC_SPECIAL3
,
384 OPC_DIV_G_2E
= 0x1A | OPC_SPECIAL3
,
385 OPC_DIVU_G_2E
= 0x1B | OPC_SPECIAL3
,
386 OPC_DMULT_G_2E
= 0x1C | OPC_SPECIAL3
,
387 OPC_DMULTU_G_2E
= 0x1D | OPC_SPECIAL3
,
388 OPC_DDIV_G_2E
= 0x1E | OPC_SPECIAL3
,
389 OPC_DDIVU_G_2E
= 0x1F | OPC_SPECIAL3
,
390 OPC_MOD_G_2E
= 0x22 | OPC_SPECIAL3
,
391 OPC_MODU_G_2E
= 0x23 | OPC_SPECIAL3
,
392 OPC_DMOD_G_2E
= 0x26 | OPC_SPECIAL3
,
393 OPC_DMODU_G_2E
= 0x27 | OPC_SPECIAL3
,
396 OPC_LX_DSP
= 0x0A | OPC_SPECIAL3
,
397 /* MIPS DSP Arithmetic */
398 OPC_ADDU_QB_DSP
= 0x10 | OPC_SPECIAL3
,
399 OPC_ADDU_OB_DSP
= 0x14 | OPC_SPECIAL3
,
400 OPC_ABSQ_S_PH_DSP
= 0x12 | OPC_SPECIAL3
,
401 OPC_ABSQ_S_QH_DSP
= 0x16 | OPC_SPECIAL3
,
402 /* OPC_ADDUH_QB_DSP is same as OPC_MULT_G_2E. */
403 /* OPC_ADDUH_QB_DSP = 0x18 | OPC_SPECIAL3, */
404 OPC_CMPU_EQ_QB_DSP
= 0x11 | OPC_SPECIAL3
,
405 OPC_CMPU_EQ_OB_DSP
= 0x15 | OPC_SPECIAL3
,
406 /* MIPS DSP GPR-Based Shift Sub-class */
407 OPC_SHLL_QB_DSP
= 0x13 | OPC_SPECIAL3
,
408 OPC_SHLL_OB_DSP
= 0x17 | OPC_SPECIAL3
,
409 /* MIPS DSP Multiply Sub-class insns */
410 /* OPC_MUL_PH_DSP is same as OPC_ADDUH_QB_DSP. */
411 /* OPC_MUL_PH_DSP = 0x18 | OPC_SPECIAL3, */
412 OPC_DPA_W_PH_DSP
= 0x30 | OPC_SPECIAL3
,
413 OPC_DPAQ_W_QH_DSP
= 0x34 | OPC_SPECIAL3
,
414 /* DSP Bit/Manipulation Sub-class */
415 OPC_INSV_DSP
= 0x0C | OPC_SPECIAL3
,
416 OPC_DINSV_DSP
= 0x0D | OPC_SPECIAL3
,
417 /* MIPS DSP Append Sub-class */
418 OPC_APPEND_DSP
= 0x31 | OPC_SPECIAL3
,
419 OPC_DAPPEND_DSP
= 0x35 | OPC_SPECIAL3
,
420 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
421 OPC_EXTR_W_DSP
= 0x38 | OPC_SPECIAL3
,
422 OPC_DEXTR_W_DSP
= 0x3C | OPC_SPECIAL3
,
425 OPC_LWLE
= 0x19 | OPC_SPECIAL3
,
426 OPC_LWRE
= 0x1A | OPC_SPECIAL3
,
427 OPC_CACHEE
= 0x1B | OPC_SPECIAL3
,
428 OPC_SBE
= 0x1C | OPC_SPECIAL3
,
429 OPC_SHE
= 0x1D | OPC_SPECIAL3
,
430 OPC_SCE
= 0x1E | OPC_SPECIAL3
,
431 OPC_SWE
= 0x1F | OPC_SPECIAL3
,
432 OPC_SWLE
= 0x21 | OPC_SPECIAL3
,
433 OPC_SWRE
= 0x22 | OPC_SPECIAL3
,
434 OPC_PREFE
= 0x23 | OPC_SPECIAL3
,
435 OPC_LBUE
= 0x28 | OPC_SPECIAL3
,
436 OPC_LHUE
= 0x29 | OPC_SPECIAL3
,
437 OPC_LBE
= 0x2C | OPC_SPECIAL3
,
438 OPC_LHE
= 0x2D | OPC_SPECIAL3
,
439 OPC_LLE
= 0x2E | OPC_SPECIAL3
,
440 OPC_LWE
= 0x2F | OPC_SPECIAL3
,
443 R6_OPC_PREF
= 0x35 | OPC_SPECIAL3
,
444 R6_OPC_CACHE
= 0x25 | OPC_SPECIAL3
,
445 R6_OPC_LL
= 0x36 | OPC_SPECIAL3
,
446 R6_OPC_SC
= 0x26 | OPC_SPECIAL3
,
447 R6_OPC_LLD
= 0x37 | OPC_SPECIAL3
,
448 R6_OPC_SCD
= 0x27 | OPC_SPECIAL3
,
451 /* Loongson EXT load/store quad word opcodes */
452 #define MASK_LOONGSON_GSLSQ(op) (MASK_OP_MAJOR(op) | (op & 0x8020))
454 OPC_GSLQ
= 0x0020 | OPC_LWC2
,
455 OPC_GSLQC1
= 0x8020 | OPC_LWC2
,
456 OPC_GSSHFL
= OPC_LWC2
,
457 OPC_GSSQ
= 0x0020 | OPC_SWC2
,
458 OPC_GSSQC1
= 0x8020 | OPC_SWC2
,
459 OPC_GSSHFS
= OPC_SWC2
,
462 /* Loongson EXT shifted load/store opcodes */
463 #define MASK_LOONGSON_GSSHFLS(op) (MASK_OP_MAJOR(op) | (op & 0xc03f))
465 OPC_GSLWLC1
= 0x4 | OPC_GSSHFL
,
466 OPC_GSLWRC1
= 0x5 | OPC_GSSHFL
,
467 OPC_GSLDLC1
= 0x6 | OPC_GSSHFL
,
468 OPC_GSLDRC1
= 0x7 | OPC_GSSHFL
,
469 OPC_GSSWLC1
= 0x4 | OPC_GSSHFS
,
470 OPC_GSSWRC1
= 0x5 | OPC_GSSHFS
,
471 OPC_GSSDLC1
= 0x6 | OPC_GSSHFS
,
472 OPC_GSSDRC1
= 0x7 | OPC_GSSHFS
,
475 /* Loongson EXT LDC2/SDC2 opcodes */
476 #define MASK_LOONGSON_LSDC2(op) (MASK_OP_MAJOR(op) | (op & 0x7))
479 OPC_GSLBX
= 0x0 | OPC_LDC2
,
480 OPC_GSLHX
= 0x1 | OPC_LDC2
,
481 OPC_GSLWX
= 0x2 | OPC_LDC2
,
482 OPC_GSLDX
= 0x3 | OPC_LDC2
,
483 OPC_GSLWXC1
= 0x6 | OPC_LDC2
,
484 OPC_GSLDXC1
= 0x7 | OPC_LDC2
,
485 OPC_GSSBX
= 0x0 | OPC_SDC2
,
486 OPC_GSSHX
= 0x1 | OPC_SDC2
,
487 OPC_GSSWX
= 0x2 | OPC_SDC2
,
488 OPC_GSSDX
= 0x3 | OPC_SDC2
,
489 OPC_GSSWXC1
= 0x6 | OPC_SDC2
,
490 OPC_GSSDXC1
= 0x7 | OPC_SDC2
,
494 #define MASK_BSHFL(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
497 OPC_WSBH
= (0x02 << 6) | OPC_BSHFL
,
498 OPC_SEB
= (0x10 << 6) | OPC_BSHFL
,
499 OPC_SEH
= (0x18 << 6) | OPC_BSHFL
,
500 OPC_ALIGN
= (0x08 << 6) | OPC_BSHFL
, /* 010.bp (010.00 to 010.11) */
501 OPC_ALIGN_1
= (0x09 << 6) | OPC_BSHFL
,
502 OPC_ALIGN_2
= (0x0A << 6) | OPC_BSHFL
,
503 OPC_ALIGN_3
= (0x0B << 6) | OPC_BSHFL
,
504 OPC_BITSWAP
= (0x00 << 6) | OPC_BSHFL
/* 00000 */
508 #define MASK_DBSHFL(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
511 OPC_DSBH
= (0x02 << 6) | OPC_DBSHFL
,
512 OPC_DSHD
= (0x05 << 6) | OPC_DBSHFL
,
513 OPC_DALIGN
= (0x08 << 6) | OPC_DBSHFL
, /* 01.bp (01.000 to 01.111) */
514 OPC_DALIGN_1
= (0x09 << 6) | OPC_DBSHFL
,
515 OPC_DALIGN_2
= (0x0A << 6) | OPC_DBSHFL
,
516 OPC_DALIGN_3
= (0x0B << 6) | OPC_DBSHFL
,
517 OPC_DALIGN_4
= (0x0C << 6) | OPC_DBSHFL
,
518 OPC_DALIGN_5
= (0x0D << 6) | OPC_DBSHFL
,
519 OPC_DALIGN_6
= (0x0E << 6) | OPC_DBSHFL
,
520 OPC_DALIGN_7
= (0x0F << 6) | OPC_DBSHFL
,
521 OPC_DBITSWAP
= (0x00 << 6) | OPC_DBSHFL
, /* 00000 */
524 /* MIPS DSP REGIMM opcodes */
526 OPC_BPOSGE32
= (0x1C << 16) | OPC_REGIMM
,
527 OPC_BPOSGE64
= (0x1D << 16) | OPC_REGIMM
,
530 #define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
533 OPC_LBUX
= (0x06 << 6) | OPC_LX_DSP
,
534 OPC_LHX
= (0x04 << 6) | OPC_LX_DSP
,
535 OPC_LWX
= (0x00 << 6) | OPC_LX_DSP
,
536 OPC_LDX
= (0x08 << 6) | OPC_LX_DSP
,
539 #define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
541 /* MIPS DSP Arithmetic Sub-class */
542 OPC_ADDQ_PH
= (0x0A << 6) | OPC_ADDU_QB_DSP
,
543 OPC_ADDQ_S_PH
= (0x0E << 6) | OPC_ADDU_QB_DSP
,
544 OPC_ADDQ_S_W
= (0x16 << 6) | OPC_ADDU_QB_DSP
,
545 OPC_ADDU_QB
= (0x00 << 6) | OPC_ADDU_QB_DSP
,
546 OPC_ADDU_S_QB
= (0x04 << 6) | OPC_ADDU_QB_DSP
,
547 OPC_ADDU_PH
= (0x08 << 6) | OPC_ADDU_QB_DSP
,
548 OPC_ADDU_S_PH
= (0x0C << 6) | OPC_ADDU_QB_DSP
,
549 OPC_SUBQ_PH
= (0x0B << 6) | OPC_ADDU_QB_DSP
,
550 OPC_SUBQ_S_PH
= (0x0F << 6) | OPC_ADDU_QB_DSP
,
551 OPC_SUBQ_S_W
= (0x17 << 6) | OPC_ADDU_QB_DSP
,
552 OPC_SUBU_QB
= (0x01 << 6) | OPC_ADDU_QB_DSP
,
553 OPC_SUBU_S_QB
= (0x05 << 6) | OPC_ADDU_QB_DSP
,
554 OPC_SUBU_PH
= (0x09 << 6) | OPC_ADDU_QB_DSP
,
555 OPC_SUBU_S_PH
= (0x0D << 6) | OPC_ADDU_QB_DSP
,
556 OPC_ADDSC
= (0x10 << 6) | OPC_ADDU_QB_DSP
,
557 OPC_ADDWC
= (0x11 << 6) | OPC_ADDU_QB_DSP
,
558 OPC_MODSUB
= (0x12 << 6) | OPC_ADDU_QB_DSP
,
559 OPC_RADDU_W_QB
= (0x14 << 6) | OPC_ADDU_QB_DSP
,
560 /* MIPS DSP Multiply Sub-class insns */
561 OPC_MULEU_S_PH_QBL
= (0x06 << 6) | OPC_ADDU_QB_DSP
,
562 OPC_MULEU_S_PH_QBR
= (0x07 << 6) | OPC_ADDU_QB_DSP
,
563 OPC_MULQ_RS_PH
= (0x1F << 6) | OPC_ADDU_QB_DSP
,
564 OPC_MULEQ_S_W_PHL
= (0x1C << 6) | OPC_ADDU_QB_DSP
,
565 OPC_MULEQ_S_W_PHR
= (0x1D << 6) | OPC_ADDU_QB_DSP
,
566 OPC_MULQ_S_PH
= (0x1E << 6) | OPC_ADDU_QB_DSP
,
569 #define OPC_ADDUH_QB_DSP OPC_MULT_G_2E
570 #define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
572 /* MIPS DSP Arithmetic Sub-class */
573 OPC_ADDUH_QB
= (0x00 << 6) | OPC_ADDUH_QB_DSP
,
574 OPC_ADDUH_R_QB
= (0x02 << 6) | OPC_ADDUH_QB_DSP
,
575 OPC_ADDQH_PH
= (0x08 << 6) | OPC_ADDUH_QB_DSP
,
576 OPC_ADDQH_R_PH
= (0x0A << 6) | OPC_ADDUH_QB_DSP
,
577 OPC_ADDQH_W
= (0x10 << 6) | OPC_ADDUH_QB_DSP
,
578 OPC_ADDQH_R_W
= (0x12 << 6) | OPC_ADDUH_QB_DSP
,
579 OPC_SUBUH_QB
= (0x01 << 6) | OPC_ADDUH_QB_DSP
,
580 OPC_SUBUH_R_QB
= (0x03 << 6) | OPC_ADDUH_QB_DSP
,
581 OPC_SUBQH_PH
= (0x09 << 6) | OPC_ADDUH_QB_DSP
,
582 OPC_SUBQH_R_PH
= (0x0B << 6) | OPC_ADDUH_QB_DSP
,
583 OPC_SUBQH_W
= (0x11 << 6) | OPC_ADDUH_QB_DSP
,
584 OPC_SUBQH_R_W
= (0x13 << 6) | OPC_ADDUH_QB_DSP
,
585 /* MIPS DSP Multiply Sub-class insns */
586 OPC_MUL_PH
= (0x0C << 6) | OPC_ADDUH_QB_DSP
,
587 OPC_MUL_S_PH
= (0x0E << 6) | OPC_ADDUH_QB_DSP
,
588 OPC_MULQ_S_W
= (0x16 << 6) | OPC_ADDUH_QB_DSP
,
589 OPC_MULQ_RS_W
= (0x17 << 6) | OPC_ADDUH_QB_DSP
,
592 #define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
594 /* MIPS DSP Arithmetic Sub-class */
595 OPC_ABSQ_S_QB
= (0x01 << 6) | OPC_ABSQ_S_PH_DSP
,
596 OPC_ABSQ_S_PH
= (0x09 << 6) | OPC_ABSQ_S_PH_DSP
,
597 OPC_ABSQ_S_W
= (0x11 << 6) | OPC_ABSQ_S_PH_DSP
,
598 OPC_PRECEQ_W_PHL
= (0x0C << 6) | OPC_ABSQ_S_PH_DSP
,
599 OPC_PRECEQ_W_PHR
= (0x0D << 6) | OPC_ABSQ_S_PH_DSP
,
600 OPC_PRECEQU_PH_QBL
= (0x04 << 6) | OPC_ABSQ_S_PH_DSP
,
601 OPC_PRECEQU_PH_QBR
= (0x05 << 6) | OPC_ABSQ_S_PH_DSP
,
602 OPC_PRECEQU_PH_QBLA
= (0x06 << 6) | OPC_ABSQ_S_PH_DSP
,
603 OPC_PRECEQU_PH_QBRA
= (0x07 << 6) | OPC_ABSQ_S_PH_DSP
,
604 OPC_PRECEU_PH_QBL
= (0x1C << 6) | OPC_ABSQ_S_PH_DSP
,
605 OPC_PRECEU_PH_QBR
= (0x1D << 6) | OPC_ABSQ_S_PH_DSP
,
606 OPC_PRECEU_PH_QBLA
= (0x1E << 6) | OPC_ABSQ_S_PH_DSP
,
607 OPC_PRECEU_PH_QBRA
= (0x1F << 6) | OPC_ABSQ_S_PH_DSP
,
608 /* DSP Bit/Manipulation Sub-class */
609 OPC_BITREV
= (0x1B << 6) | OPC_ABSQ_S_PH_DSP
,
610 OPC_REPL_QB
= (0x02 << 6) | OPC_ABSQ_S_PH_DSP
,
611 OPC_REPLV_QB
= (0x03 << 6) | OPC_ABSQ_S_PH_DSP
,
612 OPC_REPL_PH
= (0x0A << 6) | OPC_ABSQ_S_PH_DSP
,
613 OPC_REPLV_PH
= (0x0B << 6) | OPC_ABSQ_S_PH_DSP
,
616 #define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
618 /* MIPS DSP Arithmetic Sub-class */
619 OPC_PRECR_QB_PH
= (0x0D << 6) | OPC_CMPU_EQ_QB_DSP
,
620 OPC_PRECRQ_QB_PH
= (0x0C << 6) | OPC_CMPU_EQ_QB_DSP
,
621 OPC_PRECR_SRA_PH_W
= (0x1E << 6) | OPC_CMPU_EQ_QB_DSP
,
622 OPC_PRECR_SRA_R_PH_W
= (0x1F << 6) | OPC_CMPU_EQ_QB_DSP
,
623 OPC_PRECRQ_PH_W
= (0x14 << 6) | OPC_CMPU_EQ_QB_DSP
,
624 OPC_PRECRQ_RS_PH_W
= (0x15 << 6) | OPC_CMPU_EQ_QB_DSP
,
625 OPC_PRECRQU_S_QB_PH
= (0x0F << 6) | OPC_CMPU_EQ_QB_DSP
,
626 /* DSP Compare-Pick Sub-class */
627 OPC_CMPU_EQ_QB
= (0x00 << 6) | OPC_CMPU_EQ_QB_DSP
,
628 OPC_CMPU_LT_QB
= (0x01 << 6) | OPC_CMPU_EQ_QB_DSP
,
629 OPC_CMPU_LE_QB
= (0x02 << 6) | OPC_CMPU_EQ_QB_DSP
,
630 OPC_CMPGU_EQ_QB
= (0x04 << 6) | OPC_CMPU_EQ_QB_DSP
,
631 OPC_CMPGU_LT_QB
= (0x05 << 6) | OPC_CMPU_EQ_QB_DSP
,
632 OPC_CMPGU_LE_QB
= (0x06 << 6) | OPC_CMPU_EQ_QB_DSP
,
633 OPC_CMPGDU_EQ_QB
= (0x18 << 6) | OPC_CMPU_EQ_QB_DSP
,
634 OPC_CMPGDU_LT_QB
= (0x19 << 6) | OPC_CMPU_EQ_QB_DSP
,
635 OPC_CMPGDU_LE_QB
= (0x1A << 6) | OPC_CMPU_EQ_QB_DSP
,
636 OPC_CMP_EQ_PH
= (0x08 << 6) | OPC_CMPU_EQ_QB_DSP
,
637 OPC_CMP_LT_PH
= (0x09 << 6) | OPC_CMPU_EQ_QB_DSP
,
638 OPC_CMP_LE_PH
= (0x0A << 6) | OPC_CMPU_EQ_QB_DSP
,
639 OPC_PICK_QB
= (0x03 << 6) | OPC_CMPU_EQ_QB_DSP
,
640 OPC_PICK_PH
= (0x0B << 6) | OPC_CMPU_EQ_QB_DSP
,
641 OPC_PACKRL_PH
= (0x0E << 6) | OPC_CMPU_EQ_QB_DSP
,
644 #define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
646 /* MIPS DSP GPR-Based Shift Sub-class */
647 OPC_SHLL_QB
= (0x00 << 6) | OPC_SHLL_QB_DSP
,
648 OPC_SHLLV_QB
= (0x02 << 6) | OPC_SHLL_QB_DSP
,
649 OPC_SHLL_PH
= (0x08 << 6) | OPC_SHLL_QB_DSP
,
650 OPC_SHLLV_PH
= (0x0A << 6) | OPC_SHLL_QB_DSP
,
651 OPC_SHLL_S_PH
= (0x0C << 6) | OPC_SHLL_QB_DSP
,
652 OPC_SHLLV_S_PH
= (0x0E << 6) | OPC_SHLL_QB_DSP
,
653 OPC_SHLL_S_W
= (0x14 << 6) | OPC_SHLL_QB_DSP
,
654 OPC_SHLLV_S_W
= (0x16 << 6) | OPC_SHLL_QB_DSP
,
655 OPC_SHRL_QB
= (0x01 << 6) | OPC_SHLL_QB_DSP
,
656 OPC_SHRLV_QB
= (0x03 << 6) | OPC_SHLL_QB_DSP
,
657 OPC_SHRL_PH
= (0x19 << 6) | OPC_SHLL_QB_DSP
,
658 OPC_SHRLV_PH
= (0x1B << 6) | OPC_SHLL_QB_DSP
,
659 OPC_SHRA_QB
= (0x04 << 6) | OPC_SHLL_QB_DSP
,
660 OPC_SHRA_R_QB
= (0x05 << 6) | OPC_SHLL_QB_DSP
,
661 OPC_SHRAV_QB
= (0x06 << 6) | OPC_SHLL_QB_DSP
,
662 OPC_SHRAV_R_QB
= (0x07 << 6) | OPC_SHLL_QB_DSP
,
663 OPC_SHRA_PH
= (0x09 << 6) | OPC_SHLL_QB_DSP
,
664 OPC_SHRAV_PH
= (0x0B << 6) | OPC_SHLL_QB_DSP
,
665 OPC_SHRA_R_PH
= (0x0D << 6) | OPC_SHLL_QB_DSP
,
666 OPC_SHRAV_R_PH
= (0x0F << 6) | OPC_SHLL_QB_DSP
,
667 OPC_SHRA_R_W
= (0x15 << 6) | OPC_SHLL_QB_DSP
,
668 OPC_SHRAV_R_W
= (0x17 << 6) | OPC_SHLL_QB_DSP
,
671 #define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
673 /* MIPS DSP Multiply Sub-class insns */
674 OPC_DPAU_H_QBL
= (0x03 << 6) | OPC_DPA_W_PH_DSP
,
675 OPC_DPAU_H_QBR
= (0x07 << 6) | OPC_DPA_W_PH_DSP
,
676 OPC_DPSU_H_QBL
= (0x0B << 6) | OPC_DPA_W_PH_DSP
,
677 OPC_DPSU_H_QBR
= (0x0F << 6) | OPC_DPA_W_PH_DSP
,
678 OPC_DPA_W_PH
= (0x00 << 6) | OPC_DPA_W_PH_DSP
,
679 OPC_DPAX_W_PH
= (0x08 << 6) | OPC_DPA_W_PH_DSP
,
680 OPC_DPAQ_S_W_PH
= (0x04 << 6) | OPC_DPA_W_PH_DSP
,
681 OPC_DPAQX_S_W_PH
= (0x18 << 6) | OPC_DPA_W_PH_DSP
,
682 OPC_DPAQX_SA_W_PH
= (0x1A << 6) | OPC_DPA_W_PH_DSP
,
683 OPC_DPS_W_PH
= (0x01 << 6) | OPC_DPA_W_PH_DSP
,
684 OPC_DPSX_W_PH
= (0x09 << 6) | OPC_DPA_W_PH_DSP
,
685 OPC_DPSQ_S_W_PH
= (0x05 << 6) | OPC_DPA_W_PH_DSP
,
686 OPC_DPSQX_S_W_PH
= (0x19 << 6) | OPC_DPA_W_PH_DSP
,
687 OPC_DPSQX_SA_W_PH
= (0x1B << 6) | OPC_DPA_W_PH_DSP
,
688 OPC_MULSAQ_S_W_PH
= (0x06 << 6) | OPC_DPA_W_PH_DSP
,
689 OPC_DPAQ_SA_L_W
= (0x0C << 6) | OPC_DPA_W_PH_DSP
,
690 OPC_DPSQ_SA_L_W
= (0x0D << 6) | OPC_DPA_W_PH_DSP
,
691 OPC_MAQ_S_W_PHL
= (0x14 << 6) | OPC_DPA_W_PH_DSP
,
692 OPC_MAQ_S_W_PHR
= (0x16 << 6) | OPC_DPA_W_PH_DSP
,
693 OPC_MAQ_SA_W_PHL
= (0x10 << 6) | OPC_DPA_W_PH_DSP
,
694 OPC_MAQ_SA_W_PHR
= (0x12 << 6) | OPC_DPA_W_PH_DSP
,
695 OPC_MULSA_W_PH
= (0x02 << 6) | OPC_DPA_W_PH_DSP
,
698 #define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
700 /* DSP Bit/Manipulation Sub-class */
701 OPC_INSV
= (0x00 << 6) | OPC_INSV_DSP
,
704 #define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
706 /* MIPS DSP Append Sub-class */
707 OPC_APPEND
= (0x00 << 6) | OPC_APPEND_DSP
,
708 OPC_PREPEND
= (0x01 << 6) | OPC_APPEND_DSP
,
709 OPC_BALIGN
= (0x10 << 6) | OPC_APPEND_DSP
,
712 #define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
714 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
715 OPC_EXTR_W
= (0x00 << 6) | OPC_EXTR_W_DSP
,
716 OPC_EXTR_R_W
= (0x04 << 6) | OPC_EXTR_W_DSP
,
717 OPC_EXTR_RS_W
= (0x06 << 6) | OPC_EXTR_W_DSP
,
718 OPC_EXTR_S_H
= (0x0E << 6) | OPC_EXTR_W_DSP
,
719 OPC_EXTRV_S_H
= (0x0F << 6) | OPC_EXTR_W_DSP
,
720 OPC_EXTRV_W
= (0x01 << 6) | OPC_EXTR_W_DSP
,
721 OPC_EXTRV_R_W
= (0x05 << 6) | OPC_EXTR_W_DSP
,
722 OPC_EXTRV_RS_W
= (0x07 << 6) | OPC_EXTR_W_DSP
,
723 OPC_EXTP
= (0x02 << 6) | OPC_EXTR_W_DSP
,
724 OPC_EXTPV
= (0x03 << 6) | OPC_EXTR_W_DSP
,
725 OPC_EXTPDP
= (0x0A << 6) | OPC_EXTR_W_DSP
,
726 OPC_EXTPDPV
= (0x0B << 6) | OPC_EXTR_W_DSP
,
727 OPC_SHILO
= (0x1A << 6) | OPC_EXTR_W_DSP
,
728 OPC_SHILOV
= (0x1B << 6) | OPC_EXTR_W_DSP
,
729 OPC_MTHLIP
= (0x1F << 6) | OPC_EXTR_W_DSP
,
730 OPC_WRDSP
= (0x13 << 6) | OPC_EXTR_W_DSP
,
731 OPC_RDDSP
= (0x12 << 6) | OPC_EXTR_W_DSP
,
734 #define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
736 /* MIPS DSP Arithmetic Sub-class */
737 OPC_PRECEQ_L_PWL
= (0x14 << 6) | OPC_ABSQ_S_QH_DSP
,
738 OPC_PRECEQ_L_PWR
= (0x15 << 6) | OPC_ABSQ_S_QH_DSP
,
739 OPC_PRECEQ_PW_QHL
= (0x0C << 6) | OPC_ABSQ_S_QH_DSP
,
740 OPC_PRECEQ_PW_QHR
= (0x0D << 6) | OPC_ABSQ_S_QH_DSP
,
741 OPC_PRECEQ_PW_QHLA
= (0x0E << 6) | OPC_ABSQ_S_QH_DSP
,
742 OPC_PRECEQ_PW_QHRA
= (0x0F << 6) | OPC_ABSQ_S_QH_DSP
,
743 OPC_PRECEQU_QH_OBL
= (0x04 << 6) | OPC_ABSQ_S_QH_DSP
,
744 OPC_PRECEQU_QH_OBR
= (0x05 << 6) | OPC_ABSQ_S_QH_DSP
,
745 OPC_PRECEQU_QH_OBLA
= (0x06 << 6) | OPC_ABSQ_S_QH_DSP
,
746 OPC_PRECEQU_QH_OBRA
= (0x07 << 6) | OPC_ABSQ_S_QH_DSP
,
747 OPC_PRECEU_QH_OBL
= (0x1C << 6) | OPC_ABSQ_S_QH_DSP
,
748 OPC_PRECEU_QH_OBR
= (0x1D << 6) | OPC_ABSQ_S_QH_DSP
,
749 OPC_PRECEU_QH_OBLA
= (0x1E << 6) | OPC_ABSQ_S_QH_DSP
,
750 OPC_PRECEU_QH_OBRA
= (0x1F << 6) | OPC_ABSQ_S_QH_DSP
,
751 OPC_ABSQ_S_OB
= (0x01 << 6) | OPC_ABSQ_S_QH_DSP
,
752 OPC_ABSQ_S_PW
= (0x11 << 6) | OPC_ABSQ_S_QH_DSP
,
753 OPC_ABSQ_S_QH
= (0x09 << 6) | OPC_ABSQ_S_QH_DSP
,
754 /* DSP Bit/Manipulation Sub-class */
755 OPC_REPL_OB
= (0x02 << 6) | OPC_ABSQ_S_QH_DSP
,
756 OPC_REPL_PW
= (0x12 << 6) | OPC_ABSQ_S_QH_DSP
,
757 OPC_REPL_QH
= (0x0A << 6) | OPC_ABSQ_S_QH_DSP
,
758 OPC_REPLV_OB
= (0x03 << 6) | OPC_ABSQ_S_QH_DSP
,
759 OPC_REPLV_PW
= (0x13 << 6) | OPC_ABSQ_S_QH_DSP
,
760 OPC_REPLV_QH
= (0x0B << 6) | OPC_ABSQ_S_QH_DSP
,
763 #define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
765 /* MIPS DSP Multiply Sub-class insns */
766 OPC_MULEQ_S_PW_QHL
= (0x1C << 6) | OPC_ADDU_OB_DSP
,
767 OPC_MULEQ_S_PW_QHR
= (0x1D << 6) | OPC_ADDU_OB_DSP
,
768 OPC_MULEU_S_QH_OBL
= (0x06 << 6) | OPC_ADDU_OB_DSP
,
769 OPC_MULEU_S_QH_OBR
= (0x07 << 6) | OPC_ADDU_OB_DSP
,
770 OPC_MULQ_RS_QH
= (0x1F << 6) | OPC_ADDU_OB_DSP
,
771 /* MIPS DSP Arithmetic Sub-class */
772 OPC_RADDU_L_OB
= (0x14 << 6) | OPC_ADDU_OB_DSP
,
773 OPC_SUBQ_PW
= (0x13 << 6) | OPC_ADDU_OB_DSP
,
774 OPC_SUBQ_S_PW
= (0x17 << 6) | OPC_ADDU_OB_DSP
,
775 OPC_SUBQ_QH
= (0x0B << 6) | OPC_ADDU_OB_DSP
,
776 OPC_SUBQ_S_QH
= (0x0F << 6) | OPC_ADDU_OB_DSP
,
777 OPC_SUBU_OB
= (0x01 << 6) | OPC_ADDU_OB_DSP
,
778 OPC_SUBU_S_OB
= (0x05 << 6) | OPC_ADDU_OB_DSP
,
779 OPC_SUBU_QH
= (0x09 << 6) | OPC_ADDU_OB_DSP
,
780 OPC_SUBU_S_QH
= (0x0D << 6) | OPC_ADDU_OB_DSP
,
781 OPC_SUBUH_OB
= (0x19 << 6) | OPC_ADDU_OB_DSP
,
782 OPC_SUBUH_R_OB
= (0x1B << 6) | OPC_ADDU_OB_DSP
,
783 OPC_ADDQ_PW
= (0x12 << 6) | OPC_ADDU_OB_DSP
,
784 OPC_ADDQ_S_PW
= (0x16 << 6) | OPC_ADDU_OB_DSP
,
785 OPC_ADDQ_QH
= (0x0A << 6) | OPC_ADDU_OB_DSP
,
786 OPC_ADDQ_S_QH
= (0x0E << 6) | OPC_ADDU_OB_DSP
,
787 OPC_ADDU_OB
= (0x00 << 6) | OPC_ADDU_OB_DSP
,
788 OPC_ADDU_S_OB
= (0x04 << 6) | OPC_ADDU_OB_DSP
,
789 OPC_ADDU_QH
= (0x08 << 6) | OPC_ADDU_OB_DSP
,
790 OPC_ADDU_S_QH
= (0x0C << 6) | OPC_ADDU_OB_DSP
,
791 OPC_ADDUH_OB
= (0x18 << 6) | OPC_ADDU_OB_DSP
,
792 OPC_ADDUH_R_OB
= (0x1A << 6) | OPC_ADDU_OB_DSP
,
795 #define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
797 /* DSP Compare-Pick Sub-class */
798 OPC_CMP_EQ_PW
= (0x10 << 6) | OPC_CMPU_EQ_OB_DSP
,
799 OPC_CMP_LT_PW
= (0x11 << 6) | OPC_CMPU_EQ_OB_DSP
,
800 OPC_CMP_LE_PW
= (0x12 << 6) | OPC_CMPU_EQ_OB_DSP
,
801 OPC_CMP_EQ_QH
= (0x08 << 6) | OPC_CMPU_EQ_OB_DSP
,
802 OPC_CMP_LT_QH
= (0x09 << 6) | OPC_CMPU_EQ_OB_DSP
,
803 OPC_CMP_LE_QH
= (0x0A << 6) | OPC_CMPU_EQ_OB_DSP
,
804 OPC_CMPGDU_EQ_OB
= (0x18 << 6) | OPC_CMPU_EQ_OB_DSP
,
805 OPC_CMPGDU_LT_OB
= (0x19 << 6) | OPC_CMPU_EQ_OB_DSP
,
806 OPC_CMPGDU_LE_OB
= (0x1A << 6) | OPC_CMPU_EQ_OB_DSP
,
807 OPC_CMPGU_EQ_OB
= (0x04 << 6) | OPC_CMPU_EQ_OB_DSP
,
808 OPC_CMPGU_LT_OB
= (0x05 << 6) | OPC_CMPU_EQ_OB_DSP
,
809 OPC_CMPGU_LE_OB
= (0x06 << 6) | OPC_CMPU_EQ_OB_DSP
,
810 OPC_CMPU_EQ_OB
= (0x00 << 6) | OPC_CMPU_EQ_OB_DSP
,
811 OPC_CMPU_LT_OB
= (0x01 << 6) | OPC_CMPU_EQ_OB_DSP
,
812 OPC_CMPU_LE_OB
= (0x02 << 6) | OPC_CMPU_EQ_OB_DSP
,
813 OPC_PACKRL_PW
= (0x0E << 6) | OPC_CMPU_EQ_OB_DSP
,
814 OPC_PICK_OB
= (0x03 << 6) | OPC_CMPU_EQ_OB_DSP
,
815 OPC_PICK_PW
= (0x13 << 6) | OPC_CMPU_EQ_OB_DSP
,
816 OPC_PICK_QH
= (0x0B << 6) | OPC_CMPU_EQ_OB_DSP
,
817 /* MIPS DSP Arithmetic Sub-class */
818 OPC_PRECR_OB_QH
= (0x0D << 6) | OPC_CMPU_EQ_OB_DSP
,
819 OPC_PRECR_SRA_QH_PW
= (0x1E << 6) | OPC_CMPU_EQ_OB_DSP
,
820 OPC_PRECR_SRA_R_QH_PW
= (0x1F << 6) | OPC_CMPU_EQ_OB_DSP
,
821 OPC_PRECRQ_OB_QH
= (0x0C << 6) | OPC_CMPU_EQ_OB_DSP
,
822 OPC_PRECRQ_PW_L
= (0x1C << 6) | OPC_CMPU_EQ_OB_DSP
,
823 OPC_PRECRQ_QH_PW
= (0x14 << 6) | OPC_CMPU_EQ_OB_DSP
,
824 OPC_PRECRQ_RS_QH_PW
= (0x15 << 6) | OPC_CMPU_EQ_OB_DSP
,
825 OPC_PRECRQU_S_OB_QH
= (0x0F << 6) | OPC_CMPU_EQ_OB_DSP
,
828 #define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
830 /* DSP Append Sub-class */
831 OPC_DAPPEND
= (0x00 << 6) | OPC_DAPPEND_DSP
,
832 OPC_PREPENDD
= (0x03 << 6) | OPC_DAPPEND_DSP
,
833 OPC_PREPENDW
= (0x01 << 6) | OPC_DAPPEND_DSP
,
834 OPC_DBALIGN
= (0x10 << 6) | OPC_DAPPEND_DSP
,
837 #define MASK_DEXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
839 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
840 OPC_DMTHLIP
= (0x1F << 6) | OPC_DEXTR_W_DSP
,
841 OPC_DSHILO
= (0x1A << 6) | OPC_DEXTR_W_DSP
,
842 OPC_DEXTP
= (0x02 << 6) | OPC_DEXTR_W_DSP
,
843 OPC_DEXTPDP
= (0x0A << 6) | OPC_DEXTR_W_DSP
,
844 OPC_DEXTPDPV
= (0x0B << 6) | OPC_DEXTR_W_DSP
,
845 OPC_DEXTPV
= (0x03 << 6) | OPC_DEXTR_W_DSP
,
846 OPC_DEXTR_L
= (0x10 << 6) | OPC_DEXTR_W_DSP
,
847 OPC_DEXTR_R_L
= (0x14 << 6) | OPC_DEXTR_W_DSP
,
848 OPC_DEXTR_RS_L
= (0x16 << 6) | OPC_DEXTR_W_DSP
,
849 OPC_DEXTR_W
= (0x00 << 6) | OPC_DEXTR_W_DSP
,
850 OPC_DEXTR_R_W
= (0x04 << 6) | OPC_DEXTR_W_DSP
,
851 OPC_DEXTR_RS_W
= (0x06 << 6) | OPC_DEXTR_W_DSP
,
852 OPC_DEXTR_S_H
= (0x0E << 6) | OPC_DEXTR_W_DSP
,
853 OPC_DEXTRV_L
= (0x11 << 6) | OPC_DEXTR_W_DSP
,
854 OPC_DEXTRV_R_L
= (0x15 << 6) | OPC_DEXTR_W_DSP
,
855 OPC_DEXTRV_RS_L
= (0x17 << 6) | OPC_DEXTR_W_DSP
,
856 OPC_DEXTRV_S_H
= (0x0F << 6) | OPC_DEXTR_W_DSP
,
857 OPC_DEXTRV_W
= (0x01 << 6) | OPC_DEXTR_W_DSP
,
858 OPC_DEXTRV_R_W
= (0x05 << 6) | OPC_DEXTR_W_DSP
,
859 OPC_DEXTRV_RS_W
= (0x07 << 6) | OPC_DEXTR_W_DSP
,
860 OPC_DSHILOV
= (0x1B << 6) | OPC_DEXTR_W_DSP
,
863 #define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
865 /* DSP Bit/Manipulation Sub-class */
866 OPC_DINSV
= (0x00 << 6) | OPC_DINSV_DSP
,
869 #define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
871 /* MIPS DSP Multiply Sub-class insns */
872 OPC_DMADD
= (0x19 << 6) | OPC_DPAQ_W_QH_DSP
,
873 OPC_DMADDU
= (0x1D << 6) | OPC_DPAQ_W_QH_DSP
,
874 OPC_DMSUB
= (0x1B << 6) | OPC_DPAQ_W_QH_DSP
,
875 OPC_DMSUBU
= (0x1F << 6) | OPC_DPAQ_W_QH_DSP
,
876 OPC_DPA_W_QH
= (0x00 << 6) | OPC_DPAQ_W_QH_DSP
,
877 OPC_DPAQ_S_W_QH
= (0x04 << 6) | OPC_DPAQ_W_QH_DSP
,
878 OPC_DPAQ_SA_L_PW
= (0x0C << 6) | OPC_DPAQ_W_QH_DSP
,
879 OPC_DPAU_H_OBL
= (0x03 << 6) | OPC_DPAQ_W_QH_DSP
,
880 OPC_DPAU_H_OBR
= (0x07 << 6) | OPC_DPAQ_W_QH_DSP
,
881 OPC_DPS_W_QH
= (0x01 << 6) | OPC_DPAQ_W_QH_DSP
,
882 OPC_DPSQ_S_W_QH
= (0x05 << 6) | OPC_DPAQ_W_QH_DSP
,
883 OPC_DPSQ_SA_L_PW
= (0x0D << 6) | OPC_DPAQ_W_QH_DSP
,
884 OPC_DPSU_H_OBL
= (0x0B << 6) | OPC_DPAQ_W_QH_DSP
,
885 OPC_DPSU_H_OBR
= (0x0F << 6) | OPC_DPAQ_W_QH_DSP
,
886 OPC_MAQ_S_L_PWL
= (0x1C << 6) | OPC_DPAQ_W_QH_DSP
,
887 OPC_MAQ_S_L_PWR
= (0x1E << 6) | OPC_DPAQ_W_QH_DSP
,
888 OPC_MAQ_S_W_QHLL
= (0x14 << 6) | OPC_DPAQ_W_QH_DSP
,
889 OPC_MAQ_SA_W_QHLL
= (0x10 << 6) | OPC_DPAQ_W_QH_DSP
,
890 OPC_MAQ_S_W_QHLR
= (0x15 << 6) | OPC_DPAQ_W_QH_DSP
,
891 OPC_MAQ_SA_W_QHLR
= (0x11 << 6) | OPC_DPAQ_W_QH_DSP
,
892 OPC_MAQ_S_W_QHRL
= (0x16 << 6) | OPC_DPAQ_W_QH_DSP
,
893 OPC_MAQ_SA_W_QHRL
= (0x12 << 6) | OPC_DPAQ_W_QH_DSP
,
894 OPC_MAQ_S_W_QHRR
= (0x17 << 6) | OPC_DPAQ_W_QH_DSP
,
895 OPC_MAQ_SA_W_QHRR
= (0x13 << 6) | OPC_DPAQ_W_QH_DSP
,
896 OPC_MULSAQ_S_L_PW
= (0x0E << 6) | OPC_DPAQ_W_QH_DSP
,
897 OPC_MULSAQ_S_W_QH
= (0x06 << 6) | OPC_DPAQ_W_QH_DSP
,
900 #define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
902 /* MIPS DSP GPR-Based Shift Sub-class */
903 OPC_SHLL_PW
= (0x10 << 6) | OPC_SHLL_OB_DSP
,
904 OPC_SHLL_S_PW
= (0x14 << 6) | OPC_SHLL_OB_DSP
,
905 OPC_SHLLV_OB
= (0x02 << 6) | OPC_SHLL_OB_DSP
,
906 OPC_SHLLV_PW
= (0x12 << 6) | OPC_SHLL_OB_DSP
,
907 OPC_SHLLV_S_PW
= (0x16 << 6) | OPC_SHLL_OB_DSP
,
908 OPC_SHLLV_QH
= (0x0A << 6) | OPC_SHLL_OB_DSP
,
909 OPC_SHLLV_S_QH
= (0x0E << 6) | OPC_SHLL_OB_DSP
,
910 OPC_SHRA_PW
= (0x11 << 6) | OPC_SHLL_OB_DSP
,
911 OPC_SHRA_R_PW
= (0x15 << 6) | OPC_SHLL_OB_DSP
,
912 OPC_SHRAV_OB
= (0x06 << 6) | OPC_SHLL_OB_DSP
,
913 OPC_SHRAV_R_OB
= (0x07 << 6) | OPC_SHLL_OB_DSP
,
914 OPC_SHRAV_PW
= (0x13 << 6) | OPC_SHLL_OB_DSP
,
915 OPC_SHRAV_R_PW
= (0x17 << 6) | OPC_SHLL_OB_DSP
,
916 OPC_SHRAV_QH
= (0x0B << 6) | OPC_SHLL_OB_DSP
,
917 OPC_SHRAV_R_QH
= (0x0F << 6) | OPC_SHLL_OB_DSP
,
918 OPC_SHRLV_OB
= (0x03 << 6) | OPC_SHLL_OB_DSP
,
919 OPC_SHRLV_QH
= (0x1B << 6) | OPC_SHLL_OB_DSP
,
920 OPC_SHLL_OB
= (0x00 << 6) | OPC_SHLL_OB_DSP
,
921 OPC_SHLL_QH
= (0x08 << 6) | OPC_SHLL_OB_DSP
,
922 OPC_SHLL_S_QH
= (0x0C << 6) | OPC_SHLL_OB_DSP
,
923 OPC_SHRA_OB
= (0x04 << 6) | OPC_SHLL_OB_DSP
,
924 OPC_SHRA_R_OB
= (0x05 << 6) | OPC_SHLL_OB_DSP
,
925 OPC_SHRA_QH
= (0x09 << 6) | OPC_SHLL_OB_DSP
,
926 OPC_SHRA_R_QH
= (0x0D << 6) | OPC_SHLL_OB_DSP
,
927 OPC_SHRL_OB
= (0x01 << 6) | OPC_SHLL_OB_DSP
,
928 OPC_SHRL_QH
= (0x19 << 6) | OPC_SHLL_OB_DSP
,
931 /* Coprocessor 0 (rs field) */
932 #define MASK_CP0(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)))
935 OPC_MFC0
= (0x00 << 21) | OPC_CP0
,
936 OPC_DMFC0
= (0x01 << 21) | OPC_CP0
,
937 OPC_MFHC0
= (0x02 << 21) | OPC_CP0
,
938 OPC_MTC0
= (0x04 << 21) | OPC_CP0
,
939 OPC_DMTC0
= (0x05 << 21) | OPC_CP0
,
940 OPC_MTHC0
= (0x06 << 21) | OPC_CP0
,
941 OPC_MFTR
= (0x08 << 21) | OPC_CP0
,
942 OPC_RDPGPR
= (0x0A << 21) | OPC_CP0
,
943 OPC_MFMC0
= (0x0B << 21) | OPC_CP0
,
944 OPC_MTTR
= (0x0C << 21) | OPC_CP0
,
945 OPC_WRPGPR
= (0x0E << 21) | OPC_CP0
,
946 OPC_C0
= (0x10 << 21) | OPC_CP0
,
947 OPC_C0_1
= (0x11 << 21) | OPC_CP0
,
948 OPC_C0_2
= (0x12 << 21) | OPC_CP0
,
949 OPC_C0_3
= (0x13 << 21) | OPC_CP0
,
950 OPC_C0_4
= (0x14 << 21) | OPC_CP0
,
951 OPC_C0_5
= (0x15 << 21) | OPC_CP0
,
952 OPC_C0_6
= (0x16 << 21) | OPC_CP0
,
953 OPC_C0_7
= (0x17 << 21) | OPC_CP0
,
954 OPC_C0_8
= (0x18 << 21) | OPC_CP0
,
955 OPC_C0_9
= (0x19 << 21) | OPC_CP0
,
956 OPC_C0_A
= (0x1A << 21) | OPC_CP0
,
957 OPC_C0_B
= (0x1B << 21) | OPC_CP0
,
958 OPC_C0_C
= (0x1C << 21) | OPC_CP0
,
959 OPC_C0_D
= (0x1D << 21) | OPC_CP0
,
960 OPC_C0_E
= (0x1E << 21) | OPC_CP0
,
961 OPC_C0_F
= (0x1F << 21) | OPC_CP0
,
965 #define MASK_MFMC0(op) (MASK_CP0(op) | (op & 0xFFFF))
968 OPC_DMT
= 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0
,
969 OPC_EMT
= 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0
,
970 OPC_DVPE
= 0x01 | (0 << 5) | OPC_MFMC0
,
971 OPC_EVPE
= 0x01 | (1 << 5) | OPC_MFMC0
,
972 OPC_DI
= (0 << 5) | (0x0C << 11) | OPC_MFMC0
,
973 OPC_EI
= (1 << 5) | (0x0C << 11) | OPC_MFMC0
,
974 OPC_DVP
= 0x04 | (0 << 3) | (1 << 5) | (0 << 11) | OPC_MFMC0
,
975 OPC_EVP
= 0x04 | (0 << 3) | (0 << 5) | (0 << 11) | OPC_MFMC0
,
978 /* Coprocessor 0 (with rs == C0) */
979 #define MASK_C0(op) (MASK_CP0(op) | (op & 0x3F))
982 OPC_TLBR
= 0x01 | OPC_C0
,
983 OPC_TLBWI
= 0x02 | OPC_C0
,
984 OPC_TLBINV
= 0x03 | OPC_C0
,
985 OPC_TLBINVF
= 0x04 | OPC_C0
,
986 OPC_TLBWR
= 0x06 | OPC_C0
,
987 OPC_TLBP
= 0x08 | OPC_C0
,
988 OPC_RFE
= 0x10 | OPC_C0
,
989 OPC_ERET
= 0x18 | OPC_C0
,
990 OPC_DERET
= 0x1F | OPC_C0
,
991 OPC_WAIT
= 0x20 | OPC_C0
,
994 #define MASK_CP2(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)))
997 OPC_MFC2
= (0x00 << 21) | OPC_CP2
,
998 OPC_DMFC2
= (0x01 << 21) | OPC_CP2
,
999 OPC_CFC2
= (0x02 << 21) | OPC_CP2
,
1000 OPC_MFHC2
= (0x03 << 21) | OPC_CP2
,
1001 OPC_MTC2
= (0x04 << 21) | OPC_CP2
,
1002 OPC_DMTC2
= (0x05 << 21) | OPC_CP2
,
1003 OPC_CTC2
= (0x06 << 21) | OPC_CP2
,
1004 OPC_MTHC2
= (0x07 << 21) | OPC_CP2
,
1005 OPC_BC2
= (0x08 << 21) | OPC_CP2
,
1006 OPC_BC2EQZ
= (0x09 << 21) | OPC_CP2
,
1007 OPC_BC2NEZ
= (0x0D << 21) | OPC_CP2
,
1010 #define MASK_LMMI(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
1013 OPC_PADDSH
= (24 << 21) | (0x00) | OPC_CP2
,
1014 OPC_PADDUSH
= (25 << 21) | (0x00) | OPC_CP2
,
1015 OPC_PADDH
= (26 << 21) | (0x00) | OPC_CP2
,
1016 OPC_PADDW
= (27 << 21) | (0x00) | OPC_CP2
,
1017 OPC_PADDSB
= (28 << 21) | (0x00) | OPC_CP2
,
1018 OPC_PADDUSB
= (29 << 21) | (0x00) | OPC_CP2
,
1019 OPC_PADDB
= (30 << 21) | (0x00) | OPC_CP2
,
1020 OPC_PADDD
= (31 << 21) | (0x00) | OPC_CP2
,
1022 OPC_PSUBSH
= (24 << 21) | (0x01) | OPC_CP2
,
1023 OPC_PSUBUSH
= (25 << 21) | (0x01) | OPC_CP2
,
1024 OPC_PSUBH
= (26 << 21) | (0x01) | OPC_CP2
,
1025 OPC_PSUBW
= (27 << 21) | (0x01) | OPC_CP2
,
1026 OPC_PSUBSB
= (28 << 21) | (0x01) | OPC_CP2
,
1027 OPC_PSUBUSB
= (29 << 21) | (0x01) | OPC_CP2
,
1028 OPC_PSUBB
= (30 << 21) | (0x01) | OPC_CP2
,
1029 OPC_PSUBD
= (31 << 21) | (0x01) | OPC_CP2
,
1031 OPC_PSHUFH
= (24 << 21) | (0x02) | OPC_CP2
,
1032 OPC_PACKSSWH
= (25 << 21) | (0x02) | OPC_CP2
,
1033 OPC_PACKSSHB
= (26 << 21) | (0x02) | OPC_CP2
,
1034 OPC_PACKUSHB
= (27 << 21) | (0x02) | OPC_CP2
,
1035 OPC_XOR_CP2
= (28 << 21) | (0x02) | OPC_CP2
,
1036 OPC_NOR_CP2
= (29 << 21) | (0x02) | OPC_CP2
,
1037 OPC_AND_CP2
= (30 << 21) | (0x02) | OPC_CP2
,
1038 OPC_PANDN
= (31 << 21) | (0x02) | OPC_CP2
,
1040 OPC_PUNPCKLHW
= (24 << 21) | (0x03) | OPC_CP2
,
1041 OPC_PUNPCKHHW
= (25 << 21) | (0x03) | OPC_CP2
,
1042 OPC_PUNPCKLBH
= (26 << 21) | (0x03) | OPC_CP2
,
1043 OPC_PUNPCKHBH
= (27 << 21) | (0x03) | OPC_CP2
,
1044 OPC_PINSRH_0
= (28 << 21) | (0x03) | OPC_CP2
,
1045 OPC_PINSRH_1
= (29 << 21) | (0x03) | OPC_CP2
,
1046 OPC_PINSRH_2
= (30 << 21) | (0x03) | OPC_CP2
,
1047 OPC_PINSRH_3
= (31 << 21) | (0x03) | OPC_CP2
,
1049 OPC_PAVGH
= (24 << 21) | (0x08) | OPC_CP2
,
1050 OPC_PAVGB
= (25 << 21) | (0x08) | OPC_CP2
,
1051 OPC_PMAXSH
= (26 << 21) | (0x08) | OPC_CP2
,
1052 OPC_PMINSH
= (27 << 21) | (0x08) | OPC_CP2
,
1053 OPC_PMAXUB
= (28 << 21) | (0x08) | OPC_CP2
,
1054 OPC_PMINUB
= (29 << 21) | (0x08) | OPC_CP2
,
1056 OPC_PCMPEQW
= (24 << 21) | (0x09) | OPC_CP2
,
1057 OPC_PCMPGTW
= (25 << 21) | (0x09) | OPC_CP2
,
1058 OPC_PCMPEQH
= (26 << 21) | (0x09) | OPC_CP2
,
1059 OPC_PCMPGTH
= (27 << 21) | (0x09) | OPC_CP2
,
1060 OPC_PCMPEQB
= (28 << 21) | (0x09) | OPC_CP2
,
1061 OPC_PCMPGTB
= (29 << 21) | (0x09) | OPC_CP2
,
1063 OPC_PSLLW
= (24 << 21) | (0x0A) | OPC_CP2
,
1064 OPC_PSLLH
= (25 << 21) | (0x0A) | OPC_CP2
,
1065 OPC_PMULLH
= (26 << 21) | (0x0A) | OPC_CP2
,
1066 OPC_PMULHH
= (27 << 21) | (0x0A) | OPC_CP2
,
1067 OPC_PMULUW
= (28 << 21) | (0x0A) | OPC_CP2
,
1068 OPC_PMULHUH
= (29 << 21) | (0x0A) | OPC_CP2
,
1070 OPC_PSRLW
= (24 << 21) | (0x0B) | OPC_CP2
,
1071 OPC_PSRLH
= (25 << 21) | (0x0B) | OPC_CP2
,
1072 OPC_PSRAW
= (26 << 21) | (0x0B) | OPC_CP2
,
1073 OPC_PSRAH
= (27 << 21) | (0x0B) | OPC_CP2
,
1074 OPC_PUNPCKLWD
= (28 << 21) | (0x0B) | OPC_CP2
,
1075 OPC_PUNPCKHWD
= (29 << 21) | (0x0B) | OPC_CP2
,
1077 OPC_ADDU_CP2
= (24 << 21) | (0x0C) | OPC_CP2
,
1078 OPC_OR_CP2
= (25 << 21) | (0x0C) | OPC_CP2
,
1079 OPC_ADD_CP2
= (26 << 21) | (0x0C) | OPC_CP2
,
1080 OPC_DADD_CP2
= (27 << 21) | (0x0C) | OPC_CP2
,
1081 OPC_SEQU_CP2
= (28 << 21) | (0x0C) | OPC_CP2
,
1082 OPC_SEQ_CP2
= (29 << 21) | (0x0C) | OPC_CP2
,
1084 OPC_SUBU_CP2
= (24 << 21) | (0x0D) | OPC_CP2
,
1085 OPC_PASUBUB
= (25 << 21) | (0x0D) | OPC_CP2
,
1086 OPC_SUB_CP2
= (26 << 21) | (0x0D) | OPC_CP2
,
1087 OPC_DSUB_CP2
= (27 << 21) | (0x0D) | OPC_CP2
,
1088 OPC_SLTU_CP2
= (28 << 21) | (0x0D) | OPC_CP2
,
1089 OPC_SLT_CP2
= (29 << 21) | (0x0D) | OPC_CP2
,
1091 OPC_SLL_CP2
= (24 << 21) | (0x0E) | OPC_CP2
,
1092 OPC_DSLL_CP2
= (25 << 21) | (0x0E) | OPC_CP2
,
1093 OPC_PEXTRH
= (26 << 21) | (0x0E) | OPC_CP2
,
1094 OPC_PMADDHW
= (27 << 21) | (0x0E) | OPC_CP2
,
1095 OPC_SLEU_CP2
= (28 << 21) | (0x0E) | OPC_CP2
,
1096 OPC_SLE_CP2
= (29 << 21) | (0x0E) | OPC_CP2
,
1098 OPC_SRL_CP2
= (24 << 21) | (0x0F) | OPC_CP2
,
1099 OPC_DSRL_CP2
= (25 << 21) | (0x0F) | OPC_CP2
,
1100 OPC_SRA_CP2
= (26 << 21) | (0x0F) | OPC_CP2
,
1101 OPC_DSRA_CP2
= (27 << 21) | (0x0F) | OPC_CP2
,
1102 OPC_BIADD
= (28 << 21) | (0x0F) | OPC_CP2
,
1103 OPC_PMOVMSKB
= (29 << 21) | (0x0F) | OPC_CP2
,
1107 #define MASK_CP3(op) (MASK_OP_MAJOR(op) | (op & 0x3F))
1110 OPC_LWXC1
= 0x00 | OPC_CP3
,
1111 OPC_LDXC1
= 0x01 | OPC_CP3
,
1112 OPC_LUXC1
= 0x05 | OPC_CP3
,
1113 OPC_SWXC1
= 0x08 | OPC_CP3
,
1114 OPC_SDXC1
= 0x09 | OPC_CP3
,
1115 OPC_SUXC1
= 0x0D | OPC_CP3
,
1116 OPC_PREFX
= 0x0F | OPC_CP3
,
1117 OPC_ALNV_PS
= 0x1E | OPC_CP3
,
1118 OPC_MADD_S
= 0x20 | OPC_CP3
,
1119 OPC_MADD_D
= 0x21 | OPC_CP3
,
1120 OPC_MADD_PS
= 0x26 | OPC_CP3
,
1121 OPC_MSUB_S
= 0x28 | OPC_CP3
,
1122 OPC_MSUB_D
= 0x29 | OPC_CP3
,
1123 OPC_MSUB_PS
= 0x2E | OPC_CP3
,
1124 OPC_NMADD_S
= 0x30 | OPC_CP3
,
1125 OPC_NMADD_D
= 0x31 | OPC_CP3
,
1126 OPC_NMADD_PS
= 0x36 | OPC_CP3
,
1127 OPC_NMSUB_S
= 0x38 | OPC_CP3
,
1128 OPC_NMSUB_D
= 0x39 | OPC_CP3
,
1129 OPC_NMSUB_PS
= 0x3E | OPC_CP3
,
1134 * AN OVERVIEW OF MXU EXTENSION INSTRUCTION SET
1135 * ============================================
1138 * MXU (full name: MIPS eXtension/enhanced Unit) is a SIMD extension of MIPS32
1139 * instructions set. It is designed to fit the needs of signal, graphical and
1140 * video processing applications. MXU instruction set is used in Xburst family
1141 * of microprocessors by Ingenic.
1143 * MXU unit contains 17 registers called X0-X16. X0 is always zero, and X16 is
1144 * the control register.
1147 * The notation used in MXU assembler mnemonics
1148 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1150 * Register operands:
1152 * XRa, XRb, XRc, XRd - MXU registers
1153 * Rb, Rc, Rd, Rs, Rt - general purpose MIPS registers
1155 * Non-register operands:
1157 * aptn1 - 1-bit accumulate add/subtract pattern
1158 * aptn2 - 2-bit accumulate add/subtract pattern
1159 * eptn2 - 2-bit execute add/subtract pattern
1160 * optn2 - 2-bit operand pattern
1161 * optn3 - 3-bit operand pattern
1162 * sft4 - 4-bit shift amount
1163 * strd2 - 2-bit stride amount
1167 * Level of parallelism: Operand size:
1168 * S - single operation at a time 32 - word
1169 * D - two operations in parallel 16 - half word
1170 * Q - four operations in parallel 8 - byte
1174 * ADD - Add or subtract
1175 * ADDC - Add with carry-in
1177 * ASUM - Sum together then accumulate (add or subtract)
1178 * ASUMC - Sum together then accumulate (add or subtract) with carry-in
1179 * AVG - Average between 2 operands
1180 * ABD - Absolute difference
1182 * AND - Logical bitwise 'and' operation
1184 * EXTR - Extract bits
1185 * I2M - Move from GPR register to MXU register
1186 * LDD - Load data from memory to XRF
1187 * LDI - Load data from memory to XRF (and increase the address base)
1188 * LUI - Load unsigned immediate
1190 * MULU - Unsigned multiply
1191 * MADD - 64-bit operand add 32x32 product
1192 * MSUB - 64-bit operand subtract 32x32 product
1193 * MAC - Multiply and accumulate (add or subtract)
1194 * MAD - Multiply and add or subtract
1195 * MAX - Maximum between 2 operands
1196 * MIN - Minimum between 2 operands
1197 * M2I - Move from MXU register to GPR register
1198 * MOVZ - Move if zero
1199 * MOVN - Move if non-zero
1200 * NOR - Logical bitwise 'nor' operation
1201 * OR - Logical bitwise 'or' operation
1202 * STD - Store data from XRF to memory
1203 * SDI - Store data from XRF to memory (and increase the address base)
1204 * SLT - Set of less than comparison
1205 * SAD - Sum of absolute differences
1206 * SLL - Logical shift left
1207 * SLR - Logical shift right
1208 * SAR - Arithmetic shift right
1211 * SCOP - Calculate x’s scope (-1, means x<0; 0, means x==0; 1, means x>0)
1212 * XOR - Logical bitwise 'exclusive or' operation
1216 * E - Expand results
1217 * F - Fixed point multiplication
1218 * L - Low part result
1219 * R - Doing rounding
1220 * V - Variable instead of immediate
1221 * W - Combine above L and V
1224 * The list of MXU instructions grouped by functionality
1225 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1227 * Load/Store instructions Multiplication instructions
1228 * ----------------------- ---------------------------
1230 * S32LDD XRa, Rb, s12 S32MADD XRa, XRd, Rs, Rt
1231 * S32STD XRa, Rb, s12 S32MADDU XRa, XRd, Rs, Rt
1232 * S32LDDV XRa, Rb, rc, strd2 S32MSUB XRa, XRd, Rs, Rt
1233 * S32STDV XRa, Rb, rc, strd2 S32MSUBU XRa, XRd, Rs, Rt
1234 * S32LDI XRa, Rb, s12 S32MUL XRa, XRd, Rs, Rt
1235 * S32SDI XRa, Rb, s12 S32MULU XRa, XRd, Rs, Rt
1236 * S32LDIV XRa, Rb, rc, strd2 D16MUL XRa, XRb, XRc, XRd, optn2
1237 * S32SDIV XRa, Rb, rc, strd2 D16MULE XRa, XRb, XRc, optn2
1238 * S32LDDR XRa, Rb, s12 D16MULF XRa, XRb, XRc, optn2
1239 * S32STDR XRa, Rb, s12 D16MAC XRa, XRb, XRc, XRd, aptn2, optn2
1240 * S32LDDVR XRa, Rb, rc, strd2 D16MACE XRa, XRb, XRc, XRd, aptn2, optn2
1241 * S32STDVR XRa, Rb, rc, strd2 D16MACF XRa, XRb, XRc, XRd, aptn2, optn2
1242 * S32LDIR XRa, Rb, s12 D16MADL XRa, XRb, XRc, XRd, aptn2, optn2
1243 * S32SDIR XRa, Rb, s12 S16MAD XRa, XRb, XRc, XRd, aptn1, optn2
1244 * S32LDIVR XRa, Rb, rc, strd2 Q8MUL XRa, XRb, XRc, XRd
1245 * S32SDIVR XRa, Rb, rc, strd2 Q8MULSU XRa, XRb, XRc, XRd
1246 * S16LDD XRa, Rb, s10, eptn2 Q8MAC XRa, XRb, XRc, XRd, aptn2
1247 * S16STD XRa, Rb, s10, eptn2 Q8MACSU XRa, XRb, XRc, XRd, aptn2
1248 * S16LDI XRa, Rb, s10, eptn2 Q8MADL XRa, XRb, XRc, XRd, aptn2
1249 * S16SDI XRa, Rb, s10, eptn2
1250 * S8LDD XRa, Rb, s8, eptn3
1251 * S8STD XRa, Rb, s8, eptn3 Addition and subtraction instructions
1252 * S8LDI XRa, Rb, s8, eptn3 -------------------------------------
1253 * S8SDI XRa, Rb, s8, eptn3
1254 * LXW Rd, Rs, Rt, strd2 D32ADD XRa, XRb, XRc, XRd, eptn2
1255 * LXH Rd, Rs, Rt, strd2 D32ADDC XRa, XRb, XRc, XRd
1256 * LXHU Rd, Rs, Rt, strd2 D32ACC XRa, XRb, XRc, XRd, eptn2
1257 * LXB Rd, Rs, Rt, strd2 D32ACCM XRa, XRb, XRc, XRd, eptn2
1258 * LXBU Rd, Rs, Rt, strd2 D32ASUM XRa, XRb, XRc, XRd, eptn2
1259 * S32CPS XRa, XRb, XRc
1260 * Q16ADD XRa, XRb, XRc, XRd, eptn2, optn2
1261 * Comparison instructions Q16ACC XRa, XRb, XRc, XRd, eptn2
1262 * ----------------------- Q16ACCM XRa, XRb, XRc, XRd, eptn2
1263 * D16ASUM XRa, XRb, XRc, XRd, eptn2
1264 * S32MAX XRa, XRb, XRc D16CPS XRa, XRb,
1265 * S32MIN XRa, XRb, XRc D16AVG XRa, XRb, XRc
1266 * S32SLT XRa, XRb, XRc D16AVGR XRa, XRb, XRc
1267 * S32MOVZ XRa, XRb, XRc Q8ADD XRa, XRb, XRc, eptn2
1268 * S32MOVN XRa, XRb, XRc Q8ADDE XRa, XRb, XRc, XRd, eptn2
1269 * D16MAX XRa, XRb, XRc Q8ACCE XRa, XRb, XRc, XRd, eptn2
1270 * D16MIN XRa, XRb, XRc Q8ABD XRa, XRb, XRc
1271 * D16SLT XRa, XRb, XRc Q8SAD XRa, XRb, XRc, XRd
1272 * D16MOVZ XRa, XRb, XRc Q8AVG XRa, XRb, XRc
1273 * D16MOVN XRa, XRb, XRc Q8AVGR XRa, XRb, XRc
1274 * Q8MAX XRa, XRb, XRc D8SUM XRa, XRb, XRc, XRd
1275 * Q8MIN XRa, XRb, XRc D8SUMC XRa, XRb, XRc, XRd
1276 * Q8SLT XRa, XRb, XRc
1277 * Q8SLTU XRa, XRb, XRc
1278 * Q8MOVZ XRa, XRb, XRc Shift instructions
1279 * Q8MOVN XRa, XRb, XRc ------------------
1281 * D32SLL XRa, XRb, XRc, XRd, sft4
1282 * Bitwise instructions D32SLR XRa, XRb, XRc, XRd, sft4
1283 * -------------------- D32SAR XRa, XRb, XRc, XRd, sft4
1284 * D32SARL XRa, XRb, XRc, sft4
1285 * S32NOR XRa, XRb, XRc D32SLLV XRa, XRb, Rb
1286 * S32AND XRa, XRb, XRc D32SLRV XRa, XRb, Rb
1287 * S32XOR XRa, XRb, XRc D32SARV XRa, XRb, Rb
1288 * S32OR XRa, XRb, XRc D32SARW XRa, XRb, XRc, Rb
1289 * Q16SLL XRa, XRb, XRc, XRd, sft4
1290 * Q16SLR XRa, XRb, XRc, XRd, sft4
1291 * Miscellaneous instructions Q16SAR XRa, XRb, XRc, XRd, sft4
1292 * ------------------------- Q16SLLV XRa, XRb, Rb
1293 * Q16SLRV XRa, XRb, Rb
1294 * S32SFL XRa, XRb, XRc, XRd, optn2 Q16SARV XRa, XRb, Rb
1295 * S32ALN XRa, XRb, XRc, Rb
1296 * S32ALNI XRa, XRb, XRc, s3
1297 * S32LUI XRa, s8, optn3 Move instructions
1298 * S32EXTR XRa, XRb, Rb, bits5 -----------------
1299 * S32EXTRV XRa, XRb, Rs, Rt
1300 * Q16SCOP XRa, XRb, XRc, XRd S32M2I XRa, Rb
1301 * Q16SAT XRa, XRb, XRc S32I2M XRa, Rb
1304 * The opcode organization of MXU instructions
1305 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1307 * The bits 31..26 of all MXU instructions are equal to 0x1C (also referred
1308 * as opcode SPECIAL2 in the base MIPS ISA). The organization and meaning of
1309 * other bits up to the instruction level is as follows:
1314 * ┌─ 000000 ─ OPC_MXU_S32MADD
1315 * ├─ 000001 ─ OPC_MXU_S32MADDU
1316 * ├─ 000010 ─ <not assigned> (non-MXU OPC_MUL)
1319 * ├─ 000011 ─ OPC_MXU__POOL00 ─┬─ 000 ─ OPC_MXU_S32MAX
1320 * │ ├─ 001 ─ OPC_MXU_S32MIN
1321 * │ ├─ 010 ─ OPC_MXU_D16MAX
1322 * │ ├─ 011 ─ OPC_MXU_D16MIN
1323 * │ ├─ 100 ─ OPC_MXU_Q8MAX
1324 * │ ├─ 101 ─ OPC_MXU_Q8MIN
1325 * │ ├─ 110 ─ OPC_MXU_Q8SLT
1326 * │ └─ 111 ─ OPC_MXU_Q8SLTU
1327 * ├─ 000100 ─ OPC_MXU_S32MSUB
1328 * ├─ 000101 ─ OPC_MXU_S32MSUBU 20..18
1329 * ├─ 000110 ─ OPC_MXU__POOL01 ─┬─ 000 ─ OPC_MXU_S32SLT
1330 * │ ├─ 001 ─ OPC_MXU_D16SLT
1331 * │ ├─ 010 ─ OPC_MXU_D16AVG
1332 * │ ├─ 011 ─ OPC_MXU_D16AVGR
1333 * │ ├─ 100 ─ OPC_MXU_Q8AVG
1334 * │ ├─ 101 ─ OPC_MXU_Q8AVGR
1335 * │ └─ 111 ─ OPC_MXU_Q8ADD
1338 * ├─ 000111 ─ OPC_MXU__POOL02 ─┬─ 000 ─ OPC_MXU_S32CPS
1339 * │ ├─ 010 ─ OPC_MXU_D16CPS
1340 * │ ├─ 100 ─ OPC_MXU_Q8ABD
1341 * │ └─ 110 ─ OPC_MXU_Q16SAT
1342 * ├─ 001000 ─ OPC_MXU_D16MUL
1344 * ├─ 001001 ─ OPC_MXU__POOL03 ─┬─ 00 ─ OPC_MXU_D16MULF
1345 * │ └─ 01 ─ OPC_MXU_D16MULE
1346 * ├─ 001010 ─ OPC_MXU_D16MAC
1347 * ├─ 001011 ─ OPC_MXU_D16MACF
1348 * ├─ 001100 ─ OPC_MXU_D16MADL
1349 * ├─ 001101 ─ OPC_MXU_S16MAD
1350 * ├─ 001110 ─ OPC_MXU_Q16ADD
1351 * ├─ 001111 ─ OPC_MXU_D16MACE 23
1352 * │ ┌─ 0 ─ OPC_MXU_S32LDD
1353 * ├─ 010000 ─ OPC_MXU__POOL04 ─┴─ 1 ─ OPC_MXU_S32LDDR
1356 * ├─ 010001 ─ OPC_MXU__POOL05 ─┬─ 0 ─ OPC_MXU_S32STD
1357 * │ └─ 1 ─ OPC_MXU_S32STDR
1360 * ├─ 010010 ─ OPC_MXU__POOL06 ─┬─ 0000 ─ OPC_MXU_S32LDDV
1361 * │ └─ 0001 ─ OPC_MXU_S32LDDVR
1364 * ├─ 010011 ─ OPC_MXU__POOL07 ─┬─ 0000 ─ OPC_MXU_S32STDV
1365 * │ └─ 0001 ─ OPC_MXU_S32STDVR
1368 * ├─ 010100 ─ OPC_MXU__POOL08 ─┬─ 0 ─ OPC_MXU_S32LDI
1369 * │ └─ 1 ─ OPC_MXU_S32LDIR
1372 * ├─ 010101 ─ OPC_MXU__POOL09 ─┬─ 0 ─ OPC_MXU_S32SDI
1373 * │ └─ 1 ─ OPC_MXU_S32SDIR
1376 * ├─ 010110 ─ OPC_MXU__POOL10 ─┬─ 0000 ─ OPC_MXU_S32LDIV
1377 * │ └─ 0001 ─ OPC_MXU_S32LDIVR
1380 * ├─ 010111 ─ OPC_MXU__POOL11 ─┬─ 0000 ─ OPC_MXU_S32SDIV
1381 * │ └─ 0001 ─ OPC_MXU_S32SDIVR
1382 * ├─ 011000 ─ OPC_MXU_D32ADD
1384 * MXU ├─ 011001 ─ OPC_MXU__POOL12 ─┬─ 00 ─ OPC_MXU_D32ACC
1385 * opcodes ─┤ ├─ 01 ─ OPC_MXU_D32ACCM
1386 * │ └─ 10 ─ OPC_MXU_D32ASUM
1387 * ├─ 011010 ─ <not assigned>
1389 * ├─ 011011 ─ OPC_MXU__POOL13 ─┬─ 00 ─ OPC_MXU_Q16ACC
1390 * │ ├─ 01 ─ OPC_MXU_Q16ACCM
1391 * │ └─ 10 ─ OPC_MXU_Q16ASUM
1394 * ├─ 011100 ─ OPC_MXU__POOL14 ─┬─ 00 ─ OPC_MXU_Q8ADDE
1395 * │ ├─ 01 ─ OPC_MXU_D8SUM
1396 * ├─ 011101 ─ OPC_MXU_Q8ACCE └─ 10 ─ OPC_MXU_D8SUMC
1397 * ├─ 011110 ─ <not assigned>
1398 * ├─ 011111 ─ <not assigned>
1399 * ├─ 100000 ─ <not assigned> (overlaps with CLZ)
1400 * ├─ 100001 ─ <not assigned> (overlaps with CLO)
1401 * ├─ 100010 ─ OPC_MXU_S8LDD
1402 * ├─ 100011 ─ OPC_MXU_S8STD 15..14
1403 * ├─ 100100 ─ OPC_MXU_S8LDI ┌─ 00 ─ OPC_MXU_S32MUL
1404 * ├─ 100101 ─ OPC_MXU_S8SDI ├─ 00 ─ OPC_MXU_S32MULU
1405 * │ ├─ 00 ─ OPC_MXU_S32EXTR
1406 * ├─ 100110 ─ OPC_MXU__POOL15 ─┴─ 00 ─ OPC_MXU_S32EXTRV
1409 * ├─ 100111 ─ OPC_MXU__POOL16 ─┬─ 000 ─ OPC_MXU_D32SARW
1410 * │ ├─ 001 ─ OPC_MXU_S32ALN
1411 * │ ├─ 010 ─ OPC_MXU_S32ALNI
1412 * │ ├─ 011 ─ OPC_MXU_S32LUI
1413 * │ ├─ 100 ─ OPC_MXU_S32NOR
1414 * │ ├─ 101 ─ OPC_MXU_S32AND
1415 * │ ├─ 110 ─ OPC_MXU_S32OR
1416 * │ └─ 111 ─ OPC_MXU_S32XOR
1419 * ├─ 101000 ─ OPC_MXU__POOL17 ─┬─ 000 ─ OPC_MXU_LXB
1420 * │ ├─ 001 ─ OPC_MXU_LXH
1421 * ├─ 101001 ─ <not assigned> ├─ 011 ─ OPC_MXU_LXW
1422 * ├─ 101010 ─ OPC_MXU_S16LDD ├─ 100 ─ OPC_MXU_LXBU
1423 * ├─ 101011 ─ OPC_MXU_S16STD └─ 101 ─ OPC_MXU_LXHU
1424 * ├─ 101100 ─ OPC_MXU_S16LDI
1425 * ├─ 101101 ─ OPC_MXU_S16SDI
1426 * ├─ 101110 ─ OPC_MXU_S32M2I
1427 * ├─ 101111 ─ OPC_MXU_S32I2M
1428 * ├─ 110000 ─ OPC_MXU_D32SLL
1429 * ├─ 110001 ─ OPC_MXU_D32SLR 20..18
1430 * ├─ 110010 ─ OPC_MXU_D32SARL ┌─ 000 ─ OPC_MXU_D32SLLV
1431 * ├─ 110011 ─ OPC_MXU_D32SAR ├─ 001 ─ OPC_MXU_D32SLRV
1432 * ├─ 110100 ─ OPC_MXU_Q16SLL ├─ 010 ─ OPC_MXU_D32SARV
1433 * ├─ 110101 ─ OPC_MXU_Q16SLR ├─ 011 ─ OPC_MXU_Q16SLLV
1434 * │ ├─ 100 ─ OPC_MXU_Q16SLRV
1435 * ├─ 110110 ─ OPC_MXU__POOL18 ─┴─ 101 ─ OPC_MXU_Q16SARV
1437 * ├─ 110111 ─ OPC_MXU_Q16SAR
1439 * ├─ 111000 ─ OPC_MXU__POOL19 ─┬─ 00 ─ OPC_MXU_Q8MUL
1440 * │ └─ 01 ─ OPC_MXU_Q8MULSU
1443 * ├─ 111001 ─ OPC_MXU__POOL20 ─┬─ 000 ─ OPC_MXU_Q8MOVZ
1444 * │ ├─ 001 ─ OPC_MXU_Q8MOVN
1445 * │ ├─ 010 ─ OPC_MXU_D16MOVZ
1446 * │ ├─ 011 ─ OPC_MXU_D16MOVN
1447 * │ ├─ 100 ─ OPC_MXU_S32MOVZ
1448 * │ └─ 101 ─ OPC_MXU_S32MOVN
1451 * ├─ 111010 ─ OPC_MXU__POOL21 ─┬─ 00 ─ OPC_MXU_Q8MAC
1452 * │ └─ 10 ─ OPC_MXU_Q8MACSU
1453 * ├─ 111011 ─ OPC_MXU_Q16SCOP
1454 * ├─ 111100 ─ OPC_MXU_Q8MADL
1455 * ├─ 111101 ─ OPC_MXU_S32SFL
1456 * ├─ 111110 ─ OPC_MXU_Q8SAD
1457 * └─ 111111 ─ <not assigned> (overlaps with SDBBP)
1462 * "XBurst® Instruction Set Architecture MIPS eXtension/enhanced Unit
1463 * Programming Manual", Ingenic Semiconductor Co, Ltd., revision June 2, 2017
1467 OPC_MXU_S32MADD
= 0x00,
1468 OPC_MXU_S32MADDU
= 0x01,
1469 OPC__MXU_MUL
= 0x02,
1470 OPC_MXU__POOL00
= 0x03,
1471 OPC_MXU_S32MSUB
= 0x04,
1472 OPC_MXU_S32MSUBU
= 0x05,
1473 OPC_MXU__POOL01
= 0x06,
1474 OPC_MXU__POOL02
= 0x07,
1475 OPC_MXU_D16MUL
= 0x08,
1476 OPC_MXU__POOL03
= 0x09,
1477 OPC_MXU_D16MAC
= 0x0A,
1478 OPC_MXU_D16MACF
= 0x0B,
1479 OPC_MXU_D16MADL
= 0x0C,
1480 OPC_MXU_S16MAD
= 0x0D,
1481 OPC_MXU_Q16ADD
= 0x0E,
1482 OPC_MXU_D16MACE
= 0x0F,
1483 OPC_MXU__POOL04
= 0x10,
1484 OPC_MXU__POOL05
= 0x11,
1485 OPC_MXU__POOL06
= 0x12,
1486 OPC_MXU__POOL07
= 0x13,
1487 OPC_MXU__POOL08
= 0x14,
1488 OPC_MXU__POOL09
= 0x15,
1489 OPC_MXU__POOL10
= 0x16,
1490 OPC_MXU__POOL11
= 0x17,
1491 OPC_MXU_D32ADD
= 0x18,
1492 OPC_MXU__POOL12
= 0x19,
1493 /* not assigned 0x1A */
1494 OPC_MXU__POOL13
= 0x1B,
1495 OPC_MXU__POOL14
= 0x1C,
1496 OPC_MXU_Q8ACCE
= 0x1D,
1497 /* not assigned 0x1E */
1498 /* not assigned 0x1F */
1499 /* not assigned 0x20 */
1500 /* not assigned 0x21 */
1501 OPC_MXU_S8LDD
= 0x22,
1502 OPC_MXU_S8STD
= 0x23,
1503 OPC_MXU_S8LDI
= 0x24,
1504 OPC_MXU_S8SDI
= 0x25,
1505 OPC_MXU__POOL15
= 0x26,
1506 OPC_MXU__POOL16
= 0x27,
1507 OPC_MXU__POOL17
= 0x28,
1508 /* not assigned 0x29 */
1509 OPC_MXU_S16LDD
= 0x2A,
1510 OPC_MXU_S16STD
= 0x2B,
1511 OPC_MXU_S16LDI
= 0x2C,
1512 OPC_MXU_S16SDI
= 0x2D,
1513 OPC_MXU_S32M2I
= 0x2E,
1514 OPC_MXU_S32I2M
= 0x2F,
1515 OPC_MXU_D32SLL
= 0x30,
1516 OPC_MXU_D32SLR
= 0x31,
1517 OPC_MXU_D32SARL
= 0x32,
1518 OPC_MXU_D32SAR
= 0x33,
1519 OPC_MXU_Q16SLL
= 0x34,
1520 OPC_MXU_Q16SLR
= 0x35,
1521 OPC_MXU__POOL18
= 0x36,
1522 OPC_MXU_Q16SAR
= 0x37,
1523 OPC_MXU__POOL19
= 0x38,
1524 OPC_MXU__POOL20
= 0x39,
1525 OPC_MXU__POOL21
= 0x3A,
1526 OPC_MXU_Q16SCOP
= 0x3B,
1527 OPC_MXU_Q8MADL
= 0x3C,
1528 OPC_MXU_S32SFL
= 0x3D,
1529 OPC_MXU_Q8SAD
= 0x3E,
1530 /* not assigned 0x3F */
1538 OPC_MXU_S32MAX
= 0x00,
1539 OPC_MXU_S32MIN
= 0x01,
1540 OPC_MXU_D16MAX
= 0x02,
1541 OPC_MXU_D16MIN
= 0x03,
1542 OPC_MXU_Q8MAX
= 0x04,
1543 OPC_MXU_Q8MIN
= 0x05,
1544 OPC_MXU_Q8SLT
= 0x06,
1545 OPC_MXU_Q8SLTU
= 0x07,
1552 OPC_MXU_S32SLT
= 0x00,
1553 OPC_MXU_D16SLT
= 0x01,
1554 OPC_MXU_D16AVG
= 0x02,
1555 OPC_MXU_D16AVGR
= 0x03,
1556 OPC_MXU_Q8AVG
= 0x04,
1557 OPC_MXU_Q8AVGR
= 0x05,
1558 OPC_MXU_Q8ADD
= 0x07,
1565 OPC_MXU_S32CPS
= 0x00,
1566 OPC_MXU_D16CPS
= 0x02,
1567 OPC_MXU_Q8ABD
= 0x04,
1568 OPC_MXU_Q16SAT
= 0x06,
1575 OPC_MXU_D16MULF
= 0x00,
1576 OPC_MXU_D16MULE
= 0x01,
1583 OPC_MXU_S32LDD
= 0x00,
1584 OPC_MXU_S32LDDR
= 0x01,
1591 OPC_MXU_S32STD
= 0x00,
1592 OPC_MXU_S32STDR
= 0x01,
1599 OPC_MXU_S32LDDV
= 0x00,
1600 OPC_MXU_S32LDDVR
= 0x01,
1607 OPC_MXU_S32STDV
= 0x00,
1608 OPC_MXU_S32STDVR
= 0x01,
1615 OPC_MXU_S32LDI
= 0x00,
1616 OPC_MXU_S32LDIR
= 0x01,
1623 OPC_MXU_S32SDI
= 0x00,
1624 OPC_MXU_S32SDIR
= 0x01,
1631 OPC_MXU_S32LDIV
= 0x00,
1632 OPC_MXU_S32LDIVR
= 0x01,
1639 OPC_MXU_S32SDIV
= 0x00,
1640 OPC_MXU_S32SDIVR
= 0x01,
1647 OPC_MXU_D32ACC
= 0x00,
1648 OPC_MXU_D32ACCM
= 0x01,
1649 OPC_MXU_D32ASUM
= 0x02,
1656 OPC_MXU_Q16ACC
= 0x00,
1657 OPC_MXU_Q16ACCM
= 0x01,
1658 OPC_MXU_Q16ASUM
= 0x02,
1665 OPC_MXU_Q8ADDE
= 0x00,
1666 OPC_MXU_D8SUM
= 0x01,
1667 OPC_MXU_D8SUMC
= 0x02,
1674 OPC_MXU_S32MUL
= 0x00,
1675 OPC_MXU_S32MULU
= 0x01,
1676 OPC_MXU_S32EXTR
= 0x02,
1677 OPC_MXU_S32EXTRV
= 0x03,
1684 OPC_MXU_D32SARW
= 0x00,
1685 OPC_MXU_S32ALN
= 0x01,
1686 OPC_MXU_S32ALNI
= 0x02,
1687 OPC_MXU_S32LUI
= 0x03,
1688 OPC_MXU_S32NOR
= 0x04,
1689 OPC_MXU_S32AND
= 0x05,
1690 OPC_MXU_S32OR
= 0x06,
1691 OPC_MXU_S32XOR
= 0x07,
1701 OPC_MXU_LXBU
= 0x04,
1702 OPC_MXU_LXHU
= 0x05,
1709 OPC_MXU_D32SLLV
= 0x00,
1710 OPC_MXU_D32SLRV
= 0x01,
1711 OPC_MXU_D32SARV
= 0x03,
1712 OPC_MXU_Q16SLLV
= 0x04,
1713 OPC_MXU_Q16SLRV
= 0x05,
1714 OPC_MXU_Q16SARV
= 0x07,
1721 OPC_MXU_Q8MUL
= 0x00,
1722 OPC_MXU_Q8MULSU
= 0x01,
1729 OPC_MXU_Q8MOVZ
= 0x00,
1730 OPC_MXU_Q8MOVN
= 0x01,
1731 OPC_MXU_D16MOVZ
= 0x02,
1732 OPC_MXU_D16MOVN
= 0x03,
1733 OPC_MXU_S32MOVZ
= 0x04,
1734 OPC_MXU_S32MOVN
= 0x05,
1741 OPC_MXU_Q8MAC
= 0x00,
1742 OPC_MXU_Q8MACSU
= 0x01,
1746 * Overview of the TX79-specific instruction set
1747 * =============================================
1749 * The R5900 and the C790 have 128-bit wide GPRs, where the upper 64 bits
1750 * are only used by the specific quadword (128-bit) LQ/SQ load/store
1751 * instructions and certain multimedia instructions (MMIs). These MMIs
1752 * configure the 128-bit data path as two 64-bit, four 32-bit, eight 16-bit
1753 * or sixteen 8-bit paths.
1757 * The Toshiba TX System RISC TX79 Core Architecture manual,
1758 * https://wiki.qemu.org/File:C790.pdf
1760 * Three-Operand Multiply and Multiply-Add (4 instructions)
1761 * --------------------------------------------------------
1762 * MADD [rd,] rs, rt Multiply/Add
1763 * MADDU [rd,] rs, rt Multiply/Add Unsigned
1764 * MULT [rd,] rs, rt Multiply (3-operand)
1765 * MULTU [rd,] rs, rt Multiply Unsigned (3-operand)
1767 * Multiply Instructions for Pipeline 1 (10 instructions)
1768 * ------------------------------------------------------
1769 * MULT1 [rd,] rs, rt Multiply Pipeline 1
1770 * MULTU1 [rd,] rs, rt Multiply Unsigned Pipeline 1
1771 * DIV1 rs, rt Divide Pipeline 1
1772 * DIVU1 rs, rt Divide Unsigned Pipeline 1
1773 * MADD1 [rd,] rs, rt Multiply-Add Pipeline 1
1774 * MADDU1 [rd,] rs, rt Multiply-Add Unsigned Pipeline 1
1775 * MFHI1 rd Move From HI1 Register
1776 * MFLO1 rd Move From LO1 Register
1777 * MTHI1 rs Move To HI1 Register
1778 * MTLO1 rs Move To LO1 Register
1780 * Arithmetic (19 instructions)
1781 * ----------------------------
1782 * PADDB rd, rs, rt Parallel Add Byte
1783 * PSUBB rd, rs, rt Parallel Subtract Byte
1784 * PADDH rd, rs, rt Parallel Add Halfword
1785 * PSUBH rd, rs, rt Parallel Subtract Halfword
1786 * PADDW rd, rs, rt Parallel Add Word
1787 * PSUBW rd, rs, rt Parallel Subtract Word
1788 * PADSBH rd, rs, rt Parallel Add/Subtract Halfword
1789 * PADDSB rd, rs, rt Parallel Add with Signed Saturation Byte
1790 * PSUBSB rd, rs, rt Parallel Subtract with Signed Saturation Byte
1791 * PADDSH rd, rs, rt Parallel Add with Signed Saturation Halfword
1792 * PSUBSH rd, rs, rt Parallel Subtract with Signed Saturation Halfword
1793 * PADDSW rd, rs, rt Parallel Add with Signed Saturation Word
1794 * PSUBSW rd, rs, rt Parallel Subtract with Signed Saturation Word
1795 * PADDUB rd, rs, rt Parallel Add with Unsigned saturation Byte
1796 * PSUBUB rd, rs, rt Parallel Subtract with Unsigned saturation Byte
1797 * PADDUH rd, rs, rt Parallel Add with Unsigned saturation Halfword
1798 * PSUBUH rd, rs, rt Parallel Subtract with Unsigned saturation Halfword
1799 * PADDUW rd, rs, rt Parallel Add with Unsigned saturation Word
1800 * PSUBUW rd, rs, rt Parallel Subtract with Unsigned saturation Word
1802 * Min/Max (4 instructions)
1803 * ------------------------
1804 * PMAXH rd, rs, rt Parallel Maximum Halfword
1805 * PMINH rd, rs, rt Parallel Minimum Halfword
1806 * PMAXW rd, rs, rt Parallel Maximum Word
1807 * PMINW rd, rs, rt Parallel Minimum Word
1809 * Absolute (2 instructions)
1810 * -------------------------
1811 * PABSH rd, rt Parallel Absolute Halfword
1812 * PABSW rd, rt Parallel Absolute Word
1814 * Logical (4 instructions)
1815 * ------------------------
1816 * PAND rd, rs, rt Parallel AND
1817 * POR rd, rs, rt Parallel OR
1818 * PXOR rd, rs, rt Parallel XOR
1819 * PNOR rd, rs, rt Parallel NOR
1821 * Shift (9 instructions)
1822 * ----------------------
1823 * PSLLH rd, rt, sa Parallel Shift Left Logical Halfword
1824 * PSRLH rd, rt, sa Parallel Shift Right Logical Halfword
1825 * PSRAH rd, rt, sa Parallel Shift Right Arithmetic Halfword
1826 * PSLLW rd, rt, sa Parallel Shift Left Logical Word
1827 * PSRLW rd, rt, sa Parallel Shift Right Logical Word
1828 * PSRAW rd, rt, sa Parallel Shift Right Arithmetic Word
1829 * PSLLVW rd, rt, rs Parallel Shift Left Logical Variable Word
1830 * PSRLVW rd, rt, rs Parallel Shift Right Logical Variable Word
1831 * PSRAVW rd, rt, rs Parallel Shift Right Arithmetic Variable Word
1833 * Compare (6 instructions)
1834 * ------------------------
1835 * PCGTB rd, rs, rt Parallel Compare for Greater Than Byte
1836 * PCEQB rd, rs, rt Parallel Compare for Equal Byte
1837 * PCGTH rd, rs, rt Parallel Compare for Greater Than Halfword
1838 * PCEQH rd, rs, rt Parallel Compare for Equal Halfword
1839 * PCGTW rd, rs, rt Parallel Compare for Greater Than Word
1840 * PCEQW rd, rs, rt Parallel Compare for Equal Word
1842 * LZC (1 instruction)
1843 * -------------------
1844 * PLZCW rd, rs Parallel Leading Zero or One Count Word
1846 * Quadword Load and Store (2 instructions)
1847 * ----------------------------------------
1848 * LQ rt, offset(base) Load Quadword
1849 * SQ rt, offset(base) Store Quadword
1851 * Multiply and Divide (19 instructions)
1852 * -------------------------------------
1853 * PMULTW rd, rs, rt Parallel Multiply Word
1854 * PMULTUW rd, rs, rt Parallel Multiply Unsigned Word
1855 * PDIVW rs, rt Parallel Divide Word
1856 * PDIVUW rs, rt Parallel Divide Unsigned Word
1857 * PMADDW rd, rs, rt Parallel Multiply-Add Word
1858 * PMADDUW rd, rs, rt Parallel Multiply-Add Unsigned Word
1859 * PMSUBW rd, rs, rt Parallel Multiply-Subtract Word
1860 * PMULTH rd, rs, rt Parallel Multiply Halfword
1861 * PMADDH rd, rs, rt Parallel Multiply-Add Halfword
1862 * PMSUBH rd, rs, rt Parallel Multiply-Subtract Halfword
1863 * PHMADH rd, rs, rt Parallel Horizontal Multiply-Add Halfword
1864 * PHMSBH rd, rs, rt Parallel Horizontal Multiply-Subtract Halfword
1865 * PDIVBW rs, rt Parallel Divide Broadcast Word
1866 * PMFHI rd Parallel Move From HI Register
1867 * PMFLO rd Parallel Move From LO Register
1868 * PMTHI rs Parallel Move To HI Register
1869 * PMTLO rs Parallel Move To LO Register
1870 * PMFHL rd Parallel Move From HI/LO Register
1871 * PMTHL rs Parallel Move To HI/LO Register
1873 * Pack/Extend (11 instructions)
1874 * -----------------------------
1875 * PPAC5 rd, rt Parallel Pack to 5 bits
1876 * PPACB rd, rs, rt Parallel Pack to Byte
1877 * PPACH rd, rs, rt Parallel Pack to Halfword
1878 * PPACW rd, rs, rt Parallel Pack to Word
1879 * PEXT5 rd, rt Parallel Extend Upper from 5 bits
1880 * PEXTUB rd, rs, rt Parallel Extend Upper from Byte
1881 * PEXTLB rd, rs, rt Parallel Extend Lower from Byte
1882 * PEXTUH rd, rs, rt Parallel Extend Upper from Halfword
1883 * PEXTLH rd, rs, rt Parallel Extend Lower from Halfword
1884 * PEXTUW rd, rs, rt Parallel Extend Upper from Word
1885 * PEXTLW rd, rs, rt Parallel Extend Lower from Word
1887 * Others (16 instructions)
1888 * ------------------------
1889 * PCPYH rd, rt Parallel Copy Halfword
1890 * PCPYLD rd, rs, rt Parallel Copy Lower Doubleword
1891 * PCPYUD rd, rs, rt Parallel Copy Upper Doubleword
1892 * PREVH rd, rt Parallel Reverse Halfword
1893 * PINTH rd, rs, rt Parallel Interleave Halfword
1894 * PINTEH rd, rs, rt Parallel Interleave Even Halfword
1895 * PEXEH rd, rt Parallel Exchange Even Halfword
1896 * PEXCH rd, rt Parallel Exchange Center Halfword
1897 * PEXEW rd, rt Parallel Exchange Even Word
1898 * PEXCW rd, rt Parallel Exchange Center Word
1899 * QFSRV rd, rs, rt Quadword Funnel Shift Right Variable
1900 * MFSA rd Move from Shift Amount Register
1901 * MTSA rs Move to Shift Amount Register
1902 * MTSAB rs, immediate Move Byte Count to Shift Amount Register
1903 * MTSAH rs, immediate Move Halfword Count to Shift Amount Register
1904 * PROT3W rd, rt Parallel Rotate 3 Words
1906 * MMI (MultiMedia Instruction) encodings
1907 * ======================================
1909 * MMI instructions encoding table keys:
1911 * * This code is reserved for future use. An attempt to execute it
1912 * causes a Reserved Instruction exception.
1913 * % This code indicates an instruction class. The instruction word
1914 * must be further decoded by examining additional tables that show
1915 * the values for other instruction fields.
1916 * # This code is reserved for the unsupported instructions DMULT,
1917 * DMULTU, DDIV, DDIVU, LL, LLD, SC, SCD, LWC2 and SWC2. An attempt
1918 * to execute it causes a Reserved Instruction exception.
1920 * MMI instructions encoded by opcode field (MMI, LQ, SQ):
1923 * +--------+----------------------------------------+
1925 * +--------+----------------------------------------+
1927 * opcode bits 28..26
1928 * bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
1929 * 31..29 | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111
1930 * -------+-------+-------+-------+-------+-------+-------+-------+-------
1931 * 0 000 |SPECIAL| REGIMM| J | JAL | BEQ | BNE | BLEZ | BGTZ
1932 * 1 001 | ADDI | ADDIU | SLTI | SLTIU | ANDI | ORI | XORI | LUI
1933 * 2 010 | COP0 | COP1 | * | * | BEQL | BNEL | BLEZL | BGTZL
1934 * 3 011 | DADDI | DADDIU| LDL | LDR | MMI% | * | LQ | SQ
1935 * 4 100 | LB | LH | LWL | LW | LBU | LHU | LWR | LWU
1936 * 5 101 | SB | SH | SWL | SW | SDL | SDR | SWR | CACHE
1937 * 6 110 | # | LWC1 | # | PREF | # | LDC1 | # | LD
1938 * 7 111 | # | SWC1 | # | * | # | SDC1 | # | SD
1942 MMI_OPC_CLASS_MMI
= 0x1C << 26, /* Same as OPC_SPECIAL2 */
1943 MMI_OPC_LQ
= 0x1E << 26, /* Same as OPC_MSA */
1944 MMI_OPC_SQ
= 0x1F << 26, /* Same as OPC_SPECIAL3 */
1948 * MMI instructions with opcode field = MMI:
1951 * +--------+-------------------------------+--------+
1952 * | MMI | |function|
1953 * +--------+-------------------------------+--------+
1955 * function bits 2..0
1956 * bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
1957 * 5..3 | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111
1958 * -------+-------+-------+-------+-------+-------+-------+-------+-------
1959 * 0 000 | MADD | MADDU | * | * | PLZCW | * | * | *
1960 * 1 001 | MMI0% | MMI2% | * | * | * | * | * | *
1961 * 2 010 | MFHI1 | MTHI1 | MFLO1 | MTLO1 | * | * | * | *
1962 * 3 011 | MULT1 | MULTU1| DIV1 | DIVU1 | * | * | * | *
1963 * 4 100 | MADD1 | MADDU1| * | * | * | * | * | *
1964 * 5 101 | MMI1% | MMI3% | * | * | * | * | * | *
1965 * 6 110 | PMFHL | PMTHL | * | * | PSLLH | * | PSRLH | PSRAH
1966 * 7 111 | * | * | * | * | PSLLW | * | PSRLW | PSRAW
1969 #define MASK_MMI(op) (MASK_OP_MAJOR(op) | ((op) & 0x3F))
1971 MMI_OPC_MADD
= 0x00 | MMI_OPC_CLASS_MMI
, /* Same as OPC_MADD */
1972 MMI_OPC_MADDU
= 0x01 | MMI_OPC_CLASS_MMI
, /* Same as OPC_MADDU */
1973 MMI_OPC_PLZCW
= 0x04 | MMI_OPC_CLASS_MMI
,
1974 MMI_OPC_CLASS_MMI0
= 0x08 | MMI_OPC_CLASS_MMI
,
1975 MMI_OPC_CLASS_MMI2
= 0x09 | MMI_OPC_CLASS_MMI
,
1976 MMI_OPC_MFHI1
= 0x10 | MMI_OPC_CLASS_MMI
, /* Same minor as OPC_MFHI */
1977 MMI_OPC_MTHI1
= 0x11 | MMI_OPC_CLASS_MMI
, /* Same minor as OPC_MTHI */
1978 MMI_OPC_MFLO1
= 0x12 | MMI_OPC_CLASS_MMI
, /* Same minor as OPC_MFLO */
1979 MMI_OPC_MTLO1
= 0x13 | MMI_OPC_CLASS_MMI
, /* Same minor as OPC_MTLO */
1980 MMI_OPC_MULT1
= 0x18 | MMI_OPC_CLASS_MMI
, /* Same minor as OPC_MULT */
1981 MMI_OPC_MULTU1
= 0x19 | MMI_OPC_CLASS_MMI
, /* Same min. as OPC_MULTU */
1982 MMI_OPC_DIV1
= 0x1A | MMI_OPC_CLASS_MMI
, /* Same minor as OPC_DIV */
1983 MMI_OPC_DIVU1
= 0x1B | MMI_OPC_CLASS_MMI
, /* Same minor as OPC_DIVU */
1984 MMI_OPC_MADD1
= 0x20 | MMI_OPC_CLASS_MMI
,
1985 MMI_OPC_MADDU1
= 0x21 | MMI_OPC_CLASS_MMI
,
1986 MMI_OPC_CLASS_MMI1
= 0x28 | MMI_OPC_CLASS_MMI
,
1987 MMI_OPC_CLASS_MMI3
= 0x29 | MMI_OPC_CLASS_MMI
,
1988 MMI_OPC_PMFHL
= 0x30 | MMI_OPC_CLASS_MMI
,
1989 MMI_OPC_PMTHL
= 0x31 | MMI_OPC_CLASS_MMI
,
1990 MMI_OPC_PSLLH
= 0x34 | MMI_OPC_CLASS_MMI
,
1991 MMI_OPC_PSRLH
= 0x36 | MMI_OPC_CLASS_MMI
,
1992 MMI_OPC_PSRAH
= 0x37 | MMI_OPC_CLASS_MMI
,
1993 MMI_OPC_PSLLW
= 0x3C | MMI_OPC_CLASS_MMI
,
1994 MMI_OPC_PSRLW
= 0x3E | MMI_OPC_CLASS_MMI
,
1995 MMI_OPC_PSRAW
= 0x3F | MMI_OPC_CLASS_MMI
,
1999 * MMI instructions with opcode field = MMI and bits 5..0 = MMI0:
2002 * +--------+----------------------+--------+--------+
2003 * | MMI | |function| MMI0 |
2004 * +--------+----------------------+--------+--------+
2006 * function bits 7..6
2007 * bits | 0 | 1 | 2 | 3
2008 * 10..8 | 00 | 01 | 10 | 11
2009 * -------+-------+-------+-------+-------
2010 * 0 000 | PADDW | PSUBW | PCGTW | PMAXW
2011 * 1 001 | PADDH | PSUBH | PCGTH | PMAXH
2012 * 2 010 | PADDB | PSUBB | PCGTB | *
2013 * 3 011 | * | * | * | *
2014 * 4 100 | PADDSW| PSUBSW| PEXTLW| PPACW
2015 * 5 101 | PADDSH| PSUBSH| PEXTLH| PPACH
2016 * 6 110 | PADDSB| PSUBSB| PEXTLB| PPACB
2017 * 7 111 | * | * | PEXT5 | PPAC5
2020 #define MASK_MMI0(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
2022 MMI_OPC_0_PADDW
= (0x00 << 6) | MMI_OPC_CLASS_MMI0
,
2023 MMI_OPC_0_PSUBW
= (0x01 << 6) | MMI_OPC_CLASS_MMI0
,
2024 MMI_OPC_0_PCGTW
= (0x02 << 6) | MMI_OPC_CLASS_MMI0
,
2025 MMI_OPC_0_PMAXW
= (0x03 << 6) | MMI_OPC_CLASS_MMI0
,
2026 MMI_OPC_0_PADDH
= (0x04 << 6) | MMI_OPC_CLASS_MMI0
,
2027 MMI_OPC_0_PSUBH
= (0x05 << 6) | MMI_OPC_CLASS_MMI0
,
2028 MMI_OPC_0_PCGTH
= (0x06 << 6) | MMI_OPC_CLASS_MMI0
,
2029 MMI_OPC_0_PMAXH
= (0x07 << 6) | MMI_OPC_CLASS_MMI0
,
2030 MMI_OPC_0_PADDB
= (0x08 << 6) | MMI_OPC_CLASS_MMI0
,
2031 MMI_OPC_0_PSUBB
= (0x09 << 6) | MMI_OPC_CLASS_MMI0
,
2032 MMI_OPC_0_PCGTB
= (0x0A << 6) | MMI_OPC_CLASS_MMI0
,
2033 MMI_OPC_0_PADDSW
= (0x10 << 6) | MMI_OPC_CLASS_MMI0
,
2034 MMI_OPC_0_PSUBSW
= (0x11 << 6) | MMI_OPC_CLASS_MMI0
,
2035 MMI_OPC_0_PEXTLW
= (0x12 << 6) | MMI_OPC_CLASS_MMI0
,
2036 MMI_OPC_0_PPACW
= (0x13 << 6) | MMI_OPC_CLASS_MMI0
,
2037 MMI_OPC_0_PADDSH
= (0x14 << 6) | MMI_OPC_CLASS_MMI0
,
2038 MMI_OPC_0_PSUBSH
= (0x15 << 6) | MMI_OPC_CLASS_MMI0
,
2039 MMI_OPC_0_PEXTLH
= (0x16 << 6) | MMI_OPC_CLASS_MMI0
,
2040 MMI_OPC_0_PPACH
= (0x17 << 6) | MMI_OPC_CLASS_MMI0
,
2041 MMI_OPC_0_PADDSB
= (0x18 << 6) | MMI_OPC_CLASS_MMI0
,
2042 MMI_OPC_0_PSUBSB
= (0x19 << 6) | MMI_OPC_CLASS_MMI0
,
2043 MMI_OPC_0_PEXTLB
= (0x1A << 6) | MMI_OPC_CLASS_MMI0
,
2044 MMI_OPC_0_PPACB
= (0x1B << 6) | MMI_OPC_CLASS_MMI0
,
2045 MMI_OPC_0_PEXT5
= (0x1E << 6) | MMI_OPC_CLASS_MMI0
,
2046 MMI_OPC_0_PPAC5
= (0x1F << 6) | MMI_OPC_CLASS_MMI0
,
2050 * MMI instructions with opcode field = MMI and bits 5..0 = MMI1:
2053 * +--------+----------------------+--------+--------+
2054 * | MMI | |function| MMI1 |
2055 * +--------+----------------------+--------+--------+
2057 * function bits 7..6
2058 * bits | 0 | 1 | 2 | 3
2059 * 10..8 | 00 | 01 | 10 | 11
2060 * -------+-------+-------+-------+-------
2061 * 0 000 | * | PABSW | PCEQW | PMINW
2062 * 1 001 | PADSBH| PABSH | PCEQH | PMINH
2063 * 2 010 | * | * | PCEQB | *
2064 * 3 011 | * | * | * | *
2065 * 4 100 | PADDUW| PSUBUW| PEXTUW| *
2066 * 5 101 | PADDUH| PSUBUH| PEXTUH| *
2067 * 6 110 | PADDUB| PSUBUB| PEXTUB| QFSRV
2068 * 7 111 | * | * | * | *
2071 #define MASK_MMI1(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
2073 MMI_OPC_1_PABSW
= (0x01 << 6) | MMI_OPC_CLASS_MMI1
,
2074 MMI_OPC_1_PCEQW
= (0x02 << 6) | MMI_OPC_CLASS_MMI1
,
2075 MMI_OPC_1_PMINW
= (0x03 << 6) | MMI_OPC_CLASS_MMI1
,
2076 MMI_OPC_1_PADSBH
= (0x04 << 6) | MMI_OPC_CLASS_MMI1
,
2077 MMI_OPC_1_PABSH
= (0x05 << 6) | MMI_OPC_CLASS_MMI1
,
2078 MMI_OPC_1_PCEQH
= (0x06 << 6) | MMI_OPC_CLASS_MMI1
,
2079 MMI_OPC_1_PMINH
= (0x07 << 6) | MMI_OPC_CLASS_MMI1
,
2080 MMI_OPC_1_PCEQB
= (0x0A << 6) | MMI_OPC_CLASS_MMI1
,
2081 MMI_OPC_1_PADDUW
= (0x10 << 6) | MMI_OPC_CLASS_MMI1
,
2082 MMI_OPC_1_PSUBUW
= (0x11 << 6) | MMI_OPC_CLASS_MMI1
,
2083 MMI_OPC_1_PEXTUW
= (0x12 << 6) | MMI_OPC_CLASS_MMI1
,
2084 MMI_OPC_1_PADDUH
= (0x14 << 6) | MMI_OPC_CLASS_MMI1
,
2085 MMI_OPC_1_PSUBUH
= (0x15 << 6) | MMI_OPC_CLASS_MMI1
,
2086 MMI_OPC_1_PEXTUH
= (0x16 << 6) | MMI_OPC_CLASS_MMI1
,
2087 MMI_OPC_1_PADDUB
= (0x18 << 6) | MMI_OPC_CLASS_MMI1
,
2088 MMI_OPC_1_PSUBUB
= (0x19 << 6) | MMI_OPC_CLASS_MMI1
,
2089 MMI_OPC_1_PEXTUB
= (0x1A << 6) | MMI_OPC_CLASS_MMI1
,
2090 MMI_OPC_1_QFSRV
= (0x1B << 6) | MMI_OPC_CLASS_MMI1
,
2094 * MMI instructions with opcode field = MMI and bits 5..0 = MMI2:
2097 * +--------+----------------------+--------+--------+
2098 * | MMI | |function| MMI2 |
2099 * +--------+----------------------+--------+--------+
2101 * function bits 7..6
2102 * bits | 0 | 1 | 2 | 3
2103 * 10..8 | 00 | 01 | 10 | 11
2104 * -------+-------+-------+-------+-------
2105 * 0 000 | PMADDW| * | PSLLVW| PSRLVW
2106 * 1 001 | PMSUBW| * | * | *
2107 * 2 010 | PMFHI | PMFLO | PINTH | *
2108 * 3 011 | PMULTW| PDIVW | PCPYLD| *
2109 * 4 100 | PMADDH| PHMADH| PAND | PXOR
2110 * 5 101 | PMSUBH| PHMSBH| * | *
2111 * 6 110 | * | * | PEXEH | PREVH
2112 * 7 111 | PMULTH| PDIVBW| PEXEW | PROT3W
2115 #define MASK_MMI2(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
2117 MMI_OPC_2_PMADDW
= (0x00 << 6) | MMI_OPC_CLASS_MMI2
,
2118 MMI_OPC_2_PSLLVW
= (0x02 << 6) | MMI_OPC_CLASS_MMI2
,
2119 MMI_OPC_2_PSRLVW
= (0x03 << 6) | MMI_OPC_CLASS_MMI2
,
2120 MMI_OPC_2_PMSUBW
= (0x04 << 6) | MMI_OPC_CLASS_MMI2
,
2121 MMI_OPC_2_PMFHI
= (0x08 << 6) | MMI_OPC_CLASS_MMI2
,
2122 MMI_OPC_2_PMFLO
= (0x09 << 6) | MMI_OPC_CLASS_MMI2
,
2123 MMI_OPC_2_PINTH
= (0x0A << 6) | MMI_OPC_CLASS_MMI2
,
2124 MMI_OPC_2_PMULTW
= (0x0C << 6) | MMI_OPC_CLASS_MMI2
,
2125 MMI_OPC_2_PDIVW
= (0x0D << 6) | MMI_OPC_CLASS_MMI2
,
2126 MMI_OPC_2_PCPYLD
= (0x0E << 6) | MMI_OPC_CLASS_MMI2
,
2127 MMI_OPC_2_PMADDH
= (0x10 << 6) | MMI_OPC_CLASS_MMI2
,
2128 MMI_OPC_2_PHMADH
= (0x11 << 6) | MMI_OPC_CLASS_MMI2
,
2129 MMI_OPC_2_PAND
= (0x12 << 6) | MMI_OPC_CLASS_MMI2
,
2130 MMI_OPC_2_PXOR
= (0x13 << 6) | MMI_OPC_CLASS_MMI2
,
2131 MMI_OPC_2_PMSUBH
= (0x14 << 6) | MMI_OPC_CLASS_MMI2
,
2132 MMI_OPC_2_PHMSBH
= (0x15 << 6) | MMI_OPC_CLASS_MMI2
,
2133 MMI_OPC_2_PEXEH
= (0x1A << 6) | MMI_OPC_CLASS_MMI2
,
2134 MMI_OPC_2_PREVH
= (0x1B << 6) | MMI_OPC_CLASS_MMI2
,
2135 MMI_OPC_2_PMULTH
= (0x1C << 6) | MMI_OPC_CLASS_MMI2
,
2136 MMI_OPC_2_PDIVBW
= (0x1D << 6) | MMI_OPC_CLASS_MMI2
,
2137 MMI_OPC_2_PEXEW
= (0x1E << 6) | MMI_OPC_CLASS_MMI2
,
2138 MMI_OPC_2_PROT3W
= (0x1F << 6) | MMI_OPC_CLASS_MMI2
,
2142 * MMI instructions with opcode field = MMI and bits 5..0 = MMI3:
2145 * +--------+----------------------+--------+--------+
2146 * | MMI | |function| MMI3 |
2147 * +--------+----------------------+--------+--------+
2149 * function bits 7..6
2150 * bits | 0 | 1 | 2 | 3
2151 * 10..8 | 00 | 01 | 10 | 11
2152 * -------+-------+-------+-------+-------
2153 * 0 000 |PMADDUW| * | * | PSRAVW
2154 * 1 001 | * | * | * | *
2155 * 2 010 | PMTHI | PMTLO | PINTEH| *
2156 * 3 011 |PMULTUW| PDIVUW| PCPYUD| *
2157 * 4 100 | * | * | POR | PNOR
2158 * 5 101 | * | * | * | *
2159 * 6 110 | * | * | PEXCH | PCPYH
2160 * 7 111 | * | * | PEXCW | *
2163 #define MASK_MMI3(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
2165 MMI_OPC_3_PMADDUW
= (0x00 << 6) | MMI_OPC_CLASS_MMI3
,
2166 MMI_OPC_3_PSRAVW
= (0x03 << 6) | MMI_OPC_CLASS_MMI3
,
2167 MMI_OPC_3_PMTHI
= (0x08 << 6) | MMI_OPC_CLASS_MMI3
,
2168 MMI_OPC_3_PMTLO
= (0x09 << 6) | MMI_OPC_CLASS_MMI3
,
2169 MMI_OPC_3_PINTEH
= (0x0A << 6) | MMI_OPC_CLASS_MMI3
,
2170 MMI_OPC_3_PMULTUW
= (0x0C << 6) | MMI_OPC_CLASS_MMI3
,
2171 MMI_OPC_3_PDIVUW
= (0x0D << 6) | MMI_OPC_CLASS_MMI3
,
2172 MMI_OPC_3_PCPYUD
= (0x0E << 6) | MMI_OPC_CLASS_MMI3
,
2173 MMI_OPC_3_POR
= (0x12 << 6) | MMI_OPC_CLASS_MMI3
,
2174 MMI_OPC_3_PNOR
= (0x13 << 6) | MMI_OPC_CLASS_MMI3
,
2175 MMI_OPC_3_PEXCH
= (0x1A << 6) | MMI_OPC_CLASS_MMI3
,
2176 MMI_OPC_3_PCPYH
= (0x1B << 6) | MMI_OPC_CLASS_MMI3
,
2177 MMI_OPC_3_PEXCW
= (0x1E << 6) | MMI_OPC_CLASS_MMI3
,
2180 /* global register indices */
2181 TCGv cpu_gpr
[32], cpu_PC
;
2182 static TCGv cpu_HI
[MIPS_DSP_ACC
], cpu_LO
[MIPS_DSP_ACC
];
2183 static TCGv cpu_dspctrl
, btarget
;
2185 static TCGv cpu_lladdr
, cpu_llval
;
2186 static TCGv_i32 hflags
;
2187 TCGv_i32 fpu_fcr0
, fpu_fcr31
;
2188 TCGv_i64 fpu_f64
[32];
2190 #if defined(TARGET_MIPS64)
2191 /* Upper halves of R5900's 128-bit registers: MMRs (multimedia registers) */
2192 static TCGv_i64 cpu_mmr
[32];
2195 #if !defined(TARGET_MIPS64)
2197 static TCGv mxu_gpr
[NUMBER_OF_MXU_REGISTERS
- 1];
2201 #include "exec/gen-icount.h"
2203 #define gen_helper_0e0i(name, arg) do { \
2204 TCGv_i32 helper_tmp = tcg_const_i32(arg); \
2205 gen_helper_##name(cpu_env, helper_tmp); \
2206 tcg_temp_free_i32(helper_tmp); \
2209 #define gen_helper_0e1i(name, arg1, arg2) do { \
2210 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
2211 gen_helper_##name(cpu_env, arg1, helper_tmp); \
2212 tcg_temp_free_i32(helper_tmp); \
2215 #define gen_helper_1e0i(name, ret, arg1) do { \
2216 TCGv_i32 helper_tmp = tcg_const_i32(arg1); \
2217 gen_helper_##name(ret, cpu_env, helper_tmp); \
2218 tcg_temp_free_i32(helper_tmp); \
2221 #define gen_helper_1e1i(name, ret, arg1, arg2) do { \
2222 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
2223 gen_helper_##name(ret, cpu_env, arg1, helper_tmp); \
2224 tcg_temp_free_i32(helper_tmp); \
2227 #define gen_helper_0e2i(name, arg1, arg2, arg3) do { \
2228 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
2229 gen_helper_##name(cpu_env, arg1, arg2, helper_tmp); \
2230 tcg_temp_free_i32(helper_tmp); \
2233 #define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do { \
2234 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
2235 gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp); \
2236 tcg_temp_free_i32(helper_tmp); \
2239 #define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do { \
2240 TCGv_i32 helper_tmp = tcg_const_i32(arg4); \
2241 gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp); \
2242 tcg_temp_free_i32(helper_tmp); \
2245 #define DISAS_STOP DISAS_TARGET_0
2246 #define DISAS_EXIT DISAS_TARGET_1
2248 static const char * const regnames
[] = {
2249 "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
2250 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
2251 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
2252 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
2255 static const char * const regnames_HI
[] = {
2256 "HI0", "HI1", "HI2", "HI3",
2259 static const char * const regnames_LO
[] = {
2260 "LO0", "LO1", "LO2", "LO3",
2263 static const char * const fregnames
[] = {
2264 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
2265 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
2266 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
2267 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
2270 #if !defined(TARGET_MIPS64)
2271 static const char * const mxuregnames
[] = {
2272 "XR1", "XR2", "XR3", "XR4", "XR5", "XR6", "XR7", "XR8",
2273 "XR9", "XR10", "XR11", "XR12", "XR13", "XR14", "XR15", "MXU_CR",
2277 /* General purpose registers moves. */
2278 void gen_load_gpr(TCGv t
, int reg
)
2281 tcg_gen_movi_tl(t
, 0);
2283 tcg_gen_mov_tl(t
, cpu_gpr
[reg
]);
2287 void gen_store_gpr(TCGv t
, int reg
)
2290 tcg_gen_mov_tl(cpu_gpr
[reg
], t
);
2294 /* Moves to/from shadow registers. */
2295 static inline void gen_load_srsgpr(int from
, int to
)
2297 TCGv t0
= tcg_temp_new();
2300 tcg_gen_movi_tl(t0
, 0);
2302 TCGv_i32 t2
= tcg_temp_new_i32();
2303 TCGv_ptr addr
= tcg_temp_new_ptr();
2305 tcg_gen_ld_i32(t2
, cpu_env
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
2306 tcg_gen_shri_i32(t2
, t2
, CP0SRSCtl_PSS
);
2307 tcg_gen_andi_i32(t2
, t2
, 0xf);
2308 tcg_gen_muli_i32(t2
, t2
, sizeof(target_ulong
) * 32);
2309 tcg_gen_ext_i32_ptr(addr
, t2
);
2310 tcg_gen_add_ptr(addr
, cpu_env
, addr
);
2312 tcg_gen_ld_tl(t0
, addr
, sizeof(target_ulong
) * from
);
2313 tcg_temp_free_ptr(addr
);
2314 tcg_temp_free_i32(t2
);
2316 gen_store_gpr(t0
, to
);
2320 static inline void gen_store_srsgpr(int from
, int to
)
2323 TCGv t0
= tcg_temp_new();
2324 TCGv_i32 t2
= tcg_temp_new_i32();
2325 TCGv_ptr addr
= tcg_temp_new_ptr();
2327 gen_load_gpr(t0
, from
);
2328 tcg_gen_ld_i32(t2
, cpu_env
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
2329 tcg_gen_shri_i32(t2
, t2
, CP0SRSCtl_PSS
);
2330 tcg_gen_andi_i32(t2
, t2
, 0xf);
2331 tcg_gen_muli_i32(t2
, t2
, sizeof(target_ulong
) * 32);
2332 tcg_gen_ext_i32_ptr(addr
, t2
);
2333 tcg_gen_add_ptr(addr
, cpu_env
, addr
);
2335 tcg_gen_st_tl(t0
, addr
, sizeof(target_ulong
) * to
);
2336 tcg_temp_free_ptr(addr
);
2337 tcg_temp_free_i32(t2
);
2342 #if !defined(TARGET_MIPS64)
2343 /* MXU General purpose registers moves. */
2344 static inline void gen_load_mxu_gpr(TCGv t
, unsigned int reg
)
2347 tcg_gen_movi_tl(t
, 0);
2348 } else if (reg
<= 15) {
2349 tcg_gen_mov_tl(t
, mxu_gpr
[reg
- 1]);
2353 static inline void gen_store_mxu_gpr(TCGv t
, unsigned int reg
)
2355 if (reg
> 0 && reg
<= 15) {
2356 tcg_gen_mov_tl(mxu_gpr
[reg
- 1], t
);
2360 /* MXU control register moves. */
2361 static inline void gen_load_mxu_cr(TCGv t
)
2363 tcg_gen_mov_tl(t
, mxu_CR
);
2366 static inline void gen_store_mxu_cr(TCGv t
)
2368 /* TODO: Add handling of RW rules for MXU_CR. */
2369 tcg_gen_mov_tl(mxu_CR
, t
);
2375 static inline void gen_save_pc(target_ulong pc
)
2377 tcg_gen_movi_tl(cpu_PC
, pc
);
2380 static inline void save_cpu_state(DisasContext
*ctx
, int do_save_pc
)
2382 LOG_DISAS("hflags %08x saved %08x\n", ctx
->hflags
, ctx
->saved_hflags
);
2383 if (do_save_pc
&& ctx
->base
.pc_next
!= ctx
->saved_pc
) {
2384 gen_save_pc(ctx
->base
.pc_next
);
2385 ctx
->saved_pc
= ctx
->base
.pc_next
;
2387 if (ctx
->hflags
!= ctx
->saved_hflags
) {
2388 tcg_gen_movi_i32(hflags
, ctx
->hflags
);
2389 ctx
->saved_hflags
= ctx
->hflags
;
2390 switch (ctx
->hflags
& MIPS_HFLAG_BMASK_BASE
) {
2396 tcg_gen_movi_tl(btarget
, ctx
->btarget
);
2402 static inline void restore_cpu_state(CPUMIPSState
*env
, DisasContext
*ctx
)
2404 ctx
->saved_hflags
= ctx
->hflags
;
2405 switch (ctx
->hflags
& MIPS_HFLAG_BMASK_BASE
) {
2411 ctx
->btarget
= env
->btarget
;
2416 void generate_exception_err(DisasContext
*ctx
, int excp
, int err
)
2418 TCGv_i32 texcp
= tcg_const_i32(excp
);
2419 TCGv_i32 terr
= tcg_const_i32(err
);
2420 save_cpu_state(ctx
, 1);
2421 gen_helper_raise_exception_err(cpu_env
, texcp
, terr
);
2422 tcg_temp_free_i32(terr
);
2423 tcg_temp_free_i32(texcp
);
2424 ctx
->base
.is_jmp
= DISAS_NORETURN
;
2427 void generate_exception(DisasContext
*ctx
, int excp
)
2429 gen_helper_0e0i(raise_exception
, excp
);
2432 void generate_exception_end(DisasContext
*ctx
, int excp
)
2434 generate_exception_err(ctx
, excp
, 0);
2437 void gen_reserved_instruction(DisasContext
*ctx
)
2439 generate_exception_end(ctx
, EXCP_RI
);
2442 /* Floating point register moves. */
2443 void gen_load_fpr32(DisasContext
*ctx
, TCGv_i32 t
, int reg
)
2445 if (ctx
->hflags
& MIPS_HFLAG_FRE
) {
2446 generate_exception(ctx
, EXCP_RI
);
2448 tcg_gen_extrl_i64_i32(t
, fpu_f64
[reg
]);
2451 void gen_store_fpr32(DisasContext
*ctx
, TCGv_i32 t
, int reg
)
2454 if (ctx
->hflags
& MIPS_HFLAG_FRE
) {
2455 generate_exception(ctx
, EXCP_RI
);
2457 t64
= tcg_temp_new_i64();
2458 tcg_gen_extu_i32_i64(t64
, t
);
2459 tcg_gen_deposit_i64(fpu_f64
[reg
], fpu_f64
[reg
], t64
, 0, 32);
2460 tcg_temp_free_i64(t64
);
2463 static void gen_load_fpr32h(DisasContext
*ctx
, TCGv_i32 t
, int reg
)
2465 if (ctx
->hflags
& MIPS_HFLAG_F64
) {
2466 tcg_gen_extrh_i64_i32(t
, fpu_f64
[reg
]);
2468 gen_load_fpr32(ctx
, t
, reg
| 1);
2472 static void gen_store_fpr32h(DisasContext
*ctx
, TCGv_i32 t
, int reg
)
2474 if (ctx
->hflags
& MIPS_HFLAG_F64
) {
2475 TCGv_i64 t64
= tcg_temp_new_i64();
2476 tcg_gen_extu_i32_i64(t64
, t
);
2477 tcg_gen_deposit_i64(fpu_f64
[reg
], fpu_f64
[reg
], t64
, 32, 32);
2478 tcg_temp_free_i64(t64
);
2480 gen_store_fpr32(ctx
, t
, reg
| 1);
2484 void gen_load_fpr64(DisasContext
*ctx
, TCGv_i64 t
, int reg
)
2486 if (ctx
->hflags
& MIPS_HFLAG_F64
) {
2487 tcg_gen_mov_i64(t
, fpu_f64
[reg
]);
2489 tcg_gen_concat32_i64(t
, fpu_f64
[reg
& ~1], fpu_f64
[reg
| 1]);
2493 void gen_store_fpr64(DisasContext
*ctx
, TCGv_i64 t
, int reg
)
2495 if (ctx
->hflags
& MIPS_HFLAG_F64
) {
2496 tcg_gen_mov_i64(fpu_f64
[reg
], t
);
2499 tcg_gen_deposit_i64(fpu_f64
[reg
& ~1], fpu_f64
[reg
& ~1], t
, 0, 32);
2500 t0
= tcg_temp_new_i64();
2501 tcg_gen_shri_i64(t0
, t
, 32);
2502 tcg_gen_deposit_i64(fpu_f64
[reg
| 1], fpu_f64
[reg
| 1], t0
, 0, 32);
2503 tcg_temp_free_i64(t0
);
2507 int get_fp_bit(int cc
)
2516 /* Addresses computation */
2517 void gen_op_addr_add(DisasContext
*ctx
, TCGv ret
, TCGv arg0
, TCGv arg1
)
2519 tcg_gen_add_tl(ret
, arg0
, arg1
);
2521 #if defined(TARGET_MIPS64)
2522 if (ctx
->hflags
& MIPS_HFLAG_AWRAP
) {
2523 tcg_gen_ext32s_i64(ret
, ret
);
2528 static inline void gen_op_addr_addi(DisasContext
*ctx
, TCGv ret
, TCGv base
,
2531 tcg_gen_addi_tl(ret
, base
, ofs
);
2533 #if defined(TARGET_MIPS64)
2534 if (ctx
->hflags
& MIPS_HFLAG_AWRAP
) {
2535 tcg_gen_ext32s_i64(ret
, ret
);
2540 /* Addresses computation (translation time) */
2541 static target_long
addr_add(DisasContext
*ctx
, target_long base
,
2544 target_long sum
= base
+ offset
;
2546 #if defined(TARGET_MIPS64)
2547 if (ctx
->hflags
& MIPS_HFLAG_AWRAP
) {
2554 /* Sign-extract the low 32-bits to a target_long. */
2555 void gen_move_low32(TCGv ret
, TCGv_i64 arg
)
2557 #if defined(TARGET_MIPS64)
2558 tcg_gen_ext32s_i64(ret
, arg
);
2560 tcg_gen_extrl_i64_i32(ret
, arg
);
2564 /* Sign-extract the high 32-bits to a target_long. */
2565 void gen_move_high32(TCGv ret
, TCGv_i64 arg
)
2567 #if defined(TARGET_MIPS64)
2568 tcg_gen_sari_i64(ret
, arg
, 32);
2570 tcg_gen_extrh_i64_i32(ret
, arg
);
2574 void check_cp0_enabled(DisasContext
*ctx
)
2576 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_CP0
))) {
2577 generate_exception_end(ctx
, EXCP_CpU
);
2581 void check_cp1_enabled(DisasContext
*ctx
)
2583 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_FPU
))) {
2584 generate_exception_err(ctx
, EXCP_CpU
, 1);
2589 * Verify that the processor is running with COP1X instructions enabled.
2590 * This is associated with the nabla symbol in the MIPS32 and MIPS64
2593 void check_cop1x(DisasContext
*ctx
)
2595 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_COP1X
))) {
2596 gen_reserved_instruction(ctx
);
2601 * Verify that the processor is running with 64-bit floating-point
2602 * operations enabled.
2604 void check_cp1_64bitmode(DisasContext
*ctx
)
2606 if (unlikely(~ctx
->hflags
& (MIPS_HFLAG_F64
| MIPS_HFLAG_COP1X
))) {
2607 gen_reserved_instruction(ctx
);
2612 * Verify if floating point register is valid; an operation is not defined
2613 * if bit 0 of any register specification is set and the FR bit in the
2614 * Status register equals zero, since the register numbers specify an
2615 * even-odd pair of adjacent coprocessor general registers. When the FR bit
2616 * in the Status register equals one, both even and odd register numbers
2617 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
2619 * Multiple 64 bit wide registers can be checked by calling
2620 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
2622 void check_cp1_registers(DisasContext
*ctx
, int regs
)
2624 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_F64
) && (regs
& 1))) {
2625 gen_reserved_instruction(ctx
);
2630 * Verify that the processor is running with DSP instructions enabled.
2631 * This is enabled by CP0 Status register MX(24) bit.
2633 static inline void check_dsp(DisasContext
*ctx
)
2635 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_DSP
))) {
2636 if (ctx
->insn_flags
& ASE_DSP
) {
2637 generate_exception_end(ctx
, EXCP_DSPDIS
);
2639 gen_reserved_instruction(ctx
);
2644 static inline void check_dsp_r2(DisasContext
*ctx
)
2646 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_DSP_R2
))) {
2647 if (ctx
->insn_flags
& ASE_DSP
) {
2648 generate_exception_end(ctx
, EXCP_DSPDIS
);
2650 gen_reserved_instruction(ctx
);
2655 static inline void check_dsp_r3(DisasContext
*ctx
)
2657 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_DSP_R3
))) {
2658 if (ctx
->insn_flags
& ASE_DSP
) {
2659 generate_exception_end(ctx
, EXCP_DSPDIS
);
2661 gen_reserved_instruction(ctx
);
2667 * This code generates a "reserved instruction" exception if the
2668 * CPU does not support the instruction set corresponding to flags.
2670 void check_insn(DisasContext
*ctx
, uint64_t flags
)
2672 if (unlikely(!(ctx
->insn_flags
& flags
))) {
2673 gen_reserved_instruction(ctx
);
2678 * This code generates a "reserved instruction" exception if the
2679 * CPU has corresponding flag set which indicates that the instruction
2682 static inline void check_insn_opc_removed(DisasContext
*ctx
, uint64_t flags
)
2684 if (unlikely(ctx
->insn_flags
& flags
)) {
2685 gen_reserved_instruction(ctx
);
2690 * The Linux kernel traps certain reserved instruction exceptions to
2691 * emulate the corresponding instructions. QEMU is the kernel in user
2692 * mode, so those traps are emulated by accepting the instructions.
2694 * A reserved instruction exception is generated for flagged CPUs if
2695 * QEMU runs in system mode.
2697 static inline void check_insn_opc_user_only(DisasContext
*ctx
, uint64_t flags
)
2699 #ifndef CONFIG_USER_ONLY
2700 check_insn_opc_removed(ctx
, flags
);
2705 * This code generates a "reserved instruction" exception if the
2706 * CPU does not support 64-bit paired-single (PS) floating point data type.
2708 static inline void check_ps(DisasContext
*ctx
)
2710 if (unlikely(!ctx
->ps
)) {
2711 generate_exception(ctx
, EXCP_RI
);
2713 check_cp1_64bitmode(ctx
);
2717 * This code generates a "reserved instruction" exception if cpu is not
2718 * 64-bit or 64-bit instructions are not enabled.
2720 void check_mips_64(DisasContext
*ctx
)
2722 if (unlikely((TARGET_LONG_BITS
!= 64) || !(ctx
->hflags
& MIPS_HFLAG_64
))) {
2723 gen_reserved_instruction(ctx
);
2727 #ifndef CONFIG_USER_ONLY
2728 static inline void check_mvh(DisasContext
*ctx
)
2730 if (unlikely(!ctx
->mvh
)) {
2731 generate_exception(ctx
, EXCP_RI
);
2737 * This code generates a "reserved instruction" exception if the
2738 * Config5 XNP bit is set.
2740 static inline void check_xnp(DisasContext
*ctx
)
2742 if (unlikely(ctx
->CP0_Config5
& (1 << CP0C5_XNP
))) {
2743 gen_reserved_instruction(ctx
);
2747 #ifndef CONFIG_USER_ONLY
2749 * This code generates a "reserved instruction" exception if the
2750 * Config3 PW bit is NOT set.
2752 static inline void check_pw(DisasContext
*ctx
)
2754 if (unlikely(!(ctx
->CP0_Config3
& (1 << CP0C3_PW
)))) {
2755 gen_reserved_instruction(ctx
);
2761 * This code generates a "reserved instruction" exception if the
2762 * Config3 MT bit is NOT set.
2764 static inline void check_mt(DisasContext
*ctx
)
2766 if (unlikely(!(ctx
->CP0_Config3
& (1 << CP0C3_MT
)))) {
2767 gen_reserved_instruction(ctx
);
2771 #ifndef CONFIG_USER_ONLY
2773 * This code generates a "coprocessor unusable" exception if CP0 is not
2774 * available, and, if that is not the case, generates a "reserved instruction"
2775 * exception if the Config5 MT bit is NOT set. This is needed for availability
2776 * control of some of MT ASE instructions.
2778 static inline void check_cp0_mt(DisasContext
*ctx
)
2780 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_CP0
))) {
2781 generate_exception_end(ctx
, EXCP_CpU
);
2783 if (unlikely(!(ctx
->CP0_Config3
& (1 << CP0C3_MT
)))) {
2784 gen_reserved_instruction(ctx
);
2791 * This code generates a "reserved instruction" exception if the
2792 * Config5 NMS bit is set.
2794 static inline void check_nms(DisasContext
*ctx
)
2796 if (unlikely(ctx
->CP0_Config5
& (1 << CP0C5_NMS
))) {
2797 gen_reserved_instruction(ctx
);
2802 * This code generates a "reserved instruction" exception if the
2803 * Config5 NMS bit is set, and Config1 DL, Config1 IL, Config2 SL,
2804 * Config2 TL, and Config5 L2C are unset.
2806 static inline void check_nms_dl_il_sl_tl_l2c(DisasContext
*ctx
)
2808 if (unlikely((ctx
->CP0_Config5
& (1 << CP0C5_NMS
)) &&
2809 !(ctx
->CP0_Config1
& (1 << CP0C1_DL
)) &&
2810 !(ctx
->CP0_Config1
& (1 << CP0C1_IL
)) &&
2811 !(ctx
->CP0_Config2
& (1 << CP0C2_SL
)) &&
2812 !(ctx
->CP0_Config2
& (1 << CP0C2_TL
)) &&
2813 !(ctx
->CP0_Config5
& (1 << CP0C5_L2C
)))) {
2814 gen_reserved_instruction(ctx
);
2819 * This code generates a "reserved instruction" exception if the
2820 * Config5 EVA bit is NOT set.
2822 static inline void check_eva(DisasContext
*ctx
)
2824 if (unlikely(!(ctx
->CP0_Config5
& (1 << CP0C5_EVA
)))) {
2825 gen_reserved_instruction(ctx
);
2831 * Define small wrappers for gen_load_fpr* so that we have a uniform
2832 * calling interface for 32 and 64-bit FPRs. No sense in changing
2833 * all callers for gen_load_fpr32 when we need the CTX parameter for
2836 #define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(ctx, x, y)
2837 #define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
2838 #define FOP_CONDS(type, abs, fmt, ifmt, bits) \
2839 static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
2840 int ft, int fs, int cc) \
2842 TCGv_i##bits fp0 = tcg_temp_new_i##bits(); \
2843 TCGv_i##bits fp1 = tcg_temp_new_i##bits(); \
2852 check_cp1_registers(ctx, fs | ft); \
2860 gen_ldcmp_fpr##bits(ctx, fp0, fs); \
2861 gen_ldcmp_fpr##bits(ctx, fp1, ft); \
2864 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); \
2867 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); \
2870 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); \
2873 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); \
2876 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); \
2879 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); \
2882 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); \
2885 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); \
2888 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); \
2891 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); \
2894 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); \
2897 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); \
2900 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); \
2903 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); \
2906 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); \
2909 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); \
2914 tcg_temp_free_i##bits(fp0); \
2915 tcg_temp_free_i##bits(fp1); \
2918 FOP_CONDS(, 0, d
, FMT_D
, 64)
2919 FOP_CONDS(abs
, 1, d
, FMT_D
, 64)
2920 FOP_CONDS(, 0, s
, FMT_S
, 32)
2921 FOP_CONDS(abs
, 1, s
, FMT_S
, 32)
2922 FOP_CONDS(, 0, ps
, FMT_PS
, 64)
2923 FOP_CONDS(abs
, 1, ps
, FMT_PS
, 64)
2926 #define FOP_CONDNS(fmt, ifmt, bits, STORE) \
2927 static inline void gen_r6_cmp_ ## fmt(DisasContext *ctx, int n, \
2928 int ft, int fs, int fd) \
2930 TCGv_i ## bits fp0 = tcg_temp_new_i ## bits(); \
2931 TCGv_i ## bits fp1 = tcg_temp_new_i ## bits(); \
2932 if (ifmt == FMT_D) { \
2933 check_cp1_registers(ctx, fs | ft | fd); \
2935 gen_ldcmp_fpr ## bits(ctx, fp0, fs); \
2936 gen_ldcmp_fpr ## bits(ctx, fp1, ft); \
2939 gen_helper_r6_cmp_ ## fmt ## _af(fp0, cpu_env, fp0, fp1); \
2942 gen_helper_r6_cmp_ ## fmt ## _un(fp0, cpu_env, fp0, fp1); \
2945 gen_helper_r6_cmp_ ## fmt ## _eq(fp0, cpu_env, fp0, fp1); \
2948 gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, cpu_env, fp0, fp1); \
2951 gen_helper_r6_cmp_ ## fmt ## _lt(fp0, cpu_env, fp0, fp1); \
2954 gen_helper_r6_cmp_ ## fmt ## _ult(fp0, cpu_env, fp0, fp1); \
2957 gen_helper_r6_cmp_ ## fmt ## _le(fp0, cpu_env, fp0, fp1); \
2960 gen_helper_r6_cmp_ ## fmt ## _ule(fp0, cpu_env, fp0, fp1); \
2963 gen_helper_r6_cmp_ ## fmt ## _saf(fp0, cpu_env, fp0, fp1); \
2966 gen_helper_r6_cmp_ ## fmt ## _sun(fp0, cpu_env, fp0, fp1); \
2969 gen_helper_r6_cmp_ ## fmt ## _seq(fp0, cpu_env, fp0, fp1); \
2972 gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, cpu_env, fp0, fp1); \
2975 gen_helper_r6_cmp_ ## fmt ## _slt(fp0, cpu_env, fp0, fp1); \
2978 gen_helper_r6_cmp_ ## fmt ## _sult(fp0, cpu_env, fp0, fp1); \
2981 gen_helper_r6_cmp_ ## fmt ## _sle(fp0, cpu_env, fp0, fp1); \
2984 gen_helper_r6_cmp_ ## fmt ## _sule(fp0, cpu_env, fp0, fp1); \
2987 gen_helper_r6_cmp_ ## fmt ## _or(fp0, cpu_env, fp0, fp1); \
2990 gen_helper_r6_cmp_ ## fmt ## _une(fp0, cpu_env, fp0, fp1); \
2993 gen_helper_r6_cmp_ ## fmt ## _ne(fp0, cpu_env, fp0, fp1); \
2996 gen_helper_r6_cmp_ ## fmt ## _sor(fp0, cpu_env, fp0, fp1); \
2999 gen_helper_r6_cmp_ ## fmt ## _sune(fp0, cpu_env, fp0, fp1); \
3002 gen_helper_r6_cmp_ ## fmt ## _sne(fp0, cpu_env, fp0, fp1); \
3008 tcg_temp_free_i ## bits(fp0); \
3009 tcg_temp_free_i ## bits(fp1); \
3012 FOP_CONDNS(d
, FMT_D
, 64, gen_store_fpr64(ctx
, fp0
, fd
))
3013 FOP_CONDNS(s
, FMT_S
, 32, gen_store_fpr32(ctx
, fp0
, fd
))
3015 #undef gen_ldcmp_fpr32
3016 #undef gen_ldcmp_fpr64
3018 /* load/store instructions. */
3019 #ifdef CONFIG_USER_ONLY
3020 #define OP_LD_ATOMIC(insn, fname) \
3021 static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \
3022 DisasContext *ctx) \
3024 TCGv t0 = tcg_temp_new(); \
3025 tcg_gen_mov_tl(t0, arg1); \
3026 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
3027 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
3028 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
3029 tcg_temp_free(t0); \
3032 #define OP_LD_ATOMIC(insn, fname) \
3033 static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \
3034 DisasContext *ctx) \
3036 gen_helper_1e1i(insn, ret, arg1, mem_idx); \
3039 OP_LD_ATOMIC(ll
, ld32s
);
3040 #if defined(TARGET_MIPS64)
3041 OP_LD_ATOMIC(lld
, ld64
);
3045 void gen_base_offset_addr(DisasContext
*ctx
, TCGv addr
, int base
, int offset
)
3048 tcg_gen_movi_tl(addr
, offset
);
3049 } else if (offset
== 0) {
3050 gen_load_gpr(addr
, base
);
3052 tcg_gen_movi_tl(addr
, offset
);
3053 gen_op_addr_add(ctx
, addr
, cpu_gpr
[base
], addr
);
3057 static target_ulong
pc_relative_pc(DisasContext
*ctx
)
3059 target_ulong pc
= ctx
->base
.pc_next
;
3061 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
3062 int branch_bytes
= ctx
->hflags
& MIPS_HFLAG_BDS16
? 2 : 4;
3067 pc
&= ~(target_ulong
)3;
3072 static void gen_ld(DisasContext
*ctx
, uint32_t opc
,
3073 int rt
, int base
, int offset
)
3076 int mem_idx
= ctx
->mem_idx
;
3078 if (rt
== 0 && ctx
->insn_flags
& (INSN_LOONGSON2E
| INSN_LOONGSON2F
|
3081 * Loongson CPU uses a load to zero register for prefetch.
3082 * We emulate it as a NOP. On other CPU we must perform the
3083 * actual memory access.
3088 t0
= tcg_temp_new();
3089 gen_base_offset_addr(ctx
, t0
, base
, offset
);
3092 #if defined(TARGET_MIPS64)
3094 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEUL
|
3095 ctx
->default_tcg_memop_mask
);
3096 gen_store_gpr(t0
, rt
);
3099 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEQ
|
3100 ctx
->default_tcg_memop_mask
);
3101 gen_store_gpr(t0
, rt
);
3105 op_ld_lld(t0
, t0
, mem_idx
, ctx
);
3106 gen_store_gpr(t0
, rt
);
3109 t1
= tcg_temp_new();
3111 * Do a byte access to possibly trigger a page
3112 * fault with the unaligned address.
3114 tcg_gen_qemu_ld_tl(t1
, t0
, mem_idx
, MO_UB
);
3115 tcg_gen_andi_tl(t1
, t0
, 7);
3116 #ifndef TARGET_WORDS_BIGENDIAN
3117 tcg_gen_xori_tl(t1
, t1
, 7);
3119 tcg_gen_shli_tl(t1
, t1
, 3);
3120 tcg_gen_andi_tl(t0
, t0
, ~7);
3121 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEQ
);
3122 tcg_gen_shl_tl(t0
, t0
, t1
);
3123 t2
= tcg_const_tl(-1);
3124 tcg_gen_shl_tl(t2
, t2
, t1
);
3125 gen_load_gpr(t1
, rt
);
3126 tcg_gen_andc_tl(t1
, t1
, t2
);
3128 tcg_gen_or_tl(t0
, t0
, t1
);
3130 gen_store_gpr(t0
, rt
);
3133 t1
= tcg_temp_new();
3135 * Do a byte access to possibly trigger a page
3136 * fault with the unaligned address.
3138 tcg_gen_qemu_ld_tl(t1
, t0
, mem_idx
, MO_UB
);
3139 tcg_gen_andi_tl(t1
, t0
, 7);
3140 #ifdef TARGET_WORDS_BIGENDIAN
3141 tcg_gen_xori_tl(t1
, t1
, 7);
3143 tcg_gen_shli_tl(t1
, t1
, 3);
3144 tcg_gen_andi_tl(t0
, t0
, ~7);
3145 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEQ
);
3146 tcg_gen_shr_tl(t0
, t0
, t1
);
3147 tcg_gen_xori_tl(t1
, t1
, 63);
3148 t2
= tcg_const_tl(0xfffffffffffffffeull
);
3149 tcg_gen_shl_tl(t2
, t2
, t1
);
3150 gen_load_gpr(t1
, rt
);
3151 tcg_gen_and_tl(t1
, t1
, t2
);
3153 tcg_gen_or_tl(t0
, t0
, t1
);
3155 gen_store_gpr(t0
, rt
);
3158 t1
= tcg_const_tl(pc_relative_pc(ctx
));
3159 gen_op_addr_add(ctx
, t0
, t0
, t1
);
3161 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEQ
);
3162 gen_store_gpr(t0
, rt
);
3166 t1
= tcg_const_tl(pc_relative_pc(ctx
));
3167 gen_op_addr_add(ctx
, t0
, t0
, t1
);
3169 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TESL
);
3170 gen_store_gpr(t0
, rt
);
3173 mem_idx
= MIPS_HFLAG_UM
;
3176 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TESL
|
3177 ctx
->default_tcg_memop_mask
);
3178 gen_store_gpr(t0
, rt
);
3181 mem_idx
= MIPS_HFLAG_UM
;
3184 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TESW
|
3185 ctx
->default_tcg_memop_mask
);
3186 gen_store_gpr(t0
, rt
);
3189 mem_idx
= MIPS_HFLAG_UM
;
3192 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEUW
|
3193 ctx
->default_tcg_memop_mask
);
3194 gen_store_gpr(t0
, rt
);
3197 mem_idx
= MIPS_HFLAG_UM
;
3200 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_SB
);
3201 gen_store_gpr(t0
, rt
);
3204 mem_idx
= MIPS_HFLAG_UM
;
3207 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_UB
);
3208 gen_store_gpr(t0
, rt
);
3211 mem_idx
= MIPS_HFLAG_UM
;
3214 t1
= tcg_temp_new();
3216 * Do a byte access to possibly trigger a page
3217 * fault with the unaligned address.
3219 tcg_gen_qemu_ld_tl(t1
, t0
, mem_idx
, MO_UB
);
3220 tcg_gen_andi_tl(t1
, t0
, 3);
3221 #ifndef TARGET_WORDS_BIGENDIAN
3222 tcg_gen_xori_tl(t1
, t1
, 3);
3224 tcg_gen_shli_tl(t1
, t1
, 3);
3225 tcg_gen_andi_tl(t0
, t0
, ~3);
3226 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEUL
);
3227 tcg_gen_shl_tl(t0
, t0
, t1
);
3228 t2
= tcg_const_tl(-1);
3229 tcg_gen_shl_tl(t2
, t2
, t1
);
3230 gen_load_gpr(t1
, rt
);
3231 tcg_gen_andc_tl(t1
, t1
, t2
);
3233 tcg_gen_or_tl(t0
, t0
, t1
);
3235 tcg_gen_ext32s_tl(t0
, t0
);
3236 gen_store_gpr(t0
, rt
);
3239 mem_idx
= MIPS_HFLAG_UM
;
3242 t1
= tcg_temp_new();
3244 * Do a byte access to possibly trigger a page
3245 * fault with the unaligned address.
3247 tcg_gen_qemu_ld_tl(t1
, t0
, mem_idx
, MO_UB
);
3248 tcg_gen_andi_tl(t1
, t0
, 3);
3249 #ifdef TARGET_WORDS_BIGENDIAN
3250 tcg_gen_xori_tl(t1
, t1
, 3);
3252 tcg_gen_shli_tl(t1
, t1
, 3);
3253 tcg_gen_andi_tl(t0
, t0
, ~3);
3254 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEUL
);
3255 tcg_gen_shr_tl(t0
, t0
, t1
);
3256 tcg_gen_xori_tl(t1
, t1
, 31);
3257 t2
= tcg_const_tl(0xfffffffeull
);
3258 tcg_gen_shl_tl(t2
, t2
, t1
);
3259 gen_load_gpr(t1
, rt
);
3260 tcg_gen_and_tl(t1
, t1
, t2
);
3262 tcg_gen_or_tl(t0
, t0
, t1
);
3264 tcg_gen_ext32s_tl(t0
, t0
);
3265 gen_store_gpr(t0
, rt
);
3268 mem_idx
= MIPS_HFLAG_UM
;
3272 op_ld_ll(t0
, t0
, mem_idx
, ctx
);
3273 gen_store_gpr(t0
, rt
);
3279 static void gen_llwp(DisasContext
*ctx
, uint32_t base
, int16_t offset
,
3280 uint32_t reg1
, uint32_t reg2
)
3282 TCGv taddr
= tcg_temp_new();
3283 TCGv_i64 tval
= tcg_temp_new_i64();
3284 TCGv tmp1
= tcg_temp_new();
3285 TCGv tmp2
= tcg_temp_new();
3287 gen_base_offset_addr(ctx
, taddr
, base
, offset
);
3288 tcg_gen_qemu_ld64(tval
, taddr
, ctx
->mem_idx
);
3289 #ifdef TARGET_WORDS_BIGENDIAN
3290 tcg_gen_extr_i64_tl(tmp2
, tmp1
, tval
);
3292 tcg_gen_extr_i64_tl(tmp1
, tmp2
, tval
);
3294 gen_store_gpr(tmp1
, reg1
);
3295 tcg_temp_free(tmp1
);
3296 gen_store_gpr(tmp2
, reg2
);
3297 tcg_temp_free(tmp2
);
3298 tcg_gen_st_i64(tval
, cpu_env
, offsetof(CPUMIPSState
, llval_wp
));
3299 tcg_temp_free_i64(tval
);
3300 tcg_gen_st_tl(taddr
, cpu_env
, offsetof(CPUMIPSState
, lladdr
));
3301 tcg_temp_free(taddr
);
3305 static void gen_st(DisasContext
*ctx
, uint32_t opc
, int rt
,
3306 int base
, int offset
)
3308 TCGv t0
= tcg_temp_new();
3309 TCGv t1
= tcg_temp_new();
3310 int mem_idx
= ctx
->mem_idx
;
3312 gen_base_offset_addr(ctx
, t0
, base
, offset
);
3313 gen_load_gpr(t1
, rt
);
3315 #if defined(TARGET_MIPS64)
3317 tcg_gen_qemu_st_tl(t1
, t0
, mem_idx
, MO_TEQ
|
3318 ctx
->default_tcg_memop_mask
);
3321 gen_helper_0e2i(sdl
, t1
, t0
, mem_idx
);
3324 gen_helper_0e2i(sdr
, t1
, t0
, mem_idx
);
3328 mem_idx
= MIPS_HFLAG_UM
;
3331 tcg_gen_qemu_st_tl(t1
, t0
, mem_idx
, MO_TEUL
|
3332 ctx
->default_tcg_memop_mask
);
3335 mem_idx
= MIPS_HFLAG_UM
;
3338 tcg_gen_qemu_st_tl(t1
, t0
, mem_idx
, MO_TEUW
|
3339 ctx
->default_tcg_memop_mask
);
3342 mem_idx
= MIPS_HFLAG_UM
;
3345 tcg_gen_qemu_st_tl(t1
, t0
, mem_idx
, MO_8
);
3348 mem_idx
= MIPS_HFLAG_UM
;
3351 gen_helper_0e2i(swl
, t1
, t0
, mem_idx
);
3354 mem_idx
= MIPS_HFLAG_UM
;
3357 gen_helper_0e2i(swr
, t1
, t0
, mem_idx
);
3365 /* Store conditional */
3366 static void gen_st_cond(DisasContext
*ctx
, int rt
, int base
, int offset
,
3367 MemOp tcg_mo
, bool eva
)
3370 TCGLabel
*l1
= gen_new_label();
3371 TCGLabel
*done
= gen_new_label();
3373 t0
= tcg_temp_new();
3374 addr
= tcg_temp_new();
3375 /* compare the address against that of the preceding LL */
3376 gen_base_offset_addr(ctx
, addr
, base
, offset
);
3377 tcg_gen_brcond_tl(TCG_COND_EQ
, addr
, cpu_lladdr
, l1
);
3378 tcg_temp_free(addr
);
3379 tcg_gen_movi_tl(t0
, 0);
3380 gen_store_gpr(t0
, rt
);
3384 /* generate cmpxchg */
3385 val
= tcg_temp_new();
3386 gen_load_gpr(val
, rt
);
3387 tcg_gen_atomic_cmpxchg_tl(t0
, cpu_lladdr
, cpu_llval
, val
,
3388 eva
? MIPS_HFLAG_UM
: ctx
->mem_idx
, tcg_mo
);
3389 tcg_gen_setcond_tl(TCG_COND_EQ
, t0
, t0
, cpu_llval
);
3390 gen_store_gpr(t0
, rt
);
3393 gen_set_label(done
);
3398 static void gen_scwp(DisasContext
*ctx
, uint32_t base
, int16_t offset
,
3399 uint32_t reg1
, uint32_t reg2
, bool eva
)
3401 TCGv taddr
= tcg_temp_local_new();
3402 TCGv lladdr
= tcg_temp_local_new();
3403 TCGv_i64 tval
= tcg_temp_new_i64();
3404 TCGv_i64 llval
= tcg_temp_new_i64();
3405 TCGv_i64 val
= tcg_temp_new_i64();
3406 TCGv tmp1
= tcg_temp_new();
3407 TCGv tmp2
= tcg_temp_new();
3408 TCGLabel
*lab_fail
= gen_new_label();
3409 TCGLabel
*lab_done
= gen_new_label();
3411 gen_base_offset_addr(ctx
, taddr
, base
, offset
);
3413 tcg_gen_ld_tl(lladdr
, cpu_env
, offsetof(CPUMIPSState
, lladdr
));
3414 tcg_gen_brcond_tl(TCG_COND_NE
, taddr
, lladdr
, lab_fail
);
3416 gen_load_gpr(tmp1
, reg1
);
3417 gen_load_gpr(tmp2
, reg2
);
3419 #ifdef TARGET_WORDS_BIGENDIAN
3420 tcg_gen_concat_tl_i64(tval
, tmp2
, tmp1
);
3422 tcg_gen_concat_tl_i64(tval
, tmp1
, tmp2
);
3425 tcg_gen_ld_i64(llval
, cpu_env
, offsetof(CPUMIPSState
, llval_wp
));
3426 tcg_gen_atomic_cmpxchg_i64(val
, taddr
, llval
, tval
,
3427 eva
? MIPS_HFLAG_UM
: ctx
->mem_idx
, MO_64
);
3429 tcg_gen_movi_tl(cpu_gpr
[reg1
], 1);
3431 tcg_gen_brcond_i64(TCG_COND_EQ
, val
, llval
, lab_done
);
3433 gen_set_label(lab_fail
);
3436 tcg_gen_movi_tl(cpu_gpr
[reg1
], 0);
3438 gen_set_label(lab_done
);
3439 tcg_gen_movi_tl(lladdr
, -1);
3440 tcg_gen_st_tl(lladdr
, cpu_env
, offsetof(CPUMIPSState
, lladdr
));
3443 /* Load and store */
3444 static void gen_flt_ldst(DisasContext
*ctx
, uint32_t opc
, int ft
,
3448 * Don't do NOP if destination is zero: we must perform the actual
3454 TCGv_i32 fp0
= tcg_temp_new_i32();
3455 tcg_gen_qemu_ld_i32(fp0
, t0
, ctx
->mem_idx
, MO_TESL
|
3456 ctx
->default_tcg_memop_mask
);
3457 gen_store_fpr32(ctx
, fp0
, ft
);
3458 tcg_temp_free_i32(fp0
);
3463 TCGv_i32 fp0
= tcg_temp_new_i32();
3464 gen_load_fpr32(ctx
, fp0
, ft
);
3465 tcg_gen_qemu_st_i32(fp0
, t0
, ctx
->mem_idx
, MO_TEUL
|
3466 ctx
->default_tcg_memop_mask
);
3467 tcg_temp_free_i32(fp0
);
3472 TCGv_i64 fp0
= tcg_temp_new_i64();
3473 tcg_gen_qemu_ld_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
|
3474 ctx
->default_tcg_memop_mask
);
3475 gen_store_fpr64(ctx
, fp0
, ft
);
3476 tcg_temp_free_i64(fp0
);
3481 TCGv_i64 fp0
= tcg_temp_new_i64();
3482 gen_load_fpr64(ctx
, fp0
, ft
);
3483 tcg_gen_qemu_st_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
|
3484 ctx
->default_tcg_memop_mask
);
3485 tcg_temp_free_i64(fp0
);
3489 MIPS_INVAL("flt_ldst");
3490 gen_reserved_instruction(ctx
);
3495 static void gen_cop1_ldst(DisasContext
*ctx
, uint32_t op
, int rt
,
3496 int rs
, int16_t imm
)
3498 TCGv t0
= tcg_temp_new();
3500 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
3501 check_cp1_enabled(ctx
);
3505 check_insn(ctx
, ISA_MIPS2
);
3508 gen_base_offset_addr(ctx
, t0
, rs
, imm
);
3509 gen_flt_ldst(ctx
, op
, rt
, t0
);
3512 generate_exception_err(ctx
, EXCP_CpU
, 1);
3517 /* Arithmetic with immediate operand */
3518 static void gen_arith_imm(DisasContext
*ctx
, uint32_t opc
,
3519 int rt
, int rs
, int imm
)
3521 target_ulong uimm
= (target_long
)imm
; /* Sign extend to 32/64 bits */
3523 if (rt
== 0 && opc
!= OPC_ADDI
&& opc
!= OPC_DADDI
) {
3525 * If no destination, treat it as a NOP.
3526 * For addi, we must generate the overflow exception when needed.
3533 TCGv t0
= tcg_temp_local_new();
3534 TCGv t1
= tcg_temp_new();
3535 TCGv t2
= tcg_temp_new();
3536 TCGLabel
*l1
= gen_new_label();
3538 gen_load_gpr(t1
, rs
);
3539 tcg_gen_addi_tl(t0
, t1
, uimm
);
3540 tcg_gen_ext32s_tl(t0
, t0
);
3542 tcg_gen_xori_tl(t1
, t1
, ~uimm
);
3543 tcg_gen_xori_tl(t2
, t0
, uimm
);
3544 tcg_gen_and_tl(t1
, t1
, t2
);
3546 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
3548 /* operands of same sign, result different sign */
3549 generate_exception(ctx
, EXCP_OVERFLOW
);
3551 tcg_gen_ext32s_tl(t0
, t0
);
3552 gen_store_gpr(t0
, rt
);
3558 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
3559 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
3561 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
3564 #if defined(TARGET_MIPS64)
3567 TCGv t0
= tcg_temp_local_new();
3568 TCGv t1
= tcg_temp_new();
3569 TCGv t2
= tcg_temp_new();
3570 TCGLabel
*l1
= gen_new_label();
3572 gen_load_gpr(t1
, rs
);
3573 tcg_gen_addi_tl(t0
, t1
, uimm
);
3575 tcg_gen_xori_tl(t1
, t1
, ~uimm
);
3576 tcg_gen_xori_tl(t2
, t0
, uimm
);
3577 tcg_gen_and_tl(t1
, t1
, t2
);
3579 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
3581 /* operands of same sign, result different sign */
3582 generate_exception(ctx
, EXCP_OVERFLOW
);
3584 gen_store_gpr(t0
, rt
);
3590 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
3592 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
3599 /* Logic with immediate operand */
3600 static void gen_logic_imm(DisasContext
*ctx
, uint32_t opc
,
3601 int rt
, int rs
, int16_t imm
)
3606 /* If no destination, treat it as a NOP. */
3609 uimm
= (uint16_t)imm
;
3612 if (likely(rs
!= 0)) {
3613 tcg_gen_andi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
3615 tcg_gen_movi_tl(cpu_gpr
[rt
], 0);
3620 tcg_gen_ori_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
3622 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
3626 if (likely(rs
!= 0)) {
3627 tcg_gen_xori_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
3629 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
3633 if (rs
!= 0 && (ctx
->insn_flags
& ISA_MIPS_R6
)) {
3635 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], imm
<< 16);
3636 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
3638 tcg_gen_movi_tl(cpu_gpr
[rt
], imm
<< 16);
3647 /* Set on less than with immediate operand */
3648 static void gen_slt_imm(DisasContext
*ctx
, uint32_t opc
,
3649 int rt
, int rs
, int16_t imm
)
3651 target_ulong uimm
= (target_long
)imm
; /* Sign extend to 32/64 bits */
3655 /* If no destination, treat it as a NOP. */
3658 t0
= tcg_temp_new();
3659 gen_load_gpr(t0
, rs
);
3662 tcg_gen_setcondi_tl(TCG_COND_LT
, cpu_gpr
[rt
], t0
, uimm
);
3665 tcg_gen_setcondi_tl(TCG_COND_LTU
, cpu_gpr
[rt
], t0
, uimm
);
3671 /* Shifts with immediate operand */
3672 static void gen_shift_imm(DisasContext
*ctx
, uint32_t opc
,
3673 int rt
, int rs
, int16_t imm
)
3675 target_ulong uimm
= ((uint16_t)imm
) & 0x1f;
3679 /* If no destination, treat it as a NOP. */
3683 t0
= tcg_temp_new();
3684 gen_load_gpr(t0
, rs
);
3687 tcg_gen_shli_tl(t0
, t0
, uimm
);
3688 tcg_gen_ext32s_tl(cpu_gpr
[rt
], t0
);
3691 tcg_gen_sari_tl(cpu_gpr
[rt
], t0
, uimm
);
3695 tcg_gen_ext32u_tl(t0
, t0
);
3696 tcg_gen_shri_tl(cpu_gpr
[rt
], t0
, uimm
);
3698 tcg_gen_ext32s_tl(cpu_gpr
[rt
], t0
);
3703 TCGv_i32 t1
= tcg_temp_new_i32();
3705 tcg_gen_trunc_tl_i32(t1
, t0
);
3706 tcg_gen_rotri_i32(t1
, t1
, uimm
);
3707 tcg_gen_ext_i32_tl(cpu_gpr
[rt
], t1
);
3708 tcg_temp_free_i32(t1
);
3710 tcg_gen_ext32s_tl(cpu_gpr
[rt
], t0
);
3713 #if defined(TARGET_MIPS64)
3715 tcg_gen_shli_tl(cpu_gpr
[rt
], t0
, uimm
);
3718 tcg_gen_sari_tl(cpu_gpr
[rt
], t0
, uimm
);
3721 tcg_gen_shri_tl(cpu_gpr
[rt
], t0
, uimm
);
3725 tcg_gen_rotri_tl(cpu_gpr
[rt
], t0
, uimm
);
3727 tcg_gen_mov_tl(cpu_gpr
[rt
], t0
);
3731 tcg_gen_shli_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
3734 tcg_gen_sari_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
3737 tcg_gen_shri_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
3740 tcg_gen_rotri_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
3748 static void gen_arith(DisasContext
*ctx
, uint32_t opc
,
3749 int rd
, int rs
, int rt
)
3751 if (rd
== 0 && opc
!= OPC_ADD
&& opc
!= OPC_SUB
3752 && opc
!= OPC_DADD
&& opc
!= OPC_DSUB
) {
3754 * If no destination, treat it as a NOP.
3755 * For add & sub, we must generate the overflow exception when needed.
3763 TCGv t0
= tcg_temp_local_new();
3764 TCGv t1
= tcg_temp_new();
3765 TCGv t2
= tcg_temp_new();
3766 TCGLabel
*l1
= gen_new_label();
3768 gen_load_gpr(t1
, rs
);
3769 gen_load_gpr(t2
, rt
);
3770 tcg_gen_add_tl(t0
, t1
, t2
);
3771 tcg_gen_ext32s_tl(t0
, t0
);
3772 tcg_gen_xor_tl(t1
, t1
, t2
);
3773 tcg_gen_xor_tl(t2
, t0
, t2
);
3774 tcg_gen_andc_tl(t1
, t2
, t1
);
3776 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
3778 /* operands of same sign, result different sign */
3779 generate_exception(ctx
, EXCP_OVERFLOW
);
3781 gen_store_gpr(t0
, rd
);
3786 if (rs
!= 0 && rt
!= 0) {
3787 tcg_gen_add_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
3788 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3789 } else if (rs
== 0 && rt
!= 0) {
3790 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
3791 } else if (rs
!= 0 && rt
== 0) {
3792 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
3794 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3799 TCGv t0
= tcg_temp_local_new();
3800 TCGv t1
= tcg_temp_new();
3801 TCGv t2
= tcg_temp_new();
3802 TCGLabel
*l1
= gen_new_label();
3804 gen_load_gpr(t1
, rs
);
3805 gen_load_gpr(t2
, rt
);
3806 tcg_gen_sub_tl(t0
, t1
, t2
);
3807 tcg_gen_ext32s_tl(t0
, t0
);
3808 tcg_gen_xor_tl(t2
, t1
, t2
);
3809 tcg_gen_xor_tl(t1
, t0
, t1
);
3810 tcg_gen_and_tl(t1
, t1
, t2
);
3812 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
3815 * operands of different sign, first operand and the result
3818 generate_exception(ctx
, EXCP_OVERFLOW
);
3820 gen_store_gpr(t0
, rd
);
3825 if (rs
!= 0 && rt
!= 0) {
3826 tcg_gen_sub_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
3827 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3828 } else if (rs
== 0 && rt
!= 0) {
3829 tcg_gen_neg_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
3830 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3831 } else if (rs
!= 0 && rt
== 0) {
3832 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
3834 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3837 #if defined(TARGET_MIPS64)
3840 TCGv t0
= tcg_temp_local_new();
3841 TCGv t1
= tcg_temp_new();
3842 TCGv t2
= tcg_temp_new();
3843 TCGLabel
*l1
= gen_new_label();
3845 gen_load_gpr(t1
, rs
);
3846 gen_load_gpr(t2
, rt
);
3847 tcg_gen_add_tl(t0
, t1
, t2
);
3848 tcg_gen_xor_tl(t1
, t1
, t2
);
3849 tcg_gen_xor_tl(t2
, t0
, t2
);
3850 tcg_gen_andc_tl(t1
, t2
, t1
);
3852 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
3854 /* operands of same sign, result different sign */
3855 generate_exception(ctx
, EXCP_OVERFLOW
);
3857 gen_store_gpr(t0
, rd
);
3862 if (rs
!= 0 && rt
!= 0) {
3863 tcg_gen_add_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
3864 } else if (rs
== 0 && rt
!= 0) {
3865 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
3866 } else if (rs
!= 0 && rt
== 0) {
3867 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
3869 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3874 TCGv t0
= tcg_temp_local_new();
3875 TCGv t1
= tcg_temp_new();
3876 TCGv t2
= tcg_temp_new();
3877 TCGLabel
*l1
= gen_new_label();
3879 gen_load_gpr(t1
, rs
);
3880 gen_load_gpr(t2
, rt
);
3881 tcg_gen_sub_tl(t0
, t1
, t2
);
3882 tcg_gen_xor_tl(t2
, t1
, t2
);
3883 tcg_gen_xor_tl(t1
, t0
, t1
);
3884 tcg_gen_and_tl(t1
, t1
, t2
);
3886 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
3889 * Operands of different sign, first operand and result different
3892 generate_exception(ctx
, EXCP_OVERFLOW
);
3894 gen_store_gpr(t0
, rd
);
3899 if (rs
!= 0 && rt
!= 0) {
3900 tcg_gen_sub_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
3901 } else if (rs
== 0 && rt
!= 0) {
3902 tcg_gen_neg_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
3903 } else if (rs
!= 0 && rt
== 0) {
3904 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
3906 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3911 if (likely(rs
!= 0 && rt
!= 0)) {
3912 tcg_gen_mul_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
3913 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3915 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3921 /* Conditional move */
3922 static void gen_cond_move(DisasContext
*ctx
, uint32_t opc
,
3923 int rd
, int rs
, int rt
)
3928 /* If no destination, treat it as a NOP. */
3932 t0
= tcg_temp_new();
3933 gen_load_gpr(t0
, rt
);
3934 t1
= tcg_const_tl(0);
3935 t2
= tcg_temp_new();
3936 gen_load_gpr(t2
, rs
);
3939 tcg_gen_movcond_tl(TCG_COND_NE
, cpu_gpr
[rd
], t0
, t1
, t2
, cpu_gpr
[rd
]);
3942 tcg_gen_movcond_tl(TCG_COND_EQ
, cpu_gpr
[rd
], t0
, t1
, t2
, cpu_gpr
[rd
]);
3945 tcg_gen_movcond_tl(TCG_COND_NE
, cpu_gpr
[rd
], t0
, t1
, t2
, t1
);
3948 tcg_gen_movcond_tl(TCG_COND_EQ
, cpu_gpr
[rd
], t0
, t1
, t2
, t1
);
3957 static void gen_logic(DisasContext
*ctx
, uint32_t opc
,
3958 int rd
, int rs
, int rt
)
3961 /* If no destination, treat it as a NOP. */
3967 if (likely(rs
!= 0 && rt
!= 0)) {
3968 tcg_gen_and_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
3970 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3974 if (rs
!= 0 && rt
!= 0) {
3975 tcg_gen_nor_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
3976 } else if (rs
== 0 && rt
!= 0) {
3977 tcg_gen_not_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
3978 } else if (rs
!= 0 && rt
== 0) {
3979 tcg_gen_not_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
3981 tcg_gen_movi_tl(cpu_gpr
[rd
], ~((target_ulong
)0));
3985 if (likely(rs
!= 0 && rt
!= 0)) {
3986 tcg_gen_or_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
3987 } else if (rs
== 0 && rt
!= 0) {
3988 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
3989 } else if (rs
!= 0 && rt
== 0) {
3990 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
3992 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3996 if (likely(rs
!= 0 && rt
!= 0)) {
3997 tcg_gen_xor_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
3998 } else if (rs
== 0 && rt
!= 0) {
3999 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
4000 } else if (rs
!= 0 && rt
== 0) {
4001 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
4003 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4009 /* Set on lower than */
4010 static void gen_slt(DisasContext
*ctx
, uint32_t opc
,
4011 int rd
, int rs
, int rt
)
4016 /* If no destination, treat it as a NOP. */
4020 t0
= tcg_temp_new();
4021 t1
= tcg_temp_new();
4022 gen_load_gpr(t0
, rs
);
4023 gen_load_gpr(t1
, rt
);
4026 tcg_gen_setcond_tl(TCG_COND_LT
, cpu_gpr
[rd
], t0
, t1
);
4029 tcg_gen_setcond_tl(TCG_COND_LTU
, cpu_gpr
[rd
], t0
, t1
);
4037 static void gen_shift(DisasContext
*ctx
, uint32_t opc
,
4038 int rd
, int rs
, int rt
)
4044 * If no destination, treat it as a NOP.
4045 * For add & sub, we must generate the overflow exception when needed.
4050 t0
= tcg_temp_new();
4051 t1
= tcg_temp_new();
4052 gen_load_gpr(t0
, rs
);
4053 gen_load_gpr(t1
, rt
);
4056 tcg_gen_andi_tl(t0
, t0
, 0x1f);
4057 tcg_gen_shl_tl(t0
, t1
, t0
);
4058 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
4061 tcg_gen_andi_tl(t0
, t0
, 0x1f);
4062 tcg_gen_sar_tl(cpu_gpr
[rd
], t1
, t0
);
4065 tcg_gen_ext32u_tl(t1
, t1
);
4066 tcg_gen_andi_tl(t0
, t0
, 0x1f);
4067 tcg_gen_shr_tl(t0
, t1
, t0
);
4068 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
4072 TCGv_i32 t2
= tcg_temp_new_i32();
4073 TCGv_i32 t3
= tcg_temp_new_i32();
4075 tcg_gen_trunc_tl_i32(t2
, t0
);
4076 tcg_gen_trunc_tl_i32(t3
, t1
);
4077 tcg_gen_andi_i32(t2
, t2
, 0x1f);
4078 tcg_gen_rotr_i32(t2
, t3
, t2
);
4079 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
4080 tcg_temp_free_i32(t2
);
4081 tcg_temp_free_i32(t3
);
4084 #if defined(TARGET_MIPS64)
4086 tcg_gen_andi_tl(t0
, t0
, 0x3f);
4087 tcg_gen_shl_tl(cpu_gpr
[rd
], t1
, t0
);
4090 tcg_gen_andi_tl(t0
, t0
, 0x3f);
4091 tcg_gen_sar_tl(cpu_gpr
[rd
], t1
, t0
);
4094 tcg_gen_andi_tl(t0
, t0
, 0x3f);
4095 tcg_gen_shr_tl(cpu_gpr
[rd
], t1
, t0
);
4098 tcg_gen_andi_tl(t0
, t0
, 0x3f);
4099 tcg_gen_rotr_tl(cpu_gpr
[rd
], t1
, t0
);
4107 #if defined(TARGET_MIPS64)
4108 /* Copy GPR to and from TX79 HI1/LO1 register. */
4109 static void gen_HILO1_tx79(DisasContext
*ctx
, uint32_t opc
, int reg
)
4111 if (reg
== 0 && (opc
== MMI_OPC_MFHI1
|| opc
== MMI_OPC_MFLO1
)) {
4118 tcg_gen_mov_tl(cpu_gpr
[reg
], cpu_HI
[1]);
4121 tcg_gen_mov_tl(cpu_gpr
[reg
], cpu_LO
[1]);
4125 tcg_gen_mov_tl(cpu_HI
[1], cpu_gpr
[reg
]);
4127 tcg_gen_movi_tl(cpu_HI
[1], 0);
4132 tcg_gen_mov_tl(cpu_LO
[1], cpu_gpr
[reg
]);
4134 tcg_gen_movi_tl(cpu_LO
[1], 0);
4138 MIPS_INVAL("mfthilo1 TX79");
4139 gen_reserved_instruction(ctx
);
4145 /* Arithmetic on HI/LO registers */
4146 static void gen_HILO(DisasContext
*ctx
, uint32_t opc
, int acc
, int reg
)
4148 if (reg
== 0 && (opc
== OPC_MFHI
|| opc
== OPC_MFLO
)) {
4159 #if defined(TARGET_MIPS64)
4161 tcg_gen_ext32s_tl(cpu_gpr
[reg
], cpu_HI
[acc
]);
4165 tcg_gen_mov_tl(cpu_gpr
[reg
], cpu_HI
[acc
]);
4169 #if defined(TARGET_MIPS64)
4171 tcg_gen_ext32s_tl(cpu_gpr
[reg
], cpu_LO
[acc
]);
4175 tcg_gen_mov_tl(cpu_gpr
[reg
], cpu_LO
[acc
]);
4180 #if defined(TARGET_MIPS64)
4182 tcg_gen_ext32s_tl(cpu_HI
[acc
], cpu_gpr
[reg
]);
4186 tcg_gen_mov_tl(cpu_HI
[acc
], cpu_gpr
[reg
]);
4189 tcg_gen_movi_tl(cpu_HI
[acc
], 0);
4194 #if defined(TARGET_MIPS64)
4196 tcg_gen_ext32s_tl(cpu_LO
[acc
], cpu_gpr
[reg
]);
4200 tcg_gen_mov_tl(cpu_LO
[acc
], cpu_gpr
[reg
]);
4203 tcg_gen_movi_tl(cpu_LO
[acc
], 0);
4209 static inline void gen_r6_ld(target_long addr
, int reg
, int memidx
,
4212 TCGv t0
= tcg_const_tl(addr
);
4213 tcg_gen_qemu_ld_tl(t0
, t0
, memidx
, memop
);
4214 gen_store_gpr(t0
, reg
);
4218 static inline void gen_pcrel(DisasContext
*ctx
, int opc
, target_ulong pc
,
4224 switch (MASK_OPC_PCREL_TOP2BITS(opc
)) {
4227 offset
= sextract32(ctx
->opcode
<< 2, 0, 21);
4228 addr
= addr_add(ctx
, pc
, offset
);
4229 tcg_gen_movi_tl(cpu_gpr
[rs
], addr
);
4233 offset
= sextract32(ctx
->opcode
<< 2, 0, 21);
4234 addr
= addr_add(ctx
, pc
, offset
);
4235 gen_r6_ld(addr
, rs
, ctx
->mem_idx
, MO_TESL
);
4237 #if defined(TARGET_MIPS64)
4240 offset
= sextract32(ctx
->opcode
<< 2, 0, 21);
4241 addr
= addr_add(ctx
, pc
, offset
);
4242 gen_r6_ld(addr
, rs
, ctx
->mem_idx
, MO_TEUL
);
4246 switch (MASK_OPC_PCREL_TOP5BITS(opc
)) {
4249 offset
= sextract32(ctx
->opcode
, 0, 16) << 16;
4250 addr
= addr_add(ctx
, pc
, offset
);
4251 tcg_gen_movi_tl(cpu_gpr
[rs
], addr
);
4256 offset
= sextract32(ctx
->opcode
, 0, 16) << 16;
4257 addr
= ~0xFFFF & addr_add(ctx
, pc
, offset
);
4258 tcg_gen_movi_tl(cpu_gpr
[rs
], addr
);
4261 #if defined(TARGET_MIPS64)
4262 case R6_OPC_LDPC
: /* bits 16 and 17 are part of immediate */
4263 case R6_OPC_LDPC
+ (1 << 16):
4264 case R6_OPC_LDPC
+ (2 << 16):
4265 case R6_OPC_LDPC
+ (3 << 16):
4267 offset
= sextract32(ctx
->opcode
<< 3, 0, 21);
4268 addr
= addr_add(ctx
, (pc
& ~0x7), offset
);
4269 gen_r6_ld(addr
, rs
, ctx
->mem_idx
, MO_TEQ
);
4273 MIPS_INVAL("OPC_PCREL");
4274 gen_reserved_instruction(ctx
);
4281 static void gen_r6_muldiv(DisasContext
*ctx
, int opc
, int rd
, int rs
, int rt
)
4290 t0
= tcg_temp_new();
4291 t1
= tcg_temp_new();
4293 gen_load_gpr(t0
, rs
);
4294 gen_load_gpr(t1
, rt
);
4299 TCGv t2
= tcg_temp_new();
4300 TCGv t3
= tcg_temp_new();
4301 tcg_gen_ext32s_tl(t0
, t0
);
4302 tcg_gen_ext32s_tl(t1
, t1
);
4303 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, INT_MIN
);
4304 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1);
4305 tcg_gen_and_tl(t2
, t2
, t3
);
4306 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
4307 tcg_gen_or_tl(t2
, t2
, t3
);
4308 tcg_gen_movi_tl(t3
, 0);
4309 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
4310 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
4311 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
4318 TCGv t2
= tcg_temp_new();
4319 TCGv t3
= tcg_temp_new();
4320 tcg_gen_ext32s_tl(t0
, t0
);
4321 tcg_gen_ext32s_tl(t1
, t1
);
4322 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, INT_MIN
);
4323 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1);
4324 tcg_gen_and_tl(t2
, t2
, t3
);
4325 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
4326 tcg_gen_or_tl(t2
, t2
, t3
);
4327 tcg_gen_movi_tl(t3
, 0);
4328 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
4329 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
4330 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
4337 TCGv t2
= tcg_const_tl(0);
4338 TCGv t3
= tcg_const_tl(1);
4339 tcg_gen_ext32u_tl(t0
, t0
);
4340 tcg_gen_ext32u_tl(t1
, t1
);
4341 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
4342 tcg_gen_divu_tl(cpu_gpr
[rd
], t0
, t1
);
4343 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
4350 TCGv t2
= tcg_const_tl(0);
4351 TCGv t3
= tcg_const_tl(1);
4352 tcg_gen_ext32u_tl(t0
, t0
);
4353 tcg_gen_ext32u_tl(t1
, t1
);
4354 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
4355 tcg_gen_remu_tl(cpu_gpr
[rd
], t0
, t1
);
4356 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
4363 TCGv_i32 t2
= tcg_temp_new_i32();
4364 TCGv_i32 t3
= tcg_temp_new_i32();
4365 tcg_gen_trunc_tl_i32(t2
, t0
);
4366 tcg_gen_trunc_tl_i32(t3
, t1
);
4367 tcg_gen_mul_i32(t2
, t2
, t3
);
4368 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
4369 tcg_temp_free_i32(t2
);
4370 tcg_temp_free_i32(t3
);
4375 TCGv_i32 t2
= tcg_temp_new_i32();
4376 TCGv_i32 t3
= tcg_temp_new_i32();
4377 tcg_gen_trunc_tl_i32(t2
, t0
);
4378 tcg_gen_trunc_tl_i32(t3
, t1
);
4379 tcg_gen_muls2_i32(t2
, t3
, t2
, t3
);
4380 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t3
);
4381 tcg_temp_free_i32(t2
);
4382 tcg_temp_free_i32(t3
);
4387 TCGv_i32 t2
= tcg_temp_new_i32();
4388 TCGv_i32 t3
= tcg_temp_new_i32();
4389 tcg_gen_trunc_tl_i32(t2
, t0
);
4390 tcg_gen_trunc_tl_i32(t3
, t1
);
4391 tcg_gen_mul_i32(t2
, t2
, t3
);
4392 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
4393 tcg_temp_free_i32(t2
);
4394 tcg_temp_free_i32(t3
);
4399 TCGv_i32 t2
= tcg_temp_new_i32();
4400 TCGv_i32 t3
= tcg_temp_new_i32();
4401 tcg_gen_trunc_tl_i32(t2
, t0
);
4402 tcg_gen_trunc_tl_i32(t3
, t1
);
4403 tcg_gen_mulu2_i32(t2
, t3
, t2
, t3
);
4404 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t3
);
4405 tcg_temp_free_i32(t2
);
4406 tcg_temp_free_i32(t3
);
4409 #if defined(TARGET_MIPS64)
4412 TCGv t2
= tcg_temp_new();
4413 TCGv t3
= tcg_temp_new();
4414 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, -1LL << 63);
4415 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1LL);
4416 tcg_gen_and_tl(t2
, t2
, t3
);
4417 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
4418 tcg_gen_or_tl(t2
, t2
, t3
);
4419 tcg_gen_movi_tl(t3
, 0);
4420 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
4421 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
4428 TCGv t2
= tcg_temp_new();
4429 TCGv t3
= tcg_temp_new();
4430 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, -1LL << 63);
4431 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1LL);
4432 tcg_gen_and_tl(t2
, t2
, t3
);
4433 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
4434 tcg_gen_or_tl(t2
, t2
, t3
);
4435 tcg_gen_movi_tl(t3
, 0);
4436 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
4437 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
4444 TCGv t2
= tcg_const_tl(0);
4445 TCGv t3
= tcg_const_tl(1);
4446 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
4447 tcg_gen_divu_i64(cpu_gpr
[rd
], t0
, t1
);
4454 TCGv t2
= tcg_const_tl(0);
4455 TCGv t3
= tcg_const_tl(1);
4456 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
4457 tcg_gen_remu_i64(cpu_gpr
[rd
], t0
, t1
);
4463 tcg_gen_mul_i64(cpu_gpr
[rd
], t0
, t1
);
4467 TCGv t2
= tcg_temp_new();
4468 tcg_gen_muls2_i64(t2
, cpu_gpr
[rd
], t0
, t1
);
4473 tcg_gen_mul_i64(cpu_gpr
[rd
], t0
, t1
);
4477 TCGv t2
= tcg_temp_new();
4478 tcg_gen_mulu2_i64(t2
, cpu_gpr
[rd
], t0
, t1
);
4484 MIPS_INVAL("r6 mul/div");
4485 gen_reserved_instruction(ctx
);
4493 #if defined(TARGET_MIPS64)
4494 static void gen_div1_tx79(DisasContext
*ctx
, uint32_t opc
, int rs
, int rt
)
4498 t0
= tcg_temp_new();
4499 t1
= tcg_temp_new();
4501 gen_load_gpr(t0
, rs
);
4502 gen_load_gpr(t1
, rt
);
4507 TCGv t2
= tcg_temp_new();
4508 TCGv t3
= tcg_temp_new();
4509 tcg_gen_ext32s_tl(t0
, t0
);
4510 tcg_gen_ext32s_tl(t1
, t1
);
4511 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, INT_MIN
);
4512 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1);
4513 tcg_gen_and_tl(t2
, t2
, t3
);
4514 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
4515 tcg_gen_or_tl(t2
, t2
, t3
);
4516 tcg_gen_movi_tl(t3
, 0);
4517 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
4518 tcg_gen_div_tl(cpu_LO
[1], t0
, t1
);
4519 tcg_gen_rem_tl(cpu_HI
[1], t0
, t1
);
4520 tcg_gen_ext32s_tl(cpu_LO
[1], cpu_LO
[1]);
4521 tcg_gen_ext32s_tl(cpu_HI
[1], cpu_HI
[1]);
4528 TCGv t2
= tcg_const_tl(0);
4529 TCGv t3
= tcg_const_tl(1);
4530 tcg_gen_ext32u_tl(t0
, t0
);
4531 tcg_gen_ext32u_tl(t1
, t1
);
4532 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
4533 tcg_gen_divu_tl(cpu_LO
[1], t0
, t1
);
4534 tcg_gen_remu_tl(cpu_HI
[1], t0
, t1
);
4535 tcg_gen_ext32s_tl(cpu_LO
[1], cpu_LO
[1]);
4536 tcg_gen_ext32s_tl(cpu_HI
[1], cpu_HI
[1]);
4542 MIPS_INVAL("div1 TX79");
4543 gen_reserved_instruction(ctx
);
4552 static void gen_muldiv(DisasContext
*ctx
, uint32_t opc
,
4553 int acc
, int rs
, int rt
)
4557 t0
= tcg_temp_new();
4558 t1
= tcg_temp_new();
4560 gen_load_gpr(t0
, rs
);
4561 gen_load_gpr(t1
, rt
);
4570 TCGv t2
= tcg_temp_new();
4571 TCGv t3
= tcg_temp_new();
4572 tcg_gen_ext32s_tl(t0
, t0
);
4573 tcg_gen_ext32s_tl(t1
, t1
);
4574 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, INT_MIN
);
4575 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1);
4576 tcg_gen_and_tl(t2
, t2
, t3
);
4577 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
4578 tcg_gen_or_tl(t2
, t2
, t3
);
4579 tcg_gen_movi_tl(t3
, 0);
4580 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
4581 tcg_gen_div_tl(cpu_LO
[acc
], t0
, t1
);
4582 tcg_gen_rem_tl(cpu_HI
[acc
], t0
, t1
);
4583 tcg_gen_ext32s_tl(cpu_LO
[acc
], cpu_LO
[acc
]);
4584 tcg_gen_ext32s_tl(cpu_HI
[acc
], cpu_HI
[acc
]);
4591 TCGv t2
= tcg_const_tl(0);
4592 TCGv t3
= tcg_const_tl(1);
4593 tcg_gen_ext32u_tl(t0
, t0
);
4594 tcg_gen_ext32u_tl(t1
, t1
);
4595 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
4596 tcg_gen_divu_tl(cpu_LO
[acc
], t0
, t1
);
4597 tcg_gen_remu_tl(cpu_HI
[acc
], t0
, t1
);
4598 tcg_gen_ext32s_tl(cpu_LO
[acc
], cpu_LO
[acc
]);
4599 tcg_gen_ext32s_tl(cpu_HI
[acc
], cpu_HI
[acc
]);
4606 TCGv_i32 t2
= tcg_temp_new_i32();
4607 TCGv_i32 t3
= tcg_temp_new_i32();
4608 tcg_gen_trunc_tl_i32(t2
, t0
);
4609 tcg_gen_trunc_tl_i32(t3
, t1
);
4610 tcg_gen_muls2_i32(t2
, t3
, t2
, t3
);
4611 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
4612 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
4613 tcg_temp_free_i32(t2
);
4614 tcg_temp_free_i32(t3
);
4619 TCGv_i32 t2
= tcg_temp_new_i32();
4620 TCGv_i32 t3
= tcg_temp_new_i32();
4621 tcg_gen_trunc_tl_i32(t2
, t0
);
4622 tcg_gen_trunc_tl_i32(t3
, t1
);
4623 tcg_gen_mulu2_i32(t2
, t3
, t2
, t3
);
4624 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
4625 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
4626 tcg_temp_free_i32(t2
);
4627 tcg_temp_free_i32(t3
);
4630 #if defined(TARGET_MIPS64)
4633 TCGv t2
= tcg_temp_new();
4634 TCGv t3
= tcg_temp_new();
4635 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, -1LL << 63);
4636 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1LL);
4637 tcg_gen_and_tl(t2
, t2
, t3
);
4638 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
4639 tcg_gen_or_tl(t2
, t2
, t3
);
4640 tcg_gen_movi_tl(t3
, 0);
4641 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
4642 tcg_gen_div_tl(cpu_LO
[acc
], t0
, t1
);
4643 tcg_gen_rem_tl(cpu_HI
[acc
], t0
, t1
);
4650 TCGv t2
= tcg_const_tl(0);
4651 TCGv t3
= tcg_const_tl(1);
4652 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
4653 tcg_gen_divu_i64(cpu_LO
[acc
], t0
, t1
);
4654 tcg_gen_remu_i64(cpu_HI
[acc
], t0
, t1
);
4660 tcg_gen_muls2_i64(cpu_LO
[acc
], cpu_HI
[acc
], t0
, t1
);
4663 tcg_gen_mulu2_i64(cpu_LO
[acc
], cpu_HI
[acc
], t0
, t1
);
4668 TCGv_i64 t2
= tcg_temp_new_i64();
4669 TCGv_i64 t3
= tcg_temp_new_i64();
4671 tcg_gen_ext_tl_i64(t2
, t0
);
4672 tcg_gen_ext_tl_i64(t3
, t1
);
4673 tcg_gen_mul_i64(t2
, t2
, t3
);
4674 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
4675 tcg_gen_add_i64(t2
, t2
, t3
);
4676 tcg_temp_free_i64(t3
);
4677 gen_move_low32(cpu_LO
[acc
], t2
);
4678 gen_move_high32(cpu_HI
[acc
], t2
);
4679 tcg_temp_free_i64(t2
);
4684 TCGv_i64 t2
= tcg_temp_new_i64();
4685 TCGv_i64 t3
= tcg_temp_new_i64();
4687 tcg_gen_ext32u_tl(t0
, t0
);
4688 tcg_gen_ext32u_tl(t1
, t1
);
4689 tcg_gen_extu_tl_i64(t2
, t0
);
4690 tcg_gen_extu_tl_i64(t3
, t1
);
4691 tcg_gen_mul_i64(t2
, t2
, t3
);
4692 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
4693 tcg_gen_add_i64(t2
, t2
, t3
);
4694 tcg_temp_free_i64(t3
);
4695 gen_move_low32(cpu_LO
[acc
], t2
);
4696 gen_move_high32(cpu_HI
[acc
], t2
);
4697 tcg_temp_free_i64(t2
);
4702 TCGv_i64 t2
= tcg_temp_new_i64();
4703 TCGv_i64 t3
= tcg_temp_new_i64();
4705 tcg_gen_ext_tl_i64(t2
, t0
);
4706 tcg_gen_ext_tl_i64(t3
, t1
);
4707 tcg_gen_mul_i64(t2
, t2
, t3
);
4708 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
4709 tcg_gen_sub_i64(t2
, t3
, t2
);
4710 tcg_temp_free_i64(t3
);
4711 gen_move_low32(cpu_LO
[acc
], t2
);
4712 gen_move_high32(cpu_HI
[acc
], t2
);
4713 tcg_temp_free_i64(t2
);
4718 TCGv_i64 t2
= tcg_temp_new_i64();
4719 TCGv_i64 t3
= tcg_temp_new_i64();
4721 tcg_gen_ext32u_tl(t0
, t0
);
4722 tcg_gen_ext32u_tl(t1
, t1
);
4723 tcg_gen_extu_tl_i64(t2
, t0
);
4724 tcg_gen_extu_tl_i64(t3
, t1
);
4725 tcg_gen_mul_i64(t2
, t2
, t3
);
4726 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
4727 tcg_gen_sub_i64(t2
, t3
, t2
);
4728 tcg_temp_free_i64(t3
);
4729 gen_move_low32(cpu_LO
[acc
], t2
);
4730 gen_move_high32(cpu_HI
[acc
], t2
);
4731 tcg_temp_free_i64(t2
);
4735 MIPS_INVAL("mul/div");
4736 gen_reserved_instruction(ctx
);
4745 * These MULT[U] and MADD[U] instructions implemented in for example
4746 * the Toshiba/Sony R5900 and the Toshiba TX19, TX39 and TX79 core
4747 * architectures are special three-operand variants with the syntax
4749 * MULT[U][1] rd, rs, rt
4753 * (rd, LO, HI) <- rs * rt
4757 * MADD[U][1] rd, rs, rt
4761 * (rd, LO, HI) <- (LO, HI) + rs * rt
4763 * where the low-order 32-bits of the result is placed into both the
4764 * GPR rd and the special register LO. The high-order 32-bits of the
4765 * result is placed into the special register HI.
4767 * If the GPR rd is omitted in assembly language, it is taken to be 0,
4768 * which is the zero register that always reads as 0.
4770 static void gen_mul_txx9(DisasContext
*ctx
, uint32_t opc
,
4771 int rd
, int rs
, int rt
)
4773 TCGv t0
= tcg_temp_new();
4774 TCGv t1
= tcg_temp_new();
4777 gen_load_gpr(t0
, rs
);
4778 gen_load_gpr(t1
, rt
);
4786 TCGv_i32 t2
= tcg_temp_new_i32();
4787 TCGv_i32 t3
= tcg_temp_new_i32();
4788 tcg_gen_trunc_tl_i32(t2
, t0
);
4789 tcg_gen_trunc_tl_i32(t3
, t1
);
4790 tcg_gen_muls2_i32(t2
, t3
, t2
, t3
);
4792 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
4794 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
4795 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
4796 tcg_temp_free_i32(t2
);
4797 tcg_temp_free_i32(t3
);
4800 case MMI_OPC_MULTU1
:
4805 TCGv_i32 t2
= tcg_temp_new_i32();
4806 TCGv_i32 t3
= tcg_temp_new_i32();
4807 tcg_gen_trunc_tl_i32(t2
, t0
);
4808 tcg_gen_trunc_tl_i32(t3
, t1
);
4809 tcg_gen_mulu2_i32(t2
, t3
, t2
, t3
);
4811 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
4813 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
4814 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
4815 tcg_temp_free_i32(t2
);
4816 tcg_temp_free_i32(t3
);
4824 TCGv_i64 t2
= tcg_temp_new_i64();
4825 TCGv_i64 t3
= tcg_temp_new_i64();
4827 tcg_gen_ext_tl_i64(t2
, t0
);
4828 tcg_gen_ext_tl_i64(t3
, t1
);
4829 tcg_gen_mul_i64(t2
, t2
, t3
);
4830 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
4831 tcg_gen_add_i64(t2
, t2
, t3
);
4832 tcg_temp_free_i64(t3
);
4833 gen_move_low32(cpu_LO
[acc
], t2
);
4834 gen_move_high32(cpu_HI
[acc
], t2
);
4836 gen_move_low32(cpu_gpr
[rd
], t2
);
4838 tcg_temp_free_i64(t2
);
4841 case MMI_OPC_MADDU1
:
4846 TCGv_i64 t2
= tcg_temp_new_i64();
4847 TCGv_i64 t3
= tcg_temp_new_i64();
4849 tcg_gen_ext32u_tl(t0
, t0
);
4850 tcg_gen_ext32u_tl(t1
, t1
);
4851 tcg_gen_extu_tl_i64(t2
, t0
);
4852 tcg_gen_extu_tl_i64(t3
, t1
);
4853 tcg_gen_mul_i64(t2
, t2
, t3
);
4854 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
4855 tcg_gen_add_i64(t2
, t2
, t3
);
4856 tcg_temp_free_i64(t3
);
4857 gen_move_low32(cpu_LO
[acc
], t2
);
4858 gen_move_high32(cpu_HI
[acc
], t2
);
4860 gen_move_low32(cpu_gpr
[rd
], t2
);
4862 tcg_temp_free_i64(t2
);
4866 MIPS_INVAL("mul/madd TXx9");
4867 gen_reserved_instruction(ctx
);
4876 static void gen_mul_vr54xx(DisasContext
*ctx
, uint32_t opc
,
4877 int rd
, int rs
, int rt
)
4879 TCGv t0
= tcg_temp_new();
4880 TCGv t1
= tcg_temp_new();
4882 gen_load_gpr(t0
, rs
);
4883 gen_load_gpr(t1
, rt
);
4886 case OPC_VR54XX_MULS
:
4887 gen_helper_muls(t0
, cpu_env
, t0
, t1
);
4889 case OPC_VR54XX_MULSU
:
4890 gen_helper_mulsu(t0
, cpu_env
, t0
, t1
);
4892 case OPC_VR54XX_MACC
:
4893 gen_helper_macc(t0
, cpu_env
, t0
, t1
);
4895 case OPC_VR54XX_MACCU
:
4896 gen_helper_maccu(t0
, cpu_env
, t0
, t1
);
4898 case OPC_VR54XX_MSAC
:
4899 gen_helper_msac(t0
, cpu_env
, t0
, t1
);
4901 case OPC_VR54XX_MSACU
:
4902 gen_helper_msacu(t0
, cpu_env
, t0
, t1
);
4904 case OPC_VR54XX_MULHI
:
4905 gen_helper_mulhi(t0
, cpu_env
, t0
, t1
);
4907 case OPC_VR54XX_MULHIU
:
4908 gen_helper_mulhiu(t0
, cpu_env
, t0
, t1
);
4910 case OPC_VR54XX_MULSHI
:
4911 gen_helper_mulshi(t0
, cpu_env
, t0
, t1
);
4913 case OPC_VR54XX_MULSHIU
:
4914 gen_helper_mulshiu(t0
, cpu_env
, t0
, t1
);
4916 case OPC_VR54XX_MACCHI
:
4917 gen_helper_macchi(t0
, cpu_env
, t0
, t1
);
4919 case OPC_VR54XX_MACCHIU
:
4920 gen_helper_macchiu(t0
, cpu_env
, t0
, t1
);
4922 case OPC_VR54XX_MSACHI
:
4923 gen_helper_msachi(t0
, cpu_env
, t0
, t1
);
4925 case OPC_VR54XX_MSACHIU
:
4926 gen_helper_msachiu(t0
, cpu_env
, t0
, t1
);
4929 MIPS_INVAL("mul vr54xx");
4930 gen_reserved_instruction(ctx
);
4933 gen_store_gpr(t0
, rd
);
4940 static void gen_cl(DisasContext
*ctx
, uint32_t opc
,
4950 gen_load_gpr(t0
, rs
);
4955 #if defined(TARGET_MIPS64)
4959 tcg_gen_not_tl(t0
, t0
);
4968 tcg_gen_ext32u_tl(t0
, t0
);
4969 tcg_gen_clzi_tl(t0
, t0
, TARGET_LONG_BITS
);
4970 tcg_gen_subi_tl(t0
, t0
, TARGET_LONG_BITS
- 32);
4972 #if defined(TARGET_MIPS64)
4977 tcg_gen_clzi_i64(t0
, t0
, 64);
4983 /* Godson integer instructions */
4984 static void gen_loongson_integer(DisasContext
*ctx
, uint32_t opc
,
4985 int rd
, int rs
, int rt
)
4997 case OPC_MULTU_G_2E
:
4998 case OPC_MULTU_G_2F
:
4999 #if defined(TARGET_MIPS64)
5000 case OPC_DMULT_G_2E
:
5001 case OPC_DMULT_G_2F
:
5002 case OPC_DMULTU_G_2E
:
5003 case OPC_DMULTU_G_2F
:
5005 t0
= tcg_temp_new();
5006 t1
= tcg_temp_new();
5009 t0
= tcg_temp_local_new();
5010 t1
= tcg_temp_local_new();
5014 gen_load_gpr(t0
, rs
);
5015 gen_load_gpr(t1
, rt
);
5020 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
5021 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
5023 case OPC_MULTU_G_2E
:
5024 case OPC_MULTU_G_2F
:
5025 tcg_gen_ext32u_tl(t0
, t0
);
5026 tcg_gen_ext32u_tl(t1
, t1
);
5027 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
5028 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
5033 TCGLabel
*l1
= gen_new_label();
5034 TCGLabel
*l2
= gen_new_label();
5035 TCGLabel
*l3
= gen_new_label();
5036 tcg_gen_ext32s_tl(t0
, t0
);
5037 tcg_gen_ext32s_tl(t1
, t1
);
5038 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
5039 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
5042 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, INT_MIN
, l2
);
5043 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1, l2
);
5044 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
5047 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
5048 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
5055 TCGLabel
*l1
= gen_new_label();
5056 TCGLabel
*l2
= gen_new_label();
5057 tcg_gen_ext32u_tl(t0
, t0
);
5058 tcg_gen_ext32u_tl(t1
, t1
);
5059 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
5060 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
5063 tcg_gen_divu_tl(cpu_gpr
[rd
], t0
, t1
);
5064 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
5071 TCGLabel
*l1
= gen_new_label();
5072 TCGLabel
*l2
= gen_new_label();
5073 TCGLabel
*l3
= gen_new_label();
5074 tcg_gen_ext32u_tl(t0
, t0
);
5075 tcg_gen_ext32u_tl(t1
, t1
);
5076 tcg_gen_brcondi_tl(TCG_COND_EQ
, t1
, 0, l1
);
5077 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, INT_MIN
, l2
);
5078 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1, l2
);
5080 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
5083 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
5084 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
5091 TCGLabel
*l1
= gen_new_label();
5092 TCGLabel
*l2
= gen_new_label();
5093 tcg_gen_ext32u_tl(t0
, t0
);
5094 tcg_gen_ext32u_tl(t1
, t1
);
5095 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
5096 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
5099 tcg_gen_remu_tl(cpu_gpr
[rd
], t0
, t1
);
5100 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
5104 #if defined(TARGET_MIPS64)
5105 case OPC_DMULT_G_2E
:
5106 case OPC_DMULT_G_2F
:
5107 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
5109 case OPC_DMULTU_G_2E
:
5110 case OPC_DMULTU_G_2F
:
5111 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
5116 TCGLabel
*l1
= gen_new_label();
5117 TCGLabel
*l2
= gen_new_label();
5118 TCGLabel
*l3
= gen_new_label();
5119 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
5120 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
5123 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, -1LL << 63, l2
);
5124 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1LL, l2
);
5125 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
5128 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
5132 case OPC_DDIVU_G_2E
:
5133 case OPC_DDIVU_G_2F
:
5135 TCGLabel
*l1
= gen_new_label();
5136 TCGLabel
*l2
= gen_new_label();
5137 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
5138 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
5141 tcg_gen_divu_tl(cpu_gpr
[rd
], t0
, t1
);
5148 TCGLabel
*l1
= gen_new_label();
5149 TCGLabel
*l2
= gen_new_label();
5150 TCGLabel
*l3
= gen_new_label();
5151 tcg_gen_brcondi_tl(TCG_COND_EQ
, t1
, 0, l1
);
5152 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, -1LL << 63, l2
);
5153 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1LL, l2
);
5155 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
5158 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
5162 case OPC_DMODU_G_2E
:
5163 case OPC_DMODU_G_2F
:
5165 TCGLabel
*l1
= gen_new_label();
5166 TCGLabel
*l2
= gen_new_label();
5167 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
5168 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
5171 tcg_gen_remu_tl(cpu_gpr
[rd
], t0
, t1
);
5182 /* Loongson multimedia instructions */
5183 static void gen_loongson_multimedia(DisasContext
*ctx
, int rd
, int rs
, int rt
)
5185 uint32_t opc
, shift_max
;
5189 opc
= MASK_LMMI(ctx
->opcode
);
5195 t0
= tcg_temp_local_new_i64();
5196 t1
= tcg_temp_local_new_i64();
5199 t0
= tcg_temp_new_i64();
5200 t1
= tcg_temp_new_i64();
5204 check_cp1_enabled(ctx
);
5205 gen_load_fpr64(ctx
, t0
, rs
);
5206 gen_load_fpr64(ctx
, t1
, rt
);
5210 gen_helper_paddsh(t0
, t0
, t1
);
5213 gen_helper_paddush(t0
, t0
, t1
);
5216 gen_helper_paddh(t0
, t0
, t1
);
5219 gen_helper_paddw(t0
, t0
, t1
);
5222 gen_helper_paddsb(t0
, t0
, t1
);
5225 gen_helper_paddusb(t0
, t0
, t1
);
5228 gen_helper_paddb(t0
, t0
, t1
);
5232 gen_helper_psubsh(t0
, t0
, t1
);
5235 gen_helper_psubush(t0
, t0
, t1
);
5238 gen_helper_psubh(t0
, t0
, t1
);
5241 gen_helper_psubw(t0
, t0
, t1
);
5244 gen_helper_psubsb(t0
, t0
, t1
);
5247 gen_helper_psubusb(t0
, t0
, t1
);
5250 gen_helper_psubb(t0
, t0
, t1
);
5254 gen_helper_pshufh(t0
, t0
, t1
);
5257 gen_helper_packsswh(t0
, t0
, t1
);
5260 gen_helper_packsshb(t0
, t0
, t1
);
5263 gen_helper_packushb(t0
, t0
, t1
);
5267 gen_helper_punpcklhw(t0
, t0
, t1
);
5270 gen_helper_punpckhhw(t0
, t0
, t1
);
5273 gen_helper_punpcklbh(t0
, t0
, t1
);
5276 gen_helper_punpckhbh(t0
, t0
, t1
);
5279 gen_helper_punpcklwd(t0
, t0
, t1
);
5282 gen_helper_punpckhwd(t0
, t0
, t1
);
5286 gen_helper_pavgh(t0
, t0
, t1
);
5289 gen_helper_pavgb(t0
, t0
, t1
);
5292 gen_helper_pmaxsh(t0
, t0
, t1
);
5295 gen_helper_pminsh(t0
, t0
, t1
);
5298 gen_helper_pmaxub(t0
, t0
, t1
);
5301 gen_helper_pminub(t0
, t0
, t1
);
5305 gen_helper_pcmpeqw(t0
, t0
, t1
);
5308 gen_helper_pcmpgtw(t0
, t0
, t1
);
5311 gen_helper_pcmpeqh(t0
, t0
, t1
);
5314 gen_helper_pcmpgth(t0
, t0
, t1
);
5317 gen_helper_pcmpeqb(t0
, t0
, t1
);
5320 gen_helper_pcmpgtb(t0
, t0
, t1
);
5324 gen_helper_psllw(t0
, t0
, t1
);
5327 gen_helper_psllh(t0
, t0
, t1
);
5330 gen_helper_psrlw(t0
, t0
, t1
);
5333 gen_helper_psrlh(t0
, t0
, t1
);
5336 gen_helper_psraw(t0
, t0
, t1
);
5339 gen_helper_psrah(t0
, t0
, t1
);
5343 gen_helper_pmullh(t0
, t0
, t1
);
5346 gen_helper_pmulhh(t0
, t0
, t1
);
5349 gen_helper_pmulhuh(t0
, t0
, t1
);
5352 gen_helper_pmaddhw(t0
, t0
, t1
);
5356 gen_helper_pasubub(t0
, t0
, t1
);
5359 gen_helper_biadd(t0
, t0
);
5362 gen_helper_pmovmskb(t0
, t0
);
5366 tcg_gen_add_i64(t0
, t0
, t1
);
5369 tcg_gen_sub_i64(t0
, t0
, t1
);
5372 tcg_gen_xor_i64(t0
, t0
, t1
);
5375 tcg_gen_nor_i64(t0
, t0
, t1
);
5378 tcg_gen_and_i64(t0
, t0
, t1
);
5381 tcg_gen_or_i64(t0
, t0
, t1
);
5385 tcg_gen_andc_i64(t0
, t1
, t0
);
5389 tcg_gen_deposit_i64(t0
, t0
, t1
, 0, 16);
5392 tcg_gen_deposit_i64(t0
, t0
, t1
, 16, 16);
5395 tcg_gen_deposit_i64(t0
, t0
, t1
, 32, 16);
5398 tcg_gen_deposit_i64(t0
, t0
, t1
, 48, 16);
5402 tcg_gen_andi_i64(t1
, t1
, 3);
5403 tcg_gen_shli_i64(t1
, t1
, 4);
5404 tcg_gen_shr_i64(t0
, t0
, t1
);
5405 tcg_gen_ext16u_i64(t0
, t0
);
5409 tcg_gen_add_i64(t0
, t0
, t1
);
5410 tcg_gen_ext32s_i64(t0
, t0
);
5413 tcg_gen_sub_i64(t0
, t0
, t1
);
5414 tcg_gen_ext32s_i64(t0
, t0
);
5436 /* Make sure shift count isn't TCG undefined behaviour. */
5437 tcg_gen_andi_i64(t1
, t1
, shift_max
- 1);
5442 tcg_gen_shl_i64(t0
, t0
, t1
);
5447 * Since SRA is UndefinedResult without sign-extended inputs,
5448 * we can treat SRA and DSRA the same.
5450 tcg_gen_sar_i64(t0
, t0
, t1
);
5453 /* We want to shift in zeros for SRL; zero-extend first. */
5454 tcg_gen_ext32u_i64(t0
, t0
);
5457 tcg_gen_shr_i64(t0
, t0
, t1
);
5461 if (shift_max
== 32) {
5462 tcg_gen_ext32s_i64(t0
, t0
);
5465 /* Shifts larger than MAX produce zero. */
5466 tcg_gen_setcondi_i64(TCG_COND_LTU
, t1
, t1
, shift_max
);
5467 tcg_gen_neg_i64(t1
, t1
);
5468 tcg_gen_and_i64(t0
, t0
, t1
);
5474 TCGv_i64 t2
= tcg_temp_new_i64();
5475 TCGLabel
*lab
= gen_new_label();
5477 tcg_gen_mov_i64(t2
, t0
);
5478 tcg_gen_add_i64(t0
, t1
, t2
);
5479 if (opc
== OPC_ADD_CP2
) {
5480 tcg_gen_ext32s_i64(t0
, t0
);
5482 tcg_gen_xor_i64(t1
, t1
, t2
);
5483 tcg_gen_xor_i64(t2
, t2
, t0
);
5484 tcg_gen_andc_i64(t1
, t2
, t1
);
5485 tcg_temp_free_i64(t2
);
5486 tcg_gen_brcondi_i64(TCG_COND_GE
, t1
, 0, lab
);
5487 generate_exception(ctx
, EXCP_OVERFLOW
);
5495 TCGv_i64 t2
= tcg_temp_new_i64();
5496 TCGLabel
*lab
= gen_new_label();
5498 tcg_gen_mov_i64(t2
, t0
);
5499 tcg_gen_sub_i64(t0
, t1
, t2
);
5500 if (opc
== OPC_SUB_CP2
) {
5501 tcg_gen_ext32s_i64(t0
, t0
);
5503 tcg_gen_xor_i64(t1
, t1
, t2
);
5504 tcg_gen_xor_i64(t2
, t2
, t0
);
5505 tcg_gen_and_i64(t1
, t1
, t2
);
5506 tcg_temp_free_i64(t2
);
5507 tcg_gen_brcondi_i64(TCG_COND_GE
, t1
, 0, lab
);
5508 generate_exception(ctx
, EXCP_OVERFLOW
);
5514 tcg_gen_ext32u_i64(t0
, t0
);
5515 tcg_gen_ext32u_i64(t1
, t1
);
5516 tcg_gen_mul_i64(t0
, t0
, t1
);
5525 cond
= TCG_COND_LTU
;
5533 cond
= TCG_COND_LEU
;
5540 int cc
= (ctx
->opcode
>> 8) & 0x7;
5541 TCGv_i64 t64
= tcg_temp_new_i64();
5542 TCGv_i32 t32
= tcg_temp_new_i32();
5544 tcg_gen_setcond_i64(cond
, t64
, t0
, t1
);
5545 tcg_gen_extrl_i64_i32(t32
, t64
);
5546 tcg_gen_deposit_i32(fpu_fcr31
, fpu_fcr31
, t32
,
5549 tcg_temp_free_i32(t32
);
5550 tcg_temp_free_i64(t64
);
5555 MIPS_INVAL("loongson_cp2");
5556 gen_reserved_instruction(ctx
);
5560 gen_store_fpr64(ctx
, t0
, rd
);
5563 tcg_temp_free_i64(t0
);
5564 tcg_temp_free_i64(t1
);
5567 static void gen_loongson_lswc2(DisasContext
*ctx
, int rt
,
5572 #if defined(TARGET_MIPS64)
5573 int lsq_rt1
= ctx
->opcode
& 0x1f;
5574 int lsq_offset
= sextract32(ctx
->opcode
, 6, 9) << 4;
5576 int shf_offset
= sextract32(ctx
->opcode
, 6, 8);
5578 t0
= tcg_temp_new();
5580 switch (MASK_LOONGSON_GSLSQ(ctx
->opcode
)) {
5581 #if defined(TARGET_MIPS64)
5583 t1
= tcg_temp_new();
5584 gen_base_offset_addr(ctx
, t0
, rs
, lsq_offset
);
5585 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
|
5586 ctx
->default_tcg_memop_mask
);
5587 gen_base_offset_addr(ctx
, t0
, rs
, lsq_offset
+ 8);
5588 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
|
5589 ctx
->default_tcg_memop_mask
);
5590 gen_store_gpr(t1
, rt
);
5591 gen_store_gpr(t0
, lsq_rt1
);
5595 check_cp1_enabled(ctx
);
5596 t1
= tcg_temp_new();
5597 gen_base_offset_addr(ctx
, t0
, rs
, lsq_offset
);
5598 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
|
5599 ctx
->default_tcg_memop_mask
);
5600 gen_base_offset_addr(ctx
, t0
, rs
, lsq_offset
+ 8);
5601 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
|
5602 ctx
->default_tcg_memop_mask
);
5603 gen_store_fpr64(ctx
, t1
, rt
);
5604 gen_store_fpr64(ctx
, t0
, lsq_rt1
);
5608 t1
= tcg_temp_new();
5609 gen_base_offset_addr(ctx
, t0
, rs
, lsq_offset
);
5610 gen_load_gpr(t1
, rt
);
5611 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
|
5612 ctx
->default_tcg_memop_mask
);
5613 gen_base_offset_addr(ctx
, t0
, rs
, lsq_offset
+ 8);
5614 gen_load_gpr(t1
, lsq_rt1
);
5615 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
|
5616 ctx
->default_tcg_memop_mask
);
5620 check_cp1_enabled(ctx
);
5621 t1
= tcg_temp_new();
5622 gen_base_offset_addr(ctx
, t0
, rs
, lsq_offset
);
5623 gen_load_fpr64(ctx
, t1
, rt
);
5624 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
|
5625 ctx
->default_tcg_memop_mask
);
5626 gen_base_offset_addr(ctx
, t0
, rs
, lsq_offset
+ 8);
5627 gen_load_fpr64(ctx
, t1
, lsq_rt1
);
5628 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
|
5629 ctx
->default_tcg_memop_mask
);
5634 switch (MASK_LOONGSON_GSSHFLS(ctx
->opcode
)) {
5636 check_cp1_enabled(ctx
);
5637 gen_base_offset_addr(ctx
, t0
, rs
, shf_offset
);
5638 t1
= tcg_temp_new();
5639 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
5640 tcg_gen_andi_tl(t1
, t0
, 3);
5641 #ifndef TARGET_WORDS_BIGENDIAN
5642 tcg_gen_xori_tl(t1
, t1
, 3);
5644 tcg_gen_shli_tl(t1
, t1
, 3);
5645 tcg_gen_andi_tl(t0
, t0
, ~3);
5646 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEUL
);
5647 tcg_gen_shl_tl(t0
, t0
, t1
);
5648 t2
= tcg_const_tl(-1);
5649 tcg_gen_shl_tl(t2
, t2
, t1
);
5650 fp0
= tcg_temp_new_i32();
5651 gen_load_fpr32(ctx
, fp0
, rt
);
5652 tcg_gen_ext_i32_tl(t1
, fp0
);
5653 tcg_gen_andc_tl(t1
, t1
, t2
);
5655 tcg_gen_or_tl(t0
, t0
, t1
);
5657 #if defined(TARGET_MIPS64)
5658 tcg_gen_extrl_i64_i32(fp0
, t0
);
5660 tcg_gen_ext32s_tl(fp0
, t0
);
5662 gen_store_fpr32(ctx
, fp0
, rt
);
5663 tcg_temp_free_i32(fp0
);
5666 check_cp1_enabled(ctx
);
5667 gen_base_offset_addr(ctx
, t0
, rs
, shf_offset
);
5668 t1
= tcg_temp_new();
5669 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
5670 tcg_gen_andi_tl(t1
, t0
, 3);
5671 #ifdef TARGET_WORDS_BIGENDIAN
5672 tcg_gen_xori_tl(t1
, t1
, 3);
5674 tcg_gen_shli_tl(t1
, t1
, 3);
5675 tcg_gen_andi_tl(t0
, t0
, ~3);
5676 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEUL
);
5677 tcg_gen_shr_tl(t0
, t0
, t1
);
5678 tcg_gen_xori_tl(t1
, t1
, 31);
5679 t2
= tcg_const_tl(0xfffffffeull
);
5680 tcg_gen_shl_tl(t2
, t2
, t1
);
5681 fp0
= tcg_temp_new_i32();
5682 gen_load_fpr32(ctx
, fp0
, rt
);
5683 tcg_gen_ext_i32_tl(t1
, fp0
);
5684 tcg_gen_and_tl(t1
, t1
, t2
);
5686 tcg_gen_or_tl(t0
, t0
, t1
);
5688 #if defined(TARGET_MIPS64)
5689 tcg_gen_extrl_i64_i32(fp0
, t0
);
5691 tcg_gen_ext32s_tl(fp0
, t0
);
5693 gen_store_fpr32(ctx
, fp0
, rt
);
5694 tcg_temp_free_i32(fp0
);
5696 #if defined(TARGET_MIPS64)
5698 check_cp1_enabled(ctx
);
5699 gen_base_offset_addr(ctx
, t0
, rs
, shf_offset
);
5700 t1
= tcg_temp_new();
5701 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
5702 tcg_gen_andi_tl(t1
, t0
, 7);
5703 #ifndef TARGET_WORDS_BIGENDIAN
5704 tcg_gen_xori_tl(t1
, t1
, 7);
5706 tcg_gen_shli_tl(t1
, t1
, 3);
5707 tcg_gen_andi_tl(t0
, t0
, ~7);
5708 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
);
5709 tcg_gen_shl_tl(t0
, t0
, t1
);
5710 t2
= tcg_const_tl(-1);
5711 tcg_gen_shl_tl(t2
, t2
, t1
);
5712 gen_load_fpr64(ctx
, t1
, rt
);
5713 tcg_gen_andc_tl(t1
, t1
, t2
);
5715 tcg_gen_or_tl(t0
, t0
, t1
);
5717 gen_store_fpr64(ctx
, t0
, rt
);
5720 check_cp1_enabled(ctx
);
5721 gen_base_offset_addr(ctx
, t0
, rs
, shf_offset
);
5722 t1
= tcg_temp_new();
5723 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
5724 tcg_gen_andi_tl(t1
, t0
, 7);
5725 #ifdef TARGET_WORDS_BIGENDIAN
5726 tcg_gen_xori_tl(t1
, t1
, 7);
5728 tcg_gen_shli_tl(t1
, t1
, 3);
5729 tcg_gen_andi_tl(t0
, t0
, ~7);
5730 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
);
5731 tcg_gen_shr_tl(t0
, t0
, t1
);
5732 tcg_gen_xori_tl(t1
, t1
, 63);
5733 t2
= tcg_const_tl(0xfffffffffffffffeull
);
5734 tcg_gen_shl_tl(t2
, t2
, t1
);
5735 gen_load_fpr64(ctx
, t1
, rt
);
5736 tcg_gen_and_tl(t1
, t1
, t2
);
5738 tcg_gen_or_tl(t0
, t0
, t1
);
5740 gen_store_fpr64(ctx
, t0
, rt
);
5744 MIPS_INVAL("loongson_gsshfl");
5745 gen_reserved_instruction(ctx
);
5750 switch (MASK_LOONGSON_GSSHFLS(ctx
->opcode
)) {
5752 check_cp1_enabled(ctx
);
5753 t1
= tcg_temp_new();
5754 gen_base_offset_addr(ctx
, t0
, rs
, shf_offset
);
5755 fp0
= tcg_temp_new_i32();
5756 gen_load_fpr32(ctx
, fp0
, rt
);
5757 tcg_gen_ext_i32_tl(t1
, fp0
);
5758 gen_helper_0e2i(swl
, t1
, t0
, ctx
->mem_idx
);
5759 tcg_temp_free_i32(fp0
);
5763 check_cp1_enabled(ctx
);
5764 t1
= tcg_temp_new();
5765 gen_base_offset_addr(ctx
, t0
, rs
, shf_offset
);
5766 fp0
= tcg_temp_new_i32();
5767 gen_load_fpr32(ctx
, fp0
, rt
);
5768 tcg_gen_ext_i32_tl(t1
, fp0
);
5769 gen_helper_0e2i(swr
, t1
, t0
, ctx
->mem_idx
);
5770 tcg_temp_free_i32(fp0
);
5773 #if defined(TARGET_MIPS64)
5775 check_cp1_enabled(ctx
);
5776 t1
= tcg_temp_new();
5777 gen_base_offset_addr(ctx
, t0
, rs
, shf_offset
);
5778 gen_load_fpr64(ctx
, t1
, rt
);
5779 gen_helper_0e2i(sdl
, t1
, t0
, ctx
->mem_idx
);
5783 check_cp1_enabled(ctx
);
5784 t1
= tcg_temp_new();
5785 gen_base_offset_addr(ctx
, t0
, rs
, shf_offset
);
5786 gen_load_fpr64(ctx
, t1
, rt
);
5787 gen_helper_0e2i(sdr
, t1
, t0
, ctx
->mem_idx
);
5792 MIPS_INVAL("loongson_gsshfs");
5793 gen_reserved_instruction(ctx
);
5798 MIPS_INVAL("loongson_gslsq");
5799 gen_reserved_instruction(ctx
);
5805 /* Loongson EXT LDC2/SDC2 */
5806 static void gen_loongson_lsdc2(DisasContext
*ctx
, int rt
,
5809 int offset
= sextract32(ctx
->opcode
, 3, 8);
5810 uint32_t opc
= MASK_LOONGSON_LSDC2(ctx
->opcode
);
5814 /* Pre-conditions */
5820 /* prefetch, implement as NOP */
5831 #if defined(TARGET_MIPS64)
5834 check_cp1_enabled(ctx
);
5835 /* prefetch, implement as NOP */
5841 #if defined(TARGET_MIPS64)
5844 check_cp1_enabled(ctx
);
5847 MIPS_INVAL("loongson_lsdc2");
5848 gen_reserved_instruction(ctx
);
5853 t0
= tcg_temp_new();
5855 gen_base_offset_addr(ctx
, t0
, rs
, offset
);
5856 gen_op_addr_add(ctx
, t0
, cpu_gpr
[rd
], t0
);
5860 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_SB
);
5861 gen_store_gpr(t0
, rt
);
5864 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESW
|
5865 ctx
->default_tcg_memop_mask
);
5866 gen_store_gpr(t0
, rt
);
5869 gen_base_offset_addr(ctx
, t0
, rs
, offset
);
5871 gen_op_addr_add(ctx
, t0
, cpu_gpr
[rd
], t0
);
5873 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESL
|
5874 ctx
->default_tcg_memop_mask
);
5875 gen_store_gpr(t0
, rt
);
5877 #if defined(TARGET_MIPS64)
5879 gen_base_offset_addr(ctx
, t0
, rs
, offset
);
5881 gen_op_addr_add(ctx
, t0
, cpu_gpr
[rd
], t0
);
5883 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
|
5884 ctx
->default_tcg_memop_mask
);
5885 gen_store_gpr(t0
, rt
);
5889 check_cp1_enabled(ctx
);
5890 gen_base_offset_addr(ctx
, t0
, rs
, offset
);
5892 gen_op_addr_add(ctx
, t0
, cpu_gpr
[rd
], t0
);
5894 fp0
= tcg_temp_new_i32();
5895 tcg_gen_qemu_ld_i32(fp0
, t0
, ctx
->mem_idx
, MO_TESL
|
5896 ctx
->default_tcg_memop_mask
);
5897 gen_store_fpr32(ctx
, fp0
, rt
);
5898 tcg_temp_free_i32(fp0
);
5900 #if defined(TARGET_MIPS64)
5902 check_cp1_enabled(ctx
);
5903 gen_base_offset_addr(ctx
, t0
, rs
, offset
);
5905 gen_op_addr_add(ctx
, t0
, cpu_gpr
[rd
], t0
);
5907 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
|
5908 ctx
->default_tcg_memop_mask
);
5909 gen_store_fpr64(ctx
, t0
, rt
);
5913 t1
= tcg_temp_new();
5914 gen_load_gpr(t1
, rt
);
5915 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_SB
);
5919 t1
= tcg_temp_new();
5920 gen_load_gpr(t1
, rt
);
5921 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUW
|
5922 ctx
->default_tcg_memop_mask
);
5926 t1
= tcg_temp_new();
5927 gen_load_gpr(t1
, rt
);
5928 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
|
5929 ctx
->default_tcg_memop_mask
);
5932 #if defined(TARGET_MIPS64)
5934 t1
= tcg_temp_new();
5935 gen_load_gpr(t1
, rt
);
5936 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
|
5937 ctx
->default_tcg_memop_mask
);
5942 fp0
= tcg_temp_new_i32();
5943 gen_load_fpr32(ctx
, fp0
, rt
);
5944 tcg_gen_qemu_st_i32(fp0
, t0
, ctx
->mem_idx
, MO_TEUL
|
5945 ctx
->default_tcg_memop_mask
);
5946 tcg_temp_free_i32(fp0
);
5948 #if defined(TARGET_MIPS64)
5950 t1
= tcg_temp_new();
5951 gen_load_fpr64(ctx
, t1
, rt
);
5952 tcg_gen_qemu_st_i64(t1
, t0
, ctx
->mem_idx
, MO_TEQ
|
5953 ctx
->default_tcg_memop_mask
);
5965 static void gen_trap(DisasContext
*ctx
, uint32_t opc
,
5966 int rs
, int rt
, int16_t imm
)
5969 TCGv t0
= tcg_temp_new();
5970 TCGv t1
= tcg_temp_new();
5973 /* Load needed operands */
5981 /* Compare two registers */
5983 gen_load_gpr(t0
, rs
);
5984 gen_load_gpr(t1
, rt
);
5994 /* Compare register to immediate */
5995 if (rs
!= 0 || imm
!= 0) {
5996 gen_load_gpr(t0
, rs
);
5997 tcg_gen_movi_tl(t1
, (int32_t)imm
);
6004 case OPC_TEQ
: /* rs == rs */
6005 case OPC_TEQI
: /* r0 == 0 */
6006 case OPC_TGE
: /* rs >= rs */
6007 case OPC_TGEI
: /* r0 >= 0 */
6008 case OPC_TGEU
: /* rs >= rs unsigned */
6009 case OPC_TGEIU
: /* r0 >= 0 unsigned */
6011 generate_exception_end(ctx
, EXCP_TRAP
);
6013 case OPC_TLT
: /* rs < rs */
6014 case OPC_TLTI
: /* r0 < 0 */
6015 case OPC_TLTU
: /* rs < rs unsigned */
6016 case OPC_TLTIU
: /* r0 < 0 unsigned */
6017 case OPC_TNE
: /* rs != rs */
6018 case OPC_TNEI
: /* r0 != 0 */
6019 /* Never trap: treat as NOP. */
6023 TCGLabel
*l1
= gen_new_label();
6028 tcg_gen_brcond_tl(TCG_COND_NE
, t0
, t1
, l1
);
6032 tcg_gen_brcond_tl(TCG_COND_LT
, t0
, t1
, l1
);
6036 tcg_gen_brcond_tl(TCG_COND_LTU
, t0
, t1
, l1
);
6040 tcg_gen_brcond_tl(TCG_COND_GE
, t0
, t1
, l1
);
6044 tcg_gen_brcond_tl(TCG_COND_GEU
, t0
, t1
, l1
);
6048 tcg_gen_brcond_tl(TCG_COND_EQ
, t0
, t1
, l1
);
6051 generate_exception(ctx
, EXCP_TRAP
);
6058 static inline bool use_goto_tb(DisasContext
*ctx
, target_ulong dest
)
6060 if (unlikely(ctx
->base
.singlestep_enabled
)) {
6064 #ifndef CONFIG_USER_ONLY
6065 return (ctx
->base
.tb
->pc
& TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
);
6071 static inline void gen_goto_tb(DisasContext
*ctx
, int n
, target_ulong dest
)
6073 if (use_goto_tb(ctx
, dest
)) {
6076 tcg_gen_exit_tb(ctx
->base
.tb
, n
);
6079 if (ctx
->base
.singlestep_enabled
) {
6080 save_cpu_state(ctx
, 0);
6081 gen_helper_raise_exception_debug(cpu_env
);
6083 tcg_gen_lookup_and_goto_ptr();
6087 /* Branches (before delay slot) */
6088 static void gen_compute_branch(DisasContext
*ctx
, uint32_t opc
,
6090 int rs
, int rt
, int32_t offset
,
6093 target_ulong btgt
= -1;
6095 int bcond_compute
= 0;
6096 TCGv t0
= tcg_temp_new();
6097 TCGv t1
= tcg_temp_new();
6099 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
6100 #ifdef MIPS_DEBUG_DISAS
6101 LOG_DISAS("Branch in delay / forbidden slot at PC 0x"
6102 TARGET_FMT_lx
"\n", ctx
->base
.pc_next
);
6104 gen_reserved_instruction(ctx
);
6108 /* Load needed operands */
6114 /* Compare two registers */
6116 gen_load_gpr(t0
, rs
);
6117 gen_load_gpr(t1
, rt
);
6120 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ offset
;
6134 /* Compare to zero */
6136 gen_load_gpr(t0
, rs
);
6139 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ offset
;
6142 #if defined(TARGET_MIPS64)
6144 tcg_gen_andi_tl(t0
, cpu_dspctrl
, 0x7F);
6146 tcg_gen_andi_tl(t0
, cpu_dspctrl
, 0x3F);
6149 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ offset
;
6154 /* Jump to immediate */
6155 btgt
= ((ctx
->base
.pc_next
+ insn_bytes
) & (int32_t)0xF0000000) |
6160 /* Jump to register */
6161 if (offset
!= 0 && offset
!= 16) {
6163 * Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
6164 * others are reserved.
6166 MIPS_INVAL("jump hint");
6167 gen_reserved_instruction(ctx
);
6170 gen_load_gpr(btarget
, rs
);
6173 MIPS_INVAL("branch/jump");
6174 gen_reserved_instruction(ctx
);
6177 if (bcond_compute
== 0) {
6178 /* No condition to be computed */
6180 case OPC_BEQ
: /* rx == rx */
6181 case OPC_BEQL
: /* rx == rx likely */
6182 case OPC_BGEZ
: /* 0 >= 0 */
6183 case OPC_BGEZL
: /* 0 >= 0 likely */
6184 case OPC_BLEZ
: /* 0 <= 0 */
6185 case OPC_BLEZL
: /* 0 <= 0 likely */
6187 ctx
->hflags
|= MIPS_HFLAG_B
;
6189 case OPC_BGEZAL
: /* 0 >= 0 */
6190 case OPC_BGEZALL
: /* 0 >= 0 likely */
6191 /* Always take and link */
6193 ctx
->hflags
|= MIPS_HFLAG_B
;
6195 case OPC_BNE
: /* rx != rx */
6196 case OPC_BGTZ
: /* 0 > 0 */
6197 case OPC_BLTZ
: /* 0 < 0 */
6200 case OPC_BLTZAL
: /* 0 < 0 */
6202 * Handle as an unconditional branch to get correct delay
6206 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ delayslot_size
;
6207 ctx
->hflags
|= MIPS_HFLAG_B
;
6209 case OPC_BLTZALL
: /* 0 < 0 likely */
6210 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 8);
6211 /* Skip the instruction in the delay slot */
6212 ctx
->base
.pc_next
+= 4;
6214 case OPC_BNEL
: /* rx != rx likely */
6215 case OPC_BGTZL
: /* 0 > 0 likely */
6216 case OPC_BLTZL
: /* 0 < 0 likely */
6217 /* Skip the instruction in the delay slot */
6218 ctx
->base
.pc_next
+= 4;
6221 ctx
->hflags
|= MIPS_HFLAG_B
;
6224 ctx
->hflags
|= MIPS_HFLAG_BX
;
6228 ctx
->hflags
|= MIPS_HFLAG_B
;
6231 ctx
->hflags
|= MIPS_HFLAG_BR
;
6235 ctx
->hflags
|= MIPS_HFLAG_BR
;
6238 MIPS_INVAL("branch/jump");
6239 gen_reserved_instruction(ctx
);
6245 tcg_gen_setcond_tl(TCG_COND_EQ
, bcond
, t0
, t1
);
6248 tcg_gen_setcond_tl(TCG_COND_EQ
, bcond
, t0
, t1
);
6251 tcg_gen_setcond_tl(TCG_COND_NE
, bcond
, t0
, t1
);
6254 tcg_gen_setcond_tl(TCG_COND_NE
, bcond
, t0
, t1
);
6257 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
6260 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
6263 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
6267 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
6271 tcg_gen_setcondi_tl(TCG_COND_GT
, bcond
, t0
, 0);
6274 tcg_gen_setcondi_tl(TCG_COND_GT
, bcond
, t0
, 0);
6277 tcg_gen_setcondi_tl(TCG_COND_LE
, bcond
, t0
, 0);
6280 tcg_gen_setcondi_tl(TCG_COND_LE
, bcond
, t0
, 0);
6283 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
6286 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
6289 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 32);
6291 #if defined(TARGET_MIPS64)
6293 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 64);
6297 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
6300 ctx
->hflags
|= MIPS_HFLAG_BC
;
6303 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
6306 ctx
->hflags
|= MIPS_HFLAG_BL
;
6309 MIPS_INVAL("conditional branch/jump");
6310 gen_reserved_instruction(ctx
);
6315 ctx
->btarget
= btgt
;
6317 switch (delayslot_size
) {
6319 ctx
->hflags
|= MIPS_HFLAG_BDS16
;
6322 ctx
->hflags
|= MIPS_HFLAG_BDS32
;
6327 int post_delay
= insn_bytes
+ delayslot_size
;
6328 int lowbit
= !!(ctx
->hflags
& MIPS_HFLAG_M16
);
6330 tcg_gen_movi_tl(cpu_gpr
[blink
],
6331 ctx
->base
.pc_next
+ post_delay
+ lowbit
);
6335 if (insn_bytes
== 2) {
6336 ctx
->hflags
|= MIPS_HFLAG_B16
;
6343 /* nanoMIPS Branches */
6344 static void gen_compute_branch_nm(DisasContext
*ctx
, uint32_t opc
,
6346 int rs
, int rt
, int32_t offset
)
6348 target_ulong btgt
= -1;
6349 int bcond_compute
= 0;
6350 TCGv t0
= tcg_temp_new();
6351 TCGv t1
= tcg_temp_new();
6353 /* Load needed operands */
6357 /* Compare two registers */
6359 gen_load_gpr(t0
, rs
);
6360 gen_load_gpr(t1
, rt
);
6363 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ offset
;
6366 /* Compare to zero */
6368 gen_load_gpr(t0
, rs
);
6371 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ offset
;
6374 tcg_gen_andi_tl(t0
, cpu_dspctrl
, 0x3F);
6376 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ offset
;
6380 /* Jump to register */
6381 if (offset
!= 0 && offset
!= 16) {
6383 * Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
6384 * others are reserved.
6386 MIPS_INVAL("jump hint");
6387 gen_reserved_instruction(ctx
);
6390 gen_load_gpr(btarget
, rs
);
6393 MIPS_INVAL("branch/jump");
6394 gen_reserved_instruction(ctx
);
6397 if (bcond_compute
== 0) {
6398 /* No condition to be computed */
6400 case OPC_BEQ
: /* rx == rx */
6402 ctx
->hflags
|= MIPS_HFLAG_B
;
6404 case OPC_BGEZAL
: /* 0 >= 0 */
6405 /* Always take and link */
6406 tcg_gen_movi_tl(cpu_gpr
[31],
6407 ctx
->base
.pc_next
+ insn_bytes
);
6408 ctx
->hflags
|= MIPS_HFLAG_B
;
6410 case OPC_BNE
: /* rx != rx */
6411 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 8);
6412 /* Skip the instruction in the delay slot */
6413 ctx
->base
.pc_next
+= 4;
6416 ctx
->hflags
|= MIPS_HFLAG_BR
;
6420 tcg_gen_movi_tl(cpu_gpr
[rt
],
6421 ctx
->base
.pc_next
+ insn_bytes
);
6423 ctx
->hflags
|= MIPS_HFLAG_BR
;
6426 MIPS_INVAL("branch/jump");
6427 gen_reserved_instruction(ctx
);
6433 tcg_gen_setcond_tl(TCG_COND_EQ
, bcond
, t0
, t1
);
6436 tcg_gen_setcond_tl(TCG_COND_NE
, bcond
, t0
, t1
);
6439 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
6440 tcg_gen_movi_tl(cpu_gpr
[31],
6441 ctx
->base
.pc_next
+ insn_bytes
);
6444 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 32);
6446 ctx
->hflags
|= MIPS_HFLAG_BC
;
6449 MIPS_INVAL("conditional branch/jump");
6450 gen_reserved_instruction(ctx
);
6455 ctx
->btarget
= btgt
;
6458 if (insn_bytes
== 2) {
6459 ctx
->hflags
|= MIPS_HFLAG_B16
;
6466 /* special3 bitfield operations */
6467 static void gen_bitops(DisasContext
*ctx
, uint32_t opc
, int rt
,
6468 int rs
, int lsb
, int msb
)
6470 TCGv t0
= tcg_temp_new();
6471 TCGv t1
= tcg_temp_new();
6473 gen_load_gpr(t1
, rs
);
6476 if (lsb
+ msb
> 31) {
6480 tcg_gen_extract_tl(t0
, t1
, lsb
, msb
+ 1);
6483 * The two checks together imply that lsb == 0,
6484 * so this is a simple sign-extension.
6486 tcg_gen_ext32s_tl(t0
, t1
);
6489 #if defined(TARGET_MIPS64)
6498 if (lsb
+ msb
> 63) {
6501 tcg_gen_extract_tl(t0
, t1
, lsb
, msb
+ 1);
6508 gen_load_gpr(t0
, rt
);
6509 tcg_gen_deposit_tl(t0
, t0
, t1
, lsb
, msb
- lsb
+ 1);
6510 tcg_gen_ext32s_tl(t0
, t0
);
6512 #if defined(TARGET_MIPS64)
6523 gen_load_gpr(t0
, rt
);
6524 tcg_gen_deposit_tl(t0
, t0
, t1
, lsb
, msb
- lsb
+ 1);
6529 MIPS_INVAL("bitops");
6530 gen_reserved_instruction(ctx
);
6535 gen_store_gpr(t0
, rt
);
6540 static void gen_bshfl(DisasContext
*ctx
, uint32_t op2
, int rt
, int rd
)
6545 /* If no destination, treat it as a NOP. */
6549 t0
= tcg_temp_new();
6550 gen_load_gpr(t0
, rt
);
6554 TCGv t1
= tcg_temp_new();
6555 TCGv t2
= tcg_const_tl(0x00FF00FF);
6557 tcg_gen_shri_tl(t1
, t0
, 8);
6558 tcg_gen_and_tl(t1
, t1
, t2
);
6559 tcg_gen_and_tl(t0
, t0
, t2
);
6560 tcg_gen_shli_tl(t0
, t0
, 8);
6561 tcg_gen_or_tl(t0
, t0
, t1
);
6564 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
6568 tcg_gen_ext8s_tl(cpu_gpr
[rd
], t0
);
6571 tcg_gen_ext16s_tl(cpu_gpr
[rd
], t0
);
6573 #if defined(TARGET_MIPS64)
6576 TCGv t1
= tcg_temp_new();
6577 TCGv t2
= tcg_const_tl(0x00FF00FF00FF00FFULL
);
6579 tcg_gen_shri_tl(t1
, t0
, 8);
6580 tcg_gen_and_tl(t1
, t1
, t2
);
6581 tcg_gen_and_tl(t0
, t0
, t2
);
6582 tcg_gen_shli_tl(t0
, t0
, 8);
6583 tcg_gen_or_tl(cpu_gpr
[rd
], t0
, t1
);
6590 TCGv t1
= tcg_temp_new();
6591 TCGv t2
= tcg_const_tl(0x0000FFFF0000FFFFULL
);
6593 tcg_gen_shri_tl(t1
, t0
, 16);
6594 tcg_gen_and_tl(t1
, t1
, t2
);
6595 tcg_gen_and_tl(t0
, t0
, t2
);
6596 tcg_gen_shli_tl(t0
, t0
, 16);
6597 tcg_gen_or_tl(t0
, t0
, t1
);
6598 tcg_gen_shri_tl(t1
, t0
, 32);
6599 tcg_gen_shli_tl(t0
, t0
, 32);
6600 tcg_gen_or_tl(cpu_gpr
[rd
], t0
, t1
);
6607 MIPS_INVAL("bsfhl");
6608 gen_reserved_instruction(ctx
);
6615 static void gen_align_bits(DisasContext
*ctx
, int wordsz
, int rd
, int rs
,
6623 t0
= tcg_temp_new();
6624 if (bits
== 0 || bits
== wordsz
) {
6626 gen_load_gpr(t0
, rt
);
6628 gen_load_gpr(t0
, rs
);
6632 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
6634 #if defined(TARGET_MIPS64)
6636 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
6641 TCGv t1
= tcg_temp_new();
6642 gen_load_gpr(t0
, rt
);
6643 gen_load_gpr(t1
, rs
);
6647 TCGv_i64 t2
= tcg_temp_new_i64();
6648 tcg_gen_concat_tl_i64(t2
, t1
, t0
);
6649 tcg_gen_shri_i64(t2
, t2
, 32 - bits
);
6650 gen_move_low32(cpu_gpr
[rd
], t2
);
6651 tcg_temp_free_i64(t2
);
6654 #if defined(TARGET_MIPS64)
6656 tcg_gen_shli_tl(t0
, t0
, bits
);
6657 tcg_gen_shri_tl(t1
, t1
, 64 - bits
);
6658 tcg_gen_or_tl(cpu_gpr
[rd
], t1
, t0
);
6668 static void gen_align(DisasContext
*ctx
, int wordsz
, int rd
, int rs
, int rt
,
6671 gen_align_bits(ctx
, wordsz
, rd
, rs
, rt
, bp
* 8);
6674 static void gen_ext(DisasContext
*ctx
, int wordsz
, int rd
, int rs
, int rt
,
6677 gen_align_bits(ctx
, wordsz
, rd
, rs
, rt
, wordsz
- shift
);
6680 static void gen_bitswap(DisasContext
*ctx
, int opc
, int rd
, int rt
)
6687 t0
= tcg_temp_new();
6688 gen_load_gpr(t0
, rt
);
6691 gen_helper_bitswap(cpu_gpr
[rd
], t0
);
6693 #if defined(TARGET_MIPS64)
6695 gen_helper_dbitswap(cpu_gpr
[rd
], t0
);
6702 #ifndef CONFIG_USER_ONLY
6703 /* CP0 (MMU and control) */
6704 static inline void gen_mthc0_entrylo(TCGv arg
, target_ulong off
)
6706 TCGv_i64 t0
= tcg_temp_new_i64();
6707 TCGv_i64 t1
= tcg_temp_new_i64();
6709 tcg_gen_ext_tl_i64(t0
, arg
);
6710 tcg_gen_ld_i64(t1
, cpu_env
, off
);
6711 #if defined(TARGET_MIPS64)
6712 tcg_gen_deposit_i64(t1
, t1
, t0
, 30, 32);
6714 tcg_gen_concat32_i64(t1
, t1
, t0
);
6716 tcg_gen_st_i64(t1
, cpu_env
, off
);
6717 tcg_temp_free_i64(t1
);
6718 tcg_temp_free_i64(t0
);
6721 static inline void gen_mthc0_store64(TCGv arg
, target_ulong off
)
6723 TCGv_i64 t0
= tcg_temp_new_i64();
6724 TCGv_i64 t1
= tcg_temp_new_i64();
6726 tcg_gen_ext_tl_i64(t0
, arg
);
6727 tcg_gen_ld_i64(t1
, cpu_env
, off
);
6728 tcg_gen_concat32_i64(t1
, t1
, t0
);
6729 tcg_gen_st_i64(t1
, cpu_env
, off
);
6730 tcg_temp_free_i64(t1
);
6731 tcg_temp_free_i64(t0
);
6734 static inline void gen_mfhc0_entrylo(TCGv arg
, target_ulong off
)
6736 TCGv_i64 t0
= tcg_temp_new_i64();
6738 tcg_gen_ld_i64(t0
, cpu_env
, off
);
6739 #if defined(TARGET_MIPS64)
6740 tcg_gen_shri_i64(t0
, t0
, 30);
6742 tcg_gen_shri_i64(t0
, t0
, 32);
6744 gen_move_low32(arg
, t0
);
6745 tcg_temp_free_i64(t0
);
6748 static inline void gen_mfhc0_load64(TCGv arg
, target_ulong off
, int shift
)
6750 TCGv_i64 t0
= tcg_temp_new_i64();
6752 tcg_gen_ld_i64(t0
, cpu_env
, off
);
6753 tcg_gen_shri_i64(t0
, t0
, 32 + shift
);
6754 gen_move_low32(arg
, t0
);
6755 tcg_temp_free_i64(t0
);
6758 static inline void gen_mfc0_load32(TCGv arg
, target_ulong off
)
6760 TCGv_i32 t0
= tcg_temp_new_i32();
6762 tcg_gen_ld_i32(t0
, cpu_env
, off
);
6763 tcg_gen_ext_i32_tl(arg
, t0
);
6764 tcg_temp_free_i32(t0
);
6767 static inline void gen_mfc0_load64(TCGv arg
, target_ulong off
)
6769 tcg_gen_ld_tl(arg
, cpu_env
, off
);
6770 tcg_gen_ext32s_tl(arg
, arg
);
6773 static inline void gen_mtc0_store32(TCGv arg
, target_ulong off
)
6775 TCGv_i32 t0
= tcg_temp_new_i32();
6777 tcg_gen_trunc_tl_i32(t0
, arg
);
6778 tcg_gen_st_i32(t0
, cpu_env
, off
);
6779 tcg_temp_free_i32(t0
);
6782 #define CP0_CHECK(c) \
6785 goto cp0_unimplemented; \
6789 static void gen_mfhc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
6791 const char *register_name
= "invalid";
6794 case CP0_REGISTER_02
:
6797 CP0_CHECK(ctx
->hflags
& MIPS_HFLAG_ELPA
);
6798 gen_mfhc0_entrylo(arg
, offsetof(CPUMIPSState
, CP0_EntryLo0
));
6799 register_name
= "EntryLo0";
6802 goto cp0_unimplemented
;
6805 case CP0_REGISTER_03
:
6807 case CP0_REG03__ENTRYLO1
:
6808 CP0_CHECK(ctx
->hflags
& MIPS_HFLAG_ELPA
);
6809 gen_mfhc0_entrylo(arg
, offsetof(CPUMIPSState
, CP0_EntryLo1
));
6810 register_name
= "EntryLo1";
6813 goto cp0_unimplemented
;
6816 case CP0_REGISTER_09
:
6818 case CP0_REG09__SAAR
:
6819 CP0_CHECK(ctx
->saar
);
6820 gen_helper_mfhc0_saar(arg
, cpu_env
);
6821 register_name
= "SAAR";
6824 goto cp0_unimplemented
;
6827 case CP0_REGISTER_17
:
6829 case CP0_REG17__LLADDR
:
6830 gen_mfhc0_load64(arg
, offsetof(CPUMIPSState
, CP0_LLAddr
),
6831 ctx
->CP0_LLAddr_shift
);
6832 register_name
= "LLAddr";
6834 case CP0_REG17__MAAR
:
6835 CP0_CHECK(ctx
->mrp
);
6836 gen_helper_mfhc0_maar(arg
, cpu_env
);
6837 register_name
= "MAAR";
6840 goto cp0_unimplemented
;
6843 case CP0_REGISTER_19
:
6845 case CP0_REG19__WATCHHI0
:
6846 case CP0_REG19__WATCHHI1
:
6847 case CP0_REG19__WATCHHI2
:
6848 case CP0_REG19__WATCHHI3
:
6849 case CP0_REG19__WATCHHI4
:
6850 case CP0_REG19__WATCHHI5
:
6851 case CP0_REG19__WATCHHI6
:
6852 case CP0_REG19__WATCHHI7
:
6853 /* upper 32 bits are only available when Config5MI != 0 */
6855 gen_mfhc0_load64(arg
, offsetof(CPUMIPSState
, CP0_WatchHi
[sel
]), 0);
6856 register_name
= "WatchHi";
6859 goto cp0_unimplemented
;
6862 case CP0_REGISTER_28
:
6868 gen_mfhc0_load64(arg
, offsetof(CPUMIPSState
, CP0_TagLo
), 0);
6869 register_name
= "TagLo";
6872 goto cp0_unimplemented
;
6876 goto cp0_unimplemented
;
6878 trace_mips_translate_c0("mfhc0", register_name
, reg
, sel
);
6882 qemu_log_mask(LOG_UNIMP
, "mfhc0 %s (reg %d sel %d)\n",
6883 register_name
, reg
, sel
);
6884 tcg_gen_movi_tl(arg
, 0);
6887 static void gen_mthc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
6889 const char *register_name
= "invalid";
6890 uint64_t mask
= ctx
->PAMask
>> 36;
6893 case CP0_REGISTER_02
:
6896 CP0_CHECK(ctx
->hflags
& MIPS_HFLAG_ELPA
);
6897 tcg_gen_andi_tl(arg
, arg
, mask
);
6898 gen_mthc0_entrylo(arg
, offsetof(CPUMIPSState
, CP0_EntryLo0
));
6899 register_name
= "EntryLo0";
6902 goto cp0_unimplemented
;
6905 case CP0_REGISTER_03
:
6907 case CP0_REG03__ENTRYLO1
:
6908 CP0_CHECK(ctx
->hflags
& MIPS_HFLAG_ELPA
);
6909 tcg_gen_andi_tl(arg
, arg
, mask
);
6910 gen_mthc0_entrylo(arg
, offsetof(CPUMIPSState
, CP0_EntryLo1
));
6911 register_name
= "EntryLo1";
6914 goto cp0_unimplemented
;
6917 case CP0_REGISTER_09
:
6919 case CP0_REG09__SAAR
:
6920 CP0_CHECK(ctx
->saar
);
6921 gen_helper_mthc0_saar(cpu_env
, arg
);
6922 register_name
= "SAAR";
6925 goto cp0_unimplemented
;
6928 case CP0_REGISTER_17
:
6930 case CP0_REG17__LLADDR
:
6932 * LLAddr is read-only (the only exception is bit 0 if LLB is
6933 * supported); the CP0_LLAddr_rw_bitmask does not seem to be
6934 * relevant for modern MIPS cores supporting MTHC0, therefore
6935 * treating MTHC0 to LLAddr as NOP.
6937 register_name
= "LLAddr";
6939 case CP0_REG17__MAAR
:
6940 CP0_CHECK(ctx
->mrp
);
6941 gen_helper_mthc0_maar(cpu_env
, arg
);
6942 register_name
= "MAAR";
6945 goto cp0_unimplemented
;
6948 case CP0_REGISTER_19
:
6950 case CP0_REG19__WATCHHI0
:
6951 case CP0_REG19__WATCHHI1
:
6952 case CP0_REG19__WATCHHI2
:
6953 case CP0_REG19__WATCHHI3
:
6954 case CP0_REG19__WATCHHI4
:
6955 case CP0_REG19__WATCHHI5
:
6956 case CP0_REG19__WATCHHI6
:
6957 case CP0_REG19__WATCHHI7
:
6958 /* upper 32 bits are only available when Config5MI != 0 */
6960 gen_helper_0e1i(mthc0_watchhi
, arg
, sel
);
6961 register_name
= "WatchHi";
6964 goto cp0_unimplemented
;
6967 case CP0_REGISTER_28
:
6973 tcg_gen_andi_tl(arg
, arg
, mask
);
6974 gen_mthc0_store64(arg
, offsetof(CPUMIPSState
, CP0_TagLo
));
6975 register_name
= "TagLo";
6978 goto cp0_unimplemented
;
6982 goto cp0_unimplemented
;
6984 trace_mips_translate_c0("mthc0", register_name
, reg
, sel
);
6987 qemu_log_mask(LOG_UNIMP
, "mthc0 %s (reg %d sel %d)\n",
6988 register_name
, reg
, sel
);
6991 static inline void gen_mfc0_unimplemented(DisasContext
*ctx
, TCGv arg
)
6993 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
6994 tcg_gen_movi_tl(arg
, 0);
6996 tcg_gen_movi_tl(arg
, ~0);
7000 static void gen_mfc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
7002 const char *register_name
= "invalid";
7005 check_insn(ctx
, ISA_MIPS_R1
);
7009 case CP0_REGISTER_00
:
7011 case CP0_REG00__INDEX
:
7012 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Index
));
7013 register_name
= "Index";
7015 case CP0_REG00__MVPCONTROL
:
7016 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7017 gen_helper_mfc0_mvpcontrol(arg
, cpu_env
);
7018 register_name
= "MVPControl";
7020 case CP0_REG00__MVPCONF0
:
7021 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7022 gen_helper_mfc0_mvpconf0(arg
, cpu_env
);
7023 register_name
= "MVPConf0";
7025 case CP0_REG00__MVPCONF1
:
7026 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7027 gen_helper_mfc0_mvpconf1(arg
, cpu_env
);
7028 register_name
= "MVPConf1";
7030 case CP0_REG00__VPCONTROL
:
7032 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPControl
));
7033 register_name
= "VPControl";
7036 goto cp0_unimplemented
;
7039 case CP0_REGISTER_01
:
7041 case CP0_REG01__RANDOM
:
7042 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS_R6
));
7043 gen_helper_mfc0_random(arg
, cpu_env
);
7044 register_name
= "Random";
7046 case CP0_REG01__VPECONTROL
:
7047 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7048 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEControl
));
7049 register_name
= "VPEControl";
7051 case CP0_REG01__VPECONF0
:
7052 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7053 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf0
));
7054 register_name
= "VPEConf0";
7056 case CP0_REG01__VPECONF1
:
7057 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7058 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf1
));
7059 register_name
= "VPEConf1";
7061 case CP0_REG01__YQMASK
:
7062 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7063 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_YQMask
));
7064 register_name
= "YQMask";
7066 case CP0_REG01__VPESCHEDULE
:
7067 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7068 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_VPESchedule
));
7069 register_name
= "VPESchedule";
7071 case CP0_REG01__VPESCHEFBACK
:
7072 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7073 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
7074 register_name
= "VPEScheFBack";
7076 case CP0_REG01__VPEOPT
:
7077 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7078 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEOpt
));
7079 register_name
= "VPEOpt";
7082 goto cp0_unimplemented
;
7085 case CP0_REGISTER_02
:
7087 case CP0_REG02__ENTRYLO0
:
7089 TCGv_i64 tmp
= tcg_temp_new_i64();
7090 tcg_gen_ld_i64(tmp
, cpu_env
,
7091 offsetof(CPUMIPSState
, CP0_EntryLo0
));
7092 #if defined(TARGET_MIPS64)
7094 /* Move RI/XI fields to bits 31:30 */
7095 tcg_gen_shri_tl(arg
, tmp
, CP0EnLo_XI
);
7096 tcg_gen_deposit_tl(tmp
, tmp
, arg
, 30, 2);
7099 gen_move_low32(arg
, tmp
);
7100 tcg_temp_free_i64(tmp
);
7102 register_name
= "EntryLo0";
7104 case CP0_REG02__TCSTATUS
:
7105 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7106 gen_helper_mfc0_tcstatus(arg
, cpu_env
);
7107 register_name
= "TCStatus";
7109 case CP0_REG02__TCBIND
:
7110 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7111 gen_helper_mfc0_tcbind(arg
, cpu_env
);
7112 register_name
= "TCBind";
7114 case CP0_REG02__TCRESTART
:
7115 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7116 gen_helper_mfc0_tcrestart(arg
, cpu_env
);
7117 register_name
= "TCRestart";
7119 case CP0_REG02__TCHALT
:
7120 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7121 gen_helper_mfc0_tchalt(arg
, cpu_env
);
7122 register_name
= "TCHalt";
7124 case CP0_REG02__TCCONTEXT
:
7125 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7126 gen_helper_mfc0_tccontext(arg
, cpu_env
);
7127 register_name
= "TCContext";
7129 case CP0_REG02__TCSCHEDULE
:
7130 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7131 gen_helper_mfc0_tcschedule(arg
, cpu_env
);
7132 register_name
= "TCSchedule";
7134 case CP0_REG02__TCSCHEFBACK
:
7135 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7136 gen_helper_mfc0_tcschefback(arg
, cpu_env
);
7137 register_name
= "TCScheFBack";
7140 goto cp0_unimplemented
;
7143 case CP0_REGISTER_03
:
7145 case CP0_REG03__ENTRYLO1
:
7147 TCGv_i64 tmp
= tcg_temp_new_i64();
7148 tcg_gen_ld_i64(tmp
, cpu_env
,
7149 offsetof(CPUMIPSState
, CP0_EntryLo1
));
7150 #if defined(TARGET_MIPS64)
7152 /* Move RI/XI fields to bits 31:30 */
7153 tcg_gen_shri_tl(arg
, tmp
, CP0EnLo_XI
);
7154 tcg_gen_deposit_tl(tmp
, tmp
, arg
, 30, 2);
7157 gen_move_low32(arg
, tmp
);
7158 tcg_temp_free_i64(tmp
);
7160 register_name
= "EntryLo1";
7162 case CP0_REG03__GLOBALNUM
:
7164 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_GlobalNumber
));
7165 register_name
= "GlobalNumber";
7168 goto cp0_unimplemented
;
7171 case CP0_REGISTER_04
:
7173 case CP0_REG04__CONTEXT
:
7174 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_Context
));
7175 tcg_gen_ext32s_tl(arg
, arg
);
7176 register_name
= "Context";
7178 case CP0_REG04__CONTEXTCONFIG
:
7180 /* gen_helper_mfc0_contextconfig(arg); */
7181 register_name
= "ContextConfig";
7182 goto cp0_unimplemented
;
7183 case CP0_REG04__USERLOCAL
:
7184 CP0_CHECK(ctx
->ulri
);
7185 tcg_gen_ld_tl(arg
, cpu_env
,
7186 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
7187 tcg_gen_ext32s_tl(arg
, arg
);
7188 register_name
= "UserLocal";
7190 case CP0_REG04__MMID
:
7192 gen_helper_mtc0_memorymapid(cpu_env
, arg
);
7193 register_name
= "MMID";
7196 goto cp0_unimplemented
;
7199 case CP0_REGISTER_05
:
7201 case CP0_REG05__PAGEMASK
:
7202 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageMask
));
7203 register_name
= "PageMask";
7205 case CP0_REG05__PAGEGRAIN
:
7206 check_insn(ctx
, ISA_MIPS_R2
);
7207 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageGrain
));
7208 register_name
= "PageGrain";
7210 case CP0_REG05__SEGCTL0
:
7212 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_SegCtl0
));
7213 tcg_gen_ext32s_tl(arg
, arg
);
7214 register_name
= "SegCtl0";
7216 case CP0_REG05__SEGCTL1
:
7218 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_SegCtl1
));
7219 tcg_gen_ext32s_tl(arg
, arg
);
7220 register_name
= "SegCtl1";
7222 case CP0_REG05__SEGCTL2
:
7224 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_SegCtl2
));
7225 tcg_gen_ext32s_tl(arg
, arg
);
7226 register_name
= "SegCtl2";
7228 case CP0_REG05__PWBASE
:
7230 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PWBase
));
7231 register_name
= "PWBase";
7233 case CP0_REG05__PWFIELD
:
7235 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PWField
));
7236 register_name
= "PWField";
7238 case CP0_REG05__PWSIZE
:
7240 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PWSize
));
7241 register_name
= "PWSize";
7244 goto cp0_unimplemented
;
7247 case CP0_REGISTER_06
:
7249 case CP0_REG06__WIRED
:
7250 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Wired
));
7251 register_name
= "Wired";
7253 case CP0_REG06__SRSCONF0
:
7254 check_insn(ctx
, ISA_MIPS_R2
);
7255 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf0
));
7256 register_name
= "SRSConf0";
7258 case CP0_REG06__SRSCONF1
:
7259 check_insn(ctx
, ISA_MIPS_R2
);
7260 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf1
));
7261 register_name
= "SRSConf1";
7263 case CP0_REG06__SRSCONF2
:
7264 check_insn(ctx
, ISA_MIPS_R2
);
7265 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf2
));
7266 register_name
= "SRSConf2";
7268 case CP0_REG06__SRSCONF3
:
7269 check_insn(ctx
, ISA_MIPS_R2
);
7270 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf3
));
7271 register_name
= "SRSConf3";
7273 case CP0_REG06__SRSCONF4
:
7274 check_insn(ctx
, ISA_MIPS_R2
);
7275 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf4
));
7276 register_name
= "SRSConf4";
7278 case CP0_REG06__PWCTL
:
7280 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PWCtl
));
7281 register_name
= "PWCtl";
7284 goto cp0_unimplemented
;
7287 case CP0_REGISTER_07
:
7289 case CP0_REG07__HWRENA
:
7290 check_insn(ctx
, ISA_MIPS_R2
);
7291 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_HWREna
));
7292 register_name
= "HWREna";
7295 goto cp0_unimplemented
;
7298 case CP0_REGISTER_08
:
7300 case CP0_REG08__BADVADDR
:
7301 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_BadVAddr
));
7302 tcg_gen_ext32s_tl(arg
, arg
);
7303 register_name
= "BadVAddr";
7305 case CP0_REG08__BADINSTR
:
7307 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstr
));
7308 register_name
= "BadInstr";
7310 case CP0_REG08__BADINSTRP
:
7312 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstrP
));
7313 register_name
= "BadInstrP";
7315 case CP0_REG08__BADINSTRX
:
7317 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstrX
));
7318 tcg_gen_andi_tl(arg
, arg
, ~0xffff);
7319 register_name
= "BadInstrX";
7322 goto cp0_unimplemented
;
7325 case CP0_REGISTER_09
:
7327 case CP0_REG09__COUNT
:
7328 /* Mark as an IO operation because we read the time. */
7329 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
7332 gen_helper_mfc0_count(arg
, cpu_env
);
7334 * Break the TB to be able to take timer interrupts immediately
7335 * after reading count. DISAS_STOP isn't sufficient, we need to
7336 * ensure we break completely out of translated code.
7338 gen_save_pc(ctx
->base
.pc_next
+ 4);
7339 ctx
->base
.is_jmp
= DISAS_EXIT
;
7340 register_name
= "Count";
7342 case CP0_REG09__SAARI
:
7343 CP0_CHECK(ctx
->saar
);
7344 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SAARI
));
7345 register_name
= "SAARI";
7347 case CP0_REG09__SAAR
:
7348 CP0_CHECK(ctx
->saar
);
7349 gen_helper_mfc0_saar(arg
, cpu_env
);
7350 register_name
= "SAAR";
7353 goto cp0_unimplemented
;
7356 case CP0_REGISTER_10
:
7358 case CP0_REG10__ENTRYHI
:
7359 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryHi
));
7360 tcg_gen_ext32s_tl(arg
, arg
);
7361 register_name
= "EntryHi";
7364 goto cp0_unimplemented
;
7367 case CP0_REGISTER_11
:
7369 case CP0_REG11__COMPARE
:
7370 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Compare
));
7371 register_name
= "Compare";
7373 /* 6,7 are implementation dependent */
7375 goto cp0_unimplemented
;
7378 case CP0_REGISTER_12
:
7380 case CP0_REG12__STATUS
:
7381 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Status
));
7382 register_name
= "Status";
7384 case CP0_REG12__INTCTL
:
7385 check_insn(ctx
, ISA_MIPS_R2
);
7386 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_IntCtl
));
7387 register_name
= "IntCtl";
7389 case CP0_REG12__SRSCTL
:
7390 check_insn(ctx
, ISA_MIPS_R2
);
7391 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
7392 register_name
= "SRSCtl";
7394 case CP0_REG12__SRSMAP
:
7395 check_insn(ctx
, ISA_MIPS_R2
);
7396 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
7397 register_name
= "SRSMap";
7400 goto cp0_unimplemented
;
7403 case CP0_REGISTER_13
:
7405 case CP0_REG13__CAUSE
:
7406 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Cause
));
7407 register_name
= "Cause";
7410 goto cp0_unimplemented
;
7413 case CP0_REGISTER_14
:
7415 case CP0_REG14__EPC
:
7416 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
7417 tcg_gen_ext32s_tl(arg
, arg
);
7418 register_name
= "EPC";
7421 goto cp0_unimplemented
;
7424 case CP0_REGISTER_15
:
7426 case CP0_REG15__PRID
:
7427 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PRid
));
7428 register_name
= "PRid";
7430 case CP0_REG15__EBASE
:
7431 check_insn(ctx
, ISA_MIPS_R2
);
7432 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EBase
));
7433 tcg_gen_ext32s_tl(arg
, arg
);
7434 register_name
= "EBase";
7436 case CP0_REG15__CMGCRBASE
:
7437 check_insn(ctx
, ISA_MIPS_R2
);
7438 CP0_CHECK(ctx
->cmgcr
);
7439 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_CMGCRBase
));
7440 tcg_gen_ext32s_tl(arg
, arg
);
7441 register_name
= "CMGCRBase";
7444 goto cp0_unimplemented
;
7447 case CP0_REGISTER_16
:
7449 case CP0_REG16__CONFIG
:
7450 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config0
));
7451 register_name
= "Config";
7453 case CP0_REG16__CONFIG1
:
7454 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config1
));
7455 register_name
= "Config1";
7457 case CP0_REG16__CONFIG2
:
7458 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config2
));
7459 register_name
= "Config2";
7461 case CP0_REG16__CONFIG3
:
7462 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config3
));
7463 register_name
= "Config3";
7465 case CP0_REG16__CONFIG4
:
7466 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config4
));
7467 register_name
= "Config4";
7469 case CP0_REG16__CONFIG5
:
7470 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config5
));
7471 register_name
= "Config5";
7473 /* 6,7 are implementation dependent */
7474 case CP0_REG16__CONFIG6
:
7475 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config6
));
7476 register_name
= "Config6";
7478 case CP0_REG16__CONFIG7
:
7479 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config7
));
7480 register_name
= "Config7";
7483 goto cp0_unimplemented
;
7486 case CP0_REGISTER_17
:
7488 case CP0_REG17__LLADDR
:
7489 gen_helper_mfc0_lladdr(arg
, cpu_env
);
7490 register_name
= "LLAddr";
7492 case CP0_REG17__MAAR
:
7493 CP0_CHECK(ctx
->mrp
);
7494 gen_helper_mfc0_maar(arg
, cpu_env
);
7495 register_name
= "MAAR";
7497 case CP0_REG17__MAARI
:
7498 CP0_CHECK(ctx
->mrp
);
7499 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_MAARI
));
7500 register_name
= "MAARI";
7503 goto cp0_unimplemented
;
7506 case CP0_REGISTER_18
:
7508 case CP0_REG18__WATCHLO0
:
7509 case CP0_REG18__WATCHLO1
:
7510 case CP0_REG18__WATCHLO2
:
7511 case CP0_REG18__WATCHLO3
:
7512 case CP0_REG18__WATCHLO4
:
7513 case CP0_REG18__WATCHLO5
:
7514 case CP0_REG18__WATCHLO6
:
7515 case CP0_REG18__WATCHLO7
:
7516 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
7517 gen_helper_1e0i(mfc0_watchlo
, arg
, sel
);
7518 register_name
= "WatchLo";
7521 goto cp0_unimplemented
;
7524 case CP0_REGISTER_19
:
7526 case CP0_REG19__WATCHHI0
:
7527 case CP0_REG19__WATCHHI1
:
7528 case CP0_REG19__WATCHHI2
:
7529 case CP0_REG19__WATCHHI3
:
7530 case CP0_REG19__WATCHHI4
:
7531 case CP0_REG19__WATCHHI5
:
7532 case CP0_REG19__WATCHHI6
:
7533 case CP0_REG19__WATCHHI7
:
7534 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
7535 gen_helper_1e0i(mfc0_watchhi
, arg
, sel
);
7536 register_name
= "WatchHi";
7539 goto cp0_unimplemented
;
7542 case CP0_REGISTER_20
:
7544 case CP0_REG20__XCONTEXT
:
7545 #if defined(TARGET_MIPS64)
7546 check_insn(ctx
, ISA_MIPS3
);
7547 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_XContext
));
7548 tcg_gen_ext32s_tl(arg
, arg
);
7549 register_name
= "XContext";
7553 goto cp0_unimplemented
;
7556 case CP0_REGISTER_21
:
7557 /* Officially reserved, but sel 0 is used for R1x000 framemask */
7558 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS_R6
));
7561 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Framemask
));
7562 register_name
= "Framemask";
7565 goto cp0_unimplemented
;
7568 case CP0_REGISTER_22
:
7569 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
7570 register_name
= "'Diagnostic"; /* implementation dependent */
7572 case CP0_REGISTER_23
:
7574 case CP0_REG23__DEBUG
:
7575 gen_helper_mfc0_debug(arg
, cpu_env
); /* EJTAG support */
7576 register_name
= "Debug";
7578 case CP0_REG23__TRACECONTROL
:
7579 /* PDtrace support */
7580 /* gen_helper_mfc0_tracecontrol(arg); */
7581 register_name
= "TraceControl";
7582 goto cp0_unimplemented
;
7583 case CP0_REG23__TRACECONTROL2
:
7584 /* PDtrace support */
7585 /* gen_helper_mfc0_tracecontrol2(arg); */
7586 register_name
= "TraceControl2";
7587 goto cp0_unimplemented
;
7588 case CP0_REG23__USERTRACEDATA1
:
7589 /* PDtrace support */
7590 /* gen_helper_mfc0_usertracedata1(arg);*/
7591 register_name
= "UserTraceData1";
7592 goto cp0_unimplemented
;
7593 case CP0_REG23__TRACEIBPC
:
7594 /* PDtrace support */
7595 /* gen_helper_mfc0_traceibpc(arg); */
7596 register_name
= "TraceIBPC";
7597 goto cp0_unimplemented
;
7598 case CP0_REG23__TRACEDBPC
:
7599 /* PDtrace support */
7600 /* gen_helper_mfc0_tracedbpc(arg); */
7601 register_name
= "TraceDBPC";
7602 goto cp0_unimplemented
;
7604 goto cp0_unimplemented
;
7607 case CP0_REGISTER_24
:
7609 case CP0_REG24__DEPC
:
7611 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
7612 tcg_gen_ext32s_tl(arg
, arg
);
7613 register_name
= "DEPC";
7616 goto cp0_unimplemented
;
7619 case CP0_REGISTER_25
:
7621 case CP0_REG25__PERFCTL0
:
7622 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Performance0
));
7623 register_name
= "Performance0";
7625 case CP0_REG25__PERFCNT0
:
7626 /* gen_helper_mfc0_performance1(arg); */
7627 register_name
= "Performance1";
7628 goto cp0_unimplemented
;
7629 case CP0_REG25__PERFCTL1
:
7630 /* gen_helper_mfc0_performance2(arg); */
7631 register_name
= "Performance2";
7632 goto cp0_unimplemented
;
7633 case CP0_REG25__PERFCNT1
:
7634 /* gen_helper_mfc0_performance3(arg); */
7635 register_name
= "Performance3";
7636 goto cp0_unimplemented
;
7637 case CP0_REG25__PERFCTL2
:
7638 /* gen_helper_mfc0_performance4(arg); */
7639 register_name
= "Performance4";
7640 goto cp0_unimplemented
;
7641 case CP0_REG25__PERFCNT2
:
7642 /* gen_helper_mfc0_performance5(arg); */
7643 register_name
= "Performance5";
7644 goto cp0_unimplemented
;
7645 case CP0_REG25__PERFCTL3
:
7646 /* gen_helper_mfc0_performance6(arg); */
7647 register_name
= "Performance6";
7648 goto cp0_unimplemented
;
7649 case CP0_REG25__PERFCNT3
:
7650 /* gen_helper_mfc0_performance7(arg); */
7651 register_name
= "Performance7";
7652 goto cp0_unimplemented
;
7654 goto cp0_unimplemented
;
7657 case CP0_REGISTER_26
:
7659 case CP0_REG26__ERRCTL
:
7660 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_ErrCtl
));
7661 register_name
= "ErrCtl";
7664 goto cp0_unimplemented
;
7667 case CP0_REGISTER_27
:
7669 case CP0_REG27__CACHERR
:
7670 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
7671 register_name
= "CacheErr";
7674 goto cp0_unimplemented
;
7677 case CP0_REGISTER_28
:
7679 case CP0_REG28__TAGLO
:
7680 case CP0_REG28__TAGLO1
:
7681 case CP0_REG28__TAGLO2
:
7682 case CP0_REG28__TAGLO3
:
7684 TCGv_i64 tmp
= tcg_temp_new_i64();
7685 tcg_gen_ld_i64(tmp
, cpu_env
, offsetof(CPUMIPSState
, CP0_TagLo
));
7686 gen_move_low32(arg
, tmp
);
7687 tcg_temp_free_i64(tmp
);
7689 register_name
= "TagLo";
7691 case CP0_REG28__DATALO
:
7692 case CP0_REG28__DATALO1
:
7693 case CP0_REG28__DATALO2
:
7694 case CP0_REG28__DATALO3
:
7695 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataLo
));
7696 register_name
= "DataLo";
7699 goto cp0_unimplemented
;
7702 case CP0_REGISTER_29
:
7704 case CP0_REG29__TAGHI
:
7705 case CP0_REG29__TAGHI1
:
7706 case CP0_REG29__TAGHI2
:
7707 case CP0_REG29__TAGHI3
:
7708 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagHi
));
7709 register_name
= "TagHi";
7711 case CP0_REG29__DATAHI
:
7712 case CP0_REG29__DATAHI1
:
7713 case CP0_REG29__DATAHI2
:
7714 case CP0_REG29__DATAHI3
:
7715 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataHi
));
7716 register_name
= "DataHi";
7719 goto cp0_unimplemented
;
7722 case CP0_REGISTER_30
:
7724 case CP0_REG30__ERROREPC
:
7725 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
7726 tcg_gen_ext32s_tl(arg
, arg
);
7727 register_name
= "ErrorEPC";
7730 goto cp0_unimplemented
;
7733 case CP0_REGISTER_31
:
7735 case CP0_REG31__DESAVE
:
7737 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
7738 register_name
= "DESAVE";
7740 case CP0_REG31__KSCRATCH1
:
7741 case CP0_REG31__KSCRATCH2
:
7742 case CP0_REG31__KSCRATCH3
:
7743 case CP0_REG31__KSCRATCH4
:
7744 case CP0_REG31__KSCRATCH5
:
7745 case CP0_REG31__KSCRATCH6
:
7746 CP0_CHECK(ctx
->kscrexist
& (1 << sel
));
7747 tcg_gen_ld_tl(arg
, cpu_env
,
7748 offsetof(CPUMIPSState
, CP0_KScratch
[sel
- 2]));
7749 tcg_gen_ext32s_tl(arg
, arg
);
7750 register_name
= "KScratch";
7753 goto cp0_unimplemented
;
7757 goto cp0_unimplemented
;
7759 trace_mips_translate_c0("mfc0", register_name
, reg
, sel
);
7763 qemu_log_mask(LOG_UNIMP
, "mfc0 %s (reg %d sel %d)\n",
7764 register_name
, reg
, sel
);
7765 gen_mfc0_unimplemented(ctx
, arg
);
7768 static void gen_mtc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
7770 const char *register_name
= "invalid";
7773 check_insn(ctx
, ISA_MIPS_R1
);
7776 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
7781 case CP0_REGISTER_00
:
7783 case CP0_REG00__INDEX
:
7784 gen_helper_mtc0_index(cpu_env
, arg
);
7785 register_name
= "Index";
7787 case CP0_REG00__MVPCONTROL
:
7788 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7789 gen_helper_mtc0_mvpcontrol(cpu_env
, arg
);
7790 register_name
= "MVPControl";
7792 case CP0_REG00__MVPCONF0
:
7793 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7795 register_name
= "MVPConf0";
7797 case CP0_REG00__MVPCONF1
:
7798 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7800 register_name
= "MVPConf1";
7802 case CP0_REG00__VPCONTROL
:
7805 register_name
= "VPControl";
7808 goto cp0_unimplemented
;
7811 case CP0_REGISTER_01
:
7813 case CP0_REG01__RANDOM
:
7815 register_name
= "Random";
7817 case CP0_REG01__VPECONTROL
:
7818 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7819 gen_helper_mtc0_vpecontrol(cpu_env
, arg
);
7820 register_name
= "VPEControl";
7822 case CP0_REG01__VPECONF0
:
7823 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7824 gen_helper_mtc0_vpeconf0(cpu_env
, arg
);
7825 register_name
= "VPEConf0";
7827 case CP0_REG01__VPECONF1
:
7828 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7829 gen_helper_mtc0_vpeconf1(cpu_env
, arg
);
7830 register_name
= "VPEConf1";
7832 case CP0_REG01__YQMASK
:
7833 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7834 gen_helper_mtc0_yqmask(cpu_env
, arg
);
7835 register_name
= "YQMask";
7837 case CP0_REG01__VPESCHEDULE
:
7838 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7839 tcg_gen_st_tl(arg
, cpu_env
,
7840 offsetof(CPUMIPSState
, CP0_VPESchedule
));
7841 register_name
= "VPESchedule";
7843 case CP0_REG01__VPESCHEFBACK
:
7844 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7845 tcg_gen_st_tl(arg
, cpu_env
,
7846 offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
7847 register_name
= "VPEScheFBack";
7849 case CP0_REG01__VPEOPT
:
7850 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7851 gen_helper_mtc0_vpeopt(cpu_env
, arg
);
7852 register_name
= "VPEOpt";
7855 goto cp0_unimplemented
;
7858 case CP0_REGISTER_02
:
7860 case CP0_REG02__ENTRYLO0
:
7861 gen_helper_mtc0_entrylo0(cpu_env
, arg
);
7862 register_name
= "EntryLo0";
7864 case CP0_REG02__TCSTATUS
:
7865 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7866 gen_helper_mtc0_tcstatus(cpu_env
, arg
);
7867 register_name
= "TCStatus";
7869 case CP0_REG02__TCBIND
:
7870 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7871 gen_helper_mtc0_tcbind(cpu_env
, arg
);
7872 register_name
= "TCBind";
7874 case CP0_REG02__TCRESTART
:
7875 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7876 gen_helper_mtc0_tcrestart(cpu_env
, arg
);
7877 register_name
= "TCRestart";
7879 case CP0_REG02__TCHALT
:
7880 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7881 gen_helper_mtc0_tchalt(cpu_env
, arg
);
7882 register_name
= "TCHalt";
7884 case CP0_REG02__TCCONTEXT
:
7885 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7886 gen_helper_mtc0_tccontext(cpu_env
, arg
);
7887 register_name
= "TCContext";
7889 case CP0_REG02__TCSCHEDULE
:
7890 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7891 gen_helper_mtc0_tcschedule(cpu_env
, arg
);
7892 register_name
= "TCSchedule";
7894 case CP0_REG02__TCSCHEFBACK
:
7895 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7896 gen_helper_mtc0_tcschefback(cpu_env
, arg
);
7897 register_name
= "TCScheFBack";
7900 goto cp0_unimplemented
;
7903 case CP0_REGISTER_03
:
7905 case CP0_REG03__ENTRYLO1
:
7906 gen_helper_mtc0_entrylo1(cpu_env
, arg
);
7907 register_name
= "EntryLo1";
7909 case CP0_REG03__GLOBALNUM
:
7912 register_name
= "GlobalNumber";
7915 goto cp0_unimplemented
;
7918 case CP0_REGISTER_04
:
7920 case CP0_REG04__CONTEXT
:
7921 gen_helper_mtc0_context(cpu_env
, arg
);
7922 register_name
= "Context";
7924 case CP0_REG04__CONTEXTCONFIG
:
7926 /* gen_helper_mtc0_contextconfig(arg); */
7927 register_name
= "ContextConfig";
7928 goto cp0_unimplemented
;
7929 case CP0_REG04__USERLOCAL
:
7930 CP0_CHECK(ctx
->ulri
);
7931 tcg_gen_st_tl(arg
, cpu_env
,
7932 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
7933 register_name
= "UserLocal";
7935 case CP0_REG04__MMID
:
7937 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_MemoryMapID
));
7938 register_name
= "MMID";
7941 goto cp0_unimplemented
;
7944 case CP0_REGISTER_05
:
7946 case CP0_REG05__PAGEMASK
:
7947 gen_helper_mtc0_pagemask(cpu_env
, arg
);
7948 register_name
= "PageMask";
7950 case CP0_REG05__PAGEGRAIN
:
7951 check_insn(ctx
, ISA_MIPS_R2
);
7952 gen_helper_mtc0_pagegrain(cpu_env
, arg
);
7953 register_name
= "PageGrain";
7954 ctx
->base
.is_jmp
= DISAS_STOP
;
7956 case CP0_REG05__SEGCTL0
:
7958 gen_helper_mtc0_segctl0(cpu_env
, arg
);
7959 register_name
= "SegCtl0";
7961 case CP0_REG05__SEGCTL1
:
7963 gen_helper_mtc0_segctl1(cpu_env
, arg
);
7964 register_name
= "SegCtl1";
7966 case CP0_REG05__SEGCTL2
:
7968 gen_helper_mtc0_segctl2(cpu_env
, arg
);
7969 register_name
= "SegCtl2";
7971 case CP0_REG05__PWBASE
:
7973 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_PWBase
));
7974 register_name
= "PWBase";
7976 case CP0_REG05__PWFIELD
:
7978 gen_helper_mtc0_pwfield(cpu_env
, arg
);
7979 register_name
= "PWField";
7981 case CP0_REG05__PWSIZE
:
7983 gen_helper_mtc0_pwsize(cpu_env
, arg
);
7984 register_name
= "PWSize";
7987 goto cp0_unimplemented
;
7990 case CP0_REGISTER_06
:
7992 case CP0_REG06__WIRED
:
7993 gen_helper_mtc0_wired(cpu_env
, arg
);
7994 register_name
= "Wired";
7996 case CP0_REG06__SRSCONF0
:
7997 check_insn(ctx
, ISA_MIPS_R2
);
7998 gen_helper_mtc0_srsconf0(cpu_env
, arg
);
7999 register_name
= "SRSConf0";
8001 case CP0_REG06__SRSCONF1
:
8002 check_insn(ctx
, ISA_MIPS_R2
);
8003 gen_helper_mtc0_srsconf1(cpu_env
, arg
);
8004 register_name
= "SRSConf1";
8006 case CP0_REG06__SRSCONF2
:
8007 check_insn(ctx
, ISA_MIPS_R2
);
8008 gen_helper_mtc0_srsconf2(cpu_env
, arg
);
8009 register_name
= "SRSConf2";
8011 case CP0_REG06__SRSCONF3
:
8012 check_insn(ctx
, ISA_MIPS_R2
);
8013 gen_helper_mtc0_srsconf3(cpu_env
, arg
);
8014 register_name
= "SRSConf3";
8016 case CP0_REG06__SRSCONF4
:
8017 check_insn(ctx
, ISA_MIPS_R2
);
8018 gen_helper_mtc0_srsconf4(cpu_env
, arg
);
8019 register_name
= "SRSConf4";
8021 case CP0_REG06__PWCTL
:
8023 gen_helper_mtc0_pwctl(cpu_env
, arg
);
8024 register_name
= "PWCtl";
8027 goto cp0_unimplemented
;
8030 case CP0_REGISTER_07
:
8032 case CP0_REG07__HWRENA
:
8033 check_insn(ctx
, ISA_MIPS_R2
);
8034 gen_helper_mtc0_hwrena(cpu_env
, arg
);
8035 ctx
->base
.is_jmp
= DISAS_STOP
;
8036 register_name
= "HWREna";
8039 goto cp0_unimplemented
;
8042 case CP0_REGISTER_08
:
8044 case CP0_REG08__BADVADDR
:
8046 register_name
= "BadVAddr";
8048 case CP0_REG08__BADINSTR
:
8050 register_name
= "BadInstr";
8052 case CP0_REG08__BADINSTRP
:
8054 register_name
= "BadInstrP";
8056 case CP0_REG08__BADINSTRX
:
8058 register_name
= "BadInstrX";
8061 goto cp0_unimplemented
;
8064 case CP0_REGISTER_09
:
8066 case CP0_REG09__COUNT
:
8067 gen_helper_mtc0_count(cpu_env
, arg
);
8068 register_name
= "Count";
8070 case CP0_REG09__SAARI
:
8071 CP0_CHECK(ctx
->saar
);
8072 gen_helper_mtc0_saari(cpu_env
, arg
);
8073 register_name
= "SAARI";
8075 case CP0_REG09__SAAR
:
8076 CP0_CHECK(ctx
->saar
);
8077 gen_helper_mtc0_saar(cpu_env
, arg
);
8078 register_name
= "SAAR";
8081 goto cp0_unimplemented
;
8084 case CP0_REGISTER_10
:
8086 case CP0_REG10__ENTRYHI
:
8087 gen_helper_mtc0_entryhi(cpu_env
, arg
);
8088 register_name
= "EntryHi";
8091 goto cp0_unimplemented
;
8094 case CP0_REGISTER_11
:
8096 case CP0_REG11__COMPARE
:
8097 gen_helper_mtc0_compare(cpu_env
, arg
);
8098 register_name
= "Compare";
8100 /* 6,7 are implementation dependent */
8102 goto cp0_unimplemented
;
8105 case CP0_REGISTER_12
:
8107 case CP0_REG12__STATUS
:
8108 save_cpu_state(ctx
, 1);
8109 gen_helper_mtc0_status(cpu_env
, arg
);
8110 /* DISAS_STOP isn't good enough here, hflags may have changed. */
8111 gen_save_pc(ctx
->base
.pc_next
+ 4);
8112 ctx
->base
.is_jmp
= DISAS_EXIT
;
8113 register_name
= "Status";
8115 case CP0_REG12__INTCTL
:
8116 check_insn(ctx
, ISA_MIPS_R2
);
8117 gen_helper_mtc0_intctl(cpu_env
, arg
);
8118 /* Stop translation as we may have switched the execution mode */
8119 ctx
->base
.is_jmp
= DISAS_STOP
;
8120 register_name
= "IntCtl";
8122 case CP0_REG12__SRSCTL
:
8123 check_insn(ctx
, ISA_MIPS_R2
);
8124 gen_helper_mtc0_srsctl(cpu_env
, arg
);
8125 /* Stop translation as we may have switched the execution mode */
8126 ctx
->base
.is_jmp
= DISAS_STOP
;
8127 register_name
= "SRSCtl";
8129 case CP0_REG12__SRSMAP
:
8130 check_insn(ctx
, ISA_MIPS_R2
);
8131 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
8132 /* Stop translation as we may have switched the execution mode */
8133 ctx
->base
.is_jmp
= DISAS_STOP
;
8134 register_name
= "SRSMap";
8137 goto cp0_unimplemented
;
8140 case CP0_REGISTER_13
:
8142 case CP0_REG13__CAUSE
:
8143 save_cpu_state(ctx
, 1);
8144 gen_helper_mtc0_cause(cpu_env
, arg
);
8146 * Stop translation as we may have triggered an interrupt.
8147 * DISAS_STOP isn't sufficient, we need to ensure we break out of
8148 * translated code to check for pending interrupts.
8150 gen_save_pc(ctx
->base
.pc_next
+ 4);
8151 ctx
->base
.is_jmp
= DISAS_EXIT
;
8152 register_name
= "Cause";
8155 goto cp0_unimplemented
;
8158 case CP0_REGISTER_14
:
8160 case CP0_REG14__EPC
:
8161 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
8162 register_name
= "EPC";
8165 goto cp0_unimplemented
;
8168 case CP0_REGISTER_15
:
8170 case CP0_REG15__PRID
:
8172 register_name
= "PRid";
8174 case CP0_REG15__EBASE
:
8175 check_insn(ctx
, ISA_MIPS_R2
);
8176 gen_helper_mtc0_ebase(cpu_env
, arg
);
8177 register_name
= "EBase";
8180 goto cp0_unimplemented
;
8183 case CP0_REGISTER_16
:
8185 case CP0_REG16__CONFIG
:
8186 gen_helper_mtc0_config0(cpu_env
, arg
);
8187 register_name
= "Config";
8188 /* Stop translation as we may have switched the execution mode */
8189 ctx
->base
.is_jmp
= DISAS_STOP
;
8191 case CP0_REG16__CONFIG1
:
8192 /* ignored, read only */
8193 register_name
= "Config1";
8195 case CP0_REG16__CONFIG2
:
8196 gen_helper_mtc0_config2(cpu_env
, arg
);
8197 register_name
= "Config2";
8198 /* Stop translation as we may have switched the execution mode */
8199 ctx
->base
.is_jmp
= DISAS_STOP
;
8201 case CP0_REG16__CONFIG3
:
8202 gen_helper_mtc0_config3(cpu_env
, arg
);
8203 register_name
= "Config3";
8204 /* Stop translation as we may have switched the execution mode */
8205 ctx
->base
.is_jmp
= DISAS_STOP
;
8207 case CP0_REG16__CONFIG4
:
8208 gen_helper_mtc0_config4(cpu_env
, arg
);
8209 register_name
= "Config4";
8210 ctx
->base
.is_jmp
= DISAS_STOP
;
8212 case CP0_REG16__CONFIG5
:
8213 gen_helper_mtc0_config5(cpu_env
, arg
);
8214 register_name
= "Config5";
8215 /* Stop translation as we may have switched the execution mode */
8216 ctx
->base
.is_jmp
= DISAS_STOP
;
8218 /* 6,7 are implementation dependent */
8219 case CP0_REG16__CONFIG6
:
8221 register_name
= "Config6";
8223 case CP0_REG16__CONFIG7
:
8225 register_name
= "Config7";
8228 register_name
= "Invalid config selector";
8229 goto cp0_unimplemented
;
8232 case CP0_REGISTER_17
:
8234 case CP0_REG17__LLADDR
:
8235 gen_helper_mtc0_lladdr(cpu_env
, arg
);
8236 register_name
= "LLAddr";
8238 case CP0_REG17__MAAR
:
8239 CP0_CHECK(ctx
->mrp
);
8240 gen_helper_mtc0_maar(cpu_env
, arg
);
8241 register_name
= "MAAR";
8243 case CP0_REG17__MAARI
:
8244 CP0_CHECK(ctx
->mrp
);
8245 gen_helper_mtc0_maari(cpu_env
, arg
);
8246 register_name
= "MAARI";
8249 goto cp0_unimplemented
;
8252 case CP0_REGISTER_18
:
8254 case CP0_REG18__WATCHLO0
:
8255 case CP0_REG18__WATCHLO1
:
8256 case CP0_REG18__WATCHLO2
:
8257 case CP0_REG18__WATCHLO3
:
8258 case CP0_REG18__WATCHLO4
:
8259 case CP0_REG18__WATCHLO5
:
8260 case CP0_REG18__WATCHLO6
:
8261 case CP0_REG18__WATCHLO7
:
8262 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
8263 gen_helper_0e1i(mtc0_watchlo
, arg
, sel
);
8264 register_name
= "WatchLo";
8267 goto cp0_unimplemented
;
8270 case CP0_REGISTER_19
:
8272 case CP0_REG19__WATCHHI0
:
8273 case CP0_REG19__WATCHHI1
:
8274 case CP0_REG19__WATCHHI2
:
8275 case CP0_REG19__WATCHHI3
:
8276 case CP0_REG19__WATCHHI4
:
8277 case CP0_REG19__WATCHHI5
:
8278 case CP0_REG19__WATCHHI6
:
8279 case CP0_REG19__WATCHHI7
:
8280 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
8281 gen_helper_0e1i(mtc0_watchhi
, arg
, sel
);
8282 register_name
= "WatchHi";
8285 goto cp0_unimplemented
;
8288 case CP0_REGISTER_20
:
8290 case CP0_REG20__XCONTEXT
:
8291 #if defined(TARGET_MIPS64)
8292 check_insn(ctx
, ISA_MIPS3
);
8293 gen_helper_mtc0_xcontext(cpu_env
, arg
);
8294 register_name
= "XContext";
8298 goto cp0_unimplemented
;
8301 case CP0_REGISTER_21
:
8302 /* Officially reserved, but sel 0 is used for R1x000 framemask */
8303 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS_R6
));
8306 gen_helper_mtc0_framemask(cpu_env
, arg
);
8307 register_name
= "Framemask";
8310 goto cp0_unimplemented
;
8313 case CP0_REGISTER_22
:
8315 register_name
= "Diagnostic"; /* implementation dependent */
8317 case CP0_REGISTER_23
:
8319 case CP0_REG23__DEBUG
:
8320 gen_helper_mtc0_debug(cpu_env
, arg
); /* EJTAG support */
8321 /* DISAS_STOP isn't good enough here, hflags may have changed. */
8322 gen_save_pc(ctx
->base
.pc_next
+ 4);
8323 ctx
->base
.is_jmp
= DISAS_EXIT
;
8324 register_name
= "Debug";
8326 case CP0_REG23__TRACECONTROL
:
8327 /* PDtrace support */
8328 /* gen_helper_mtc0_tracecontrol(cpu_env, arg); */
8329 register_name
= "TraceControl";
8330 /* Stop translation as we may have switched the execution mode */
8331 ctx
->base
.is_jmp
= DISAS_STOP
;
8332 goto cp0_unimplemented
;
8333 case CP0_REG23__TRACECONTROL2
:
8334 /* PDtrace support */
8335 /* gen_helper_mtc0_tracecontrol2(cpu_env, arg); */
8336 register_name
= "TraceControl2";
8337 /* Stop translation as we may have switched the execution mode */
8338 ctx
->base
.is_jmp
= DISAS_STOP
;
8339 goto cp0_unimplemented
;
8340 case CP0_REG23__USERTRACEDATA1
:
8341 /* Stop translation as we may have switched the execution mode */
8342 ctx
->base
.is_jmp
= DISAS_STOP
;
8343 /* PDtrace support */
8344 /* gen_helper_mtc0_usertracedata1(cpu_env, arg);*/
8345 register_name
= "UserTraceData";
8346 /* Stop translation as we may have switched the execution mode */
8347 ctx
->base
.is_jmp
= DISAS_STOP
;
8348 goto cp0_unimplemented
;
8349 case CP0_REG23__TRACEIBPC
:
8350 /* PDtrace support */
8351 /* gen_helper_mtc0_traceibpc(cpu_env, arg); */
8352 /* Stop translation as we may have switched the execution mode */
8353 ctx
->base
.is_jmp
= DISAS_STOP
;
8354 register_name
= "TraceIBPC";
8355 goto cp0_unimplemented
;
8356 case CP0_REG23__TRACEDBPC
:
8357 /* PDtrace support */
8358 /* gen_helper_mtc0_tracedbpc(cpu_env, arg); */
8359 /* Stop translation as we may have switched the execution mode */
8360 ctx
->base
.is_jmp
= DISAS_STOP
;
8361 register_name
= "TraceDBPC";
8362 goto cp0_unimplemented
;
8364 goto cp0_unimplemented
;
8367 case CP0_REGISTER_24
:
8369 case CP0_REG24__DEPC
:
8371 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
8372 register_name
= "DEPC";
8375 goto cp0_unimplemented
;
8378 case CP0_REGISTER_25
:
8380 case CP0_REG25__PERFCTL0
:
8381 gen_helper_mtc0_performance0(cpu_env
, arg
);
8382 register_name
= "Performance0";
8384 case CP0_REG25__PERFCNT0
:
8385 /* gen_helper_mtc0_performance1(arg); */
8386 register_name
= "Performance1";
8387 goto cp0_unimplemented
;
8388 case CP0_REG25__PERFCTL1
:
8389 /* gen_helper_mtc0_performance2(arg); */
8390 register_name
= "Performance2";
8391 goto cp0_unimplemented
;
8392 case CP0_REG25__PERFCNT1
:
8393 /* gen_helper_mtc0_performance3(arg); */
8394 register_name
= "Performance3";
8395 goto cp0_unimplemented
;
8396 case CP0_REG25__PERFCTL2
:
8397 /* gen_helper_mtc0_performance4(arg); */
8398 register_name
= "Performance4";
8399 goto cp0_unimplemented
;
8400 case CP0_REG25__PERFCNT2
:
8401 /* gen_helper_mtc0_performance5(arg); */
8402 register_name
= "Performance5";
8403 goto cp0_unimplemented
;
8404 case CP0_REG25__PERFCTL3
:
8405 /* gen_helper_mtc0_performance6(arg); */
8406 register_name
= "Performance6";
8407 goto cp0_unimplemented
;
8408 case CP0_REG25__PERFCNT3
:
8409 /* gen_helper_mtc0_performance7(arg); */
8410 register_name
= "Performance7";
8411 goto cp0_unimplemented
;
8413 goto cp0_unimplemented
;
8416 case CP0_REGISTER_26
:
8418 case CP0_REG26__ERRCTL
:
8419 gen_helper_mtc0_errctl(cpu_env
, arg
);
8420 ctx
->base
.is_jmp
= DISAS_STOP
;
8421 register_name
= "ErrCtl";
8424 goto cp0_unimplemented
;
8427 case CP0_REGISTER_27
:
8429 case CP0_REG27__CACHERR
:
8431 register_name
= "CacheErr";
8434 goto cp0_unimplemented
;
8437 case CP0_REGISTER_28
:
8439 case CP0_REG28__TAGLO
:
8440 case CP0_REG28__TAGLO1
:
8441 case CP0_REG28__TAGLO2
:
8442 case CP0_REG28__TAGLO3
:
8443 gen_helper_mtc0_taglo(cpu_env
, arg
);
8444 register_name
= "TagLo";
8446 case CP0_REG28__DATALO
:
8447 case CP0_REG28__DATALO1
:
8448 case CP0_REG28__DATALO2
:
8449 case CP0_REG28__DATALO3
:
8450 gen_helper_mtc0_datalo(cpu_env
, arg
);
8451 register_name
= "DataLo";
8454 goto cp0_unimplemented
;
8457 case CP0_REGISTER_29
:
8459 case CP0_REG29__TAGHI
:
8460 case CP0_REG29__TAGHI1
:
8461 case CP0_REG29__TAGHI2
:
8462 case CP0_REG29__TAGHI3
:
8463 gen_helper_mtc0_taghi(cpu_env
, arg
);
8464 register_name
= "TagHi";
8466 case CP0_REG29__DATAHI
:
8467 case CP0_REG29__DATAHI1
:
8468 case CP0_REG29__DATAHI2
:
8469 case CP0_REG29__DATAHI3
:
8470 gen_helper_mtc0_datahi(cpu_env
, arg
);
8471 register_name
= "DataHi";
8474 register_name
= "invalid sel";
8475 goto cp0_unimplemented
;
8478 case CP0_REGISTER_30
:
8480 case CP0_REG30__ERROREPC
:
8481 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
8482 register_name
= "ErrorEPC";
8485 goto cp0_unimplemented
;
8488 case CP0_REGISTER_31
:
8490 case CP0_REG31__DESAVE
:
8492 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
8493 register_name
= "DESAVE";
8495 case CP0_REG31__KSCRATCH1
:
8496 case CP0_REG31__KSCRATCH2
:
8497 case CP0_REG31__KSCRATCH3
:
8498 case CP0_REG31__KSCRATCH4
:
8499 case CP0_REG31__KSCRATCH5
:
8500 case CP0_REG31__KSCRATCH6
:
8501 CP0_CHECK(ctx
->kscrexist
& (1 << sel
));
8502 tcg_gen_st_tl(arg
, cpu_env
,
8503 offsetof(CPUMIPSState
, CP0_KScratch
[sel
- 2]));
8504 register_name
= "KScratch";
8507 goto cp0_unimplemented
;
8511 goto cp0_unimplemented
;
8513 trace_mips_translate_c0("mtc0", register_name
, reg
, sel
);
8515 /* For simplicity assume that all writes can cause interrupts. */
8516 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
8518 * DISAS_STOP isn't sufficient, we need to ensure we break out of
8519 * translated code to check for pending interrupts.
8521 gen_save_pc(ctx
->base
.pc_next
+ 4);
8522 ctx
->base
.is_jmp
= DISAS_EXIT
;
8527 qemu_log_mask(LOG_UNIMP
, "mtc0 %s (reg %d sel %d)\n",
8528 register_name
, reg
, sel
);
8531 #if defined(TARGET_MIPS64)
8532 static void gen_dmfc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
8534 const char *register_name
= "invalid";
8537 check_insn(ctx
, ISA_MIPS_R1
);
8541 case CP0_REGISTER_00
:
8543 case CP0_REG00__INDEX
:
8544 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Index
));
8545 register_name
= "Index";
8547 case CP0_REG00__MVPCONTROL
:
8548 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8549 gen_helper_mfc0_mvpcontrol(arg
, cpu_env
);
8550 register_name
= "MVPControl";
8552 case CP0_REG00__MVPCONF0
:
8553 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8554 gen_helper_mfc0_mvpconf0(arg
, cpu_env
);
8555 register_name
= "MVPConf0";
8557 case CP0_REG00__MVPCONF1
:
8558 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8559 gen_helper_mfc0_mvpconf1(arg
, cpu_env
);
8560 register_name
= "MVPConf1";
8562 case CP0_REG00__VPCONTROL
:
8564 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPControl
));
8565 register_name
= "VPControl";
8568 goto cp0_unimplemented
;
8571 case CP0_REGISTER_01
:
8573 case CP0_REG01__RANDOM
:
8574 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS_R6
));
8575 gen_helper_mfc0_random(arg
, cpu_env
);
8576 register_name
= "Random";
8578 case CP0_REG01__VPECONTROL
:
8579 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8580 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEControl
));
8581 register_name
= "VPEControl";
8583 case CP0_REG01__VPECONF0
:
8584 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8585 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf0
));
8586 register_name
= "VPEConf0";
8588 case CP0_REG01__VPECONF1
:
8589 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8590 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf1
));
8591 register_name
= "VPEConf1";
8593 case CP0_REG01__YQMASK
:
8594 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8595 tcg_gen_ld_tl(arg
, cpu_env
,
8596 offsetof(CPUMIPSState
, CP0_YQMask
));
8597 register_name
= "YQMask";
8599 case CP0_REG01__VPESCHEDULE
:
8600 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8601 tcg_gen_ld_tl(arg
, cpu_env
,
8602 offsetof(CPUMIPSState
, CP0_VPESchedule
));
8603 register_name
= "VPESchedule";
8605 case CP0_REG01__VPESCHEFBACK
:
8606 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8607 tcg_gen_ld_tl(arg
, cpu_env
,
8608 offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
8609 register_name
= "VPEScheFBack";
8611 case CP0_REG01__VPEOPT
:
8612 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8613 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEOpt
));
8614 register_name
= "VPEOpt";
8617 goto cp0_unimplemented
;
8620 case CP0_REGISTER_02
:
8622 case CP0_REG02__ENTRYLO0
:
8623 tcg_gen_ld_tl(arg
, cpu_env
,
8624 offsetof(CPUMIPSState
, CP0_EntryLo0
));
8625 register_name
= "EntryLo0";
8627 case CP0_REG02__TCSTATUS
:
8628 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8629 gen_helper_mfc0_tcstatus(arg
, cpu_env
);
8630 register_name
= "TCStatus";
8632 case CP0_REG02__TCBIND
:
8633 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8634 gen_helper_mfc0_tcbind(arg
, cpu_env
);
8635 register_name
= "TCBind";
8637 case CP0_REG02__TCRESTART
:
8638 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8639 gen_helper_dmfc0_tcrestart(arg
, cpu_env
);
8640 register_name
= "TCRestart";
8642 case CP0_REG02__TCHALT
:
8643 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8644 gen_helper_dmfc0_tchalt(arg
, cpu_env
);
8645 register_name
= "TCHalt";
8647 case CP0_REG02__TCCONTEXT
:
8648 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8649 gen_helper_dmfc0_tccontext(arg
, cpu_env
);
8650 register_name
= "TCContext";
8652 case CP0_REG02__TCSCHEDULE
:
8653 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8654 gen_helper_dmfc0_tcschedule(arg
, cpu_env
);
8655 register_name
= "TCSchedule";
8657 case CP0_REG02__TCSCHEFBACK
:
8658 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8659 gen_helper_dmfc0_tcschefback(arg
, cpu_env
);
8660 register_name
= "TCScheFBack";
8663 goto cp0_unimplemented
;
8666 case CP0_REGISTER_03
:
8668 case CP0_REG03__ENTRYLO1
:
8669 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryLo1
));
8670 register_name
= "EntryLo1";
8672 case CP0_REG03__GLOBALNUM
:
8674 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_GlobalNumber
));
8675 register_name
= "GlobalNumber";
8678 goto cp0_unimplemented
;
8681 case CP0_REGISTER_04
:
8683 case CP0_REG04__CONTEXT
:
8684 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_Context
));
8685 register_name
= "Context";
8687 case CP0_REG04__CONTEXTCONFIG
:
8689 /* gen_helper_dmfc0_contextconfig(arg); */
8690 register_name
= "ContextConfig";
8691 goto cp0_unimplemented
;
8692 case CP0_REG04__USERLOCAL
:
8693 CP0_CHECK(ctx
->ulri
);
8694 tcg_gen_ld_tl(arg
, cpu_env
,
8695 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
8696 register_name
= "UserLocal";
8698 case CP0_REG04__MMID
:
8700 gen_helper_mtc0_memorymapid(cpu_env
, arg
);
8701 register_name
= "MMID";
8704 goto cp0_unimplemented
;
8707 case CP0_REGISTER_05
:
8709 case CP0_REG05__PAGEMASK
:
8710 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageMask
));
8711 register_name
= "PageMask";
8713 case CP0_REG05__PAGEGRAIN
:
8714 check_insn(ctx
, ISA_MIPS_R2
);
8715 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageGrain
));
8716 register_name
= "PageGrain";
8718 case CP0_REG05__SEGCTL0
:
8720 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_SegCtl0
));
8721 register_name
= "SegCtl0";
8723 case CP0_REG05__SEGCTL1
:
8725 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_SegCtl1
));
8726 register_name
= "SegCtl1";
8728 case CP0_REG05__SEGCTL2
:
8730 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_SegCtl2
));
8731 register_name
= "SegCtl2";
8733 case CP0_REG05__PWBASE
:
8735 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_PWBase
));
8736 register_name
= "PWBase";
8738 case CP0_REG05__PWFIELD
:
8740 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_PWField
));
8741 register_name
= "PWField";
8743 case CP0_REG05__PWSIZE
:
8745 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_PWSize
));
8746 register_name
= "PWSize";
8749 goto cp0_unimplemented
;
8752 case CP0_REGISTER_06
:
8754 case CP0_REG06__WIRED
:
8755 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Wired
));
8756 register_name
= "Wired";
8758 case CP0_REG06__SRSCONF0
:
8759 check_insn(ctx
, ISA_MIPS_R2
);
8760 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf0
));
8761 register_name
= "SRSConf0";
8763 case CP0_REG06__SRSCONF1
:
8764 check_insn(ctx
, ISA_MIPS_R2
);
8765 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf1
));
8766 register_name
= "SRSConf1";
8768 case CP0_REG06__SRSCONF2
:
8769 check_insn(ctx
, ISA_MIPS_R2
);
8770 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf2
));
8771 register_name
= "SRSConf2";
8773 case CP0_REG06__SRSCONF3
:
8774 check_insn(ctx
, ISA_MIPS_R2
);
8775 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf3
));
8776 register_name
= "SRSConf3";
8778 case CP0_REG06__SRSCONF4
:
8779 check_insn(ctx
, ISA_MIPS_R2
);
8780 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf4
));
8781 register_name
= "SRSConf4";
8783 case CP0_REG06__PWCTL
:
8785 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PWCtl
));
8786 register_name
= "PWCtl";
8789 goto cp0_unimplemented
;
8792 case CP0_REGISTER_07
:
8794 case CP0_REG07__HWRENA
:
8795 check_insn(ctx
, ISA_MIPS_R2
);
8796 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_HWREna
));
8797 register_name
= "HWREna";
8800 goto cp0_unimplemented
;
8803 case CP0_REGISTER_08
:
8805 case CP0_REG08__BADVADDR
:
8806 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_BadVAddr
));
8807 register_name
= "BadVAddr";
8809 case CP0_REG08__BADINSTR
:
8811 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstr
));
8812 register_name
= "BadInstr";
8814 case CP0_REG08__BADINSTRP
:
8816 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstrP
));
8817 register_name
= "BadInstrP";
8819 case CP0_REG08__BADINSTRX
:
8821 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstrX
));
8822 tcg_gen_andi_tl(arg
, arg
, ~0xffff);
8823 register_name
= "BadInstrX";
8826 goto cp0_unimplemented
;
8829 case CP0_REGISTER_09
:
8831 case CP0_REG09__COUNT
:
8832 /* Mark as an IO operation because we read the time. */
8833 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
8836 gen_helper_mfc0_count(arg
, cpu_env
);
8838 * Break the TB to be able to take timer interrupts immediately
8839 * after reading count. DISAS_STOP isn't sufficient, we need to
8840 * ensure we break completely out of translated code.
8842 gen_save_pc(ctx
->base
.pc_next
+ 4);
8843 ctx
->base
.is_jmp
= DISAS_EXIT
;
8844 register_name
= "Count";
8846 case CP0_REG09__SAARI
:
8847 CP0_CHECK(ctx
->saar
);
8848 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SAARI
));
8849 register_name
= "SAARI";
8851 case CP0_REG09__SAAR
:
8852 CP0_CHECK(ctx
->saar
);
8853 gen_helper_dmfc0_saar(arg
, cpu_env
);
8854 register_name
= "SAAR";
8857 goto cp0_unimplemented
;
8860 case CP0_REGISTER_10
:
8862 case CP0_REG10__ENTRYHI
:
8863 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryHi
));
8864 register_name
= "EntryHi";
8867 goto cp0_unimplemented
;
8870 case CP0_REGISTER_11
:
8872 case CP0_REG11__COMPARE
:
8873 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Compare
));
8874 register_name
= "Compare";
8876 /* 6,7 are implementation dependent */
8878 goto cp0_unimplemented
;
8881 case CP0_REGISTER_12
:
8883 case CP0_REG12__STATUS
:
8884 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Status
));
8885 register_name
= "Status";
8887 case CP0_REG12__INTCTL
:
8888 check_insn(ctx
, ISA_MIPS_R2
);
8889 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_IntCtl
));
8890 register_name
= "IntCtl";
8892 case CP0_REG12__SRSCTL
:
8893 check_insn(ctx
, ISA_MIPS_R2
);
8894 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
8895 register_name
= "SRSCtl";
8897 case CP0_REG12__SRSMAP
:
8898 check_insn(ctx
, ISA_MIPS_R2
);
8899 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
8900 register_name
= "SRSMap";
8903 goto cp0_unimplemented
;
8906 case CP0_REGISTER_13
:
8908 case CP0_REG13__CAUSE
:
8909 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Cause
));
8910 register_name
= "Cause";
8913 goto cp0_unimplemented
;
8916 case CP0_REGISTER_14
:
8918 case CP0_REG14__EPC
:
8919 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
8920 register_name
= "EPC";
8923 goto cp0_unimplemented
;
8926 case CP0_REGISTER_15
:
8928 case CP0_REG15__PRID
:
8929 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PRid
));
8930 register_name
= "PRid";
8932 case CP0_REG15__EBASE
:
8933 check_insn(ctx
, ISA_MIPS_R2
);
8934 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EBase
));
8935 register_name
= "EBase";
8937 case CP0_REG15__CMGCRBASE
:
8938 check_insn(ctx
, ISA_MIPS_R2
);
8939 CP0_CHECK(ctx
->cmgcr
);
8940 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_CMGCRBase
));
8941 register_name
= "CMGCRBase";
8944 goto cp0_unimplemented
;
8947 case CP0_REGISTER_16
:
8949 case CP0_REG16__CONFIG
:
8950 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config0
));
8951 register_name
= "Config";
8953 case CP0_REG16__CONFIG1
:
8954 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config1
));
8955 register_name
= "Config1";
8957 case CP0_REG16__CONFIG2
:
8958 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config2
));
8959 register_name
= "Config2";
8961 case CP0_REG16__CONFIG3
:
8962 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config3
));
8963 register_name
= "Config3";
8965 case CP0_REG16__CONFIG4
:
8966 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config4
));
8967 register_name
= "Config4";
8969 case CP0_REG16__CONFIG5
:
8970 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config5
));
8971 register_name
= "Config5";
8973 /* 6,7 are implementation dependent */
8974 case CP0_REG16__CONFIG6
:
8975 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config6
));
8976 register_name
= "Config6";
8978 case CP0_REG16__CONFIG7
:
8979 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config7
));
8980 register_name
= "Config7";
8983 goto cp0_unimplemented
;
8986 case CP0_REGISTER_17
:
8988 case CP0_REG17__LLADDR
:
8989 gen_helper_dmfc0_lladdr(arg
, cpu_env
);
8990 register_name
= "LLAddr";
8992 case CP0_REG17__MAAR
:
8993 CP0_CHECK(ctx
->mrp
);
8994 gen_helper_dmfc0_maar(arg
, cpu_env
);
8995 register_name
= "MAAR";
8997 case CP0_REG17__MAARI
:
8998 CP0_CHECK(ctx
->mrp
);
8999 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_MAARI
));
9000 register_name
= "MAARI";
9003 goto cp0_unimplemented
;
9006 case CP0_REGISTER_18
:
9008 case CP0_REG18__WATCHLO0
:
9009 case CP0_REG18__WATCHLO1
:
9010 case CP0_REG18__WATCHLO2
:
9011 case CP0_REG18__WATCHLO3
:
9012 case CP0_REG18__WATCHLO4
:
9013 case CP0_REG18__WATCHLO5
:
9014 case CP0_REG18__WATCHLO6
:
9015 case CP0_REG18__WATCHLO7
:
9016 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
9017 gen_helper_1e0i(dmfc0_watchlo
, arg
, sel
);
9018 register_name
= "WatchLo";
9021 goto cp0_unimplemented
;
9024 case CP0_REGISTER_19
:
9026 case CP0_REG19__WATCHHI0
:
9027 case CP0_REG19__WATCHHI1
:
9028 case CP0_REG19__WATCHHI2
:
9029 case CP0_REG19__WATCHHI3
:
9030 case CP0_REG19__WATCHHI4
:
9031 case CP0_REG19__WATCHHI5
:
9032 case CP0_REG19__WATCHHI6
:
9033 case CP0_REG19__WATCHHI7
:
9034 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
9035 gen_helper_1e0i(dmfc0_watchhi
, arg
, sel
);
9036 register_name
= "WatchHi";
9039 goto cp0_unimplemented
;
9042 case CP0_REGISTER_20
:
9044 case CP0_REG20__XCONTEXT
:
9045 check_insn(ctx
, ISA_MIPS3
);
9046 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_XContext
));
9047 register_name
= "XContext";
9050 goto cp0_unimplemented
;
9053 case CP0_REGISTER_21
:
9054 /* Officially reserved, but sel 0 is used for R1x000 framemask */
9055 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS_R6
));
9058 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Framemask
));
9059 register_name
= "Framemask";
9062 goto cp0_unimplemented
;
9065 case CP0_REGISTER_22
:
9066 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
9067 register_name
= "'Diagnostic"; /* implementation dependent */
9069 case CP0_REGISTER_23
:
9071 case CP0_REG23__DEBUG
:
9072 gen_helper_mfc0_debug(arg
, cpu_env
); /* EJTAG support */
9073 register_name
= "Debug";
9075 case CP0_REG23__TRACECONTROL
:
9076 /* PDtrace support */
9077 /* gen_helper_dmfc0_tracecontrol(arg, cpu_env); */
9078 register_name
= "TraceControl";
9079 goto cp0_unimplemented
;
9080 case CP0_REG23__TRACECONTROL2
:
9081 /* PDtrace support */
9082 /* gen_helper_dmfc0_tracecontrol2(arg, cpu_env); */
9083 register_name
= "TraceControl2";
9084 goto cp0_unimplemented
;
9085 case CP0_REG23__USERTRACEDATA1
:
9086 /* PDtrace support */
9087 /* gen_helper_dmfc0_usertracedata1(arg, cpu_env);*/
9088 register_name
= "UserTraceData1";
9089 goto cp0_unimplemented
;
9090 case CP0_REG23__TRACEIBPC
:
9091 /* PDtrace support */
9092 /* gen_helper_dmfc0_traceibpc(arg, cpu_env); */
9093 register_name
= "TraceIBPC";
9094 goto cp0_unimplemented
;
9095 case CP0_REG23__TRACEDBPC
:
9096 /* PDtrace support */
9097 /* gen_helper_dmfc0_tracedbpc(arg, cpu_env); */
9098 register_name
= "TraceDBPC";
9099 goto cp0_unimplemented
;
9101 goto cp0_unimplemented
;
9104 case CP0_REGISTER_24
:
9106 case CP0_REG24__DEPC
:
9108 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
9109 register_name
= "DEPC";
9112 goto cp0_unimplemented
;
9115 case CP0_REGISTER_25
:
9117 case CP0_REG25__PERFCTL0
:
9118 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Performance0
));
9119 register_name
= "Performance0";
9121 case CP0_REG25__PERFCNT0
:
9122 /* gen_helper_dmfc0_performance1(arg); */
9123 register_name
= "Performance1";
9124 goto cp0_unimplemented
;
9125 case CP0_REG25__PERFCTL1
:
9126 /* gen_helper_dmfc0_performance2(arg); */
9127 register_name
= "Performance2";
9128 goto cp0_unimplemented
;
9129 case CP0_REG25__PERFCNT1
:
9130 /* gen_helper_dmfc0_performance3(arg); */
9131 register_name
= "Performance3";
9132 goto cp0_unimplemented
;
9133 case CP0_REG25__PERFCTL2
:
9134 /* gen_helper_dmfc0_performance4(arg); */
9135 register_name
= "Performance4";
9136 goto cp0_unimplemented
;
9137 case CP0_REG25__PERFCNT2
:
9138 /* gen_helper_dmfc0_performance5(arg); */
9139 register_name
= "Performance5";
9140 goto cp0_unimplemented
;
9141 case CP0_REG25__PERFCTL3
:
9142 /* gen_helper_dmfc0_performance6(arg); */
9143 register_name
= "Performance6";
9144 goto cp0_unimplemented
;
9145 case CP0_REG25__PERFCNT3
:
9146 /* gen_helper_dmfc0_performance7(arg); */
9147 register_name
= "Performance7";
9148 goto cp0_unimplemented
;
9150 goto cp0_unimplemented
;
9153 case CP0_REGISTER_26
:
9155 case CP0_REG26__ERRCTL
:
9156 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_ErrCtl
));
9157 register_name
= "ErrCtl";
9160 goto cp0_unimplemented
;
9163 case CP0_REGISTER_27
:
9166 case CP0_REG27__CACHERR
:
9167 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
9168 register_name
= "CacheErr";
9171 goto cp0_unimplemented
;
9174 case CP0_REGISTER_28
:
9176 case CP0_REG28__TAGLO
:
9177 case CP0_REG28__TAGLO1
:
9178 case CP0_REG28__TAGLO2
:
9179 case CP0_REG28__TAGLO3
:
9180 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagLo
));
9181 register_name
= "TagLo";
9183 case CP0_REG28__DATALO
:
9184 case CP0_REG28__DATALO1
:
9185 case CP0_REG28__DATALO2
:
9186 case CP0_REG28__DATALO3
:
9187 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataLo
));
9188 register_name
= "DataLo";
9191 goto cp0_unimplemented
;
9194 case CP0_REGISTER_29
:
9196 case CP0_REG29__TAGHI
:
9197 case CP0_REG29__TAGHI1
:
9198 case CP0_REG29__TAGHI2
:
9199 case CP0_REG29__TAGHI3
:
9200 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagHi
));
9201 register_name
= "TagHi";
9203 case CP0_REG29__DATAHI
:
9204 case CP0_REG29__DATAHI1
:
9205 case CP0_REG29__DATAHI2
:
9206 case CP0_REG29__DATAHI3
:
9207 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataHi
));
9208 register_name
= "DataHi";
9211 goto cp0_unimplemented
;
9214 case CP0_REGISTER_30
:
9216 case CP0_REG30__ERROREPC
:
9217 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
9218 register_name
= "ErrorEPC";
9221 goto cp0_unimplemented
;
9224 case CP0_REGISTER_31
:
9226 case CP0_REG31__DESAVE
:
9228 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
9229 register_name
= "DESAVE";
9231 case CP0_REG31__KSCRATCH1
:
9232 case CP0_REG31__KSCRATCH2
:
9233 case CP0_REG31__KSCRATCH3
:
9234 case CP0_REG31__KSCRATCH4
:
9235 case CP0_REG31__KSCRATCH5
:
9236 case CP0_REG31__KSCRATCH6
:
9237 CP0_CHECK(ctx
->kscrexist
& (1 << sel
));
9238 tcg_gen_ld_tl(arg
, cpu_env
,
9239 offsetof(CPUMIPSState
, CP0_KScratch
[sel
- 2]));
9240 register_name
= "KScratch";
9243 goto cp0_unimplemented
;
9247 goto cp0_unimplemented
;
9249 trace_mips_translate_c0("dmfc0", register_name
, reg
, sel
);
9253 qemu_log_mask(LOG_UNIMP
, "dmfc0 %s (reg %d sel %d)\n",
9254 register_name
, reg
, sel
);
9255 gen_mfc0_unimplemented(ctx
, arg
);
9258 static void gen_dmtc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
9260 const char *register_name
= "invalid";
9263 check_insn(ctx
, ISA_MIPS_R1
);
9266 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
9271 case CP0_REGISTER_00
:
9273 case CP0_REG00__INDEX
:
9274 gen_helper_mtc0_index(cpu_env
, arg
);
9275 register_name
= "Index";
9277 case CP0_REG00__MVPCONTROL
:
9278 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9279 gen_helper_mtc0_mvpcontrol(cpu_env
, arg
);
9280 register_name
= "MVPControl";
9282 case CP0_REG00__MVPCONF0
:
9283 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9285 register_name
= "MVPConf0";
9287 case CP0_REG00__MVPCONF1
:
9288 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9290 register_name
= "MVPConf1";
9292 case CP0_REG00__VPCONTROL
:
9295 register_name
= "VPControl";
9298 goto cp0_unimplemented
;
9301 case CP0_REGISTER_01
:
9303 case CP0_REG01__RANDOM
:
9305 register_name
= "Random";
9307 case CP0_REG01__VPECONTROL
:
9308 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9309 gen_helper_mtc0_vpecontrol(cpu_env
, arg
);
9310 register_name
= "VPEControl";
9312 case CP0_REG01__VPECONF0
:
9313 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9314 gen_helper_mtc0_vpeconf0(cpu_env
, arg
);
9315 register_name
= "VPEConf0";
9317 case CP0_REG01__VPECONF1
:
9318 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9319 gen_helper_mtc0_vpeconf1(cpu_env
, arg
);
9320 register_name
= "VPEConf1";
9322 case CP0_REG01__YQMASK
:
9323 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9324 gen_helper_mtc0_yqmask(cpu_env
, arg
);
9325 register_name
= "YQMask";
9327 case CP0_REG01__VPESCHEDULE
:
9328 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9329 tcg_gen_st_tl(arg
, cpu_env
,
9330 offsetof(CPUMIPSState
, CP0_VPESchedule
));
9331 register_name
= "VPESchedule";
9333 case CP0_REG01__VPESCHEFBACK
:
9334 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9335 tcg_gen_st_tl(arg
, cpu_env
,
9336 offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
9337 register_name
= "VPEScheFBack";
9339 case CP0_REG01__VPEOPT
:
9340 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9341 gen_helper_mtc0_vpeopt(cpu_env
, arg
);
9342 register_name
= "VPEOpt";
9345 goto cp0_unimplemented
;
9348 case CP0_REGISTER_02
:
9350 case CP0_REG02__ENTRYLO0
:
9351 gen_helper_dmtc0_entrylo0(cpu_env
, arg
);
9352 register_name
= "EntryLo0";
9354 case CP0_REG02__TCSTATUS
:
9355 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9356 gen_helper_mtc0_tcstatus(cpu_env
, arg
);
9357 register_name
= "TCStatus";
9359 case CP0_REG02__TCBIND
:
9360 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9361 gen_helper_mtc0_tcbind(cpu_env
, arg
);
9362 register_name
= "TCBind";
9364 case CP0_REG02__TCRESTART
:
9365 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9366 gen_helper_mtc0_tcrestart(cpu_env
, arg
);
9367 register_name
= "TCRestart";
9369 case CP0_REG02__TCHALT
:
9370 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9371 gen_helper_mtc0_tchalt(cpu_env
, arg
);
9372 register_name
= "TCHalt";
9374 case CP0_REG02__TCCONTEXT
:
9375 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9376 gen_helper_mtc0_tccontext(cpu_env
, arg
);
9377 register_name
= "TCContext";
9379 case CP0_REG02__TCSCHEDULE
:
9380 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9381 gen_helper_mtc0_tcschedule(cpu_env
, arg
);
9382 register_name
= "TCSchedule";
9384 case CP0_REG02__TCSCHEFBACK
:
9385 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9386 gen_helper_mtc0_tcschefback(cpu_env
, arg
);
9387 register_name
= "TCScheFBack";
9390 goto cp0_unimplemented
;
9393 case CP0_REGISTER_03
:
9395 case CP0_REG03__ENTRYLO1
:
9396 gen_helper_dmtc0_entrylo1(cpu_env
, arg
);
9397 register_name
= "EntryLo1";
9399 case CP0_REG03__GLOBALNUM
:
9402 register_name
= "GlobalNumber";
9405 goto cp0_unimplemented
;
9408 case CP0_REGISTER_04
:
9410 case CP0_REG04__CONTEXT
:
9411 gen_helper_mtc0_context(cpu_env
, arg
);
9412 register_name
= "Context";
9414 case CP0_REG04__CONTEXTCONFIG
:
9416 /* gen_helper_dmtc0_contextconfig(arg); */
9417 register_name
= "ContextConfig";
9418 goto cp0_unimplemented
;
9419 case CP0_REG04__USERLOCAL
:
9420 CP0_CHECK(ctx
->ulri
);
9421 tcg_gen_st_tl(arg
, cpu_env
,
9422 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
9423 register_name
= "UserLocal";
9425 case CP0_REG04__MMID
:
9427 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_MemoryMapID
));
9428 register_name
= "MMID";
9431 goto cp0_unimplemented
;
9434 case CP0_REGISTER_05
:
9436 case CP0_REG05__PAGEMASK
:
9437 gen_helper_mtc0_pagemask(cpu_env
, arg
);
9438 register_name
= "PageMask";
9440 case CP0_REG05__PAGEGRAIN
:
9441 check_insn(ctx
, ISA_MIPS_R2
);
9442 gen_helper_mtc0_pagegrain(cpu_env
, arg
);
9443 register_name
= "PageGrain";
9445 case CP0_REG05__SEGCTL0
:
9447 gen_helper_mtc0_segctl0(cpu_env
, arg
);
9448 register_name
= "SegCtl0";
9450 case CP0_REG05__SEGCTL1
:
9452 gen_helper_mtc0_segctl1(cpu_env
, arg
);
9453 register_name
= "SegCtl1";
9455 case CP0_REG05__SEGCTL2
:
9457 gen_helper_mtc0_segctl2(cpu_env
, arg
);
9458 register_name
= "SegCtl2";
9460 case CP0_REG05__PWBASE
:
9462 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_PWBase
));
9463 register_name
= "PWBase";
9465 case CP0_REG05__PWFIELD
:
9467 gen_helper_mtc0_pwfield(cpu_env
, arg
);
9468 register_name
= "PWField";
9470 case CP0_REG05__PWSIZE
:
9472 gen_helper_mtc0_pwsize(cpu_env
, arg
);
9473 register_name
= "PWSize";
9476 goto cp0_unimplemented
;
9479 case CP0_REGISTER_06
:
9481 case CP0_REG06__WIRED
:
9482 gen_helper_mtc0_wired(cpu_env
, arg
);
9483 register_name
= "Wired";
9485 case CP0_REG06__SRSCONF0
:
9486 check_insn(ctx
, ISA_MIPS_R2
);
9487 gen_helper_mtc0_srsconf0(cpu_env
, arg
);
9488 register_name
= "SRSConf0";
9490 case CP0_REG06__SRSCONF1
:
9491 check_insn(ctx
, ISA_MIPS_R2
);
9492 gen_helper_mtc0_srsconf1(cpu_env
, arg
);
9493 register_name
= "SRSConf1";
9495 case CP0_REG06__SRSCONF2
:
9496 check_insn(ctx
, ISA_MIPS_R2
);
9497 gen_helper_mtc0_srsconf2(cpu_env
, arg
);
9498 register_name
= "SRSConf2";
9500 case CP0_REG06__SRSCONF3
:
9501 check_insn(ctx
, ISA_MIPS_R2
);
9502 gen_helper_mtc0_srsconf3(cpu_env
, arg
);
9503 register_name
= "SRSConf3";
9505 case CP0_REG06__SRSCONF4
:
9506 check_insn(ctx
, ISA_MIPS_R2
);
9507 gen_helper_mtc0_srsconf4(cpu_env
, arg
);
9508 register_name
= "SRSConf4";
9510 case CP0_REG06__PWCTL
:
9512 gen_helper_mtc0_pwctl(cpu_env
, arg
);
9513 register_name
= "PWCtl";
9516 goto cp0_unimplemented
;
9519 case CP0_REGISTER_07
:
9521 case CP0_REG07__HWRENA
:
9522 check_insn(ctx
, ISA_MIPS_R2
);
9523 gen_helper_mtc0_hwrena(cpu_env
, arg
);
9524 ctx
->base
.is_jmp
= DISAS_STOP
;
9525 register_name
= "HWREna";
9528 goto cp0_unimplemented
;
9531 case CP0_REGISTER_08
:
9533 case CP0_REG08__BADVADDR
:
9535 register_name
= "BadVAddr";
9537 case CP0_REG08__BADINSTR
:
9539 register_name
= "BadInstr";
9541 case CP0_REG08__BADINSTRP
:
9543 register_name
= "BadInstrP";
9545 case CP0_REG08__BADINSTRX
:
9547 register_name
= "BadInstrX";
9550 goto cp0_unimplemented
;
9553 case CP0_REGISTER_09
:
9555 case CP0_REG09__COUNT
:
9556 gen_helper_mtc0_count(cpu_env
, arg
);
9557 register_name
= "Count";
9559 case CP0_REG09__SAARI
:
9560 CP0_CHECK(ctx
->saar
);
9561 gen_helper_mtc0_saari(cpu_env
, arg
);
9562 register_name
= "SAARI";
9564 case CP0_REG09__SAAR
:
9565 CP0_CHECK(ctx
->saar
);
9566 gen_helper_mtc0_saar(cpu_env
, arg
);
9567 register_name
= "SAAR";
9570 goto cp0_unimplemented
;
9572 /* Stop translation as we may have switched the execution mode */
9573 ctx
->base
.is_jmp
= DISAS_STOP
;
9575 case CP0_REGISTER_10
:
9577 case CP0_REG10__ENTRYHI
:
9578 gen_helper_mtc0_entryhi(cpu_env
, arg
);
9579 register_name
= "EntryHi";
9582 goto cp0_unimplemented
;
9585 case CP0_REGISTER_11
:
9587 case CP0_REG11__COMPARE
:
9588 gen_helper_mtc0_compare(cpu_env
, arg
);
9589 register_name
= "Compare";
9591 /* 6,7 are implementation dependent */
9593 goto cp0_unimplemented
;
9595 /* Stop translation as we may have switched the execution mode */
9596 ctx
->base
.is_jmp
= DISAS_STOP
;
9598 case CP0_REGISTER_12
:
9600 case CP0_REG12__STATUS
:
9601 save_cpu_state(ctx
, 1);
9602 gen_helper_mtc0_status(cpu_env
, arg
);
9603 /* DISAS_STOP isn't good enough here, hflags may have changed. */
9604 gen_save_pc(ctx
->base
.pc_next
+ 4);
9605 ctx
->base
.is_jmp
= DISAS_EXIT
;
9606 register_name
= "Status";
9608 case CP0_REG12__INTCTL
:
9609 check_insn(ctx
, ISA_MIPS_R2
);
9610 gen_helper_mtc0_intctl(cpu_env
, arg
);
9611 /* Stop translation as we may have switched the execution mode */
9612 ctx
->base
.is_jmp
= DISAS_STOP
;
9613 register_name
= "IntCtl";
9615 case CP0_REG12__SRSCTL
:
9616 check_insn(ctx
, ISA_MIPS_R2
);
9617 gen_helper_mtc0_srsctl(cpu_env
, arg
);
9618 /* Stop translation as we may have switched the execution mode */
9619 ctx
->base
.is_jmp
= DISAS_STOP
;
9620 register_name
= "SRSCtl";
9622 case CP0_REG12__SRSMAP
:
9623 check_insn(ctx
, ISA_MIPS_R2
);
9624 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
9625 /* Stop translation as we may have switched the execution mode */
9626 ctx
->base
.is_jmp
= DISAS_STOP
;
9627 register_name
= "SRSMap";
9630 goto cp0_unimplemented
;
9633 case CP0_REGISTER_13
:
9635 case CP0_REG13__CAUSE
:
9636 save_cpu_state(ctx
, 1);
9637 gen_helper_mtc0_cause(cpu_env
, arg
);
9639 * Stop translation as we may have triggered an interrupt.
9640 * DISAS_STOP isn't sufficient, we need to ensure we break out of
9641 * translated code to check for pending interrupts.
9643 gen_save_pc(ctx
->base
.pc_next
+ 4);
9644 ctx
->base
.is_jmp
= DISAS_EXIT
;
9645 register_name
= "Cause";
9648 goto cp0_unimplemented
;
9651 case CP0_REGISTER_14
:
9653 case CP0_REG14__EPC
:
9654 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
9655 register_name
= "EPC";
9658 goto cp0_unimplemented
;
9661 case CP0_REGISTER_15
:
9663 case CP0_REG15__PRID
:
9665 register_name
= "PRid";
9667 case CP0_REG15__EBASE
:
9668 check_insn(ctx
, ISA_MIPS_R2
);
9669 gen_helper_mtc0_ebase(cpu_env
, arg
);
9670 register_name
= "EBase";
9673 goto cp0_unimplemented
;
9676 case CP0_REGISTER_16
:
9678 case CP0_REG16__CONFIG
:
9679 gen_helper_mtc0_config0(cpu_env
, arg
);
9680 register_name
= "Config";
9681 /* Stop translation as we may have switched the execution mode */
9682 ctx
->base
.is_jmp
= DISAS_STOP
;
9684 case CP0_REG16__CONFIG1
:
9685 /* ignored, read only */
9686 register_name
= "Config1";
9688 case CP0_REG16__CONFIG2
:
9689 gen_helper_mtc0_config2(cpu_env
, arg
);
9690 register_name
= "Config2";
9691 /* Stop translation as we may have switched the execution mode */
9692 ctx
->base
.is_jmp
= DISAS_STOP
;
9694 case CP0_REG16__CONFIG3
:
9695 gen_helper_mtc0_config3(cpu_env
, arg
);
9696 register_name
= "Config3";
9697 /* Stop translation as we may have switched the execution mode */
9698 ctx
->base
.is_jmp
= DISAS_STOP
;
9700 case CP0_REG16__CONFIG4
:
9701 /* currently ignored */
9702 register_name
= "Config4";
9704 case CP0_REG16__CONFIG5
:
9705 gen_helper_mtc0_config5(cpu_env
, arg
);
9706 register_name
= "Config5";
9707 /* Stop translation as we may have switched the execution mode */
9708 ctx
->base
.is_jmp
= DISAS_STOP
;
9710 /* 6,7 are implementation dependent */
9712 register_name
= "Invalid config selector";
9713 goto cp0_unimplemented
;
9716 case CP0_REGISTER_17
:
9718 case CP0_REG17__LLADDR
:
9719 gen_helper_mtc0_lladdr(cpu_env
, arg
);
9720 register_name
= "LLAddr";
9722 case CP0_REG17__MAAR
:
9723 CP0_CHECK(ctx
->mrp
);
9724 gen_helper_mtc0_maar(cpu_env
, arg
);
9725 register_name
= "MAAR";
9727 case CP0_REG17__MAARI
:
9728 CP0_CHECK(ctx
->mrp
);
9729 gen_helper_mtc0_maari(cpu_env
, arg
);
9730 register_name
= "MAARI";
9733 goto cp0_unimplemented
;
9736 case CP0_REGISTER_18
:
9738 case CP0_REG18__WATCHLO0
:
9739 case CP0_REG18__WATCHLO1
:
9740 case CP0_REG18__WATCHLO2
:
9741 case CP0_REG18__WATCHLO3
:
9742 case CP0_REG18__WATCHLO4
:
9743 case CP0_REG18__WATCHLO5
:
9744 case CP0_REG18__WATCHLO6
:
9745 case CP0_REG18__WATCHLO7
:
9746 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
9747 gen_helper_0e1i(mtc0_watchlo
, arg
, sel
);
9748 register_name
= "WatchLo";
9751 goto cp0_unimplemented
;
9754 case CP0_REGISTER_19
:
9756 case CP0_REG19__WATCHHI0
:
9757 case CP0_REG19__WATCHHI1
:
9758 case CP0_REG19__WATCHHI2
:
9759 case CP0_REG19__WATCHHI3
:
9760 case CP0_REG19__WATCHHI4
:
9761 case CP0_REG19__WATCHHI5
:
9762 case CP0_REG19__WATCHHI6
:
9763 case CP0_REG19__WATCHHI7
:
9764 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
9765 gen_helper_0e1i(mtc0_watchhi
, arg
, sel
);
9766 register_name
= "WatchHi";
9769 goto cp0_unimplemented
;
9772 case CP0_REGISTER_20
:
9774 case CP0_REG20__XCONTEXT
:
9775 check_insn(ctx
, ISA_MIPS3
);
9776 gen_helper_mtc0_xcontext(cpu_env
, arg
);
9777 register_name
= "XContext";
9780 goto cp0_unimplemented
;
9783 case CP0_REGISTER_21
:
9784 /* Officially reserved, but sel 0 is used for R1x000 framemask */
9785 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS_R6
));
9788 gen_helper_mtc0_framemask(cpu_env
, arg
);
9789 register_name
= "Framemask";
9792 goto cp0_unimplemented
;
9795 case CP0_REGISTER_22
:
9797 register_name
= "Diagnostic"; /* implementation dependent */
9799 case CP0_REGISTER_23
:
9801 case CP0_REG23__DEBUG
:
9802 gen_helper_mtc0_debug(cpu_env
, arg
); /* EJTAG support */
9803 /* DISAS_STOP isn't good enough here, hflags may have changed. */
9804 gen_save_pc(ctx
->base
.pc_next
+ 4);
9805 ctx
->base
.is_jmp
= DISAS_EXIT
;
9806 register_name
= "Debug";
9808 case CP0_REG23__TRACECONTROL
:
9809 /* PDtrace support */
9810 /* gen_helper_mtc0_tracecontrol(cpu_env, arg); */
9811 /* Stop translation as we may have switched the execution mode */
9812 ctx
->base
.is_jmp
= DISAS_STOP
;
9813 register_name
= "TraceControl";
9814 goto cp0_unimplemented
;
9815 case CP0_REG23__TRACECONTROL2
:
9816 /* PDtrace support */
9817 /* gen_helper_mtc0_tracecontrol2(cpu_env, arg); */
9818 /* Stop translation as we may have switched the execution mode */
9819 ctx
->base
.is_jmp
= DISAS_STOP
;
9820 register_name
= "TraceControl2";
9821 goto cp0_unimplemented
;
9822 case CP0_REG23__USERTRACEDATA1
:
9823 /* PDtrace support */
9824 /* gen_helper_mtc0_usertracedata1(cpu_env, arg);*/
9825 /* Stop translation as we may have switched the execution mode */
9826 ctx
->base
.is_jmp
= DISAS_STOP
;
9827 register_name
= "UserTraceData1";
9828 goto cp0_unimplemented
;
9829 case CP0_REG23__TRACEIBPC
:
9830 /* PDtrace support */
9831 /* gen_helper_mtc0_traceibpc(cpu_env, arg); */
9832 /* Stop translation as we may have switched the execution mode */
9833 ctx
->base
.is_jmp
= DISAS_STOP
;
9834 register_name
= "TraceIBPC";
9835 goto cp0_unimplemented
;
9836 case CP0_REG23__TRACEDBPC
:
9837 /* PDtrace support */
9838 /* gen_helper_mtc0_tracedbpc(cpu_env, arg); */
9839 /* Stop translation as we may have switched the execution mode */
9840 ctx
->base
.is_jmp
= DISAS_STOP
;
9841 register_name
= "TraceDBPC";
9842 goto cp0_unimplemented
;
9844 goto cp0_unimplemented
;
9847 case CP0_REGISTER_24
:
9849 case CP0_REG24__DEPC
:
9851 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
9852 register_name
= "DEPC";
9855 goto cp0_unimplemented
;
9858 case CP0_REGISTER_25
:
9860 case CP0_REG25__PERFCTL0
:
9861 gen_helper_mtc0_performance0(cpu_env
, arg
);
9862 register_name
= "Performance0";
9864 case CP0_REG25__PERFCNT0
:
9865 /* gen_helper_mtc0_performance1(cpu_env, arg); */
9866 register_name
= "Performance1";
9867 goto cp0_unimplemented
;
9868 case CP0_REG25__PERFCTL1
:
9869 /* gen_helper_mtc0_performance2(cpu_env, arg); */
9870 register_name
= "Performance2";
9871 goto cp0_unimplemented
;
9872 case CP0_REG25__PERFCNT1
:
9873 /* gen_helper_mtc0_performance3(cpu_env, arg); */
9874 register_name
= "Performance3";
9875 goto cp0_unimplemented
;
9876 case CP0_REG25__PERFCTL2
:
9877 /* gen_helper_mtc0_performance4(cpu_env, arg); */
9878 register_name
= "Performance4";
9879 goto cp0_unimplemented
;
9880 case CP0_REG25__PERFCNT2
:
9881 /* gen_helper_mtc0_performance5(cpu_env, arg); */
9882 register_name
= "Performance5";
9883 goto cp0_unimplemented
;
9884 case CP0_REG25__PERFCTL3
:
9885 /* gen_helper_mtc0_performance6(cpu_env, arg); */
9886 register_name
= "Performance6";
9887 goto cp0_unimplemented
;
9888 case CP0_REG25__PERFCNT3
:
9889 /* gen_helper_mtc0_performance7(cpu_env, arg); */
9890 register_name
= "Performance7";
9891 goto cp0_unimplemented
;
9893 goto cp0_unimplemented
;
9896 case CP0_REGISTER_26
:
9898 case CP0_REG26__ERRCTL
:
9899 gen_helper_mtc0_errctl(cpu_env
, arg
);
9900 ctx
->base
.is_jmp
= DISAS_STOP
;
9901 register_name
= "ErrCtl";
9904 goto cp0_unimplemented
;
9907 case CP0_REGISTER_27
:
9909 case CP0_REG27__CACHERR
:
9911 register_name
= "CacheErr";
9914 goto cp0_unimplemented
;
9917 case CP0_REGISTER_28
:
9919 case CP0_REG28__TAGLO
:
9920 case CP0_REG28__TAGLO1
:
9921 case CP0_REG28__TAGLO2
:
9922 case CP0_REG28__TAGLO3
:
9923 gen_helper_mtc0_taglo(cpu_env
, arg
);
9924 register_name
= "TagLo";
9926 case CP0_REG28__DATALO
:
9927 case CP0_REG28__DATALO1
:
9928 case CP0_REG28__DATALO2
:
9929 case CP0_REG28__DATALO3
:
9930 gen_helper_mtc0_datalo(cpu_env
, arg
);
9931 register_name
= "DataLo";
9934 goto cp0_unimplemented
;
9937 case CP0_REGISTER_29
:
9939 case CP0_REG29__TAGHI
:
9940 case CP0_REG29__TAGHI1
:
9941 case CP0_REG29__TAGHI2
:
9942 case CP0_REG29__TAGHI3
:
9943 gen_helper_mtc0_taghi(cpu_env
, arg
);
9944 register_name
= "TagHi";
9946 case CP0_REG29__DATAHI
:
9947 case CP0_REG29__DATAHI1
:
9948 case CP0_REG29__DATAHI2
:
9949 case CP0_REG29__DATAHI3
:
9950 gen_helper_mtc0_datahi(cpu_env
, arg
);
9951 register_name
= "DataHi";
9954 register_name
= "invalid sel";
9955 goto cp0_unimplemented
;
9958 case CP0_REGISTER_30
:
9960 case CP0_REG30__ERROREPC
:
9961 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
9962 register_name
= "ErrorEPC";
9965 goto cp0_unimplemented
;
9968 case CP0_REGISTER_31
:
9970 case CP0_REG31__DESAVE
:
9972 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
9973 register_name
= "DESAVE";
9975 case CP0_REG31__KSCRATCH1
:
9976 case CP0_REG31__KSCRATCH2
:
9977 case CP0_REG31__KSCRATCH3
:
9978 case CP0_REG31__KSCRATCH4
:
9979 case CP0_REG31__KSCRATCH5
:
9980 case CP0_REG31__KSCRATCH6
:
9981 CP0_CHECK(ctx
->kscrexist
& (1 << sel
));
9982 tcg_gen_st_tl(arg
, cpu_env
,
9983 offsetof(CPUMIPSState
, CP0_KScratch
[sel
- 2]));
9984 register_name
= "KScratch";
9987 goto cp0_unimplemented
;
9991 goto cp0_unimplemented
;
9993 trace_mips_translate_c0("dmtc0", register_name
, reg
, sel
);
9995 /* For simplicity assume that all writes can cause interrupts. */
9996 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
9998 * DISAS_STOP isn't sufficient, we need to ensure we break out of
9999 * translated code to check for pending interrupts.
10001 gen_save_pc(ctx
->base
.pc_next
+ 4);
10002 ctx
->base
.is_jmp
= DISAS_EXIT
;
10007 qemu_log_mask(LOG_UNIMP
, "dmtc0 %s (reg %d sel %d)\n",
10008 register_name
, reg
, sel
);
10010 #endif /* TARGET_MIPS64 */
10012 static void gen_mftr(CPUMIPSState
*env
, DisasContext
*ctx
, int rt
, int rd
,
10013 int u
, int sel
, int h
)
10015 int other_tc
= env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
);
10016 TCGv t0
= tcg_temp_local_new();
10018 if ((env
->CP0_VPEConf0
& (1 << CP0VPEC0_MVP
)) == 0 &&
10019 ((env
->tcs
[other_tc
].CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)) !=
10020 (env
->active_tc
.CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)))) {
10021 tcg_gen_movi_tl(t0
, -1);
10022 } else if ((env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
)) >
10023 (env
->mvp
->CP0_MVPConf0
& (0xff << CP0MVPC0_PTC
))) {
10024 tcg_gen_movi_tl(t0
, -1);
10025 } else if (u
== 0) {
10030 gen_helper_mftc0_vpecontrol(t0
, cpu_env
);
10033 gen_helper_mftc0_vpeconf0(t0
, cpu_env
);
10043 gen_helper_mftc0_tcstatus(t0
, cpu_env
);
10046 gen_helper_mftc0_tcbind(t0
, cpu_env
);
10049 gen_helper_mftc0_tcrestart(t0
, cpu_env
);
10052 gen_helper_mftc0_tchalt(t0
, cpu_env
);
10055 gen_helper_mftc0_tccontext(t0
, cpu_env
);
10058 gen_helper_mftc0_tcschedule(t0
, cpu_env
);
10061 gen_helper_mftc0_tcschefback(t0
, cpu_env
);
10064 gen_mfc0(ctx
, t0
, rt
, sel
);
10071 gen_helper_mftc0_entryhi(t0
, cpu_env
);
10074 gen_mfc0(ctx
, t0
, rt
, sel
);
10081 gen_helper_mftc0_status(t0
, cpu_env
);
10084 gen_mfc0(ctx
, t0
, rt
, sel
);
10091 gen_helper_mftc0_cause(t0
, cpu_env
);
10101 gen_helper_mftc0_epc(t0
, cpu_env
);
10111 gen_helper_mftc0_ebase(t0
, cpu_env
);
10128 gen_helper_mftc0_configx(t0
, cpu_env
, tcg_const_tl(sel
));
10138 gen_helper_mftc0_debug(t0
, cpu_env
);
10141 gen_mfc0(ctx
, t0
, rt
, sel
);
10146 gen_mfc0(ctx
, t0
, rt
, sel
);
10150 /* GPR registers. */
10152 gen_helper_1e0i(mftgpr
, t0
, rt
);
10154 /* Auxiliary CPU registers */
10158 gen_helper_1e0i(mftlo
, t0
, 0);
10161 gen_helper_1e0i(mfthi
, t0
, 0);
10164 gen_helper_1e0i(mftacx
, t0
, 0);
10167 gen_helper_1e0i(mftlo
, t0
, 1);
10170 gen_helper_1e0i(mfthi
, t0
, 1);
10173 gen_helper_1e0i(mftacx
, t0
, 1);
10176 gen_helper_1e0i(mftlo
, t0
, 2);
10179 gen_helper_1e0i(mfthi
, t0
, 2);
10182 gen_helper_1e0i(mftacx
, t0
, 2);
10185 gen_helper_1e0i(mftlo
, t0
, 3);
10188 gen_helper_1e0i(mfthi
, t0
, 3);
10191 gen_helper_1e0i(mftacx
, t0
, 3);
10194 gen_helper_mftdsp(t0
, cpu_env
);
10200 /* Floating point (COP1). */
10202 /* XXX: For now we support only a single FPU context. */
10204 TCGv_i32 fp0
= tcg_temp_new_i32();
10206 gen_load_fpr32(ctx
, fp0
, rt
);
10207 tcg_gen_ext_i32_tl(t0
, fp0
);
10208 tcg_temp_free_i32(fp0
);
10210 TCGv_i32 fp0
= tcg_temp_new_i32();
10212 gen_load_fpr32h(ctx
, fp0
, rt
);
10213 tcg_gen_ext_i32_tl(t0
, fp0
);
10214 tcg_temp_free_i32(fp0
);
10218 /* XXX: For now we support only a single FPU context. */
10219 gen_helper_1e0i(cfc1
, t0
, rt
);
10221 /* COP2: Not implemented. */
10229 trace_mips_translate_tr("mftr", rt
, u
, sel
, h
);
10230 gen_store_gpr(t0
, rd
);
10236 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt
, u
, sel
, h
);
10237 gen_reserved_instruction(ctx
);
10240 static void gen_mttr(CPUMIPSState
*env
, DisasContext
*ctx
, int rd
, int rt
,
10241 int u
, int sel
, int h
)
10243 int other_tc
= env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
);
10244 TCGv t0
= tcg_temp_local_new();
10246 gen_load_gpr(t0
, rt
);
10247 if ((env
->CP0_VPEConf0
& (1 << CP0VPEC0_MVP
)) == 0 &&
10248 ((env
->tcs
[other_tc
].CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)) !=
10249 (env
->active_tc
.CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)))) {
10252 } else if ((env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
)) >
10253 (env
->mvp
->CP0_MVPConf0
& (0xff << CP0MVPC0_PTC
))) {
10256 } else if (u
== 0) {
10261 gen_helper_mttc0_vpecontrol(cpu_env
, t0
);
10264 gen_helper_mttc0_vpeconf0(cpu_env
, t0
);
10274 gen_helper_mttc0_tcstatus(cpu_env
, t0
);
10277 gen_helper_mttc0_tcbind(cpu_env
, t0
);
10280 gen_helper_mttc0_tcrestart(cpu_env
, t0
);
10283 gen_helper_mttc0_tchalt(cpu_env
, t0
);
10286 gen_helper_mttc0_tccontext(cpu_env
, t0
);
10289 gen_helper_mttc0_tcschedule(cpu_env
, t0
);
10292 gen_helper_mttc0_tcschefback(cpu_env
, t0
);
10295 gen_mtc0(ctx
, t0
, rd
, sel
);
10302 gen_helper_mttc0_entryhi(cpu_env
, t0
);
10305 gen_mtc0(ctx
, t0
, rd
, sel
);
10312 gen_helper_mttc0_status(cpu_env
, t0
);
10315 gen_mtc0(ctx
, t0
, rd
, sel
);
10322 gen_helper_mttc0_cause(cpu_env
, t0
);
10332 gen_helper_mttc0_ebase(cpu_env
, t0
);
10342 gen_helper_mttc0_debug(cpu_env
, t0
);
10345 gen_mtc0(ctx
, t0
, rd
, sel
);
10350 gen_mtc0(ctx
, t0
, rd
, sel
);
10354 /* GPR registers. */
10356 gen_helper_0e1i(mttgpr
, t0
, rd
);
10358 /* Auxiliary CPU registers */
10362 gen_helper_0e1i(mttlo
, t0
, 0);
10365 gen_helper_0e1i(mtthi
, t0
, 0);
10368 gen_helper_0e1i(mttacx
, t0
, 0);
10371 gen_helper_0e1i(mttlo
, t0
, 1);
10374 gen_helper_0e1i(mtthi
, t0
, 1);
10377 gen_helper_0e1i(mttacx
, t0
, 1);
10380 gen_helper_0e1i(mttlo
, t0
, 2);
10383 gen_helper_0e1i(mtthi
, t0
, 2);
10386 gen_helper_0e1i(mttacx
, t0
, 2);
10389 gen_helper_0e1i(mttlo
, t0
, 3);
10392 gen_helper_0e1i(mtthi
, t0
, 3);
10395 gen_helper_0e1i(mttacx
, t0
, 3);
10398 gen_helper_mttdsp(cpu_env
, t0
);
10404 /* Floating point (COP1). */
10406 /* XXX: For now we support only a single FPU context. */
10408 TCGv_i32 fp0
= tcg_temp_new_i32();
10410 tcg_gen_trunc_tl_i32(fp0
, t0
);
10411 gen_store_fpr32(ctx
, fp0
, rd
);
10412 tcg_temp_free_i32(fp0
);
10414 TCGv_i32 fp0
= tcg_temp_new_i32();
10416 tcg_gen_trunc_tl_i32(fp0
, t0
);
10417 gen_store_fpr32h(ctx
, fp0
, rd
);
10418 tcg_temp_free_i32(fp0
);
10422 /* XXX: For now we support only a single FPU context. */
10424 TCGv_i32 fs_tmp
= tcg_const_i32(rd
);
10426 gen_helper_0e2i(ctc1
, t0
, fs_tmp
, rt
);
10427 tcg_temp_free_i32(fs_tmp
);
10429 /* Stop translation as we may have changed hflags */
10430 ctx
->base
.is_jmp
= DISAS_STOP
;
10432 /* COP2: Not implemented. */
10440 trace_mips_translate_tr("mttr", rd
, u
, sel
, h
);
10446 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd
, u
, sel
, h
);
10447 gen_reserved_instruction(ctx
);
10450 static void gen_cp0(CPUMIPSState
*env
, DisasContext
*ctx
, uint32_t opc
,
10453 const char *opn
= "ldst";
10455 check_cp0_enabled(ctx
);
10459 /* Treat as NOP. */
10462 gen_mfc0(ctx
, cpu_gpr
[rt
], rd
, ctx
->opcode
& 0x7);
10467 TCGv t0
= tcg_temp_new();
10469 gen_load_gpr(t0
, rt
);
10470 gen_mtc0(ctx
, t0
, rd
, ctx
->opcode
& 0x7);
10475 #if defined(TARGET_MIPS64)
10477 check_insn(ctx
, ISA_MIPS3
);
10479 /* Treat as NOP. */
10482 gen_dmfc0(ctx
, cpu_gpr
[rt
], rd
, ctx
->opcode
& 0x7);
10486 check_insn(ctx
, ISA_MIPS3
);
10488 TCGv t0
= tcg_temp_new();
10490 gen_load_gpr(t0
, rt
);
10491 gen_dmtc0(ctx
, t0
, rd
, ctx
->opcode
& 0x7);
10500 /* Treat as NOP. */
10503 gen_mfhc0(ctx
, cpu_gpr
[rt
], rd
, ctx
->opcode
& 0x7);
10509 TCGv t0
= tcg_temp_new();
10510 gen_load_gpr(t0
, rt
);
10511 gen_mthc0(ctx
, t0
, rd
, ctx
->opcode
& 0x7);
10517 check_cp0_enabled(ctx
);
10519 /* Treat as NOP. */
10522 gen_mftr(env
, ctx
, rt
, rd
, (ctx
->opcode
>> 5) & 1,
10523 ctx
->opcode
& 0x7, (ctx
->opcode
>> 4) & 1);
10527 check_cp0_enabled(ctx
);
10528 gen_mttr(env
, ctx
, rd
, rt
, (ctx
->opcode
>> 5) & 1,
10529 ctx
->opcode
& 0x7, (ctx
->opcode
>> 4) & 1);
10534 if (!env
->tlb
->helper_tlbwi
) {
10537 gen_helper_tlbwi(cpu_env
);
10541 if (ctx
->ie
>= 2) {
10542 if (!env
->tlb
->helper_tlbinv
) {
10545 gen_helper_tlbinv(cpu_env
);
10546 } /* treat as nop if TLBINV not supported */
10550 if (ctx
->ie
>= 2) {
10551 if (!env
->tlb
->helper_tlbinvf
) {
10554 gen_helper_tlbinvf(cpu_env
);
10555 } /* treat as nop if TLBINV not supported */
10559 if (!env
->tlb
->helper_tlbwr
) {
10562 gen_helper_tlbwr(cpu_env
);
10566 if (!env
->tlb
->helper_tlbp
) {
10569 gen_helper_tlbp(cpu_env
);
10573 if (!env
->tlb
->helper_tlbr
) {
10576 gen_helper_tlbr(cpu_env
);
10578 case OPC_ERET
: /* OPC_ERETNC */
10579 if ((ctx
->insn_flags
& ISA_MIPS_R6
) &&
10580 (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
10583 int bit_shift
= (ctx
->hflags
& MIPS_HFLAG_M16
) ? 16 : 6;
10584 if (ctx
->opcode
& (1 << bit_shift
)) {
10587 check_insn(ctx
, ISA_MIPS_R5
);
10588 gen_helper_eretnc(cpu_env
);
10592 check_insn(ctx
, ISA_MIPS2
);
10593 gen_helper_eret(cpu_env
);
10595 ctx
->base
.is_jmp
= DISAS_EXIT
;
10600 check_insn(ctx
, ISA_MIPS_R1
);
10601 if ((ctx
->insn_flags
& ISA_MIPS_R6
) &&
10602 (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
10605 if (!(ctx
->hflags
& MIPS_HFLAG_DM
)) {
10607 gen_reserved_instruction(ctx
);
10609 gen_helper_deret(cpu_env
);
10610 ctx
->base
.is_jmp
= DISAS_EXIT
;
10615 check_insn(ctx
, ISA_MIPS3
| ISA_MIPS_R1
);
10616 if ((ctx
->insn_flags
& ISA_MIPS_R6
) &&
10617 (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
10620 /* If we get an exception, we want to restart at next instruction */
10621 ctx
->base
.pc_next
+= 4;
10622 save_cpu_state(ctx
, 1);
10623 ctx
->base
.pc_next
-= 4;
10624 gen_helper_wait(cpu_env
);
10625 ctx
->base
.is_jmp
= DISAS_NORETURN
;
10630 gen_reserved_instruction(ctx
);
10633 (void)opn
; /* avoid a compiler warning */
10635 #endif /* !CONFIG_USER_ONLY */
10637 /* CP1 Branches (before delay slot) */
10638 static void gen_compute_branch1(DisasContext
*ctx
, uint32_t op
,
10639 int32_t cc
, int32_t offset
)
10641 target_ulong btarget
;
10642 TCGv_i32 t0
= tcg_temp_new_i32();
10644 if ((ctx
->insn_flags
& ISA_MIPS_R6
) && (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
10645 gen_reserved_instruction(ctx
);
10650 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS_R1
);
10653 btarget
= ctx
->base
.pc_next
+ 4 + offset
;
10657 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
10658 tcg_gen_not_i32(t0
, t0
);
10659 tcg_gen_andi_i32(t0
, t0
, 1);
10660 tcg_gen_extu_i32_tl(bcond
, t0
);
10663 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
10664 tcg_gen_not_i32(t0
, t0
);
10665 tcg_gen_andi_i32(t0
, t0
, 1);
10666 tcg_gen_extu_i32_tl(bcond
, t0
);
10669 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
10670 tcg_gen_andi_i32(t0
, t0
, 1);
10671 tcg_gen_extu_i32_tl(bcond
, t0
);
10674 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
10675 tcg_gen_andi_i32(t0
, t0
, 1);
10676 tcg_gen_extu_i32_tl(bcond
, t0
);
10678 ctx
->hflags
|= MIPS_HFLAG_BL
;
10682 TCGv_i32 t1
= tcg_temp_new_i32();
10683 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
10684 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 1));
10685 tcg_gen_nand_i32(t0
, t0
, t1
);
10686 tcg_temp_free_i32(t1
);
10687 tcg_gen_andi_i32(t0
, t0
, 1);
10688 tcg_gen_extu_i32_tl(bcond
, t0
);
10693 TCGv_i32 t1
= tcg_temp_new_i32();
10694 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
10695 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 1));
10696 tcg_gen_or_i32(t0
, t0
, t1
);
10697 tcg_temp_free_i32(t1
);
10698 tcg_gen_andi_i32(t0
, t0
, 1);
10699 tcg_gen_extu_i32_tl(bcond
, t0
);
10704 TCGv_i32 t1
= tcg_temp_new_i32();
10705 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
10706 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 1));
10707 tcg_gen_and_i32(t0
, t0
, t1
);
10708 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 2));
10709 tcg_gen_and_i32(t0
, t0
, t1
);
10710 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 3));
10711 tcg_gen_nand_i32(t0
, t0
, t1
);
10712 tcg_temp_free_i32(t1
);
10713 tcg_gen_andi_i32(t0
, t0
, 1);
10714 tcg_gen_extu_i32_tl(bcond
, t0
);
10719 TCGv_i32 t1
= tcg_temp_new_i32();
10720 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
10721 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 1));
10722 tcg_gen_or_i32(t0
, t0
, t1
);
10723 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 2));
10724 tcg_gen_or_i32(t0
, t0
, t1
);
10725 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 3));
10726 tcg_gen_or_i32(t0
, t0
, t1
);
10727 tcg_temp_free_i32(t1
);
10728 tcg_gen_andi_i32(t0
, t0
, 1);
10729 tcg_gen_extu_i32_tl(bcond
, t0
);
10732 ctx
->hflags
|= MIPS_HFLAG_BC
;
10735 MIPS_INVAL("cp1 cond branch");
10736 gen_reserved_instruction(ctx
);
10739 ctx
->btarget
= btarget
;
10740 ctx
->hflags
|= MIPS_HFLAG_BDS32
;
10742 tcg_temp_free_i32(t0
);
10745 /* R6 CP1 Branches */
10746 static void gen_compute_branch1_r6(DisasContext
*ctx
, uint32_t op
,
10747 int32_t ft
, int32_t offset
,
10748 int delayslot_size
)
10750 target_ulong btarget
;
10751 TCGv_i64 t0
= tcg_temp_new_i64();
10753 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
10754 #ifdef MIPS_DEBUG_DISAS
10755 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
10756 "\n", ctx
->base
.pc_next
);
10758 gen_reserved_instruction(ctx
);
10762 gen_load_fpr64(ctx
, t0
, ft
);
10763 tcg_gen_andi_i64(t0
, t0
, 1);
10765 btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
10769 tcg_gen_xori_i64(t0
, t0
, 1);
10770 ctx
->hflags
|= MIPS_HFLAG_BC
;
10773 /* t0 already set */
10774 ctx
->hflags
|= MIPS_HFLAG_BC
;
10777 MIPS_INVAL("cp1 cond branch");
10778 gen_reserved_instruction(ctx
);
10782 tcg_gen_trunc_i64_tl(bcond
, t0
);
10784 ctx
->btarget
= btarget
;
10786 switch (delayslot_size
) {
10788 ctx
->hflags
|= MIPS_HFLAG_BDS16
;
10791 ctx
->hflags
|= MIPS_HFLAG_BDS32
;
10796 tcg_temp_free_i64(t0
);
10799 /* Coprocessor 1 (FPU) */
10801 #define FOP(func, fmt) (((fmt) << 21) | (func))
10804 OPC_ADD_S
= FOP(0, FMT_S
),
10805 OPC_SUB_S
= FOP(1, FMT_S
),
10806 OPC_MUL_S
= FOP(2, FMT_S
),
10807 OPC_DIV_S
= FOP(3, FMT_S
),
10808 OPC_SQRT_S
= FOP(4, FMT_S
),
10809 OPC_ABS_S
= FOP(5, FMT_S
),
10810 OPC_MOV_S
= FOP(6, FMT_S
),
10811 OPC_NEG_S
= FOP(7, FMT_S
),
10812 OPC_ROUND_L_S
= FOP(8, FMT_S
),
10813 OPC_TRUNC_L_S
= FOP(9, FMT_S
),
10814 OPC_CEIL_L_S
= FOP(10, FMT_S
),
10815 OPC_FLOOR_L_S
= FOP(11, FMT_S
),
10816 OPC_ROUND_W_S
= FOP(12, FMT_S
),
10817 OPC_TRUNC_W_S
= FOP(13, FMT_S
),
10818 OPC_CEIL_W_S
= FOP(14, FMT_S
),
10819 OPC_FLOOR_W_S
= FOP(15, FMT_S
),
10820 OPC_SEL_S
= FOP(16, FMT_S
),
10821 OPC_MOVCF_S
= FOP(17, FMT_S
),
10822 OPC_MOVZ_S
= FOP(18, FMT_S
),
10823 OPC_MOVN_S
= FOP(19, FMT_S
),
10824 OPC_SELEQZ_S
= FOP(20, FMT_S
),
10825 OPC_RECIP_S
= FOP(21, FMT_S
),
10826 OPC_RSQRT_S
= FOP(22, FMT_S
),
10827 OPC_SELNEZ_S
= FOP(23, FMT_S
),
10828 OPC_MADDF_S
= FOP(24, FMT_S
),
10829 OPC_MSUBF_S
= FOP(25, FMT_S
),
10830 OPC_RINT_S
= FOP(26, FMT_S
),
10831 OPC_CLASS_S
= FOP(27, FMT_S
),
10832 OPC_MIN_S
= FOP(28, FMT_S
),
10833 OPC_RECIP2_S
= FOP(28, FMT_S
),
10834 OPC_MINA_S
= FOP(29, FMT_S
),
10835 OPC_RECIP1_S
= FOP(29, FMT_S
),
10836 OPC_MAX_S
= FOP(30, FMT_S
),
10837 OPC_RSQRT1_S
= FOP(30, FMT_S
),
10838 OPC_MAXA_S
= FOP(31, FMT_S
),
10839 OPC_RSQRT2_S
= FOP(31, FMT_S
),
10840 OPC_CVT_D_S
= FOP(33, FMT_S
),
10841 OPC_CVT_W_S
= FOP(36, FMT_S
),
10842 OPC_CVT_L_S
= FOP(37, FMT_S
),
10843 OPC_CVT_PS_S
= FOP(38, FMT_S
),
10844 OPC_CMP_F_S
= FOP(48, FMT_S
),
10845 OPC_CMP_UN_S
= FOP(49, FMT_S
),
10846 OPC_CMP_EQ_S
= FOP(50, FMT_S
),
10847 OPC_CMP_UEQ_S
= FOP(51, FMT_S
),
10848 OPC_CMP_OLT_S
= FOP(52, FMT_S
),
10849 OPC_CMP_ULT_S
= FOP(53, FMT_S
),
10850 OPC_CMP_OLE_S
= FOP(54, FMT_S
),
10851 OPC_CMP_ULE_S
= FOP(55, FMT_S
),
10852 OPC_CMP_SF_S
= FOP(56, FMT_S
),
10853 OPC_CMP_NGLE_S
= FOP(57, FMT_S
),
10854 OPC_CMP_SEQ_S
= FOP(58, FMT_S
),
10855 OPC_CMP_NGL_S
= FOP(59, FMT_S
),
10856 OPC_CMP_LT_S
= FOP(60, FMT_S
),
10857 OPC_CMP_NGE_S
= FOP(61, FMT_S
),
10858 OPC_CMP_LE_S
= FOP(62, FMT_S
),
10859 OPC_CMP_NGT_S
= FOP(63, FMT_S
),
10861 OPC_ADD_D
= FOP(0, FMT_D
),
10862 OPC_SUB_D
= FOP(1, FMT_D
),
10863 OPC_MUL_D
= FOP(2, FMT_D
),
10864 OPC_DIV_D
= FOP(3, FMT_D
),
10865 OPC_SQRT_D
= FOP(4, FMT_D
),
10866 OPC_ABS_D
= FOP(5, FMT_D
),
10867 OPC_MOV_D
= FOP(6, FMT_D
),
10868 OPC_NEG_D
= FOP(7, FMT_D
),
10869 OPC_ROUND_L_D
= FOP(8, FMT_D
),
10870 OPC_TRUNC_L_D
= FOP(9, FMT_D
),
10871 OPC_CEIL_L_D
= FOP(10, FMT_D
),
10872 OPC_FLOOR_L_D
= FOP(11, FMT_D
),
10873 OPC_ROUND_W_D
= FOP(12, FMT_D
),
10874 OPC_TRUNC_W_D
= FOP(13, FMT_D
),
10875 OPC_CEIL_W_D
= FOP(14, FMT_D
),
10876 OPC_FLOOR_W_D
= FOP(15, FMT_D
),
10877 OPC_SEL_D
= FOP(16, FMT_D
),
10878 OPC_MOVCF_D
= FOP(17, FMT_D
),
10879 OPC_MOVZ_D
= FOP(18, FMT_D
),
10880 OPC_MOVN_D
= FOP(19, FMT_D
),
10881 OPC_SELEQZ_D
= FOP(20, FMT_D
),
10882 OPC_RECIP_D
= FOP(21, FMT_D
),
10883 OPC_RSQRT_D
= FOP(22, FMT_D
),
10884 OPC_SELNEZ_D
= FOP(23, FMT_D
),
10885 OPC_MADDF_D
= FOP(24, FMT_D
),
10886 OPC_MSUBF_D
= FOP(25, FMT_D
),
10887 OPC_RINT_D
= FOP(26, FMT_D
),
10888 OPC_CLASS_D
= FOP(27, FMT_D
),
10889 OPC_MIN_D
= FOP(28, FMT_D
),
10890 OPC_RECIP2_D
= FOP(28, FMT_D
),
10891 OPC_MINA_D
= FOP(29, FMT_D
),
10892 OPC_RECIP1_D
= FOP(29, FMT_D
),
10893 OPC_MAX_D
= FOP(30, FMT_D
),
10894 OPC_RSQRT1_D
= FOP(30, FMT_D
),
10895 OPC_MAXA_D
= FOP(31, FMT_D
),
10896 OPC_RSQRT2_D
= FOP(31, FMT_D
),
10897 OPC_CVT_S_D
= FOP(32, FMT_D
),
10898 OPC_CVT_W_D
= FOP(36, FMT_D
),
10899 OPC_CVT_L_D
= FOP(37, FMT_D
),
10900 OPC_CMP_F_D
= FOP(48, FMT_D
),
10901 OPC_CMP_UN_D
= FOP(49, FMT_D
),
10902 OPC_CMP_EQ_D
= FOP(50, FMT_D
),
10903 OPC_CMP_UEQ_D
= FOP(51, FMT_D
),
10904 OPC_CMP_OLT_D
= FOP(52, FMT_D
),
10905 OPC_CMP_ULT_D
= FOP(53, FMT_D
),
10906 OPC_CMP_OLE_D
= FOP(54, FMT_D
),
10907 OPC_CMP_ULE_D
= FOP(55, FMT_D
),
10908 OPC_CMP_SF_D
= FOP(56, FMT_D
),
10909 OPC_CMP_NGLE_D
= FOP(57, FMT_D
),
10910 OPC_CMP_SEQ_D
= FOP(58, FMT_D
),
10911 OPC_CMP_NGL_D
= FOP(59, FMT_D
),
10912 OPC_CMP_LT_D
= FOP(60, FMT_D
),
10913 OPC_CMP_NGE_D
= FOP(61, FMT_D
),
10914 OPC_CMP_LE_D
= FOP(62, FMT_D
),
10915 OPC_CMP_NGT_D
= FOP(63, FMT_D
),
10917 OPC_CVT_S_W
= FOP(32, FMT_W
),
10918 OPC_CVT_D_W
= FOP(33, FMT_W
),
10919 OPC_CVT_S_L
= FOP(32, FMT_L
),
10920 OPC_CVT_D_L
= FOP(33, FMT_L
),
10921 OPC_CVT_PS_PW
= FOP(38, FMT_W
),
10923 OPC_ADD_PS
= FOP(0, FMT_PS
),
10924 OPC_SUB_PS
= FOP(1, FMT_PS
),
10925 OPC_MUL_PS
= FOP(2, FMT_PS
),
10926 OPC_DIV_PS
= FOP(3, FMT_PS
),
10927 OPC_ABS_PS
= FOP(5, FMT_PS
),
10928 OPC_MOV_PS
= FOP(6, FMT_PS
),
10929 OPC_NEG_PS
= FOP(7, FMT_PS
),
10930 OPC_MOVCF_PS
= FOP(17, FMT_PS
),
10931 OPC_MOVZ_PS
= FOP(18, FMT_PS
),
10932 OPC_MOVN_PS
= FOP(19, FMT_PS
),
10933 OPC_ADDR_PS
= FOP(24, FMT_PS
),
10934 OPC_MULR_PS
= FOP(26, FMT_PS
),
10935 OPC_RECIP2_PS
= FOP(28, FMT_PS
),
10936 OPC_RECIP1_PS
= FOP(29, FMT_PS
),
10937 OPC_RSQRT1_PS
= FOP(30, FMT_PS
),
10938 OPC_RSQRT2_PS
= FOP(31, FMT_PS
),
10940 OPC_CVT_S_PU
= FOP(32, FMT_PS
),
10941 OPC_CVT_PW_PS
= FOP(36, FMT_PS
),
10942 OPC_CVT_S_PL
= FOP(40, FMT_PS
),
10943 OPC_PLL_PS
= FOP(44, FMT_PS
),
10944 OPC_PLU_PS
= FOP(45, FMT_PS
),
10945 OPC_PUL_PS
= FOP(46, FMT_PS
),
10946 OPC_PUU_PS
= FOP(47, FMT_PS
),
10947 OPC_CMP_F_PS
= FOP(48, FMT_PS
),
10948 OPC_CMP_UN_PS
= FOP(49, FMT_PS
),
10949 OPC_CMP_EQ_PS
= FOP(50, FMT_PS
),
10950 OPC_CMP_UEQ_PS
= FOP(51, FMT_PS
),
10951 OPC_CMP_OLT_PS
= FOP(52, FMT_PS
),
10952 OPC_CMP_ULT_PS
= FOP(53, FMT_PS
),
10953 OPC_CMP_OLE_PS
= FOP(54, FMT_PS
),
10954 OPC_CMP_ULE_PS
= FOP(55, FMT_PS
),
10955 OPC_CMP_SF_PS
= FOP(56, FMT_PS
),
10956 OPC_CMP_NGLE_PS
= FOP(57, FMT_PS
),
10957 OPC_CMP_SEQ_PS
= FOP(58, FMT_PS
),
10958 OPC_CMP_NGL_PS
= FOP(59, FMT_PS
),
10959 OPC_CMP_LT_PS
= FOP(60, FMT_PS
),
10960 OPC_CMP_NGE_PS
= FOP(61, FMT_PS
),
10961 OPC_CMP_LE_PS
= FOP(62, FMT_PS
),
10962 OPC_CMP_NGT_PS
= FOP(63, FMT_PS
),
10966 R6_OPC_CMP_AF_S
= FOP(0, FMT_W
),
10967 R6_OPC_CMP_UN_S
= FOP(1, FMT_W
),
10968 R6_OPC_CMP_EQ_S
= FOP(2, FMT_W
),
10969 R6_OPC_CMP_UEQ_S
= FOP(3, FMT_W
),
10970 R6_OPC_CMP_LT_S
= FOP(4, FMT_W
),
10971 R6_OPC_CMP_ULT_S
= FOP(5, FMT_W
),
10972 R6_OPC_CMP_LE_S
= FOP(6, FMT_W
),
10973 R6_OPC_CMP_ULE_S
= FOP(7, FMT_W
),
10974 R6_OPC_CMP_SAF_S
= FOP(8, FMT_W
),
10975 R6_OPC_CMP_SUN_S
= FOP(9, FMT_W
),
10976 R6_OPC_CMP_SEQ_S
= FOP(10, FMT_W
),
10977 R6_OPC_CMP_SEUQ_S
= FOP(11, FMT_W
),
10978 R6_OPC_CMP_SLT_S
= FOP(12, FMT_W
),
10979 R6_OPC_CMP_SULT_S
= FOP(13, FMT_W
),
10980 R6_OPC_CMP_SLE_S
= FOP(14, FMT_W
),
10981 R6_OPC_CMP_SULE_S
= FOP(15, FMT_W
),
10982 R6_OPC_CMP_OR_S
= FOP(17, FMT_W
),
10983 R6_OPC_CMP_UNE_S
= FOP(18, FMT_W
),
10984 R6_OPC_CMP_NE_S
= FOP(19, FMT_W
),
10985 R6_OPC_CMP_SOR_S
= FOP(25, FMT_W
),
10986 R6_OPC_CMP_SUNE_S
= FOP(26, FMT_W
),
10987 R6_OPC_CMP_SNE_S
= FOP(27, FMT_W
),
10989 R6_OPC_CMP_AF_D
= FOP(0, FMT_L
),
10990 R6_OPC_CMP_UN_D
= FOP(1, FMT_L
),
10991 R6_OPC_CMP_EQ_D
= FOP(2, FMT_L
),
10992 R6_OPC_CMP_UEQ_D
= FOP(3, FMT_L
),
10993 R6_OPC_CMP_LT_D
= FOP(4, FMT_L
),
10994 R6_OPC_CMP_ULT_D
= FOP(5, FMT_L
),
10995 R6_OPC_CMP_LE_D
= FOP(6, FMT_L
),
10996 R6_OPC_CMP_ULE_D
= FOP(7, FMT_L
),
10997 R6_OPC_CMP_SAF_D
= FOP(8, FMT_L
),
10998 R6_OPC_CMP_SUN_D
= FOP(9, FMT_L
),
10999 R6_OPC_CMP_SEQ_D
= FOP(10, FMT_L
),
11000 R6_OPC_CMP_SEUQ_D
= FOP(11, FMT_L
),
11001 R6_OPC_CMP_SLT_D
= FOP(12, FMT_L
),
11002 R6_OPC_CMP_SULT_D
= FOP(13, FMT_L
),
11003 R6_OPC_CMP_SLE_D
= FOP(14, FMT_L
),
11004 R6_OPC_CMP_SULE_D
= FOP(15, FMT_L
),
11005 R6_OPC_CMP_OR_D
= FOP(17, FMT_L
),
11006 R6_OPC_CMP_UNE_D
= FOP(18, FMT_L
),
11007 R6_OPC_CMP_NE_D
= FOP(19, FMT_L
),
11008 R6_OPC_CMP_SOR_D
= FOP(25, FMT_L
),
11009 R6_OPC_CMP_SUNE_D
= FOP(26, FMT_L
),
11010 R6_OPC_CMP_SNE_D
= FOP(27, FMT_L
),
11013 static void gen_cp1(DisasContext
*ctx
, uint32_t opc
, int rt
, int fs
)
11015 TCGv t0
= tcg_temp_new();
11020 TCGv_i32 fp0
= tcg_temp_new_i32();
11022 gen_load_fpr32(ctx
, fp0
, fs
);
11023 tcg_gen_ext_i32_tl(t0
, fp0
);
11024 tcg_temp_free_i32(fp0
);
11026 gen_store_gpr(t0
, rt
);
11029 gen_load_gpr(t0
, rt
);
11031 TCGv_i32 fp0
= tcg_temp_new_i32();
11033 tcg_gen_trunc_tl_i32(fp0
, t0
);
11034 gen_store_fpr32(ctx
, fp0
, fs
);
11035 tcg_temp_free_i32(fp0
);
11039 gen_helper_1e0i(cfc1
, t0
, fs
);
11040 gen_store_gpr(t0
, rt
);
11043 gen_load_gpr(t0
, rt
);
11044 save_cpu_state(ctx
, 0);
11046 TCGv_i32 fs_tmp
= tcg_const_i32(fs
);
11048 gen_helper_0e2i(ctc1
, t0
, fs_tmp
, rt
);
11049 tcg_temp_free_i32(fs_tmp
);
11051 /* Stop translation as we may have changed hflags */
11052 ctx
->base
.is_jmp
= DISAS_STOP
;
11054 #if defined(TARGET_MIPS64)
11056 gen_load_fpr64(ctx
, t0
, fs
);
11057 gen_store_gpr(t0
, rt
);
11060 gen_load_gpr(t0
, rt
);
11061 gen_store_fpr64(ctx
, t0
, fs
);
11066 TCGv_i32 fp0
= tcg_temp_new_i32();
11068 gen_load_fpr32h(ctx
, fp0
, fs
);
11069 tcg_gen_ext_i32_tl(t0
, fp0
);
11070 tcg_temp_free_i32(fp0
);
11072 gen_store_gpr(t0
, rt
);
11075 gen_load_gpr(t0
, rt
);
11077 TCGv_i32 fp0
= tcg_temp_new_i32();
11079 tcg_gen_trunc_tl_i32(fp0
, t0
);
11080 gen_store_fpr32h(ctx
, fp0
, fs
);
11081 tcg_temp_free_i32(fp0
);
11085 MIPS_INVAL("cp1 move");
11086 gen_reserved_instruction(ctx
);
11094 static void gen_movci(DisasContext
*ctx
, int rd
, int rs
, int cc
, int tf
)
11101 /* Treat as NOP. */
11106 cond
= TCG_COND_EQ
;
11108 cond
= TCG_COND_NE
;
11111 l1
= gen_new_label();
11112 t0
= tcg_temp_new_i32();
11113 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
11114 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
11115 tcg_temp_free_i32(t0
);
11117 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
11119 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
11124 static inline void gen_movcf_s(DisasContext
*ctx
, int fs
, int fd
, int cc
,
11128 TCGv_i32 t0
= tcg_temp_new_i32();
11129 TCGLabel
*l1
= gen_new_label();
11132 cond
= TCG_COND_EQ
;
11134 cond
= TCG_COND_NE
;
11137 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
11138 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
11139 gen_load_fpr32(ctx
, t0
, fs
);
11140 gen_store_fpr32(ctx
, t0
, fd
);
11142 tcg_temp_free_i32(t0
);
11145 static inline void gen_movcf_d(DisasContext
*ctx
, int fs
, int fd
, int cc
,
11149 TCGv_i32 t0
= tcg_temp_new_i32();
11151 TCGLabel
*l1
= gen_new_label();
11154 cond
= TCG_COND_EQ
;
11156 cond
= TCG_COND_NE
;
11159 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
11160 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
11161 tcg_temp_free_i32(t0
);
11162 fp0
= tcg_temp_new_i64();
11163 gen_load_fpr64(ctx
, fp0
, fs
);
11164 gen_store_fpr64(ctx
, fp0
, fd
);
11165 tcg_temp_free_i64(fp0
);
11169 static inline void gen_movcf_ps(DisasContext
*ctx
, int fs
, int fd
,
11173 TCGv_i32 t0
= tcg_temp_new_i32();
11174 TCGLabel
*l1
= gen_new_label();
11175 TCGLabel
*l2
= gen_new_label();
11178 cond
= TCG_COND_EQ
;
11180 cond
= TCG_COND_NE
;
11183 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
11184 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
11185 gen_load_fpr32(ctx
, t0
, fs
);
11186 gen_store_fpr32(ctx
, t0
, fd
);
11189 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
+ 1));
11190 tcg_gen_brcondi_i32(cond
, t0
, 0, l2
);
11191 gen_load_fpr32h(ctx
, t0
, fs
);
11192 gen_store_fpr32h(ctx
, t0
, fd
);
11193 tcg_temp_free_i32(t0
);
11197 static void gen_sel_s(DisasContext
*ctx
, enum fopcode op1
, int fd
, int ft
,
11200 TCGv_i32 t1
= tcg_const_i32(0);
11201 TCGv_i32 fp0
= tcg_temp_new_i32();
11202 TCGv_i32 fp1
= tcg_temp_new_i32();
11203 TCGv_i32 fp2
= tcg_temp_new_i32();
11204 gen_load_fpr32(ctx
, fp0
, fd
);
11205 gen_load_fpr32(ctx
, fp1
, ft
);
11206 gen_load_fpr32(ctx
, fp2
, fs
);
11210 tcg_gen_andi_i32(fp0
, fp0
, 1);
11211 tcg_gen_movcond_i32(TCG_COND_NE
, fp0
, fp0
, t1
, fp1
, fp2
);
11214 tcg_gen_andi_i32(fp1
, fp1
, 1);
11215 tcg_gen_movcond_i32(TCG_COND_EQ
, fp0
, fp1
, t1
, fp2
, t1
);
11218 tcg_gen_andi_i32(fp1
, fp1
, 1);
11219 tcg_gen_movcond_i32(TCG_COND_NE
, fp0
, fp1
, t1
, fp2
, t1
);
11222 MIPS_INVAL("gen_sel_s");
11223 gen_reserved_instruction(ctx
);
11227 gen_store_fpr32(ctx
, fp0
, fd
);
11228 tcg_temp_free_i32(fp2
);
11229 tcg_temp_free_i32(fp1
);
11230 tcg_temp_free_i32(fp0
);
11231 tcg_temp_free_i32(t1
);
11234 static void gen_sel_d(DisasContext
*ctx
, enum fopcode op1
, int fd
, int ft
,
11237 TCGv_i64 t1
= tcg_const_i64(0);
11238 TCGv_i64 fp0
= tcg_temp_new_i64();
11239 TCGv_i64 fp1
= tcg_temp_new_i64();
11240 TCGv_i64 fp2
= tcg_temp_new_i64();
11241 gen_load_fpr64(ctx
, fp0
, fd
);
11242 gen_load_fpr64(ctx
, fp1
, ft
);
11243 gen_load_fpr64(ctx
, fp2
, fs
);
11247 tcg_gen_andi_i64(fp0
, fp0
, 1);
11248 tcg_gen_movcond_i64(TCG_COND_NE
, fp0
, fp0
, t1
, fp1
, fp2
);
11251 tcg_gen_andi_i64(fp1
, fp1
, 1);
11252 tcg_gen_movcond_i64(TCG_COND_EQ
, fp0
, fp1
, t1
, fp2
, t1
);
11255 tcg_gen_andi_i64(fp1
, fp1
, 1);
11256 tcg_gen_movcond_i64(TCG_COND_NE
, fp0
, fp1
, t1
, fp2
, t1
);
11259 MIPS_INVAL("gen_sel_d");
11260 gen_reserved_instruction(ctx
);
11264 gen_store_fpr64(ctx
, fp0
, fd
);
11265 tcg_temp_free_i64(fp2
);
11266 tcg_temp_free_i64(fp1
);
11267 tcg_temp_free_i64(fp0
);
11268 tcg_temp_free_i64(t1
);
11271 static void gen_farith(DisasContext
*ctx
, enum fopcode op1
,
11272 int ft
, int fs
, int fd
, int cc
)
11274 uint32_t func
= ctx
->opcode
& 0x3f;
11278 TCGv_i32 fp0
= tcg_temp_new_i32();
11279 TCGv_i32 fp1
= tcg_temp_new_i32();
11281 gen_load_fpr32(ctx
, fp0
, fs
);
11282 gen_load_fpr32(ctx
, fp1
, ft
);
11283 gen_helper_float_add_s(fp0
, cpu_env
, fp0
, fp1
);
11284 tcg_temp_free_i32(fp1
);
11285 gen_store_fpr32(ctx
, fp0
, fd
);
11286 tcg_temp_free_i32(fp0
);
11291 TCGv_i32 fp0
= tcg_temp_new_i32();
11292 TCGv_i32 fp1
= tcg_temp_new_i32();
11294 gen_load_fpr32(ctx
, fp0
, fs
);
11295 gen_load_fpr32(ctx
, fp1
, ft
);
11296 gen_helper_float_sub_s(fp0
, cpu_env
, fp0
, fp1
);
11297 tcg_temp_free_i32(fp1
);
11298 gen_store_fpr32(ctx
, fp0
, fd
);
11299 tcg_temp_free_i32(fp0
);
11304 TCGv_i32 fp0
= tcg_temp_new_i32();
11305 TCGv_i32 fp1
= tcg_temp_new_i32();
11307 gen_load_fpr32(ctx
, fp0
, fs
);
11308 gen_load_fpr32(ctx
, fp1
, ft
);
11309 gen_helper_float_mul_s(fp0
, cpu_env
, fp0
, fp1
);
11310 tcg_temp_free_i32(fp1
);
11311 gen_store_fpr32(ctx
, fp0
, fd
);
11312 tcg_temp_free_i32(fp0
);
11317 TCGv_i32 fp0
= tcg_temp_new_i32();
11318 TCGv_i32 fp1
= tcg_temp_new_i32();
11320 gen_load_fpr32(ctx
, fp0
, fs
);
11321 gen_load_fpr32(ctx
, fp1
, ft
);
11322 gen_helper_float_div_s(fp0
, cpu_env
, fp0
, fp1
);
11323 tcg_temp_free_i32(fp1
);
11324 gen_store_fpr32(ctx
, fp0
, fd
);
11325 tcg_temp_free_i32(fp0
);
11330 TCGv_i32 fp0
= tcg_temp_new_i32();
11332 gen_load_fpr32(ctx
, fp0
, fs
);
11333 gen_helper_float_sqrt_s(fp0
, cpu_env
, fp0
);
11334 gen_store_fpr32(ctx
, fp0
, fd
);
11335 tcg_temp_free_i32(fp0
);
11340 TCGv_i32 fp0
= tcg_temp_new_i32();
11342 gen_load_fpr32(ctx
, fp0
, fs
);
11343 if (ctx
->abs2008
) {
11344 tcg_gen_andi_i32(fp0
, fp0
, 0x7fffffffUL
);
11346 gen_helper_float_abs_s(fp0
, fp0
);
11348 gen_store_fpr32(ctx
, fp0
, fd
);
11349 tcg_temp_free_i32(fp0
);
11354 TCGv_i32 fp0
= tcg_temp_new_i32();
11356 gen_load_fpr32(ctx
, fp0
, fs
);
11357 gen_store_fpr32(ctx
, fp0
, fd
);
11358 tcg_temp_free_i32(fp0
);
11363 TCGv_i32 fp0
= tcg_temp_new_i32();
11365 gen_load_fpr32(ctx
, fp0
, fs
);
11366 if (ctx
->abs2008
) {
11367 tcg_gen_xori_i32(fp0
, fp0
, 1UL << 31);
11369 gen_helper_float_chs_s(fp0
, fp0
);
11371 gen_store_fpr32(ctx
, fp0
, fd
);
11372 tcg_temp_free_i32(fp0
);
11375 case OPC_ROUND_L_S
:
11376 check_cp1_64bitmode(ctx
);
11378 TCGv_i32 fp32
= tcg_temp_new_i32();
11379 TCGv_i64 fp64
= tcg_temp_new_i64();
11381 gen_load_fpr32(ctx
, fp32
, fs
);
11382 if (ctx
->nan2008
) {
11383 gen_helper_float_round_2008_l_s(fp64
, cpu_env
, fp32
);
11385 gen_helper_float_round_l_s(fp64
, cpu_env
, fp32
);
11387 tcg_temp_free_i32(fp32
);
11388 gen_store_fpr64(ctx
, fp64
, fd
);
11389 tcg_temp_free_i64(fp64
);
11392 case OPC_TRUNC_L_S
:
11393 check_cp1_64bitmode(ctx
);
11395 TCGv_i32 fp32
= tcg_temp_new_i32();
11396 TCGv_i64 fp64
= tcg_temp_new_i64();
11398 gen_load_fpr32(ctx
, fp32
, fs
);
11399 if (ctx
->nan2008
) {
11400 gen_helper_float_trunc_2008_l_s(fp64
, cpu_env
, fp32
);
11402 gen_helper_float_trunc_l_s(fp64
, cpu_env
, fp32
);
11404 tcg_temp_free_i32(fp32
);
11405 gen_store_fpr64(ctx
, fp64
, fd
);
11406 tcg_temp_free_i64(fp64
);
11410 check_cp1_64bitmode(ctx
);
11412 TCGv_i32 fp32
= tcg_temp_new_i32();
11413 TCGv_i64 fp64
= tcg_temp_new_i64();
11415 gen_load_fpr32(ctx
, fp32
, fs
);
11416 if (ctx
->nan2008
) {
11417 gen_helper_float_ceil_2008_l_s(fp64
, cpu_env
, fp32
);
11419 gen_helper_float_ceil_l_s(fp64
, cpu_env
, fp32
);
11421 tcg_temp_free_i32(fp32
);
11422 gen_store_fpr64(ctx
, fp64
, fd
);
11423 tcg_temp_free_i64(fp64
);
11426 case OPC_FLOOR_L_S
:
11427 check_cp1_64bitmode(ctx
);
11429 TCGv_i32 fp32
= tcg_temp_new_i32();
11430 TCGv_i64 fp64
= tcg_temp_new_i64();
11432 gen_load_fpr32(ctx
, fp32
, fs
);
11433 if (ctx
->nan2008
) {
11434 gen_helper_float_floor_2008_l_s(fp64
, cpu_env
, fp32
);
11436 gen_helper_float_floor_l_s(fp64
, cpu_env
, fp32
);
11438 tcg_temp_free_i32(fp32
);
11439 gen_store_fpr64(ctx
, fp64
, fd
);
11440 tcg_temp_free_i64(fp64
);
11443 case OPC_ROUND_W_S
:
11445 TCGv_i32 fp0
= tcg_temp_new_i32();
11447 gen_load_fpr32(ctx
, fp0
, fs
);
11448 if (ctx
->nan2008
) {
11449 gen_helper_float_round_2008_w_s(fp0
, cpu_env
, fp0
);
11451 gen_helper_float_round_w_s(fp0
, cpu_env
, fp0
);
11453 gen_store_fpr32(ctx
, fp0
, fd
);
11454 tcg_temp_free_i32(fp0
);
11457 case OPC_TRUNC_W_S
:
11459 TCGv_i32 fp0
= tcg_temp_new_i32();
11461 gen_load_fpr32(ctx
, fp0
, fs
);
11462 if (ctx
->nan2008
) {
11463 gen_helper_float_trunc_2008_w_s(fp0
, cpu_env
, fp0
);
11465 gen_helper_float_trunc_w_s(fp0
, cpu_env
, fp0
);
11467 gen_store_fpr32(ctx
, fp0
, fd
);
11468 tcg_temp_free_i32(fp0
);
11473 TCGv_i32 fp0
= tcg_temp_new_i32();
11475 gen_load_fpr32(ctx
, fp0
, fs
);
11476 if (ctx
->nan2008
) {
11477 gen_helper_float_ceil_2008_w_s(fp0
, cpu_env
, fp0
);
11479 gen_helper_float_ceil_w_s(fp0
, cpu_env
, fp0
);
11481 gen_store_fpr32(ctx
, fp0
, fd
);
11482 tcg_temp_free_i32(fp0
);
11485 case OPC_FLOOR_W_S
:
11487 TCGv_i32 fp0
= tcg_temp_new_i32();
11489 gen_load_fpr32(ctx
, fp0
, fs
);
11490 if (ctx
->nan2008
) {
11491 gen_helper_float_floor_2008_w_s(fp0
, cpu_env
, fp0
);
11493 gen_helper_float_floor_w_s(fp0
, cpu_env
, fp0
);
11495 gen_store_fpr32(ctx
, fp0
, fd
);
11496 tcg_temp_free_i32(fp0
);
11500 check_insn(ctx
, ISA_MIPS_R6
);
11501 gen_sel_s(ctx
, op1
, fd
, ft
, fs
);
11504 check_insn(ctx
, ISA_MIPS_R6
);
11505 gen_sel_s(ctx
, op1
, fd
, ft
, fs
);
11508 check_insn(ctx
, ISA_MIPS_R6
);
11509 gen_sel_s(ctx
, op1
, fd
, ft
, fs
);
11512 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
11513 gen_movcf_s(ctx
, fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
11516 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
11518 TCGLabel
*l1
= gen_new_label();
11522 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
11524 fp0
= tcg_temp_new_i32();
11525 gen_load_fpr32(ctx
, fp0
, fs
);
11526 gen_store_fpr32(ctx
, fp0
, fd
);
11527 tcg_temp_free_i32(fp0
);
11532 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
11534 TCGLabel
*l1
= gen_new_label();
11538 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
11539 fp0
= tcg_temp_new_i32();
11540 gen_load_fpr32(ctx
, fp0
, fs
);
11541 gen_store_fpr32(ctx
, fp0
, fd
);
11542 tcg_temp_free_i32(fp0
);
11549 TCGv_i32 fp0
= tcg_temp_new_i32();
11551 gen_load_fpr32(ctx
, fp0
, fs
);
11552 gen_helper_float_recip_s(fp0
, cpu_env
, fp0
);
11553 gen_store_fpr32(ctx
, fp0
, fd
);
11554 tcg_temp_free_i32(fp0
);
11559 TCGv_i32 fp0
= tcg_temp_new_i32();
11561 gen_load_fpr32(ctx
, fp0
, fs
);
11562 gen_helper_float_rsqrt_s(fp0
, cpu_env
, fp0
);
11563 gen_store_fpr32(ctx
, fp0
, fd
);
11564 tcg_temp_free_i32(fp0
);
11568 check_insn(ctx
, ISA_MIPS_R6
);
11570 TCGv_i32 fp0
= tcg_temp_new_i32();
11571 TCGv_i32 fp1
= tcg_temp_new_i32();
11572 TCGv_i32 fp2
= tcg_temp_new_i32();
11573 gen_load_fpr32(ctx
, fp0
, fs
);
11574 gen_load_fpr32(ctx
, fp1
, ft
);
11575 gen_load_fpr32(ctx
, fp2
, fd
);
11576 gen_helper_float_maddf_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
11577 gen_store_fpr32(ctx
, fp2
, fd
);
11578 tcg_temp_free_i32(fp2
);
11579 tcg_temp_free_i32(fp1
);
11580 tcg_temp_free_i32(fp0
);
11584 check_insn(ctx
, ISA_MIPS_R6
);
11586 TCGv_i32 fp0
= tcg_temp_new_i32();
11587 TCGv_i32 fp1
= tcg_temp_new_i32();
11588 TCGv_i32 fp2
= tcg_temp_new_i32();
11589 gen_load_fpr32(ctx
, fp0
, fs
);
11590 gen_load_fpr32(ctx
, fp1
, ft
);
11591 gen_load_fpr32(ctx
, fp2
, fd
);
11592 gen_helper_float_msubf_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
11593 gen_store_fpr32(ctx
, fp2
, fd
);
11594 tcg_temp_free_i32(fp2
);
11595 tcg_temp_free_i32(fp1
);
11596 tcg_temp_free_i32(fp0
);
11600 check_insn(ctx
, ISA_MIPS_R6
);
11602 TCGv_i32 fp0
= tcg_temp_new_i32();
11603 gen_load_fpr32(ctx
, fp0
, fs
);
11604 gen_helper_float_rint_s(fp0
, cpu_env
, fp0
);
11605 gen_store_fpr32(ctx
, fp0
, fd
);
11606 tcg_temp_free_i32(fp0
);
11610 check_insn(ctx
, ISA_MIPS_R6
);
11612 TCGv_i32 fp0
= tcg_temp_new_i32();
11613 gen_load_fpr32(ctx
, fp0
, fs
);
11614 gen_helper_float_class_s(fp0
, cpu_env
, fp0
);
11615 gen_store_fpr32(ctx
, fp0
, fd
);
11616 tcg_temp_free_i32(fp0
);
11619 case OPC_MIN_S
: /* OPC_RECIP2_S */
11620 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
11622 TCGv_i32 fp0
= tcg_temp_new_i32();
11623 TCGv_i32 fp1
= tcg_temp_new_i32();
11624 TCGv_i32 fp2
= tcg_temp_new_i32();
11625 gen_load_fpr32(ctx
, fp0
, fs
);
11626 gen_load_fpr32(ctx
, fp1
, ft
);
11627 gen_helper_float_min_s(fp2
, cpu_env
, fp0
, fp1
);
11628 gen_store_fpr32(ctx
, fp2
, fd
);
11629 tcg_temp_free_i32(fp2
);
11630 tcg_temp_free_i32(fp1
);
11631 tcg_temp_free_i32(fp0
);
11634 check_cp1_64bitmode(ctx
);
11636 TCGv_i32 fp0
= tcg_temp_new_i32();
11637 TCGv_i32 fp1
= tcg_temp_new_i32();
11639 gen_load_fpr32(ctx
, fp0
, fs
);
11640 gen_load_fpr32(ctx
, fp1
, ft
);
11641 gen_helper_float_recip2_s(fp0
, cpu_env
, fp0
, fp1
);
11642 tcg_temp_free_i32(fp1
);
11643 gen_store_fpr32(ctx
, fp0
, fd
);
11644 tcg_temp_free_i32(fp0
);
11648 case OPC_MINA_S
: /* OPC_RECIP1_S */
11649 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
11651 TCGv_i32 fp0
= tcg_temp_new_i32();
11652 TCGv_i32 fp1
= tcg_temp_new_i32();
11653 TCGv_i32 fp2
= tcg_temp_new_i32();
11654 gen_load_fpr32(ctx
, fp0
, fs
);
11655 gen_load_fpr32(ctx
, fp1
, ft
);
11656 gen_helper_float_mina_s(fp2
, cpu_env
, fp0
, fp1
);
11657 gen_store_fpr32(ctx
, fp2
, fd
);
11658 tcg_temp_free_i32(fp2
);
11659 tcg_temp_free_i32(fp1
);
11660 tcg_temp_free_i32(fp0
);
11663 check_cp1_64bitmode(ctx
);
11665 TCGv_i32 fp0
= tcg_temp_new_i32();
11667 gen_load_fpr32(ctx
, fp0
, fs
);
11668 gen_helper_float_recip1_s(fp0
, cpu_env
, fp0
);
11669 gen_store_fpr32(ctx
, fp0
, fd
);
11670 tcg_temp_free_i32(fp0
);
11674 case OPC_MAX_S
: /* OPC_RSQRT1_S */
11675 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
11677 TCGv_i32 fp0
= tcg_temp_new_i32();
11678 TCGv_i32 fp1
= tcg_temp_new_i32();
11679 gen_load_fpr32(ctx
, fp0
, fs
);
11680 gen_load_fpr32(ctx
, fp1
, ft
);
11681 gen_helper_float_max_s(fp1
, cpu_env
, fp0
, fp1
);
11682 gen_store_fpr32(ctx
, fp1
, fd
);
11683 tcg_temp_free_i32(fp1
);
11684 tcg_temp_free_i32(fp0
);
11687 check_cp1_64bitmode(ctx
);
11689 TCGv_i32 fp0
= tcg_temp_new_i32();
11691 gen_load_fpr32(ctx
, fp0
, fs
);
11692 gen_helper_float_rsqrt1_s(fp0
, cpu_env
, fp0
);
11693 gen_store_fpr32(ctx
, fp0
, fd
);
11694 tcg_temp_free_i32(fp0
);
11698 case OPC_MAXA_S
: /* OPC_RSQRT2_S */
11699 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
11701 TCGv_i32 fp0
= tcg_temp_new_i32();
11702 TCGv_i32 fp1
= tcg_temp_new_i32();
11703 gen_load_fpr32(ctx
, fp0
, fs
);
11704 gen_load_fpr32(ctx
, fp1
, ft
);
11705 gen_helper_float_maxa_s(fp1
, cpu_env
, fp0
, fp1
);
11706 gen_store_fpr32(ctx
, fp1
, fd
);
11707 tcg_temp_free_i32(fp1
);
11708 tcg_temp_free_i32(fp0
);
11711 check_cp1_64bitmode(ctx
);
11713 TCGv_i32 fp0
= tcg_temp_new_i32();
11714 TCGv_i32 fp1
= tcg_temp_new_i32();
11716 gen_load_fpr32(ctx
, fp0
, fs
);
11717 gen_load_fpr32(ctx
, fp1
, ft
);
11718 gen_helper_float_rsqrt2_s(fp0
, cpu_env
, fp0
, fp1
);
11719 tcg_temp_free_i32(fp1
);
11720 gen_store_fpr32(ctx
, fp0
, fd
);
11721 tcg_temp_free_i32(fp0
);
11726 check_cp1_registers(ctx
, fd
);
11728 TCGv_i32 fp32
= tcg_temp_new_i32();
11729 TCGv_i64 fp64
= tcg_temp_new_i64();
11731 gen_load_fpr32(ctx
, fp32
, fs
);
11732 gen_helper_float_cvtd_s(fp64
, cpu_env
, fp32
);
11733 tcg_temp_free_i32(fp32
);
11734 gen_store_fpr64(ctx
, fp64
, fd
);
11735 tcg_temp_free_i64(fp64
);
11740 TCGv_i32 fp0
= tcg_temp_new_i32();
11742 gen_load_fpr32(ctx
, fp0
, fs
);
11743 if (ctx
->nan2008
) {
11744 gen_helper_float_cvt_2008_w_s(fp0
, cpu_env
, fp0
);
11746 gen_helper_float_cvt_w_s(fp0
, cpu_env
, fp0
);
11748 gen_store_fpr32(ctx
, fp0
, fd
);
11749 tcg_temp_free_i32(fp0
);
11753 check_cp1_64bitmode(ctx
);
11755 TCGv_i32 fp32
= tcg_temp_new_i32();
11756 TCGv_i64 fp64
= tcg_temp_new_i64();
11758 gen_load_fpr32(ctx
, fp32
, fs
);
11759 if (ctx
->nan2008
) {
11760 gen_helper_float_cvt_2008_l_s(fp64
, cpu_env
, fp32
);
11762 gen_helper_float_cvt_l_s(fp64
, cpu_env
, fp32
);
11764 tcg_temp_free_i32(fp32
);
11765 gen_store_fpr64(ctx
, fp64
, fd
);
11766 tcg_temp_free_i64(fp64
);
11772 TCGv_i64 fp64
= tcg_temp_new_i64();
11773 TCGv_i32 fp32_0
= tcg_temp_new_i32();
11774 TCGv_i32 fp32_1
= tcg_temp_new_i32();
11776 gen_load_fpr32(ctx
, fp32_0
, fs
);
11777 gen_load_fpr32(ctx
, fp32_1
, ft
);
11778 tcg_gen_concat_i32_i64(fp64
, fp32_1
, fp32_0
);
11779 tcg_temp_free_i32(fp32_1
);
11780 tcg_temp_free_i32(fp32_0
);
11781 gen_store_fpr64(ctx
, fp64
, fd
);
11782 tcg_temp_free_i64(fp64
);
11788 case OPC_CMP_UEQ_S
:
11789 case OPC_CMP_OLT_S
:
11790 case OPC_CMP_ULT_S
:
11791 case OPC_CMP_OLE_S
:
11792 case OPC_CMP_ULE_S
:
11794 case OPC_CMP_NGLE_S
:
11795 case OPC_CMP_SEQ_S
:
11796 case OPC_CMP_NGL_S
:
11798 case OPC_CMP_NGE_S
:
11800 case OPC_CMP_NGT_S
:
11801 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
11802 if (ctx
->opcode
& (1 << 6)) {
11803 gen_cmpabs_s(ctx
, func
- 48, ft
, fs
, cc
);
11805 gen_cmp_s(ctx
, func
- 48, ft
, fs
, cc
);
11809 check_cp1_registers(ctx
, fs
| ft
| fd
);
11811 TCGv_i64 fp0
= tcg_temp_new_i64();
11812 TCGv_i64 fp1
= tcg_temp_new_i64();
11814 gen_load_fpr64(ctx
, fp0
, fs
);
11815 gen_load_fpr64(ctx
, fp1
, ft
);
11816 gen_helper_float_add_d(fp0
, cpu_env
, fp0
, fp1
);
11817 tcg_temp_free_i64(fp1
);
11818 gen_store_fpr64(ctx
, fp0
, fd
);
11819 tcg_temp_free_i64(fp0
);
11823 check_cp1_registers(ctx
, fs
| ft
| fd
);
11825 TCGv_i64 fp0
= tcg_temp_new_i64();
11826 TCGv_i64 fp1
= tcg_temp_new_i64();
11828 gen_load_fpr64(ctx
, fp0
, fs
);
11829 gen_load_fpr64(ctx
, fp1
, ft
);
11830 gen_helper_float_sub_d(fp0
, cpu_env
, fp0
, fp1
);
11831 tcg_temp_free_i64(fp1
);
11832 gen_store_fpr64(ctx
, fp0
, fd
);
11833 tcg_temp_free_i64(fp0
);
11837 check_cp1_registers(ctx
, fs
| ft
| fd
);
11839 TCGv_i64 fp0
= tcg_temp_new_i64();
11840 TCGv_i64 fp1
= tcg_temp_new_i64();
11842 gen_load_fpr64(ctx
, fp0
, fs
);
11843 gen_load_fpr64(ctx
, fp1
, ft
);
11844 gen_helper_float_mul_d(fp0
, cpu_env
, fp0
, fp1
);
11845 tcg_temp_free_i64(fp1
);
11846 gen_store_fpr64(ctx
, fp0
, fd
);
11847 tcg_temp_free_i64(fp0
);
11851 check_cp1_registers(ctx
, fs
| ft
| fd
);
11853 TCGv_i64 fp0
= tcg_temp_new_i64();
11854 TCGv_i64 fp1
= tcg_temp_new_i64();
11856 gen_load_fpr64(ctx
, fp0
, fs
);
11857 gen_load_fpr64(ctx
, fp1
, ft
);
11858 gen_helper_float_div_d(fp0
, cpu_env
, fp0
, fp1
);
11859 tcg_temp_free_i64(fp1
);
11860 gen_store_fpr64(ctx
, fp0
, fd
);
11861 tcg_temp_free_i64(fp0
);
11865 check_cp1_registers(ctx
, fs
| fd
);
11867 TCGv_i64 fp0
= tcg_temp_new_i64();
11869 gen_load_fpr64(ctx
, fp0
, fs
);
11870 gen_helper_float_sqrt_d(fp0
, cpu_env
, fp0
);
11871 gen_store_fpr64(ctx
, fp0
, fd
);
11872 tcg_temp_free_i64(fp0
);
11876 check_cp1_registers(ctx
, fs
| fd
);
11878 TCGv_i64 fp0
= tcg_temp_new_i64();
11880 gen_load_fpr64(ctx
, fp0
, fs
);
11881 if (ctx
->abs2008
) {
11882 tcg_gen_andi_i64(fp0
, fp0
, 0x7fffffffffffffffULL
);
11884 gen_helper_float_abs_d(fp0
, fp0
);
11886 gen_store_fpr64(ctx
, fp0
, fd
);
11887 tcg_temp_free_i64(fp0
);
11891 check_cp1_registers(ctx
, fs
| fd
);
11893 TCGv_i64 fp0
= tcg_temp_new_i64();
11895 gen_load_fpr64(ctx
, fp0
, fs
);
11896 gen_store_fpr64(ctx
, fp0
, fd
);
11897 tcg_temp_free_i64(fp0
);
11901 check_cp1_registers(ctx
, fs
| fd
);
11903 TCGv_i64 fp0
= tcg_temp_new_i64();
11905 gen_load_fpr64(ctx
, fp0
, fs
);
11906 if (ctx
->abs2008
) {
11907 tcg_gen_xori_i64(fp0
, fp0
, 1ULL << 63);
11909 gen_helper_float_chs_d(fp0
, fp0
);
11911 gen_store_fpr64(ctx
, fp0
, fd
);
11912 tcg_temp_free_i64(fp0
);
11915 case OPC_ROUND_L_D
:
11916 check_cp1_64bitmode(ctx
);
11918 TCGv_i64 fp0
= tcg_temp_new_i64();
11920 gen_load_fpr64(ctx
, fp0
, fs
);
11921 if (ctx
->nan2008
) {
11922 gen_helper_float_round_2008_l_d(fp0
, cpu_env
, fp0
);
11924 gen_helper_float_round_l_d(fp0
, cpu_env
, fp0
);
11926 gen_store_fpr64(ctx
, fp0
, fd
);
11927 tcg_temp_free_i64(fp0
);
11930 case OPC_TRUNC_L_D
:
11931 check_cp1_64bitmode(ctx
);
11933 TCGv_i64 fp0
= tcg_temp_new_i64();
11935 gen_load_fpr64(ctx
, fp0
, fs
);
11936 if (ctx
->nan2008
) {
11937 gen_helper_float_trunc_2008_l_d(fp0
, cpu_env
, fp0
);
11939 gen_helper_float_trunc_l_d(fp0
, cpu_env
, fp0
);
11941 gen_store_fpr64(ctx
, fp0
, fd
);
11942 tcg_temp_free_i64(fp0
);
11946 check_cp1_64bitmode(ctx
);
11948 TCGv_i64 fp0
= tcg_temp_new_i64();
11950 gen_load_fpr64(ctx
, fp0
, fs
);
11951 if (ctx
->nan2008
) {
11952 gen_helper_float_ceil_2008_l_d(fp0
, cpu_env
, fp0
);
11954 gen_helper_float_ceil_l_d(fp0
, cpu_env
, fp0
);
11956 gen_store_fpr64(ctx
, fp0
, fd
);
11957 tcg_temp_free_i64(fp0
);
11960 case OPC_FLOOR_L_D
:
11961 check_cp1_64bitmode(ctx
);
11963 TCGv_i64 fp0
= tcg_temp_new_i64();
11965 gen_load_fpr64(ctx
, fp0
, fs
);
11966 if (ctx
->nan2008
) {
11967 gen_helper_float_floor_2008_l_d(fp0
, cpu_env
, fp0
);
11969 gen_helper_float_floor_l_d(fp0
, cpu_env
, fp0
);
11971 gen_store_fpr64(ctx
, fp0
, fd
);
11972 tcg_temp_free_i64(fp0
);
11975 case OPC_ROUND_W_D
:
11976 check_cp1_registers(ctx
, fs
);
11978 TCGv_i32 fp32
= tcg_temp_new_i32();
11979 TCGv_i64 fp64
= tcg_temp_new_i64();
11981 gen_load_fpr64(ctx
, fp64
, fs
);
11982 if (ctx
->nan2008
) {
11983 gen_helper_float_round_2008_w_d(fp32
, cpu_env
, fp64
);
11985 gen_helper_float_round_w_d(fp32
, cpu_env
, fp64
);
11987 tcg_temp_free_i64(fp64
);
11988 gen_store_fpr32(ctx
, fp32
, fd
);
11989 tcg_temp_free_i32(fp32
);
11992 case OPC_TRUNC_W_D
:
11993 check_cp1_registers(ctx
, fs
);
11995 TCGv_i32 fp32
= tcg_temp_new_i32();
11996 TCGv_i64 fp64
= tcg_temp_new_i64();
11998 gen_load_fpr64(ctx
, fp64
, fs
);
11999 if (ctx
->nan2008
) {
12000 gen_helper_float_trunc_2008_w_d(fp32
, cpu_env
, fp64
);
12002 gen_helper_float_trunc_w_d(fp32
, cpu_env
, fp64
);
12004 tcg_temp_free_i64(fp64
);
12005 gen_store_fpr32(ctx
, fp32
, fd
);
12006 tcg_temp_free_i32(fp32
);
12010 check_cp1_registers(ctx
, fs
);
12012 TCGv_i32 fp32
= tcg_temp_new_i32();
12013 TCGv_i64 fp64
= tcg_temp_new_i64();
12015 gen_load_fpr64(ctx
, fp64
, fs
);
12016 if (ctx
->nan2008
) {
12017 gen_helper_float_ceil_2008_w_d(fp32
, cpu_env
, fp64
);
12019 gen_helper_float_ceil_w_d(fp32
, cpu_env
, fp64
);
12021 tcg_temp_free_i64(fp64
);
12022 gen_store_fpr32(ctx
, fp32
, fd
);
12023 tcg_temp_free_i32(fp32
);
12026 case OPC_FLOOR_W_D
:
12027 check_cp1_registers(ctx
, fs
);
12029 TCGv_i32 fp32
= tcg_temp_new_i32();
12030 TCGv_i64 fp64
= tcg_temp_new_i64();
12032 gen_load_fpr64(ctx
, fp64
, fs
);
12033 if (ctx
->nan2008
) {
12034 gen_helper_float_floor_2008_w_d(fp32
, cpu_env
, fp64
);
12036 gen_helper_float_floor_w_d(fp32
, cpu_env
, fp64
);
12038 tcg_temp_free_i64(fp64
);
12039 gen_store_fpr32(ctx
, fp32
, fd
);
12040 tcg_temp_free_i32(fp32
);
12044 check_insn(ctx
, ISA_MIPS_R6
);
12045 gen_sel_d(ctx
, op1
, fd
, ft
, fs
);
12048 check_insn(ctx
, ISA_MIPS_R6
);
12049 gen_sel_d(ctx
, op1
, fd
, ft
, fs
);
12052 check_insn(ctx
, ISA_MIPS_R6
);
12053 gen_sel_d(ctx
, op1
, fd
, ft
, fs
);
12056 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
12057 gen_movcf_d(ctx
, fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
12060 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
12062 TCGLabel
*l1
= gen_new_label();
12066 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
12068 fp0
= tcg_temp_new_i64();
12069 gen_load_fpr64(ctx
, fp0
, fs
);
12070 gen_store_fpr64(ctx
, fp0
, fd
);
12071 tcg_temp_free_i64(fp0
);
12076 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
12078 TCGLabel
*l1
= gen_new_label();
12082 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
12083 fp0
= tcg_temp_new_i64();
12084 gen_load_fpr64(ctx
, fp0
, fs
);
12085 gen_store_fpr64(ctx
, fp0
, fd
);
12086 tcg_temp_free_i64(fp0
);
12092 check_cp1_registers(ctx
, fs
| fd
);
12094 TCGv_i64 fp0
= tcg_temp_new_i64();
12096 gen_load_fpr64(ctx
, fp0
, fs
);
12097 gen_helper_float_recip_d(fp0
, cpu_env
, fp0
);
12098 gen_store_fpr64(ctx
, fp0
, fd
);
12099 tcg_temp_free_i64(fp0
);
12103 check_cp1_registers(ctx
, fs
| fd
);
12105 TCGv_i64 fp0
= tcg_temp_new_i64();
12107 gen_load_fpr64(ctx
, fp0
, fs
);
12108 gen_helper_float_rsqrt_d(fp0
, cpu_env
, fp0
);
12109 gen_store_fpr64(ctx
, fp0
, fd
);
12110 tcg_temp_free_i64(fp0
);
12114 check_insn(ctx
, ISA_MIPS_R6
);
12116 TCGv_i64 fp0
= tcg_temp_new_i64();
12117 TCGv_i64 fp1
= tcg_temp_new_i64();
12118 TCGv_i64 fp2
= tcg_temp_new_i64();
12119 gen_load_fpr64(ctx
, fp0
, fs
);
12120 gen_load_fpr64(ctx
, fp1
, ft
);
12121 gen_load_fpr64(ctx
, fp2
, fd
);
12122 gen_helper_float_maddf_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12123 gen_store_fpr64(ctx
, fp2
, fd
);
12124 tcg_temp_free_i64(fp2
);
12125 tcg_temp_free_i64(fp1
);
12126 tcg_temp_free_i64(fp0
);
12130 check_insn(ctx
, ISA_MIPS_R6
);
12132 TCGv_i64 fp0
= tcg_temp_new_i64();
12133 TCGv_i64 fp1
= tcg_temp_new_i64();
12134 TCGv_i64 fp2
= tcg_temp_new_i64();
12135 gen_load_fpr64(ctx
, fp0
, fs
);
12136 gen_load_fpr64(ctx
, fp1
, ft
);
12137 gen_load_fpr64(ctx
, fp2
, fd
);
12138 gen_helper_float_msubf_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12139 gen_store_fpr64(ctx
, fp2
, fd
);
12140 tcg_temp_free_i64(fp2
);
12141 tcg_temp_free_i64(fp1
);
12142 tcg_temp_free_i64(fp0
);
12146 check_insn(ctx
, ISA_MIPS_R6
);
12148 TCGv_i64 fp0
= tcg_temp_new_i64();
12149 gen_load_fpr64(ctx
, fp0
, fs
);
12150 gen_helper_float_rint_d(fp0
, cpu_env
, fp0
);
12151 gen_store_fpr64(ctx
, fp0
, fd
);
12152 tcg_temp_free_i64(fp0
);
12156 check_insn(ctx
, ISA_MIPS_R6
);
12158 TCGv_i64 fp0
= tcg_temp_new_i64();
12159 gen_load_fpr64(ctx
, fp0
, fs
);
12160 gen_helper_float_class_d(fp0
, cpu_env
, fp0
);
12161 gen_store_fpr64(ctx
, fp0
, fd
);
12162 tcg_temp_free_i64(fp0
);
12165 case OPC_MIN_D
: /* OPC_RECIP2_D */
12166 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
12168 TCGv_i64 fp0
= tcg_temp_new_i64();
12169 TCGv_i64 fp1
= tcg_temp_new_i64();
12170 gen_load_fpr64(ctx
, fp0
, fs
);
12171 gen_load_fpr64(ctx
, fp1
, ft
);
12172 gen_helper_float_min_d(fp1
, cpu_env
, fp0
, fp1
);
12173 gen_store_fpr64(ctx
, fp1
, fd
);
12174 tcg_temp_free_i64(fp1
);
12175 tcg_temp_free_i64(fp0
);
12178 check_cp1_64bitmode(ctx
);
12180 TCGv_i64 fp0
= tcg_temp_new_i64();
12181 TCGv_i64 fp1
= tcg_temp_new_i64();
12183 gen_load_fpr64(ctx
, fp0
, fs
);
12184 gen_load_fpr64(ctx
, fp1
, ft
);
12185 gen_helper_float_recip2_d(fp0
, cpu_env
, fp0
, fp1
);
12186 tcg_temp_free_i64(fp1
);
12187 gen_store_fpr64(ctx
, fp0
, fd
);
12188 tcg_temp_free_i64(fp0
);
12192 case OPC_MINA_D
: /* OPC_RECIP1_D */
12193 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
12195 TCGv_i64 fp0
= tcg_temp_new_i64();
12196 TCGv_i64 fp1
= tcg_temp_new_i64();
12197 gen_load_fpr64(ctx
, fp0
, fs
);
12198 gen_load_fpr64(ctx
, fp1
, ft
);
12199 gen_helper_float_mina_d(fp1
, cpu_env
, fp0
, fp1
);
12200 gen_store_fpr64(ctx
, fp1
, fd
);
12201 tcg_temp_free_i64(fp1
);
12202 tcg_temp_free_i64(fp0
);
12205 check_cp1_64bitmode(ctx
);
12207 TCGv_i64 fp0
= tcg_temp_new_i64();
12209 gen_load_fpr64(ctx
, fp0
, fs
);
12210 gen_helper_float_recip1_d(fp0
, cpu_env
, fp0
);
12211 gen_store_fpr64(ctx
, fp0
, fd
);
12212 tcg_temp_free_i64(fp0
);
12216 case OPC_MAX_D
: /* OPC_RSQRT1_D */
12217 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
12219 TCGv_i64 fp0
= tcg_temp_new_i64();
12220 TCGv_i64 fp1
= tcg_temp_new_i64();
12221 gen_load_fpr64(ctx
, fp0
, fs
);
12222 gen_load_fpr64(ctx
, fp1
, ft
);
12223 gen_helper_float_max_d(fp1
, cpu_env
, fp0
, fp1
);
12224 gen_store_fpr64(ctx
, fp1
, fd
);
12225 tcg_temp_free_i64(fp1
);
12226 tcg_temp_free_i64(fp0
);
12229 check_cp1_64bitmode(ctx
);
12231 TCGv_i64 fp0
= tcg_temp_new_i64();
12233 gen_load_fpr64(ctx
, fp0
, fs
);
12234 gen_helper_float_rsqrt1_d(fp0
, cpu_env
, fp0
);
12235 gen_store_fpr64(ctx
, fp0
, fd
);
12236 tcg_temp_free_i64(fp0
);
12240 case OPC_MAXA_D
: /* OPC_RSQRT2_D */
12241 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
12243 TCGv_i64 fp0
= tcg_temp_new_i64();
12244 TCGv_i64 fp1
= tcg_temp_new_i64();
12245 gen_load_fpr64(ctx
, fp0
, fs
);
12246 gen_load_fpr64(ctx
, fp1
, ft
);
12247 gen_helper_float_maxa_d(fp1
, cpu_env
, fp0
, fp1
);
12248 gen_store_fpr64(ctx
, fp1
, fd
);
12249 tcg_temp_free_i64(fp1
);
12250 tcg_temp_free_i64(fp0
);
12253 check_cp1_64bitmode(ctx
);
12255 TCGv_i64 fp0
= tcg_temp_new_i64();
12256 TCGv_i64 fp1
= tcg_temp_new_i64();
12258 gen_load_fpr64(ctx
, fp0
, fs
);
12259 gen_load_fpr64(ctx
, fp1
, ft
);
12260 gen_helper_float_rsqrt2_d(fp0
, cpu_env
, fp0
, fp1
);
12261 tcg_temp_free_i64(fp1
);
12262 gen_store_fpr64(ctx
, fp0
, fd
);
12263 tcg_temp_free_i64(fp0
);
12270 case OPC_CMP_UEQ_D
:
12271 case OPC_CMP_OLT_D
:
12272 case OPC_CMP_ULT_D
:
12273 case OPC_CMP_OLE_D
:
12274 case OPC_CMP_ULE_D
:
12276 case OPC_CMP_NGLE_D
:
12277 case OPC_CMP_SEQ_D
:
12278 case OPC_CMP_NGL_D
:
12280 case OPC_CMP_NGE_D
:
12282 case OPC_CMP_NGT_D
:
12283 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
12284 if (ctx
->opcode
& (1 << 6)) {
12285 gen_cmpabs_d(ctx
, func
- 48, ft
, fs
, cc
);
12287 gen_cmp_d(ctx
, func
- 48, ft
, fs
, cc
);
12291 check_cp1_registers(ctx
, fs
);
12293 TCGv_i32 fp32
= tcg_temp_new_i32();
12294 TCGv_i64 fp64
= tcg_temp_new_i64();
12296 gen_load_fpr64(ctx
, fp64
, fs
);
12297 gen_helper_float_cvts_d(fp32
, cpu_env
, fp64
);
12298 tcg_temp_free_i64(fp64
);
12299 gen_store_fpr32(ctx
, fp32
, fd
);
12300 tcg_temp_free_i32(fp32
);
12304 check_cp1_registers(ctx
, fs
);
12306 TCGv_i32 fp32
= tcg_temp_new_i32();
12307 TCGv_i64 fp64
= tcg_temp_new_i64();
12309 gen_load_fpr64(ctx
, fp64
, fs
);
12310 if (ctx
->nan2008
) {
12311 gen_helper_float_cvt_2008_w_d(fp32
, cpu_env
, fp64
);
12313 gen_helper_float_cvt_w_d(fp32
, cpu_env
, fp64
);
12315 tcg_temp_free_i64(fp64
);
12316 gen_store_fpr32(ctx
, fp32
, fd
);
12317 tcg_temp_free_i32(fp32
);
12321 check_cp1_64bitmode(ctx
);
12323 TCGv_i64 fp0
= tcg_temp_new_i64();
12325 gen_load_fpr64(ctx
, fp0
, fs
);
12326 if (ctx
->nan2008
) {
12327 gen_helper_float_cvt_2008_l_d(fp0
, cpu_env
, fp0
);
12329 gen_helper_float_cvt_l_d(fp0
, cpu_env
, fp0
);
12331 gen_store_fpr64(ctx
, fp0
, fd
);
12332 tcg_temp_free_i64(fp0
);
12337 TCGv_i32 fp0
= tcg_temp_new_i32();
12339 gen_load_fpr32(ctx
, fp0
, fs
);
12340 gen_helper_float_cvts_w(fp0
, cpu_env
, fp0
);
12341 gen_store_fpr32(ctx
, fp0
, fd
);
12342 tcg_temp_free_i32(fp0
);
12346 check_cp1_registers(ctx
, fd
);
12348 TCGv_i32 fp32
= tcg_temp_new_i32();
12349 TCGv_i64 fp64
= tcg_temp_new_i64();
12351 gen_load_fpr32(ctx
, fp32
, fs
);
12352 gen_helper_float_cvtd_w(fp64
, cpu_env
, fp32
);
12353 tcg_temp_free_i32(fp32
);
12354 gen_store_fpr64(ctx
, fp64
, fd
);
12355 tcg_temp_free_i64(fp64
);
12359 check_cp1_64bitmode(ctx
);
12361 TCGv_i32 fp32
= tcg_temp_new_i32();
12362 TCGv_i64 fp64
= tcg_temp_new_i64();
12364 gen_load_fpr64(ctx
, fp64
, fs
);
12365 gen_helper_float_cvts_l(fp32
, cpu_env
, fp64
);
12366 tcg_temp_free_i64(fp64
);
12367 gen_store_fpr32(ctx
, fp32
, fd
);
12368 tcg_temp_free_i32(fp32
);
12372 check_cp1_64bitmode(ctx
);
12374 TCGv_i64 fp0
= tcg_temp_new_i64();
12376 gen_load_fpr64(ctx
, fp0
, fs
);
12377 gen_helper_float_cvtd_l(fp0
, cpu_env
, fp0
);
12378 gen_store_fpr64(ctx
, fp0
, fd
);
12379 tcg_temp_free_i64(fp0
);
12382 case OPC_CVT_PS_PW
:
12385 TCGv_i64 fp0
= tcg_temp_new_i64();
12387 gen_load_fpr64(ctx
, fp0
, fs
);
12388 gen_helper_float_cvtps_pw(fp0
, cpu_env
, fp0
);
12389 gen_store_fpr64(ctx
, fp0
, fd
);
12390 tcg_temp_free_i64(fp0
);
12396 TCGv_i64 fp0
= tcg_temp_new_i64();
12397 TCGv_i64 fp1
= tcg_temp_new_i64();
12399 gen_load_fpr64(ctx
, fp0
, fs
);
12400 gen_load_fpr64(ctx
, fp1
, ft
);
12401 gen_helper_float_add_ps(fp0
, cpu_env
, fp0
, fp1
);
12402 tcg_temp_free_i64(fp1
);
12403 gen_store_fpr64(ctx
, fp0
, fd
);
12404 tcg_temp_free_i64(fp0
);
12410 TCGv_i64 fp0
= tcg_temp_new_i64();
12411 TCGv_i64 fp1
= tcg_temp_new_i64();
12413 gen_load_fpr64(ctx
, fp0
, fs
);
12414 gen_load_fpr64(ctx
, fp1
, ft
);
12415 gen_helper_float_sub_ps(fp0
, cpu_env
, fp0
, fp1
);
12416 tcg_temp_free_i64(fp1
);
12417 gen_store_fpr64(ctx
, fp0
, fd
);
12418 tcg_temp_free_i64(fp0
);
12424 TCGv_i64 fp0
= tcg_temp_new_i64();
12425 TCGv_i64 fp1
= tcg_temp_new_i64();
12427 gen_load_fpr64(ctx
, fp0
, fs
);
12428 gen_load_fpr64(ctx
, fp1
, ft
);
12429 gen_helper_float_mul_ps(fp0
, cpu_env
, fp0
, fp1
);
12430 tcg_temp_free_i64(fp1
);
12431 gen_store_fpr64(ctx
, fp0
, fd
);
12432 tcg_temp_free_i64(fp0
);
12438 TCGv_i64 fp0
= tcg_temp_new_i64();
12440 gen_load_fpr64(ctx
, fp0
, fs
);
12441 gen_helper_float_abs_ps(fp0
, fp0
);
12442 gen_store_fpr64(ctx
, fp0
, fd
);
12443 tcg_temp_free_i64(fp0
);
12449 TCGv_i64 fp0
= tcg_temp_new_i64();
12451 gen_load_fpr64(ctx
, fp0
, fs
);
12452 gen_store_fpr64(ctx
, fp0
, fd
);
12453 tcg_temp_free_i64(fp0
);
12459 TCGv_i64 fp0
= tcg_temp_new_i64();
12461 gen_load_fpr64(ctx
, fp0
, fs
);
12462 gen_helper_float_chs_ps(fp0
, fp0
);
12463 gen_store_fpr64(ctx
, fp0
, fd
);
12464 tcg_temp_free_i64(fp0
);
12469 gen_movcf_ps(ctx
, fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
12474 TCGLabel
*l1
= gen_new_label();
12478 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
12480 fp0
= tcg_temp_new_i64();
12481 gen_load_fpr64(ctx
, fp0
, fs
);
12482 gen_store_fpr64(ctx
, fp0
, fd
);
12483 tcg_temp_free_i64(fp0
);
12490 TCGLabel
*l1
= gen_new_label();
12494 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
12495 fp0
= tcg_temp_new_i64();
12496 gen_load_fpr64(ctx
, fp0
, fs
);
12497 gen_store_fpr64(ctx
, fp0
, fd
);
12498 tcg_temp_free_i64(fp0
);
12506 TCGv_i64 fp0
= tcg_temp_new_i64();
12507 TCGv_i64 fp1
= tcg_temp_new_i64();
12509 gen_load_fpr64(ctx
, fp0
, ft
);
12510 gen_load_fpr64(ctx
, fp1
, fs
);
12511 gen_helper_float_addr_ps(fp0
, cpu_env
, fp0
, fp1
);
12512 tcg_temp_free_i64(fp1
);
12513 gen_store_fpr64(ctx
, fp0
, fd
);
12514 tcg_temp_free_i64(fp0
);
12520 TCGv_i64 fp0
= tcg_temp_new_i64();
12521 TCGv_i64 fp1
= tcg_temp_new_i64();
12523 gen_load_fpr64(ctx
, fp0
, ft
);
12524 gen_load_fpr64(ctx
, fp1
, fs
);
12525 gen_helper_float_mulr_ps(fp0
, cpu_env
, fp0
, fp1
);
12526 tcg_temp_free_i64(fp1
);
12527 gen_store_fpr64(ctx
, fp0
, fd
);
12528 tcg_temp_free_i64(fp0
);
12531 case OPC_RECIP2_PS
:
12534 TCGv_i64 fp0
= tcg_temp_new_i64();
12535 TCGv_i64 fp1
= tcg_temp_new_i64();
12537 gen_load_fpr64(ctx
, fp0
, fs
);
12538 gen_load_fpr64(ctx
, fp1
, ft
);
12539 gen_helper_float_recip2_ps(fp0
, cpu_env
, fp0
, fp1
);
12540 tcg_temp_free_i64(fp1
);
12541 gen_store_fpr64(ctx
, fp0
, fd
);
12542 tcg_temp_free_i64(fp0
);
12545 case OPC_RECIP1_PS
:
12548 TCGv_i64 fp0
= tcg_temp_new_i64();
12550 gen_load_fpr64(ctx
, fp0
, fs
);
12551 gen_helper_float_recip1_ps(fp0
, cpu_env
, fp0
);
12552 gen_store_fpr64(ctx
, fp0
, fd
);
12553 tcg_temp_free_i64(fp0
);
12556 case OPC_RSQRT1_PS
:
12559 TCGv_i64 fp0
= tcg_temp_new_i64();
12561 gen_load_fpr64(ctx
, fp0
, fs
);
12562 gen_helper_float_rsqrt1_ps(fp0
, cpu_env
, fp0
);
12563 gen_store_fpr64(ctx
, fp0
, fd
);
12564 tcg_temp_free_i64(fp0
);
12567 case OPC_RSQRT2_PS
:
12570 TCGv_i64 fp0
= tcg_temp_new_i64();
12571 TCGv_i64 fp1
= tcg_temp_new_i64();
12573 gen_load_fpr64(ctx
, fp0
, fs
);
12574 gen_load_fpr64(ctx
, fp1
, ft
);
12575 gen_helper_float_rsqrt2_ps(fp0
, cpu_env
, fp0
, fp1
);
12576 tcg_temp_free_i64(fp1
);
12577 gen_store_fpr64(ctx
, fp0
, fd
);
12578 tcg_temp_free_i64(fp0
);
12582 check_cp1_64bitmode(ctx
);
12584 TCGv_i32 fp0
= tcg_temp_new_i32();
12586 gen_load_fpr32h(ctx
, fp0
, fs
);
12587 gen_helper_float_cvts_pu(fp0
, cpu_env
, fp0
);
12588 gen_store_fpr32(ctx
, fp0
, fd
);
12589 tcg_temp_free_i32(fp0
);
12592 case OPC_CVT_PW_PS
:
12595 TCGv_i64 fp0
= tcg_temp_new_i64();
12597 gen_load_fpr64(ctx
, fp0
, fs
);
12598 gen_helper_float_cvtpw_ps(fp0
, cpu_env
, fp0
);
12599 gen_store_fpr64(ctx
, fp0
, fd
);
12600 tcg_temp_free_i64(fp0
);
12604 check_cp1_64bitmode(ctx
);
12606 TCGv_i32 fp0
= tcg_temp_new_i32();
12608 gen_load_fpr32(ctx
, fp0
, fs
);
12609 gen_helper_float_cvts_pl(fp0
, cpu_env
, fp0
);
12610 gen_store_fpr32(ctx
, fp0
, fd
);
12611 tcg_temp_free_i32(fp0
);
12617 TCGv_i32 fp0
= tcg_temp_new_i32();
12618 TCGv_i32 fp1
= tcg_temp_new_i32();
12620 gen_load_fpr32(ctx
, fp0
, fs
);
12621 gen_load_fpr32(ctx
, fp1
, ft
);
12622 gen_store_fpr32h(ctx
, fp0
, fd
);
12623 gen_store_fpr32(ctx
, fp1
, fd
);
12624 tcg_temp_free_i32(fp0
);
12625 tcg_temp_free_i32(fp1
);
12631 TCGv_i32 fp0
= tcg_temp_new_i32();
12632 TCGv_i32 fp1
= tcg_temp_new_i32();
12634 gen_load_fpr32(ctx
, fp0
, fs
);
12635 gen_load_fpr32h(ctx
, fp1
, ft
);
12636 gen_store_fpr32(ctx
, fp1
, fd
);
12637 gen_store_fpr32h(ctx
, fp0
, fd
);
12638 tcg_temp_free_i32(fp0
);
12639 tcg_temp_free_i32(fp1
);
12645 TCGv_i32 fp0
= tcg_temp_new_i32();
12646 TCGv_i32 fp1
= tcg_temp_new_i32();
12648 gen_load_fpr32h(ctx
, fp0
, fs
);
12649 gen_load_fpr32(ctx
, fp1
, ft
);
12650 gen_store_fpr32(ctx
, fp1
, fd
);
12651 gen_store_fpr32h(ctx
, fp0
, fd
);
12652 tcg_temp_free_i32(fp0
);
12653 tcg_temp_free_i32(fp1
);
12659 TCGv_i32 fp0
= tcg_temp_new_i32();
12660 TCGv_i32 fp1
= tcg_temp_new_i32();
12662 gen_load_fpr32h(ctx
, fp0
, fs
);
12663 gen_load_fpr32h(ctx
, fp1
, ft
);
12664 gen_store_fpr32(ctx
, fp1
, fd
);
12665 gen_store_fpr32h(ctx
, fp0
, fd
);
12666 tcg_temp_free_i32(fp0
);
12667 tcg_temp_free_i32(fp1
);
12671 case OPC_CMP_UN_PS
:
12672 case OPC_CMP_EQ_PS
:
12673 case OPC_CMP_UEQ_PS
:
12674 case OPC_CMP_OLT_PS
:
12675 case OPC_CMP_ULT_PS
:
12676 case OPC_CMP_OLE_PS
:
12677 case OPC_CMP_ULE_PS
:
12678 case OPC_CMP_SF_PS
:
12679 case OPC_CMP_NGLE_PS
:
12680 case OPC_CMP_SEQ_PS
:
12681 case OPC_CMP_NGL_PS
:
12682 case OPC_CMP_LT_PS
:
12683 case OPC_CMP_NGE_PS
:
12684 case OPC_CMP_LE_PS
:
12685 case OPC_CMP_NGT_PS
:
12686 if (ctx
->opcode
& (1 << 6)) {
12687 gen_cmpabs_ps(ctx
, func
- 48, ft
, fs
, cc
);
12689 gen_cmp_ps(ctx
, func
- 48, ft
, fs
, cc
);
12693 MIPS_INVAL("farith");
12694 gen_reserved_instruction(ctx
);
12699 /* Coprocessor 3 (FPU) */
12700 static void gen_flt3_ldst(DisasContext
*ctx
, uint32_t opc
,
12701 int fd
, int fs
, int base
, int index
)
12703 TCGv t0
= tcg_temp_new();
12706 gen_load_gpr(t0
, index
);
12707 } else if (index
== 0) {
12708 gen_load_gpr(t0
, base
);
12710 gen_op_addr_add(ctx
, t0
, cpu_gpr
[base
], cpu_gpr
[index
]);
12713 * Don't do NOP if destination is zero: we must perform the actual
12720 TCGv_i32 fp0
= tcg_temp_new_i32();
12722 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESL
);
12723 tcg_gen_trunc_tl_i32(fp0
, t0
);
12724 gen_store_fpr32(ctx
, fp0
, fd
);
12725 tcg_temp_free_i32(fp0
);
12730 check_cp1_registers(ctx
, fd
);
12732 TCGv_i64 fp0
= tcg_temp_new_i64();
12733 tcg_gen_qemu_ld_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
12734 gen_store_fpr64(ctx
, fp0
, fd
);
12735 tcg_temp_free_i64(fp0
);
12739 check_cp1_64bitmode(ctx
);
12740 tcg_gen_andi_tl(t0
, t0
, ~0x7);
12742 TCGv_i64 fp0
= tcg_temp_new_i64();
12744 tcg_gen_qemu_ld_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
12745 gen_store_fpr64(ctx
, fp0
, fd
);
12746 tcg_temp_free_i64(fp0
);
12752 TCGv_i32 fp0
= tcg_temp_new_i32();
12753 gen_load_fpr32(ctx
, fp0
, fs
);
12754 tcg_gen_qemu_st_i32(fp0
, t0
, ctx
->mem_idx
, MO_TEUL
);
12755 tcg_temp_free_i32(fp0
);
12760 check_cp1_registers(ctx
, fs
);
12762 TCGv_i64 fp0
= tcg_temp_new_i64();
12763 gen_load_fpr64(ctx
, fp0
, fs
);
12764 tcg_gen_qemu_st_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
12765 tcg_temp_free_i64(fp0
);
12769 check_cp1_64bitmode(ctx
);
12770 tcg_gen_andi_tl(t0
, t0
, ~0x7);
12772 TCGv_i64 fp0
= tcg_temp_new_i64();
12773 gen_load_fpr64(ctx
, fp0
, fs
);
12774 tcg_gen_qemu_st_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
12775 tcg_temp_free_i64(fp0
);
12782 static void gen_flt3_arith(DisasContext
*ctx
, uint32_t opc
,
12783 int fd
, int fr
, int fs
, int ft
)
12789 TCGv t0
= tcg_temp_local_new();
12790 TCGv_i32 fp
= tcg_temp_new_i32();
12791 TCGv_i32 fph
= tcg_temp_new_i32();
12792 TCGLabel
*l1
= gen_new_label();
12793 TCGLabel
*l2
= gen_new_label();
12795 gen_load_gpr(t0
, fr
);
12796 tcg_gen_andi_tl(t0
, t0
, 0x7);
12798 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, 0, l1
);
12799 gen_load_fpr32(ctx
, fp
, fs
);
12800 gen_load_fpr32h(ctx
, fph
, fs
);
12801 gen_store_fpr32(ctx
, fp
, fd
);
12802 gen_store_fpr32h(ctx
, fph
, fd
);
12805 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, 4, l2
);
12807 #ifdef TARGET_WORDS_BIGENDIAN
12808 gen_load_fpr32(ctx
, fp
, fs
);
12809 gen_load_fpr32h(ctx
, fph
, ft
);
12810 gen_store_fpr32h(ctx
, fp
, fd
);
12811 gen_store_fpr32(ctx
, fph
, fd
);
12813 gen_load_fpr32h(ctx
, fph
, fs
);
12814 gen_load_fpr32(ctx
, fp
, ft
);
12815 gen_store_fpr32(ctx
, fph
, fd
);
12816 gen_store_fpr32h(ctx
, fp
, fd
);
12819 tcg_temp_free_i32(fp
);
12820 tcg_temp_free_i32(fph
);
12826 TCGv_i32 fp0
= tcg_temp_new_i32();
12827 TCGv_i32 fp1
= tcg_temp_new_i32();
12828 TCGv_i32 fp2
= tcg_temp_new_i32();
12830 gen_load_fpr32(ctx
, fp0
, fs
);
12831 gen_load_fpr32(ctx
, fp1
, ft
);
12832 gen_load_fpr32(ctx
, fp2
, fr
);
12833 gen_helper_float_madd_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12834 tcg_temp_free_i32(fp0
);
12835 tcg_temp_free_i32(fp1
);
12836 gen_store_fpr32(ctx
, fp2
, fd
);
12837 tcg_temp_free_i32(fp2
);
12842 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
12844 TCGv_i64 fp0
= tcg_temp_new_i64();
12845 TCGv_i64 fp1
= tcg_temp_new_i64();
12846 TCGv_i64 fp2
= tcg_temp_new_i64();
12848 gen_load_fpr64(ctx
, fp0
, fs
);
12849 gen_load_fpr64(ctx
, fp1
, ft
);
12850 gen_load_fpr64(ctx
, fp2
, fr
);
12851 gen_helper_float_madd_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12852 tcg_temp_free_i64(fp0
);
12853 tcg_temp_free_i64(fp1
);
12854 gen_store_fpr64(ctx
, fp2
, fd
);
12855 tcg_temp_free_i64(fp2
);
12861 TCGv_i64 fp0
= tcg_temp_new_i64();
12862 TCGv_i64 fp1
= tcg_temp_new_i64();
12863 TCGv_i64 fp2
= tcg_temp_new_i64();
12865 gen_load_fpr64(ctx
, fp0
, fs
);
12866 gen_load_fpr64(ctx
, fp1
, ft
);
12867 gen_load_fpr64(ctx
, fp2
, fr
);
12868 gen_helper_float_madd_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12869 tcg_temp_free_i64(fp0
);
12870 tcg_temp_free_i64(fp1
);
12871 gen_store_fpr64(ctx
, fp2
, fd
);
12872 tcg_temp_free_i64(fp2
);
12878 TCGv_i32 fp0
= tcg_temp_new_i32();
12879 TCGv_i32 fp1
= tcg_temp_new_i32();
12880 TCGv_i32 fp2
= tcg_temp_new_i32();
12882 gen_load_fpr32(ctx
, fp0
, fs
);
12883 gen_load_fpr32(ctx
, fp1
, ft
);
12884 gen_load_fpr32(ctx
, fp2
, fr
);
12885 gen_helper_float_msub_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12886 tcg_temp_free_i32(fp0
);
12887 tcg_temp_free_i32(fp1
);
12888 gen_store_fpr32(ctx
, fp2
, fd
);
12889 tcg_temp_free_i32(fp2
);
12894 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
12896 TCGv_i64 fp0
= tcg_temp_new_i64();
12897 TCGv_i64 fp1
= tcg_temp_new_i64();
12898 TCGv_i64 fp2
= tcg_temp_new_i64();
12900 gen_load_fpr64(ctx
, fp0
, fs
);
12901 gen_load_fpr64(ctx
, fp1
, ft
);
12902 gen_load_fpr64(ctx
, fp2
, fr
);
12903 gen_helper_float_msub_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12904 tcg_temp_free_i64(fp0
);
12905 tcg_temp_free_i64(fp1
);
12906 gen_store_fpr64(ctx
, fp2
, fd
);
12907 tcg_temp_free_i64(fp2
);
12913 TCGv_i64 fp0
= tcg_temp_new_i64();
12914 TCGv_i64 fp1
= tcg_temp_new_i64();
12915 TCGv_i64 fp2
= tcg_temp_new_i64();
12917 gen_load_fpr64(ctx
, fp0
, fs
);
12918 gen_load_fpr64(ctx
, fp1
, ft
);
12919 gen_load_fpr64(ctx
, fp2
, fr
);
12920 gen_helper_float_msub_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12921 tcg_temp_free_i64(fp0
);
12922 tcg_temp_free_i64(fp1
);
12923 gen_store_fpr64(ctx
, fp2
, fd
);
12924 tcg_temp_free_i64(fp2
);
12930 TCGv_i32 fp0
= tcg_temp_new_i32();
12931 TCGv_i32 fp1
= tcg_temp_new_i32();
12932 TCGv_i32 fp2
= tcg_temp_new_i32();
12934 gen_load_fpr32(ctx
, fp0
, fs
);
12935 gen_load_fpr32(ctx
, fp1
, ft
);
12936 gen_load_fpr32(ctx
, fp2
, fr
);
12937 gen_helper_float_nmadd_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12938 tcg_temp_free_i32(fp0
);
12939 tcg_temp_free_i32(fp1
);
12940 gen_store_fpr32(ctx
, fp2
, fd
);
12941 tcg_temp_free_i32(fp2
);
12946 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
12948 TCGv_i64 fp0
= tcg_temp_new_i64();
12949 TCGv_i64 fp1
= tcg_temp_new_i64();
12950 TCGv_i64 fp2
= tcg_temp_new_i64();
12952 gen_load_fpr64(ctx
, fp0
, fs
);
12953 gen_load_fpr64(ctx
, fp1
, ft
);
12954 gen_load_fpr64(ctx
, fp2
, fr
);
12955 gen_helper_float_nmadd_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12956 tcg_temp_free_i64(fp0
);
12957 tcg_temp_free_i64(fp1
);
12958 gen_store_fpr64(ctx
, fp2
, fd
);
12959 tcg_temp_free_i64(fp2
);
12965 TCGv_i64 fp0
= tcg_temp_new_i64();
12966 TCGv_i64 fp1
= tcg_temp_new_i64();
12967 TCGv_i64 fp2
= tcg_temp_new_i64();
12969 gen_load_fpr64(ctx
, fp0
, fs
);
12970 gen_load_fpr64(ctx
, fp1
, ft
);
12971 gen_load_fpr64(ctx
, fp2
, fr
);
12972 gen_helper_float_nmadd_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12973 tcg_temp_free_i64(fp0
);
12974 tcg_temp_free_i64(fp1
);
12975 gen_store_fpr64(ctx
, fp2
, fd
);
12976 tcg_temp_free_i64(fp2
);
12982 TCGv_i32 fp0
= tcg_temp_new_i32();
12983 TCGv_i32 fp1
= tcg_temp_new_i32();
12984 TCGv_i32 fp2
= tcg_temp_new_i32();
12986 gen_load_fpr32(ctx
, fp0
, fs
);
12987 gen_load_fpr32(ctx
, fp1
, ft
);
12988 gen_load_fpr32(ctx
, fp2
, fr
);
12989 gen_helper_float_nmsub_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12990 tcg_temp_free_i32(fp0
);
12991 tcg_temp_free_i32(fp1
);
12992 gen_store_fpr32(ctx
, fp2
, fd
);
12993 tcg_temp_free_i32(fp2
);
12998 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
13000 TCGv_i64 fp0
= tcg_temp_new_i64();
13001 TCGv_i64 fp1
= tcg_temp_new_i64();
13002 TCGv_i64 fp2
= tcg_temp_new_i64();
13004 gen_load_fpr64(ctx
, fp0
, fs
);
13005 gen_load_fpr64(ctx
, fp1
, ft
);
13006 gen_load_fpr64(ctx
, fp2
, fr
);
13007 gen_helper_float_nmsub_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
13008 tcg_temp_free_i64(fp0
);
13009 tcg_temp_free_i64(fp1
);
13010 gen_store_fpr64(ctx
, fp2
, fd
);
13011 tcg_temp_free_i64(fp2
);
13017 TCGv_i64 fp0
= tcg_temp_new_i64();
13018 TCGv_i64 fp1
= tcg_temp_new_i64();
13019 TCGv_i64 fp2
= tcg_temp_new_i64();
13021 gen_load_fpr64(ctx
, fp0
, fs
);
13022 gen_load_fpr64(ctx
, fp1
, ft
);
13023 gen_load_fpr64(ctx
, fp2
, fr
);
13024 gen_helper_float_nmsub_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
13025 tcg_temp_free_i64(fp0
);
13026 tcg_temp_free_i64(fp1
);
13027 gen_store_fpr64(ctx
, fp2
, fd
);
13028 tcg_temp_free_i64(fp2
);
13032 MIPS_INVAL("flt3_arith");
13033 gen_reserved_instruction(ctx
);
13038 static void gen_rdhwr(DisasContext
*ctx
, int rt
, int rd
, int sel
)
13042 #if !defined(CONFIG_USER_ONLY)
13044 * The Linux kernel will emulate rdhwr if it's not supported natively.
13045 * Therefore only check the ISA in system mode.
13047 check_insn(ctx
, ISA_MIPS_R2
);
13049 t0
= tcg_temp_new();
13053 gen_helper_rdhwr_cpunum(t0
, cpu_env
);
13054 gen_store_gpr(t0
, rt
);
13057 gen_helper_rdhwr_synci_step(t0
, cpu_env
);
13058 gen_store_gpr(t0
, rt
);
13061 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
13064 gen_helper_rdhwr_cc(t0
, cpu_env
);
13065 gen_store_gpr(t0
, rt
);
13067 * Break the TB to be able to take timer interrupts immediately
13068 * after reading count. DISAS_STOP isn't sufficient, we need to ensure
13069 * we break completely out of translated code.
13071 gen_save_pc(ctx
->base
.pc_next
+ 4);
13072 ctx
->base
.is_jmp
= DISAS_EXIT
;
13075 gen_helper_rdhwr_ccres(t0
, cpu_env
);
13076 gen_store_gpr(t0
, rt
);
13079 check_insn(ctx
, ISA_MIPS_R6
);
13082 * Performance counter registers are not implemented other than
13083 * control register 0.
13085 generate_exception(ctx
, EXCP_RI
);
13087 gen_helper_rdhwr_performance(t0
, cpu_env
);
13088 gen_store_gpr(t0
, rt
);
13091 check_insn(ctx
, ISA_MIPS_R6
);
13092 gen_helper_rdhwr_xnp(t0
, cpu_env
);
13093 gen_store_gpr(t0
, rt
);
13096 #if defined(CONFIG_USER_ONLY)
13097 tcg_gen_ld_tl(t0
, cpu_env
,
13098 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
13099 gen_store_gpr(t0
, rt
);
13102 if ((ctx
->hflags
& MIPS_HFLAG_CP0
) ||
13103 (ctx
->hflags
& MIPS_HFLAG_HWRENA_ULR
)) {
13104 tcg_gen_ld_tl(t0
, cpu_env
,
13105 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
13106 gen_store_gpr(t0
, rt
);
13108 gen_reserved_instruction(ctx
);
13112 default: /* Invalid */
13113 MIPS_INVAL("rdhwr");
13114 gen_reserved_instruction(ctx
);
13120 static inline void clear_branch_hflags(DisasContext
*ctx
)
13122 ctx
->hflags
&= ~MIPS_HFLAG_BMASK
;
13123 if (ctx
->base
.is_jmp
== DISAS_NEXT
) {
13124 save_cpu_state(ctx
, 0);
13127 * It is not safe to save ctx->hflags as hflags may be changed
13128 * in execution time by the instruction in delay / forbidden slot.
13130 tcg_gen_andi_i32(hflags
, hflags
, ~MIPS_HFLAG_BMASK
);
13134 static void gen_branch(DisasContext
*ctx
, int insn_bytes
)
13136 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
13137 int proc_hflags
= ctx
->hflags
& MIPS_HFLAG_BMASK
;
13138 /* Branches completion */
13139 clear_branch_hflags(ctx
);
13140 ctx
->base
.is_jmp
= DISAS_NORETURN
;
13141 /* FIXME: Need to clear can_do_io. */
13142 switch (proc_hflags
& MIPS_HFLAG_BMASK_BASE
) {
13143 case MIPS_HFLAG_FBNSLOT
:
13144 gen_goto_tb(ctx
, 0, ctx
->base
.pc_next
+ insn_bytes
);
13147 /* unconditional branch */
13148 if (proc_hflags
& MIPS_HFLAG_BX
) {
13149 tcg_gen_xori_i32(hflags
, hflags
, MIPS_HFLAG_M16
);
13151 gen_goto_tb(ctx
, 0, ctx
->btarget
);
13153 case MIPS_HFLAG_BL
:
13154 /* blikely taken case */
13155 gen_goto_tb(ctx
, 0, ctx
->btarget
);
13157 case MIPS_HFLAG_BC
:
13158 /* Conditional branch */
13160 TCGLabel
*l1
= gen_new_label();
13162 tcg_gen_brcondi_tl(TCG_COND_NE
, bcond
, 0, l1
);
13163 gen_goto_tb(ctx
, 1, ctx
->base
.pc_next
+ insn_bytes
);
13165 gen_goto_tb(ctx
, 0, ctx
->btarget
);
13168 case MIPS_HFLAG_BR
:
13169 /* unconditional branch to register */
13170 if (ctx
->insn_flags
& (ASE_MIPS16
| ASE_MICROMIPS
)) {
13171 TCGv t0
= tcg_temp_new();
13172 TCGv_i32 t1
= tcg_temp_new_i32();
13174 tcg_gen_andi_tl(t0
, btarget
, 0x1);
13175 tcg_gen_trunc_tl_i32(t1
, t0
);
13177 tcg_gen_andi_i32(hflags
, hflags
, ~(uint32_t)MIPS_HFLAG_M16
);
13178 tcg_gen_shli_i32(t1
, t1
, MIPS_HFLAG_M16_SHIFT
);
13179 tcg_gen_or_i32(hflags
, hflags
, t1
);
13180 tcg_temp_free_i32(t1
);
13182 tcg_gen_andi_tl(cpu_PC
, btarget
, ~(target_ulong
)0x1);
13184 tcg_gen_mov_tl(cpu_PC
, btarget
);
13186 if (ctx
->base
.singlestep_enabled
) {
13187 save_cpu_state(ctx
, 0);
13188 gen_helper_raise_exception_debug(cpu_env
);
13190 tcg_gen_lookup_and_goto_ptr();
13193 fprintf(stderr
, "unknown branch 0x%x\n", proc_hflags
);
13199 /* Compact Branches */
13200 static void gen_compute_compact_branch(DisasContext
*ctx
, uint32_t opc
,
13201 int rs
, int rt
, int32_t offset
)
13203 int bcond_compute
= 0;
13204 TCGv t0
= tcg_temp_new();
13205 TCGv t1
= tcg_temp_new();
13206 int m16_lowbit
= (ctx
->hflags
& MIPS_HFLAG_M16
) != 0;
13208 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
13209 #ifdef MIPS_DEBUG_DISAS
13210 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
13211 "\n", ctx
->base
.pc_next
);
13213 gen_reserved_instruction(ctx
);
13217 /* Load needed operands and calculate btarget */
13219 /* compact branch */
13220 case OPC_BOVC
: /* OPC_BEQZALC, OPC_BEQC */
13221 case OPC_BNVC
: /* OPC_BNEZALC, OPC_BNEC */
13222 gen_load_gpr(t0
, rs
);
13223 gen_load_gpr(t1
, rt
);
13225 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
13226 if (rs
<= rt
&& rs
== 0) {
13227 /* OPC_BEQZALC, OPC_BNEZALC */
13228 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 4 + m16_lowbit
);
13231 case OPC_BLEZC
: /* OPC_BGEZC, OPC_BGEC */
13232 case OPC_BGTZC
: /* OPC_BLTZC, OPC_BLTC */
13233 gen_load_gpr(t0
, rs
);
13234 gen_load_gpr(t1
, rt
);
13236 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
13238 case OPC_BLEZALC
: /* OPC_BGEZALC, OPC_BGEUC */
13239 case OPC_BGTZALC
: /* OPC_BLTZALC, OPC_BLTUC */
13240 if (rs
== 0 || rs
== rt
) {
13241 /* OPC_BLEZALC, OPC_BGEZALC */
13242 /* OPC_BGTZALC, OPC_BLTZALC */
13243 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 4 + m16_lowbit
);
13245 gen_load_gpr(t0
, rs
);
13246 gen_load_gpr(t1
, rt
);
13248 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
13252 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
13257 /* OPC_BEQZC, OPC_BNEZC */
13258 gen_load_gpr(t0
, rs
);
13260 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
13262 /* OPC_JIC, OPC_JIALC */
13263 TCGv tbase
= tcg_temp_new();
13264 TCGv toffset
= tcg_temp_new();
13266 gen_load_gpr(tbase
, rt
);
13267 tcg_gen_movi_tl(toffset
, offset
);
13268 gen_op_addr_add(ctx
, btarget
, tbase
, toffset
);
13269 tcg_temp_free(tbase
);
13270 tcg_temp_free(toffset
);
13274 MIPS_INVAL("Compact branch/jump");
13275 gen_reserved_instruction(ctx
);
13279 if (bcond_compute
== 0) {
13280 /* Uncoditional compact branch */
13283 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 4 + m16_lowbit
);
13286 ctx
->hflags
|= MIPS_HFLAG_BR
;
13289 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 4 + m16_lowbit
);
13292 ctx
->hflags
|= MIPS_HFLAG_B
;
13295 MIPS_INVAL("Compact branch/jump");
13296 gen_reserved_instruction(ctx
);
13300 /* Generating branch here as compact branches don't have delay slot */
13301 gen_branch(ctx
, 4);
13303 /* Conditional compact branch */
13304 TCGLabel
*fs
= gen_new_label();
13305 save_cpu_state(ctx
, 0);
13308 case OPC_BLEZALC
: /* OPC_BGEZALC, OPC_BGEUC */
13309 if (rs
== 0 && rt
!= 0) {
13311 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE
), t1
, 0, fs
);
13312 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
13314 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE
), t1
, 0, fs
);
13317 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU
), t0
, t1
, fs
);
13320 case OPC_BGTZALC
: /* OPC_BLTZALC, OPC_BLTUC */
13321 if (rs
== 0 && rt
!= 0) {
13323 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT
), t1
, 0, fs
);
13324 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
13326 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT
), t1
, 0, fs
);
13329 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU
), t0
, t1
, fs
);
13332 case OPC_BLEZC
: /* OPC_BGEZC, OPC_BGEC */
13333 if (rs
== 0 && rt
!= 0) {
13335 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE
), t1
, 0, fs
);
13336 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
13338 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE
), t1
, 0, fs
);
13341 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE
), t0
, t1
, fs
);
13344 case OPC_BGTZC
: /* OPC_BLTZC, OPC_BLTC */
13345 if (rs
== 0 && rt
!= 0) {
13347 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT
), t1
, 0, fs
);
13348 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
13350 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT
), t1
, 0, fs
);
13353 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT
), t0
, t1
, fs
);
13356 case OPC_BOVC
: /* OPC_BEQZALC, OPC_BEQC */
13357 case OPC_BNVC
: /* OPC_BNEZALC, OPC_BNEC */
13359 /* OPC_BOVC, OPC_BNVC */
13360 TCGv t2
= tcg_temp_new();
13361 TCGv t3
= tcg_temp_new();
13362 TCGv t4
= tcg_temp_new();
13363 TCGv input_overflow
= tcg_temp_new();
13365 gen_load_gpr(t0
, rs
);
13366 gen_load_gpr(t1
, rt
);
13367 tcg_gen_ext32s_tl(t2
, t0
);
13368 tcg_gen_setcond_tl(TCG_COND_NE
, input_overflow
, t2
, t0
);
13369 tcg_gen_ext32s_tl(t3
, t1
);
13370 tcg_gen_setcond_tl(TCG_COND_NE
, t4
, t3
, t1
);
13371 tcg_gen_or_tl(input_overflow
, input_overflow
, t4
);
13373 tcg_gen_add_tl(t4
, t2
, t3
);
13374 tcg_gen_ext32s_tl(t4
, t4
);
13375 tcg_gen_xor_tl(t2
, t2
, t3
);
13376 tcg_gen_xor_tl(t3
, t4
, t3
);
13377 tcg_gen_andc_tl(t2
, t3
, t2
);
13378 tcg_gen_setcondi_tl(TCG_COND_LT
, t4
, t2
, 0);
13379 tcg_gen_or_tl(t4
, t4
, input_overflow
);
13380 if (opc
== OPC_BOVC
) {
13382 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE
), t4
, 0, fs
);
13385 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ
), t4
, 0, fs
);
13387 tcg_temp_free(input_overflow
);
13391 } else if (rs
< rt
&& rs
== 0) {
13392 /* OPC_BEQZALC, OPC_BNEZALC */
13393 if (opc
== OPC_BEQZALC
) {
13395 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ
), t1
, 0, fs
);
13398 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE
), t1
, 0, fs
);
13401 /* OPC_BEQC, OPC_BNEC */
13402 if (opc
== OPC_BEQC
) {
13404 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ
), t0
, t1
, fs
);
13407 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE
), t0
, t1
, fs
);
13412 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ
), t0
, 0, fs
);
13415 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE
), t0
, 0, fs
);
13418 MIPS_INVAL("Compact conditional branch/jump");
13419 gen_reserved_instruction(ctx
);
13423 /* Generating branch here as compact branches don't have delay slot */
13424 gen_goto_tb(ctx
, 1, ctx
->btarget
);
13427 ctx
->hflags
|= MIPS_HFLAG_FBNSLOT
;
13435 /* ISA extensions (ASEs) */
13436 /* MIPS16 extension to MIPS32 */
13438 /* MIPS16 major opcodes */
13440 M16_OPC_ADDIUSP
= 0x00,
13441 M16_OPC_ADDIUPC
= 0x01,
13443 M16_OPC_JAL
= 0x03,
13444 M16_OPC_BEQZ
= 0x04,
13445 M16_OPC_BNEQZ
= 0x05,
13446 M16_OPC_SHIFT
= 0x06,
13448 M16_OPC_RRIA
= 0x08,
13449 M16_OPC_ADDIU8
= 0x09,
13450 M16_OPC_SLTI
= 0x0a,
13451 M16_OPC_SLTIU
= 0x0b,
13454 M16_OPC_CMPI
= 0x0e,
13458 M16_OPC_LWSP
= 0x12,
13460 M16_OPC_LBU
= 0x14,
13461 M16_OPC_LHU
= 0x15,
13462 M16_OPC_LWPC
= 0x16,
13463 M16_OPC_LWU
= 0x17,
13466 M16_OPC_SWSP
= 0x1a,
13468 M16_OPC_RRR
= 0x1c,
13470 M16_OPC_EXTEND
= 0x1e,
13474 /* I8 funct field */
13493 /* RR funct field */
13527 /* I64 funct field */
13535 I64_DADDIUPC
= 0x6,
13539 /* RR ry field for CNVT */
13541 RR_RY_CNVT_ZEB
= 0x0,
13542 RR_RY_CNVT_ZEH
= 0x1,
13543 RR_RY_CNVT_ZEW
= 0x2,
13544 RR_RY_CNVT_SEB
= 0x4,
13545 RR_RY_CNVT_SEH
= 0x5,
13546 RR_RY_CNVT_SEW
= 0x6,
13549 static int xlat(int r
)
13551 static int map
[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
13556 static void gen_mips16_save(DisasContext
*ctx
,
13557 int xsregs
, int aregs
,
13558 int do_ra
, int do_s0
, int do_s1
,
13561 TCGv t0
= tcg_temp_new();
13562 TCGv t1
= tcg_temp_new();
13563 TCGv t2
= tcg_temp_new();
13593 gen_reserved_instruction(ctx
);
13599 gen_base_offset_addr(ctx
, t0
, 29, 12);
13600 gen_load_gpr(t1
, 7);
13601 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
13604 gen_base_offset_addr(ctx
, t0
, 29, 8);
13605 gen_load_gpr(t1
, 6);
13606 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
13609 gen_base_offset_addr(ctx
, t0
, 29, 4);
13610 gen_load_gpr(t1
, 5);
13611 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
13614 gen_base_offset_addr(ctx
, t0
, 29, 0);
13615 gen_load_gpr(t1
, 4);
13616 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
13619 gen_load_gpr(t0
, 29);
13621 #define DECR_AND_STORE(reg) do { \
13622 tcg_gen_movi_tl(t2, -4); \
13623 gen_op_addr_add(ctx, t0, t0, t2); \
13624 gen_load_gpr(t1, reg); \
13625 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \
13629 DECR_AND_STORE(31);
13634 DECR_AND_STORE(30);
13637 DECR_AND_STORE(23);
13640 DECR_AND_STORE(22);
13643 DECR_AND_STORE(21);
13646 DECR_AND_STORE(20);
13649 DECR_AND_STORE(19);
13652 DECR_AND_STORE(18);
13656 DECR_AND_STORE(17);
13659 DECR_AND_STORE(16);
13689 gen_reserved_instruction(ctx
);
13705 #undef DECR_AND_STORE
13707 tcg_gen_movi_tl(t2
, -framesize
);
13708 gen_op_addr_add(ctx
, cpu_gpr
[29], cpu_gpr
[29], t2
);
13714 static void gen_mips16_restore(DisasContext
*ctx
,
13715 int xsregs
, int aregs
,
13716 int do_ra
, int do_s0
, int do_s1
,
13720 TCGv t0
= tcg_temp_new();
13721 TCGv t1
= tcg_temp_new();
13722 TCGv t2
= tcg_temp_new();
13724 tcg_gen_movi_tl(t2
, framesize
);
13725 gen_op_addr_add(ctx
, t0
, cpu_gpr
[29], t2
);
13727 #define DECR_AND_LOAD(reg) do { \
13728 tcg_gen_movi_tl(t2, -4); \
13729 gen_op_addr_add(ctx, t0, t0, t2); \
13730 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \
13731 gen_store_gpr(t1, reg); \
13795 gen_reserved_instruction(ctx
);
13811 #undef DECR_AND_LOAD
13813 tcg_gen_movi_tl(t2
, framesize
);
13814 gen_op_addr_add(ctx
, cpu_gpr
[29], cpu_gpr
[29], t2
);
13820 static void gen_addiupc(DisasContext
*ctx
, int rx
, int imm
,
13821 int is_64_bit
, int extended
)
13825 if (extended
&& (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
13826 gen_reserved_instruction(ctx
);
13830 t0
= tcg_temp_new();
13832 tcg_gen_movi_tl(t0
, pc_relative_pc(ctx
));
13833 tcg_gen_addi_tl(cpu_gpr
[rx
], t0
, imm
);
13835 tcg_gen_ext32s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
13841 static void gen_cache_operation(DisasContext
*ctx
, uint32_t op
, int base
,
13844 TCGv_i32 t0
= tcg_const_i32(op
);
13845 TCGv t1
= tcg_temp_new();
13846 gen_base_offset_addr(ctx
, t1
, base
, offset
);
13847 gen_helper_cache(cpu_env
, t1
, t0
);
13850 #if defined(TARGET_MIPS64)
13851 static void decode_i64_mips16(DisasContext
*ctx
,
13852 int ry
, int funct
, int16_t offset
,
13857 check_insn(ctx
, ISA_MIPS3
);
13858 check_mips_64(ctx
);
13859 offset
= extended
? offset
: offset
<< 3;
13860 gen_ld(ctx
, OPC_LD
, ry
, 29, offset
);
13863 check_insn(ctx
, ISA_MIPS3
);
13864 check_mips_64(ctx
);
13865 offset
= extended
? offset
: offset
<< 3;
13866 gen_st(ctx
, OPC_SD
, ry
, 29, offset
);
13869 check_insn(ctx
, ISA_MIPS3
);
13870 check_mips_64(ctx
);
13871 offset
= extended
? offset
: (ctx
->opcode
& 0xff) << 3;
13872 gen_st(ctx
, OPC_SD
, 31, 29, offset
);
13875 check_insn(ctx
, ISA_MIPS3
);
13876 check_mips_64(ctx
);
13877 offset
= extended
? offset
: ((int8_t)ctx
->opcode
) << 3;
13878 gen_arith_imm(ctx
, OPC_DADDIU
, 29, 29, offset
);
13881 check_insn(ctx
, ISA_MIPS3
);
13882 check_mips_64(ctx
);
13883 if (extended
&& (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
13884 gen_reserved_instruction(ctx
);
13886 offset
= extended
? offset
: offset
<< 3;
13887 gen_ld(ctx
, OPC_LDPC
, ry
, 0, offset
);
13891 check_insn(ctx
, ISA_MIPS3
);
13892 check_mips_64(ctx
);
13893 offset
= extended
? offset
: ((int8_t)(offset
<< 3)) >> 3;
13894 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, ry
, offset
);
13897 check_insn(ctx
, ISA_MIPS3
);
13898 check_mips_64(ctx
);
13899 offset
= extended
? offset
: offset
<< 2;
13900 gen_addiupc(ctx
, ry
, offset
, 1, extended
);
13903 check_insn(ctx
, ISA_MIPS3
);
13904 check_mips_64(ctx
);
13905 offset
= extended
? offset
: offset
<< 2;
13906 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, 29, offset
);
13912 static int decode_extended_mips16_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
13914 int extend
= cpu_lduw_code(env
, ctx
->base
.pc_next
+ 2);
13915 int op
, rx
, ry
, funct
, sa
;
13916 int16_t imm
, offset
;
13918 ctx
->opcode
= (ctx
->opcode
<< 16) | extend
;
13919 op
= (ctx
->opcode
>> 11) & 0x1f;
13920 sa
= (ctx
->opcode
>> 22) & 0x1f;
13921 funct
= (ctx
->opcode
>> 8) & 0x7;
13922 rx
= xlat((ctx
->opcode
>> 8) & 0x7);
13923 ry
= xlat((ctx
->opcode
>> 5) & 0x7);
13924 offset
= imm
= (int16_t) (((ctx
->opcode
>> 16) & 0x1f) << 11
13925 | ((ctx
->opcode
>> 21) & 0x3f) << 5
13926 | (ctx
->opcode
& 0x1f));
13929 * The extended opcodes cleverly reuse the opcodes from their 16-bit
13933 case M16_OPC_ADDIUSP
:
13934 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 29, imm
);
13936 case M16_OPC_ADDIUPC
:
13937 gen_addiupc(ctx
, rx
, imm
, 0, 1);
13940 gen_compute_branch(ctx
, OPC_BEQ
, 4, 0, 0, offset
<< 1, 0);
13941 /* No delay slot, so just process as a normal instruction */
13944 gen_compute_branch(ctx
, OPC_BEQ
, 4, rx
, 0, offset
<< 1, 0);
13945 /* No delay slot, so just process as a normal instruction */
13947 case M16_OPC_BNEQZ
:
13948 gen_compute_branch(ctx
, OPC_BNE
, 4, rx
, 0, offset
<< 1, 0);
13949 /* No delay slot, so just process as a normal instruction */
13951 case M16_OPC_SHIFT
:
13952 switch (ctx
->opcode
& 0x3) {
13954 gen_shift_imm(ctx
, OPC_SLL
, rx
, ry
, sa
);
13957 #if defined(TARGET_MIPS64)
13958 check_mips_64(ctx
);
13959 gen_shift_imm(ctx
, OPC_DSLL
, rx
, ry
, sa
);
13961 gen_reserved_instruction(ctx
);
13965 gen_shift_imm(ctx
, OPC_SRL
, rx
, ry
, sa
);
13968 gen_shift_imm(ctx
, OPC_SRA
, rx
, ry
, sa
);
13972 #if defined(TARGET_MIPS64)
13974 check_insn(ctx
, ISA_MIPS3
);
13975 check_mips_64(ctx
);
13976 gen_ld(ctx
, OPC_LD
, ry
, rx
, offset
);
13980 imm
= ctx
->opcode
& 0xf;
13981 imm
= imm
| ((ctx
->opcode
>> 20) & 0x7f) << 4;
13982 imm
= imm
| ((ctx
->opcode
>> 16) & 0xf) << 11;
13983 imm
= (int16_t) (imm
<< 1) >> 1;
13984 if ((ctx
->opcode
>> 4) & 0x1) {
13985 #if defined(TARGET_MIPS64)
13986 check_mips_64(ctx
);
13987 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, rx
, imm
);
13989 gen_reserved_instruction(ctx
);
13992 gen_arith_imm(ctx
, OPC_ADDIU
, ry
, rx
, imm
);
13995 case M16_OPC_ADDIU8
:
13996 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, rx
, imm
);
13999 gen_slt_imm(ctx
, OPC_SLTI
, 24, rx
, imm
);
14001 case M16_OPC_SLTIU
:
14002 gen_slt_imm(ctx
, OPC_SLTIU
, 24, rx
, imm
);
14007 gen_compute_branch(ctx
, OPC_BEQ
, 4, 24, 0, offset
<< 1, 0);
14010 gen_compute_branch(ctx
, OPC_BNE
, 4, 24, 0, offset
<< 1, 0);
14013 gen_st(ctx
, OPC_SW
, 31, 29, imm
);
14016 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, imm
);
14019 check_insn(ctx
, ISA_MIPS_R1
);
14021 int xsregs
= (ctx
->opcode
>> 24) & 0x7;
14022 int aregs
= (ctx
->opcode
>> 16) & 0xf;
14023 int do_ra
= (ctx
->opcode
>> 6) & 0x1;
14024 int do_s0
= (ctx
->opcode
>> 5) & 0x1;
14025 int do_s1
= (ctx
->opcode
>> 4) & 0x1;
14026 int framesize
= (((ctx
->opcode
>> 20) & 0xf) << 4
14027 | (ctx
->opcode
& 0xf)) << 3;
14029 if (ctx
->opcode
& (1 << 7)) {
14030 gen_mips16_save(ctx
, xsregs
, aregs
,
14031 do_ra
, do_s0
, do_s1
,
14034 gen_mips16_restore(ctx
, xsregs
, aregs
,
14035 do_ra
, do_s0
, do_s1
,
14041 gen_reserved_instruction(ctx
);
14046 tcg_gen_movi_tl(cpu_gpr
[rx
], (uint16_t) imm
);
14049 tcg_gen_xori_tl(cpu_gpr
[24], cpu_gpr
[rx
], (uint16_t) imm
);
14051 #if defined(TARGET_MIPS64)
14053 check_insn(ctx
, ISA_MIPS3
);
14054 check_mips_64(ctx
);
14055 gen_st(ctx
, OPC_SD
, ry
, rx
, offset
);
14059 gen_ld(ctx
, OPC_LB
, ry
, rx
, offset
);
14062 gen_ld(ctx
, OPC_LH
, ry
, rx
, offset
);
14065 gen_ld(ctx
, OPC_LW
, rx
, 29, offset
);
14068 gen_ld(ctx
, OPC_LW
, ry
, rx
, offset
);
14071 gen_ld(ctx
, OPC_LBU
, ry
, rx
, offset
);
14074 gen_ld(ctx
, OPC_LHU
, ry
, rx
, offset
);
14077 gen_ld(ctx
, OPC_LWPC
, rx
, 0, offset
);
14079 #if defined(TARGET_MIPS64)
14081 check_insn(ctx
, ISA_MIPS3
);
14082 check_mips_64(ctx
);
14083 gen_ld(ctx
, OPC_LWU
, ry
, rx
, offset
);
14087 gen_st(ctx
, OPC_SB
, ry
, rx
, offset
);
14090 gen_st(ctx
, OPC_SH
, ry
, rx
, offset
);
14093 gen_st(ctx
, OPC_SW
, rx
, 29, offset
);
14096 gen_st(ctx
, OPC_SW
, ry
, rx
, offset
);
14098 #if defined(TARGET_MIPS64)
14100 decode_i64_mips16(ctx
, ry
, funct
, offset
, 1);
14104 gen_reserved_instruction(ctx
);
14111 static inline bool is_uhi(int sdbbp_code
)
14113 #ifdef CONFIG_USER_ONLY
14116 return semihosting_enabled() && sdbbp_code
== 1;
14120 #ifdef CONFIG_USER_ONLY
14121 /* The above should dead-code away any calls to this..*/
14122 static inline void gen_helper_do_semihosting(void *env
)
14124 g_assert_not_reached();
14128 static int decode_mips16_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
14132 int op
, cnvt_op
, op1
, offset
;
14136 op
= (ctx
->opcode
>> 11) & 0x1f;
14137 sa
= (ctx
->opcode
>> 2) & 0x7;
14138 sa
= sa
== 0 ? 8 : sa
;
14139 rx
= xlat((ctx
->opcode
>> 8) & 0x7);
14140 cnvt_op
= (ctx
->opcode
>> 5) & 0x7;
14141 ry
= xlat((ctx
->opcode
>> 5) & 0x7);
14142 op1
= offset
= ctx
->opcode
& 0x1f;
14147 case M16_OPC_ADDIUSP
:
14149 int16_t imm
= ((uint8_t) ctx
->opcode
) << 2;
14151 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 29, imm
);
14154 case M16_OPC_ADDIUPC
:
14155 gen_addiupc(ctx
, rx
, ((uint8_t) ctx
->opcode
) << 2, 0, 0);
14158 offset
= (ctx
->opcode
& 0x7ff) << 1;
14159 offset
= (int16_t)(offset
<< 4) >> 4;
14160 gen_compute_branch(ctx
, OPC_BEQ
, 2, 0, 0, offset
, 0);
14161 /* No delay slot, so just process as a normal instruction */
14164 offset
= cpu_lduw_code(env
, ctx
->base
.pc_next
+ 2);
14165 offset
= (((ctx
->opcode
& 0x1f) << 21)
14166 | ((ctx
->opcode
>> 5) & 0x1f) << 16
14168 op
= ((ctx
->opcode
>> 10) & 0x1) ? OPC_JALX
: OPC_JAL
;
14169 gen_compute_branch(ctx
, op
, 4, rx
, ry
, offset
, 2);
14173 gen_compute_branch(ctx
, OPC_BEQ
, 2, rx
, 0,
14174 ((int8_t)ctx
->opcode
) << 1, 0);
14175 /* No delay slot, so just process as a normal instruction */
14177 case M16_OPC_BNEQZ
:
14178 gen_compute_branch(ctx
, OPC_BNE
, 2, rx
, 0,
14179 ((int8_t)ctx
->opcode
) << 1, 0);
14180 /* No delay slot, so just process as a normal instruction */
14182 case M16_OPC_SHIFT
:
14183 switch (ctx
->opcode
& 0x3) {
14185 gen_shift_imm(ctx
, OPC_SLL
, rx
, ry
, sa
);
14188 #if defined(TARGET_MIPS64)
14189 check_insn(ctx
, ISA_MIPS3
);
14190 check_mips_64(ctx
);
14191 gen_shift_imm(ctx
, OPC_DSLL
, rx
, ry
, sa
);
14193 gen_reserved_instruction(ctx
);
14197 gen_shift_imm(ctx
, OPC_SRL
, rx
, ry
, sa
);
14200 gen_shift_imm(ctx
, OPC_SRA
, rx
, ry
, sa
);
14204 #if defined(TARGET_MIPS64)
14206 check_insn(ctx
, ISA_MIPS3
);
14207 check_mips_64(ctx
);
14208 gen_ld(ctx
, OPC_LD
, ry
, rx
, offset
<< 3);
14213 int16_t imm
= (int8_t)((ctx
->opcode
& 0xf) << 4) >> 4;
14215 if ((ctx
->opcode
>> 4) & 1) {
14216 #if defined(TARGET_MIPS64)
14217 check_insn(ctx
, ISA_MIPS3
);
14218 check_mips_64(ctx
);
14219 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, rx
, imm
);
14221 gen_reserved_instruction(ctx
);
14224 gen_arith_imm(ctx
, OPC_ADDIU
, ry
, rx
, imm
);
14228 case M16_OPC_ADDIU8
:
14230 int16_t imm
= (int8_t) ctx
->opcode
;
14232 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, rx
, imm
);
14237 int16_t imm
= (uint8_t) ctx
->opcode
;
14238 gen_slt_imm(ctx
, OPC_SLTI
, 24, rx
, imm
);
14241 case M16_OPC_SLTIU
:
14243 int16_t imm
= (uint8_t) ctx
->opcode
;
14244 gen_slt_imm(ctx
, OPC_SLTIU
, 24, rx
, imm
);
14251 funct
= (ctx
->opcode
>> 8) & 0x7;
14254 gen_compute_branch(ctx
, OPC_BEQ
, 2, 24, 0,
14255 ((int8_t)ctx
->opcode
) << 1, 0);
14258 gen_compute_branch(ctx
, OPC_BNE
, 2, 24, 0,
14259 ((int8_t)ctx
->opcode
) << 1, 0);
14262 gen_st(ctx
, OPC_SW
, 31, 29, (ctx
->opcode
& 0xff) << 2);
14265 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29,
14266 ((int8_t)ctx
->opcode
) << 3);
14269 check_insn(ctx
, ISA_MIPS_R1
);
14271 int do_ra
= ctx
->opcode
& (1 << 6);
14272 int do_s0
= ctx
->opcode
& (1 << 5);
14273 int do_s1
= ctx
->opcode
& (1 << 4);
14274 int framesize
= ctx
->opcode
& 0xf;
14276 if (framesize
== 0) {
14279 framesize
= framesize
<< 3;
14282 if (ctx
->opcode
& (1 << 7)) {
14283 gen_mips16_save(ctx
, 0, 0,
14284 do_ra
, do_s0
, do_s1
, framesize
);
14286 gen_mips16_restore(ctx
, 0, 0,
14287 do_ra
, do_s0
, do_s1
, framesize
);
14293 int rz
= xlat(ctx
->opcode
& 0x7);
14295 reg32
= (((ctx
->opcode
>> 3) & 0x3) << 3) |
14296 ((ctx
->opcode
>> 5) & 0x7);
14297 gen_arith(ctx
, OPC_ADDU
, reg32
, rz
, 0);
14301 reg32
= ctx
->opcode
& 0x1f;
14302 gen_arith(ctx
, OPC_ADDU
, ry
, reg32
, 0);
14305 gen_reserved_instruction(ctx
);
14312 int16_t imm
= (uint8_t) ctx
->opcode
;
14314 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 0, imm
);
14319 int16_t imm
= (uint8_t) ctx
->opcode
;
14320 gen_logic_imm(ctx
, OPC_XORI
, 24, rx
, imm
);
14323 #if defined(TARGET_MIPS64)
14325 check_insn(ctx
, ISA_MIPS3
);
14326 check_mips_64(ctx
);
14327 gen_st(ctx
, OPC_SD
, ry
, rx
, offset
<< 3);
14331 gen_ld(ctx
, OPC_LB
, ry
, rx
, offset
);
14334 gen_ld(ctx
, OPC_LH
, ry
, rx
, offset
<< 1);
14337 gen_ld(ctx
, OPC_LW
, rx
, 29, ((uint8_t)ctx
->opcode
) << 2);
14340 gen_ld(ctx
, OPC_LW
, ry
, rx
, offset
<< 2);
14343 gen_ld(ctx
, OPC_LBU
, ry
, rx
, offset
);
14346 gen_ld(ctx
, OPC_LHU
, ry
, rx
, offset
<< 1);
14349 gen_ld(ctx
, OPC_LWPC
, rx
, 0, ((uint8_t)ctx
->opcode
) << 2);
14351 #if defined(TARGET_MIPS64)
14353 check_insn(ctx
, ISA_MIPS3
);
14354 check_mips_64(ctx
);
14355 gen_ld(ctx
, OPC_LWU
, ry
, rx
, offset
<< 2);
14359 gen_st(ctx
, OPC_SB
, ry
, rx
, offset
);
14362 gen_st(ctx
, OPC_SH
, ry
, rx
, offset
<< 1);
14365 gen_st(ctx
, OPC_SW
, rx
, 29, ((uint8_t)ctx
->opcode
) << 2);
14368 gen_st(ctx
, OPC_SW
, ry
, rx
, offset
<< 2);
14372 int rz
= xlat((ctx
->opcode
>> 2) & 0x7);
14375 switch (ctx
->opcode
& 0x3) {
14377 mips32_op
= OPC_ADDU
;
14380 mips32_op
= OPC_SUBU
;
14382 #if defined(TARGET_MIPS64)
14384 mips32_op
= OPC_DADDU
;
14385 check_insn(ctx
, ISA_MIPS3
);
14386 check_mips_64(ctx
);
14389 mips32_op
= OPC_DSUBU
;
14390 check_insn(ctx
, ISA_MIPS3
);
14391 check_mips_64(ctx
);
14395 gen_reserved_instruction(ctx
);
14399 gen_arith(ctx
, mips32_op
, rz
, rx
, ry
);
14408 int nd
= (ctx
->opcode
>> 7) & 0x1;
14409 int link
= (ctx
->opcode
>> 6) & 0x1;
14410 int ra
= (ctx
->opcode
>> 5) & 0x1;
14413 check_insn(ctx
, ISA_MIPS_R1
);
14422 gen_compute_branch(ctx
, op
, 2, ra
? 31 : rx
, 31, 0,
14427 if (is_uhi(extract32(ctx
->opcode
, 5, 6))) {
14428 gen_helper_do_semihosting(cpu_env
);
14431 * XXX: not clear which exception should be raised
14432 * when in debug mode...
14434 check_insn(ctx
, ISA_MIPS_R1
);
14435 generate_exception_end(ctx
, EXCP_DBp
);
14439 gen_slt(ctx
, OPC_SLT
, 24, rx
, ry
);
14442 gen_slt(ctx
, OPC_SLTU
, 24, rx
, ry
);
14445 generate_exception_end(ctx
, EXCP_BREAK
);
14448 gen_shift(ctx
, OPC_SLLV
, ry
, rx
, ry
);
14451 gen_shift(ctx
, OPC_SRLV
, ry
, rx
, ry
);
14454 gen_shift(ctx
, OPC_SRAV
, ry
, rx
, ry
);
14456 #if defined(TARGET_MIPS64)
14458 check_insn(ctx
, ISA_MIPS3
);
14459 check_mips_64(ctx
);
14460 gen_shift_imm(ctx
, OPC_DSRL
, ry
, ry
, sa
);
14464 gen_logic(ctx
, OPC_XOR
, 24, rx
, ry
);
14467 gen_arith(ctx
, OPC_SUBU
, rx
, 0, ry
);
14470 gen_logic(ctx
, OPC_AND
, rx
, rx
, ry
);
14473 gen_logic(ctx
, OPC_OR
, rx
, rx
, ry
);
14476 gen_logic(ctx
, OPC_XOR
, rx
, rx
, ry
);
14479 gen_logic(ctx
, OPC_NOR
, rx
, ry
, 0);
14482 gen_HILO(ctx
, OPC_MFHI
, 0, rx
);
14485 check_insn(ctx
, ISA_MIPS_R1
);
14487 case RR_RY_CNVT_ZEB
:
14488 tcg_gen_ext8u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
14490 case RR_RY_CNVT_ZEH
:
14491 tcg_gen_ext16u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
14493 case RR_RY_CNVT_SEB
:
14494 tcg_gen_ext8s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
14496 case RR_RY_CNVT_SEH
:
14497 tcg_gen_ext16s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
14499 #if defined(TARGET_MIPS64)
14500 case RR_RY_CNVT_ZEW
:
14501 check_insn(ctx
, ISA_MIPS_R1
);
14502 check_mips_64(ctx
);
14503 tcg_gen_ext32u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
14505 case RR_RY_CNVT_SEW
:
14506 check_insn(ctx
, ISA_MIPS_R1
);
14507 check_mips_64(ctx
);
14508 tcg_gen_ext32s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
14512 gen_reserved_instruction(ctx
);
14517 gen_HILO(ctx
, OPC_MFLO
, 0, rx
);
14519 #if defined(TARGET_MIPS64)
14521 check_insn(ctx
, ISA_MIPS3
);
14522 check_mips_64(ctx
);
14523 gen_shift_imm(ctx
, OPC_DSRA
, ry
, ry
, sa
);
14526 check_insn(ctx
, ISA_MIPS3
);
14527 check_mips_64(ctx
);
14528 gen_shift(ctx
, OPC_DSLLV
, ry
, rx
, ry
);
14531 check_insn(ctx
, ISA_MIPS3
);
14532 check_mips_64(ctx
);
14533 gen_shift(ctx
, OPC_DSRLV
, ry
, rx
, ry
);
14536 check_insn(ctx
, ISA_MIPS3
);
14537 check_mips_64(ctx
);
14538 gen_shift(ctx
, OPC_DSRAV
, ry
, rx
, ry
);
14542 gen_muldiv(ctx
, OPC_MULT
, 0, rx
, ry
);
14545 gen_muldiv(ctx
, OPC_MULTU
, 0, rx
, ry
);
14548 gen_muldiv(ctx
, OPC_DIV
, 0, rx
, ry
);
14551 gen_muldiv(ctx
, OPC_DIVU
, 0, rx
, ry
);
14553 #if defined(TARGET_MIPS64)
14555 check_insn(ctx
, ISA_MIPS3
);
14556 check_mips_64(ctx
);
14557 gen_muldiv(ctx
, OPC_DMULT
, 0, rx
, ry
);
14560 check_insn(ctx
, ISA_MIPS3
);
14561 check_mips_64(ctx
);
14562 gen_muldiv(ctx
, OPC_DMULTU
, 0, rx
, ry
);
14565 check_insn(ctx
, ISA_MIPS3
);
14566 check_mips_64(ctx
);
14567 gen_muldiv(ctx
, OPC_DDIV
, 0, rx
, ry
);
14570 check_insn(ctx
, ISA_MIPS3
);
14571 check_mips_64(ctx
);
14572 gen_muldiv(ctx
, OPC_DDIVU
, 0, rx
, ry
);
14576 gen_reserved_instruction(ctx
);
14580 case M16_OPC_EXTEND
:
14581 decode_extended_mips16_opc(env
, ctx
);
14584 #if defined(TARGET_MIPS64)
14586 funct
= (ctx
->opcode
>> 8) & 0x7;
14587 decode_i64_mips16(ctx
, ry
, funct
, offset
, 0);
14591 gen_reserved_instruction(ctx
);
14598 /* microMIPS extension to MIPS32/MIPS64 */
14601 * microMIPS32/microMIPS64 major opcodes
14603 * 1. MIPS Architecture for Programmers Volume II-B:
14604 * The microMIPS32 Instruction Set (Revision 3.05)
14606 * Table 6.2 microMIPS32 Encoding of Major Opcode Field
14608 * 2. MIPS Architecture For Programmers Volume II-A:
14609 * The MIPS64 Instruction Set (Revision 3.51)
14639 POOL32S
= 0x16, /* MIPS64 */
14640 DADDIU32
= 0x17, /* MIPS64 */
14669 /* 0x29 is reserved */
14682 /* 0x31 is reserved */
14695 SD32
= 0x36, /* MIPS64 */
14696 LD32
= 0x37, /* MIPS64 */
14698 /* 0x39 is reserved */
14714 /* PCREL Instructions perform PC-Relative address calculation. bits 20..16 */
14736 /* POOL32A encoding of minor opcode field */
14740 * These opcodes are distinguished only by bits 9..6; those bits are
14741 * what are recorded below.
14779 /* The following can be distinguished by their lower 6 bits. */
14789 /* POOL32AXF encoding of minor opcode field extension */
14792 * 1. MIPS Architecture for Programmers Volume II-B:
14793 * The microMIPS32 Instruction Set (Revision 3.05)
14795 * Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
14797 * 2. MIPS Architecture for Programmers VolumeIV-e:
14798 * The MIPS DSP Application-Specific Extension
14799 * to the microMIPS32 Architecture (Revision 2.34)
14801 * Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
14816 /* begin of microMIPS32 DSP */
14818 /* bits 13..12 for 0x01 */
14824 /* bits 13..12 for 0x2a */
14830 /* bits 13..12 for 0x32 */
14834 /* end of microMIPS32 DSP */
14836 /* bits 15..12 for 0x2c */
14853 /* bits 15..12 for 0x34 */
14861 /* bits 15..12 for 0x3c */
14863 JR
= 0x0, /* alias */
14871 /* bits 15..12 for 0x05 */
14875 /* bits 15..12 for 0x0d */
14887 /* bits 15..12 for 0x15 */
14893 /* bits 15..12 for 0x1d */
14897 /* bits 15..12 for 0x2d */
14902 /* bits 15..12 for 0x35 */
14909 /* POOL32B encoding of minor opcode field (bits 15..12) */
14925 /* POOL32C encoding of minor opcode field (bits 15..12) */
14946 /* POOL32C LD-EVA encoding of minor opcode field (bits 11..9) */
14959 /* POOL32C ST-EVA encoding of minor opcode field (bits 11..9) */
14972 /* POOL32F encoding of minor opcode field (bits 5..0) */
14975 /* These are the bit 7..6 values */
14984 /* These are the bit 8..6 values */
15009 MOVZ_FMT_05
= 0x05,
15043 CABS_COND_FMT
= 0x1c, /* MIPS3D */
15050 /* POOL32Fxf encoding of minor opcode extension field */
15088 /* POOL32I encoding of minor opcode field (bits 25..21) */
15118 /* These overlap and are distinguished by bit16 of the instruction */
15127 /* POOL16A encoding of minor opcode field */
15134 /* POOL16B encoding of minor opcode field */
15141 /* POOL16C encoding of minor opcode field */
15161 /* R6 POOL16C encoding of minor opcode field (bits 0..5) */
15185 /* POOL16D encoding of minor opcode field */
15192 /* POOL16E encoding of minor opcode field */
15199 static int mmreg(int r
)
15201 static const int map
[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
15206 /* Used for 16-bit store instructions. */
15207 static int mmreg2(int r
)
15209 static const int map
[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
15214 #define uMIPS_RD(op) ((op >> 7) & 0x7)
15215 #define uMIPS_RS(op) ((op >> 4) & 0x7)
15216 #define uMIPS_RS2(op) uMIPS_RS(op)
15217 #define uMIPS_RS1(op) ((op >> 1) & 0x7)
15218 #define uMIPS_RD5(op) ((op >> 5) & 0x1f)
15219 #define uMIPS_RS5(op) (op & 0x1f)
15221 /* Signed immediate */
15222 #define SIMM(op, start, width) \
15223 ((int32_t)(((op >> start) & ((~0U) >> (32 - width))) \
15226 /* Zero-extended immediate */
15227 #define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32 - width)))
15229 static void gen_addiur1sp(DisasContext
*ctx
)
15231 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
15233 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, 29, ((ctx
->opcode
>> 1) & 0x3f) << 2);
15236 static void gen_addiur2(DisasContext
*ctx
)
15238 static const int decoded_imm
[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
15239 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
15240 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
15242 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, rs
, decoded_imm
[ZIMM(ctx
->opcode
, 1, 3)]);
15245 static void gen_addiusp(DisasContext
*ctx
)
15247 int encoded
= ZIMM(ctx
->opcode
, 1, 9);
15250 if (encoded
<= 1) {
15251 decoded
= 256 + encoded
;
15252 } else if (encoded
<= 255) {
15254 } else if (encoded
<= 509) {
15255 decoded
= encoded
- 512;
15257 decoded
= encoded
- 768;
15260 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, decoded
<< 2);
15263 static void gen_addius5(DisasContext
*ctx
)
15265 int imm
= SIMM(ctx
->opcode
, 1, 4);
15266 int rd
= (ctx
->opcode
>> 5) & 0x1f;
15268 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, rd
, imm
);
15271 static void gen_andi16(DisasContext
*ctx
)
15273 static const int decoded_imm
[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
15274 31, 32, 63, 64, 255, 32768, 65535 };
15275 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
15276 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
15277 int encoded
= ZIMM(ctx
->opcode
, 0, 4);
15279 gen_logic_imm(ctx
, OPC_ANDI
, rd
, rs
, decoded_imm
[encoded
]);
15282 static void gen_ldst_multiple(DisasContext
*ctx
, uint32_t opc
, int reglist
,
15283 int base
, int16_t offset
)
15288 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
15289 gen_reserved_instruction(ctx
);
15293 t0
= tcg_temp_new();
15295 gen_base_offset_addr(ctx
, t0
, base
, offset
);
15297 t1
= tcg_const_tl(reglist
);
15298 t2
= tcg_const_i32(ctx
->mem_idx
);
15300 save_cpu_state(ctx
, 1);
15303 gen_helper_lwm(cpu_env
, t0
, t1
, t2
);
15306 gen_helper_swm(cpu_env
, t0
, t1
, t2
);
15308 #ifdef TARGET_MIPS64
15310 gen_helper_ldm(cpu_env
, t0
, t1
, t2
);
15313 gen_helper_sdm(cpu_env
, t0
, t1
, t2
);
15319 tcg_temp_free_i32(t2
);
15323 static void gen_pool16c_insn(DisasContext
*ctx
)
15325 int rd
= mmreg((ctx
->opcode
>> 3) & 0x7);
15326 int rs
= mmreg(ctx
->opcode
& 0x7);
15328 switch (((ctx
->opcode
) >> 4) & 0x3f) {
15333 gen_logic(ctx
, OPC_NOR
, rd
, rs
, 0);
15339 gen_logic(ctx
, OPC_XOR
, rd
, rd
, rs
);
15345 gen_logic(ctx
, OPC_AND
, rd
, rd
, rs
);
15351 gen_logic(ctx
, OPC_OR
, rd
, rd
, rs
);
15358 static const int lwm_convert
[] = { 0x11, 0x12, 0x13, 0x14 };
15359 int offset
= ZIMM(ctx
->opcode
, 0, 4);
15361 gen_ldst_multiple(ctx
, LWM32
, lwm_convert
[(ctx
->opcode
>> 4) & 0x3],
15370 static const int swm_convert
[] = { 0x11, 0x12, 0x13, 0x14 };
15371 int offset
= ZIMM(ctx
->opcode
, 0, 4);
15373 gen_ldst_multiple(ctx
, SWM32
, swm_convert
[(ctx
->opcode
>> 4) & 0x3],
15380 int reg
= ctx
->opcode
& 0x1f;
15382 gen_compute_branch(ctx
, OPC_JR
, 2, reg
, 0, 0, 4);
15388 int reg
= ctx
->opcode
& 0x1f;
15389 gen_compute_branch(ctx
, OPC_JR
, 2, reg
, 0, 0, 0);
15391 * Let normal delay slot handling in our caller take us
15392 * to the branch target.
15398 gen_compute_branch(ctx
, OPC_JALR
, 2, ctx
->opcode
& 0x1f, 31, 0, 4);
15399 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
15403 gen_compute_branch(ctx
, OPC_JALR
, 2, ctx
->opcode
& 0x1f, 31, 0, 2);
15404 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
15408 gen_HILO(ctx
, OPC_MFHI
, 0, uMIPS_RS5(ctx
->opcode
));
15412 gen_HILO(ctx
, OPC_MFLO
, 0, uMIPS_RS5(ctx
->opcode
));
15415 generate_exception_end(ctx
, EXCP_BREAK
);
15418 if (is_uhi(extract32(ctx
->opcode
, 0, 4))) {
15419 gen_helper_do_semihosting(cpu_env
);
15422 * XXX: not clear which exception should be raised
15423 * when in debug mode...
15425 check_insn(ctx
, ISA_MIPS_R1
);
15426 generate_exception_end(ctx
, EXCP_DBp
);
15429 case JRADDIUSP
+ 0:
15430 case JRADDIUSP
+ 1:
15432 int imm
= ZIMM(ctx
->opcode
, 0, 5);
15433 gen_compute_branch(ctx
, OPC_JR
, 2, 31, 0, 0, 0);
15434 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, imm
<< 2);
15436 * Let normal delay slot handling in our caller take us
15437 * to the branch target.
15442 gen_reserved_instruction(ctx
);
15447 static inline void gen_movep(DisasContext
*ctx
, int enc_dest
, int enc_rt
,
15450 int rd
, rs
, re
, rt
;
15451 static const int rd_enc
[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
15452 static const int re_enc
[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
15453 static const int rs_rt_enc
[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
15454 rd
= rd_enc
[enc_dest
];
15455 re
= re_enc
[enc_dest
];
15456 rs
= rs_rt_enc
[enc_rs
];
15457 rt
= rs_rt_enc
[enc_rt
];
15459 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
15461 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
15464 tcg_gen_mov_tl(cpu_gpr
[re
], cpu_gpr
[rt
]);
15466 tcg_gen_movi_tl(cpu_gpr
[re
], 0);
15470 static void gen_pool16c_r6_insn(DisasContext
*ctx
)
15472 int rt
= mmreg((ctx
->opcode
>> 7) & 0x7);
15473 int rs
= mmreg((ctx
->opcode
>> 4) & 0x7);
15475 switch (ctx
->opcode
& 0xf) {
15477 gen_logic(ctx
, OPC_NOR
, rt
, rs
, 0);
15480 gen_logic(ctx
, OPC_AND
, rt
, rt
, rs
);
15484 int lwm_converted
= 0x11 + extract32(ctx
->opcode
, 8, 2);
15485 int offset
= extract32(ctx
->opcode
, 4, 4);
15486 gen_ldst_multiple(ctx
, LWM32
, lwm_converted
, 29, offset
<< 2);
15489 case R6_JRC16
: /* JRCADDIUSP */
15490 if ((ctx
->opcode
>> 4) & 1) {
15492 int imm
= extract32(ctx
->opcode
, 5, 5);
15493 gen_compute_branch(ctx
, OPC_JR
, 2, 31, 0, 0, 0);
15494 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, imm
<< 2);
15497 rs
= extract32(ctx
->opcode
, 5, 5);
15498 gen_compute_branch(ctx
, OPC_JR
, 2, rs
, 0, 0, 0);
15510 int enc_dest
= uMIPS_RD(ctx
->opcode
);
15511 int enc_rt
= uMIPS_RS2(ctx
->opcode
);
15512 int enc_rs
= (ctx
->opcode
& 3) | ((ctx
->opcode
>> 1) & 4);
15513 gen_movep(ctx
, enc_dest
, enc_rt
, enc_rs
);
15517 gen_logic(ctx
, OPC_XOR
, rt
, rt
, rs
);
15520 gen_logic(ctx
, OPC_OR
, rt
, rt
, rs
);
15524 int swm_converted
= 0x11 + extract32(ctx
->opcode
, 8, 2);
15525 int offset
= extract32(ctx
->opcode
, 4, 4);
15526 gen_ldst_multiple(ctx
, SWM32
, swm_converted
, 29, offset
<< 2);
15529 case JALRC16
: /* BREAK16, SDBBP16 */
15530 switch (ctx
->opcode
& 0x3f) {
15532 case JALRC16
+ 0x20:
15534 gen_compute_branch(ctx
, OPC_JALR
, 2, (ctx
->opcode
>> 5) & 0x1f,
15539 generate_exception(ctx
, EXCP_BREAK
);
15543 if (is_uhi(extract32(ctx
->opcode
, 6, 4))) {
15544 gen_helper_do_semihosting(cpu_env
);
15546 if (ctx
->hflags
& MIPS_HFLAG_SBRI
) {
15547 generate_exception(ctx
, EXCP_RI
);
15549 generate_exception(ctx
, EXCP_DBp
);
15556 generate_exception(ctx
, EXCP_RI
);
15561 static void gen_ldxs(DisasContext
*ctx
, int base
, int index
, int rd
)
15563 TCGv t0
= tcg_temp_new();
15564 TCGv t1
= tcg_temp_new();
15566 gen_load_gpr(t0
, base
);
15569 gen_load_gpr(t1
, index
);
15570 tcg_gen_shli_tl(t1
, t1
, 2);
15571 gen_op_addr_add(ctx
, t0
, t1
, t0
);
15574 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TESL
);
15575 gen_store_gpr(t1
, rd
);
15581 static void gen_ldst_pair(DisasContext
*ctx
, uint32_t opc
, int rd
,
15582 int base
, int16_t offset
)
15586 if (ctx
->hflags
& MIPS_HFLAG_BMASK
|| rd
== 31) {
15587 gen_reserved_instruction(ctx
);
15591 t0
= tcg_temp_new();
15592 t1
= tcg_temp_new();
15594 gen_base_offset_addr(ctx
, t0
, base
, offset
);
15599 gen_reserved_instruction(ctx
);
15602 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TESL
);
15603 gen_store_gpr(t1
, rd
);
15604 tcg_gen_movi_tl(t1
, 4);
15605 gen_op_addr_add(ctx
, t0
, t0
, t1
);
15606 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TESL
);
15607 gen_store_gpr(t1
, rd
+ 1);
15610 gen_load_gpr(t1
, rd
);
15611 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
15612 tcg_gen_movi_tl(t1
, 4);
15613 gen_op_addr_add(ctx
, t0
, t0
, t1
);
15614 gen_load_gpr(t1
, rd
+ 1);
15615 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
15617 #ifdef TARGET_MIPS64
15620 gen_reserved_instruction(ctx
);
15623 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
15624 gen_store_gpr(t1
, rd
);
15625 tcg_gen_movi_tl(t1
, 8);
15626 gen_op_addr_add(ctx
, t0
, t0
, t1
);
15627 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
15628 gen_store_gpr(t1
, rd
+ 1);
15631 gen_load_gpr(t1
, rd
);
15632 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
15633 tcg_gen_movi_tl(t1
, 8);
15634 gen_op_addr_add(ctx
, t0
, t0
, t1
);
15635 gen_load_gpr(t1
, rd
+ 1);
15636 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
15644 static void gen_sync(int stype
)
15646 TCGBar tcg_mo
= TCG_BAR_SC
;
15649 case 0x4: /* SYNC_WMB */
15650 tcg_mo
|= TCG_MO_ST_ST
;
15652 case 0x10: /* SYNC_MB */
15653 tcg_mo
|= TCG_MO_ALL
;
15655 case 0x11: /* SYNC_ACQUIRE */
15656 tcg_mo
|= TCG_MO_LD_LD
| TCG_MO_LD_ST
;
15658 case 0x12: /* SYNC_RELEASE */
15659 tcg_mo
|= TCG_MO_ST_ST
| TCG_MO_LD_ST
;
15661 case 0x13: /* SYNC_RMB */
15662 tcg_mo
|= TCG_MO_LD_LD
;
15665 tcg_mo
|= TCG_MO_ALL
;
15669 tcg_gen_mb(tcg_mo
);
15672 static void gen_pool32axf(CPUMIPSState
*env
, DisasContext
*ctx
, int rt
, int rs
)
15674 int extension
= (ctx
->opcode
>> 6) & 0x3f;
15675 int minor
= (ctx
->opcode
>> 12) & 0xf;
15676 uint32_t mips32_op
;
15678 switch (extension
) {
15680 mips32_op
= OPC_TEQ
;
15683 mips32_op
= OPC_TGE
;
15686 mips32_op
= OPC_TGEU
;
15689 mips32_op
= OPC_TLT
;
15692 mips32_op
= OPC_TLTU
;
15695 mips32_op
= OPC_TNE
;
15697 gen_trap(ctx
, mips32_op
, rs
, rt
, -1);
15699 #ifndef CONFIG_USER_ONLY
15702 check_cp0_enabled(ctx
);
15704 /* Treat as NOP. */
15707 gen_mfc0(ctx
, cpu_gpr
[rt
], rs
, (ctx
->opcode
>> 11) & 0x7);
15711 check_cp0_enabled(ctx
);
15713 TCGv t0
= tcg_temp_new();
15715 gen_load_gpr(t0
, rt
);
15716 gen_mtc0(ctx
, t0
, rs
, (ctx
->opcode
>> 11) & 0x7);
15722 switch (minor
& 3) {
15724 gen_muldiv(ctx
, OPC_MADD
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
15727 gen_muldiv(ctx
, OPC_MADDU
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
15730 gen_muldiv(ctx
, OPC_MSUB
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
15733 gen_muldiv(ctx
, OPC_MSUBU
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
15736 goto pool32axf_invalid
;
15740 switch (minor
& 3) {
15742 gen_muldiv(ctx
, OPC_MULT
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
15745 gen_muldiv(ctx
, OPC_MULTU
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
15748 goto pool32axf_invalid
;
15754 check_insn(ctx
, ISA_MIPS_R6
);
15755 gen_bitswap(ctx
, OPC_BITSWAP
, rs
, rt
);
15758 gen_bshfl(ctx
, OPC_SEB
, rs
, rt
);
15761 gen_bshfl(ctx
, OPC_SEH
, rs
, rt
);
15764 mips32_op
= OPC_CLO
;
15767 mips32_op
= OPC_CLZ
;
15769 check_insn(ctx
, ISA_MIPS_R1
);
15770 gen_cl(ctx
, mips32_op
, rt
, rs
);
15773 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15774 gen_rdhwr(ctx
, rt
, rs
, 0);
15777 gen_bshfl(ctx
, OPC_WSBH
, rs
, rt
);
15780 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15781 mips32_op
= OPC_MULT
;
15784 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15785 mips32_op
= OPC_MULTU
;
15788 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15789 mips32_op
= OPC_DIV
;
15792 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15793 mips32_op
= OPC_DIVU
;
15796 check_insn(ctx
, ISA_MIPS_R1
);
15797 gen_muldiv(ctx
, mips32_op
, 0, rs
, rt
);
15800 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15801 mips32_op
= OPC_MADD
;
15804 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15805 mips32_op
= OPC_MADDU
;
15808 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15809 mips32_op
= OPC_MSUB
;
15812 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15813 mips32_op
= OPC_MSUBU
;
15815 check_insn(ctx
, ISA_MIPS_R1
);
15816 gen_muldiv(ctx
, mips32_op
, 0, rs
, rt
);
15819 goto pool32axf_invalid
;
15830 generate_exception_err(ctx
, EXCP_CpU
, 2);
15833 goto pool32axf_invalid
;
15838 case JALR
: /* JALRC */
15839 case JALR_HB
: /* JALRC_HB */
15840 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
15841 /* JALRC, JALRC_HB */
15842 gen_compute_branch(ctx
, OPC_JALR
, 4, rs
, rt
, 0, 0);
15844 /* JALR, JALR_HB */
15845 gen_compute_branch(ctx
, OPC_JALR
, 4, rs
, rt
, 0, 4);
15846 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
15851 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15852 gen_compute_branch(ctx
, OPC_JALR
, 4, rs
, rt
, 0, 2);
15853 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
15856 goto pool32axf_invalid
;
15862 check_cp0_enabled(ctx
);
15863 check_insn(ctx
, ISA_MIPS_R2
);
15864 gen_load_srsgpr(rs
, rt
);
15867 check_cp0_enabled(ctx
);
15868 check_insn(ctx
, ISA_MIPS_R2
);
15869 gen_store_srsgpr(rs
, rt
);
15872 goto pool32axf_invalid
;
15875 #ifndef CONFIG_USER_ONLY
15879 mips32_op
= OPC_TLBP
;
15882 mips32_op
= OPC_TLBR
;
15885 mips32_op
= OPC_TLBWI
;
15888 mips32_op
= OPC_TLBWR
;
15891 mips32_op
= OPC_TLBINV
;
15894 mips32_op
= OPC_TLBINVF
;
15897 mips32_op
= OPC_WAIT
;
15900 mips32_op
= OPC_DERET
;
15903 mips32_op
= OPC_ERET
;
15905 gen_cp0(env
, ctx
, mips32_op
, rt
, rs
);
15908 goto pool32axf_invalid
;
15914 check_cp0_enabled(ctx
);
15916 TCGv t0
= tcg_temp_new();
15918 save_cpu_state(ctx
, 1);
15919 gen_helper_di(t0
, cpu_env
);
15920 gen_store_gpr(t0
, rs
);
15922 * Stop translation as we may have switched the execution
15925 ctx
->base
.is_jmp
= DISAS_STOP
;
15930 check_cp0_enabled(ctx
);
15932 TCGv t0
= tcg_temp_new();
15934 save_cpu_state(ctx
, 1);
15935 gen_helper_ei(t0
, cpu_env
);
15936 gen_store_gpr(t0
, rs
);
15938 * DISAS_STOP isn't sufficient, we need to ensure we break out
15939 * of translated code to check for pending interrupts.
15941 gen_save_pc(ctx
->base
.pc_next
+ 4);
15942 ctx
->base
.is_jmp
= DISAS_EXIT
;
15947 goto pool32axf_invalid
;
15954 gen_sync(extract32(ctx
->opcode
, 16, 5));
15957 generate_exception_end(ctx
, EXCP_SYSCALL
);
15960 if (is_uhi(extract32(ctx
->opcode
, 16, 10))) {
15961 gen_helper_do_semihosting(cpu_env
);
15963 check_insn(ctx
, ISA_MIPS_R1
);
15964 if (ctx
->hflags
& MIPS_HFLAG_SBRI
) {
15965 gen_reserved_instruction(ctx
);
15967 generate_exception_end(ctx
, EXCP_DBp
);
15972 goto pool32axf_invalid
;
15976 switch (minor
& 3) {
15978 gen_HILO(ctx
, OPC_MFHI
, minor
>> 2, rs
);
15981 gen_HILO(ctx
, OPC_MFLO
, minor
>> 2, rs
);
15984 gen_HILO(ctx
, OPC_MTHI
, minor
>> 2, rs
);
15987 gen_HILO(ctx
, OPC_MTLO
, minor
>> 2, rs
);
15990 goto pool32axf_invalid
;
15994 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15997 gen_HILO(ctx
, OPC_MFHI
, 0, rs
);
16000 gen_HILO(ctx
, OPC_MFLO
, 0, rs
);
16003 gen_HILO(ctx
, OPC_MTHI
, 0, rs
);
16006 gen_HILO(ctx
, OPC_MTLO
, 0, rs
);
16009 goto pool32axf_invalid
;
16014 MIPS_INVAL("pool32axf");
16015 gen_reserved_instruction(ctx
);
16021 * Values for microMIPS fmt field. Variable-width, depending on which
16022 * formats the instruction supports.
16041 static void gen_pool32fxf(DisasContext
*ctx
, int rt
, int rs
)
16043 int extension
= (ctx
->opcode
>> 6) & 0x3ff;
16044 uint32_t mips32_op
;
16046 #define FLOAT_1BIT_FMT(opc, fmt) ((fmt << 8) | opc)
16047 #define FLOAT_2BIT_FMT(opc, fmt) ((fmt << 7) | opc)
16048 #define COND_FLOAT_MOV(opc, cond) ((cond << 7) | opc)
16050 switch (extension
) {
16051 case FLOAT_1BIT_FMT(CFC1
, 0):
16052 mips32_op
= OPC_CFC1
;
16054 case FLOAT_1BIT_FMT(CTC1
, 0):
16055 mips32_op
= OPC_CTC1
;
16057 case FLOAT_1BIT_FMT(MFC1
, 0):
16058 mips32_op
= OPC_MFC1
;
16060 case FLOAT_1BIT_FMT(MTC1
, 0):
16061 mips32_op
= OPC_MTC1
;
16063 case FLOAT_1BIT_FMT(MFHC1
, 0):
16064 mips32_op
= OPC_MFHC1
;
16066 case FLOAT_1BIT_FMT(MTHC1
, 0):
16067 mips32_op
= OPC_MTHC1
;
16069 gen_cp1(ctx
, mips32_op
, rt
, rs
);
16072 /* Reciprocal square root */
16073 case FLOAT_1BIT_FMT(RSQRT_FMT
, FMT_SD_S
):
16074 mips32_op
= OPC_RSQRT_S
;
16076 case FLOAT_1BIT_FMT(RSQRT_FMT
, FMT_SD_D
):
16077 mips32_op
= OPC_RSQRT_D
;
16081 case FLOAT_1BIT_FMT(SQRT_FMT
, FMT_SD_S
):
16082 mips32_op
= OPC_SQRT_S
;
16084 case FLOAT_1BIT_FMT(SQRT_FMT
, FMT_SD_D
):
16085 mips32_op
= OPC_SQRT_D
;
16089 case FLOAT_1BIT_FMT(RECIP_FMT
, FMT_SD_S
):
16090 mips32_op
= OPC_RECIP_S
;
16092 case FLOAT_1BIT_FMT(RECIP_FMT
, FMT_SD_D
):
16093 mips32_op
= OPC_RECIP_D
;
16097 case FLOAT_1BIT_FMT(FLOOR_L
, FMT_SD_S
):
16098 mips32_op
= OPC_FLOOR_L_S
;
16100 case FLOAT_1BIT_FMT(FLOOR_L
, FMT_SD_D
):
16101 mips32_op
= OPC_FLOOR_L_D
;
16103 case FLOAT_1BIT_FMT(FLOOR_W
, FMT_SD_S
):
16104 mips32_op
= OPC_FLOOR_W_S
;
16106 case FLOAT_1BIT_FMT(FLOOR_W
, FMT_SD_D
):
16107 mips32_op
= OPC_FLOOR_W_D
;
16111 case FLOAT_1BIT_FMT(CEIL_L
, FMT_SD_S
):
16112 mips32_op
= OPC_CEIL_L_S
;
16114 case FLOAT_1BIT_FMT(CEIL_L
, FMT_SD_D
):
16115 mips32_op
= OPC_CEIL_L_D
;
16117 case FLOAT_1BIT_FMT(CEIL_W
, FMT_SD_S
):
16118 mips32_op
= OPC_CEIL_W_S
;
16120 case FLOAT_1BIT_FMT(CEIL_W
, FMT_SD_D
):
16121 mips32_op
= OPC_CEIL_W_D
;
16125 case FLOAT_1BIT_FMT(TRUNC_L
, FMT_SD_S
):
16126 mips32_op
= OPC_TRUNC_L_S
;
16128 case FLOAT_1BIT_FMT(TRUNC_L
, FMT_SD_D
):
16129 mips32_op
= OPC_TRUNC_L_D
;
16131 case FLOAT_1BIT_FMT(TRUNC_W
, FMT_SD_S
):
16132 mips32_op
= OPC_TRUNC_W_S
;
16134 case FLOAT_1BIT_FMT(TRUNC_W
, FMT_SD_D
):
16135 mips32_op
= OPC_TRUNC_W_D
;
16139 case FLOAT_1BIT_FMT(ROUND_L
, FMT_SD_S
):
16140 mips32_op
= OPC_ROUND_L_S
;
16142 case FLOAT_1BIT_FMT(ROUND_L
, FMT_SD_D
):
16143 mips32_op
= OPC_ROUND_L_D
;
16145 case FLOAT_1BIT_FMT(ROUND_W
, FMT_SD_S
):
16146 mips32_op
= OPC_ROUND_W_S
;
16148 case FLOAT_1BIT_FMT(ROUND_W
, FMT_SD_D
):
16149 mips32_op
= OPC_ROUND_W_D
;
16152 /* Integer to floating-point conversion */
16153 case FLOAT_1BIT_FMT(CVT_L
, FMT_SD_S
):
16154 mips32_op
= OPC_CVT_L_S
;
16156 case FLOAT_1BIT_FMT(CVT_L
, FMT_SD_D
):
16157 mips32_op
= OPC_CVT_L_D
;
16159 case FLOAT_1BIT_FMT(CVT_W
, FMT_SD_S
):
16160 mips32_op
= OPC_CVT_W_S
;
16162 case FLOAT_1BIT_FMT(CVT_W
, FMT_SD_D
):
16163 mips32_op
= OPC_CVT_W_D
;
16166 /* Paired-foo conversions */
16167 case FLOAT_1BIT_FMT(CVT_S_PL
, 0):
16168 mips32_op
= OPC_CVT_S_PL
;
16170 case FLOAT_1BIT_FMT(CVT_S_PU
, 0):
16171 mips32_op
= OPC_CVT_S_PU
;
16173 case FLOAT_1BIT_FMT(CVT_PW_PS
, 0):
16174 mips32_op
= OPC_CVT_PW_PS
;
16176 case FLOAT_1BIT_FMT(CVT_PS_PW
, 0):
16177 mips32_op
= OPC_CVT_PS_PW
;
16180 /* Floating-point moves */
16181 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_S
):
16182 mips32_op
= OPC_MOV_S
;
16184 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_D
):
16185 mips32_op
= OPC_MOV_D
;
16187 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_PS
):
16188 mips32_op
= OPC_MOV_PS
;
16191 /* Absolute value */
16192 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_S
):
16193 mips32_op
= OPC_ABS_S
;
16195 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_D
):
16196 mips32_op
= OPC_ABS_D
;
16198 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_PS
):
16199 mips32_op
= OPC_ABS_PS
;
16203 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_S
):
16204 mips32_op
= OPC_NEG_S
;
16206 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_D
):
16207 mips32_op
= OPC_NEG_D
;
16209 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_PS
):
16210 mips32_op
= OPC_NEG_PS
;
16213 /* Reciprocal square root step */
16214 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_S
):
16215 mips32_op
= OPC_RSQRT1_S
;
16217 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_D
):
16218 mips32_op
= OPC_RSQRT1_D
;
16220 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_PS
):
16221 mips32_op
= OPC_RSQRT1_PS
;
16224 /* Reciprocal step */
16225 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_S
):
16226 mips32_op
= OPC_RECIP1_S
;
16228 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_D
):
16229 mips32_op
= OPC_RECIP1_S
;
16231 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_PS
):
16232 mips32_op
= OPC_RECIP1_PS
;
16235 /* Conversions from double */
16236 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_S
):
16237 mips32_op
= OPC_CVT_D_S
;
16239 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_W
):
16240 mips32_op
= OPC_CVT_D_W
;
16242 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_L
):
16243 mips32_op
= OPC_CVT_D_L
;
16246 /* Conversions from single */
16247 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_D
):
16248 mips32_op
= OPC_CVT_S_D
;
16250 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_W
):
16251 mips32_op
= OPC_CVT_S_W
;
16253 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_L
):
16254 mips32_op
= OPC_CVT_S_L
;
16256 gen_farith(ctx
, mips32_op
, -1, rs
, rt
, 0);
16259 /* Conditional moves on floating-point codes */
16260 case COND_FLOAT_MOV(MOVT
, 0):
16261 case COND_FLOAT_MOV(MOVT
, 1):
16262 case COND_FLOAT_MOV(MOVT
, 2):
16263 case COND_FLOAT_MOV(MOVT
, 3):
16264 case COND_FLOAT_MOV(MOVT
, 4):
16265 case COND_FLOAT_MOV(MOVT
, 5):
16266 case COND_FLOAT_MOV(MOVT
, 6):
16267 case COND_FLOAT_MOV(MOVT
, 7):
16268 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16269 gen_movci(ctx
, rt
, rs
, (ctx
->opcode
>> 13) & 0x7, 1);
16271 case COND_FLOAT_MOV(MOVF
, 0):
16272 case COND_FLOAT_MOV(MOVF
, 1):
16273 case COND_FLOAT_MOV(MOVF
, 2):
16274 case COND_FLOAT_MOV(MOVF
, 3):
16275 case COND_FLOAT_MOV(MOVF
, 4):
16276 case COND_FLOAT_MOV(MOVF
, 5):
16277 case COND_FLOAT_MOV(MOVF
, 6):
16278 case COND_FLOAT_MOV(MOVF
, 7):
16279 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16280 gen_movci(ctx
, rt
, rs
, (ctx
->opcode
>> 13) & 0x7, 0);
16283 MIPS_INVAL("pool32fxf");
16284 gen_reserved_instruction(ctx
);
16289 static void decode_micromips32_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
16293 int rt
, rs
, rd
, rr
;
16295 uint32_t op
, minor
, minor2
, mips32_op
;
16296 uint32_t cond
, fmt
, cc
;
16298 insn
= cpu_lduw_code(env
, ctx
->base
.pc_next
+ 2);
16299 ctx
->opcode
= (ctx
->opcode
<< 16) | insn
;
16301 rt
= (ctx
->opcode
>> 21) & 0x1f;
16302 rs
= (ctx
->opcode
>> 16) & 0x1f;
16303 rd
= (ctx
->opcode
>> 11) & 0x1f;
16304 rr
= (ctx
->opcode
>> 6) & 0x1f;
16305 imm
= (int16_t) ctx
->opcode
;
16307 op
= (ctx
->opcode
>> 26) & 0x3f;
16310 minor
= ctx
->opcode
& 0x3f;
16313 minor
= (ctx
->opcode
>> 6) & 0xf;
16316 mips32_op
= OPC_SLL
;
16319 mips32_op
= OPC_SRA
;
16322 mips32_op
= OPC_SRL
;
16325 mips32_op
= OPC_ROTR
;
16327 gen_shift_imm(ctx
, mips32_op
, rt
, rs
, rd
);
16330 check_insn(ctx
, ISA_MIPS_R6
);
16331 gen_cond_move(ctx
, OPC_SELEQZ
, rd
, rs
, rt
);
16334 check_insn(ctx
, ISA_MIPS_R6
);
16335 gen_cond_move(ctx
, OPC_SELNEZ
, rd
, rs
, rt
);
16338 check_insn(ctx
, ISA_MIPS_R6
);
16339 gen_rdhwr(ctx
, rt
, rs
, extract32(ctx
->opcode
, 11, 3));
16342 goto pool32a_invalid
;
16346 minor
= (ctx
->opcode
>> 6) & 0xf;
16350 mips32_op
= OPC_ADD
;
16353 mips32_op
= OPC_ADDU
;
16356 mips32_op
= OPC_SUB
;
16359 mips32_op
= OPC_SUBU
;
16362 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16363 mips32_op
= OPC_MUL
;
16365 gen_arith(ctx
, mips32_op
, rd
, rs
, rt
);
16369 mips32_op
= OPC_SLLV
;
16372 mips32_op
= OPC_SRLV
;
16375 mips32_op
= OPC_SRAV
;
16378 mips32_op
= OPC_ROTRV
;
16380 gen_shift(ctx
, mips32_op
, rd
, rs
, rt
);
16382 /* Logical operations */
16384 mips32_op
= OPC_AND
;
16387 mips32_op
= OPC_OR
;
16390 mips32_op
= OPC_NOR
;
16393 mips32_op
= OPC_XOR
;
16395 gen_logic(ctx
, mips32_op
, rd
, rs
, rt
);
16397 /* Set less than */
16399 mips32_op
= OPC_SLT
;
16402 mips32_op
= OPC_SLTU
;
16404 gen_slt(ctx
, mips32_op
, rd
, rs
, rt
);
16407 goto pool32a_invalid
;
16411 minor
= (ctx
->opcode
>> 6) & 0xf;
16413 /* Conditional moves */
16414 case MOVN
: /* MUL */
16415 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16417 gen_r6_muldiv(ctx
, R6_OPC_MUL
, rd
, rs
, rt
);
16420 gen_cond_move(ctx
, OPC_MOVN
, rd
, rs
, rt
);
16423 case MOVZ
: /* MUH */
16424 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16426 gen_r6_muldiv(ctx
, R6_OPC_MUH
, rd
, rs
, rt
);
16429 gen_cond_move(ctx
, OPC_MOVZ
, rd
, rs
, rt
);
16433 check_insn(ctx
, ISA_MIPS_R6
);
16434 gen_r6_muldiv(ctx
, R6_OPC_MULU
, rd
, rs
, rt
);
16437 check_insn(ctx
, ISA_MIPS_R6
);
16438 gen_r6_muldiv(ctx
, R6_OPC_MUHU
, rd
, rs
, rt
);
16440 case LWXS
: /* DIV */
16441 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16443 gen_r6_muldiv(ctx
, R6_OPC_DIV
, rd
, rs
, rt
);
16446 gen_ldxs(ctx
, rs
, rt
, rd
);
16450 check_insn(ctx
, ISA_MIPS_R6
);
16451 gen_r6_muldiv(ctx
, R6_OPC_MOD
, rd
, rs
, rt
);
16454 check_insn(ctx
, ISA_MIPS_R6
);
16455 gen_r6_muldiv(ctx
, R6_OPC_DIVU
, rd
, rs
, rt
);
16458 check_insn(ctx
, ISA_MIPS_R6
);
16459 gen_r6_muldiv(ctx
, R6_OPC_MODU
, rd
, rs
, rt
);
16462 goto pool32a_invalid
;
16466 gen_bitops(ctx
, OPC_INS
, rt
, rs
, rr
, rd
);
16469 check_insn(ctx
, ISA_MIPS_R6
);
16470 gen_lsa(ctx
, rd
, rt
, rs
, extract32(ctx
->opcode
, 9, 2));
16473 check_insn(ctx
, ISA_MIPS_R6
);
16474 gen_align(ctx
, 32, rd
, rs
, rt
, extract32(ctx
->opcode
, 9, 2));
16477 gen_bitops(ctx
, OPC_EXT
, rt
, rs
, rr
, rd
);
16480 gen_pool32axf(env
, ctx
, rt
, rs
);
16483 generate_exception_end(ctx
, EXCP_BREAK
);
16486 check_insn(ctx
, ISA_MIPS_R6
);
16487 gen_reserved_instruction(ctx
);
16491 MIPS_INVAL("pool32a");
16492 gen_reserved_instruction(ctx
);
16497 minor
= (ctx
->opcode
>> 12) & 0xf;
16500 check_cp0_enabled(ctx
);
16501 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
16502 gen_cache_operation(ctx
, rt
, rs
, imm
);
16507 /* COP2: Not implemented. */
16508 generate_exception_err(ctx
, EXCP_CpU
, 2);
16510 #ifdef TARGET_MIPS64
16513 check_insn(ctx
, ISA_MIPS3
);
16514 check_mips_64(ctx
);
16519 gen_ldst_pair(ctx
, minor
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
16521 #ifdef TARGET_MIPS64
16524 check_insn(ctx
, ISA_MIPS3
);
16525 check_mips_64(ctx
);
16530 gen_ldst_multiple(ctx
, minor
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
16533 MIPS_INVAL("pool32b");
16534 gen_reserved_instruction(ctx
);
16539 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
16540 minor
= ctx
->opcode
& 0x3f;
16541 check_cp1_enabled(ctx
);
16544 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16545 mips32_op
= OPC_ALNV_PS
;
16548 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16549 mips32_op
= OPC_MADD_S
;
16552 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16553 mips32_op
= OPC_MADD_D
;
16556 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16557 mips32_op
= OPC_MADD_PS
;
16560 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16561 mips32_op
= OPC_MSUB_S
;
16564 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16565 mips32_op
= OPC_MSUB_D
;
16568 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16569 mips32_op
= OPC_MSUB_PS
;
16572 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16573 mips32_op
= OPC_NMADD_S
;
16576 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16577 mips32_op
= OPC_NMADD_D
;
16580 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16581 mips32_op
= OPC_NMADD_PS
;
16584 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16585 mips32_op
= OPC_NMSUB_S
;
16588 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16589 mips32_op
= OPC_NMSUB_D
;
16592 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16593 mips32_op
= OPC_NMSUB_PS
;
16595 gen_flt3_arith(ctx
, mips32_op
, rd
, rr
, rs
, rt
);
16597 case CABS_COND_FMT
:
16598 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16599 cond
= (ctx
->opcode
>> 6) & 0xf;
16600 cc
= (ctx
->opcode
>> 13) & 0x7;
16601 fmt
= (ctx
->opcode
>> 10) & 0x3;
16604 gen_cmpabs_s(ctx
, cond
, rt
, rs
, cc
);
16607 gen_cmpabs_d(ctx
, cond
, rt
, rs
, cc
);
16610 gen_cmpabs_ps(ctx
, cond
, rt
, rs
, cc
);
16613 goto pool32f_invalid
;
16617 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16618 cond
= (ctx
->opcode
>> 6) & 0xf;
16619 cc
= (ctx
->opcode
>> 13) & 0x7;
16620 fmt
= (ctx
->opcode
>> 10) & 0x3;
16623 gen_cmp_s(ctx
, cond
, rt
, rs
, cc
);
16626 gen_cmp_d(ctx
, cond
, rt
, rs
, cc
);
16629 gen_cmp_ps(ctx
, cond
, rt
, rs
, cc
);
16632 goto pool32f_invalid
;
16636 check_insn(ctx
, ISA_MIPS_R6
);
16637 gen_r6_cmp_s(ctx
, (ctx
->opcode
>> 6) & 0x1f, rt
, rs
, rd
);
16640 check_insn(ctx
, ISA_MIPS_R6
);
16641 gen_r6_cmp_d(ctx
, (ctx
->opcode
>> 6) & 0x1f, rt
, rs
, rd
);
16644 gen_pool32fxf(ctx
, rt
, rs
);
16648 switch ((ctx
->opcode
>> 6) & 0x7) {
16650 mips32_op
= OPC_PLL_PS
;
16653 mips32_op
= OPC_PLU_PS
;
16656 mips32_op
= OPC_PUL_PS
;
16659 mips32_op
= OPC_PUU_PS
;
16662 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16663 mips32_op
= OPC_CVT_PS_S
;
16665 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
16668 goto pool32f_invalid
;
16672 check_insn(ctx
, ISA_MIPS_R6
);
16673 switch ((ctx
->opcode
>> 9) & 0x3) {
16675 gen_farith(ctx
, OPC_MIN_S
, rt
, rs
, rd
, 0);
16678 gen_farith(ctx
, OPC_MIN_D
, rt
, rs
, rd
, 0);
16681 goto pool32f_invalid
;
16686 switch ((ctx
->opcode
>> 6) & 0x7) {
16688 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16689 mips32_op
= OPC_LWXC1
;
16692 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16693 mips32_op
= OPC_SWXC1
;
16696 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16697 mips32_op
= OPC_LDXC1
;
16700 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16701 mips32_op
= OPC_SDXC1
;
16704 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16705 mips32_op
= OPC_LUXC1
;
16708 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16709 mips32_op
= OPC_SUXC1
;
16711 gen_flt3_ldst(ctx
, mips32_op
, rd
, rd
, rt
, rs
);
16714 goto pool32f_invalid
;
16718 check_insn(ctx
, ISA_MIPS_R6
);
16719 switch ((ctx
->opcode
>> 9) & 0x3) {
16721 gen_farith(ctx
, OPC_MAX_S
, rt
, rs
, rd
, 0);
16724 gen_farith(ctx
, OPC_MAX_D
, rt
, rs
, rd
, 0);
16727 goto pool32f_invalid
;
16732 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16733 fmt
= (ctx
->opcode
>> 9) & 0x3;
16734 switch ((ctx
->opcode
>> 6) & 0x7) {
16738 mips32_op
= OPC_RSQRT2_S
;
16741 mips32_op
= OPC_RSQRT2_D
;
16744 mips32_op
= OPC_RSQRT2_PS
;
16747 goto pool32f_invalid
;
16753 mips32_op
= OPC_RECIP2_S
;
16756 mips32_op
= OPC_RECIP2_D
;
16759 mips32_op
= OPC_RECIP2_PS
;
16762 goto pool32f_invalid
;
16766 mips32_op
= OPC_ADDR_PS
;
16769 mips32_op
= OPC_MULR_PS
;
16771 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
16774 goto pool32f_invalid
;
16778 /* MOV[FT].fmt, PREFX, RINT.fmt, CLASS.fmt*/
16779 cc
= (ctx
->opcode
>> 13) & 0x7;
16780 fmt
= (ctx
->opcode
>> 9) & 0x3;
16781 switch ((ctx
->opcode
>> 6) & 0x7) {
16782 case MOVF_FMT
: /* RINT_FMT */
16783 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16787 gen_farith(ctx
, OPC_RINT_S
, 0, rt
, rs
, 0);
16790 gen_farith(ctx
, OPC_RINT_D
, 0, rt
, rs
, 0);
16793 goto pool32f_invalid
;
16799 gen_movcf_s(ctx
, rs
, rt
, cc
, 0);
16802 gen_movcf_d(ctx
, rs
, rt
, cc
, 0);
16806 gen_movcf_ps(ctx
, rs
, rt
, cc
, 0);
16809 goto pool32f_invalid
;
16813 case MOVT_FMT
: /* CLASS_FMT */
16814 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16818 gen_farith(ctx
, OPC_CLASS_S
, 0, rt
, rs
, 0);
16821 gen_farith(ctx
, OPC_CLASS_D
, 0, rt
, rs
, 0);
16824 goto pool32f_invalid
;
16830 gen_movcf_s(ctx
, rs
, rt
, cc
, 1);
16833 gen_movcf_d(ctx
, rs
, rt
, cc
, 1);
16837 gen_movcf_ps(ctx
, rs
, rt
, cc
, 1);
16840 goto pool32f_invalid
;
16845 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16848 goto pool32f_invalid
;
16851 #define FINSN_3ARG_SDPS(prfx) \
16852 switch ((ctx->opcode >> 8) & 0x3) { \
16854 mips32_op = OPC_##prfx##_S; \
16857 mips32_op = OPC_##prfx##_D; \
16859 case FMT_SDPS_PS: \
16861 mips32_op = OPC_##prfx##_PS; \
16864 goto pool32f_invalid; \
16867 check_insn(ctx
, ISA_MIPS_R6
);
16868 switch ((ctx
->opcode
>> 9) & 0x3) {
16870 gen_farith(ctx
, OPC_MINA_S
, rt
, rs
, rd
, 0);
16873 gen_farith(ctx
, OPC_MINA_D
, rt
, rs
, rd
, 0);
16876 goto pool32f_invalid
;
16880 check_insn(ctx
, ISA_MIPS_R6
);
16881 switch ((ctx
->opcode
>> 9) & 0x3) {
16883 gen_farith(ctx
, OPC_MAXA_S
, rt
, rs
, rd
, 0);
16886 gen_farith(ctx
, OPC_MAXA_D
, rt
, rs
, rd
, 0);
16889 goto pool32f_invalid
;
16893 /* regular FP ops */
16894 switch ((ctx
->opcode
>> 6) & 0x3) {
16896 FINSN_3ARG_SDPS(ADD
);
16899 FINSN_3ARG_SDPS(SUB
);
16902 FINSN_3ARG_SDPS(MUL
);
16905 fmt
= (ctx
->opcode
>> 8) & 0x3;
16907 mips32_op
= OPC_DIV_D
;
16908 } else if (fmt
== 0) {
16909 mips32_op
= OPC_DIV_S
;
16911 goto pool32f_invalid
;
16915 goto pool32f_invalid
;
16920 switch ((ctx
->opcode
>> 6) & 0x7) {
16921 case MOVN_FMT
: /* SELEQZ_FMT */
16922 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16924 switch ((ctx
->opcode
>> 9) & 0x3) {
16926 gen_sel_s(ctx
, OPC_SELEQZ_S
, rd
, rt
, rs
);
16929 gen_sel_d(ctx
, OPC_SELEQZ_D
, rd
, rt
, rs
);
16932 goto pool32f_invalid
;
16936 FINSN_3ARG_SDPS(MOVN
);
16940 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16941 FINSN_3ARG_SDPS(MOVN
);
16943 case MOVZ_FMT
: /* SELNEZ_FMT */
16944 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16946 switch ((ctx
->opcode
>> 9) & 0x3) {
16948 gen_sel_s(ctx
, OPC_SELNEZ_S
, rd
, rt
, rs
);
16951 gen_sel_d(ctx
, OPC_SELNEZ_D
, rd
, rt
, rs
);
16954 goto pool32f_invalid
;
16958 FINSN_3ARG_SDPS(MOVZ
);
16962 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16963 FINSN_3ARG_SDPS(MOVZ
);
16966 check_insn(ctx
, ISA_MIPS_R6
);
16967 switch ((ctx
->opcode
>> 9) & 0x3) {
16969 gen_sel_s(ctx
, OPC_SEL_S
, rd
, rt
, rs
);
16972 gen_sel_d(ctx
, OPC_SEL_D
, rd
, rt
, rs
);
16975 goto pool32f_invalid
;
16979 check_insn(ctx
, ISA_MIPS_R6
);
16980 switch ((ctx
->opcode
>> 9) & 0x3) {
16982 mips32_op
= OPC_MADDF_S
;
16985 mips32_op
= OPC_MADDF_D
;
16988 goto pool32f_invalid
;
16992 check_insn(ctx
, ISA_MIPS_R6
);
16993 switch ((ctx
->opcode
>> 9) & 0x3) {
16995 mips32_op
= OPC_MSUBF_S
;
16998 mips32_op
= OPC_MSUBF_D
;
17001 goto pool32f_invalid
;
17005 goto pool32f_invalid
;
17009 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
17013 MIPS_INVAL("pool32f");
17014 gen_reserved_instruction(ctx
);
17018 generate_exception_err(ctx
, EXCP_CpU
, 1);
17022 minor
= (ctx
->opcode
>> 21) & 0x1f;
17025 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17026 gen_compute_branch(ctx
, OPC_BLTZ
, 4, rs
, -1, imm
<< 1, 4);
17029 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17030 gen_compute_branch(ctx
, OPC_BLTZAL
, 4, rs
, -1, imm
<< 1, 4);
17031 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
17034 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17035 gen_compute_branch(ctx
, OPC_BLTZAL
, 4, rs
, -1, imm
<< 1, 2);
17036 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
17039 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17040 gen_compute_branch(ctx
, OPC_BGEZ
, 4, rs
, -1, imm
<< 1, 4);
17043 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17044 gen_compute_branch(ctx
, OPC_BGEZAL
, 4, rs
, -1, imm
<< 1, 4);
17045 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
17048 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17049 gen_compute_branch(ctx
, OPC_BGEZAL
, 4, rs
, -1, imm
<< 1, 2);
17050 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
17053 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17054 gen_compute_branch(ctx
, OPC_BLEZ
, 4, rs
, -1, imm
<< 1, 4);
17057 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17058 gen_compute_branch(ctx
, OPC_BGTZ
, 4, rs
, -1, imm
<< 1, 4);
17062 case TLTI
: /* BC1EQZC */
17063 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
17065 check_cp1_enabled(ctx
);
17066 gen_compute_branch1_r6(ctx
, OPC_BC1EQZ
, rs
, imm
<< 1, 0);
17069 mips32_op
= OPC_TLTI
;
17073 case TGEI
: /* BC1NEZC */
17074 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
17076 check_cp1_enabled(ctx
);
17077 gen_compute_branch1_r6(ctx
, OPC_BC1NEZ
, rs
, imm
<< 1, 0);
17080 mips32_op
= OPC_TGEI
;
17085 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17086 mips32_op
= OPC_TLTIU
;
17089 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17090 mips32_op
= OPC_TGEIU
;
17092 case TNEI
: /* SYNCI */
17093 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
17096 * Break the TB to be able to sync copied instructions
17099 ctx
->base
.is_jmp
= DISAS_STOP
;
17102 mips32_op
= OPC_TNEI
;
17107 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17108 mips32_op
= OPC_TEQI
;
17110 gen_trap(ctx
, mips32_op
, rs
, -1, imm
);
17115 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17116 gen_compute_branch(ctx
, minor
== BNEZC
? OPC_BNE
: OPC_BEQ
,
17117 4, rs
, 0, imm
<< 1, 0);
17119 * Compact branches don't have a delay slot, so just let
17120 * the normal delay slot handling take us to the branch
17125 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17126 gen_logic_imm(ctx
, OPC_LUI
, rs
, 0, imm
);
17129 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17131 * Break the TB to be able to sync copied instructions
17134 ctx
->base
.is_jmp
= DISAS_STOP
;
17138 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17139 /* COP2: Not implemented. */
17140 generate_exception_err(ctx
, EXCP_CpU
, 2);
17143 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17144 mips32_op
= (ctx
->opcode
& (1 << 16)) ? OPC_BC1FANY2
: OPC_BC1F
;
17147 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17148 mips32_op
= (ctx
->opcode
& (1 << 16)) ? OPC_BC1TANY2
: OPC_BC1T
;
17151 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17152 mips32_op
= OPC_BC1FANY4
;
17155 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17156 mips32_op
= OPC_BC1TANY4
;
17159 check_insn(ctx
, ASE_MIPS3D
);
17162 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
17163 check_cp1_enabled(ctx
);
17164 gen_compute_branch1(ctx
, mips32_op
,
17165 (ctx
->opcode
>> 18) & 0x7, imm
<< 1);
17167 generate_exception_err(ctx
, EXCP_CpU
, 1);
17172 /* MIPS DSP: not implemented */
17175 MIPS_INVAL("pool32i");
17176 gen_reserved_instruction(ctx
);
17181 minor
= (ctx
->opcode
>> 12) & 0xf;
17182 offset
= sextract32(ctx
->opcode
, 0,
17183 (ctx
->insn_flags
& ISA_MIPS_R6
) ? 9 : 12);
17186 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17187 mips32_op
= OPC_LWL
;
17190 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17191 mips32_op
= OPC_SWL
;
17194 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17195 mips32_op
= OPC_LWR
;
17198 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17199 mips32_op
= OPC_SWR
;
17201 #if defined(TARGET_MIPS64)
17203 check_insn(ctx
, ISA_MIPS3
);
17204 check_mips_64(ctx
);
17205 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17206 mips32_op
= OPC_LDL
;
17209 check_insn(ctx
, ISA_MIPS3
);
17210 check_mips_64(ctx
);
17211 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17212 mips32_op
= OPC_SDL
;
17215 check_insn(ctx
, ISA_MIPS3
);
17216 check_mips_64(ctx
);
17217 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17218 mips32_op
= OPC_LDR
;
17221 check_insn(ctx
, ISA_MIPS3
);
17222 check_mips_64(ctx
);
17223 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17224 mips32_op
= OPC_SDR
;
17227 check_insn(ctx
, ISA_MIPS3
);
17228 check_mips_64(ctx
);
17229 mips32_op
= OPC_LWU
;
17232 check_insn(ctx
, ISA_MIPS3
);
17233 check_mips_64(ctx
);
17234 mips32_op
= OPC_LLD
;
17238 mips32_op
= OPC_LL
;
17241 gen_ld(ctx
, mips32_op
, rt
, rs
, offset
);
17244 gen_st(ctx
, mips32_op
, rt
, rs
, offset
);
17247 gen_st_cond(ctx
, rt
, rs
, offset
, MO_TESL
, false);
17249 #if defined(TARGET_MIPS64)
17251 check_insn(ctx
, ISA_MIPS3
);
17252 check_mips_64(ctx
);
17253 gen_st_cond(ctx
, rt
, rs
, offset
, MO_TEQ
, false);
17258 MIPS_INVAL("pool32c ld-eva");
17259 gen_reserved_instruction(ctx
);
17262 check_cp0_enabled(ctx
);
17264 minor2
= (ctx
->opcode
>> 9) & 0x7;
17265 offset
= sextract32(ctx
->opcode
, 0, 9);
17268 mips32_op
= OPC_LBUE
;
17271 mips32_op
= OPC_LHUE
;
17274 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17275 mips32_op
= OPC_LWLE
;
17278 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17279 mips32_op
= OPC_LWRE
;
17282 mips32_op
= OPC_LBE
;
17285 mips32_op
= OPC_LHE
;
17288 mips32_op
= OPC_LLE
;
17291 mips32_op
= OPC_LWE
;
17297 MIPS_INVAL("pool32c st-eva");
17298 gen_reserved_instruction(ctx
);
17301 check_cp0_enabled(ctx
);
17303 minor2
= (ctx
->opcode
>> 9) & 0x7;
17304 offset
= sextract32(ctx
->opcode
, 0, 9);
17307 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17308 mips32_op
= OPC_SWLE
;
17311 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17312 mips32_op
= OPC_SWRE
;
17315 /* Treat as no-op */
17316 if ((ctx
->insn_flags
& ISA_MIPS_R6
) && (rt
>= 24)) {
17317 /* hint codes 24-31 are reserved and signal RI */
17318 generate_exception(ctx
, EXCP_RI
);
17322 /* Treat as no-op */
17323 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
17324 gen_cache_operation(ctx
, rt
, rs
, offset
);
17328 mips32_op
= OPC_SBE
;
17331 mips32_op
= OPC_SHE
;
17334 gen_st_cond(ctx
, rt
, rs
, offset
, MO_TESL
, true);
17337 mips32_op
= OPC_SWE
;
17342 /* Treat as no-op */
17343 if ((ctx
->insn_flags
& ISA_MIPS_R6
) && (rt
>= 24)) {
17344 /* hint codes 24-31 are reserved and signal RI */
17345 generate_exception(ctx
, EXCP_RI
);
17349 MIPS_INVAL("pool32c");
17350 gen_reserved_instruction(ctx
);
17354 case ADDI32
: /* AUI, LUI */
17355 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
17357 gen_logic_imm(ctx
, OPC_LUI
, rt
, rs
, imm
);
17360 mips32_op
= OPC_ADDI
;
17365 mips32_op
= OPC_ADDIU
;
17367 gen_arith_imm(ctx
, mips32_op
, rt
, rs
, imm
);
17370 /* Logical operations */
17372 mips32_op
= OPC_ORI
;
17375 mips32_op
= OPC_XORI
;
17378 mips32_op
= OPC_ANDI
;
17380 gen_logic_imm(ctx
, mips32_op
, rt
, rs
, imm
);
17383 /* Set less than immediate */
17385 mips32_op
= OPC_SLTI
;
17388 mips32_op
= OPC_SLTIU
;
17390 gen_slt_imm(ctx
, mips32_op
, rt
, rs
, imm
);
17393 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17394 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
17395 gen_compute_branch(ctx
, OPC_JALX
, 4, rt
, rs
, offset
, 4);
17396 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
17398 case JALS32
: /* BOVC, BEQC, BEQZALC */
17399 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
17402 mips32_op
= OPC_BOVC
;
17403 } else if (rs
< rt
&& rs
== 0) {
17405 mips32_op
= OPC_BEQZALC
;
17408 mips32_op
= OPC_BEQC
;
17410 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
17413 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1;
17414 gen_compute_branch(ctx
, OPC_JAL
, 4, rt
, rs
, offset
, 2);
17415 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
17418 case BEQ32
: /* BC */
17419 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
17421 gen_compute_compact_branch(ctx
, OPC_BC
, 0, 0,
17422 sextract32(ctx
->opcode
<< 1, 0, 27));
17425 gen_compute_branch(ctx
, OPC_BEQ
, 4, rt
, rs
, imm
<< 1, 4);
17428 case BNE32
: /* BALC */
17429 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
17431 gen_compute_compact_branch(ctx
, OPC_BALC
, 0, 0,
17432 sextract32(ctx
->opcode
<< 1, 0, 27));
17435 gen_compute_branch(ctx
, OPC_BNE
, 4, rt
, rs
, imm
<< 1, 4);
17438 case J32
: /* BGTZC, BLTZC, BLTC */
17439 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
17440 if (rs
== 0 && rt
!= 0) {
17442 mips32_op
= OPC_BGTZC
;
17443 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
17445 mips32_op
= OPC_BLTZC
;
17448 mips32_op
= OPC_BLTC
;
17450 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
17453 gen_compute_branch(ctx
, OPC_J
, 4, rt
, rs
,
17454 (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1, 4);
17457 case JAL32
: /* BLEZC, BGEZC, BGEC */
17458 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
17459 if (rs
== 0 && rt
!= 0) {
17461 mips32_op
= OPC_BLEZC
;
17462 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
17464 mips32_op
= OPC_BGEZC
;
17467 mips32_op
= OPC_BGEC
;
17469 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
17472 gen_compute_branch(ctx
, OPC_JAL
, 4, rt
, rs
,
17473 (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1, 4);
17474 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
17477 /* Floating point (COP1) */
17479 mips32_op
= OPC_LWC1
;
17482 mips32_op
= OPC_LDC1
;
17485 mips32_op
= OPC_SWC1
;
17488 mips32_op
= OPC_SDC1
;
17490 gen_cop1_ldst(ctx
, mips32_op
, rt
, rs
, imm
);
17492 case ADDIUPC
: /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
17493 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
17494 /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
17495 switch ((ctx
->opcode
>> 16) & 0x1f) {
17504 gen_pcrel(ctx
, OPC_ADDIUPC
, ctx
->base
.pc_next
& ~0x3, rt
);
17507 gen_pcrel(ctx
, OPC_AUIPC
, ctx
->base
.pc_next
, rt
);
17510 gen_pcrel(ctx
, OPC_ALUIPC
, ctx
->base
.pc_next
, rt
);
17520 gen_pcrel(ctx
, R6_OPC_LWPC
, ctx
->base
.pc_next
& ~0x3, rt
);
17523 generate_exception(ctx
, EXCP_RI
);
17528 int reg
= mmreg(ZIMM(ctx
->opcode
, 23, 3));
17529 offset
= SIMM(ctx
->opcode
, 0, 23) << 2;
17531 gen_addiupc(ctx
, reg
, offset
, 0, 0);
17534 case BNVC
: /* BNEC, BNEZALC */
17535 check_insn(ctx
, ISA_MIPS_R6
);
17538 mips32_op
= OPC_BNVC
;
17539 } else if (rs
< rt
&& rs
== 0) {
17541 mips32_op
= OPC_BNEZALC
;
17544 mips32_op
= OPC_BNEC
;
17546 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
17548 case R6_BNEZC
: /* JIALC */
17549 check_insn(ctx
, ISA_MIPS_R6
);
17552 gen_compute_compact_branch(ctx
, OPC_BNEZC
, rt
, 0,
17553 sextract32(ctx
->opcode
<< 1, 0, 22));
17556 gen_compute_compact_branch(ctx
, OPC_JIALC
, 0, rs
, imm
);
17559 case R6_BEQZC
: /* JIC */
17560 check_insn(ctx
, ISA_MIPS_R6
);
17563 gen_compute_compact_branch(ctx
, OPC_BEQZC
, rt
, 0,
17564 sextract32(ctx
->opcode
<< 1, 0, 22));
17567 gen_compute_compact_branch(ctx
, OPC_JIC
, 0, rs
, imm
);
17570 case BLEZALC
: /* BGEZALC, BGEUC */
17571 check_insn(ctx
, ISA_MIPS_R6
);
17572 if (rs
== 0 && rt
!= 0) {
17574 mips32_op
= OPC_BLEZALC
;
17575 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
17577 mips32_op
= OPC_BGEZALC
;
17580 mips32_op
= OPC_BGEUC
;
17582 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
17584 case BGTZALC
: /* BLTZALC, BLTUC */
17585 check_insn(ctx
, ISA_MIPS_R6
);
17586 if (rs
== 0 && rt
!= 0) {
17588 mips32_op
= OPC_BGTZALC
;
17589 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
17591 mips32_op
= OPC_BLTZALC
;
17594 mips32_op
= OPC_BLTUC
;
17596 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
17598 /* Loads and stores */
17600 mips32_op
= OPC_LB
;
17603 mips32_op
= OPC_LBU
;
17606 mips32_op
= OPC_LH
;
17609 mips32_op
= OPC_LHU
;
17612 mips32_op
= OPC_LW
;
17614 #ifdef TARGET_MIPS64
17616 check_insn(ctx
, ISA_MIPS3
);
17617 check_mips_64(ctx
);
17618 mips32_op
= OPC_LD
;
17621 check_insn(ctx
, ISA_MIPS3
);
17622 check_mips_64(ctx
);
17623 mips32_op
= OPC_SD
;
17627 mips32_op
= OPC_SB
;
17630 mips32_op
= OPC_SH
;
17633 mips32_op
= OPC_SW
;
17636 gen_ld(ctx
, mips32_op
, rt
, rs
, imm
);
17639 gen_st(ctx
, mips32_op
, rt
, rs
, imm
);
17642 gen_reserved_instruction(ctx
);
17647 static int decode_micromips_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
17651 /* make sure instructions are on a halfword boundary */
17652 if (ctx
->base
.pc_next
& 0x1) {
17653 env
->CP0_BadVAddr
= ctx
->base
.pc_next
;
17654 generate_exception_end(ctx
, EXCP_AdEL
);
17658 op
= (ctx
->opcode
>> 10) & 0x3f;
17659 /* Enforce properly-sized instructions in a delay slot */
17660 if (ctx
->hflags
& MIPS_HFLAG_BDS_STRICT
) {
17661 switch (op
& 0x7) { /* MSB-3..MSB-5 */
17663 /* POOL32A, POOL32B, POOL32I, POOL32C */
17665 /* ADDI32, ADDIU32, ORI32, XORI32, SLTI32, SLTIU32, ANDI32, JALX32 */
17667 /* LBU32, LHU32, POOL32F, JALS32, BEQ32, BNE32, J32, JAL32 */
17669 /* SB32, SH32, ADDIUPC, SWC132, SDC132, SW32 */
17671 /* LB32, LH32, LWC132, LDC132, LW32 */
17672 if (ctx
->hflags
& MIPS_HFLAG_BDS16
) {
17673 gen_reserved_instruction(ctx
);
17678 /* POOL16A, POOL16B, POOL16C, LWGP16, POOL16F */
17680 /* LBU16, LHU16, LWSP16, LW16, SB16, SH16, SWSP16, SW16 */
17682 /* MOVE16, ANDI16, POOL16D, POOL16E, BEQZ16, BNEZ16, B16, LI16 */
17683 if (ctx
->hflags
& MIPS_HFLAG_BDS32
) {
17684 gen_reserved_instruction(ctx
);
17694 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
17695 int rs1
= mmreg(uMIPS_RS1(ctx
->opcode
));
17696 int rs2
= mmreg(uMIPS_RS2(ctx
->opcode
));
17699 switch (ctx
->opcode
& 0x1) {
17707 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
17709 * In the Release 6, the register number location in
17710 * the instruction encoding has changed.
17712 gen_arith(ctx
, opc
, rs1
, rd
, rs2
);
17714 gen_arith(ctx
, opc
, rd
, rs1
, rs2
);
17720 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
17721 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
17722 int amount
= (ctx
->opcode
>> 1) & 0x7;
17724 amount
= amount
== 0 ? 8 : amount
;
17726 switch (ctx
->opcode
& 0x1) {
17735 gen_shift_imm(ctx
, opc
, rd
, rs
, amount
);
17739 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
17740 gen_pool16c_r6_insn(ctx
);
17742 gen_pool16c_insn(ctx
);
17747 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
17748 int rb
= 28; /* GP */
17749 int16_t offset
= SIMM(ctx
->opcode
, 0, 7) << 2;
17751 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
17755 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17756 if (ctx
->opcode
& 1) {
17757 gen_reserved_instruction(ctx
);
17760 int enc_dest
= uMIPS_RD(ctx
->opcode
);
17761 int enc_rt
= uMIPS_RS2(ctx
->opcode
);
17762 int enc_rs
= uMIPS_RS1(ctx
->opcode
);
17763 gen_movep(ctx
, enc_dest
, enc_rt
, enc_rs
);
17768 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
17769 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
17770 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4);
17771 offset
= (offset
== 0xf ? -1 : offset
);
17773 gen_ld(ctx
, OPC_LBU
, rd
, rb
, offset
);
17778 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
17779 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
17780 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 1;
17782 gen_ld(ctx
, OPC_LHU
, rd
, rb
, offset
);
17787 int rd
= (ctx
->opcode
>> 5) & 0x1f;
17788 int rb
= 29; /* SP */
17789 int16_t offset
= ZIMM(ctx
->opcode
, 0, 5) << 2;
17791 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
17796 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
17797 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
17798 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 2;
17800 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
17805 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
17806 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
17807 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4);
17809 gen_st(ctx
, OPC_SB
, rd
, rb
, offset
);
17814 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
17815 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
17816 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 1;
17818 gen_st(ctx
, OPC_SH
, rd
, rb
, offset
);
17823 int rd
= (ctx
->opcode
>> 5) & 0x1f;
17824 int rb
= 29; /* SP */
17825 int16_t offset
= ZIMM(ctx
->opcode
, 0, 5) << 2;
17827 gen_st(ctx
, OPC_SW
, rd
, rb
, offset
);
17832 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
17833 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
17834 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 2;
17836 gen_st(ctx
, OPC_SW
, rd
, rb
, offset
);
17841 int rd
= uMIPS_RD5(ctx
->opcode
);
17842 int rs
= uMIPS_RS5(ctx
->opcode
);
17844 gen_arith(ctx
, OPC_ADDU
, rd
, rs
, 0);
17851 switch (ctx
->opcode
& 0x1) {
17861 switch (ctx
->opcode
& 0x1) {
17866 gen_addiur1sp(ctx
);
17870 case B16
: /* BC16 */
17871 gen_compute_branch(ctx
, OPC_BEQ
, 2, 0, 0,
17872 sextract32(ctx
->opcode
, 0, 10) << 1,
17873 (ctx
->insn_flags
& ISA_MIPS_R6
) ? 0 : 4);
17875 case BNEZ16
: /* BNEZC16 */
17876 case BEQZ16
: /* BEQZC16 */
17877 gen_compute_branch(ctx
, op
== BNEZ16
? OPC_BNE
: OPC_BEQ
, 2,
17878 mmreg(uMIPS_RD(ctx
->opcode
)),
17879 0, sextract32(ctx
->opcode
, 0, 7) << 1,
17880 (ctx
->insn_flags
& ISA_MIPS_R6
) ? 0 : 4);
17885 int reg
= mmreg(uMIPS_RD(ctx
->opcode
));
17886 int imm
= ZIMM(ctx
->opcode
, 0, 7);
17888 imm
= (imm
== 0x7f ? -1 : imm
);
17889 tcg_gen_movi_tl(cpu_gpr
[reg
], imm
);
17895 gen_reserved_instruction(ctx
);
17898 decode_micromips32_opc(env
, ctx
);
17911 /* MAJOR, P16, and P32 pools opcodes */
17915 NM_MOVE_BALC
= 0x02,
17923 NM_P16_SHIFT
= 0x0c,
17941 NM_P_LS_U12
= 0x21,
17951 NM_P16_ADDU
= 0x2c,
17965 NM_MOVEPREV
= 0x3f,
17968 /* POOL32A instruction pool */
17970 NM_POOL32A0
= 0x00,
17971 NM_SPECIAL2
= 0x01,
17974 NM_POOL32A5
= 0x05,
17975 NM_POOL32A7
= 0x07,
17978 /* P.GP.W instruction pool */
17980 NM_ADDIUGP_W
= 0x00,
17985 /* P48I instruction pool */
17989 NM_ADDIUGP48
= 0x02,
17990 NM_ADDIUPC48
= 0x03,
17995 /* P.U12 instruction pool */
18004 NM_ADDIUNEG
= 0x08,
18011 /* POOL32F instruction pool */
18013 NM_POOL32F_0
= 0x00,
18014 NM_POOL32F_3
= 0x03,
18015 NM_POOL32F_5
= 0x05,
18018 /* POOL32S instruction pool */
18020 NM_POOL32S_0
= 0x00,
18021 NM_POOL32S_4
= 0x04,
18024 /* P.LUI instruction pool */
18030 /* P.GP.BH instruction pool */
18035 NM_ADDIUGP_B
= 0x03,
18038 NM_P_GP_CP1
= 0x06,
18041 /* P.LS.U12 instruction pool */
18046 NM_P_PREFU12
= 0x03,
18059 /* P.LS.S9 instruction pool */
18065 NM_P_LS_UAWM
= 0x05,
18068 /* P.BAL instruction pool */
18074 /* P.J instruction pool */
18077 NM_JALRC_HB
= 0x01,
18078 NM_P_BALRSC
= 0x08,
18081 /* P.BR1 instruction pool */
18089 /* P.BR2 instruction pool */
18096 /* P.BRI instruction pool */
18108 /* P16.SHIFT instruction pool */
18114 /* POOL16C instruction pool */
18116 NM_POOL16C_0
= 0x00,
18120 /* P16.A1 instruction pool */
18122 NM_ADDIUR1SP
= 0x01,
18125 /* P16.A2 instruction pool */
18128 NM_P_ADDIURS5
= 0x01,
18131 /* P16.ADDU instruction pool */
18137 /* P16.SR instruction pool */
18140 NM_RESTORE_JRC16
= 0x01,
18143 /* P16.4X4 instruction pool */
18149 /* P16.LB instruction pool */
18156 /* P16.LH instruction pool */
18163 /* P.RI instruction pool */
18166 NM_P_SYSCALL
= 0x01,
18171 /* POOL32A0 instruction pool */
18206 NM_D_E_MT_VPE
= 0x56,
18214 /* CRC32 instruction pool */
18224 /* POOL32A5 instruction pool */
18226 NM_CMP_EQ_PH
= 0x00,
18227 NM_CMP_LT_PH
= 0x08,
18228 NM_CMP_LE_PH
= 0x10,
18229 NM_CMPGU_EQ_QB
= 0x18,
18230 NM_CMPGU_LT_QB
= 0x20,
18231 NM_CMPGU_LE_QB
= 0x28,
18232 NM_CMPGDU_EQ_QB
= 0x30,
18233 NM_CMPGDU_LT_QB
= 0x38,
18234 NM_CMPGDU_LE_QB
= 0x40,
18235 NM_CMPU_EQ_QB
= 0x48,
18236 NM_CMPU_LT_QB
= 0x50,
18237 NM_CMPU_LE_QB
= 0x58,
18238 NM_ADDQ_S_W
= 0x60,
18239 NM_SUBQ_S_W
= 0x68,
18243 NM_ADDQ_S_PH
= 0x01,
18244 NM_ADDQH_R_PH
= 0x09,
18245 NM_ADDQH_R_W
= 0x11,
18246 NM_ADDU_S_QB
= 0x19,
18247 NM_ADDU_S_PH
= 0x21,
18248 NM_ADDUH_R_QB
= 0x29,
18249 NM_SHRAV_R_PH
= 0x31,
18250 NM_SHRAV_R_QB
= 0x39,
18251 NM_SUBQ_S_PH
= 0x41,
18252 NM_SUBQH_R_PH
= 0x49,
18253 NM_SUBQH_R_W
= 0x51,
18254 NM_SUBU_S_QB
= 0x59,
18255 NM_SUBU_S_PH
= 0x61,
18256 NM_SUBUH_R_QB
= 0x69,
18257 NM_SHLLV_S_PH
= 0x71,
18258 NM_PRECR_SRA_R_PH_W
= 0x79,
18260 NM_MULEU_S_PH_QBL
= 0x12,
18261 NM_MULEU_S_PH_QBR
= 0x1a,
18262 NM_MULQ_RS_PH
= 0x22,
18263 NM_MULQ_S_PH
= 0x2a,
18264 NM_MULQ_RS_W
= 0x32,
18265 NM_MULQ_S_W
= 0x3a,
18268 NM_SHRAV_R_W
= 0x5a,
18269 NM_SHRLV_PH
= 0x62,
18270 NM_SHRLV_QB
= 0x6a,
18271 NM_SHLLV_QB
= 0x72,
18272 NM_SHLLV_S_W
= 0x7a,
18276 NM_MULEQ_S_W_PHL
= 0x04,
18277 NM_MULEQ_S_W_PHR
= 0x0c,
18279 NM_MUL_S_PH
= 0x05,
18280 NM_PRECR_QB_PH
= 0x0d,
18281 NM_PRECRQ_QB_PH
= 0x15,
18282 NM_PRECRQ_PH_W
= 0x1d,
18283 NM_PRECRQ_RS_PH_W
= 0x25,
18284 NM_PRECRQU_S_QB_PH
= 0x2d,
18285 NM_PACKRL_PH
= 0x35,
18289 NM_SHRA_R_W
= 0x5e,
18290 NM_SHRA_R_PH
= 0x66,
18291 NM_SHLL_S_PH
= 0x76,
18292 NM_SHLL_S_W
= 0x7e,
18297 /* POOL32A7 instruction pool */
18302 NM_POOL32AXF
= 0x07,
18305 /* P.SR instruction pool */
18311 /* P.SHIFT instruction pool */
18319 /* P.ROTX instruction pool */
18324 /* P.INS instruction pool */
18329 /* P.EXT instruction pool */
18334 /* POOL32F_0 (fmt) instruction pool */
18339 NM_SELEQZ_S
= 0x07,
18340 NM_SELEQZ_D
= 0x47,
18344 NM_SELNEZ_S
= 0x0f,
18345 NM_SELNEZ_D
= 0x4f,
18360 /* POOL32F_3 instruction pool */
18364 NM_MINA_FMT
= 0x04,
18365 NM_MAXA_FMT
= 0x05,
18366 NM_POOL32FXF
= 0x07,
18369 /* POOL32F_5 instruction pool */
18371 NM_CMP_CONDN_S
= 0x00,
18372 NM_CMP_CONDN_D
= 0x02,
18375 /* P.GP.LH instruction pool */
18381 /* P.GP.SH instruction pool */
18386 /* P.GP.CP1 instruction pool */
18394 /* P.LS.S0 instruction pool */
18411 NM_P_PREFS9
= 0x03,
18417 /* P.LS.S1 instruction pool */
18419 NM_ASET_ACLR
= 0x02,
18427 /* P.LS.E0 instruction pool */
18443 /* P.PREFE instruction pool */
18449 /* P.LLE instruction pool */
18455 /* P.SCE instruction pool */
18461 /* P.LS.WM instruction pool */
18467 /* P.LS.UAWM instruction pool */
18473 /* P.BR3A instruction pool */
18479 NM_BPOSGE32C
= 0x04,
18482 /* P16.RI instruction pool */
18484 NM_P16_SYSCALL
= 0x01,
18489 /* POOL16C_0 instruction pool */
18491 NM_POOL16C_00
= 0x00,
18494 /* P16.JRC instruction pool */
18500 /* P.SYSCALL instruction pool */
18506 /* P.TRAP instruction pool */
18512 /* P.CMOVE instruction pool */
18518 /* POOL32Axf instruction pool */
18520 NM_POOL32AXF_1
= 0x01,
18521 NM_POOL32AXF_2
= 0x02,
18522 NM_POOL32AXF_4
= 0x04,
18523 NM_POOL32AXF_5
= 0x05,
18524 NM_POOL32AXF_7
= 0x07,
18527 /* POOL32Axf_1 instruction pool */
18529 NM_POOL32AXF_1_0
= 0x00,
18530 NM_POOL32AXF_1_1
= 0x01,
18531 NM_POOL32AXF_1_3
= 0x03,
18532 NM_POOL32AXF_1_4
= 0x04,
18533 NM_POOL32AXF_1_5
= 0x05,
18534 NM_POOL32AXF_1_7
= 0x07,
18537 /* POOL32Axf_2 instruction pool */
18539 NM_POOL32AXF_2_0_7
= 0x00,
18540 NM_POOL32AXF_2_8_15
= 0x01,
18541 NM_POOL32AXF_2_16_23
= 0x02,
18542 NM_POOL32AXF_2_24_31
= 0x03,
18545 /* POOL32Axf_7 instruction pool */
18547 NM_SHRA_R_QB
= 0x0,
18552 /* POOL32Axf_1_0 instruction pool */
18560 /* POOL32Axf_1_1 instruction pool */
18566 /* POOL32Axf_1_3 instruction pool */
18574 /* POOL32Axf_1_4 instruction pool */
18580 /* POOL32Axf_1_5 instruction pool */
18582 NM_MAQ_S_W_PHR
= 0x0,
18583 NM_MAQ_S_W_PHL
= 0x1,
18584 NM_MAQ_SA_W_PHR
= 0x2,
18585 NM_MAQ_SA_W_PHL
= 0x3,
18588 /* POOL32Axf_1_7 instruction pool */
18592 NM_EXTR_RS_W
= 0x2,
18596 /* POOL32Axf_2_0_7 instruction pool */
18599 NM_DPAQ_S_W_PH
= 0x1,
18601 NM_DPSQ_S_W_PH
= 0x3,
18608 /* POOL32Axf_2_8_15 instruction pool */
18610 NM_DPAX_W_PH
= 0x0,
18611 NM_DPAQ_SA_L_W
= 0x1,
18612 NM_DPSX_W_PH
= 0x2,
18613 NM_DPSQ_SA_L_W
= 0x3,
18616 NM_EXTRV_R_W
= 0x7,
18619 /* POOL32Axf_2_16_23 instruction pool */
18621 NM_DPAU_H_QBL
= 0x0,
18622 NM_DPAQX_S_W_PH
= 0x1,
18623 NM_DPSU_H_QBL
= 0x2,
18624 NM_DPSQX_S_W_PH
= 0x3,
18627 NM_MULSA_W_PH
= 0x6,
18628 NM_EXTRV_RS_W
= 0x7,
18631 /* POOL32Axf_2_24_31 instruction pool */
18633 NM_DPAU_H_QBR
= 0x0,
18634 NM_DPAQX_SA_W_PH
= 0x1,
18635 NM_DPSU_H_QBR
= 0x2,
18636 NM_DPSQX_SA_W_PH
= 0x3,
18639 NM_MULSAQ_S_W_PH
= 0x6,
18640 NM_EXTRV_S_H
= 0x7,
18643 /* POOL32Axf_{4, 5} instruction pool */
18662 /* nanoMIPS DSP instructions */
18663 NM_ABSQ_S_QB
= 0x00,
18664 NM_ABSQ_S_PH
= 0x08,
18665 NM_ABSQ_S_W
= 0x10,
18666 NM_PRECEQ_W_PHL
= 0x28,
18667 NM_PRECEQ_W_PHR
= 0x30,
18668 NM_PRECEQU_PH_QBL
= 0x38,
18669 NM_PRECEQU_PH_QBR
= 0x48,
18670 NM_PRECEU_PH_QBL
= 0x58,
18671 NM_PRECEU_PH_QBR
= 0x68,
18672 NM_PRECEQU_PH_QBLA
= 0x39,
18673 NM_PRECEQU_PH_QBRA
= 0x49,
18674 NM_PRECEU_PH_QBLA
= 0x59,
18675 NM_PRECEU_PH_QBRA
= 0x69,
18676 NM_REPLV_PH
= 0x01,
18677 NM_REPLV_QB
= 0x09,
18680 NM_RADDU_W_QB
= 0x78,
18686 /* PP.SR instruction pool */
18690 NM_RESTORE_JRC
= 0x03,
18693 /* P.SR.F instruction pool */
18696 NM_RESTOREF
= 0x01,
18699 /* P16.SYSCALL instruction pool */
18701 NM_SYSCALL16
= 0x00,
18702 NM_HYPCALL16
= 0x01,
18705 /* POOL16C_00 instruction pool */
18713 /* PP.LSX and PP.LSXS instruction pool */
18751 /* ERETx instruction pool */
18757 /* POOL32FxF_{0, 1} insturction pool */
18766 NM_CVT_S_PL
= 0x84,
18767 NM_CVT_S_PU
= 0xa4,
18769 NM_CVT_L_S
= 0x004,
18770 NM_CVT_L_D
= 0x104,
18771 NM_CVT_W_S
= 0x024,
18772 NM_CVT_W_D
= 0x124,
18774 NM_RSQRT_S
= 0x008,
18775 NM_RSQRT_D
= 0x108,
18780 NM_RECIP_S
= 0x048,
18781 NM_RECIP_D
= 0x148,
18783 NM_FLOOR_L_S
= 0x00c,
18784 NM_FLOOR_L_D
= 0x10c,
18786 NM_FLOOR_W_S
= 0x02c,
18787 NM_FLOOR_W_D
= 0x12c,
18789 NM_CEIL_L_S
= 0x04c,
18790 NM_CEIL_L_D
= 0x14c,
18791 NM_CEIL_W_S
= 0x06c,
18792 NM_CEIL_W_D
= 0x16c,
18793 NM_TRUNC_L_S
= 0x08c,
18794 NM_TRUNC_L_D
= 0x18c,
18795 NM_TRUNC_W_S
= 0x0ac,
18796 NM_TRUNC_W_D
= 0x1ac,
18797 NM_ROUND_L_S
= 0x0cc,
18798 NM_ROUND_L_D
= 0x1cc,
18799 NM_ROUND_W_S
= 0x0ec,
18800 NM_ROUND_W_D
= 0x1ec,
18808 NM_CVT_D_S
= 0x04d,
18809 NM_CVT_D_W
= 0x0cd,
18810 NM_CVT_D_L
= 0x14d,
18811 NM_CVT_S_D
= 0x06d,
18812 NM_CVT_S_W
= 0x0ed,
18813 NM_CVT_S_L
= 0x16d,
18816 /* P.LL instruction pool */
18822 /* P.SC instruction pool */
18828 /* P.DVP instruction pool */
18837 * nanoMIPS decoding engine
18842 /* extraction utilities */
18844 #define NANOMIPS_EXTRACT_RT3(op) ((op >> 7) & 0x7)
18845 #define NANOMIPS_EXTRACT_RS3(op) ((op >> 4) & 0x7)
18846 #define NANOMIPS_EXTRACT_RD3(op) ((op >> 1) & 0x7)
18847 #define NANOMIPS_EXTRACT_RD5(op) ((op >> 5) & 0x1f)
18848 #define NANOMIPS_EXTRACT_RS5(op) (op & 0x1f)
18850 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3'). */
18851 static inline int decode_gpr_gpr3(int r
)
18853 static const int map
[] = { 16, 17, 18, 19, 4, 5, 6, 7 };
18855 return map
[r
& 0x7];
18858 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3.src.store'). */
18859 static inline int decode_gpr_gpr3_src_store(int r
)
18861 static const int map
[] = { 0, 17, 18, 19, 4, 5, 6, 7 };
18863 return map
[r
& 0x7];
18866 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4'). */
18867 static inline int decode_gpr_gpr4(int r
)
18869 static const int map
[] = { 8, 9, 10, 11, 4, 5, 6, 7,
18870 16, 17, 18, 19, 20, 21, 22, 23 };
18872 return map
[r
& 0xf];
18875 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4.zero'). */
18876 static inline int decode_gpr_gpr4_zero(int r
)
18878 static const int map
[] = { 8, 9, 10, 0, 4, 5, 6, 7,
18879 16, 17, 18, 19, 20, 21, 22, 23 };
18881 return map
[r
& 0xf];
18885 static void gen_adjust_sp(DisasContext
*ctx
, int u
)
18887 gen_op_addr_addi(ctx
, cpu_gpr
[29], cpu_gpr
[29], u
);
18890 static void gen_save(DisasContext
*ctx
, uint8_t rt
, uint8_t count
,
18891 uint8_t gp
, uint16_t u
)
18894 TCGv va
= tcg_temp_new();
18895 TCGv t0
= tcg_temp_new();
18897 while (counter
!= count
) {
18898 bool use_gp
= gp
&& (counter
== count
- 1);
18899 int this_rt
= use_gp
? 28 : (rt
& 0x10) | ((rt
+ counter
) & 0x1f);
18900 int this_offset
= -((counter
+ 1) << 2);
18901 gen_base_offset_addr(ctx
, va
, 29, this_offset
);
18902 gen_load_gpr(t0
, this_rt
);
18903 tcg_gen_qemu_st_tl(t0
, va
, ctx
->mem_idx
,
18904 (MO_TEUL
| ctx
->default_tcg_memop_mask
));
18908 /* adjust stack pointer */
18909 gen_adjust_sp(ctx
, -u
);
18915 static void gen_restore(DisasContext
*ctx
, uint8_t rt
, uint8_t count
,
18916 uint8_t gp
, uint16_t u
)
18919 TCGv va
= tcg_temp_new();
18920 TCGv t0
= tcg_temp_new();
18922 while (counter
!= count
) {
18923 bool use_gp
= gp
&& (counter
== count
- 1);
18924 int this_rt
= use_gp
? 28 : (rt
& 0x10) | ((rt
+ counter
) & 0x1f);
18925 int this_offset
= u
- ((counter
+ 1) << 2);
18926 gen_base_offset_addr(ctx
, va
, 29, this_offset
);
18927 tcg_gen_qemu_ld_tl(t0
, va
, ctx
->mem_idx
, MO_TESL
|
18928 ctx
->default_tcg_memop_mask
);
18929 tcg_gen_ext32s_tl(t0
, t0
);
18930 gen_store_gpr(t0
, this_rt
);
18934 /* adjust stack pointer */
18935 gen_adjust_sp(ctx
, u
);
18941 static void gen_pool16c_nanomips_insn(DisasContext
*ctx
)
18943 int rt
= decode_gpr_gpr3(NANOMIPS_EXTRACT_RT3(ctx
->opcode
));
18944 int rs
= decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx
->opcode
));
18946 switch (extract32(ctx
->opcode
, 2, 2)) {
18948 gen_logic(ctx
, OPC_NOR
, rt
, rs
, 0);
18951 gen_logic(ctx
, OPC_AND
, rt
, rt
, rs
);
18954 gen_logic(ctx
, OPC_XOR
, rt
, rt
, rs
);
18957 gen_logic(ctx
, OPC_OR
, rt
, rt
, rs
);
18962 static void gen_pool32a0_nanomips_insn(CPUMIPSState
*env
, DisasContext
*ctx
)
18964 int rt
= extract32(ctx
->opcode
, 21, 5);
18965 int rs
= extract32(ctx
->opcode
, 16, 5);
18966 int rd
= extract32(ctx
->opcode
, 11, 5);
18968 switch (extract32(ctx
->opcode
, 3, 7)) {
18970 switch (extract32(ctx
->opcode
, 10, 1)) {
18973 gen_trap(ctx
, OPC_TEQ
, rs
, rt
, -1);
18977 gen_trap(ctx
, OPC_TNE
, rs
, rt
, -1);
18983 gen_rdhwr(ctx
, rt
, rs
, extract32(ctx
->opcode
, 11, 3));
18987 gen_bshfl(ctx
, OPC_SEB
, rs
, rt
);
18990 gen_bshfl(ctx
, OPC_SEH
, rs
, rt
);
18993 gen_shift(ctx
, OPC_SLLV
, rd
, rt
, rs
);
18996 gen_shift(ctx
, OPC_SRLV
, rd
, rt
, rs
);
18999 gen_shift(ctx
, OPC_SRAV
, rd
, rt
, rs
);
19002 gen_shift(ctx
, OPC_ROTRV
, rd
, rt
, rs
);
19005 gen_arith(ctx
, OPC_ADD
, rd
, rs
, rt
);
19008 gen_arith(ctx
, OPC_ADDU
, rd
, rs
, rt
);
19012 gen_arith(ctx
, OPC_SUB
, rd
, rs
, rt
);
19015 gen_arith(ctx
, OPC_SUBU
, rd
, rs
, rt
);
19018 switch (extract32(ctx
->opcode
, 10, 1)) {
19020 gen_cond_move(ctx
, OPC_MOVZ
, rd
, rs
, rt
);
19023 gen_cond_move(ctx
, OPC_MOVN
, rd
, rs
, rt
);
19028 gen_logic(ctx
, OPC_AND
, rd
, rs
, rt
);
19031 gen_logic(ctx
, OPC_OR
, rd
, rs
, rt
);
19034 gen_logic(ctx
, OPC_NOR
, rd
, rs
, rt
);
19037 gen_logic(ctx
, OPC_XOR
, rd
, rs
, rt
);
19040 gen_slt(ctx
, OPC_SLT
, rd
, rs
, rt
);
19045 #ifndef CONFIG_USER_ONLY
19046 TCGv t0
= tcg_temp_new();
19047 switch (extract32(ctx
->opcode
, 10, 1)) {
19050 check_cp0_enabled(ctx
);
19051 gen_helper_dvp(t0
, cpu_env
);
19052 gen_store_gpr(t0
, rt
);
19057 check_cp0_enabled(ctx
);
19058 gen_helper_evp(t0
, cpu_env
);
19059 gen_store_gpr(t0
, rt
);
19066 gen_slt(ctx
, OPC_SLTU
, rd
, rs
, rt
);
19071 TCGv t0
= tcg_temp_new();
19072 TCGv t1
= tcg_temp_new();
19073 TCGv t2
= tcg_temp_new();
19075 gen_load_gpr(t1
, rs
);
19076 gen_load_gpr(t2
, rt
);
19077 tcg_gen_add_tl(t0
, t1
, t2
);
19078 tcg_gen_ext32s_tl(t0
, t0
);
19079 tcg_gen_xor_tl(t1
, t1
, t2
);
19080 tcg_gen_xor_tl(t2
, t0
, t2
);
19081 tcg_gen_andc_tl(t1
, t2
, t1
);
19083 /* operands of same sign, result different sign */
19084 tcg_gen_setcondi_tl(TCG_COND_LT
, t0
, t1
, 0);
19085 gen_store_gpr(t0
, rd
);
19093 gen_r6_muldiv(ctx
, R6_OPC_MUL
, rd
, rs
, rt
);
19096 gen_r6_muldiv(ctx
, R6_OPC_MUH
, rd
, rs
, rt
);
19099 gen_r6_muldiv(ctx
, R6_OPC_MULU
, rd
, rs
, rt
);
19102 gen_r6_muldiv(ctx
, R6_OPC_MUHU
, rd
, rs
, rt
);
19105 gen_r6_muldiv(ctx
, R6_OPC_DIV
, rd
, rs
, rt
);
19108 gen_r6_muldiv(ctx
, R6_OPC_MOD
, rd
, rs
, rt
);
19111 gen_r6_muldiv(ctx
, R6_OPC_DIVU
, rd
, rs
, rt
);
19114 gen_r6_muldiv(ctx
, R6_OPC_MODU
, rd
, rs
, rt
);
19116 #ifndef CONFIG_USER_ONLY
19118 check_cp0_enabled(ctx
);
19120 /* Treat as NOP. */
19123 gen_mfc0(ctx
, cpu_gpr
[rt
], rs
, extract32(ctx
->opcode
, 11, 3));
19126 check_cp0_enabled(ctx
);
19128 TCGv t0
= tcg_temp_new();
19130 gen_load_gpr(t0
, rt
);
19131 gen_mtc0(ctx
, t0
, rs
, extract32(ctx
->opcode
, 11, 3));
19135 case NM_D_E_MT_VPE
:
19137 uint8_t sc
= extract32(ctx
->opcode
, 10, 1);
19138 TCGv t0
= tcg_temp_new();
19145 gen_helper_dmt(t0
);
19146 gen_store_gpr(t0
, rt
);
19147 } else if (rs
== 0) {
19150 gen_helper_dvpe(t0
, cpu_env
);
19151 gen_store_gpr(t0
, rt
);
19153 gen_reserved_instruction(ctx
);
19160 gen_helper_emt(t0
);
19161 gen_store_gpr(t0
, rt
);
19162 } else if (rs
== 0) {
19165 gen_helper_evpe(t0
, cpu_env
);
19166 gen_store_gpr(t0
, rt
);
19168 gen_reserved_instruction(ctx
);
19179 TCGv t0
= tcg_temp_new();
19180 TCGv t1
= tcg_temp_new();
19182 gen_load_gpr(t0
, rt
);
19183 gen_load_gpr(t1
, rs
);
19184 gen_helper_fork(t0
, t1
);
19191 check_cp0_enabled(ctx
);
19193 /* Treat as NOP. */
19196 gen_mftr(env
, ctx
, rs
, rt
, extract32(ctx
->opcode
, 10, 1),
19197 extract32(ctx
->opcode
, 11, 5), extract32(ctx
->opcode
, 3, 1));
19201 check_cp0_enabled(ctx
);
19202 gen_mttr(env
, ctx
, rs
, rt
, extract32(ctx
->opcode
, 10, 1),
19203 extract32(ctx
->opcode
, 11, 5), extract32(ctx
->opcode
, 3, 1));
19208 TCGv t0
= tcg_temp_new();
19210 gen_load_gpr(t0
, rs
);
19211 gen_helper_yield(t0
, cpu_env
, t0
);
19212 gen_store_gpr(t0
, rt
);
19218 gen_reserved_instruction(ctx
);
19224 static void gen_pool32axf_1_5_nanomips_insn(DisasContext
*ctx
, uint32_t opc
,
19225 int ret
, int v1
, int v2
)
19231 t0
= tcg_temp_new_i32();
19233 v0_t
= tcg_temp_new();
19234 v1_t
= tcg_temp_new();
19236 tcg_gen_movi_i32(t0
, v2
>> 3);
19238 gen_load_gpr(v0_t
, ret
);
19239 gen_load_gpr(v1_t
, v1
);
19242 case NM_MAQ_S_W_PHR
:
19244 gen_helper_maq_s_w_phr(t0
, v1_t
, v0_t
, cpu_env
);
19246 case NM_MAQ_S_W_PHL
:
19248 gen_helper_maq_s_w_phl(t0
, v1_t
, v0_t
, cpu_env
);
19250 case NM_MAQ_SA_W_PHR
:
19252 gen_helper_maq_sa_w_phr(t0
, v1_t
, v0_t
, cpu_env
);
19254 case NM_MAQ_SA_W_PHL
:
19256 gen_helper_maq_sa_w_phl(t0
, v1_t
, v0_t
, cpu_env
);
19259 gen_reserved_instruction(ctx
);
19263 tcg_temp_free_i32(t0
);
19265 tcg_temp_free(v0_t
);
19266 tcg_temp_free(v1_t
);
19270 static void gen_pool32axf_1_nanomips_insn(DisasContext
*ctx
, uint32_t opc
,
19271 int ret
, int v1
, int v2
)
19274 TCGv t0
= tcg_temp_new();
19275 TCGv t1
= tcg_temp_new();
19276 TCGv v0_t
= tcg_temp_new();
19278 gen_load_gpr(v0_t
, v1
);
19281 case NM_POOL32AXF_1_0
:
19283 switch (extract32(ctx
->opcode
, 12, 2)) {
19285 gen_HILO(ctx
, OPC_MFHI
, v2
>> 3, ret
);
19288 gen_HILO(ctx
, OPC_MFLO
, v2
>> 3, ret
);
19291 gen_HILO(ctx
, OPC_MTHI
, v2
>> 3, v1
);
19294 gen_HILO(ctx
, OPC_MTLO
, v2
>> 3, v1
);
19298 case NM_POOL32AXF_1_1
:
19300 switch (extract32(ctx
->opcode
, 12, 2)) {
19302 tcg_gen_movi_tl(t0
, v2
);
19303 gen_helper_mthlip(t0
, v0_t
, cpu_env
);
19306 tcg_gen_movi_tl(t0
, v2
>> 3);
19307 gen_helper_shilo(t0
, v0_t
, cpu_env
);
19310 gen_reserved_instruction(ctx
);
19314 case NM_POOL32AXF_1_3
:
19316 imm
= extract32(ctx
->opcode
, 14, 7);
19317 switch (extract32(ctx
->opcode
, 12, 2)) {
19319 tcg_gen_movi_tl(t0
, imm
);
19320 gen_helper_rddsp(t0
, t0
, cpu_env
);
19321 gen_store_gpr(t0
, ret
);
19324 gen_load_gpr(t0
, ret
);
19325 tcg_gen_movi_tl(t1
, imm
);
19326 gen_helper_wrdsp(t0
, t1
, cpu_env
);
19329 tcg_gen_movi_tl(t0
, v2
>> 3);
19330 tcg_gen_movi_tl(t1
, v1
);
19331 gen_helper_extp(t0
, t0
, t1
, cpu_env
);
19332 gen_store_gpr(t0
, ret
);
19335 tcg_gen_movi_tl(t0
, v2
>> 3);
19336 tcg_gen_movi_tl(t1
, v1
);
19337 gen_helper_extpdp(t0
, t0
, t1
, cpu_env
);
19338 gen_store_gpr(t0
, ret
);
19342 case NM_POOL32AXF_1_4
:
19344 tcg_gen_movi_tl(t0
, v2
>> 2);
19345 switch (extract32(ctx
->opcode
, 12, 1)) {
19347 gen_helper_shll_qb(t0
, t0
, v0_t
, cpu_env
);
19348 gen_store_gpr(t0
, ret
);
19351 gen_helper_shrl_qb(t0
, t0
, v0_t
);
19352 gen_store_gpr(t0
, ret
);
19356 case NM_POOL32AXF_1_5
:
19357 opc
= extract32(ctx
->opcode
, 12, 2);
19358 gen_pool32axf_1_5_nanomips_insn(ctx
, opc
, ret
, v1
, v2
);
19360 case NM_POOL32AXF_1_7
:
19362 tcg_gen_movi_tl(t0
, v2
>> 3);
19363 tcg_gen_movi_tl(t1
, v1
);
19364 switch (extract32(ctx
->opcode
, 12, 2)) {
19366 gen_helper_extr_w(t0
, t0
, t1
, cpu_env
);
19367 gen_store_gpr(t0
, ret
);
19370 gen_helper_extr_r_w(t0
, t0
, t1
, cpu_env
);
19371 gen_store_gpr(t0
, ret
);
19374 gen_helper_extr_rs_w(t0
, t0
, t1
, cpu_env
);
19375 gen_store_gpr(t0
, ret
);
19378 gen_helper_extr_s_h(t0
, t0
, t1
, cpu_env
);
19379 gen_store_gpr(t0
, ret
);
19384 gen_reserved_instruction(ctx
);
19390 tcg_temp_free(v0_t
);
19393 static void gen_pool32axf_2_multiply(DisasContext
*ctx
, uint32_t opc
,
19394 TCGv v0
, TCGv v1
, int rd
)
19398 t0
= tcg_temp_new_i32();
19400 tcg_gen_movi_i32(t0
, rd
>> 3);
19403 case NM_POOL32AXF_2_0_7
:
19404 switch (extract32(ctx
->opcode
, 9, 3)) {
19407 gen_helper_dpa_w_ph(t0
, v1
, v0
, cpu_env
);
19409 case NM_DPAQ_S_W_PH
:
19411 gen_helper_dpaq_s_w_ph(t0
, v1
, v0
, cpu_env
);
19415 gen_helper_dps_w_ph(t0
, v1
, v0
, cpu_env
);
19417 case NM_DPSQ_S_W_PH
:
19419 gen_helper_dpsq_s_w_ph(t0
, v1
, v0
, cpu_env
);
19422 gen_reserved_instruction(ctx
);
19426 case NM_POOL32AXF_2_8_15
:
19427 switch (extract32(ctx
->opcode
, 9, 3)) {
19430 gen_helper_dpax_w_ph(t0
, v0
, v1
, cpu_env
);
19432 case NM_DPAQ_SA_L_W
:
19434 gen_helper_dpaq_sa_l_w(t0
, v0
, v1
, cpu_env
);
19438 gen_helper_dpsx_w_ph(t0
, v0
, v1
, cpu_env
);
19440 case NM_DPSQ_SA_L_W
:
19442 gen_helper_dpsq_sa_l_w(t0
, v0
, v1
, cpu_env
);
19445 gen_reserved_instruction(ctx
);
19449 case NM_POOL32AXF_2_16_23
:
19450 switch (extract32(ctx
->opcode
, 9, 3)) {
19451 case NM_DPAU_H_QBL
:
19453 gen_helper_dpau_h_qbl(t0
, v0
, v1
, cpu_env
);
19455 case NM_DPAQX_S_W_PH
:
19457 gen_helper_dpaqx_s_w_ph(t0
, v0
, v1
, cpu_env
);
19459 case NM_DPSU_H_QBL
:
19461 gen_helper_dpsu_h_qbl(t0
, v0
, v1
, cpu_env
);
19463 case NM_DPSQX_S_W_PH
:
19465 gen_helper_dpsqx_s_w_ph(t0
, v0
, v1
, cpu_env
);
19467 case NM_MULSA_W_PH
:
19469 gen_helper_mulsa_w_ph(t0
, v0
, v1
, cpu_env
);
19472 gen_reserved_instruction(ctx
);
19476 case NM_POOL32AXF_2_24_31
:
19477 switch (extract32(ctx
->opcode
, 9, 3)) {
19478 case NM_DPAU_H_QBR
:
19480 gen_helper_dpau_h_qbr(t0
, v1
, v0
, cpu_env
);
19482 case NM_DPAQX_SA_W_PH
:
19484 gen_helper_dpaqx_sa_w_ph(t0
, v1
, v0
, cpu_env
);
19486 case NM_DPSU_H_QBR
:
19488 gen_helper_dpsu_h_qbr(t0
, v1
, v0
, cpu_env
);
19490 case NM_DPSQX_SA_W_PH
:
19492 gen_helper_dpsqx_sa_w_ph(t0
, v1
, v0
, cpu_env
);
19494 case NM_MULSAQ_S_W_PH
:
19496 gen_helper_mulsaq_s_w_ph(t0
, v1
, v0
, cpu_env
);
19499 gen_reserved_instruction(ctx
);
19504 gen_reserved_instruction(ctx
);
19508 tcg_temp_free_i32(t0
);
19511 static void gen_pool32axf_2_nanomips_insn(DisasContext
*ctx
, uint32_t opc
,
19512 int rt
, int rs
, int rd
)
19515 TCGv t0
= tcg_temp_new();
19516 TCGv t1
= tcg_temp_new();
19517 TCGv v0_t
= tcg_temp_new();
19518 TCGv v1_t
= tcg_temp_new();
19520 gen_load_gpr(v0_t
, rt
);
19521 gen_load_gpr(v1_t
, rs
);
19524 case NM_POOL32AXF_2_0_7
:
19525 switch (extract32(ctx
->opcode
, 9, 3)) {
19527 case NM_DPAQ_S_W_PH
:
19529 case NM_DPSQ_S_W_PH
:
19530 gen_pool32axf_2_multiply(ctx
, opc
, v0_t
, v1_t
, rd
);
19535 gen_load_gpr(t0
, rs
);
19537 if (rd
!= 0 && rd
!= 2) {
19538 tcg_gen_shli_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], 8 * rd
);
19539 tcg_gen_ext32u_tl(t0
, t0
);
19540 tcg_gen_shri_tl(t0
, t0
, 8 * (4 - rd
));
19541 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
19543 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
19549 int acc
= extract32(ctx
->opcode
, 14, 2);
19550 TCGv_i64 t2
= tcg_temp_new_i64();
19551 TCGv_i64 t3
= tcg_temp_new_i64();
19553 gen_load_gpr(t0
, rt
);
19554 gen_load_gpr(t1
, rs
);
19555 tcg_gen_ext_tl_i64(t2
, t0
);
19556 tcg_gen_ext_tl_i64(t3
, t1
);
19557 tcg_gen_mul_i64(t2
, t2
, t3
);
19558 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
19559 tcg_gen_add_i64(t2
, t2
, t3
);
19560 tcg_temp_free_i64(t3
);
19561 gen_move_low32(cpu_LO
[acc
], t2
);
19562 gen_move_high32(cpu_HI
[acc
], t2
);
19563 tcg_temp_free_i64(t2
);
19569 int acc
= extract32(ctx
->opcode
, 14, 2);
19570 TCGv_i32 t2
= tcg_temp_new_i32();
19571 TCGv_i32 t3
= tcg_temp_new_i32();
19573 gen_load_gpr(t0
, rs
);
19574 gen_load_gpr(t1
, rt
);
19575 tcg_gen_trunc_tl_i32(t2
, t0
);
19576 tcg_gen_trunc_tl_i32(t3
, t1
);
19577 tcg_gen_muls2_i32(t2
, t3
, t2
, t3
);
19578 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
19579 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
19580 tcg_temp_free_i32(t2
);
19581 tcg_temp_free_i32(t3
);
19586 gen_load_gpr(v1_t
, rs
);
19587 tcg_gen_movi_tl(t0
, rd
>> 3);
19588 gen_helper_extr_w(t0
, t0
, v1_t
, cpu_env
);
19589 gen_store_gpr(t0
, ret
);
19593 case NM_POOL32AXF_2_8_15
:
19594 switch (extract32(ctx
->opcode
, 9, 3)) {
19596 case NM_DPAQ_SA_L_W
:
19598 case NM_DPSQ_SA_L_W
:
19599 gen_pool32axf_2_multiply(ctx
, opc
, v0_t
, v1_t
, rd
);
19604 int acc
= extract32(ctx
->opcode
, 14, 2);
19605 TCGv_i64 t2
= tcg_temp_new_i64();
19606 TCGv_i64 t3
= tcg_temp_new_i64();
19608 gen_load_gpr(t0
, rs
);
19609 gen_load_gpr(t1
, rt
);
19610 tcg_gen_ext32u_tl(t0
, t0
);
19611 tcg_gen_ext32u_tl(t1
, t1
);
19612 tcg_gen_extu_tl_i64(t2
, t0
);
19613 tcg_gen_extu_tl_i64(t3
, t1
);
19614 tcg_gen_mul_i64(t2
, t2
, t3
);
19615 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
19616 tcg_gen_add_i64(t2
, t2
, t3
);
19617 tcg_temp_free_i64(t3
);
19618 gen_move_low32(cpu_LO
[acc
], t2
);
19619 gen_move_high32(cpu_HI
[acc
], t2
);
19620 tcg_temp_free_i64(t2
);
19626 int acc
= extract32(ctx
->opcode
, 14, 2);
19627 TCGv_i32 t2
= tcg_temp_new_i32();
19628 TCGv_i32 t3
= tcg_temp_new_i32();
19630 gen_load_gpr(t0
, rs
);
19631 gen_load_gpr(t1
, rt
);
19632 tcg_gen_trunc_tl_i32(t2
, t0
);
19633 tcg_gen_trunc_tl_i32(t3
, t1
);
19634 tcg_gen_mulu2_i32(t2
, t3
, t2
, t3
);
19635 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
19636 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
19637 tcg_temp_free_i32(t2
);
19638 tcg_temp_free_i32(t3
);
19643 tcg_gen_movi_tl(t0
, rd
>> 3);
19644 gen_helper_extr_r_w(t0
, t0
, v1_t
, cpu_env
);
19645 gen_store_gpr(t0
, ret
);
19648 gen_reserved_instruction(ctx
);
19652 case NM_POOL32AXF_2_16_23
:
19653 switch (extract32(ctx
->opcode
, 9, 3)) {
19654 case NM_DPAU_H_QBL
:
19655 case NM_DPAQX_S_W_PH
:
19656 case NM_DPSU_H_QBL
:
19657 case NM_DPSQX_S_W_PH
:
19658 case NM_MULSA_W_PH
:
19659 gen_pool32axf_2_multiply(ctx
, opc
, v0_t
, v1_t
, rd
);
19663 tcg_gen_movi_tl(t0
, rd
>> 3);
19664 gen_helper_extp(t0
, t0
, v1_t
, cpu_env
);
19665 gen_store_gpr(t0
, ret
);
19670 int acc
= extract32(ctx
->opcode
, 14, 2);
19671 TCGv_i64 t2
= tcg_temp_new_i64();
19672 TCGv_i64 t3
= tcg_temp_new_i64();
19674 gen_load_gpr(t0
, rs
);
19675 gen_load_gpr(t1
, rt
);
19676 tcg_gen_ext_tl_i64(t2
, t0
);
19677 tcg_gen_ext_tl_i64(t3
, t1
);
19678 tcg_gen_mul_i64(t2
, t2
, t3
);
19679 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
19680 tcg_gen_sub_i64(t2
, t3
, t2
);
19681 tcg_temp_free_i64(t3
);
19682 gen_move_low32(cpu_LO
[acc
], t2
);
19683 gen_move_high32(cpu_HI
[acc
], t2
);
19684 tcg_temp_free_i64(t2
);
19687 case NM_EXTRV_RS_W
:
19689 tcg_gen_movi_tl(t0
, rd
>> 3);
19690 gen_helper_extr_rs_w(t0
, t0
, v1_t
, cpu_env
);
19691 gen_store_gpr(t0
, ret
);
19695 case NM_POOL32AXF_2_24_31
:
19696 switch (extract32(ctx
->opcode
, 9, 3)) {
19697 case NM_DPAU_H_QBR
:
19698 case NM_DPAQX_SA_W_PH
:
19699 case NM_DPSU_H_QBR
:
19700 case NM_DPSQX_SA_W_PH
:
19701 case NM_MULSAQ_S_W_PH
:
19702 gen_pool32axf_2_multiply(ctx
, opc
, v0_t
, v1_t
, rd
);
19706 tcg_gen_movi_tl(t0
, rd
>> 3);
19707 gen_helper_extpdp(t0
, t0
, v1_t
, cpu_env
);
19708 gen_store_gpr(t0
, ret
);
19713 int acc
= extract32(ctx
->opcode
, 14, 2);
19714 TCGv_i64 t2
= tcg_temp_new_i64();
19715 TCGv_i64 t3
= tcg_temp_new_i64();
19717 gen_load_gpr(t0
, rs
);
19718 gen_load_gpr(t1
, rt
);
19719 tcg_gen_ext32u_tl(t0
, t0
);
19720 tcg_gen_ext32u_tl(t1
, t1
);
19721 tcg_gen_extu_tl_i64(t2
, t0
);
19722 tcg_gen_extu_tl_i64(t3
, t1
);
19723 tcg_gen_mul_i64(t2
, t2
, t3
);
19724 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
19725 tcg_gen_sub_i64(t2
, t3
, t2
);
19726 tcg_temp_free_i64(t3
);
19727 gen_move_low32(cpu_LO
[acc
], t2
);
19728 gen_move_high32(cpu_HI
[acc
], t2
);
19729 tcg_temp_free_i64(t2
);
19734 tcg_gen_movi_tl(t0
, rd
>> 3);
19735 gen_helper_extr_s_h(t0
, t0
, v0_t
, cpu_env
);
19736 gen_store_gpr(t0
, ret
);
19741 gen_reserved_instruction(ctx
);
19748 tcg_temp_free(v0_t
);
19749 tcg_temp_free(v1_t
);
19752 static void gen_pool32axf_4_nanomips_insn(DisasContext
*ctx
, uint32_t opc
,
19756 TCGv t0
= tcg_temp_new();
19757 TCGv v0_t
= tcg_temp_new();
19759 gen_load_gpr(v0_t
, rs
);
19764 gen_helper_absq_s_qb(v0_t
, v0_t
, cpu_env
);
19765 gen_store_gpr(v0_t
, ret
);
19769 gen_helper_absq_s_ph(v0_t
, v0_t
, cpu_env
);
19770 gen_store_gpr(v0_t
, ret
);
19774 gen_helper_absq_s_w(v0_t
, v0_t
, cpu_env
);
19775 gen_store_gpr(v0_t
, ret
);
19777 case NM_PRECEQ_W_PHL
:
19779 tcg_gen_andi_tl(v0_t
, v0_t
, 0xFFFF0000);
19780 tcg_gen_ext32s_tl(v0_t
, v0_t
);
19781 gen_store_gpr(v0_t
, ret
);
19783 case NM_PRECEQ_W_PHR
:
19785 tcg_gen_andi_tl(v0_t
, v0_t
, 0x0000FFFF);
19786 tcg_gen_shli_tl(v0_t
, v0_t
, 16);
19787 tcg_gen_ext32s_tl(v0_t
, v0_t
);
19788 gen_store_gpr(v0_t
, ret
);
19790 case NM_PRECEQU_PH_QBL
:
19792 gen_helper_precequ_ph_qbl(v0_t
, v0_t
);
19793 gen_store_gpr(v0_t
, ret
);
19795 case NM_PRECEQU_PH_QBR
:
19797 gen_helper_precequ_ph_qbr(v0_t
, v0_t
);
19798 gen_store_gpr(v0_t
, ret
);
19800 case NM_PRECEQU_PH_QBLA
:
19802 gen_helper_precequ_ph_qbla(v0_t
, v0_t
);
19803 gen_store_gpr(v0_t
, ret
);
19805 case NM_PRECEQU_PH_QBRA
:
19807 gen_helper_precequ_ph_qbra(v0_t
, v0_t
);
19808 gen_store_gpr(v0_t
, ret
);
19810 case NM_PRECEU_PH_QBL
:
19812 gen_helper_preceu_ph_qbl(v0_t
, v0_t
);
19813 gen_store_gpr(v0_t
, ret
);
19815 case NM_PRECEU_PH_QBR
:
19817 gen_helper_preceu_ph_qbr(v0_t
, v0_t
);
19818 gen_store_gpr(v0_t
, ret
);
19820 case NM_PRECEU_PH_QBLA
:
19822 gen_helper_preceu_ph_qbla(v0_t
, v0_t
);
19823 gen_store_gpr(v0_t
, ret
);
19825 case NM_PRECEU_PH_QBRA
:
19827 gen_helper_preceu_ph_qbra(v0_t
, v0_t
);
19828 gen_store_gpr(v0_t
, ret
);
19832 tcg_gen_ext16u_tl(v0_t
, v0_t
);
19833 tcg_gen_shli_tl(t0
, v0_t
, 16);
19834 tcg_gen_or_tl(v0_t
, v0_t
, t0
);
19835 tcg_gen_ext32s_tl(v0_t
, v0_t
);
19836 gen_store_gpr(v0_t
, ret
);
19840 tcg_gen_ext8u_tl(v0_t
, v0_t
);
19841 tcg_gen_shli_tl(t0
, v0_t
, 8);
19842 tcg_gen_or_tl(v0_t
, v0_t
, t0
);
19843 tcg_gen_shli_tl(t0
, v0_t
, 16);
19844 tcg_gen_or_tl(v0_t
, v0_t
, t0
);
19845 tcg_gen_ext32s_tl(v0_t
, v0_t
);
19846 gen_store_gpr(v0_t
, ret
);
19850 gen_helper_bitrev(v0_t
, v0_t
);
19851 gen_store_gpr(v0_t
, ret
);
19856 TCGv tv0
= tcg_temp_new();
19858 gen_load_gpr(tv0
, rt
);
19859 gen_helper_insv(v0_t
, cpu_env
, v0_t
, tv0
);
19860 gen_store_gpr(v0_t
, ret
);
19861 tcg_temp_free(tv0
);
19864 case NM_RADDU_W_QB
:
19866 gen_helper_raddu_w_qb(v0_t
, v0_t
);
19867 gen_store_gpr(v0_t
, ret
);
19870 gen_bitswap(ctx
, OPC_BITSWAP
, ret
, rs
);
19874 gen_cl(ctx
, OPC_CLO
, ret
, rs
);
19878 gen_cl(ctx
, OPC_CLZ
, ret
, rs
);
19881 gen_bshfl(ctx
, OPC_WSBH
, ret
, rs
);
19884 gen_reserved_instruction(ctx
);
19888 tcg_temp_free(v0_t
);
19892 static void gen_pool32axf_7_nanomips_insn(DisasContext
*ctx
, uint32_t opc
,
19893 int rt
, int rs
, int rd
)
19895 TCGv t0
= tcg_temp_new();
19896 TCGv rs_t
= tcg_temp_new();
19898 gen_load_gpr(rs_t
, rs
);
19903 tcg_gen_movi_tl(t0
, rd
>> 2);
19904 switch (extract32(ctx
->opcode
, 12, 1)) {
19907 gen_helper_shra_qb(t0
, t0
, rs_t
);
19908 gen_store_gpr(t0
, rt
);
19912 gen_helper_shra_r_qb(t0
, t0
, rs_t
);
19913 gen_store_gpr(t0
, rt
);
19919 tcg_gen_movi_tl(t0
, rd
>> 1);
19920 gen_helper_shrl_ph(t0
, t0
, rs_t
);
19921 gen_store_gpr(t0
, rt
);
19927 target_long result
;
19928 imm
= extract32(ctx
->opcode
, 13, 8);
19929 result
= (uint32_t)imm
<< 24 |
19930 (uint32_t)imm
<< 16 |
19931 (uint32_t)imm
<< 8 |
19933 result
= (int32_t)result
;
19934 tcg_gen_movi_tl(t0
, result
);
19935 gen_store_gpr(t0
, rt
);
19939 gen_reserved_instruction(ctx
);
19943 tcg_temp_free(rs_t
);
19947 static void gen_pool32axf_nanomips_insn(CPUMIPSState
*env
, DisasContext
*ctx
)
19949 int rt
= extract32(ctx
->opcode
, 21, 5);
19950 int rs
= extract32(ctx
->opcode
, 16, 5);
19951 int rd
= extract32(ctx
->opcode
, 11, 5);
19953 switch (extract32(ctx
->opcode
, 6, 3)) {
19954 case NM_POOL32AXF_1
:
19956 int32_t op1
= extract32(ctx
->opcode
, 9, 3);
19957 gen_pool32axf_1_nanomips_insn(ctx
, op1
, rt
, rs
, rd
);
19960 case NM_POOL32AXF_2
:
19962 int32_t op1
= extract32(ctx
->opcode
, 12, 2);
19963 gen_pool32axf_2_nanomips_insn(ctx
, op1
, rt
, rs
, rd
);
19966 case NM_POOL32AXF_4
:
19968 int32_t op1
= extract32(ctx
->opcode
, 9, 7);
19969 gen_pool32axf_4_nanomips_insn(ctx
, op1
, rt
, rs
);
19972 case NM_POOL32AXF_5
:
19973 switch (extract32(ctx
->opcode
, 9, 7)) {
19974 #ifndef CONFIG_USER_ONLY
19976 gen_cp0(env
, ctx
, OPC_TLBP
, 0, 0);
19979 gen_cp0(env
, ctx
, OPC_TLBR
, 0, 0);
19982 gen_cp0(env
, ctx
, OPC_TLBWI
, 0, 0);
19985 gen_cp0(env
, ctx
, OPC_TLBWR
, 0, 0);
19988 gen_cp0(env
, ctx
, OPC_TLBINV
, 0, 0);
19991 gen_cp0(env
, ctx
, OPC_TLBINVF
, 0, 0);
19994 check_cp0_enabled(ctx
);
19996 TCGv t0
= tcg_temp_new();
19998 save_cpu_state(ctx
, 1);
19999 gen_helper_di(t0
, cpu_env
);
20000 gen_store_gpr(t0
, rt
);
20001 /* Stop translation as we may have switched the execution mode */
20002 ctx
->base
.is_jmp
= DISAS_STOP
;
20007 check_cp0_enabled(ctx
);
20009 TCGv t0
= tcg_temp_new();
20011 save_cpu_state(ctx
, 1);
20012 gen_helper_ei(t0
, cpu_env
);
20013 gen_store_gpr(t0
, rt
);
20014 /* Stop translation as we may have switched the execution mode */
20015 ctx
->base
.is_jmp
= DISAS_STOP
;
20020 gen_load_srsgpr(rs
, rt
);
20023 gen_store_srsgpr(rs
, rt
);
20026 gen_cp0(env
, ctx
, OPC_WAIT
, 0, 0);
20029 gen_cp0(env
, ctx
, OPC_DERET
, 0, 0);
20032 gen_cp0(env
, ctx
, OPC_ERET
, 0, 0);
20036 gen_reserved_instruction(ctx
);
20040 case NM_POOL32AXF_7
:
20042 int32_t op1
= extract32(ctx
->opcode
, 9, 3);
20043 gen_pool32axf_7_nanomips_insn(ctx
, op1
, rt
, rs
, rd
);
20047 gen_reserved_instruction(ctx
);
20052 /* Immediate Value Compact Branches */
20053 static void gen_compute_imm_branch(DisasContext
*ctx
, uint32_t opc
,
20054 int rt
, int32_t imm
, int32_t offset
)
20056 TCGCond cond
= TCG_COND_ALWAYS
;
20057 TCGv t0
= tcg_temp_new();
20058 TCGv t1
= tcg_temp_new();
20060 gen_load_gpr(t0
, rt
);
20061 tcg_gen_movi_tl(t1
, imm
);
20062 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
20064 /* Load needed operands and calculate btarget */
20067 if (rt
== 0 && imm
== 0) {
20068 /* Unconditional branch */
20069 } else if (rt
== 0 && imm
!= 0) {
20073 cond
= TCG_COND_EQ
;
20079 if (imm
>= 32 && !(ctx
->hflags
& MIPS_HFLAG_64
)) {
20080 gen_reserved_instruction(ctx
);
20082 } else if (rt
== 0 && opc
== NM_BBEQZC
) {
20083 /* Unconditional branch */
20084 } else if (rt
== 0 && opc
== NM_BBNEZC
) {
20088 tcg_gen_shri_tl(t0
, t0
, imm
);
20089 tcg_gen_andi_tl(t0
, t0
, 1);
20090 tcg_gen_movi_tl(t1
, 0);
20091 if (opc
== NM_BBEQZC
) {
20092 cond
= TCG_COND_EQ
;
20094 cond
= TCG_COND_NE
;
20099 if (rt
== 0 && imm
== 0) {
20102 } else if (rt
== 0 && imm
!= 0) {
20103 /* Unconditional branch */
20105 cond
= TCG_COND_NE
;
20109 if (rt
== 0 && imm
== 0) {
20110 /* Unconditional branch */
20112 cond
= TCG_COND_GE
;
20116 cond
= TCG_COND_LT
;
20119 if (rt
== 0 && imm
== 0) {
20120 /* Unconditional branch */
20122 cond
= TCG_COND_GEU
;
20126 cond
= TCG_COND_LTU
;
20129 MIPS_INVAL("Immediate Value Compact branch");
20130 gen_reserved_instruction(ctx
);
20134 /* branch completion */
20135 clear_branch_hflags(ctx
);
20136 ctx
->base
.is_jmp
= DISAS_NORETURN
;
20138 if (cond
== TCG_COND_ALWAYS
) {
20139 /* Uncoditional compact branch */
20140 gen_goto_tb(ctx
, 0, ctx
->btarget
);
20142 /* Conditional compact branch */
20143 TCGLabel
*fs
= gen_new_label();
20145 tcg_gen_brcond_tl(tcg_invert_cond(cond
), t0
, t1
, fs
);
20147 gen_goto_tb(ctx
, 1, ctx
->btarget
);
20150 gen_goto_tb(ctx
, 0, ctx
->base
.pc_next
+ 4);
20158 /* P.BALRSC type nanoMIPS R6 branches: BALRSC and BRSC */
20159 static void gen_compute_nanomips_pbalrsc_branch(DisasContext
*ctx
, int rs
,
20162 TCGv t0
= tcg_temp_new();
20163 TCGv t1
= tcg_temp_new();
20166 gen_load_gpr(t0
, rs
);
20170 tcg_gen_movi_tl(cpu_gpr
[rt
], ctx
->base
.pc_next
+ 4);
20173 /* calculate btarget */
20174 tcg_gen_shli_tl(t0
, t0
, 1);
20175 tcg_gen_movi_tl(t1
, ctx
->base
.pc_next
+ 4);
20176 gen_op_addr_add(ctx
, btarget
, t1
, t0
);
20178 /* branch completion */
20179 clear_branch_hflags(ctx
);
20180 ctx
->base
.is_jmp
= DISAS_NORETURN
;
20182 /* unconditional branch to register */
20183 tcg_gen_mov_tl(cpu_PC
, btarget
);
20184 tcg_gen_lookup_and_goto_ptr();
20190 /* nanoMIPS Branches */
20191 static void gen_compute_compact_branch_nm(DisasContext
*ctx
, uint32_t opc
,
20192 int rs
, int rt
, int32_t offset
)
20194 int bcond_compute
= 0;
20195 TCGv t0
= tcg_temp_new();
20196 TCGv t1
= tcg_temp_new();
20198 /* Load needed operands and calculate btarget */
20200 /* compact branch */
20203 gen_load_gpr(t0
, rs
);
20204 gen_load_gpr(t1
, rt
);
20206 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
20210 if (rs
== 0 || rs
== rt
) {
20211 /* OPC_BLEZALC, OPC_BGEZALC */
20212 /* OPC_BGTZALC, OPC_BLTZALC */
20213 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 4);
20215 gen_load_gpr(t0
, rs
);
20216 gen_load_gpr(t1
, rt
);
20218 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
20221 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
20225 /* OPC_BEQZC, OPC_BNEZC */
20226 gen_load_gpr(t0
, rs
);
20228 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
20230 /* OPC_JIC, OPC_JIALC */
20231 TCGv tbase
= tcg_temp_new();
20232 TCGv toffset
= tcg_temp_new();
20234 gen_load_gpr(tbase
, rt
);
20235 tcg_gen_movi_tl(toffset
, offset
);
20236 gen_op_addr_add(ctx
, btarget
, tbase
, toffset
);
20237 tcg_temp_free(tbase
);
20238 tcg_temp_free(toffset
);
20242 MIPS_INVAL("Compact branch/jump");
20243 gen_reserved_instruction(ctx
);
20247 if (bcond_compute
== 0) {
20248 /* Uncoditional compact branch */
20251 gen_goto_tb(ctx
, 0, ctx
->btarget
);
20254 MIPS_INVAL("Compact branch/jump");
20255 gen_reserved_instruction(ctx
);
20259 /* Conditional compact branch */
20260 TCGLabel
*fs
= gen_new_label();
20264 if (rs
== 0 && rt
!= 0) {
20266 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE
), t1
, 0, fs
);
20267 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
20269 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE
), t1
, 0, fs
);
20272 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU
), t0
, t1
, fs
);
20276 if (rs
== 0 && rt
!= 0) {
20278 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT
), t1
, 0, fs
);
20279 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
20281 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT
), t1
, 0, fs
);
20284 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU
), t0
, t1
, fs
);
20288 if (rs
== 0 && rt
!= 0) {
20290 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE
), t1
, 0, fs
);
20291 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
20293 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE
), t1
, 0, fs
);
20296 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE
), t0
, t1
, fs
);
20300 if (rs
== 0 && rt
!= 0) {
20302 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT
), t1
, 0, fs
);
20303 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
20305 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT
), t1
, 0, fs
);
20308 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT
), t0
, t1
, fs
);
20312 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ
), t0
, 0, fs
);
20315 MIPS_INVAL("Compact conditional branch/jump");
20316 gen_reserved_instruction(ctx
);
20320 /* branch completion */
20321 clear_branch_hflags(ctx
);
20322 ctx
->base
.is_jmp
= DISAS_NORETURN
;
20324 /* Generating branch here as compact branches don't have delay slot */
20325 gen_goto_tb(ctx
, 1, ctx
->btarget
);
20328 gen_goto_tb(ctx
, 0, ctx
->base
.pc_next
+ 4);
20337 /* nanoMIPS CP1 Branches */
20338 static void gen_compute_branch_cp1_nm(DisasContext
*ctx
, uint32_t op
,
20339 int32_t ft
, int32_t offset
)
20341 target_ulong btarget
;
20342 TCGv_i64 t0
= tcg_temp_new_i64();
20344 gen_load_fpr64(ctx
, t0
, ft
);
20345 tcg_gen_andi_i64(t0
, t0
, 1);
20347 btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
20351 tcg_gen_xori_i64(t0
, t0
, 1);
20352 ctx
->hflags
|= MIPS_HFLAG_BC
;
20355 /* t0 already set */
20356 ctx
->hflags
|= MIPS_HFLAG_BC
;
20359 MIPS_INVAL("cp1 cond branch");
20360 gen_reserved_instruction(ctx
);
20364 tcg_gen_trunc_i64_tl(bcond
, t0
);
20366 ctx
->btarget
= btarget
;
20369 tcg_temp_free_i64(t0
);
20373 static void gen_p_lsx(DisasContext
*ctx
, int rd
, int rs
, int rt
)
20376 t0
= tcg_temp_new();
20377 t1
= tcg_temp_new();
20379 gen_load_gpr(t0
, rs
);
20380 gen_load_gpr(t1
, rt
);
20382 if ((extract32(ctx
->opcode
, 6, 1)) == 1) {
20383 /* PP.LSXS instructions require shifting */
20384 switch (extract32(ctx
->opcode
, 7, 4)) {
20390 tcg_gen_shli_tl(t0
, t0
, 1);
20398 tcg_gen_shli_tl(t0
, t0
, 2);
20402 tcg_gen_shli_tl(t0
, t0
, 3);
20406 gen_op_addr_add(ctx
, t0
, t0
, t1
);
20408 switch (extract32(ctx
->opcode
, 7, 4)) {
20410 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
,
20412 gen_store_gpr(t0
, rd
);
20416 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
,
20418 gen_store_gpr(t0
, rd
);
20422 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
,
20424 gen_store_gpr(t0
, rd
);
20427 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
,
20429 gen_store_gpr(t0
, rd
);
20433 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
,
20435 gen_store_gpr(t0
, rd
);
20439 gen_load_gpr(t1
, rd
);
20440 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
,
20446 gen_load_gpr(t1
, rd
);
20447 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
,
20453 gen_load_gpr(t1
, rd
);
20454 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
,
20458 /*case NM_LWC1XS:*/
20460 /*case NM_LDC1XS:*/
20462 /*case NM_SWC1XS:*/
20464 /*case NM_SDC1XS:*/
20465 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
20466 check_cp1_enabled(ctx
);
20467 switch (extract32(ctx
->opcode
, 7, 4)) {
20469 /*case NM_LWC1XS:*/
20470 gen_flt_ldst(ctx
, OPC_LWC1
, rd
, t0
);
20473 /*case NM_LDC1XS:*/
20474 gen_flt_ldst(ctx
, OPC_LDC1
, rd
, t0
);
20477 /*case NM_SWC1XS:*/
20478 gen_flt_ldst(ctx
, OPC_SWC1
, rd
, t0
);
20481 /*case NM_SDC1XS:*/
20482 gen_flt_ldst(ctx
, OPC_SDC1
, rd
, t0
);
20486 generate_exception_err(ctx
, EXCP_CpU
, 1);
20490 gen_reserved_instruction(ctx
);
20498 static void gen_pool32f_nanomips_insn(DisasContext
*ctx
)
20502 rt
= extract32(ctx
->opcode
, 21, 5);
20503 rs
= extract32(ctx
->opcode
, 16, 5);
20504 rd
= extract32(ctx
->opcode
, 11, 5);
20506 if (!(ctx
->CP0_Config1
& (1 << CP0C1_FP
))) {
20507 gen_reserved_instruction(ctx
);
20510 check_cp1_enabled(ctx
);
20511 switch (extract32(ctx
->opcode
, 0, 3)) {
20513 switch (extract32(ctx
->opcode
, 3, 7)) {
20515 gen_farith(ctx
, OPC_RINT_S
, 0, rt
, rs
, 0);
20518 gen_farith(ctx
, OPC_RINT_D
, 0, rt
, rs
, 0);
20521 gen_farith(ctx
, OPC_CLASS_S
, 0, rt
, rs
, 0);
20524 gen_farith(ctx
, OPC_CLASS_D
, 0, rt
, rs
, 0);
20527 gen_farith(ctx
, OPC_ADD_S
, rt
, rs
, rd
, 0);
20530 gen_farith(ctx
, OPC_ADD_D
, rt
, rs
, rd
, 0);
20533 gen_farith(ctx
, OPC_SUB_S
, rt
, rs
, rd
, 0);
20536 gen_farith(ctx
, OPC_SUB_D
, rt
, rs
, rd
, 0);
20539 gen_farith(ctx
, OPC_MUL_S
, rt
, rs
, rd
, 0);
20542 gen_farith(ctx
, OPC_MUL_D
, rt
, rs
, rd
, 0);
20545 gen_farith(ctx
, OPC_DIV_S
, rt
, rs
, rd
, 0);
20548 gen_farith(ctx
, OPC_DIV_D
, rt
, rs
, rd
, 0);
20551 gen_sel_s(ctx
, OPC_SELEQZ_S
, rd
, rt
, rs
);
20554 gen_sel_d(ctx
, OPC_SELEQZ_D
, rd
, rt
, rs
);
20557 gen_sel_s(ctx
, OPC_SELNEZ_S
, rd
, rt
, rs
);
20560 gen_sel_d(ctx
, OPC_SELNEZ_D
, rd
, rt
, rs
);
20563 gen_sel_s(ctx
, OPC_SEL_S
, rd
, rt
, rs
);
20566 gen_sel_d(ctx
, OPC_SEL_D
, rd
, rt
, rs
);
20569 gen_farith(ctx
, OPC_MADDF_S
, rt
, rs
, rd
, 0);
20572 gen_farith(ctx
, OPC_MADDF_D
, rt
, rs
, rd
, 0);
20575 gen_farith(ctx
, OPC_MSUBF_S
, rt
, rs
, rd
, 0);
20578 gen_farith(ctx
, OPC_MSUBF_D
, rt
, rs
, rd
, 0);
20581 gen_reserved_instruction(ctx
);
20586 switch (extract32(ctx
->opcode
, 3, 3)) {
20588 switch (extract32(ctx
->opcode
, 9, 1)) {
20590 gen_farith(ctx
, OPC_MIN_S
, rt
, rs
, rd
, 0);
20593 gen_farith(ctx
, OPC_MIN_D
, rt
, rs
, rd
, 0);
20598 switch (extract32(ctx
->opcode
, 9, 1)) {
20600 gen_farith(ctx
, OPC_MAX_S
, rt
, rs
, rd
, 0);
20603 gen_farith(ctx
, OPC_MAX_D
, rt
, rs
, rd
, 0);
20608 switch (extract32(ctx
->opcode
, 9, 1)) {
20610 gen_farith(ctx
, OPC_MINA_S
, rt
, rs
, rd
, 0);
20613 gen_farith(ctx
, OPC_MINA_D
, rt
, rs
, rd
, 0);
20618 switch (extract32(ctx
->opcode
, 9, 1)) {
20620 gen_farith(ctx
, OPC_MAXA_S
, rt
, rs
, rd
, 0);
20623 gen_farith(ctx
, OPC_MAXA_D
, rt
, rs
, rd
, 0);
20628 switch (extract32(ctx
->opcode
, 6, 8)) {
20630 gen_cp1(ctx
, OPC_CFC1
, rt
, rs
);
20633 gen_cp1(ctx
, OPC_CTC1
, rt
, rs
);
20636 gen_cp1(ctx
, OPC_MFC1
, rt
, rs
);
20639 gen_cp1(ctx
, OPC_MTC1
, rt
, rs
);
20642 gen_cp1(ctx
, OPC_MFHC1
, rt
, rs
);
20645 gen_cp1(ctx
, OPC_MTHC1
, rt
, rs
);
20648 gen_farith(ctx
, OPC_CVT_S_PL
, -1, rs
, rt
, 0);
20651 gen_farith(ctx
, OPC_CVT_S_PU
, -1, rs
, rt
, 0);
20654 switch (extract32(ctx
->opcode
, 6, 9)) {
20656 gen_farith(ctx
, OPC_CVT_L_S
, -1, rs
, rt
, 0);
20659 gen_farith(ctx
, OPC_CVT_L_D
, -1, rs
, rt
, 0);
20662 gen_farith(ctx
, OPC_CVT_W_S
, -1, rs
, rt
, 0);
20665 gen_farith(ctx
, OPC_CVT_W_D
, -1, rs
, rt
, 0);
20668 gen_farith(ctx
, OPC_RSQRT_S
, -1, rs
, rt
, 0);
20671 gen_farith(ctx
, OPC_RSQRT_D
, -1, rs
, rt
, 0);
20674 gen_farith(ctx
, OPC_SQRT_S
, -1, rs
, rt
, 0);
20677 gen_farith(ctx
, OPC_SQRT_D
, -1, rs
, rt
, 0);
20680 gen_farith(ctx
, OPC_RECIP_S
, -1, rs
, rt
, 0);
20683 gen_farith(ctx
, OPC_RECIP_D
, -1, rs
, rt
, 0);
20686 gen_farith(ctx
, OPC_FLOOR_L_S
, -1, rs
, rt
, 0);
20689 gen_farith(ctx
, OPC_FLOOR_L_D
, -1, rs
, rt
, 0);
20692 gen_farith(ctx
, OPC_FLOOR_W_S
, -1, rs
, rt
, 0);
20695 gen_farith(ctx
, OPC_FLOOR_W_D
, -1, rs
, rt
, 0);
20698 gen_farith(ctx
, OPC_CEIL_L_S
, -1, rs
, rt
, 0);
20701 gen_farith(ctx
, OPC_CEIL_L_D
, -1, rs
, rt
, 0);
20704 gen_farith(ctx
, OPC_CEIL_W_S
, -1, rs
, rt
, 0);
20707 gen_farith(ctx
, OPC_CEIL_W_D
, -1, rs
, rt
, 0);
20710 gen_farith(ctx
, OPC_TRUNC_L_S
, -1, rs
, rt
, 0);
20713 gen_farith(ctx
, OPC_TRUNC_L_D
, -1, rs
, rt
, 0);
20716 gen_farith(ctx
, OPC_TRUNC_W_S
, -1, rs
, rt
, 0);
20719 gen_farith(ctx
, OPC_TRUNC_W_D
, -1, rs
, rt
, 0);
20722 gen_farith(ctx
, OPC_ROUND_L_S
, -1, rs
, rt
, 0);
20725 gen_farith(ctx
, OPC_ROUND_L_D
, -1, rs
, rt
, 0);
20728 gen_farith(ctx
, OPC_ROUND_W_S
, -1, rs
, rt
, 0);
20731 gen_farith(ctx
, OPC_ROUND_W_D
, -1, rs
, rt
, 0);
20734 gen_farith(ctx
, OPC_MOV_S
, -1, rs
, rt
, 0);
20737 gen_farith(ctx
, OPC_MOV_D
, -1, rs
, rt
, 0);
20740 gen_farith(ctx
, OPC_ABS_S
, -1, rs
, rt
, 0);
20743 gen_farith(ctx
, OPC_ABS_D
, -1, rs
, rt
, 0);
20746 gen_farith(ctx
, OPC_NEG_S
, -1, rs
, rt
, 0);
20749 gen_farith(ctx
, OPC_NEG_D
, -1, rs
, rt
, 0);
20752 gen_farith(ctx
, OPC_CVT_D_S
, -1, rs
, rt
, 0);
20755 gen_farith(ctx
, OPC_CVT_D_W
, -1, rs
, rt
, 0);
20758 gen_farith(ctx
, OPC_CVT_D_L
, -1, rs
, rt
, 0);
20761 gen_farith(ctx
, OPC_CVT_S_D
, -1, rs
, rt
, 0);
20764 gen_farith(ctx
, OPC_CVT_S_W
, -1, rs
, rt
, 0);
20767 gen_farith(ctx
, OPC_CVT_S_L
, -1, rs
, rt
, 0);
20770 gen_reserved_instruction(ctx
);
20779 switch (extract32(ctx
->opcode
, 3, 3)) {
20780 case NM_CMP_CONDN_S
:
20781 gen_r6_cmp_s(ctx
, extract32(ctx
->opcode
, 6, 5), rt
, rs
, rd
);
20783 case NM_CMP_CONDN_D
:
20784 gen_r6_cmp_d(ctx
, extract32(ctx
->opcode
, 6, 5), rt
, rs
, rd
);
20787 gen_reserved_instruction(ctx
);
20792 gen_reserved_instruction(ctx
);
20797 static void gen_pool32a5_nanomips_insn(DisasContext
*ctx
, int opc
,
20798 int rd
, int rs
, int rt
)
20801 TCGv t0
= tcg_temp_new();
20802 TCGv v1_t
= tcg_temp_new();
20803 TCGv v2_t
= tcg_temp_new();
20805 gen_load_gpr(v1_t
, rs
);
20806 gen_load_gpr(v2_t
, rt
);
20811 gen_helper_cmp_eq_ph(v1_t
, v2_t
, cpu_env
);
20815 gen_helper_cmp_lt_ph(v1_t
, v2_t
, cpu_env
);
20819 gen_helper_cmp_le_ph(v1_t
, v2_t
, cpu_env
);
20821 case NM_CMPU_EQ_QB
:
20823 gen_helper_cmpu_eq_qb(v1_t
, v2_t
, cpu_env
);
20825 case NM_CMPU_LT_QB
:
20827 gen_helper_cmpu_lt_qb(v1_t
, v2_t
, cpu_env
);
20829 case NM_CMPU_LE_QB
:
20831 gen_helper_cmpu_le_qb(v1_t
, v2_t
, cpu_env
);
20833 case NM_CMPGU_EQ_QB
:
20835 gen_helper_cmpgu_eq_qb(v1_t
, v1_t
, v2_t
);
20836 gen_store_gpr(v1_t
, ret
);
20838 case NM_CMPGU_LT_QB
:
20840 gen_helper_cmpgu_lt_qb(v1_t
, v1_t
, v2_t
);
20841 gen_store_gpr(v1_t
, ret
);
20843 case NM_CMPGU_LE_QB
:
20845 gen_helper_cmpgu_le_qb(v1_t
, v1_t
, v2_t
);
20846 gen_store_gpr(v1_t
, ret
);
20848 case NM_CMPGDU_EQ_QB
:
20850 gen_helper_cmpgu_eq_qb(v1_t
, v1_t
, v2_t
);
20851 tcg_gen_deposit_tl(cpu_dspctrl
, cpu_dspctrl
, v1_t
, 24, 4);
20852 gen_store_gpr(v1_t
, ret
);
20854 case NM_CMPGDU_LT_QB
:
20856 gen_helper_cmpgu_lt_qb(v1_t
, v1_t
, v2_t
);
20857 tcg_gen_deposit_tl(cpu_dspctrl
, cpu_dspctrl
, v1_t
, 24, 4);
20858 gen_store_gpr(v1_t
, ret
);
20860 case NM_CMPGDU_LE_QB
:
20862 gen_helper_cmpgu_le_qb(v1_t
, v1_t
, v2_t
);
20863 tcg_gen_deposit_tl(cpu_dspctrl
, cpu_dspctrl
, v1_t
, 24, 4);
20864 gen_store_gpr(v1_t
, ret
);
20868 gen_helper_packrl_ph(v1_t
, v1_t
, v2_t
);
20869 gen_store_gpr(v1_t
, ret
);
20873 gen_helper_pick_qb(v1_t
, v1_t
, v2_t
, cpu_env
);
20874 gen_store_gpr(v1_t
, ret
);
20878 gen_helper_pick_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20879 gen_store_gpr(v1_t
, ret
);
20883 gen_helper_addq_s_w(v1_t
, v1_t
, v2_t
, cpu_env
);
20884 gen_store_gpr(v1_t
, ret
);
20888 gen_helper_subq_s_w(v1_t
, v1_t
, v2_t
, cpu_env
);
20889 gen_store_gpr(v1_t
, ret
);
20893 gen_helper_addsc(v1_t
, v1_t
, v2_t
, cpu_env
);
20894 gen_store_gpr(v1_t
, ret
);
20898 gen_helper_addwc(v1_t
, v1_t
, v2_t
, cpu_env
);
20899 gen_store_gpr(v1_t
, ret
);
20903 switch (extract32(ctx
->opcode
, 10, 1)) {
20906 gen_helper_addq_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20907 gen_store_gpr(v1_t
, ret
);
20911 gen_helper_addq_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20912 gen_store_gpr(v1_t
, ret
);
20916 case NM_ADDQH_R_PH
:
20918 switch (extract32(ctx
->opcode
, 10, 1)) {
20921 gen_helper_addqh_ph(v1_t
, v1_t
, v2_t
);
20922 gen_store_gpr(v1_t
, ret
);
20926 gen_helper_addqh_r_ph(v1_t
, v1_t
, v2_t
);
20927 gen_store_gpr(v1_t
, ret
);
20933 switch (extract32(ctx
->opcode
, 10, 1)) {
20936 gen_helper_addqh_w(v1_t
, v1_t
, v2_t
);
20937 gen_store_gpr(v1_t
, ret
);
20941 gen_helper_addqh_r_w(v1_t
, v1_t
, v2_t
);
20942 gen_store_gpr(v1_t
, ret
);
20948 switch (extract32(ctx
->opcode
, 10, 1)) {
20951 gen_helper_addu_qb(v1_t
, v1_t
, v2_t
, cpu_env
);
20952 gen_store_gpr(v1_t
, ret
);
20956 gen_helper_addu_s_qb(v1_t
, v1_t
, v2_t
, cpu_env
);
20957 gen_store_gpr(v1_t
, ret
);
20963 switch (extract32(ctx
->opcode
, 10, 1)) {
20966 gen_helper_addu_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20967 gen_store_gpr(v1_t
, ret
);
20971 gen_helper_addu_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20972 gen_store_gpr(v1_t
, ret
);
20976 case NM_ADDUH_R_QB
:
20978 switch (extract32(ctx
->opcode
, 10, 1)) {
20981 gen_helper_adduh_qb(v1_t
, v1_t
, v2_t
);
20982 gen_store_gpr(v1_t
, ret
);
20986 gen_helper_adduh_r_qb(v1_t
, v1_t
, v2_t
);
20987 gen_store_gpr(v1_t
, ret
);
20991 case NM_SHRAV_R_PH
:
20993 switch (extract32(ctx
->opcode
, 10, 1)) {
20996 gen_helper_shra_ph(v1_t
, v1_t
, v2_t
);
20997 gen_store_gpr(v1_t
, ret
);
21001 gen_helper_shra_r_ph(v1_t
, v1_t
, v2_t
);
21002 gen_store_gpr(v1_t
, ret
);
21006 case NM_SHRAV_R_QB
:
21008 switch (extract32(ctx
->opcode
, 10, 1)) {
21011 gen_helper_shra_qb(v1_t
, v1_t
, v2_t
);
21012 gen_store_gpr(v1_t
, ret
);
21016 gen_helper_shra_r_qb(v1_t
, v1_t
, v2_t
);
21017 gen_store_gpr(v1_t
, ret
);
21023 switch (extract32(ctx
->opcode
, 10, 1)) {
21026 gen_helper_subq_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21027 gen_store_gpr(v1_t
, ret
);
21031 gen_helper_subq_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21032 gen_store_gpr(v1_t
, ret
);
21036 case NM_SUBQH_R_PH
:
21038 switch (extract32(ctx
->opcode
, 10, 1)) {
21041 gen_helper_subqh_ph(v1_t
, v1_t
, v2_t
);
21042 gen_store_gpr(v1_t
, ret
);
21046 gen_helper_subqh_r_ph(v1_t
, v1_t
, v2_t
);
21047 gen_store_gpr(v1_t
, ret
);
21053 switch (extract32(ctx
->opcode
, 10, 1)) {
21056 gen_helper_subqh_w(v1_t
, v1_t
, v2_t
);
21057 gen_store_gpr(v1_t
, ret
);
21061 gen_helper_subqh_r_w(v1_t
, v1_t
, v2_t
);
21062 gen_store_gpr(v1_t
, ret
);
21068 switch (extract32(ctx
->opcode
, 10, 1)) {
21071 gen_helper_subu_qb(v1_t
, v1_t
, v2_t
, cpu_env
);
21072 gen_store_gpr(v1_t
, ret
);
21076 gen_helper_subu_s_qb(v1_t
, v1_t
, v2_t
, cpu_env
);
21077 gen_store_gpr(v1_t
, ret
);
21083 switch (extract32(ctx
->opcode
, 10, 1)) {
21086 gen_helper_subu_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21087 gen_store_gpr(v1_t
, ret
);
21091 gen_helper_subu_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21092 gen_store_gpr(v1_t
, ret
);
21096 case NM_SUBUH_R_QB
:
21098 switch (extract32(ctx
->opcode
, 10, 1)) {
21101 gen_helper_subuh_qb(v1_t
, v1_t
, v2_t
);
21102 gen_store_gpr(v1_t
, ret
);
21106 gen_helper_subuh_r_qb(v1_t
, v1_t
, v2_t
);
21107 gen_store_gpr(v1_t
, ret
);
21111 case NM_SHLLV_S_PH
:
21113 switch (extract32(ctx
->opcode
, 10, 1)) {
21116 gen_helper_shll_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21117 gen_store_gpr(v1_t
, ret
);
21121 gen_helper_shll_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21122 gen_store_gpr(v1_t
, ret
);
21126 case NM_PRECR_SRA_R_PH_W
:
21128 switch (extract32(ctx
->opcode
, 10, 1)) {
21130 /* PRECR_SRA_PH_W */
21132 TCGv_i32 sa_t
= tcg_const_i32(rd
);
21133 gen_helper_precr_sra_ph_w(v1_t
, sa_t
, v1_t
,
21135 gen_store_gpr(v1_t
, rt
);
21136 tcg_temp_free_i32(sa_t
);
21140 /* PRECR_SRA_R_PH_W */
21142 TCGv_i32 sa_t
= tcg_const_i32(rd
);
21143 gen_helper_precr_sra_r_ph_w(v1_t
, sa_t
, v1_t
,
21145 gen_store_gpr(v1_t
, rt
);
21146 tcg_temp_free_i32(sa_t
);
21151 case NM_MULEU_S_PH_QBL
:
21153 gen_helper_muleu_s_ph_qbl(v1_t
, v1_t
, v2_t
, cpu_env
);
21154 gen_store_gpr(v1_t
, ret
);
21156 case NM_MULEU_S_PH_QBR
:
21158 gen_helper_muleu_s_ph_qbr(v1_t
, v1_t
, v2_t
, cpu_env
);
21159 gen_store_gpr(v1_t
, ret
);
21161 case NM_MULQ_RS_PH
:
21163 gen_helper_mulq_rs_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21164 gen_store_gpr(v1_t
, ret
);
21168 gen_helper_mulq_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21169 gen_store_gpr(v1_t
, ret
);
21173 gen_helper_mulq_rs_w(v1_t
, v1_t
, v2_t
, cpu_env
);
21174 gen_store_gpr(v1_t
, ret
);
21178 gen_helper_mulq_s_w(v1_t
, v1_t
, v2_t
, cpu_env
);
21179 gen_store_gpr(v1_t
, ret
);
21183 gen_load_gpr(t0
, rs
);
21185 tcg_gen_deposit_tl(cpu_gpr
[rt
], t0
, cpu_gpr
[rt
], rd
, 32 - rd
);
21187 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
21191 gen_helper_modsub(v1_t
, v1_t
, v2_t
);
21192 gen_store_gpr(v1_t
, ret
);
21196 gen_helper_shra_r_w(v1_t
, v1_t
, v2_t
);
21197 gen_store_gpr(v1_t
, ret
);
21201 gen_helper_shrl_ph(v1_t
, v1_t
, v2_t
);
21202 gen_store_gpr(v1_t
, ret
);
21206 gen_helper_shrl_qb(v1_t
, v1_t
, v2_t
);
21207 gen_store_gpr(v1_t
, ret
);
21211 gen_helper_shll_qb(v1_t
, v1_t
, v2_t
, cpu_env
);
21212 gen_store_gpr(v1_t
, ret
);
21216 gen_helper_shll_s_w(v1_t
, v1_t
, v2_t
, cpu_env
);
21217 gen_store_gpr(v1_t
, ret
);
21222 TCGv tv0
= tcg_temp_new();
21223 TCGv tv1
= tcg_temp_new();
21224 int16_t imm
= extract32(ctx
->opcode
, 16, 7);
21226 tcg_gen_movi_tl(tv0
, rd
>> 3);
21227 tcg_gen_movi_tl(tv1
, imm
);
21228 gen_helper_shilo(tv0
, tv1
, cpu_env
);
21231 case NM_MULEQ_S_W_PHL
:
21233 gen_helper_muleq_s_w_phl(v1_t
, v1_t
, v2_t
, cpu_env
);
21234 gen_store_gpr(v1_t
, ret
);
21236 case NM_MULEQ_S_W_PHR
:
21238 gen_helper_muleq_s_w_phr(v1_t
, v1_t
, v2_t
, cpu_env
);
21239 gen_store_gpr(v1_t
, ret
);
21243 switch (extract32(ctx
->opcode
, 10, 1)) {
21246 gen_helper_mul_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21247 gen_store_gpr(v1_t
, ret
);
21251 gen_helper_mul_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21252 gen_store_gpr(v1_t
, ret
);
21256 case NM_PRECR_QB_PH
:
21258 gen_helper_precr_qb_ph(v1_t
, v1_t
, v2_t
);
21259 gen_store_gpr(v1_t
, ret
);
21261 case NM_PRECRQ_QB_PH
:
21263 gen_helper_precrq_qb_ph(v1_t
, v1_t
, v2_t
);
21264 gen_store_gpr(v1_t
, ret
);
21266 case NM_PRECRQ_PH_W
:
21268 gen_helper_precrq_ph_w(v1_t
, v1_t
, v2_t
);
21269 gen_store_gpr(v1_t
, ret
);
21271 case NM_PRECRQ_RS_PH_W
:
21273 gen_helper_precrq_rs_ph_w(v1_t
, v1_t
, v2_t
, cpu_env
);
21274 gen_store_gpr(v1_t
, ret
);
21276 case NM_PRECRQU_S_QB_PH
:
21278 gen_helper_precrqu_s_qb_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21279 gen_store_gpr(v1_t
, ret
);
21283 tcg_gen_movi_tl(t0
, rd
);
21284 gen_helper_shra_r_w(v1_t
, t0
, v1_t
);
21285 gen_store_gpr(v1_t
, rt
);
21289 tcg_gen_movi_tl(t0
, rd
>> 1);
21290 switch (extract32(ctx
->opcode
, 10, 1)) {
21293 gen_helper_shra_ph(v1_t
, t0
, v1_t
);
21294 gen_store_gpr(v1_t
, rt
);
21298 gen_helper_shra_r_ph(v1_t
, t0
, v1_t
);
21299 gen_store_gpr(v1_t
, rt
);
21305 tcg_gen_movi_tl(t0
, rd
>> 1);
21306 switch (extract32(ctx
->opcode
, 10, 2)) {
21309 gen_helper_shll_ph(v1_t
, t0
, v1_t
, cpu_env
);
21310 gen_store_gpr(v1_t
, rt
);
21314 gen_helper_shll_s_ph(v1_t
, t0
, v1_t
, cpu_env
);
21315 gen_store_gpr(v1_t
, rt
);
21318 gen_reserved_instruction(ctx
);
21324 tcg_gen_movi_tl(t0
, rd
);
21325 gen_helper_shll_s_w(v1_t
, t0
, v1_t
, cpu_env
);
21326 gen_store_gpr(v1_t
, rt
);
21332 imm
= sextract32(ctx
->opcode
, 11, 11);
21333 imm
= (int16_t)(imm
<< 6) >> 6;
21335 tcg_gen_movi_tl(cpu_gpr
[rt
], dup_const(MO_16
, imm
));
21340 gen_reserved_instruction(ctx
);
21345 static int decode_nanomips_32_48_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
21353 insn
= cpu_lduw_code(env
, ctx
->base
.pc_next
+ 2);
21354 ctx
->opcode
= (ctx
->opcode
<< 16) | insn
;
21356 rt
= extract32(ctx
->opcode
, 21, 5);
21357 rs
= extract32(ctx
->opcode
, 16, 5);
21358 rd
= extract32(ctx
->opcode
, 11, 5);
21360 op
= extract32(ctx
->opcode
, 26, 6);
21365 switch (extract32(ctx
->opcode
, 19, 2)) {
21368 gen_reserved_instruction(ctx
);
21371 if ((extract32(ctx
->opcode
, 18, 1)) == NM_SYSCALL
) {
21372 generate_exception_end(ctx
, EXCP_SYSCALL
);
21374 gen_reserved_instruction(ctx
);
21378 generate_exception_end(ctx
, EXCP_BREAK
);
21381 if (is_uhi(extract32(ctx
->opcode
, 0, 19))) {
21382 gen_helper_do_semihosting(cpu_env
);
21384 if (ctx
->hflags
& MIPS_HFLAG_SBRI
) {
21385 gen_reserved_instruction(ctx
);
21387 generate_exception_end(ctx
, EXCP_DBp
);
21394 imm
= extract32(ctx
->opcode
, 0, 16);
21396 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], imm
);
21398 tcg_gen_movi_tl(cpu_gpr
[rt
], imm
);
21400 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
21405 offset
= sextract32(ctx
->opcode
, 0, 1) << 21 |
21406 extract32(ctx
->opcode
, 1, 20) << 1;
21407 target_long addr
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
21408 tcg_gen_movi_tl(cpu_gpr
[rt
], addr
);
21412 switch (ctx
->opcode
& 0x07) {
21414 gen_pool32a0_nanomips_insn(env
, ctx
);
21418 int32_t op1
= extract32(ctx
->opcode
, 3, 7);
21419 gen_pool32a5_nanomips_insn(ctx
, op1
, rd
, rs
, rt
);
21423 switch (extract32(ctx
->opcode
, 3, 3)) {
21425 gen_p_lsx(ctx
, rd
, rs
, rt
);
21429 * In nanoMIPS, the shift field directly encodes the shift
21430 * amount, meaning that the supported shift values are in
21431 * the range 0 to 3 (instead of 1 to 4 in MIPSR6).
21433 gen_lsa(ctx
, rd
, rt
, rs
, extract32(ctx
->opcode
, 9, 2) - 1);
21436 gen_ext(ctx
, 32, rd
, rs
, rt
, extract32(ctx
->opcode
, 6, 5));
21439 gen_pool32axf_nanomips_insn(env
, ctx
);
21442 gen_reserved_instruction(ctx
);
21447 gen_reserved_instruction(ctx
);
21452 switch (ctx
->opcode
& 0x03) {
21455 offset
= extract32(ctx
->opcode
, 0, 21);
21456 gen_op_addr_addi(ctx
, cpu_gpr
[rt
], cpu_gpr
[28], offset
);
21460 gen_ld(ctx
, OPC_LW
, rt
, 28, extract32(ctx
->opcode
, 2, 19) << 2);
21463 gen_st(ctx
, OPC_SW
, rt
, 28, extract32(ctx
->opcode
, 2, 19) << 2);
21466 gen_reserved_instruction(ctx
);
21472 insn
= cpu_lduw_code(env
, ctx
->base
.pc_next
+ 4);
21473 target_long addr_off
= extract32(ctx
->opcode
, 0, 16) | insn
<< 16;
21474 switch (extract32(ctx
->opcode
, 16, 5)) {
21478 tcg_gen_movi_tl(cpu_gpr
[rt
], addr_off
);
21484 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], addr_off
);
21485 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
21491 gen_op_addr_addi(ctx
, cpu_gpr
[rt
], cpu_gpr
[28], addr_off
);
21497 target_long addr
= addr_add(ctx
, ctx
->base
.pc_next
+ 6,
21500 tcg_gen_movi_tl(cpu_gpr
[rt
], addr
);
21507 t0
= tcg_temp_new();
21509 target_long addr
= addr_add(ctx
, ctx
->base
.pc_next
+ 6,
21512 tcg_gen_movi_tl(t0
, addr
);
21513 tcg_gen_qemu_ld_tl(cpu_gpr
[rt
], t0
, ctx
->mem_idx
, MO_TESL
);
21521 t0
= tcg_temp_new();
21522 t1
= tcg_temp_new();
21524 target_long addr
= addr_add(ctx
, ctx
->base
.pc_next
+ 6,
21527 tcg_gen_movi_tl(t0
, addr
);
21528 gen_load_gpr(t1
, rt
);
21530 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
21537 gen_reserved_instruction(ctx
);
21543 switch (extract32(ctx
->opcode
, 12, 4)) {
21545 gen_logic_imm(ctx
, OPC_ORI
, rt
, rs
, extract32(ctx
->opcode
, 0, 12));
21548 gen_logic_imm(ctx
, OPC_XORI
, rt
, rs
, extract32(ctx
->opcode
, 0, 12));
21551 gen_logic_imm(ctx
, OPC_ANDI
, rt
, rs
, extract32(ctx
->opcode
, 0, 12));
21554 switch (extract32(ctx
->opcode
, 20, 1)) {
21556 switch (ctx
->opcode
& 3) {
21558 gen_save(ctx
, rt
, extract32(ctx
->opcode
, 16, 4),
21559 extract32(ctx
->opcode
, 2, 1),
21560 extract32(ctx
->opcode
, 3, 9) << 3);
21563 case NM_RESTORE_JRC
:
21564 gen_restore(ctx
, rt
, extract32(ctx
->opcode
, 16, 4),
21565 extract32(ctx
->opcode
, 2, 1),
21566 extract32(ctx
->opcode
, 3, 9) << 3);
21567 if ((ctx
->opcode
& 3) == NM_RESTORE_JRC
) {
21568 gen_compute_branch_nm(ctx
, OPC_JR
, 2, 31, 0, 0);
21572 gen_reserved_instruction(ctx
);
21577 gen_reserved_instruction(ctx
);
21582 gen_slt_imm(ctx
, OPC_SLTI
, rt
, rs
, extract32(ctx
->opcode
, 0, 12));
21585 gen_slt_imm(ctx
, OPC_SLTIU
, rt
, rs
, extract32(ctx
->opcode
, 0, 12));
21589 TCGv t0
= tcg_temp_new();
21591 imm
= extract32(ctx
->opcode
, 0, 12);
21592 gen_load_gpr(t0
, rs
);
21593 tcg_gen_setcondi_tl(TCG_COND_EQ
, t0
, t0
, imm
);
21594 gen_store_gpr(t0
, rt
);
21600 imm
= (int16_t) extract32(ctx
->opcode
, 0, 12);
21601 gen_arith_imm(ctx
, OPC_ADDIU
, rt
, rs
, -imm
);
21605 int shift
= extract32(ctx
->opcode
, 0, 5);
21606 switch (extract32(ctx
->opcode
, 5, 4)) {
21608 if (rt
== 0 && shift
== 0) {
21610 } else if (rt
== 0 && shift
== 3) {
21611 /* EHB - treat as NOP */
21612 } else if (rt
== 0 && shift
== 5) {
21613 /* PAUSE - treat as NOP */
21614 } else if (rt
== 0 && shift
== 6) {
21616 gen_sync(extract32(ctx
->opcode
, 16, 5));
21619 gen_shift_imm(ctx
, OPC_SLL
, rt
, rs
,
21620 extract32(ctx
->opcode
, 0, 5));
21624 gen_shift_imm(ctx
, OPC_SRL
, rt
, rs
,
21625 extract32(ctx
->opcode
, 0, 5));
21628 gen_shift_imm(ctx
, OPC_SRA
, rt
, rs
,
21629 extract32(ctx
->opcode
, 0, 5));
21632 gen_shift_imm(ctx
, OPC_ROTR
, rt
, rs
,
21633 extract32(ctx
->opcode
, 0, 5));
21641 TCGv t0
= tcg_temp_new();
21642 TCGv_i32 shift
= tcg_const_i32(extract32(ctx
->opcode
, 0, 5));
21643 TCGv_i32 shiftx
= tcg_const_i32(extract32(ctx
->opcode
, 7, 4)
21645 TCGv_i32 stripe
= tcg_const_i32(extract32(ctx
->opcode
, 6, 1));
21647 gen_load_gpr(t0
, rs
);
21648 gen_helper_rotx(cpu_gpr
[rt
], t0
, shift
, shiftx
, stripe
);
21651 tcg_temp_free_i32(shift
);
21652 tcg_temp_free_i32(shiftx
);
21653 tcg_temp_free_i32(stripe
);
21657 switch (((ctx
->opcode
>> 10) & 2) |
21658 (extract32(ctx
->opcode
, 5, 1))) {
21661 gen_bitops(ctx
, OPC_INS
, rt
, rs
, extract32(ctx
->opcode
, 0, 5),
21662 extract32(ctx
->opcode
, 6, 5));
21665 gen_reserved_instruction(ctx
);
21670 switch (((ctx
->opcode
>> 10) & 2) |
21671 (extract32(ctx
->opcode
, 5, 1))) {
21674 gen_bitops(ctx
, OPC_EXT
, rt
, rs
, extract32(ctx
->opcode
, 0, 5),
21675 extract32(ctx
->opcode
, 6, 5));
21678 gen_reserved_instruction(ctx
);
21683 gen_reserved_instruction(ctx
);
21688 gen_pool32f_nanomips_insn(ctx
);
21693 switch (extract32(ctx
->opcode
, 1, 1)) {
21696 tcg_gen_movi_tl(cpu_gpr
[rt
],
21697 sextract32(ctx
->opcode
, 0, 1) << 31 |
21698 extract32(ctx
->opcode
, 2, 10) << 21 |
21699 extract32(ctx
->opcode
, 12, 9) << 12);
21704 offset
= sextract32(ctx
->opcode
, 0, 1) << 31 |
21705 extract32(ctx
->opcode
, 2, 10) << 21 |
21706 extract32(ctx
->opcode
, 12, 9) << 12;
21708 addr
= ~0xFFF & addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
21709 tcg_gen_movi_tl(cpu_gpr
[rt
], addr
);
21716 uint32_t u
= extract32(ctx
->opcode
, 0, 18);
21718 switch (extract32(ctx
->opcode
, 18, 3)) {
21720 gen_ld(ctx
, OPC_LB
, rt
, 28, u
);
21723 gen_st(ctx
, OPC_SB
, rt
, 28, u
);
21726 gen_ld(ctx
, OPC_LBU
, rt
, 28, u
);
21730 gen_op_addr_addi(ctx
, cpu_gpr
[rt
], cpu_gpr
[28], u
);
21735 switch (ctx
->opcode
& 1) {
21737 gen_ld(ctx
, OPC_LH
, rt
, 28, u
);
21740 gen_ld(ctx
, OPC_LHU
, rt
, 28, u
);
21746 switch (ctx
->opcode
& 1) {
21748 gen_st(ctx
, OPC_SH
, rt
, 28, u
);
21751 gen_reserved_instruction(ctx
);
21757 switch (ctx
->opcode
& 0x3) {
21759 gen_cop1_ldst(ctx
, OPC_LWC1
, rt
, 28, u
);
21762 gen_cop1_ldst(ctx
, OPC_LDC1
, rt
, 28, u
);
21765 gen_cop1_ldst(ctx
, OPC_SWC1
, rt
, 28, u
);
21768 gen_cop1_ldst(ctx
, OPC_SDC1
, rt
, 28, u
);
21773 gen_reserved_instruction(ctx
);
21780 uint32_t u
= extract32(ctx
->opcode
, 0, 12);
21782 switch (extract32(ctx
->opcode
, 12, 4)) {
21787 * Break the TB to be able to sync copied instructions
21790 ctx
->base
.is_jmp
= DISAS_STOP
;
21793 /* Treat as NOP. */
21797 gen_ld(ctx
, OPC_LB
, rt
, rs
, u
);
21800 gen_ld(ctx
, OPC_LH
, rt
, rs
, u
);
21803 gen_ld(ctx
, OPC_LW
, rt
, rs
, u
);
21806 gen_ld(ctx
, OPC_LBU
, rt
, rs
, u
);
21809 gen_ld(ctx
, OPC_LHU
, rt
, rs
, u
);
21812 gen_st(ctx
, OPC_SB
, rt
, rs
, u
);
21815 gen_st(ctx
, OPC_SH
, rt
, rs
, u
);
21818 gen_st(ctx
, OPC_SW
, rt
, rs
, u
);
21821 gen_cop1_ldst(ctx
, OPC_LWC1
, rt
, rs
, u
);
21824 gen_cop1_ldst(ctx
, OPC_LDC1
, rt
, rs
, u
);
21827 gen_cop1_ldst(ctx
, OPC_SWC1
, rt
, rs
, u
);
21830 gen_cop1_ldst(ctx
, OPC_SDC1
, rt
, rs
, u
);
21833 gen_reserved_instruction(ctx
);
21840 int32_t s
= (sextract32(ctx
->opcode
, 15, 1) << 8) |
21841 extract32(ctx
->opcode
, 0, 8);
21843 switch (extract32(ctx
->opcode
, 8, 3)) {
21845 switch (extract32(ctx
->opcode
, 11, 4)) {
21847 gen_ld(ctx
, OPC_LB
, rt
, rs
, s
);
21850 gen_ld(ctx
, OPC_LH
, rt
, rs
, s
);
21853 gen_ld(ctx
, OPC_LW
, rt
, rs
, s
);
21856 gen_ld(ctx
, OPC_LBU
, rt
, rs
, s
);
21859 gen_ld(ctx
, OPC_LHU
, rt
, rs
, s
);
21862 gen_st(ctx
, OPC_SB
, rt
, rs
, s
);
21865 gen_st(ctx
, OPC_SH
, rt
, rs
, s
);
21868 gen_st(ctx
, OPC_SW
, rt
, rs
, s
);
21871 gen_cop1_ldst(ctx
, OPC_LWC1
, rt
, rs
, s
);
21874 gen_cop1_ldst(ctx
, OPC_LDC1
, rt
, rs
, s
);
21877 gen_cop1_ldst(ctx
, OPC_SWC1
, rt
, rs
, s
);
21880 gen_cop1_ldst(ctx
, OPC_SDC1
, rt
, rs
, s
);
21886 * Break the TB to be able to sync copied instructions
21889 ctx
->base
.is_jmp
= DISAS_STOP
;
21892 /* Treat as NOP. */
21896 gen_reserved_instruction(ctx
);
21901 switch (extract32(ctx
->opcode
, 11, 4)) {
21906 TCGv t0
= tcg_temp_new();
21907 TCGv t1
= tcg_temp_new();
21909 gen_base_offset_addr(ctx
, t0
, rs
, s
);
21911 switch (extract32(ctx
->opcode
, 11, 4)) {
21913 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESW
|
21915 gen_store_gpr(t0
, rt
);
21918 gen_load_gpr(t1
, rt
);
21919 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUW
|
21928 switch (ctx
->opcode
& 0x03) {
21930 gen_ld(ctx
, OPC_LL
, rt
, rs
, s
);
21934 gen_llwp(ctx
, rs
, 0, rt
, extract32(ctx
->opcode
, 3, 5));
21939 switch (ctx
->opcode
& 0x03) {
21941 gen_st_cond(ctx
, rt
, rs
, s
, MO_TESL
, false);
21945 gen_scwp(ctx
, rs
, 0, rt
, extract32(ctx
->opcode
, 3, 5),
21951 check_cp0_enabled(ctx
);
21952 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
21953 gen_cache_operation(ctx
, rt
, rs
, s
);
21959 switch (extract32(ctx
->opcode
, 11, 4)) {
21962 check_cp0_enabled(ctx
);
21963 gen_ld(ctx
, OPC_LBE
, rt
, rs
, s
);
21967 check_cp0_enabled(ctx
);
21968 gen_st(ctx
, OPC_SBE
, rt
, rs
, s
);
21972 check_cp0_enabled(ctx
);
21973 gen_ld(ctx
, OPC_LBUE
, rt
, rs
, s
);
21977 /* case NM_SYNCIE */
21979 check_cp0_enabled(ctx
);
21981 * Break the TB to be able to sync copied instructions
21984 ctx
->base
.is_jmp
= DISAS_STOP
;
21986 /* case NM_PREFE */
21988 check_cp0_enabled(ctx
);
21989 /* Treat as NOP. */
21994 check_cp0_enabled(ctx
);
21995 gen_ld(ctx
, OPC_LHE
, rt
, rs
, s
);
21999 check_cp0_enabled(ctx
);
22000 gen_st(ctx
, OPC_SHE
, rt
, rs
, s
);
22004 check_cp0_enabled(ctx
);
22005 gen_ld(ctx
, OPC_LHUE
, rt
, rs
, s
);
22008 check_nms_dl_il_sl_tl_l2c(ctx
);
22009 gen_cache_operation(ctx
, rt
, rs
, s
);
22013 check_cp0_enabled(ctx
);
22014 gen_ld(ctx
, OPC_LWE
, rt
, rs
, s
);
22018 check_cp0_enabled(ctx
);
22019 gen_st(ctx
, OPC_SWE
, rt
, rs
, s
);
22022 switch (extract32(ctx
->opcode
, 2, 2)) {
22026 check_cp0_enabled(ctx
);
22027 gen_ld(ctx
, OPC_LLE
, rt
, rs
, s
);
22032 check_cp0_enabled(ctx
);
22033 gen_llwp(ctx
, rs
, 0, rt
, extract32(ctx
->opcode
, 3, 5));
22036 gen_reserved_instruction(ctx
);
22041 switch (extract32(ctx
->opcode
, 2, 2)) {
22045 check_cp0_enabled(ctx
);
22046 gen_st_cond(ctx
, rt
, rs
, s
, MO_TESL
, true);
22051 check_cp0_enabled(ctx
);
22052 gen_scwp(ctx
, rs
, 0, rt
, extract32(ctx
->opcode
, 3, 5),
22056 gen_reserved_instruction(ctx
);
22066 int count
= extract32(ctx
->opcode
, 12, 3);
22069 offset
= sextract32(ctx
->opcode
, 15, 1) << 8 |
22070 extract32(ctx
->opcode
, 0, 8);
22071 TCGv va
= tcg_temp_new();
22072 TCGv t1
= tcg_temp_new();
22073 MemOp memop
= (extract32(ctx
->opcode
, 8, 3)) ==
22074 NM_P_LS_UAWM
? MO_UNALN
: 0;
22076 count
= (count
== 0) ? 8 : count
;
22077 while (counter
!= count
) {
22078 int this_rt
= ((rt
+ counter
) & 0x1f) | (rt
& 0x10);
22079 int this_offset
= offset
+ (counter
<< 2);
22081 gen_base_offset_addr(ctx
, va
, rs
, this_offset
);
22083 switch (extract32(ctx
->opcode
, 11, 1)) {
22085 tcg_gen_qemu_ld_tl(t1
, va
, ctx
->mem_idx
,
22087 gen_store_gpr(t1
, this_rt
);
22088 if ((this_rt
== rs
) &&
22089 (counter
!= (count
- 1))) {
22090 /* UNPREDICTABLE */
22094 this_rt
= (rt
== 0) ? 0 : this_rt
;
22095 gen_load_gpr(t1
, this_rt
);
22096 tcg_gen_qemu_st_tl(t1
, va
, ctx
->mem_idx
,
22107 gen_reserved_instruction(ctx
);
22115 TCGv t0
= tcg_temp_new();
22116 int32_t s
= sextract32(ctx
->opcode
, 0, 1) << 21 |
22117 extract32(ctx
->opcode
, 1, 20) << 1;
22118 rd
= (extract32(ctx
->opcode
, 24, 1)) == 0 ? 4 : 5;
22119 rt
= decode_gpr_gpr4_zero(extract32(ctx
->opcode
, 25, 1) << 3 |
22120 extract32(ctx
->opcode
, 21, 3));
22121 gen_load_gpr(t0
, rt
);
22122 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
22123 gen_compute_branch_nm(ctx
, OPC_BGEZAL
, 4, 0, 0, s
);
22129 int32_t s
= sextract32(ctx
->opcode
, 0, 1) << 25 |
22130 extract32(ctx
->opcode
, 1, 24) << 1;
22132 if ((extract32(ctx
->opcode
, 25, 1)) == 0) {
22134 gen_compute_branch_nm(ctx
, OPC_BEQ
, 4, 0, 0, s
);
22137 gen_compute_branch_nm(ctx
, OPC_BGEZAL
, 4, 0, 0, s
);
22142 switch (extract32(ctx
->opcode
, 12, 4)) {
22145 gen_compute_branch_nm(ctx
, OPC_JALR
, 4, rs
, rt
, 0);
22148 gen_compute_nanomips_pbalrsc_branch(ctx
, rs
, rt
);
22151 gen_reserved_instruction(ctx
);
22157 int32_t s
= sextract32(ctx
->opcode
, 0, 1) << 14 |
22158 extract32(ctx
->opcode
, 1, 13) << 1;
22159 switch (extract32(ctx
->opcode
, 14, 2)) {
22162 gen_compute_branch_nm(ctx
, OPC_BEQ
, 4, rs
, rt
, s
);
22165 s
= sextract32(ctx
->opcode
, 0, 1) << 14 |
22166 extract32(ctx
->opcode
, 1, 13) << 1;
22167 check_cp1_enabled(ctx
);
22168 switch (extract32(ctx
->opcode
, 16, 5)) {
22170 gen_compute_branch_cp1_nm(ctx
, OPC_BC1EQZ
, rt
, s
);
22173 gen_compute_branch_cp1_nm(ctx
, OPC_BC1NEZ
, rt
, s
);
22178 int32_t imm
= extract32(ctx
->opcode
, 1, 13) |
22179 extract32(ctx
->opcode
, 0, 1) << 13;
22181 gen_compute_branch_nm(ctx
, OPC_BPOSGE32
, 4, -1, -2,
22186 gen_reserved_instruction(ctx
);
22192 gen_compute_compact_branch_nm(ctx
, OPC_BC
, rs
, rt
, s
);
22194 gen_compute_compact_branch_nm(ctx
, OPC_BGEC
, rs
, rt
, s
);
22198 if (rs
== rt
|| rt
== 0) {
22199 gen_compute_compact_branch_nm(ctx
, OPC_BC
, 0, 0, s
);
22200 } else if (rs
== 0) {
22201 gen_compute_compact_branch_nm(ctx
, OPC_BEQZC
, rt
, 0, s
);
22203 gen_compute_compact_branch_nm(ctx
, OPC_BGEUC
, rs
, rt
, s
);
22211 int32_t s
= sextract32(ctx
->opcode
, 0, 1) << 14 |
22212 extract32(ctx
->opcode
, 1, 13) << 1;
22213 switch (extract32(ctx
->opcode
, 14, 2)) {
22216 gen_compute_branch_nm(ctx
, OPC_BNE
, 4, rs
, rt
, s
);
22219 if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
22221 ctx
->hflags
|= MIPS_HFLAG_FBNSLOT
;
22223 gen_compute_compact_branch_nm(ctx
, OPC_BLTC
, rs
, rt
, s
);
22227 if (rs
== 0 || rs
== rt
) {
22229 ctx
->hflags
|= MIPS_HFLAG_FBNSLOT
;
22231 gen_compute_compact_branch_nm(ctx
, OPC_BLTUC
, rs
, rt
, s
);
22235 gen_reserved_instruction(ctx
);
22242 int32_t s
= sextract32(ctx
->opcode
, 0, 1) << 11 |
22243 extract32(ctx
->opcode
, 1, 10) << 1;
22244 uint32_t u
= extract32(ctx
->opcode
, 11, 7);
22246 gen_compute_imm_branch(ctx
, extract32(ctx
->opcode
, 18, 3),
22251 gen_reserved_instruction(ctx
);
22257 static int decode_nanomips_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
22260 int rt
= decode_gpr_gpr3(NANOMIPS_EXTRACT_RT3(ctx
->opcode
));
22261 int rs
= decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx
->opcode
));
22262 int rd
= decode_gpr_gpr3(NANOMIPS_EXTRACT_RD3(ctx
->opcode
));
22266 /* make sure instructions are on a halfword boundary */
22267 if (ctx
->base
.pc_next
& 0x1) {
22268 TCGv tmp
= tcg_const_tl(ctx
->base
.pc_next
);
22269 tcg_gen_st_tl(tmp
, cpu_env
, offsetof(CPUMIPSState
, CP0_BadVAddr
));
22270 tcg_temp_free(tmp
);
22271 generate_exception_end(ctx
, EXCP_AdEL
);
22275 op
= extract32(ctx
->opcode
, 10, 6);
22278 rt
= NANOMIPS_EXTRACT_RD5(ctx
->opcode
);
22281 rs
= NANOMIPS_EXTRACT_RS5(ctx
->opcode
);
22282 gen_arith(ctx
, OPC_ADDU
, rt
, rs
, 0);
22285 switch (extract32(ctx
->opcode
, 3, 2)) {
22286 case NM_P16_SYSCALL
:
22287 if (extract32(ctx
->opcode
, 2, 1) == 0) {
22288 generate_exception_end(ctx
, EXCP_SYSCALL
);
22290 gen_reserved_instruction(ctx
);
22294 generate_exception_end(ctx
, EXCP_BREAK
);
22297 if (is_uhi(extract32(ctx
->opcode
, 0, 3))) {
22298 gen_helper_do_semihosting(cpu_env
);
22300 if (ctx
->hflags
& MIPS_HFLAG_SBRI
) {
22301 gen_reserved_instruction(ctx
);
22303 generate_exception_end(ctx
, EXCP_DBp
);
22308 gen_reserved_instruction(ctx
);
22315 int shift
= extract32(ctx
->opcode
, 0, 3);
22317 shift
= (shift
== 0) ? 8 : shift
;
22319 switch (extract32(ctx
->opcode
, 3, 1)) {
22327 gen_shift_imm(ctx
, opc
, rt
, rs
, shift
);
22331 switch (ctx
->opcode
& 1) {
22333 gen_pool16c_nanomips_insn(ctx
);
22336 gen_ldxs(ctx
, rt
, rs
, rd
);
22341 switch (extract32(ctx
->opcode
, 6, 1)) {
22343 imm
= extract32(ctx
->opcode
, 0, 6) << 2;
22344 gen_arith_imm(ctx
, OPC_ADDIU
, rt
, 29, imm
);
22347 gen_reserved_instruction(ctx
);
22352 switch (extract32(ctx
->opcode
, 3, 1)) {
22354 imm
= extract32(ctx
->opcode
, 0, 3) << 2;
22355 gen_arith_imm(ctx
, OPC_ADDIU
, rt
, rs
, imm
);
22357 case NM_P_ADDIURS5
:
22358 rt
= extract32(ctx
->opcode
, 5, 5);
22360 /* imm = sign_extend(s[3] . s[2:0] , from_nbits = 4) */
22361 imm
= (sextract32(ctx
->opcode
, 4, 1) << 3) |
22362 (extract32(ctx
->opcode
, 0, 3));
22363 gen_arith_imm(ctx
, OPC_ADDIU
, rt
, rt
, imm
);
22369 switch (ctx
->opcode
& 0x1) {
22371 gen_arith(ctx
, OPC_ADDU
, rd
, rs
, rt
);
22374 gen_arith(ctx
, OPC_SUBU
, rd
, rs
, rt
);
22379 rt
= (extract32(ctx
->opcode
, 9, 1) << 3) |
22380 extract32(ctx
->opcode
, 5, 3);
22381 rs
= (extract32(ctx
->opcode
, 4, 1) << 3) |
22382 extract32(ctx
->opcode
, 0, 3);
22383 rt
= decode_gpr_gpr4(rt
);
22384 rs
= decode_gpr_gpr4(rs
);
22385 switch ((extract32(ctx
->opcode
, 7, 2) & 0x2) |
22386 (extract32(ctx
->opcode
, 3, 1))) {
22389 gen_arith(ctx
, OPC_ADDU
, rt
, rs
, rt
);
22393 gen_r6_muldiv(ctx
, R6_OPC_MUL
, rt
, rs
, rt
);
22396 gen_reserved_instruction(ctx
);
22402 int imm
= extract32(ctx
->opcode
, 0, 7);
22403 imm
= (imm
== 0x7f ? -1 : imm
);
22405 tcg_gen_movi_tl(cpu_gpr
[rt
], imm
);
22411 uint32_t u
= extract32(ctx
->opcode
, 0, 4);
22412 u
= (u
== 12) ? 0xff :
22413 (u
== 13) ? 0xffff : u
;
22414 gen_logic_imm(ctx
, OPC_ANDI
, rt
, rs
, u
);
22418 offset
= extract32(ctx
->opcode
, 0, 2);
22419 switch (extract32(ctx
->opcode
, 2, 2)) {
22421 gen_ld(ctx
, OPC_LB
, rt
, rs
, offset
);
22424 rt
= decode_gpr_gpr3_src_store(
22425 NANOMIPS_EXTRACT_RT3(ctx
->opcode
));
22426 gen_st(ctx
, OPC_SB
, rt
, rs
, offset
);
22429 gen_ld(ctx
, OPC_LBU
, rt
, rs
, offset
);
22432 gen_reserved_instruction(ctx
);
22437 offset
= extract32(ctx
->opcode
, 1, 2) << 1;
22438 switch ((extract32(ctx
->opcode
, 3, 1) << 1) | (ctx
->opcode
& 1)) {
22440 gen_ld(ctx
, OPC_LH
, rt
, rs
, offset
);
22443 rt
= decode_gpr_gpr3_src_store(
22444 NANOMIPS_EXTRACT_RT3(ctx
->opcode
));
22445 gen_st(ctx
, OPC_SH
, rt
, rs
, offset
);
22448 gen_ld(ctx
, OPC_LHU
, rt
, rs
, offset
);
22451 gen_reserved_instruction(ctx
);
22456 offset
= extract32(ctx
->opcode
, 0, 4) << 2;
22457 gen_ld(ctx
, OPC_LW
, rt
, rs
, offset
);
22460 rt
= NANOMIPS_EXTRACT_RD5(ctx
->opcode
);
22461 offset
= extract32(ctx
->opcode
, 0, 5) << 2;
22462 gen_ld(ctx
, OPC_LW
, rt
, 29, offset
);
22466 rt
= (extract32(ctx
->opcode
, 9, 1) << 3) |
22467 extract32(ctx
->opcode
, 5, 3);
22468 rs
= (extract32(ctx
->opcode
, 4, 1) << 3) |
22469 extract32(ctx
->opcode
, 0, 3);
22470 offset
= (extract32(ctx
->opcode
, 3, 1) << 3) |
22471 (extract32(ctx
->opcode
, 8, 1) << 2);
22472 rt
= decode_gpr_gpr4(rt
);
22473 rs
= decode_gpr_gpr4(rs
);
22474 gen_ld(ctx
, OPC_LW
, rt
, rs
, offset
);
22478 rt
= (extract32(ctx
->opcode
, 9, 1) << 3) |
22479 extract32(ctx
->opcode
, 5, 3);
22480 rs
= (extract32(ctx
->opcode
, 4, 1) << 3) |
22481 extract32(ctx
->opcode
, 0, 3);
22482 offset
= (extract32(ctx
->opcode
, 3, 1) << 3) |
22483 (extract32(ctx
->opcode
, 8, 1) << 2);
22484 rt
= decode_gpr_gpr4_zero(rt
);
22485 rs
= decode_gpr_gpr4(rs
);
22486 gen_st(ctx
, OPC_SW
, rt
, rs
, offset
);
22489 offset
= extract32(ctx
->opcode
, 0, 7) << 2;
22490 gen_ld(ctx
, OPC_LW
, rt
, 28, offset
);
22493 rt
= NANOMIPS_EXTRACT_RD5(ctx
->opcode
);
22494 offset
= extract32(ctx
->opcode
, 0, 5) << 2;
22495 gen_st(ctx
, OPC_SW
, rt
, 29, offset
);
22498 rt
= decode_gpr_gpr3_src_store(
22499 NANOMIPS_EXTRACT_RT3(ctx
->opcode
));
22500 rs
= decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx
->opcode
));
22501 offset
= extract32(ctx
->opcode
, 0, 4) << 2;
22502 gen_st(ctx
, OPC_SW
, rt
, rs
, offset
);
22505 rt
= decode_gpr_gpr3_src_store(
22506 NANOMIPS_EXTRACT_RT3(ctx
->opcode
));
22507 offset
= extract32(ctx
->opcode
, 0, 7) << 2;
22508 gen_st(ctx
, OPC_SW
, rt
, 28, offset
);
22511 gen_compute_branch_nm(ctx
, OPC_BEQ
, 2, 0, 0,
22512 (sextract32(ctx
->opcode
, 0, 1) << 10) |
22513 (extract32(ctx
->opcode
, 1, 9) << 1));
22516 gen_compute_branch_nm(ctx
, OPC_BGEZAL
, 2, 0, 0,
22517 (sextract32(ctx
->opcode
, 0, 1) << 10) |
22518 (extract32(ctx
->opcode
, 1, 9) << 1));
22521 gen_compute_branch_nm(ctx
, OPC_BEQ
, 2, rt
, 0,
22522 (sextract32(ctx
->opcode
, 0, 1) << 7) |
22523 (extract32(ctx
->opcode
, 1, 6) << 1));
22526 gen_compute_branch_nm(ctx
, OPC_BNE
, 2, rt
, 0,
22527 (sextract32(ctx
->opcode
, 0, 1) << 7) |
22528 (extract32(ctx
->opcode
, 1, 6) << 1));
22531 switch (ctx
->opcode
& 0xf) {
22534 switch (extract32(ctx
->opcode
, 4, 1)) {
22536 gen_compute_branch_nm(ctx
, OPC_JR
, 2,
22537 extract32(ctx
->opcode
, 5, 5), 0, 0);
22540 gen_compute_branch_nm(ctx
, OPC_JALR
, 2,
22541 extract32(ctx
->opcode
, 5, 5), 31, 0);
22548 uint32_t opc
= extract32(ctx
->opcode
, 4, 3) <
22549 extract32(ctx
->opcode
, 7, 3) ? OPC_BEQ
: OPC_BNE
;
22550 gen_compute_branch_nm(ctx
, opc
, 2, rs
, rt
,
22551 extract32(ctx
->opcode
, 0, 4) << 1);
22558 int count
= extract32(ctx
->opcode
, 0, 4);
22559 int u
= extract32(ctx
->opcode
, 4, 4) << 4;
22561 rt
= 30 + extract32(ctx
->opcode
, 9, 1);
22562 switch (extract32(ctx
->opcode
, 8, 1)) {
22564 gen_save(ctx
, rt
, count
, 0, u
);
22566 case NM_RESTORE_JRC16
:
22567 gen_restore(ctx
, rt
, count
, 0, u
);
22568 gen_compute_branch_nm(ctx
, OPC_JR
, 2, 31, 0, 0);
22577 static const int gpr2reg1
[] = {4, 5, 6, 7};
22578 static const int gpr2reg2
[] = {5, 6, 7, 8};
22580 int rd2
= extract32(ctx
->opcode
, 3, 1) << 1 |
22581 extract32(ctx
->opcode
, 8, 1);
22582 int r1
= gpr2reg1
[rd2
];
22583 int r2
= gpr2reg2
[rd2
];
22584 int r3
= extract32(ctx
->opcode
, 4, 1) << 3 |
22585 extract32(ctx
->opcode
, 0, 3);
22586 int r4
= extract32(ctx
->opcode
, 9, 1) << 3 |
22587 extract32(ctx
->opcode
, 5, 3);
22588 TCGv t0
= tcg_temp_new();
22589 TCGv t1
= tcg_temp_new();
22590 if (op
== NM_MOVEP
) {
22593 rs
= decode_gpr_gpr4_zero(r3
);
22594 rt
= decode_gpr_gpr4_zero(r4
);
22596 rd
= decode_gpr_gpr4(r3
);
22597 re
= decode_gpr_gpr4(r4
);
22601 gen_load_gpr(t0
, rs
);
22602 gen_load_gpr(t1
, rt
);
22603 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
22604 tcg_gen_mov_tl(cpu_gpr
[re
], t1
);
22610 return decode_nanomips_32_48_opc(env
, ctx
);
22617 /* SmartMIPS extension to MIPS32 */
22619 #if defined(TARGET_MIPS64)
22621 /* MDMX extension to MIPS64 */
22625 /* MIPSDSP functions. */
22626 static void gen_mipsdsp_ld(DisasContext
*ctx
, uint32_t opc
,
22627 int rd
, int base
, int offset
)
22632 t0
= tcg_temp_new();
22635 gen_load_gpr(t0
, offset
);
22636 } else if (offset
== 0) {
22637 gen_load_gpr(t0
, base
);
22639 gen_op_addr_add(ctx
, t0
, cpu_gpr
[base
], cpu_gpr
[offset
]);
22644 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_UB
);
22645 gen_store_gpr(t0
, rd
);
22648 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESW
);
22649 gen_store_gpr(t0
, rd
);
22652 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESL
);
22653 gen_store_gpr(t0
, rd
);
22655 #if defined(TARGET_MIPS64)
22657 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
);
22658 gen_store_gpr(t0
, rd
);
22665 static void gen_mipsdsp_arith(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
22666 int ret
, int v1
, int v2
)
22672 /* Treat as NOP. */
22676 v1_t
= tcg_temp_new();
22677 v2_t
= tcg_temp_new();
22679 gen_load_gpr(v1_t
, v1
);
22680 gen_load_gpr(v2_t
, v2
);
22683 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
22684 case OPC_MULT_G_2E
:
22688 gen_helper_adduh_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
22690 case OPC_ADDUH_R_QB
:
22691 gen_helper_adduh_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
22694 gen_helper_addqh_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
22696 case OPC_ADDQH_R_PH
:
22697 gen_helper_addqh_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
22700 gen_helper_addqh_w(cpu_gpr
[ret
], v1_t
, v2_t
);
22702 case OPC_ADDQH_R_W
:
22703 gen_helper_addqh_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
22706 gen_helper_subuh_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
22708 case OPC_SUBUH_R_QB
:
22709 gen_helper_subuh_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
22712 gen_helper_subqh_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
22714 case OPC_SUBQH_R_PH
:
22715 gen_helper_subqh_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
22718 gen_helper_subqh_w(cpu_gpr
[ret
], v1_t
, v2_t
);
22720 case OPC_SUBQH_R_W
:
22721 gen_helper_subqh_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
22725 case OPC_ABSQ_S_PH_DSP
:
22727 case OPC_ABSQ_S_QB
:
22729 gen_helper_absq_s_qb(cpu_gpr
[ret
], v2_t
, cpu_env
);
22731 case OPC_ABSQ_S_PH
:
22733 gen_helper_absq_s_ph(cpu_gpr
[ret
], v2_t
, cpu_env
);
22737 gen_helper_absq_s_w(cpu_gpr
[ret
], v2_t
, cpu_env
);
22739 case OPC_PRECEQ_W_PHL
:
22741 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0xFFFF0000);
22742 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
22744 case OPC_PRECEQ_W_PHR
:
22746 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0x0000FFFF);
22747 tcg_gen_shli_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], 16);
22748 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
22750 case OPC_PRECEQU_PH_QBL
:
22752 gen_helper_precequ_ph_qbl(cpu_gpr
[ret
], v2_t
);
22754 case OPC_PRECEQU_PH_QBR
:
22756 gen_helper_precequ_ph_qbr(cpu_gpr
[ret
], v2_t
);
22758 case OPC_PRECEQU_PH_QBLA
:
22760 gen_helper_precequ_ph_qbla(cpu_gpr
[ret
], v2_t
);
22762 case OPC_PRECEQU_PH_QBRA
:
22764 gen_helper_precequ_ph_qbra(cpu_gpr
[ret
], v2_t
);
22766 case OPC_PRECEU_PH_QBL
:
22768 gen_helper_preceu_ph_qbl(cpu_gpr
[ret
], v2_t
);
22770 case OPC_PRECEU_PH_QBR
:
22772 gen_helper_preceu_ph_qbr(cpu_gpr
[ret
], v2_t
);
22774 case OPC_PRECEU_PH_QBLA
:
22776 gen_helper_preceu_ph_qbla(cpu_gpr
[ret
], v2_t
);
22778 case OPC_PRECEU_PH_QBRA
:
22780 gen_helper_preceu_ph_qbra(cpu_gpr
[ret
], v2_t
);
22784 case OPC_ADDU_QB_DSP
:
22788 gen_helper_addq_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22790 case OPC_ADDQ_S_PH
:
22792 gen_helper_addq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22796 gen_helper_addq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22800 gen_helper_addu_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22802 case OPC_ADDU_S_QB
:
22804 gen_helper_addu_s_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22808 gen_helper_addu_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22810 case OPC_ADDU_S_PH
:
22812 gen_helper_addu_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22816 gen_helper_subq_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22818 case OPC_SUBQ_S_PH
:
22820 gen_helper_subq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22824 gen_helper_subq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22828 gen_helper_subu_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22830 case OPC_SUBU_S_QB
:
22832 gen_helper_subu_s_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22836 gen_helper_subu_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22838 case OPC_SUBU_S_PH
:
22840 gen_helper_subu_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22844 gen_helper_addsc(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22848 gen_helper_addwc(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22852 gen_helper_modsub(cpu_gpr
[ret
], v1_t
, v2_t
);
22854 case OPC_RADDU_W_QB
:
22856 gen_helper_raddu_w_qb(cpu_gpr
[ret
], v1_t
);
22860 case OPC_CMPU_EQ_QB_DSP
:
22862 case OPC_PRECR_QB_PH
:
22864 gen_helper_precr_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
22866 case OPC_PRECRQ_QB_PH
:
22868 gen_helper_precrq_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
22870 case OPC_PRECR_SRA_PH_W
:
22873 TCGv_i32 sa_t
= tcg_const_i32(v2
);
22874 gen_helper_precr_sra_ph_w(cpu_gpr
[ret
], sa_t
, v1_t
,
22876 tcg_temp_free_i32(sa_t
);
22879 case OPC_PRECR_SRA_R_PH_W
:
22882 TCGv_i32 sa_t
= tcg_const_i32(v2
);
22883 gen_helper_precr_sra_r_ph_w(cpu_gpr
[ret
], sa_t
, v1_t
,
22885 tcg_temp_free_i32(sa_t
);
22888 case OPC_PRECRQ_PH_W
:
22890 gen_helper_precrq_ph_w(cpu_gpr
[ret
], v1_t
, v2_t
);
22892 case OPC_PRECRQ_RS_PH_W
:
22894 gen_helper_precrq_rs_ph_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22896 case OPC_PRECRQU_S_QB_PH
:
22898 gen_helper_precrqu_s_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22902 #ifdef TARGET_MIPS64
22903 case OPC_ABSQ_S_QH_DSP
:
22905 case OPC_PRECEQ_L_PWL
:
22907 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0xFFFFFFFF00000000ull
);
22909 case OPC_PRECEQ_L_PWR
:
22911 tcg_gen_shli_tl(cpu_gpr
[ret
], v2_t
, 32);
22913 case OPC_PRECEQ_PW_QHL
:
22915 gen_helper_preceq_pw_qhl(cpu_gpr
[ret
], v2_t
);
22917 case OPC_PRECEQ_PW_QHR
:
22919 gen_helper_preceq_pw_qhr(cpu_gpr
[ret
], v2_t
);
22921 case OPC_PRECEQ_PW_QHLA
:
22923 gen_helper_preceq_pw_qhla(cpu_gpr
[ret
], v2_t
);
22925 case OPC_PRECEQ_PW_QHRA
:
22927 gen_helper_preceq_pw_qhra(cpu_gpr
[ret
], v2_t
);
22929 case OPC_PRECEQU_QH_OBL
:
22931 gen_helper_precequ_qh_obl(cpu_gpr
[ret
], v2_t
);
22933 case OPC_PRECEQU_QH_OBR
:
22935 gen_helper_precequ_qh_obr(cpu_gpr
[ret
], v2_t
);
22937 case OPC_PRECEQU_QH_OBLA
:
22939 gen_helper_precequ_qh_obla(cpu_gpr
[ret
], v2_t
);
22941 case OPC_PRECEQU_QH_OBRA
:
22943 gen_helper_precequ_qh_obra(cpu_gpr
[ret
], v2_t
);
22945 case OPC_PRECEU_QH_OBL
:
22947 gen_helper_preceu_qh_obl(cpu_gpr
[ret
], v2_t
);
22949 case OPC_PRECEU_QH_OBR
:
22951 gen_helper_preceu_qh_obr(cpu_gpr
[ret
], v2_t
);
22953 case OPC_PRECEU_QH_OBLA
:
22955 gen_helper_preceu_qh_obla(cpu_gpr
[ret
], v2_t
);
22957 case OPC_PRECEU_QH_OBRA
:
22959 gen_helper_preceu_qh_obra(cpu_gpr
[ret
], v2_t
);
22961 case OPC_ABSQ_S_OB
:
22963 gen_helper_absq_s_ob(cpu_gpr
[ret
], v2_t
, cpu_env
);
22965 case OPC_ABSQ_S_PW
:
22967 gen_helper_absq_s_pw(cpu_gpr
[ret
], v2_t
, cpu_env
);
22969 case OPC_ABSQ_S_QH
:
22971 gen_helper_absq_s_qh(cpu_gpr
[ret
], v2_t
, cpu_env
);
22975 case OPC_ADDU_OB_DSP
:
22977 case OPC_RADDU_L_OB
:
22979 gen_helper_raddu_l_ob(cpu_gpr
[ret
], v1_t
);
22983 gen_helper_subq_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22985 case OPC_SUBQ_S_PW
:
22987 gen_helper_subq_s_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22991 gen_helper_subq_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22993 case OPC_SUBQ_S_QH
:
22995 gen_helper_subq_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22999 gen_helper_subu_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23001 case OPC_SUBU_S_OB
:
23003 gen_helper_subu_s_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23007 gen_helper_subu_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23009 case OPC_SUBU_S_QH
:
23011 gen_helper_subu_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23015 gen_helper_subuh_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
23017 case OPC_SUBUH_R_OB
:
23019 gen_helper_subuh_r_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
23023 gen_helper_addq_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23025 case OPC_ADDQ_S_PW
:
23027 gen_helper_addq_s_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23031 gen_helper_addq_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23033 case OPC_ADDQ_S_QH
:
23035 gen_helper_addq_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23039 gen_helper_addu_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23041 case OPC_ADDU_S_OB
:
23043 gen_helper_addu_s_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23047 gen_helper_addu_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23049 case OPC_ADDU_S_QH
:
23051 gen_helper_addu_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23055 gen_helper_adduh_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
23057 case OPC_ADDUH_R_OB
:
23059 gen_helper_adduh_r_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
23063 case OPC_CMPU_EQ_OB_DSP
:
23065 case OPC_PRECR_OB_QH
:
23067 gen_helper_precr_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
);
23069 case OPC_PRECR_SRA_QH_PW
:
23072 TCGv_i32 ret_t
= tcg_const_i32(ret
);
23073 gen_helper_precr_sra_qh_pw(v2_t
, v1_t
, v2_t
, ret_t
);
23074 tcg_temp_free_i32(ret_t
);
23077 case OPC_PRECR_SRA_R_QH_PW
:
23080 TCGv_i32 sa_v
= tcg_const_i32(ret
);
23081 gen_helper_precr_sra_r_qh_pw(v2_t
, v1_t
, v2_t
, sa_v
);
23082 tcg_temp_free_i32(sa_v
);
23085 case OPC_PRECRQ_OB_QH
:
23087 gen_helper_precrq_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
);
23089 case OPC_PRECRQ_PW_L
:
23091 gen_helper_precrq_pw_l(cpu_gpr
[ret
], v1_t
, v2_t
);
23093 case OPC_PRECRQ_QH_PW
:
23095 gen_helper_precrq_qh_pw(cpu_gpr
[ret
], v1_t
, v2_t
);
23097 case OPC_PRECRQ_RS_QH_PW
:
23099 gen_helper_precrq_rs_qh_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23101 case OPC_PRECRQU_S_OB_QH
:
23103 gen_helper_precrqu_s_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23110 tcg_temp_free(v1_t
);
23111 tcg_temp_free(v2_t
);
23114 static void gen_mipsdsp_shift(DisasContext
*ctx
, uint32_t opc
,
23115 int ret
, int v1
, int v2
)
23123 /* Treat as NOP. */
23127 t0
= tcg_temp_new();
23128 v1_t
= tcg_temp_new();
23129 v2_t
= tcg_temp_new();
23131 tcg_gen_movi_tl(t0
, v1
);
23132 gen_load_gpr(v1_t
, v1
);
23133 gen_load_gpr(v2_t
, v2
);
23136 case OPC_SHLL_QB_DSP
:
23138 op2
= MASK_SHLL_QB(ctx
->opcode
);
23142 gen_helper_shll_qb(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
23146 gen_helper_shll_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23150 gen_helper_shll_ph(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
23154 gen_helper_shll_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23156 case OPC_SHLL_S_PH
:
23158 gen_helper_shll_s_ph(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
23160 case OPC_SHLLV_S_PH
:
23162 gen_helper_shll_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23166 gen_helper_shll_s_w(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
23168 case OPC_SHLLV_S_W
:
23170 gen_helper_shll_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23174 gen_helper_shrl_qb(cpu_gpr
[ret
], t0
, v2_t
);
23178 gen_helper_shrl_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
23182 gen_helper_shrl_ph(cpu_gpr
[ret
], t0
, v2_t
);
23186 gen_helper_shrl_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
23190 gen_helper_shra_qb(cpu_gpr
[ret
], t0
, v2_t
);
23192 case OPC_SHRA_R_QB
:
23194 gen_helper_shra_r_qb(cpu_gpr
[ret
], t0
, v2_t
);
23198 gen_helper_shra_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
23200 case OPC_SHRAV_R_QB
:
23202 gen_helper_shra_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
23206 gen_helper_shra_ph(cpu_gpr
[ret
], t0
, v2_t
);
23208 case OPC_SHRA_R_PH
:
23210 gen_helper_shra_r_ph(cpu_gpr
[ret
], t0
, v2_t
);
23214 gen_helper_shra_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
23216 case OPC_SHRAV_R_PH
:
23218 gen_helper_shra_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
23222 gen_helper_shra_r_w(cpu_gpr
[ret
], t0
, v2_t
);
23224 case OPC_SHRAV_R_W
:
23226 gen_helper_shra_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
23228 default: /* Invalid */
23229 MIPS_INVAL("MASK SHLL.QB");
23230 gen_reserved_instruction(ctx
);
23235 #ifdef TARGET_MIPS64
23236 case OPC_SHLL_OB_DSP
:
23237 op2
= MASK_SHLL_OB(ctx
->opcode
);
23241 gen_helper_shll_pw(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
23245 gen_helper_shll_pw(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
23247 case OPC_SHLL_S_PW
:
23249 gen_helper_shll_s_pw(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
23251 case OPC_SHLLV_S_PW
:
23253 gen_helper_shll_s_pw(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
23257 gen_helper_shll_ob(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
23261 gen_helper_shll_ob(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
23265 gen_helper_shll_qh(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
23269 gen_helper_shll_qh(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
23271 case OPC_SHLL_S_QH
:
23273 gen_helper_shll_s_qh(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
23275 case OPC_SHLLV_S_QH
:
23277 gen_helper_shll_s_qh(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
23281 gen_helper_shra_ob(cpu_gpr
[ret
], v2_t
, t0
);
23285 gen_helper_shra_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
23287 case OPC_SHRA_R_OB
:
23289 gen_helper_shra_r_ob(cpu_gpr
[ret
], v2_t
, t0
);
23291 case OPC_SHRAV_R_OB
:
23293 gen_helper_shra_r_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
23297 gen_helper_shra_pw(cpu_gpr
[ret
], v2_t
, t0
);
23301 gen_helper_shra_pw(cpu_gpr
[ret
], v2_t
, v1_t
);
23303 case OPC_SHRA_R_PW
:
23305 gen_helper_shra_r_pw(cpu_gpr
[ret
], v2_t
, t0
);
23307 case OPC_SHRAV_R_PW
:
23309 gen_helper_shra_r_pw(cpu_gpr
[ret
], v2_t
, v1_t
);
23313 gen_helper_shra_qh(cpu_gpr
[ret
], v2_t
, t0
);
23317 gen_helper_shra_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
23319 case OPC_SHRA_R_QH
:
23321 gen_helper_shra_r_qh(cpu_gpr
[ret
], v2_t
, t0
);
23323 case OPC_SHRAV_R_QH
:
23325 gen_helper_shra_r_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
23329 gen_helper_shrl_ob(cpu_gpr
[ret
], v2_t
, t0
);
23333 gen_helper_shrl_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
23337 gen_helper_shrl_qh(cpu_gpr
[ret
], v2_t
, t0
);
23341 gen_helper_shrl_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
23343 default: /* Invalid */
23344 MIPS_INVAL("MASK SHLL.OB");
23345 gen_reserved_instruction(ctx
);
23353 tcg_temp_free(v1_t
);
23354 tcg_temp_free(v2_t
);
23357 static void gen_mipsdsp_multiply(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
23358 int ret
, int v1
, int v2
, int check_ret
)
23364 if ((ret
== 0) && (check_ret
== 1)) {
23365 /* Treat as NOP. */
23369 t0
= tcg_temp_new_i32();
23370 v1_t
= tcg_temp_new();
23371 v2_t
= tcg_temp_new();
23373 tcg_gen_movi_i32(t0
, ret
);
23374 gen_load_gpr(v1_t
, v1
);
23375 gen_load_gpr(v2_t
, v2
);
23379 * OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
23380 * the same mask and op1.
23382 case OPC_MULT_G_2E
:
23386 gen_helper_mul_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23389 gen_helper_mul_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23392 gen_helper_mulq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23394 case OPC_MULQ_RS_W
:
23395 gen_helper_mulq_rs_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23399 case OPC_DPA_W_PH_DSP
:
23401 case OPC_DPAU_H_QBL
:
23403 gen_helper_dpau_h_qbl(t0
, v1_t
, v2_t
, cpu_env
);
23405 case OPC_DPAU_H_QBR
:
23407 gen_helper_dpau_h_qbr(t0
, v1_t
, v2_t
, cpu_env
);
23409 case OPC_DPSU_H_QBL
:
23411 gen_helper_dpsu_h_qbl(t0
, v1_t
, v2_t
, cpu_env
);
23413 case OPC_DPSU_H_QBR
:
23415 gen_helper_dpsu_h_qbr(t0
, v1_t
, v2_t
, cpu_env
);
23419 gen_helper_dpa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23421 case OPC_DPAX_W_PH
:
23423 gen_helper_dpax_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23425 case OPC_DPAQ_S_W_PH
:
23427 gen_helper_dpaq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23429 case OPC_DPAQX_S_W_PH
:
23431 gen_helper_dpaqx_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23433 case OPC_DPAQX_SA_W_PH
:
23435 gen_helper_dpaqx_sa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23439 gen_helper_dps_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23441 case OPC_DPSX_W_PH
:
23443 gen_helper_dpsx_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23445 case OPC_DPSQ_S_W_PH
:
23447 gen_helper_dpsq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23449 case OPC_DPSQX_S_W_PH
:
23451 gen_helper_dpsqx_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23453 case OPC_DPSQX_SA_W_PH
:
23455 gen_helper_dpsqx_sa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23457 case OPC_MULSAQ_S_W_PH
:
23459 gen_helper_mulsaq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23461 case OPC_DPAQ_SA_L_W
:
23463 gen_helper_dpaq_sa_l_w(t0
, v1_t
, v2_t
, cpu_env
);
23465 case OPC_DPSQ_SA_L_W
:
23467 gen_helper_dpsq_sa_l_w(t0
, v1_t
, v2_t
, cpu_env
);
23469 case OPC_MAQ_S_W_PHL
:
23471 gen_helper_maq_s_w_phl(t0
, v1_t
, v2_t
, cpu_env
);
23473 case OPC_MAQ_S_W_PHR
:
23475 gen_helper_maq_s_w_phr(t0
, v1_t
, v2_t
, cpu_env
);
23477 case OPC_MAQ_SA_W_PHL
:
23479 gen_helper_maq_sa_w_phl(t0
, v1_t
, v2_t
, cpu_env
);
23481 case OPC_MAQ_SA_W_PHR
:
23483 gen_helper_maq_sa_w_phr(t0
, v1_t
, v2_t
, cpu_env
);
23485 case OPC_MULSA_W_PH
:
23487 gen_helper_mulsa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23491 #ifdef TARGET_MIPS64
23492 case OPC_DPAQ_W_QH_DSP
:
23494 int ac
= ret
& 0x03;
23495 tcg_gen_movi_i32(t0
, ac
);
23500 gen_helper_dmadd(v1_t
, v2_t
, t0
, cpu_env
);
23504 gen_helper_dmaddu(v1_t
, v2_t
, t0
, cpu_env
);
23508 gen_helper_dmsub(v1_t
, v2_t
, t0
, cpu_env
);
23512 gen_helper_dmsubu(v1_t
, v2_t
, t0
, cpu_env
);
23516 gen_helper_dpa_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
23518 case OPC_DPAQ_S_W_QH
:
23520 gen_helper_dpaq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
23522 case OPC_DPAQ_SA_L_PW
:
23524 gen_helper_dpaq_sa_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
23526 case OPC_DPAU_H_OBL
:
23528 gen_helper_dpau_h_obl(v1_t
, v2_t
, t0
, cpu_env
);
23530 case OPC_DPAU_H_OBR
:
23532 gen_helper_dpau_h_obr(v1_t
, v2_t
, t0
, cpu_env
);
23536 gen_helper_dps_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
23538 case OPC_DPSQ_S_W_QH
:
23540 gen_helper_dpsq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
23542 case OPC_DPSQ_SA_L_PW
:
23544 gen_helper_dpsq_sa_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
23546 case OPC_DPSU_H_OBL
:
23548 gen_helper_dpsu_h_obl(v1_t
, v2_t
, t0
, cpu_env
);
23550 case OPC_DPSU_H_OBR
:
23552 gen_helper_dpsu_h_obr(v1_t
, v2_t
, t0
, cpu_env
);
23554 case OPC_MAQ_S_L_PWL
:
23556 gen_helper_maq_s_l_pwl(v1_t
, v2_t
, t0
, cpu_env
);
23558 case OPC_MAQ_S_L_PWR
:
23560 gen_helper_maq_s_l_pwr(v1_t
, v2_t
, t0
, cpu_env
);
23562 case OPC_MAQ_S_W_QHLL
:
23564 gen_helper_maq_s_w_qhll(v1_t
, v2_t
, t0
, cpu_env
);
23566 case OPC_MAQ_SA_W_QHLL
:
23568 gen_helper_maq_sa_w_qhll(v1_t
, v2_t
, t0
, cpu_env
);
23570 case OPC_MAQ_S_W_QHLR
:
23572 gen_helper_maq_s_w_qhlr(v1_t
, v2_t
, t0
, cpu_env
);
23574 case OPC_MAQ_SA_W_QHLR
:
23576 gen_helper_maq_sa_w_qhlr(v1_t
, v2_t
, t0
, cpu_env
);
23578 case OPC_MAQ_S_W_QHRL
:
23580 gen_helper_maq_s_w_qhrl(v1_t
, v2_t
, t0
, cpu_env
);
23582 case OPC_MAQ_SA_W_QHRL
:
23584 gen_helper_maq_sa_w_qhrl(v1_t
, v2_t
, t0
, cpu_env
);
23586 case OPC_MAQ_S_W_QHRR
:
23588 gen_helper_maq_s_w_qhrr(v1_t
, v2_t
, t0
, cpu_env
);
23590 case OPC_MAQ_SA_W_QHRR
:
23592 gen_helper_maq_sa_w_qhrr(v1_t
, v2_t
, t0
, cpu_env
);
23594 case OPC_MULSAQ_S_L_PW
:
23596 gen_helper_mulsaq_s_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
23598 case OPC_MULSAQ_S_W_QH
:
23600 gen_helper_mulsaq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
23606 case OPC_ADDU_QB_DSP
:
23608 case OPC_MULEU_S_PH_QBL
:
23610 gen_helper_muleu_s_ph_qbl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23612 case OPC_MULEU_S_PH_QBR
:
23614 gen_helper_muleu_s_ph_qbr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23616 case OPC_MULQ_RS_PH
:
23618 gen_helper_mulq_rs_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23620 case OPC_MULEQ_S_W_PHL
:
23622 gen_helper_muleq_s_w_phl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23624 case OPC_MULEQ_S_W_PHR
:
23626 gen_helper_muleq_s_w_phr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23628 case OPC_MULQ_S_PH
:
23630 gen_helper_mulq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23634 #ifdef TARGET_MIPS64
23635 case OPC_ADDU_OB_DSP
:
23637 case OPC_MULEQ_S_PW_QHL
:
23639 gen_helper_muleq_s_pw_qhl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23641 case OPC_MULEQ_S_PW_QHR
:
23643 gen_helper_muleq_s_pw_qhr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23645 case OPC_MULEU_S_QH_OBL
:
23647 gen_helper_muleu_s_qh_obl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23649 case OPC_MULEU_S_QH_OBR
:
23651 gen_helper_muleu_s_qh_obr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23653 case OPC_MULQ_RS_QH
:
23655 gen_helper_mulq_rs_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23662 tcg_temp_free_i32(t0
);
23663 tcg_temp_free(v1_t
);
23664 tcg_temp_free(v2_t
);
23667 static void gen_mipsdsp_bitinsn(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
23675 /* Treat as NOP. */
23679 t0
= tcg_temp_new();
23680 val_t
= tcg_temp_new();
23681 gen_load_gpr(val_t
, val
);
23684 case OPC_ABSQ_S_PH_DSP
:
23688 gen_helper_bitrev(cpu_gpr
[ret
], val_t
);
23693 target_long result
;
23694 imm
= (ctx
->opcode
>> 16) & 0xFF;
23695 result
= (uint32_t)imm
<< 24 |
23696 (uint32_t)imm
<< 16 |
23697 (uint32_t)imm
<< 8 |
23699 result
= (int32_t)result
;
23700 tcg_gen_movi_tl(cpu_gpr
[ret
], result
);
23705 tcg_gen_ext8u_tl(cpu_gpr
[ret
], val_t
);
23706 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 8);
23707 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
23708 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
23709 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
23710 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
23715 imm
= (ctx
->opcode
>> 16) & 0x03FF;
23716 imm
= (int16_t)(imm
<< 6) >> 6;
23717 tcg_gen_movi_tl(cpu_gpr
[ret
], \
23718 (target_long
)((int32_t)imm
<< 16 | \
23724 tcg_gen_ext16u_tl(cpu_gpr
[ret
], val_t
);
23725 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
23726 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
23727 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
23731 #ifdef TARGET_MIPS64
23732 case OPC_ABSQ_S_QH_DSP
:
23739 imm
= (ctx
->opcode
>> 16) & 0xFF;
23740 temp
= ((uint64_t)imm
<< 8) | (uint64_t)imm
;
23741 temp
= (temp
<< 16) | temp
;
23742 temp
= (temp
<< 32) | temp
;
23743 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
23751 imm
= (ctx
->opcode
>> 16) & 0x03FF;
23752 imm
= (int16_t)(imm
<< 6) >> 6;
23753 temp
= ((target_long
)imm
<< 32) \
23754 | ((target_long
)imm
& 0xFFFFFFFF);
23755 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
23763 imm
= (ctx
->opcode
>> 16) & 0x03FF;
23764 imm
= (int16_t)(imm
<< 6) >> 6;
23766 temp
= ((uint64_t)(uint16_t)imm
<< 48) |
23767 ((uint64_t)(uint16_t)imm
<< 32) |
23768 ((uint64_t)(uint16_t)imm
<< 16) |
23769 (uint64_t)(uint16_t)imm
;
23770 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
23775 tcg_gen_ext8u_tl(cpu_gpr
[ret
], val_t
);
23776 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 8);
23777 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
23778 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
23779 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
23780 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
23781 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
23785 tcg_gen_ext32u_i64(cpu_gpr
[ret
], val_t
);
23786 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
23787 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
23791 tcg_gen_ext16u_tl(cpu_gpr
[ret
], val_t
);
23792 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
23793 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
23794 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
23795 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
23802 tcg_temp_free(val_t
);
23805 static void gen_mipsdsp_add_cmp_pick(DisasContext
*ctx
,
23806 uint32_t op1
, uint32_t op2
,
23807 int ret
, int v1
, int v2
, int check_ret
)
23813 if ((ret
== 0) && (check_ret
== 1)) {
23814 /* Treat as NOP. */
23818 t1
= tcg_temp_new();
23819 v1_t
= tcg_temp_new();
23820 v2_t
= tcg_temp_new();
23822 gen_load_gpr(v1_t
, v1
);
23823 gen_load_gpr(v2_t
, v2
);
23826 case OPC_CMPU_EQ_QB_DSP
:
23828 case OPC_CMPU_EQ_QB
:
23830 gen_helper_cmpu_eq_qb(v1_t
, v2_t
, cpu_env
);
23832 case OPC_CMPU_LT_QB
:
23834 gen_helper_cmpu_lt_qb(v1_t
, v2_t
, cpu_env
);
23836 case OPC_CMPU_LE_QB
:
23838 gen_helper_cmpu_le_qb(v1_t
, v2_t
, cpu_env
);
23840 case OPC_CMPGU_EQ_QB
:
23842 gen_helper_cmpgu_eq_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
23844 case OPC_CMPGU_LT_QB
:
23846 gen_helper_cmpgu_lt_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
23848 case OPC_CMPGU_LE_QB
:
23850 gen_helper_cmpgu_le_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
23852 case OPC_CMPGDU_EQ_QB
:
23854 gen_helper_cmpgu_eq_qb(t1
, v1_t
, v2_t
);
23855 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
23856 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
23857 tcg_gen_shli_tl(t1
, t1
, 24);
23858 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
23860 case OPC_CMPGDU_LT_QB
:
23862 gen_helper_cmpgu_lt_qb(t1
, v1_t
, v2_t
);
23863 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
23864 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
23865 tcg_gen_shli_tl(t1
, t1
, 24);
23866 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
23868 case OPC_CMPGDU_LE_QB
:
23870 gen_helper_cmpgu_le_qb(t1
, v1_t
, v2_t
);
23871 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
23872 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
23873 tcg_gen_shli_tl(t1
, t1
, 24);
23874 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
23876 case OPC_CMP_EQ_PH
:
23878 gen_helper_cmp_eq_ph(v1_t
, v2_t
, cpu_env
);
23880 case OPC_CMP_LT_PH
:
23882 gen_helper_cmp_lt_ph(v1_t
, v2_t
, cpu_env
);
23884 case OPC_CMP_LE_PH
:
23886 gen_helper_cmp_le_ph(v1_t
, v2_t
, cpu_env
);
23890 gen_helper_pick_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23894 gen_helper_pick_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23896 case OPC_PACKRL_PH
:
23898 gen_helper_packrl_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
23902 #ifdef TARGET_MIPS64
23903 case OPC_CMPU_EQ_OB_DSP
:
23905 case OPC_CMP_EQ_PW
:
23907 gen_helper_cmp_eq_pw(v1_t
, v2_t
, cpu_env
);
23909 case OPC_CMP_LT_PW
:
23911 gen_helper_cmp_lt_pw(v1_t
, v2_t
, cpu_env
);
23913 case OPC_CMP_LE_PW
:
23915 gen_helper_cmp_le_pw(v1_t
, v2_t
, cpu_env
);
23917 case OPC_CMP_EQ_QH
:
23919 gen_helper_cmp_eq_qh(v1_t
, v2_t
, cpu_env
);
23921 case OPC_CMP_LT_QH
:
23923 gen_helper_cmp_lt_qh(v1_t
, v2_t
, cpu_env
);
23925 case OPC_CMP_LE_QH
:
23927 gen_helper_cmp_le_qh(v1_t
, v2_t
, cpu_env
);
23929 case OPC_CMPGDU_EQ_OB
:
23931 gen_helper_cmpgdu_eq_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23933 case OPC_CMPGDU_LT_OB
:
23935 gen_helper_cmpgdu_lt_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23937 case OPC_CMPGDU_LE_OB
:
23939 gen_helper_cmpgdu_le_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23941 case OPC_CMPGU_EQ_OB
:
23943 gen_helper_cmpgu_eq_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
23945 case OPC_CMPGU_LT_OB
:
23947 gen_helper_cmpgu_lt_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
23949 case OPC_CMPGU_LE_OB
:
23951 gen_helper_cmpgu_le_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
23953 case OPC_CMPU_EQ_OB
:
23955 gen_helper_cmpu_eq_ob(v1_t
, v2_t
, cpu_env
);
23957 case OPC_CMPU_LT_OB
:
23959 gen_helper_cmpu_lt_ob(v1_t
, v2_t
, cpu_env
);
23961 case OPC_CMPU_LE_OB
:
23963 gen_helper_cmpu_le_ob(v1_t
, v2_t
, cpu_env
);
23965 case OPC_PACKRL_PW
:
23967 gen_helper_packrl_pw(cpu_gpr
[ret
], v1_t
, v2_t
);
23971 gen_helper_pick_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23975 gen_helper_pick_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23979 gen_helper_pick_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23987 tcg_temp_free(v1_t
);
23988 tcg_temp_free(v2_t
);
23991 static void gen_mipsdsp_append(CPUMIPSState
*env
, DisasContext
*ctx
,
23992 uint32_t op1
, int rt
, int rs
, int sa
)
23999 /* Treat as NOP. */
24003 t0
= tcg_temp_new();
24004 gen_load_gpr(t0
, rs
);
24007 case OPC_APPEND_DSP
:
24008 switch (MASK_APPEND(ctx
->opcode
)) {
24011 tcg_gen_deposit_tl(cpu_gpr
[rt
], t0
, cpu_gpr
[rt
], sa
, 32 - sa
);
24013 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
24017 tcg_gen_ext32u_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
24018 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], sa
);
24019 tcg_gen_shli_tl(t0
, t0
, 32 - sa
);
24020 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
24022 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
24026 if (sa
!= 0 && sa
!= 2) {
24027 tcg_gen_shli_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 8 * sa
);
24028 tcg_gen_ext32u_tl(t0
, t0
);
24029 tcg_gen_shri_tl(t0
, t0
, 8 * (4 - sa
));
24030 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
24032 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
24034 default: /* Invalid */
24035 MIPS_INVAL("MASK APPEND");
24036 gen_reserved_instruction(ctx
);
24040 #ifdef TARGET_MIPS64
24041 case OPC_DAPPEND_DSP
:
24042 switch (MASK_DAPPEND(ctx
->opcode
)) {
24045 tcg_gen_deposit_tl(cpu_gpr
[rt
], t0
, cpu_gpr
[rt
], sa
, 64 - sa
);
24049 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 0x20 | sa
);
24050 tcg_gen_shli_tl(t0
, t0
, 64 - (0x20 | sa
));
24051 tcg_gen_or_tl(cpu_gpr
[rt
], t0
, t0
);
24055 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], sa
);
24056 tcg_gen_shli_tl(t0
, t0
, 64 - sa
);
24057 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
24062 if (sa
!= 0 && sa
!= 2 && sa
!= 4) {
24063 tcg_gen_shli_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 8 * sa
);
24064 tcg_gen_shri_tl(t0
, t0
, 8 * (8 - sa
));
24065 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
24068 default: /* Invalid */
24069 MIPS_INVAL("MASK DAPPEND");
24070 gen_reserved_instruction(ctx
);
24079 static void gen_mipsdsp_accinsn(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
24080 int ret
, int v1
, int v2
, int check_ret
)
24089 if ((ret
== 0) && (check_ret
== 1)) {
24090 /* Treat as NOP. */
24094 t0
= tcg_temp_new();
24095 t1
= tcg_temp_new();
24096 v1_t
= tcg_temp_new();
24097 v2_t
= tcg_temp_new();
24099 gen_load_gpr(v1_t
, v1
);
24100 gen_load_gpr(v2_t
, v2
);
24103 case OPC_EXTR_W_DSP
:
24107 tcg_gen_movi_tl(t0
, v2
);
24108 tcg_gen_movi_tl(t1
, v1
);
24109 gen_helper_extr_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24112 tcg_gen_movi_tl(t0
, v2
);
24113 tcg_gen_movi_tl(t1
, v1
);
24114 gen_helper_extr_r_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24116 case OPC_EXTR_RS_W
:
24117 tcg_gen_movi_tl(t0
, v2
);
24118 tcg_gen_movi_tl(t1
, v1
);
24119 gen_helper_extr_rs_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24122 tcg_gen_movi_tl(t0
, v2
);
24123 tcg_gen_movi_tl(t1
, v1
);
24124 gen_helper_extr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24126 case OPC_EXTRV_S_H
:
24127 tcg_gen_movi_tl(t0
, v2
);
24128 gen_helper_extr_s_h(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24131 tcg_gen_movi_tl(t0
, v2
);
24132 gen_helper_extr_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24134 case OPC_EXTRV_R_W
:
24135 tcg_gen_movi_tl(t0
, v2
);
24136 gen_helper_extr_r_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24138 case OPC_EXTRV_RS_W
:
24139 tcg_gen_movi_tl(t0
, v2
);
24140 gen_helper_extr_rs_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24143 tcg_gen_movi_tl(t0
, v2
);
24144 tcg_gen_movi_tl(t1
, v1
);
24145 gen_helper_extp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24148 tcg_gen_movi_tl(t0
, v2
);
24149 gen_helper_extp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24152 tcg_gen_movi_tl(t0
, v2
);
24153 tcg_gen_movi_tl(t1
, v1
);
24154 gen_helper_extpdp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24157 tcg_gen_movi_tl(t0
, v2
);
24158 gen_helper_extpdp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24161 imm
= (ctx
->opcode
>> 20) & 0x3F;
24162 tcg_gen_movi_tl(t0
, ret
);
24163 tcg_gen_movi_tl(t1
, imm
);
24164 gen_helper_shilo(t0
, t1
, cpu_env
);
24167 tcg_gen_movi_tl(t0
, ret
);
24168 gen_helper_shilo(t0
, v1_t
, cpu_env
);
24171 tcg_gen_movi_tl(t0
, ret
);
24172 gen_helper_mthlip(t0
, v1_t
, cpu_env
);
24175 imm
= (ctx
->opcode
>> 11) & 0x3FF;
24176 tcg_gen_movi_tl(t0
, imm
);
24177 gen_helper_wrdsp(v1_t
, t0
, cpu_env
);
24180 imm
= (ctx
->opcode
>> 16) & 0x03FF;
24181 tcg_gen_movi_tl(t0
, imm
);
24182 gen_helper_rddsp(cpu_gpr
[ret
], t0
, cpu_env
);
24186 #ifdef TARGET_MIPS64
24187 case OPC_DEXTR_W_DSP
:
24191 tcg_gen_movi_tl(t0
, ret
);
24192 gen_helper_dmthlip(v1_t
, t0
, cpu_env
);
24196 int shift
= (ctx
->opcode
>> 19) & 0x7F;
24197 int ac
= (ctx
->opcode
>> 11) & 0x03;
24198 tcg_gen_movi_tl(t0
, shift
);
24199 tcg_gen_movi_tl(t1
, ac
);
24200 gen_helper_dshilo(t0
, t1
, cpu_env
);
24205 int ac
= (ctx
->opcode
>> 11) & 0x03;
24206 tcg_gen_movi_tl(t0
, ac
);
24207 gen_helper_dshilo(v1_t
, t0
, cpu_env
);
24211 tcg_gen_movi_tl(t0
, v2
);
24212 tcg_gen_movi_tl(t1
, v1
);
24214 gen_helper_dextp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24217 tcg_gen_movi_tl(t0
, v2
);
24218 gen_helper_dextp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24221 tcg_gen_movi_tl(t0
, v2
);
24222 tcg_gen_movi_tl(t1
, v1
);
24223 gen_helper_dextpdp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24226 tcg_gen_movi_tl(t0
, v2
);
24227 gen_helper_dextpdp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24230 tcg_gen_movi_tl(t0
, v2
);
24231 tcg_gen_movi_tl(t1
, v1
);
24232 gen_helper_dextr_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24234 case OPC_DEXTR_R_L
:
24235 tcg_gen_movi_tl(t0
, v2
);
24236 tcg_gen_movi_tl(t1
, v1
);
24237 gen_helper_dextr_r_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24239 case OPC_DEXTR_RS_L
:
24240 tcg_gen_movi_tl(t0
, v2
);
24241 tcg_gen_movi_tl(t1
, v1
);
24242 gen_helper_dextr_rs_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24245 tcg_gen_movi_tl(t0
, v2
);
24246 tcg_gen_movi_tl(t1
, v1
);
24247 gen_helper_dextr_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24249 case OPC_DEXTR_R_W
:
24250 tcg_gen_movi_tl(t0
, v2
);
24251 tcg_gen_movi_tl(t1
, v1
);
24252 gen_helper_dextr_r_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24254 case OPC_DEXTR_RS_W
:
24255 tcg_gen_movi_tl(t0
, v2
);
24256 tcg_gen_movi_tl(t1
, v1
);
24257 gen_helper_dextr_rs_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24259 case OPC_DEXTR_S_H
:
24260 tcg_gen_movi_tl(t0
, v2
);
24261 tcg_gen_movi_tl(t1
, v1
);
24262 gen_helper_dextr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24264 case OPC_DEXTRV_S_H
:
24265 tcg_gen_movi_tl(t0
, v2
);
24266 tcg_gen_movi_tl(t1
, v1
);
24267 gen_helper_dextr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24270 tcg_gen_movi_tl(t0
, v2
);
24271 gen_helper_dextr_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24273 case OPC_DEXTRV_R_L
:
24274 tcg_gen_movi_tl(t0
, v2
);
24275 gen_helper_dextr_r_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24277 case OPC_DEXTRV_RS_L
:
24278 tcg_gen_movi_tl(t0
, v2
);
24279 gen_helper_dextr_rs_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24282 tcg_gen_movi_tl(t0
, v2
);
24283 gen_helper_dextr_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24285 case OPC_DEXTRV_R_W
:
24286 tcg_gen_movi_tl(t0
, v2
);
24287 gen_helper_dextr_r_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24289 case OPC_DEXTRV_RS_W
:
24290 tcg_gen_movi_tl(t0
, v2
);
24291 gen_helper_dextr_rs_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24300 tcg_temp_free(v1_t
);
24301 tcg_temp_free(v2_t
);
24304 /* End MIPSDSP functions. */
24306 static void decode_opc_special_r6(CPUMIPSState
*env
, DisasContext
*ctx
)
24308 int rs
, rt
, rd
, sa
;
24311 rs
= (ctx
->opcode
>> 21) & 0x1f;
24312 rt
= (ctx
->opcode
>> 16) & 0x1f;
24313 rd
= (ctx
->opcode
>> 11) & 0x1f;
24314 sa
= (ctx
->opcode
>> 6) & 0x1f;
24316 op1
= MASK_SPECIAL(ctx
->opcode
);
24322 op2
= MASK_R6_MULDIV(ctx
->opcode
);
24332 gen_r6_muldiv(ctx
, op2
, rd
, rs
, rt
);
24335 MIPS_INVAL("special_r6 muldiv");
24336 gen_reserved_instruction(ctx
);
24342 gen_cond_move(ctx
, op1
, rd
, rs
, rt
);
24346 if (rt
== 0 && sa
== 1) {
24348 * Major opcode and function field is shared with preR6 MFHI/MTHI.
24349 * We need additionally to check other fields.
24351 gen_cl(ctx
, op1
, rd
, rs
);
24353 gen_reserved_instruction(ctx
);
24357 if (is_uhi(extract32(ctx
->opcode
, 6, 20))) {
24358 gen_helper_do_semihosting(cpu_env
);
24360 if (ctx
->hflags
& MIPS_HFLAG_SBRI
) {
24361 gen_reserved_instruction(ctx
);
24363 generate_exception_end(ctx
, EXCP_DBp
);
24367 #if defined(TARGET_MIPS64)
24370 if (rt
== 0 && sa
== 1) {
24372 * Major opcode and function field is shared with preR6 MFHI/MTHI.
24373 * We need additionally to check other fields.
24375 check_mips_64(ctx
);
24376 gen_cl(ctx
, op1
, rd
, rs
);
24378 gen_reserved_instruction(ctx
);
24386 op2
= MASK_R6_MULDIV(ctx
->opcode
);
24396 check_mips_64(ctx
);
24397 gen_r6_muldiv(ctx
, op2
, rd
, rs
, rt
);
24400 MIPS_INVAL("special_r6 muldiv");
24401 gen_reserved_instruction(ctx
);
24406 default: /* Invalid */
24407 MIPS_INVAL("special_r6");
24408 gen_reserved_instruction(ctx
);
24413 static void decode_opc_special_tx79(CPUMIPSState
*env
, DisasContext
*ctx
)
24415 int rs
= extract32(ctx
->opcode
, 21, 5);
24416 int rt
= extract32(ctx
->opcode
, 16, 5);
24417 int rd
= extract32(ctx
->opcode
, 11, 5);
24418 uint32_t op1
= MASK_SPECIAL(ctx
->opcode
);
24421 case OPC_MOVN
: /* Conditional move */
24423 gen_cond_move(ctx
, op1
, rd
, rs
, rt
);
24425 case OPC_MFHI
: /* Move from HI/LO */
24427 gen_HILO(ctx
, op1
, 0, rd
);
24430 case OPC_MTLO
: /* Move to HI/LO */
24431 gen_HILO(ctx
, op1
, 0, rs
);
24435 gen_mul_txx9(ctx
, op1
, rd
, rs
, rt
);
24439 gen_muldiv(ctx
, op1
, 0, rs
, rt
);
24441 #if defined(TARGET_MIPS64)
24446 check_insn_opc_user_only(ctx
, INSN_R5900
);
24447 gen_muldiv(ctx
, op1
, 0, rs
, rt
);
24451 gen_compute_branch(ctx
, op1
, 4, rs
, 0, 0, 4);
24453 default: /* Invalid */
24454 MIPS_INVAL("special_tx79");
24455 gen_reserved_instruction(ctx
);
24460 static void decode_opc_special_legacy(CPUMIPSState
*env
, DisasContext
*ctx
)
24462 int rs
, rt
, rd
, sa
;
24465 rs
= (ctx
->opcode
>> 21) & 0x1f;
24466 rt
= (ctx
->opcode
>> 16) & 0x1f;
24467 rd
= (ctx
->opcode
>> 11) & 0x1f;
24468 sa
= (ctx
->opcode
>> 6) & 0x1f;
24470 op1
= MASK_SPECIAL(ctx
->opcode
);
24472 case OPC_MOVN
: /* Conditional move */
24474 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS_R1
|
24475 INSN_LOONGSON2E
| INSN_LOONGSON2F
);
24476 gen_cond_move(ctx
, op1
, rd
, rs
, rt
);
24478 case OPC_MFHI
: /* Move from HI/LO */
24480 gen_HILO(ctx
, op1
, rs
& 3, rd
);
24483 case OPC_MTLO
: /* Move to HI/LO */
24484 gen_HILO(ctx
, op1
, rd
& 3, rs
);
24487 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS_R1
);
24488 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
24489 check_cp1_enabled(ctx
);
24490 gen_movci(ctx
, rd
, rs
, (ctx
->opcode
>> 18) & 0x7,
24491 (ctx
->opcode
>> 16) & 1);
24493 generate_exception_err(ctx
, EXCP_CpU
, 1);
24499 check_insn(ctx
, INSN_VR54XX
);
24500 op1
= MASK_MUL_VR54XX(ctx
->opcode
);
24501 gen_mul_vr54xx(ctx
, op1
, rd
, rs
, rt
);
24503 gen_muldiv(ctx
, op1
, rd
& 3, rs
, rt
);
24508 gen_muldiv(ctx
, op1
, 0, rs
, rt
);
24510 #if defined(TARGET_MIPS64)
24515 check_insn(ctx
, ISA_MIPS3
);
24516 check_mips_64(ctx
);
24517 gen_muldiv(ctx
, op1
, 0, rs
, rt
);
24521 gen_compute_branch(ctx
, op1
, 4, rs
, rd
, sa
, 4);
24524 #ifdef MIPS_STRICT_STANDARD
24525 MIPS_INVAL("SPIM");
24526 gen_reserved_instruction(ctx
);
24528 /* Implemented as RI exception for now. */
24529 MIPS_INVAL("spim (unofficial)");
24530 gen_reserved_instruction(ctx
);
24533 default: /* Invalid */
24534 MIPS_INVAL("special_legacy");
24535 gen_reserved_instruction(ctx
);
24540 static void decode_opc_special(CPUMIPSState
*env
, DisasContext
*ctx
)
24542 int rs
, rt
, rd
, sa
;
24545 rs
= (ctx
->opcode
>> 21) & 0x1f;
24546 rt
= (ctx
->opcode
>> 16) & 0x1f;
24547 rd
= (ctx
->opcode
>> 11) & 0x1f;
24548 sa
= (ctx
->opcode
>> 6) & 0x1f;
24550 op1
= MASK_SPECIAL(ctx
->opcode
);
24552 case OPC_SLL
: /* Shift with immediate */
24553 if (sa
== 5 && rd
== 0 &&
24554 rs
== 0 && rt
== 0) { /* PAUSE */
24555 if ((ctx
->insn_flags
& ISA_MIPS_R6
) &&
24556 (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
24557 gen_reserved_instruction(ctx
);
24563 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
24566 switch ((ctx
->opcode
>> 21) & 0x1f) {
24568 /* rotr is decoded as srl on non-R2 CPUs */
24569 if (ctx
->insn_flags
& ISA_MIPS_R2
) {
24574 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
24577 gen_reserved_instruction(ctx
);
24585 gen_arith(ctx
, op1
, rd
, rs
, rt
);
24587 case OPC_SLLV
: /* Shifts */
24589 gen_shift(ctx
, op1
, rd
, rs
, rt
);
24592 switch ((ctx
->opcode
>> 6) & 0x1f) {
24594 /* rotrv is decoded as srlv on non-R2 CPUs */
24595 if (ctx
->insn_flags
& ISA_MIPS_R2
) {
24600 gen_shift(ctx
, op1
, rd
, rs
, rt
);
24603 gen_reserved_instruction(ctx
);
24607 case OPC_SLT
: /* Set on less than */
24609 gen_slt(ctx
, op1
, rd
, rs
, rt
);
24611 case OPC_AND
: /* Logic*/
24615 gen_logic(ctx
, op1
, rd
, rs
, rt
);
24618 gen_compute_branch(ctx
, op1
, 4, rs
, rd
, sa
, 4);
24620 case OPC_TGE
: /* Traps */
24626 check_insn(ctx
, ISA_MIPS2
);
24627 gen_trap(ctx
, op1
, rs
, rt
, -1);
24630 /* Pmon entry point, also R4010 selsl */
24631 #ifdef MIPS_STRICT_STANDARD
24632 MIPS_INVAL("PMON / selsl");
24633 gen_reserved_instruction(ctx
);
24635 gen_helper_0e0i(pmon
, sa
);
24639 generate_exception_end(ctx
, EXCP_SYSCALL
);
24642 generate_exception_end(ctx
, EXCP_BREAK
);
24645 check_insn(ctx
, ISA_MIPS2
);
24646 gen_sync(extract32(ctx
->opcode
, 6, 5));
24649 #if defined(TARGET_MIPS64)
24650 /* MIPS64 specific opcodes */
24655 check_insn(ctx
, ISA_MIPS3
);
24656 check_mips_64(ctx
);
24657 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
24660 switch ((ctx
->opcode
>> 21) & 0x1f) {
24662 /* drotr is decoded as dsrl on non-R2 CPUs */
24663 if (ctx
->insn_flags
& ISA_MIPS_R2
) {
24668 check_insn(ctx
, ISA_MIPS3
);
24669 check_mips_64(ctx
);
24670 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
24673 gen_reserved_instruction(ctx
);
24678 switch ((ctx
->opcode
>> 21) & 0x1f) {
24680 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
24681 if (ctx
->insn_flags
& ISA_MIPS_R2
) {
24686 check_insn(ctx
, ISA_MIPS3
);
24687 check_mips_64(ctx
);
24688 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
24691 gen_reserved_instruction(ctx
);
24699 check_insn(ctx
, ISA_MIPS3
);
24700 check_mips_64(ctx
);
24701 gen_arith(ctx
, op1
, rd
, rs
, rt
);
24705 check_insn(ctx
, ISA_MIPS3
);
24706 check_mips_64(ctx
);
24707 gen_shift(ctx
, op1
, rd
, rs
, rt
);
24710 switch ((ctx
->opcode
>> 6) & 0x1f) {
24712 /* drotrv is decoded as dsrlv on non-R2 CPUs */
24713 if (ctx
->insn_flags
& ISA_MIPS_R2
) {
24718 check_insn(ctx
, ISA_MIPS3
);
24719 check_mips_64(ctx
);
24720 gen_shift(ctx
, op1
, rd
, rs
, rt
);
24723 gen_reserved_instruction(ctx
);
24729 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
24730 decode_opc_special_r6(env
, ctx
);
24731 } else if (ctx
->insn_flags
& INSN_R5900
) {
24732 decode_opc_special_tx79(env
, ctx
);
24734 decode_opc_special_legacy(env
, ctx
);
24740 #if defined(TARGET_MIPS64)
24744 * MMI (MultiMedia Interface) ASE instructions
24745 * ===========================================
24749 * MMI instructions category: data communication
24750 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
24752 * PCPYH PEXCH PEXTLB PINTH PPACB PEXT5 PREVH
24753 * PCPYLD PEXCW PEXTLH PINTEH PPACH PPAC5 PROT3W
24754 * PCPYUD PEXEH PEXTLW PPACW
24763 * Parallel Copy Halfword
24765 * 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
24766 * +-----------+---------+---------+---------+---------+-----------+
24767 * | MMI |0 0 0 0 0| rt | rd | PCPYH | MMI3 |
24768 * +-----------+---------+---------+---------+---------+-----------+
24770 static void gen_mmi_pcpyh(DisasContext
*ctx
)
24772 uint32_t pd
, rt
, rd
;
24775 opcode
= ctx
->opcode
;
24777 pd
= extract32(opcode
, 21, 5);
24778 rt
= extract32(opcode
, 16, 5);
24779 rd
= extract32(opcode
, 11, 5);
24781 if (unlikely(pd
!= 0)) {
24782 gen_reserved_instruction(ctx
);
24783 } else if (rd
== 0) {
24785 } else if (rt
== 0) {
24786 tcg_gen_movi_i64(cpu_gpr
[rd
], 0);
24787 tcg_gen_movi_i64(cpu_mmr
[rd
], 0);
24789 TCGv_i64 t0
= tcg_temp_new();
24790 TCGv_i64 t1
= tcg_temp_new();
24791 uint64_t mask
= (1ULL << 16) - 1;
24793 tcg_gen_andi_i64(t0
, cpu_gpr
[rt
], mask
);
24794 tcg_gen_movi_i64(t1
, 0);
24795 tcg_gen_or_i64(t1
, t0
, t1
);
24796 tcg_gen_shli_i64(t0
, t0
, 16);
24797 tcg_gen_or_i64(t1
, t0
, t1
);
24798 tcg_gen_shli_i64(t0
, t0
, 16);
24799 tcg_gen_or_i64(t1
, t0
, t1
);
24800 tcg_gen_shli_i64(t0
, t0
, 16);
24801 tcg_gen_or_i64(t1
, t0
, t1
);
24803 tcg_gen_mov_i64(cpu_gpr
[rd
], t1
);
24805 tcg_gen_andi_i64(t0
, cpu_mmr
[rt
], mask
);
24806 tcg_gen_movi_i64(t1
, 0);
24807 tcg_gen_or_i64(t1
, t0
, t1
);
24808 tcg_gen_shli_i64(t0
, t0
, 16);
24809 tcg_gen_or_i64(t1
, t0
, t1
);
24810 tcg_gen_shli_i64(t0
, t0
, 16);
24811 tcg_gen_or_i64(t1
, t0
, t1
);
24812 tcg_gen_shli_i64(t0
, t0
, 16);
24813 tcg_gen_or_i64(t1
, t0
, t1
);
24815 tcg_gen_mov_i64(cpu_mmr
[rd
], t1
);
24823 * PCPYLD rd, rs, rt
24825 * Parallel Copy Lower Doubleword
24827 * 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
24828 * +-----------+---------+---------+---------+---------+-----------+
24829 * | MMI | rs | rt | rd | PCPYLD | MMI2 |
24830 * +-----------+---------+---------+---------+---------+-----------+
24832 static void gen_mmi_pcpyld(DisasContext
*ctx
)
24834 uint32_t rs
, rt
, rd
;
24837 opcode
= ctx
->opcode
;
24839 rs
= extract32(opcode
, 21, 5);
24840 rt
= extract32(opcode
, 16, 5);
24841 rd
= extract32(opcode
, 11, 5);
24847 tcg_gen_movi_i64(cpu_mmr
[rd
], 0);
24849 tcg_gen_mov_i64(cpu_mmr
[rd
], cpu_gpr
[rs
]);
24852 tcg_gen_movi_i64(cpu_gpr
[rd
], 0);
24855 tcg_gen_mov_i64(cpu_gpr
[rd
], cpu_gpr
[rt
]);
24862 * PCPYUD rd, rs, rt
24864 * Parallel Copy Upper Doubleword
24866 * 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
24867 * +-----------+---------+---------+---------+---------+-----------+
24868 * | MMI | rs | rt | rd | PCPYUD | MMI3 |
24869 * +-----------+---------+---------+---------+---------+-----------+
24871 static void gen_mmi_pcpyud(DisasContext
*ctx
)
24873 uint32_t rs
, rt
, rd
;
24876 opcode
= ctx
->opcode
;
24878 rs
= extract32(opcode
, 21, 5);
24879 rt
= extract32(opcode
, 16, 5);
24880 rd
= extract32(opcode
, 11, 5);
24886 tcg_gen_movi_i64(cpu_gpr
[rd
], 0);
24888 tcg_gen_mov_i64(cpu_gpr
[rd
], cpu_mmr
[rs
]);
24891 tcg_gen_movi_i64(cpu_mmr
[rd
], 0);
24894 tcg_gen_mov_i64(cpu_mmr
[rd
], cpu_mmr
[rt
]);
24903 #if !defined(TARGET_MIPS64)
24905 /* MXU accumulate add/subtract 1-bit pattern 'aptn1' */
24906 #define MXU_APTN1_A 0
24907 #define MXU_APTN1_S 1
24909 /* MXU accumulate add/subtract 2-bit pattern 'aptn2' */
24910 #define MXU_APTN2_AA 0
24911 #define MXU_APTN2_AS 1
24912 #define MXU_APTN2_SA 2
24913 #define MXU_APTN2_SS 3
24915 /* MXU execute add/subtract 2-bit pattern 'eptn2' */
24916 #define MXU_EPTN2_AA 0
24917 #define MXU_EPTN2_AS 1
24918 #define MXU_EPTN2_SA 2
24919 #define MXU_EPTN2_SS 3
24921 /* MXU operand getting pattern 'optn2' */
24922 #define MXU_OPTN2_PTN0 0
24923 #define MXU_OPTN2_PTN1 1
24924 #define MXU_OPTN2_PTN2 2
24925 #define MXU_OPTN2_PTN3 3
24926 /* alternative naming scheme for 'optn2' */
24927 #define MXU_OPTN2_WW 0
24928 #define MXU_OPTN2_LW 1
24929 #define MXU_OPTN2_HW 2
24930 #define MXU_OPTN2_XW 3
24932 /* MXU operand getting pattern 'optn3' */
24933 #define MXU_OPTN3_PTN0 0
24934 #define MXU_OPTN3_PTN1 1
24935 #define MXU_OPTN3_PTN2 2
24936 #define MXU_OPTN3_PTN3 3
24937 #define MXU_OPTN3_PTN4 4
24938 #define MXU_OPTN3_PTN5 5
24939 #define MXU_OPTN3_PTN6 6
24940 #define MXU_OPTN3_PTN7 7
24944 * S32I2M XRa, rb - Register move from GRF to XRF
24946 static void gen_mxu_s32i2m(DisasContext
*ctx
)
24951 t0
= tcg_temp_new();
24953 XRa
= extract32(ctx
->opcode
, 6, 5);
24954 Rb
= extract32(ctx
->opcode
, 16, 5);
24956 gen_load_gpr(t0
, Rb
);
24958 gen_store_mxu_gpr(t0
, XRa
);
24959 } else if (XRa
== 16) {
24960 gen_store_mxu_cr(t0
);
24967 * S32M2I XRa, rb - Register move from XRF to GRF
24969 static void gen_mxu_s32m2i(DisasContext
*ctx
)
24974 t0
= tcg_temp_new();
24976 XRa
= extract32(ctx
->opcode
, 6, 5);
24977 Rb
= extract32(ctx
->opcode
, 16, 5);
24980 gen_load_mxu_gpr(t0
, XRa
);
24981 } else if (XRa
== 16) {
24982 gen_load_mxu_cr(t0
);
24985 gen_store_gpr(t0
, Rb
);
24991 * S8LDD XRa, Rb, s8, optn3 - Load a byte from memory to XRF
24993 static void gen_mxu_s8ldd(DisasContext
*ctx
)
24996 uint32_t XRa
, Rb
, s8
, optn3
;
24998 t0
= tcg_temp_new();
24999 t1
= tcg_temp_new();
25001 XRa
= extract32(ctx
->opcode
, 6, 4);
25002 s8
= extract32(ctx
->opcode
, 10, 8);
25003 optn3
= extract32(ctx
->opcode
, 18, 3);
25004 Rb
= extract32(ctx
->opcode
, 21, 5);
25006 gen_load_gpr(t0
, Rb
);
25007 tcg_gen_addi_tl(t0
, t0
, (int8_t)s8
);
25010 /* XRa[7:0] = tmp8 */
25011 case MXU_OPTN3_PTN0
:
25012 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
25013 gen_load_mxu_gpr(t0
, XRa
);
25014 tcg_gen_deposit_tl(t0
, t0
, t1
, 0, 8);
25016 /* XRa[15:8] = tmp8 */
25017 case MXU_OPTN3_PTN1
:
25018 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
25019 gen_load_mxu_gpr(t0
, XRa
);
25020 tcg_gen_deposit_tl(t0
, t0
, t1
, 8, 8);
25022 /* XRa[23:16] = tmp8 */
25023 case MXU_OPTN3_PTN2
:
25024 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
25025 gen_load_mxu_gpr(t0
, XRa
);
25026 tcg_gen_deposit_tl(t0
, t0
, t1
, 16, 8);
25028 /* XRa[31:24] = tmp8 */
25029 case MXU_OPTN3_PTN3
:
25030 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
25031 gen_load_mxu_gpr(t0
, XRa
);
25032 tcg_gen_deposit_tl(t0
, t0
, t1
, 24, 8);
25034 /* XRa = {8'b0, tmp8, 8'b0, tmp8} */
25035 case MXU_OPTN3_PTN4
:
25036 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
25037 tcg_gen_deposit_tl(t0
, t1
, t1
, 16, 16);
25039 /* XRa = {tmp8, 8'b0, tmp8, 8'b0} */
25040 case MXU_OPTN3_PTN5
:
25041 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
25042 tcg_gen_shli_tl(t1
, t1
, 8);
25043 tcg_gen_deposit_tl(t0
, t1
, t1
, 16, 16);
25045 /* XRa = {{8{sign of tmp8}}, tmp8, {8{sign of tmp8}}, tmp8} */
25046 case MXU_OPTN3_PTN6
:
25047 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_SB
);
25048 tcg_gen_mov_tl(t0
, t1
);
25049 tcg_gen_andi_tl(t0
, t0
, 0xFF00FFFF);
25050 tcg_gen_shli_tl(t1
, t1
, 16);
25051 tcg_gen_or_tl(t0
, t0
, t1
);
25053 /* XRa = {tmp8, tmp8, tmp8, tmp8} */
25054 case MXU_OPTN3_PTN7
:
25055 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
25056 tcg_gen_deposit_tl(t1
, t1
, t1
, 8, 8);
25057 tcg_gen_deposit_tl(t0
, t1
, t1
, 16, 16);
25061 gen_store_mxu_gpr(t0
, XRa
);
25068 * D16MUL XRa, XRb, XRc, XRd, optn2 - Signed 16 bit pattern multiplication
25070 static void gen_mxu_d16mul(DisasContext
*ctx
)
25072 TCGv t0
, t1
, t2
, t3
;
25073 uint32_t XRa
, XRb
, XRc
, XRd
, optn2
;
25075 t0
= tcg_temp_new();
25076 t1
= tcg_temp_new();
25077 t2
= tcg_temp_new();
25078 t3
= tcg_temp_new();
25080 XRa
= extract32(ctx
->opcode
, 6, 4);
25081 XRb
= extract32(ctx
->opcode
, 10, 4);
25082 XRc
= extract32(ctx
->opcode
, 14, 4);
25083 XRd
= extract32(ctx
->opcode
, 18, 4);
25084 optn2
= extract32(ctx
->opcode
, 22, 2);
25086 gen_load_mxu_gpr(t1
, XRb
);
25087 tcg_gen_sextract_tl(t0
, t1
, 0, 16);
25088 tcg_gen_sextract_tl(t1
, t1
, 16, 16);
25089 gen_load_mxu_gpr(t3
, XRc
);
25090 tcg_gen_sextract_tl(t2
, t3
, 0, 16);
25091 tcg_gen_sextract_tl(t3
, t3
, 16, 16);
25094 case MXU_OPTN2_WW
: /* XRB.H*XRC.H == lop, XRB.L*XRC.L == rop */
25095 tcg_gen_mul_tl(t3
, t1
, t3
);
25096 tcg_gen_mul_tl(t2
, t0
, t2
);
25098 case MXU_OPTN2_LW
: /* XRB.L*XRC.H == lop, XRB.L*XRC.L == rop */
25099 tcg_gen_mul_tl(t3
, t0
, t3
);
25100 tcg_gen_mul_tl(t2
, t0
, t2
);
25102 case MXU_OPTN2_HW
: /* XRB.H*XRC.H == lop, XRB.H*XRC.L == rop */
25103 tcg_gen_mul_tl(t3
, t1
, t3
);
25104 tcg_gen_mul_tl(t2
, t1
, t2
);
25106 case MXU_OPTN2_XW
: /* XRB.L*XRC.H == lop, XRB.H*XRC.L == rop */
25107 tcg_gen_mul_tl(t3
, t0
, t3
);
25108 tcg_gen_mul_tl(t2
, t1
, t2
);
25111 gen_store_mxu_gpr(t3
, XRa
);
25112 gen_store_mxu_gpr(t2
, XRd
);
25121 * D16MAC XRa, XRb, XRc, XRd, aptn2, optn2 - Signed 16 bit pattern multiply
25124 static void gen_mxu_d16mac(DisasContext
*ctx
)
25126 TCGv t0
, t1
, t2
, t3
;
25127 uint32_t XRa
, XRb
, XRc
, XRd
, optn2
, aptn2
;
25129 t0
= tcg_temp_new();
25130 t1
= tcg_temp_new();
25131 t2
= tcg_temp_new();
25132 t3
= tcg_temp_new();
25134 XRa
= extract32(ctx
->opcode
, 6, 4);
25135 XRb
= extract32(ctx
->opcode
, 10, 4);
25136 XRc
= extract32(ctx
->opcode
, 14, 4);
25137 XRd
= extract32(ctx
->opcode
, 18, 4);
25138 optn2
= extract32(ctx
->opcode
, 22, 2);
25139 aptn2
= extract32(ctx
->opcode
, 24, 2);
25141 gen_load_mxu_gpr(t1
, XRb
);
25142 tcg_gen_sextract_tl(t0
, t1
, 0, 16);
25143 tcg_gen_sextract_tl(t1
, t1
, 16, 16);
25145 gen_load_mxu_gpr(t3
, XRc
);
25146 tcg_gen_sextract_tl(t2
, t3
, 0, 16);
25147 tcg_gen_sextract_tl(t3
, t3
, 16, 16);
25150 case MXU_OPTN2_WW
: /* XRB.H*XRC.H == lop, XRB.L*XRC.L == rop */
25151 tcg_gen_mul_tl(t3
, t1
, t3
);
25152 tcg_gen_mul_tl(t2
, t0
, t2
);
25154 case MXU_OPTN2_LW
: /* XRB.L*XRC.H == lop, XRB.L*XRC.L == rop */
25155 tcg_gen_mul_tl(t3
, t0
, t3
);
25156 tcg_gen_mul_tl(t2
, t0
, t2
);
25158 case MXU_OPTN2_HW
: /* XRB.H*XRC.H == lop, XRB.H*XRC.L == rop */
25159 tcg_gen_mul_tl(t3
, t1
, t3
);
25160 tcg_gen_mul_tl(t2
, t1
, t2
);
25162 case MXU_OPTN2_XW
: /* XRB.L*XRC.H == lop, XRB.H*XRC.L == rop */
25163 tcg_gen_mul_tl(t3
, t0
, t3
);
25164 tcg_gen_mul_tl(t2
, t1
, t2
);
25167 gen_load_mxu_gpr(t0
, XRa
);
25168 gen_load_mxu_gpr(t1
, XRd
);
25172 tcg_gen_add_tl(t3
, t0
, t3
);
25173 tcg_gen_add_tl(t2
, t1
, t2
);
25176 tcg_gen_add_tl(t3
, t0
, t3
);
25177 tcg_gen_sub_tl(t2
, t1
, t2
);
25180 tcg_gen_sub_tl(t3
, t0
, t3
);
25181 tcg_gen_add_tl(t2
, t1
, t2
);
25184 tcg_gen_sub_tl(t3
, t0
, t3
);
25185 tcg_gen_sub_tl(t2
, t1
, t2
);
25188 gen_store_mxu_gpr(t3
, XRa
);
25189 gen_store_mxu_gpr(t2
, XRd
);
25198 * Q8MUL XRa, XRb, XRc, XRd - Parallel unsigned 8 bit pattern multiply
25199 * Q8MULSU XRa, XRb, XRc, XRd - Parallel signed 8 bit pattern multiply
25201 static void gen_mxu_q8mul_q8mulsu(DisasContext
*ctx
)
25203 TCGv t0
, t1
, t2
, t3
, t4
, t5
, t6
, t7
;
25204 uint32_t XRa
, XRb
, XRc
, XRd
, sel
;
25206 t0
= tcg_temp_new();
25207 t1
= tcg_temp_new();
25208 t2
= tcg_temp_new();
25209 t3
= tcg_temp_new();
25210 t4
= tcg_temp_new();
25211 t5
= tcg_temp_new();
25212 t6
= tcg_temp_new();
25213 t7
= tcg_temp_new();
25215 XRa
= extract32(ctx
->opcode
, 6, 4);
25216 XRb
= extract32(ctx
->opcode
, 10, 4);
25217 XRc
= extract32(ctx
->opcode
, 14, 4);
25218 XRd
= extract32(ctx
->opcode
, 18, 4);
25219 sel
= extract32(ctx
->opcode
, 22, 2);
25221 gen_load_mxu_gpr(t3
, XRb
);
25222 gen_load_mxu_gpr(t7
, XRc
);
25226 tcg_gen_ext8s_tl(t0
, t3
);
25227 tcg_gen_shri_tl(t3
, t3
, 8);
25228 tcg_gen_ext8s_tl(t1
, t3
);
25229 tcg_gen_shri_tl(t3
, t3
, 8);
25230 tcg_gen_ext8s_tl(t2
, t3
);
25231 tcg_gen_shri_tl(t3
, t3
, 8);
25232 tcg_gen_ext8s_tl(t3
, t3
);
25235 tcg_gen_ext8u_tl(t0
, t3
);
25236 tcg_gen_shri_tl(t3
, t3
, 8);
25237 tcg_gen_ext8u_tl(t1
, t3
);
25238 tcg_gen_shri_tl(t3
, t3
, 8);
25239 tcg_gen_ext8u_tl(t2
, t3
);
25240 tcg_gen_shri_tl(t3
, t3
, 8);
25241 tcg_gen_ext8u_tl(t3
, t3
);
25244 tcg_gen_ext8u_tl(t4
, t7
);
25245 tcg_gen_shri_tl(t7
, t7
, 8);
25246 tcg_gen_ext8u_tl(t5
, t7
);
25247 tcg_gen_shri_tl(t7
, t7
, 8);
25248 tcg_gen_ext8u_tl(t6
, t7
);
25249 tcg_gen_shri_tl(t7
, t7
, 8);
25250 tcg_gen_ext8u_tl(t7
, t7
);
25252 tcg_gen_mul_tl(t0
, t0
, t4
);
25253 tcg_gen_mul_tl(t1
, t1
, t5
);
25254 tcg_gen_mul_tl(t2
, t2
, t6
);
25255 tcg_gen_mul_tl(t3
, t3
, t7
);
25257 tcg_gen_andi_tl(t0
, t0
, 0xFFFF);
25258 tcg_gen_andi_tl(t1
, t1
, 0xFFFF);
25259 tcg_gen_andi_tl(t2
, t2
, 0xFFFF);
25260 tcg_gen_andi_tl(t3
, t3
, 0xFFFF);
25262 tcg_gen_shli_tl(t1
, t1
, 16);
25263 tcg_gen_shli_tl(t3
, t3
, 16);
25265 tcg_gen_or_tl(t0
, t0
, t1
);
25266 tcg_gen_or_tl(t1
, t2
, t3
);
25268 gen_store_mxu_gpr(t0
, XRd
);
25269 gen_store_mxu_gpr(t1
, XRa
);
25282 * S32LDD XRa, Rb, S12 - Load a word from memory to XRF
25283 * S32LDDR XRa, Rb, S12 - Load a word from memory to XRF, reversed byte seq.
25285 static void gen_mxu_s32ldd_s32lddr(DisasContext
*ctx
)
25288 uint32_t XRa
, Rb
, s12
, sel
;
25290 t0
= tcg_temp_new();
25291 t1
= tcg_temp_new();
25293 XRa
= extract32(ctx
->opcode
, 6, 4);
25294 s12
= extract32(ctx
->opcode
, 10, 10);
25295 sel
= extract32(ctx
->opcode
, 20, 1);
25296 Rb
= extract32(ctx
->opcode
, 21, 5);
25298 gen_load_gpr(t0
, Rb
);
25300 tcg_gen_movi_tl(t1
, s12
);
25301 tcg_gen_shli_tl(t1
, t1
, 2);
25303 tcg_gen_ori_tl(t1
, t1
, 0xFFFFF000);
25305 tcg_gen_add_tl(t1
, t0
, t1
);
25306 tcg_gen_qemu_ld_tl(t1
, t1
, ctx
->mem_idx
, MO_SL
);
25310 tcg_gen_bswap32_tl(t1
, t1
);
25312 gen_store_mxu_gpr(t1
, XRa
);
25320 * MXU instruction category: logic
25321 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
25323 * S32NOR S32AND S32OR S32XOR
25327 * S32NOR XRa, XRb, XRc
25328 * Update XRa with the result of logical bitwise 'nor' operation
25329 * applied to the content of XRb and XRc.
25331 * 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
25332 * +-----------+---------+-----+-------+-------+-------+-----------+
25333 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL16|
25334 * +-----------+---------+-----+-------+-------+-------+-----------+
25336 static void gen_mxu_S32NOR(DisasContext
*ctx
)
25338 uint32_t pad
, XRc
, XRb
, XRa
;
25340 pad
= extract32(ctx
->opcode
, 21, 5);
25341 XRc
= extract32(ctx
->opcode
, 14, 4);
25342 XRb
= extract32(ctx
->opcode
, 10, 4);
25343 XRa
= extract32(ctx
->opcode
, 6, 4);
25345 if (unlikely(pad
!= 0)) {
25346 /* opcode padding incorrect -> do nothing */
25347 } else if (unlikely(XRa
== 0)) {
25348 /* destination is zero register -> do nothing */
25349 } else if (unlikely((XRb
== 0) && (XRc
== 0))) {
25350 /* both operands zero registers -> just set destination to all 1s */
25351 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0xFFFFFFFF);
25352 } else if (unlikely(XRb
== 0)) {
25353 /* XRb zero register -> just set destination to the negation of XRc */
25354 tcg_gen_not_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRc
- 1]);
25355 } else if (unlikely(XRc
== 0)) {
25356 /* XRa zero register -> just set destination to the negation of XRb */
25357 tcg_gen_not_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25358 } else if (unlikely(XRb
== XRc
)) {
25359 /* both operands same -> just set destination to the negation of XRb */
25360 tcg_gen_not_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25362 /* the most general case */
25363 tcg_gen_nor_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1], mxu_gpr
[XRc
- 1]);
25368 * S32AND XRa, XRb, XRc
25369 * Update XRa with the result of logical bitwise 'and' operation
25370 * applied to the content of XRb and XRc.
25372 * 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
25373 * +-----------+---------+-----+-------+-------+-------+-----------+
25374 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL16|
25375 * +-----------+---------+-----+-------+-------+-------+-----------+
25377 static void gen_mxu_S32AND(DisasContext
*ctx
)
25379 uint32_t pad
, XRc
, XRb
, XRa
;
25381 pad
= extract32(ctx
->opcode
, 21, 5);
25382 XRc
= extract32(ctx
->opcode
, 14, 4);
25383 XRb
= extract32(ctx
->opcode
, 10, 4);
25384 XRa
= extract32(ctx
->opcode
, 6, 4);
25386 if (unlikely(pad
!= 0)) {
25387 /* opcode padding incorrect -> do nothing */
25388 } else if (unlikely(XRa
== 0)) {
25389 /* destination is zero register -> do nothing */
25390 } else if (unlikely((XRb
== 0) || (XRc
== 0))) {
25391 /* one of operands zero register -> just set destination to all 0s */
25392 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0);
25393 } else if (unlikely(XRb
== XRc
)) {
25394 /* both operands same -> just set destination to one of them */
25395 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25397 /* the most general case */
25398 tcg_gen_and_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1], mxu_gpr
[XRc
- 1]);
25403 * S32OR XRa, XRb, XRc
25404 * Update XRa with the result of logical bitwise 'or' operation
25405 * applied to the content of XRb and XRc.
25407 * 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
25408 * +-----------+---------+-----+-------+-------+-------+-----------+
25409 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL16|
25410 * +-----------+---------+-----+-------+-------+-------+-----------+
25412 static void gen_mxu_S32OR(DisasContext
*ctx
)
25414 uint32_t pad
, XRc
, XRb
, XRa
;
25416 pad
= extract32(ctx
->opcode
, 21, 5);
25417 XRc
= extract32(ctx
->opcode
, 14, 4);
25418 XRb
= extract32(ctx
->opcode
, 10, 4);
25419 XRa
= extract32(ctx
->opcode
, 6, 4);
25421 if (unlikely(pad
!= 0)) {
25422 /* opcode padding incorrect -> do nothing */
25423 } else if (unlikely(XRa
== 0)) {
25424 /* destination is zero register -> do nothing */
25425 } else if (unlikely((XRb
== 0) && (XRc
== 0))) {
25426 /* both operands zero registers -> just set destination to all 0s */
25427 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0);
25428 } else if (unlikely(XRb
== 0)) {
25429 /* XRb zero register -> just set destination to the content of XRc */
25430 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRc
- 1]);
25431 } else if (unlikely(XRc
== 0)) {
25432 /* XRc zero register -> just set destination to the content of XRb */
25433 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25434 } else if (unlikely(XRb
== XRc
)) {
25435 /* both operands same -> just set destination to one of them */
25436 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25438 /* the most general case */
25439 tcg_gen_or_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1], mxu_gpr
[XRc
- 1]);
25444 * S32XOR XRa, XRb, XRc
25445 * Update XRa with the result of logical bitwise 'xor' operation
25446 * applied to the content of XRb and XRc.
25448 * 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
25449 * +-----------+---------+-----+-------+-------+-------+-----------+
25450 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL16|
25451 * +-----------+---------+-----+-------+-------+-------+-----------+
25453 static void gen_mxu_S32XOR(DisasContext
*ctx
)
25455 uint32_t pad
, XRc
, XRb
, XRa
;
25457 pad
= extract32(ctx
->opcode
, 21, 5);
25458 XRc
= extract32(ctx
->opcode
, 14, 4);
25459 XRb
= extract32(ctx
->opcode
, 10, 4);
25460 XRa
= extract32(ctx
->opcode
, 6, 4);
25462 if (unlikely(pad
!= 0)) {
25463 /* opcode padding incorrect -> do nothing */
25464 } else if (unlikely(XRa
== 0)) {
25465 /* destination is zero register -> do nothing */
25466 } else if (unlikely((XRb
== 0) && (XRc
== 0))) {
25467 /* both operands zero registers -> just set destination to all 0s */
25468 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0);
25469 } else if (unlikely(XRb
== 0)) {
25470 /* XRb zero register -> just set destination to the content of XRc */
25471 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRc
- 1]);
25472 } else if (unlikely(XRc
== 0)) {
25473 /* XRc zero register -> just set destination to the content of XRb */
25474 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25475 } else if (unlikely(XRb
== XRc
)) {
25476 /* both operands same -> just set destination to all 0s */
25477 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0);
25479 /* the most general case */
25480 tcg_gen_xor_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1], mxu_gpr
[XRc
- 1]);
25486 * MXU instruction category max/min
25487 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
25489 * S32MAX D16MAX Q8MAX
25490 * S32MIN D16MIN Q8MIN
25494 * S32MAX XRa, XRb, XRc
25495 * Update XRa with the maximum of signed 32-bit integers contained
25498 * S32MIN XRa, XRb, XRc
25499 * Update XRa with the minimum of signed 32-bit integers contained
25502 * 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
25503 * +-----------+---------+-----+-------+-------+-------+-----------+
25504 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL00|
25505 * +-----------+---------+-----+-------+-------+-------+-----------+
25507 static void gen_mxu_S32MAX_S32MIN(DisasContext
*ctx
)
25509 uint32_t pad
, opc
, XRc
, XRb
, XRa
;
25511 pad
= extract32(ctx
->opcode
, 21, 5);
25512 opc
= extract32(ctx
->opcode
, 18, 3);
25513 XRc
= extract32(ctx
->opcode
, 14, 4);
25514 XRb
= extract32(ctx
->opcode
, 10, 4);
25515 XRa
= extract32(ctx
->opcode
, 6, 4);
25517 if (unlikely(pad
!= 0)) {
25518 /* opcode padding incorrect -> do nothing */
25519 } else if (unlikely(XRa
== 0)) {
25520 /* destination is zero register -> do nothing */
25521 } else if (unlikely((XRb
== 0) && (XRc
== 0))) {
25522 /* both operands zero registers -> just set destination to zero */
25523 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0);
25524 } else if (unlikely((XRb
== 0) || (XRc
== 0))) {
25525 /* exactly one operand is zero register - find which one is not...*/
25526 uint32_t XRx
= XRb
? XRb
: XRc
;
25527 /* ...and do max/min operation with one operand 0 */
25528 if (opc
== OPC_MXU_S32MAX
) {
25529 tcg_gen_smax_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRx
- 1], 0);
25531 tcg_gen_smin_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRx
- 1], 0);
25533 } else if (unlikely(XRb
== XRc
)) {
25534 /* both operands same -> just set destination to one of them */
25535 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25537 /* the most general case */
25538 if (opc
== OPC_MXU_S32MAX
) {
25539 tcg_gen_smax_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1],
25542 tcg_gen_smin_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1],
25550 * Update XRa with the 16-bit-wise maximums of signed integers
25551 * contained in XRb and XRc.
25554 * Update XRa with the 16-bit-wise minimums of signed integers
25555 * contained in XRb and XRc.
25557 * 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
25558 * +-----------+---------+-----+-------+-------+-------+-----------+
25559 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL00|
25560 * +-----------+---------+-----+-------+-------+-------+-----------+
25562 static void gen_mxu_D16MAX_D16MIN(DisasContext
*ctx
)
25564 uint32_t pad
, opc
, XRc
, XRb
, XRa
;
25566 pad
= extract32(ctx
->opcode
, 21, 5);
25567 opc
= extract32(ctx
->opcode
, 18, 3);
25568 XRc
= extract32(ctx
->opcode
, 14, 4);
25569 XRb
= extract32(ctx
->opcode
, 10, 4);
25570 XRa
= extract32(ctx
->opcode
, 6, 4);
25572 if (unlikely(pad
!= 0)) {
25573 /* opcode padding incorrect -> do nothing */
25574 } else if (unlikely(XRc
== 0)) {
25575 /* destination is zero register -> do nothing */
25576 } else if (unlikely((XRb
== 0) && (XRa
== 0))) {
25577 /* both operands zero registers -> just set destination to zero */
25578 tcg_gen_movi_i32(mxu_gpr
[XRc
- 1], 0);
25579 } else if (unlikely((XRb
== 0) || (XRa
== 0))) {
25580 /* exactly one operand is zero register - find which one is not...*/
25581 uint32_t XRx
= XRb
? XRb
: XRc
;
25582 /* ...and do half-word-wise max/min with one operand 0 */
25583 TCGv_i32 t0
= tcg_temp_new();
25584 TCGv_i32 t1
= tcg_const_i32(0);
25586 /* the left half-word first */
25587 tcg_gen_andi_i32(t0
, mxu_gpr
[XRx
- 1], 0xFFFF0000);
25588 if (opc
== OPC_MXU_D16MAX
) {
25589 tcg_gen_smax_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
25591 tcg_gen_smin_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
25594 /* the right half-word */
25595 tcg_gen_andi_i32(t0
, mxu_gpr
[XRx
- 1], 0x0000FFFF);
25596 /* move half-words to the leftmost position */
25597 tcg_gen_shli_i32(t0
, t0
, 16);
25598 /* t0 will be max/min of t0 and t1 */
25599 if (opc
== OPC_MXU_D16MAX
) {
25600 tcg_gen_smax_i32(t0
, t0
, t1
);
25602 tcg_gen_smin_i32(t0
, t0
, t1
);
25604 /* return resulting half-words to its original position */
25605 tcg_gen_shri_i32(t0
, t0
, 16);
25606 /* finally update the destination */
25607 tcg_gen_or_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRa
- 1], t0
);
25611 } else if (unlikely(XRb
== XRc
)) {
25612 /* both operands same -> just set destination to one of them */
25613 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25615 /* the most general case */
25616 TCGv_i32 t0
= tcg_temp_new();
25617 TCGv_i32 t1
= tcg_temp_new();
25619 /* the left half-word first */
25620 tcg_gen_andi_i32(t0
, mxu_gpr
[XRb
- 1], 0xFFFF0000);
25621 tcg_gen_andi_i32(t1
, mxu_gpr
[XRc
- 1], 0xFFFF0000);
25622 if (opc
== OPC_MXU_D16MAX
) {
25623 tcg_gen_smax_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
25625 tcg_gen_smin_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
25628 /* the right half-word */
25629 tcg_gen_andi_i32(t0
, mxu_gpr
[XRb
- 1], 0x0000FFFF);
25630 tcg_gen_andi_i32(t1
, mxu_gpr
[XRc
- 1], 0x0000FFFF);
25631 /* move half-words to the leftmost position */
25632 tcg_gen_shli_i32(t0
, t0
, 16);
25633 tcg_gen_shli_i32(t1
, t1
, 16);
25634 /* t0 will be max/min of t0 and t1 */
25635 if (opc
== OPC_MXU_D16MAX
) {
25636 tcg_gen_smax_i32(t0
, t0
, t1
);
25638 tcg_gen_smin_i32(t0
, t0
, t1
);
25640 /* return resulting half-words to its original position */
25641 tcg_gen_shri_i32(t0
, t0
, 16);
25642 /* finally update the destination */
25643 tcg_gen_or_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRa
- 1], t0
);
25652 * Update XRa with the 8-bit-wise maximums of signed integers
25653 * contained in XRb and XRc.
25656 * Update XRa with the 8-bit-wise minimums of signed integers
25657 * contained in XRb and XRc.
25659 * 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
25660 * +-----------+---------+-----+-------+-------+-------+-----------+
25661 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL00|
25662 * +-----------+---------+-----+-------+-------+-------+-----------+
25664 static void gen_mxu_Q8MAX_Q8MIN(DisasContext
*ctx
)
25666 uint32_t pad
, opc
, XRc
, XRb
, XRa
;
25668 pad
= extract32(ctx
->opcode
, 21, 5);
25669 opc
= extract32(ctx
->opcode
, 18, 3);
25670 XRc
= extract32(ctx
->opcode
, 14, 4);
25671 XRb
= extract32(ctx
->opcode
, 10, 4);
25672 XRa
= extract32(ctx
->opcode
, 6, 4);
25674 if (unlikely(pad
!= 0)) {
25675 /* opcode padding incorrect -> do nothing */
25676 } else if (unlikely(XRa
== 0)) {
25677 /* destination is zero register -> do nothing */
25678 } else if (unlikely((XRb
== 0) && (XRc
== 0))) {
25679 /* both operands zero registers -> just set destination to zero */
25680 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0);
25681 } else if (unlikely((XRb
== 0) || (XRc
== 0))) {
25682 /* exactly one operand is zero register - make it be the first...*/
25683 uint32_t XRx
= XRb
? XRb
: XRc
;
25684 /* ...and do byte-wise max/min with one operand 0 */
25685 TCGv_i32 t0
= tcg_temp_new();
25686 TCGv_i32 t1
= tcg_const_i32(0);
25689 /* the leftmost byte (byte 3) first */
25690 tcg_gen_andi_i32(t0
, mxu_gpr
[XRx
- 1], 0xFF000000);
25691 if (opc
== OPC_MXU_Q8MAX
) {
25692 tcg_gen_smax_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
25694 tcg_gen_smin_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
25697 /* bytes 2, 1, 0 */
25698 for (i
= 2; i
>= 0; i
--) {
25699 /* extract the byte */
25700 tcg_gen_andi_i32(t0
, mxu_gpr
[XRx
- 1], 0xFF << (8 * i
));
25701 /* move the byte to the leftmost position */
25702 tcg_gen_shli_i32(t0
, t0
, 8 * (3 - i
));
25703 /* t0 will be max/min of t0 and t1 */
25704 if (opc
== OPC_MXU_Q8MAX
) {
25705 tcg_gen_smax_i32(t0
, t0
, t1
);
25707 tcg_gen_smin_i32(t0
, t0
, t1
);
25709 /* return resulting byte to its original position */
25710 tcg_gen_shri_i32(t0
, t0
, 8 * (3 - i
));
25711 /* finally update the destination */
25712 tcg_gen_or_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRa
- 1], t0
);
25717 } else if (unlikely(XRb
== XRc
)) {
25718 /* both operands same -> just set destination to one of them */
25719 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25721 /* the most general case */
25722 TCGv_i32 t0
= tcg_temp_new();
25723 TCGv_i32 t1
= tcg_temp_new();
25726 /* the leftmost bytes (bytes 3) first */
25727 tcg_gen_andi_i32(t0
, mxu_gpr
[XRb
- 1], 0xFF000000);
25728 tcg_gen_andi_i32(t1
, mxu_gpr
[XRc
- 1], 0xFF000000);
25729 if (opc
== OPC_MXU_Q8MAX
) {
25730 tcg_gen_smax_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
25732 tcg_gen_smin_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
25735 /* bytes 2, 1, 0 */
25736 for (i
= 2; i
>= 0; i
--) {
25737 /* extract corresponding bytes */
25738 tcg_gen_andi_i32(t0
, mxu_gpr
[XRb
- 1], 0xFF << (8 * i
));
25739 tcg_gen_andi_i32(t1
, mxu_gpr
[XRc
- 1], 0xFF << (8 * i
));
25740 /* move the bytes to the leftmost position */
25741 tcg_gen_shli_i32(t0
, t0
, 8 * (3 - i
));
25742 tcg_gen_shli_i32(t1
, t1
, 8 * (3 - i
));
25743 /* t0 will be max/min of t0 and t1 */
25744 if (opc
== OPC_MXU_Q8MAX
) {
25745 tcg_gen_smax_i32(t0
, t0
, t1
);
25747 tcg_gen_smin_i32(t0
, t0
, t1
);
25749 /* return resulting byte to its original position */
25750 tcg_gen_shri_i32(t0
, t0
, 8 * (3 - i
));
25751 /* finally update the destination */
25752 tcg_gen_or_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRa
- 1], t0
);
25762 * MXU instruction category: align
25763 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
25769 * S32ALNI XRc, XRb, XRa, optn3
25770 * Arrange bytes from XRb and XRc according to one of five sets of
25771 * rules determined by optn3, and place the result in XRa.
25773 * 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
25774 * +-----------+-----+---+-----+-------+-------+-------+-----------+
25775 * | SPECIAL2 |optn3|0 0|x x x| XRc | XRb | XRa |MXU__POOL16|
25776 * +-----------+-----+---+-----+-------+-------+-------+-----------+
25779 static void gen_mxu_S32ALNI(DisasContext
*ctx
)
25781 uint32_t optn3
, pad
, XRc
, XRb
, XRa
;
25783 optn3
= extract32(ctx
->opcode
, 23, 3);
25784 pad
= extract32(ctx
->opcode
, 21, 2);
25785 XRc
= extract32(ctx
->opcode
, 14, 4);
25786 XRb
= extract32(ctx
->opcode
, 10, 4);
25787 XRa
= extract32(ctx
->opcode
, 6, 4);
25789 if (unlikely(pad
!= 0)) {
25790 /* opcode padding incorrect -> do nothing */
25791 } else if (unlikely(XRa
== 0)) {
25792 /* destination is zero register -> do nothing */
25793 } else if (unlikely((XRb
== 0) && (XRc
== 0))) {
25794 /* both operands zero registers -> just set destination to all 0s */
25795 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0);
25796 } else if (unlikely(XRb
== 0)) {
25797 /* XRb zero register -> just appropriatelly shift XRc into XRa */
25799 case MXU_OPTN3_PTN0
:
25800 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0);
25802 case MXU_OPTN3_PTN1
:
25803 case MXU_OPTN3_PTN2
:
25804 case MXU_OPTN3_PTN3
:
25805 tcg_gen_shri_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRc
- 1],
25808 case MXU_OPTN3_PTN4
:
25809 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRc
- 1]);
25812 } else if (unlikely(XRc
== 0)) {
25813 /* XRc zero register -> just appropriatelly shift XRb into XRa */
25815 case MXU_OPTN3_PTN0
:
25816 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25818 case MXU_OPTN3_PTN1
:
25819 case MXU_OPTN3_PTN2
:
25820 case MXU_OPTN3_PTN3
:
25821 tcg_gen_shri_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1], 8 * optn3
);
25823 case MXU_OPTN3_PTN4
:
25824 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0);
25827 } else if (unlikely(XRb
== XRc
)) {
25828 /* both operands same -> just rotation or moving from any of them */
25830 case MXU_OPTN3_PTN0
:
25831 case MXU_OPTN3_PTN4
:
25832 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25834 case MXU_OPTN3_PTN1
:
25835 case MXU_OPTN3_PTN2
:
25836 case MXU_OPTN3_PTN3
:
25837 tcg_gen_rotli_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1], 8 * optn3
);
25841 /* the most general case */
25843 case MXU_OPTN3_PTN0
:
25847 /* +---------------+ */
25848 /* | A B C D | E F G H */
25849 /* +-------+-------+ */
25854 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25857 case MXU_OPTN3_PTN1
:
25861 /* +-------------------+ */
25862 /* A | B C D E | F G H */
25863 /* +---------+---------+ */
25868 TCGv_i32 t0
= tcg_temp_new();
25869 TCGv_i32 t1
= tcg_temp_new();
25871 tcg_gen_andi_i32(t0
, mxu_gpr
[XRb
- 1], 0x00FFFFFF);
25872 tcg_gen_shli_i32(t0
, t0
, 8);
25874 tcg_gen_andi_i32(t1
, mxu_gpr
[XRc
- 1], 0xFF000000);
25875 tcg_gen_shri_i32(t1
, t1
, 24);
25877 tcg_gen_or_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
25883 case MXU_OPTN3_PTN2
:
25887 /* +-------------------+ */
25888 /* A B | C D E F | G H */
25889 /* +---------+---------+ */
25894 TCGv_i32 t0
= tcg_temp_new();
25895 TCGv_i32 t1
= tcg_temp_new();
25897 tcg_gen_andi_i32(t0
, mxu_gpr
[XRb
- 1], 0x0000FFFF);
25898 tcg_gen_shli_i32(t0
, t0
, 16);
25900 tcg_gen_andi_i32(t1
, mxu_gpr
[XRc
- 1], 0xFFFF0000);
25901 tcg_gen_shri_i32(t1
, t1
, 16);
25903 tcg_gen_or_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
25909 case MXU_OPTN3_PTN3
:
25913 /* +-------------------+ */
25914 /* A B C | D E F G | H */
25915 /* +---------+---------+ */
25920 TCGv_i32 t0
= tcg_temp_new();
25921 TCGv_i32 t1
= tcg_temp_new();
25923 tcg_gen_andi_i32(t0
, mxu_gpr
[XRb
- 1], 0x000000FF);
25924 tcg_gen_shli_i32(t0
, t0
, 24);
25926 tcg_gen_andi_i32(t1
, mxu_gpr
[XRc
- 1], 0xFFFFFF00);
25927 tcg_gen_shri_i32(t1
, t1
, 8);
25929 tcg_gen_or_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
25935 case MXU_OPTN3_PTN4
:
25939 /* +---------------+ */
25940 /* A B C D | E F G H | */
25941 /* +-------+-------+ */
25946 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRc
- 1]);
25955 * Decoding engine for MXU
25956 * =======================
25961 * Decode MXU pool00
25963 * 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
25964 * +-----------+---------+-----+-------+-------+-------+-----------+
25965 * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL00|
25966 * +-----------+---------+-----+-------+-------+-------+-----------+
25969 static void decode_opc_mxu__pool00(CPUMIPSState
*env
, DisasContext
*ctx
)
25971 uint32_t opcode
= extract32(ctx
->opcode
, 18, 3);
25974 case OPC_MXU_S32MAX
:
25975 case OPC_MXU_S32MIN
:
25976 gen_mxu_S32MAX_S32MIN(ctx
);
25978 case OPC_MXU_D16MAX
:
25979 case OPC_MXU_D16MIN
:
25980 gen_mxu_D16MAX_D16MIN(ctx
);
25982 case OPC_MXU_Q8MAX
:
25983 case OPC_MXU_Q8MIN
:
25984 gen_mxu_Q8MAX_Q8MIN(ctx
);
25986 case OPC_MXU_Q8SLT
:
25987 /* TODO: Implement emulation of Q8SLT instruction. */
25988 MIPS_INVAL("OPC_MXU_Q8SLT");
25989 gen_reserved_instruction(ctx
);
25991 case OPC_MXU_Q8SLTU
:
25992 /* TODO: Implement emulation of Q8SLTU instruction. */
25993 MIPS_INVAL("OPC_MXU_Q8SLTU");
25994 gen_reserved_instruction(ctx
);
25997 MIPS_INVAL("decode_opc_mxu");
25998 gen_reserved_instruction(ctx
);
26005 * Decode MXU pool01
26007 * S32SLT, D16SLT, D16AVG, D16AVGR, Q8AVG, Q8AVGR:
26008 * 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
26009 * +-----------+---------+-----+-------+-------+-------+-----------+
26010 * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL01|
26011 * +-----------+---------+-----+-------+-------+-------+-----------+
26014 * 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
26015 * +-----------+---+-----+-----+-------+-------+-------+-----------+
26016 * | SPECIAL2 |en2|0 0 0|x x x| XRc | XRb | XRa |MXU__POOL01|
26017 * +-----------+---+-----+-----+-------+-------+-------+-----------+
26020 static void decode_opc_mxu__pool01(CPUMIPSState
*env
, DisasContext
*ctx
)
26022 uint32_t opcode
= extract32(ctx
->opcode
, 18, 3);
26025 case OPC_MXU_S32SLT
:
26026 /* TODO: Implement emulation of S32SLT instruction. */
26027 MIPS_INVAL("OPC_MXU_S32SLT");
26028 gen_reserved_instruction(ctx
);
26030 case OPC_MXU_D16SLT
:
26031 /* TODO: Implement emulation of D16SLT instruction. */
26032 MIPS_INVAL("OPC_MXU_D16SLT");
26033 gen_reserved_instruction(ctx
);
26035 case OPC_MXU_D16AVG
:
26036 /* TODO: Implement emulation of D16AVG instruction. */
26037 MIPS_INVAL("OPC_MXU_D16AVG");
26038 gen_reserved_instruction(ctx
);
26040 case OPC_MXU_D16AVGR
:
26041 /* TODO: Implement emulation of D16AVGR instruction. */
26042 MIPS_INVAL("OPC_MXU_D16AVGR");
26043 gen_reserved_instruction(ctx
);
26045 case OPC_MXU_Q8AVG
:
26046 /* TODO: Implement emulation of Q8AVG instruction. */
26047 MIPS_INVAL("OPC_MXU_Q8AVG");
26048 gen_reserved_instruction(ctx
);
26050 case OPC_MXU_Q8AVGR
:
26051 /* TODO: Implement emulation of Q8AVGR instruction. */
26052 MIPS_INVAL("OPC_MXU_Q8AVGR");
26053 gen_reserved_instruction(ctx
);
26055 case OPC_MXU_Q8ADD
:
26056 /* TODO: Implement emulation of Q8ADD instruction. */
26057 MIPS_INVAL("OPC_MXU_Q8ADD");
26058 gen_reserved_instruction(ctx
);
26061 MIPS_INVAL("decode_opc_mxu");
26062 gen_reserved_instruction(ctx
);
26069 * Decode MXU pool02
26071 * 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
26072 * +-----------+---------+-----+-------+-------+-------+-----------+
26073 * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL02|
26074 * +-----------+---------+-----+-------+-------+-------+-----------+
26077 static void decode_opc_mxu__pool02(CPUMIPSState
*env
, DisasContext
*ctx
)
26079 uint32_t opcode
= extract32(ctx
->opcode
, 18, 3);
26082 case OPC_MXU_S32CPS
:
26083 /* TODO: Implement emulation of S32CPS instruction. */
26084 MIPS_INVAL("OPC_MXU_S32CPS");
26085 gen_reserved_instruction(ctx
);
26087 case OPC_MXU_D16CPS
:
26088 /* TODO: Implement emulation of D16CPS instruction. */
26089 MIPS_INVAL("OPC_MXU_D16CPS");
26090 gen_reserved_instruction(ctx
);
26092 case OPC_MXU_Q8ABD
:
26093 /* TODO: Implement emulation of Q8ABD instruction. */
26094 MIPS_INVAL("OPC_MXU_Q8ABD");
26095 gen_reserved_instruction(ctx
);
26097 case OPC_MXU_Q16SAT
:
26098 /* TODO: Implement emulation of Q16SAT instruction. */
26099 MIPS_INVAL("OPC_MXU_Q16SAT");
26100 gen_reserved_instruction(ctx
);
26103 MIPS_INVAL("decode_opc_mxu");
26104 gen_reserved_instruction(ctx
);
26111 * Decode MXU pool03
26114 * 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
26115 * +-----------+---+---+-------+-------+-------+-------+-----------+
26116 * | SPECIAL2 |x x|on2|0 0 0 0| XRc | XRb | XRa |MXU__POOL03|
26117 * +-----------+---+---+-------+-------+-------+-------+-----------+
26120 * 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
26121 * +-----------+---+---+-------+-------+-------+-------+-----------+
26122 * | SPECIAL2 |x x|on2| Xd | XRc | XRb | XRa |MXU__POOL03|
26123 * +-----------+---+---+-------+-------+-------+-------+-----------+
26126 static void decode_opc_mxu__pool03(CPUMIPSState
*env
, DisasContext
*ctx
)
26128 uint32_t opcode
= extract32(ctx
->opcode
, 24, 2);
26131 case OPC_MXU_D16MULF
:
26132 /* TODO: Implement emulation of D16MULF instruction. */
26133 MIPS_INVAL("OPC_MXU_D16MULF");
26134 gen_reserved_instruction(ctx
);
26136 case OPC_MXU_D16MULE
:
26137 /* TODO: Implement emulation of D16MULE instruction. */
26138 MIPS_INVAL("OPC_MXU_D16MULE");
26139 gen_reserved_instruction(ctx
);
26142 MIPS_INVAL("decode_opc_mxu");
26143 gen_reserved_instruction(ctx
);
26150 * Decode MXU pool04
26152 * 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
26153 * +-----------+---------+-+-------------------+-------+-----------+
26154 * | SPECIAL2 | rb |x| s12 | XRa |MXU__POOL04|
26155 * +-----------+---------+-+-------------------+-------+-----------+
26158 static void decode_opc_mxu__pool04(CPUMIPSState
*env
, DisasContext
*ctx
)
26160 uint32_t opcode
= extract32(ctx
->opcode
, 20, 1);
26163 case OPC_MXU_S32LDD
:
26164 case OPC_MXU_S32LDDR
:
26165 gen_mxu_s32ldd_s32lddr(ctx
);
26168 MIPS_INVAL("decode_opc_mxu");
26169 gen_reserved_instruction(ctx
);
26176 * Decode MXU pool05
26178 * 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
26179 * +-----------+---------+-+-------------------+-------+-----------+
26180 * | SPECIAL2 | rb |x| s12 | XRa |MXU__POOL05|
26181 * +-----------+---------+-+-------------------+-------+-----------+
26184 static void decode_opc_mxu__pool05(CPUMIPSState
*env
, DisasContext
*ctx
)
26186 uint32_t opcode
= extract32(ctx
->opcode
, 20, 1);
26189 case OPC_MXU_S32STD
:
26190 /* TODO: Implement emulation of S32STD instruction. */
26191 MIPS_INVAL("OPC_MXU_S32STD");
26192 gen_reserved_instruction(ctx
);
26194 case OPC_MXU_S32STDR
:
26195 /* TODO: Implement emulation of S32STDR instruction. */
26196 MIPS_INVAL("OPC_MXU_S32STDR");
26197 gen_reserved_instruction(ctx
);
26200 MIPS_INVAL("decode_opc_mxu");
26201 gen_reserved_instruction(ctx
);
26208 * Decode MXU pool06
26210 * 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
26211 * +-----------+---------+---------+---+-------+-------+-----------+
26212 * | SPECIAL2 | rb | rc |st2|x x x x| XRa |MXU__POOL06|
26213 * +-----------+---------+---------+---+-------+-------+-----------+
26216 static void decode_opc_mxu__pool06(CPUMIPSState
*env
, DisasContext
*ctx
)
26218 uint32_t opcode
= extract32(ctx
->opcode
, 10, 4);
26221 case OPC_MXU_S32LDDV
:
26222 /* TODO: Implement emulation of S32LDDV instruction. */
26223 MIPS_INVAL("OPC_MXU_S32LDDV");
26224 gen_reserved_instruction(ctx
);
26226 case OPC_MXU_S32LDDVR
:
26227 /* TODO: Implement emulation of S32LDDVR instruction. */
26228 MIPS_INVAL("OPC_MXU_S32LDDVR");
26229 gen_reserved_instruction(ctx
);
26232 MIPS_INVAL("decode_opc_mxu");
26233 gen_reserved_instruction(ctx
);
26240 * Decode MXU pool07
26242 * 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
26243 * +-----------+---------+---------+---+-------+-------+-----------+
26244 * | SPECIAL2 | rb | rc |st2|x x x x| XRa |MXU__POOL07|
26245 * +-----------+---------+---------+---+-------+-------+-----------+
26248 static void decode_opc_mxu__pool07(CPUMIPSState
*env
, DisasContext
*ctx
)
26250 uint32_t opcode
= extract32(ctx
->opcode
, 10, 4);
26253 case OPC_MXU_S32STDV
:
26254 /* TODO: Implement emulation of S32TDV instruction. */
26255 MIPS_INVAL("OPC_MXU_S32TDV");
26256 gen_reserved_instruction(ctx
);
26258 case OPC_MXU_S32STDVR
:
26259 /* TODO: Implement emulation of S32TDVR instruction. */
26260 MIPS_INVAL("OPC_MXU_S32TDVR");
26261 gen_reserved_instruction(ctx
);
26264 MIPS_INVAL("decode_opc_mxu");
26265 gen_reserved_instruction(ctx
);
26272 * Decode MXU pool08
26274 * 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
26275 * +-----------+---------+-+-------------------+-------+-----------+
26276 * | SPECIAL2 | rb |x| s12 | XRa |MXU__POOL08|
26277 * +-----------+---------+-+-------------------+-------+-----------+
26280 static void decode_opc_mxu__pool08(CPUMIPSState
*env
, DisasContext
*ctx
)
26282 uint32_t opcode
= extract32(ctx
->opcode
, 20, 1);
26285 case OPC_MXU_S32LDI
:
26286 /* TODO: Implement emulation of S32LDI instruction. */
26287 MIPS_INVAL("OPC_MXU_S32LDI");
26288 gen_reserved_instruction(ctx
);
26290 case OPC_MXU_S32LDIR
:
26291 /* TODO: Implement emulation of S32LDIR instruction. */
26292 MIPS_INVAL("OPC_MXU_S32LDIR");
26293 gen_reserved_instruction(ctx
);
26296 MIPS_INVAL("decode_opc_mxu");
26297 gen_reserved_instruction(ctx
);
26304 * Decode MXU pool09
26306 * 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
26307 * +-----------+---------+-+-------------------+-------+-----------+
26308 * | SPECIAL2 | rb |x| s12 | XRa |MXU__POOL09|
26309 * +-----------+---------+-+-------------------+-------+-----------+
26312 static void decode_opc_mxu__pool09(CPUMIPSState
*env
, DisasContext
*ctx
)
26314 uint32_t opcode
= extract32(ctx
->opcode
, 5, 0);
26317 case OPC_MXU_S32SDI
:
26318 /* TODO: Implement emulation of S32SDI instruction. */
26319 MIPS_INVAL("OPC_MXU_S32SDI");
26320 gen_reserved_instruction(ctx
);
26322 case OPC_MXU_S32SDIR
:
26323 /* TODO: Implement emulation of S32SDIR instruction. */
26324 MIPS_INVAL("OPC_MXU_S32SDIR");
26325 gen_reserved_instruction(ctx
);
26328 MIPS_INVAL("decode_opc_mxu");
26329 gen_reserved_instruction(ctx
);
26336 * Decode MXU pool10
26338 * 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
26339 * +-----------+---------+---------+---+-------+-------+-----------+
26340 * | SPECIAL2 | rb | rc |st2|x x x x| XRa |MXU__POOL10|
26341 * +-----------+---------+---------+---+-------+-------+-----------+
26344 static void decode_opc_mxu__pool10(CPUMIPSState
*env
, DisasContext
*ctx
)
26346 uint32_t opcode
= extract32(ctx
->opcode
, 5, 0);
26349 case OPC_MXU_S32LDIV
:
26350 /* TODO: Implement emulation of S32LDIV instruction. */
26351 MIPS_INVAL("OPC_MXU_S32LDIV");
26352 gen_reserved_instruction(ctx
);
26354 case OPC_MXU_S32LDIVR
:
26355 /* TODO: Implement emulation of S32LDIVR instruction. */
26356 MIPS_INVAL("OPC_MXU_S32LDIVR");
26357 gen_reserved_instruction(ctx
);
26360 MIPS_INVAL("decode_opc_mxu");
26361 gen_reserved_instruction(ctx
);
26368 * Decode MXU pool11
26370 * 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
26371 * +-----------+---------+---------+---+-------+-------+-----------+
26372 * | SPECIAL2 | rb | rc |st2|x x x x| XRa |MXU__POOL11|
26373 * +-----------+---------+---------+---+-------+-------+-----------+
26376 static void decode_opc_mxu__pool11(CPUMIPSState
*env
, DisasContext
*ctx
)
26378 uint32_t opcode
= extract32(ctx
->opcode
, 10, 4);
26381 case OPC_MXU_S32SDIV
:
26382 /* TODO: Implement emulation of S32SDIV instruction. */
26383 MIPS_INVAL("OPC_MXU_S32SDIV");
26384 gen_reserved_instruction(ctx
);
26386 case OPC_MXU_S32SDIVR
:
26387 /* TODO: Implement emulation of S32SDIVR instruction. */
26388 MIPS_INVAL("OPC_MXU_S32SDIVR");
26389 gen_reserved_instruction(ctx
);
26392 MIPS_INVAL("decode_opc_mxu");
26393 gen_reserved_instruction(ctx
);
26400 * Decode MXU pool12
26402 * 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
26403 * +-----------+---+---+-------+-------+-------+-------+-----------+
26404 * | SPECIAL2 |an2|x x| Xd | XRc | XRb | XRa |MXU__POOL12|
26405 * +-----------+---+---+-------+-------+-------+-------+-----------+
26408 static void decode_opc_mxu__pool12(CPUMIPSState
*env
, DisasContext
*ctx
)
26410 uint32_t opcode
= extract32(ctx
->opcode
, 22, 2);
26413 case OPC_MXU_D32ACC
:
26414 /* TODO: Implement emulation of D32ACC instruction. */
26415 MIPS_INVAL("OPC_MXU_D32ACC");
26416 gen_reserved_instruction(ctx
);
26418 case OPC_MXU_D32ACCM
:
26419 /* TODO: Implement emulation of D32ACCM instruction. */
26420 MIPS_INVAL("OPC_MXU_D32ACCM");
26421 gen_reserved_instruction(ctx
);
26423 case OPC_MXU_D32ASUM
:
26424 /* TODO: Implement emulation of D32ASUM instruction. */
26425 MIPS_INVAL("OPC_MXU_D32ASUM");
26426 gen_reserved_instruction(ctx
);
26429 MIPS_INVAL("decode_opc_mxu");
26430 gen_reserved_instruction(ctx
);
26437 * Decode MXU pool13
26439 * 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
26440 * +-----------+---+---+-------+-------+-------+-------+-----------+
26441 * | SPECIAL2 |en2|x x|0 0 0 0| XRc | XRb | XRa |MXU__POOL13|
26442 * +-----------+---+---+-------+-------+-------+-------+-----------+
26445 static void decode_opc_mxu__pool13(CPUMIPSState
*env
, DisasContext
*ctx
)
26447 uint32_t opcode
= extract32(ctx
->opcode
, 22, 2);
26450 case OPC_MXU_Q16ACC
:
26451 /* TODO: Implement emulation of Q16ACC instruction. */
26452 MIPS_INVAL("OPC_MXU_Q16ACC");
26453 gen_reserved_instruction(ctx
);
26455 case OPC_MXU_Q16ACCM
:
26456 /* TODO: Implement emulation of Q16ACCM instruction. */
26457 MIPS_INVAL("OPC_MXU_Q16ACCM");
26458 gen_reserved_instruction(ctx
);
26460 case OPC_MXU_Q16ASUM
:
26461 /* TODO: Implement emulation of Q16ASUM instruction. */
26462 MIPS_INVAL("OPC_MXU_Q16ASUM");
26463 gen_reserved_instruction(ctx
);
26466 MIPS_INVAL("decode_opc_mxu");
26467 gen_reserved_instruction(ctx
);
26474 * Decode MXU pool14
26477 * 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
26478 * +-----------+---+---+-------+-------+-------+-------+-----------+
26479 * | SPECIAL2 |0 0|x x| XRd | XRc | XRb | XRa |MXU__POOL14|
26480 * +-----------+---+---+-------+-------+-------+-------+-----------+
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 |en2|x x|0 0 0 0| XRc | XRb | XRa |MXU__POOL14|
26486 * +-----------+---+---+-------+-------+-------+-------+-----------+
26489 static void decode_opc_mxu__pool14(CPUMIPSState
*env
, DisasContext
*ctx
)
26491 uint32_t opcode
= extract32(ctx
->opcode
, 22, 2);
26494 case OPC_MXU_Q8ADDE
:
26495 /* TODO: Implement emulation of Q8ADDE instruction. */
26496 MIPS_INVAL("OPC_MXU_Q8ADDE");
26497 gen_reserved_instruction(ctx
);
26499 case OPC_MXU_D8SUM
:
26500 /* TODO: Implement emulation of D8SUM instruction. */
26501 MIPS_INVAL("OPC_MXU_D8SUM");
26502 gen_reserved_instruction(ctx
);
26504 case OPC_MXU_D8SUMC
:
26505 /* TODO: Implement emulation of D8SUMC instruction. */
26506 MIPS_INVAL("OPC_MXU_D8SUMC");
26507 gen_reserved_instruction(ctx
);
26510 MIPS_INVAL("decode_opc_mxu");
26511 gen_reserved_instruction(ctx
);
26518 * Decode MXU pool15
26520 * S32MUL, S32MULU, S32EXTRV:
26521 * 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
26522 * +-----------+---------+---------+---+-------+-------+-----------+
26523 * | SPECIAL2 | rs | rt |x x| XRd | XRa |MXU__POOL15|
26524 * +-----------+---------+---------+---+-------+-------+-----------+
26527 * 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
26528 * +-----------+---------+---------+---+-------+-------+-----------+
26529 * | SPECIAL2 | rb | sft5 |x x| XRd | XRa |MXU__POOL15|
26530 * +-----------+---------+---------+---+-------+-------+-----------+
26533 static void decode_opc_mxu__pool15(CPUMIPSState
*env
, DisasContext
*ctx
)
26535 uint32_t opcode
= extract32(ctx
->opcode
, 14, 2);
26538 case OPC_MXU_S32MUL
:
26539 /* TODO: Implement emulation of S32MUL instruction. */
26540 MIPS_INVAL("OPC_MXU_S32MUL");
26541 gen_reserved_instruction(ctx
);
26543 case OPC_MXU_S32MULU
:
26544 /* TODO: Implement emulation of S32MULU instruction. */
26545 MIPS_INVAL("OPC_MXU_S32MULU");
26546 gen_reserved_instruction(ctx
);
26548 case OPC_MXU_S32EXTR
:
26549 /* TODO: Implement emulation of S32EXTR instruction. */
26550 MIPS_INVAL("OPC_MXU_S32EXTR");
26551 gen_reserved_instruction(ctx
);
26553 case OPC_MXU_S32EXTRV
:
26554 /* TODO: Implement emulation of S32EXTRV instruction. */
26555 MIPS_INVAL("OPC_MXU_S32EXTRV");
26556 gen_reserved_instruction(ctx
);
26559 MIPS_INVAL("decode_opc_mxu");
26560 gen_reserved_instruction(ctx
);
26567 * Decode MXU pool16
26570 * 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
26571 * +-----------+---------+-----+-------+-------+-------+-----------+
26572 * | SPECIAL2 | rb |x x x| XRc | XRb | XRa |MXU__POOL16|
26573 * +-----------+---------+-----+-------+-------+-------+-----------+
26576 * 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
26577 * +-----------+---------+-----+-------+-------+-------+-----------+
26578 * | SPECIAL2 | rs |x x x| XRc | XRb | XRa |MXU__POOL16|
26579 * +-----------+---------+-----+-------+-------+-------+-----------+
26582 * 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
26583 * +-----------+-----+---+-----+-------+-------+-------+-----------+
26584 * | SPECIAL2 | s3 |0 0|x x x| XRc | XRb | XRa |MXU__POOL16|
26585 * +-----------+-----+---+-----+-------+-------+-------+-----------+
26588 * 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
26589 * +-----------+-----+---+-----+-------+---------------+-----------+
26590 * | SPECIAL2 |optn3|0 0|x x x| XRc | s8 |MXU__POOL16|
26591 * +-----------+-----+---+-----+-------+---------------+-----------+
26593 * S32NOR, S32AND, S32OR, S32XOR:
26594 * 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
26595 * +-----------+---------+-----+-------+-------+-------+-----------+
26596 * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL16|
26597 * +-----------+---------+-----+-------+-------+-------+-----------+
26600 static void decode_opc_mxu__pool16(CPUMIPSState
*env
, DisasContext
*ctx
)
26602 uint32_t opcode
= extract32(ctx
->opcode
, 18, 3);
26605 case OPC_MXU_D32SARW
:
26606 /* TODO: Implement emulation of D32SARW instruction. */
26607 MIPS_INVAL("OPC_MXU_D32SARW");
26608 gen_reserved_instruction(ctx
);
26610 case OPC_MXU_S32ALN
:
26611 /* TODO: Implement emulation of S32ALN instruction. */
26612 MIPS_INVAL("OPC_MXU_S32ALN");
26613 gen_reserved_instruction(ctx
);
26615 case OPC_MXU_S32ALNI
:
26616 gen_mxu_S32ALNI(ctx
);
26618 case OPC_MXU_S32LUI
:
26619 /* TODO: Implement emulation of S32LUI instruction. */
26620 MIPS_INVAL("OPC_MXU_S32LUI");
26621 gen_reserved_instruction(ctx
);
26623 case OPC_MXU_S32NOR
:
26624 gen_mxu_S32NOR(ctx
);
26626 case OPC_MXU_S32AND
:
26627 gen_mxu_S32AND(ctx
);
26629 case OPC_MXU_S32OR
:
26630 gen_mxu_S32OR(ctx
);
26632 case OPC_MXU_S32XOR
:
26633 gen_mxu_S32XOR(ctx
);
26636 MIPS_INVAL("decode_opc_mxu");
26637 gen_reserved_instruction(ctx
);
26644 * Decode MXU pool17
26646 * 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
26647 * +-----------+---------+---------+---+---------+-----+-----------+
26648 * | SPECIAL2 | rs | rt |0 0| rd |x x x|MXU__POOL15|
26649 * +-----------+---------+---------+---+---------+-----+-----------+
26652 static void decode_opc_mxu__pool17(CPUMIPSState
*env
, DisasContext
*ctx
)
26654 uint32_t opcode
= extract32(ctx
->opcode
, 6, 2);
26658 /* TODO: Implement emulation of LXW instruction. */
26659 MIPS_INVAL("OPC_MXU_LXW");
26660 gen_reserved_instruction(ctx
);
26663 /* TODO: Implement emulation of LXH instruction. */
26664 MIPS_INVAL("OPC_MXU_LXH");
26665 gen_reserved_instruction(ctx
);
26668 /* TODO: Implement emulation of LXHU instruction. */
26669 MIPS_INVAL("OPC_MXU_LXHU");
26670 gen_reserved_instruction(ctx
);
26673 /* TODO: Implement emulation of LXB instruction. */
26674 MIPS_INVAL("OPC_MXU_LXB");
26675 gen_reserved_instruction(ctx
);
26678 /* TODO: Implement emulation of LXBU instruction. */
26679 MIPS_INVAL("OPC_MXU_LXBU");
26680 gen_reserved_instruction(ctx
);
26683 MIPS_INVAL("decode_opc_mxu");
26684 gen_reserved_instruction(ctx
);
26690 * Decode MXU pool18
26692 * 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
26693 * +-----------+---------+-----+-------+-------+-------+-----------+
26694 * | SPECIAL2 | rb |x x x| XRd | XRa |0 0 0 0|MXU__POOL18|
26695 * +-----------+---------+-----+-------+-------+-------+-----------+
26698 static void decode_opc_mxu__pool18(CPUMIPSState
*env
, DisasContext
*ctx
)
26700 uint32_t opcode
= extract32(ctx
->opcode
, 18, 3);
26703 case OPC_MXU_D32SLLV
:
26704 /* TODO: Implement emulation of D32SLLV instruction. */
26705 MIPS_INVAL("OPC_MXU_D32SLLV");
26706 gen_reserved_instruction(ctx
);
26708 case OPC_MXU_D32SLRV
:
26709 /* TODO: Implement emulation of D32SLRV instruction. */
26710 MIPS_INVAL("OPC_MXU_D32SLRV");
26711 gen_reserved_instruction(ctx
);
26713 case OPC_MXU_D32SARV
:
26714 /* TODO: Implement emulation of D32SARV instruction. */
26715 MIPS_INVAL("OPC_MXU_D32SARV");
26716 gen_reserved_instruction(ctx
);
26718 case OPC_MXU_Q16SLLV
:
26719 /* TODO: Implement emulation of Q16SLLV instruction. */
26720 MIPS_INVAL("OPC_MXU_Q16SLLV");
26721 gen_reserved_instruction(ctx
);
26723 case OPC_MXU_Q16SLRV
:
26724 /* TODO: Implement emulation of Q16SLRV instruction. */
26725 MIPS_INVAL("OPC_MXU_Q16SLRV");
26726 gen_reserved_instruction(ctx
);
26728 case OPC_MXU_Q16SARV
:
26729 /* TODO: Implement emulation of Q16SARV instruction. */
26730 MIPS_INVAL("OPC_MXU_Q16SARV");
26731 gen_reserved_instruction(ctx
);
26734 MIPS_INVAL("decode_opc_mxu");
26735 gen_reserved_instruction(ctx
);
26742 * Decode MXU pool19
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 |0 0|x x| XRd | XRc | XRb | XRa |MXU__POOL19|
26747 * +-----------+---+---+-------+-------+-------+-------+-----------+
26750 static void decode_opc_mxu__pool19(CPUMIPSState
*env
, DisasContext
*ctx
)
26752 uint32_t opcode
= extract32(ctx
->opcode
, 22, 2);
26755 case OPC_MXU_Q8MUL
:
26756 case OPC_MXU_Q8MULSU
:
26757 gen_mxu_q8mul_q8mulsu(ctx
);
26760 MIPS_INVAL("decode_opc_mxu");
26761 gen_reserved_instruction(ctx
);
26768 * Decode MXU pool20
26770 * 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
26771 * +-----------+---------+-----+-------+-------+-------+-----------+
26772 * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL20|
26773 * +-----------+---------+-----+-------+-------+-------+-----------+
26776 static void decode_opc_mxu__pool20(CPUMIPSState
*env
, DisasContext
*ctx
)
26778 uint32_t opcode
= extract32(ctx
->opcode
, 18, 3);
26781 case OPC_MXU_Q8MOVZ
:
26782 /* TODO: Implement emulation of Q8MOVZ instruction. */
26783 MIPS_INVAL("OPC_MXU_Q8MOVZ");
26784 gen_reserved_instruction(ctx
);
26786 case OPC_MXU_Q8MOVN
:
26787 /* TODO: Implement emulation of Q8MOVN instruction. */
26788 MIPS_INVAL("OPC_MXU_Q8MOVN");
26789 gen_reserved_instruction(ctx
);
26791 case OPC_MXU_D16MOVZ
:
26792 /* TODO: Implement emulation of D16MOVZ instruction. */
26793 MIPS_INVAL("OPC_MXU_D16MOVZ");
26794 gen_reserved_instruction(ctx
);
26796 case OPC_MXU_D16MOVN
:
26797 /* TODO: Implement emulation of D16MOVN instruction. */
26798 MIPS_INVAL("OPC_MXU_D16MOVN");
26799 gen_reserved_instruction(ctx
);
26801 case OPC_MXU_S32MOVZ
:
26802 /* TODO: Implement emulation of S32MOVZ instruction. */
26803 MIPS_INVAL("OPC_MXU_S32MOVZ");
26804 gen_reserved_instruction(ctx
);
26806 case OPC_MXU_S32MOVN
:
26807 /* TODO: Implement emulation of S32MOVN instruction. */
26808 MIPS_INVAL("OPC_MXU_S32MOVN");
26809 gen_reserved_instruction(ctx
);
26812 MIPS_INVAL("decode_opc_mxu");
26813 gen_reserved_instruction(ctx
);
26820 * Decode MXU pool21
26822 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26823 * +-----------+---+---+-------+-------+-------+-------+-----------+
26824 * | SPECIAL2 |an2|x x| XRd | XRc | XRb | XRa |MXU__POOL21|
26825 * +-----------+---+---+-------+-------+-------+-------+-----------+
26828 static void decode_opc_mxu__pool21(CPUMIPSState
*env
, DisasContext
*ctx
)
26830 uint32_t opcode
= extract32(ctx
->opcode
, 22, 2);
26833 case OPC_MXU_Q8MAC
:
26834 /* TODO: Implement emulation of Q8MAC instruction. */
26835 MIPS_INVAL("OPC_MXU_Q8MAC");
26836 gen_reserved_instruction(ctx
);
26838 case OPC_MXU_Q8MACSU
:
26839 /* TODO: Implement emulation of Q8MACSU instruction. */
26840 MIPS_INVAL("OPC_MXU_Q8MACSU");
26841 gen_reserved_instruction(ctx
);
26844 MIPS_INVAL("decode_opc_mxu");
26845 gen_reserved_instruction(ctx
);
26852 * Main MXU decoding function
26854 * 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
26855 * +-----------+---------------------------------------+-----------+
26856 * | SPECIAL2 | |x x x x x x|
26857 * +-----------+---------------------------------------+-----------+
26860 static void decode_opc_mxu(CPUMIPSState
*env
, DisasContext
*ctx
)
26863 * TODO: Investigate necessity of including handling of
26864 * CLZ, CLO, SDBB in this function, as they belong to
26865 * SPECIAL2 opcode space for regular pre-R6 MIPS ISAs.
26867 uint32_t opcode
= extract32(ctx
->opcode
, 0, 6);
26869 if (opcode
== OPC__MXU_MUL
) {
26870 uint32_t rs
, rt
, rd
, op1
;
26872 rs
= extract32(ctx
->opcode
, 21, 5);
26873 rt
= extract32(ctx
->opcode
, 16, 5);
26874 rd
= extract32(ctx
->opcode
, 11, 5);
26875 op1
= MASK_SPECIAL2(ctx
->opcode
);
26877 gen_arith(ctx
, op1
, rd
, rs
, rt
);
26882 if (opcode
== OPC_MXU_S32M2I
) {
26883 gen_mxu_s32m2i(ctx
);
26887 if (opcode
== OPC_MXU_S32I2M
) {
26888 gen_mxu_s32i2m(ctx
);
26893 TCGv t_mxu_cr
= tcg_temp_new();
26894 TCGLabel
*l_exit
= gen_new_label();
26896 gen_load_mxu_cr(t_mxu_cr
);
26897 tcg_gen_andi_tl(t_mxu_cr
, t_mxu_cr
, MXU_CR_MXU_EN
);
26898 tcg_gen_brcondi_tl(TCG_COND_NE
, t_mxu_cr
, MXU_CR_MXU_EN
, l_exit
);
26901 case OPC_MXU_S32MADD
:
26902 /* TODO: Implement emulation of S32MADD instruction. */
26903 MIPS_INVAL("OPC_MXU_S32MADD");
26904 gen_reserved_instruction(ctx
);
26906 case OPC_MXU_S32MADDU
:
26907 /* TODO: Implement emulation of S32MADDU instruction. */
26908 MIPS_INVAL("OPC_MXU_S32MADDU");
26909 gen_reserved_instruction(ctx
);
26911 case OPC_MXU__POOL00
:
26912 decode_opc_mxu__pool00(env
, ctx
);
26914 case OPC_MXU_S32MSUB
:
26915 /* TODO: Implement emulation of S32MSUB instruction. */
26916 MIPS_INVAL("OPC_MXU_S32MSUB");
26917 gen_reserved_instruction(ctx
);
26919 case OPC_MXU_S32MSUBU
:
26920 /* TODO: Implement emulation of S32MSUBU instruction. */
26921 MIPS_INVAL("OPC_MXU_S32MSUBU");
26922 gen_reserved_instruction(ctx
);
26924 case OPC_MXU__POOL01
:
26925 decode_opc_mxu__pool01(env
, ctx
);
26927 case OPC_MXU__POOL02
:
26928 decode_opc_mxu__pool02(env
, ctx
);
26930 case OPC_MXU_D16MUL
:
26931 gen_mxu_d16mul(ctx
);
26933 case OPC_MXU__POOL03
:
26934 decode_opc_mxu__pool03(env
, ctx
);
26936 case OPC_MXU_D16MAC
:
26937 gen_mxu_d16mac(ctx
);
26939 case OPC_MXU_D16MACF
:
26940 /* TODO: Implement emulation of D16MACF instruction. */
26941 MIPS_INVAL("OPC_MXU_D16MACF");
26942 gen_reserved_instruction(ctx
);
26944 case OPC_MXU_D16MADL
:
26945 /* TODO: Implement emulation of D16MADL instruction. */
26946 MIPS_INVAL("OPC_MXU_D16MADL");
26947 gen_reserved_instruction(ctx
);
26949 case OPC_MXU_S16MAD
:
26950 /* TODO: Implement emulation of S16MAD instruction. */
26951 MIPS_INVAL("OPC_MXU_S16MAD");
26952 gen_reserved_instruction(ctx
);
26954 case OPC_MXU_Q16ADD
:
26955 /* TODO: Implement emulation of Q16ADD instruction. */
26956 MIPS_INVAL("OPC_MXU_Q16ADD");
26957 gen_reserved_instruction(ctx
);
26959 case OPC_MXU_D16MACE
:
26960 /* TODO: Implement emulation of D16MACE instruction. */
26961 MIPS_INVAL("OPC_MXU_D16MACE");
26962 gen_reserved_instruction(ctx
);
26964 case OPC_MXU__POOL04
:
26965 decode_opc_mxu__pool04(env
, ctx
);
26967 case OPC_MXU__POOL05
:
26968 decode_opc_mxu__pool05(env
, ctx
);
26970 case OPC_MXU__POOL06
:
26971 decode_opc_mxu__pool06(env
, ctx
);
26973 case OPC_MXU__POOL07
:
26974 decode_opc_mxu__pool07(env
, ctx
);
26976 case OPC_MXU__POOL08
:
26977 decode_opc_mxu__pool08(env
, ctx
);
26979 case OPC_MXU__POOL09
:
26980 decode_opc_mxu__pool09(env
, ctx
);
26982 case OPC_MXU__POOL10
:
26983 decode_opc_mxu__pool10(env
, ctx
);
26985 case OPC_MXU__POOL11
:
26986 decode_opc_mxu__pool11(env
, ctx
);
26988 case OPC_MXU_D32ADD
:
26989 /* TODO: Implement emulation of D32ADD instruction. */
26990 MIPS_INVAL("OPC_MXU_D32ADD");
26991 gen_reserved_instruction(ctx
);
26993 case OPC_MXU__POOL12
:
26994 decode_opc_mxu__pool12(env
, ctx
);
26996 case OPC_MXU__POOL13
:
26997 decode_opc_mxu__pool13(env
, ctx
);
26999 case OPC_MXU__POOL14
:
27000 decode_opc_mxu__pool14(env
, ctx
);
27002 case OPC_MXU_Q8ACCE
:
27003 /* TODO: Implement emulation of Q8ACCE instruction. */
27004 MIPS_INVAL("OPC_MXU_Q8ACCE");
27005 gen_reserved_instruction(ctx
);
27007 case OPC_MXU_S8LDD
:
27008 gen_mxu_s8ldd(ctx
);
27010 case OPC_MXU_S8STD
:
27011 /* TODO: Implement emulation of S8STD instruction. */
27012 MIPS_INVAL("OPC_MXU_S8STD");
27013 gen_reserved_instruction(ctx
);
27015 case OPC_MXU_S8LDI
:
27016 /* TODO: Implement emulation of S8LDI instruction. */
27017 MIPS_INVAL("OPC_MXU_S8LDI");
27018 gen_reserved_instruction(ctx
);
27020 case OPC_MXU_S8SDI
:
27021 /* TODO: Implement emulation of S8SDI instruction. */
27022 MIPS_INVAL("OPC_MXU_S8SDI");
27023 gen_reserved_instruction(ctx
);
27025 case OPC_MXU__POOL15
:
27026 decode_opc_mxu__pool15(env
, ctx
);
27028 case OPC_MXU__POOL16
:
27029 decode_opc_mxu__pool16(env
, ctx
);
27031 case OPC_MXU__POOL17
:
27032 decode_opc_mxu__pool17(env
, ctx
);
27034 case OPC_MXU_S16LDD
:
27035 /* TODO: Implement emulation of S16LDD instruction. */
27036 MIPS_INVAL("OPC_MXU_S16LDD");
27037 gen_reserved_instruction(ctx
);
27039 case OPC_MXU_S16STD
:
27040 /* TODO: Implement emulation of S16STD instruction. */
27041 MIPS_INVAL("OPC_MXU_S16STD");
27042 gen_reserved_instruction(ctx
);
27044 case OPC_MXU_S16LDI
:
27045 /* TODO: Implement emulation of S16LDI instruction. */
27046 MIPS_INVAL("OPC_MXU_S16LDI");
27047 gen_reserved_instruction(ctx
);
27049 case OPC_MXU_S16SDI
:
27050 /* TODO: Implement emulation of S16SDI instruction. */
27051 MIPS_INVAL("OPC_MXU_S16SDI");
27052 gen_reserved_instruction(ctx
);
27054 case OPC_MXU_D32SLL
:
27055 /* TODO: Implement emulation of D32SLL instruction. */
27056 MIPS_INVAL("OPC_MXU_D32SLL");
27057 gen_reserved_instruction(ctx
);
27059 case OPC_MXU_D32SLR
:
27060 /* TODO: Implement emulation of D32SLR instruction. */
27061 MIPS_INVAL("OPC_MXU_D32SLR");
27062 gen_reserved_instruction(ctx
);
27064 case OPC_MXU_D32SARL
:
27065 /* TODO: Implement emulation of D32SARL instruction. */
27066 MIPS_INVAL("OPC_MXU_D32SARL");
27067 gen_reserved_instruction(ctx
);
27069 case OPC_MXU_D32SAR
:
27070 /* TODO: Implement emulation of D32SAR instruction. */
27071 MIPS_INVAL("OPC_MXU_D32SAR");
27072 gen_reserved_instruction(ctx
);
27074 case OPC_MXU_Q16SLL
:
27075 /* TODO: Implement emulation of Q16SLL instruction. */
27076 MIPS_INVAL("OPC_MXU_Q16SLL");
27077 gen_reserved_instruction(ctx
);
27079 case OPC_MXU_Q16SLR
:
27080 /* TODO: Implement emulation of Q16SLR instruction. */
27081 MIPS_INVAL("OPC_MXU_Q16SLR");
27082 gen_reserved_instruction(ctx
);
27084 case OPC_MXU__POOL18
:
27085 decode_opc_mxu__pool18(env
, ctx
);
27087 case OPC_MXU_Q16SAR
:
27088 /* TODO: Implement emulation of Q16SAR instruction. */
27089 MIPS_INVAL("OPC_MXU_Q16SAR");
27090 gen_reserved_instruction(ctx
);
27092 case OPC_MXU__POOL19
:
27093 decode_opc_mxu__pool19(env
, ctx
);
27095 case OPC_MXU__POOL20
:
27096 decode_opc_mxu__pool20(env
, ctx
);
27098 case OPC_MXU__POOL21
:
27099 decode_opc_mxu__pool21(env
, ctx
);
27101 case OPC_MXU_Q16SCOP
:
27102 /* TODO: Implement emulation of Q16SCOP instruction. */
27103 MIPS_INVAL("OPC_MXU_Q16SCOP");
27104 gen_reserved_instruction(ctx
);
27106 case OPC_MXU_Q8MADL
:
27107 /* TODO: Implement emulation of Q8MADL instruction. */
27108 MIPS_INVAL("OPC_MXU_Q8MADL");
27109 gen_reserved_instruction(ctx
);
27111 case OPC_MXU_S32SFL
:
27112 /* TODO: Implement emulation of S32SFL instruction. */
27113 MIPS_INVAL("OPC_MXU_S32SFL");
27114 gen_reserved_instruction(ctx
);
27116 case OPC_MXU_Q8SAD
:
27117 /* TODO: Implement emulation of Q8SAD instruction. */
27118 MIPS_INVAL("OPC_MXU_Q8SAD");
27119 gen_reserved_instruction(ctx
);
27122 MIPS_INVAL("decode_opc_mxu");
27123 gen_reserved_instruction(ctx
);
27126 gen_set_label(l_exit
);
27127 tcg_temp_free(t_mxu_cr
);
27131 #endif /* !defined(TARGET_MIPS64) */
27134 static void decode_opc_special2_legacy(CPUMIPSState
*env
, DisasContext
*ctx
)
27139 rs
= (ctx
->opcode
>> 21) & 0x1f;
27140 rt
= (ctx
->opcode
>> 16) & 0x1f;
27141 rd
= (ctx
->opcode
>> 11) & 0x1f;
27143 op1
= MASK_SPECIAL2(ctx
->opcode
);
27145 case OPC_MADD
: /* Multiply and add/sub */
27149 check_insn(ctx
, ISA_MIPS_R1
);
27150 gen_muldiv(ctx
, op1
, rd
& 3, rs
, rt
);
27153 gen_arith(ctx
, op1
, rd
, rs
, rt
);
27156 case OPC_DIVU_G_2F
:
27157 case OPC_MULT_G_2F
:
27158 case OPC_MULTU_G_2F
:
27160 case OPC_MODU_G_2F
:
27161 check_insn(ctx
, INSN_LOONGSON2F
| ASE_LEXT
);
27162 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
27166 check_insn(ctx
, ISA_MIPS_R1
);
27167 gen_cl(ctx
, op1
, rd
, rs
);
27170 if (is_uhi(extract32(ctx
->opcode
, 6, 20))) {
27171 gen_helper_do_semihosting(cpu_env
);
27174 * XXX: not clear which exception should be raised
27175 * when in debug mode...
27177 check_insn(ctx
, ISA_MIPS_R1
);
27178 generate_exception_end(ctx
, EXCP_DBp
);
27181 #if defined(TARGET_MIPS64)
27184 check_insn(ctx
, ISA_MIPS_R1
);
27185 check_mips_64(ctx
);
27186 gen_cl(ctx
, op1
, rd
, rs
);
27188 case OPC_DMULT_G_2F
:
27189 case OPC_DMULTU_G_2F
:
27190 case OPC_DDIV_G_2F
:
27191 case OPC_DDIVU_G_2F
:
27192 case OPC_DMOD_G_2F
:
27193 case OPC_DMODU_G_2F
:
27194 check_insn(ctx
, INSN_LOONGSON2F
| ASE_LEXT
);
27195 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
27198 default: /* Invalid */
27199 MIPS_INVAL("special2_legacy");
27200 gen_reserved_instruction(ctx
);
27205 static void decode_opc_special3_r6(CPUMIPSState
*env
, DisasContext
*ctx
)
27207 int rs
, rt
, rd
, sa
;
27211 rs
= (ctx
->opcode
>> 21) & 0x1f;
27212 rt
= (ctx
->opcode
>> 16) & 0x1f;
27213 rd
= (ctx
->opcode
>> 11) & 0x1f;
27214 sa
= (ctx
->opcode
>> 6) & 0x1f;
27215 imm
= (int16_t)ctx
->opcode
>> 7;
27217 op1
= MASK_SPECIAL3(ctx
->opcode
);
27221 /* hint codes 24-31 are reserved and signal RI */
27222 gen_reserved_instruction(ctx
);
27224 /* Treat as NOP. */
27227 check_cp0_enabled(ctx
);
27228 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
27229 gen_cache_operation(ctx
, rt
, rs
, imm
);
27233 gen_st_cond(ctx
, rt
, rs
, imm
, MO_TESL
, false);
27236 gen_ld(ctx
, op1
, rt
, rs
, imm
);
27241 /* Treat as NOP. */
27244 op2
= MASK_BSHFL(ctx
->opcode
);
27250 gen_align(ctx
, 32, rd
, rs
, rt
, sa
& 3);
27253 gen_bitswap(ctx
, op2
, rd
, rt
);
27258 #ifndef CONFIG_USER_ONLY
27260 if (unlikely(ctx
->gi
<= 1)) {
27261 gen_reserved_instruction(ctx
);
27263 check_cp0_enabled(ctx
);
27264 switch ((ctx
->opcode
>> 6) & 3) {
27265 case 0: /* GINVI */
27266 /* Treat as NOP. */
27268 case 2: /* GINVT */
27269 gen_helper_0e1i(ginvt
, cpu_gpr
[rs
], extract32(ctx
->opcode
, 8, 2));
27272 gen_reserved_instruction(ctx
);
27277 #if defined(TARGET_MIPS64)
27279 gen_st_cond(ctx
, rt
, rs
, imm
, MO_TEQ
, false);
27282 gen_ld(ctx
, op1
, rt
, rs
, imm
);
27285 check_mips_64(ctx
);
27288 /* Treat as NOP. */
27291 op2
= MASK_DBSHFL(ctx
->opcode
);
27301 gen_align(ctx
, 64, rd
, rs
, rt
, sa
& 7);
27304 gen_bitswap(ctx
, op2
, rd
, rt
);
27311 default: /* Invalid */
27312 MIPS_INVAL("special3_r6");
27313 gen_reserved_instruction(ctx
);
27318 static void decode_opc_special3_legacy(CPUMIPSState
*env
, DisasContext
*ctx
)
27323 rs
= (ctx
->opcode
>> 21) & 0x1f;
27324 rt
= (ctx
->opcode
>> 16) & 0x1f;
27325 rd
= (ctx
->opcode
>> 11) & 0x1f;
27327 op1
= MASK_SPECIAL3(ctx
->opcode
);
27330 case OPC_DIVU_G_2E
:
27332 case OPC_MODU_G_2E
:
27333 case OPC_MULT_G_2E
:
27334 case OPC_MULTU_G_2E
:
27336 * OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
27337 * the same mask and op1.
27339 if ((ctx
->insn_flags
& ASE_DSP_R2
) && (op1
== OPC_MULT_G_2E
)) {
27340 op2
= MASK_ADDUH_QB(ctx
->opcode
);
27343 case OPC_ADDUH_R_QB
:
27345 case OPC_ADDQH_R_PH
:
27347 case OPC_ADDQH_R_W
:
27349 case OPC_SUBUH_R_QB
:
27351 case OPC_SUBQH_R_PH
:
27353 case OPC_SUBQH_R_W
:
27354 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
27359 case OPC_MULQ_RS_W
:
27360 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
27363 MIPS_INVAL("MASK ADDUH.QB");
27364 gen_reserved_instruction(ctx
);
27367 } else if (ctx
->insn_flags
& INSN_LOONGSON2E
) {
27368 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
27370 gen_reserved_instruction(ctx
);
27374 op2
= MASK_LX(ctx
->opcode
);
27376 #if defined(TARGET_MIPS64)
27382 gen_mipsdsp_ld(ctx
, op2
, rd
, rs
, rt
);
27384 default: /* Invalid */
27385 MIPS_INVAL("MASK LX");
27386 gen_reserved_instruction(ctx
);
27390 case OPC_ABSQ_S_PH_DSP
:
27391 op2
= MASK_ABSQ_S_PH(ctx
->opcode
);
27393 case OPC_ABSQ_S_QB
:
27394 case OPC_ABSQ_S_PH
:
27396 case OPC_PRECEQ_W_PHL
:
27397 case OPC_PRECEQ_W_PHR
:
27398 case OPC_PRECEQU_PH_QBL
:
27399 case OPC_PRECEQU_PH_QBR
:
27400 case OPC_PRECEQU_PH_QBLA
:
27401 case OPC_PRECEQU_PH_QBRA
:
27402 case OPC_PRECEU_PH_QBL
:
27403 case OPC_PRECEU_PH_QBR
:
27404 case OPC_PRECEU_PH_QBLA
:
27405 case OPC_PRECEU_PH_QBRA
:
27406 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
27413 gen_mipsdsp_bitinsn(ctx
, op1
, op2
, rd
, rt
);
27416 MIPS_INVAL("MASK ABSQ_S.PH");
27417 gen_reserved_instruction(ctx
);
27421 case OPC_ADDU_QB_DSP
:
27422 op2
= MASK_ADDU_QB(ctx
->opcode
);
27425 case OPC_ADDQ_S_PH
:
27428 case OPC_ADDU_S_QB
:
27430 case OPC_ADDU_S_PH
:
27432 case OPC_SUBQ_S_PH
:
27435 case OPC_SUBU_S_QB
:
27437 case OPC_SUBU_S_PH
:
27441 case OPC_RADDU_W_QB
:
27442 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
27444 case OPC_MULEU_S_PH_QBL
:
27445 case OPC_MULEU_S_PH_QBR
:
27446 case OPC_MULQ_RS_PH
:
27447 case OPC_MULEQ_S_W_PHL
:
27448 case OPC_MULEQ_S_W_PHR
:
27449 case OPC_MULQ_S_PH
:
27450 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
27452 default: /* Invalid */
27453 MIPS_INVAL("MASK ADDU.QB");
27454 gen_reserved_instruction(ctx
);
27459 case OPC_CMPU_EQ_QB_DSP
:
27460 op2
= MASK_CMPU_EQ_QB(ctx
->opcode
);
27462 case OPC_PRECR_SRA_PH_W
:
27463 case OPC_PRECR_SRA_R_PH_W
:
27464 gen_mipsdsp_arith(ctx
, op1
, op2
, rt
, rs
, rd
);
27466 case OPC_PRECR_QB_PH
:
27467 case OPC_PRECRQ_QB_PH
:
27468 case OPC_PRECRQ_PH_W
:
27469 case OPC_PRECRQ_RS_PH_W
:
27470 case OPC_PRECRQU_S_QB_PH
:
27471 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
27473 case OPC_CMPU_EQ_QB
:
27474 case OPC_CMPU_LT_QB
:
27475 case OPC_CMPU_LE_QB
:
27476 case OPC_CMP_EQ_PH
:
27477 case OPC_CMP_LT_PH
:
27478 case OPC_CMP_LE_PH
:
27479 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
27481 case OPC_CMPGU_EQ_QB
:
27482 case OPC_CMPGU_LT_QB
:
27483 case OPC_CMPGU_LE_QB
:
27484 case OPC_CMPGDU_EQ_QB
:
27485 case OPC_CMPGDU_LT_QB
:
27486 case OPC_CMPGDU_LE_QB
:
27489 case OPC_PACKRL_PH
:
27490 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
27492 default: /* Invalid */
27493 MIPS_INVAL("MASK CMPU.EQ.QB");
27494 gen_reserved_instruction(ctx
);
27498 case OPC_SHLL_QB_DSP
:
27499 gen_mipsdsp_shift(ctx
, op1
, rd
, rs
, rt
);
27501 case OPC_DPA_W_PH_DSP
:
27502 op2
= MASK_DPA_W_PH(ctx
->opcode
);
27504 case OPC_DPAU_H_QBL
:
27505 case OPC_DPAU_H_QBR
:
27506 case OPC_DPSU_H_QBL
:
27507 case OPC_DPSU_H_QBR
:
27509 case OPC_DPAX_W_PH
:
27510 case OPC_DPAQ_S_W_PH
:
27511 case OPC_DPAQX_S_W_PH
:
27512 case OPC_DPAQX_SA_W_PH
:
27514 case OPC_DPSX_W_PH
:
27515 case OPC_DPSQ_S_W_PH
:
27516 case OPC_DPSQX_S_W_PH
:
27517 case OPC_DPSQX_SA_W_PH
:
27518 case OPC_MULSAQ_S_W_PH
:
27519 case OPC_DPAQ_SA_L_W
:
27520 case OPC_DPSQ_SA_L_W
:
27521 case OPC_MAQ_S_W_PHL
:
27522 case OPC_MAQ_S_W_PHR
:
27523 case OPC_MAQ_SA_W_PHL
:
27524 case OPC_MAQ_SA_W_PHR
:
27525 case OPC_MULSA_W_PH
:
27526 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
27528 default: /* Invalid */
27529 MIPS_INVAL("MASK DPAW.PH");
27530 gen_reserved_instruction(ctx
);
27535 op2
= MASK_INSV(ctx
->opcode
);
27546 t0
= tcg_temp_new();
27547 t1
= tcg_temp_new();
27549 gen_load_gpr(t0
, rt
);
27550 gen_load_gpr(t1
, rs
);
27552 gen_helper_insv(cpu_gpr
[rt
], cpu_env
, t1
, t0
);
27558 default: /* Invalid */
27559 MIPS_INVAL("MASK INSV");
27560 gen_reserved_instruction(ctx
);
27564 case OPC_APPEND_DSP
:
27565 gen_mipsdsp_append(env
, ctx
, op1
, rt
, rs
, rd
);
27567 case OPC_EXTR_W_DSP
:
27568 op2
= MASK_EXTR_W(ctx
->opcode
);
27572 case OPC_EXTR_RS_W
:
27574 case OPC_EXTRV_S_H
:
27576 case OPC_EXTRV_R_W
:
27577 case OPC_EXTRV_RS_W
:
27582 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rt
, rs
, rd
, 1);
27585 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
27591 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
27593 default: /* Invalid */
27594 MIPS_INVAL("MASK EXTR.W");
27595 gen_reserved_instruction(ctx
);
27599 #if defined(TARGET_MIPS64)
27600 case OPC_DDIV_G_2E
:
27601 case OPC_DDIVU_G_2E
:
27602 case OPC_DMULT_G_2E
:
27603 case OPC_DMULTU_G_2E
:
27604 case OPC_DMOD_G_2E
:
27605 case OPC_DMODU_G_2E
:
27606 check_insn(ctx
, INSN_LOONGSON2E
);
27607 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
27609 case OPC_ABSQ_S_QH_DSP
:
27610 op2
= MASK_ABSQ_S_QH(ctx
->opcode
);
27612 case OPC_PRECEQ_L_PWL
:
27613 case OPC_PRECEQ_L_PWR
:
27614 case OPC_PRECEQ_PW_QHL
:
27615 case OPC_PRECEQ_PW_QHR
:
27616 case OPC_PRECEQ_PW_QHLA
:
27617 case OPC_PRECEQ_PW_QHRA
:
27618 case OPC_PRECEQU_QH_OBL
:
27619 case OPC_PRECEQU_QH_OBR
:
27620 case OPC_PRECEQU_QH_OBLA
:
27621 case OPC_PRECEQU_QH_OBRA
:
27622 case OPC_PRECEU_QH_OBL
:
27623 case OPC_PRECEU_QH_OBR
:
27624 case OPC_PRECEU_QH_OBLA
:
27625 case OPC_PRECEU_QH_OBRA
:
27626 case OPC_ABSQ_S_OB
:
27627 case OPC_ABSQ_S_PW
:
27628 case OPC_ABSQ_S_QH
:
27629 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
27637 gen_mipsdsp_bitinsn(ctx
, op1
, op2
, rd
, rt
);
27639 default: /* Invalid */
27640 MIPS_INVAL("MASK ABSQ_S.QH");
27641 gen_reserved_instruction(ctx
);
27645 case OPC_ADDU_OB_DSP
:
27646 op2
= MASK_ADDU_OB(ctx
->opcode
);
27648 case OPC_RADDU_L_OB
:
27650 case OPC_SUBQ_S_PW
:
27652 case OPC_SUBQ_S_QH
:
27654 case OPC_SUBU_S_OB
:
27656 case OPC_SUBU_S_QH
:
27658 case OPC_SUBUH_R_OB
:
27660 case OPC_ADDQ_S_PW
:
27662 case OPC_ADDQ_S_QH
:
27664 case OPC_ADDU_S_OB
:
27666 case OPC_ADDU_S_QH
:
27668 case OPC_ADDUH_R_OB
:
27669 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
27671 case OPC_MULEQ_S_PW_QHL
:
27672 case OPC_MULEQ_S_PW_QHR
:
27673 case OPC_MULEU_S_QH_OBL
:
27674 case OPC_MULEU_S_QH_OBR
:
27675 case OPC_MULQ_RS_QH
:
27676 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
27678 default: /* Invalid */
27679 MIPS_INVAL("MASK ADDU.OB");
27680 gen_reserved_instruction(ctx
);
27684 case OPC_CMPU_EQ_OB_DSP
:
27685 op2
= MASK_CMPU_EQ_OB(ctx
->opcode
);
27687 case OPC_PRECR_SRA_QH_PW
:
27688 case OPC_PRECR_SRA_R_QH_PW
:
27689 /* Return value is rt. */
27690 gen_mipsdsp_arith(ctx
, op1
, op2
, rt
, rs
, rd
);
27692 case OPC_PRECR_OB_QH
:
27693 case OPC_PRECRQ_OB_QH
:
27694 case OPC_PRECRQ_PW_L
:
27695 case OPC_PRECRQ_QH_PW
:
27696 case OPC_PRECRQ_RS_QH_PW
:
27697 case OPC_PRECRQU_S_OB_QH
:
27698 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
27700 case OPC_CMPU_EQ_OB
:
27701 case OPC_CMPU_LT_OB
:
27702 case OPC_CMPU_LE_OB
:
27703 case OPC_CMP_EQ_QH
:
27704 case OPC_CMP_LT_QH
:
27705 case OPC_CMP_LE_QH
:
27706 case OPC_CMP_EQ_PW
:
27707 case OPC_CMP_LT_PW
:
27708 case OPC_CMP_LE_PW
:
27709 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
27711 case OPC_CMPGDU_EQ_OB
:
27712 case OPC_CMPGDU_LT_OB
:
27713 case OPC_CMPGDU_LE_OB
:
27714 case OPC_CMPGU_EQ_OB
:
27715 case OPC_CMPGU_LT_OB
:
27716 case OPC_CMPGU_LE_OB
:
27717 case OPC_PACKRL_PW
:
27721 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
27723 default: /* Invalid */
27724 MIPS_INVAL("MASK CMPU_EQ.OB");
27725 gen_reserved_instruction(ctx
);
27729 case OPC_DAPPEND_DSP
:
27730 gen_mipsdsp_append(env
, ctx
, op1
, rt
, rs
, rd
);
27732 case OPC_DEXTR_W_DSP
:
27733 op2
= MASK_DEXTR_W(ctx
->opcode
);
27740 case OPC_DEXTR_R_L
:
27741 case OPC_DEXTR_RS_L
:
27743 case OPC_DEXTR_R_W
:
27744 case OPC_DEXTR_RS_W
:
27745 case OPC_DEXTR_S_H
:
27747 case OPC_DEXTRV_R_L
:
27748 case OPC_DEXTRV_RS_L
:
27749 case OPC_DEXTRV_S_H
:
27751 case OPC_DEXTRV_R_W
:
27752 case OPC_DEXTRV_RS_W
:
27753 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rt
, rs
, rd
, 1);
27758 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
27760 default: /* Invalid */
27761 MIPS_INVAL("MASK EXTR.W");
27762 gen_reserved_instruction(ctx
);
27766 case OPC_DPAQ_W_QH_DSP
:
27767 op2
= MASK_DPAQ_W_QH(ctx
->opcode
);
27769 case OPC_DPAU_H_OBL
:
27770 case OPC_DPAU_H_OBR
:
27771 case OPC_DPSU_H_OBL
:
27772 case OPC_DPSU_H_OBR
:
27774 case OPC_DPAQ_S_W_QH
:
27776 case OPC_DPSQ_S_W_QH
:
27777 case OPC_MULSAQ_S_W_QH
:
27778 case OPC_DPAQ_SA_L_PW
:
27779 case OPC_DPSQ_SA_L_PW
:
27780 case OPC_MULSAQ_S_L_PW
:
27781 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
27783 case OPC_MAQ_S_W_QHLL
:
27784 case OPC_MAQ_S_W_QHLR
:
27785 case OPC_MAQ_S_W_QHRL
:
27786 case OPC_MAQ_S_W_QHRR
:
27787 case OPC_MAQ_SA_W_QHLL
:
27788 case OPC_MAQ_SA_W_QHLR
:
27789 case OPC_MAQ_SA_W_QHRL
:
27790 case OPC_MAQ_SA_W_QHRR
:
27791 case OPC_MAQ_S_L_PWL
:
27792 case OPC_MAQ_S_L_PWR
:
27797 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
27799 default: /* Invalid */
27800 MIPS_INVAL("MASK DPAQ.W.QH");
27801 gen_reserved_instruction(ctx
);
27805 case OPC_DINSV_DSP
:
27806 op2
= MASK_INSV(ctx
->opcode
);
27817 t0
= tcg_temp_new();
27818 t1
= tcg_temp_new();
27820 gen_load_gpr(t0
, rt
);
27821 gen_load_gpr(t1
, rs
);
27823 gen_helper_dinsv(cpu_gpr
[rt
], cpu_env
, t1
, t0
);
27829 default: /* Invalid */
27830 MIPS_INVAL("MASK DINSV");
27831 gen_reserved_instruction(ctx
);
27835 case OPC_SHLL_OB_DSP
:
27836 gen_mipsdsp_shift(ctx
, op1
, rd
, rs
, rt
);
27839 default: /* Invalid */
27840 MIPS_INVAL("special3_legacy");
27841 gen_reserved_instruction(ctx
);
27847 #if defined(TARGET_MIPS64)
27849 static void decode_mmi0(CPUMIPSState
*env
, DisasContext
*ctx
)
27851 uint32_t opc
= MASK_MMI0(ctx
->opcode
);
27854 case MMI_OPC_0_PADDW
: /* TODO: MMI_OPC_0_PADDW */
27855 case MMI_OPC_0_PSUBW
: /* TODO: MMI_OPC_0_PSUBW */
27856 case MMI_OPC_0_PCGTW
: /* TODO: MMI_OPC_0_PCGTW */
27857 case MMI_OPC_0_PMAXW
: /* TODO: MMI_OPC_0_PMAXW */
27858 case MMI_OPC_0_PADDH
: /* TODO: MMI_OPC_0_PADDH */
27859 case MMI_OPC_0_PSUBH
: /* TODO: MMI_OPC_0_PSUBH */
27860 case MMI_OPC_0_PCGTH
: /* TODO: MMI_OPC_0_PCGTH */
27861 case MMI_OPC_0_PMAXH
: /* TODO: MMI_OPC_0_PMAXH */
27862 case MMI_OPC_0_PADDB
: /* TODO: MMI_OPC_0_PADDB */
27863 case MMI_OPC_0_PSUBB
: /* TODO: MMI_OPC_0_PSUBB */
27864 case MMI_OPC_0_PCGTB
: /* TODO: MMI_OPC_0_PCGTB */
27865 case MMI_OPC_0_PADDSW
: /* TODO: MMI_OPC_0_PADDSW */
27866 case MMI_OPC_0_PSUBSW
: /* TODO: MMI_OPC_0_PSUBSW */
27867 case MMI_OPC_0_PEXTLW
: /* TODO: MMI_OPC_0_PEXTLW */
27868 case MMI_OPC_0_PPACW
: /* TODO: MMI_OPC_0_PPACW */
27869 case MMI_OPC_0_PADDSH
: /* TODO: MMI_OPC_0_PADDSH */
27870 case MMI_OPC_0_PSUBSH
: /* TODO: MMI_OPC_0_PSUBSH */
27871 case MMI_OPC_0_PEXTLH
: /* TODO: MMI_OPC_0_PEXTLH */
27872 case MMI_OPC_0_PPACH
: /* TODO: MMI_OPC_0_PPACH */
27873 case MMI_OPC_0_PADDSB
: /* TODO: MMI_OPC_0_PADDSB */
27874 case MMI_OPC_0_PSUBSB
: /* TODO: MMI_OPC_0_PSUBSB */
27875 case MMI_OPC_0_PEXTLB
: /* TODO: MMI_OPC_0_PEXTLB */
27876 case MMI_OPC_0_PPACB
: /* TODO: MMI_OPC_0_PPACB */
27877 case MMI_OPC_0_PEXT5
: /* TODO: MMI_OPC_0_PEXT5 */
27878 case MMI_OPC_0_PPAC5
: /* TODO: MMI_OPC_0_PPAC5 */
27879 gen_reserved_instruction(ctx
); /* TODO: MMI_OPC_CLASS_MMI0 */
27882 MIPS_INVAL("TX79 MMI class MMI0");
27883 gen_reserved_instruction(ctx
);
27888 static void decode_mmi1(CPUMIPSState
*env
, DisasContext
*ctx
)
27890 uint32_t opc
= MASK_MMI1(ctx
->opcode
);
27893 case MMI_OPC_1_PABSW
: /* TODO: MMI_OPC_1_PABSW */
27894 case MMI_OPC_1_PCEQW
: /* TODO: MMI_OPC_1_PCEQW */
27895 case MMI_OPC_1_PMINW
: /* TODO: MMI_OPC_1_PMINW */
27896 case MMI_OPC_1_PADSBH
: /* TODO: MMI_OPC_1_PADSBH */
27897 case MMI_OPC_1_PABSH
: /* TODO: MMI_OPC_1_PABSH */
27898 case MMI_OPC_1_PCEQH
: /* TODO: MMI_OPC_1_PCEQH */
27899 case MMI_OPC_1_PMINH
: /* TODO: MMI_OPC_1_PMINH */
27900 case MMI_OPC_1_PCEQB
: /* TODO: MMI_OPC_1_PCEQB */
27901 case MMI_OPC_1_PADDUW
: /* TODO: MMI_OPC_1_PADDUW */
27902 case MMI_OPC_1_PSUBUW
: /* TODO: MMI_OPC_1_PSUBUW */
27903 case MMI_OPC_1_PEXTUW
: /* TODO: MMI_OPC_1_PEXTUW */
27904 case MMI_OPC_1_PADDUH
: /* TODO: MMI_OPC_1_PADDUH */
27905 case MMI_OPC_1_PSUBUH
: /* TODO: MMI_OPC_1_PSUBUH */
27906 case MMI_OPC_1_PEXTUH
: /* TODO: MMI_OPC_1_PEXTUH */
27907 case MMI_OPC_1_PADDUB
: /* TODO: MMI_OPC_1_PADDUB */
27908 case MMI_OPC_1_PSUBUB
: /* TODO: MMI_OPC_1_PSUBUB */
27909 case MMI_OPC_1_PEXTUB
: /* TODO: MMI_OPC_1_PEXTUB */
27910 case MMI_OPC_1_QFSRV
: /* TODO: MMI_OPC_1_QFSRV */
27911 gen_reserved_instruction(ctx
); /* TODO: MMI_OPC_CLASS_MMI1 */
27914 MIPS_INVAL("TX79 MMI class MMI1");
27915 gen_reserved_instruction(ctx
);
27920 static void decode_mmi2(CPUMIPSState
*env
, DisasContext
*ctx
)
27922 uint32_t opc
= MASK_MMI2(ctx
->opcode
);
27925 case MMI_OPC_2_PMADDW
: /* TODO: MMI_OPC_2_PMADDW */
27926 case MMI_OPC_2_PSLLVW
: /* TODO: MMI_OPC_2_PSLLVW */
27927 case MMI_OPC_2_PSRLVW
: /* TODO: MMI_OPC_2_PSRLVW */
27928 case MMI_OPC_2_PMSUBW
: /* TODO: MMI_OPC_2_PMSUBW */
27929 case MMI_OPC_2_PMFHI
: /* TODO: MMI_OPC_2_PMFHI */
27930 case MMI_OPC_2_PMFLO
: /* TODO: MMI_OPC_2_PMFLO */
27931 case MMI_OPC_2_PINTH
: /* TODO: MMI_OPC_2_PINTH */
27932 case MMI_OPC_2_PMULTW
: /* TODO: MMI_OPC_2_PMULTW */
27933 case MMI_OPC_2_PDIVW
: /* TODO: MMI_OPC_2_PDIVW */
27934 case MMI_OPC_2_PMADDH
: /* TODO: MMI_OPC_2_PMADDH */
27935 case MMI_OPC_2_PHMADH
: /* TODO: MMI_OPC_2_PHMADH */
27936 case MMI_OPC_2_PAND
: /* TODO: MMI_OPC_2_PAND */
27937 case MMI_OPC_2_PXOR
: /* TODO: MMI_OPC_2_PXOR */
27938 case MMI_OPC_2_PMSUBH
: /* TODO: MMI_OPC_2_PMSUBH */
27939 case MMI_OPC_2_PHMSBH
: /* TODO: MMI_OPC_2_PHMSBH */
27940 case MMI_OPC_2_PEXEH
: /* TODO: MMI_OPC_2_PEXEH */
27941 case MMI_OPC_2_PREVH
: /* TODO: MMI_OPC_2_PREVH */
27942 case MMI_OPC_2_PMULTH
: /* TODO: MMI_OPC_2_PMULTH */
27943 case MMI_OPC_2_PDIVBW
: /* TODO: MMI_OPC_2_PDIVBW */
27944 case MMI_OPC_2_PEXEW
: /* TODO: MMI_OPC_2_PEXEW */
27945 case MMI_OPC_2_PROT3W
: /* TODO: MMI_OPC_2_PROT3W */
27946 gen_reserved_instruction(ctx
); /* TODO: MMI_OPC_CLASS_MMI2 */
27948 case MMI_OPC_2_PCPYLD
:
27949 gen_mmi_pcpyld(ctx
);
27952 MIPS_INVAL("TX79 MMI class MMI2");
27953 gen_reserved_instruction(ctx
);
27958 static void decode_mmi3(CPUMIPSState
*env
, DisasContext
*ctx
)
27960 uint32_t opc
= MASK_MMI3(ctx
->opcode
);
27963 case MMI_OPC_3_PMADDUW
: /* TODO: MMI_OPC_3_PMADDUW */
27964 case MMI_OPC_3_PSRAVW
: /* TODO: MMI_OPC_3_PSRAVW */
27965 case MMI_OPC_3_PMTHI
: /* TODO: MMI_OPC_3_PMTHI */
27966 case MMI_OPC_3_PMTLO
: /* TODO: MMI_OPC_3_PMTLO */
27967 case MMI_OPC_3_PINTEH
: /* TODO: MMI_OPC_3_PINTEH */
27968 case MMI_OPC_3_PMULTUW
: /* TODO: MMI_OPC_3_PMULTUW */
27969 case MMI_OPC_3_PDIVUW
: /* TODO: MMI_OPC_3_PDIVUW */
27970 case MMI_OPC_3_POR
: /* TODO: MMI_OPC_3_POR */
27971 case MMI_OPC_3_PNOR
: /* TODO: MMI_OPC_3_PNOR */
27972 case MMI_OPC_3_PEXCH
: /* TODO: MMI_OPC_3_PEXCH */
27973 case MMI_OPC_3_PEXCW
: /* TODO: MMI_OPC_3_PEXCW */
27974 gen_reserved_instruction(ctx
); /* TODO: MMI_OPC_CLASS_MMI3 */
27976 case MMI_OPC_3_PCPYH
:
27977 gen_mmi_pcpyh(ctx
);
27979 case MMI_OPC_3_PCPYUD
:
27980 gen_mmi_pcpyud(ctx
);
27983 MIPS_INVAL("TX79 MMI class MMI3");
27984 gen_reserved_instruction(ctx
);
27989 static void decode_mmi(CPUMIPSState
*env
, DisasContext
*ctx
)
27991 uint32_t opc
= MASK_MMI(ctx
->opcode
);
27992 int rs
= extract32(ctx
->opcode
, 21, 5);
27993 int rt
= extract32(ctx
->opcode
, 16, 5);
27994 int rd
= extract32(ctx
->opcode
, 11, 5);
27997 case MMI_OPC_CLASS_MMI0
:
27998 decode_mmi0(env
, ctx
);
28000 case MMI_OPC_CLASS_MMI1
:
28001 decode_mmi1(env
, ctx
);
28003 case MMI_OPC_CLASS_MMI2
:
28004 decode_mmi2(env
, ctx
);
28006 case MMI_OPC_CLASS_MMI3
:
28007 decode_mmi3(env
, ctx
);
28009 case MMI_OPC_MULT1
:
28010 case MMI_OPC_MULTU1
:
28012 case MMI_OPC_MADDU
:
28013 case MMI_OPC_MADD1
:
28014 case MMI_OPC_MADDU1
:
28015 gen_mul_txx9(ctx
, opc
, rd
, rs
, rt
);
28018 case MMI_OPC_DIVU1
:
28019 gen_div1_tx79(ctx
, opc
, rs
, rt
);
28021 case MMI_OPC_MTLO1
:
28022 case MMI_OPC_MTHI1
:
28023 gen_HILO1_tx79(ctx
, opc
, rs
);
28025 case MMI_OPC_MFLO1
:
28026 case MMI_OPC_MFHI1
:
28027 gen_HILO1_tx79(ctx
, opc
, rd
);
28029 case MMI_OPC_PLZCW
: /* TODO: MMI_OPC_PLZCW */
28030 case MMI_OPC_PMFHL
: /* TODO: MMI_OPC_PMFHL */
28031 case MMI_OPC_PMTHL
: /* TODO: MMI_OPC_PMTHL */
28032 case MMI_OPC_PSLLH
: /* TODO: MMI_OPC_PSLLH */
28033 case MMI_OPC_PSRLH
: /* TODO: MMI_OPC_PSRLH */
28034 case MMI_OPC_PSRAH
: /* TODO: MMI_OPC_PSRAH */
28035 case MMI_OPC_PSLLW
: /* TODO: MMI_OPC_PSLLW */
28036 case MMI_OPC_PSRLW
: /* TODO: MMI_OPC_PSRLW */
28037 case MMI_OPC_PSRAW
: /* TODO: MMI_OPC_PSRAW */
28038 gen_reserved_instruction(ctx
); /* TODO: MMI_OPC_CLASS_MMI */
28041 MIPS_INVAL("TX79 MMI class");
28042 gen_reserved_instruction(ctx
);
28047 static void gen_mmi_lq(CPUMIPSState
*env
, DisasContext
*ctx
)
28049 gen_reserved_instruction(ctx
); /* TODO: MMI_OPC_LQ */
28052 static void gen_mmi_sq(DisasContext
*ctx
, int base
, int rt
, int offset
)
28054 gen_reserved_instruction(ctx
); /* TODO: MMI_OPC_SQ */
28058 * The TX79-specific instruction Store Quadword
28060 * +--------+-------+-------+------------------------+
28061 * | 011111 | base | rt | offset | SQ
28062 * +--------+-------+-------+------------------------+
28065 * has the same opcode as the Read Hardware Register instruction
28067 * +--------+-------+-------+-------+-------+--------+
28068 * | 011111 | 00000 | rt | rd | 00000 | 111011 | RDHWR
28069 * +--------+-------+-------+-------+-------+--------+
28072 * that is required, trapped and emulated by the Linux kernel. However, all
28073 * RDHWR encodings yield address error exceptions on the TX79 since the SQ
28074 * offset is odd. Therefore all valid SQ instructions can execute normally.
28075 * In user mode, QEMU must verify the upper and lower 11 bits to distinguish
28076 * between SQ and RDHWR, as the Linux kernel does.
28078 static void decode_mmi_sq(CPUMIPSState
*env
, DisasContext
*ctx
)
28080 int base
= extract32(ctx
->opcode
, 21, 5);
28081 int rt
= extract32(ctx
->opcode
, 16, 5);
28082 int offset
= extract32(ctx
->opcode
, 0, 16);
28084 #ifdef CONFIG_USER_ONLY
28085 uint32_t op1
= MASK_SPECIAL3(ctx
->opcode
);
28086 uint32_t op2
= extract32(ctx
->opcode
, 6, 5);
28088 if (base
== 0 && op2
== 0 && op1
== OPC_RDHWR
) {
28089 int rd
= extract32(ctx
->opcode
, 11, 5);
28091 gen_rdhwr(ctx
, rt
, rd
, 0);
28096 gen_mmi_sq(ctx
, base
, rt
, offset
);
28101 static void decode_opc_special3(CPUMIPSState
*env
, DisasContext
*ctx
)
28103 int rs
, rt
, rd
, sa
;
28107 rs
= (ctx
->opcode
>> 21) & 0x1f;
28108 rt
= (ctx
->opcode
>> 16) & 0x1f;
28109 rd
= (ctx
->opcode
>> 11) & 0x1f;
28110 sa
= (ctx
->opcode
>> 6) & 0x1f;
28111 imm
= sextract32(ctx
->opcode
, 7, 9);
28113 op1
= MASK_SPECIAL3(ctx
->opcode
);
28116 * EVA loads and stores overlap Loongson 2E instructions decoded by
28117 * decode_opc_special3_legacy(), so be careful to allow their decoding when
28130 check_cp0_enabled(ctx
);
28131 gen_ld(ctx
, op1
, rt
, rs
, imm
);
28138 check_cp0_enabled(ctx
);
28139 gen_st(ctx
, op1
, rt
, rs
, imm
);
28142 check_cp0_enabled(ctx
);
28143 gen_st_cond(ctx
, rt
, rs
, imm
, MO_TESL
, true);
28146 check_cp0_enabled(ctx
);
28147 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
28148 gen_cache_operation(ctx
, rt
, rs
, imm
);
28150 /* Treat as NOP. */
28153 check_cp0_enabled(ctx
);
28154 /* Treat as NOP. */
28162 check_insn(ctx
, ISA_MIPS_R2
);
28163 gen_bitops(ctx
, op1
, rt
, rs
, sa
, rd
);
28166 op2
= MASK_BSHFL(ctx
->opcode
);
28173 check_insn(ctx
, ISA_MIPS_R6
);
28174 decode_opc_special3_r6(env
, ctx
);
28177 check_insn(ctx
, ISA_MIPS_R2
);
28178 gen_bshfl(ctx
, op2
, rt
, rd
);
28182 #if defined(TARGET_MIPS64)
28189 check_insn(ctx
, ISA_MIPS_R2
);
28190 check_mips_64(ctx
);
28191 gen_bitops(ctx
, op1
, rt
, rs
, sa
, rd
);
28194 op2
= MASK_DBSHFL(ctx
->opcode
);
28205 check_insn(ctx
, ISA_MIPS_R6
);
28206 decode_opc_special3_r6(env
, ctx
);
28209 check_insn(ctx
, ISA_MIPS_R2
);
28210 check_mips_64(ctx
);
28211 op2
= MASK_DBSHFL(ctx
->opcode
);
28212 gen_bshfl(ctx
, op2
, rt
, rd
);
28218 gen_rdhwr(ctx
, rt
, rd
, extract32(ctx
->opcode
, 6, 3));
28223 TCGv t0
= tcg_temp_new();
28224 TCGv t1
= tcg_temp_new();
28226 gen_load_gpr(t0
, rt
);
28227 gen_load_gpr(t1
, rs
);
28228 gen_helper_fork(t0
, t1
);
28236 TCGv t0
= tcg_temp_new();
28238 gen_load_gpr(t0
, rs
);
28239 gen_helper_yield(t0
, cpu_env
, t0
);
28240 gen_store_gpr(t0
, rd
);
28245 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
28246 decode_opc_special3_r6(env
, ctx
);
28248 decode_opc_special3_legacy(env
, ctx
);
28253 static bool decode_opc_legacy(CPUMIPSState
*env
, DisasContext
*ctx
)
28256 int rs
, rt
, rd
, sa
;
28260 op
= MASK_OP_MAJOR(ctx
->opcode
);
28261 rs
= (ctx
->opcode
>> 21) & 0x1f;
28262 rt
= (ctx
->opcode
>> 16) & 0x1f;
28263 rd
= (ctx
->opcode
>> 11) & 0x1f;
28264 sa
= (ctx
->opcode
>> 6) & 0x1f;
28265 imm
= (int16_t)ctx
->opcode
;
28268 decode_opc_special(env
, ctx
);
28271 #if defined(TARGET_MIPS64)
28272 if ((ctx
->insn_flags
& INSN_R5900
) && (ctx
->insn_flags
& ASE_MMI
)) {
28273 decode_mmi(env
, ctx
);
28275 if (ctx
->insn_flags
& ASE_MXU
) {
28276 decode_opc_mxu(env
, ctx
);
28279 decode_opc_special2_legacy(env
, ctx
);
28283 #if defined(TARGET_MIPS64)
28284 if (ctx
->insn_flags
& INSN_R5900
) {
28285 decode_mmi_sq(env
, ctx
); /* MMI_OPC_SQ */
28287 decode_opc_special3(env
, ctx
);
28290 decode_opc_special3(env
, ctx
);
28294 op1
= MASK_REGIMM(ctx
->opcode
);
28296 case OPC_BLTZL
: /* REGIMM branches */
28300 check_insn(ctx
, ISA_MIPS2
);
28301 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
28305 gen_compute_branch(ctx
, op1
, 4, rs
, -1, imm
<< 2, 4);
28309 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
28311 /* OPC_NAL, OPC_BAL */
28312 gen_compute_branch(ctx
, op1
, 4, 0, -1, imm
<< 2, 4);
28314 gen_reserved_instruction(ctx
);
28317 gen_compute_branch(ctx
, op1
, 4, rs
, -1, imm
<< 2, 4);
28320 case OPC_TGEI
: /* REGIMM traps */
28327 check_insn(ctx
, ISA_MIPS2
);
28328 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
28329 gen_trap(ctx
, op1
, rs
, -1, imm
);
28332 check_insn(ctx
, ISA_MIPS_R6
);
28333 gen_reserved_instruction(ctx
);
28336 check_insn(ctx
, ISA_MIPS_R2
);
28338 * Break the TB to be able to sync copied instructions
28341 ctx
->base
.is_jmp
= DISAS_STOP
;
28343 case OPC_BPOSGE32
: /* MIPS DSP branch */
28344 #if defined(TARGET_MIPS64)
28348 gen_compute_branch(ctx
, op1
, 4, -1, -2, (int32_t)imm
<< 2, 4);
28350 #if defined(TARGET_MIPS64)
28352 check_insn(ctx
, ISA_MIPS_R6
);
28353 check_mips_64(ctx
);
28355 tcg_gen_addi_tl(cpu_gpr
[rs
], cpu_gpr
[rs
], (int64_t)imm
<< 32);
28359 check_insn(ctx
, ISA_MIPS_R6
);
28360 check_mips_64(ctx
);
28362 tcg_gen_addi_tl(cpu_gpr
[rs
], cpu_gpr
[rs
], (int64_t)imm
<< 48);
28366 default: /* Invalid */
28367 MIPS_INVAL("regimm");
28368 gen_reserved_instruction(ctx
);
28373 check_cp0_enabled(ctx
);
28374 op1
= MASK_CP0(ctx
->opcode
);
28382 #if defined(TARGET_MIPS64)
28386 #ifndef CONFIG_USER_ONLY
28387 gen_cp0(env
, ctx
, op1
, rt
, rd
);
28388 #endif /* !CONFIG_USER_ONLY */
28406 #ifndef CONFIG_USER_ONLY
28407 gen_cp0(env
, ctx
, MASK_C0(ctx
->opcode
), rt
, rd
);
28408 #endif /* !CONFIG_USER_ONLY */
28411 #ifndef CONFIG_USER_ONLY
28414 TCGv t0
= tcg_temp_new();
28416 op2
= MASK_MFMC0(ctx
->opcode
);
28420 gen_helper_dmt(t0
);
28421 gen_store_gpr(t0
, rt
);
28425 gen_helper_emt(t0
);
28426 gen_store_gpr(t0
, rt
);
28430 gen_helper_dvpe(t0
, cpu_env
);
28431 gen_store_gpr(t0
, rt
);
28435 gen_helper_evpe(t0
, cpu_env
);
28436 gen_store_gpr(t0
, rt
);
28439 check_insn(ctx
, ISA_MIPS_R6
);
28441 gen_helper_dvp(t0
, cpu_env
);
28442 gen_store_gpr(t0
, rt
);
28446 check_insn(ctx
, ISA_MIPS_R6
);
28448 gen_helper_evp(t0
, cpu_env
);
28449 gen_store_gpr(t0
, rt
);
28453 check_insn(ctx
, ISA_MIPS_R2
);
28454 save_cpu_state(ctx
, 1);
28455 gen_helper_di(t0
, cpu_env
);
28456 gen_store_gpr(t0
, rt
);
28458 * Stop translation as we may have switched
28459 * the execution mode.
28461 ctx
->base
.is_jmp
= DISAS_STOP
;
28464 check_insn(ctx
, ISA_MIPS_R2
);
28465 save_cpu_state(ctx
, 1);
28466 gen_helper_ei(t0
, cpu_env
);
28467 gen_store_gpr(t0
, rt
);
28469 * DISAS_STOP isn't sufficient, we need to ensure we break
28470 * out of translated code to check for pending interrupts.
28472 gen_save_pc(ctx
->base
.pc_next
+ 4);
28473 ctx
->base
.is_jmp
= DISAS_EXIT
;
28475 default: /* Invalid */
28476 MIPS_INVAL("mfmc0");
28477 gen_reserved_instruction(ctx
);
28482 #endif /* !CONFIG_USER_ONLY */
28485 check_insn(ctx
, ISA_MIPS_R2
);
28486 gen_load_srsgpr(rt
, rd
);
28489 check_insn(ctx
, ISA_MIPS_R2
);
28490 gen_store_srsgpr(rt
, rd
);
28494 gen_reserved_instruction(ctx
);
28498 case OPC_BOVC
: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */
28499 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
28500 /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */
28501 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
28504 /* Arithmetic with immediate opcode */
28505 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
28509 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
28511 case OPC_SLTI
: /* Set on less than with immediate opcode */
28513 gen_slt_imm(ctx
, op
, rt
, rs
, imm
);
28515 case OPC_ANDI
: /* Arithmetic with immediate opcode */
28516 case OPC_LUI
: /* OPC_AUI */
28519 gen_logic_imm(ctx
, op
, rt
, rs
, imm
);
28521 case OPC_J
: /* Jump */
28523 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
28524 gen_compute_branch(ctx
, op
, 4, rs
, rt
, offset
, 4);
28527 case OPC_BLEZC
: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */
28528 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
28530 gen_reserved_instruction(ctx
);
28533 /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */
28534 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
28537 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
28540 case OPC_BGTZC
: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */
28541 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
28543 gen_reserved_instruction(ctx
);
28546 /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */
28547 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
28550 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
28553 case OPC_BLEZALC
: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */
28556 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
28558 check_insn(ctx
, ISA_MIPS_R6
);
28559 /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */
28560 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
28563 case OPC_BGTZALC
: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */
28566 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
28568 check_insn(ctx
, ISA_MIPS_R6
);
28569 /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */
28570 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
28575 check_insn(ctx
, ISA_MIPS2
);
28576 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
28580 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
28582 case OPC_LL
: /* Load and stores */
28583 check_insn(ctx
, ISA_MIPS2
);
28584 if (ctx
->insn_flags
& INSN_R5900
) {
28585 check_insn_opc_user_only(ctx
, INSN_R5900
);
28596 gen_ld(ctx
, op
, rt
, rs
, imm
);
28603 gen_st(ctx
, op
, rt
, rs
, imm
);
28606 check_insn(ctx
, ISA_MIPS2
);
28607 if (ctx
->insn_flags
& INSN_R5900
) {
28608 check_insn_opc_user_only(ctx
, INSN_R5900
);
28610 gen_st_cond(ctx
, rt
, rs
, imm
, MO_TESL
, false);
28613 check_cp0_enabled(ctx
);
28614 check_insn(ctx
, ISA_MIPS3
| ISA_MIPS_R1
);
28615 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
28616 gen_cache_operation(ctx
, rt
, rs
, imm
);
28618 /* Treat as NOP. */
28621 if (ctx
->insn_flags
& INSN_R5900
) {
28622 /* Treat as NOP. */
28624 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS_R1
);
28625 /* Treat as NOP. */
28629 /* Floating point (COP1). */
28634 gen_cop1_ldst(ctx
, op
, rt
, rs
, imm
);
28638 op1
= MASK_CP1(ctx
->opcode
);
28643 check_cp1_enabled(ctx
);
28644 check_insn(ctx
, ISA_MIPS_R2
);
28650 check_cp1_enabled(ctx
);
28651 gen_cp1(ctx
, op1
, rt
, rd
);
28653 #if defined(TARGET_MIPS64)
28656 check_cp1_enabled(ctx
);
28657 check_insn(ctx
, ISA_MIPS3
);
28658 check_mips_64(ctx
);
28659 gen_cp1(ctx
, op1
, rt
, rd
);
28662 case OPC_BC1EQZ
: /* OPC_BC1ANY2 */
28663 check_cp1_enabled(ctx
);
28664 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
28666 gen_compute_branch1_r6(ctx
, MASK_CP1(ctx
->opcode
),
28671 check_insn(ctx
, ASE_MIPS3D
);
28672 gen_compute_branch1(ctx
, MASK_BC1(ctx
->opcode
),
28673 (rt
>> 2) & 0x7, imm
<< 2);
28677 check_cp1_enabled(ctx
);
28678 check_insn(ctx
, ISA_MIPS_R6
);
28679 gen_compute_branch1_r6(ctx
, MASK_CP1(ctx
->opcode
),
28683 check_cp1_enabled(ctx
);
28684 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
28686 check_insn(ctx
, ASE_MIPS3D
);
28689 check_cp1_enabled(ctx
);
28690 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
28691 gen_compute_branch1(ctx
, MASK_BC1(ctx
->opcode
),
28692 (rt
>> 2) & 0x7, imm
<< 2);
28699 check_cp1_enabled(ctx
);
28700 gen_farith(ctx
, ctx
->opcode
& FOP(0x3f, 0x1f), rt
, rd
, sa
,
28706 int r6_op
= ctx
->opcode
& FOP(0x3f, 0x1f);
28707 check_cp1_enabled(ctx
);
28708 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
28710 case R6_OPC_CMP_AF_S
:
28711 case R6_OPC_CMP_UN_S
:
28712 case R6_OPC_CMP_EQ_S
:
28713 case R6_OPC_CMP_UEQ_S
:
28714 case R6_OPC_CMP_LT_S
:
28715 case R6_OPC_CMP_ULT_S
:
28716 case R6_OPC_CMP_LE_S
:
28717 case R6_OPC_CMP_ULE_S
:
28718 case R6_OPC_CMP_SAF_S
:
28719 case R6_OPC_CMP_SUN_S
:
28720 case R6_OPC_CMP_SEQ_S
:
28721 case R6_OPC_CMP_SEUQ_S
:
28722 case R6_OPC_CMP_SLT_S
:
28723 case R6_OPC_CMP_SULT_S
:
28724 case R6_OPC_CMP_SLE_S
:
28725 case R6_OPC_CMP_SULE_S
:
28726 case R6_OPC_CMP_OR_S
:
28727 case R6_OPC_CMP_UNE_S
:
28728 case R6_OPC_CMP_NE_S
:
28729 case R6_OPC_CMP_SOR_S
:
28730 case R6_OPC_CMP_SUNE_S
:
28731 case R6_OPC_CMP_SNE_S
:
28732 gen_r6_cmp_s(ctx
, ctx
->opcode
& 0x1f, rt
, rd
, sa
);
28734 case R6_OPC_CMP_AF_D
:
28735 case R6_OPC_CMP_UN_D
:
28736 case R6_OPC_CMP_EQ_D
:
28737 case R6_OPC_CMP_UEQ_D
:
28738 case R6_OPC_CMP_LT_D
:
28739 case R6_OPC_CMP_ULT_D
:
28740 case R6_OPC_CMP_LE_D
:
28741 case R6_OPC_CMP_ULE_D
:
28742 case R6_OPC_CMP_SAF_D
:
28743 case R6_OPC_CMP_SUN_D
:
28744 case R6_OPC_CMP_SEQ_D
:
28745 case R6_OPC_CMP_SEUQ_D
:
28746 case R6_OPC_CMP_SLT_D
:
28747 case R6_OPC_CMP_SULT_D
:
28748 case R6_OPC_CMP_SLE_D
:
28749 case R6_OPC_CMP_SULE_D
:
28750 case R6_OPC_CMP_OR_D
:
28751 case R6_OPC_CMP_UNE_D
:
28752 case R6_OPC_CMP_NE_D
:
28753 case R6_OPC_CMP_SOR_D
:
28754 case R6_OPC_CMP_SUNE_D
:
28755 case R6_OPC_CMP_SNE_D
:
28756 gen_r6_cmp_d(ctx
, ctx
->opcode
& 0x1f, rt
, rd
, sa
);
28759 gen_farith(ctx
, ctx
->opcode
& FOP(0x3f, 0x1f),
28760 rt
, rd
, sa
, (imm
>> 8) & 0x7);
28765 gen_farith(ctx
, ctx
->opcode
& FOP(0x3f, 0x1f), rt
, rd
, sa
,
28772 gen_reserved_instruction(ctx
);
28777 /* Compact branches [R6] and COP2 [non-R6] */
28778 case OPC_BC
: /* OPC_LWC2 */
28779 case OPC_BALC
: /* OPC_SWC2 */
28780 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
28781 /* OPC_BC, OPC_BALC */
28782 gen_compute_compact_branch(ctx
, op
, 0, 0,
28783 sextract32(ctx
->opcode
<< 2, 0, 28));
28784 } else if (ctx
->insn_flags
& ASE_LEXT
) {
28785 gen_loongson_lswc2(ctx
, rt
, rs
, rd
);
28787 /* OPC_LWC2, OPC_SWC2 */
28788 /* COP2: Not implemented. */
28789 generate_exception_err(ctx
, EXCP_CpU
, 2);
28792 case OPC_BEQZC
: /* OPC_JIC, OPC_LDC2 */
28793 case OPC_BNEZC
: /* OPC_JIALC, OPC_SDC2 */
28794 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
28796 /* OPC_BEQZC, OPC_BNEZC */
28797 gen_compute_compact_branch(ctx
, op
, rs
, 0,
28798 sextract32(ctx
->opcode
<< 2, 0, 23));
28800 /* OPC_JIC, OPC_JIALC */
28801 gen_compute_compact_branch(ctx
, op
, 0, rt
, imm
);
28803 } else if (ctx
->insn_flags
& ASE_LEXT
) {
28804 gen_loongson_lsdc2(ctx
, rt
, rs
, rd
);
28806 /* OPC_LWC2, OPC_SWC2 */
28807 /* COP2: Not implemented. */
28808 generate_exception_err(ctx
, EXCP_CpU
, 2);
28812 check_insn(ctx
, ASE_LMMI
);
28813 /* Note that these instructions use different fields. */
28814 gen_loongson_multimedia(ctx
, sa
, rd
, rt
);
28818 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
28819 check_cp1_enabled(ctx
);
28820 op1
= MASK_CP3(ctx
->opcode
);
28824 check_insn(ctx
, ISA_MIPS5
| ISA_MIPS_R2
);
28830 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS_R2
);
28831 gen_flt3_ldst(ctx
, op1
, sa
, rd
, rs
, rt
);
28834 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS_R2
);
28835 /* Treat as NOP. */
28838 check_insn(ctx
, ISA_MIPS5
| ISA_MIPS_R2
);
28852 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS_R2
);
28853 gen_flt3_arith(ctx
, op1
, sa
, rs
, rd
, rt
);
28857 gen_reserved_instruction(ctx
);
28861 generate_exception_err(ctx
, EXCP_CpU
, 1);
28865 #if defined(TARGET_MIPS64)
28866 /* MIPS64 opcodes */
28868 if (ctx
->insn_flags
& INSN_R5900
) {
28869 check_insn_opc_user_only(ctx
, INSN_R5900
);
28876 check_insn(ctx
, ISA_MIPS3
);
28877 check_mips_64(ctx
);
28878 gen_ld(ctx
, op
, rt
, rs
, imm
);
28883 check_insn(ctx
, ISA_MIPS3
);
28884 check_mips_64(ctx
);
28885 gen_st(ctx
, op
, rt
, rs
, imm
);
28888 check_insn(ctx
, ISA_MIPS3
);
28889 if (ctx
->insn_flags
& INSN_R5900
) {
28890 check_insn_opc_user_only(ctx
, INSN_R5900
);
28892 check_mips_64(ctx
);
28893 gen_st_cond(ctx
, rt
, rs
, imm
, MO_TEQ
, false);
28895 case OPC_BNVC
: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */
28896 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
28897 /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */
28898 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
28901 check_insn(ctx
, ISA_MIPS3
);
28902 check_mips_64(ctx
);
28903 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
28907 check_insn(ctx
, ISA_MIPS3
);
28908 check_mips_64(ctx
);
28909 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
28912 case OPC_BNVC
: /* OPC_BNEZALC, OPC_BNEC */
28913 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
28914 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
28916 MIPS_INVAL("major opcode");
28917 gen_reserved_instruction(ctx
);
28921 case OPC_DAUI
: /* OPC_JALX */
28922 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
28923 #if defined(TARGET_MIPS64)
28925 check_mips_64(ctx
);
28927 generate_exception(ctx
, EXCP_RI
);
28928 } else if (rt
!= 0) {
28929 TCGv t0
= tcg_temp_new();
28930 gen_load_gpr(t0
, rs
);
28931 tcg_gen_addi_tl(cpu_gpr
[rt
], t0
, imm
<< 16);
28935 gen_reserved_instruction(ctx
);
28936 MIPS_INVAL("major opcode");
28940 check_insn(ctx
, ASE_MIPS16
| ASE_MICROMIPS
);
28941 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
28942 gen_compute_branch(ctx
, op
, 4, rs
, rt
, offset
, 4);
28945 case OPC_MDMX
: /* MMI_OPC_LQ */
28946 if (ctx
->insn_flags
& INSN_R5900
) {
28947 #if defined(TARGET_MIPS64)
28948 gen_mmi_lq(env
, ctx
);
28951 /* MDMX: Not implemented. */
28955 check_insn(ctx
, ISA_MIPS_R6
);
28956 gen_pcrel(ctx
, ctx
->opcode
, ctx
->base
.pc_next
, rs
);
28958 default: /* Invalid */
28959 MIPS_INVAL("major opcode");
28965 static void decode_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
28967 /* make sure instructions are on a word boundary */
28968 if (ctx
->base
.pc_next
& 0x3) {
28969 env
->CP0_BadVAddr
= ctx
->base
.pc_next
;
28970 generate_exception_err(ctx
, EXCP_AdEL
, EXCP_INST_NOTAVAIL
);
28974 /* Handle blikely not taken case */
28975 if ((ctx
->hflags
& MIPS_HFLAG_BMASK_BASE
) == MIPS_HFLAG_BL
) {
28976 TCGLabel
*l1
= gen_new_label();
28978 tcg_gen_brcondi_tl(TCG_COND_NE
, bcond
, 0, l1
);
28979 tcg_gen_movi_i32(hflags
, ctx
->hflags
& ~MIPS_HFLAG_BMASK
);
28980 gen_goto_tb(ctx
, 1, ctx
->base
.pc_next
+ 4);
28984 /* Transition to the auto-generated decoder. */
28986 /* ISA extensions */
28987 if (ase_msa_available(env
) && decode_ase_msa(ctx
, ctx
->opcode
)) {
28991 /* ISA (from latest to oldest) */
28992 if (cpu_supports_isa(env
, ISA_MIPS_R6
) && decode_isa_rel6(ctx
, ctx
->opcode
)) {
28996 if (decode_opc_legacy(env
, ctx
)) {
29000 gen_reserved_instruction(ctx
);
29003 static void mips_tr_init_disas_context(DisasContextBase
*dcbase
, CPUState
*cs
)
29005 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
29006 CPUMIPSState
*env
= cs
->env_ptr
;
29008 ctx
->page_start
= ctx
->base
.pc_first
& TARGET_PAGE_MASK
;
29009 ctx
->saved_pc
= -1;
29010 ctx
->insn_flags
= env
->insn_flags
;
29011 ctx
->CP0_Config1
= env
->CP0_Config1
;
29012 ctx
->CP0_Config2
= env
->CP0_Config2
;
29013 ctx
->CP0_Config3
= env
->CP0_Config3
;
29014 ctx
->CP0_Config5
= env
->CP0_Config5
;
29016 ctx
->kscrexist
= (env
->CP0_Config4
>> CP0C4_KScrExist
) & 0xff;
29017 ctx
->rxi
= (env
->CP0_Config3
>> CP0C3_RXI
) & 1;
29018 ctx
->ie
= (env
->CP0_Config4
>> CP0C4_IE
) & 3;
29019 ctx
->bi
= (env
->CP0_Config3
>> CP0C3_BI
) & 1;
29020 ctx
->bp
= (env
->CP0_Config3
>> CP0C3_BP
) & 1;
29021 ctx
->PAMask
= env
->PAMask
;
29022 ctx
->mvh
= (env
->CP0_Config5
>> CP0C5_MVH
) & 1;
29023 ctx
->eva
= (env
->CP0_Config5
>> CP0C5_EVA
) & 1;
29024 ctx
->sc
= (env
->CP0_Config3
>> CP0C3_SC
) & 1;
29025 ctx
->CP0_LLAddr_shift
= env
->CP0_LLAddr_shift
;
29026 ctx
->cmgcr
= (env
->CP0_Config3
>> CP0C3_CMGCR
) & 1;
29027 /* Restore delay slot state from the tb context. */
29028 ctx
->hflags
= (uint32_t)ctx
->base
.tb
->flags
; /* FIXME: maybe use 64 bits? */
29029 ctx
->ulri
= (env
->CP0_Config3
>> CP0C3_ULRI
) & 1;
29030 ctx
->ps
= ((env
->active_fpu
.fcr0
>> FCR0_PS
) & 1) ||
29031 (env
->insn_flags
& (INSN_LOONGSON2E
| INSN_LOONGSON2F
));
29032 ctx
->vp
= (env
->CP0_Config5
>> CP0C5_VP
) & 1;
29033 ctx
->mrp
= (env
->CP0_Config5
>> CP0C5_MRP
) & 1;
29034 ctx
->nan2008
= (env
->active_fpu
.fcr31
>> FCR31_NAN2008
) & 1;
29035 ctx
->abs2008
= (env
->active_fpu
.fcr31
>> FCR31_ABS2008
) & 1;
29036 ctx
->mi
= (env
->CP0_Config5
>> CP0C5_MI
) & 1;
29037 ctx
->gi
= (env
->CP0_Config5
>> CP0C5_GI
) & 3;
29038 restore_cpu_state(env
, ctx
);
29039 #ifdef CONFIG_USER_ONLY
29040 ctx
->mem_idx
= MIPS_HFLAG_UM
;
29042 ctx
->mem_idx
= hflags_mmu_index(ctx
->hflags
);
29044 ctx
->default_tcg_memop_mask
= (ctx
->insn_flags
& (ISA_MIPS_R6
|
29045 INSN_LOONGSON3A
)) ? MO_UNALN
: MO_ALIGN
;
29047 LOG_DISAS("\ntb %p idx %d hflags %04x\n", ctx
->base
.tb
, ctx
->mem_idx
,
29051 static void mips_tr_tb_start(DisasContextBase
*dcbase
, CPUState
*cs
)
29055 static void mips_tr_insn_start(DisasContextBase
*dcbase
, CPUState
*cs
)
29057 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
29059 tcg_gen_insn_start(ctx
->base
.pc_next
, ctx
->hflags
& MIPS_HFLAG_BMASK
,
29063 static bool mips_tr_breakpoint_check(DisasContextBase
*dcbase
, CPUState
*cs
,
29064 const CPUBreakpoint
*bp
)
29066 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
29068 save_cpu_state(ctx
, 1);
29069 ctx
->base
.is_jmp
= DISAS_NORETURN
;
29070 gen_helper_raise_exception_debug(cpu_env
);
29072 * The address covered by the breakpoint must be included in
29073 * [tb->pc, tb->pc + tb->size) in order to for it to be
29074 * properly cleared -- thus we increment the PC here so that
29075 * the logic setting tb->size below does the right thing.
29077 ctx
->base
.pc_next
+= 4;
29081 static void mips_tr_translate_insn(DisasContextBase
*dcbase
, CPUState
*cs
)
29083 CPUMIPSState
*env
= cs
->env_ptr
;
29084 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
29088 is_slot
= ctx
->hflags
& MIPS_HFLAG_BMASK
;
29089 if (ctx
->insn_flags
& ISA_NANOMIPS32
) {
29090 ctx
->opcode
= cpu_lduw_code(env
, ctx
->base
.pc_next
);
29091 insn_bytes
= decode_nanomips_opc(env
, ctx
);
29092 } else if (!(ctx
->hflags
& MIPS_HFLAG_M16
)) {
29093 ctx
->opcode
= cpu_ldl_code(env
, ctx
->base
.pc_next
);
29095 decode_opc(env
, ctx
);
29096 } else if (ctx
->insn_flags
& ASE_MICROMIPS
) {
29097 ctx
->opcode
= cpu_lduw_code(env
, ctx
->base
.pc_next
);
29098 insn_bytes
= decode_micromips_opc(env
, ctx
);
29099 } else if (ctx
->insn_flags
& ASE_MIPS16
) {
29100 ctx
->opcode
= cpu_lduw_code(env
, ctx
->base
.pc_next
);
29101 insn_bytes
= decode_mips16_opc(env
, ctx
);
29103 gen_reserved_instruction(ctx
);
29104 g_assert(ctx
->base
.is_jmp
== DISAS_NORETURN
);
29108 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
29109 if (!(ctx
->hflags
& (MIPS_HFLAG_BDS16
| MIPS_HFLAG_BDS32
|
29110 MIPS_HFLAG_FBNSLOT
))) {
29112 * Force to generate branch as there is neither delay nor
29117 if ((ctx
->hflags
& MIPS_HFLAG_M16
) &&
29118 (ctx
->hflags
& MIPS_HFLAG_FBNSLOT
)) {
29120 * Force to generate branch as microMIPS R6 doesn't restrict
29121 * branches in the forbidden slot.
29127 gen_branch(ctx
, insn_bytes
);
29129 ctx
->base
.pc_next
+= insn_bytes
;
29131 if (ctx
->base
.is_jmp
!= DISAS_NEXT
) {
29135 * Execute a branch and its delay slot as a single instruction.
29136 * This is what GDB expects and is consistent with what the
29137 * hardware does (e.g. if a delay slot instruction faults, the
29138 * reported PC is the PC of the branch).
29140 if (ctx
->base
.singlestep_enabled
&&
29141 (ctx
->hflags
& MIPS_HFLAG_BMASK
) == 0) {
29142 ctx
->base
.is_jmp
= DISAS_TOO_MANY
;
29144 if (ctx
->base
.pc_next
- ctx
->page_start
>= TARGET_PAGE_SIZE
) {
29145 ctx
->base
.is_jmp
= DISAS_TOO_MANY
;
29149 static void mips_tr_tb_stop(DisasContextBase
*dcbase
, CPUState
*cs
)
29151 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
29153 if (ctx
->base
.singlestep_enabled
&& ctx
->base
.is_jmp
!= DISAS_NORETURN
) {
29154 save_cpu_state(ctx
, ctx
->base
.is_jmp
!= DISAS_EXIT
);
29155 gen_helper_raise_exception_debug(cpu_env
);
29157 switch (ctx
->base
.is_jmp
) {
29159 gen_save_pc(ctx
->base
.pc_next
);
29160 tcg_gen_lookup_and_goto_ptr();
29163 case DISAS_TOO_MANY
:
29164 save_cpu_state(ctx
, 0);
29165 gen_goto_tb(ctx
, 0, ctx
->base
.pc_next
);
29168 tcg_gen_exit_tb(NULL
, 0);
29170 case DISAS_NORETURN
:
29173 g_assert_not_reached();
29178 static void mips_tr_disas_log(const DisasContextBase
*dcbase
, CPUState
*cs
)
29180 qemu_log("IN: %s\n", lookup_symbol(dcbase
->pc_first
));
29181 log_target_disas(cs
, dcbase
->pc_first
, dcbase
->tb
->size
);
29184 static const TranslatorOps mips_tr_ops
= {
29185 .init_disas_context
= mips_tr_init_disas_context
,
29186 .tb_start
= mips_tr_tb_start
,
29187 .insn_start
= mips_tr_insn_start
,
29188 .breakpoint_check
= mips_tr_breakpoint_check
,
29189 .translate_insn
= mips_tr_translate_insn
,
29190 .tb_stop
= mips_tr_tb_stop
,
29191 .disas_log
= mips_tr_disas_log
,
29194 void gen_intermediate_code(CPUState
*cs
, TranslationBlock
*tb
, int max_insns
)
29198 translator_loop(&mips_tr_ops
, &ctx
.base
, cs
, tb
, max_insns
);
29201 static void fpu_dump_state(CPUMIPSState
*env
, FILE * f
, int flags
)
29204 int is_fpu64
= !!(env
->hflags
& MIPS_HFLAG_F64
);
29206 #define printfpr(fp) \
29209 qemu_fprintf(f, "w:%08x d:%016" PRIx64 \
29210 " fd:%13g fs:%13g psu: %13g\n", \
29211 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
29212 (double)(fp)->fd, \
29213 (double)(fp)->fs[FP_ENDIAN_IDX], \
29214 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
29217 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
29218 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
29219 qemu_fprintf(f, "w:%08x d:%016" PRIx64 \
29220 " fd:%13g fs:%13g psu:%13g\n", \
29221 tmp.w[FP_ENDIAN_IDX], tmp.d, \
29223 (double)tmp.fs[FP_ENDIAN_IDX], \
29224 (double)tmp.fs[!FP_ENDIAN_IDX]); \
29230 "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
29231 env
->active_fpu
.fcr0
, env
->active_fpu
.fcr31
, is_fpu64
,
29232 get_float_exception_flags(&env
->active_fpu
.fp_status
));
29233 for (i
= 0; i
< 32; (is_fpu64
) ? i
++ : (i
+= 2)) {
29234 qemu_fprintf(f
, "%3s: ", fregnames
[i
]);
29235 printfpr(&env
->active_fpu
.fpr
[i
]);
29241 void mips_cpu_dump_state(CPUState
*cs
, FILE *f
, int flags
)
29243 MIPSCPU
*cpu
= MIPS_CPU(cs
);
29244 CPUMIPSState
*env
= &cpu
->env
;
29247 qemu_fprintf(f
, "pc=0x" TARGET_FMT_lx
" HI=0x" TARGET_FMT_lx
29248 " LO=0x" TARGET_FMT_lx
" ds %04x "
29249 TARGET_FMT_lx
" " TARGET_FMT_ld
"\n",
29250 env
->active_tc
.PC
, env
->active_tc
.HI
[0], env
->active_tc
.LO
[0],
29251 env
->hflags
, env
->btarget
, env
->bcond
);
29252 for (i
= 0; i
< 32; i
++) {
29253 if ((i
& 3) == 0) {
29254 qemu_fprintf(f
, "GPR%02d:", i
);
29256 qemu_fprintf(f
, " %s " TARGET_FMT_lx
,
29257 regnames
[i
], env
->active_tc
.gpr
[i
]);
29258 if ((i
& 3) == 3) {
29259 qemu_fprintf(f
, "\n");
29263 qemu_fprintf(f
, "CP0 Status 0x%08x Cause 0x%08x EPC 0x"
29264 TARGET_FMT_lx
"\n",
29265 env
->CP0_Status
, env
->CP0_Cause
, env
->CP0_EPC
);
29266 qemu_fprintf(f
, " Config0 0x%08x Config1 0x%08x LLAddr 0x%016"
29268 env
->CP0_Config0
, env
->CP0_Config1
, env
->CP0_LLAddr
);
29269 qemu_fprintf(f
, " Config2 0x%08x Config3 0x%08x\n",
29270 env
->CP0_Config2
, env
->CP0_Config3
);
29271 qemu_fprintf(f
, " Config4 0x%08x Config5 0x%08x\n",
29272 env
->CP0_Config4
, env
->CP0_Config5
);
29273 if ((flags
& CPU_DUMP_FPU
) && (env
->hflags
& MIPS_HFLAG_FPU
)) {
29274 fpu_dump_state(env
, f
, flags
);
29278 void mips_tcg_init(void)
29283 for (i
= 1; i
< 32; i
++)
29284 cpu_gpr
[i
] = tcg_global_mem_new(cpu_env
,
29285 offsetof(CPUMIPSState
,
29288 for (i
= 0; i
< 32; i
++) {
29289 int off
= offsetof(CPUMIPSState
, active_fpu
.fpr
[i
].wr
.d
[0]);
29291 fpu_f64
[i
] = tcg_global_mem_new_i64(cpu_env
, off
, fregnames
[i
]);
29293 msa_translate_init();
29294 cpu_PC
= tcg_global_mem_new(cpu_env
,
29295 offsetof(CPUMIPSState
, active_tc
.PC
), "PC");
29296 for (i
= 0; i
< MIPS_DSP_ACC
; i
++) {
29297 cpu_HI
[i
] = tcg_global_mem_new(cpu_env
,
29298 offsetof(CPUMIPSState
, active_tc
.HI
[i
]),
29300 cpu_LO
[i
] = tcg_global_mem_new(cpu_env
,
29301 offsetof(CPUMIPSState
, active_tc
.LO
[i
]),
29304 cpu_dspctrl
= tcg_global_mem_new(cpu_env
,
29305 offsetof(CPUMIPSState
,
29306 active_tc
.DSPControl
),
29308 bcond
= tcg_global_mem_new(cpu_env
,
29309 offsetof(CPUMIPSState
, bcond
), "bcond");
29310 btarget
= tcg_global_mem_new(cpu_env
,
29311 offsetof(CPUMIPSState
, btarget
), "btarget");
29312 hflags
= tcg_global_mem_new_i32(cpu_env
,
29313 offsetof(CPUMIPSState
, hflags
), "hflags");
29315 fpu_fcr0
= tcg_global_mem_new_i32(cpu_env
,
29316 offsetof(CPUMIPSState
, active_fpu
.fcr0
),
29318 fpu_fcr31
= tcg_global_mem_new_i32(cpu_env
,
29319 offsetof(CPUMIPSState
, active_fpu
.fcr31
),
29321 cpu_lladdr
= tcg_global_mem_new(cpu_env
, offsetof(CPUMIPSState
, lladdr
),
29323 cpu_llval
= tcg_global_mem_new(cpu_env
, offsetof(CPUMIPSState
, llval
),
29326 #if defined(TARGET_MIPS64)
29328 for (i
= 1; i
< 32; i
++) {
29329 cpu_mmr
[i
] = tcg_global_mem_new_i64(cpu_env
,
29330 offsetof(CPUMIPSState
,
29336 #if !defined(TARGET_MIPS64)
29337 for (i
= 0; i
< NUMBER_OF_MXU_REGISTERS
- 1; i
++) {
29338 mxu_gpr
[i
] = tcg_global_mem_new(cpu_env
,
29339 offsetof(CPUMIPSState
,
29340 active_tc
.mxu_gpr
[i
]),
29344 mxu_CR
= tcg_global_mem_new(cpu_env
,
29345 offsetof(CPUMIPSState
, active_tc
.mxu_cr
),
29346 mxuregnames
[NUMBER_OF_MXU_REGISTERS
- 1]);
29350 void restore_state_to_opc(CPUMIPSState
*env
, TranslationBlock
*tb
,
29351 target_ulong
*data
)
29353 env
->active_tc
.PC
= data
[0];
29354 env
->hflags
&= ~MIPS_HFLAG_BMASK
;
29355 env
->hflags
|= data
[1];
29356 switch (env
->hflags
& MIPS_HFLAG_BMASK_BASE
) {
29357 case MIPS_HFLAG_BR
:
29359 case MIPS_HFLAG_BC
:
29360 case MIPS_HFLAG_BL
:
29362 env
->btarget
= data
[2];