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/translator.h"
30 #include "exec/helper-proto.h"
31 #include "exec/helper-gen.h"
32 #include "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
,
1133 * Overview of the TX79-specific instruction set
1134 * =============================================
1136 * The R5900 and the C790 have 128-bit wide GPRs, where the upper 64 bits
1137 * are only used by the specific quadword (128-bit) LQ/SQ load/store
1138 * instructions and certain multimedia instructions (MMIs). These MMIs
1139 * configure the 128-bit data path as two 64-bit, four 32-bit, eight 16-bit
1140 * or sixteen 8-bit paths.
1144 * The Toshiba TX System RISC TX79 Core Architecture manual,
1145 * https://wiki.qemu.org/File:C790.pdf
1147 * Three-Operand Multiply and Multiply-Add (4 instructions)
1148 * --------------------------------------------------------
1149 * MADD [rd,] rs, rt Multiply/Add
1150 * MADDU [rd,] rs, rt Multiply/Add Unsigned
1151 * MULT [rd,] rs, rt Multiply (3-operand)
1152 * MULTU [rd,] rs, rt Multiply Unsigned (3-operand)
1154 * Multiply Instructions for Pipeline 1 (10 instructions)
1155 * ------------------------------------------------------
1156 * MULT1 [rd,] rs, rt Multiply Pipeline 1
1157 * MULTU1 [rd,] rs, rt Multiply Unsigned Pipeline 1
1158 * DIV1 rs, rt Divide Pipeline 1
1159 * DIVU1 rs, rt Divide Unsigned Pipeline 1
1160 * MADD1 [rd,] rs, rt Multiply-Add Pipeline 1
1161 * MADDU1 [rd,] rs, rt Multiply-Add Unsigned Pipeline 1
1162 * MFHI1 rd Move From HI1 Register
1163 * MFLO1 rd Move From LO1 Register
1164 * MTHI1 rs Move To HI1 Register
1165 * MTLO1 rs Move To LO1 Register
1167 * Arithmetic (19 instructions)
1168 * ----------------------------
1169 * PADDB rd, rs, rt Parallel Add Byte
1170 * PSUBB rd, rs, rt Parallel Subtract Byte
1171 * PADDH rd, rs, rt Parallel Add Halfword
1172 * PSUBH rd, rs, rt Parallel Subtract Halfword
1173 * PADDW rd, rs, rt Parallel Add Word
1174 * PSUBW rd, rs, rt Parallel Subtract Word
1175 * PADSBH rd, rs, rt Parallel Add/Subtract Halfword
1176 * PADDSB rd, rs, rt Parallel Add with Signed Saturation Byte
1177 * PSUBSB rd, rs, rt Parallel Subtract with Signed Saturation Byte
1178 * PADDSH rd, rs, rt Parallel Add with Signed Saturation Halfword
1179 * PSUBSH rd, rs, rt Parallel Subtract with Signed Saturation Halfword
1180 * PADDSW rd, rs, rt Parallel Add with Signed Saturation Word
1181 * PSUBSW rd, rs, rt Parallel Subtract with Signed Saturation Word
1182 * PADDUB rd, rs, rt Parallel Add with Unsigned saturation Byte
1183 * PSUBUB rd, rs, rt Parallel Subtract with Unsigned saturation Byte
1184 * PADDUH rd, rs, rt Parallel Add with Unsigned saturation Halfword
1185 * PSUBUH rd, rs, rt Parallel Subtract with Unsigned saturation Halfword
1186 * PADDUW rd, rs, rt Parallel Add with Unsigned saturation Word
1187 * PSUBUW rd, rs, rt Parallel Subtract with Unsigned saturation Word
1189 * Min/Max (4 instructions)
1190 * ------------------------
1191 * PMAXH rd, rs, rt Parallel Maximum Halfword
1192 * PMINH rd, rs, rt Parallel Minimum Halfword
1193 * PMAXW rd, rs, rt Parallel Maximum Word
1194 * PMINW rd, rs, rt Parallel Minimum Word
1196 * Absolute (2 instructions)
1197 * -------------------------
1198 * PABSH rd, rt Parallel Absolute Halfword
1199 * PABSW rd, rt Parallel Absolute Word
1201 * Logical (4 instructions)
1202 * ------------------------
1203 * PAND rd, rs, rt Parallel AND
1204 * POR rd, rs, rt Parallel OR
1205 * PXOR rd, rs, rt Parallel XOR
1206 * PNOR rd, rs, rt Parallel NOR
1208 * Shift (9 instructions)
1209 * ----------------------
1210 * PSLLH rd, rt, sa Parallel Shift Left Logical Halfword
1211 * PSRLH rd, rt, sa Parallel Shift Right Logical Halfword
1212 * PSRAH rd, rt, sa Parallel Shift Right Arithmetic Halfword
1213 * PSLLW rd, rt, sa Parallel Shift Left Logical Word
1214 * PSRLW rd, rt, sa Parallel Shift Right Logical Word
1215 * PSRAW rd, rt, sa Parallel Shift Right Arithmetic Word
1216 * PSLLVW rd, rt, rs Parallel Shift Left Logical Variable Word
1217 * PSRLVW rd, rt, rs Parallel Shift Right Logical Variable Word
1218 * PSRAVW rd, rt, rs Parallel Shift Right Arithmetic Variable Word
1220 * Compare (6 instructions)
1221 * ------------------------
1222 * PCGTB rd, rs, rt Parallel Compare for Greater Than Byte
1223 * PCEQB rd, rs, rt Parallel Compare for Equal Byte
1224 * PCGTH rd, rs, rt Parallel Compare for Greater Than Halfword
1225 * PCEQH rd, rs, rt Parallel Compare for Equal Halfword
1226 * PCGTW rd, rs, rt Parallel Compare for Greater Than Word
1227 * PCEQW rd, rs, rt Parallel Compare for Equal Word
1229 * LZC (1 instruction)
1230 * -------------------
1231 * PLZCW rd, rs Parallel Leading Zero or One Count Word
1233 * Quadword Load and Store (2 instructions)
1234 * ----------------------------------------
1235 * LQ rt, offset(base) Load Quadword
1236 * SQ rt, offset(base) Store Quadword
1238 * Multiply and Divide (19 instructions)
1239 * -------------------------------------
1240 * PMULTW rd, rs, rt Parallel Multiply Word
1241 * PMULTUW rd, rs, rt Parallel Multiply Unsigned Word
1242 * PDIVW rs, rt Parallel Divide Word
1243 * PDIVUW rs, rt Parallel Divide Unsigned Word
1244 * PMADDW rd, rs, rt Parallel Multiply-Add Word
1245 * PMADDUW rd, rs, rt Parallel Multiply-Add Unsigned Word
1246 * PMSUBW rd, rs, rt Parallel Multiply-Subtract Word
1247 * PMULTH rd, rs, rt Parallel Multiply Halfword
1248 * PMADDH rd, rs, rt Parallel Multiply-Add Halfword
1249 * PMSUBH rd, rs, rt Parallel Multiply-Subtract Halfword
1250 * PHMADH rd, rs, rt Parallel Horizontal Multiply-Add Halfword
1251 * PHMSBH rd, rs, rt Parallel Horizontal Multiply-Subtract Halfword
1252 * PDIVBW rs, rt Parallel Divide Broadcast Word
1253 * PMFHI rd Parallel Move From HI Register
1254 * PMFLO rd Parallel Move From LO Register
1255 * PMTHI rs Parallel Move To HI Register
1256 * PMTLO rs Parallel Move To LO Register
1257 * PMFHL rd Parallel Move From HI/LO Register
1258 * PMTHL rs Parallel Move To HI/LO Register
1260 * Pack/Extend (11 instructions)
1261 * -----------------------------
1262 * PPAC5 rd, rt Parallel Pack to 5 bits
1263 * PPACB rd, rs, rt Parallel Pack to Byte
1264 * PPACH rd, rs, rt Parallel Pack to Halfword
1265 * PPACW rd, rs, rt Parallel Pack to Word
1266 * PEXT5 rd, rt Parallel Extend Upper from 5 bits
1267 * PEXTUB rd, rs, rt Parallel Extend Upper from Byte
1268 * PEXTLB rd, rs, rt Parallel Extend Lower from Byte
1269 * PEXTUH rd, rs, rt Parallel Extend Upper from Halfword
1270 * PEXTLH rd, rs, rt Parallel Extend Lower from Halfword
1271 * PEXTUW rd, rs, rt Parallel Extend Upper from Word
1272 * PEXTLW rd, rs, rt Parallel Extend Lower from Word
1274 * Others (16 instructions)
1275 * ------------------------
1276 * PCPYH rd, rt Parallel Copy Halfword
1277 * PCPYLD rd, rs, rt Parallel Copy Lower Doubleword
1278 * PCPYUD rd, rs, rt Parallel Copy Upper Doubleword
1279 * PREVH rd, rt Parallel Reverse Halfword
1280 * PINTH rd, rs, rt Parallel Interleave Halfword
1281 * PINTEH rd, rs, rt Parallel Interleave Even Halfword
1282 * PEXEH rd, rt Parallel Exchange Even Halfword
1283 * PEXCH rd, rt Parallel Exchange Center Halfword
1284 * PEXEW rd, rt Parallel Exchange Even Word
1285 * PEXCW rd, rt Parallel Exchange Center Word
1286 * QFSRV rd, rs, rt Quadword Funnel Shift Right Variable
1287 * MFSA rd Move from Shift Amount Register
1288 * MTSA rs Move to Shift Amount Register
1289 * MTSAB rs, immediate Move Byte Count to Shift Amount Register
1290 * MTSAH rs, immediate Move Halfword Count to Shift Amount Register
1291 * PROT3W rd, rt Parallel Rotate 3 Words
1293 * MMI (MultiMedia Instruction) encodings
1294 * ======================================
1296 * MMI instructions encoding table keys:
1298 * * This code is reserved for future use. An attempt to execute it
1299 * causes a Reserved Instruction exception.
1300 * % This code indicates an instruction class. The instruction word
1301 * must be further decoded by examining additional tables that show
1302 * the values for other instruction fields.
1303 * # This code is reserved for the unsupported instructions DMULT,
1304 * DMULTU, DDIV, DDIVU, LL, LLD, SC, SCD, LWC2 and SWC2. An attempt
1305 * to execute it causes a Reserved Instruction exception.
1307 * MMI instructions encoded by opcode field (MMI, LQ, SQ):
1310 * +--------+----------------------------------------+
1312 * +--------+----------------------------------------+
1314 * opcode bits 28..26
1315 * bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
1316 * 31..29 | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111
1317 * -------+-------+-------+-------+-------+-------+-------+-------+-------
1318 * 0 000 |SPECIAL| REGIMM| J | JAL | BEQ | BNE | BLEZ | BGTZ
1319 * 1 001 | ADDI | ADDIU | SLTI | SLTIU | ANDI | ORI | XORI | LUI
1320 * 2 010 | COP0 | COP1 | * | * | BEQL | BNEL | BLEZL | BGTZL
1321 * 3 011 | DADDI | DADDIU| LDL | LDR | MMI% | * | LQ | SQ
1322 * 4 100 | LB | LH | LWL | LW | LBU | LHU | LWR | LWU
1323 * 5 101 | SB | SH | SWL | SW | SDL | SDR | SWR | CACHE
1324 * 6 110 | # | LWC1 | # | PREF | # | LDC1 | # | LD
1325 * 7 111 | # | SWC1 | # | * | # | SDC1 | # | SD
1329 MMI_OPC_CLASS_MMI
= 0x1C << 26, /* Same as OPC_SPECIAL2 */
1330 MMI_OPC_LQ
= 0x1E << 26, /* Same as OPC_MSA */
1331 MMI_OPC_SQ
= 0x1F << 26, /* Same as OPC_SPECIAL3 */
1335 * MMI instructions with opcode field = MMI:
1338 * +--------+-------------------------------+--------+
1339 * | MMI | |function|
1340 * +--------+-------------------------------+--------+
1342 * function bits 2..0
1343 * bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
1344 * 5..3 | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111
1345 * -------+-------+-------+-------+-------+-------+-------+-------+-------
1346 * 0 000 | MADD | MADDU | * | * | PLZCW | * | * | *
1347 * 1 001 | MMI0% | MMI2% | * | * | * | * | * | *
1348 * 2 010 | MFHI1 | MTHI1 | MFLO1 | MTLO1 | * | * | * | *
1349 * 3 011 | MULT1 | MULTU1| DIV1 | DIVU1 | * | * | * | *
1350 * 4 100 | MADD1 | MADDU1| * | * | * | * | * | *
1351 * 5 101 | MMI1% | MMI3% | * | * | * | * | * | *
1352 * 6 110 | PMFHL | PMTHL | * | * | PSLLH | * | PSRLH | PSRAH
1353 * 7 111 | * | * | * | * | PSLLW | * | PSRLW | PSRAW
1356 #define MASK_MMI(op) (MASK_OP_MAJOR(op) | ((op) & 0x3F))
1358 MMI_OPC_MADD
= 0x00 | MMI_OPC_CLASS_MMI
, /* Same as OPC_MADD */
1359 MMI_OPC_MADDU
= 0x01 | MMI_OPC_CLASS_MMI
, /* Same as OPC_MADDU */
1360 MMI_OPC_PLZCW
= 0x04 | MMI_OPC_CLASS_MMI
,
1361 MMI_OPC_CLASS_MMI0
= 0x08 | MMI_OPC_CLASS_MMI
,
1362 MMI_OPC_CLASS_MMI2
= 0x09 | MMI_OPC_CLASS_MMI
,
1363 MMI_OPC_MULT1
= 0x18 | MMI_OPC_CLASS_MMI
, /* Same minor as OPC_MULT */
1364 MMI_OPC_MULTU1
= 0x19 | MMI_OPC_CLASS_MMI
, /* Same min. as OPC_MULTU */
1365 MMI_OPC_DIV1
= 0x1A | MMI_OPC_CLASS_MMI
, /* Same minor as OPC_DIV */
1366 MMI_OPC_DIVU1
= 0x1B | MMI_OPC_CLASS_MMI
, /* Same minor as OPC_DIVU */
1367 MMI_OPC_MADD1
= 0x20 | MMI_OPC_CLASS_MMI
,
1368 MMI_OPC_MADDU1
= 0x21 | MMI_OPC_CLASS_MMI
,
1369 MMI_OPC_CLASS_MMI1
= 0x28 | MMI_OPC_CLASS_MMI
,
1370 MMI_OPC_CLASS_MMI3
= 0x29 | MMI_OPC_CLASS_MMI
,
1371 MMI_OPC_PMFHL
= 0x30 | MMI_OPC_CLASS_MMI
,
1372 MMI_OPC_PMTHL
= 0x31 | MMI_OPC_CLASS_MMI
,
1373 MMI_OPC_PSLLH
= 0x34 | MMI_OPC_CLASS_MMI
,
1374 MMI_OPC_PSRLH
= 0x36 | MMI_OPC_CLASS_MMI
,
1375 MMI_OPC_PSRAH
= 0x37 | MMI_OPC_CLASS_MMI
,
1376 MMI_OPC_PSLLW
= 0x3C | MMI_OPC_CLASS_MMI
,
1377 MMI_OPC_PSRLW
= 0x3E | MMI_OPC_CLASS_MMI
,
1378 MMI_OPC_PSRAW
= 0x3F | MMI_OPC_CLASS_MMI
,
1382 * MMI instructions with opcode field = MMI and bits 5..0 = MMI0:
1385 * +--------+----------------------+--------+--------+
1386 * | MMI | |function| MMI0 |
1387 * +--------+----------------------+--------+--------+
1389 * function bits 7..6
1390 * bits | 0 | 1 | 2 | 3
1391 * 10..8 | 00 | 01 | 10 | 11
1392 * -------+-------+-------+-------+-------
1393 * 0 000 | PADDW | PSUBW | PCGTW | PMAXW
1394 * 1 001 | PADDH | PSUBH | PCGTH | PMAXH
1395 * 2 010 | PADDB | PSUBB | PCGTB | *
1396 * 3 011 | * | * | * | *
1397 * 4 100 | PADDSW| PSUBSW| PEXTLW| PPACW
1398 * 5 101 | PADDSH| PSUBSH| PEXTLH| PPACH
1399 * 6 110 | PADDSB| PSUBSB| PEXTLB| PPACB
1400 * 7 111 | * | * | PEXT5 | PPAC5
1403 #define MASK_MMI0(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
1405 MMI_OPC_0_PADDW
= (0x00 << 6) | MMI_OPC_CLASS_MMI0
,
1406 MMI_OPC_0_PSUBW
= (0x01 << 6) | MMI_OPC_CLASS_MMI0
,
1407 MMI_OPC_0_PCGTW
= (0x02 << 6) | MMI_OPC_CLASS_MMI0
,
1408 MMI_OPC_0_PMAXW
= (0x03 << 6) | MMI_OPC_CLASS_MMI0
,
1409 MMI_OPC_0_PADDH
= (0x04 << 6) | MMI_OPC_CLASS_MMI0
,
1410 MMI_OPC_0_PSUBH
= (0x05 << 6) | MMI_OPC_CLASS_MMI0
,
1411 MMI_OPC_0_PCGTH
= (0x06 << 6) | MMI_OPC_CLASS_MMI0
,
1412 MMI_OPC_0_PMAXH
= (0x07 << 6) | MMI_OPC_CLASS_MMI0
,
1413 MMI_OPC_0_PADDB
= (0x08 << 6) | MMI_OPC_CLASS_MMI0
,
1414 MMI_OPC_0_PSUBB
= (0x09 << 6) | MMI_OPC_CLASS_MMI0
,
1415 MMI_OPC_0_PCGTB
= (0x0A << 6) | MMI_OPC_CLASS_MMI0
,
1416 MMI_OPC_0_PADDSW
= (0x10 << 6) | MMI_OPC_CLASS_MMI0
,
1417 MMI_OPC_0_PSUBSW
= (0x11 << 6) | MMI_OPC_CLASS_MMI0
,
1418 MMI_OPC_0_PEXTLW
= (0x12 << 6) | MMI_OPC_CLASS_MMI0
,
1419 MMI_OPC_0_PPACW
= (0x13 << 6) | MMI_OPC_CLASS_MMI0
,
1420 MMI_OPC_0_PADDSH
= (0x14 << 6) | MMI_OPC_CLASS_MMI0
,
1421 MMI_OPC_0_PSUBSH
= (0x15 << 6) | MMI_OPC_CLASS_MMI0
,
1422 MMI_OPC_0_PEXTLH
= (0x16 << 6) | MMI_OPC_CLASS_MMI0
,
1423 MMI_OPC_0_PPACH
= (0x17 << 6) | MMI_OPC_CLASS_MMI0
,
1424 MMI_OPC_0_PADDSB
= (0x18 << 6) | MMI_OPC_CLASS_MMI0
,
1425 MMI_OPC_0_PSUBSB
= (0x19 << 6) | MMI_OPC_CLASS_MMI0
,
1426 MMI_OPC_0_PEXTLB
= (0x1A << 6) | MMI_OPC_CLASS_MMI0
,
1427 MMI_OPC_0_PPACB
= (0x1B << 6) | MMI_OPC_CLASS_MMI0
,
1428 MMI_OPC_0_PEXT5
= (0x1E << 6) | MMI_OPC_CLASS_MMI0
,
1429 MMI_OPC_0_PPAC5
= (0x1F << 6) | MMI_OPC_CLASS_MMI0
,
1433 * MMI instructions with opcode field = MMI and bits 5..0 = MMI1:
1436 * +--------+----------------------+--------+--------+
1437 * | MMI | |function| MMI1 |
1438 * +--------+----------------------+--------+--------+
1440 * function bits 7..6
1441 * bits | 0 | 1 | 2 | 3
1442 * 10..8 | 00 | 01 | 10 | 11
1443 * -------+-------+-------+-------+-------
1444 * 0 000 | * | PABSW | PCEQW | PMINW
1445 * 1 001 | PADSBH| PABSH | PCEQH | PMINH
1446 * 2 010 | * | * | PCEQB | *
1447 * 3 011 | * | * | * | *
1448 * 4 100 | PADDUW| PSUBUW| PEXTUW| *
1449 * 5 101 | PADDUH| PSUBUH| PEXTUH| *
1450 * 6 110 | PADDUB| PSUBUB| PEXTUB| QFSRV
1451 * 7 111 | * | * | * | *
1454 #define MASK_MMI1(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
1456 MMI_OPC_1_PABSW
= (0x01 << 6) | MMI_OPC_CLASS_MMI1
,
1457 MMI_OPC_1_PCEQW
= (0x02 << 6) | MMI_OPC_CLASS_MMI1
,
1458 MMI_OPC_1_PMINW
= (0x03 << 6) | MMI_OPC_CLASS_MMI1
,
1459 MMI_OPC_1_PADSBH
= (0x04 << 6) | MMI_OPC_CLASS_MMI1
,
1460 MMI_OPC_1_PABSH
= (0x05 << 6) | MMI_OPC_CLASS_MMI1
,
1461 MMI_OPC_1_PCEQH
= (0x06 << 6) | MMI_OPC_CLASS_MMI1
,
1462 MMI_OPC_1_PMINH
= (0x07 << 6) | MMI_OPC_CLASS_MMI1
,
1463 MMI_OPC_1_PCEQB
= (0x0A << 6) | MMI_OPC_CLASS_MMI1
,
1464 MMI_OPC_1_PADDUW
= (0x10 << 6) | MMI_OPC_CLASS_MMI1
,
1465 MMI_OPC_1_PSUBUW
= (0x11 << 6) | MMI_OPC_CLASS_MMI1
,
1466 MMI_OPC_1_PEXTUW
= (0x12 << 6) | MMI_OPC_CLASS_MMI1
,
1467 MMI_OPC_1_PADDUH
= (0x14 << 6) | MMI_OPC_CLASS_MMI1
,
1468 MMI_OPC_1_PSUBUH
= (0x15 << 6) | MMI_OPC_CLASS_MMI1
,
1469 MMI_OPC_1_PEXTUH
= (0x16 << 6) | MMI_OPC_CLASS_MMI1
,
1470 MMI_OPC_1_PADDUB
= (0x18 << 6) | MMI_OPC_CLASS_MMI1
,
1471 MMI_OPC_1_PSUBUB
= (0x19 << 6) | MMI_OPC_CLASS_MMI1
,
1472 MMI_OPC_1_PEXTUB
= (0x1A << 6) | MMI_OPC_CLASS_MMI1
,
1473 MMI_OPC_1_QFSRV
= (0x1B << 6) | MMI_OPC_CLASS_MMI1
,
1477 * MMI instructions with opcode field = MMI and bits 5..0 = MMI2:
1480 * +--------+----------------------+--------+--------+
1481 * | MMI | |function| MMI2 |
1482 * +--------+----------------------+--------+--------+
1484 * function bits 7..6
1485 * bits | 0 | 1 | 2 | 3
1486 * 10..8 | 00 | 01 | 10 | 11
1487 * -------+-------+-------+-------+-------
1488 * 0 000 | PMADDW| * | PSLLVW| PSRLVW
1489 * 1 001 | PMSUBW| * | * | *
1490 * 2 010 | PMFHI | PMFLO | PINTH | *
1491 * 3 011 | PMULTW| PDIVW | PCPYLD| *
1492 * 4 100 | PMADDH| PHMADH| PAND | PXOR
1493 * 5 101 | PMSUBH| PHMSBH| * | *
1494 * 6 110 | * | * | PEXEH | PREVH
1495 * 7 111 | PMULTH| PDIVBW| PEXEW | PROT3W
1498 #define MASK_MMI2(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
1500 MMI_OPC_2_PMADDW
= (0x00 << 6) | MMI_OPC_CLASS_MMI2
,
1501 MMI_OPC_2_PSLLVW
= (0x02 << 6) | MMI_OPC_CLASS_MMI2
,
1502 MMI_OPC_2_PSRLVW
= (0x03 << 6) | MMI_OPC_CLASS_MMI2
,
1503 MMI_OPC_2_PMSUBW
= (0x04 << 6) | MMI_OPC_CLASS_MMI2
,
1504 MMI_OPC_2_PMFHI
= (0x08 << 6) | MMI_OPC_CLASS_MMI2
,
1505 MMI_OPC_2_PMFLO
= (0x09 << 6) | MMI_OPC_CLASS_MMI2
,
1506 MMI_OPC_2_PINTH
= (0x0A << 6) | MMI_OPC_CLASS_MMI2
,
1507 MMI_OPC_2_PMULTW
= (0x0C << 6) | MMI_OPC_CLASS_MMI2
,
1508 MMI_OPC_2_PDIVW
= (0x0D << 6) | MMI_OPC_CLASS_MMI2
,
1509 MMI_OPC_2_PCPYLD
= (0x0E << 6) | MMI_OPC_CLASS_MMI2
,
1510 MMI_OPC_2_PMADDH
= (0x10 << 6) | MMI_OPC_CLASS_MMI2
,
1511 MMI_OPC_2_PHMADH
= (0x11 << 6) | MMI_OPC_CLASS_MMI2
,
1512 MMI_OPC_2_PAND
= (0x12 << 6) | MMI_OPC_CLASS_MMI2
,
1513 MMI_OPC_2_PXOR
= (0x13 << 6) | MMI_OPC_CLASS_MMI2
,
1514 MMI_OPC_2_PMSUBH
= (0x14 << 6) | MMI_OPC_CLASS_MMI2
,
1515 MMI_OPC_2_PHMSBH
= (0x15 << 6) | MMI_OPC_CLASS_MMI2
,
1516 MMI_OPC_2_PEXEH
= (0x1A << 6) | MMI_OPC_CLASS_MMI2
,
1517 MMI_OPC_2_PREVH
= (0x1B << 6) | MMI_OPC_CLASS_MMI2
,
1518 MMI_OPC_2_PMULTH
= (0x1C << 6) | MMI_OPC_CLASS_MMI2
,
1519 MMI_OPC_2_PDIVBW
= (0x1D << 6) | MMI_OPC_CLASS_MMI2
,
1520 MMI_OPC_2_PEXEW
= (0x1E << 6) | MMI_OPC_CLASS_MMI2
,
1521 MMI_OPC_2_PROT3W
= (0x1F << 6) | MMI_OPC_CLASS_MMI2
,
1525 * MMI instructions with opcode field = MMI and bits 5..0 = MMI3:
1528 * +--------+----------------------+--------+--------+
1529 * | MMI | |function| MMI3 |
1530 * +--------+----------------------+--------+--------+
1532 * function bits 7..6
1533 * bits | 0 | 1 | 2 | 3
1534 * 10..8 | 00 | 01 | 10 | 11
1535 * -------+-------+-------+-------+-------
1536 * 0 000 |PMADDUW| * | * | PSRAVW
1537 * 1 001 | * | * | * | *
1538 * 2 010 | PMTHI | PMTLO | PINTEH| *
1539 * 3 011 |PMULTUW| PDIVUW| PCPYUD| *
1540 * 4 100 | * | * | POR | PNOR
1541 * 5 101 | * | * | * | *
1542 * 6 110 | * | * | PEXCH | PCPYH
1543 * 7 111 | * | * | PEXCW | *
1546 #define MASK_MMI3(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
1548 MMI_OPC_3_PMADDUW
= (0x00 << 6) | MMI_OPC_CLASS_MMI3
,
1549 MMI_OPC_3_PSRAVW
= (0x03 << 6) | MMI_OPC_CLASS_MMI3
,
1550 MMI_OPC_3_PMTHI
= (0x08 << 6) | MMI_OPC_CLASS_MMI3
,
1551 MMI_OPC_3_PMTLO
= (0x09 << 6) | MMI_OPC_CLASS_MMI3
,
1552 MMI_OPC_3_PINTEH
= (0x0A << 6) | MMI_OPC_CLASS_MMI3
,
1553 MMI_OPC_3_PMULTUW
= (0x0C << 6) | MMI_OPC_CLASS_MMI3
,
1554 MMI_OPC_3_PDIVUW
= (0x0D << 6) | MMI_OPC_CLASS_MMI3
,
1555 MMI_OPC_3_PCPYUD
= (0x0E << 6) | MMI_OPC_CLASS_MMI3
,
1556 MMI_OPC_3_POR
= (0x12 << 6) | MMI_OPC_CLASS_MMI3
,
1557 MMI_OPC_3_PNOR
= (0x13 << 6) | MMI_OPC_CLASS_MMI3
,
1558 MMI_OPC_3_PEXCH
= (0x1A << 6) | MMI_OPC_CLASS_MMI3
,
1559 MMI_OPC_3_PCPYH
= (0x1B << 6) | MMI_OPC_CLASS_MMI3
,
1560 MMI_OPC_3_PEXCW
= (0x1E << 6) | MMI_OPC_CLASS_MMI3
,
1563 /* global register indices */
1564 TCGv cpu_gpr
[32], cpu_PC
;
1566 * For CPUs using 128-bit GPR registers, we put the lower halves in cpu_gpr[])
1567 * and the upper halves in cpu_gpr_hi[].
1569 TCGv_i64 cpu_gpr_hi
[32];
1570 TCGv cpu_HI
[MIPS_DSP_ACC
], cpu_LO
[MIPS_DSP_ACC
];
1571 static TCGv cpu_dspctrl
, btarget
;
1573 static TCGv cpu_lladdr
, cpu_llval
;
1574 static TCGv_i32 hflags
;
1575 TCGv_i32 fpu_fcr0
, fpu_fcr31
;
1576 TCGv_i64 fpu_f64
[32];
1578 #include "exec/gen-icount.h"
1580 #define gen_helper_0e0i(name, arg) do { \
1581 TCGv_i32 helper_tmp = tcg_const_i32(arg); \
1582 gen_helper_##name(cpu_env, helper_tmp); \
1583 tcg_temp_free_i32(helper_tmp); \
1586 #define gen_helper_0e1i(name, arg1, arg2) do { \
1587 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1588 gen_helper_##name(cpu_env, arg1, helper_tmp); \
1589 tcg_temp_free_i32(helper_tmp); \
1592 #define gen_helper_1e0i(name, ret, arg1) do { \
1593 TCGv_i32 helper_tmp = tcg_const_i32(arg1); \
1594 gen_helper_##name(ret, cpu_env, helper_tmp); \
1595 tcg_temp_free_i32(helper_tmp); \
1598 #define gen_helper_1e1i(name, ret, arg1, arg2) do { \
1599 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1600 gen_helper_##name(ret, cpu_env, arg1, helper_tmp); \
1601 tcg_temp_free_i32(helper_tmp); \
1604 #define gen_helper_0e2i(name, arg1, arg2, arg3) do { \
1605 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1606 gen_helper_##name(cpu_env, arg1, arg2, helper_tmp); \
1607 tcg_temp_free_i32(helper_tmp); \
1610 #define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do { \
1611 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1612 gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp); \
1613 tcg_temp_free_i32(helper_tmp); \
1616 #define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do { \
1617 TCGv_i32 helper_tmp = tcg_const_i32(arg4); \
1618 gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp); \
1619 tcg_temp_free_i32(helper_tmp); \
1622 #define DISAS_STOP DISAS_TARGET_0
1623 #define DISAS_EXIT DISAS_TARGET_1
1625 static const char * const regnames
[] = {
1626 "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
1627 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
1628 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
1629 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
1632 static const char * const regnames_HI
[] = {
1633 "HI0", "HI1", "HI2", "HI3",
1636 static const char * const regnames_LO
[] = {
1637 "LO0", "LO1", "LO2", "LO3",
1640 static const char * const fregnames
[] = {
1641 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
1642 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
1643 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
1644 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
1647 /* General purpose registers moves. */
1648 void gen_load_gpr(TCGv t
, int reg
)
1651 tcg_gen_movi_tl(t
, 0);
1653 tcg_gen_mov_tl(t
, cpu_gpr
[reg
]);
1657 void gen_store_gpr(TCGv t
, int reg
)
1660 tcg_gen_mov_tl(cpu_gpr
[reg
], t
);
1664 #if defined(TARGET_MIPS64)
1665 void gen_load_gpr_hi(TCGv_i64 t
, int reg
)
1668 tcg_gen_movi_i64(t
, 0);
1670 tcg_gen_mov_i64(t
, cpu_gpr_hi
[reg
]);
1674 void gen_store_gpr_hi(TCGv_i64 t
, int reg
)
1677 tcg_gen_mov_i64(cpu_gpr_hi
[reg
], t
);
1680 #endif /* TARGET_MIPS64 */
1682 /* Moves to/from shadow registers. */
1683 static inline void gen_load_srsgpr(int from
, int to
)
1685 TCGv t0
= tcg_temp_new();
1688 tcg_gen_movi_tl(t0
, 0);
1690 TCGv_i32 t2
= tcg_temp_new_i32();
1691 TCGv_ptr addr
= tcg_temp_new_ptr();
1693 tcg_gen_ld_i32(t2
, cpu_env
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
1694 tcg_gen_shri_i32(t2
, t2
, CP0SRSCtl_PSS
);
1695 tcg_gen_andi_i32(t2
, t2
, 0xf);
1696 tcg_gen_muli_i32(t2
, t2
, sizeof(target_ulong
) * 32);
1697 tcg_gen_ext_i32_ptr(addr
, t2
);
1698 tcg_gen_add_ptr(addr
, cpu_env
, addr
);
1700 tcg_gen_ld_tl(t0
, addr
, sizeof(target_ulong
) * from
);
1701 tcg_temp_free_ptr(addr
);
1702 tcg_temp_free_i32(t2
);
1704 gen_store_gpr(t0
, to
);
1708 static inline void gen_store_srsgpr(int from
, int to
)
1711 TCGv t0
= tcg_temp_new();
1712 TCGv_i32 t2
= tcg_temp_new_i32();
1713 TCGv_ptr addr
= tcg_temp_new_ptr();
1715 gen_load_gpr(t0
, from
);
1716 tcg_gen_ld_i32(t2
, cpu_env
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
1717 tcg_gen_shri_i32(t2
, t2
, CP0SRSCtl_PSS
);
1718 tcg_gen_andi_i32(t2
, t2
, 0xf);
1719 tcg_gen_muli_i32(t2
, t2
, sizeof(target_ulong
) * 32);
1720 tcg_gen_ext_i32_ptr(addr
, t2
);
1721 tcg_gen_add_ptr(addr
, cpu_env
, addr
);
1723 tcg_gen_st_tl(t0
, addr
, sizeof(target_ulong
) * to
);
1724 tcg_temp_free_ptr(addr
);
1725 tcg_temp_free_i32(t2
);
1731 static inline void gen_save_pc(target_ulong pc
)
1733 tcg_gen_movi_tl(cpu_PC
, pc
);
1736 static inline void save_cpu_state(DisasContext
*ctx
, int do_save_pc
)
1738 LOG_DISAS("hflags %08x saved %08x\n", ctx
->hflags
, ctx
->saved_hflags
);
1739 if (do_save_pc
&& ctx
->base
.pc_next
!= ctx
->saved_pc
) {
1740 gen_save_pc(ctx
->base
.pc_next
);
1741 ctx
->saved_pc
= ctx
->base
.pc_next
;
1743 if (ctx
->hflags
!= ctx
->saved_hflags
) {
1744 tcg_gen_movi_i32(hflags
, ctx
->hflags
);
1745 ctx
->saved_hflags
= ctx
->hflags
;
1746 switch (ctx
->hflags
& MIPS_HFLAG_BMASK_BASE
) {
1752 tcg_gen_movi_tl(btarget
, ctx
->btarget
);
1758 static inline void restore_cpu_state(CPUMIPSState
*env
, DisasContext
*ctx
)
1760 ctx
->saved_hflags
= ctx
->hflags
;
1761 switch (ctx
->hflags
& MIPS_HFLAG_BMASK_BASE
) {
1767 ctx
->btarget
= env
->btarget
;
1772 void generate_exception_err(DisasContext
*ctx
, int excp
, int err
)
1774 TCGv_i32 texcp
= tcg_const_i32(excp
);
1775 TCGv_i32 terr
= tcg_const_i32(err
);
1776 save_cpu_state(ctx
, 1);
1777 gen_helper_raise_exception_err(cpu_env
, texcp
, terr
);
1778 tcg_temp_free_i32(terr
);
1779 tcg_temp_free_i32(texcp
);
1780 ctx
->base
.is_jmp
= DISAS_NORETURN
;
1783 void generate_exception(DisasContext
*ctx
, int excp
)
1785 gen_helper_0e0i(raise_exception
, excp
);
1788 void generate_exception_end(DisasContext
*ctx
, int excp
)
1790 generate_exception_err(ctx
, excp
, 0);
1793 void gen_reserved_instruction(DisasContext
*ctx
)
1795 generate_exception_end(ctx
, EXCP_RI
);
1798 /* Floating point register moves. */
1799 void gen_load_fpr32(DisasContext
*ctx
, TCGv_i32 t
, int reg
)
1801 if (ctx
->hflags
& MIPS_HFLAG_FRE
) {
1802 generate_exception(ctx
, EXCP_RI
);
1804 tcg_gen_extrl_i64_i32(t
, fpu_f64
[reg
]);
1807 void gen_store_fpr32(DisasContext
*ctx
, TCGv_i32 t
, int reg
)
1810 if (ctx
->hflags
& MIPS_HFLAG_FRE
) {
1811 generate_exception(ctx
, EXCP_RI
);
1813 t64
= tcg_temp_new_i64();
1814 tcg_gen_extu_i32_i64(t64
, t
);
1815 tcg_gen_deposit_i64(fpu_f64
[reg
], fpu_f64
[reg
], t64
, 0, 32);
1816 tcg_temp_free_i64(t64
);
1819 static void gen_load_fpr32h(DisasContext
*ctx
, TCGv_i32 t
, int reg
)
1821 if (ctx
->hflags
& MIPS_HFLAG_F64
) {
1822 tcg_gen_extrh_i64_i32(t
, fpu_f64
[reg
]);
1824 gen_load_fpr32(ctx
, t
, reg
| 1);
1828 static void gen_store_fpr32h(DisasContext
*ctx
, TCGv_i32 t
, int reg
)
1830 if (ctx
->hflags
& MIPS_HFLAG_F64
) {
1831 TCGv_i64 t64
= tcg_temp_new_i64();
1832 tcg_gen_extu_i32_i64(t64
, t
);
1833 tcg_gen_deposit_i64(fpu_f64
[reg
], fpu_f64
[reg
], t64
, 32, 32);
1834 tcg_temp_free_i64(t64
);
1836 gen_store_fpr32(ctx
, t
, reg
| 1);
1840 void gen_load_fpr64(DisasContext
*ctx
, TCGv_i64 t
, int reg
)
1842 if (ctx
->hflags
& MIPS_HFLAG_F64
) {
1843 tcg_gen_mov_i64(t
, fpu_f64
[reg
]);
1845 tcg_gen_concat32_i64(t
, fpu_f64
[reg
& ~1], fpu_f64
[reg
| 1]);
1849 void gen_store_fpr64(DisasContext
*ctx
, TCGv_i64 t
, int reg
)
1851 if (ctx
->hflags
& MIPS_HFLAG_F64
) {
1852 tcg_gen_mov_i64(fpu_f64
[reg
], t
);
1855 tcg_gen_deposit_i64(fpu_f64
[reg
& ~1], fpu_f64
[reg
& ~1], t
, 0, 32);
1856 t0
= tcg_temp_new_i64();
1857 tcg_gen_shri_i64(t0
, t
, 32);
1858 tcg_gen_deposit_i64(fpu_f64
[reg
| 1], fpu_f64
[reg
| 1], t0
, 0, 32);
1859 tcg_temp_free_i64(t0
);
1863 int get_fp_bit(int cc
)
1872 /* Addresses computation */
1873 void gen_op_addr_add(DisasContext
*ctx
, TCGv ret
, TCGv arg0
, TCGv arg1
)
1875 tcg_gen_add_tl(ret
, arg0
, arg1
);
1877 #if defined(TARGET_MIPS64)
1878 if (ctx
->hflags
& MIPS_HFLAG_AWRAP
) {
1879 tcg_gen_ext32s_i64(ret
, ret
);
1884 static inline void gen_op_addr_addi(DisasContext
*ctx
, TCGv ret
, TCGv base
,
1887 tcg_gen_addi_tl(ret
, base
, ofs
);
1889 #if defined(TARGET_MIPS64)
1890 if (ctx
->hflags
& MIPS_HFLAG_AWRAP
) {
1891 tcg_gen_ext32s_i64(ret
, ret
);
1896 /* Addresses computation (translation time) */
1897 static target_long
addr_add(DisasContext
*ctx
, target_long base
,
1900 target_long sum
= base
+ offset
;
1902 #if defined(TARGET_MIPS64)
1903 if (ctx
->hflags
& MIPS_HFLAG_AWRAP
) {
1910 /* Sign-extract the low 32-bits to a target_long. */
1911 void gen_move_low32(TCGv ret
, TCGv_i64 arg
)
1913 #if defined(TARGET_MIPS64)
1914 tcg_gen_ext32s_i64(ret
, arg
);
1916 tcg_gen_extrl_i64_i32(ret
, arg
);
1920 /* Sign-extract the high 32-bits to a target_long. */
1921 void gen_move_high32(TCGv ret
, TCGv_i64 arg
)
1923 #if defined(TARGET_MIPS64)
1924 tcg_gen_sari_i64(ret
, arg
, 32);
1926 tcg_gen_extrh_i64_i32(ret
, arg
);
1930 void check_cp0_enabled(DisasContext
*ctx
)
1932 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_CP0
))) {
1933 generate_exception_end(ctx
, EXCP_CpU
);
1937 void check_cp1_enabled(DisasContext
*ctx
)
1939 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_FPU
))) {
1940 generate_exception_err(ctx
, EXCP_CpU
, 1);
1945 * Verify that the processor is running with COP1X instructions enabled.
1946 * This is associated with the nabla symbol in the MIPS32 and MIPS64
1949 void check_cop1x(DisasContext
*ctx
)
1951 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_COP1X
))) {
1952 gen_reserved_instruction(ctx
);
1957 * Verify that the processor is running with 64-bit floating-point
1958 * operations enabled.
1960 void check_cp1_64bitmode(DisasContext
*ctx
)
1962 if (unlikely(~ctx
->hflags
& (MIPS_HFLAG_F64
| MIPS_HFLAG_COP1X
))) {
1963 gen_reserved_instruction(ctx
);
1968 * Verify if floating point register is valid; an operation is not defined
1969 * if bit 0 of any register specification is set and the FR bit in the
1970 * Status register equals zero, since the register numbers specify an
1971 * even-odd pair of adjacent coprocessor general registers. When the FR bit
1972 * in the Status register equals one, both even and odd register numbers
1973 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
1975 * Multiple 64 bit wide registers can be checked by calling
1976 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
1978 void check_cp1_registers(DisasContext
*ctx
, int regs
)
1980 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_F64
) && (regs
& 1))) {
1981 gen_reserved_instruction(ctx
);
1986 * Verify that the processor is running with DSP instructions enabled.
1987 * This is enabled by CP0 Status register MX(24) bit.
1989 static inline void check_dsp(DisasContext
*ctx
)
1991 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_DSP
))) {
1992 if (ctx
->insn_flags
& ASE_DSP
) {
1993 generate_exception_end(ctx
, EXCP_DSPDIS
);
1995 gen_reserved_instruction(ctx
);
2000 static inline void check_dsp_r2(DisasContext
*ctx
)
2002 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_DSP_R2
))) {
2003 if (ctx
->insn_flags
& ASE_DSP
) {
2004 generate_exception_end(ctx
, EXCP_DSPDIS
);
2006 gen_reserved_instruction(ctx
);
2011 static inline void check_dsp_r3(DisasContext
*ctx
)
2013 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_DSP_R3
))) {
2014 if (ctx
->insn_flags
& ASE_DSP
) {
2015 generate_exception_end(ctx
, EXCP_DSPDIS
);
2017 gen_reserved_instruction(ctx
);
2023 * This code generates a "reserved instruction" exception if the
2024 * CPU does not support the instruction set corresponding to flags.
2026 void check_insn(DisasContext
*ctx
, uint64_t flags
)
2028 if (unlikely(!(ctx
->insn_flags
& flags
))) {
2029 gen_reserved_instruction(ctx
);
2034 * This code generates a "reserved instruction" exception if the
2035 * CPU has corresponding flag set which indicates that the instruction
2038 static inline void check_insn_opc_removed(DisasContext
*ctx
, uint64_t flags
)
2040 if (unlikely(ctx
->insn_flags
& flags
)) {
2041 gen_reserved_instruction(ctx
);
2046 * The Linux kernel traps certain reserved instruction exceptions to
2047 * emulate the corresponding instructions. QEMU is the kernel in user
2048 * mode, so those traps are emulated by accepting the instructions.
2050 * A reserved instruction exception is generated for flagged CPUs if
2051 * QEMU runs in system mode.
2053 static inline void check_insn_opc_user_only(DisasContext
*ctx
, uint64_t flags
)
2055 #ifndef CONFIG_USER_ONLY
2056 check_insn_opc_removed(ctx
, flags
);
2061 * This code generates a "reserved instruction" exception if the
2062 * CPU does not support 64-bit paired-single (PS) floating point data type.
2064 static inline void check_ps(DisasContext
*ctx
)
2066 if (unlikely(!ctx
->ps
)) {
2067 generate_exception(ctx
, EXCP_RI
);
2069 check_cp1_64bitmode(ctx
);
2073 * This code generates a "reserved instruction" exception if cpu is not
2074 * 64-bit or 64-bit instructions are not enabled.
2076 void check_mips_64(DisasContext
*ctx
)
2078 if (unlikely((TARGET_LONG_BITS
!= 64) || !(ctx
->hflags
& MIPS_HFLAG_64
))) {
2079 gen_reserved_instruction(ctx
);
2083 #ifndef CONFIG_USER_ONLY
2084 static inline void check_mvh(DisasContext
*ctx
)
2086 if (unlikely(!ctx
->mvh
)) {
2087 generate_exception(ctx
, EXCP_RI
);
2093 * This code generates a "reserved instruction" exception if the
2094 * Config5 XNP bit is set.
2096 static inline void check_xnp(DisasContext
*ctx
)
2098 if (unlikely(ctx
->CP0_Config5
& (1 << CP0C5_XNP
))) {
2099 gen_reserved_instruction(ctx
);
2103 #ifndef CONFIG_USER_ONLY
2105 * This code generates a "reserved instruction" exception if the
2106 * Config3 PW bit is NOT set.
2108 static inline void check_pw(DisasContext
*ctx
)
2110 if (unlikely(!(ctx
->CP0_Config3
& (1 << CP0C3_PW
)))) {
2111 gen_reserved_instruction(ctx
);
2117 * This code generates a "reserved instruction" exception if the
2118 * Config3 MT bit is NOT set.
2120 static inline void check_mt(DisasContext
*ctx
)
2122 if (unlikely(!(ctx
->CP0_Config3
& (1 << CP0C3_MT
)))) {
2123 gen_reserved_instruction(ctx
);
2127 #ifndef CONFIG_USER_ONLY
2129 * This code generates a "coprocessor unusable" exception if CP0 is not
2130 * available, and, if that is not the case, generates a "reserved instruction"
2131 * exception if the Config5 MT bit is NOT set. This is needed for availability
2132 * control of some of MT ASE instructions.
2134 static inline void check_cp0_mt(DisasContext
*ctx
)
2136 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_CP0
))) {
2137 generate_exception_end(ctx
, EXCP_CpU
);
2139 if (unlikely(!(ctx
->CP0_Config3
& (1 << CP0C3_MT
)))) {
2140 gen_reserved_instruction(ctx
);
2147 * This code generates a "reserved instruction" exception if the
2148 * Config5 NMS bit is set.
2150 static inline void check_nms(DisasContext
*ctx
)
2152 if (unlikely(ctx
->CP0_Config5
& (1 << CP0C5_NMS
))) {
2153 gen_reserved_instruction(ctx
);
2158 * This code generates a "reserved instruction" exception if the
2159 * Config5 NMS bit is set, and Config1 DL, Config1 IL, Config2 SL,
2160 * Config2 TL, and Config5 L2C are unset.
2162 static inline void check_nms_dl_il_sl_tl_l2c(DisasContext
*ctx
)
2164 if (unlikely((ctx
->CP0_Config5
& (1 << CP0C5_NMS
)) &&
2165 !(ctx
->CP0_Config1
& (1 << CP0C1_DL
)) &&
2166 !(ctx
->CP0_Config1
& (1 << CP0C1_IL
)) &&
2167 !(ctx
->CP0_Config2
& (1 << CP0C2_SL
)) &&
2168 !(ctx
->CP0_Config2
& (1 << CP0C2_TL
)) &&
2169 !(ctx
->CP0_Config5
& (1 << CP0C5_L2C
)))) {
2170 gen_reserved_instruction(ctx
);
2175 * This code generates a "reserved instruction" exception if the
2176 * Config5 EVA bit is NOT set.
2178 static inline void check_eva(DisasContext
*ctx
)
2180 if (unlikely(!(ctx
->CP0_Config5
& (1 << CP0C5_EVA
)))) {
2181 gen_reserved_instruction(ctx
);
2187 * Define small wrappers for gen_load_fpr* so that we have a uniform
2188 * calling interface for 32 and 64-bit FPRs. No sense in changing
2189 * all callers for gen_load_fpr32 when we need the CTX parameter for
2192 #define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(ctx, x, y)
2193 #define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
2194 #define FOP_CONDS(type, abs, fmt, ifmt, bits) \
2195 static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
2196 int ft, int fs, int cc) \
2198 TCGv_i##bits fp0 = tcg_temp_new_i##bits(); \
2199 TCGv_i##bits fp1 = tcg_temp_new_i##bits(); \
2208 check_cp1_registers(ctx, fs | ft); \
2216 gen_ldcmp_fpr##bits(ctx, fp0, fs); \
2217 gen_ldcmp_fpr##bits(ctx, fp1, ft); \
2220 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); \
2223 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); \
2226 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); \
2229 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); \
2232 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); \
2235 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); \
2238 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); \
2241 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); \
2244 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); \
2247 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); \
2250 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); \
2253 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); \
2256 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); \
2259 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); \
2262 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); \
2265 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); \
2270 tcg_temp_free_i##bits(fp0); \
2271 tcg_temp_free_i##bits(fp1); \
2274 FOP_CONDS(, 0, d
, FMT_D
, 64)
2275 FOP_CONDS(abs
, 1, d
, FMT_D
, 64)
2276 FOP_CONDS(, 0, s
, FMT_S
, 32)
2277 FOP_CONDS(abs
, 1, s
, FMT_S
, 32)
2278 FOP_CONDS(, 0, ps
, FMT_PS
, 64)
2279 FOP_CONDS(abs
, 1, ps
, FMT_PS
, 64)
2282 #define FOP_CONDNS(fmt, ifmt, bits, STORE) \
2283 static inline void gen_r6_cmp_ ## fmt(DisasContext *ctx, int n, \
2284 int ft, int fs, int fd) \
2286 TCGv_i ## bits fp0 = tcg_temp_new_i ## bits(); \
2287 TCGv_i ## bits fp1 = tcg_temp_new_i ## bits(); \
2288 if (ifmt == FMT_D) { \
2289 check_cp1_registers(ctx, fs | ft | fd); \
2291 gen_ldcmp_fpr ## bits(ctx, fp0, fs); \
2292 gen_ldcmp_fpr ## bits(ctx, fp1, ft); \
2295 gen_helper_r6_cmp_ ## fmt ## _af(fp0, cpu_env, fp0, fp1); \
2298 gen_helper_r6_cmp_ ## fmt ## _un(fp0, cpu_env, fp0, fp1); \
2301 gen_helper_r6_cmp_ ## fmt ## _eq(fp0, cpu_env, fp0, fp1); \
2304 gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, cpu_env, fp0, fp1); \
2307 gen_helper_r6_cmp_ ## fmt ## _lt(fp0, cpu_env, fp0, fp1); \
2310 gen_helper_r6_cmp_ ## fmt ## _ult(fp0, cpu_env, fp0, fp1); \
2313 gen_helper_r6_cmp_ ## fmt ## _le(fp0, cpu_env, fp0, fp1); \
2316 gen_helper_r6_cmp_ ## fmt ## _ule(fp0, cpu_env, fp0, fp1); \
2319 gen_helper_r6_cmp_ ## fmt ## _saf(fp0, cpu_env, fp0, fp1); \
2322 gen_helper_r6_cmp_ ## fmt ## _sun(fp0, cpu_env, fp0, fp1); \
2325 gen_helper_r6_cmp_ ## fmt ## _seq(fp0, cpu_env, fp0, fp1); \
2328 gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, cpu_env, fp0, fp1); \
2331 gen_helper_r6_cmp_ ## fmt ## _slt(fp0, cpu_env, fp0, fp1); \
2334 gen_helper_r6_cmp_ ## fmt ## _sult(fp0, cpu_env, fp0, fp1); \
2337 gen_helper_r6_cmp_ ## fmt ## _sle(fp0, cpu_env, fp0, fp1); \
2340 gen_helper_r6_cmp_ ## fmt ## _sule(fp0, cpu_env, fp0, fp1); \
2343 gen_helper_r6_cmp_ ## fmt ## _or(fp0, cpu_env, fp0, fp1); \
2346 gen_helper_r6_cmp_ ## fmt ## _une(fp0, cpu_env, fp0, fp1); \
2349 gen_helper_r6_cmp_ ## fmt ## _ne(fp0, cpu_env, fp0, fp1); \
2352 gen_helper_r6_cmp_ ## fmt ## _sor(fp0, cpu_env, fp0, fp1); \
2355 gen_helper_r6_cmp_ ## fmt ## _sune(fp0, cpu_env, fp0, fp1); \
2358 gen_helper_r6_cmp_ ## fmt ## _sne(fp0, cpu_env, fp0, fp1); \
2364 tcg_temp_free_i ## bits(fp0); \
2365 tcg_temp_free_i ## bits(fp1); \
2368 FOP_CONDNS(d
, FMT_D
, 64, gen_store_fpr64(ctx
, fp0
, fd
))
2369 FOP_CONDNS(s
, FMT_S
, 32, gen_store_fpr32(ctx
, fp0
, fd
))
2371 #undef gen_ldcmp_fpr32
2372 #undef gen_ldcmp_fpr64
2374 /* load/store instructions. */
2375 #ifdef CONFIG_USER_ONLY
2376 #define OP_LD_ATOMIC(insn, fname) \
2377 static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \
2378 DisasContext *ctx) \
2380 TCGv t0 = tcg_temp_new(); \
2381 tcg_gen_mov_tl(t0, arg1); \
2382 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
2383 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
2384 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
2385 tcg_temp_free(t0); \
2388 #define OP_LD_ATOMIC(insn, fname) \
2389 static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \
2390 DisasContext *ctx) \
2392 gen_helper_1e1i(insn, ret, arg1, mem_idx); \
2395 OP_LD_ATOMIC(ll
, ld32s
);
2396 #if defined(TARGET_MIPS64)
2397 OP_LD_ATOMIC(lld
, ld64
);
2401 void gen_base_offset_addr(DisasContext
*ctx
, TCGv addr
, int base
, int offset
)
2404 tcg_gen_movi_tl(addr
, offset
);
2405 } else if (offset
== 0) {
2406 gen_load_gpr(addr
, base
);
2408 tcg_gen_movi_tl(addr
, offset
);
2409 gen_op_addr_add(ctx
, addr
, cpu_gpr
[base
], addr
);
2413 static target_ulong
pc_relative_pc(DisasContext
*ctx
)
2415 target_ulong pc
= ctx
->base
.pc_next
;
2417 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
2418 int branch_bytes
= ctx
->hflags
& MIPS_HFLAG_BDS16
? 2 : 4;
2423 pc
&= ~(target_ulong
)3;
2428 static void gen_ld(DisasContext
*ctx
, uint32_t opc
,
2429 int rt
, int base
, int offset
)
2432 int mem_idx
= ctx
->mem_idx
;
2434 if (rt
== 0 && ctx
->insn_flags
& (INSN_LOONGSON2E
| INSN_LOONGSON2F
|
2437 * Loongson CPU uses a load to zero register for prefetch.
2438 * We emulate it as a NOP. On other CPU we must perform the
2439 * actual memory access.
2444 t0
= tcg_temp_new();
2445 gen_base_offset_addr(ctx
, t0
, base
, offset
);
2448 #if defined(TARGET_MIPS64)
2450 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEUL
|
2451 ctx
->default_tcg_memop_mask
);
2452 gen_store_gpr(t0
, rt
);
2455 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEQ
|
2456 ctx
->default_tcg_memop_mask
);
2457 gen_store_gpr(t0
, rt
);
2461 op_ld_lld(t0
, t0
, mem_idx
, ctx
);
2462 gen_store_gpr(t0
, rt
);
2465 t1
= tcg_temp_new();
2467 * Do a byte access to possibly trigger a page
2468 * fault with the unaligned address.
2470 tcg_gen_qemu_ld_tl(t1
, t0
, mem_idx
, MO_UB
);
2471 tcg_gen_andi_tl(t1
, t0
, 7);
2472 #ifndef TARGET_WORDS_BIGENDIAN
2473 tcg_gen_xori_tl(t1
, t1
, 7);
2475 tcg_gen_shli_tl(t1
, t1
, 3);
2476 tcg_gen_andi_tl(t0
, t0
, ~7);
2477 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEQ
);
2478 tcg_gen_shl_tl(t0
, t0
, t1
);
2479 t2
= tcg_const_tl(-1);
2480 tcg_gen_shl_tl(t2
, t2
, t1
);
2481 gen_load_gpr(t1
, rt
);
2482 tcg_gen_andc_tl(t1
, t1
, t2
);
2484 tcg_gen_or_tl(t0
, t0
, t1
);
2486 gen_store_gpr(t0
, rt
);
2489 t1
= tcg_temp_new();
2491 * Do a byte access to possibly trigger a page
2492 * fault with the unaligned address.
2494 tcg_gen_qemu_ld_tl(t1
, t0
, mem_idx
, MO_UB
);
2495 tcg_gen_andi_tl(t1
, t0
, 7);
2496 #ifdef TARGET_WORDS_BIGENDIAN
2497 tcg_gen_xori_tl(t1
, t1
, 7);
2499 tcg_gen_shli_tl(t1
, t1
, 3);
2500 tcg_gen_andi_tl(t0
, t0
, ~7);
2501 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEQ
);
2502 tcg_gen_shr_tl(t0
, t0
, t1
);
2503 tcg_gen_xori_tl(t1
, t1
, 63);
2504 t2
= tcg_const_tl(0xfffffffffffffffeull
);
2505 tcg_gen_shl_tl(t2
, t2
, t1
);
2506 gen_load_gpr(t1
, rt
);
2507 tcg_gen_and_tl(t1
, t1
, t2
);
2509 tcg_gen_or_tl(t0
, t0
, t1
);
2511 gen_store_gpr(t0
, rt
);
2514 t1
= tcg_const_tl(pc_relative_pc(ctx
));
2515 gen_op_addr_add(ctx
, t0
, t0
, t1
);
2517 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEQ
);
2518 gen_store_gpr(t0
, rt
);
2522 t1
= tcg_const_tl(pc_relative_pc(ctx
));
2523 gen_op_addr_add(ctx
, t0
, t0
, t1
);
2525 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TESL
);
2526 gen_store_gpr(t0
, rt
);
2529 mem_idx
= MIPS_HFLAG_UM
;
2532 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TESL
|
2533 ctx
->default_tcg_memop_mask
);
2534 gen_store_gpr(t0
, rt
);
2537 mem_idx
= MIPS_HFLAG_UM
;
2540 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TESW
|
2541 ctx
->default_tcg_memop_mask
);
2542 gen_store_gpr(t0
, rt
);
2545 mem_idx
= MIPS_HFLAG_UM
;
2548 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEUW
|
2549 ctx
->default_tcg_memop_mask
);
2550 gen_store_gpr(t0
, rt
);
2553 mem_idx
= MIPS_HFLAG_UM
;
2556 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_SB
);
2557 gen_store_gpr(t0
, rt
);
2560 mem_idx
= MIPS_HFLAG_UM
;
2563 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_UB
);
2564 gen_store_gpr(t0
, rt
);
2567 mem_idx
= MIPS_HFLAG_UM
;
2570 t1
= tcg_temp_new();
2572 * Do a byte access to possibly trigger a page
2573 * fault with the unaligned address.
2575 tcg_gen_qemu_ld_tl(t1
, t0
, mem_idx
, MO_UB
);
2576 tcg_gen_andi_tl(t1
, t0
, 3);
2577 #ifndef TARGET_WORDS_BIGENDIAN
2578 tcg_gen_xori_tl(t1
, t1
, 3);
2580 tcg_gen_shli_tl(t1
, t1
, 3);
2581 tcg_gen_andi_tl(t0
, t0
, ~3);
2582 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEUL
);
2583 tcg_gen_shl_tl(t0
, t0
, t1
);
2584 t2
= tcg_const_tl(-1);
2585 tcg_gen_shl_tl(t2
, t2
, t1
);
2586 gen_load_gpr(t1
, rt
);
2587 tcg_gen_andc_tl(t1
, t1
, t2
);
2589 tcg_gen_or_tl(t0
, t0
, t1
);
2591 tcg_gen_ext32s_tl(t0
, t0
);
2592 gen_store_gpr(t0
, rt
);
2595 mem_idx
= MIPS_HFLAG_UM
;
2598 t1
= tcg_temp_new();
2600 * Do a byte access to possibly trigger a page
2601 * fault with the unaligned address.
2603 tcg_gen_qemu_ld_tl(t1
, t0
, mem_idx
, MO_UB
);
2604 tcg_gen_andi_tl(t1
, t0
, 3);
2605 #ifdef TARGET_WORDS_BIGENDIAN
2606 tcg_gen_xori_tl(t1
, t1
, 3);
2608 tcg_gen_shli_tl(t1
, t1
, 3);
2609 tcg_gen_andi_tl(t0
, t0
, ~3);
2610 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEUL
);
2611 tcg_gen_shr_tl(t0
, t0
, t1
);
2612 tcg_gen_xori_tl(t1
, t1
, 31);
2613 t2
= tcg_const_tl(0xfffffffeull
);
2614 tcg_gen_shl_tl(t2
, t2
, t1
);
2615 gen_load_gpr(t1
, rt
);
2616 tcg_gen_and_tl(t1
, t1
, t2
);
2618 tcg_gen_or_tl(t0
, t0
, t1
);
2620 tcg_gen_ext32s_tl(t0
, t0
);
2621 gen_store_gpr(t0
, rt
);
2624 mem_idx
= MIPS_HFLAG_UM
;
2628 op_ld_ll(t0
, t0
, mem_idx
, ctx
);
2629 gen_store_gpr(t0
, rt
);
2635 static void gen_llwp(DisasContext
*ctx
, uint32_t base
, int16_t offset
,
2636 uint32_t reg1
, uint32_t reg2
)
2638 TCGv taddr
= tcg_temp_new();
2639 TCGv_i64 tval
= tcg_temp_new_i64();
2640 TCGv tmp1
= tcg_temp_new();
2641 TCGv tmp2
= tcg_temp_new();
2643 gen_base_offset_addr(ctx
, taddr
, base
, offset
);
2644 tcg_gen_qemu_ld64(tval
, taddr
, ctx
->mem_idx
);
2645 #ifdef TARGET_WORDS_BIGENDIAN
2646 tcg_gen_extr_i64_tl(tmp2
, tmp1
, tval
);
2648 tcg_gen_extr_i64_tl(tmp1
, tmp2
, tval
);
2650 gen_store_gpr(tmp1
, reg1
);
2651 tcg_temp_free(tmp1
);
2652 gen_store_gpr(tmp2
, reg2
);
2653 tcg_temp_free(tmp2
);
2654 tcg_gen_st_i64(tval
, cpu_env
, offsetof(CPUMIPSState
, llval_wp
));
2655 tcg_temp_free_i64(tval
);
2656 tcg_gen_st_tl(taddr
, cpu_env
, offsetof(CPUMIPSState
, lladdr
));
2657 tcg_temp_free(taddr
);
2661 static void gen_st(DisasContext
*ctx
, uint32_t opc
, int rt
,
2662 int base
, int offset
)
2664 TCGv t0
= tcg_temp_new();
2665 TCGv t1
= tcg_temp_new();
2666 int mem_idx
= ctx
->mem_idx
;
2668 gen_base_offset_addr(ctx
, t0
, base
, offset
);
2669 gen_load_gpr(t1
, rt
);
2671 #if defined(TARGET_MIPS64)
2673 tcg_gen_qemu_st_tl(t1
, t0
, mem_idx
, MO_TEQ
|
2674 ctx
->default_tcg_memop_mask
);
2677 gen_helper_0e2i(sdl
, t1
, t0
, mem_idx
);
2680 gen_helper_0e2i(sdr
, t1
, t0
, mem_idx
);
2684 mem_idx
= MIPS_HFLAG_UM
;
2687 tcg_gen_qemu_st_tl(t1
, t0
, mem_idx
, MO_TEUL
|
2688 ctx
->default_tcg_memop_mask
);
2691 mem_idx
= MIPS_HFLAG_UM
;
2694 tcg_gen_qemu_st_tl(t1
, t0
, mem_idx
, MO_TEUW
|
2695 ctx
->default_tcg_memop_mask
);
2698 mem_idx
= MIPS_HFLAG_UM
;
2701 tcg_gen_qemu_st_tl(t1
, t0
, mem_idx
, MO_8
);
2704 mem_idx
= MIPS_HFLAG_UM
;
2707 gen_helper_0e2i(swl
, t1
, t0
, mem_idx
);
2710 mem_idx
= MIPS_HFLAG_UM
;
2713 gen_helper_0e2i(swr
, t1
, t0
, mem_idx
);
2721 /* Store conditional */
2722 static void gen_st_cond(DisasContext
*ctx
, int rt
, int base
, int offset
,
2723 MemOp tcg_mo
, bool eva
)
2726 TCGLabel
*l1
= gen_new_label();
2727 TCGLabel
*done
= gen_new_label();
2729 t0
= tcg_temp_new();
2730 addr
= tcg_temp_new();
2731 /* compare the address against that of the preceding LL */
2732 gen_base_offset_addr(ctx
, addr
, base
, offset
);
2733 tcg_gen_brcond_tl(TCG_COND_EQ
, addr
, cpu_lladdr
, l1
);
2734 tcg_temp_free(addr
);
2735 tcg_gen_movi_tl(t0
, 0);
2736 gen_store_gpr(t0
, rt
);
2740 /* generate cmpxchg */
2741 val
= tcg_temp_new();
2742 gen_load_gpr(val
, rt
);
2743 tcg_gen_atomic_cmpxchg_tl(t0
, cpu_lladdr
, cpu_llval
, val
,
2744 eva
? MIPS_HFLAG_UM
: ctx
->mem_idx
, tcg_mo
);
2745 tcg_gen_setcond_tl(TCG_COND_EQ
, t0
, t0
, cpu_llval
);
2746 gen_store_gpr(t0
, rt
);
2749 gen_set_label(done
);
2754 static void gen_scwp(DisasContext
*ctx
, uint32_t base
, int16_t offset
,
2755 uint32_t reg1
, uint32_t reg2
, bool eva
)
2757 TCGv taddr
= tcg_temp_local_new();
2758 TCGv lladdr
= tcg_temp_local_new();
2759 TCGv_i64 tval
= tcg_temp_new_i64();
2760 TCGv_i64 llval
= tcg_temp_new_i64();
2761 TCGv_i64 val
= tcg_temp_new_i64();
2762 TCGv tmp1
= tcg_temp_new();
2763 TCGv tmp2
= tcg_temp_new();
2764 TCGLabel
*lab_fail
= gen_new_label();
2765 TCGLabel
*lab_done
= gen_new_label();
2767 gen_base_offset_addr(ctx
, taddr
, base
, offset
);
2769 tcg_gen_ld_tl(lladdr
, cpu_env
, offsetof(CPUMIPSState
, lladdr
));
2770 tcg_gen_brcond_tl(TCG_COND_NE
, taddr
, lladdr
, lab_fail
);
2772 gen_load_gpr(tmp1
, reg1
);
2773 gen_load_gpr(tmp2
, reg2
);
2775 #ifdef TARGET_WORDS_BIGENDIAN
2776 tcg_gen_concat_tl_i64(tval
, tmp2
, tmp1
);
2778 tcg_gen_concat_tl_i64(tval
, tmp1
, tmp2
);
2781 tcg_gen_ld_i64(llval
, cpu_env
, offsetof(CPUMIPSState
, llval_wp
));
2782 tcg_gen_atomic_cmpxchg_i64(val
, taddr
, llval
, tval
,
2783 eva
? MIPS_HFLAG_UM
: ctx
->mem_idx
, MO_64
);
2785 tcg_gen_movi_tl(cpu_gpr
[reg1
], 1);
2787 tcg_gen_brcond_i64(TCG_COND_EQ
, val
, llval
, lab_done
);
2789 gen_set_label(lab_fail
);
2792 tcg_gen_movi_tl(cpu_gpr
[reg1
], 0);
2794 gen_set_label(lab_done
);
2795 tcg_gen_movi_tl(lladdr
, -1);
2796 tcg_gen_st_tl(lladdr
, cpu_env
, offsetof(CPUMIPSState
, lladdr
));
2799 /* Load and store */
2800 static void gen_flt_ldst(DisasContext
*ctx
, uint32_t opc
, int ft
,
2804 * Don't do NOP if destination is zero: we must perform the actual
2810 TCGv_i32 fp0
= tcg_temp_new_i32();
2811 tcg_gen_qemu_ld_i32(fp0
, t0
, ctx
->mem_idx
, MO_TESL
|
2812 ctx
->default_tcg_memop_mask
);
2813 gen_store_fpr32(ctx
, fp0
, ft
);
2814 tcg_temp_free_i32(fp0
);
2819 TCGv_i32 fp0
= tcg_temp_new_i32();
2820 gen_load_fpr32(ctx
, fp0
, ft
);
2821 tcg_gen_qemu_st_i32(fp0
, t0
, ctx
->mem_idx
, MO_TEUL
|
2822 ctx
->default_tcg_memop_mask
);
2823 tcg_temp_free_i32(fp0
);
2828 TCGv_i64 fp0
= tcg_temp_new_i64();
2829 tcg_gen_qemu_ld_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
|
2830 ctx
->default_tcg_memop_mask
);
2831 gen_store_fpr64(ctx
, fp0
, ft
);
2832 tcg_temp_free_i64(fp0
);
2837 TCGv_i64 fp0
= tcg_temp_new_i64();
2838 gen_load_fpr64(ctx
, fp0
, ft
);
2839 tcg_gen_qemu_st_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
|
2840 ctx
->default_tcg_memop_mask
);
2841 tcg_temp_free_i64(fp0
);
2845 MIPS_INVAL("flt_ldst");
2846 gen_reserved_instruction(ctx
);
2851 static void gen_cop1_ldst(DisasContext
*ctx
, uint32_t op
, int rt
,
2852 int rs
, int16_t imm
)
2854 TCGv t0
= tcg_temp_new();
2856 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
2857 check_cp1_enabled(ctx
);
2861 check_insn(ctx
, ISA_MIPS2
);
2864 gen_base_offset_addr(ctx
, t0
, rs
, imm
);
2865 gen_flt_ldst(ctx
, op
, rt
, t0
);
2868 generate_exception_err(ctx
, EXCP_CpU
, 1);
2873 /* Arithmetic with immediate operand */
2874 static void gen_arith_imm(DisasContext
*ctx
, uint32_t opc
,
2875 int rt
, int rs
, int imm
)
2877 target_ulong uimm
= (target_long
)imm
; /* Sign extend to 32/64 bits */
2879 if (rt
== 0 && opc
!= OPC_ADDI
&& opc
!= OPC_DADDI
) {
2881 * If no destination, treat it as a NOP.
2882 * For addi, we must generate the overflow exception when needed.
2889 TCGv t0
= tcg_temp_local_new();
2890 TCGv t1
= tcg_temp_new();
2891 TCGv t2
= tcg_temp_new();
2892 TCGLabel
*l1
= gen_new_label();
2894 gen_load_gpr(t1
, rs
);
2895 tcg_gen_addi_tl(t0
, t1
, uimm
);
2896 tcg_gen_ext32s_tl(t0
, t0
);
2898 tcg_gen_xori_tl(t1
, t1
, ~uimm
);
2899 tcg_gen_xori_tl(t2
, t0
, uimm
);
2900 tcg_gen_and_tl(t1
, t1
, t2
);
2902 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2904 /* operands of same sign, result different sign */
2905 generate_exception(ctx
, EXCP_OVERFLOW
);
2907 tcg_gen_ext32s_tl(t0
, t0
);
2908 gen_store_gpr(t0
, rt
);
2914 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
2915 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
2917 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
2920 #if defined(TARGET_MIPS64)
2923 TCGv t0
= tcg_temp_local_new();
2924 TCGv t1
= tcg_temp_new();
2925 TCGv t2
= tcg_temp_new();
2926 TCGLabel
*l1
= gen_new_label();
2928 gen_load_gpr(t1
, rs
);
2929 tcg_gen_addi_tl(t0
, t1
, uimm
);
2931 tcg_gen_xori_tl(t1
, t1
, ~uimm
);
2932 tcg_gen_xori_tl(t2
, t0
, uimm
);
2933 tcg_gen_and_tl(t1
, t1
, t2
);
2935 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2937 /* operands of same sign, result different sign */
2938 generate_exception(ctx
, EXCP_OVERFLOW
);
2940 gen_store_gpr(t0
, rt
);
2946 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
2948 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
2955 /* Logic with immediate operand */
2956 static void gen_logic_imm(DisasContext
*ctx
, uint32_t opc
,
2957 int rt
, int rs
, int16_t imm
)
2962 /* If no destination, treat it as a NOP. */
2965 uimm
= (uint16_t)imm
;
2968 if (likely(rs
!= 0)) {
2969 tcg_gen_andi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
2971 tcg_gen_movi_tl(cpu_gpr
[rt
], 0);
2976 tcg_gen_ori_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
2978 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
2982 if (likely(rs
!= 0)) {
2983 tcg_gen_xori_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
2985 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
2989 if (rs
!= 0 && (ctx
->insn_flags
& ISA_MIPS_R6
)) {
2991 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], imm
<< 16);
2992 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
2994 tcg_gen_movi_tl(cpu_gpr
[rt
], imm
<< 16);
3003 /* Set on less than with immediate operand */
3004 static void gen_slt_imm(DisasContext
*ctx
, uint32_t opc
,
3005 int rt
, int rs
, int16_t imm
)
3007 target_ulong uimm
= (target_long
)imm
; /* Sign extend to 32/64 bits */
3011 /* If no destination, treat it as a NOP. */
3014 t0
= tcg_temp_new();
3015 gen_load_gpr(t0
, rs
);
3018 tcg_gen_setcondi_tl(TCG_COND_LT
, cpu_gpr
[rt
], t0
, uimm
);
3021 tcg_gen_setcondi_tl(TCG_COND_LTU
, cpu_gpr
[rt
], t0
, uimm
);
3027 /* Shifts with immediate operand */
3028 static void gen_shift_imm(DisasContext
*ctx
, uint32_t opc
,
3029 int rt
, int rs
, int16_t imm
)
3031 target_ulong uimm
= ((uint16_t)imm
) & 0x1f;
3035 /* If no destination, treat it as a NOP. */
3039 t0
= tcg_temp_new();
3040 gen_load_gpr(t0
, rs
);
3043 tcg_gen_shli_tl(t0
, t0
, uimm
);
3044 tcg_gen_ext32s_tl(cpu_gpr
[rt
], t0
);
3047 tcg_gen_sari_tl(cpu_gpr
[rt
], t0
, uimm
);
3051 tcg_gen_ext32u_tl(t0
, t0
);
3052 tcg_gen_shri_tl(cpu_gpr
[rt
], t0
, uimm
);
3054 tcg_gen_ext32s_tl(cpu_gpr
[rt
], t0
);
3059 TCGv_i32 t1
= tcg_temp_new_i32();
3061 tcg_gen_trunc_tl_i32(t1
, t0
);
3062 tcg_gen_rotri_i32(t1
, t1
, uimm
);
3063 tcg_gen_ext_i32_tl(cpu_gpr
[rt
], t1
);
3064 tcg_temp_free_i32(t1
);
3066 tcg_gen_ext32s_tl(cpu_gpr
[rt
], t0
);
3069 #if defined(TARGET_MIPS64)
3071 tcg_gen_shli_tl(cpu_gpr
[rt
], t0
, uimm
);
3074 tcg_gen_sari_tl(cpu_gpr
[rt
], t0
, uimm
);
3077 tcg_gen_shri_tl(cpu_gpr
[rt
], t0
, uimm
);
3081 tcg_gen_rotri_tl(cpu_gpr
[rt
], t0
, uimm
);
3083 tcg_gen_mov_tl(cpu_gpr
[rt
], t0
);
3087 tcg_gen_shli_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
3090 tcg_gen_sari_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
3093 tcg_gen_shri_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
3096 tcg_gen_rotri_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
3104 static void gen_arith(DisasContext
*ctx
, uint32_t opc
,
3105 int rd
, int rs
, int rt
)
3107 if (rd
== 0 && opc
!= OPC_ADD
&& opc
!= OPC_SUB
3108 && opc
!= OPC_DADD
&& opc
!= OPC_DSUB
) {
3110 * If no destination, treat it as a NOP.
3111 * For add & sub, we must generate the overflow exception when needed.
3119 TCGv t0
= tcg_temp_local_new();
3120 TCGv t1
= tcg_temp_new();
3121 TCGv t2
= tcg_temp_new();
3122 TCGLabel
*l1
= gen_new_label();
3124 gen_load_gpr(t1
, rs
);
3125 gen_load_gpr(t2
, rt
);
3126 tcg_gen_add_tl(t0
, t1
, t2
);
3127 tcg_gen_ext32s_tl(t0
, t0
);
3128 tcg_gen_xor_tl(t1
, t1
, t2
);
3129 tcg_gen_xor_tl(t2
, t0
, t2
);
3130 tcg_gen_andc_tl(t1
, t2
, t1
);
3132 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
3134 /* operands of same sign, result different sign */
3135 generate_exception(ctx
, EXCP_OVERFLOW
);
3137 gen_store_gpr(t0
, rd
);
3142 if (rs
!= 0 && rt
!= 0) {
3143 tcg_gen_add_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
3144 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3145 } else if (rs
== 0 && rt
!= 0) {
3146 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
3147 } else if (rs
!= 0 && rt
== 0) {
3148 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
3150 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3155 TCGv t0
= tcg_temp_local_new();
3156 TCGv t1
= tcg_temp_new();
3157 TCGv t2
= tcg_temp_new();
3158 TCGLabel
*l1
= gen_new_label();
3160 gen_load_gpr(t1
, rs
);
3161 gen_load_gpr(t2
, rt
);
3162 tcg_gen_sub_tl(t0
, t1
, t2
);
3163 tcg_gen_ext32s_tl(t0
, t0
);
3164 tcg_gen_xor_tl(t2
, t1
, t2
);
3165 tcg_gen_xor_tl(t1
, t0
, t1
);
3166 tcg_gen_and_tl(t1
, t1
, t2
);
3168 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
3171 * operands of different sign, first operand and the result
3174 generate_exception(ctx
, EXCP_OVERFLOW
);
3176 gen_store_gpr(t0
, rd
);
3181 if (rs
!= 0 && rt
!= 0) {
3182 tcg_gen_sub_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
3183 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3184 } else if (rs
== 0 && rt
!= 0) {
3185 tcg_gen_neg_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
3186 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3187 } else if (rs
!= 0 && rt
== 0) {
3188 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
3190 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3193 #if defined(TARGET_MIPS64)
3196 TCGv t0
= tcg_temp_local_new();
3197 TCGv t1
= tcg_temp_new();
3198 TCGv t2
= tcg_temp_new();
3199 TCGLabel
*l1
= gen_new_label();
3201 gen_load_gpr(t1
, rs
);
3202 gen_load_gpr(t2
, rt
);
3203 tcg_gen_add_tl(t0
, t1
, t2
);
3204 tcg_gen_xor_tl(t1
, t1
, t2
);
3205 tcg_gen_xor_tl(t2
, t0
, t2
);
3206 tcg_gen_andc_tl(t1
, t2
, t1
);
3208 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
3210 /* operands of same sign, result different sign */
3211 generate_exception(ctx
, EXCP_OVERFLOW
);
3213 gen_store_gpr(t0
, rd
);
3218 if (rs
!= 0 && rt
!= 0) {
3219 tcg_gen_add_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
3220 } else if (rs
== 0 && rt
!= 0) {
3221 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
3222 } else if (rs
!= 0 && rt
== 0) {
3223 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
3225 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3230 TCGv t0
= tcg_temp_local_new();
3231 TCGv t1
= tcg_temp_new();
3232 TCGv t2
= tcg_temp_new();
3233 TCGLabel
*l1
= gen_new_label();
3235 gen_load_gpr(t1
, rs
);
3236 gen_load_gpr(t2
, rt
);
3237 tcg_gen_sub_tl(t0
, t1
, t2
);
3238 tcg_gen_xor_tl(t2
, t1
, t2
);
3239 tcg_gen_xor_tl(t1
, t0
, t1
);
3240 tcg_gen_and_tl(t1
, t1
, t2
);
3242 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
3245 * Operands of different sign, first operand and result different
3248 generate_exception(ctx
, EXCP_OVERFLOW
);
3250 gen_store_gpr(t0
, rd
);
3255 if (rs
!= 0 && rt
!= 0) {
3256 tcg_gen_sub_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
3257 } else if (rs
== 0 && rt
!= 0) {
3258 tcg_gen_neg_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
3259 } else if (rs
!= 0 && rt
== 0) {
3260 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
3262 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3267 if (likely(rs
!= 0 && rt
!= 0)) {
3268 tcg_gen_mul_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
3269 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3271 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3277 /* Conditional move */
3278 static void gen_cond_move(DisasContext
*ctx
, uint32_t opc
,
3279 int rd
, int rs
, int rt
)
3284 /* If no destination, treat it as a NOP. */
3288 t0
= tcg_temp_new();
3289 gen_load_gpr(t0
, rt
);
3290 t1
= tcg_const_tl(0);
3291 t2
= tcg_temp_new();
3292 gen_load_gpr(t2
, rs
);
3295 tcg_gen_movcond_tl(TCG_COND_NE
, cpu_gpr
[rd
], t0
, t1
, t2
, cpu_gpr
[rd
]);
3298 tcg_gen_movcond_tl(TCG_COND_EQ
, cpu_gpr
[rd
], t0
, t1
, t2
, cpu_gpr
[rd
]);
3301 tcg_gen_movcond_tl(TCG_COND_NE
, cpu_gpr
[rd
], t0
, t1
, t2
, t1
);
3304 tcg_gen_movcond_tl(TCG_COND_EQ
, cpu_gpr
[rd
], t0
, t1
, t2
, t1
);
3313 static void gen_logic(DisasContext
*ctx
, uint32_t opc
,
3314 int rd
, int rs
, int rt
)
3317 /* If no destination, treat it as a NOP. */
3323 if (likely(rs
!= 0 && rt
!= 0)) {
3324 tcg_gen_and_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
3326 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3330 if (rs
!= 0 && rt
!= 0) {
3331 tcg_gen_nor_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
3332 } else if (rs
== 0 && rt
!= 0) {
3333 tcg_gen_not_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
3334 } else if (rs
!= 0 && rt
== 0) {
3335 tcg_gen_not_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
3337 tcg_gen_movi_tl(cpu_gpr
[rd
], ~((target_ulong
)0));
3341 if (likely(rs
!= 0 && rt
!= 0)) {
3342 tcg_gen_or_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
3343 } else if (rs
== 0 && rt
!= 0) {
3344 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
3345 } else if (rs
!= 0 && rt
== 0) {
3346 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
3348 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3352 if (likely(rs
!= 0 && rt
!= 0)) {
3353 tcg_gen_xor_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
3354 } else if (rs
== 0 && rt
!= 0) {
3355 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
3356 } else if (rs
!= 0 && rt
== 0) {
3357 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
3359 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3365 /* Set on lower than */
3366 static void gen_slt(DisasContext
*ctx
, uint32_t opc
,
3367 int rd
, int rs
, int rt
)
3372 /* If no destination, treat it as a NOP. */
3376 t0
= tcg_temp_new();
3377 t1
= tcg_temp_new();
3378 gen_load_gpr(t0
, rs
);
3379 gen_load_gpr(t1
, rt
);
3382 tcg_gen_setcond_tl(TCG_COND_LT
, cpu_gpr
[rd
], t0
, t1
);
3385 tcg_gen_setcond_tl(TCG_COND_LTU
, cpu_gpr
[rd
], t0
, t1
);
3393 static void gen_shift(DisasContext
*ctx
, uint32_t opc
,
3394 int rd
, int rs
, int rt
)
3400 * If no destination, treat it as a NOP.
3401 * For add & sub, we must generate the overflow exception when needed.
3406 t0
= tcg_temp_new();
3407 t1
= tcg_temp_new();
3408 gen_load_gpr(t0
, rs
);
3409 gen_load_gpr(t1
, rt
);
3412 tcg_gen_andi_tl(t0
, t0
, 0x1f);
3413 tcg_gen_shl_tl(t0
, t1
, t0
);
3414 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
3417 tcg_gen_andi_tl(t0
, t0
, 0x1f);
3418 tcg_gen_sar_tl(cpu_gpr
[rd
], t1
, t0
);
3421 tcg_gen_ext32u_tl(t1
, t1
);
3422 tcg_gen_andi_tl(t0
, t0
, 0x1f);
3423 tcg_gen_shr_tl(t0
, t1
, t0
);
3424 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
3428 TCGv_i32 t2
= tcg_temp_new_i32();
3429 TCGv_i32 t3
= tcg_temp_new_i32();
3431 tcg_gen_trunc_tl_i32(t2
, t0
);
3432 tcg_gen_trunc_tl_i32(t3
, t1
);
3433 tcg_gen_andi_i32(t2
, t2
, 0x1f);
3434 tcg_gen_rotr_i32(t2
, t3
, t2
);
3435 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
3436 tcg_temp_free_i32(t2
);
3437 tcg_temp_free_i32(t3
);
3440 #if defined(TARGET_MIPS64)
3442 tcg_gen_andi_tl(t0
, t0
, 0x3f);
3443 tcg_gen_shl_tl(cpu_gpr
[rd
], t1
, t0
);
3446 tcg_gen_andi_tl(t0
, t0
, 0x3f);
3447 tcg_gen_sar_tl(cpu_gpr
[rd
], t1
, t0
);
3450 tcg_gen_andi_tl(t0
, t0
, 0x3f);
3451 tcg_gen_shr_tl(cpu_gpr
[rd
], t1
, t0
);
3454 tcg_gen_andi_tl(t0
, t0
, 0x3f);
3455 tcg_gen_rotr_tl(cpu_gpr
[rd
], t1
, t0
);
3463 /* Arithmetic on HI/LO registers */
3464 static void gen_HILO(DisasContext
*ctx
, uint32_t opc
, int acc
, int reg
)
3466 if (reg
== 0 && (opc
== OPC_MFHI
|| opc
== OPC_MFLO
)) {
3477 #if defined(TARGET_MIPS64)
3479 tcg_gen_ext32s_tl(cpu_gpr
[reg
], cpu_HI
[acc
]);
3483 tcg_gen_mov_tl(cpu_gpr
[reg
], cpu_HI
[acc
]);
3487 #if defined(TARGET_MIPS64)
3489 tcg_gen_ext32s_tl(cpu_gpr
[reg
], cpu_LO
[acc
]);
3493 tcg_gen_mov_tl(cpu_gpr
[reg
], cpu_LO
[acc
]);
3498 #if defined(TARGET_MIPS64)
3500 tcg_gen_ext32s_tl(cpu_HI
[acc
], cpu_gpr
[reg
]);
3504 tcg_gen_mov_tl(cpu_HI
[acc
], cpu_gpr
[reg
]);
3507 tcg_gen_movi_tl(cpu_HI
[acc
], 0);
3512 #if defined(TARGET_MIPS64)
3514 tcg_gen_ext32s_tl(cpu_LO
[acc
], cpu_gpr
[reg
]);
3518 tcg_gen_mov_tl(cpu_LO
[acc
], cpu_gpr
[reg
]);
3521 tcg_gen_movi_tl(cpu_LO
[acc
], 0);
3527 static inline void gen_r6_ld(target_long addr
, int reg
, int memidx
,
3530 TCGv t0
= tcg_const_tl(addr
);
3531 tcg_gen_qemu_ld_tl(t0
, t0
, memidx
, memop
);
3532 gen_store_gpr(t0
, reg
);
3536 static inline void gen_pcrel(DisasContext
*ctx
, int opc
, target_ulong pc
,
3542 switch (MASK_OPC_PCREL_TOP2BITS(opc
)) {
3545 offset
= sextract32(ctx
->opcode
<< 2, 0, 21);
3546 addr
= addr_add(ctx
, pc
, offset
);
3547 tcg_gen_movi_tl(cpu_gpr
[rs
], addr
);
3551 offset
= sextract32(ctx
->opcode
<< 2, 0, 21);
3552 addr
= addr_add(ctx
, pc
, offset
);
3553 gen_r6_ld(addr
, rs
, ctx
->mem_idx
, MO_TESL
);
3555 #if defined(TARGET_MIPS64)
3558 offset
= sextract32(ctx
->opcode
<< 2, 0, 21);
3559 addr
= addr_add(ctx
, pc
, offset
);
3560 gen_r6_ld(addr
, rs
, ctx
->mem_idx
, MO_TEUL
);
3564 switch (MASK_OPC_PCREL_TOP5BITS(opc
)) {
3567 offset
= sextract32(ctx
->opcode
, 0, 16) << 16;
3568 addr
= addr_add(ctx
, pc
, offset
);
3569 tcg_gen_movi_tl(cpu_gpr
[rs
], addr
);
3574 offset
= sextract32(ctx
->opcode
, 0, 16) << 16;
3575 addr
= ~0xFFFF & addr_add(ctx
, pc
, offset
);
3576 tcg_gen_movi_tl(cpu_gpr
[rs
], addr
);
3579 #if defined(TARGET_MIPS64)
3580 case R6_OPC_LDPC
: /* bits 16 and 17 are part of immediate */
3581 case R6_OPC_LDPC
+ (1 << 16):
3582 case R6_OPC_LDPC
+ (2 << 16):
3583 case R6_OPC_LDPC
+ (3 << 16):
3585 offset
= sextract32(ctx
->opcode
<< 3, 0, 21);
3586 addr
= addr_add(ctx
, (pc
& ~0x7), offset
);
3587 gen_r6_ld(addr
, rs
, ctx
->mem_idx
, MO_TEQ
);
3591 MIPS_INVAL("OPC_PCREL");
3592 gen_reserved_instruction(ctx
);
3599 static void gen_r6_muldiv(DisasContext
*ctx
, int opc
, int rd
, int rs
, int rt
)
3608 t0
= tcg_temp_new();
3609 t1
= tcg_temp_new();
3611 gen_load_gpr(t0
, rs
);
3612 gen_load_gpr(t1
, rt
);
3617 TCGv t2
= tcg_temp_new();
3618 TCGv t3
= tcg_temp_new();
3619 tcg_gen_ext32s_tl(t0
, t0
);
3620 tcg_gen_ext32s_tl(t1
, t1
);
3621 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, INT_MIN
);
3622 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1);
3623 tcg_gen_and_tl(t2
, t2
, t3
);
3624 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
3625 tcg_gen_or_tl(t2
, t2
, t3
);
3626 tcg_gen_movi_tl(t3
, 0);
3627 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
3628 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
3629 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3636 TCGv t2
= tcg_temp_new();
3637 TCGv t3
= tcg_temp_new();
3638 tcg_gen_ext32s_tl(t0
, t0
);
3639 tcg_gen_ext32s_tl(t1
, t1
);
3640 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, INT_MIN
);
3641 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1);
3642 tcg_gen_and_tl(t2
, t2
, t3
);
3643 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
3644 tcg_gen_or_tl(t2
, t2
, t3
);
3645 tcg_gen_movi_tl(t3
, 0);
3646 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
3647 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
3648 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3655 TCGv t2
= tcg_const_tl(0);
3656 TCGv t3
= tcg_const_tl(1);
3657 tcg_gen_ext32u_tl(t0
, t0
);
3658 tcg_gen_ext32u_tl(t1
, t1
);
3659 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
3660 tcg_gen_divu_tl(cpu_gpr
[rd
], t0
, t1
);
3661 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3668 TCGv t2
= tcg_const_tl(0);
3669 TCGv t3
= tcg_const_tl(1);
3670 tcg_gen_ext32u_tl(t0
, t0
);
3671 tcg_gen_ext32u_tl(t1
, t1
);
3672 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
3673 tcg_gen_remu_tl(cpu_gpr
[rd
], t0
, t1
);
3674 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3681 TCGv_i32 t2
= tcg_temp_new_i32();
3682 TCGv_i32 t3
= tcg_temp_new_i32();
3683 tcg_gen_trunc_tl_i32(t2
, t0
);
3684 tcg_gen_trunc_tl_i32(t3
, t1
);
3685 tcg_gen_mul_i32(t2
, t2
, t3
);
3686 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
3687 tcg_temp_free_i32(t2
);
3688 tcg_temp_free_i32(t3
);
3693 TCGv_i32 t2
= tcg_temp_new_i32();
3694 TCGv_i32 t3
= tcg_temp_new_i32();
3695 tcg_gen_trunc_tl_i32(t2
, t0
);
3696 tcg_gen_trunc_tl_i32(t3
, t1
);
3697 tcg_gen_muls2_i32(t2
, t3
, t2
, t3
);
3698 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t3
);
3699 tcg_temp_free_i32(t2
);
3700 tcg_temp_free_i32(t3
);
3705 TCGv_i32 t2
= tcg_temp_new_i32();
3706 TCGv_i32 t3
= tcg_temp_new_i32();
3707 tcg_gen_trunc_tl_i32(t2
, t0
);
3708 tcg_gen_trunc_tl_i32(t3
, t1
);
3709 tcg_gen_mul_i32(t2
, t2
, t3
);
3710 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
3711 tcg_temp_free_i32(t2
);
3712 tcg_temp_free_i32(t3
);
3717 TCGv_i32 t2
= tcg_temp_new_i32();
3718 TCGv_i32 t3
= tcg_temp_new_i32();
3719 tcg_gen_trunc_tl_i32(t2
, t0
);
3720 tcg_gen_trunc_tl_i32(t3
, t1
);
3721 tcg_gen_mulu2_i32(t2
, t3
, t2
, t3
);
3722 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t3
);
3723 tcg_temp_free_i32(t2
);
3724 tcg_temp_free_i32(t3
);
3727 #if defined(TARGET_MIPS64)
3730 TCGv t2
= tcg_temp_new();
3731 TCGv t3
= tcg_temp_new();
3732 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, -1LL << 63);
3733 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1LL);
3734 tcg_gen_and_tl(t2
, t2
, t3
);
3735 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
3736 tcg_gen_or_tl(t2
, t2
, t3
);
3737 tcg_gen_movi_tl(t3
, 0);
3738 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
3739 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
3746 TCGv t2
= tcg_temp_new();
3747 TCGv t3
= tcg_temp_new();
3748 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, -1LL << 63);
3749 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1LL);
3750 tcg_gen_and_tl(t2
, t2
, t3
);
3751 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
3752 tcg_gen_or_tl(t2
, t2
, t3
);
3753 tcg_gen_movi_tl(t3
, 0);
3754 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
3755 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
3762 TCGv t2
= tcg_const_tl(0);
3763 TCGv t3
= tcg_const_tl(1);
3764 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
3765 tcg_gen_divu_i64(cpu_gpr
[rd
], t0
, t1
);
3772 TCGv t2
= tcg_const_tl(0);
3773 TCGv t3
= tcg_const_tl(1);
3774 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
3775 tcg_gen_remu_i64(cpu_gpr
[rd
], t0
, t1
);
3781 tcg_gen_mul_i64(cpu_gpr
[rd
], t0
, t1
);
3785 TCGv t2
= tcg_temp_new();
3786 tcg_gen_muls2_i64(t2
, cpu_gpr
[rd
], t0
, t1
);
3791 tcg_gen_mul_i64(cpu_gpr
[rd
], t0
, t1
);
3795 TCGv t2
= tcg_temp_new();
3796 tcg_gen_mulu2_i64(t2
, cpu_gpr
[rd
], t0
, t1
);
3802 MIPS_INVAL("r6 mul/div");
3803 gen_reserved_instruction(ctx
);
3811 #if defined(TARGET_MIPS64)
3812 static void gen_div1_tx79(DisasContext
*ctx
, uint32_t opc
, int rs
, int rt
)
3816 t0
= tcg_temp_new();
3817 t1
= tcg_temp_new();
3819 gen_load_gpr(t0
, rs
);
3820 gen_load_gpr(t1
, rt
);
3825 TCGv t2
= tcg_temp_new();
3826 TCGv t3
= tcg_temp_new();
3827 tcg_gen_ext32s_tl(t0
, t0
);
3828 tcg_gen_ext32s_tl(t1
, t1
);
3829 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, INT_MIN
);
3830 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1);
3831 tcg_gen_and_tl(t2
, t2
, t3
);
3832 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
3833 tcg_gen_or_tl(t2
, t2
, t3
);
3834 tcg_gen_movi_tl(t3
, 0);
3835 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
3836 tcg_gen_div_tl(cpu_LO
[1], t0
, t1
);
3837 tcg_gen_rem_tl(cpu_HI
[1], t0
, t1
);
3838 tcg_gen_ext32s_tl(cpu_LO
[1], cpu_LO
[1]);
3839 tcg_gen_ext32s_tl(cpu_HI
[1], cpu_HI
[1]);
3846 TCGv t2
= tcg_const_tl(0);
3847 TCGv t3
= tcg_const_tl(1);
3848 tcg_gen_ext32u_tl(t0
, t0
);
3849 tcg_gen_ext32u_tl(t1
, t1
);
3850 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
3851 tcg_gen_divu_tl(cpu_LO
[1], t0
, t1
);
3852 tcg_gen_remu_tl(cpu_HI
[1], t0
, t1
);
3853 tcg_gen_ext32s_tl(cpu_LO
[1], cpu_LO
[1]);
3854 tcg_gen_ext32s_tl(cpu_HI
[1], cpu_HI
[1]);
3860 MIPS_INVAL("div1 TX79");
3861 gen_reserved_instruction(ctx
);
3870 static void gen_muldiv(DisasContext
*ctx
, uint32_t opc
,
3871 int acc
, int rs
, int rt
)
3875 t0
= tcg_temp_new();
3876 t1
= tcg_temp_new();
3878 gen_load_gpr(t0
, rs
);
3879 gen_load_gpr(t1
, rt
);
3888 TCGv t2
= tcg_temp_new();
3889 TCGv t3
= tcg_temp_new();
3890 tcg_gen_ext32s_tl(t0
, t0
);
3891 tcg_gen_ext32s_tl(t1
, t1
);
3892 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, INT_MIN
);
3893 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1);
3894 tcg_gen_and_tl(t2
, t2
, t3
);
3895 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
3896 tcg_gen_or_tl(t2
, t2
, t3
);
3897 tcg_gen_movi_tl(t3
, 0);
3898 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
3899 tcg_gen_div_tl(cpu_LO
[acc
], t0
, t1
);
3900 tcg_gen_rem_tl(cpu_HI
[acc
], t0
, t1
);
3901 tcg_gen_ext32s_tl(cpu_LO
[acc
], cpu_LO
[acc
]);
3902 tcg_gen_ext32s_tl(cpu_HI
[acc
], cpu_HI
[acc
]);
3909 TCGv t2
= tcg_const_tl(0);
3910 TCGv t3
= tcg_const_tl(1);
3911 tcg_gen_ext32u_tl(t0
, t0
);
3912 tcg_gen_ext32u_tl(t1
, t1
);
3913 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
3914 tcg_gen_divu_tl(cpu_LO
[acc
], t0
, t1
);
3915 tcg_gen_remu_tl(cpu_HI
[acc
], t0
, t1
);
3916 tcg_gen_ext32s_tl(cpu_LO
[acc
], cpu_LO
[acc
]);
3917 tcg_gen_ext32s_tl(cpu_HI
[acc
], cpu_HI
[acc
]);
3924 TCGv_i32 t2
= tcg_temp_new_i32();
3925 TCGv_i32 t3
= tcg_temp_new_i32();
3926 tcg_gen_trunc_tl_i32(t2
, t0
);
3927 tcg_gen_trunc_tl_i32(t3
, t1
);
3928 tcg_gen_muls2_i32(t2
, t3
, t2
, t3
);
3929 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
3930 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
3931 tcg_temp_free_i32(t2
);
3932 tcg_temp_free_i32(t3
);
3937 TCGv_i32 t2
= tcg_temp_new_i32();
3938 TCGv_i32 t3
= tcg_temp_new_i32();
3939 tcg_gen_trunc_tl_i32(t2
, t0
);
3940 tcg_gen_trunc_tl_i32(t3
, t1
);
3941 tcg_gen_mulu2_i32(t2
, t3
, t2
, t3
);
3942 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
3943 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
3944 tcg_temp_free_i32(t2
);
3945 tcg_temp_free_i32(t3
);
3948 #if defined(TARGET_MIPS64)
3951 TCGv t2
= tcg_temp_new();
3952 TCGv t3
= tcg_temp_new();
3953 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, -1LL << 63);
3954 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1LL);
3955 tcg_gen_and_tl(t2
, t2
, t3
);
3956 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
3957 tcg_gen_or_tl(t2
, t2
, t3
);
3958 tcg_gen_movi_tl(t3
, 0);
3959 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
3960 tcg_gen_div_tl(cpu_LO
[acc
], t0
, t1
);
3961 tcg_gen_rem_tl(cpu_HI
[acc
], t0
, t1
);
3968 TCGv t2
= tcg_const_tl(0);
3969 TCGv t3
= tcg_const_tl(1);
3970 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
3971 tcg_gen_divu_i64(cpu_LO
[acc
], t0
, t1
);
3972 tcg_gen_remu_i64(cpu_HI
[acc
], t0
, t1
);
3978 tcg_gen_muls2_i64(cpu_LO
[acc
], cpu_HI
[acc
], t0
, t1
);
3981 tcg_gen_mulu2_i64(cpu_LO
[acc
], cpu_HI
[acc
], t0
, t1
);
3986 TCGv_i64 t2
= tcg_temp_new_i64();
3987 TCGv_i64 t3
= tcg_temp_new_i64();
3989 tcg_gen_ext_tl_i64(t2
, t0
);
3990 tcg_gen_ext_tl_i64(t3
, t1
);
3991 tcg_gen_mul_i64(t2
, t2
, t3
);
3992 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
3993 tcg_gen_add_i64(t2
, t2
, t3
);
3994 tcg_temp_free_i64(t3
);
3995 gen_move_low32(cpu_LO
[acc
], t2
);
3996 gen_move_high32(cpu_HI
[acc
], t2
);
3997 tcg_temp_free_i64(t2
);
4002 TCGv_i64 t2
= tcg_temp_new_i64();
4003 TCGv_i64 t3
= tcg_temp_new_i64();
4005 tcg_gen_ext32u_tl(t0
, t0
);
4006 tcg_gen_ext32u_tl(t1
, t1
);
4007 tcg_gen_extu_tl_i64(t2
, t0
);
4008 tcg_gen_extu_tl_i64(t3
, t1
);
4009 tcg_gen_mul_i64(t2
, t2
, t3
);
4010 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
4011 tcg_gen_add_i64(t2
, t2
, t3
);
4012 tcg_temp_free_i64(t3
);
4013 gen_move_low32(cpu_LO
[acc
], t2
);
4014 gen_move_high32(cpu_HI
[acc
], t2
);
4015 tcg_temp_free_i64(t2
);
4020 TCGv_i64 t2
= tcg_temp_new_i64();
4021 TCGv_i64 t3
= tcg_temp_new_i64();
4023 tcg_gen_ext_tl_i64(t2
, t0
);
4024 tcg_gen_ext_tl_i64(t3
, t1
);
4025 tcg_gen_mul_i64(t2
, t2
, t3
);
4026 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
4027 tcg_gen_sub_i64(t2
, t3
, t2
);
4028 tcg_temp_free_i64(t3
);
4029 gen_move_low32(cpu_LO
[acc
], t2
);
4030 gen_move_high32(cpu_HI
[acc
], t2
);
4031 tcg_temp_free_i64(t2
);
4036 TCGv_i64 t2
= tcg_temp_new_i64();
4037 TCGv_i64 t3
= tcg_temp_new_i64();
4039 tcg_gen_ext32u_tl(t0
, t0
);
4040 tcg_gen_ext32u_tl(t1
, t1
);
4041 tcg_gen_extu_tl_i64(t2
, t0
);
4042 tcg_gen_extu_tl_i64(t3
, t1
);
4043 tcg_gen_mul_i64(t2
, t2
, t3
);
4044 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
4045 tcg_gen_sub_i64(t2
, t3
, t2
);
4046 tcg_temp_free_i64(t3
);
4047 gen_move_low32(cpu_LO
[acc
], t2
);
4048 gen_move_high32(cpu_HI
[acc
], t2
);
4049 tcg_temp_free_i64(t2
);
4053 MIPS_INVAL("mul/div");
4054 gen_reserved_instruction(ctx
);
4063 * These MULT[U] and MADD[U] instructions implemented in for example
4064 * the Toshiba/Sony R5900 and the Toshiba TX19, TX39 and TX79 core
4065 * architectures are special three-operand variants with the syntax
4067 * MULT[U][1] rd, rs, rt
4071 * (rd, LO, HI) <- rs * rt
4075 * MADD[U][1] rd, rs, rt
4079 * (rd, LO, HI) <- (LO, HI) + rs * rt
4081 * where the low-order 32-bits of the result is placed into both the
4082 * GPR rd and the special register LO. The high-order 32-bits of the
4083 * result is placed into the special register HI.
4085 * If the GPR rd is omitted in assembly language, it is taken to be 0,
4086 * which is the zero register that always reads as 0.
4088 static void gen_mul_txx9(DisasContext
*ctx
, uint32_t opc
,
4089 int rd
, int rs
, int rt
)
4091 TCGv t0
= tcg_temp_new();
4092 TCGv t1
= tcg_temp_new();
4095 gen_load_gpr(t0
, rs
);
4096 gen_load_gpr(t1
, rt
);
4104 TCGv_i32 t2
= tcg_temp_new_i32();
4105 TCGv_i32 t3
= tcg_temp_new_i32();
4106 tcg_gen_trunc_tl_i32(t2
, t0
);
4107 tcg_gen_trunc_tl_i32(t3
, t1
);
4108 tcg_gen_muls2_i32(t2
, t3
, t2
, t3
);
4110 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
4112 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
4113 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
4114 tcg_temp_free_i32(t2
);
4115 tcg_temp_free_i32(t3
);
4118 case MMI_OPC_MULTU1
:
4123 TCGv_i32 t2
= tcg_temp_new_i32();
4124 TCGv_i32 t3
= tcg_temp_new_i32();
4125 tcg_gen_trunc_tl_i32(t2
, t0
);
4126 tcg_gen_trunc_tl_i32(t3
, t1
);
4127 tcg_gen_mulu2_i32(t2
, t3
, t2
, t3
);
4129 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
4131 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
4132 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
4133 tcg_temp_free_i32(t2
);
4134 tcg_temp_free_i32(t3
);
4142 TCGv_i64 t2
= tcg_temp_new_i64();
4143 TCGv_i64 t3
= tcg_temp_new_i64();
4145 tcg_gen_ext_tl_i64(t2
, t0
);
4146 tcg_gen_ext_tl_i64(t3
, t1
);
4147 tcg_gen_mul_i64(t2
, t2
, t3
);
4148 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
4149 tcg_gen_add_i64(t2
, t2
, t3
);
4150 tcg_temp_free_i64(t3
);
4151 gen_move_low32(cpu_LO
[acc
], t2
);
4152 gen_move_high32(cpu_HI
[acc
], t2
);
4154 gen_move_low32(cpu_gpr
[rd
], t2
);
4156 tcg_temp_free_i64(t2
);
4159 case MMI_OPC_MADDU1
:
4164 TCGv_i64 t2
= tcg_temp_new_i64();
4165 TCGv_i64 t3
= tcg_temp_new_i64();
4167 tcg_gen_ext32u_tl(t0
, t0
);
4168 tcg_gen_ext32u_tl(t1
, t1
);
4169 tcg_gen_extu_tl_i64(t2
, t0
);
4170 tcg_gen_extu_tl_i64(t3
, t1
);
4171 tcg_gen_mul_i64(t2
, t2
, t3
);
4172 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
4173 tcg_gen_add_i64(t2
, t2
, t3
);
4174 tcg_temp_free_i64(t3
);
4175 gen_move_low32(cpu_LO
[acc
], t2
);
4176 gen_move_high32(cpu_HI
[acc
], t2
);
4178 gen_move_low32(cpu_gpr
[rd
], t2
);
4180 tcg_temp_free_i64(t2
);
4184 MIPS_INVAL("mul/madd TXx9");
4185 gen_reserved_instruction(ctx
);
4194 static void gen_mul_vr54xx(DisasContext
*ctx
, uint32_t opc
,
4195 int rd
, int rs
, int rt
)
4197 TCGv t0
= tcg_temp_new();
4198 TCGv t1
= tcg_temp_new();
4200 gen_load_gpr(t0
, rs
);
4201 gen_load_gpr(t1
, rt
);
4204 case OPC_VR54XX_MULS
:
4205 gen_helper_muls(t0
, cpu_env
, t0
, t1
);
4207 case OPC_VR54XX_MULSU
:
4208 gen_helper_mulsu(t0
, cpu_env
, t0
, t1
);
4210 case OPC_VR54XX_MACC
:
4211 gen_helper_macc(t0
, cpu_env
, t0
, t1
);
4213 case OPC_VR54XX_MACCU
:
4214 gen_helper_maccu(t0
, cpu_env
, t0
, t1
);
4216 case OPC_VR54XX_MSAC
:
4217 gen_helper_msac(t0
, cpu_env
, t0
, t1
);
4219 case OPC_VR54XX_MSACU
:
4220 gen_helper_msacu(t0
, cpu_env
, t0
, t1
);
4222 case OPC_VR54XX_MULHI
:
4223 gen_helper_mulhi(t0
, cpu_env
, t0
, t1
);
4225 case OPC_VR54XX_MULHIU
:
4226 gen_helper_mulhiu(t0
, cpu_env
, t0
, t1
);
4228 case OPC_VR54XX_MULSHI
:
4229 gen_helper_mulshi(t0
, cpu_env
, t0
, t1
);
4231 case OPC_VR54XX_MULSHIU
:
4232 gen_helper_mulshiu(t0
, cpu_env
, t0
, t1
);
4234 case OPC_VR54XX_MACCHI
:
4235 gen_helper_macchi(t0
, cpu_env
, t0
, t1
);
4237 case OPC_VR54XX_MACCHIU
:
4238 gen_helper_macchiu(t0
, cpu_env
, t0
, t1
);
4240 case OPC_VR54XX_MSACHI
:
4241 gen_helper_msachi(t0
, cpu_env
, t0
, t1
);
4243 case OPC_VR54XX_MSACHIU
:
4244 gen_helper_msachiu(t0
, cpu_env
, t0
, t1
);
4247 MIPS_INVAL("mul vr54xx");
4248 gen_reserved_instruction(ctx
);
4251 gen_store_gpr(t0
, rd
);
4258 static void gen_cl(DisasContext
*ctx
, uint32_t opc
,
4268 gen_load_gpr(t0
, rs
);
4273 #if defined(TARGET_MIPS64)
4277 tcg_gen_not_tl(t0
, t0
);
4286 tcg_gen_ext32u_tl(t0
, t0
);
4287 tcg_gen_clzi_tl(t0
, t0
, TARGET_LONG_BITS
);
4288 tcg_gen_subi_tl(t0
, t0
, TARGET_LONG_BITS
- 32);
4290 #if defined(TARGET_MIPS64)
4295 tcg_gen_clzi_i64(t0
, t0
, 64);
4301 /* Godson integer instructions */
4302 static void gen_loongson_integer(DisasContext
*ctx
, uint32_t opc
,
4303 int rd
, int rs
, int rt
)
4315 case OPC_MULTU_G_2E
:
4316 case OPC_MULTU_G_2F
:
4317 #if defined(TARGET_MIPS64)
4318 case OPC_DMULT_G_2E
:
4319 case OPC_DMULT_G_2F
:
4320 case OPC_DMULTU_G_2E
:
4321 case OPC_DMULTU_G_2F
:
4323 t0
= tcg_temp_new();
4324 t1
= tcg_temp_new();
4327 t0
= tcg_temp_local_new();
4328 t1
= tcg_temp_local_new();
4332 gen_load_gpr(t0
, rs
);
4333 gen_load_gpr(t1
, rt
);
4338 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
4339 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
4341 case OPC_MULTU_G_2E
:
4342 case OPC_MULTU_G_2F
:
4343 tcg_gen_ext32u_tl(t0
, t0
);
4344 tcg_gen_ext32u_tl(t1
, t1
);
4345 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
4346 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
4351 TCGLabel
*l1
= gen_new_label();
4352 TCGLabel
*l2
= gen_new_label();
4353 TCGLabel
*l3
= gen_new_label();
4354 tcg_gen_ext32s_tl(t0
, t0
);
4355 tcg_gen_ext32s_tl(t1
, t1
);
4356 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
4357 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4360 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, INT_MIN
, l2
);
4361 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1, l2
);
4362 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
4365 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
4366 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
4373 TCGLabel
*l1
= gen_new_label();
4374 TCGLabel
*l2
= gen_new_label();
4375 tcg_gen_ext32u_tl(t0
, t0
);
4376 tcg_gen_ext32u_tl(t1
, t1
);
4377 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
4378 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4381 tcg_gen_divu_tl(cpu_gpr
[rd
], t0
, t1
);
4382 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
4389 TCGLabel
*l1
= gen_new_label();
4390 TCGLabel
*l2
= gen_new_label();
4391 TCGLabel
*l3
= gen_new_label();
4392 tcg_gen_ext32u_tl(t0
, t0
);
4393 tcg_gen_ext32u_tl(t1
, t1
);
4394 tcg_gen_brcondi_tl(TCG_COND_EQ
, t1
, 0, l1
);
4395 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, INT_MIN
, l2
);
4396 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1, l2
);
4398 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4401 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
4402 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
4409 TCGLabel
*l1
= gen_new_label();
4410 TCGLabel
*l2
= gen_new_label();
4411 tcg_gen_ext32u_tl(t0
, t0
);
4412 tcg_gen_ext32u_tl(t1
, t1
);
4413 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
4414 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4417 tcg_gen_remu_tl(cpu_gpr
[rd
], t0
, t1
);
4418 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
4422 #if defined(TARGET_MIPS64)
4423 case OPC_DMULT_G_2E
:
4424 case OPC_DMULT_G_2F
:
4425 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
4427 case OPC_DMULTU_G_2E
:
4428 case OPC_DMULTU_G_2F
:
4429 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
4434 TCGLabel
*l1
= gen_new_label();
4435 TCGLabel
*l2
= gen_new_label();
4436 TCGLabel
*l3
= gen_new_label();
4437 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
4438 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4441 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, -1LL << 63, l2
);
4442 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1LL, l2
);
4443 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
4446 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
4450 case OPC_DDIVU_G_2E
:
4451 case OPC_DDIVU_G_2F
:
4453 TCGLabel
*l1
= gen_new_label();
4454 TCGLabel
*l2
= gen_new_label();
4455 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
4456 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4459 tcg_gen_divu_tl(cpu_gpr
[rd
], t0
, t1
);
4466 TCGLabel
*l1
= gen_new_label();
4467 TCGLabel
*l2
= gen_new_label();
4468 TCGLabel
*l3
= gen_new_label();
4469 tcg_gen_brcondi_tl(TCG_COND_EQ
, t1
, 0, l1
);
4470 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, -1LL << 63, l2
);
4471 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1LL, l2
);
4473 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4476 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
4480 case OPC_DMODU_G_2E
:
4481 case OPC_DMODU_G_2F
:
4483 TCGLabel
*l1
= gen_new_label();
4484 TCGLabel
*l2
= gen_new_label();
4485 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
4486 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4489 tcg_gen_remu_tl(cpu_gpr
[rd
], t0
, t1
);
4500 /* Loongson multimedia instructions */
4501 static void gen_loongson_multimedia(DisasContext
*ctx
, int rd
, int rs
, int rt
)
4503 uint32_t opc
, shift_max
;
4507 opc
= MASK_LMMI(ctx
->opcode
);
4513 t0
= tcg_temp_local_new_i64();
4514 t1
= tcg_temp_local_new_i64();
4517 t0
= tcg_temp_new_i64();
4518 t1
= tcg_temp_new_i64();
4522 check_cp1_enabled(ctx
);
4523 gen_load_fpr64(ctx
, t0
, rs
);
4524 gen_load_fpr64(ctx
, t1
, rt
);
4528 gen_helper_paddsh(t0
, t0
, t1
);
4531 gen_helper_paddush(t0
, t0
, t1
);
4534 gen_helper_paddh(t0
, t0
, t1
);
4537 gen_helper_paddw(t0
, t0
, t1
);
4540 gen_helper_paddsb(t0
, t0
, t1
);
4543 gen_helper_paddusb(t0
, t0
, t1
);
4546 gen_helper_paddb(t0
, t0
, t1
);
4550 gen_helper_psubsh(t0
, t0
, t1
);
4553 gen_helper_psubush(t0
, t0
, t1
);
4556 gen_helper_psubh(t0
, t0
, t1
);
4559 gen_helper_psubw(t0
, t0
, t1
);
4562 gen_helper_psubsb(t0
, t0
, t1
);
4565 gen_helper_psubusb(t0
, t0
, t1
);
4568 gen_helper_psubb(t0
, t0
, t1
);
4572 gen_helper_pshufh(t0
, t0
, t1
);
4575 gen_helper_packsswh(t0
, t0
, t1
);
4578 gen_helper_packsshb(t0
, t0
, t1
);
4581 gen_helper_packushb(t0
, t0
, t1
);
4585 gen_helper_punpcklhw(t0
, t0
, t1
);
4588 gen_helper_punpckhhw(t0
, t0
, t1
);
4591 gen_helper_punpcklbh(t0
, t0
, t1
);
4594 gen_helper_punpckhbh(t0
, t0
, t1
);
4597 gen_helper_punpcklwd(t0
, t0
, t1
);
4600 gen_helper_punpckhwd(t0
, t0
, t1
);
4604 gen_helper_pavgh(t0
, t0
, t1
);
4607 gen_helper_pavgb(t0
, t0
, t1
);
4610 gen_helper_pmaxsh(t0
, t0
, t1
);
4613 gen_helper_pminsh(t0
, t0
, t1
);
4616 gen_helper_pmaxub(t0
, t0
, t1
);
4619 gen_helper_pminub(t0
, t0
, t1
);
4623 gen_helper_pcmpeqw(t0
, t0
, t1
);
4626 gen_helper_pcmpgtw(t0
, t0
, t1
);
4629 gen_helper_pcmpeqh(t0
, t0
, t1
);
4632 gen_helper_pcmpgth(t0
, t0
, t1
);
4635 gen_helper_pcmpeqb(t0
, t0
, t1
);
4638 gen_helper_pcmpgtb(t0
, t0
, t1
);
4642 gen_helper_psllw(t0
, t0
, t1
);
4645 gen_helper_psllh(t0
, t0
, t1
);
4648 gen_helper_psrlw(t0
, t0
, t1
);
4651 gen_helper_psrlh(t0
, t0
, t1
);
4654 gen_helper_psraw(t0
, t0
, t1
);
4657 gen_helper_psrah(t0
, t0
, t1
);
4661 gen_helper_pmullh(t0
, t0
, t1
);
4664 gen_helper_pmulhh(t0
, t0
, t1
);
4667 gen_helper_pmulhuh(t0
, t0
, t1
);
4670 gen_helper_pmaddhw(t0
, t0
, t1
);
4674 gen_helper_pasubub(t0
, t0
, t1
);
4677 gen_helper_biadd(t0
, t0
);
4680 gen_helper_pmovmskb(t0
, t0
);
4684 tcg_gen_add_i64(t0
, t0
, t1
);
4687 tcg_gen_sub_i64(t0
, t0
, t1
);
4690 tcg_gen_xor_i64(t0
, t0
, t1
);
4693 tcg_gen_nor_i64(t0
, t0
, t1
);
4696 tcg_gen_and_i64(t0
, t0
, t1
);
4699 tcg_gen_or_i64(t0
, t0
, t1
);
4703 tcg_gen_andc_i64(t0
, t1
, t0
);
4707 tcg_gen_deposit_i64(t0
, t0
, t1
, 0, 16);
4710 tcg_gen_deposit_i64(t0
, t0
, t1
, 16, 16);
4713 tcg_gen_deposit_i64(t0
, t0
, t1
, 32, 16);
4716 tcg_gen_deposit_i64(t0
, t0
, t1
, 48, 16);
4720 tcg_gen_andi_i64(t1
, t1
, 3);
4721 tcg_gen_shli_i64(t1
, t1
, 4);
4722 tcg_gen_shr_i64(t0
, t0
, t1
);
4723 tcg_gen_ext16u_i64(t0
, t0
);
4727 tcg_gen_add_i64(t0
, t0
, t1
);
4728 tcg_gen_ext32s_i64(t0
, t0
);
4731 tcg_gen_sub_i64(t0
, t0
, t1
);
4732 tcg_gen_ext32s_i64(t0
, t0
);
4754 /* Make sure shift count isn't TCG undefined behaviour. */
4755 tcg_gen_andi_i64(t1
, t1
, shift_max
- 1);
4760 tcg_gen_shl_i64(t0
, t0
, t1
);
4765 * Since SRA is UndefinedResult without sign-extended inputs,
4766 * we can treat SRA and DSRA the same.
4768 tcg_gen_sar_i64(t0
, t0
, t1
);
4771 /* We want to shift in zeros for SRL; zero-extend first. */
4772 tcg_gen_ext32u_i64(t0
, t0
);
4775 tcg_gen_shr_i64(t0
, t0
, t1
);
4779 if (shift_max
== 32) {
4780 tcg_gen_ext32s_i64(t0
, t0
);
4783 /* Shifts larger than MAX produce zero. */
4784 tcg_gen_setcondi_i64(TCG_COND_LTU
, t1
, t1
, shift_max
);
4785 tcg_gen_neg_i64(t1
, t1
);
4786 tcg_gen_and_i64(t0
, t0
, t1
);
4792 TCGv_i64 t2
= tcg_temp_new_i64();
4793 TCGLabel
*lab
= gen_new_label();
4795 tcg_gen_mov_i64(t2
, t0
);
4796 tcg_gen_add_i64(t0
, t1
, t2
);
4797 if (opc
== OPC_ADD_CP2
) {
4798 tcg_gen_ext32s_i64(t0
, t0
);
4800 tcg_gen_xor_i64(t1
, t1
, t2
);
4801 tcg_gen_xor_i64(t2
, t2
, t0
);
4802 tcg_gen_andc_i64(t1
, t2
, t1
);
4803 tcg_temp_free_i64(t2
);
4804 tcg_gen_brcondi_i64(TCG_COND_GE
, t1
, 0, lab
);
4805 generate_exception(ctx
, EXCP_OVERFLOW
);
4813 TCGv_i64 t2
= tcg_temp_new_i64();
4814 TCGLabel
*lab
= gen_new_label();
4816 tcg_gen_mov_i64(t2
, t0
);
4817 tcg_gen_sub_i64(t0
, t1
, t2
);
4818 if (opc
== OPC_SUB_CP2
) {
4819 tcg_gen_ext32s_i64(t0
, t0
);
4821 tcg_gen_xor_i64(t1
, t1
, t2
);
4822 tcg_gen_xor_i64(t2
, t2
, t0
);
4823 tcg_gen_and_i64(t1
, t1
, t2
);
4824 tcg_temp_free_i64(t2
);
4825 tcg_gen_brcondi_i64(TCG_COND_GE
, t1
, 0, lab
);
4826 generate_exception(ctx
, EXCP_OVERFLOW
);
4832 tcg_gen_ext32u_i64(t0
, t0
);
4833 tcg_gen_ext32u_i64(t1
, t1
);
4834 tcg_gen_mul_i64(t0
, t0
, t1
);
4843 cond
= TCG_COND_LTU
;
4851 cond
= TCG_COND_LEU
;
4858 int cc
= (ctx
->opcode
>> 8) & 0x7;
4859 TCGv_i64 t64
= tcg_temp_new_i64();
4860 TCGv_i32 t32
= tcg_temp_new_i32();
4862 tcg_gen_setcond_i64(cond
, t64
, t0
, t1
);
4863 tcg_gen_extrl_i64_i32(t32
, t64
);
4864 tcg_gen_deposit_i32(fpu_fcr31
, fpu_fcr31
, t32
,
4867 tcg_temp_free_i32(t32
);
4868 tcg_temp_free_i64(t64
);
4873 MIPS_INVAL("loongson_cp2");
4874 gen_reserved_instruction(ctx
);
4878 gen_store_fpr64(ctx
, t0
, rd
);
4881 tcg_temp_free_i64(t0
);
4882 tcg_temp_free_i64(t1
);
4885 static void gen_loongson_lswc2(DisasContext
*ctx
, int rt
,
4890 #if defined(TARGET_MIPS64)
4891 int lsq_rt1
= ctx
->opcode
& 0x1f;
4892 int lsq_offset
= sextract32(ctx
->opcode
, 6, 9) << 4;
4894 int shf_offset
= sextract32(ctx
->opcode
, 6, 8);
4896 t0
= tcg_temp_new();
4898 switch (MASK_LOONGSON_GSLSQ(ctx
->opcode
)) {
4899 #if defined(TARGET_MIPS64)
4901 t1
= tcg_temp_new();
4902 gen_base_offset_addr(ctx
, t0
, rs
, lsq_offset
);
4903 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
|
4904 ctx
->default_tcg_memop_mask
);
4905 gen_base_offset_addr(ctx
, t0
, rs
, lsq_offset
+ 8);
4906 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
|
4907 ctx
->default_tcg_memop_mask
);
4908 gen_store_gpr(t1
, rt
);
4909 gen_store_gpr(t0
, lsq_rt1
);
4913 check_cp1_enabled(ctx
);
4914 t1
= tcg_temp_new();
4915 gen_base_offset_addr(ctx
, t0
, rs
, lsq_offset
);
4916 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
|
4917 ctx
->default_tcg_memop_mask
);
4918 gen_base_offset_addr(ctx
, t0
, rs
, lsq_offset
+ 8);
4919 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
|
4920 ctx
->default_tcg_memop_mask
);
4921 gen_store_fpr64(ctx
, t1
, rt
);
4922 gen_store_fpr64(ctx
, t0
, lsq_rt1
);
4926 t1
= tcg_temp_new();
4927 gen_base_offset_addr(ctx
, t0
, rs
, lsq_offset
);
4928 gen_load_gpr(t1
, rt
);
4929 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
|
4930 ctx
->default_tcg_memop_mask
);
4931 gen_base_offset_addr(ctx
, t0
, rs
, lsq_offset
+ 8);
4932 gen_load_gpr(t1
, lsq_rt1
);
4933 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
|
4934 ctx
->default_tcg_memop_mask
);
4938 check_cp1_enabled(ctx
);
4939 t1
= tcg_temp_new();
4940 gen_base_offset_addr(ctx
, t0
, rs
, lsq_offset
);
4941 gen_load_fpr64(ctx
, t1
, rt
);
4942 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
|
4943 ctx
->default_tcg_memop_mask
);
4944 gen_base_offset_addr(ctx
, t0
, rs
, lsq_offset
+ 8);
4945 gen_load_fpr64(ctx
, t1
, lsq_rt1
);
4946 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
|
4947 ctx
->default_tcg_memop_mask
);
4952 switch (MASK_LOONGSON_GSSHFLS(ctx
->opcode
)) {
4954 check_cp1_enabled(ctx
);
4955 gen_base_offset_addr(ctx
, t0
, rs
, shf_offset
);
4956 t1
= tcg_temp_new();
4957 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
4958 tcg_gen_andi_tl(t1
, t0
, 3);
4959 #ifndef TARGET_WORDS_BIGENDIAN
4960 tcg_gen_xori_tl(t1
, t1
, 3);
4962 tcg_gen_shli_tl(t1
, t1
, 3);
4963 tcg_gen_andi_tl(t0
, t0
, ~3);
4964 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEUL
);
4965 tcg_gen_shl_tl(t0
, t0
, t1
);
4966 t2
= tcg_const_tl(-1);
4967 tcg_gen_shl_tl(t2
, t2
, t1
);
4968 fp0
= tcg_temp_new_i32();
4969 gen_load_fpr32(ctx
, fp0
, rt
);
4970 tcg_gen_ext_i32_tl(t1
, fp0
);
4971 tcg_gen_andc_tl(t1
, t1
, t2
);
4973 tcg_gen_or_tl(t0
, t0
, t1
);
4975 #if defined(TARGET_MIPS64)
4976 tcg_gen_extrl_i64_i32(fp0
, t0
);
4978 tcg_gen_ext32s_tl(fp0
, t0
);
4980 gen_store_fpr32(ctx
, fp0
, rt
);
4981 tcg_temp_free_i32(fp0
);
4984 check_cp1_enabled(ctx
);
4985 gen_base_offset_addr(ctx
, t0
, rs
, shf_offset
);
4986 t1
= tcg_temp_new();
4987 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
4988 tcg_gen_andi_tl(t1
, t0
, 3);
4989 #ifdef TARGET_WORDS_BIGENDIAN
4990 tcg_gen_xori_tl(t1
, t1
, 3);
4992 tcg_gen_shli_tl(t1
, t1
, 3);
4993 tcg_gen_andi_tl(t0
, t0
, ~3);
4994 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEUL
);
4995 tcg_gen_shr_tl(t0
, t0
, t1
);
4996 tcg_gen_xori_tl(t1
, t1
, 31);
4997 t2
= tcg_const_tl(0xfffffffeull
);
4998 tcg_gen_shl_tl(t2
, t2
, t1
);
4999 fp0
= tcg_temp_new_i32();
5000 gen_load_fpr32(ctx
, fp0
, rt
);
5001 tcg_gen_ext_i32_tl(t1
, fp0
);
5002 tcg_gen_and_tl(t1
, t1
, t2
);
5004 tcg_gen_or_tl(t0
, t0
, t1
);
5006 #if defined(TARGET_MIPS64)
5007 tcg_gen_extrl_i64_i32(fp0
, t0
);
5009 tcg_gen_ext32s_tl(fp0
, t0
);
5011 gen_store_fpr32(ctx
, fp0
, rt
);
5012 tcg_temp_free_i32(fp0
);
5014 #if defined(TARGET_MIPS64)
5016 check_cp1_enabled(ctx
);
5017 gen_base_offset_addr(ctx
, t0
, rs
, shf_offset
);
5018 t1
= tcg_temp_new();
5019 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
5020 tcg_gen_andi_tl(t1
, t0
, 7);
5021 #ifndef TARGET_WORDS_BIGENDIAN
5022 tcg_gen_xori_tl(t1
, t1
, 7);
5024 tcg_gen_shli_tl(t1
, t1
, 3);
5025 tcg_gen_andi_tl(t0
, t0
, ~7);
5026 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
);
5027 tcg_gen_shl_tl(t0
, t0
, t1
);
5028 t2
= tcg_const_tl(-1);
5029 tcg_gen_shl_tl(t2
, t2
, t1
);
5030 gen_load_fpr64(ctx
, t1
, rt
);
5031 tcg_gen_andc_tl(t1
, t1
, t2
);
5033 tcg_gen_or_tl(t0
, t0
, t1
);
5035 gen_store_fpr64(ctx
, t0
, rt
);
5038 check_cp1_enabled(ctx
);
5039 gen_base_offset_addr(ctx
, t0
, rs
, shf_offset
);
5040 t1
= tcg_temp_new();
5041 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
5042 tcg_gen_andi_tl(t1
, t0
, 7);
5043 #ifdef TARGET_WORDS_BIGENDIAN
5044 tcg_gen_xori_tl(t1
, t1
, 7);
5046 tcg_gen_shli_tl(t1
, t1
, 3);
5047 tcg_gen_andi_tl(t0
, t0
, ~7);
5048 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
);
5049 tcg_gen_shr_tl(t0
, t0
, t1
);
5050 tcg_gen_xori_tl(t1
, t1
, 63);
5051 t2
= tcg_const_tl(0xfffffffffffffffeull
);
5052 tcg_gen_shl_tl(t2
, t2
, t1
);
5053 gen_load_fpr64(ctx
, t1
, rt
);
5054 tcg_gen_and_tl(t1
, t1
, t2
);
5056 tcg_gen_or_tl(t0
, t0
, t1
);
5058 gen_store_fpr64(ctx
, t0
, rt
);
5062 MIPS_INVAL("loongson_gsshfl");
5063 gen_reserved_instruction(ctx
);
5068 switch (MASK_LOONGSON_GSSHFLS(ctx
->opcode
)) {
5070 check_cp1_enabled(ctx
);
5071 t1
= tcg_temp_new();
5072 gen_base_offset_addr(ctx
, t0
, rs
, shf_offset
);
5073 fp0
= tcg_temp_new_i32();
5074 gen_load_fpr32(ctx
, fp0
, rt
);
5075 tcg_gen_ext_i32_tl(t1
, fp0
);
5076 gen_helper_0e2i(swl
, t1
, t0
, ctx
->mem_idx
);
5077 tcg_temp_free_i32(fp0
);
5081 check_cp1_enabled(ctx
);
5082 t1
= tcg_temp_new();
5083 gen_base_offset_addr(ctx
, t0
, rs
, shf_offset
);
5084 fp0
= tcg_temp_new_i32();
5085 gen_load_fpr32(ctx
, fp0
, rt
);
5086 tcg_gen_ext_i32_tl(t1
, fp0
);
5087 gen_helper_0e2i(swr
, t1
, t0
, ctx
->mem_idx
);
5088 tcg_temp_free_i32(fp0
);
5091 #if defined(TARGET_MIPS64)
5093 check_cp1_enabled(ctx
);
5094 t1
= tcg_temp_new();
5095 gen_base_offset_addr(ctx
, t0
, rs
, shf_offset
);
5096 gen_load_fpr64(ctx
, t1
, rt
);
5097 gen_helper_0e2i(sdl
, t1
, t0
, ctx
->mem_idx
);
5101 check_cp1_enabled(ctx
);
5102 t1
= tcg_temp_new();
5103 gen_base_offset_addr(ctx
, t0
, rs
, shf_offset
);
5104 gen_load_fpr64(ctx
, t1
, rt
);
5105 gen_helper_0e2i(sdr
, t1
, t0
, ctx
->mem_idx
);
5110 MIPS_INVAL("loongson_gsshfs");
5111 gen_reserved_instruction(ctx
);
5116 MIPS_INVAL("loongson_gslsq");
5117 gen_reserved_instruction(ctx
);
5123 /* Loongson EXT LDC2/SDC2 */
5124 static void gen_loongson_lsdc2(DisasContext
*ctx
, int rt
,
5127 int offset
= sextract32(ctx
->opcode
, 3, 8);
5128 uint32_t opc
= MASK_LOONGSON_LSDC2(ctx
->opcode
);
5132 /* Pre-conditions */
5138 /* prefetch, implement as NOP */
5149 #if defined(TARGET_MIPS64)
5152 check_cp1_enabled(ctx
);
5153 /* prefetch, implement as NOP */
5159 #if defined(TARGET_MIPS64)
5162 check_cp1_enabled(ctx
);
5165 MIPS_INVAL("loongson_lsdc2");
5166 gen_reserved_instruction(ctx
);
5171 t0
= tcg_temp_new();
5173 gen_base_offset_addr(ctx
, t0
, rs
, offset
);
5174 gen_op_addr_add(ctx
, t0
, cpu_gpr
[rd
], t0
);
5178 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_SB
);
5179 gen_store_gpr(t0
, rt
);
5182 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESW
|
5183 ctx
->default_tcg_memop_mask
);
5184 gen_store_gpr(t0
, rt
);
5187 gen_base_offset_addr(ctx
, t0
, rs
, offset
);
5189 gen_op_addr_add(ctx
, t0
, cpu_gpr
[rd
], t0
);
5191 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESL
|
5192 ctx
->default_tcg_memop_mask
);
5193 gen_store_gpr(t0
, rt
);
5195 #if defined(TARGET_MIPS64)
5197 gen_base_offset_addr(ctx
, t0
, rs
, offset
);
5199 gen_op_addr_add(ctx
, t0
, cpu_gpr
[rd
], t0
);
5201 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
|
5202 ctx
->default_tcg_memop_mask
);
5203 gen_store_gpr(t0
, rt
);
5207 check_cp1_enabled(ctx
);
5208 gen_base_offset_addr(ctx
, t0
, rs
, offset
);
5210 gen_op_addr_add(ctx
, t0
, cpu_gpr
[rd
], t0
);
5212 fp0
= tcg_temp_new_i32();
5213 tcg_gen_qemu_ld_i32(fp0
, t0
, ctx
->mem_idx
, MO_TESL
|
5214 ctx
->default_tcg_memop_mask
);
5215 gen_store_fpr32(ctx
, fp0
, rt
);
5216 tcg_temp_free_i32(fp0
);
5218 #if defined(TARGET_MIPS64)
5220 check_cp1_enabled(ctx
);
5221 gen_base_offset_addr(ctx
, t0
, rs
, offset
);
5223 gen_op_addr_add(ctx
, t0
, cpu_gpr
[rd
], t0
);
5225 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
|
5226 ctx
->default_tcg_memop_mask
);
5227 gen_store_fpr64(ctx
, t0
, rt
);
5231 t1
= tcg_temp_new();
5232 gen_load_gpr(t1
, rt
);
5233 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_SB
);
5237 t1
= tcg_temp_new();
5238 gen_load_gpr(t1
, rt
);
5239 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUW
|
5240 ctx
->default_tcg_memop_mask
);
5244 t1
= tcg_temp_new();
5245 gen_load_gpr(t1
, rt
);
5246 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
|
5247 ctx
->default_tcg_memop_mask
);
5250 #if defined(TARGET_MIPS64)
5252 t1
= tcg_temp_new();
5253 gen_load_gpr(t1
, rt
);
5254 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
|
5255 ctx
->default_tcg_memop_mask
);
5260 fp0
= tcg_temp_new_i32();
5261 gen_load_fpr32(ctx
, fp0
, rt
);
5262 tcg_gen_qemu_st_i32(fp0
, t0
, ctx
->mem_idx
, MO_TEUL
|
5263 ctx
->default_tcg_memop_mask
);
5264 tcg_temp_free_i32(fp0
);
5266 #if defined(TARGET_MIPS64)
5268 t1
= tcg_temp_new();
5269 gen_load_fpr64(ctx
, t1
, rt
);
5270 tcg_gen_qemu_st_i64(t1
, t0
, ctx
->mem_idx
, MO_TEQ
|
5271 ctx
->default_tcg_memop_mask
);
5283 static void gen_trap(DisasContext
*ctx
, uint32_t opc
,
5284 int rs
, int rt
, int16_t imm
)
5287 TCGv t0
= tcg_temp_new();
5288 TCGv t1
= tcg_temp_new();
5291 /* Load needed operands */
5299 /* Compare two registers */
5301 gen_load_gpr(t0
, rs
);
5302 gen_load_gpr(t1
, rt
);
5312 /* Compare register to immediate */
5313 if (rs
!= 0 || imm
!= 0) {
5314 gen_load_gpr(t0
, rs
);
5315 tcg_gen_movi_tl(t1
, (int32_t)imm
);
5322 case OPC_TEQ
: /* rs == rs */
5323 case OPC_TEQI
: /* r0 == 0 */
5324 case OPC_TGE
: /* rs >= rs */
5325 case OPC_TGEI
: /* r0 >= 0 */
5326 case OPC_TGEU
: /* rs >= rs unsigned */
5327 case OPC_TGEIU
: /* r0 >= 0 unsigned */
5329 generate_exception_end(ctx
, EXCP_TRAP
);
5331 case OPC_TLT
: /* rs < rs */
5332 case OPC_TLTI
: /* r0 < 0 */
5333 case OPC_TLTU
: /* rs < rs unsigned */
5334 case OPC_TLTIU
: /* r0 < 0 unsigned */
5335 case OPC_TNE
: /* rs != rs */
5336 case OPC_TNEI
: /* r0 != 0 */
5337 /* Never trap: treat as NOP. */
5341 TCGLabel
*l1
= gen_new_label();
5346 tcg_gen_brcond_tl(TCG_COND_NE
, t0
, t1
, l1
);
5350 tcg_gen_brcond_tl(TCG_COND_LT
, t0
, t1
, l1
);
5354 tcg_gen_brcond_tl(TCG_COND_LTU
, t0
, t1
, l1
);
5358 tcg_gen_brcond_tl(TCG_COND_GE
, t0
, t1
, l1
);
5362 tcg_gen_brcond_tl(TCG_COND_GEU
, t0
, t1
, l1
);
5366 tcg_gen_brcond_tl(TCG_COND_EQ
, t0
, t1
, l1
);
5369 generate_exception(ctx
, EXCP_TRAP
);
5376 static inline bool use_goto_tb(DisasContext
*ctx
, target_ulong dest
)
5378 if (unlikely(ctx
->base
.singlestep_enabled
)) {
5382 #ifndef CONFIG_USER_ONLY
5383 return (ctx
->base
.tb
->pc
& TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
);
5389 static inline void gen_goto_tb(DisasContext
*ctx
, int n
, target_ulong dest
)
5391 if (use_goto_tb(ctx
, dest
)) {
5394 tcg_gen_exit_tb(ctx
->base
.tb
, n
);
5397 if (ctx
->base
.singlestep_enabled
) {
5398 save_cpu_state(ctx
, 0);
5399 gen_helper_raise_exception_debug(cpu_env
);
5401 tcg_gen_lookup_and_goto_ptr();
5405 /* Branches (before delay slot) */
5406 static void gen_compute_branch(DisasContext
*ctx
, uint32_t opc
,
5408 int rs
, int rt
, int32_t offset
,
5411 target_ulong btgt
= -1;
5413 int bcond_compute
= 0;
5414 TCGv t0
= tcg_temp_new();
5415 TCGv t1
= tcg_temp_new();
5417 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
5418 #ifdef MIPS_DEBUG_DISAS
5419 LOG_DISAS("Branch in delay / forbidden slot at PC 0x"
5420 TARGET_FMT_lx
"\n", ctx
->base
.pc_next
);
5422 gen_reserved_instruction(ctx
);
5426 /* Load needed operands */
5432 /* Compare two registers */
5434 gen_load_gpr(t0
, rs
);
5435 gen_load_gpr(t1
, rt
);
5438 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ offset
;
5452 /* Compare to zero */
5454 gen_load_gpr(t0
, rs
);
5457 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ offset
;
5460 #if defined(TARGET_MIPS64)
5462 tcg_gen_andi_tl(t0
, cpu_dspctrl
, 0x7F);
5464 tcg_gen_andi_tl(t0
, cpu_dspctrl
, 0x3F);
5467 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ offset
;
5472 /* Jump to immediate */
5473 btgt
= ((ctx
->base
.pc_next
+ insn_bytes
) & (int32_t)0xF0000000) |
5478 /* Jump to register */
5479 if (offset
!= 0 && offset
!= 16) {
5481 * Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
5482 * others are reserved.
5484 MIPS_INVAL("jump hint");
5485 gen_reserved_instruction(ctx
);
5488 gen_load_gpr(btarget
, rs
);
5491 MIPS_INVAL("branch/jump");
5492 gen_reserved_instruction(ctx
);
5495 if (bcond_compute
== 0) {
5496 /* No condition to be computed */
5498 case OPC_BEQ
: /* rx == rx */
5499 case OPC_BEQL
: /* rx == rx likely */
5500 case OPC_BGEZ
: /* 0 >= 0 */
5501 case OPC_BGEZL
: /* 0 >= 0 likely */
5502 case OPC_BLEZ
: /* 0 <= 0 */
5503 case OPC_BLEZL
: /* 0 <= 0 likely */
5505 ctx
->hflags
|= MIPS_HFLAG_B
;
5507 case OPC_BGEZAL
: /* 0 >= 0 */
5508 case OPC_BGEZALL
: /* 0 >= 0 likely */
5509 /* Always take and link */
5511 ctx
->hflags
|= MIPS_HFLAG_B
;
5513 case OPC_BNE
: /* rx != rx */
5514 case OPC_BGTZ
: /* 0 > 0 */
5515 case OPC_BLTZ
: /* 0 < 0 */
5518 case OPC_BLTZAL
: /* 0 < 0 */
5520 * Handle as an unconditional branch to get correct delay
5524 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ delayslot_size
;
5525 ctx
->hflags
|= MIPS_HFLAG_B
;
5527 case OPC_BLTZALL
: /* 0 < 0 likely */
5528 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 8);
5529 /* Skip the instruction in the delay slot */
5530 ctx
->base
.pc_next
+= 4;
5532 case OPC_BNEL
: /* rx != rx likely */
5533 case OPC_BGTZL
: /* 0 > 0 likely */
5534 case OPC_BLTZL
: /* 0 < 0 likely */
5535 /* Skip the instruction in the delay slot */
5536 ctx
->base
.pc_next
+= 4;
5539 ctx
->hflags
|= MIPS_HFLAG_B
;
5542 ctx
->hflags
|= MIPS_HFLAG_BX
;
5546 ctx
->hflags
|= MIPS_HFLAG_B
;
5549 ctx
->hflags
|= MIPS_HFLAG_BR
;
5553 ctx
->hflags
|= MIPS_HFLAG_BR
;
5556 MIPS_INVAL("branch/jump");
5557 gen_reserved_instruction(ctx
);
5563 tcg_gen_setcond_tl(TCG_COND_EQ
, bcond
, t0
, t1
);
5566 tcg_gen_setcond_tl(TCG_COND_EQ
, bcond
, t0
, t1
);
5569 tcg_gen_setcond_tl(TCG_COND_NE
, bcond
, t0
, t1
);
5572 tcg_gen_setcond_tl(TCG_COND_NE
, bcond
, t0
, t1
);
5575 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
5578 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
5581 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
5585 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
5589 tcg_gen_setcondi_tl(TCG_COND_GT
, bcond
, t0
, 0);
5592 tcg_gen_setcondi_tl(TCG_COND_GT
, bcond
, t0
, 0);
5595 tcg_gen_setcondi_tl(TCG_COND_LE
, bcond
, t0
, 0);
5598 tcg_gen_setcondi_tl(TCG_COND_LE
, bcond
, t0
, 0);
5601 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
5604 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
5607 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 32);
5609 #if defined(TARGET_MIPS64)
5611 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 64);
5615 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
5618 ctx
->hflags
|= MIPS_HFLAG_BC
;
5621 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
5624 ctx
->hflags
|= MIPS_HFLAG_BL
;
5627 MIPS_INVAL("conditional branch/jump");
5628 gen_reserved_instruction(ctx
);
5633 ctx
->btarget
= btgt
;
5635 switch (delayslot_size
) {
5637 ctx
->hflags
|= MIPS_HFLAG_BDS16
;
5640 ctx
->hflags
|= MIPS_HFLAG_BDS32
;
5645 int post_delay
= insn_bytes
+ delayslot_size
;
5646 int lowbit
= !!(ctx
->hflags
& MIPS_HFLAG_M16
);
5648 tcg_gen_movi_tl(cpu_gpr
[blink
],
5649 ctx
->base
.pc_next
+ post_delay
+ lowbit
);
5653 if (insn_bytes
== 2) {
5654 ctx
->hflags
|= MIPS_HFLAG_B16
;
5661 /* nanoMIPS Branches */
5662 static void gen_compute_branch_nm(DisasContext
*ctx
, uint32_t opc
,
5664 int rs
, int rt
, int32_t offset
)
5666 target_ulong btgt
= -1;
5667 int bcond_compute
= 0;
5668 TCGv t0
= tcg_temp_new();
5669 TCGv t1
= tcg_temp_new();
5671 /* Load needed operands */
5675 /* Compare two registers */
5677 gen_load_gpr(t0
, rs
);
5678 gen_load_gpr(t1
, rt
);
5681 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ offset
;
5684 /* Compare to zero */
5686 gen_load_gpr(t0
, rs
);
5689 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ offset
;
5692 tcg_gen_andi_tl(t0
, cpu_dspctrl
, 0x3F);
5694 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ offset
;
5698 /* Jump to register */
5699 if (offset
!= 0 && offset
!= 16) {
5701 * Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
5702 * others are reserved.
5704 MIPS_INVAL("jump hint");
5705 gen_reserved_instruction(ctx
);
5708 gen_load_gpr(btarget
, rs
);
5711 MIPS_INVAL("branch/jump");
5712 gen_reserved_instruction(ctx
);
5715 if (bcond_compute
== 0) {
5716 /* No condition to be computed */
5718 case OPC_BEQ
: /* rx == rx */
5720 ctx
->hflags
|= MIPS_HFLAG_B
;
5722 case OPC_BGEZAL
: /* 0 >= 0 */
5723 /* Always take and link */
5724 tcg_gen_movi_tl(cpu_gpr
[31],
5725 ctx
->base
.pc_next
+ insn_bytes
);
5726 ctx
->hflags
|= MIPS_HFLAG_B
;
5728 case OPC_BNE
: /* rx != rx */
5729 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 8);
5730 /* Skip the instruction in the delay slot */
5731 ctx
->base
.pc_next
+= 4;
5734 ctx
->hflags
|= MIPS_HFLAG_BR
;
5738 tcg_gen_movi_tl(cpu_gpr
[rt
],
5739 ctx
->base
.pc_next
+ insn_bytes
);
5741 ctx
->hflags
|= MIPS_HFLAG_BR
;
5744 MIPS_INVAL("branch/jump");
5745 gen_reserved_instruction(ctx
);
5751 tcg_gen_setcond_tl(TCG_COND_EQ
, bcond
, t0
, t1
);
5754 tcg_gen_setcond_tl(TCG_COND_NE
, bcond
, t0
, t1
);
5757 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
5758 tcg_gen_movi_tl(cpu_gpr
[31],
5759 ctx
->base
.pc_next
+ insn_bytes
);
5762 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 32);
5764 ctx
->hflags
|= MIPS_HFLAG_BC
;
5767 MIPS_INVAL("conditional branch/jump");
5768 gen_reserved_instruction(ctx
);
5773 ctx
->btarget
= btgt
;
5776 if (insn_bytes
== 2) {
5777 ctx
->hflags
|= MIPS_HFLAG_B16
;
5784 /* special3 bitfield operations */
5785 static void gen_bitops(DisasContext
*ctx
, uint32_t opc
, int rt
,
5786 int rs
, int lsb
, int msb
)
5788 TCGv t0
= tcg_temp_new();
5789 TCGv t1
= tcg_temp_new();
5791 gen_load_gpr(t1
, rs
);
5794 if (lsb
+ msb
> 31) {
5798 tcg_gen_extract_tl(t0
, t1
, lsb
, msb
+ 1);
5801 * The two checks together imply that lsb == 0,
5802 * so this is a simple sign-extension.
5804 tcg_gen_ext32s_tl(t0
, t1
);
5807 #if defined(TARGET_MIPS64)
5816 if (lsb
+ msb
> 63) {
5819 tcg_gen_extract_tl(t0
, t1
, lsb
, msb
+ 1);
5826 gen_load_gpr(t0
, rt
);
5827 tcg_gen_deposit_tl(t0
, t0
, t1
, lsb
, msb
- lsb
+ 1);
5828 tcg_gen_ext32s_tl(t0
, t0
);
5830 #if defined(TARGET_MIPS64)
5841 gen_load_gpr(t0
, rt
);
5842 tcg_gen_deposit_tl(t0
, t0
, t1
, lsb
, msb
- lsb
+ 1);
5847 MIPS_INVAL("bitops");
5848 gen_reserved_instruction(ctx
);
5853 gen_store_gpr(t0
, rt
);
5858 static void gen_bshfl(DisasContext
*ctx
, uint32_t op2
, int rt
, int rd
)
5863 /* If no destination, treat it as a NOP. */
5867 t0
= tcg_temp_new();
5868 gen_load_gpr(t0
, rt
);
5872 TCGv t1
= tcg_temp_new();
5873 TCGv t2
= tcg_const_tl(0x00FF00FF);
5875 tcg_gen_shri_tl(t1
, t0
, 8);
5876 tcg_gen_and_tl(t1
, t1
, t2
);
5877 tcg_gen_and_tl(t0
, t0
, t2
);
5878 tcg_gen_shli_tl(t0
, t0
, 8);
5879 tcg_gen_or_tl(t0
, t0
, t1
);
5882 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
5886 tcg_gen_ext8s_tl(cpu_gpr
[rd
], t0
);
5889 tcg_gen_ext16s_tl(cpu_gpr
[rd
], t0
);
5891 #if defined(TARGET_MIPS64)
5894 TCGv t1
= tcg_temp_new();
5895 TCGv t2
= tcg_const_tl(0x00FF00FF00FF00FFULL
);
5897 tcg_gen_shri_tl(t1
, t0
, 8);
5898 tcg_gen_and_tl(t1
, t1
, t2
);
5899 tcg_gen_and_tl(t0
, t0
, t2
);
5900 tcg_gen_shli_tl(t0
, t0
, 8);
5901 tcg_gen_or_tl(cpu_gpr
[rd
], t0
, t1
);
5908 TCGv t1
= tcg_temp_new();
5909 TCGv t2
= tcg_const_tl(0x0000FFFF0000FFFFULL
);
5911 tcg_gen_shri_tl(t1
, t0
, 16);
5912 tcg_gen_and_tl(t1
, t1
, t2
);
5913 tcg_gen_and_tl(t0
, t0
, t2
);
5914 tcg_gen_shli_tl(t0
, t0
, 16);
5915 tcg_gen_or_tl(t0
, t0
, t1
);
5916 tcg_gen_shri_tl(t1
, t0
, 32);
5917 tcg_gen_shli_tl(t0
, t0
, 32);
5918 tcg_gen_or_tl(cpu_gpr
[rd
], t0
, t1
);
5925 MIPS_INVAL("bsfhl");
5926 gen_reserved_instruction(ctx
);
5933 static void gen_align_bits(DisasContext
*ctx
, int wordsz
, int rd
, int rs
,
5941 t0
= tcg_temp_new();
5942 if (bits
== 0 || bits
== wordsz
) {
5944 gen_load_gpr(t0
, rt
);
5946 gen_load_gpr(t0
, rs
);
5950 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
5952 #if defined(TARGET_MIPS64)
5954 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
5959 TCGv t1
= tcg_temp_new();
5960 gen_load_gpr(t0
, rt
);
5961 gen_load_gpr(t1
, rs
);
5965 TCGv_i64 t2
= tcg_temp_new_i64();
5966 tcg_gen_concat_tl_i64(t2
, t1
, t0
);
5967 tcg_gen_shri_i64(t2
, t2
, 32 - bits
);
5968 gen_move_low32(cpu_gpr
[rd
], t2
);
5969 tcg_temp_free_i64(t2
);
5972 #if defined(TARGET_MIPS64)
5974 tcg_gen_shli_tl(t0
, t0
, bits
);
5975 tcg_gen_shri_tl(t1
, t1
, 64 - bits
);
5976 tcg_gen_or_tl(cpu_gpr
[rd
], t1
, t0
);
5986 static void gen_align(DisasContext
*ctx
, int wordsz
, int rd
, int rs
, int rt
,
5989 gen_align_bits(ctx
, wordsz
, rd
, rs
, rt
, bp
* 8);
5992 static void gen_ext(DisasContext
*ctx
, int wordsz
, int rd
, int rs
, int rt
,
5995 gen_align_bits(ctx
, wordsz
, rd
, rs
, rt
, wordsz
- shift
);
5998 static void gen_bitswap(DisasContext
*ctx
, int opc
, int rd
, int rt
)
6005 t0
= tcg_temp_new();
6006 gen_load_gpr(t0
, rt
);
6009 gen_helper_bitswap(cpu_gpr
[rd
], t0
);
6011 #if defined(TARGET_MIPS64)
6013 gen_helper_dbitswap(cpu_gpr
[rd
], t0
);
6020 #ifndef CONFIG_USER_ONLY
6021 /* CP0 (MMU and control) */
6022 static inline void gen_mthc0_entrylo(TCGv arg
, target_ulong off
)
6024 TCGv_i64 t0
= tcg_temp_new_i64();
6025 TCGv_i64 t1
= tcg_temp_new_i64();
6027 tcg_gen_ext_tl_i64(t0
, arg
);
6028 tcg_gen_ld_i64(t1
, cpu_env
, off
);
6029 #if defined(TARGET_MIPS64)
6030 tcg_gen_deposit_i64(t1
, t1
, t0
, 30, 32);
6032 tcg_gen_concat32_i64(t1
, t1
, t0
);
6034 tcg_gen_st_i64(t1
, cpu_env
, off
);
6035 tcg_temp_free_i64(t1
);
6036 tcg_temp_free_i64(t0
);
6039 static inline void gen_mthc0_store64(TCGv arg
, target_ulong off
)
6041 TCGv_i64 t0
= tcg_temp_new_i64();
6042 TCGv_i64 t1
= tcg_temp_new_i64();
6044 tcg_gen_ext_tl_i64(t0
, arg
);
6045 tcg_gen_ld_i64(t1
, cpu_env
, off
);
6046 tcg_gen_concat32_i64(t1
, t1
, t0
);
6047 tcg_gen_st_i64(t1
, cpu_env
, off
);
6048 tcg_temp_free_i64(t1
);
6049 tcg_temp_free_i64(t0
);
6052 static inline void gen_mfhc0_entrylo(TCGv arg
, target_ulong off
)
6054 TCGv_i64 t0
= tcg_temp_new_i64();
6056 tcg_gen_ld_i64(t0
, cpu_env
, off
);
6057 #if defined(TARGET_MIPS64)
6058 tcg_gen_shri_i64(t0
, t0
, 30);
6060 tcg_gen_shri_i64(t0
, t0
, 32);
6062 gen_move_low32(arg
, t0
);
6063 tcg_temp_free_i64(t0
);
6066 static inline void gen_mfhc0_load64(TCGv arg
, target_ulong off
, int shift
)
6068 TCGv_i64 t0
= tcg_temp_new_i64();
6070 tcg_gen_ld_i64(t0
, cpu_env
, off
);
6071 tcg_gen_shri_i64(t0
, t0
, 32 + shift
);
6072 gen_move_low32(arg
, t0
);
6073 tcg_temp_free_i64(t0
);
6076 static inline void gen_mfc0_load32(TCGv arg
, target_ulong off
)
6078 TCGv_i32 t0
= tcg_temp_new_i32();
6080 tcg_gen_ld_i32(t0
, cpu_env
, off
);
6081 tcg_gen_ext_i32_tl(arg
, t0
);
6082 tcg_temp_free_i32(t0
);
6085 static inline void gen_mfc0_load64(TCGv arg
, target_ulong off
)
6087 tcg_gen_ld_tl(arg
, cpu_env
, off
);
6088 tcg_gen_ext32s_tl(arg
, arg
);
6091 static inline void gen_mtc0_store32(TCGv arg
, target_ulong off
)
6093 TCGv_i32 t0
= tcg_temp_new_i32();
6095 tcg_gen_trunc_tl_i32(t0
, arg
);
6096 tcg_gen_st_i32(t0
, cpu_env
, off
);
6097 tcg_temp_free_i32(t0
);
6100 #define CP0_CHECK(c) \
6103 goto cp0_unimplemented; \
6107 static void gen_mfhc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
6109 const char *register_name
= "invalid";
6112 case CP0_REGISTER_02
:
6115 CP0_CHECK(ctx
->hflags
& MIPS_HFLAG_ELPA
);
6116 gen_mfhc0_entrylo(arg
, offsetof(CPUMIPSState
, CP0_EntryLo0
));
6117 register_name
= "EntryLo0";
6120 goto cp0_unimplemented
;
6123 case CP0_REGISTER_03
:
6125 case CP0_REG03__ENTRYLO1
:
6126 CP0_CHECK(ctx
->hflags
& MIPS_HFLAG_ELPA
);
6127 gen_mfhc0_entrylo(arg
, offsetof(CPUMIPSState
, CP0_EntryLo1
));
6128 register_name
= "EntryLo1";
6131 goto cp0_unimplemented
;
6134 case CP0_REGISTER_09
:
6136 case CP0_REG09__SAAR
:
6137 CP0_CHECK(ctx
->saar
);
6138 gen_helper_mfhc0_saar(arg
, cpu_env
);
6139 register_name
= "SAAR";
6142 goto cp0_unimplemented
;
6145 case CP0_REGISTER_17
:
6147 case CP0_REG17__LLADDR
:
6148 gen_mfhc0_load64(arg
, offsetof(CPUMIPSState
, CP0_LLAddr
),
6149 ctx
->CP0_LLAddr_shift
);
6150 register_name
= "LLAddr";
6152 case CP0_REG17__MAAR
:
6153 CP0_CHECK(ctx
->mrp
);
6154 gen_helper_mfhc0_maar(arg
, cpu_env
);
6155 register_name
= "MAAR";
6158 goto cp0_unimplemented
;
6161 case CP0_REGISTER_19
:
6163 case CP0_REG19__WATCHHI0
:
6164 case CP0_REG19__WATCHHI1
:
6165 case CP0_REG19__WATCHHI2
:
6166 case CP0_REG19__WATCHHI3
:
6167 case CP0_REG19__WATCHHI4
:
6168 case CP0_REG19__WATCHHI5
:
6169 case CP0_REG19__WATCHHI6
:
6170 case CP0_REG19__WATCHHI7
:
6171 /* upper 32 bits are only available when Config5MI != 0 */
6173 gen_mfhc0_load64(arg
, offsetof(CPUMIPSState
, CP0_WatchHi
[sel
]), 0);
6174 register_name
= "WatchHi";
6177 goto cp0_unimplemented
;
6180 case CP0_REGISTER_28
:
6186 gen_mfhc0_load64(arg
, offsetof(CPUMIPSState
, CP0_TagLo
), 0);
6187 register_name
= "TagLo";
6190 goto cp0_unimplemented
;
6194 goto cp0_unimplemented
;
6196 trace_mips_translate_c0("mfhc0", register_name
, reg
, sel
);
6200 qemu_log_mask(LOG_UNIMP
, "mfhc0 %s (reg %d sel %d)\n",
6201 register_name
, reg
, sel
);
6202 tcg_gen_movi_tl(arg
, 0);
6205 static void gen_mthc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
6207 const char *register_name
= "invalid";
6208 uint64_t mask
= ctx
->PAMask
>> 36;
6211 case CP0_REGISTER_02
:
6214 CP0_CHECK(ctx
->hflags
& MIPS_HFLAG_ELPA
);
6215 tcg_gen_andi_tl(arg
, arg
, mask
);
6216 gen_mthc0_entrylo(arg
, offsetof(CPUMIPSState
, CP0_EntryLo0
));
6217 register_name
= "EntryLo0";
6220 goto cp0_unimplemented
;
6223 case CP0_REGISTER_03
:
6225 case CP0_REG03__ENTRYLO1
:
6226 CP0_CHECK(ctx
->hflags
& MIPS_HFLAG_ELPA
);
6227 tcg_gen_andi_tl(arg
, arg
, mask
);
6228 gen_mthc0_entrylo(arg
, offsetof(CPUMIPSState
, CP0_EntryLo1
));
6229 register_name
= "EntryLo1";
6232 goto cp0_unimplemented
;
6235 case CP0_REGISTER_09
:
6237 case CP0_REG09__SAAR
:
6238 CP0_CHECK(ctx
->saar
);
6239 gen_helper_mthc0_saar(cpu_env
, arg
);
6240 register_name
= "SAAR";
6243 goto cp0_unimplemented
;
6246 case CP0_REGISTER_17
:
6248 case CP0_REG17__LLADDR
:
6250 * LLAddr is read-only (the only exception is bit 0 if LLB is
6251 * supported); the CP0_LLAddr_rw_bitmask does not seem to be
6252 * relevant for modern MIPS cores supporting MTHC0, therefore
6253 * treating MTHC0 to LLAddr as NOP.
6255 register_name
= "LLAddr";
6257 case CP0_REG17__MAAR
:
6258 CP0_CHECK(ctx
->mrp
);
6259 gen_helper_mthc0_maar(cpu_env
, arg
);
6260 register_name
= "MAAR";
6263 goto cp0_unimplemented
;
6266 case CP0_REGISTER_19
:
6268 case CP0_REG19__WATCHHI0
:
6269 case CP0_REG19__WATCHHI1
:
6270 case CP0_REG19__WATCHHI2
:
6271 case CP0_REG19__WATCHHI3
:
6272 case CP0_REG19__WATCHHI4
:
6273 case CP0_REG19__WATCHHI5
:
6274 case CP0_REG19__WATCHHI6
:
6275 case CP0_REG19__WATCHHI7
:
6276 /* upper 32 bits are only available when Config5MI != 0 */
6278 gen_helper_0e1i(mthc0_watchhi
, arg
, sel
);
6279 register_name
= "WatchHi";
6282 goto cp0_unimplemented
;
6285 case CP0_REGISTER_28
:
6291 tcg_gen_andi_tl(arg
, arg
, mask
);
6292 gen_mthc0_store64(arg
, offsetof(CPUMIPSState
, CP0_TagLo
));
6293 register_name
= "TagLo";
6296 goto cp0_unimplemented
;
6300 goto cp0_unimplemented
;
6302 trace_mips_translate_c0("mthc0", register_name
, reg
, sel
);
6305 qemu_log_mask(LOG_UNIMP
, "mthc0 %s (reg %d sel %d)\n",
6306 register_name
, reg
, sel
);
6309 static inline void gen_mfc0_unimplemented(DisasContext
*ctx
, TCGv arg
)
6311 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
6312 tcg_gen_movi_tl(arg
, 0);
6314 tcg_gen_movi_tl(arg
, ~0);
6318 static void gen_mfc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
6320 const char *register_name
= "invalid";
6323 check_insn(ctx
, ISA_MIPS_R1
);
6327 case CP0_REGISTER_00
:
6329 case CP0_REG00__INDEX
:
6330 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Index
));
6331 register_name
= "Index";
6333 case CP0_REG00__MVPCONTROL
:
6334 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6335 gen_helper_mfc0_mvpcontrol(arg
, cpu_env
);
6336 register_name
= "MVPControl";
6338 case CP0_REG00__MVPCONF0
:
6339 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6340 gen_helper_mfc0_mvpconf0(arg
, cpu_env
);
6341 register_name
= "MVPConf0";
6343 case CP0_REG00__MVPCONF1
:
6344 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6345 gen_helper_mfc0_mvpconf1(arg
, cpu_env
);
6346 register_name
= "MVPConf1";
6348 case CP0_REG00__VPCONTROL
:
6350 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPControl
));
6351 register_name
= "VPControl";
6354 goto cp0_unimplemented
;
6357 case CP0_REGISTER_01
:
6359 case CP0_REG01__RANDOM
:
6360 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS_R6
));
6361 gen_helper_mfc0_random(arg
, cpu_env
);
6362 register_name
= "Random";
6364 case CP0_REG01__VPECONTROL
:
6365 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6366 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEControl
));
6367 register_name
= "VPEControl";
6369 case CP0_REG01__VPECONF0
:
6370 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6371 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf0
));
6372 register_name
= "VPEConf0";
6374 case CP0_REG01__VPECONF1
:
6375 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6376 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf1
));
6377 register_name
= "VPEConf1";
6379 case CP0_REG01__YQMASK
:
6380 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6381 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_YQMask
));
6382 register_name
= "YQMask";
6384 case CP0_REG01__VPESCHEDULE
:
6385 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6386 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_VPESchedule
));
6387 register_name
= "VPESchedule";
6389 case CP0_REG01__VPESCHEFBACK
:
6390 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6391 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
6392 register_name
= "VPEScheFBack";
6394 case CP0_REG01__VPEOPT
:
6395 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6396 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEOpt
));
6397 register_name
= "VPEOpt";
6400 goto cp0_unimplemented
;
6403 case CP0_REGISTER_02
:
6405 case CP0_REG02__ENTRYLO0
:
6407 TCGv_i64 tmp
= tcg_temp_new_i64();
6408 tcg_gen_ld_i64(tmp
, cpu_env
,
6409 offsetof(CPUMIPSState
, CP0_EntryLo0
));
6410 #if defined(TARGET_MIPS64)
6412 /* Move RI/XI fields to bits 31:30 */
6413 tcg_gen_shri_tl(arg
, tmp
, CP0EnLo_XI
);
6414 tcg_gen_deposit_tl(tmp
, tmp
, arg
, 30, 2);
6417 gen_move_low32(arg
, tmp
);
6418 tcg_temp_free_i64(tmp
);
6420 register_name
= "EntryLo0";
6422 case CP0_REG02__TCSTATUS
:
6423 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6424 gen_helper_mfc0_tcstatus(arg
, cpu_env
);
6425 register_name
= "TCStatus";
6427 case CP0_REG02__TCBIND
:
6428 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6429 gen_helper_mfc0_tcbind(arg
, cpu_env
);
6430 register_name
= "TCBind";
6432 case CP0_REG02__TCRESTART
:
6433 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6434 gen_helper_mfc0_tcrestart(arg
, cpu_env
);
6435 register_name
= "TCRestart";
6437 case CP0_REG02__TCHALT
:
6438 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6439 gen_helper_mfc0_tchalt(arg
, cpu_env
);
6440 register_name
= "TCHalt";
6442 case CP0_REG02__TCCONTEXT
:
6443 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6444 gen_helper_mfc0_tccontext(arg
, cpu_env
);
6445 register_name
= "TCContext";
6447 case CP0_REG02__TCSCHEDULE
:
6448 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6449 gen_helper_mfc0_tcschedule(arg
, cpu_env
);
6450 register_name
= "TCSchedule";
6452 case CP0_REG02__TCSCHEFBACK
:
6453 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6454 gen_helper_mfc0_tcschefback(arg
, cpu_env
);
6455 register_name
= "TCScheFBack";
6458 goto cp0_unimplemented
;
6461 case CP0_REGISTER_03
:
6463 case CP0_REG03__ENTRYLO1
:
6465 TCGv_i64 tmp
= tcg_temp_new_i64();
6466 tcg_gen_ld_i64(tmp
, cpu_env
,
6467 offsetof(CPUMIPSState
, CP0_EntryLo1
));
6468 #if defined(TARGET_MIPS64)
6470 /* Move RI/XI fields to bits 31:30 */
6471 tcg_gen_shri_tl(arg
, tmp
, CP0EnLo_XI
);
6472 tcg_gen_deposit_tl(tmp
, tmp
, arg
, 30, 2);
6475 gen_move_low32(arg
, tmp
);
6476 tcg_temp_free_i64(tmp
);
6478 register_name
= "EntryLo1";
6480 case CP0_REG03__GLOBALNUM
:
6482 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_GlobalNumber
));
6483 register_name
= "GlobalNumber";
6486 goto cp0_unimplemented
;
6489 case CP0_REGISTER_04
:
6491 case CP0_REG04__CONTEXT
:
6492 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_Context
));
6493 tcg_gen_ext32s_tl(arg
, arg
);
6494 register_name
= "Context";
6496 case CP0_REG04__CONTEXTCONFIG
:
6498 /* gen_helper_mfc0_contextconfig(arg); */
6499 register_name
= "ContextConfig";
6500 goto cp0_unimplemented
;
6501 case CP0_REG04__USERLOCAL
:
6502 CP0_CHECK(ctx
->ulri
);
6503 tcg_gen_ld_tl(arg
, cpu_env
,
6504 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
6505 tcg_gen_ext32s_tl(arg
, arg
);
6506 register_name
= "UserLocal";
6508 case CP0_REG04__MMID
:
6510 gen_helper_mtc0_memorymapid(cpu_env
, arg
);
6511 register_name
= "MMID";
6514 goto cp0_unimplemented
;
6517 case CP0_REGISTER_05
:
6519 case CP0_REG05__PAGEMASK
:
6520 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageMask
));
6521 register_name
= "PageMask";
6523 case CP0_REG05__PAGEGRAIN
:
6524 check_insn(ctx
, ISA_MIPS_R2
);
6525 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageGrain
));
6526 register_name
= "PageGrain";
6528 case CP0_REG05__SEGCTL0
:
6530 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_SegCtl0
));
6531 tcg_gen_ext32s_tl(arg
, arg
);
6532 register_name
= "SegCtl0";
6534 case CP0_REG05__SEGCTL1
:
6536 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_SegCtl1
));
6537 tcg_gen_ext32s_tl(arg
, arg
);
6538 register_name
= "SegCtl1";
6540 case CP0_REG05__SEGCTL2
:
6542 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_SegCtl2
));
6543 tcg_gen_ext32s_tl(arg
, arg
);
6544 register_name
= "SegCtl2";
6546 case CP0_REG05__PWBASE
:
6548 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PWBase
));
6549 register_name
= "PWBase";
6551 case CP0_REG05__PWFIELD
:
6553 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PWField
));
6554 register_name
= "PWField";
6556 case CP0_REG05__PWSIZE
:
6558 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PWSize
));
6559 register_name
= "PWSize";
6562 goto cp0_unimplemented
;
6565 case CP0_REGISTER_06
:
6567 case CP0_REG06__WIRED
:
6568 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Wired
));
6569 register_name
= "Wired";
6571 case CP0_REG06__SRSCONF0
:
6572 check_insn(ctx
, ISA_MIPS_R2
);
6573 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf0
));
6574 register_name
= "SRSConf0";
6576 case CP0_REG06__SRSCONF1
:
6577 check_insn(ctx
, ISA_MIPS_R2
);
6578 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf1
));
6579 register_name
= "SRSConf1";
6581 case CP0_REG06__SRSCONF2
:
6582 check_insn(ctx
, ISA_MIPS_R2
);
6583 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf2
));
6584 register_name
= "SRSConf2";
6586 case CP0_REG06__SRSCONF3
:
6587 check_insn(ctx
, ISA_MIPS_R2
);
6588 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf3
));
6589 register_name
= "SRSConf3";
6591 case CP0_REG06__SRSCONF4
:
6592 check_insn(ctx
, ISA_MIPS_R2
);
6593 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf4
));
6594 register_name
= "SRSConf4";
6596 case CP0_REG06__PWCTL
:
6598 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PWCtl
));
6599 register_name
= "PWCtl";
6602 goto cp0_unimplemented
;
6605 case CP0_REGISTER_07
:
6607 case CP0_REG07__HWRENA
:
6608 check_insn(ctx
, ISA_MIPS_R2
);
6609 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_HWREna
));
6610 register_name
= "HWREna";
6613 goto cp0_unimplemented
;
6616 case CP0_REGISTER_08
:
6618 case CP0_REG08__BADVADDR
:
6619 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_BadVAddr
));
6620 tcg_gen_ext32s_tl(arg
, arg
);
6621 register_name
= "BadVAddr";
6623 case CP0_REG08__BADINSTR
:
6625 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstr
));
6626 register_name
= "BadInstr";
6628 case CP0_REG08__BADINSTRP
:
6630 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstrP
));
6631 register_name
= "BadInstrP";
6633 case CP0_REG08__BADINSTRX
:
6635 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstrX
));
6636 tcg_gen_andi_tl(arg
, arg
, ~0xffff);
6637 register_name
= "BadInstrX";
6640 goto cp0_unimplemented
;
6643 case CP0_REGISTER_09
:
6645 case CP0_REG09__COUNT
:
6646 /* Mark as an IO operation because we read the time. */
6647 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
6650 gen_helper_mfc0_count(arg
, cpu_env
);
6652 * Break the TB to be able to take timer interrupts immediately
6653 * after reading count. DISAS_STOP isn't sufficient, we need to
6654 * ensure we break completely out of translated code.
6656 gen_save_pc(ctx
->base
.pc_next
+ 4);
6657 ctx
->base
.is_jmp
= DISAS_EXIT
;
6658 register_name
= "Count";
6660 case CP0_REG09__SAARI
:
6661 CP0_CHECK(ctx
->saar
);
6662 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SAARI
));
6663 register_name
= "SAARI";
6665 case CP0_REG09__SAAR
:
6666 CP0_CHECK(ctx
->saar
);
6667 gen_helper_mfc0_saar(arg
, cpu_env
);
6668 register_name
= "SAAR";
6671 goto cp0_unimplemented
;
6674 case CP0_REGISTER_10
:
6676 case CP0_REG10__ENTRYHI
:
6677 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryHi
));
6678 tcg_gen_ext32s_tl(arg
, arg
);
6679 register_name
= "EntryHi";
6682 goto cp0_unimplemented
;
6685 case CP0_REGISTER_11
:
6687 case CP0_REG11__COMPARE
:
6688 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Compare
));
6689 register_name
= "Compare";
6691 /* 6,7 are implementation dependent */
6693 goto cp0_unimplemented
;
6696 case CP0_REGISTER_12
:
6698 case CP0_REG12__STATUS
:
6699 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Status
));
6700 register_name
= "Status";
6702 case CP0_REG12__INTCTL
:
6703 check_insn(ctx
, ISA_MIPS_R2
);
6704 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_IntCtl
));
6705 register_name
= "IntCtl";
6707 case CP0_REG12__SRSCTL
:
6708 check_insn(ctx
, ISA_MIPS_R2
);
6709 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
6710 register_name
= "SRSCtl";
6712 case CP0_REG12__SRSMAP
:
6713 check_insn(ctx
, ISA_MIPS_R2
);
6714 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
6715 register_name
= "SRSMap";
6718 goto cp0_unimplemented
;
6721 case CP0_REGISTER_13
:
6723 case CP0_REG13__CAUSE
:
6724 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Cause
));
6725 register_name
= "Cause";
6728 goto cp0_unimplemented
;
6731 case CP0_REGISTER_14
:
6733 case CP0_REG14__EPC
:
6734 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
6735 tcg_gen_ext32s_tl(arg
, arg
);
6736 register_name
= "EPC";
6739 goto cp0_unimplemented
;
6742 case CP0_REGISTER_15
:
6744 case CP0_REG15__PRID
:
6745 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PRid
));
6746 register_name
= "PRid";
6748 case CP0_REG15__EBASE
:
6749 check_insn(ctx
, ISA_MIPS_R2
);
6750 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EBase
));
6751 tcg_gen_ext32s_tl(arg
, arg
);
6752 register_name
= "EBase";
6754 case CP0_REG15__CMGCRBASE
:
6755 check_insn(ctx
, ISA_MIPS_R2
);
6756 CP0_CHECK(ctx
->cmgcr
);
6757 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_CMGCRBase
));
6758 tcg_gen_ext32s_tl(arg
, arg
);
6759 register_name
= "CMGCRBase";
6762 goto cp0_unimplemented
;
6765 case CP0_REGISTER_16
:
6767 case CP0_REG16__CONFIG
:
6768 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config0
));
6769 register_name
= "Config";
6771 case CP0_REG16__CONFIG1
:
6772 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config1
));
6773 register_name
= "Config1";
6775 case CP0_REG16__CONFIG2
:
6776 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config2
));
6777 register_name
= "Config2";
6779 case CP0_REG16__CONFIG3
:
6780 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config3
));
6781 register_name
= "Config3";
6783 case CP0_REG16__CONFIG4
:
6784 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config4
));
6785 register_name
= "Config4";
6787 case CP0_REG16__CONFIG5
:
6788 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config5
));
6789 register_name
= "Config5";
6791 /* 6,7 are implementation dependent */
6792 case CP0_REG16__CONFIG6
:
6793 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config6
));
6794 register_name
= "Config6";
6796 case CP0_REG16__CONFIG7
:
6797 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config7
));
6798 register_name
= "Config7";
6801 goto cp0_unimplemented
;
6804 case CP0_REGISTER_17
:
6806 case CP0_REG17__LLADDR
:
6807 gen_helper_mfc0_lladdr(arg
, cpu_env
);
6808 register_name
= "LLAddr";
6810 case CP0_REG17__MAAR
:
6811 CP0_CHECK(ctx
->mrp
);
6812 gen_helper_mfc0_maar(arg
, cpu_env
);
6813 register_name
= "MAAR";
6815 case CP0_REG17__MAARI
:
6816 CP0_CHECK(ctx
->mrp
);
6817 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_MAARI
));
6818 register_name
= "MAARI";
6821 goto cp0_unimplemented
;
6824 case CP0_REGISTER_18
:
6826 case CP0_REG18__WATCHLO0
:
6827 case CP0_REG18__WATCHLO1
:
6828 case CP0_REG18__WATCHLO2
:
6829 case CP0_REG18__WATCHLO3
:
6830 case CP0_REG18__WATCHLO4
:
6831 case CP0_REG18__WATCHLO5
:
6832 case CP0_REG18__WATCHLO6
:
6833 case CP0_REG18__WATCHLO7
:
6834 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
6835 gen_helper_1e0i(mfc0_watchlo
, arg
, sel
);
6836 register_name
= "WatchLo";
6839 goto cp0_unimplemented
;
6842 case CP0_REGISTER_19
:
6844 case CP0_REG19__WATCHHI0
:
6845 case CP0_REG19__WATCHHI1
:
6846 case CP0_REG19__WATCHHI2
:
6847 case CP0_REG19__WATCHHI3
:
6848 case CP0_REG19__WATCHHI4
:
6849 case CP0_REG19__WATCHHI5
:
6850 case CP0_REG19__WATCHHI6
:
6851 case CP0_REG19__WATCHHI7
:
6852 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
6853 gen_helper_1e0i(mfc0_watchhi
, arg
, sel
);
6854 register_name
= "WatchHi";
6857 goto cp0_unimplemented
;
6860 case CP0_REGISTER_20
:
6862 case CP0_REG20__XCONTEXT
:
6863 #if defined(TARGET_MIPS64)
6864 check_insn(ctx
, ISA_MIPS3
);
6865 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_XContext
));
6866 tcg_gen_ext32s_tl(arg
, arg
);
6867 register_name
= "XContext";
6871 goto cp0_unimplemented
;
6874 case CP0_REGISTER_21
:
6875 /* Officially reserved, but sel 0 is used for R1x000 framemask */
6876 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS_R6
));
6879 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Framemask
));
6880 register_name
= "Framemask";
6883 goto cp0_unimplemented
;
6886 case CP0_REGISTER_22
:
6887 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
6888 register_name
= "'Diagnostic"; /* implementation dependent */
6890 case CP0_REGISTER_23
:
6892 case CP0_REG23__DEBUG
:
6893 gen_helper_mfc0_debug(arg
, cpu_env
); /* EJTAG support */
6894 register_name
= "Debug";
6896 case CP0_REG23__TRACECONTROL
:
6897 /* PDtrace support */
6898 /* gen_helper_mfc0_tracecontrol(arg); */
6899 register_name
= "TraceControl";
6900 goto cp0_unimplemented
;
6901 case CP0_REG23__TRACECONTROL2
:
6902 /* PDtrace support */
6903 /* gen_helper_mfc0_tracecontrol2(arg); */
6904 register_name
= "TraceControl2";
6905 goto cp0_unimplemented
;
6906 case CP0_REG23__USERTRACEDATA1
:
6907 /* PDtrace support */
6908 /* gen_helper_mfc0_usertracedata1(arg);*/
6909 register_name
= "UserTraceData1";
6910 goto cp0_unimplemented
;
6911 case CP0_REG23__TRACEIBPC
:
6912 /* PDtrace support */
6913 /* gen_helper_mfc0_traceibpc(arg); */
6914 register_name
= "TraceIBPC";
6915 goto cp0_unimplemented
;
6916 case CP0_REG23__TRACEDBPC
:
6917 /* PDtrace support */
6918 /* gen_helper_mfc0_tracedbpc(arg); */
6919 register_name
= "TraceDBPC";
6920 goto cp0_unimplemented
;
6922 goto cp0_unimplemented
;
6925 case CP0_REGISTER_24
:
6927 case CP0_REG24__DEPC
:
6929 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
6930 tcg_gen_ext32s_tl(arg
, arg
);
6931 register_name
= "DEPC";
6934 goto cp0_unimplemented
;
6937 case CP0_REGISTER_25
:
6939 case CP0_REG25__PERFCTL0
:
6940 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Performance0
));
6941 register_name
= "Performance0";
6943 case CP0_REG25__PERFCNT0
:
6944 /* gen_helper_mfc0_performance1(arg); */
6945 register_name
= "Performance1";
6946 goto cp0_unimplemented
;
6947 case CP0_REG25__PERFCTL1
:
6948 /* gen_helper_mfc0_performance2(arg); */
6949 register_name
= "Performance2";
6950 goto cp0_unimplemented
;
6951 case CP0_REG25__PERFCNT1
:
6952 /* gen_helper_mfc0_performance3(arg); */
6953 register_name
= "Performance3";
6954 goto cp0_unimplemented
;
6955 case CP0_REG25__PERFCTL2
:
6956 /* gen_helper_mfc0_performance4(arg); */
6957 register_name
= "Performance4";
6958 goto cp0_unimplemented
;
6959 case CP0_REG25__PERFCNT2
:
6960 /* gen_helper_mfc0_performance5(arg); */
6961 register_name
= "Performance5";
6962 goto cp0_unimplemented
;
6963 case CP0_REG25__PERFCTL3
:
6964 /* gen_helper_mfc0_performance6(arg); */
6965 register_name
= "Performance6";
6966 goto cp0_unimplemented
;
6967 case CP0_REG25__PERFCNT3
:
6968 /* gen_helper_mfc0_performance7(arg); */
6969 register_name
= "Performance7";
6970 goto cp0_unimplemented
;
6972 goto cp0_unimplemented
;
6975 case CP0_REGISTER_26
:
6977 case CP0_REG26__ERRCTL
:
6978 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_ErrCtl
));
6979 register_name
= "ErrCtl";
6982 goto cp0_unimplemented
;
6985 case CP0_REGISTER_27
:
6987 case CP0_REG27__CACHERR
:
6988 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
6989 register_name
= "CacheErr";
6992 goto cp0_unimplemented
;
6995 case CP0_REGISTER_28
:
6997 case CP0_REG28__TAGLO
:
6998 case CP0_REG28__TAGLO1
:
6999 case CP0_REG28__TAGLO2
:
7000 case CP0_REG28__TAGLO3
:
7002 TCGv_i64 tmp
= tcg_temp_new_i64();
7003 tcg_gen_ld_i64(tmp
, cpu_env
, offsetof(CPUMIPSState
, CP0_TagLo
));
7004 gen_move_low32(arg
, tmp
);
7005 tcg_temp_free_i64(tmp
);
7007 register_name
= "TagLo";
7009 case CP0_REG28__DATALO
:
7010 case CP0_REG28__DATALO1
:
7011 case CP0_REG28__DATALO2
:
7012 case CP0_REG28__DATALO3
:
7013 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataLo
));
7014 register_name
= "DataLo";
7017 goto cp0_unimplemented
;
7020 case CP0_REGISTER_29
:
7022 case CP0_REG29__TAGHI
:
7023 case CP0_REG29__TAGHI1
:
7024 case CP0_REG29__TAGHI2
:
7025 case CP0_REG29__TAGHI3
:
7026 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagHi
));
7027 register_name
= "TagHi";
7029 case CP0_REG29__DATAHI
:
7030 case CP0_REG29__DATAHI1
:
7031 case CP0_REG29__DATAHI2
:
7032 case CP0_REG29__DATAHI3
:
7033 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataHi
));
7034 register_name
= "DataHi";
7037 goto cp0_unimplemented
;
7040 case CP0_REGISTER_30
:
7042 case CP0_REG30__ERROREPC
:
7043 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
7044 tcg_gen_ext32s_tl(arg
, arg
);
7045 register_name
= "ErrorEPC";
7048 goto cp0_unimplemented
;
7051 case CP0_REGISTER_31
:
7053 case CP0_REG31__DESAVE
:
7055 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
7056 register_name
= "DESAVE";
7058 case CP0_REG31__KSCRATCH1
:
7059 case CP0_REG31__KSCRATCH2
:
7060 case CP0_REG31__KSCRATCH3
:
7061 case CP0_REG31__KSCRATCH4
:
7062 case CP0_REG31__KSCRATCH5
:
7063 case CP0_REG31__KSCRATCH6
:
7064 CP0_CHECK(ctx
->kscrexist
& (1 << sel
));
7065 tcg_gen_ld_tl(arg
, cpu_env
,
7066 offsetof(CPUMIPSState
, CP0_KScratch
[sel
- 2]));
7067 tcg_gen_ext32s_tl(arg
, arg
);
7068 register_name
= "KScratch";
7071 goto cp0_unimplemented
;
7075 goto cp0_unimplemented
;
7077 trace_mips_translate_c0("mfc0", register_name
, reg
, sel
);
7081 qemu_log_mask(LOG_UNIMP
, "mfc0 %s (reg %d sel %d)\n",
7082 register_name
, reg
, sel
);
7083 gen_mfc0_unimplemented(ctx
, arg
);
7086 static void gen_mtc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
7088 const char *register_name
= "invalid";
7091 check_insn(ctx
, ISA_MIPS_R1
);
7094 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
7099 case CP0_REGISTER_00
:
7101 case CP0_REG00__INDEX
:
7102 gen_helper_mtc0_index(cpu_env
, arg
);
7103 register_name
= "Index";
7105 case CP0_REG00__MVPCONTROL
:
7106 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7107 gen_helper_mtc0_mvpcontrol(cpu_env
, arg
);
7108 register_name
= "MVPControl";
7110 case CP0_REG00__MVPCONF0
:
7111 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7113 register_name
= "MVPConf0";
7115 case CP0_REG00__MVPCONF1
:
7116 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7118 register_name
= "MVPConf1";
7120 case CP0_REG00__VPCONTROL
:
7123 register_name
= "VPControl";
7126 goto cp0_unimplemented
;
7129 case CP0_REGISTER_01
:
7131 case CP0_REG01__RANDOM
:
7133 register_name
= "Random";
7135 case CP0_REG01__VPECONTROL
:
7136 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7137 gen_helper_mtc0_vpecontrol(cpu_env
, arg
);
7138 register_name
= "VPEControl";
7140 case CP0_REG01__VPECONF0
:
7141 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7142 gen_helper_mtc0_vpeconf0(cpu_env
, arg
);
7143 register_name
= "VPEConf0";
7145 case CP0_REG01__VPECONF1
:
7146 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7147 gen_helper_mtc0_vpeconf1(cpu_env
, arg
);
7148 register_name
= "VPEConf1";
7150 case CP0_REG01__YQMASK
:
7151 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7152 gen_helper_mtc0_yqmask(cpu_env
, arg
);
7153 register_name
= "YQMask";
7155 case CP0_REG01__VPESCHEDULE
:
7156 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7157 tcg_gen_st_tl(arg
, cpu_env
,
7158 offsetof(CPUMIPSState
, CP0_VPESchedule
));
7159 register_name
= "VPESchedule";
7161 case CP0_REG01__VPESCHEFBACK
:
7162 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7163 tcg_gen_st_tl(arg
, cpu_env
,
7164 offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
7165 register_name
= "VPEScheFBack";
7167 case CP0_REG01__VPEOPT
:
7168 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7169 gen_helper_mtc0_vpeopt(cpu_env
, arg
);
7170 register_name
= "VPEOpt";
7173 goto cp0_unimplemented
;
7176 case CP0_REGISTER_02
:
7178 case CP0_REG02__ENTRYLO0
:
7179 gen_helper_mtc0_entrylo0(cpu_env
, arg
);
7180 register_name
= "EntryLo0";
7182 case CP0_REG02__TCSTATUS
:
7183 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7184 gen_helper_mtc0_tcstatus(cpu_env
, arg
);
7185 register_name
= "TCStatus";
7187 case CP0_REG02__TCBIND
:
7188 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7189 gen_helper_mtc0_tcbind(cpu_env
, arg
);
7190 register_name
= "TCBind";
7192 case CP0_REG02__TCRESTART
:
7193 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7194 gen_helper_mtc0_tcrestart(cpu_env
, arg
);
7195 register_name
= "TCRestart";
7197 case CP0_REG02__TCHALT
:
7198 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7199 gen_helper_mtc0_tchalt(cpu_env
, arg
);
7200 register_name
= "TCHalt";
7202 case CP0_REG02__TCCONTEXT
:
7203 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7204 gen_helper_mtc0_tccontext(cpu_env
, arg
);
7205 register_name
= "TCContext";
7207 case CP0_REG02__TCSCHEDULE
:
7208 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7209 gen_helper_mtc0_tcschedule(cpu_env
, arg
);
7210 register_name
= "TCSchedule";
7212 case CP0_REG02__TCSCHEFBACK
:
7213 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7214 gen_helper_mtc0_tcschefback(cpu_env
, arg
);
7215 register_name
= "TCScheFBack";
7218 goto cp0_unimplemented
;
7221 case CP0_REGISTER_03
:
7223 case CP0_REG03__ENTRYLO1
:
7224 gen_helper_mtc0_entrylo1(cpu_env
, arg
);
7225 register_name
= "EntryLo1";
7227 case CP0_REG03__GLOBALNUM
:
7230 register_name
= "GlobalNumber";
7233 goto cp0_unimplemented
;
7236 case CP0_REGISTER_04
:
7238 case CP0_REG04__CONTEXT
:
7239 gen_helper_mtc0_context(cpu_env
, arg
);
7240 register_name
= "Context";
7242 case CP0_REG04__CONTEXTCONFIG
:
7244 /* gen_helper_mtc0_contextconfig(arg); */
7245 register_name
= "ContextConfig";
7246 goto cp0_unimplemented
;
7247 case CP0_REG04__USERLOCAL
:
7248 CP0_CHECK(ctx
->ulri
);
7249 tcg_gen_st_tl(arg
, cpu_env
,
7250 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
7251 register_name
= "UserLocal";
7253 case CP0_REG04__MMID
:
7255 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_MemoryMapID
));
7256 register_name
= "MMID";
7259 goto cp0_unimplemented
;
7262 case CP0_REGISTER_05
:
7264 case CP0_REG05__PAGEMASK
:
7265 gen_helper_mtc0_pagemask(cpu_env
, arg
);
7266 register_name
= "PageMask";
7268 case CP0_REG05__PAGEGRAIN
:
7269 check_insn(ctx
, ISA_MIPS_R2
);
7270 gen_helper_mtc0_pagegrain(cpu_env
, arg
);
7271 register_name
= "PageGrain";
7272 ctx
->base
.is_jmp
= DISAS_STOP
;
7274 case CP0_REG05__SEGCTL0
:
7276 gen_helper_mtc0_segctl0(cpu_env
, arg
);
7277 register_name
= "SegCtl0";
7279 case CP0_REG05__SEGCTL1
:
7281 gen_helper_mtc0_segctl1(cpu_env
, arg
);
7282 register_name
= "SegCtl1";
7284 case CP0_REG05__SEGCTL2
:
7286 gen_helper_mtc0_segctl2(cpu_env
, arg
);
7287 register_name
= "SegCtl2";
7289 case CP0_REG05__PWBASE
:
7291 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_PWBase
));
7292 register_name
= "PWBase";
7294 case CP0_REG05__PWFIELD
:
7296 gen_helper_mtc0_pwfield(cpu_env
, arg
);
7297 register_name
= "PWField";
7299 case CP0_REG05__PWSIZE
:
7301 gen_helper_mtc0_pwsize(cpu_env
, arg
);
7302 register_name
= "PWSize";
7305 goto cp0_unimplemented
;
7308 case CP0_REGISTER_06
:
7310 case CP0_REG06__WIRED
:
7311 gen_helper_mtc0_wired(cpu_env
, arg
);
7312 register_name
= "Wired";
7314 case CP0_REG06__SRSCONF0
:
7315 check_insn(ctx
, ISA_MIPS_R2
);
7316 gen_helper_mtc0_srsconf0(cpu_env
, arg
);
7317 register_name
= "SRSConf0";
7319 case CP0_REG06__SRSCONF1
:
7320 check_insn(ctx
, ISA_MIPS_R2
);
7321 gen_helper_mtc0_srsconf1(cpu_env
, arg
);
7322 register_name
= "SRSConf1";
7324 case CP0_REG06__SRSCONF2
:
7325 check_insn(ctx
, ISA_MIPS_R2
);
7326 gen_helper_mtc0_srsconf2(cpu_env
, arg
);
7327 register_name
= "SRSConf2";
7329 case CP0_REG06__SRSCONF3
:
7330 check_insn(ctx
, ISA_MIPS_R2
);
7331 gen_helper_mtc0_srsconf3(cpu_env
, arg
);
7332 register_name
= "SRSConf3";
7334 case CP0_REG06__SRSCONF4
:
7335 check_insn(ctx
, ISA_MIPS_R2
);
7336 gen_helper_mtc0_srsconf4(cpu_env
, arg
);
7337 register_name
= "SRSConf4";
7339 case CP0_REG06__PWCTL
:
7341 gen_helper_mtc0_pwctl(cpu_env
, arg
);
7342 register_name
= "PWCtl";
7345 goto cp0_unimplemented
;
7348 case CP0_REGISTER_07
:
7350 case CP0_REG07__HWRENA
:
7351 check_insn(ctx
, ISA_MIPS_R2
);
7352 gen_helper_mtc0_hwrena(cpu_env
, arg
);
7353 ctx
->base
.is_jmp
= DISAS_STOP
;
7354 register_name
= "HWREna";
7357 goto cp0_unimplemented
;
7360 case CP0_REGISTER_08
:
7362 case CP0_REG08__BADVADDR
:
7364 register_name
= "BadVAddr";
7366 case CP0_REG08__BADINSTR
:
7368 register_name
= "BadInstr";
7370 case CP0_REG08__BADINSTRP
:
7372 register_name
= "BadInstrP";
7374 case CP0_REG08__BADINSTRX
:
7376 register_name
= "BadInstrX";
7379 goto cp0_unimplemented
;
7382 case CP0_REGISTER_09
:
7384 case CP0_REG09__COUNT
:
7385 gen_helper_mtc0_count(cpu_env
, arg
);
7386 register_name
= "Count";
7388 case CP0_REG09__SAARI
:
7389 CP0_CHECK(ctx
->saar
);
7390 gen_helper_mtc0_saari(cpu_env
, arg
);
7391 register_name
= "SAARI";
7393 case CP0_REG09__SAAR
:
7394 CP0_CHECK(ctx
->saar
);
7395 gen_helper_mtc0_saar(cpu_env
, arg
);
7396 register_name
= "SAAR";
7399 goto cp0_unimplemented
;
7402 case CP0_REGISTER_10
:
7404 case CP0_REG10__ENTRYHI
:
7405 gen_helper_mtc0_entryhi(cpu_env
, arg
);
7406 register_name
= "EntryHi";
7409 goto cp0_unimplemented
;
7412 case CP0_REGISTER_11
:
7414 case CP0_REG11__COMPARE
:
7415 gen_helper_mtc0_compare(cpu_env
, arg
);
7416 register_name
= "Compare";
7418 /* 6,7 are implementation dependent */
7420 goto cp0_unimplemented
;
7423 case CP0_REGISTER_12
:
7425 case CP0_REG12__STATUS
:
7426 save_cpu_state(ctx
, 1);
7427 gen_helper_mtc0_status(cpu_env
, arg
);
7428 /* DISAS_STOP isn't good enough here, hflags may have changed. */
7429 gen_save_pc(ctx
->base
.pc_next
+ 4);
7430 ctx
->base
.is_jmp
= DISAS_EXIT
;
7431 register_name
= "Status";
7433 case CP0_REG12__INTCTL
:
7434 check_insn(ctx
, ISA_MIPS_R2
);
7435 gen_helper_mtc0_intctl(cpu_env
, arg
);
7436 /* Stop translation as we may have switched the execution mode */
7437 ctx
->base
.is_jmp
= DISAS_STOP
;
7438 register_name
= "IntCtl";
7440 case CP0_REG12__SRSCTL
:
7441 check_insn(ctx
, ISA_MIPS_R2
);
7442 gen_helper_mtc0_srsctl(cpu_env
, arg
);
7443 /* Stop translation as we may have switched the execution mode */
7444 ctx
->base
.is_jmp
= DISAS_STOP
;
7445 register_name
= "SRSCtl";
7447 case CP0_REG12__SRSMAP
:
7448 check_insn(ctx
, ISA_MIPS_R2
);
7449 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
7450 /* Stop translation as we may have switched the execution mode */
7451 ctx
->base
.is_jmp
= DISAS_STOP
;
7452 register_name
= "SRSMap";
7455 goto cp0_unimplemented
;
7458 case CP0_REGISTER_13
:
7460 case CP0_REG13__CAUSE
:
7461 save_cpu_state(ctx
, 1);
7462 gen_helper_mtc0_cause(cpu_env
, arg
);
7464 * Stop translation as we may have triggered an interrupt.
7465 * DISAS_STOP isn't sufficient, we need to ensure we break out of
7466 * translated code to check for pending interrupts.
7468 gen_save_pc(ctx
->base
.pc_next
+ 4);
7469 ctx
->base
.is_jmp
= DISAS_EXIT
;
7470 register_name
= "Cause";
7473 goto cp0_unimplemented
;
7476 case CP0_REGISTER_14
:
7478 case CP0_REG14__EPC
:
7479 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
7480 register_name
= "EPC";
7483 goto cp0_unimplemented
;
7486 case CP0_REGISTER_15
:
7488 case CP0_REG15__PRID
:
7490 register_name
= "PRid";
7492 case CP0_REG15__EBASE
:
7493 check_insn(ctx
, ISA_MIPS_R2
);
7494 gen_helper_mtc0_ebase(cpu_env
, arg
);
7495 register_name
= "EBase";
7498 goto cp0_unimplemented
;
7501 case CP0_REGISTER_16
:
7503 case CP0_REG16__CONFIG
:
7504 gen_helper_mtc0_config0(cpu_env
, arg
);
7505 register_name
= "Config";
7506 /* Stop translation as we may have switched the execution mode */
7507 ctx
->base
.is_jmp
= DISAS_STOP
;
7509 case CP0_REG16__CONFIG1
:
7510 /* ignored, read only */
7511 register_name
= "Config1";
7513 case CP0_REG16__CONFIG2
:
7514 gen_helper_mtc0_config2(cpu_env
, arg
);
7515 register_name
= "Config2";
7516 /* Stop translation as we may have switched the execution mode */
7517 ctx
->base
.is_jmp
= DISAS_STOP
;
7519 case CP0_REG16__CONFIG3
:
7520 gen_helper_mtc0_config3(cpu_env
, arg
);
7521 register_name
= "Config3";
7522 /* Stop translation as we may have switched the execution mode */
7523 ctx
->base
.is_jmp
= DISAS_STOP
;
7525 case CP0_REG16__CONFIG4
:
7526 gen_helper_mtc0_config4(cpu_env
, arg
);
7527 register_name
= "Config4";
7528 ctx
->base
.is_jmp
= DISAS_STOP
;
7530 case CP0_REG16__CONFIG5
:
7531 gen_helper_mtc0_config5(cpu_env
, arg
);
7532 register_name
= "Config5";
7533 /* Stop translation as we may have switched the execution mode */
7534 ctx
->base
.is_jmp
= DISAS_STOP
;
7536 /* 6,7 are implementation dependent */
7537 case CP0_REG16__CONFIG6
:
7539 register_name
= "Config6";
7541 case CP0_REG16__CONFIG7
:
7543 register_name
= "Config7";
7546 register_name
= "Invalid config selector";
7547 goto cp0_unimplemented
;
7550 case CP0_REGISTER_17
:
7552 case CP0_REG17__LLADDR
:
7553 gen_helper_mtc0_lladdr(cpu_env
, arg
);
7554 register_name
= "LLAddr";
7556 case CP0_REG17__MAAR
:
7557 CP0_CHECK(ctx
->mrp
);
7558 gen_helper_mtc0_maar(cpu_env
, arg
);
7559 register_name
= "MAAR";
7561 case CP0_REG17__MAARI
:
7562 CP0_CHECK(ctx
->mrp
);
7563 gen_helper_mtc0_maari(cpu_env
, arg
);
7564 register_name
= "MAARI";
7567 goto cp0_unimplemented
;
7570 case CP0_REGISTER_18
:
7572 case CP0_REG18__WATCHLO0
:
7573 case CP0_REG18__WATCHLO1
:
7574 case CP0_REG18__WATCHLO2
:
7575 case CP0_REG18__WATCHLO3
:
7576 case CP0_REG18__WATCHLO4
:
7577 case CP0_REG18__WATCHLO5
:
7578 case CP0_REG18__WATCHLO6
:
7579 case CP0_REG18__WATCHLO7
:
7580 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
7581 gen_helper_0e1i(mtc0_watchlo
, arg
, sel
);
7582 register_name
= "WatchLo";
7585 goto cp0_unimplemented
;
7588 case CP0_REGISTER_19
:
7590 case CP0_REG19__WATCHHI0
:
7591 case CP0_REG19__WATCHHI1
:
7592 case CP0_REG19__WATCHHI2
:
7593 case CP0_REG19__WATCHHI3
:
7594 case CP0_REG19__WATCHHI4
:
7595 case CP0_REG19__WATCHHI5
:
7596 case CP0_REG19__WATCHHI6
:
7597 case CP0_REG19__WATCHHI7
:
7598 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
7599 gen_helper_0e1i(mtc0_watchhi
, arg
, sel
);
7600 register_name
= "WatchHi";
7603 goto cp0_unimplemented
;
7606 case CP0_REGISTER_20
:
7608 case CP0_REG20__XCONTEXT
:
7609 #if defined(TARGET_MIPS64)
7610 check_insn(ctx
, ISA_MIPS3
);
7611 gen_helper_mtc0_xcontext(cpu_env
, arg
);
7612 register_name
= "XContext";
7616 goto cp0_unimplemented
;
7619 case CP0_REGISTER_21
:
7620 /* Officially reserved, but sel 0 is used for R1x000 framemask */
7621 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS_R6
));
7624 gen_helper_mtc0_framemask(cpu_env
, arg
);
7625 register_name
= "Framemask";
7628 goto cp0_unimplemented
;
7631 case CP0_REGISTER_22
:
7633 register_name
= "Diagnostic"; /* implementation dependent */
7635 case CP0_REGISTER_23
:
7637 case CP0_REG23__DEBUG
:
7638 gen_helper_mtc0_debug(cpu_env
, arg
); /* EJTAG support */
7639 /* DISAS_STOP isn't good enough here, hflags may have changed. */
7640 gen_save_pc(ctx
->base
.pc_next
+ 4);
7641 ctx
->base
.is_jmp
= DISAS_EXIT
;
7642 register_name
= "Debug";
7644 case CP0_REG23__TRACECONTROL
:
7645 /* PDtrace support */
7646 /* gen_helper_mtc0_tracecontrol(cpu_env, arg); */
7647 register_name
= "TraceControl";
7648 /* Stop translation as we may have switched the execution mode */
7649 ctx
->base
.is_jmp
= DISAS_STOP
;
7650 goto cp0_unimplemented
;
7651 case CP0_REG23__TRACECONTROL2
:
7652 /* PDtrace support */
7653 /* gen_helper_mtc0_tracecontrol2(cpu_env, arg); */
7654 register_name
= "TraceControl2";
7655 /* Stop translation as we may have switched the execution mode */
7656 ctx
->base
.is_jmp
= DISAS_STOP
;
7657 goto cp0_unimplemented
;
7658 case CP0_REG23__USERTRACEDATA1
:
7659 /* Stop translation as we may have switched the execution mode */
7660 ctx
->base
.is_jmp
= DISAS_STOP
;
7661 /* PDtrace support */
7662 /* gen_helper_mtc0_usertracedata1(cpu_env, arg);*/
7663 register_name
= "UserTraceData";
7664 /* Stop translation as we may have switched the execution mode */
7665 ctx
->base
.is_jmp
= DISAS_STOP
;
7666 goto cp0_unimplemented
;
7667 case CP0_REG23__TRACEIBPC
:
7668 /* PDtrace support */
7669 /* gen_helper_mtc0_traceibpc(cpu_env, arg); */
7670 /* Stop translation as we may have switched the execution mode */
7671 ctx
->base
.is_jmp
= DISAS_STOP
;
7672 register_name
= "TraceIBPC";
7673 goto cp0_unimplemented
;
7674 case CP0_REG23__TRACEDBPC
:
7675 /* PDtrace support */
7676 /* gen_helper_mtc0_tracedbpc(cpu_env, arg); */
7677 /* Stop translation as we may have switched the execution mode */
7678 ctx
->base
.is_jmp
= DISAS_STOP
;
7679 register_name
= "TraceDBPC";
7680 goto cp0_unimplemented
;
7682 goto cp0_unimplemented
;
7685 case CP0_REGISTER_24
:
7687 case CP0_REG24__DEPC
:
7689 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
7690 register_name
= "DEPC";
7693 goto cp0_unimplemented
;
7696 case CP0_REGISTER_25
:
7698 case CP0_REG25__PERFCTL0
:
7699 gen_helper_mtc0_performance0(cpu_env
, arg
);
7700 register_name
= "Performance0";
7702 case CP0_REG25__PERFCNT0
:
7703 /* gen_helper_mtc0_performance1(arg); */
7704 register_name
= "Performance1";
7705 goto cp0_unimplemented
;
7706 case CP0_REG25__PERFCTL1
:
7707 /* gen_helper_mtc0_performance2(arg); */
7708 register_name
= "Performance2";
7709 goto cp0_unimplemented
;
7710 case CP0_REG25__PERFCNT1
:
7711 /* gen_helper_mtc0_performance3(arg); */
7712 register_name
= "Performance3";
7713 goto cp0_unimplemented
;
7714 case CP0_REG25__PERFCTL2
:
7715 /* gen_helper_mtc0_performance4(arg); */
7716 register_name
= "Performance4";
7717 goto cp0_unimplemented
;
7718 case CP0_REG25__PERFCNT2
:
7719 /* gen_helper_mtc0_performance5(arg); */
7720 register_name
= "Performance5";
7721 goto cp0_unimplemented
;
7722 case CP0_REG25__PERFCTL3
:
7723 /* gen_helper_mtc0_performance6(arg); */
7724 register_name
= "Performance6";
7725 goto cp0_unimplemented
;
7726 case CP0_REG25__PERFCNT3
:
7727 /* gen_helper_mtc0_performance7(arg); */
7728 register_name
= "Performance7";
7729 goto cp0_unimplemented
;
7731 goto cp0_unimplemented
;
7734 case CP0_REGISTER_26
:
7736 case CP0_REG26__ERRCTL
:
7737 gen_helper_mtc0_errctl(cpu_env
, arg
);
7738 ctx
->base
.is_jmp
= DISAS_STOP
;
7739 register_name
= "ErrCtl";
7742 goto cp0_unimplemented
;
7745 case CP0_REGISTER_27
:
7747 case CP0_REG27__CACHERR
:
7749 register_name
= "CacheErr";
7752 goto cp0_unimplemented
;
7755 case CP0_REGISTER_28
:
7757 case CP0_REG28__TAGLO
:
7758 case CP0_REG28__TAGLO1
:
7759 case CP0_REG28__TAGLO2
:
7760 case CP0_REG28__TAGLO3
:
7761 gen_helper_mtc0_taglo(cpu_env
, arg
);
7762 register_name
= "TagLo";
7764 case CP0_REG28__DATALO
:
7765 case CP0_REG28__DATALO1
:
7766 case CP0_REG28__DATALO2
:
7767 case CP0_REG28__DATALO3
:
7768 gen_helper_mtc0_datalo(cpu_env
, arg
);
7769 register_name
= "DataLo";
7772 goto cp0_unimplemented
;
7775 case CP0_REGISTER_29
:
7777 case CP0_REG29__TAGHI
:
7778 case CP0_REG29__TAGHI1
:
7779 case CP0_REG29__TAGHI2
:
7780 case CP0_REG29__TAGHI3
:
7781 gen_helper_mtc0_taghi(cpu_env
, arg
);
7782 register_name
= "TagHi";
7784 case CP0_REG29__DATAHI
:
7785 case CP0_REG29__DATAHI1
:
7786 case CP0_REG29__DATAHI2
:
7787 case CP0_REG29__DATAHI3
:
7788 gen_helper_mtc0_datahi(cpu_env
, arg
);
7789 register_name
= "DataHi";
7792 register_name
= "invalid sel";
7793 goto cp0_unimplemented
;
7796 case CP0_REGISTER_30
:
7798 case CP0_REG30__ERROREPC
:
7799 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
7800 register_name
= "ErrorEPC";
7803 goto cp0_unimplemented
;
7806 case CP0_REGISTER_31
:
7808 case CP0_REG31__DESAVE
:
7810 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
7811 register_name
= "DESAVE";
7813 case CP0_REG31__KSCRATCH1
:
7814 case CP0_REG31__KSCRATCH2
:
7815 case CP0_REG31__KSCRATCH3
:
7816 case CP0_REG31__KSCRATCH4
:
7817 case CP0_REG31__KSCRATCH5
:
7818 case CP0_REG31__KSCRATCH6
:
7819 CP0_CHECK(ctx
->kscrexist
& (1 << sel
));
7820 tcg_gen_st_tl(arg
, cpu_env
,
7821 offsetof(CPUMIPSState
, CP0_KScratch
[sel
- 2]));
7822 register_name
= "KScratch";
7825 goto cp0_unimplemented
;
7829 goto cp0_unimplemented
;
7831 trace_mips_translate_c0("mtc0", register_name
, reg
, sel
);
7833 /* For simplicity assume that all writes can cause interrupts. */
7834 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
7836 * DISAS_STOP isn't sufficient, we need to ensure we break out of
7837 * translated code to check for pending interrupts.
7839 gen_save_pc(ctx
->base
.pc_next
+ 4);
7840 ctx
->base
.is_jmp
= DISAS_EXIT
;
7845 qemu_log_mask(LOG_UNIMP
, "mtc0 %s (reg %d sel %d)\n",
7846 register_name
, reg
, sel
);
7849 #if defined(TARGET_MIPS64)
7850 static void gen_dmfc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
7852 const char *register_name
= "invalid";
7855 check_insn(ctx
, ISA_MIPS_R1
);
7859 case CP0_REGISTER_00
:
7861 case CP0_REG00__INDEX
:
7862 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Index
));
7863 register_name
= "Index";
7865 case CP0_REG00__MVPCONTROL
:
7866 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7867 gen_helper_mfc0_mvpcontrol(arg
, cpu_env
);
7868 register_name
= "MVPControl";
7870 case CP0_REG00__MVPCONF0
:
7871 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7872 gen_helper_mfc0_mvpconf0(arg
, cpu_env
);
7873 register_name
= "MVPConf0";
7875 case CP0_REG00__MVPCONF1
:
7876 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7877 gen_helper_mfc0_mvpconf1(arg
, cpu_env
);
7878 register_name
= "MVPConf1";
7880 case CP0_REG00__VPCONTROL
:
7882 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPControl
));
7883 register_name
= "VPControl";
7886 goto cp0_unimplemented
;
7889 case CP0_REGISTER_01
:
7891 case CP0_REG01__RANDOM
:
7892 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS_R6
));
7893 gen_helper_mfc0_random(arg
, cpu_env
);
7894 register_name
= "Random";
7896 case CP0_REG01__VPECONTROL
:
7897 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7898 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEControl
));
7899 register_name
= "VPEControl";
7901 case CP0_REG01__VPECONF0
:
7902 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7903 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf0
));
7904 register_name
= "VPEConf0";
7906 case CP0_REG01__VPECONF1
:
7907 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7908 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf1
));
7909 register_name
= "VPEConf1";
7911 case CP0_REG01__YQMASK
:
7912 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7913 tcg_gen_ld_tl(arg
, cpu_env
,
7914 offsetof(CPUMIPSState
, CP0_YQMask
));
7915 register_name
= "YQMask";
7917 case CP0_REG01__VPESCHEDULE
:
7918 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7919 tcg_gen_ld_tl(arg
, cpu_env
,
7920 offsetof(CPUMIPSState
, CP0_VPESchedule
));
7921 register_name
= "VPESchedule";
7923 case CP0_REG01__VPESCHEFBACK
:
7924 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7925 tcg_gen_ld_tl(arg
, cpu_env
,
7926 offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
7927 register_name
= "VPEScheFBack";
7929 case CP0_REG01__VPEOPT
:
7930 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7931 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEOpt
));
7932 register_name
= "VPEOpt";
7935 goto cp0_unimplemented
;
7938 case CP0_REGISTER_02
:
7940 case CP0_REG02__ENTRYLO0
:
7941 tcg_gen_ld_tl(arg
, cpu_env
,
7942 offsetof(CPUMIPSState
, CP0_EntryLo0
));
7943 register_name
= "EntryLo0";
7945 case CP0_REG02__TCSTATUS
:
7946 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7947 gen_helper_mfc0_tcstatus(arg
, cpu_env
);
7948 register_name
= "TCStatus";
7950 case CP0_REG02__TCBIND
:
7951 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7952 gen_helper_mfc0_tcbind(arg
, cpu_env
);
7953 register_name
= "TCBind";
7955 case CP0_REG02__TCRESTART
:
7956 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7957 gen_helper_dmfc0_tcrestart(arg
, cpu_env
);
7958 register_name
= "TCRestart";
7960 case CP0_REG02__TCHALT
:
7961 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7962 gen_helper_dmfc0_tchalt(arg
, cpu_env
);
7963 register_name
= "TCHalt";
7965 case CP0_REG02__TCCONTEXT
:
7966 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7967 gen_helper_dmfc0_tccontext(arg
, cpu_env
);
7968 register_name
= "TCContext";
7970 case CP0_REG02__TCSCHEDULE
:
7971 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7972 gen_helper_dmfc0_tcschedule(arg
, cpu_env
);
7973 register_name
= "TCSchedule";
7975 case CP0_REG02__TCSCHEFBACK
:
7976 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7977 gen_helper_dmfc0_tcschefback(arg
, cpu_env
);
7978 register_name
= "TCScheFBack";
7981 goto cp0_unimplemented
;
7984 case CP0_REGISTER_03
:
7986 case CP0_REG03__ENTRYLO1
:
7987 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryLo1
));
7988 register_name
= "EntryLo1";
7990 case CP0_REG03__GLOBALNUM
:
7992 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_GlobalNumber
));
7993 register_name
= "GlobalNumber";
7996 goto cp0_unimplemented
;
7999 case CP0_REGISTER_04
:
8001 case CP0_REG04__CONTEXT
:
8002 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_Context
));
8003 register_name
= "Context";
8005 case CP0_REG04__CONTEXTCONFIG
:
8007 /* gen_helper_dmfc0_contextconfig(arg); */
8008 register_name
= "ContextConfig";
8009 goto cp0_unimplemented
;
8010 case CP0_REG04__USERLOCAL
:
8011 CP0_CHECK(ctx
->ulri
);
8012 tcg_gen_ld_tl(arg
, cpu_env
,
8013 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
8014 register_name
= "UserLocal";
8016 case CP0_REG04__MMID
:
8018 gen_helper_mtc0_memorymapid(cpu_env
, arg
);
8019 register_name
= "MMID";
8022 goto cp0_unimplemented
;
8025 case CP0_REGISTER_05
:
8027 case CP0_REG05__PAGEMASK
:
8028 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageMask
));
8029 register_name
= "PageMask";
8031 case CP0_REG05__PAGEGRAIN
:
8032 check_insn(ctx
, ISA_MIPS_R2
);
8033 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageGrain
));
8034 register_name
= "PageGrain";
8036 case CP0_REG05__SEGCTL0
:
8038 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_SegCtl0
));
8039 register_name
= "SegCtl0";
8041 case CP0_REG05__SEGCTL1
:
8043 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_SegCtl1
));
8044 register_name
= "SegCtl1";
8046 case CP0_REG05__SEGCTL2
:
8048 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_SegCtl2
));
8049 register_name
= "SegCtl2";
8051 case CP0_REG05__PWBASE
:
8053 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_PWBase
));
8054 register_name
= "PWBase";
8056 case CP0_REG05__PWFIELD
:
8058 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_PWField
));
8059 register_name
= "PWField";
8061 case CP0_REG05__PWSIZE
:
8063 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_PWSize
));
8064 register_name
= "PWSize";
8067 goto cp0_unimplemented
;
8070 case CP0_REGISTER_06
:
8072 case CP0_REG06__WIRED
:
8073 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Wired
));
8074 register_name
= "Wired";
8076 case CP0_REG06__SRSCONF0
:
8077 check_insn(ctx
, ISA_MIPS_R2
);
8078 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf0
));
8079 register_name
= "SRSConf0";
8081 case CP0_REG06__SRSCONF1
:
8082 check_insn(ctx
, ISA_MIPS_R2
);
8083 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf1
));
8084 register_name
= "SRSConf1";
8086 case CP0_REG06__SRSCONF2
:
8087 check_insn(ctx
, ISA_MIPS_R2
);
8088 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf2
));
8089 register_name
= "SRSConf2";
8091 case CP0_REG06__SRSCONF3
:
8092 check_insn(ctx
, ISA_MIPS_R2
);
8093 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf3
));
8094 register_name
= "SRSConf3";
8096 case CP0_REG06__SRSCONF4
:
8097 check_insn(ctx
, ISA_MIPS_R2
);
8098 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf4
));
8099 register_name
= "SRSConf4";
8101 case CP0_REG06__PWCTL
:
8103 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PWCtl
));
8104 register_name
= "PWCtl";
8107 goto cp0_unimplemented
;
8110 case CP0_REGISTER_07
:
8112 case CP0_REG07__HWRENA
:
8113 check_insn(ctx
, ISA_MIPS_R2
);
8114 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_HWREna
));
8115 register_name
= "HWREna";
8118 goto cp0_unimplemented
;
8121 case CP0_REGISTER_08
:
8123 case CP0_REG08__BADVADDR
:
8124 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_BadVAddr
));
8125 register_name
= "BadVAddr";
8127 case CP0_REG08__BADINSTR
:
8129 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstr
));
8130 register_name
= "BadInstr";
8132 case CP0_REG08__BADINSTRP
:
8134 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstrP
));
8135 register_name
= "BadInstrP";
8137 case CP0_REG08__BADINSTRX
:
8139 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstrX
));
8140 tcg_gen_andi_tl(arg
, arg
, ~0xffff);
8141 register_name
= "BadInstrX";
8144 goto cp0_unimplemented
;
8147 case CP0_REGISTER_09
:
8149 case CP0_REG09__COUNT
:
8150 /* Mark as an IO operation because we read the time. */
8151 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
8154 gen_helper_mfc0_count(arg
, cpu_env
);
8156 * Break the TB to be able to take timer interrupts immediately
8157 * after reading count. DISAS_STOP isn't sufficient, we need to
8158 * ensure we break completely out of translated code.
8160 gen_save_pc(ctx
->base
.pc_next
+ 4);
8161 ctx
->base
.is_jmp
= DISAS_EXIT
;
8162 register_name
= "Count";
8164 case CP0_REG09__SAARI
:
8165 CP0_CHECK(ctx
->saar
);
8166 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SAARI
));
8167 register_name
= "SAARI";
8169 case CP0_REG09__SAAR
:
8170 CP0_CHECK(ctx
->saar
);
8171 gen_helper_dmfc0_saar(arg
, cpu_env
);
8172 register_name
= "SAAR";
8175 goto cp0_unimplemented
;
8178 case CP0_REGISTER_10
:
8180 case CP0_REG10__ENTRYHI
:
8181 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryHi
));
8182 register_name
= "EntryHi";
8185 goto cp0_unimplemented
;
8188 case CP0_REGISTER_11
:
8190 case CP0_REG11__COMPARE
:
8191 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Compare
));
8192 register_name
= "Compare";
8194 /* 6,7 are implementation dependent */
8196 goto cp0_unimplemented
;
8199 case CP0_REGISTER_12
:
8201 case CP0_REG12__STATUS
:
8202 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Status
));
8203 register_name
= "Status";
8205 case CP0_REG12__INTCTL
:
8206 check_insn(ctx
, ISA_MIPS_R2
);
8207 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_IntCtl
));
8208 register_name
= "IntCtl";
8210 case CP0_REG12__SRSCTL
:
8211 check_insn(ctx
, ISA_MIPS_R2
);
8212 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
8213 register_name
= "SRSCtl";
8215 case CP0_REG12__SRSMAP
:
8216 check_insn(ctx
, ISA_MIPS_R2
);
8217 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
8218 register_name
= "SRSMap";
8221 goto cp0_unimplemented
;
8224 case CP0_REGISTER_13
:
8226 case CP0_REG13__CAUSE
:
8227 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Cause
));
8228 register_name
= "Cause";
8231 goto cp0_unimplemented
;
8234 case CP0_REGISTER_14
:
8236 case CP0_REG14__EPC
:
8237 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
8238 register_name
= "EPC";
8241 goto cp0_unimplemented
;
8244 case CP0_REGISTER_15
:
8246 case CP0_REG15__PRID
:
8247 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PRid
));
8248 register_name
= "PRid";
8250 case CP0_REG15__EBASE
:
8251 check_insn(ctx
, ISA_MIPS_R2
);
8252 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EBase
));
8253 register_name
= "EBase";
8255 case CP0_REG15__CMGCRBASE
:
8256 check_insn(ctx
, ISA_MIPS_R2
);
8257 CP0_CHECK(ctx
->cmgcr
);
8258 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_CMGCRBase
));
8259 register_name
= "CMGCRBase";
8262 goto cp0_unimplemented
;
8265 case CP0_REGISTER_16
:
8267 case CP0_REG16__CONFIG
:
8268 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config0
));
8269 register_name
= "Config";
8271 case CP0_REG16__CONFIG1
:
8272 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config1
));
8273 register_name
= "Config1";
8275 case CP0_REG16__CONFIG2
:
8276 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config2
));
8277 register_name
= "Config2";
8279 case CP0_REG16__CONFIG3
:
8280 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config3
));
8281 register_name
= "Config3";
8283 case CP0_REG16__CONFIG4
:
8284 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config4
));
8285 register_name
= "Config4";
8287 case CP0_REG16__CONFIG5
:
8288 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config5
));
8289 register_name
= "Config5";
8291 /* 6,7 are implementation dependent */
8292 case CP0_REG16__CONFIG6
:
8293 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config6
));
8294 register_name
= "Config6";
8296 case CP0_REG16__CONFIG7
:
8297 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config7
));
8298 register_name
= "Config7";
8301 goto cp0_unimplemented
;
8304 case CP0_REGISTER_17
:
8306 case CP0_REG17__LLADDR
:
8307 gen_helper_dmfc0_lladdr(arg
, cpu_env
);
8308 register_name
= "LLAddr";
8310 case CP0_REG17__MAAR
:
8311 CP0_CHECK(ctx
->mrp
);
8312 gen_helper_dmfc0_maar(arg
, cpu_env
);
8313 register_name
= "MAAR";
8315 case CP0_REG17__MAARI
:
8316 CP0_CHECK(ctx
->mrp
);
8317 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_MAARI
));
8318 register_name
= "MAARI";
8321 goto cp0_unimplemented
;
8324 case CP0_REGISTER_18
:
8326 case CP0_REG18__WATCHLO0
:
8327 case CP0_REG18__WATCHLO1
:
8328 case CP0_REG18__WATCHLO2
:
8329 case CP0_REG18__WATCHLO3
:
8330 case CP0_REG18__WATCHLO4
:
8331 case CP0_REG18__WATCHLO5
:
8332 case CP0_REG18__WATCHLO6
:
8333 case CP0_REG18__WATCHLO7
:
8334 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
8335 gen_helper_1e0i(dmfc0_watchlo
, arg
, sel
);
8336 register_name
= "WatchLo";
8339 goto cp0_unimplemented
;
8342 case CP0_REGISTER_19
:
8344 case CP0_REG19__WATCHHI0
:
8345 case CP0_REG19__WATCHHI1
:
8346 case CP0_REG19__WATCHHI2
:
8347 case CP0_REG19__WATCHHI3
:
8348 case CP0_REG19__WATCHHI4
:
8349 case CP0_REG19__WATCHHI5
:
8350 case CP0_REG19__WATCHHI6
:
8351 case CP0_REG19__WATCHHI7
:
8352 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
8353 gen_helper_1e0i(dmfc0_watchhi
, arg
, sel
);
8354 register_name
= "WatchHi";
8357 goto cp0_unimplemented
;
8360 case CP0_REGISTER_20
:
8362 case CP0_REG20__XCONTEXT
:
8363 check_insn(ctx
, ISA_MIPS3
);
8364 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_XContext
));
8365 register_name
= "XContext";
8368 goto cp0_unimplemented
;
8371 case CP0_REGISTER_21
:
8372 /* Officially reserved, but sel 0 is used for R1x000 framemask */
8373 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS_R6
));
8376 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Framemask
));
8377 register_name
= "Framemask";
8380 goto cp0_unimplemented
;
8383 case CP0_REGISTER_22
:
8384 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
8385 register_name
= "'Diagnostic"; /* implementation dependent */
8387 case CP0_REGISTER_23
:
8389 case CP0_REG23__DEBUG
:
8390 gen_helper_mfc0_debug(arg
, cpu_env
); /* EJTAG support */
8391 register_name
= "Debug";
8393 case CP0_REG23__TRACECONTROL
:
8394 /* PDtrace support */
8395 /* gen_helper_dmfc0_tracecontrol(arg, cpu_env); */
8396 register_name
= "TraceControl";
8397 goto cp0_unimplemented
;
8398 case CP0_REG23__TRACECONTROL2
:
8399 /* PDtrace support */
8400 /* gen_helper_dmfc0_tracecontrol2(arg, cpu_env); */
8401 register_name
= "TraceControl2";
8402 goto cp0_unimplemented
;
8403 case CP0_REG23__USERTRACEDATA1
:
8404 /* PDtrace support */
8405 /* gen_helper_dmfc0_usertracedata1(arg, cpu_env);*/
8406 register_name
= "UserTraceData1";
8407 goto cp0_unimplemented
;
8408 case CP0_REG23__TRACEIBPC
:
8409 /* PDtrace support */
8410 /* gen_helper_dmfc0_traceibpc(arg, cpu_env); */
8411 register_name
= "TraceIBPC";
8412 goto cp0_unimplemented
;
8413 case CP0_REG23__TRACEDBPC
:
8414 /* PDtrace support */
8415 /* gen_helper_dmfc0_tracedbpc(arg, cpu_env); */
8416 register_name
= "TraceDBPC";
8417 goto cp0_unimplemented
;
8419 goto cp0_unimplemented
;
8422 case CP0_REGISTER_24
:
8424 case CP0_REG24__DEPC
:
8426 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
8427 register_name
= "DEPC";
8430 goto cp0_unimplemented
;
8433 case CP0_REGISTER_25
:
8435 case CP0_REG25__PERFCTL0
:
8436 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Performance0
));
8437 register_name
= "Performance0";
8439 case CP0_REG25__PERFCNT0
:
8440 /* gen_helper_dmfc0_performance1(arg); */
8441 register_name
= "Performance1";
8442 goto cp0_unimplemented
;
8443 case CP0_REG25__PERFCTL1
:
8444 /* gen_helper_dmfc0_performance2(arg); */
8445 register_name
= "Performance2";
8446 goto cp0_unimplemented
;
8447 case CP0_REG25__PERFCNT1
:
8448 /* gen_helper_dmfc0_performance3(arg); */
8449 register_name
= "Performance3";
8450 goto cp0_unimplemented
;
8451 case CP0_REG25__PERFCTL2
:
8452 /* gen_helper_dmfc0_performance4(arg); */
8453 register_name
= "Performance4";
8454 goto cp0_unimplemented
;
8455 case CP0_REG25__PERFCNT2
:
8456 /* gen_helper_dmfc0_performance5(arg); */
8457 register_name
= "Performance5";
8458 goto cp0_unimplemented
;
8459 case CP0_REG25__PERFCTL3
:
8460 /* gen_helper_dmfc0_performance6(arg); */
8461 register_name
= "Performance6";
8462 goto cp0_unimplemented
;
8463 case CP0_REG25__PERFCNT3
:
8464 /* gen_helper_dmfc0_performance7(arg); */
8465 register_name
= "Performance7";
8466 goto cp0_unimplemented
;
8468 goto cp0_unimplemented
;
8471 case CP0_REGISTER_26
:
8473 case CP0_REG26__ERRCTL
:
8474 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_ErrCtl
));
8475 register_name
= "ErrCtl";
8478 goto cp0_unimplemented
;
8481 case CP0_REGISTER_27
:
8484 case CP0_REG27__CACHERR
:
8485 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
8486 register_name
= "CacheErr";
8489 goto cp0_unimplemented
;
8492 case CP0_REGISTER_28
:
8494 case CP0_REG28__TAGLO
:
8495 case CP0_REG28__TAGLO1
:
8496 case CP0_REG28__TAGLO2
:
8497 case CP0_REG28__TAGLO3
:
8498 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagLo
));
8499 register_name
= "TagLo";
8501 case CP0_REG28__DATALO
:
8502 case CP0_REG28__DATALO1
:
8503 case CP0_REG28__DATALO2
:
8504 case CP0_REG28__DATALO3
:
8505 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataLo
));
8506 register_name
= "DataLo";
8509 goto cp0_unimplemented
;
8512 case CP0_REGISTER_29
:
8514 case CP0_REG29__TAGHI
:
8515 case CP0_REG29__TAGHI1
:
8516 case CP0_REG29__TAGHI2
:
8517 case CP0_REG29__TAGHI3
:
8518 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagHi
));
8519 register_name
= "TagHi";
8521 case CP0_REG29__DATAHI
:
8522 case CP0_REG29__DATAHI1
:
8523 case CP0_REG29__DATAHI2
:
8524 case CP0_REG29__DATAHI3
:
8525 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataHi
));
8526 register_name
= "DataHi";
8529 goto cp0_unimplemented
;
8532 case CP0_REGISTER_30
:
8534 case CP0_REG30__ERROREPC
:
8535 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
8536 register_name
= "ErrorEPC";
8539 goto cp0_unimplemented
;
8542 case CP0_REGISTER_31
:
8544 case CP0_REG31__DESAVE
:
8546 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
8547 register_name
= "DESAVE";
8549 case CP0_REG31__KSCRATCH1
:
8550 case CP0_REG31__KSCRATCH2
:
8551 case CP0_REG31__KSCRATCH3
:
8552 case CP0_REG31__KSCRATCH4
:
8553 case CP0_REG31__KSCRATCH5
:
8554 case CP0_REG31__KSCRATCH6
:
8555 CP0_CHECK(ctx
->kscrexist
& (1 << sel
));
8556 tcg_gen_ld_tl(arg
, cpu_env
,
8557 offsetof(CPUMIPSState
, CP0_KScratch
[sel
- 2]));
8558 register_name
= "KScratch";
8561 goto cp0_unimplemented
;
8565 goto cp0_unimplemented
;
8567 trace_mips_translate_c0("dmfc0", register_name
, reg
, sel
);
8571 qemu_log_mask(LOG_UNIMP
, "dmfc0 %s (reg %d sel %d)\n",
8572 register_name
, reg
, sel
);
8573 gen_mfc0_unimplemented(ctx
, arg
);
8576 static void gen_dmtc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
8578 const char *register_name
= "invalid";
8581 check_insn(ctx
, ISA_MIPS_R1
);
8584 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
8589 case CP0_REGISTER_00
:
8591 case CP0_REG00__INDEX
:
8592 gen_helper_mtc0_index(cpu_env
, arg
);
8593 register_name
= "Index";
8595 case CP0_REG00__MVPCONTROL
:
8596 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8597 gen_helper_mtc0_mvpcontrol(cpu_env
, arg
);
8598 register_name
= "MVPControl";
8600 case CP0_REG00__MVPCONF0
:
8601 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8603 register_name
= "MVPConf0";
8605 case CP0_REG00__MVPCONF1
:
8606 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8608 register_name
= "MVPConf1";
8610 case CP0_REG00__VPCONTROL
:
8613 register_name
= "VPControl";
8616 goto cp0_unimplemented
;
8619 case CP0_REGISTER_01
:
8621 case CP0_REG01__RANDOM
:
8623 register_name
= "Random";
8625 case CP0_REG01__VPECONTROL
:
8626 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8627 gen_helper_mtc0_vpecontrol(cpu_env
, arg
);
8628 register_name
= "VPEControl";
8630 case CP0_REG01__VPECONF0
:
8631 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8632 gen_helper_mtc0_vpeconf0(cpu_env
, arg
);
8633 register_name
= "VPEConf0";
8635 case CP0_REG01__VPECONF1
:
8636 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8637 gen_helper_mtc0_vpeconf1(cpu_env
, arg
);
8638 register_name
= "VPEConf1";
8640 case CP0_REG01__YQMASK
:
8641 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8642 gen_helper_mtc0_yqmask(cpu_env
, arg
);
8643 register_name
= "YQMask";
8645 case CP0_REG01__VPESCHEDULE
:
8646 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8647 tcg_gen_st_tl(arg
, cpu_env
,
8648 offsetof(CPUMIPSState
, CP0_VPESchedule
));
8649 register_name
= "VPESchedule";
8651 case CP0_REG01__VPESCHEFBACK
:
8652 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8653 tcg_gen_st_tl(arg
, cpu_env
,
8654 offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
8655 register_name
= "VPEScheFBack";
8657 case CP0_REG01__VPEOPT
:
8658 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8659 gen_helper_mtc0_vpeopt(cpu_env
, arg
);
8660 register_name
= "VPEOpt";
8663 goto cp0_unimplemented
;
8666 case CP0_REGISTER_02
:
8668 case CP0_REG02__ENTRYLO0
:
8669 gen_helper_dmtc0_entrylo0(cpu_env
, arg
);
8670 register_name
= "EntryLo0";
8672 case CP0_REG02__TCSTATUS
:
8673 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8674 gen_helper_mtc0_tcstatus(cpu_env
, arg
);
8675 register_name
= "TCStatus";
8677 case CP0_REG02__TCBIND
:
8678 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8679 gen_helper_mtc0_tcbind(cpu_env
, arg
);
8680 register_name
= "TCBind";
8682 case CP0_REG02__TCRESTART
:
8683 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8684 gen_helper_mtc0_tcrestart(cpu_env
, arg
);
8685 register_name
= "TCRestart";
8687 case CP0_REG02__TCHALT
:
8688 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8689 gen_helper_mtc0_tchalt(cpu_env
, arg
);
8690 register_name
= "TCHalt";
8692 case CP0_REG02__TCCONTEXT
:
8693 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8694 gen_helper_mtc0_tccontext(cpu_env
, arg
);
8695 register_name
= "TCContext";
8697 case CP0_REG02__TCSCHEDULE
:
8698 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8699 gen_helper_mtc0_tcschedule(cpu_env
, arg
);
8700 register_name
= "TCSchedule";
8702 case CP0_REG02__TCSCHEFBACK
:
8703 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8704 gen_helper_mtc0_tcschefback(cpu_env
, arg
);
8705 register_name
= "TCScheFBack";
8708 goto cp0_unimplemented
;
8711 case CP0_REGISTER_03
:
8713 case CP0_REG03__ENTRYLO1
:
8714 gen_helper_dmtc0_entrylo1(cpu_env
, arg
);
8715 register_name
= "EntryLo1";
8717 case CP0_REG03__GLOBALNUM
:
8720 register_name
= "GlobalNumber";
8723 goto cp0_unimplemented
;
8726 case CP0_REGISTER_04
:
8728 case CP0_REG04__CONTEXT
:
8729 gen_helper_mtc0_context(cpu_env
, arg
);
8730 register_name
= "Context";
8732 case CP0_REG04__CONTEXTCONFIG
:
8734 /* gen_helper_dmtc0_contextconfig(arg); */
8735 register_name
= "ContextConfig";
8736 goto cp0_unimplemented
;
8737 case CP0_REG04__USERLOCAL
:
8738 CP0_CHECK(ctx
->ulri
);
8739 tcg_gen_st_tl(arg
, cpu_env
,
8740 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
8741 register_name
= "UserLocal";
8743 case CP0_REG04__MMID
:
8745 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_MemoryMapID
));
8746 register_name
= "MMID";
8749 goto cp0_unimplemented
;
8752 case CP0_REGISTER_05
:
8754 case CP0_REG05__PAGEMASK
:
8755 gen_helper_mtc0_pagemask(cpu_env
, arg
);
8756 register_name
= "PageMask";
8758 case CP0_REG05__PAGEGRAIN
:
8759 check_insn(ctx
, ISA_MIPS_R2
);
8760 gen_helper_mtc0_pagegrain(cpu_env
, arg
);
8761 register_name
= "PageGrain";
8763 case CP0_REG05__SEGCTL0
:
8765 gen_helper_mtc0_segctl0(cpu_env
, arg
);
8766 register_name
= "SegCtl0";
8768 case CP0_REG05__SEGCTL1
:
8770 gen_helper_mtc0_segctl1(cpu_env
, arg
);
8771 register_name
= "SegCtl1";
8773 case CP0_REG05__SEGCTL2
:
8775 gen_helper_mtc0_segctl2(cpu_env
, arg
);
8776 register_name
= "SegCtl2";
8778 case CP0_REG05__PWBASE
:
8780 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_PWBase
));
8781 register_name
= "PWBase";
8783 case CP0_REG05__PWFIELD
:
8785 gen_helper_mtc0_pwfield(cpu_env
, arg
);
8786 register_name
= "PWField";
8788 case CP0_REG05__PWSIZE
:
8790 gen_helper_mtc0_pwsize(cpu_env
, arg
);
8791 register_name
= "PWSize";
8794 goto cp0_unimplemented
;
8797 case CP0_REGISTER_06
:
8799 case CP0_REG06__WIRED
:
8800 gen_helper_mtc0_wired(cpu_env
, arg
);
8801 register_name
= "Wired";
8803 case CP0_REG06__SRSCONF0
:
8804 check_insn(ctx
, ISA_MIPS_R2
);
8805 gen_helper_mtc0_srsconf0(cpu_env
, arg
);
8806 register_name
= "SRSConf0";
8808 case CP0_REG06__SRSCONF1
:
8809 check_insn(ctx
, ISA_MIPS_R2
);
8810 gen_helper_mtc0_srsconf1(cpu_env
, arg
);
8811 register_name
= "SRSConf1";
8813 case CP0_REG06__SRSCONF2
:
8814 check_insn(ctx
, ISA_MIPS_R2
);
8815 gen_helper_mtc0_srsconf2(cpu_env
, arg
);
8816 register_name
= "SRSConf2";
8818 case CP0_REG06__SRSCONF3
:
8819 check_insn(ctx
, ISA_MIPS_R2
);
8820 gen_helper_mtc0_srsconf3(cpu_env
, arg
);
8821 register_name
= "SRSConf3";
8823 case CP0_REG06__SRSCONF4
:
8824 check_insn(ctx
, ISA_MIPS_R2
);
8825 gen_helper_mtc0_srsconf4(cpu_env
, arg
);
8826 register_name
= "SRSConf4";
8828 case CP0_REG06__PWCTL
:
8830 gen_helper_mtc0_pwctl(cpu_env
, arg
);
8831 register_name
= "PWCtl";
8834 goto cp0_unimplemented
;
8837 case CP0_REGISTER_07
:
8839 case CP0_REG07__HWRENA
:
8840 check_insn(ctx
, ISA_MIPS_R2
);
8841 gen_helper_mtc0_hwrena(cpu_env
, arg
);
8842 ctx
->base
.is_jmp
= DISAS_STOP
;
8843 register_name
= "HWREna";
8846 goto cp0_unimplemented
;
8849 case CP0_REGISTER_08
:
8851 case CP0_REG08__BADVADDR
:
8853 register_name
= "BadVAddr";
8855 case CP0_REG08__BADINSTR
:
8857 register_name
= "BadInstr";
8859 case CP0_REG08__BADINSTRP
:
8861 register_name
= "BadInstrP";
8863 case CP0_REG08__BADINSTRX
:
8865 register_name
= "BadInstrX";
8868 goto cp0_unimplemented
;
8871 case CP0_REGISTER_09
:
8873 case CP0_REG09__COUNT
:
8874 gen_helper_mtc0_count(cpu_env
, arg
);
8875 register_name
= "Count";
8877 case CP0_REG09__SAARI
:
8878 CP0_CHECK(ctx
->saar
);
8879 gen_helper_mtc0_saari(cpu_env
, arg
);
8880 register_name
= "SAARI";
8882 case CP0_REG09__SAAR
:
8883 CP0_CHECK(ctx
->saar
);
8884 gen_helper_mtc0_saar(cpu_env
, arg
);
8885 register_name
= "SAAR";
8888 goto cp0_unimplemented
;
8890 /* Stop translation as we may have switched the execution mode */
8891 ctx
->base
.is_jmp
= DISAS_STOP
;
8893 case CP0_REGISTER_10
:
8895 case CP0_REG10__ENTRYHI
:
8896 gen_helper_mtc0_entryhi(cpu_env
, arg
);
8897 register_name
= "EntryHi";
8900 goto cp0_unimplemented
;
8903 case CP0_REGISTER_11
:
8905 case CP0_REG11__COMPARE
:
8906 gen_helper_mtc0_compare(cpu_env
, arg
);
8907 register_name
= "Compare";
8909 /* 6,7 are implementation dependent */
8911 goto cp0_unimplemented
;
8913 /* Stop translation as we may have switched the execution mode */
8914 ctx
->base
.is_jmp
= DISAS_STOP
;
8916 case CP0_REGISTER_12
:
8918 case CP0_REG12__STATUS
:
8919 save_cpu_state(ctx
, 1);
8920 gen_helper_mtc0_status(cpu_env
, arg
);
8921 /* DISAS_STOP isn't good enough here, hflags may have changed. */
8922 gen_save_pc(ctx
->base
.pc_next
+ 4);
8923 ctx
->base
.is_jmp
= DISAS_EXIT
;
8924 register_name
= "Status";
8926 case CP0_REG12__INTCTL
:
8927 check_insn(ctx
, ISA_MIPS_R2
);
8928 gen_helper_mtc0_intctl(cpu_env
, arg
);
8929 /* Stop translation as we may have switched the execution mode */
8930 ctx
->base
.is_jmp
= DISAS_STOP
;
8931 register_name
= "IntCtl";
8933 case CP0_REG12__SRSCTL
:
8934 check_insn(ctx
, ISA_MIPS_R2
);
8935 gen_helper_mtc0_srsctl(cpu_env
, arg
);
8936 /* Stop translation as we may have switched the execution mode */
8937 ctx
->base
.is_jmp
= DISAS_STOP
;
8938 register_name
= "SRSCtl";
8940 case CP0_REG12__SRSMAP
:
8941 check_insn(ctx
, ISA_MIPS_R2
);
8942 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
8943 /* Stop translation as we may have switched the execution mode */
8944 ctx
->base
.is_jmp
= DISAS_STOP
;
8945 register_name
= "SRSMap";
8948 goto cp0_unimplemented
;
8951 case CP0_REGISTER_13
:
8953 case CP0_REG13__CAUSE
:
8954 save_cpu_state(ctx
, 1);
8955 gen_helper_mtc0_cause(cpu_env
, arg
);
8957 * Stop translation as we may have triggered an interrupt.
8958 * DISAS_STOP isn't sufficient, we need to ensure we break out of
8959 * translated code to check for pending interrupts.
8961 gen_save_pc(ctx
->base
.pc_next
+ 4);
8962 ctx
->base
.is_jmp
= DISAS_EXIT
;
8963 register_name
= "Cause";
8966 goto cp0_unimplemented
;
8969 case CP0_REGISTER_14
:
8971 case CP0_REG14__EPC
:
8972 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
8973 register_name
= "EPC";
8976 goto cp0_unimplemented
;
8979 case CP0_REGISTER_15
:
8981 case CP0_REG15__PRID
:
8983 register_name
= "PRid";
8985 case CP0_REG15__EBASE
:
8986 check_insn(ctx
, ISA_MIPS_R2
);
8987 gen_helper_mtc0_ebase(cpu_env
, arg
);
8988 register_name
= "EBase";
8991 goto cp0_unimplemented
;
8994 case CP0_REGISTER_16
:
8996 case CP0_REG16__CONFIG
:
8997 gen_helper_mtc0_config0(cpu_env
, arg
);
8998 register_name
= "Config";
8999 /* Stop translation as we may have switched the execution mode */
9000 ctx
->base
.is_jmp
= DISAS_STOP
;
9002 case CP0_REG16__CONFIG1
:
9003 /* ignored, read only */
9004 register_name
= "Config1";
9006 case CP0_REG16__CONFIG2
:
9007 gen_helper_mtc0_config2(cpu_env
, arg
);
9008 register_name
= "Config2";
9009 /* Stop translation as we may have switched the execution mode */
9010 ctx
->base
.is_jmp
= DISAS_STOP
;
9012 case CP0_REG16__CONFIG3
:
9013 gen_helper_mtc0_config3(cpu_env
, arg
);
9014 register_name
= "Config3";
9015 /* Stop translation as we may have switched the execution mode */
9016 ctx
->base
.is_jmp
= DISAS_STOP
;
9018 case CP0_REG16__CONFIG4
:
9019 /* currently ignored */
9020 register_name
= "Config4";
9022 case CP0_REG16__CONFIG5
:
9023 gen_helper_mtc0_config5(cpu_env
, arg
);
9024 register_name
= "Config5";
9025 /* Stop translation as we may have switched the execution mode */
9026 ctx
->base
.is_jmp
= DISAS_STOP
;
9028 /* 6,7 are implementation dependent */
9030 register_name
= "Invalid config selector";
9031 goto cp0_unimplemented
;
9034 case CP0_REGISTER_17
:
9036 case CP0_REG17__LLADDR
:
9037 gen_helper_mtc0_lladdr(cpu_env
, arg
);
9038 register_name
= "LLAddr";
9040 case CP0_REG17__MAAR
:
9041 CP0_CHECK(ctx
->mrp
);
9042 gen_helper_mtc0_maar(cpu_env
, arg
);
9043 register_name
= "MAAR";
9045 case CP0_REG17__MAARI
:
9046 CP0_CHECK(ctx
->mrp
);
9047 gen_helper_mtc0_maari(cpu_env
, arg
);
9048 register_name
= "MAARI";
9051 goto cp0_unimplemented
;
9054 case CP0_REGISTER_18
:
9056 case CP0_REG18__WATCHLO0
:
9057 case CP0_REG18__WATCHLO1
:
9058 case CP0_REG18__WATCHLO2
:
9059 case CP0_REG18__WATCHLO3
:
9060 case CP0_REG18__WATCHLO4
:
9061 case CP0_REG18__WATCHLO5
:
9062 case CP0_REG18__WATCHLO6
:
9063 case CP0_REG18__WATCHLO7
:
9064 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
9065 gen_helper_0e1i(mtc0_watchlo
, arg
, sel
);
9066 register_name
= "WatchLo";
9069 goto cp0_unimplemented
;
9072 case CP0_REGISTER_19
:
9074 case CP0_REG19__WATCHHI0
:
9075 case CP0_REG19__WATCHHI1
:
9076 case CP0_REG19__WATCHHI2
:
9077 case CP0_REG19__WATCHHI3
:
9078 case CP0_REG19__WATCHHI4
:
9079 case CP0_REG19__WATCHHI5
:
9080 case CP0_REG19__WATCHHI6
:
9081 case CP0_REG19__WATCHHI7
:
9082 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
9083 gen_helper_0e1i(mtc0_watchhi
, arg
, sel
);
9084 register_name
= "WatchHi";
9087 goto cp0_unimplemented
;
9090 case CP0_REGISTER_20
:
9092 case CP0_REG20__XCONTEXT
:
9093 check_insn(ctx
, ISA_MIPS3
);
9094 gen_helper_mtc0_xcontext(cpu_env
, arg
);
9095 register_name
= "XContext";
9098 goto cp0_unimplemented
;
9101 case CP0_REGISTER_21
:
9102 /* Officially reserved, but sel 0 is used for R1x000 framemask */
9103 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS_R6
));
9106 gen_helper_mtc0_framemask(cpu_env
, arg
);
9107 register_name
= "Framemask";
9110 goto cp0_unimplemented
;
9113 case CP0_REGISTER_22
:
9115 register_name
= "Diagnostic"; /* implementation dependent */
9117 case CP0_REGISTER_23
:
9119 case CP0_REG23__DEBUG
:
9120 gen_helper_mtc0_debug(cpu_env
, arg
); /* EJTAG support */
9121 /* DISAS_STOP isn't good enough here, hflags may have changed. */
9122 gen_save_pc(ctx
->base
.pc_next
+ 4);
9123 ctx
->base
.is_jmp
= DISAS_EXIT
;
9124 register_name
= "Debug";
9126 case CP0_REG23__TRACECONTROL
:
9127 /* PDtrace support */
9128 /* gen_helper_mtc0_tracecontrol(cpu_env, arg); */
9129 /* Stop translation as we may have switched the execution mode */
9130 ctx
->base
.is_jmp
= DISAS_STOP
;
9131 register_name
= "TraceControl";
9132 goto cp0_unimplemented
;
9133 case CP0_REG23__TRACECONTROL2
:
9134 /* PDtrace support */
9135 /* gen_helper_mtc0_tracecontrol2(cpu_env, arg); */
9136 /* Stop translation as we may have switched the execution mode */
9137 ctx
->base
.is_jmp
= DISAS_STOP
;
9138 register_name
= "TraceControl2";
9139 goto cp0_unimplemented
;
9140 case CP0_REG23__USERTRACEDATA1
:
9141 /* PDtrace support */
9142 /* gen_helper_mtc0_usertracedata1(cpu_env, arg);*/
9143 /* Stop translation as we may have switched the execution mode */
9144 ctx
->base
.is_jmp
= DISAS_STOP
;
9145 register_name
= "UserTraceData1";
9146 goto cp0_unimplemented
;
9147 case CP0_REG23__TRACEIBPC
:
9148 /* PDtrace support */
9149 /* gen_helper_mtc0_traceibpc(cpu_env, arg); */
9150 /* Stop translation as we may have switched the execution mode */
9151 ctx
->base
.is_jmp
= DISAS_STOP
;
9152 register_name
= "TraceIBPC";
9153 goto cp0_unimplemented
;
9154 case CP0_REG23__TRACEDBPC
:
9155 /* PDtrace support */
9156 /* gen_helper_mtc0_tracedbpc(cpu_env, arg); */
9157 /* Stop translation as we may have switched the execution mode */
9158 ctx
->base
.is_jmp
= DISAS_STOP
;
9159 register_name
= "TraceDBPC";
9160 goto cp0_unimplemented
;
9162 goto cp0_unimplemented
;
9165 case CP0_REGISTER_24
:
9167 case CP0_REG24__DEPC
:
9169 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
9170 register_name
= "DEPC";
9173 goto cp0_unimplemented
;
9176 case CP0_REGISTER_25
:
9178 case CP0_REG25__PERFCTL0
:
9179 gen_helper_mtc0_performance0(cpu_env
, arg
);
9180 register_name
= "Performance0";
9182 case CP0_REG25__PERFCNT0
:
9183 /* gen_helper_mtc0_performance1(cpu_env, arg); */
9184 register_name
= "Performance1";
9185 goto cp0_unimplemented
;
9186 case CP0_REG25__PERFCTL1
:
9187 /* gen_helper_mtc0_performance2(cpu_env, arg); */
9188 register_name
= "Performance2";
9189 goto cp0_unimplemented
;
9190 case CP0_REG25__PERFCNT1
:
9191 /* gen_helper_mtc0_performance3(cpu_env, arg); */
9192 register_name
= "Performance3";
9193 goto cp0_unimplemented
;
9194 case CP0_REG25__PERFCTL2
:
9195 /* gen_helper_mtc0_performance4(cpu_env, arg); */
9196 register_name
= "Performance4";
9197 goto cp0_unimplemented
;
9198 case CP0_REG25__PERFCNT2
:
9199 /* gen_helper_mtc0_performance5(cpu_env, arg); */
9200 register_name
= "Performance5";
9201 goto cp0_unimplemented
;
9202 case CP0_REG25__PERFCTL3
:
9203 /* gen_helper_mtc0_performance6(cpu_env, arg); */
9204 register_name
= "Performance6";
9205 goto cp0_unimplemented
;
9206 case CP0_REG25__PERFCNT3
:
9207 /* gen_helper_mtc0_performance7(cpu_env, arg); */
9208 register_name
= "Performance7";
9209 goto cp0_unimplemented
;
9211 goto cp0_unimplemented
;
9214 case CP0_REGISTER_26
:
9216 case CP0_REG26__ERRCTL
:
9217 gen_helper_mtc0_errctl(cpu_env
, arg
);
9218 ctx
->base
.is_jmp
= DISAS_STOP
;
9219 register_name
= "ErrCtl";
9222 goto cp0_unimplemented
;
9225 case CP0_REGISTER_27
:
9227 case CP0_REG27__CACHERR
:
9229 register_name
= "CacheErr";
9232 goto cp0_unimplemented
;
9235 case CP0_REGISTER_28
:
9237 case CP0_REG28__TAGLO
:
9238 case CP0_REG28__TAGLO1
:
9239 case CP0_REG28__TAGLO2
:
9240 case CP0_REG28__TAGLO3
:
9241 gen_helper_mtc0_taglo(cpu_env
, arg
);
9242 register_name
= "TagLo";
9244 case CP0_REG28__DATALO
:
9245 case CP0_REG28__DATALO1
:
9246 case CP0_REG28__DATALO2
:
9247 case CP0_REG28__DATALO3
:
9248 gen_helper_mtc0_datalo(cpu_env
, arg
);
9249 register_name
= "DataLo";
9252 goto cp0_unimplemented
;
9255 case CP0_REGISTER_29
:
9257 case CP0_REG29__TAGHI
:
9258 case CP0_REG29__TAGHI1
:
9259 case CP0_REG29__TAGHI2
:
9260 case CP0_REG29__TAGHI3
:
9261 gen_helper_mtc0_taghi(cpu_env
, arg
);
9262 register_name
= "TagHi";
9264 case CP0_REG29__DATAHI
:
9265 case CP0_REG29__DATAHI1
:
9266 case CP0_REG29__DATAHI2
:
9267 case CP0_REG29__DATAHI3
:
9268 gen_helper_mtc0_datahi(cpu_env
, arg
);
9269 register_name
= "DataHi";
9272 register_name
= "invalid sel";
9273 goto cp0_unimplemented
;
9276 case CP0_REGISTER_30
:
9278 case CP0_REG30__ERROREPC
:
9279 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
9280 register_name
= "ErrorEPC";
9283 goto cp0_unimplemented
;
9286 case CP0_REGISTER_31
:
9288 case CP0_REG31__DESAVE
:
9290 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
9291 register_name
= "DESAVE";
9293 case CP0_REG31__KSCRATCH1
:
9294 case CP0_REG31__KSCRATCH2
:
9295 case CP0_REG31__KSCRATCH3
:
9296 case CP0_REG31__KSCRATCH4
:
9297 case CP0_REG31__KSCRATCH5
:
9298 case CP0_REG31__KSCRATCH6
:
9299 CP0_CHECK(ctx
->kscrexist
& (1 << sel
));
9300 tcg_gen_st_tl(arg
, cpu_env
,
9301 offsetof(CPUMIPSState
, CP0_KScratch
[sel
- 2]));
9302 register_name
= "KScratch";
9305 goto cp0_unimplemented
;
9309 goto cp0_unimplemented
;
9311 trace_mips_translate_c0("dmtc0", register_name
, reg
, sel
);
9313 /* For simplicity assume that all writes can cause interrupts. */
9314 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
9316 * DISAS_STOP isn't sufficient, we need to ensure we break out of
9317 * translated code to check for pending interrupts.
9319 gen_save_pc(ctx
->base
.pc_next
+ 4);
9320 ctx
->base
.is_jmp
= DISAS_EXIT
;
9325 qemu_log_mask(LOG_UNIMP
, "dmtc0 %s (reg %d sel %d)\n",
9326 register_name
, reg
, sel
);
9328 #endif /* TARGET_MIPS64 */
9330 static void gen_mftr(CPUMIPSState
*env
, DisasContext
*ctx
, int rt
, int rd
,
9331 int u
, int sel
, int h
)
9333 int other_tc
= env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
);
9334 TCGv t0
= tcg_temp_local_new();
9336 if ((env
->CP0_VPEConf0
& (1 << CP0VPEC0_MVP
)) == 0 &&
9337 ((env
->tcs
[other_tc
].CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)) !=
9338 (env
->active_tc
.CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)))) {
9339 tcg_gen_movi_tl(t0
, -1);
9340 } else if ((env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
)) >
9341 (env
->mvp
->CP0_MVPConf0
& (0xff << CP0MVPC0_PTC
))) {
9342 tcg_gen_movi_tl(t0
, -1);
9343 } else if (u
== 0) {
9348 gen_helper_mftc0_vpecontrol(t0
, cpu_env
);
9351 gen_helper_mftc0_vpeconf0(t0
, cpu_env
);
9361 gen_helper_mftc0_tcstatus(t0
, cpu_env
);
9364 gen_helper_mftc0_tcbind(t0
, cpu_env
);
9367 gen_helper_mftc0_tcrestart(t0
, cpu_env
);
9370 gen_helper_mftc0_tchalt(t0
, cpu_env
);
9373 gen_helper_mftc0_tccontext(t0
, cpu_env
);
9376 gen_helper_mftc0_tcschedule(t0
, cpu_env
);
9379 gen_helper_mftc0_tcschefback(t0
, cpu_env
);
9382 gen_mfc0(ctx
, t0
, rt
, sel
);
9389 gen_helper_mftc0_entryhi(t0
, cpu_env
);
9392 gen_mfc0(ctx
, t0
, rt
, sel
);
9399 gen_helper_mftc0_status(t0
, cpu_env
);
9402 gen_mfc0(ctx
, t0
, rt
, sel
);
9409 gen_helper_mftc0_cause(t0
, cpu_env
);
9419 gen_helper_mftc0_epc(t0
, cpu_env
);
9429 gen_helper_mftc0_ebase(t0
, cpu_env
);
9446 gen_helper_mftc0_configx(t0
, cpu_env
, tcg_const_tl(sel
));
9456 gen_helper_mftc0_debug(t0
, cpu_env
);
9459 gen_mfc0(ctx
, t0
, rt
, sel
);
9464 gen_mfc0(ctx
, t0
, rt
, sel
);
9468 /* GPR registers. */
9470 gen_helper_1e0i(mftgpr
, t0
, rt
);
9472 /* Auxiliary CPU registers */
9476 gen_helper_1e0i(mftlo
, t0
, 0);
9479 gen_helper_1e0i(mfthi
, t0
, 0);
9482 gen_helper_1e0i(mftacx
, t0
, 0);
9485 gen_helper_1e0i(mftlo
, t0
, 1);
9488 gen_helper_1e0i(mfthi
, t0
, 1);
9491 gen_helper_1e0i(mftacx
, t0
, 1);
9494 gen_helper_1e0i(mftlo
, t0
, 2);
9497 gen_helper_1e0i(mfthi
, t0
, 2);
9500 gen_helper_1e0i(mftacx
, t0
, 2);
9503 gen_helper_1e0i(mftlo
, t0
, 3);
9506 gen_helper_1e0i(mfthi
, t0
, 3);
9509 gen_helper_1e0i(mftacx
, t0
, 3);
9512 gen_helper_mftdsp(t0
, cpu_env
);
9518 /* Floating point (COP1). */
9520 /* XXX: For now we support only a single FPU context. */
9522 TCGv_i32 fp0
= tcg_temp_new_i32();
9524 gen_load_fpr32(ctx
, fp0
, rt
);
9525 tcg_gen_ext_i32_tl(t0
, fp0
);
9526 tcg_temp_free_i32(fp0
);
9528 TCGv_i32 fp0
= tcg_temp_new_i32();
9530 gen_load_fpr32h(ctx
, fp0
, rt
);
9531 tcg_gen_ext_i32_tl(t0
, fp0
);
9532 tcg_temp_free_i32(fp0
);
9536 /* XXX: For now we support only a single FPU context. */
9537 gen_helper_1e0i(cfc1
, t0
, rt
);
9539 /* COP2: Not implemented. */
9547 trace_mips_translate_tr("mftr", rt
, u
, sel
, h
);
9548 gen_store_gpr(t0
, rd
);
9554 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt
, u
, sel
, h
);
9555 gen_reserved_instruction(ctx
);
9558 static void gen_mttr(CPUMIPSState
*env
, DisasContext
*ctx
, int rd
, int rt
,
9559 int u
, int sel
, int h
)
9561 int other_tc
= env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
);
9562 TCGv t0
= tcg_temp_local_new();
9564 gen_load_gpr(t0
, rt
);
9565 if ((env
->CP0_VPEConf0
& (1 << CP0VPEC0_MVP
)) == 0 &&
9566 ((env
->tcs
[other_tc
].CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)) !=
9567 (env
->active_tc
.CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)))) {
9570 } else if ((env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
)) >
9571 (env
->mvp
->CP0_MVPConf0
& (0xff << CP0MVPC0_PTC
))) {
9574 } else if (u
== 0) {
9579 gen_helper_mttc0_vpecontrol(cpu_env
, t0
);
9582 gen_helper_mttc0_vpeconf0(cpu_env
, t0
);
9592 gen_helper_mttc0_tcstatus(cpu_env
, t0
);
9595 gen_helper_mttc0_tcbind(cpu_env
, t0
);
9598 gen_helper_mttc0_tcrestart(cpu_env
, t0
);
9601 gen_helper_mttc0_tchalt(cpu_env
, t0
);
9604 gen_helper_mttc0_tccontext(cpu_env
, t0
);
9607 gen_helper_mttc0_tcschedule(cpu_env
, t0
);
9610 gen_helper_mttc0_tcschefback(cpu_env
, t0
);
9613 gen_mtc0(ctx
, t0
, rd
, sel
);
9620 gen_helper_mttc0_entryhi(cpu_env
, t0
);
9623 gen_mtc0(ctx
, t0
, rd
, sel
);
9630 gen_helper_mttc0_status(cpu_env
, t0
);
9633 gen_mtc0(ctx
, t0
, rd
, sel
);
9640 gen_helper_mttc0_cause(cpu_env
, t0
);
9650 gen_helper_mttc0_ebase(cpu_env
, t0
);
9660 gen_helper_mttc0_debug(cpu_env
, t0
);
9663 gen_mtc0(ctx
, t0
, rd
, sel
);
9668 gen_mtc0(ctx
, t0
, rd
, sel
);
9672 /* GPR registers. */
9674 gen_helper_0e1i(mttgpr
, t0
, rd
);
9676 /* Auxiliary CPU registers */
9680 gen_helper_0e1i(mttlo
, t0
, 0);
9683 gen_helper_0e1i(mtthi
, t0
, 0);
9686 gen_helper_0e1i(mttacx
, t0
, 0);
9689 gen_helper_0e1i(mttlo
, t0
, 1);
9692 gen_helper_0e1i(mtthi
, t0
, 1);
9695 gen_helper_0e1i(mttacx
, t0
, 1);
9698 gen_helper_0e1i(mttlo
, t0
, 2);
9701 gen_helper_0e1i(mtthi
, t0
, 2);
9704 gen_helper_0e1i(mttacx
, t0
, 2);
9707 gen_helper_0e1i(mttlo
, t0
, 3);
9710 gen_helper_0e1i(mtthi
, t0
, 3);
9713 gen_helper_0e1i(mttacx
, t0
, 3);
9716 gen_helper_mttdsp(cpu_env
, t0
);
9722 /* Floating point (COP1). */
9724 /* XXX: For now we support only a single FPU context. */
9726 TCGv_i32 fp0
= tcg_temp_new_i32();
9728 tcg_gen_trunc_tl_i32(fp0
, t0
);
9729 gen_store_fpr32(ctx
, fp0
, rd
);
9730 tcg_temp_free_i32(fp0
);
9732 TCGv_i32 fp0
= tcg_temp_new_i32();
9734 tcg_gen_trunc_tl_i32(fp0
, t0
);
9735 gen_store_fpr32h(ctx
, fp0
, rd
);
9736 tcg_temp_free_i32(fp0
);
9740 /* XXX: For now we support only a single FPU context. */
9742 TCGv_i32 fs_tmp
= tcg_const_i32(rd
);
9744 gen_helper_0e2i(ctc1
, t0
, fs_tmp
, rt
);
9745 tcg_temp_free_i32(fs_tmp
);
9747 /* Stop translation as we may have changed hflags */
9748 ctx
->base
.is_jmp
= DISAS_STOP
;
9750 /* COP2: Not implemented. */
9758 trace_mips_translate_tr("mttr", rd
, u
, sel
, h
);
9764 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd
, u
, sel
, h
);
9765 gen_reserved_instruction(ctx
);
9768 static void gen_cp0(CPUMIPSState
*env
, DisasContext
*ctx
, uint32_t opc
,
9771 const char *opn
= "ldst";
9773 check_cp0_enabled(ctx
);
9780 gen_mfc0(ctx
, cpu_gpr
[rt
], rd
, ctx
->opcode
& 0x7);
9785 TCGv t0
= tcg_temp_new();
9787 gen_load_gpr(t0
, rt
);
9788 gen_mtc0(ctx
, t0
, rd
, ctx
->opcode
& 0x7);
9793 #if defined(TARGET_MIPS64)
9795 check_insn(ctx
, ISA_MIPS3
);
9800 gen_dmfc0(ctx
, cpu_gpr
[rt
], rd
, ctx
->opcode
& 0x7);
9804 check_insn(ctx
, ISA_MIPS3
);
9806 TCGv t0
= tcg_temp_new();
9808 gen_load_gpr(t0
, rt
);
9809 gen_dmtc0(ctx
, t0
, rd
, ctx
->opcode
& 0x7);
9821 gen_mfhc0(ctx
, cpu_gpr
[rt
], rd
, ctx
->opcode
& 0x7);
9827 TCGv t0
= tcg_temp_new();
9828 gen_load_gpr(t0
, rt
);
9829 gen_mthc0(ctx
, t0
, rd
, ctx
->opcode
& 0x7);
9835 check_cp0_enabled(ctx
);
9840 gen_mftr(env
, ctx
, rt
, rd
, (ctx
->opcode
>> 5) & 1,
9841 ctx
->opcode
& 0x7, (ctx
->opcode
>> 4) & 1);
9845 check_cp0_enabled(ctx
);
9846 gen_mttr(env
, ctx
, rd
, rt
, (ctx
->opcode
>> 5) & 1,
9847 ctx
->opcode
& 0x7, (ctx
->opcode
>> 4) & 1);
9852 if (!env
->tlb
->helper_tlbwi
) {
9855 gen_helper_tlbwi(cpu_env
);
9860 if (!env
->tlb
->helper_tlbinv
) {
9863 gen_helper_tlbinv(cpu_env
);
9864 } /* treat as nop if TLBINV not supported */
9869 if (!env
->tlb
->helper_tlbinvf
) {
9872 gen_helper_tlbinvf(cpu_env
);
9873 } /* treat as nop if TLBINV not supported */
9877 if (!env
->tlb
->helper_tlbwr
) {
9880 gen_helper_tlbwr(cpu_env
);
9884 if (!env
->tlb
->helper_tlbp
) {
9887 gen_helper_tlbp(cpu_env
);
9891 if (!env
->tlb
->helper_tlbr
) {
9894 gen_helper_tlbr(cpu_env
);
9896 case OPC_ERET
: /* OPC_ERETNC */
9897 if ((ctx
->insn_flags
& ISA_MIPS_R6
) &&
9898 (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
9901 int bit_shift
= (ctx
->hflags
& MIPS_HFLAG_M16
) ? 16 : 6;
9902 if (ctx
->opcode
& (1 << bit_shift
)) {
9905 check_insn(ctx
, ISA_MIPS_R5
);
9906 gen_helper_eretnc(cpu_env
);
9910 check_insn(ctx
, ISA_MIPS2
);
9911 gen_helper_eret(cpu_env
);
9913 ctx
->base
.is_jmp
= DISAS_EXIT
;
9918 check_insn(ctx
, ISA_MIPS_R1
);
9919 if ((ctx
->insn_flags
& ISA_MIPS_R6
) &&
9920 (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
9923 if (!(ctx
->hflags
& MIPS_HFLAG_DM
)) {
9925 gen_reserved_instruction(ctx
);
9927 gen_helper_deret(cpu_env
);
9928 ctx
->base
.is_jmp
= DISAS_EXIT
;
9933 check_insn(ctx
, ISA_MIPS3
| ISA_MIPS_R1
);
9934 if ((ctx
->insn_flags
& ISA_MIPS_R6
) &&
9935 (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
9938 /* If we get an exception, we want to restart at next instruction */
9939 ctx
->base
.pc_next
+= 4;
9940 save_cpu_state(ctx
, 1);
9941 ctx
->base
.pc_next
-= 4;
9942 gen_helper_wait(cpu_env
);
9943 ctx
->base
.is_jmp
= DISAS_NORETURN
;
9948 gen_reserved_instruction(ctx
);
9951 (void)opn
; /* avoid a compiler warning */
9953 #endif /* !CONFIG_USER_ONLY */
9955 /* CP1 Branches (before delay slot) */
9956 static void gen_compute_branch1(DisasContext
*ctx
, uint32_t op
,
9957 int32_t cc
, int32_t offset
)
9959 target_ulong btarget
;
9960 TCGv_i32 t0
= tcg_temp_new_i32();
9962 if ((ctx
->insn_flags
& ISA_MIPS_R6
) && (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
9963 gen_reserved_instruction(ctx
);
9968 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS_R1
);
9971 btarget
= ctx
->base
.pc_next
+ 4 + offset
;
9975 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
9976 tcg_gen_not_i32(t0
, t0
);
9977 tcg_gen_andi_i32(t0
, t0
, 1);
9978 tcg_gen_extu_i32_tl(bcond
, t0
);
9981 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
9982 tcg_gen_not_i32(t0
, t0
);
9983 tcg_gen_andi_i32(t0
, t0
, 1);
9984 tcg_gen_extu_i32_tl(bcond
, t0
);
9987 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
9988 tcg_gen_andi_i32(t0
, t0
, 1);
9989 tcg_gen_extu_i32_tl(bcond
, t0
);
9992 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
9993 tcg_gen_andi_i32(t0
, t0
, 1);
9994 tcg_gen_extu_i32_tl(bcond
, t0
);
9996 ctx
->hflags
|= MIPS_HFLAG_BL
;
10000 TCGv_i32 t1
= tcg_temp_new_i32();
10001 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
10002 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 1));
10003 tcg_gen_nand_i32(t0
, t0
, t1
);
10004 tcg_temp_free_i32(t1
);
10005 tcg_gen_andi_i32(t0
, t0
, 1);
10006 tcg_gen_extu_i32_tl(bcond
, t0
);
10011 TCGv_i32 t1
= tcg_temp_new_i32();
10012 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
10013 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 1));
10014 tcg_gen_or_i32(t0
, t0
, t1
);
10015 tcg_temp_free_i32(t1
);
10016 tcg_gen_andi_i32(t0
, t0
, 1);
10017 tcg_gen_extu_i32_tl(bcond
, t0
);
10022 TCGv_i32 t1
= tcg_temp_new_i32();
10023 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
10024 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 1));
10025 tcg_gen_and_i32(t0
, t0
, t1
);
10026 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 2));
10027 tcg_gen_and_i32(t0
, t0
, t1
);
10028 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 3));
10029 tcg_gen_nand_i32(t0
, t0
, t1
);
10030 tcg_temp_free_i32(t1
);
10031 tcg_gen_andi_i32(t0
, t0
, 1);
10032 tcg_gen_extu_i32_tl(bcond
, t0
);
10037 TCGv_i32 t1
= tcg_temp_new_i32();
10038 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
10039 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 1));
10040 tcg_gen_or_i32(t0
, t0
, t1
);
10041 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 2));
10042 tcg_gen_or_i32(t0
, t0
, t1
);
10043 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 3));
10044 tcg_gen_or_i32(t0
, t0
, t1
);
10045 tcg_temp_free_i32(t1
);
10046 tcg_gen_andi_i32(t0
, t0
, 1);
10047 tcg_gen_extu_i32_tl(bcond
, t0
);
10050 ctx
->hflags
|= MIPS_HFLAG_BC
;
10053 MIPS_INVAL("cp1 cond branch");
10054 gen_reserved_instruction(ctx
);
10057 ctx
->btarget
= btarget
;
10058 ctx
->hflags
|= MIPS_HFLAG_BDS32
;
10060 tcg_temp_free_i32(t0
);
10063 /* R6 CP1 Branches */
10064 static void gen_compute_branch1_r6(DisasContext
*ctx
, uint32_t op
,
10065 int32_t ft
, int32_t offset
,
10066 int delayslot_size
)
10068 target_ulong btarget
;
10069 TCGv_i64 t0
= tcg_temp_new_i64();
10071 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
10072 #ifdef MIPS_DEBUG_DISAS
10073 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
10074 "\n", ctx
->base
.pc_next
);
10076 gen_reserved_instruction(ctx
);
10080 gen_load_fpr64(ctx
, t0
, ft
);
10081 tcg_gen_andi_i64(t0
, t0
, 1);
10083 btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
10087 tcg_gen_xori_i64(t0
, t0
, 1);
10088 ctx
->hflags
|= MIPS_HFLAG_BC
;
10091 /* t0 already set */
10092 ctx
->hflags
|= MIPS_HFLAG_BC
;
10095 MIPS_INVAL("cp1 cond branch");
10096 gen_reserved_instruction(ctx
);
10100 tcg_gen_trunc_i64_tl(bcond
, t0
);
10102 ctx
->btarget
= btarget
;
10104 switch (delayslot_size
) {
10106 ctx
->hflags
|= MIPS_HFLAG_BDS16
;
10109 ctx
->hflags
|= MIPS_HFLAG_BDS32
;
10114 tcg_temp_free_i64(t0
);
10117 /* Coprocessor 1 (FPU) */
10119 #define FOP(func, fmt) (((fmt) << 21) | (func))
10122 OPC_ADD_S
= FOP(0, FMT_S
),
10123 OPC_SUB_S
= FOP(1, FMT_S
),
10124 OPC_MUL_S
= FOP(2, FMT_S
),
10125 OPC_DIV_S
= FOP(3, FMT_S
),
10126 OPC_SQRT_S
= FOP(4, FMT_S
),
10127 OPC_ABS_S
= FOP(5, FMT_S
),
10128 OPC_MOV_S
= FOP(6, FMT_S
),
10129 OPC_NEG_S
= FOP(7, FMT_S
),
10130 OPC_ROUND_L_S
= FOP(8, FMT_S
),
10131 OPC_TRUNC_L_S
= FOP(9, FMT_S
),
10132 OPC_CEIL_L_S
= FOP(10, FMT_S
),
10133 OPC_FLOOR_L_S
= FOP(11, FMT_S
),
10134 OPC_ROUND_W_S
= FOP(12, FMT_S
),
10135 OPC_TRUNC_W_S
= FOP(13, FMT_S
),
10136 OPC_CEIL_W_S
= FOP(14, FMT_S
),
10137 OPC_FLOOR_W_S
= FOP(15, FMT_S
),
10138 OPC_SEL_S
= FOP(16, FMT_S
),
10139 OPC_MOVCF_S
= FOP(17, FMT_S
),
10140 OPC_MOVZ_S
= FOP(18, FMT_S
),
10141 OPC_MOVN_S
= FOP(19, FMT_S
),
10142 OPC_SELEQZ_S
= FOP(20, FMT_S
),
10143 OPC_RECIP_S
= FOP(21, FMT_S
),
10144 OPC_RSQRT_S
= FOP(22, FMT_S
),
10145 OPC_SELNEZ_S
= FOP(23, FMT_S
),
10146 OPC_MADDF_S
= FOP(24, FMT_S
),
10147 OPC_MSUBF_S
= FOP(25, FMT_S
),
10148 OPC_RINT_S
= FOP(26, FMT_S
),
10149 OPC_CLASS_S
= FOP(27, FMT_S
),
10150 OPC_MIN_S
= FOP(28, FMT_S
),
10151 OPC_RECIP2_S
= FOP(28, FMT_S
),
10152 OPC_MINA_S
= FOP(29, FMT_S
),
10153 OPC_RECIP1_S
= FOP(29, FMT_S
),
10154 OPC_MAX_S
= FOP(30, FMT_S
),
10155 OPC_RSQRT1_S
= FOP(30, FMT_S
),
10156 OPC_MAXA_S
= FOP(31, FMT_S
),
10157 OPC_RSQRT2_S
= FOP(31, FMT_S
),
10158 OPC_CVT_D_S
= FOP(33, FMT_S
),
10159 OPC_CVT_W_S
= FOP(36, FMT_S
),
10160 OPC_CVT_L_S
= FOP(37, FMT_S
),
10161 OPC_CVT_PS_S
= FOP(38, FMT_S
),
10162 OPC_CMP_F_S
= FOP(48, FMT_S
),
10163 OPC_CMP_UN_S
= FOP(49, FMT_S
),
10164 OPC_CMP_EQ_S
= FOP(50, FMT_S
),
10165 OPC_CMP_UEQ_S
= FOP(51, FMT_S
),
10166 OPC_CMP_OLT_S
= FOP(52, FMT_S
),
10167 OPC_CMP_ULT_S
= FOP(53, FMT_S
),
10168 OPC_CMP_OLE_S
= FOP(54, FMT_S
),
10169 OPC_CMP_ULE_S
= FOP(55, FMT_S
),
10170 OPC_CMP_SF_S
= FOP(56, FMT_S
),
10171 OPC_CMP_NGLE_S
= FOP(57, FMT_S
),
10172 OPC_CMP_SEQ_S
= FOP(58, FMT_S
),
10173 OPC_CMP_NGL_S
= FOP(59, FMT_S
),
10174 OPC_CMP_LT_S
= FOP(60, FMT_S
),
10175 OPC_CMP_NGE_S
= FOP(61, FMT_S
),
10176 OPC_CMP_LE_S
= FOP(62, FMT_S
),
10177 OPC_CMP_NGT_S
= FOP(63, FMT_S
),
10179 OPC_ADD_D
= FOP(0, FMT_D
),
10180 OPC_SUB_D
= FOP(1, FMT_D
),
10181 OPC_MUL_D
= FOP(2, FMT_D
),
10182 OPC_DIV_D
= FOP(3, FMT_D
),
10183 OPC_SQRT_D
= FOP(4, FMT_D
),
10184 OPC_ABS_D
= FOP(5, FMT_D
),
10185 OPC_MOV_D
= FOP(6, FMT_D
),
10186 OPC_NEG_D
= FOP(7, FMT_D
),
10187 OPC_ROUND_L_D
= FOP(8, FMT_D
),
10188 OPC_TRUNC_L_D
= FOP(9, FMT_D
),
10189 OPC_CEIL_L_D
= FOP(10, FMT_D
),
10190 OPC_FLOOR_L_D
= FOP(11, FMT_D
),
10191 OPC_ROUND_W_D
= FOP(12, FMT_D
),
10192 OPC_TRUNC_W_D
= FOP(13, FMT_D
),
10193 OPC_CEIL_W_D
= FOP(14, FMT_D
),
10194 OPC_FLOOR_W_D
= FOP(15, FMT_D
),
10195 OPC_SEL_D
= FOP(16, FMT_D
),
10196 OPC_MOVCF_D
= FOP(17, FMT_D
),
10197 OPC_MOVZ_D
= FOP(18, FMT_D
),
10198 OPC_MOVN_D
= FOP(19, FMT_D
),
10199 OPC_SELEQZ_D
= FOP(20, FMT_D
),
10200 OPC_RECIP_D
= FOP(21, FMT_D
),
10201 OPC_RSQRT_D
= FOP(22, FMT_D
),
10202 OPC_SELNEZ_D
= FOP(23, FMT_D
),
10203 OPC_MADDF_D
= FOP(24, FMT_D
),
10204 OPC_MSUBF_D
= FOP(25, FMT_D
),
10205 OPC_RINT_D
= FOP(26, FMT_D
),
10206 OPC_CLASS_D
= FOP(27, FMT_D
),
10207 OPC_MIN_D
= FOP(28, FMT_D
),
10208 OPC_RECIP2_D
= FOP(28, FMT_D
),
10209 OPC_MINA_D
= FOP(29, FMT_D
),
10210 OPC_RECIP1_D
= FOP(29, FMT_D
),
10211 OPC_MAX_D
= FOP(30, FMT_D
),
10212 OPC_RSQRT1_D
= FOP(30, FMT_D
),
10213 OPC_MAXA_D
= FOP(31, FMT_D
),
10214 OPC_RSQRT2_D
= FOP(31, FMT_D
),
10215 OPC_CVT_S_D
= FOP(32, FMT_D
),
10216 OPC_CVT_W_D
= FOP(36, FMT_D
),
10217 OPC_CVT_L_D
= FOP(37, FMT_D
),
10218 OPC_CMP_F_D
= FOP(48, FMT_D
),
10219 OPC_CMP_UN_D
= FOP(49, FMT_D
),
10220 OPC_CMP_EQ_D
= FOP(50, FMT_D
),
10221 OPC_CMP_UEQ_D
= FOP(51, FMT_D
),
10222 OPC_CMP_OLT_D
= FOP(52, FMT_D
),
10223 OPC_CMP_ULT_D
= FOP(53, FMT_D
),
10224 OPC_CMP_OLE_D
= FOP(54, FMT_D
),
10225 OPC_CMP_ULE_D
= FOP(55, FMT_D
),
10226 OPC_CMP_SF_D
= FOP(56, FMT_D
),
10227 OPC_CMP_NGLE_D
= FOP(57, FMT_D
),
10228 OPC_CMP_SEQ_D
= FOP(58, FMT_D
),
10229 OPC_CMP_NGL_D
= FOP(59, FMT_D
),
10230 OPC_CMP_LT_D
= FOP(60, FMT_D
),
10231 OPC_CMP_NGE_D
= FOP(61, FMT_D
),
10232 OPC_CMP_LE_D
= FOP(62, FMT_D
),
10233 OPC_CMP_NGT_D
= FOP(63, FMT_D
),
10235 OPC_CVT_S_W
= FOP(32, FMT_W
),
10236 OPC_CVT_D_W
= FOP(33, FMT_W
),
10237 OPC_CVT_S_L
= FOP(32, FMT_L
),
10238 OPC_CVT_D_L
= FOP(33, FMT_L
),
10239 OPC_CVT_PS_PW
= FOP(38, FMT_W
),
10241 OPC_ADD_PS
= FOP(0, FMT_PS
),
10242 OPC_SUB_PS
= FOP(1, FMT_PS
),
10243 OPC_MUL_PS
= FOP(2, FMT_PS
),
10244 OPC_DIV_PS
= FOP(3, FMT_PS
),
10245 OPC_ABS_PS
= FOP(5, FMT_PS
),
10246 OPC_MOV_PS
= FOP(6, FMT_PS
),
10247 OPC_NEG_PS
= FOP(7, FMT_PS
),
10248 OPC_MOVCF_PS
= FOP(17, FMT_PS
),
10249 OPC_MOVZ_PS
= FOP(18, FMT_PS
),
10250 OPC_MOVN_PS
= FOP(19, FMT_PS
),
10251 OPC_ADDR_PS
= FOP(24, FMT_PS
),
10252 OPC_MULR_PS
= FOP(26, FMT_PS
),
10253 OPC_RECIP2_PS
= FOP(28, FMT_PS
),
10254 OPC_RECIP1_PS
= FOP(29, FMT_PS
),
10255 OPC_RSQRT1_PS
= FOP(30, FMT_PS
),
10256 OPC_RSQRT2_PS
= FOP(31, FMT_PS
),
10258 OPC_CVT_S_PU
= FOP(32, FMT_PS
),
10259 OPC_CVT_PW_PS
= FOP(36, FMT_PS
),
10260 OPC_CVT_S_PL
= FOP(40, FMT_PS
),
10261 OPC_PLL_PS
= FOP(44, FMT_PS
),
10262 OPC_PLU_PS
= FOP(45, FMT_PS
),
10263 OPC_PUL_PS
= FOP(46, FMT_PS
),
10264 OPC_PUU_PS
= FOP(47, FMT_PS
),
10265 OPC_CMP_F_PS
= FOP(48, FMT_PS
),
10266 OPC_CMP_UN_PS
= FOP(49, FMT_PS
),
10267 OPC_CMP_EQ_PS
= FOP(50, FMT_PS
),
10268 OPC_CMP_UEQ_PS
= FOP(51, FMT_PS
),
10269 OPC_CMP_OLT_PS
= FOP(52, FMT_PS
),
10270 OPC_CMP_ULT_PS
= FOP(53, FMT_PS
),
10271 OPC_CMP_OLE_PS
= FOP(54, FMT_PS
),
10272 OPC_CMP_ULE_PS
= FOP(55, FMT_PS
),
10273 OPC_CMP_SF_PS
= FOP(56, FMT_PS
),
10274 OPC_CMP_NGLE_PS
= FOP(57, FMT_PS
),
10275 OPC_CMP_SEQ_PS
= FOP(58, FMT_PS
),
10276 OPC_CMP_NGL_PS
= FOP(59, FMT_PS
),
10277 OPC_CMP_LT_PS
= FOP(60, FMT_PS
),
10278 OPC_CMP_NGE_PS
= FOP(61, FMT_PS
),
10279 OPC_CMP_LE_PS
= FOP(62, FMT_PS
),
10280 OPC_CMP_NGT_PS
= FOP(63, FMT_PS
),
10284 R6_OPC_CMP_AF_S
= FOP(0, FMT_W
),
10285 R6_OPC_CMP_UN_S
= FOP(1, FMT_W
),
10286 R6_OPC_CMP_EQ_S
= FOP(2, FMT_W
),
10287 R6_OPC_CMP_UEQ_S
= FOP(3, FMT_W
),
10288 R6_OPC_CMP_LT_S
= FOP(4, FMT_W
),
10289 R6_OPC_CMP_ULT_S
= FOP(5, FMT_W
),
10290 R6_OPC_CMP_LE_S
= FOP(6, FMT_W
),
10291 R6_OPC_CMP_ULE_S
= FOP(7, FMT_W
),
10292 R6_OPC_CMP_SAF_S
= FOP(8, FMT_W
),
10293 R6_OPC_CMP_SUN_S
= FOP(9, FMT_W
),
10294 R6_OPC_CMP_SEQ_S
= FOP(10, FMT_W
),
10295 R6_OPC_CMP_SEUQ_S
= FOP(11, FMT_W
),
10296 R6_OPC_CMP_SLT_S
= FOP(12, FMT_W
),
10297 R6_OPC_CMP_SULT_S
= FOP(13, FMT_W
),
10298 R6_OPC_CMP_SLE_S
= FOP(14, FMT_W
),
10299 R6_OPC_CMP_SULE_S
= FOP(15, FMT_W
),
10300 R6_OPC_CMP_OR_S
= FOP(17, FMT_W
),
10301 R6_OPC_CMP_UNE_S
= FOP(18, FMT_W
),
10302 R6_OPC_CMP_NE_S
= FOP(19, FMT_W
),
10303 R6_OPC_CMP_SOR_S
= FOP(25, FMT_W
),
10304 R6_OPC_CMP_SUNE_S
= FOP(26, FMT_W
),
10305 R6_OPC_CMP_SNE_S
= FOP(27, FMT_W
),
10307 R6_OPC_CMP_AF_D
= FOP(0, FMT_L
),
10308 R6_OPC_CMP_UN_D
= FOP(1, FMT_L
),
10309 R6_OPC_CMP_EQ_D
= FOP(2, FMT_L
),
10310 R6_OPC_CMP_UEQ_D
= FOP(3, FMT_L
),
10311 R6_OPC_CMP_LT_D
= FOP(4, FMT_L
),
10312 R6_OPC_CMP_ULT_D
= FOP(5, FMT_L
),
10313 R6_OPC_CMP_LE_D
= FOP(6, FMT_L
),
10314 R6_OPC_CMP_ULE_D
= FOP(7, FMT_L
),
10315 R6_OPC_CMP_SAF_D
= FOP(8, FMT_L
),
10316 R6_OPC_CMP_SUN_D
= FOP(9, FMT_L
),
10317 R6_OPC_CMP_SEQ_D
= FOP(10, FMT_L
),
10318 R6_OPC_CMP_SEUQ_D
= FOP(11, FMT_L
),
10319 R6_OPC_CMP_SLT_D
= FOP(12, FMT_L
),
10320 R6_OPC_CMP_SULT_D
= FOP(13, FMT_L
),
10321 R6_OPC_CMP_SLE_D
= FOP(14, FMT_L
),
10322 R6_OPC_CMP_SULE_D
= FOP(15, FMT_L
),
10323 R6_OPC_CMP_OR_D
= FOP(17, FMT_L
),
10324 R6_OPC_CMP_UNE_D
= FOP(18, FMT_L
),
10325 R6_OPC_CMP_NE_D
= FOP(19, FMT_L
),
10326 R6_OPC_CMP_SOR_D
= FOP(25, FMT_L
),
10327 R6_OPC_CMP_SUNE_D
= FOP(26, FMT_L
),
10328 R6_OPC_CMP_SNE_D
= FOP(27, FMT_L
),
10331 static void gen_cp1(DisasContext
*ctx
, uint32_t opc
, int rt
, int fs
)
10333 TCGv t0
= tcg_temp_new();
10338 TCGv_i32 fp0
= tcg_temp_new_i32();
10340 gen_load_fpr32(ctx
, fp0
, fs
);
10341 tcg_gen_ext_i32_tl(t0
, fp0
);
10342 tcg_temp_free_i32(fp0
);
10344 gen_store_gpr(t0
, rt
);
10347 gen_load_gpr(t0
, rt
);
10349 TCGv_i32 fp0
= tcg_temp_new_i32();
10351 tcg_gen_trunc_tl_i32(fp0
, t0
);
10352 gen_store_fpr32(ctx
, fp0
, fs
);
10353 tcg_temp_free_i32(fp0
);
10357 gen_helper_1e0i(cfc1
, t0
, fs
);
10358 gen_store_gpr(t0
, rt
);
10361 gen_load_gpr(t0
, rt
);
10362 save_cpu_state(ctx
, 0);
10364 TCGv_i32 fs_tmp
= tcg_const_i32(fs
);
10366 gen_helper_0e2i(ctc1
, t0
, fs_tmp
, rt
);
10367 tcg_temp_free_i32(fs_tmp
);
10369 /* Stop translation as we may have changed hflags */
10370 ctx
->base
.is_jmp
= DISAS_STOP
;
10372 #if defined(TARGET_MIPS64)
10374 gen_load_fpr64(ctx
, t0
, fs
);
10375 gen_store_gpr(t0
, rt
);
10378 gen_load_gpr(t0
, rt
);
10379 gen_store_fpr64(ctx
, t0
, fs
);
10384 TCGv_i32 fp0
= tcg_temp_new_i32();
10386 gen_load_fpr32h(ctx
, fp0
, fs
);
10387 tcg_gen_ext_i32_tl(t0
, fp0
);
10388 tcg_temp_free_i32(fp0
);
10390 gen_store_gpr(t0
, rt
);
10393 gen_load_gpr(t0
, rt
);
10395 TCGv_i32 fp0
= tcg_temp_new_i32();
10397 tcg_gen_trunc_tl_i32(fp0
, t0
);
10398 gen_store_fpr32h(ctx
, fp0
, fs
);
10399 tcg_temp_free_i32(fp0
);
10403 MIPS_INVAL("cp1 move");
10404 gen_reserved_instruction(ctx
);
10412 static void gen_movci(DisasContext
*ctx
, int rd
, int rs
, int cc
, int tf
)
10419 /* Treat as NOP. */
10424 cond
= TCG_COND_EQ
;
10426 cond
= TCG_COND_NE
;
10429 l1
= gen_new_label();
10430 t0
= tcg_temp_new_i32();
10431 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
10432 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
10433 tcg_temp_free_i32(t0
);
10434 gen_load_gpr(cpu_gpr
[rd
], rs
);
10438 static inline void gen_movcf_s(DisasContext
*ctx
, int fs
, int fd
, int cc
,
10442 TCGv_i32 t0
= tcg_temp_new_i32();
10443 TCGLabel
*l1
= gen_new_label();
10446 cond
= TCG_COND_EQ
;
10448 cond
= TCG_COND_NE
;
10451 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
10452 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
10453 gen_load_fpr32(ctx
, t0
, fs
);
10454 gen_store_fpr32(ctx
, t0
, fd
);
10456 tcg_temp_free_i32(t0
);
10459 static inline void gen_movcf_d(DisasContext
*ctx
, int fs
, int fd
, int cc
,
10463 TCGv_i32 t0
= tcg_temp_new_i32();
10465 TCGLabel
*l1
= gen_new_label();
10468 cond
= TCG_COND_EQ
;
10470 cond
= TCG_COND_NE
;
10473 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
10474 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
10475 tcg_temp_free_i32(t0
);
10476 fp0
= tcg_temp_new_i64();
10477 gen_load_fpr64(ctx
, fp0
, fs
);
10478 gen_store_fpr64(ctx
, fp0
, fd
);
10479 tcg_temp_free_i64(fp0
);
10483 static inline void gen_movcf_ps(DisasContext
*ctx
, int fs
, int fd
,
10487 TCGv_i32 t0
= tcg_temp_new_i32();
10488 TCGLabel
*l1
= gen_new_label();
10489 TCGLabel
*l2
= gen_new_label();
10492 cond
= TCG_COND_EQ
;
10494 cond
= TCG_COND_NE
;
10497 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
10498 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
10499 gen_load_fpr32(ctx
, t0
, fs
);
10500 gen_store_fpr32(ctx
, t0
, fd
);
10503 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
+ 1));
10504 tcg_gen_brcondi_i32(cond
, t0
, 0, l2
);
10505 gen_load_fpr32h(ctx
, t0
, fs
);
10506 gen_store_fpr32h(ctx
, t0
, fd
);
10507 tcg_temp_free_i32(t0
);
10511 static void gen_sel_s(DisasContext
*ctx
, enum fopcode op1
, int fd
, int ft
,
10514 TCGv_i32 t1
= tcg_const_i32(0);
10515 TCGv_i32 fp0
= tcg_temp_new_i32();
10516 TCGv_i32 fp1
= tcg_temp_new_i32();
10517 TCGv_i32 fp2
= tcg_temp_new_i32();
10518 gen_load_fpr32(ctx
, fp0
, fd
);
10519 gen_load_fpr32(ctx
, fp1
, ft
);
10520 gen_load_fpr32(ctx
, fp2
, fs
);
10524 tcg_gen_andi_i32(fp0
, fp0
, 1);
10525 tcg_gen_movcond_i32(TCG_COND_NE
, fp0
, fp0
, t1
, fp1
, fp2
);
10528 tcg_gen_andi_i32(fp1
, fp1
, 1);
10529 tcg_gen_movcond_i32(TCG_COND_EQ
, fp0
, fp1
, t1
, fp2
, t1
);
10532 tcg_gen_andi_i32(fp1
, fp1
, 1);
10533 tcg_gen_movcond_i32(TCG_COND_NE
, fp0
, fp1
, t1
, fp2
, t1
);
10536 MIPS_INVAL("gen_sel_s");
10537 gen_reserved_instruction(ctx
);
10541 gen_store_fpr32(ctx
, fp0
, fd
);
10542 tcg_temp_free_i32(fp2
);
10543 tcg_temp_free_i32(fp1
);
10544 tcg_temp_free_i32(fp0
);
10545 tcg_temp_free_i32(t1
);
10548 static void gen_sel_d(DisasContext
*ctx
, enum fopcode op1
, int fd
, int ft
,
10551 TCGv_i64 t1
= tcg_const_i64(0);
10552 TCGv_i64 fp0
= tcg_temp_new_i64();
10553 TCGv_i64 fp1
= tcg_temp_new_i64();
10554 TCGv_i64 fp2
= tcg_temp_new_i64();
10555 gen_load_fpr64(ctx
, fp0
, fd
);
10556 gen_load_fpr64(ctx
, fp1
, ft
);
10557 gen_load_fpr64(ctx
, fp2
, fs
);
10561 tcg_gen_andi_i64(fp0
, fp0
, 1);
10562 tcg_gen_movcond_i64(TCG_COND_NE
, fp0
, fp0
, t1
, fp1
, fp2
);
10565 tcg_gen_andi_i64(fp1
, fp1
, 1);
10566 tcg_gen_movcond_i64(TCG_COND_EQ
, fp0
, fp1
, t1
, fp2
, t1
);
10569 tcg_gen_andi_i64(fp1
, fp1
, 1);
10570 tcg_gen_movcond_i64(TCG_COND_NE
, fp0
, fp1
, t1
, fp2
, t1
);
10573 MIPS_INVAL("gen_sel_d");
10574 gen_reserved_instruction(ctx
);
10578 gen_store_fpr64(ctx
, fp0
, fd
);
10579 tcg_temp_free_i64(fp2
);
10580 tcg_temp_free_i64(fp1
);
10581 tcg_temp_free_i64(fp0
);
10582 tcg_temp_free_i64(t1
);
10585 static void gen_farith(DisasContext
*ctx
, enum fopcode op1
,
10586 int ft
, int fs
, int fd
, int cc
)
10588 uint32_t func
= ctx
->opcode
& 0x3f;
10592 TCGv_i32 fp0
= tcg_temp_new_i32();
10593 TCGv_i32 fp1
= tcg_temp_new_i32();
10595 gen_load_fpr32(ctx
, fp0
, fs
);
10596 gen_load_fpr32(ctx
, fp1
, ft
);
10597 gen_helper_float_add_s(fp0
, cpu_env
, fp0
, fp1
);
10598 tcg_temp_free_i32(fp1
);
10599 gen_store_fpr32(ctx
, fp0
, fd
);
10600 tcg_temp_free_i32(fp0
);
10605 TCGv_i32 fp0
= tcg_temp_new_i32();
10606 TCGv_i32 fp1
= tcg_temp_new_i32();
10608 gen_load_fpr32(ctx
, fp0
, fs
);
10609 gen_load_fpr32(ctx
, fp1
, ft
);
10610 gen_helper_float_sub_s(fp0
, cpu_env
, fp0
, fp1
);
10611 tcg_temp_free_i32(fp1
);
10612 gen_store_fpr32(ctx
, fp0
, fd
);
10613 tcg_temp_free_i32(fp0
);
10618 TCGv_i32 fp0
= tcg_temp_new_i32();
10619 TCGv_i32 fp1
= tcg_temp_new_i32();
10621 gen_load_fpr32(ctx
, fp0
, fs
);
10622 gen_load_fpr32(ctx
, fp1
, ft
);
10623 gen_helper_float_mul_s(fp0
, cpu_env
, fp0
, fp1
);
10624 tcg_temp_free_i32(fp1
);
10625 gen_store_fpr32(ctx
, fp0
, fd
);
10626 tcg_temp_free_i32(fp0
);
10631 TCGv_i32 fp0
= tcg_temp_new_i32();
10632 TCGv_i32 fp1
= tcg_temp_new_i32();
10634 gen_load_fpr32(ctx
, fp0
, fs
);
10635 gen_load_fpr32(ctx
, fp1
, ft
);
10636 gen_helper_float_div_s(fp0
, cpu_env
, fp0
, fp1
);
10637 tcg_temp_free_i32(fp1
);
10638 gen_store_fpr32(ctx
, fp0
, fd
);
10639 tcg_temp_free_i32(fp0
);
10644 TCGv_i32 fp0
= tcg_temp_new_i32();
10646 gen_load_fpr32(ctx
, fp0
, fs
);
10647 gen_helper_float_sqrt_s(fp0
, cpu_env
, fp0
);
10648 gen_store_fpr32(ctx
, fp0
, fd
);
10649 tcg_temp_free_i32(fp0
);
10654 TCGv_i32 fp0
= tcg_temp_new_i32();
10656 gen_load_fpr32(ctx
, fp0
, fs
);
10657 if (ctx
->abs2008
) {
10658 tcg_gen_andi_i32(fp0
, fp0
, 0x7fffffffUL
);
10660 gen_helper_float_abs_s(fp0
, fp0
);
10662 gen_store_fpr32(ctx
, fp0
, fd
);
10663 tcg_temp_free_i32(fp0
);
10668 TCGv_i32 fp0
= tcg_temp_new_i32();
10670 gen_load_fpr32(ctx
, fp0
, fs
);
10671 gen_store_fpr32(ctx
, fp0
, fd
);
10672 tcg_temp_free_i32(fp0
);
10677 TCGv_i32 fp0
= tcg_temp_new_i32();
10679 gen_load_fpr32(ctx
, fp0
, fs
);
10680 if (ctx
->abs2008
) {
10681 tcg_gen_xori_i32(fp0
, fp0
, 1UL << 31);
10683 gen_helper_float_chs_s(fp0
, fp0
);
10685 gen_store_fpr32(ctx
, fp0
, fd
);
10686 tcg_temp_free_i32(fp0
);
10689 case OPC_ROUND_L_S
:
10690 check_cp1_64bitmode(ctx
);
10692 TCGv_i32 fp32
= tcg_temp_new_i32();
10693 TCGv_i64 fp64
= tcg_temp_new_i64();
10695 gen_load_fpr32(ctx
, fp32
, fs
);
10696 if (ctx
->nan2008
) {
10697 gen_helper_float_round_2008_l_s(fp64
, cpu_env
, fp32
);
10699 gen_helper_float_round_l_s(fp64
, cpu_env
, fp32
);
10701 tcg_temp_free_i32(fp32
);
10702 gen_store_fpr64(ctx
, fp64
, fd
);
10703 tcg_temp_free_i64(fp64
);
10706 case OPC_TRUNC_L_S
:
10707 check_cp1_64bitmode(ctx
);
10709 TCGv_i32 fp32
= tcg_temp_new_i32();
10710 TCGv_i64 fp64
= tcg_temp_new_i64();
10712 gen_load_fpr32(ctx
, fp32
, fs
);
10713 if (ctx
->nan2008
) {
10714 gen_helper_float_trunc_2008_l_s(fp64
, cpu_env
, fp32
);
10716 gen_helper_float_trunc_l_s(fp64
, cpu_env
, fp32
);
10718 tcg_temp_free_i32(fp32
);
10719 gen_store_fpr64(ctx
, fp64
, fd
);
10720 tcg_temp_free_i64(fp64
);
10724 check_cp1_64bitmode(ctx
);
10726 TCGv_i32 fp32
= tcg_temp_new_i32();
10727 TCGv_i64 fp64
= tcg_temp_new_i64();
10729 gen_load_fpr32(ctx
, fp32
, fs
);
10730 if (ctx
->nan2008
) {
10731 gen_helper_float_ceil_2008_l_s(fp64
, cpu_env
, fp32
);
10733 gen_helper_float_ceil_l_s(fp64
, cpu_env
, fp32
);
10735 tcg_temp_free_i32(fp32
);
10736 gen_store_fpr64(ctx
, fp64
, fd
);
10737 tcg_temp_free_i64(fp64
);
10740 case OPC_FLOOR_L_S
:
10741 check_cp1_64bitmode(ctx
);
10743 TCGv_i32 fp32
= tcg_temp_new_i32();
10744 TCGv_i64 fp64
= tcg_temp_new_i64();
10746 gen_load_fpr32(ctx
, fp32
, fs
);
10747 if (ctx
->nan2008
) {
10748 gen_helper_float_floor_2008_l_s(fp64
, cpu_env
, fp32
);
10750 gen_helper_float_floor_l_s(fp64
, cpu_env
, fp32
);
10752 tcg_temp_free_i32(fp32
);
10753 gen_store_fpr64(ctx
, fp64
, fd
);
10754 tcg_temp_free_i64(fp64
);
10757 case OPC_ROUND_W_S
:
10759 TCGv_i32 fp0
= tcg_temp_new_i32();
10761 gen_load_fpr32(ctx
, fp0
, fs
);
10762 if (ctx
->nan2008
) {
10763 gen_helper_float_round_2008_w_s(fp0
, cpu_env
, fp0
);
10765 gen_helper_float_round_w_s(fp0
, cpu_env
, fp0
);
10767 gen_store_fpr32(ctx
, fp0
, fd
);
10768 tcg_temp_free_i32(fp0
);
10771 case OPC_TRUNC_W_S
:
10773 TCGv_i32 fp0
= tcg_temp_new_i32();
10775 gen_load_fpr32(ctx
, fp0
, fs
);
10776 if (ctx
->nan2008
) {
10777 gen_helper_float_trunc_2008_w_s(fp0
, cpu_env
, fp0
);
10779 gen_helper_float_trunc_w_s(fp0
, cpu_env
, fp0
);
10781 gen_store_fpr32(ctx
, fp0
, fd
);
10782 tcg_temp_free_i32(fp0
);
10787 TCGv_i32 fp0
= tcg_temp_new_i32();
10789 gen_load_fpr32(ctx
, fp0
, fs
);
10790 if (ctx
->nan2008
) {
10791 gen_helper_float_ceil_2008_w_s(fp0
, cpu_env
, fp0
);
10793 gen_helper_float_ceil_w_s(fp0
, cpu_env
, fp0
);
10795 gen_store_fpr32(ctx
, fp0
, fd
);
10796 tcg_temp_free_i32(fp0
);
10799 case OPC_FLOOR_W_S
:
10801 TCGv_i32 fp0
= tcg_temp_new_i32();
10803 gen_load_fpr32(ctx
, fp0
, fs
);
10804 if (ctx
->nan2008
) {
10805 gen_helper_float_floor_2008_w_s(fp0
, cpu_env
, fp0
);
10807 gen_helper_float_floor_w_s(fp0
, cpu_env
, fp0
);
10809 gen_store_fpr32(ctx
, fp0
, fd
);
10810 tcg_temp_free_i32(fp0
);
10814 check_insn(ctx
, ISA_MIPS_R6
);
10815 gen_sel_s(ctx
, op1
, fd
, ft
, fs
);
10818 check_insn(ctx
, ISA_MIPS_R6
);
10819 gen_sel_s(ctx
, op1
, fd
, ft
, fs
);
10822 check_insn(ctx
, ISA_MIPS_R6
);
10823 gen_sel_s(ctx
, op1
, fd
, ft
, fs
);
10826 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
10827 gen_movcf_s(ctx
, fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
10830 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
10832 TCGLabel
*l1
= gen_new_label();
10836 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
10838 fp0
= tcg_temp_new_i32();
10839 gen_load_fpr32(ctx
, fp0
, fs
);
10840 gen_store_fpr32(ctx
, fp0
, fd
);
10841 tcg_temp_free_i32(fp0
);
10846 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
10848 TCGLabel
*l1
= gen_new_label();
10852 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
10853 fp0
= tcg_temp_new_i32();
10854 gen_load_fpr32(ctx
, fp0
, fs
);
10855 gen_store_fpr32(ctx
, fp0
, fd
);
10856 tcg_temp_free_i32(fp0
);
10863 TCGv_i32 fp0
= tcg_temp_new_i32();
10865 gen_load_fpr32(ctx
, fp0
, fs
);
10866 gen_helper_float_recip_s(fp0
, cpu_env
, fp0
);
10867 gen_store_fpr32(ctx
, fp0
, fd
);
10868 tcg_temp_free_i32(fp0
);
10873 TCGv_i32 fp0
= tcg_temp_new_i32();
10875 gen_load_fpr32(ctx
, fp0
, fs
);
10876 gen_helper_float_rsqrt_s(fp0
, cpu_env
, fp0
);
10877 gen_store_fpr32(ctx
, fp0
, fd
);
10878 tcg_temp_free_i32(fp0
);
10882 check_insn(ctx
, ISA_MIPS_R6
);
10884 TCGv_i32 fp0
= tcg_temp_new_i32();
10885 TCGv_i32 fp1
= tcg_temp_new_i32();
10886 TCGv_i32 fp2
= tcg_temp_new_i32();
10887 gen_load_fpr32(ctx
, fp0
, fs
);
10888 gen_load_fpr32(ctx
, fp1
, ft
);
10889 gen_load_fpr32(ctx
, fp2
, fd
);
10890 gen_helper_float_maddf_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
10891 gen_store_fpr32(ctx
, fp2
, fd
);
10892 tcg_temp_free_i32(fp2
);
10893 tcg_temp_free_i32(fp1
);
10894 tcg_temp_free_i32(fp0
);
10898 check_insn(ctx
, ISA_MIPS_R6
);
10900 TCGv_i32 fp0
= tcg_temp_new_i32();
10901 TCGv_i32 fp1
= tcg_temp_new_i32();
10902 TCGv_i32 fp2
= tcg_temp_new_i32();
10903 gen_load_fpr32(ctx
, fp0
, fs
);
10904 gen_load_fpr32(ctx
, fp1
, ft
);
10905 gen_load_fpr32(ctx
, fp2
, fd
);
10906 gen_helper_float_msubf_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
10907 gen_store_fpr32(ctx
, fp2
, fd
);
10908 tcg_temp_free_i32(fp2
);
10909 tcg_temp_free_i32(fp1
);
10910 tcg_temp_free_i32(fp0
);
10914 check_insn(ctx
, ISA_MIPS_R6
);
10916 TCGv_i32 fp0
= tcg_temp_new_i32();
10917 gen_load_fpr32(ctx
, fp0
, fs
);
10918 gen_helper_float_rint_s(fp0
, cpu_env
, fp0
);
10919 gen_store_fpr32(ctx
, fp0
, fd
);
10920 tcg_temp_free_i32(fp0
);
10924 check_insn(ctx
, ISA_MIPS_R6
);
10926 TCGv_i32 fp0
= tcg_temp_new_i32();
10927 gen_load_fpr32(ctx
, fp0
, fs
);
10928 gen_helper_float_class_s(fp0
, cpu_env
, fp0
);
10929 gen_store_fpr32(ctx
, fp0
, fd
);
10930 tcg_temp_free_i32(fp0
);
10933 case OPC_MIN_S
: /* OPC_RECIP2_S */
10934 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
10936 TCGv_i32 fp0
= tcg_temp_new_i32();
10937 TCGv_i32 fp1
= tcg_temp_new_i32();
10938 TCGv_i32 fp2
= tcg_temp_new_i32();
10939 gen_load_fpr32(ctx
, fp0
, fs
);
10940 gen_load_fpr32(ctx
, fp1
, ft
);
10941 gen_helper_float_min_s(fp2
, cpu_env
, fp0
, fp1
);
10942 gen_store_fpr32(ctx
, fp2
, fd
);
10943 tcg_temp_free_i32(fp2
);
10944 tcg_temp_free_i32(fp1
);
10945 tcg_temp_free_i32(fp0
);
10948 check_cp1_64bitmode(ctx
);
10950 TCGv_i32 fp0
= tcg_temp_new_i32();
10951 TCGv_i32 fp1
= tcg_temp_new_i32();
10953 gen_load_fpr32(ctx
, fp0
, fs
);
10954 gen_load_fpr32(ctx
, fp1
, ft
);
10955 gen_helper_float_recip2_s(fp0
, cpu_env
, fp0
, fp1
);
10956 tcg_temp_free_i32(fp1
);
10957 gen_store_fpr32(ctx
, fp0
, fd
);
10958 tcg_temp_free_i32(fp0
);
10962 case OPC_MINA_S
: /* OPC_RECIP1_S */
10963 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
10965 TCGv_i32 fp0
= tcg_temp_new_i32();
10966 TCGv_i32 fp1
= tcg_temp_new_i32();
10967 TCGv_i32 fp2
= tcg_temp_new_i32();
10968 gen_load_fpr32(ctx
, fp0
, fs
);
10969 gen_load_fpr32(ctx
, fp1
, ft
);
10970 gen_helper_float_mina_s(fp2
, cpu_env
, fp0
, fp1
);
10971 gen_store_fpr32(ctx
, fp2
, fd
);
10972 tcg_temp_free_i32(fp2
);
10973 tcg_temp_free_i32(fp1
);
10974 tcg_temp_free_i32(fp0
);
10977 check_cp1_64bitmode(ctx
);
10979 TCGv_i32 fp0
= tcg_temp_new_i32();
10981 gen_load_fpr32(ctx
, fp0
, fs
);
10982 gen_helper_float_recip1_s(fp0
, cpu_env
, fp0
);
10983 gen_store_fpr32(ctx
, fp0
, fd
);
10984 tcg_temp_free_i32(fp0
);
10988 case OPC_MAX_S
: /* OPC_RSQRT1_S */
10989 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
10991 TCGv_i32 fp0
= tcg_temp_new_i32();
10992 TCGv_i32 fp1
= tcg_temp_new_i32();
10993 gen_load_fpr32(ctx
, fp0
, fs
);
10994 gen_load_fpr32(ctx
, fp1
, ft
);
10995 gen_helper_float_max_s(fp1
, cpu_env
, fp0
, fp1
);
10996 gen_store_fpr32(ctx
, fp1
, fd
);
10997 tcg_temp_free_i32(fp1
);
10998 tcg_temp_free_i32(fp0
);
11001 check_cp1_64bitmode(ctx
);
11003 TCGv_i32 fp0
= tcg_temp_new_i32();
11005 gen_load_fpr32(ctx
, fp0
, fs
);
11006 gen_helper_float_rsqrt1_s(fp0
, cpu_env
, fp0
);
11007 gen_store_fpr32(ctx
, fp0
, fd
);
11008 tcg_temp_free_i32(fp0
);
11012 case OPC_MAXA_S
: /* OPC_RSQRT2_S */
11013 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
11015 TCGv_i32 fp0
= tcg_temp_new_i32();
11016 TCGv_i32 fp1
= tcg_temp_new_i32();
11017 gen_load_fpr32(ctx
, fp0
, fs
);
11018 gen_load_fpr32(ctx
, fp1
, ft
);
11019 gen_helper_float_maxa_s(fp1
, cpu_env
, fp0
, fp1
);
11020 gen_store_fpr32(ctx
, fp1
, fd
);
11021 tcg_temp_free_i32(fp1
);
11022 tcg_temp_free_i32(fp0
);
11025 check_cp1_64bitmode(ctx
);
11027 TCGv_i32 fp0
= tcg_temp_new_i32();
11028 TCGv_i32 fp1
= tcg_temp_new_i32();
11030 gen_load_fpr32(ctx
, fp0
, fs
);
11031 gen_load_fpr32(ctx
, fp1
, ft
);
11032 gen_helper_float_rsqrt2_s(fp0
, cpu_env
, fp0
, fp1
);
11033 tcg_temp_free_i32(fp1
);
11034 gen_store_fpr32(ctx
, fp0
, fd
);
11035 tcg_temp_free_i32(fp0
);
11040 check_cp1_registers(ctx
, fd
);
11042 TCGv_i32 fp32
= tcg_temp_new_i32();
11043 TCGv_i64 fp64
= tcg_temp_new_i64();
11045 gen_load_fpr32(ctx
, fp32
, fs
);
11046 gen_helper_float_cvtd_s(fp64
, cpu_env
, fp32
);
11047 tcg_temp_free_i32(fp32
);
11048 gen_store_fpr64(ctx
, fp64
, fd
);
11049 tcg_temp_free_i64(fp64
);
11054 TCGv_i32 fp0
= tcg_temp_new_i32();
11056 gen_load_fpr32(ctx
, fp0
, fs
);
11057 if (ctx
->nan2008
) {
11058 gen_helper_float_cvt_2008_w_s(fp0
, cpu_env
, fp0
);
11060 gen_helper_float_cvt_w_s(fp0
, cpu_env
, fp0
);
11062 gen_store_fpr32(ctx
, fp0
, fd
);
11063 tcg_temp_free_i32(fp0
);
11067 check_cp1_64bitmode(ctx
);
11069 TCGv_i32 fp32
= tcg_temp_new_i32();
11070 TCGv_i64 fp64
= tcg_temp_new_i64();
11072 gen_load_fpr32(ctx
, fp32
, fs
);
11073 if (ctx
->nan2008
) {
11074 gen_helper_float_cvt_2008_l_s(fp64
, cpu_env
, fp32
);
11076 gen_helper_float_cvt_l_s(fp64
, cpu_env
, fp32
);
11078 tcg_temp_free_i32(fp32
);
11079 gen_store_fpr64(ctx
, fp64
, fd
);
11080 tcg_temp_free_i64(fp64
);
11086 TCGv_i64 fp64
= tcg_temp_new_i64();
11087 TCGv_i32 fp32_0
= tcg_temp_new_i32();
11088 TCGv_i32 fp32_1
= tcg_temp_new_i32();
11090 gen_load_fpr32(ctx
, fp32_0
, fs
);
11091 gen_load_fpr32(ctx
, fp32_1
, ft
);
11092 tcg_gen_concat_i32_i64(fp64
, fp32_1
, fp32_0
);
11093 tcg_temp_free_i32(fp32_1
);
11094 tcg_temp_free_i32(fp32_0
);
11095 gen_store_fpr64(ctx
, fp64
, fd
);
11096 tcg_temp_free_i64(fp64
);
11102 case OPC_CMP_UEQ_S
:
11103 case OPC_CMP_OLT_S
:
11104 case OPC_CMP_ULT_S
:
11105 case OPC_CMP_OLE_S
:
11106 case OPC_CMP_ULE_S
:
11108 case OPC_CMP_NGLE_S
:
11109 case OPC_CMP_SEQ_S
:
11110 case OPC_CMP_NGL_S
:
11112 case OPC_CMP_NGE_S
:
11114 case OPC_CMP_NGT_S
:
11115 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
11116 if (ctx
->opcode
& (1 << 6)) {
11117 gen_cmpabs_s(ctx
, func
- 48, ft
, fs
, cc
);
11119 gen_cmp_s(ctx
, func
- 48, ft
, fs
, cc
);
11123 check_cp1_registers(ctx
, fs
| ft
| fd
);
11125 TCGv_i64 fp0
= tcg_temp_new_i64();
11126 TCGv_i64 fp1
= tcg_temp_new_i64();
11128 gen_load_fpr64(ctx
, fp0
, fs
);
11129 gen_load_fpr64(ctx
, fp1
, ft
);
11130 gen_helper_float_add_d(fp0
, cpu_env
, fp0
, fp1
);
11131 tcg_temp_free_i64(fp1
);
11132 gen_store_fpr64(ctx
, fp0
, fd
);
11133 tcg_temp_free_i64(fp0
);
11137 check_cp1_registers(ctx
, fs
| ft
| fd
);
11139 TCGv_i64 fp0
= tcg_temp_new_i64();
11140 TCGv_i64 fp1
= tcg_temp_new_i64();
11142 gen_load_fpr64(ctx
, fp0
, fs
);
11143 gen_load_fpr64(ctx
, fp1
, ft
);
11144 gen_helper_float_sub_d(fp0
, cpu_env
, fp0
, fp1
);
11145 tcg_temp_free_i64(fp1
);
11146 gen_store_fpr64(ctx
, fp0
, fd
);
11147 tcg_temp_free_i64(fp0
);
11151 check_cp1_registers(ctx
, fs
| ft
| fd
);
11153 TCGv_i64 fp0
= tcg_temp_new_i64();
11154 TCGv_i64 fp1
= tcg_temp_new_i64();
11156 gen_load_fpr64(ctx
, fp0
, fs
);
11157 gen_load_fpr64(ctx
, fp1
, ft
);
11158 gen_helper_float_mul_d(fp0
, cpu_env
, fp0
, fp1
);
11159 tcg_temp_free_i64(fp1
);
11160 gen_store_fpr64(ctx
, fp0
, fd
);
11161 tcg_temp_free_i64(fp0
);
11165 check_cp1_registers(ctx
, fs
| ft
| fd
);
11167 TCGv_i64 fp0
= tcg_temp_new_i64();
11168 TCGv_i64 fp1
= tcg_temp_new_i64();
11170 gen_load_fpr64(ctx
, fp0
, fs
);
11171 gen_load_fpr64(ctx
, fp1
, ft
);
11172 gen_helper_float_div_d(fp0
, cpu_env
, fp0
, fp1
);
11173 tcg_temp_free_i64(fp1
);
11174 gen_store_fpr64(ctx
, fp0
, fd
);
11175 tcg_temp_free_i64(fp0
);
11179 check_cp1_registers(ctx
, fs
| fd
);
11181 TCGv_i64 fp0
= tcg_temp_new_i64();
11183 gen_load_fpr64(ctx
, fp0
, fs
);
11184 gen_helper_float_sqrt_d(fp0
, cpu_env
, fp0
);
11185 gen_store_fpr64(ctx
, fp0
, fd
);
11186 tcg_temp_free_i64(fp0
);
11190 check_cp1_registers(ctx
, fs
| fd
);
11192 TCGv_i64 fp0
= tcg_temp_new_i64();
11194 gen_load_fpr64(ctx
, fp0
, fs
);
11195 if (ctx
->abs2008
) {
11196 tcg_gen_andi_i64(fp0
, fp0
, 0x7fffffffffffffffULL
);
11198 gen_helper_float_abs_d(fp0
, fp0
);
11200 gen_store_fpr64(ctx
, fp0
, fd
);
11201 tcg_temp_free_i64(fp0
);
11205 check_cp1_registers(ctx
, fs
| fd
);
11207 TCGv_i64 fp0
= tcg_temp_new_i64();
11209 gen_load_fpr64(ctx
, fp0
, fs
);
11210 gen_store_fpr64(ctx
, fp0
, fd
);
11211 tcg_temp_free_i64(fp0
);
11215 check_cp1_registers(ctx
, fs
| fd
);
11217 TCGv_i64 fp0
= tcg_temp_new_i64();
11219 gen_load_fpr64(ctx
, fp0
, fs
);
11220 if (ctx
->abs2008
) {
11221 tcg_gen_xori_i64(fp0
, fp0
, 1ULL << 63);
11223 gen_helper_float_chs_d(fp0
, fp0
);
11225 gen_store_fpr64(ctx
, fp0
, fd
);
11226 tcg_temp_free_i64(fp0
);
11229 case OPC_ROUND_L_D
:
11230 check_cp1_64bitmode(ctx
);
11232 TCGv_i64 fp0
= tcg_temp_new_i64();
11234 gen_load_fpr64(ctx
, fp0
, fs
);
11235 if (ctx
->nan2008
) {
11236 gen_helper_float_round_2008_l_d(fp0
, cpu_env
, fp0
);
11238 gen_helper_float_round_l_d(fp0
, cpu_env
, fp0
);
11240 gen_store_fpr64(ctx
, fp0
, fd
);
11241 tcg_temp_free_i64(fp0
);
11244 case OPC_TRUNC_L_D
:
11245 check_cp1_64bitmode(ctx
);
11247 TCGv_i64 fp0
= tcg_temp_new_i64();
11249 gen_load_fpr64(ctx
, fp0
, fs
);
11250 if (ctx
->nan2008
) {
11251 gen_helper_float_trunc_2008_l_d(fp0
, cpu_env
, fp0
);
11253 gen_helper_float_trunc_l_d(fp0
, cpu_env
, fp0
);
11255 gen_store_fpr64(ctx
, fp0
, fd
);
11256 tcg_temp_free_i64(fp0
);
11260 check_cp1_64bitmode(ctx
);
11262 TCGv_i64 fp0
= tcg_temp_new_i64();
11264 gen_load_fpr64(ctx
, fp0
, fs
);
11265 if (ctx
->nan2008
) {
11266 gen_helper_float_ceil_2008_l_d(fp0
, cpu_env
, fp0
);
11268 gen_helper_float_ceil_l_d(fp0
, cpu_env
, fp0
);
11270 gen_store_fpr64(ctx
, fp0
, fd
);
11271 tcg_temp_free_i64(fp0
);
11274 case OPC_FLOOR_L_D
:
11275 check_cp1_64bitmode(ctx
);
11277 TCGv_i64 fp0
= tcg_temp_new_i64();
11279 gen_load_fpr64(ctx
, fp0
, fs
);
11280 if (ctx
->nan2008
) {
11281 gen_helper_float_floor_2008_l_d(fp0
, cpu_env
, fp0
);
11283 gen_helper_float_floor_l_d(fp0
, cpu_env
, fp0
);
11285 gen_store_fpr64(ctx
, fp0
, fd
);
11286 tcg_temp_free_i64(fp0
);
11289 case OPC_ROUND_W_D
:
11290 check_cp1_registers(ctx
, fs
);
11292 TCGv_i32 fp32
= tcg_temp_new_i32();
11293 TCGv_i64 fp64
= tcg_temp_new_i64();
11295 gen_load_fpr64(ctx
, fp64
, fs
);
11296 if (ctx
->nan2008
) {
11297 gen_helper_float_round_2008_w_d(fp32
, cpu_env
, fp64
);
11299 gen_helper_float_round_w_d(fp32
, cpu_env
, fp64
);
11301 tcg_temp_free_i64(fp64
);
11302 gen_store_fpr32(ctx
, fp32
, fd
);
11303 tcg_temp_free_i32(fp32
);
11306 case OPC_TRUNC_W_D
:
11307 check_cp1_registers(ctx
, fs
);
11309 TCGv_i32 fp32
= tcg_temp_new_i32();
11310 TCGv_i64 fp64
= tcg_temp_new_i64();
11312 gen_load_fpr64(ctx
, fp64
, fs
);
11313 if (ctx
->nan2008
) {
11314 gen_helper_float_trunc_2008_w_d(fp32
, cpu_env
, fp64
);
11316 gen_helper_float_trunc_w_d(fp32
, cpu_env
, fp64
);
11318 tcg_temp_free_i64(fp64
);
11319 gen_store_fpr32(ctx
, fp32
, fd
);
11320 tcg_temp_free_i32(fp32
);
11324 check_cp1_registers(ctx
, fs
);
11326 TCGv_i32 fp32
= tcg_temp_new_i32();
11327 TCGv_i64 fp64
= tcg_temp_new_i64();
11329 gen_load_fpr64(ctx
, fp64
, fs
);
11330 if (ctx
->nan2008
) {
11331 gen_helper_float_ceil_2008_w_d(fp32
, cpu_env
, fp64
);
11333 gen_helper_float_ceil_w_d(fp32
, cpu_env
, fp64
);
11335 tcg_temp_free_i64(fp64
);
11336 gen_store_fpr32(ctx
, fp32
, fd
);
11337 tcg_temp_free_i32(fp32
);
11340 case OPC_FLOOR_W_D
:
11341 check_cp1_registers(ctx
, fs
);
11343 TCGv_i32 fp32
= tcg_temp_new_i32();
11344 TCGv_i64 fp64
= tcg_temp_new_i64();
11346 gen_load_fpr64(ctx
, fp64
, fs
);
11347 if (ctx
->nan2008
) {
11348 gen_helper_float_floor_2008_w_d(fp32
, cpu_env
, fp64
);
11350 gen_helper_float_floor_w_d(fp32
, cpu_env
, fp64
);
11352 tcg_temp_free_i64(fp64
);
11353 gen_store_fpr32(ctx
, fp32
, fd
);
11354 tcg_temp_free_i32(fp32
);
11358 check_insn(ctx
, ISA_MIPS_R6
);
11359 gen_sel_d(ctx
, op1
, fd
, ft
, fs
);
11362 check_insn(ctx
, ISA_MIPS_R6
);
11363 gen_sel_d(ctx
, op1
, fd
, ft
, fs
);
11366 check_insn(ctx
, ISA_MIPS_R6
);
11367 gen_sel_d(ctx
, op1
, fd
, ft
, fs
);
11370 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
11371 gen_movcf_d(ctx
, fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
11374 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
11376 TCGLabel
*l1
= gen_new_label();
11380 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
11382 fp0
= tcg_temp_new_i64();
11383 gen_load_fpr64(ctx
, fp0
, fs
);
11384 gen_store_fpr64(ctx
, fp0
, fd
);
11385 tcg_temp_free_i64(fp0
);
11390 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
11392 TCGLabel
*l1
= gen_new_label();
11396 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
11397 fp0
= tcg_temp_new_i64();
11398 gen_load_fpr64(ctx
, fp0
, fs
);
11399 gen_store_fpr64(ctx
, fp0
, fd
);
11400 tcg_temp_free_i64(fp0
);
11406 check_cp1_registers(ctx
, fs
| fd
);
11408 TCGv_i64 fp0
= tcg_temp_new_i64();
11410 gen_load_fpr64(ctx
, fp0
, fs
);
11411 gen_helper_float_recip_d(fp0
, cpu_env
, fp0
);
11412 gen_store_fpr64(ctx
, fp0
, fd
);
11413 tcg_temp_free_i64(fp0
);
11417 check_cp1_registers(ctx
, fs
| fd
);
11419 TCGv_i64 fp0
= tcg_temp_new_i64();
11421 gen_load_fpr64(ctx
, fp0
, fs
);
11422 gen_helper_float_rsqrt_d(fp0
, cpu_env
, fp0
);
11423 gen_store_fpr64(ctx
, fp0
, fd
);
11424 tcg_temp_free_i64(fp0
);
11428 check_insn(ctx
, ISA_MIPS_R6
);
11430 TCGv_i64 fp0
= tcg_temp_new_i64();
11431 TCGv_i64 fp1
= tcg_temp_new_i64();
11432 TCGv_i64 fp2
= tcg_temp_new_i64();
11433 gen_load_fpr64(ctx
, fp0
, fs
);
11434 gen_load_fpr64(ctx
, fp1
, ft
);
11435 gen_load_fpr64(ctx
, fp2
, fd
);
11436 gen_helper_float_maddf_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
11437 gen_store_fpr64(ctx
, fp2
, fd
);
11438 tcg_temp_free_i64(fp2
);
11439 tcg_temp_free_i64(fp1
);
11440 tcg_temp_free_i64(fp0
);
11444 check_insn(ctx
, ISA_MIPS_R6
);
11446 TCGv_i64 fp0
= tcg_temp_new_i64();
11447 TCGv_i64 fp1
= tcg_temp_new_i64();
11448 TCGv_i64 fp2
= tcg_temp_new_i64();
11449 gen_load_fpr64(ctx
, fp0
, fs
);
11450 gen_load_fpr64(ctx
, fp1
, ft
);
11451 gen_load_fpr64(ctx
, fp2
, fd
);
11452 gen_helper_float_msubf_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
11453 gen_store_fpr64(ctx
, fp2
, fd
);
11454 tcg_temp_free_i64(fp2
);
11455 tcg_temp_free_i64(fp1
);
11456 tcg_temp_free_i64(fp0
);
11460 check_insn(ctx
, ISA_MIPS_R6
);
11462 TCGv_i64 fp0
= tcg_temp_new_i64();
11463 gen_load_fpr64(ctx
, fp0
, fs
);
11464 gen_helper_float_rint_d(fp0
, cpu_env
, fp0
);
11465 gen_store_fpr64(ctx
, fp0
, fd
);
11466 tcg_temp_free_i64(fp0
);
11470 check_insn(ctx
, ISA_MIPS_R6
);
11472 TCGv_i64 fp0
= tcg_temp_new_i64();
11473 gen_load_fpr64(ctx
, fp0
, fs
);
11474 gen_helper_float_class_d(fp0
, cpu_env
, fp0
);
11475 gen_store_fpr64(ctx
, fp0
, fd
);
11476 tcg_temp_free_i64(fp0
);
11479 case OPC_MIN_D
: /* OPC_RECIP2_D */
11480 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
11482 TCGv_i64 fp0
= tcg_temp_new_i64();
11483 TCGv_i64 fp1
= tcg_temp_new_i64();
11484 gen_load_fpr64(ctx
, fp0
, fs
);
11485 gen_load_fpr64(ctx
, fp1
, ft
);
11486 gen_helper_float_min_d(fp1
, cpu_env
, fp0
, fp1
);
11487 gen_store_fpr64(ctx
, fp1
, fd
);
11488 tcg_temp_free_i64(fp1
);
11489 tcg_temp_free_i64(fp0
);
11492 check_cp1_64bitmode(ctx
);
11494 TCGv_i64 fp0
= tcg_temp_new_i64();
11495 TCGv_i64 fp1
= tcg_temp_new_i64();
11497 gen_load_fpr64(ctx
, fp0
, fs
);
11498 gen_load_fpr64(ctx
, fp1
, ft
);
11499 gen_helper_float_recip2_d(fp0
, cpu_env
, fp0
, fp1
);
11500 tcg_temp_free_i64(fp1
);
11501 gen_store_fpr64(ctx
, fp0
, fd
);
11502 tcg_temp_free_i64(fp0
);
11506 case OPC_MINA_D
: /* OPC_RECIP1_D */
11507 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
11509 TCGv_i64 fp0
= tcg_temp_new_i64();
11510 TCGv_i64 fp1
= tcg_temp_new_i64();
11511 gen_load_fpr64(ctx
, fp0
, fs
);
11512 gen_load_fpr64(ctx
, fp1
, ft
);
11513 gen_helper_float_mina_d(fp1
, cpu_env
, fp0
, fp1
);
11514 gen_store_fpr64(ctx
, fp1
, fd
);
11515 tcg_temp_free_i64(fp1
);
11516 tcg_temp_free_i64(fp0
);
11519 check_cp1_64bitmode(ctx
);
11521 TCGv_i64 fp0
= tcg_temp_new_i64();
11523 gen_load_fpr64(ctx
, fp0
, fs
);
11524 gen_helper_float_recip1_d(fp0
, cpu_env
, fp0
);
11525 gen_store_fpr64(ctx
, fp0
, fd
);
11526 tcg_temp_free_i64(fp0
);
11530 case OPC_MAX_D
: /* OPC_RSQRT1_D */
11531 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
11533 TCGv_i64 fp0
= tcg_temp_new_i64();
11534 TCGv_i64 fp1
= tcg_temp_new_i64();
11535 gen_load_fpr64(ctx
, fp0
, fs
);
11536 gen_load_fpr64(ctx
, fp1
, ft
);
11537 gen_helper_float_max_d(fp1
, cpu_env
, fp0
, fp1
);
11538 gen_store_fpr64(ctx
, fp1
, fd
);
11539 tcg_temp_free_i64(fp1
);
11540 tcg_temp_free_i64(fp0
);
11543 check_cp1_64bitmode(ctx
);
11545 TCGv_i64 fp0
= tcg_temp_new_i64();
11547 gen_load_fpr64(ctx
, fp0
, fs
);
11548 gen_helper_float_rsqrt1_d(fp0
, cpu_env
, fp0
);
11549 gen_store_fpr64(ctx
, fp0
, fd
);
11550 tcg_temp_free_i64(fp0
);
11554 case OPC_MAXA_D
: /* OPC_RSQRT2_D */
11555 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
11557 TCGv_i64 fp0
= tcg_temp_new_i64();
11558 TCGv_i64 fp1
= tcg_temp_new_i64();
11559 gen_load_fpr64(ctx
, fp0
, fs
);
11560 gen_load_fpr64(ctx
, fp1
, ft
);
11561 gen_helper_float_maxa_d(fp1
, cpu_env
, fp0
, fp1
);
11562 gen_store_fpr64(ctx
, fp1
, fd
);
11563 tcg_temp_free_i64(fp1
);
11564 tcg_temp_free_i64(fp0
);
11567 check_cp1_64bitmode(ctx
);
11569 TCGv_i64 fp0
= tcg_temp_new_i64();
11570 TCGv_i64 fp1
= tcg_temp_new_i64();
11572 gen_load_fpr64(ctx
, fp0
, fs
);
11573 gen_load_fpr64(ctx
, fp1
, ft
);
11574 gen_helper_float_rsqrt2_d(fp0
, cpu_env
, fp0
, fp1
);
11575 tcg_temp_free_i64(fp1
);
11576 gen_store_fpr64(ctx
, fp0
, fd
);
11577 tcg_temp_free_i64(fp0
);
11584 case OPC_CMP_UEQ_D
:
11585 case OPC_CMP_OLT_D
:
11586 case OPC_CMP_ULT_D
:
11587 case OPC_CMP_OLE_D
:
11588 case OPC_CMP_ULE_D
:
11590 case OPC_CMP_NGLE_D
:
11591 case OPC_CMP_SEQ_D
:
11592 case OPC_CMP_NGL_D
:
11594 case OPC_CMP_NGE_D
:
11596 case OPC_CMP_NGT_D
:
11597 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
11598 if (ctx
->opcode
& (1 << 6)) {
11599 gen_cmpabs_d(ctx
, func
- 48, ft
, fs
, cc
);
11601 gen_cmp_d(ctx
, func
- 48, ft
, fs
, cc
);
11605 check_cp1_registers(ctx
, fs
);
11607 TCGv_i32 fp32
= tcg_temp_new_i32();
11608 TCGv_i64 fp64
= tcg_temp_new_i64();
11610 gen_load_fpr64(ctx
, fp64
, fs
);
11611 gen_helper_float_cvts_d(fp32
, cpu_env
, fp64
);
11612 tcg_temp_free_i64(fp64
);
11613 gen_store_fpr32(ctx
, fp32
, fd
);
11614 tcg_temp_free_i32(fp32
);
11618 check_cp1_registers(ctx
, fs
);
11620 TCGv_i32 fp32
= tcg_temp_new_i32();
11621 TCGv_i64 fp64
= tcg_temp_new_i64();
11623 gen_load_fpr64(ctx
, fp64
, fs
);
11624 if (ctx
->nan2008
) {
11625 gen_helper_float_cvt_2008_w_d(fp32
, cpu_env
, fp64
);
11627 gen_helper_float_cvt_w_d(fp32
, cpu_env
, fp64
);
11629 tcg_temp_free_i64(fp64
);
11630 gen_store_fpr32(ctx
, fp32
, fd
);
11631 tcg_temp_free_i32(fp32
);
11635 check_cp1_64bitmode(ctx
);
11637 TCGv_i64 fp0
= tcg_temp_new_i64();
11639 gen_load_fpr64(ctx
, fp0
, fs
);
11640 if (ctx
->nan2008
) {
11641 gen_helper_float_cvt_2008_l_d(fp0
, cpu_env
, fp0
);
11643 gen_helper_float_cvt_l_d(fp0
, cpu_env
, fp0
);
11645 gen_store_fpr64(ctx
, fp0
, fd
);
11646 tcg_temp_free_i64(fp0
);
11651 TCGv_i32 fp0
= tcg_temp_new_i32();
11653 gen_load_fpr32(ctx
, fp0
, fs
);
11654 gen_helper_float_cvts_w(fp0
, cpu_env
, fp0
);
11655 gen_store_fpr32(ctx
, fp0
, fd
);
11656 tcg_temp_free_i32(fp0
);
11660 check_cp1_registers(ctx
, fd
);
11662 TCGv_i32 fp32
= tcg_temp_new_i32();
11663 TCGv_i64 fp64
= tcg_temp_new_i64();
11665 gen_load_fpr32(ctx
, fp32
, fs
);
11666 gen_helper_float_cvtd_w(fp64
, cpu_env
, fp32
);
11667 tcg_temp_free_i32(fp32
);
11668 gen_store_fpr64(ctx
, fp64
, fd
);
11669 tcg_temp_free_i64(fp64
);
11673 check_cp1_64bitmode(ctx
);
11675 TCGv_i32 fp32
= tcg_temp_new_i32();
11676 TCGv_i64 fp64
= tcg_temp_new_i64();
11678 gen_load_fpr64(ctx
, fp64
, fs
);
11679 gen_helper_float_cvts_l(fp32
, cpu_env
, fp64
);
11680 tcg_temp_free_i64(fp64
);
11681 gen_store_fpr32(ctx
, fp32
, fd
);
11682 tcg_temp_free_i32(fp32
);
11686 check_cp1_64bitmode(ctx
);
11688 TCGv_i64 fp0
= tcg_temp_new_i64();
11690 gen_load_fpr64(ctx
, fp0
, fs
);
11691 gen_helper_float_cvtd_l(fp0
, cpu_env
, fp0
);
11692 gen_store_fpr64(ctx
, fp0
, fd
);
11693 tcg_temp_free_i64(fp0
);
11696 case OPC_CVT_PS_PW
:
11699 TCGv_i64 fp0
= tcg_temp_new_i64();
11701 gen_load_fpr64(ctx
, fp0
, fs
);
11702 gen_helper_float_cvtps_pw(fp0
, cpu_env
, fp0
);
11703 gen_store_fpr64(ctx
, fp0
, fd
);
11704 tcg_temp_free_i64(fp0
);
11710 TCGv_i64 fp0
= tcg_temp_new_i64();
11711 TCGv_i64 fp1
= tcg_temp_new_i64();
11713 gen_load_fpr64(ctx
, fp0
, fs
);
11714 gen_load_fpr64(ctx
, fp1
, ft
);
11715 gen_helper_float_add_ps(fp0
, cpu_env
, fp0
, fp1
);
11716 tcg_temp_free_i64(fp1
);
11717 gen_store_fpr64(ctx
, fp0
, fd
);
11718 tcg_temp_free_i64(fp0
);
11724 TCGv_i64 fp0
= tcg_temp_new_i64();
11725 TCGv_i64 fp1
= tcg_temp_new_i64();
11727 gen_load_fpr64(ctx
, fp0
, fs
);
11728 gen_load_fpr64(ctx
, fp1
, ft
);
11729 gen_helper_float_sub_ps(fp0
, cpu_env
, fp0
, fp1
);
11730 tcg_temp_free_i64(fp1
);
11731 gen_store_fpr64(ctx
, fp0
, fd
);
11732 tcg_temp_free_i64(fp0
);
11738 TCGv_i64 fp0
= tcg_temp_new_i64();
11739 TCGv_i64 fp1
= tcg_temp_new_i64();
11741 gen_load_fpr64(ctx
, fp0
, fs
);
11742 gen_load_fpr64(ctx
, fp1
, ft
);
11743 gen_helper_float_mul_ps(fp0
, cpu_env
, fp0
, fp1
);
11744 tcg_temp_free_i64(fp1
);
11745 gen_store_fpr64(ctx
, fp0
, fd
);
11746 tcg_temp_free_i64(fp0
);
11752 TCGv_i64 fp0
= tcg_temp_new_i64();
11754 gen_load_fpr64(ctx
, fp0
, fs
);
11755 gen_helper_float_abs_ps(fp0
, fp0
);
11756 gen_store_fpr64(ctx
, fp0
, fd
);
11757 tcg_temp_free_i64(fp0
);
11763 TCGv_i64 fp0
= tcg_temp_new_i64();
11765 gen_load_fpr64(ctx
, fp0
, fs
);
11766 gen_store_fpr64(ctx
, fp0
, fd
);
11767 tcg_temp_free_i64(fp0
);
11773 TCGv_i64 fp0
= tcg_temp_new_i64();
11775 gen_load_fpr64(ctx
, fp0
, fs
);
11776 gen_helper_float_chs_ps(fp0
, fp0
);
11777 gen_store_fpr64(ctx
, fp0
, fd
);
11778 tcg_temp_free_i64(fp0
);
11783 gen_movcf_ps(ctx
, fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
11788 TCGLabel
*l1
= gen_new_label();
11792 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
11794 fp0
= tcg_temp_new_i64();
11795 gen_load_fpr64(ctx
, fp0
, fs
);
11796 gen_store_fpr64(ctx
, fp0
, fd
);
11797 tcg_temp_free_i64(fp0
);
11804 TCGLabel
*l1
= gen_new_label();
11808 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
11809 fp0
= tcg_temp_new_i64();
11810 gen_load_fpr64(ctx
, fp0
, fs
);
11811 gen_store_fpr64(ctx
, fp0
, fd
);
11812 tcg_temp_free_i64(fp0
);
11820 TCGv_i64 fp0
= tcg_temp_new_i64();
11821 TCGv_i64 fp1
= tcg_temp_new_i64();
11823 gen_load_fpr64(ctx
, fp0
, ft
);
11824 gen_load_fpr64(ctx
, fp1
, fs
);
11825 gen_helper_float_addr_ps(fp0
, cpu_env
, fp0
, fp1
);
11826 tcg_temp_free_i64(fp1
);
11827 gen_store_fpr64(ctx
, fp0
, fd
);
11828 tcg_temp_free_i64(fp0
);
11834 TCGv_i64 fp0
= tcg_temp_new_i64();
11835 TCGv_i64 fp1
= tcg_temp_new_i64();
11837 gen_load_fpr64(ctx
, fp0
, ft
);
11838 gen_load_fpr64(ctx
, fp1
, fs
);
11839 gen_helper_float_mulr_ps(fp0
, cpu_env
, fp0
, fp1
);
11840 tcg_temp_free_i64(fp1
);
11841 gen_store_fpr64(ctx
, fp0
, fd
);
11842 tcg_temp_free_i64(fp0
);
11845 case OPC_RECIP2_PS
:
11848 TCGv_i64 fp0
= tcg_temp_new_i64();
11849 TCGv_i64 fp1
= tcg_temp_new_i64();
11851 gen_load_fpr64(ctx
, fp0
, fs
);
11852 gen_load_fpr64(ctx
, fp1
, ft
);
11853 gen_helper_float_recip2_ps(fp0
, cpu_env
, fp0
, fp1
);
11854 tcg_temp_free_i64(fp1
);
11855 gen_store_fpr64(ctx
, fp0
, fd
);
11856 tcg_temp_free_i64(fp0
);
11859 case OPC_RECIP1_PS
:
11862 TCGv_i64 fp0
= tcg_temp_new_i64();
11864 gen_load_fpr64(ctx
, fp0
, fs
);
11865 gen_helper_float_recip1_ps(fp0
, cpu_env
, fp0
);
11866 gen_store_fpr64(ctx
, fp0
, fd
);
11867 tcg_temp_free_i64(fp0
);
11870 case OPC_RSQRT1_PS
:
11873 TCGv_i64 fp0
= tcg_temp_new_i64();
11875 gen_load_fpr64(ctx
, fp0
, fs
);
11876 gen_helper_float_rsqrt1_ps(fp0
, cpu_env
, fp0
);
11877 gen_store_fpr64(ctx
, fp0
, fd
);
11878 tcg_temp_free_i64(fp0
);
11881 case OPC_RSQRT2_PS
:
11884 TCGv_i64 fp0
= tcg_temp_new_i64();
11885 TCGv_i64 fp1
= tcg_temp_new_i64();
11887 gen_load_fpr64(ctx
, fp0
, fs
);
11888 gen_load_fpr64(ctx
, fp1
, ft
);
11889 gen_helper_float_rsqrt2_ps(fp0
, cpu_env
, fp0
, fp1
);
11890 tcg_temp_free_i64(fp1
);
11891 gen_store_fpr64(ctx
, fp0
, fd
);
11892 tcg_temp_free_i64(fp0
);
11896 check_cp1_64bitmode(ctx
);
11898 TCGv_i32 fp0
= tcg_temp_new_i32();
11900 gen_load_fpr32h(ctx
, fp0
, fs
);
11901 gen_helper_float_cvts_pu(fp0
, cpu_env
, fp0
);
11902 gen_store_fpr32(ctx
, fp0
, fd
);
11903 tcg_temp_free_i32(fp0
);
11906 case OPC_CVT_PW_PS
:
11909 TCGv_i64 fp0
= tcg_temp_new_i64();
11911 gen_load_fpr64(ctx
, fp0
, fs
);
11912 gen_helper_float_cvtpw_ps(fp0
, cpu_env
, fp0
);
11913 gen_store_fpr64(ctx
, fp0
, fd
);
11914 tcg_temp_free_i64(fp0
);
11918 check_cp1_64bitmode(ctx
);
11920 TCGv_i32 fp0
= tcg_temp_new_i32();
11922 gen_load_fpr32(ctx
, fp0
, fs
);
11923 gen_helper_float_cvts_pl(fp0
, cpu_env
, fp0
);
11924 gen_store_fpr32(ctx
, fp0
, fd
);
11925 tcg_temp_free_i32(fp0
);
11931 TCGv_i32 fp0
= tcg_temp_new_i32();
11932 TCGv_i32 fp1
= tcg_temp_new_i32();
11934 gen_load_fpr32(ctx
, fp0
, fs
);
11935 gen_load_fpr32(ctx
, fp1
, ft
);
11936 gen_store_fpr32h(ctx
, fp0
, fd
);
11937 gen_store_fpr32(ctx
, fp1
, fd
);
11938 tcg_temp_free_i32(fp0
);
11939 tcg_temp_free_i32(fp1
);
11945 TCGv_i32 fp0
= tcg_temp_new_i32();
11946 TCGv_i32 fp1
= tcg_temp_new_i32();
11948 gen_load_fpr32(ctx
, fp0
, fs
);
11949 gen_load_fpr32h(ctx
, fp1
, ft
);
11950 gen_store_fpr32(ctx
, fp1
, fd
);
11951 gen_store_fpr32h(ctx
, fp0
, fd
);
11952 tcg_temp_free_i32(fp0
);
11953 tcg_temp_free_i32(fp1
);
11959 TCGv_i32 fp0
= tcg_temp_new_i32();
11960 TCGv_i32 fp1
= tcg_temp_new_i32();
11962 gen_load_fpr32h(ctx
, fp0
, fs
);
11963 gen_load_fpr32(ctx
, fp1
, ft
);
11964 gen_store_fpr32(ctx
, fp1
, fd
);
11965 gen_store_fpr32h(ctx
, fp0
, fd
);
11966 tcg_temp_free_i32(fp0
);
11967 tcg_temp_free_i32(fp1
);
11973 TCGv_i32 fp0
= tcg_temp_new_i32();
11974 TCGv_i32 fp1
= tcg_temp_new_i32();
11976 gen_load_fpr32h(ctx
, fp0
, fs
);
11977 gen_load_fpr32h(ctx
, fp1
, ft
);
11978 gen_store_fpr32(ctx
, fp1
, fd
);
11979 gen_store_fpr32h(ctx
, fp0
, fd
);
11980 tcg_temp_free_i32(fp0
);
11981 tcg_temp_free_i32(fp1
);
11985 case OPC_CMP_UN_PS
:
11986 case OPC_CMP_EQ_PS
:
11987 case OPC_CMP_UEQ_PS
:
11988 case OPC_CMP_OLT_PS
:
11989 case OPC_CMP_ULT_PS
:
11990 case OPC_CMP_OLE_PS
:
11991 case OPC_CMP_ULE_PS
:
11992 case OPC_CMP_SF_PS
:
11993 case OPC_CMP_NGLE_PS
:
11994 case OPC_CMP_SEQ_PS
:
11995 case OPC_CMP_NGL_PS
:
11996 case OPC_CMP_LT_PS
:
11997 case OPC_CMP_NGE_PS
:
11998 case OPC_CMP_LE_PS
:
11999 case OPC_CMP_NGT_PS
:
12000 if (ctx
->opcode
& (1 << 6)) {
12001 gen_cmpabs_ps(ctx
, func
- 48, ft
, fs
, cc
);
12003 gen_cmp_ps(ctx
, func
- 48, ft
, fs
, cc
);
12007 MIPS_INVAL("farith");
12008 gen_reserved_instruction(ctx
);
12013 /* Coprocessor 3 (FPU) */
12014 static void gen_flt3_ldst(DisasContext
*ctx
, uint32_t opc
,
12015 int fd
, int fs
, int base
, int index
)
12017 TCGv t0
= tcg_temp_new();
12020 gen_load_gpr(t0
, index
);
12021 } else if (index
== 0) {
12022 gen_load_gpr(t0
, base
);
12024 gen_op_addr_add(ctx
, t0
, cpu_gpr
[base
], cpu_gpr
[index
]);
12027 * Don't do NOP if destination is zero: we must perform the actual
12034 TCGv_i32 fp0
= tcg_temp_new_i32();
12036 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESL
);
12037 tcg_gen_trunc_tl_i32(fp0
, t0
);
12038 gen_store_fpr32(ctx
, fp0
, fd
);
12039 tcg_temp_free_i32(fp0
);
12044 check_cp1_registers(ctx
, fd
);
12046 TCGv_i64 fp0
= tcg_temp_new_i64();
12047 tcg_gen_qemu_ld_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
12048 gen_store_fpr64(ctx
, fp0
, fd
);
12049 tcg_temp_free_i64(fp0
);
12053 check_cp1_64bitmode(ctx
);
12054 tcg_gen_andi_tl(t0
, t0
, ~0x7);
12056 TCGv_i64 fp0
= tcg_temp_new_i64();
12058 tcg_gen_qemu_ld_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
12059 gen_store_fpr64(ctx
, fp0
, fd
);
12060 tcg_temp_free_i64(fp0
);
12066 TCGv_i32 fp0
= tcg_temp_new_i32();
12067 gen_load_fpr32(ctx
, fp0
, fs
);
12068 tcg_gen_qemu_st_i32(fp0
, t0
, ctx
->mem_idx
, MO_TEUL
);
12069 tcg_temp_free_i32(fp0
);
12074 check_cp1_registers(ctx
, fs
);
12076 TCGv_i64 fp0
= tcg_temp_new_i64();
12077 gen_load_fpr64(ctx
, fp0
, fs
);
12078 tcg_gen_qemu_st_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
12079 tcg_temp_free_i64(fp0
);
12083 check_cp1_64bitmode(ctx
);
12084 tcg_gen_andi_tl(t0
, t0
, ~0x7);
12086 TCGv_i64 fp0
= tcg_temp_new_i64();
12087 gen_load_fpr64(ctx
, fp0
, fs
);
12088 tcg_gen_qemu_st_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
12089 tcg_temp_free_i64(fp0
);
12096 static void gen_flt3_arith(DisasContext
*ctx
, uint32_t opc
,
12097 int fd
, int fr
, int fs
, int ft
)
12103 TCGv t0
= tcg_temp_local_new();
12104 TCGv_i32 fp
= tcg_temp_new_i32();
12105 TCGv_i32 fph
= tcg_temp_new_i32();
12106 TCGLabel
*l1
= gen_new_label();
12107 TCGLabel
*l2
= gen_new_label();
12109 gen_load_gpr(t0
, fr
);
12110 tcg_gen_andi_tl(t0
, t0
, 0x7);
12112 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, 0, l1
);
12113 gen_load_fpr32(ctx
, fp
, fs
);
12114 gen_load_fpr32h(ctx
, fph
, fs
);
12115 gen_store_fpr32(ctx
, fp
, fd
);
12116 gen_store_fpr32h(ctx
, fph
, fd
);
12119 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, 4, l2
);
12121 #ifdef TARGET_WORDS_BIGENDIAN
12122 gen_load_fpr32(ctx
, fp
, fs
);
12123 gen_load_fpr32h(ctx
, fph
, ft
);
12124 gen_store_fpr32h(ctx
, fp
, fd
);
12125 gen_store_fpr32(ctx
, fph
, fd
);
12127 gen_load_fpr32h(ctx
, fph
, fs
);
12128 gen_load_fpr32(ctx
, fp
, ft
);
12129 gen_store_fpr32(ctx
, fph
, fd
);
12130 gen_store_fpr32h(ctx
, fp
, fd
);
12133 tcg_temp_free_i32(fp
);
12134 tcg_temp_free_i32(fph
);
12140 TCGv_i32 fp0
= tcg_temp_new_i32();
12141 TCGv_i32 fp1
= tcg_temp_new_i32();
12142 TCGv_i32 fp2
= tcg_temp_new_i32();
12144 gen_load_fpr32(ctx
, fp0
, fs
);
12145 gen_load_fpr32(ctx
, fp1
, ft
);
12146 gen_load_fpr32(ctx
, fp2
, fr
);
12147 gen_helper_float_madd_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12148 tcg_temp_free_i32(fp0
);
12149 tcg_temp_free_i32(fp1
);
12150 gen_store_fpr32(ctx
, fp2
, fd
);
12151 tcg_temp_free_i32(fp2
);
12156 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
12158 TCGv_i64 fp0
= tcg_temp_new_i64();
12159 TCGv_i64 fp1
= tcg_temp_new_i64();
12160 TCGv_i64 fp2
= tcg_temp_new_i64();
12162 gen_load_fpr64(ctx
, fp0
, fs
);
12163 gen_load_fpr64(ctx
, fp1
, ft
);
12164 gen_load_fpr64(ctx
, fp2
, fr
);
12165 gen_helper_float_madd_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12166 tcg_temp_free_i64(fp0
);
12167 tcg_temp_free_i64(fp1
);
12168 gen_store_fpr64(ctx
, fp2
, fd
);
12169 tcg_temp_free_i64(fp2
);
12175 TCGv_i64 fp0
= tcg_temp_new_i64();
12176 TCGv_i64 fp1
= tcg_temp_new_i64();
12177 TCGv_i64 fp2
= tcg_temp_new_i64();
12179 gen_load_fpr64(ctx
, fp0
, fs
);
12180 gen_load_fpr64(ctx
, fp1
, ft
);
12181 gen_load_fpr64(ctx
, fp2
, fr
);
12182 gen_helper_float_madd_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12183 tcg_temp_free_i64(fp0
);
12184 tcg_temp_free_i64(fp1
);
12185 gen_store_fpr64(ctx
, fp2
, fd
);
12186 tcg_temp_free_i64(fp2
);
12192 TCGv_i32 fp0
= tcg_temp_new_i32();
12193 TCGv_i32 fp1
= tcg_temp_new_i32();
12194 TCGv_i32 fp2
= tcg_temp_new_i32();
12196 gen_load_fpr32(ctx
, fp0
, fs
);
12197 gen_load_fpr32(ctx
, fp1
, ft
);
12198 gen_load_fpr32(ctx
, fp2
, fr
);
12199 gen_helper_float_msub_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12200 tcg_temp_free_i32(fp0
);
12201 tcg_temp_free_i32(fp1
);
12202 gen_store_fpr32(ctx
, fp2
, fd
);
12203 tcg_temp_free_i32(fp2
);
12208 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
12210 TCGv_i64 fp0
= tcg_temp_new_i64();
12211 TCGv_i64 fp1
= tcg_temp_new_i64();
12212 TCGv_i64 fp2
= tcg_temp_new_i64();
12214 gen_load_fpr64(ctx
, fp0
, fs
);
12215 gen_load_fpr64(ctx
, fp1
, ft
);
12216 gen_load_fpr64(ctx
, fp2
, fr
);
12217 gen_helper_float_msub_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12218 tcg_temp_free_i64(fp0
);
12219 tcg_temp_free_i64(fp1
);
12220 gen_store_fpr64(ctx
, fp2
, fd
);
12221 tcg_temp_free_i64(fp2
);
12227 TCGv_i64 fp0
= tcg_temp_new_i64();
12228 TCGv_i64 fp1
= tcg_temp_new_i64();
12229 TCGv_i64 fp2
= tcg_temp_new_i64();
12231 gen_load_fpr64(ctx
, fp0
, fs
);
12232 gen_load_fpr64(ctx
, fp1
, ft
);
12233 gen_load_fpr64(ctx
, fp2
, fr
);
12234 gen_helper_float_msub_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12235 tcg_temp_free_i64(fp0
);
12236 tcg_temp_free_i64(fp1
);
12237 gen_store_fpr64(ctx
, fp2
, fd
);
12238 tcg_temp_free_i64(fp2
);
12244 TCGv_i32 fp0
= tcg_temp_new_i32();
12245 TCGv_i32 fp1
= tcg_temp_new_i32();
12246 TCGv_i32 fp2
= tcg_temp_new_i32();
12248 gen_load_fpr32(ctx
, fp0
, fs
);
12249 gen_load_fpr32(ctx
, fp1
, ft
);
12250 gen_load_fpr32(ctx
, fp2
, fr
);
12251 gen_helper_float_nmadd_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12252 tcg_temp_free_i32(fp0
);
12253 tcg_temp_free_i32(fp1
);
12254 gen_store_fpr32(ctx
, fp2
, fd
);
12255 tcg_temp_free_i32(fp2
);
12260 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
12262 TCGv_i64 fp0
= tcg_temp_new_i64();
12263 TCGv_i64 fp1
= tcg_temp_new_i64();
12264 TCGv_i64 fp2
= tcg_temp_new_i64();
12266 gen_load_fpr64(ctx
, fp0
, fs
);
12267 gen_load_fpr64(ctx
, fp1
, ft
);
12268 gen_load_fpr64(ctx
, fp2
, fr
);
12269 gen_helper_float_nmadd_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12270 tcg_temp_free_i64(fp0
);
12271 tcg_temp_free_i64(fp1
);
12272 gen_store_fpr64(ctx
, fp2
, fd
);
12273 tcg_temp_free_i64(fp2
);
12279 TCGv_i64 fp0
= tcg_temp_new_i64();
12280 TCGv_i64 fp1
= tcg_temp_new_i64();
12281 TCGv_i64 fp2
= tcg_temp_new_i64();
12283 gen_load_fpr64(ctx
, fp0
, fs
);
12284 gen_load_fpr64(ctx
, fp1
, ft
);
12285 gen_load_fpr64(ctx
, fp2
, fr
);
12286 gen_helper_float_nmadd_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12287 tcg_temp_free_i64(fp0
);
12288 tcg_temp_free_i64(fp1
);
12289 gen_store_fpr64(ctx
, fp2
, fd
);
12290 tcg_temp_free_i64(fp2
);
12296 TCGv_i32 fp0
= tcg_temp_new_i32();
12297 TCGv_i32 fp1
= tcg_temp_new_i32();
12298 TCGv_i32 fp2
= tcg_temp_new_i32();
12300 gen_load_fpr32(ctx
, fp0
, fs
);
12301 gen_load_fpr32(ctx
, fp1
, ft
);
12302 gen_load_fpr32(ctx
, fp2
, fr
);
12303 gen_helper_float_nmsub_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12304 tcg_temp_free_i32(fp0
);
12305 tcg_temp_free_i32(fp1
);
12306 gen_store_fpr32(ctx
, fp2
, fd
);
12307 tcg_temp_free_i32(fp2
);
12312 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
12314 TCGv_i64 fp0
= tcg_temp_new_i64();
12315 TCGv_i64 fp1
= tcg_temp_new_i64();
12316 TCGv_i64 fp2
= tcg_temp_new_i64();
12318 gen_load_fpr64(ctx
, fp0
, fs
);
12319 gen_load_fpr64(ctx
, fp1
, ft
);
12320 gen_load_fpr64(ctx
, fp2
, fr
);
12321 gen_helper_float_nmsub_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12322 tcg_temp_free_i64(fp0
);
12323 tcg_temp_free_i64(fp1
);
12324 gen_store_fpr64(ctx
, fp2
, fd
);
12325 tcg_temp_free_i64(fp2
);
12331 TCGv_i64 fp0
= tcg_temp_new_i64();
12332 TCGv_i64 fp1
= tcg_temp_new_i64();
12333 TCGv_i64 fp2
= tcg_temp_new_i64();
12335 gen_load_fpr64(ctx
, fp0
, fs
);
12336 gen_load_fpr64(ctx
, fp1
, ft
);
12337 gen_load_fpr64(ctx
, fp2
, fr
);
12338 gen_helper_float_nmsub_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12339 tcg_temp_free_i64(fp0
);
12340 tcg_temp_free_i64(fp1
);
12341 gen_store_fpr64(ctx
, fp2
, fd
);
12342 tcg_temp_free_i64(fp2
);
12346 MIPS_INVAL("flt3_arith");
12347 gen_reserved_instruction(ctx
);
12352 void gen_rdhwr(DisasContext
*ctx
, int rt
, int rd
, int sel
)
12356 #if !defined(CONFIG_USER_ONLY)
12358 * The Linux kernel will emulate rdhwr if it's not supported natively.
12359 * Therefore only check the ISA in system mode.
12361 check_insn(ctx
, ISA_MIPS_R2
);
12363 t0
= tcg_temp_new();
12367 gen_helper_rdhwr_cpunum(t0
, cpu_env
);
12368 gen_store_gpr(t0
, rt
);
12371 gen_helper_rdhwr_synci_step(t0
, cpu_env
);
12372 gen_store_gpr(t0
, rt
);
12375 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
12378 gen_helper_rdhwr_cc(t0
, cpu_env
);
12379 gen_store_gpr(t0
, rt
);
12381 * Break the TB to be able to take timer interrupts immediately
12382 * after reading count. DISAS_STOP isn't sufficient, we need to ensure
12383 * we break completely out of translated code.
12385 gen_save_pc(ctx
->base
.pc_next
+ 4);
12386 ctx
->base
.is_jmp
= DISAS_EXIT
;
12389 gen_helper_rdhwr_ccres(t0
, cpu_env
);
12390 gen_store_gpr(t0
, rt
);
12393 check_insn(ctx
, ISA_MIPS_R6
);
12396 * Performance counter registers are not implemented other than
12397 * control register 0.
12399 generate_exception(ctx
, EXCP_RI
);
12401 gen_helper_rdhwr_performance(t0
, cpu_env
);
12402 gen_store_gpr(t0
, rt
);
12405 check_insn(ctx
, ISA_MIPS_R6
);
12406 gen_helper_rdhwr_xnp(t0
, cpu_env
);
12407 gen_store_gpr(t0
, rt
);
12410 #if defined(CONFIG_USER_ONLY)
12411 tcg_gen_ld_tl(t0
, cpu_env
,
12412 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
12413 gen_store_gpr(t0
, rt
);
12416 if ((ctx
->hflags
& MIPS_HFLAG_CP0
) ||
12417 (ctx
->hflags
& MIPS_HFLAG_HWRENA_ULR
)) {
12418 tcg_gen_ld_tl(t0
, cpu_env
,
12419 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
12420 gen_store_gpr(t0
, rt
);
12422 gen_reserved_instruction(ctx
);
12426 default: /* Invalid */
12427 MIPS_INVAL("rdhwr");
12428 gen_reserved_instruction(ctx
);
12434 static inline void clear_branch_hflags(DisasContext
*ctx
)
12436 ctx
->hflags
&= ~MIPS_HFLAG_BMASK
;
12437 if (ctx
->base
.is_jmp
== DISAS_NEXT
) {
12438 save_cpu_state(ctx
, 0);
12441 * It is not safe to save ctx->hflags as hflags may be changed
12442 * in execution time by the instruction in delay / forbidden slot.
12444 tcg_gen_andi_i32(hflags
, hflags
, ~MIPS_HFLAG_BMASK
);
12448 static void gen_branch(DisasContext
*ctx
, int insn_bytes
)
12450 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
12451 int proc_hflags
= ctx
->hflags
& MIPS_HFLAG_BMASK
;
12452 /* Branches completion */
12453 clear_branch_hflags(ctx
);
12454 ctx
->base
.is_jmp
= DISAS_NORETURN
;
12455 /* FIXME: Need to clear can_do_io. */
12456 switch (proc_hflags
& MIPS_HFLAG_BMASK_BASE
) {
12457 case MIPS_HFLAG_FBNSLOT
:
12458 gen_goto_tb(ctx
, 0, ctx
->base
.pc_next
+ insn_bytes
);
12461 /* unconditional branch */
12462 if (proc_hflags
& MIPS_HFLAG_BX
) {
12463 tcg_gen_xori_i32(hflags
, hflags
, MIPS_HFLAG_M16
);
12465 gen_goto_tb(ctx
, 0, ctx
->btarget
);
12467 case MIPS_HFLAG_BL
:
12468 /* blikely taken case */
12469 gen_goto_tb(ctx
, 0, ctx
->btarget
);
12471 case MIPS_HFLAG_BC
:
12472 /* Conditional branch */
12474 TCGLabel
*l1
= gen_new_label();
12476 tcg_gen_brcondi_tl(TCG_COND_NE
, bcond
, 0, l1
);
12477 gen_goto_tb(ctx
, 1, ctx
->base
.pc_next
+ insn_bytes
);
12479 gen_goto_tb(ctx
, 0, ctx
->btarget
);
12482 case MIPS_HFLAG_BR
:
12483 /* unconditional branch to register */
12484 if (ctx
->insn_flags
& (ASE_MIPS16
| ASE_MICROMIPS
)) {
12485 TCGv t0
= tcg_temp_new();
12486 TCGv_i32 t1
= tcg_temp_new_i32();
12488 tcg_gen_andi_tl(t0
, btarget
, 0x1);
12489 tcg_gen_trunc_tl_i32(t1
, t0
);
12491 tcg_gen_andi_i32(hflags
, hflags
, ~(uint32_t)MIPS_HFLAG_M16
);
12492 tcg_gen_shli_i32(t1
, t1
, MIPS_HFLAG_M16_SHIFT
);
12493 tcg_gen_or_i32(hflags
, hflags
, t1
);
12494 tcg_temp_free_i32(t1
);
12496 tcg_gen_andi_tl(cpu_PC
, btarget
, ~(target_ulong
)0x1);
12498 tcg_gen_mov_tl(cpu_PC
, btarget
);
12500 if (ctx
->base
.singlestep_enabled
) {
12501 save_cpu_state(ctx
, 0);
12502 gen_helper_raise_exception_debug(cpu_env
);
12504 tcg_gen_lookup_and_goto_ptr();
12507 fprintf(stderr
, "unknown branch 0x%x\n", proc_hflags
);
12513 /* Compact Branches */
12514 static void gen_compute_compact_branch(DisasContext
*ctx
, uint32_t opc
,
12515 int rs
, int rt
, int32_t offset
)
12517 int bcond_compute
= 0;
12518 TCGv t0
= tcg_temp_new();
12519 TCGv t1
= tcg_temp_new();
12520 int m16_lowbit
= (ctx
->hflags
& MIPS_HFLAG_M16
) != 0;
12522 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
12523 #ifdef MIPS_DEBUG_DISAS
12524 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
12525 "\n", ctx
->base
.pc_next
);
12527 gen_reserved_instruction(ctx
);
12531 /* Load needed operands and calculate btarget */
12533 /* compact branch */
12534 case OPC_BOVC
: /* OPC_BEQZALC, OPC_BEQC */
12535 case OPC_BNVC
: /* OPC_BNEZALC, OPC_BNEC */
12536 gen_load_gpr(t0
, rs
);
12537 gen_load_gpr(t1
, rt
);
12539 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
12540 if (rs
<= rt
&& rs
== 0) {
12541 /* OPC_BEQZALC, OPC_BNEZALC */
12542 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 4 + m16_lowbit
);
12545 case OPC_BLEZC
: /* OPC_BGEZC, OPC_BGEC */
12546 case OPC_BGTZC
: /* OPC_BLTZC, OPC_BLTC */
12547 gen_load_gpr(t0
, rs
);
12548 gen_load_gpr(t1
, rt
);
12550 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
12552 case OPC_BLEZALC
: /* OPC_BGEZALC, OPC_BGEUC */
12553 case OPC_BGTZALC
: /* OPC_BLTZALC, OPC_BLTUC */
12554 if (rs
== 0 || rs
== rt
) {
12555 /* OPC_BLEZALC, OPC_BGEZALC */
12556 /* OPC_BGTZALC, OPC_BLTZALC */
12557 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 4 + m16_lowbit
);
12559 gen_load_gpr(t0
, rs
);
12560 gen_load_gpr(t1
, rt
);
12562 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
12566 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
12571 /* OPC_BEQZC, OPC_BNEZC */
12572 gen_load_gpr(t0
, rs
);
12574 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
12576 /* OPC_JIC, OPC_JIALC */
12577 TCGv tbase
= tcg_temp_new();
12578 TCGv toffset
= tcg_temp_new();
12580 gen_load_gpr(tbase
, rt
);
12581 tcg_gen_movi_tl(toffset
, offset
);
12582 gen_op_addr_add(ctx
, btarget
, tbase
, toffset
);
12583 tcg_temp_free(tbase
);
12584 tcg_temp_free(toffset
);
12588 MIPS_INVAL("Compact branch/jump");
12589 gen_reserved_instruction(ctx
);
12593 if (bcond_compute
== 0) {
12594 /* Uncoditional compact branch */
12597 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 4 + m16_lowbit
);
12600 ctx
->hflags
|= MIPS_HFLAG_BR
;
12603 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 4 + m16_lowbit
);
12606 ctx
->hflags
|= MIPS_HFLAG_B
;
12609 MIPS_INVAL("Compact branch/jump");
12610 gen_reserved_instruction(ctx
);
12614 /* Generating branch here as compact branches don't have delay slot */
12615 gen_branch(ctx
, 4);
12617 /* Conditional compact branch */
12618 TCGLabel
*fs
= gen_new_label();
12619 save_cpu_state(ctx
, 0);
12622 case OPC_BLEZALC
: /* OPC_BGEZALC, OPC_BGEUC */
12623 if (rs
== 0 && rt
!= 0) {
12625 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE
), t1
, 0, fs
);
12626 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
12628 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE
), t1
, 0, fs
);
12631 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU
), t0
, t1
, fs
);
12634 case OPC_BGTZALC
: /* OPC_BLTZALC, OPC_BLTUC */
12635 if (rs
== 0 && rt
!= 0) {
12637 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT
), t1
, 0, fs
);
12638 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
12640 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT
), t1
, 0, fs
);
12643 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU
), t0
, t1
, fs
);
12646 case OPC_BLEZC
: /* OPC_BGEZC, OPC_BGEC */
12647 if (rs
== 0 && rt
!= 0) {
12649 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE
), t1
, 0, fs
);
12650 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
12652 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE
), t1
, 0, fs
);
12655 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE
), t0
, t1
, fs
);
12658 case OPC_BGTZC
: /* OPC_BLTZC, OPC_BLTC */
12659 if (rs
== 0 && rt
!= 0) {
12661 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT
), t1
, 0, fs
);
12662 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
12664 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT
), t1
, 0, fs
);
12667 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT
), t0
, t1
, fs
);
12670 case OPC_BOVC
: /* OPC_BEQZALC, OPC_BEQC */
12671 case OPC_BNVC
: /* OPC_BNEZALC, OPC_BNEC */
12673 /* OPC_BOVC, OPC_BNVC */
12674 TCGv t2
= tcg_temp_new();
12675 TCGv t3
= tcg_temp_new();
12676 TCGv t4
= tcg_temp_new();
12677 TCGv input_overflow
= tcg_temp_new();
12679 gen_load_gpr(t0
, rs
);
12680 gen_load_gpr(t1
, rt
);
12681 tcg_gen_ext32s_tl(t2
, t0
);
12682 tcg_gen_setcond_tl(TCG_COND_NE
, input_overflow
, t2
, t0
);
12683 tcg_gen_ext32s_tl(t3
, t1
);
12684 tcg_gen_setcond_tl(TCG_COND_NE
, t4
, t3
, t1
);
12685 tcg_gen_or_tl(input_overflow
, input_overflow
, t4
);
12687 tcg_gen_add_tl(t4
, t2
, t3
);
12688 tcg_gen_ext32s_tl(t4
, t4
);
12689 tcg_gen_xor_tl(t2
, t2
, t3
);
12690 tcg_gen_xor_tl(t3
, t4
, t3
);
12691 tcg_gen_andc_tl(t2
, t3
, t2
);
12692 tcg_gen_setcondi_tl(TCG_COND_LT
, t4
, t2
, 0);
12693 tcg_gen_or_tl(t4
, t4
, input_overflow
);
12694 if (opc
== OPC_BOVC
) {
12696 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE
), t4
, 0, fs
);
12699 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ
), t4
, 0, fs
);
12701 tcg_temp_free(input_overflow
);
12705 } else if (rs
< rt
&& rs
== 0) {
12706 /* OPC_BEQZALC, OPC_BNEZALC */
12707 if (opc
== OPC_BEQZALC
) {
12709 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ
), t1
, 0, fs
);
12712 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE
), t1
, 0, fs
);
12715 /* OPC_BEQC, OPC_BNEC */
12716 if (opc
== OPC_BEQC
) {
12718 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ
), t0
, t1
, fs
);
12721 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE
), t0
, t1
, fs
);
12726 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ
), t0
, 0, fs
);
12729 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE
), t0
, 0, fs
);
12732 MIPS_INVAL("Compact conditional branch/jump");
12733 gen_reserved_instruction(ctx
);
12737 /* Generating branch here as compact branches don't have delay slot */
12738 gen_goto_tb(ctx
, 1, ctx
->btarget
);
12741 ctx
->hflags
|= MIPS_HFLAG_FBNSLOT
;
12749 /* ISA extensions (ASEs) */
12750 /* MIPS16 extension to MIPS32 */
12752 /* MIPS16 major opcodes */
12754 M16_OPC_ADDIUSP
= 0x00,
12755 M16_OPC_ADDIUPC
= 0x01,
12757 M16_OPC_JAL
= 0x03,
12758 M16_OPC_BEQZ
= 0x04,
12759 M16_OPC_BNEQZ
= 0x05,
12760 M16_OPC_SHIFT
= 0x06,
12762 M16_OPC_RRIA
= 0x08,
12763 M16_OPC_ADDIU8
= 0x09,
12764 M16_OPC_SLTI
= 0x0a,
12765 M16_OPC_SLTIU
= 0x0b,
12768 M16_OPC_CMPI
= 0x0e,
12772 M16_OPC_LWSP
= 0x12,
12774 M16_OPC_LBU
= 0x14,
12775 M16_OPC_LHU
= 0x15,
12776 M16_OPC_LWPC
= 0x16,
12777 M16_OPC_LWU
= 0x17,
12780 M16_OPC_SWSP
= 0x1a,
12782 M16_OPC_RRR
= 0x1c,
12784 M16_OPC_EXTEND
= 0x1e,
12788 /* I8 funct field */
12807 /* RR funct field */
12841 /* I64 funct field */
12849 I64_DADDIUPC
= 0x6,
12853 /* RR ry field for CNVT */
12855 RR_RY_CNVT_ZEB
= 0x0,
12856 RR_RY_CNVT_ZEH
= 0x1,
12857 RR_RY_CNVT_ZEW
= 0x2,
12858 RR_RY_CNVT_SEB
= 0x4,
12859 RR_RY_CNVT_SEH
= 0x5,
12860 RR_RY_CNVT_SEW
= 0x6,
12863 static int xlat(int r
)
12865 static int map
[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
12870 static void gen_mips16_save(DisasContext
*ctx
,
12871 int xsregs
, int aregs
,
12872 int do_ra
, int do_s0
, int do_s1
,
12875 TCGv t0
= tcg_temp_new();
12876 TCGv t1
= tcg_temp_new();
12877 TCGv t2
= tcg_temp_new();
12907 gen_reserved_instruction(ctx
);
12913 gen_base_offset_addr(ctx
, t0
, 29, 12);
12914 gen_load_gpr(t1
, 7);
12915 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
12918 gen_base_offset_addr(ctx
, t0
, 29, 8);
12919 gen_load_gpr(t1
, 6);
12920 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
12923 gen_base_offset_addr(ctx
, t0
, 29, 4);
12924 gen_load_gpr(t1
, 5);
12925 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
12928 gen_base_offset_addr(ctx
, t0
, 29, 0);
12929 gen_load_gpr(t1
, 4);
12930 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
12933 gen_load_gpr(t0
, 29);
12935 #define DECR_AND_STORE(reg) do { \
12936 tcg_gen_movi_tl(t2, -4); \
12937 gen_op_addr_add(ctx, t0, t0, t2); \
12938 gen_load_gpr(t1, reg); \
12939 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \
12943 DECR_AND_STORE(31);
12948 DECR_AND_STORE(30);
12951 DECR_AND_STORE(23);
12954 DECR_AND_STORE(22);
12957 DECR_AND_STORE(21);
12960 DECR_AND_STORE(20);
12963 DECR_AND_STORE(19);
12966 DECR_AND_STORE(18);
12970 DECR_AND_STORE(17);
12973 DECR_AND_STORE(16);
13003 gen_reserved_instruction(ctx
);
13019 #undef DECR_AND_STORE
13021 tcg_gen_movi_tl(t2
, -framesize
);
13022 gen_op_addr_add(ctx
, cpu_gpr
[29], cpu_gpr
[29], t2
);
13028 static void gen_mips16_restore(DisasContext
*ctx
,
13029 int xsregs
, int aregs
,
13030 int do_ra
, int do_s0
, int do_s1
,
13034 TCGv t0
= tcg_temp_new();
13035 TCGv t1
= tcg_temp_new();
13036 TCGv t2
= tcg_temp_new();
13038 tcg_gen_movi_tl(t2
, framesize
);
13039 gen_op_addr_add(ctx
, t0
, cpu_gpr
[29], t2
);
13041 #define DECR_AND_LOAD(reg) do { \
13042 tcg_gen_movi_tl(t2, -4); \
13043 gen_op_addr_add(ctx, t0, t0, t2); \
13044 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \
13045 gen_store_gpr(t1, reg); \
13109 gen_reserved_instruction(ctx
);
13125 #undef DECR_AND_LOAD
13127 tcg_gen_movi_tl(t2
, framesize
);
13128 gen_op_addr_add(ctx
, cpu_gpr
[29], cpu_gpr
[29], t2
);
13134 static void gen_addiupc(DisasContext
*ctx
, int rx
, int imm
,
13135 int is_64_bit
, int extended
)
13139 if (extended
&& (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
13140 gen_reserved_instruction(ctx
);
13144 t0
= tcg_temp_new();
13146 tcg_gen_movi_tl(t0
, pc_relative_pc(ctx
));
13147 tcg_gen_addi_tl(cpu_gpr
[rx
], t0
, imm
);
13149 tcg_gen_ext32s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
13155 static void gen_cache_operation(DisasContext
*ctx
, uint32_t op
, int base
,
13158 TCGv_i32 t0
= tcg_const_i32(op
);
13159 TCGv t1
= tcg_temp_new();
13160 gen_base_offset_addr(ctx
, t1
, base
, offset
);
13161 gen_helper_cache(cpu_env
, t1
, t0
);
13164 #if defined(TARGET_MIPS64)
13165 static void decode_i64_mips16(DisasContext
*ctx
,
13166 int ry
, int funct
, int16_t offset
,
13171 check_insn(ctx
, ISA_MIPS3
);
13172 check_mips_64(ctx
);
13173 offset
= extended
? offset
: offset
<< 3;
13174 gen_ld(ctx
, OPC_LD
, ry
, 29, offset
);
13177 check_insn(ctx
, ISA_MIPS3
);
13178 check_mips_64(ctx
);
13179 offset
= extended
? offset
: offset
<< 3;
13180 gen_st(ctx
, OPC_SD
, ry
, 29, offset
);
13183 check_insn(ctx
, ISA_MIPS3
);
13184 check_mips_64(ctx
);
13185 offset
= extended
? offset
: (ctx
->opcode
& 0xff) << 3;
13186 gen_st(ctx
, OPC_SD
, 31, 29, offset
);
13189 check_insn(ctx
, ISA_MIPS3
);
13190 check_mips_64(ctx
);
13191 offset
= extended
? offset
: ((int8_t)ctx
->opcode
) << 3;
13192 gen_arith_imm(ctx
, OPC_DADDIU
, 29, 29, offset
);
13195 check_insn(ctx
, ISA_MIPS3
);
13196 check_mips_64(ctx
);
13197 if (extended
&& (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
13198 gen_reserved_instruction(ctx
);
13200 offset
= extended
? offset
: offset
<< 3;
13201 gen_ld(ctx
, OPC_LDPC
, ry
, 0, offset
);
13205 check_insn(ctx
, ISA_MIPS3
);
13206 check_mips_64(ctx
);
13207 offset
= extended
? offset
: ((int8_t)(offset
<< 3)) >> 3;
13208 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, ry
, offset
);
13211 check_insn(ctx
, ISA_MIPS3
);
13212 check_mips_64(ctx
);
13213 offset
= extended
? offset
: offset
<< 2;
13214 gen_addiupc(ctx
, ry
, offset
, 1, extended
);
13217 check_insn(ctx
, ISA_MIPS3
);
13218 check_mips_64(ctx
);
13219 offset
= extended
? offset
: offset
<< 2;
13220 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, 29, offset
);
13226 static int decode_extended_mips16_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
13228 int extend
= translator_lduw(env
, ctx
->base
.pc_next
+ 2);
13229 int op
, rx
, ry
, funct
, sa
;
13230 int16_t imm
, offset
;
13232 ctx
->opcode
= (ctx
->opcode
<< 16) | extend
;
13233 op
= (ctx
->opcode
>> 11) & 0x1f;
13234 sa
= (ctx
->opcode
>> 22) & 0x1f;
13235 funct
= (ctx
->opcode
>> 8) & 0x7;
13236 rx
= xlat((ctx
->opcode
>> 8) & 0x7);
13237 ry
= xlat((ctx
->opcode
>> 5) & 0x7);
13238 offset
= imm
= (int16_t) (((ctx
->opcode
>> 16) & 0x1f) << 11
13239 | ((ctx
->opcode
>> 21) & 0x3f) << 5
13240 | (ctx
->opcode
& 0x1f));
13243 * The extended opcodes cleverly reuse the opcodes from their 16-bit
13247 case M16_OPC_ADDIUSP
:
13248 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 29, imm
);
13250 case M16_OPC_ADDIUPC
:
13251 gen_addiupc(ctx
, rx
, imm
, 0, 1);
13254 gen_compute_branch(ctx
, OPC_BEQ
, 4, 0, 0, offset
<< 1, 0);
13255 /* No delay slot, so just process as a normal instruction */
13258 gen_compute_branch(ctx
, OPC_BEQ
, 4, rx
, 0, offset
<< 1, 0);
13259 /* No delay slot, so just process as a normal instruction */
13261 case M16_OPC_BNEQZ
:
13262 gen_compute_branch(ctx
, OPC_BNE
, 4, rx
, 0, offset
<< 1, 0);
13263 /* No delay slot, so just process as a normal instruction */
13265 case M16_OPC_SHIFT
:
13266 switch (ctx
->opcode
& 0x3) {
13268 gen_shift_imm(ctx
, OPC_SLL
, rx
, ry
, sa
);
13271 #if defined(TARGET_MIPS64)
13272 check_mips_64(ctx
);
13273 gen_shift_imm(ctx
, OPC_DSLL
, rx
, ry
, sa
);
13275 gen_reserved_instruction(ctx
);
13279 gen_shift_imm(ctx
, OPC_SRL
, rx
, ry
, sa
);
13282 gen_shift_imm(ctx
, OPC_SRA
, rx
, ry
, sa
);
13286 #if defined(TARGET_MIPS64)
13288 check_insn(ctx
, ISA_MIPS3
);
13289 check_mips_64(ctx
);
13290 gen_ld(ctx
, OPC_LD
, ry
, rx
, offset
);
13294 imm
= ctx
->opcode
& 0xf;
13295 imm
= imm
| ((ctx
->opcode
>> 20) & 0x7f) << 4;
13296 imm
= imm
| ((ctx
->opcode
>> 16) & 0xf) << 11;
13297 imm
= (int16_t) (imm
<< 1) >> 1;
13298 if ((ctx
->opcode
>> 4) & 0x1) {
13299 #if defined(TARGET_MIPS64)
13300 check_mips_64(ctx
);
13301 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, rx
, imm
);
13303 gen_reserved_instruction(ctx
);
13306 gen_arith_imm(ctx
, OPC_ADDIU
, ry
, rx
, imm
);
13309 case M16_OPC_ADDIU8
:
13310 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, rx
, imm
);
13313 gen_slt_imm(ctx
, OPC_SLTI
, 24, rx
, imm
);
13315 case M16_OPC_SLTIU
:
13316 gen_slt_imm(ctx
, OPC_SLTIU
, 24, rx
, imm
);
13321 gen_compute_branch(ctx
, OPC_BEQ
, 4, 24, 0, offset
<< 1, 0);
13324 gen_compute_branch(ctx
, OPC_BNE
, 4, 24, 0, offset
<< 1, 0);
13327 gen_st(ctx
, OPC_SW
, 31, 29, imm
);
13330 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, imm
);
13333 check_insn(ctx
, ISA_MIPS_R1
);
13335 int xsregs
= (ctx
->opcode
>> 24) & 0x7;
13336 int aregs
= (ctx
->opcode
>> 16) & 0xf;
13337 int do_ra
= (ctx
->opcode
>> 6) & 0x1;
13338 int do_s0
= (ctx
->opcode
>> 5) & 0x1;
13339 int do_s1
= (ctx
->opcode
>> 4) & 0x1;
13340 int framesize
= (((ctx
->opcode
>> 20) & 0xf) << 4
13341 | (ctx
->opcode
& 0xf)) << 3;
13343 if (ctx
->opcode
& (1 << 7)) {
13344 gen_mips16_save(ctx
, xsregs
, aregs
,
13345 do_ra
, do_s0
, do_s1
,
13348 gen_mips16_restore(ctx
, xsregs
, aregs
,
13349 do_ra
, do_s0
, do_s1
,
13355 gen_reserved_instruction(ctx
);
13360 tcg_gen_movi_tl(cpu_gpr
[rx
], (uint16_t) imm
);
13363 tcg_gen_xori_tl(cpu_gpr
[24], cpu_gpr
[rx
], (uint16_t) imm
);
13365 #if defined(TARGET_MIPS64)
13367 check_insn(ctx
, ISA_MIPS3
);
13368 check_mips_64(ctx
);
13369 gen_st(ctx
, OPC_SD
, ry
, rx
, offset
);
13373 gen_ld(ctx
, OPC_LB
, ry
, rx
, offset
);
13376 gen_ld(ctx
, OPC_LH
, ry
, rx
, offset
);
13379 gen_ld(ctx
, OPC_LW
, rx
, 29, offset
);
13382 gen_ld(ctx
, OPC_LW
, ry
, rx
, offset
);
13385 gen_ld(ctx
, OPC_LBU
, ry
, rx
, offset
);
13388 gen_ld(ctx
, OPC_LHU
, ry
, rx
, offset
);
13391 gen_ld(ctx
, OPC_LWPC
, rx
, 0, offset
);
13393 #if defined(TARGET_MIPS64)
13395 check_insn(ctx
, ISA_MIPS3
);
13396 check_mips_64(ctx
);
13397 gen_ld(ctx
, OPC_LWU
, ry
, rx
, offset
);
13401 gen_st(ctx
, OPC_SB
, ry
, rx
, offset
);
13404 gen_st(ctx
, OPC_SH
, ry
, rx
, offset
);
13407 gen_st(ctx
, OPC_SW
, rx
, 29, offset
);
13410 gen_st(ctx
, OPC_SW
, ry
, rx
, offset
);
13412 #if defined(TARGET_MIPS64)
13414 decode_i64_mips16(ctx
, ry
, funct
, offset
, 1);
13418 gen_reserved_instruction(ctx
);
13425 static inline bool is_uhi(int sdbbp_code
)
13427 #ifdef CONFIG_USER_ONLY
13430 return semihosting_enabled() && sdbbp_code
== 1;
13434 #ifdef CONFIG_USER_ONLY
13435 /* The above should dead-code away any calls to this..*/
13436 static inline void gen_helper_do_semihosting(void *env
)
13438 g_assert_not_reached();
13442 static int decode_mips16_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
13446 int op
, cnvt_op
, op1
, offset
;
13450 op
= (ctx
->opcode
>> 11) & 0x1f;
13451 sa
= (ctx
->opcode
>> 2) & 0x7;
13452 sa
= sa
== 0 ? 8 : sa
;
13453 rx
= xlat((ctx
->opcode
>> 8) & 0x7);
13454 cnvt_op
= (ctx
->opcode
>> 5) & 0x7;
13455 ry
= xlat((ctx
->opcode
>> 5) & 0x7);
13456 op1
= offset
= ctx
->opcode
& 0x1f;
13461 case M16_OPC_ADDIUSP
:
13463 int16_t imm
= ((uint8_t) ctx
->opcode
) << 2;
13465 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 29, imm
);
13468 case M16_OPC_ADDIUPC
:
13469 gen_addiupc(ctx
, rx
, ((uint8_t) ctx
->opcode
) << 2, 0, 0);
13472 offset
= (ctx
->opcode
& 0x7ff) << 1;
13473 offset
= (int16_t)(offset
<< 4) >> 4;
13474 gen_compute_branch(ctx
, OPC_BEQ
, 2, 0, 0, offset
, 0);
13475 /* No delay slot, so just process as a normal instruction */
13478 offset
= translator_lduw(env
, ctx
->base
.pc_next
+ 2);
13479 offset
= (((ctx
->opcode
& 0x1f) << 21)
13480 | ((ctx
->opcode
>> 5) & 0x1f) << 16
13482 op
= ((ctx
->opcode
>> 10) & 0x1) ? OPC_JALX
: OPC_JAL
;
13483 gen_compute_branch(ctx
, op
, 4, rx
, ry
, offset
, 2);
13487 gen_compute_branch(ctx
, OPC_BEQ
, 2, rx
, 0,
13488 ((int8_t)ctx
->opcode
) << 1, 0);
13489 /* No delay slot, so just process as a normal instruction */
13491 case M16_OPC_BNEQZ
:
13492 gen_compute_branch(ctx
, OPC_BNE
, 2, rx
, 0,
13493 ((int8_t)ctx
->opcode
) << 1, 0);
13494 /* No delay slot, so just process as a normal instruction */
13496 case M16_OPC_SHIFT
:
13497 switch (ctx
->opcode
& 0x3) {
13499 gen_shift_imm(ctx
, OPC_SLL
, rx
, ry
, sa
);
13502 #if defined(TARGET_MIPS64)
13503 check_insn(ctx
, ISA_MIPS3
);
13504 check_mips_64(ctx
);
13505 gen_shift_imm(ctx
, OPC_DSLL
, rx
, ry
, sa
);
13507 gen_reserved_instruction(ctx
);
13511 gen_shift_imm(ctx
, OPC_SRL
, rx
, ry
, sa
);
13514 gen_shift_imm(ctx
, OPC_SRA
, rx
, ry
, sa
);
13518 #if defined(TARGET_MIPS64)
13520 check_insn(ctx
, ISA_MIPS3
);
13521 check_mips_64(ctx
);
13522 gen_ld(ctx
, OPC_LD
, ry
, rx
, offset
<< 3);
13527 int16_t imm
= (int8_t)((ctx
->opcode
& 0xf) << 4) >> 4;
13529 if ((ctx
->opcode
>> 4) & 1) {
13530 #if defined(TARGET_MIPS64)
13531 check_insn(ctx
, ISA_MIPS3
);
13532 check_mips_64(ctx
);
13533 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, rx
, imm
);
13535 gen_reserved_instruction(ctx
);
13538 gen_arith_imm(ctx
, OPC_ADDIU
, ry
, rx
, imm
);
13542 case M16_OPC_ADDIU8
:
13544 int16_t imm
= (int8_t) ctx
->opcode
;
13546 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, rx
, imm
);
13551 int16_t imm
= (uint8_t) ctx
->opcode
;
13552 gen_slt_imm(ctx
, OPC_SLTI
, 24, rx
, imm
);
13555 case M16_OPC_SLTIU
:
13557 int16_t imm
= (uint8_t) ctx
->opcode
;
13558 gen_slt_imm(ctx
, OPC_SLTIU
, 24, rx
, imm
);
13565 funct
= (ctx
->opcode
>> 8) & 0x7;
13568 gen_compute_branch(ctx
, OPC_BEQ
, 2, 24, 0,
13569 ((int8_t)ctx
->opcode
) << 1, 0);
13572 gen_compute_branch(ctx
, OPC_BNE
, 2, 24, 0,
13573 ((int8_t)ctx
->opcode
) << 1, 0);
13576 gen_st(ctx
, OPC_SW
, 31, 29, (ctx
->opcode
& 0xff) << 2);
13579 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29,
13580 ((int8_t)ctx
->opcode
) << 3);
13583 check_insn(ctx
, ISA_MIPS_R1
);
13585 int do_ra
= ctx
->opcode
& (1 << 6);
13586 int do_s0
= ctx
->opcode
& (1 << 5);
13587 int do_s1
= ctx
->opcode
& (1 << 4);
13588 int framesize
= ctx
->opcode
& 0xf;
13590 if (framesize
== 0) {
13593 framesize
= framesize
<< 3;
13596 if (ctx
->opcode
& (1 << 7)) {
13597 gen_mips16_save(ctx
, 0, 0,
13598 do_ra
, do_s0
, do_s1
, framesize
);
13600 gen_mips16_restore(ctx
, 0, 0,
13601 do_ra
, do_s0
, do_s1
, framesize
);
13607 int rz
= xlat(ctx
->opcode
& 0x7);
13609 reg32
= (((ctx
->opcode
>> 3) & 0x3) << 3) |
13610 ((ctx
->opcode
>> 5) & 0x7);
13611 gen_arith(ctx
, OPC_ADDU
, reg32
, rz
, 0);
13615 reg32
= ctx
->opcode
& 0x1f;
13616 gen_arith(ctx
, OPC_ADDU
, ry
, reg32
, 0);
13619 gen_reserved_instruction(ctx
);
13626 int16_t imm
= (uint8_t) ctx
->opcode
;
13628 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 0, imm
);
13633 int16_t imm
= (uint8_t) ctx
->opcode
;
13634 gen_logic_imm(ctx
, OPC_XORI
, 24, rx
, imm
);
13637 #if defined(TARGET_MIPS64)
13639 check_insn(ctx
, ISA_MIPS3
);
13640 check_mips_64(ctx
);
13641 gen_st(ctx
, OPC_SD
, ry
, rx
, offset
<< 3);
13645 gen_ld(ctx
, OPC_LB
, ry
, rx
, offset
);
13648 gen_ld(ctx
, OPC_LH
, ry
, rx
, offset
<< 1);
13651 gen_ld(ctx
, OPC_LW
, rx
, 29, ((uint8_t)ctx
->opcode
) << 2);
13654 gen_ld(ctx
, OPC_LW
, ry
, rx
, offset
<< 2);
13657 gen_ld(ctx
, OPC_LBU
, ry
, rx
, offset
);
13660 gen_ld(ctx
, OPC_LHU
, ry
, rx
, offset
<< 1);
13663 gen_ld(ctx
, OPC_LWPC
, rx
, 0, ((uint8_t)ctx
->opcode
) << 2);
13665 #if defined(TARGET_MIPS64)
13667 check_insn(ctx
, ISA_MIPS3
);
13668 check_mips_64(ctx
);
13669 gen_ld(ctx
, OPC_LWU
, ry
, rx
, offset
<< 2);
13673 gen_st(ctx
, OPC_SB
, ry
, rx
, offset
);
13676 gen_st(ctx
, OPC_SH
, ry
, rx
, offset
<< 1);
13679 gen_st(ctx
, OPC_SW
, rx
, 29, ((uint8_t)ctx
->opcode
) << 2);
13682 gen_st(ctx
, OPC_SW
, ry
, rx
, offset
<< 2);
13686 int rz
= xlat((ctx
->opcode
>> 2) & 0x7);
13689 switch (ctx
->opcode
& 0x3) {
13691 mips32_op
= OPC_ADDU
;
13694 mips32_op
= OPC_SUBU
;
13696 #if defined(TARGET_MIPS64)
13698 mips32_op
= OPC_DADDU
;
13699 check_insn(ctx
, ISA_MIPS3
);
13700 check_mips_64(ctx
);
13703 mips32_op
= OPC_DSUBU
;
13704 check_insn(ctx
, ISA_MIPS3
);
13705 check_mips_64(ctx
);
13709 gen_reserved_instruction(ctx
);
13713 gen_arith(ctx
, mips32_op
, rz
, rx
, ry
);
13722 int nd
= (ctx
->opcode
>> 7) & 0x1;
13723 int link
= (ctx
->opcode
>> 6) & 0x1;
13724 int ra
= (ctx
->opcode
>> 5) & 0x1;
13727 check_insn(ctx
, ISA_MIPS_R1
);
13736 gen_compute_branch(ctx
, op
, 2, ra
? 31 : rx
, 31, 0,
13741 if (is_uhi(extract32(ctx
->opcode
, 5, 6))) {
13742 gen_helper_do_semihosting(cpu_env
);
13745 * XXX: not clear which exception should be raised
13746 * when in debug mode...
13748 check_insn(ctx
, ISA_MIPS_R1
);
13749 generate_exception_end(ctx
, EXCP_DBp
);
13753 gen_slt(ctx
, OPC_SLT
, 24, rx
, ry
);
13756 gen_slt(ctx
, OPC_SLTU
, 24, rx
, ry
);
13759 generate_exception_end(ctx
, EXCP_BREAK
);
13762 gen_shift(ctx
, OPC_SLLV
, ry
, rx
, ry
);
13765 gen_shift(ctx
, OPC_SRLV
, ry
, rx
, ry
);
13768 gen_shift(ctx
, OPC_SRAV
, ry
, rx
, ry
);
13770 #if defined(TARGET_MIPS64)
13772 check_insn(ctx
, ISA_MIPS3
);
13773 check_mips_64(ctx
);
13774 gen_shift_imm(ctx
, OPC_DSRL
, ry
, ry
, sa
);
13778 gen_logic(ctx
, OPC_XOR
, 24, rx
, ry
);
13781 gen_arith(ctx
, OPC_SUBU
, rx
, 0, ry
);
13784 gen_logic(ctx
, OPC_AND
, rx
, rx
, ry
);
13787 gen_logic(ctx
, OPC_OR
, rx
, rx
, ry
);
13790 gen_logic(ctx
, OPC_XOR
, rx
, rx
, ry
);
13793 gen_logic(ctx
, OPC_NOR
, rx
, ry
, 0);
13796 gen_HILO(ctx
, OPC_MFHI
, 0, rx
);
13799 check_insn(ctx
, ISA_MIPS_R1
);
13801 case RR_RY_CNVT_ZEB
:
13802 tcg_gen_ext8u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
13804 case RR_RY_CNVT_ZEH
:
13805 tcg_gen_ext16u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
13807 case RR_RY_CNVT_SEB
:
13808 tcg_gen_ext8s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
13810 case RR_RY_CNVT_SEH
:
13811 tcg_gen_ext16s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
13813 #if defined(TARGET_MIPS64)
13814 case RR_RY_CNVT_ZEW
:
13815 check_insn(ctx
, ISA_MIPS_R1
);
13816 check_mips_64(ctx
);
13817 tcg_gen_ext32u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
13819 case RR_RY_CNVT_SEW
:
13820 check_insn(ctx
, ISA_MIPS_R1
);
13821 check_mips_64(ctx
);
13822 tcg_gen_ext32s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
13826 gen_reserved_instruction(ctx
);
13831 gen_HILO(ctx
, OPC_MFLO
, 0, rx
);
13833 #if defined(TARGET_MIPS64)
13835 check_insn(ctx
, ISA_MIPS3
);
13836 check_mips_64(ctx
);
13837 gen_shift_imm(ctx
, OPC_DSRA
, ry
, ry
, sa
);
13840 check_insn(ctx
, ISA_MIPS3
);
13841 check_mips_64(ctx
);
13842 gen_shift(ctx
, OPC_DSLLV
, ry
, rx
, ry
);
13845 check_insn(ctx
, ISA_MIPS3
);
13846 check_mips_64(ctx
);
13847 gen_shift(ctx
, OPC_DSRLV
, ry
, rx
, ry
);
13850 check_insn(ctx
, ISA_MIPS3
);
13851 check_mips_64(ctx
);
13852 gen_shift(ctx
, OPC_DSRAV
, ry
, rx
, ry
);
13856 gen_muldiv(ctx
, OPC_MULT
, 0, rx
, ry
);
13859 gen_muldiv(ctx
, OPC_MULTU
, 0, rx
, ry
);
13862 gen_muldiv(ctx
, OPC_DIV
, 0, rx
, ry
);
13865 gen_muldiv(ctx
, OPC_DIVU
, 0, rx
, ry
);
13867 #if defined(TARGET_MIPS64)
13869 check_insn(ctx
, ISA_MIPS3
);
13870 check_mips_64(ctx
);
13871 gen_muldiv(ctx
, OPC_DMULT
, 0, rx
, ry
);
13874 check_insn(ctx
, ISA_MIPS3
);
13875 check_mips_64(ctx
);
13876 gen_muldiv(ctx
, OPC_DMULTU
, 0, rx
, ry
);
13879 check_insn(ctx
, ISA_MIPS3
);
13880 check_mips_64(ctx
);
13881 gen_muldiv(ctx
, OPC_DDIV
, 0, rx
, ry
);
13884 check_insn(ctx
, ISA_MIPS3
);
13885 check_mips_64(ctx
);
13886 gen_muldiv(ctx
, OPC_DDIVU
, 0, rx
, ry
);
13890 gen_reserved_instruction(ctx
);
13894 case M16_OPC_EXTEND
:
13895 decode_extended_mips16_opc(env
, ctx
);
13898 #if defined(TARGET_MIPS64)
13900 funct
= (ctx
->opcode
>> 8) & 0x7;
13901 decode_i64_mips16(ctx
, ry
, funct
, offset
, 0);
13905 gen_reserved_instruction(ctx
);
13912 /* microMIPS extension to MIPS32/MIPS64 */
13915 * microMIPS32/microMIPS64 major opcodes
13917 * 1. MIPS Architecture for Programmers Volume II-B:
13918 * The microMIPS32 Instruction Set (Revision 3.05)
13920 * Table 6.2 microMIPS32 Encoding of Major Opcode Field
13922 * 2. MIPS Architecture For Programmers Volume II-A:
13923 * The MIPS64 Instruction Set (Revision 3.51)
13953 POOL32S
= 0x16, /* MIPS64 */
13954 DADDIU32
= 0x17, /* MIPS64 */
13983 /* 0x29 is reserved */
13996 /* 0x31 is reserved */
14009 SD32
= 0x36, /* MIPS64 */
14010 LD32
= 0x37, /* MIPS64 */
14012 /* 0x39 is reserved */
14028 /* PCREL Instructions perform PC-Relative address calculation. bits 20..16 */
14050 /* POOL32A encoding of minor opcode field */
14054 * These opcodes are distinguished only by bits 9..6; those bits are
14055 * what are recorded below.
14093 /* The following can be distinguished by their lower 6 bits. */
14103 /* POOL32AXF encoding of minor opcode field extension */
14106 * 1. MIPS Architecture for Programmers Volume II-B:
14107 * The microMIPS32 Instruction Set (Revision 3.05)
14109 * Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
14111 * 2. MIPS Architecture for Programmers VolumeIV-e:
14112 * The MIPS DSP Application-Specific Extension
14113 * to the microMIPS32 Architecture (Revision 2.34)
14115 * Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
14130 /* begin of microMIPS32 DSP */
14132 /* bits 13..12 for 0x01 */
14138 /* bits 13..12 for 0x2a */
14144 /* bits 13..12 for 0x32 */
14148 /* end of microMIPS32 DSP */
14150 /* bits 15..12 for 0x2c */
14167 /* bits 15..12 for 0x34 */
14175 /* bits 15..12 for 0x3c */
14177 JR
= 0x0, /* alias */
14185 /* bits 15..12 for 0x05 */
14189 /* bits 15..12 for 0x0d */
14201 /* bits 15..12 for 0x15 */
14207 /* bits 15..12 for 0x1d */
14211 /* bits 15..12 for 0x2d */
14216 /* bits 15..12 for 0x35 */
14223 /* POOL32B encoding of minor opcode field (bits 15..12) */
14239 /* POOL32C encoding of minor opcode field (bits 15..12) */
14260 /* POOL32C LD-EVA encoding of minor opcode field (bits 11..9) */
14273 /* POOL32C ST-EVA encoding of minor opcode field (bits 11..9) */
14286 /* POOL32F encoding of minor opcode field (bits 5..0) */
14289 /* These are the bit 7..6 values */
14298 /* These are the bit 8..6 values */
14323 MOVZ_FMT_05
= 0x05,
14357 CABS_COND_FMT
= 0x1c, /* MIPS3D */
14364 /* POOL32Fxf encoding of minor opcode extension field */
14402 /* POOL32I encoding of minor opcode field (bits 25..21) */
14432 /* These overlap and are distinguished by bit16 of the instruction */
14441 /* POOL16A encoding of minor opcode field */
14448 /* POOL16B encoding of minor opcode field */
14455 /* POOL16C encoding of minor opcode field */
14475 /* R6 POOL16C encoding of minor opcode field (bits 0..5) */
14499 /* POOL16D encoding of minor opcode field */
14506 /* POOL16E encoding of minor opcode field */
14513 static int mmreg(int r
)
14515 static const int map
[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
14520 /* Used for 16-bit store instructions. */
14521 static int mmreg2(int r
)
14523 static const int map
[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
14528 #define uMIPS_RD(op) ((op >> 7) & 0x7)
14529 #define uMIPS_RS(op) ((op >> 4) & 0x7)
14530 #define uMIPS_RS2(op) uMIPS_RS(op)
14531 #define uMIPS_RS1(op) ((op >> 1) & 0x7)
14532 #define uMIPS_RD5(op) ((op >> 5) & 0x1f)
14533 #define uMIPS_RS5(op) (op & 0x1f)
14535 /* Signed immediate */
14536 #define SIMM(op, start, width) \
14537 ((int32_t)(((op >> start) & ((~0U) >> (32 - width))) \
14540 /* Zero-extended immediate */
14541 #define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32 - width)))
14543 static void gen_addiur1sp(DisasContext
*ctx
)
14545 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
14547 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, 29, ((ctx
->opcode
>> 1) & 0x3f) << 2);
14550 static void gen_addiur2(DisasContext
*ctx
)
14552 static const int decoded_imm
[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
14553 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
14554 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
14556 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, rs
, decoded_imm
[ZIMM(ctx
->opcode
, 1, 3)]);
14559 static void gen_addiusp(DisasContext
*ctx
)
14561 int encoded
= ZIMM(ctx
->opcode
, 1, 9);
14564 if (encoded
<= 1) {
14565 decoded
= 256 + encoded
;
14566 } else if (encoded
<= 255) {
14568 } else if (encoded
<= 509) {
14569 decoded
= encoded
- 512;
14571 decoded
= encoded
- 768;
14574 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, decoded
<< 2);
14577 static void gen_addius5(DisasContext
*ctx
)
14579 int imm
= SIMM(ctx
->opcode
, 1, 4);
14580 int rd
= (ctx
->opcode
>> 5) & 0x1f;
14582 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, rd
, imm
);
14585 static void gen_andi16(DisasContext
*ctx
)
14587 static const int decoded_imm
[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
14588 31, 32, 63, 64, 255, 32768, 65535 };
14589 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
14590 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
14591 int encoded
= ZIMM(ctx
->opcode
, 0, 4);
14593 gen_logic_imm(ctx
, OPC_ANDI
, rd
, rs
, decoded_imm
[encoded
]);
14596 static void gen_ldst_multiple(DisasContext
*ctx
, uint32_t opc
, int reglist
,
14597 int base
, int16_t offset
)
14602 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
14603 gen_reserved_instruction(ctx
);
14607 t0
= tcg_temp_new();
14609 gen_base_offset_addr(ctx
, t0
, base
, offset
);
14611 t1
= tcg_const_tl(reglist
);
14612 t2
= tcg_const_i32(ctx
->mem_idx
);
14614 save_cpu_state(ctx
, 1);
14617 gen_helper_lwm(cpu_env
, t0
, t1
, t2
);
14620 gen_helper_swm(cpu_env
, t0
, t1
, t2
);
14622 #ifdef TARGET_MIPS64
14624 gen_helper_ldm(cpu_env
, t0
, t1
, t2
);
14627 gen_helper_sdm(cpu_env
, t0
, t1
, t2
);
14633 tcg_temp_free_i32(t2
);
14637 static void gen_pool16c_insn(DisasContext
*ctx
)
14639 int rd
= mmreg((ctx
->opcode
>> 3) & 0x7);
14640 int rs
= mmreg(ctx
->opcode
& 0x7);
14642 switch (((ctx
->opcode
) >> 4) & 0x3f) {
14647 gen_logic(ctx
, OPC_NOR
, rd
, rs
, 0);
14653 gen_logic(ctx
, OPC_XOR
, rd
, rd
, rs
);
14659 gen_logic(ctx
, OPC_AND
, rd
, rd
, rs
);
14665 gen_logic(ctx
, OPC_OR
, rd
, rd
, rs
);
14672 static const int lwm_convert
[] = { 0x11, 0x12, 0x13, 0x14 };
14673 int offset
= ZIMM(ctx
->opcode
, 0, 4);
14675 gen_ldst_multiple(ctx
, LWM32
, lwm_convert
[(ctx
->opcode
>> 4) & 0x3],
14684 static const int swm_convert
[] = { 0x11, 0x12, 0x13, 0x14 };
14685 int offset
= ZIMM(ctx
->opcode
, 0, 4);
14687 gen_ldst_multiple(ctx
, SWM32
, swm_convert
[(ctx
->opcode
>> 4) & 0x3],
14694 int reg
= ctx
->opcode
& 0x1f;
14696 gen_compute_branch(ctx
, OPC_JR
, 2, reg
, 0, 0, 4);
14702 int reg
= ctx
->opcode
& 0x1f;
14703 gen_compute_branch(ctx
, OPC_JR
, 2, reg
, 0, 0, 0);
14705 * Let normal delay slot handling in our caller take us
14706 * to the branch target.
14712 gen_compute_branch(ctx
, OPC_JALR
, 2, ctx
->opcode
& 0x1f, 31, 0, 4);
14713 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
14717 gen_compute_branch(ctx
, OPC_JALR
, 2, ctx
->opcode
& 0x1f, 31, 0, 2);
14718 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
14722 gen_HILO(ctx
, OPC_MFHI
, 0, uMIPS_RS5(ctx
->opcode
));
14726 gen_HILO(ctx
, OPC_MFLO
, 0, uMIPS_RS5(ctx
->opcode
));
14729 generate_exception_end(ctx
, EXCP_BREAK
);
14732 if (is_uhi(extract32(ctx
->opcode
, 0, 4))) {
14733 gen_helper_do_semihosting(cpu_env
);
14736 * XXX: not clear which exception should be raised
14737 * when in debug mode...
14739 check_insn(ctx
, ISA_MIPS_R1
);
14740 generate_exception_end(ctx
, EXCP_DBp
);
14743 case JRADDIUSP
+ 0:
14744 case JRADDIUSP
+ 1:
14746 int imm
= ZIMM(ctx
->opcode
, 0, 5);
14747 gen_compute_branch(ctx
, OPC_JR
, 2, 31, 0, 0, 0);
14748 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, imm
<< 2);
14750 * Let normal delay slot handling in our caller take us
14751 * to the branch target.
14756 gen_reserved_instruction(ctx
);
14761 static inline void gen_movep(DisasContext
*ctx
, int enc_dest
, int enc_rt
,
14765 static const int rd_enc
[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
14766 static const int re_enc
[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
14767 static const int rs_rt_enc
[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
14769 rd
= rd_enc
[enc_dest
];
14770 re
= re_enc
[enc_dest
];
14771 gen_load_gpr(cpu_gpr
[rd
], rs_rt_enc
[enc_rs
]);
14772 gen_load_gpr(cpu_gpr
[re
], rs_rt_enc
[enc_rt
]);
14775 static void gen_pool16c_r6_insn(DisasContext
*ctx
)
14777 int rt
= mmreg((ctx
->opcode
>> 7) & 0x7);
14778 int rs
= mmreg((ctx
->opcode
>> 4) & 0x7);
14780 switch (ctx
->opcode
& 0xf) {
14782 gen_logic(ctx
, OPC_NOR
, rt
, rs
, 0);
14785 gen_logic(ctx
, OPC_AND
, rt
, rt
, rs
);
14789 int lwm_converted
= 0x11 + extract32(ctx
->opcode
, 8, 2);
14790 int offset
= extract32(ctx
->opcode
, 4, 4);
14791 gen_ldst_multiple(ctx
, LWM32
, lwm_converted
, 29, offset
<< 2);
14794 case R6_JRC16
: /* JRCADDIUSP */
14795 if ((ctx
->opcode
>> 4) & 1) {
14797 int imm
= extract32(ctx
->opcode
, 5, 5);
14798 gen_compute_branch(ctx
, OPC_JR
, 2, 31, 0, 0, 0);
14799 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, imm
<< 2);
14802 rs
= extract32(ctx
->opcode
, 5, 5);
14803 gen_compute_branch(ctx
, OPC_JR
, 2, rs
, 0, 0, 0);
14815 int enc_dest
= uMIPS_RD(ctx
->opcode
);
14816 int enc_rt
= uMIPS_RS2(ctx
->opcode
);
14817 int enc_rs
= (ctx
->opcode
& 3) | ((ctx
->opcode
>> 1) & 4);
14818 gen_movep(ctx
, enc_dest
, enc_rt
, enc_rs
);
14822 gen_logic(ctx
, OPC_XOR
, rt
, rt
, rs
);
14825 gen_logic(ctx
, OPC_OR
, rt
, rt
, rs
);
14829 int swm_converted
= 0x11 + extract32(ctx
->opcode
, 8, 2);
14830 int offset
= extract32(ctx
->opcode
, 4, 4);
14831 gen_ldst_multiple(ctx
, SWM32
, swm_converted
, 29, offset
<< 2);
14834 case JALRC16
: /* BREAK16, SDBBP16 */
14835 switch (ctx
->opcode
& 0x3f) {
14837 case JALRC16
+ 0x20:
14839 gen_compute_branch(ctx
, OPC_JALR
, 2, (ctx
->opcode
>> 5) & 0x1f,
14844 generate_exception(ctx
, EXCP_BREAK
);
14848 if (is_uhi(extract32(ctx
->opcode
, 6, 4))) {
14849 gen_helper_do_semihosting(cpu_env
);
14851 if (ctx
->hflags
& MIPS_HFLAG_SBRI
) {
14852 generate_exception(ctx
, EXCP_RI
);
14854 generate_exception(ctx
, EXCP_DBp
);
14861 generate_exception(ctx
, EXCP_RI
);
14866 static void gen_ldxs(DisasContext
*ctx
, int base
, int index
, int rd
)
14868 TCGv t0
= tcg_temp_new();
14869 TCGv t1
= tcg_temp_new();
14871 gen_load_gpr(t0
, base
);
14874 gen_load_gpr(t1
, index
);
14875 tcg_gen_shli_tl(t1
, t1
, 2);
14876 gen_op_addr_add(ctx
, t0
, t1
, t0
);
14879 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TESL
);
14880 gen_store_gpr(t1
, rd
);
14886 static void gen_ldst_pair(DisasContext
*ctx
, uint32_t opc
, int rd
,
14887 int base
, int16_t offset
)
14891 if (ctx
->hflags
& MIPS_HFLAG_BMASK
|| rd
== 31) {
14892 gen_reserved_instruction(ctx
);
14896 t0
= tcg_temp_new();
14897 t1
= tcg_temp_new();
14899 gen_base_offset_addr(ctx
, t0
, base
, offset
);
14904 gen_reserved_instruction(ctx
);
14907 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TESL
);
14908 gen_store_gpr(t1
, rd
);
14909 tcg_gen_movi_tl(t1
, 4);
14910 gen_op_addr_add(ctx
, t0
, t0
, t1
);
14911 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TESL
);
14912 gen_store_gpr(t1
, rd
+ 1);
14915 gen_load_gpr(t1
, rd
);
14916 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
14917 tcg_gen_movi_tl(t1
, 4);
14918 gen_op_addr_add(ctx
, t0
, t0
, t1
);
14919 gen_load_gpr(t1
, rd
+ 1);
14920 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
14922 #ifdef TARGET_MIPS64
14925 gen_reserved_instruction(ctx
);
14928 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
14929 gen_store_gpr(t1
, rd
);
14930 tcg_gen_movi_tl(t1
, 8);
14931 gen_op_addr_add(ctx
, t0
, t0
, t1
);
14932 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
14933 gen_store_gpr(t1
, rd
+ 1);
14936 gen_load_gpr(t1
, rd
);
14937 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
14938 tcg_gen_movi_tl(t1
, 8);
14939 gen_op_addr_add(ctx
, t0
, t0
, t1
);
14940 gen_load_gpr(t1
, rd
+ 1);
14941 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
14949 static void gen_sync(int stype
)
14951 TCGBar tcg_mo
= TCG_BAR_SC
;
14954 case 0x4: /* SYNC_WMB */
14955 tcg_mo
|= TCG_MO_ST_ST
;
14957 case 0x10: /* SYNC_MB */
14958 tcg_mo
|= TCG_MO_ALL
;
14960 case 0x11: /* SYNC_ACQUIRE */
14961 tcg_mo
|= TCG_MO_LD_LD
| TCG_MO_LD_ST
;
14963 case 0x12: /* SYNC_RELEASE */
14964 tcg_mo
|= TCG_MO_ST_ST
| TCG_MO_LD_ST
;
14966 case 0x13: /* SYNC_RMB */
14967 tcg_mo
|= TCG_MO_LD_LD
;
14970 tcg_mo
|= TCG_MO_ALL
;
14974 tcg_gen_mb(tcg_mo
);
14977 static void gen_pool32axf(CPUMIPSState
*env
, DisasContext
*ctx
, int rt
, int rs
)
14979 int extension
= (ctx
->opcode
>> 6) & 0x3f;
14980 int minor
= (ctx
->opcode
>> 12) & 0xf;
14981 uint32_t mips32_op
;
14983 switch (extension
) {
14985 mips32_op
= OPC_TEQ
;
14988 mips32_op
= OPC_TGE
;
14991 mips32_op
= OPC_TGEU
;
14994 mips32_op
= OPC_TLT
;
14997 mips32_op
= OPC_TLTU
;
15000 mips32_op
= OPC_TNE
;
15002 gen_trap(ctx
, mips32_op
, rs
, rt
, -1);
15004 #ifndef CONFIG_USER_ONLY
15007 check_cp0_enabled(ctx
);
15009 /* Treat as NOP. */
15012 gen_mfc0(ctx
, cpu_gpr
[rt
], rs
, (ctx
->opcode
>> 11) & 0x7);
15016 check_cp0_enabled(ctx
);
15018 TCGv t0
= tcg_temp_new();
15020 gen_load_gpr(t0
, rt
);
15021 gen_mtc0(ctx
, t0
, rs
, (ctx
->opcode
>> 11) & 0x7);
15027 switch (minor
& 3) {
15029 gen_muldiv(ctx
, OPC_MADD
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
15032 gen_muldiv(ctx
, OPC_MADDU
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
15035 gen_muldiv(ctx
, OPC_MSUB
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
15038 gen_muldiv(ctx
, OPC_MSUBU
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
15041 goto pool32axf_invalid
;
15045 switch (minor
& 3) {
15047 gen_muldiv(ctx
, OPC_MULT
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
15050 gen_muldiv(ctx
, OPC_MULTU
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
15053 goto pool32axf_invalid
;
15059 check_insn(ctx
, ISA_MIPS_R6
);
15060 gen_bitswap(ctx
, OPC_BITSWAP
, rs
, rt
);
15063 gen_bshfl(ctx
, OPC_SEB
, rs
, rt
);
15066 gen_bshfl(ctx
, OPC_SEH
, rs
, rt
);
15069 mips32_op
= OPC_CLO
;
15072 mips32_op
= OPC_CLZ
;
15074 check_insn(ctx
, ISA_MIPS_R1
);
15075 gen_cl(ctx
, mips32_op
, rt
, rs
);
15078 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15079 gen_rdhwr(ctx
, rt
, rs
, 0);
15082 gen_bshfl(ctx
, OPC_WSBH
, rs
, rt
);
15085 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15086 mips32_op
= OPC_MULT
;
15089 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15090 mips32_op
= OPC_MULTU
;
15093 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15094 mips32_op
= OPC_DIV
;
15097 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15098 mips32_op
= OPC_DIVU
;
15101 check_insn(ctx
, ISA_MIPS_R1
);
15102 gen_muldiv(ctx
, mips32_op
, 0, rs
, rt
);
15105 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15106 mips32_op
= OPC_MADD
;
15109 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15110 mips32_op
= OPC_MADDU
;
15113 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15114 mips32_op
= OPC_MSUB
;
15117 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15118 mips32_op
= OPC_MSUBU
;
15120 check_insn(ctx
, ISA_MIPS_R1
);
15121 gen_muldiv(ctx
, mips32_op
, 0, rs
, rt
);
15124 goto pool32axf_invalid
;
15135 generate_exception_err(ctx
, EXCP_CpU
, 2);
15138 goto pool32axf_invalid
;
15143 case JALR
: /* JALRC */
15144 case JALR_HB
: /* JALRC_HB */
15145 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
15146 /* JALRC, JALRC_HB */
15147 gen_compute_branch(ctx
, OPC_JALR
, 4, rs
, rt
, 0, 0);
15149 /* JALR, JALR_HB */
15150 gen_compute_branch(ctx
, OPC_JALR
, 4, rs
, rt
, 0, 4);
15151 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
15156 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15157 gen_compute_branch(ctx
, OPC_JALR
, 4, rs
, rt
, 0, 2);
15158 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
15161 goto pool32axf_invalid
;
15167 check_cp0_enabled(ctx
);
15168 check_insn(ctx
, ISA_MIPS_R2
);
15169 gen_load_srsgpr(rs
, rt
);
15172 check_cp0_enabled(ctx
);
15173 check_insn(ctx
, ISA_MIPS_R2
);
15174 gen_store_srsgpr(rs
, rt
);
15177 goto pool32axf_invalid
;
15180 #ifndef CONFIG_USER_ONLY
15184 mips32_op
= OPC_TLBP
;
15187 mips32_op
= OPC_TLBR
;
15190 mips32_op
= OPC_TLBWI
;
15193 mips32_op
= OPC_TLBWR
;
15196 mips32_op
= OPC_TLBINV
;
15199 mips32_op
= OPC_TLBINVF
;
15202 mips32_op
= OPC_WAIT
;
15205 mips32_op
= OPC_DERET
;
15208 mips32_op
= OPC_ERET
;
15210 gen_cp0(env
, ctx
, mips32_op
, rt
, rs
);
15213 goto pool32axf_invalid
;
15219 check_cp0_enabled(ctx
);
15221 TCGv t0
= tcg_temp_new();
15223 save_cpu_state(ctx
, 1);
15224 gen_helper_di(t0
, cpu_env
);
15225 gen_store_gpr(t0
, rs
);
15227 * Stop translation as we may have switched the execution
15230 ctx
->base
.is_jmp
= DISAS_STOP
;
15235 check_cp0_enabled(ctx
);
15237 TCGv t0
= tcg_temp_new();
15239 save_cpu_state(ctx
, 1);
15240 gen_helper_ei(t0
, cpu_env
);
15241 gen_store_gpr(t0
, rs
);
15243 * DISAS_STOP isn't sufficient, we need to ensure we break out
15244 * of translated code to check for pending interrupts.
15246 gen_save_pc(ctx
->base
.pc_next
+ 4);
15247 ctx
->base
.is_jmp
= DISAS_EXIT
;
15252 goto pool32axf_invalid
;
15259 gen_sync(extract32(ctx
->opcode
, 16, 5));
15262 generate_exception_end(ctx
, EXCP_SYSCALL
);
15265 if (is_uhi(extract32(ctx
->opcode
, 16, 10))) {
15266 gen_helper_do_semihosting(cpu_env
);
15268 check_insn(ctx
, ISA_MIPS_R1
);
15269 if (ctx
->hflags
& MIPS_HFLAG_SBRI
) {
15270 gen_reserved_instruction(ctx
);
15272 generate_exception_end(ctx
, EXCP_DBp
);
15277 goto pool32axf_invalid
;
15281 switch (minor
& 3) {
15283 gen_HILO(ctx
, OPC_MFHI
, minor
>> 2, rs
);
15286 gen_HILO(ctx
, OPC_MFLO
, minor
>> 2, rs
);
15289 gen_HILO(ctx
, OPC_MTHI
, minor
>> 2, rs
);
15292 gen_HILO(ctx
, OPC_MTLO
, minor
>> 2, rs
);
15295 goto pool32axf_invalid
;
15299 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15302 gen_HILO(ctx
, OPC_MFHI
, 0, rs
);
15305 gen_HILO(ctx
, OPC_MFLO
, 0, rs
);
15308 gen_HILO(ctx
, OPC_MTHI
, 0, rs
);
15311 gen_HILO(ctx
, OPC_MTLO
, 0, rs
);
15314 goto pool32axf_invalid
;
15319 MIPS_INVAL("pool32axf");
15320 gen_reserved_instruction(ctx
);
15326 * Values for microMIPS fmt field. Variable-width, depending on which
15327 * formats the instruction supports.
15346 static void gen_pool32fxf(DisasContext
*ctx
, int rt
, int rs
)
15348 int extension
= (ctx
->opcode
>> 6) & 0x3ff;
15349 uint32_t mips32_op
;
15351 #define FLOAT_1BIT_FMT(opc, fmt) ((fmt << 8) | opc)
15352 #define FLOAT_2BIT_FMT(opc, fmt) ((fmt << 7) | opc)
15353 #define COND_FLOAT_MOV(opc, cond) ((cond << 7) | opc)
15355 switch (extension
) {
15356 case FLOAT_1BIT_FMT(CFC1
, 0):
15357 mips32_op
= OPC_CFC1
;
15359 case FLOAT_1BIT_FMT(CTC1
, 0):
15360 mips32_op
= OPC_CTC1
;
15362 case FLOAT_1BIT_FMT(MFC1
, 0):
15363 mips32_op
= OPC_MFC1
;
15365 case FLOAT_1BIT_FMT(MTC1
, 0):
15366 mips32_op
= OPC_MTC1
;
15368 case FLOAT_1BIT_FMT(MFHC1
, 0):
15369 mips32_op
= OPC_MFHC1
;
15371 case FLOAT_1BIT_FMT(MTHC1
, 0):
15372 mips32_op
= OPC_MTHC1
;
15374 gen_cp1(ctx
, mips32_op
, rt
, rs
);
15377 /* Reciprocal square root */
15378 case FLOAT_1BIT_FMT(RSQRT_FMT
, FMT_SD_S
):
15379 mips32_op
= OPC_RSQRT_S
;
15381 case FLOAT_1BIT_FMT(RSQRT_FMT
, FMT_SD_D
):
15382 mips32_op
= OPC_RSQRT_D
;
15386 case FLOAT_1BIT_FMT(SQRT_FMT
, FMT_SD_S
):
15387 mips32_op
= OPC_SQRT_S
;
15389 case FLOAT_1BIT_FMT(SQRT_FMT
, FMT_SD_D
):
15390 mips32_op
= OPC_SQRT_D
;
15394 case FLOAT_1BIT_FMT(RECIP_FMT
, FMT_SD_S
):
15395 mips32_op
= OPC_RECIP_S
;
15397 case FLOAT_1BIT_FMT(RECIP_FMT
, FMT_SD_D
):
15398 mips32_op
= OPC_RECIP_D
;
15402 case FLOAT_1BIT_FMT(FLOOR_L
, FMT_SD_S
):
15403 mips32_op
= OPC_FLOOR_L_S
;
15405 case FLOAT_1BIT_FMT(FLOOR_L
, FMT_SD_D
):
15406 mips32_op
= OPC_FLOOR_L_D
;
15408 case FLOAT_1BIT_FMT(FLOOR_W
, FMT_SD_S
):
15409 mips32_op
= OPC_FLOOR_W_S
;
15411 case FLOAT_1BIT_FMT(FLOOR_W
, FMT_SD_D
):
15412 mips32_op
= OPC_FLOOR_W_D
;
15416 case FLOAT_1BIT_FMT(CEIL_L
, FMT_SD_S
):
15417 mips32_op
= OPC_CEIL_L_S
;
15419 case FLOAT_1BIT_FMT(CEIL_L
, FMT_SD_D
):
15420 mips32_op
= OPC_CEIL_L_D
;
15422 case FLOAT_1BIT_FMT(CEIL_W
, FMT_SD_S
):
15423 mips32_op
= OPC_CEIL_W_S
;
15425 case FLOAT_1BIT_FMT(CEIL_W
, FMT_SD_D
):
15426 mips32_op
= OPC_CEIL_W_D
;
15430 case FLOAT_1BIT_FMT(TRUNC_L
, FMT_SD_S
):
15431 mips32_op
= OPC_TRUNC_L_S
;
15433 case FLOAT_1BIT_FMT(TRUNC_L
, FMT_SD_D
):
15434 mips32_op
= OPC_TRUNC_L_D
;
15436 case FLOAT_1BIT_FMT(TRUNC_W
, FMT_SD_S
):
15437 mips32_op
= OPC_TRUNC_W_S
;
15439 case FLOAT_1BIT_FMT(TRUNC_W
, FMT_SD_D
):
15440 mips32_op
= OPC_TRUNC_W_D
;
15444 case FLOAT_1BIT_FMT(ROUND_L
, FMT_SD_S
):
15445 mips32_op
= OPC_ROUND_L_S
;
15447 case FLOAT_1BIT_FMT(ROUND_L
, FMT_SD_D
):
15448 mips32_op
= OPC_ROUND_L_D
;
15450 case FLOAT_1BIT_FMT(ROUND_W
, FMT_SD_S
):
15451 mips32_op
= OPC_ROUND_W_S
;
15453 case FLOAT_1BIT_FMT(ROUND_W
, FMT_SD_D
):
15454 mips32_op
= OPC_ROUND_W_D
;
15457 /* Integer to floating-point conversion */
15458 case FLOAT_1BIT_FMT(CVT_L
, FMT_SD_S
):
15459 mips32_op
= OPC_CVT_L_S
;
15461 case FLOAT_1BIT_FMT(CVT_L
, FMT_SD_D
):
15462 mips32_op
= OPC_CVT_L_D
;
15464 case FLOAT_1BIT_FMT(CVT_W
, FMT_SD_S
):
15465 mips32_op
= OPC_CVT_W_S
;
15467 case FLOAT_1BIT_FMT(CVT_W
, FMT_SD_D
):
15468 mips32_op
= OPC_CVT_W_D
;
15471 /* Paired-foo conversions */
15472 case FLOAT_1BIT_FMT(CVT_S_PL
, 0):
15473 mips32_op
= OPC_CVT_S_PL
;
15475 case FLOAT_1BIT_FMT(CVT_S_PU
, 0):
15476 mips32_op
= OPC_CVT_S_PU
;
15478 case FLOAT_1BIT_FMT(CVT_PW_PS
, 0):
15479 mips32_op
= OPC_CVT_PW_PS
;
15481 case FLOAT_1BIT_FMT(CVT_PS_PW
, 0):
15482 mips32_op
= OPC_CVT_PS_PW
;
15485 /* Floating-point moves */
15486 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_S
):
15487 mips32_op
= OPC_MOV_S
;
15489 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_D
):
15490 mips32_op
= OPC_MOV_D
;
15492 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_PS
):
15493 mips32_op
= OPC_MOV_PS
;
15496 /* Absolute value */
15497 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_S
):
15498 mips32_op
= OPC_ABS_S
;
15500 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_D
):
15501 mips32_op
= OPC_ABS_D
;
15503 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_PS
):
15504 mips32_op
= OPC_ABS_PS
;
15508 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_S
):
15509 mips32_op
= OPC_NEG_S
;
15511 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_D
):
15512 mips32_op
= OPC_NEG_D
;
15514 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_PS
):
15515 mips32_op
= OPC_NEG_PS
;
15518 /* Reciprocal square root step */
15519 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_S
):
15520 mips32_op
= OPC_RSQRT1_S
;
15522 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_D
):
15523 mips32_op
= OPC_RSQRT1_D
;
15525 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_PS
):
15526 mips32_op
= OPC_RSQRT1_PS
;
15529 /* Reciprocal step */
15530 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_S
):
15531 mips32_op
= OPC_RECIP1_S
;
15533 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_D
):
15534 mips32_op
= OPC_RECIP1_S
;
15536 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_PS
):
15537 mips32_op
= OPC_RECIP1_PS
;
15540 /* Conversions from double */
15541 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_S
):
15542 mips32_op
= OPC_CVT_D_S
;
15544 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_W
):
15545 mips32_op
= OPC_CVT_D_W
;
15547 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_L
):
15548 mips32_op
= OPC_CVT_D_L
;
15551 /* Conversions from single */
15552 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_D
):
15553 mips32_op
= OPC_CVT_S_D
;
15555 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_W
):
15556 mips32_op
= OPC_CVT_S_W
;
15558 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_L
):
15559 mips32_op
= OPC_CVT_S_L
;
15561 gen_farith(ctx
, mips32_op
, -1, rs
, rt
, 0);
15564 /* Conditional moves on floating-point codes */
15565 case COND_FLOAT_MOV(MOVT
, 0):
15566 case COND_FLOAT_MOV(MOVT
, 1):
15567 case COND_FLOAT_MOV(MOVT
, 2):
15568 case COND_FLOAT_MOV(MOVT
, 3):
15569 case COND_FLOAT_MOV(MOVT
, 4):
15570 case COND_FLOAT_MOV(MOVT
, 5):
15571 case COND_FLOAT_MOV(MOVT
, 6):
15572 case COND_FLOAT_MOV(MOVT
, 7):
15573 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15574 gen_movci(ctx
, rt
, rs
, (ctx
->opcode
>> 13) & 0x7, 1);
15576 case COND_FLOAT_MOV(MOVF
, 0):
15577 case COND_FLOAT_MOV(MOVF
, 1):
15578 case COND_FLOAT_MOV(MOVF
, 2):
15579 case COND_FLOAT_MOV(MOVF
, 3):
15580 case COND_FLOAT_MOV(MOVF
, 4):
15581 case COND_FLOAT_MOV(MOVF
, 5):
15582 case COND_FLOAT_MOV(MOVF
, 6):
15583 case COND_FLOAT_MOV(MOVF
, 7):
15584 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15585 gen_movci(ctx
, rt
, rs
, (ctx
->opcode
>> 13) & 0x7, 0);
15588 MIPS_INVAL("pool32fxf");
15589 gen_reserved_instruction(ctx
);
15594 static void decode_micromips32_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
15598 int rt
, rs
, rd
, rr
;
15600 uint32_t op
, minor
, minor2
, mips32_op
;
15601 uint32_t cond
, fmt
, cc
;
15603 insn
= translator_lduw(env
, ctx
->base
.pc_next
+ 2);
15604 ctx
->opcode
= (ctx
->opcode
<< 16) | insn
;
15606 rt
= (ctx
->opcode
>> 21) & 0x1f;
15607 rs
= (ctx
->opcode
>> 16) & 0x1f;
15608 rd
= (ctx
->opcode
>> 11) & 0x1f;
15609 rr
= (ctx
->opcode
>> 6) & 0x1f;
15610 imm
= (int16_t) ctx
->opcode
;
15612 op
= (ctx
->opcode
>> 26) & 0x3f;
15615 minor
= ctx
->opcode
& 0x3f;
15618 minor
= (ctx
->opcode
>> 6) & 0xf;
15621 mips32_op
= OPC_SLL
;
15624 mips32_op
= OPC_SRA
;
15627 mips32_op
= OPC_SRL
;
15630 mips32_op
= OPC_ROTR
;
15632 gen_shift_imm(ctx
, mips32_op
, rt
, rs
, rd
);
15635 check_insn(ctx
, ISA_MIPS_R6
);
15636 gen_cond_move(ctx
, OPC_SELEQZ
, rd
, rs
, rt
);
15639 check_insn(ctx
, ISA_MIPS_R6
);
15640 gen_cond_move(ctx
, OPC_SELNEZ
, rd
, rs
, rt
);
15643 check_insn(ctx
, ISA_MIPS_R6
);
15644 gen_rdhwr(ctx
, rt
, rs
, extract32(ctx
->opcode
, 11, 3));
15647 goto pool32a_invalid
;
15651 minor
= (ctx
->opcode
>> 6) & 0xf;
15655 mips32_op
= OPC_ADD
;
15658 mips32_op
= OPC_ADDU
;
15661 mips32_op
= OPC_SUB
;
15664 mips32_op
= OPC_SUBU
;
15667 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15668 mips32_op
= OPC_MUL
;
15670 gen_arith(ctx
, mips32_op
, rd
, rs
, rt
);
15674 mips32_op
= OPC_SLLV
;
15677 mips32_op
= OPC_SRLV
;
15680 mips32_op
= OPC_SRAV
;
15683 mips32_op
= OPC_ROTRV
;
15685 gen_shift(ctx
, mips32_op
, rd
, rs
, rt
);
15687 /* Logical operations */
15689 mips32_op
= OPC_AND
;
15692 mips32_op
= OPC_OR
;
15695 mips32_op
= OPC_NOR
;
15698 mips32_op
= OPC_XOR
;
15700 gen_logic(ctx
, mips32_op
, rd
, rs
, rt
);
15702 /* Set less than */
15704 mips32_op
= OPC_SLT
;
15707 mips32_op
= OPC_SLTU
;
15709 gen_slt(ctx
, mips32_op
, rd
, rs
, rt
);
15712 goto pool32a_invalid
;
15716 minor
= (ctx
->opcode
>> 6) & 0xf;
15718 /* Conditional moves */
15719 case MOVN
: /* MUL */
15720 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
15722 gen_r6_muldiv(ctx
, R6_OPC_MUL
, rd
, rs
, rt
);
15725 gen_cond_move(ctx
, OPC_MOVN
, rd
, rs
, rt
);
15728 case MOVZ
: /* MUH */
15729 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
15731 gen_r6_muldiv(ctx
, R6_OPC_MUH
, rd
, rs
, rt
);
15734 gen_cond_move(ctx
, OPC_MOVZ
, rd
, rs
, rt
);
15738 check_insn(ctx
, ISA_MIPS_R6
);
15739 gen_r6_muldiv(ctx
, R6_OPC_MULU
, rd
, rs
, rt
);
15742 check_insn(ctx
, ISA_MIPS_R6
);
15743 gen_r6_muldiv(ctx
, R6_OPC_MUHU
, rd
, rs
, rt
);
15745 case LWXS
: /* DIV */
15746 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
15748 gen_r6_muldiv(ctx
, R6_OPC_DIV
, rd
, rs
, rt
);
15751 gen_ldxs(ctx
, rs
, rt
, rd
);
15755 check_insn(ctx
, ISA_MIPS_R6
);
15756 gen_r6_muldiv(ctx
, R6_OPC_MOD
, rd
, rs
, rt
);
15759 check_insn(ctx
, ISA_MIPS_R6
);
15760 gen_r6_muldiv(ctx
, R6_OPC_DIVU
, rd
, rs
, rt
);
15763 check_insn(ctx
, ISA_MIPS_R6
);
15764 gen_r6_muldiv(ctx
, R6_OPC_MODU
, rd
, rs
, rt
);
15767 goto pool32a_invalid
;
15771 gen_bitops(ctx
, OPC_INS
, rt
, rs
, rr
, rd
);
15774 check_insn(ctx
, ISA_MIPS_R6
);
15775 gen_lsa(ctx
, rd
, rt
, rs
, extract32(ctx
->opcode
, 9, 2));
15778 check_insn(ctx
, ISA_MIPS_R6
);
15779 gen_align(ctx
, 32, rd
, rs
, rt
, extract32(ctx
->opcode
, 9, 2));
15782 gen_bitops(ctx
, OPC_EXT
, rt
, rs
, rr
, rd
);
15785 gen_pool32axf(env
, ctx
, rt
, rs
);
15788 generate_exception_end(ctx
, EXCP_BREAK
);
15791 check_insn(ctx
, ISA_MIPS_R6
);
15792 gen_reserved_instruction(ctx
);
15796 MIPS_INVAL("pool32a");
15797 gen_reserved_instruction(ctx
);
15802 minor
= (ctx
->opcode
>> 12) & 0xf;
15805 check_cp0_enabled(ctx
);
15806 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
15807 gen_cache_operation(ctx
, rt
, rs
, imm
);
15812 /* COP2: Not implemented. */
15813 generate_exception_err(ctx
, EXCP_CpU
, 2);
15815 #ifdef TARGET_MIPS64
15818 check_insn(ctx
, ISA_MIPS3
);
15819 check_mips_64(ctx
);
15824 gen_ldst_pair(ctx
, minor
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
15826 #ifdef TARGET_MIPS64
15829 check_insn(ctx
, ISA_MIPS3
);
15830 check_mips_64(ctx
);
15835 gen_ldst_multiple(ctx
, minor
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
15838 MIPS_INVAL("pool32b");
15839 gen_reserved_instruction(ctx
);
15844 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
15845 minor
= ctx
->opcode
& 0x3f;
15846 check_cp1_enabled(ctx
);
15849 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15850 mips32_op
= OPC_ALNV_PS
;
15853 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15854 mips32_op
= OPC_MADD_S
;
15857 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15858 mips32_op
= OPC_MADD_D
;
15861 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15862 mips32_op
= OPC_MADD_PS
;
15865 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15866 mips32_op
= OPC_MSUB_S
;
15869 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15870 mips32_op
= OPC_MSUB_D
;
15873 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15874 mips32_op
= OPC_MSUB_PS
;
15877 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15878 mips32_op
= OPC_NMADD_S
;
15881 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15882 mips32_op
= OPC_NMADD_D
;
15885 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15886 mips32_op
= OPC_NMADD_PS
;
15889 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15890 mips32_op
= OPC_NMSUB_S
;
15893 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15894 mips32_op
= OPC_NMSUB_D
;
15897 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15898 mips32_op
= OPC_NMSUB_PS
;
15900 gen_flt3_arith(ctx
, mips32_op
, rd
, rr
, rs
, rt
);
15902 case CABS_COND_FMT
:
15903 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15904 cond
= (ctx
->opcode
>> 6) & 0xf;
15905 cc
= (ctx
->opcode
>> 13) & 0x7;
15906 fmt
= (ctx
->opcode
>> 10) & 0x3;
15909 gen_cmpabs_s(ctx
, cond
, rt
, rs
, cc
);
15912 gen_cmpabs_d(ctx
, cond
, rt
, rs
, cc
);
15915 gen_cmpabs_ps(ctx
, cond
, rt
, rs
, cc
);
15918 goto pool32f_invalid
;
15922 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15923 cond
= (ctx
->opcode
>> 6) & 0xf;
15924 cc
= (ctx
->opcode
>> 13) & 0x7;
15925 fmt
= (ctx
->opcode
>> 10) & 0x3;
15928 gen_cmp_s(ctx
, cond
, rt
, rs
, cc
);
15931 gen_cmp_d(ctx
, cond
, rt
, rs
, cc
);
15934 gen_cmp_ps(ctx
, cond
, rt
, rs
, cc
);
15937 goto pool32f_invalid
;
15941 check_insn(ctx
, ISA_MIPS_R6
);
15942 gen_r6_cmp_s(ctx
, (ctx
->opcode
>> 6) & 0x1f, rt
, rs
, rd
);
15945 check_insn(ctx
, ISA_MIPS_R6
);
15946 gen_r6_cmp_d(ctx
, (ctx
->opcode
>> 6) & 0x1f, rt
, rs
, rd
);
15949 gen_pool32fxf(ctx
, rt
, rs
);
15953 switch ((ctx
->opcode
>> 6) & 0x7) {
15955 mips32_op
= OPC_PLL_PS
;
15958 mips32_op
= OPC_PLU_PS
;
15961 mips32_op
= OPC_PUL_PS
;
15964 mips32_op
= OPC_PUU_PS
;
15967 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15968 mips32_op
= OPC_CVT_PS_S
;
15970 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
15973 goto pool32f_invalid
;
15977 check_insn(ctx
, ISA_MIPS_R6
);
15978 switch ((ctx
->opcode
>> 9) & 0x3) {
15980 gen_farith(ctx
, OPC_MIN_S
, rt
, rs
, rd
, 0);
15983 gen_farith(ctx
, OPC_MIN_D
, rt
, rs
, rd
, 0);
15986 goto pool32f_invalid
;
15991 switch ((ctx
->opcode
>> 6) & 0x7) {
15993 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15994 mips32_op
= OPC_LWXC1
;
15997 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15998 mips32_op
= OPC_SWXC1
;
16001 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16002 mips32_op
= OPC_LDXC1
;
16005 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16006 mips32_op
= OPC_SDXC1
;
16009 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16010 mips32_op
= OPC_LUXC1
;
16013 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16014 mips32_op
= OPC_SUXC1
;
16016 gen_flt3_ldst(ctx
, mips32_op
, rd
, rd
, rt
, rs
);
16019 goto pool32f_invalid
;
16023 check_insn(ctx
, ISA_MIPS_R6
);
16024 switch ((ctx
->opcode
>> 9) & 0x3) {
16026 gen_farith(ctx
, OPC_MAX_S
, rt
, rs
, rd
, 0);
16029 gen_farith(ctx
, OPC_MAX_D
, rt
, rs
, rd
, 0);
16032 goto pool32f_invalid
;
16037 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16038 fmt
= (ctx
->opcode
>> 9) & 0x3;
16039 switch ((ctx
->opcode
>> 6) & 0x7) {
16043 mips32_op
= OPC_RSQRT2_S
;
16046 mips32_op
= OPC_RSQRT2_D
;
16049 mips32_op
= OPC_RSQRT2_PS
;
16052 goto pool32f_invalid
;
16058 mips32_op
= OPC_RECIP2_S
;
16061 mips32_op
= OPC_RECIP2_D
;
16064 mips32_op
= OPC_RECIP2_PS
;
16067 goto pool32f_invalid
;
16071 mips32_op
= OPC_ADDR_PS
;
16074 mips32_op
= OPC_MULR_PS
;
16076 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
16079 goto pool32f_invalid
;
16083 /* MOV[FT].fmt, PREFX, RINT.fmt, CLASS.fmt*/
16084 cc
= (ctx
->opcode
>> 13) & 0x7;
16085 fmt
= (ctx
->opcode
>> 9) & 0x3;
16086 switch ((ctx
->opcode
>> 6) & 0x7) {
16087 case MOVF_FMT
: /* RINT_FMT */
16088 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16092 gen_farith(ctx
, OPC_RINT_S
, 0, rt
, rs
, 0);
16095 gen_farith(ctx
, OPC_RINT_D
, 0, rt
, rs
, 0);
16098 goto pool32f_invalid
;
16104 gen_movcf_s(ctx
, rs
, rt
, cc
, 0);
16107 gen_movcf_d(ctx
, rs
, rt
, cc
, 0);
16111 gen_movcf_ps(ctx
, rs
, rt
, cc
, 0);
16114 goto pool32f_invalid
;
16118 case MOVT_FMT
: /* CLASS_FMT */
16119 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16123 gen_farith(ctx
, OPC_CLASS_S
, 0, rt
, rs
, 0);
16126 gen_farith(ctx
, OPC_CLASS_D
, 0, rt
, rs
, 0);
16129 goto pool32f_invalid
;
16135 gen_movcf_s(ctx
, rs
, rt
, cc
, 1);
16138 gen_movcf_d(ctx
, rs
, rt
, cc
, 1);
16142 gen_movcf_ps(ctx
, rs
, rt
, cc
, 1);
16145 goto pool32f_invalid
;
16150 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16153 goto pool32f_invalid
;
16156 #define FINSN_3ARG_SDPS(prfx) \
16157 switch ((ctx->opcode >> 8) & 0x3) { \
16159 mips32_op = OPC_##prfx##_S; \
16162 mips32_op = OPC_##prfx##_D; \
16164 case FMT_SDPS_PS: \
16166 mips32_op = OPC_##prfx##_PS; \
16169 goto pool32f_invalid; \
16172 check_insn(ctx
, ISA_MIPS_R6
);
16173 switch ((ctx
->opcode
>> 9) & 0x3) {
16175 gen_farith(ctx
, OPC_MINA_S
, rt
, rs
, rd
, 0);
16178 gen_farith(ctx
, OPC_MINA_D
, rt
, rs
, rd
, 0);
16181 goto pool32f_invalid
;
16185 check_insn(ctx
, ISA_MIPS_R6
);
16186 switch ((ctx
->opcode
>> 9) & 0x3) {
16188 gen_farith(ctx
, OPC_MAXA_S
, rt
, rs
, rd
, 0);
16191 gen_farith(ctx
, OPC_MAXA_D
, rt
, rs
, rd
, 0);
16194 goto pool32f_invalid
;
16198 /* regular FP ops */
16199 switch ((ctx
->opcode
>> 6) & 0x3) {
16201 FINSN_3ARG_SDPS(ADD
);
16204 FINSN_3ARG_SDPS(SUB
);
16207 FINSN_3ARG_SDPS(MUL
);
16210 fmt
= (ctx
->opcode
>> 8) & 0x3;
16212 mips32_op
= OPC_DIV_D
;
16213 } else if (fmt
== 0) {
16214 mips32_op
= OPC_DIV_S
;
16216 goto pool32f_invalid
;
16220 goto pool32f_invalid
;
16225 switch ((ctx
->opcode
>> 6) & 0x7) {
16226 case MOVN_FMT
: /* SELEQZ_FMT */
16227 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16229 switch ((ctx
->opcode
>> 9) & 0x3) {
16231 gen_sel_s(ctx
, OPC_SELEQZ_S
, rd
, rt
, rs
);
16234 gen_sel_d(ctx
, OPC_SELEQZ_D
, rd
, rt
, rs
);
16237 goto pool32f_invalid
;
16241 FINSN_3ARG_SDPS(MOVN
);
16245 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16246 FINSN_3ARG_SDPS(MOVN
);
16248 case MOVZ_FMT
: /* SELNEZ_FMT */
16249 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16251 switch ((ctx
->opcode
>> 9) & 0x3) {
16253 gen_sel_s(ctx
, OPC_SELNEZ_S
, rd
, rt
, rs
);
16256 gen_sel_d(ctx
, OPC_SELNEZ_D
, rd
, rt
, rs
);
16259 goto pool32f_invalid
;
16263 FINSN_3ARG_SDPS(MOVZ
);
16267 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16268 FINSN_3ARG_SDPS(MOVZ
);
16271 check_insn(ctx
, ISA_MIPS_R6
);
16272 switch ((ctx
->opcode
>> 9) & 0x3) {
16274 gen_sel_s(ctx
, OPC_SEL_S
, rd
, rt
, rs
);
16277 gen_sel_d(ctx
, OPC_SEL_D
, rd
, rt
, rs
);
16280 goto pool32f_invalid
;
16284 check_insn(ctx
, ISA_MIPS_R6
);
16285 switch ((ctx
->opcode
>> 9) & 0x3) {
16287 mips32_op
= OPC_MADDF_S
;
16290 mips32_op
= OPC_MADDF_D
;
16293 goto pool32f_invalid
;
16297 check_insn(ctx
, ISA_MIPS_R6
);
16298 switch ((ctx
->opcode
>> 9) & 0x3) {
16300 mips32_op
= OPC_MSUBF_S
;
16303 mips32_op
= OPC_MSUBF_D
;
16306 goto pool32f_invalid
;
16310 goto pool32f_invalid
;
16314 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
16318 MIPS_INVAL("pool32f");
16319 gen_reserved_instruction(ctx
);
16323 generate_exception_err(ctx
, EXCP_CpU
, 1);
16327 minor
= (ctx
->opcode
>> 21) & 0x1f;
16330 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16331 gen_compute_branch(ctx
, OPC_BLTZ
, 4, rs
, -1, imm
<< 1, 4);
16334 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16335 gen_compute_branch(ctx
, OPC_BLTZAL
, 4, rs
, -1, imm
<< 1, 4);
16336 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
16339 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16340 gen_compute_branch(ctx
, OPC_BLTZAL
, 4, rs
, -1, imm
<< 1, 2);
16341 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
16344 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16345 gen_compute_branch(ctx
, OPC_BGEZ
, 4, rs
, -1, imm
<< 1, 4);
16348 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16349 gen_compute_branch(ctx
, OPC_BGEZAL
, 4, rs
, -1, imm
<< 1, 4);
16350 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
16353 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16354 gen_compute_branch(ctx
, OPC_BGEZAL
, 4, rs
, -1, imm
<< 1, 2);
16355 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
16358 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16359 gen_compute_branch(ctx
, OPC_BLEZ
, 4, rs
, -1, imm
<< 1, 4);
16362 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16363 gen_compute_branch(ctx
, OPC_BGTZ
, 4, rs
, -1, imm
<< 1, 4);
16367 case TLTI
: /* BC1EQZC */
16368 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16370 check_cp1_enabled(ctx
);
16371 gen_compute_branch1_r6(ctx
, OPC_BC1EQZ
, rs
, imm
<< 1, 0);
16374 mips32_op
= OPC_TLTI
;
16378 case TGEI
: /* BC1NEZC */
16379 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16381 check_cp1_enabled(ctx
);
16382 gen_compute_branch1_r6(ctx
, OPC_BC1NEZ
, rs
, imm
<< 1, 0);
16385 mips32_op
= OPC_TGEI
;
16390 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16391 mips32_op
= OPC_TLTIU
;
16394 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16395 mips32_op
= OPC_TGEIU
;
16397 case TNEI
: /* SYNCI */
16398 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16401 * Break the TB to be able to sync copied instructions
16404 ctx
->base
.is_jmp
= DISAS_STOP
;
16407 mips32_op
= OPC_TNEI
;
16412 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16413 mips32_op
= OPC_TEQI
;
16415 gen_trap(ctx
, mips32_op
, rs
, -1, imm
);
16420 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16421 gen_compute_branch(ctx
, minor
== BNEZC
? OPC_BNE
: OPC_BEQ
,
16422 4, rs
, 0, imm
<< 1, 0);
16424 * Compact branches don't have a delay slot, so just let
16425 * the normal delay slot handling take us to the branch
16430 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16431 gen_logic_imm(ctx
, OPC_LUI
, rs
, 0, imm
);
16434 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16436 * Break the TB to be able to sync copied instructions
16439 ctx
->base
.is_jmp
= DISAS_STOP
;
16443 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16444 /* COP2: Not implemented. */
16445 generate_exception_err(ctx
, EXCP_CpU
, 2);
16448 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16449 mips32_op
= (ctx
->opcode
& (1 << 16)) ? OPC_BC1FANY2
: OPC_BC1F
;
16452 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16453 mips32_op
= (ctx
->opcode
& (1 << 16)) ? OPC_BC1TANY2
: OPC_BC1T
;
16456 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16457 mips32_op
= OPC_BC1FANY4
;
16460 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16461 mips32_op
= OPC_BC1TANY4
;
16464 check_insn(ctx
, ASE_MIPS3D
);
16467 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
16468 check_cp1_enabled(ctx
);
16469 gen_compute_branch1(ctx
, mips32_op
,
16470 (ctx
->opcode
>> 18) & 0x7, imm
<< 1);
16472 generate_exception_err(ctx
, EXCP_CpU
, 1);
16477 /* MIPS DSP: not implemented */
16480 MIPS_INVAL("pool32i");
16481 gen_reserved_instruction(ctx
);
16486 minor
= (ctx
->opcode
>> 12) & 0xf;
16487 offset
= sextract32(ctx
->opcode
, 0,
16488 (ctx
->insn_flags
& ISA_MIPS_R6
) ? 9 : 12);
16491 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16492 mips32_op
= OPC_LWL
;
16495 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16496 mips32_op
= OPC_SWL
;
16499 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16500 mips32_op
= OPC_LWR
;
16503 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16504 mips32_op
= OPC_SWR
;
16506 #if defined(TARGET_MIPS64)
16508 check_insn(ctx
, ISA_MIPS3
);
16509 check_mips_64(ctx
);
16510 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16511 mips32_op
= OPC_LDL
;
16514 check_insn(ctx
, ISA_MIPS3
);
16515 check_mips_64(ctx
);
16516 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16517 mips32_op
= OPC_SDL
;
16520 check_insn(ctx
, ISA_MIPS3
);
16521 check_mips_64(ctx
);
16522 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16523 mips32_op
= OPC_LDR
;
16526 check_insn(ctx
, ISA_MIPS3
);
16527 check_mips_64(ctx
);
16528 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16529 mips32_op
= OPC_SDR
;
16532 check_insn(ctx
, ISA_MIPS3
);
16533 check_mips_64(ctx
);
16534 mips32_op
= OPC_LWU
;
16537 check_insn(ctx
, ISA_MIPS3
);
16538 check_mips_64(ctx
);
16539 mips32_op
= OPC_LLD
;
16543 mips32_op
= OPC_LL
;
16546 gen_ld(ctx
, mips32_op
, rt
, rs
, offset
);
16549 gen_st(ctx
, mips32_op
, rt
, rs
, offset
);
16552 gen_st_cond(ctx
, rt
, rs
, offset
, MO_TESL
, false);
16554 #if defined(TARGET_MIPS64)
16556 check_insn(ctx
, ISA_MIPS3
);
16557 check_mips_64(ctx
);
16558 gen_st_cond(ctx
, rt
, rs
, offset
, MO_TEQ
, false);
16563 MIPS_INVAL("pool32c ld-eva");
16564 gen_reserved_instruction(ctx
);
16567 check_cp0_enabled(ctx
);
16569 minor2
= (ctx
->opcode
>> 9) & 0x7;
16570 offset
= sextract32(ctx
->opcode
, 0, 9);
16573 mips32_op
= OPC_LBUE
;
16576 mips32_op
= OPC_LHUE
;
16579 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16580 mips32_op
= OPC_LWLE
;
16583 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16584 mips32_op
= OPC_LWRE
;
16587 mips32_op
= OPC_LBE
;
16590 mips32_op
= OPC_LHE
;
16593 mips32_op
= OPC_LLE
;
16596 mips32_op
= OPC_LWE
;
16602 MIPS_INVAL("pool32c st-eva");
16603 gen_reserved_instruction(ctx
);
16606 check_cp0_enabled(ctx
);
16608 minor2
= (ctx
->opcode
>> 9) & 0x7;
16609 offset
= sextract32(ctx
->opcode
, 0, 9);
16612 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16613 mips32_op
= OPC_SWLE
;
16616 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16617 mips32_op
= OPC_SWRE
;
16620 /* Treat as no-op */
16621 if ((ctx
->insn_flags
& ISA_MIPS_R6
) && (rt
>= 24)) {
16622 /* hint codes 24-31 are reserved and signal RI */
16623 generate_exception(ctx
, EXCP_RI
);
16627 /* Treat as no-op */
16628 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
16629 gen_cache_operation(ctx
, rt
, rs
, offset
);
16633 mips32_op
= OPC_SBE
;
16636 mips32_op
= OPC_SHE
;
16639 gen_st_cond(ctx
, rt
, rs
, offset
, MO_TESL
, true);
16642 mips32_op
= OPC_SWE
;
16647 /* Treat as no-op */
16648 if ((ctx
->insn_flags
& ISA_MIPS_R6
) && (rt
>= 24)) {
16649 /* hint codes 24-31 are reserved and signal RI */
16650 generate_exception(ctx
, EXCP_RI
);
16654 MIPS_INVAL("pool32c");
16655 gen_reserved_instruction(ctx
);
16659 case ADDI32
: /* AUI, LUI */
16660 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16662 gen_logic_imm(ctx
, OPC_LUI
, rt
, rs
, imm
);
16665 mips32_op
= OPC_ADDI
;
16670 mips32_op
= OPC_ADDIU
;
16672 gen_arith_imm(ctx
, mips32_op
, rt
, rs
, imm
);
16675 /* Logical operations */
16677 mips32_op
= OPC_ORI
;
16680 mips32_op
= OPC_XORI
;
16683 mips32_op
= OPC_ANDI
;
16685 gen_logic_imm(ctx
, mips32_op
, rt
, rs
, imm
);
16688 /* Set less than immediate */
16690 mips32_op
= OPC_SLTI
;
16693 mips32_op
= OPC_SLTIU
;
16695 gen_slt_imm(ctx
, mips32_op
, rt
, rs
, imm
);
16698 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16699 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
16700 gen_compute_branch(ctx
, OPC_JALX
, 4, rt
, rs
, offset
, 4);
16701 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
16703 case JALS32
: /* BOVC, BEQC, BEQZALC */
16704 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16707 mips32_op
= OPC_BOVC
;
16708 } else if (rs
< rt
&& rs
== 0) {
16710 mips32_op
= OPC_BEQZALC
;
16713 mips32_op
= OPC_BEQC
;
16715 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
16718 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1;
16719 gen_compute_branch(ctx
, OPC_JAL
, 4, rt
, rs
, offset
, 2);
16720 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
16723 case BEQ32
: /* BC */
16724 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16726 gen_compute_compact_branch(ctx
, OPC_BC
, 0, 0,
16727 sextract32(ctx
->opcode
<< 1, 0, 27));
16730 gen_compute_branch(ctx
, OPC_BEQ
, 4, rt
, rs
, imm
<< 1, 4);
16733 case BNE32
: /* BALC */
16734 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16736 gen_compute_compact_branch(ctx
, OPC_BALC
, 0, 0,
16737 sextract32(ctx
->opcode
<< 1, 0, 27));
16740 gen_compute_branch(ctx
, OPC_BNE
, 4, rt
, rs
, imm
<< 1, 4);
16743 case J32
: /* BGTZC, BLTZC, BLTC */
16744 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16745 if (rs
== 0 && rt
!= 0) {
16747 mips32_op
= OPC_BGTZC
;
16748 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
16750 mips32_op
= OPC_BLTZC
;
16753 mips32_op
= OPC_BLTC
;
16755 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
16758 gen_compute_branch(ctx
, OPC_J
, 4, rt
, rs
,
16759 (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1, 4);
16762 case JAL32
: /* BLEZC, BGEZC, BGEC */
16763 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16764 if (rs
== 0 && rt
!= 0) {
16766 mips32_op
= OPC_BLEZC
;
16767 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
16769 mips32_op
= OPC_BGEZC
;
16772 mips32_op
= OPC_BGEC
;
16774 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
16777 gen_compute_branch(ctx
, OPC_JAL
, 4, rt
, rs
,
16778 (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1, 4);
16779 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
16782 /* Floating point (COP1) */
16784 mips32_op
= OPC_LWC1
;
16787 mips32_op
= OPC_LDC1
;
16790 mips32_op
= OPC_SWC1
;
16793 mips32_op
= OPC_SDC1
;
16795 gen_cop1_ldst(ctx
, mips32_op
, rt
, rs
, imm
);
16797 case ADDIUPC
: /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
16798 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16799 /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
16800 switch ((ctx
->opcode
>> 16) & 0x1f) {
16809 gen_pcrel(ctx
, OPC_ADDIUPC
, ctx
->base
.pc_next
& ~0x3, rt
);
16812 gen_pcrel(ctx
, OPC_AUIPC
, ctx
->base
.pc_next
, rt
);
16815 gen_pcrel(ctx
, OPC_ALUIPC
, ctx
->base
.pc_next
, rt
);
16825 gen_pcrel(ctx
, R6_OPC_LWPC
, ctx
->base
.pc_next
& ~0x3, rt
);
16828 generate_exception(ctx
, EXCP_RI
);
16833 int reg
= mmreg(ZIMM(ctx
->opcode
, 23, 3));
16834 offset
= SIMM(ctx
->opcode
, 0, 23) << 2;
16836 gen_addiupc(ctx
, reg
, offset
, 0, 0);
16839 case BNVC
: /* BNEC, BNEZALC */
16840 check_insn(ctx
, ISA_MIPS_R6
);
16843 mips32_op
= OPC_BNVC
;
16844 } else if (rs
< rt
&& rs
== 0) {
16846 mips32_op
= OPC_BNEZALC
;
16849 mips32_op
= OPC_BNEC
;
16851 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
16853 case R6_BNEZC
: /* JIALC */
16854 check_insn(ctx
, ISA_MIPS_R6
);
16857 gen_compute_compact_branch(ctx
, OPC_BNEZC
, rt
, 0,
16858 sextract32(ctx
->opcode
<< 1, 0, 22));
16861 gen_compute_compact_branch(ctx
, OPC_JIALC
, 0, rs
, imm
);
16864 case R6_BEQZC
: /* JIC */
16865 check_insn(ctx
, ISA_MIPS_R6
);
16868 gen_compute_compact_branch(ctx
, OPC_BEQZC
, rt
, 0,
16869 sextract32(ctx
->opcode
<< 1, 0, 22));
16872 gen_compute_compact_branch(ctx
, OPC_JIC
, 0, rs
, imm
);
16875 case BLEZALC
: /* BGEZALC, BGEUC */
16876 check_insn(ctx
, ISA_MIPS_R6
);
16877 if (rs
== 0 && rt
!= 0) {
16879 mips32_op
= OPC_BLEZALC
;
16880 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
16882 mips32_op
= OPC_BGEZALC
;
16885 mips32_op
= OPC_BGEUC
;
16887 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
16889 case BGTZALC
: /* BLTZALC, BLTUC */
16890 check_insn(ctx
, ISA_MIPS_R6
);
16891 if (rs
== 0 && rt
!= 0) {
16893 mips32_op
= OPC_BGTZALC
;
16894 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
16896 mips32_op
= OPC_BLTZALC
;
16899 mips32_op
= OPC_BLTUC
;
16901 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
16903 /* Loads and stores */
16905 mips32_op
= OPC_LB
;
16908 mips32_op
= OPC_LBU
;
16911 mips32_op
= OPC_LH
;
16914 mips32_op
= OPC_LHU
;
16917 mips32_op
= OPC_LW
;
16919 #ifdef TARGET_MIPS64
16921 check_insn(ctx
, ISA_MIPS3
);
16922 check_mips_64(ctx
);
16923 mips32_op
= OPC_LD
;
16926 check_insn(ctx
, ISA_MIPS3
);
16927 check_mips_64(ctx
);
16928 mips32_op
= OPC_SD
;
16932 mips32_op
= OPC_SB
;
16935 mips32_op
= OPC_SH
;
16938 mips32_op
= OPC_SW
;
16941 gen_ld(ctx
, mips32_op
, rt
, rs
, imm
);
16944 gen_st(ctx
, mips32_op
, rt
, rs
, imm
);
16947 gen_reserved_instruction(ctx
);
16952 static int decode_micromips_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
16956 /* make sure instructions are on a halfword boundary */
16957 if (ctx
->base
.pc_next
& 0x1) {
16958 env
->CP0_BadVAddr
= ctx
->base
.pc_next
;
16959 generate_exception_end(ctx
, EXCP_AdEL
);
16963 op
= (ctx
->opcode
>> 10) & 0x3f;
16964 /* Enforce properly-sized instructions in a delay slot */
16965 if (ctx
->hflags
& MIPS_HFLAG_BDS_STRICT
) {
16966 switch (op
& 0x7) { /* MSB-3..MSB-5 */
16968 /* POOL32A, POOL32B, POOL32I, POOL32C */
16970 /* ADDI32, ADDIU32, ORI32, XORI32, SLTI32, SLTIU32, ANDI32, JALX32 */
16972 /* LBU32, LHU32, POOL32F, JALS32, BEQ32, BNE32, J32, JAL32 */
16974 /* SB32, SH32, ADDIUPC, SWC132, SDC132, SW32 */
16976 /* LB32, LH32, LWC132, LDC132, LW32 */
16977 if (ctx
->hflags
& MIPS_HFLAG_BDS16
) {
16978 gen_reserved_instruction(ctx
);
16983 /* POOL16A, POOL16B, POOL16C, LWGP16, POOL16F */
16985 /* LBU16, LHU16, LWSP16, LW16, SB16, SH16, SWSP16, SW16 */
16987 /* MOVE16, ANDI16, POOL16D, POOL16E, BEQZ16, BNEZ16, B16, LI16 */
16988 if (ctx
->hflags
& MIPS_HFLAG_BDS32
) {
16989 gen_reserved_instruction(ctx
);
16999 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
17000 int rs1
= mmreg(uMIPS_RS1(ctx
->opcode
));
17001 int rs2
= mmreg(uMIPS_RS2(ctx
->opcode
));
17004 switch (ctx
->opcode
& 0x1) {
17012 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
17014 * In the Release 6, the register number location in
17015 * the instruction encoding has changed.
17017 gen_arith(ctx
, opc
, rs1
, rd
, rs2
);
17019 gen_arith(ctx
, opc
, rd
, rs1
, rs2
);
17025 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
17026 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
17027 int amount
= (ctx
->opcode
>> 1) & 0x7;
17029 amount
= amount
== 0 ? 8 : amount
;
17031 switch (ctx
->opcode
& 0x1) {
17040 gen_shift_imm(ctx
, opc
, rd
, rs
, amount
);
17044 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
17045 gen_pool16c_r6_insn(ctx
);
17047 gen_pool16c_insn(ctx
);
17052 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
17053 int rb
= 28; /* GP */
17054 int16_t offset
= SIMM(ctx
->opcode
, 0, 7) << 2;
17056 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
17060 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17061 if (ctx
->opcode
& 1) {
17062 gen_reserved_instruction(ctx
);
17065 int enc_dest
= uMIPS_RD(ctx
->opcode
);
17066 int enc_rt
= uMIPS_RS2(ctx
->opcode
);
17067 int enc_rs
= uMIPS_RS1(ctx
->opcode
);
17068 gen_movep(ctx
, enc_dest
, enc_rt
, enc_rs
);
17073 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
17074 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
17075 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4);
17076 offset
= (offset
== 0xf ? -1 : offset
);
17078 gen_ld(ctx
, OPC_LBU
, rd
, rb
, offset
);
17083 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
17084 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
17085 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 1;
17087 gen_ld(ctx
, OPC_LHU
, rd
, rb
, offset
);
17092 int rd
= (ctx
->opcode
>> 5) & 0x1f;
17093 int rb
= 29; /* SP */
17094 int16_t offset
= ZIMM(ctx
->opcode
, 0, 5) << 2;
17096 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
17101 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
17102 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
17103 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 2;
17105 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
17110 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
17111 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
17112 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4);
17114 gen_st(ctx
, OPC_SB
, rd
, rb
, offset
);
17119 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
17120 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
17121 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 1;
17123 gen_st(ctx
, OPC_SH
, rd
, rb
, offset
);
17128 int rd
= (ctx
->opcode
>> 5) & 0x1f;
17129 int rb
= 29; /* SP */
17130 int16_t offset
= ZIMM(ctx
->opcode
, 0, 5) << 2;
17132 gen_st(ctx
, OPC_SW
, rd
, rb
, offset
);
17137 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
17138 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
17139 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 2;
17141 gen_st(ctx
, OPC_SW
, rd
, rb
, offset
);
17146 int rd
= uMIPS_RD5(ctx
->opcode
);
17147 int rs
= uMIPS_RS5(ctx
->opcode
);
17149 gen_arith(ctx
, OPC_ADDU
, rd
, rs
, 0);
17156 switch (ctx
->opcode
& 0x1) {
17166 switch (ctx
->opcode
& 0x1) {
17171 gen_addiur1sp(ctx
);
17175 case B16
: /* BC16 */
17176 gen_compute_branch(ctx
, OPC_BEQ
, 2, 0, 0,
17177 sextract32(ctx
->opcode
, 0, 10) << 1,
17178 (ctx
->insn_flags
& ISA_MIPS_R6
) ? 0 : 4);
17180 case BNEZ16
: /* BNEZC16 */
17181 case BEQZ16
: /* BEQZC16 */
17182 gen_compute_branch(ctx
, op
== BNEZ16
? OPC_BNE
: OPC_BEQ
, 2,
17183 mmreg(uMIPS_RD(ctx
->opcode
)),
17184 0, sextract32(ctx
->opcode
, 0, 7) << 1,
17185 (ctx
->insn_flags
& ISA_MIPS_R6
) ? 0 : 4);
17190 int reg
= mmreg(uMIPS_RD(ctx
->opcode
));
17191 int imm
= ZIMM(ctx
->opcode
, 0, 7);
17193 imm
= (imm
== 0x7f ? -1 : imm
);
17194 tcg_gen_movi_tl(cpu_gpr
[reg
], imm
);
17200 gen_reserved_instruction(ctx
);
17203 decode_micromips32_opc(env
, ctx
);
17216 /* MAJOR, P16, and P32 pools opcodes */
17220 NM_MOVE_BALC
= 0x02,
17228 NM_P16_SHIFT
= 0x0c,
17246 NM_P_LS_U12
= 0x21,
17256 NM_P16_ADDU
= 0x2c,
17270 NM_MOVEPREV
= 0x3f,
17273 /* POOL32A instruction pool */
17275 NM_POOL32A0
= 0x00,
17276 NM_SPECIAL2
= 0x01,
17279 NM_POOL32A5
= 0x05,
17280 NM_POOL32A7
= 0x07,
17283 /* P.GP.W instruction pool */
17285 NM_ADDIUGP_W
= 0x00,
17290 /* P48I instruction pool */
17294 NM_ADDIUGP48
= 0x02,
17295 NM_ADDIUPC48
= 0x03,
17300 /* P.U12 instruction pool */
17309 NM_ADDIUNEG
= 0x08,
17316 /* POOL32F instruction pool */
17318 NM_POOL32F_0
= 0x00,
17319 NM_POOL32F_3
= 0x03,
17320 NM_POOL32F_5
= 0x05,
17323 /* POOL32S instruction pool */
17325 NM_POOL32S_0
= 0x00,
17326 NM_POOL32S_4
= 0x04,
17329 /* P.LUI instruction pool */
17335 /* P.GP.BH instruction pool */
17340 NM_ADDIUGP_B
= 0x03,
17343 NM_P_GP_CP1
= 0x06,
17346 /* P.LS.U12 instruction pool */
17351 NM_P_PREFU12
= 0x03,
17364 /* P.LS.S9 instruction pool */
17370 NM_P_LS_UAWM
= 0x05,
17373 /* P.BAL instruction pool */
17379 /* P.J instruction pool */
17382 NM_JALRC_HB
= 0x01,
17383 NM_P_BALRSC
= 0x08,
17386 /* P.BR1 instruction pool */
17394 /* P.BR2 instruction pool */
17401 /* P.BRI instruction pool */
17413 /* P16.SHIFT instruction pool */
17419 /* POOL16C instruction pool */
17421 NM_POOL16C_0
= 0x00,
17425 /* P16.A1 instruction pool */
17427 NM_ADDIUR1SP
= 0x01,
17430 /* P16.A2 instruction pool */
17433 NM_P_ADDIURS5
= 0x01,
17436 /* P16.ADDU instruction pool */
17442 /* P16.SR instruction pool */
17445 NM_RESTORE_JRC16
= 0x01,
17448 /* P16.4X4 instruction pool */
17454 /* P16.LB instruction pool */
17461 /* P16.LH instruction pool */
17468 /* P.RI instruction pool */
17471 NM_P_SYSCALL
= 0x01,
17476 /* POOL32A0 instruction pool */
17511 NM_D_E_MT_VPE
= 0x56,
17519 /* CRC32 instruction pool */
17529 /* POOL32A5 instruction pool */
17531 NM_CMP_EQ_PH
= 0x00,
17532 NM_CMP_LT_PH
= 0x08,
17533 NM_CMP_LE_PH
= 0x10,
17534 NM_CMPGU_EQ_QB
= 0x18,
17535 NM_CMPGU_LT_QB
= 0x20,
17536 NM_CMPGU_LE_QB
= 0x28,
17537 NM_CMPGDU_EQ_QB
= 0x30,
17538 NM_CMPGDU_LT_QB
= 0x38,
17539 NM_CMPGDU_LE_QB
= 0x40,
17540 NM_CMPU_EQ_QB
= 0x48,
17541 NM_CMPU_LT_QB
= 0x50,
17542 NM_CMPU_LE_QB
= 0x58,
17543 NM_ADDQ_S_W
= 0x60,
17544 NM_SUBQ_S_W
= 0x68,
17548 NM_ADDQ_S_PH
= 0x01,
17549 NM_ADDQH_R_PH
= 0x09,
17550 NM_ADDQH_R_W
= 0x11,
17551 NM_ADDU_S_QB
= 0x19,
17552 NM_ADDU_S_PH
= 0x21,
17553 NM_ADDUH_R_QB
= 0x29,
17554 NM_SHRAV_R_PH
= 0x31,
17555 NM_SHRAV_R_QB
= 0x39,
17556 NM_SUBQ_S_PH
= 0x41,
17557 NM_SUBQH_R_PH
= 0x49,
17558 NM_SUBQH_R_W
= 0x51,
17559 NM_SUBU_S_QB
= 0x59,
17560 NM_SUBU_S_PH
= 0x61,
17561 NM_SUBUH_R_QB
= 0x69,
17562 NM_SHLLV_S_PH
= 0x71,
17563 NM_PRECR_SRA_R_PH_W
= 0x79,
17565 NM_MULEU_S_PH_QBL
= 0x12,
17566 NM_MULEU_S_PH_QBR
= 0x1a,
17567 NM_MULQ_RS_PH
= 0x22,
17568 NM_MULQ_S_PH
= 0x2a,
17569 NM_MULQ_RS_W
= 0x32,
17570 NM_MULQ_S_W
= 0x3a,
17573 NM_SHRAV_R_W
= 0x5a,
17574 NM_SHRLV_PH
= 0x62,
17575 NM_SHRLV_QB
= 0x6a,
17576 NM_SHLLV_QB
= 0x72,
17577 NM_SHLLV_S_W
= 0x7a,
17581 NM_MULEQ_S_W_PHL
= 0x04,
17582 NM_MULEQ_S_W_PHR
= 0x0c,
17584 NM_MUL_S_PH
= 0x05,
17585 NM_PRECR_QB_PH
= 0x0d,
17586 NM_PRECRQ_QB_PH
= 0x15,
17587 NM_PRECRQ_PH_W
= 0x1d,
17588 NM_PRECRQ_RS_PH_W
= 0x25,
17589 NM_PRECRQU_S_QB_PH
= 0x2d,
17590 NM_PACKRL_PH
= 0x35,
17594 NM_SHRA_R_W
= 0x5e,
17595 NM_SHRA_R_PH
= 0x66,
17596 NM_SHLL_S_PH
= 0x76,
17597 NM_SHLL_S_W
= 0x7e,
17602 /* POOL32A7 instruction pool */
17607 NM_POOL32AXF
= 0x07,
17610 /* P.SR instruction pool */
17616 /* P.SHIFT instruction pool */
17624 /* P.ROTX instruction pool */
17629 /* P.INS instruction pool */
17634 /* P.EXT instruction pool */
17639 /* POOL32F_0 (fmt) instruction pool */
17644 NM_SELEQZ_S
= 0x07,
17645 NM_SELEQZ_D
= 0x47,
17649 NM_SELNEZ_S
= 0x0f,
17650 NM_SELNEZ_D
= 0x4f,
17665 /* POOL32F_3 instruction pool */
17669 NM_MINA_FMT
= 0x04,
17670 NM_MAXA_FMT
= 0x05,
17671 NM_POOL32FXF
= 0x07,
17674 /* POOL32F_5 instruction pool */
17676 NM_CMP_CONDN_S
= 0x00,
17677 NM_CMP_CONDN_D
= 0x02,
17680 /* P.GP.LH instruction pool */
17686 /* P.GP.SH instruction pool */
17691 /* P.GP.CP1 instruction pool */
17699 /* P.LS.S0 instruction pool */
17716 NM_P_PREFS9
= 0x03,
17722 /* P.LS.S1 instruction pool */
17724 NM_ASET_ACLR
= 0x02,
17732 /* P.LS.E0 instruction pool */
17748 /* P.PREFE instruction pool */
17754 /* P.LLE instruction pool */
17760 /* P.SCE instruction pool */
17766 /* P.LS.WM instruction pool */
17772 /* P.LS.UAWM instruction pool */
17778 /* P.BR3A instruction pool */
17784 NM_BPOSGE32C
= 0x04,
17787 /* P16.RI instruction pool */
17789 NM_P16_SYSCALL
= 0x01,
17794 /* POOL16C_0 instruction pool */
17796 NM_POOL16C_00
= 0x00,
17799 /* P16.JRC instruction pool */
17805 /* P.SYSCALL instruction pool */
17811 /* P.TRAP instruction pool */
17817 /* P.CMOVE instruction pool */
17823 /* POOL32Axf instruction pool */
17825 NM_POOL32AXF_1
= 0x01,
17826 NM_POOL32AXF_2
= 0x02,
17827 NM_POOL32AXF_4
= 0x04,
17828 NM_POOL32AXF_5
= 0x05,
17829 NM_POOL32AXF_7
= 0x07,
17832 /* POOL32Axf_1 instruction pool */
17834 NM_POOL32AXF_1_0
= 0x00,
17835 NM_POOL32AXF_1_1
= 0x01,
17836 NM_POOL32AXF_1_3
= 0x03,
17837 NM_POOL32AXF_1_4
= 0x04,
17838 NM_POOL32AXF_1_5
= 0x05,
17839 NM_POOL32AXF_1_7
= 0x07,
17842 /* POOL32Axf_2 instruction pool */
17844 NM_POOL32AXF_2_0_7
= 0x00,
17845 NM_POOL32AXF_2_8_15
= 0x01,
17846 NM_POOL32AXF_2_16_23
= 0x02,
17847 NM_POOL32AXF_2_24_31
= 0x03,
17850 /* POOL32Axf_7 instruction pool */
17852 NM_SHRA_R_QB
= 0x0,
17857 /* POOL32Axf_1_0 instruction pool */
17865 /* POOL32Axf_1_1 instruction pool */
17871 /* POOL32Axf_1_3 instruction pool */
17879 /* POOL32Axf_1_4 instruction pool */
17885 /* POOL32Axf_1_5 instruction pool */
17887 NM_MAQ_S_W_PHR
= 0x0,
17888 NM_MAQ_S_W_PHL
= 0x1,
17889 NM_MAQ_SA_W_PHR
= 0x2,
17890 NM_MAQ_SA_W_PHL
= 0x3,
17893 /* POOL32Axf_1_7 instruction pool */
17897 NM_EXTR_RS_W
= 0x2,
17901 /* POOL32Axf_2_0_7 instruction pool */
17904 NM_DPAQ_S_W_PH
= 0x1,
17906 NM_DPSQ_S_W_PH
= 0x3,
17913 /* POOL32Axf_2_8_15 instruction pool */
17915 NM_DPAX_W_PH
= 0x0,
17916 NM_DPAQ_SA_L_W
= 0x1,
17917 NM_DPSX_W_PH
= 0x2,
17918 NM_DPSQ_SA_L_W
= 0x3,
17921 NM_EXTRV_R_W
= 0x7,
17924 /* POOL32Axf_2_16_23 instruction pool */
17926 NM_DPAU_H_QBL
= 0x0,
17927 NM_DPAQX_S_W_PH
= 0x1,
17928 NM_DPSU_H_QBL
= 0x2,
17929 NM_DPSQX_S_W_PH
= 0x3,
17932 NM_MULSA_W_PH
= 0x6,
17933 NM_EXTRV_RS_W
= 0x7,
17936 /* POOL32Axf_2_24_31 instruction pool */
17938 NM_DPAU_H_QBR
= 0x0,
17939 NM_DPAQX_SA_W_PH
= 0x1,
17940 NM_DPSU_H_QBR
= 0x2,
17941 NM_DPSQX_SA_W_PH
= 0x3,
17944 NM_MULSAQ_S_W_PH
= 0x6,
17945 NM_EXTRV_S_H
= 0x7,
17948 /* POOL32Axf_{4, 5} instruction pool */
17967 /* nanoMIPS DSP instructions */
17968 NM_ABSQ_S_QB
= 0x00,
17969 NM_ABSQ_S_PH
= 0x08,
17970 NM_ABSQ_S_W
= 0x10,
17971 NM_PRECEQ_W_PHL
= 0x28,
17972 NM_PRECEQ_W_PHR
= 0x30,
17973 NM_PRECEQU_PH_QBL
= 0x38,
17974 NM_PRECEQU_PH_QBR
= 0x48,
17975 NM_PRECEU_PH_QBL
= 0x58,
17976 NM_PRECEU_PH_QBR
= 0x68,
17977 NM_PRECEQU_PH_QBLA
= 0x39,
17978 NM_PRECEQU_PH_QBRA
= 0x49,
17979 NM_PRECEU_PH_QBLA
= 0x59,
17980 NM_PRECEU_PH_QBRA
= 0x69,
17981 NM_REPLV_PH
= 0x01,
17982 NM_REPLV_QB
= 0x09,
17985 NM_RADDU_W_QB
= 0x78,
17991 /* PP.SR instruction pool */
17995 NM_RESTORE_JRC
= 0x03,
17998 /* P.SR.F instruction pool */
18001 NM_RESTOREF
= 0x01,
18004 /* P16.SYSCALL instruction pool */
18006 NM_SYSCALL16
= 0x00,
18007 NM_HYPCALL16
= 0x01,
18010 /* POOL16C_00 instruction pool */
18018 /* PP.LSX and PP.LSXS instruction pool */
18056 /* ERETx instruction pool */
18062 /* POOL32FxF_{0, 1} insturction pool */
18071 NM_CVT_S_PL
= 0x84,
18072 NM_CVT_S_PU
= 0xa4,
18074 NM_CVT_L_S
= 0x004,
18075 NM_CVT_L_D
= 0x104,
18076 NM_CVT_W_S
= 0x024,
18077 NM_CVT_W_D
= 0x124,
18079 NM_RSQRT_S
= 0x008,
18080 NM_RSQRT_D
= 0x108,
18085 NM_RECIP_S
= 0x048,
18086 NM_RECIP_D
= 0x148,
18088 NM_FLOOR_L_S
= 0x00c,
18089 NM_FLOOR_L_D
= 0x10c,
18091 NM_FLOOR_W_S
= 0x02c,
18092 NM_FLOOR_W_D
= 0x12c,
18094 NM_CEIL_L_S
= 0x04c,
18095 NM_CEIL_L_D
= 0x14c,
18096 NM_CEIL_W_S
= 0x06c,
18097 NM_CEIL_W_D
= 0x16c,
18098 NM_TRUNC_L_S
= 0x08c,
18099 NM_TRUNC_L_D
= 0x18c,
18100 NM_TRUNC_W_S
= 0x0ac,
18101 NM_TRUNC_W_D
= 0x1ac,
18102 NM_ROUND_L_S
= 0x0cc,
18103 NM_ROUND_L_D
= 0x1cc,
18104 NM_ROUND_W_S
= 0x0ec,
18105 NM_ROUND_W_D
= 0x1ec,
18113 NM_CVT_D_S
= 0x04d,
18114 NM_CVT_D_W
= 0x0cd,
18115 NM_CVT_D_L
= 0x14d,
18116 NM_CVT_S_D
= 0x06d,
18117 NM_CVT_S_W
= 0x0ed,
18118 NM_CVT_S_L
= 0x16d,
18121 /* P.LL instruction pool */
18127 /* P.SC instruction pool */
18133 /* P.DVP instruction pool */
18142 * nanoMIPS decoding engine
18147 /* extraction utilities */
18149 #define NANOMIPS_EXTRACT_RT3(op) ((op >> 7) & 0x7)
18150 #define NANOMIPS_EXTRACT_RS3(op) ((op >> 4) & 0x7)
18151 #define NANOMIPS_EXTRACT_RD3(op) ((op >> 1) & 0x7)
18152 #define NANOMIPS_EXTRACT_RD5(op) ((op >> 5) & 0x1f)
18153 #define NANOMIPS_EXTRACT_RS5(op) (op & 0x1f)
18155 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3'). */
18156 static inline int decode_gpr_gpr3(int r
)
18158 static const int map
[] = { 16, 17, 18, 19, 4, 5, 6, 7 };
18160 return map
[r
& 0x7];
18163 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3.src.store'). */
18164 static inline int decode_gpr_gpr3_src_store(int r
)
18166 static const int map
[] = { 0, 17, 18, 19, 4, 5, 6, 7 };
18168 return map
[r
& 0x7];
18171 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4'). */
18172 static inline int decode_gpr_gpr4(int r
)
18174 static const int map
[] = { 8, 9, 10, 11, 4, 5, 6, 7,
18175 16, 17, 18, 19, 20, 21, 22, 23 };
18177 return map
[r
& 0xf];
18180 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4.zero'). */
18181 static inline int decode_gpr_gpr4_zero(int r
)
18183 static const int map
[] = { 8, 9, 10, 0, 4, 5, 6, 7,
18184 16, 17, 18, 19, 20, 21, 22, 23 };
18186 return map
[r
& 0xf];
18190 static void gen_adjust_sp(DisasContext
*ctx
, int u
)
18192 gen_op_addr_addi(ctx
, cpu_gpr
[29], cpu_gpr
[29], u
);
18195 static void gen_save(DisasContext
*ctx
, uint8_t rt
, uint8_t count
,
18196 uint8_t gp
, uint16_t u
)
18199 TCGv va
= tcg_temp_new();
18200 TCGv t0
= tcg_temp_new();
18202 while (counter
!= count
) {
18203 bool use_gp
= gp
&& (counter
== count
- 1);
18204 int this_rt
= use_gp
? 28 : (rt
& 0x10) | ((rt
+ counter
) & 0x1f);
18205 int this_offset
= -((counter
+ 1) << 2);
18206 gen_base_offset_addr(ctx
, va
, 29, this_offset
);
18207 gen_load_gpr(t0
, this_rt
);
18208 tcg_gen_qemu_st_tl(t0
, va
, ctx
->mem_idx
,
18209 (MO_TEUL
| ctx
->default_tcg_memop_mask
));
18213 /* adjust stack pointer */
18214 gen_adjust_sp(ctx
, -u
);
18220 static void gen_restore(DisasContext
*ctx
, uint8_t rt
, uint8_t count
,
18221 uint8_t gp
, uint16_t u
)
18224 TCGv va
= tcg_temp_new();
18225 TCGv t0
= tcg_temp_new();
18227 while (counter
!= count
) {
18228 bool use_gp
= gp
&& (counter
== count
- 1);
18229 int this_rt
= use_gp
? 28 : (rt
& 0x10) | ((rt
+ counter
) & 0x1f);
18230 int this_offset
= u
- ((counter
+ 1) << 2);
18231 gen_base_offset_addr(ctx
, va
, 29, this_offset
);
18232 tcg_gen_qemu_ld_tl(t0
, va
, ctx
->mem_idx
, MO_TESL
|
18233 ctx
->default_tcg_memop_mask
);
18234 tcg_gen_ext32s_tl(t0
, t0
);
18235 gen_store_gpr(t0
, this_rt
);
18239 /* adjust stack pointer */
18240 gen_adjust_sp(ctx
, u
);
18246 static void gen_pool16c_nanomips_insn(DisasContext
*ctx
)
18248 int rt
= decode_gpr_gpr3(NANOMIPS_EXTRACT_RT3(ctx
->opcode
));
18249 int rs
= decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx
->opcode
));
18251 switch (extract32(ctx
->opcode
, 2, 2)) {
18253 gen_logic(ctx
, OPC_NOR
, rt
, rs
, 0);
18256 gen_logic(ctx
, OPC_AND
, rt
, rt
, rs
);
18259 gen_logic(ctx
, OPC_XOR
, rt
, rt
, rs
);
18262 gen_logic(ctx
, OPC_OR
, rt
, rt
, rs
);
18267 static void gen_pool32a0_nanomips_insn(CPUMIPSState
*env
, DisasContext
*ctx
)
18269 int rt
= extract32(ctx
->opcode
, 21, 5);
18270 int rs
= extract32(ctx
->opcode
, 16, 5);
18271 int rd
= extract32(ctx
->opcode
, 11, 5);
18273 switch (extract32(ctx
->opcode
, 3, 7)) {
18275 switch (extract32(ctx
->opcode
, 10, 1)) {
18278 gen_trap(ctx
, OPC_TEQ
, rs
, rt
, -1);
18282 gen_trap(ctx
, OPC_TNE
, rs
, rt
, -1);
18288 gen_rdhwr(ctx
, rt
, rs
, extract32(ctx
->opcode
, 11, 3));
18292 gen_bshfl(ctx
, OPC_SEB
, rs
, rt
);
18295 gen_bshfl(ctx
, OPC_SEH
, rs
, rt
);
18298 gen_shift(ctx
, OPC_SLLV
, rd
, rt
, rs
);
18301 gen_shift(ctx
, OPC_SRLV
, rd
, rt
, rs
);
18304 gen_shift(ctx
, OPC_SRAV
, rd
, rt
, rs
);
18307 gen_shift(ctx
, OPC_ROTRV
, rd
, rt
, rs
);
18310 gen_arith(ctx
, OPC_ADD
, rd
, rs
, rt
);
18313 gen_arith(ctx
, OPC_ADDU
, rd
, rs
, rt
);
18317 gen_arith(ctx
, OPC_SUB
, rd
, rs
, rt
);
18320 gen_arith(ctx
, OPC_SUBU
, rd
, rs
, rt
);
18323 switch (extract32(ctx
->opcode
, 10, 1)) {
18325 gen_cond_move(ctx
, OPC_MOVZ
, rd
, rs
, rt
);
18328 gen_cond_move(ctx
, OPC_MOVN
, rd
, rs
, rt
);
18333 gen_logic(ctx
, OPC_AND
, rd
, rs
, rt
);
18336 gen_logic(ctx
, OPC_OR
, rd
, rs
, rt
);
18339 gen_logic(ctx
, OPC_NOR
, rd
, rs
, rt
);
18342 gen_logic(ctx
, OPC_XOR
, rd
, rs
, rt
);
18345 gen_slt(ctx
, OPC_SLT
, rd
, rs
, rt
);
18350 #ifndef CONFIG_USER_ONLY
18351 TCGv t0
= tcg_temp_new();
18352 switch (extract32(ctx
->opcode
, 10, 1)) {
18355 check_cp0_enabled(ctx
);
18356 gen_helper_dvp(t0
, cpu_env
);
18357 gen_store_gpr(t0
, rt
);
18362 check_cp0_enabled(ctx
);
18363 gen_helper_evp(t0
, cpu_env
);
18364 gen_store_gpr(t0
, rt
);
18371 gen_slt(ctx
, OPC_SLTU
, rd
, rs
, rt
);
18376 TCGv t0
= tcg_temp_new();
18377 TCGv t1
= tcg_temp_new();
18378 TCGv t2
= tcg_temp_new();
18380 gen_load_gpr(t1
, rs
);
18381 gen_load_gpr(t2
, rt
);
18382 tcg_gen_add_tl(t0
, t1
, t2
);
18383 tcg_gen_ext32s_tl(t0
, t0
);
18384 tcg_gen_xor_tl(t1
, t1
, t2
);
18385 tcg_gen_xor_tl(t2
, t0
, t2
);
18386 tcg_gen_andc_tl(t1
, t2
, t1
);
18388 /* operands of same sign, result different sign */
18389 tcg_gen_setcondi_tl(TCG_COND_LT
, t0
, t1
, 0);
18390 gen_store_gpr(t0
, rd
);
18398 gen_r6_muldiv(ctx
, R6_OPC_MUL
, rd
, rs
, rt
);
18401 gen_r6_muldiv(ctx
, R6_OPC_MUH
, rd
, rs
, rt
);
18404 gen_r6_muldiv(ctx
, R6_OPC_MULU
, rd
, rs
, rt
);
18407 gen_r6_muldiv(ctx
, R6_OPC_MUHU
, rd
, rs
, rt
);
18410 gen_r6_muldiv(ctx
, R6_OPC_DIV
, rd
, rs
, rt
);
18413 gen_r6_muldiv(ctx
, R6_OPC_MOD
, rd
, rs
, rt
);
18416 gen_r6_muldiv(ctx
, R6_OPC_DIVU
, rd
, rs
, rt
);
18419 gen_r6_muldiv(ctx
, R6_OPC_MODU
, rd
, rs
, rt
);
18421 #ifndef CONFIG_USER_ONLY
18423 check_cp0_enabled(ctx
);
18425 /* Treat as NOP. */
18428 gen_mfc0(ctx
, cpu_gpr
[rt
], rs
, extract32(ctx
->opcode
, 11, 3));
18431 check_cp0_enabled(ctx
);
18433 TCGv t0
= tcg_temp_new();
18435 gen_load_gpr(t0
, rt
);
18436 gen_mtc0(ctx
, t0
, rs
, extract32(ctx
->opcode
, 11, 3));
18440 case NM_D_E_MT_VPE
:
18442 uint8_t sc
= extract32(ctx
->opcode
, 10, 1);
18443 TCGv t0
= tcg_temp_new();
18450 gen_helper_dmt(t0
);
18451 gen_store_gpr(t0
, rt
);
18452 } else if (rs
== 0) {
18455 gen_helper_dvpe(t0
, cpu_env
);
18456 gen_store_gpr(t0
, rt
);
18458 gen_reserved_instruction(ctx
);
18465 gen_helper_emt(t0
);
18466 gen_store_gpr(t0
, rt
);
18467 } else if (rs
== 0) {
18470 gen_helper_evpe(t0
, cpu_env
);
18471 gen_store_gpr(t0
, rt
);
18473 gen_reserved_instruction(ctx
);
18484 TCGv t0
= tcg_temp_new();
18485 TCGv t1
= tcg_temp_new();
18487 gen_load_gpr(t0
, rt
);
18488 gen_load_gpr(t1
, rs
);
18489 gen_helper_fork(t0
, t1
);
18496 check_cp0_enabled(ctx
);
18498 /* Treat as NOP. */
18501 gen_mftr(env
, ctx
, rs
, rt
, extract32(ctx
->opcode
, 10, 1),
18502 extract32(ctx
->opcode
, 11, 5), extract32(ctx
->opcode
, 3, 1));
18506 check_cp0_enabled(ctx
);
18507 gen_mttr(env
, ctx
, rs
, rt
, extract32(ctx
->opcode
, 10, 1),
18508 extract32(ctx
->opcode
, 11, 5), extract32(ctx
->opcode
, 3, 1));
18513 TCGv t0
= tcg_temp_new();
18515 gen_load_gpr(t0
, rs
);
18516 gen_helper_yield(t0
, cpu_env
, t0
);
18517 gen_store_gpr(t0
, rt
);
18523 gen_reserved_instruction(ctx
);
18529 static void gen_pool32axf_1_5_nanomips_insn(DisasContext
*ctx
, uint32_t opc
,
18530 int ret
, int v1
, int v2
)
18536 t0
= tcg_temp_new_i32();
18538 v0_t
= tcg_temp_new();
18539 v1_t
= tcg_temp_new();
18541 tcg_gen_movi_i32(t0
, v2
>> 3);
18543 gen_load_gpr(v0_t
, ret
);
18544 gen_load_gpr(v1_t
, v1
);
18547 case NM_MAQ_S_W_PHR
:
18549 gen_helper_maq_s_w_phr(t0
, v1_t
, v0_t
, cpu_env
);
18551 case NM_MAQ_S_W_PHL
:
18553 gen_helper_maq_s_w_phl(t0
, v1_t
, v0_t
, cpu_env
);
18555 case NM_MAQ_SA_W_PHR
:
18557 gen_helper_maq_sa_w_phr(t0
, v1_t
, v0_t
, cpu_env
);
18559 case NM_MAQ_SA_W_PHL
:
18561 gen_helper_maq_sa_w_phl(t0
, v1_t
, v0_t
, cpu_env
);
18564 gen_reserved_instruction(ctx
);
18568 tcg_temp_free_i32(t0
);
18570 tcg_temp_free(v0_t
);
18571 tcg_temp_free(v1_t
);
18575 static void gen_pool32axf_1_nanomips_insn(DisasContext
*ctx
, uint32_t opc
,
18576 int ret
, int v1
, int v2
)
18579 TCGv t0
= tcg_temp_new();
18580 TCGv t1
= tcg_temp_new();
18581 TCGv v0_t
= tcg_temp_new();
18583 gen_load_gpr(v0_t
, v1
);
18586 case NM_POOL32AXF_1_0
:
18588 switch (extract32(ctx
->opcode
, 12, 2)) {
18590 gen_HILO(ctx
, OPC_MFHI
, v2
>> 3, ret
);
18593 gen_HILO(ctx
, OPC_MFLO
, v2
>> 3, ret
);
18596 gen_HILO(ctx
, OPC_MTHI
, v2
>> 3, v1
);
18599 gen_HILO(ctx
, OPC_MTLO
, v2
>> 3, v1
);
18603 case NM_POOL32AXF_1_1
:
18605 switch (extract32(ctx
->opcode
, 12, 2)) {
18607 tcg_gen_movi_tl(t0
, v2
);
18608 gen_helper_mthlip(t0
, v0_t
, cpu_env
);
18611 tcg_gen_movi_tl(t0
, v2
>> 3);
18612 gen_helper_shilo(t0
, v0_t
, cpu_env
);
18615 gen_reserved_instruction(ctx
);
18619 case NM_POOL32AXF_1_3
:
18621 imm
= extract32(ctx
->opcode
, 14, 7);
18622 switch (extract32(ctx
->opcode
, 12, 2)) {
18624 tcg_gen_movi_tl(t0
, imm
);
18625 gen_helper_rddsp(t0
, t0
, cpu_env
);
18626 gen_store_gpr(t0
, ret
);
18629 gen_load_gpr(t0
, ret
);
18630 tcg_gen_movi_tl(t1
, imm
);
18631 gen_helper_wrdsp(t0
, t1
, cpu_env
);
18634 tcg_gen_movi_tl(t0
, v2
>> 3);
18635 tcg_gen_movi_tl(t1
, v1
);
18636 gen_helper_extp(t0
, t0
, t1
, cpu_env
);
18637 gen_store_gpr(t0
, ret
);
18640 tcg_gen_movi_tl(t0
, v2
>> 3);
18641 tcg_gen_movi_tl(t1
, v1
);
18642 gen_helper_extpdp(t0
, t0
, t1
, cpu_env
);
18643 gen_store_gpr(t0
, ret
);
18647 case NM_POOL32AXF_1_4
:
18649 tcg_gen_movi_tl(t0
, v2
>> 2);
18650 switch (extract32(ctx
->opcode
, 12, 1)) {
18652 gen_helper_shll_qb(t0
, t0
, v0_t
, cpu_env
);
18653 gen_store_gpr(t0
, ret
);
18656 gen_helper_shrl_qb(t0
, t0
, v0_t
);
18657 gen_store_gpr(t0
, ret
);
18661 case NM_POOL32AXF_1_5
:
18662 opc
= extract32(ctx
->opcode
, 12, 2);
18663 gen_pool32axf_1_5_nanomips_insn(ctx
, opc
, ret
, v1
, v2
);
18665 case NM_POOL32AXF_1_7
:
18667 tcg_gen_movi_tl(t0
, v2
>> 3);
18668 tcg_gen_movi_tl(t1
, v1
);
18669 switch (extract32(ctx
->opcode
, 12, 2)) {
18671 gen_helper_extr_w(t0
, t0
, t1
, cpu_env
);
18672 gen_store_gpr(t0
, ret
);
18675 gen_helper_extr_r_w(t0
, t0
, t1
, cpu_env
);
18676 gen_store_gpr(t0
, ret
);
18679 gen_helper_extr_rs_w(t0
, t0
, t1
, cpu_env
);
18680 gen_store_gpr(t0
, ret
);
18683 gen_helper_extr_s_h(t0
, t0
, t1
, cpu_env
);
18684 gen_store_gpr(t0
, ret
);
18689 gen_reserved_instruction(ctx
);
18695 tcg_temp_free(v0_t
);
18698 static void gen_pool32axf_2_multiply(DisasContext
*ctx
, uint32_t opc
,
18699 TCGv v0
, TCGv v1
, int rd
)
18703 t0
= tcg_temp_new_i32();
18705 tcg_gen_movi_i32(t0
, rd
>> 3);
18708 case NM_POOL32AXF_2_0_7
:
18709 switch (extract32(ctx
->opcode
, 9, 3)) {
18712 gen_helper_dpa_w_ph(t0
, v1
, v0
, cpu_env
);
18714 case NM_DPAQ_S_W_PH
:
18716 gen_helper_dpaq_s_w_ph(t0
, v1
, v0
, cpu_env
);
18720 gen_helper_dps_w_ph(t0
, v1
, v0
, cpu_env
);
18722 case NM_DPSQ_S_W_PH
:
18724 gen_helper_dpsq_s_w_ph(t0
, v1
, v0
, cpu_env
);
18727 gen_reserved_instruction(ctx
);
18731 case NM_POOL32AXF_2_8_15
:
18732 switch (extract32(ctx
->opcode
, 9, 3)) {
18735 gen_helper_dpax_w_ph(t0
, v0
, v1
, cpu_env
);
18737 case NM_DPAQ_SA_L_W
:
18739 gen_helper_dpaq_sa_l_w(t0
, v0
, v1
, cpu_env
);
18743 gen_helper_dpsx_w_ph(t0
, v0
, v1
, cpu_env
);
18745 case NM_DPSQ_SA_L_W
:
18747 gen_helper_dpsq_sa_l_w(t0
, v0
, v1
, cpu_env
);
18750 gen_reserved_instruction(ctx
);
18754 case NM_POOL32AXF_2_16_23
:
18755 switch (extract32(ctx
->opcode
, 9, 3)) {
18756 case NM_DPAU_H_QBL
:
18758 gen_helper_dpau_h_qbl(t0
, v0
, v1
, cpu_env
);
18760 case NM_DPAQX_S_W_PH
:
18762 gen_helper_dpaqx_s_w_ph(t0
, v0
, v1
, cpu_env
);
18764 case NM_DPSU_H_QBL
:
18766 gen_helper_dpsu_h_qbl(t0
, v0
, v1
, cpu_env
);
18768 case NM_DPSQX_S_W_PH
:
18770 gen_helper_dpsqx_s_w_ph(t0
, v0
, v1
, cpu_env
);
18772 case NM_MULSA_W_PH
:
18774 gen_helper_mulsa_w_ph(t0
, v0
, v1
, cpu_env
);
18777 gen_reserved_instruction(ctx
);
18781 case NM_POOL32AXF_2_24_31
:
18782 switch (extract32(ctx
->opcode
, 9, 3)) {
18783 case NM_DPAU_H_QBR
:
18785 gen_helper_dpau_h_qbr(t0
, v1
, v0
, cpu_env
);
18787 case NM_DPAQX_SA_W_PH
:
18789 gen_helper_dpaqx_sa_w_ph(t0
, v1
, v0
, cpu_env
);
18791 case NM_DPSU_H_QBR
:
18793 gen_helper_dpsu_h_qbr(t0
, v1
, v0
, cpu_env
);
18795 case NM_DPSQX_SA_W_PH
:
18797 gen_helper_dpsqx_sa_w_ph(t0
, v1
, v0
, cpu_env
);
18799 case NM_MULSAQ_S_W_PH
:
18801 gen_helper_mulsaq_s_w_ph(t0
, v1
, v0
, cpu_env
);
18804 gen_reserved_instruction(ctx
);
18809 gen_reserved_instruction(ctx
);
18813 tcg_temp_free_i32(t0
);
18816 static void gen_pool32axf_2_nanomips_insn(DisasContext
*ctx
, uint32_t opc
,
18817 int rt
, int rs
, int rd
)
18820 TCGv t0
= tcg_temp_new();
18821 TCGv t1
= tcg_temp_new();
18822 TCGv v0_t
= tcg_temp_new();
18823 TCGv v1_t
= tcg_temp_new();
18825 gen_load_gpr(v0_t
, rt
);
18826 gen_load_gpr(v1_t
, rs
);
18829 case NM_POOL32AXF_2_0_7
:
18830 switch (extract32(ctx
->opcode
, 9, 3)) {
18832 case NM_DPAQ_S_W_PH
:
18834 case NM_DPSQ_S_W_PH
:
18835 gen_pool32axf_2_multiply(ctx
, opc
, v0_t
, v1_t
, rd
);
18840 gen_load_gpr(t0
, rs
);
18842 if (rd
!= 0 && rd
!= 2) {
18843 tcg_gen_shli_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], 8 * rd
);
18844 tcg_gen_ext32u_tl(t0
, t0
);
18845 tcg_gen_shri_tl(t0
, t0
, 8 * (4 - rd
));
18846 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
18848 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
18854 int acc
= extract32(ctx
->opcode
, 14, 2);
18855 TCGv_i64 t2
= tcg_temp_new_i64();
18856 TCGv_i64 t3
= tcg_temp_new_i64();
18858 gen_load_gpr(t0
, rt
);
18859 gen_load_gpr(t1
, rs
);
18860 tcg_gen_ext_tl_i64(t2
, t0
);
18861 tcg_gen_ext_tl_i64(t3
, t1
);
18862 tcg_gen_mul_i64(t2
, t2
, t3
);
18863 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
18864 tcg_gen_add_i64(t2
, t2
, t3
);
18865 tcg_temp_free_i64(t3
);
18866 gen_move_low32(cpu_LO
[acc
], t2
);
18867 gen_move_high32(cpu_HI
[acc
], t2
);
18868 tcg_temp_free_i64(t2
);
18874 int acc
= extract32(ctx
->opcode
, 14, 2);
18875 TCGv_i32 t2
= tcg_temp_new_i32();
18876 TCGv_i32 t3
= tcg_temp_new_i32();
18878 gen_load_gpr(t0
, rs
);
18879 gen_load_gpr(t1
, rt
);
18880 tcg_gen_trunc_tl_i32(t2
, t0
);
18881 tcg_gen_trunc_tl_i32(t3
, t1
);
18882 tcg_gen_muls2_i32(t2
, t3
, t2
, t3
);
18883 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
18884 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
18885 tcg_temp_free_i32(t2
);
18886 tcg_temp_free_i32(t3
);
18891 gen_load_gpr(v1_t
, rs
);
18892 tcg_gen_movi_tl(t0
, rd
>> 3);
18893 gen_helper_extr_w(t0
, t0
, v1_t
, cpu_env
);
18894 gen_store_gpr(t0
, ret
);
18898 case NM_POOL32AXF_2_8_15
:
18899 switch (extract32(ctx
->opcode
, 9, 3)) {
18901 case NM_DPAQ_SA_L_W
:
18903 case NM_DPSQ_SA_L_W
:
18904 gen_pool32axf_2_multiply(ctx
, opc
, v0_t
, v1_t
, rd
);
18909 int acc
= extract32(ctx
->opcode
, 14, 2);
18910 TCGv_i64 t2
= tcg_temp_new_i64();
18911 TCGv_i64 t3
= tcg_temp_new_i64();
18913 gen_load_gpr(t0
, rs
);
18914 gen_load_gpr(t1
, rt
);
18915 tcg_gen_ext32u_tl(t0
, t0
);
18916 tcg_gen_ext32u_tl(t1
, t1
);
18917 tcg_gen_extu_tl_i64(t2
, t0
);
18918 tcg_gen_extu_tl_i64(t3
, t1
);
18919 tcg_gen_mul_i64(t2
, t2
, t3
);
18920 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
18921 tcg_gen_add_i64(t2
, t2
, t3
);
18922 tcg_temp_free_i64(t3
);
18923 gen_move_low32(cpu_LO
[acc
], t2
);
18924 gen_move_high32(cpu_HI
[acc
], t2
);
18925 tcg_temp_free_i64(t2
);
18931 int acc
= extract32(ctx
->opcode
, 14, 2);
18932 TCGv_i32 t2
= tcg_temp_new_i32();
18933 TCGv_i32 t3
= tcg_temp_new_i32();
18935 gen_load_gpr(t0
, rs
);
18936 gen_load_gpr(t1
, rt
);
18937 tcg_gen_trunc_tl_i32(t2
, t0
);
18938 tcg_gen_trunc_tl_i32(t3
, t1
);
18939 tcg_gen_mulu2_i32(t2
, t3
, t2
, t3
);
18940 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
18941 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
18942 tcg_temp_free_i32(t2
);
18943 tcg_temp_free_i32(t3
);
18948 tcg_gen_movi_tl(t0
, rd
>> 3);
18949 gen_helper_extr_r_w(t0
, t0
, v1_t
, cpu_env
);
18950 gen_store_gpr(t0
, ret
);
18953 gen_reserved_instruction(ctx
);
18957 case NM_POOL32AXF_2_16_23
:
18958 switch (extract32(ctx
->opcode
, 9, 3)) {
18959 case NM_DPAU_H_QBL
:
18960 case NM_DPAQX_S_W_PH
:
18961 case NM_DPSU_H_QBL
:
18962 case NM_DPSQX_S_W_PH
:
18963 case NM_MULSA_W_PH
:
18964 gen_pool32axf_2_multiply(ctx
, opc
, v0_t
, v1_t
, rd
);
18968 tcg_gen_movi_tl(t0
, rd
>> 3);
18969 gen_helper_extp(t0
, t0
, v1_t
, cpu_env
);
18970 gen_store_gpr(t0
, ret
);
18975 int acc
= extract32(ctx
->opcode
, 14, 2);
18976 TCGv_i64 t2
= tcg_temp_new_i64();
18977 TCGv_i64 t3
= tcg_temp_new_i64();
18979 gen_load_gpr(t0
, rs
);
18980 gen_load_gpr(t1
, rt
);
18981 tcg_gen_ext_tl_i64(t2
, t0
);
18982 tcg_gen_ext_tl_i64(t3
, t1
);
18983 tcg_gen_mul_i64(t2
, t2
, t3
);
18984 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
18985 tcg_gen_sub_i64(t2
, t3
, t2
);
18986 tcg_temp_free_i64(t3
);
18987 gen_move_low32(cpu_LO
[acc
], t2
);
18988 gen_move_high32(cpu_HI
[acc
], t2
);
18989 tcg_temp_free_i64(t2
);
18992 case NM_EXTRV_RS_W
:
18994 tcg_gen_movi_tl(t0
, rd
>> 3);
18995 gen_helper_extr_rs_w(t0
, t0
, v1_t
, cpu_env
);
18996 gen_store_gpr(t0
, ret
);
19000 case NM_POOL32AXF_2_24_31
:
19001 switch (extract32(ctx
->opcode
, 9, 3)) {
19002 case NM_DPAU_H_QBR
:
19003 case NM_DPAQX_SA_W_PH
:
19004 case NM_DPSU_H_QBR
:
19005 case NM_DPSQX_SA_W_PH
:
19006 case NM_MULSAQ_S_W_PH
:
19007 gen_pool32axf_2_multiply(ctx
, opc
, v0_t
, v1_t
, rd
);
19011 tcg_gen_movi_tl(t0
, rd
>> 3);
19012 gen_helper_extpdp(t0
, t0
, v1_t
, cpu_env
);
19013 gen_store_gpr(t0
, ret
);
19018 int acc
= extract32(ctx
->opcode
, 14, 2);
19019 TCGv_i64 t2
= tcg_temp_new_i64();
19020 TCGv_i64 t3
= tcg_temp_new_i64();
19022 gen_load_gpr(t0
, rs
);
19023 gen_load_gpr(t1
, rt
);
19024 tcg_gen_ext32u_tl(t0
, t0
);
19025 tcg_gen_ext32u_tl(t1
, t1
);
19026 tcg_gen_extu_tl_i64(t2
, t0
);
19027 tcg_gen_extu_tl_i64(t3
, t1
);
19028 tcg_gen_mul_i64(t2
, t2
, t3
);
19029 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
19030 tcg_gen_sub_i64(t2
, t3
, t2
);
19031 tcg_temp_free_i64(t3
);
19032 gen_move_low32(cpu_LO
[acc
], t2
);
19033 gen_move_high32(cpu_HI
[acc
], t2
);
19034 tcg_temp_free_i64(t2
);
19039 tcg_gen_movi_tl(t0
, rd
>> 3);
19040 gen_helper_extr_s_h(t0
, t0
, v0_t
, cpu_env
);
19041 gen_store_gpr(t0
, ret
);
19046 gen_reserved_instruction(ctx
);
19053 tcg_temp_free(v0_t
);
19054 tcg_temp_free(v1_t
);
19057 static void gen_pool32axf_4_nanomips_insn(DisasContext
*ctx
, uint32_t opc
,
19061 TCGv t0
= tcg_temp_new();
19062 TCGv v0_t
= tcg_temp_new();
19064 gen_load_gpr(v0_t
, rs
);
19069 gen_helper_absq_s_qb(v0_t
, v0_t
, cpu_env
);
19070 gen_store_gpr(v0_t
, ret
);
19074 gen_helper_absq_s_ph(v0_t
, v0_t
, cpu_env
);
19075 gen_store_gpr(v0_t
, ret
);
19079 gen_helper_absq_s_w(v0_t
, v0_t
, cpu_env
);
19080 gen_store_gpr(v0_t
, ret
);
19082 case NM_PRECEQ_W_PHL
:
19084 tcg_gen_andi_tl(v0_t
, v0_t
, 0xFFFF0000);
19085 tcg_gen_ext32s_tl(v0_t
, v0_t
);
19086 gen_store_gpr(v0_t
, ret
);
19088 case NM_PRECEQ_W_PHR
:
19090 tcg_gen_andi_tl(v0_t
, v0_t
, 0x0000FFFF);
19091 tcg_gen_shli_tl(v0_t
, v0_t
, 16);
19092 tcg_gen_ext32s_tl(v0_t
, v0_t
);
19093 gen_store_gpr(v0_t
, ret
);
19095 case NM_PRECEQU_PH_QBL
:
19097 gen_helper_precequ_ph_qbl(v0_t
, v0_t
);
19098 gen_store_gpr(v0_t
, ret
);
19100 case NM_PRECEQU_PH_QBR
:
19102 gen_helper_precequ_ph_qbr(v0_t
, v0_t
);
19103 gen_store_gpr(v0_t
, ret
);
19105 case NM_PRECEQU_PH_QBLA
:
19107 gen_helper_precequ_ph_qbla(v0_t
, v0_t
);
19108 gen_store_gpr(v0_t
, ret
);
19110 case NM_PRECEQU_PH_QBRA
:
19112 gen_helper_precequ_ph_qbra(v0_t
, v0_t
);
19113 gen_store_gpr(v0_t
, ret
);
19115 case NM_PRECEU_PH_QBL
:
19117 gen_helper_preceu_ph_qbl(v0_t
, v0_t
);
19118 gen_store_gpr(v0_t
, ret
);
19120 case NM_PRECEU_PH_QBR
:
19122 gen_helper_preceu_ph_qbr(v0_t
, v0_t
);
19123 gen_store_gpr(v0_t
, ret
);
19125 case NM_PRECEU_PH_QBLA
:
19127 gen_helper_preceu_ph_qbla(v0_t
, v0_t
);
19128 gen_store_gpr(v0_t
, ret
);
19130 case NM_PRECEU_PH_QBRA
:
19132 gen_helper_preceu_ph_qbra(v0_t
, v0_t
);
19133 gen_store_gpr(v0_t
, ret
);
19137 tcg_gen_ext16u_tl(v0_t
, v0_t
);
19138 tcg_gen_shli_tl(t0
, v0_t
, 16);
19139 tcg_gen_or_tl(v0_t
, v0_t
, t0
);
19140 tcg_gen_ext32s_tl(v0_t
, v0_t
);
19141 gen_store_gpr(v0_t
, ret
);
19145 tcg_gen_ext8u_tl(v0_t
, v0_t
);
19146 tcg_gen_shli_tl(t0
, v0_t
, 8);
19147 tcg_gen_or_tl(v0_t
, v0_t
, t0
);
19148 tcg_gen_shli_tl(t0
, v0_t
, 16);
19149 tcg_gen_or_tl(v0_t
, v0_t
, t0
);
19150 tcg_gen_ext32s_tl(v0_t
, v0_t
);
19151 gen_store_gpr(v0_t
, ret
);
19155 gen_helper_bitrev(v0_t
, v0_t
);
19156 gen_store_gpr(v0_t
, ret
);
19161 TCGv tv0
= tcg_temp_new();
19163 gen_load_gpr(tv0
, rt
);
19164 gen_helper_insv(v0_t
, cpu_env
, v0_t
, tv0
);
19165 gen_store_gpr(v0_t
, ret
);
19166 tcg_temp_free(tv0
);
19169 case NM_RADDU_W_QB
:
19171 gen_helper_raddu_w_qb(v0_t
, v0_t
);
19172 gen_store_gpr(v0_t
, ret
);
19175 gen_bitswap(ctx
, OPC_BITSWAP
, ret
, rs
);
19179 gen_cl(ctx
, OPC_CLO
, ret
, rs
);
19183 gen_cl(ctx
, OPC_CLZ
, ret
, rs
);
19186 gen_bshfl(ctx
, OPC_WSBH
, ret
, rs
);
19189 gen_reserved_instruction(ctx
);
19193 tcg_temp_free(v0_t
);
19197 static void gen_pool32axf_7_nanomips_insn(DisasContext
*ctx
, uint32_t opc
,
19198 int rt
, int rs
, int rd
)
19200 TCGv t0
= tcg_temp_new();
19201 TCGv rs_t
= tcg_temp_new();
19203 gen_load_gpr(rs_t
, rs
);
19208 tcg_gen_movi_tl(t0
, rd
>> 2);
19209 switch (extract32(ctx
->opcode
, 12, 1)) {
19212 gen_helper_shra_qb(t0
, t0
, rs_t
);
19213 gen_store_gpr(t0
, rt
);
19217 gen_helper_shra_r_qb(t0
, t0
, rs_t
);
19218 gen_store_gpr(t0
, rt
);
19224 tcg_gen_movi_tl(t0
, rd
>> 1);
19225 gen_helper_shrl_ph(t0
, t0
, rs_t
);
19226 gen_store_gpr(t0
, rt
);
19232 target_long result
;
19233 imm
= extract32(ctx
->opcode
, 13, 8);
19234 result
= (uint32_t)imm
<< 24 |
19235 (uint32_t)imm
<< 16 |
19236 (uint32_t)imm
<< 8 |
19238 result
= (int32_t)result
;
19239 tcg_gen_movi_tl(t0
, result
);
19240 gen_store_gpr(t0
, rt
);
19244 gen_reserved_instruction(ctx
);
19248 tcg_temp_free(rs_t
);
19252 static void gen_pool32axf_nanomips_insn(CPUMIPSState
*env
, DisasContext
*ctx
)
19254 int rt
= extract32(ctx
->opcode
, 21, 5);
19255 int rs
= extract32(ctx
->opcode
, 16, 5);
19256 int rd
= extract32(ctx
->opcode
, 11, 5);
19258 switch (extract32(ctx
->opcode
, 6, 3)) {
19259 case NM_POOL32AXF_1
:
19261 int32_t op1
= extract32(ctx
->opcode
, 9, 3);
19262 gen_pool32axf_1_nanomips_insn(ctx
, op1
, rt
, rs
, rd
);
19265 case NM_POOL32AXF_2
:
19267 int32_t op1
= extract32(ctx
->opcode
, 12, 2);
19268 gen_pool32axf_2_nanomips_insn(ctx
, op1
, rt
, rs
, rd
);
19271 case NM_POOL32AXF_4
:
19273 int32_t op1
= extract32(ctx
->opcode
, 9, 7);
19274 gen_pool32axf_4_nanomips_insn(ctx
, op1
, rt
, rs
);
19277 case NM_POOL32AXF_5
:
19278 switch (extract32(ctx
->opcode
, 9, 7)) {
19279 #ifndef CONFIG_USER_ONLY
19281 gen_cp0(env
, ctx
, OPC_TLBP
, 0, 0);
19284 gen_cp0(env
, ctx
, OPC_TLBR
, 0, 0);
19287 gen_cp0(env
, ctx
, OPC_TLBWI
, 0, 0);
19290 gen_cp0(env
, ctx
, OPC_TLBWR
, 0, 0);
19293 gen_cp0(env
, ctx
, OPC_TLBINV
, 0, 0);
19296 gen_cp0(env
, ctx
, OPC_TLBINVF
, 0, 0);
19299 check_cp0_enabled(ctx
);
19301 TCGv t0
= tcg_temp_new();
19303 save_cpu_state(ctx
, 1);
19304 gen_helper_di(t0
, cpu_env
);
19305 gen_store_gpr(t0
, rt
);
19306 /* Stop translation as we may have switched the execution mode */
19307 ctx
->base
.is_jmp
= DISAS_STOP
;
19312 check_cp0_enabled(ctx
);
19314 TCGv t0
= tcg_temp_new();
19316 save_cpu_state(ctx
, 1);
19317 gen_helper_ei(t0
, cpu_env
);
19318 gen_store_gpr(t0
, rt
);
19319 /* Stop translation as we may have switched the execution mode */
19320 ctx
->base
.is_jmp
= DISAS_STOP
;
19325 gen_load_srsgpr(rs
, rt
);
19328 gen_store_srsgpr(rs
, rt
);
19331 gen_cp0(env
, ctx
, OPC_WAIT
, 0, 0);
19334 gen_cp0(env
, ctx
, OPC_DERET
, 0, 0);
19337 gen_cp0(env
, ctx
, OPC_ERET
, 0, 0);
19341 gen_reserved_instruction(ctx
);
19345 case NM_POOL32AXF_7
:
19347 int32_t op1
= extract32(ctx
->opcode
, 9, 3);
19348 gen_pool32axf_7_nanomips_insn(ctx
, op1
, rt
, rs
, rd
);
19352 gen_reserved_instruction(ctx
);
19357 /* Immediate Value Compact Branches */
19358 static void gen_compute_imm_branch(DisasContext
*ctx
, uint32_t opc
,
19359 int rt
, int32_t imm
, int32_t offset
)
19361 TCGCond cond
= TCG_COND_ALWAYS
;
19362 TCGv t0
= tcg_temp_new();
19363 TCGv t1
= tcg_temp_new();
19365 gen_load_gpr(t0
, rt
);
19366 tcg_gen_movi_tl(t1
, imm
);
19367 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
19369 /* Load needed operands and calculate btarget */
19372 if (rt
== 0 && imm
== 0) {
19373 /* Unconditional branch */
19374 } else if (rt
== 0 && imm
!= 0) {
19378 cond
= TCG_COND_EQ
;
19384 if (imm
>= 32 && !(ctx
->hflags
& MIPS_HFLAG_64
)) {
19385 gen_reserved_instruction(ctx
);
19387 } else if (rt
== 0 && opc
== NM_BBEQZC
) {
19388 /* Unconditional branch */
19389 } else if (rt
== 0 && opc
== NM_BBNEZC
) {
19393 tcg_gen_shri_tl(t0
, t0
, imm
);
19394 tcg_gen_andi_tl(t0
, t0
, 1);
19395 tcg_gen_movi_tl(t1
, 0);
19396 if (opc
== NM_BBEQZC
) {
19397 cond
= TCG_COND_EQ
;
19399 cond
= TCG_COND_NE
;
19404 if (rt
== 0 && imm
== 0) {
19407 } else if (rt
== 0 && imm
!= 0) {
19408 /* Unconditional branch */
19410 cond
= TCG_COND_NE
;
19414 if (rt
== 0 && imm
== 0) {
19415 /* Unconditional branch */
19417 cond
= TCG_COND_GE
;
19421 cond
= TCG_COND_LT
;
19424 if (rt
== 0 && imm
== 0) {
19425 /* Unconditional branch */
19427 cond
= TCG_COND_GEU
;
19431 cond
= TCG_COND_LTU
;
19434 MIPS_INVAL("Immediate Value Compact branch");
19435 gen_reserved_instruction(ctx
);
19439 /* branch completion */
19440 clear_branch_hflags(ctx
);
19441 ctx
->base
.is_jmp
= DISAS_NORETURN
;
19443 if (cond
== TCG_COND_ALWAYS
) {
19444 /* Uncoditional compact branch */
19445 gen_goto_tb(ctx
, 0, ctx
->btarget
);
19447 /* Conditional compact branch */
19448 TCGLabel
*fs
= gen_new_label();
19450 tcg_gen_brcond_tl(tcg_invert_cond(cond
), t0
, t1
, fs
);
19452 gen_goto_tb(ctx
, 1, ctx
->btarget
);
19455 gen_goto_tb(ctx
, 0, ctx
->base
.pc_next
+ 4);
19463 /* P.BALRSC type nanoMIPS R6 branches: BALRSC and BRSC */
19464 static void gen_compute_nanomips_pbalrsc_branch(DisasContext
*ctx
, int rs
,
19467 TCGv t0
= tcg_temp_new();
19468 TCGv t1
= tcg_temp_new();
19471 gen_load_gpr(t0
, rs
);
19475 tcg_gen_movi_tl(cpu_gpr
[rt
], ctx
->base
.pc_next
+ 4);
19478 /* calculate btarget */
19479 tcg_gen_shli_tl(t0
, t0
, 1);
19480 tcg_gen_movi_tl(t1
, ctx
->base
.pc_next
+ 4);
19481 gen_op_addr_add(ctx
, btarget
, t1
, t0
);
19483 /* branch completion */
19484 clear_branch_hflags(ctx
);
19485 ctx
->base
.is_jmp
= DISAS_NORETURN
;
19487 /* unconditional branch to register */
19488 tcg_gen_mov_tl(cpu_PC
, btarget
);
19489 tcg_gen_lookup_and_goto_ptr();
19495 /* nanoMIPS Branches */
19496 static void gen_compute_compact_branch_nm(DisasContext
*ctx
, uint32_t opc
,
19497 int rs
, int rt
, int32_t offset
)
19499 int bcond_compute
= 0;
19500 TCGv t0
= tcg_temp_new();
19501 TCGv t1
= tcg_temp_new();
19503 /* Load needed operands and calculate btarget */
19505 /* compact branch */
19508 gen_load_gpr(t0
, rs
);
19509 gen_load_gpr(t1
, rt
);
19511 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
19515 if (rs
== 0 || rs
== rt
) {
19516 /* OPC_BLEZALC, OPC_BGEZALC */
19517 /* OPC_BGTZALC, OPC_BLTZALC */
19518 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 4);
19520 gen_load_gpr(t0
, rs
);
19521 gen_load_gpr(t1
, rt
);
19523 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
19526 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
19530 /* OPC_BEQZC, OPC_BNEZC */
19531 gen_load_gpr(t0
, rs
);
19533 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
19535 /* OPC_JIC, OPC_JIALC */
19536 TCGv tbase
= tcg_temp_new();
19537 TCGv toffset
= tcg_temp_new();
19539 gen_load_gpr(tbase
, rt
);
19540 tcg_gen_movi_tl(toffset
, offset
);
19541 gen_op_addr_add(ctx
, btarget
, tbase
, toffset
);
19542 tcg_temp_free(tbase
);
19543 tcg_temp_free(toffset
);
19547 MIPS_INVAL("Compact branch/jump");
19548 gen_reserved_instruction(ctx
);
19552 if (bcond_compute
== 0) {
19553 /* Uncoditional compact branch */
19556 gen_goto_tb(ctx
, 0, ctx
->btarget
);
19559 MIPS_INVAL("Compact branch/jump");
19560 gen_reserved_instruction(ctx
);
19564 /* Conditional compact branch */
19565 TCGLabel
*fs
= gen_new_label();
19569 if (rs
== 0 && rt
!= 0) {
19571 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE
), t1
, 0, fs
);
19572 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
19574 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE
), t1
, 0, fs
);
19577 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU
), t0
, t1
, fs
);
19581 if (rs
== 0 && rt
!= 0) {
19583 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT
), t1
, 0, fs
);
19584 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
19586 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT
), t1
, 0, fs
);
19589 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU
), t0
, t1
, fs
);
19593 if (rs
== 0 && rt
!= 0) {
19595 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE
), t1
, 0, fs
);
19596 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
19598 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE
), t1
, 0, fs
);
19601 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE
), t0
, t1
, fs
);
19605 if (rs
== 0 && rt
!= 0) {
19607 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT
), t1
, 0, fs
);
19608 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
19610 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT
), t1
, 0, fs
);
19613 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT
), t0
, t1
, fs
);
19617 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ
), t0
, 0, fs
);
19620 MIPS_INVAL("Compact conditional branch/jump");
19621 gen_reserved_instruction(ctx
);
19625 /* branch completion */
19626 clear_branch_hflags(ctx
);
19627 ctx
->base
.is_jmp
= DISAS_NORETURN
;
19629 /* Generating branch here as compact branches don't have delay slot */
19630 gen_goto_tb(ctx
, 1, ctx
->btarget
);
19633 gen_goto_tb(ctx
, 0, ctx
->base
.pc_next
+ 4);
19642 /* nanoMIPS CP1 Branches */
19643 static void gen_compute_branch_cp1_nm(DisasContext
*ctx
, uint32_t op
,
19644 int32_t ft
, int32_t offset
)
19646 target_ulong btarget
;
19647 TCGv_i64 t0
= tcg_temp_new_i64();
19649 gen_load_fpr64(ctx
, t0
, ft
);
19650 tcg_gen_andi_i64(t0
, t0
, 1);
19652 btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
19656 tcg_gen_xori_i64(t0
, t0
, 1);
19657 ctx
->hflags
|= MIPS_HFLAG_BC
;
19660 /* t0 already set */
19661 ctx
->hflags
|= MIPS_HFLAG_BC
;
19664 MIPS_INVAL("cp1 cond branch");
19665 gen_reserved_instruction(ctx
);
19669 tcg_gen_trunc_i64_tl(bcond
, t0
);
19671 ctx
->btarget
= btarget
;
19674 tcg_temp_free_i64(t0
);
19678 static void gen_p_lsx(DisasContext
*ctx
, int rd
, int rs
, int rt
)
19681 t0
= tcg_temp_new();
19682 t1
= tcg_temp_new();
19684 gen_load_gpr(t0
, rs
);
19685 gen_load_gpr(t1
, rt
);
19687 if ((extract32(ctx
->opcode
, 6, 1)) == 1) {
19688 /* PP.LSXS instructions require shifting */
19689 switch (extract32(ctx
->opcode
, 7, 4)) {
19695 tcg_gen_shli_tl(t0
, t0
, 1);
19703 tcg_gen_shli_tl(t0
, t0
, 2);
19707 tcg_gen_shli_tl(t0
, t0
, 3);
19711 gen_op_addr_add(ctx
, t0
, t0
, t1
);
19713 switch (extract32(ctx
->opcode
, 7, 4)) {
19715 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
,
19717 gen_store_gpr(t0
, rd
);
19721 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
,
19723 gen_store_gpr(t0
, rd
);
19727 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
,
19729 gen_store_gpr(t0
, rd
);
19732 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
,
19734 gen_store_gpr(t0
, rd
);
19738 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
,
19740 gen_store_gpr(t0
, rd
);
19744 gen_load_gpr(t1
, rd
);
19745 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
,
19751 gen_load_gpr(t1
, rd
);
19752 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
,
19758 gen_load_gpr(t1
, rd
);
19759 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
,
19763 /*case NM_LWC1XS:*/
19765 /*case NM_LDC1XS:*/
19767 /*case NM_SWC1XS:*/
19769 /*case NM_SDC1XS:*/
19770 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
19771 check_cp1_enabled(ctx
);
19772 switch (extract32(ctx
->opcode
, 7, 4)) {
19774 /*case NM_LWC1XS:*/
19775 gen_flt_ldst(ctx
, OPC_LWC1
, rd
, t0
);
19778 /*case NM_LDC1XS:*/
19779 gen_flt_ldst(ctx
, OPC_LDC1
, rd
, t0
);
19782 /*case NM_SWC1XS:*/
19783 gen_flt_ldst(ctx
, OPC_SWC1
, rd
, t0
);
19786 /*case NM_SDC1XS:*/
19787 gen_flt_ldst(ctx
, OPC_SDC1
, rd
, t0
);
19791 generate_exception_err(ctx
, EXCP_CpU
, 1);
19795 gen_reserved_instruction(ctx
);
19803 static void gen_pool32f_nanomips_insn(DisasContext
*ctx
)
19807 rt
= extract32(ctx
->opcode
, 21, 5);
19808 rs
= extract32(ctx
->opcode
, 16, 5);
19809 rd
= extract32(ctx
->opcode
, 11, 5);
19811 if (!(ctx
->CP0_Config1
& (1 << CP0C1_FP
))) {
19812 gen_reserved_instruction(ctx
);
19815 check_cp1_enabled(ctx
);
19816 switch (extract32(ctx
->opcode
, 0, 3)) {
19818 switch (extract32(ctx
->opcode
, 3, 7)) {
19820 gen_farith(ctx
, OPC_RINT_S
, 0, rt
, rs
, 0);
19823 gen_farith(ctx
, OPC_RINT_D
, 0, rt
, rs
, 0);
19826 gen_farith(ctx
, OPC_CLASS_S
, 0, rt
, rs
, 0);
19829 gen_farith(ctx
, OPC_CLASS_D
, 0, rt
, rs
, 0);
19832 gen_farith(ctx
, OPC_ADD_S
, rt
, rs
, rd
, 0);
19835 gen_farith(ctx
, OPC_ADD_D
, rt
, rs
, rd
, 0);
19838 gen_farith(ctx
, OPC_SUB_S
, rt
, rs
, rd
, 0);
19841 gen_farith(ctx
, OPC_SUB_D
, rt
, rs
, rd
, 0);
19844 gen_farith(ctx
, OPC_MUL_S
, rt
, rs
, rd
, 0);
19847 gen_farith(ctx
, OPC_MUL_D
, rt
, rs
, rd
, 0);
19850 gen_farith(ctx
, OPC_DIV_S
, rt
, rs
, rd
, 0);
19853 gen_farith(ctx
, OPC_DIV_D
, rt
, rs
, rd
, 0);
19856 gen_sel_s(ctx
, OPC_SELEQZ_S
, rd
, rt
, rs
);
19859 gen_sel_d(ctx
, OPC_SELEQZ_D
, rd
, rt
, rs
);
19862 gen_sel_s(ctx
, OPC_SELNEZ_S
, rd
, rt
, rs
);
19865 gen_sel_d(ctx
, OPC_SELNEZ_D
, rd
, rt
, rs
);
19868 gen_sel_s(ctx
, OPC_SEL_S
, rd
, rt
, rs
);
19871 gen_sel_d(ctx
, OPC_SEL_D
, rd
, rt
, rs
);
19874 gen_farith(ctx
, OPC_MADDF_S
, rt
, rs
, rd
, 0);
19877 gen_farith(ctx
, OPC_MADDF_D
, rt
, rs
, rd
, 0);
19880 gen_farith(ctx
, OPC_MSUBF_S
, rt
, rs
, rd
, 0);
19883 gen_farith(ctx
, OPC_MSUBF_D
, rt
, rs
, rd
, 0);
19886 gen_reserved_instruction(ctx
);
19891 switch (extract32(ctx
->opcode
, 3, 3)) {
19893 switch (extract32(ctx
->opcode
, 9, 1)) {
19895 gen_farith(ctx
, OPC_MIN_S
, rt
, rs
, rd
, 0);
19898 gen_farith(ctx
, OPC_MIN_D
, rt
, rs
, rd
, 0);
19903 switch (extract32(ctx
->opcode
, 9, 1)) {
19905 gen_farith(ctx
, OPC_MAX_S
, rt
, rs
, rd
, 0);
19908 gen_farith(ctx
, OPC_MAX_D
, rt
, rs
, rd
, 0);
19913 switch (extract32(ctx
->opcode
, 9, 1)) {
19915 gen_farith(ctx
, OPC_MINA_S
, rt
, rs
, rd
, 0);
19918 gen_farith(ctx
, OPC_MINA_D
, rt
, rs
, rd
, 0);
19923 switch (extract32(ctx
->opcode
, 9, 1)) {
19925 gen_farith(ctx
, OPC_MAXA_S
, rt
, rs
, rd
, 0);
19928 gen_farith(ctx
, OPC_MAXA_D
, rt
, rs
, rd
, 0);
19933 switch (extract32(ctx
->opcode
, 6, 8)) {
19935 gen_cp1(ctx
, OPC_CFC1
, rt
, rs
);
19938 gen_cp1(ctx
, OPC_CTC1
, rt
, rs
);
19941 gen_cp1(ctx
, OPC_MFC1
, rt
, rs
);
19944 gen_cp1(ctx
, OPC_MTC1
, rt
, rs
);
19947 gen_cp1(ctx
, OPC_MFHC1
, rt
, rs
);
19950 gen_cp1(ctx
, OPC_MTHC1
, rt
, rs
);
19953 gen_farith(ctx
, OPC_CVT_S_PL
, -1, rs
, rt
, 0);
19956 gen_farith(ctx
, OPC_CVT_S_PU
, -1, rs
, rt
, 0);
19959 switch (extract32(ctx
->opcode
, 6, 9)) {
19961 gen_farith(ctx
, OPC_CVT_L_S
, -1, rs
, rt
, 0);
19964 gen_farith(ctx
, OPC_CVT_L_D
, -1, rs
, rt
, 0);
19967 gen_farith(ctx
, OPC_CVT_W_S
, -1, rs
, rt
, 0);
19970 gen_farith(ctx
, OPC_CVT_W_D
, -1, rs
, rt
, 0);
19973 gen_farith(ctx
, OPC_RSQRT_S
, -1, rs
, rt
, 0);
19976 gen_farith(ctx
, OPC_RSQRT_D
, -1, rs
, rt
, 0);
19979 gen_farith(ctx
, OPC_SQRT_S
, -1, rs
, rt
, 0);
19982 gen_farith(ctx
, OPC_SQRT_D
, -1, rs
, rt
, 0);
19985 gen_farith(ctx
, OPC_RECIP_S
, -1, rs
, rt
, 0);
19988 gen_farith(ctx
, OPC_RECIP_D
, -1, rs
, rt
, 0);
19991 gen_farith(ctx
, OPC_FLOOR_L_S
, -1, rs
, rt
, 0);
19994 gen_farith(ctx
, OPC_FLOOR_L_D
, -1, rs
, rt
, 0);
19997 gen_farith(ctx
, OPC_FLOOR_W_S
, -1, rs
, rt
, 0);
20000 gen_farith(ctx
, OPC_FLOOR_W_D
, -1, rs
, rt
, 0);
20003 gen_farith(ctx
, OPC_CEIL_L_S
, -1, rs
, rt
, 0);
20006 gen_farith(ctx
, OPC_CEIL_L_D
, -1, rs
, rt
, 0);
20009 gen_farith(ctx
, OPC_CEIL_W_S
, -1, rs
, rt
, 0);
20012 gen_farith(ctx
, OPC_CEIL_W_D
, -1, rs
, rt
, 0);
20015 gen_farith(ctx
, OPC_TRUNC_L_S
, -1, rs
, rt
, 0);
20018 gen_farith(ctx
, OPC_TRUNC_L_D
, -1, rs
, rt
, 0);
20021 gen_farith(ctx
, OPC_TRUNC_W_S
, -1, rs
, rt
, 0);
20024 gen_farith(ctx
, OPC_TRUNC_W_D
, -1, rs
, rt
, 0);
20027 gen_farith(ctx
, OPC_ROUND_L_S
, -1, rs
, rt
, 0);
20030 gen_farith(ctx
, OPC_ROUND_L_D
, -1, rs
, rt
, 0);
20033 gen_farith(ctx
, OPC_ROUND_W_S
, -1, rs
, rt
, 0);
20036 gen_farith(ctx
, OPC_ROUND_W_D
, -1, rs
, rt
, 0);
20039 gen_farith(ctx
, OPC_MOV_S
, -1, rs
, rt
, 0);
20042 gen_farith(ctx
, OPC_MOV_D
, -1, rs
, rt
, 0);
20045 gen_farith(ctx
, OPC_ABS_S
, -1, rs
, rt
, 0);
20048 gen_farith(ctx
, OPC_ABS_D
, -1, rs
, rt
, 0);
20051 gen_farith(ctx
, OPC_NEG_S
, -1, rs
, rt
, 0);
20054 gen_farith(ctx
, OPC_NEG_D
, -1, rs
, rt
, 0);
20057 gen_farith(ctx
, OPC_CVT_D_S
, -1, rs
, rt
, 0);
20060 gen_farith(ctx
, OPC_CVT_D_W
, -1, rs
, rt
, 0);
20063 gen_farith(ctx
, OPC_CVT_D_L
, -1, rs
, rt
, 0);
20066 gen_farith(ctx
, OPC_CVT_S_D
, -1, rs
, rt
, 0);
20069 gen_farith(ctx
, OPC_CVT_S_W
, -1, rs
, rt
, 0);
20072 gen_farith(ctx
, OPC_CVT_S_L
, -1, rs
, rt
, 0);
20075 gen_reserved_instruction(ctx
);
20084 switch (extract32(ctx
->opcode
, 3, 3)) {
20085 case NM_CMP_CONDN_S
:
20086 gen_r6_cmp_s(ctx
, extract32(ctx
->opcode
, 6, 5), rt
, rs
, rd
);
20088 case NM_CMP_CONDN_D
:
20089 gen_r6_cmp_d(ctx
, extract32(ctx
->opcode
, 6, 5), rt
, rs
, rd
);
20092 gen_reserved_instruction(ctx
);
20097 gen_reserved_instruction(ctx
);
20102 static void gen_pool32a5_nanomips_insn(DisasContext
*ctx
, int opc
,
20103 int rd
, int rs
, int rt
)
20106 TCGv t0
= tcg_temp_new();
20107 TCGv v1_t
= tcg_temp_new();
20108 TCGv v2_t
= tcg_temp_new();
20110 gen_load_gpr(v1_t
, rs
);
20111 gen_load_gpr(v2_t
, rt
);
20116 gen_helper_cmp_eq_ph(v1_t
, v2_t
, cpu_env
);
20120 gen_helper_cmp_lt_ph(v1_t
, v2_t
, cpu_env
);
20124 gen_helper_cmp_le_ph(v1_t
, v2_t
, cpu_env
);
20126 case NM_CMPU_EQ_QB
:
20128 gen_helper_cmpu_eq_qb(v1_t
, v2_t
, cpu_env
);
20130 case NM_CMPU_LT_QB
:
20132 gen_helper_cmpu_lt_qb(v1_t
, v2_t
, cpu_env
);
20134 case NM_CMPU_LE_QB
:
20136 gen_helper_cmpu_le_qb(v1_t
, v2_t
, cpu_env
);
20138 case NM_CMPGU_EQ_QB
:
20140 gen_helper_cmpgu_eq_qb(v1_t
, v1_t
, v2_t
);
20141 gen_store_gpr(v1_t
, ret
);
20143 case NM_CMPGU_LT_QB
:
20145 gen_helper_cmpgu_lt_qb(v1_t
, v1_t
, v2_t
);
20146 gen_store_gpr(v1_t
, ret
);
20148 case NM_CMPGU_LE_QB
:
20150 gen_helper_cmpgu_le_qb(v1_t
, v1_t
, v2_t
);
20151 gen_store_gpr(v1_t
, ret
);
20153 case NM_CMPGDU_EQ_QB
:
20155 gen_helper_cmpgu_eq_qb(v1_t
, v1_t
, v2_t
);
20156 tcg_gen_deposit_tl(cpu_dspctrl
, cpu_dspctrl
, v1_t
, 24, 4);
20157 gen_store_gpr(v1_t
, ret
);
20159 case NM_CMPGDU_LT_QB
:
20161 gen_helper_cmpgu_lt_qb(v1_t
, v1_t
, v2_t
);
20162 tcg_gen_deposit_tl(cpu_dspctrl
, cpu_dspctrl
, v1_t
, 24, 4);
20163 gen_store_gpr(v1_t
, ret
);
20165 case NM_CMPGDU_LE_QB
:
20167 gen_helper_cmpgu_le_qb(v1_t
, v1_t
, v2_t
);
20168 tcg_gen_deposit_tl(cpu_dspctrl
, cpu_dspctrl
, v1_t
, 24, 4);
20169 gen_store_gpr(v1_t
, ret
);
20173 gen_helper_packrl_ph(v1_t
, v1_t
, v2_t
);
20174 gen_store_gpr(v1_t
, ret
);
20178 gen_helper_pick_qb(v1_t
, v1_t
, v2_t
, cpu_env
);
20179 gen_store_gpr(v1_t
, ret
);
20183 gen_helper_pick_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20184 gen_store_gpr(v1_t
, ret
);
20188 gen_helper_addq_s_w(v1_t
, v1_t
, v2_t
, cpu_env
);
20189 gen_store_gpr(v1_t
, ret
);
20193 gen_helper_subq_s_w(v1_t
, v1_t
, v2_t
, cpu_env
);
20194 gen_store_gpr(v1_t
, ret
);
20198 gen_helper_addsc(v1_t
, v1_t
, v2_t
, cpu_env
);
20199 gen_store_gpr(v1_t
, ret
);
20203 gen_helper_addwc(v1_t
, v1_t
, v2_t
, cpu_env
);
20204 gen_store_gpr(v1_t
, ret
);
20208 switch (extract32(ctx
->opcode
, 10, 1)) {
20211 gen_helper_addq_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20212 gen_store_gpr(v1_t
, ret
);
20216 gen_helper_addq_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20217 gen_store_gpr(v1_t
, ret
);
20221 case NM_ADDQH_R_PH
:
20223 switch (extract32(ctx
->opcode
, 10, 1)) {
20226 gen_helper_addqh_ph(v1_t
, v1_t
, v2_t
);
20227 gen_store_gpr(v1_t
, ret
);
20231 gen_helper_addqh_r_ph(v1_t
, v1_t
, v2_t
);
20232 gen_store_gpr(v1_t
, ret
);
20238 switch (extract32(ctx
->opcode
, 10, 1)) {
20241 gen_helper_addqh_w(v1_t
, v1_t
, v2_t
);
20242 gen_store_gpr(v1_t
, ret
);
20246 gen_helper_addqh_r_w(v1_t
, v1_t
, v2_t
);
20247 gen_store_gpr(v1_t
, ret
);
20253 switch (extract32(ctx
->opcode
, 10, 1)) {
20256 gen_helper_addu_qb(v1_t
, v1_t
, v2_t
, cpu_env
);
20257 gen_store_gpr(v1_t
, ret
);
20261 gen_helper_addu_s_qb(v1_t
, v1_t
, v2_t
, cpu_env
);
20262 gen_store_gpr(v1_t
, ret
);
20268 switch (extract32(ctx
->opcode
, 10, 1)) {
20271 gen_helper_addu_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20272 gen_store_gpr(v1_t
, ret
);
20276 gen_helper_addu_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20277 gen_store_gpr(v1_t
, ret
);
20281 case NM_ADDUH_R_QB
:
20283 switch (extract32(ctx
->opcode
, 10, 1)) {
20286 gen_helper_adduh_qb(v1_t
, v1_t
, v2_t
);
20287 gen_store_gpr(v1_t
, ret
);
20291 gen_helper_adduh_r_qb(v1_t
, v1_t
, v2_t
);
20292 gen_store_gpr(v1_t
, ret
);
20296 case NM_SHRAV_R_PH
:
20298 switch (extract32(ctx
->opcode
, 10, 1)) {
20301 gen_helper_shra_ph(v1_t
, v1_t
, v2_t
);
20302 gen_store_gpr(v1_t
, ret
);
20306 gen_helper_shra_r_ph(v1_t
, v1_t
, v2_t
);
20307 gen_store_gpr(v1_t
, ret
);
20311 case NM_SHRAV_R_QB
:
20313 switch (extract32(ctx
->opcode
, 10, 1)) {
20316 gen_helper_shra_qb(v1_t
, v1_t
, v2_t
);
20317 gen_store_gpr(v1_t
, ret
);
20321 gen_helper_shra_r_qb(v1_t
, v1_t
, v2_t
);
20322 gen_store_gpr(v1_t
, ret
);
20328 switch (extract32(ctx
->opcode
, 10, 1)) {
20331 gen_helper_subq_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20332 gen_store_gpr(v1_t
, ret
);
20336 gen_helper_subq_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20337 gen_store_gpr(v1_t
, ret
);
20341 case NM_SUBQH_R_PH
:
20343 switch (extract32(ctx
->opcode
, 10, 1)) {
20346 gen_helper_subqh_ph(v1_t
, v1_t
, v2_t
);
20347 gen_store_gpr(v1_t
, ret
);
20351 gen_helper_subqh_r_ph(v1_t
, v1_t
, v2_t
);
20352 gen_store_gpr(v1_t
, ret
);
20358 switch (extract32(ctx
->opcode
, 10, 1)) {
20361 gen_helper_subqh_w(v1_t
, v1_t
, v2_t
);
20362 gen_store_gpr(v1_t
, ret
);
20366 gen_helper_subqh_r_w(v1_t
, v1_t
, v2_t
);
20367 gen_store_gpr(v1_t
, ret
);
20373 switch (extract32(ctx
->opcode
, 10, 1)) {
20376 gen_helper_subu_qb(v1_t
, v1_t
, v2_t
, cpu_env
);
20377 gen_store_gpr(v1_t
, ret
);
20381 gen_helper_subu_s_qb(v1_t
, v1_t
, v2_t
, cpu_env
);
20382 gen_store_gpr(v1_t
, ret
);
20388 switch (extract32(ctx
->opcode
, 10, 1)) {
20391 gen_helper_subu_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20392 gen_store_gpr(v1_t
, ret
);
20396 gen_helper_subu_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20397 gen_store_gpr(v1_t
, ret
);
20401 case NM_SUBUH_R_QB
:
20403 switch (extract32(ctx
->opcode
, 10, 1)) {
20406 gen_helper_subuh_qb(v1_t
, v1_t
, v2_t
);
20407 gen_store_gpr(v1_t
, ret
);
20411 gen_helper_subuh_r_qb(v1_t
, v1_t
, v2_t
);
20412 gen_store_gpr(v1_t
, ret
);
20416 case NM_SHLLV_S_PH
:
20418 switch (extract32(ctx
->opcode
, 10, 1)) {
20421 gen_helper_shll_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20422 gen_store_gpr(v1_t
, ret
);
20426 gen_helper_shll_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20427 gen_store_gpr(v1_t
, ret
);
20431 case NM_PRECR_SRA_R_PH_W
:
20433 switch (extract32(ctx
->opcode
, 10, 1)) {
20435 /* PRECR_SRA_PH_W */
20437 TCGv_i32 sa_t
= tcg_const_i32(rd
);
20438 gen_helper_precr_sra_ph_w(v1_t
, sa_t
, v1_t
,
20440 gen_store_gpr(v1_t
, rt
);
20441 tcg_temp_free_i32(sa_t
);
20445 /* PRECR_SRA_R_PH_W */
20447 TCGv_i32 sa_t
= tcg_const_i32(rd
);
20448 gen_helper_precr_sra_r_ph_w(v1_t
, sa_t
, v1_t
,
20450 gen_store_gpr(v1_t
, rt
);
20451 tcg_temp_free_i32(sa_t
);
20456 case NM_MULEU_S_PH_QBL
:
20458 gen_helper_muleu_s_ph_qbl(v1_t
, v1_t
, v2_t
, cpu_env
);
20459 gen_store_gpr(v1_t
, ret
);
20461 case NM_MULEU_S_PH_QBR
:
20463 gen_helper_muleu_s_ph_qbr(v1_t
, v1_t
, v2_t
, cpu_env
);
20464 gen_store_gpr(v1_t
, ret
);
20466 case NM_MULQ_RS_PH
:
20468 gen_helper_mulq_rs_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20469 gen_store_gpr(v1_t
, ret
);
20473 gen_helper_mulq_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20474 gen_store_gpr(v1_t
, ret
);
20478 gen_helper_mulq_rs_w(v1_t
, v1_t
, v2_t
, cpu_env
);
20479 gen_store_gpr(v1_t
, ret
);
20483 gen_helper_mulq_s_w(v1_t
, v1_t
, v2_t
, cpu_env
);
20484 gen_store_gpr(v1_t
, ret
);
20488 gen_load_gpr(t0
, rs
);
20490 tcg_gen_deposit_tl(cpu_gpr
[rt
], t0
, cpu_gpr
[rt
], rd
, 32 - rd
);
20492 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
20496 gen_helper_modsub(v1_t
, v1_t
, v2_t
);
20497 gen_store_gpr(v1_t
, ret
);
20501 gen_helper_shra_r_w(v1_t
, v1_t
, v2_t
);
20502 gen_store_gpr(v1_t
, ret
);
20506 gen_helper_shrl_ph(v1_t
, v1_t
, v2_t
);
20507 gen_store_gpr(v1_t
, ret
);
20511 gen_helper_shrl_qb(v1_t
, v1_t
, v2_t
);
20512 gen_store_gpr(v1_t
, ret
);
20516 gen_helper_shll_qb(v1_t
, v1_t
, v2_t
, cpu_env
);
20517 gen_store_gpr(v1_t
, ret
);
20521 gen_helper_shll_s_w(v1_t
, v1_t
, v2_t
, cpu_env
);
20522 gen_store_gpr(v1_t
, ret
);
20527 TCGv tv0
= tcg_temp_new();
20528 TCGv tv1
= tcg_temp_new();
20529 int16_t imm
= extract32(ctx
->opcode
, 16, 7);
20531 tcg_gen_movi_tl(tv0
, rd
>> 3);
20532 tcg_gen_movi_tl(tv1
, imm
);
20533 gen_helper_shilo(tv0
, tv1
, cpu_env
);
20536 case NM_MULEQ_S_W_PHL
:
20538 gen_helper_muleq_s_w_phl(v1_t
, v1_t
, v2_t
, cpu_env
);
20539 gen_store_gpr(v1_t
, ret
);
20541 case NM_MULEQ_S_W_PHR
:
20543 gen_helper_muleq_s_w_phr(v1_t
, v1_t
, v2_t
, cpu_env
);
20544 gen_store_gpr(v1_t
, ret
);
20548 switch (extract32(ctx
->opcode
, 10, 1)) {
20551 gen_helper_mul_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20552 gen_store_gpr(v1_t
, ret
);
20556 gen_helper_mul_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20557 gen_store_gpr(v1_t
, ret
);
20561 case NM_PRECR_QB_PH
:
20563 gen_helper_precr_qb_ph(v1_t
, v1_t
, v2_t
);
20564 gen_store_gpr(v1_t
, ret
);
20566 case NM_PRECRQ_QB_PH
:
20568 gen_helper_precrq_qb_ph(v1_t
, v1_t
, v2_t
);
20569 gen_store_gpr(v1_t
, ret
);
20571 case NM_PRECRQ_PH_W
:
20573 gen_helper_precrq_ph_w(v1_t
, v1_t
, v2_t
);
20574 gen_store_gpr(v1_t
, ret
);
20576 case NM_PRECRQ_RS_PH_W
:
20578 gen_helper_precrq_rs_ph_w(v1_t
, v1_t
, v2_t
, cpu_env
);
20579 gen_store_gpr(v1_t
, ret
);
20581 case NM_PRECRQU_S_QB_PH
:
20583 gen_helper_precrqu_s_qb_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20584 gen_store_gpr(v1_t
, ret
);
20588 tcg_gen_movi_tl(t0
, rd
);
20589 gen_helper_shra_r_w(v1_t
, t0
, v1_t
);
20590 gen_store_gpr(v1_t
, rt
);
20594 tcg_gen_movi_tl(t0
, rd
>> 1);
20595 switch (extract32(ctx
->opcode
, 10, 1)) {
20598 gen_helper_shra_ph(v1_t
, t0
, v1_t
);
20599 gen_store_gpr(v1_t
, rt
);
20603 gen_helper_shra_r_ph(v1_t
, t0
, v1_t
);
20604 gen_store_gpr(v1_t
, rt
);
20610 tcg_gen_movi_tl(t0
, rd
>> 1);
20611 switch (extract32(ctx
->opcode
, 10, 2)) {
20614 gen_helper_shll_ph(v1_t
, t0
, v1_t
, cpu_env
);
20615 gen_store_gpr(v1_t
, rt
);
20619 gen_helper_shll_s_ph(v1_t
, t0
, v1_t
, cpu_env
);
20620 gen_store_gpr(v1_t
, rt
);
20623 gen_reserved_instruction(ctx
);
20629 tcg_gen_movi_tl(t0
, rd
);
20630 gen_helper_shll_s_w(v1_t
, t0
, v1_t
, cpu_env
);
20631 gen_store_gpr(v1_t
, rt
);
20637 imm
= sextract32(ctx
->opcode
, 11, 11);
20638 imm
= (int16_t)(imm
<< 6) >> 6;
20640 tcg_gen_movi_tl(cpu_gpr
[rt
], dup_const(MO_16
, imm
));
20645 gen_reserved_instruction(ctx
);
20650 static int decode_nanomips_32_48_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
20658 insn
= translator_lduw(env
, ctx
->base
.pc_next
+ 2);
20659 ctx
->opcode
= (ctx
->opcode
<< 16) | insn
;
20661 rt
= extract32(ctx
->opcode
, 21, 5);
20662 rs
= extract32(ctx
->opcode
, 16, 5);
20663 rd
= extract32(ctx
->opcode
, 11, 5);
20665 op
= extract32(ctx
->opcode
, 26, 6);
20670 switch (extract32(ctx
->opcode
, 19, 2)) {
20673 gen_reserved_instruction(ctx
);
20676 if ((extract32(ctx
->opcode
, 18, 1)) == NM_SYSCALL
) {
20677 generate_exception_end(ctx
, EXCP_SYSCALL
);
20679 gen_reserved_instruction(ctx
);
20683 generate_exception_end(ctx
, EXCP_BREAK
);
20686 if (is_uhi(extract32(ctx
->opcode
, 0, 19))) {
20687 gen_helper_do_semihosting(cpu_env
);
20689 if (ctx
->hflags
& MIPS_HFLAG_SBRI
) {
20690 gen_reserved_instruction(ctx
);
20692 generate_exception_end(ctx
, EXCP_DBp
);
20699 imm
= extract32(ctx
->opcode
, 0, 16);
20701 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], imm
);
20703 tcg_gen_movi_tl(cpu_gpr
[rt
], imm
);
20705 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
20710 offset
= sextract32(ctx
->opcode
, 0, 1) << 21 |
20711 extract32(ctx
->opcode
, 1, 20) << 1;
20712 target_long addr
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
20713 tcg_gen_movi_tl(cpu_gpr
[rt
], addr
);
20717 switch (ctx
->opcode
& 0x07) {
20719 gen_pool32a0_nanomips_insn(env
, ctx
);
20723 int32_t op1
= extract32(ctx
->opcode
, 3, 7);
20724 gen_pool32a5_nanomips_insn(ctx
, op1
, rd
, rs
, rt
);
20728 switch (extract32(ctx
->opcode
, 3, 3)) {
20730 gen_p_lsx(ctx
, rd
, rs
, rt
);
20734 * In nanoMIPS, the shift field directly encodes the shift
20735 * amount, meaning that the supported shift values are in
20736 * the range 0 to 3 (instead of 1 to 4 in MIPSR6).
20738 gen_lsa(ctx
, rd
, rt
, rs
, extract32(ctx
->opcode
, 9, 2) - 1);
20741 gen_ext(ctx
, 32, rd
, rs
, rt
, extract32(ctx
->opcode
, 6, 5));
20744 gen_pool32axf_nanomips_insn(env
, ctx
);
20747 gen_reserved_instruction(ctx
);
20752 gen_reserved_instruction(ctx
);
20757 switch (ctx
->opcode
& 0x03) {
20760 offset
= extract32(ctx
->opcode
, 0, 21);
20761 gen_op_addr_addi(ctx
, cpu_gpr
[rt
], cpu_gpr
[28], offset
);
20765 gen_ld(ctx
, OPC_LW
, rt
, 28, extract32(ctx
->opcode
, 2, 19) << 2);
20768 gen_st(ctx
, OPC_SW
, rt
, 28, extract32(ctx
->opcode
, 2, 19) << 2);
20771 gen_reserved_instruction(ctx
);
20777 insn
= translator_lduw(env
, ctx
->base
.pc_next
+ 4);
20778 target_long addr_off
= extract32(ctx
->opcode
, 0, 16) | insn
<< 16;
20779 switch (extract32(ctx
->opcode
, 16, 5)) {
20783 tcg_gen_movi_tl(cpu_gpr
[rt
], addr_off
);
20789 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], addr_off
);
20790 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
20796 gen_op_addr_addi(ctx
, cpu_gpr
[rt
], cpu_gpr
[28], addr_off
);
20802 target_long addr
= addr_add(ctx
, ctx
->base
.pc_next
+ 6,
20805 tcg_gen_movi_tl(cpu_gpr
[rt
], addr
);
20812 t0
= tcg_temp_new();
20814 target_long addr
= addr_add(ctx
, ctx
->base
.pc_next
+ 6,
20817 tcg_gen_movi_tl(t0
, addr
);
20818 tcg_gen_qemu_ld_tl(cpu_gpr
[rt
], t0
, ctx
->mem_idx
, MO_TESL
);
20826 t0
= tcg_temp_new();
20827 t1
= tcg_temp_new();
20829 target_long addr
= addr_add(ctx
, ctx
->base
.pc_next
+ 6,
20832 tcg_gen_movi_tl(t0
, addr
);
20833 gen_load_gpr(t1
, rt
);
20835 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
20842 gen_reserved_instruction(ctx
);
20848 switch (extract32(ctx
->opcode
, 12, 4)) {
20850 gen_logic_imm(ctx
, OPC_ORI
, rt
, rs
, extract32(ctx
->opcode
, 0, 12));
20853 gen_logic_imm(ctx
, OPC_XORI
, rt
, rs
, extract32(ctx
->opcode
, 0, 12));
20856 gen_logic_imm(ctx
, OPC_ANDI
, rt
, rs
, extract32(ctx
->opcode
, 0, 12));
20859 switch (extract32(ctx
->opcode
, 20, 1)) {
20861 switch (ctx
->opcode
& 3) {
20863 gen_save(ctx
, rt
, extract32(ctx
->opcode
, 16, 4),
20864 extract32(ctx
->opcode
, 2, 1),
20865 extract32(ctx
->opcode
, 3, 9) << 3);
20868 case NM_RESTORE_JRC
:
20869 gen_restore(ctx
, rt
, extract32(ctx
->opcode
, 16, 4),
20870 extract32(ctx
->opcode
, 2, 1),
20871 extract32(ctx
->opcode
, 3, 9) << 3);
20872 if ((ctx
->opcode
& 3) == NM_RESTORE_JRC
) {
20873 gen_compute_branch_nm(ctx
, OPC_JR
, 2, 31, 0, 0);
20877 gen_reserved_instruction(ctx
);
20882 gen_reserved_instruction(ctx
);
20887 gen_slt_imm(ctx
, OPC_SLTI
, rt
, rs
, extract32(ctx
->opcode
, 0, 12));
20890 gen_slt_imm(ctx
, OPC_SLTIU
, rt
, rs
, extract32(ctx
->opcode
, 0, 12));
20894 TCGv t0
= tcg_temp_new();
20896 imm
= extract32(ctx
->opcode
, 0, 12);
20897 gen_load_gpr(t0
, rs
);
20898 tcg_gen_setcondi_tl(TCG_COND_EQ
, t0
, t0
, imm
);
20899 gen_store_gpr(t0
, rt
);
20905 imm
= (int16_t) extract32(ctx
->opcode
, 0, 12);
20906 gen_arith_imm(ctx
, OPC_ADDIU
, rt
, rs
, -imm
);
20910 int shift
= extract32(ctx
->opcode
, 0, 5);
20911 switch (extract32(ctx
->opcode
, 5, 4)) {
20913 if (rt
== 0 && shift
== 0) {
20915 } else if (rt
== 0 && shift
== 3) {
20916 /* EHB - treat as NOP */
20917 } else if (rt
== 0 && shift
== 5) {
20918 /* PAUSE - treat as NOP */
20919 } else if (rt
== 0 && shift
== 6) {
20921 gen_sync(extract32(ctx
->opcode
, 16, 5));
20924 gen_shift_imm(ctx
, OPC_SLL
, rt
, rs
,
20925 extract32(ctx
->opcode
, 0, 5));
20929 gen_shift_imm(ctx
, OPC_SRL
, rt
, rs
,
20930 extract32(ctx
->opcode
, 0, 5));
20933 gen_shift_imm(ctx
, OPC_SRA
, rt
, rs
,
20934 extract32(ctx
->opcode
, 0, 5));
20937 gen_shift_imm(ctx
, OPC_ROTR
, rt
, rs
,
20938 extract32(ctx
->opcode
, 0, 5));
20946 TCGv t0
= tcg_temp_new();
20947 TCGv_i32 shift
= tcg_const_i32(extract32(ctx
->opcode
, 0, 5));
20948 TCGv_i32 shiftx
= tcg_const_i32(extract32(ctx
->opcode
, 7, 4)
20950 TCGv_i32 stripe
= tcg_const_i32(extract32(ctx
->opcode
, 6, 1));
20952 gen_load_gpr(t0
, rs
);
20953 gen_helper_rotx(cpu_gpr
[rt
], t0
, shift
, shiftx
, stripe
);
20956 tcg_temp_free_i32(shift
);
20957 tcg_temp_free_i32(shiftx
);
20958 tcg_temp_free_i32(stripe
);
20962 switch (((ctx
->opcode
>> 10) & 2) |
20963 (extract32(ctx
->opcode
, 5, 1))) {
20966 gen_bitops(ctx
, OPC_INS
, rt
, rs
, extract32(ctx
->opcode
, 0, 5),
20967 extract32(ctx
->opcode
, 6, 5));
20970 gen_reserved_instruction(ctx
);
20975 switch (((ctx
->opcode
>> 10) & 2) |
20976 (extract32(ctx
->opcode
, 5, 1))) {
20979 gen_bitops(ctx
, OPC_EXT
, rt
, rs
, extract32(ctx
->opcode
, 0, 5),
20980 extract32(ctx
->opcode
, 6, 5));
20983 gen_reserved_instruction(ctx
);
20988 gen_reserved_instruction(ctx
);
20993 gen_pool32f_nanomips_insn(ctx
);
20998 switch (extract32(ctx
->opcode
, 1, 1)) {
21001 tcg_gen_movi_tl(cpu_gpr
[rt
],
21002 sextract32(ctx
->opcode
, 0, 1) << 31 |
21003 extract32(ctx
->opcode
, 2, 10) << 21 |
21004 extract32(ctx
->opcode
, 12, 9) << 12);
21009 offset
= sextract32(ctx
->opcode
, 0, 1) << 31 |
21010 extract32(ctx
->opcode
, 2, 10) << 21 |
21011 extract32(ctx
->opcode
, 12, 9) << 12;
21013 addr
= ~0xFFF & addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
21014 tcg_gen_movi_tl(cpu_gpr
[rt
], addr
);
21021 uint32_t u
= extract32(ctx
->opcode
, 0, 18);
21023 switch (extract32(ctx
->opcode
, 18, 3)) {
21025 gen_ld(ctx
, OPC_LB
, rt
, 28, u
);
21028 gen_st(ctx
, OPC_SB
, rt
, 28, u
);
21031 gen_ld(ctx
, OPC_LBU
, rt
, 28, u
);
21035 gen_op_addr_addi(ctx
, cpu_gpr
[rt
], cpu_gpr
[28], u
);
21040 switch (ctx
->opcode
& 1) {
21042 gen_ld(ctx
, OPC_LH
, rt
, 28, u
);
21045 gen_ld(ctx
, OPC_LHU
, rt
, 28, u
);
21051 switch (ctx
->opcode
& 1) {
21053 gen_st(ctx
, OPC_SH
, rt
, 28, u
);
21056 gen_reserved_instruction(ctx
);
21062 switch (ctx
->opcode
& 0x3) {
21064 gen_cop1_ldst(ctx
, OPC_LWC1
, rt
, 28, u
);
21067 gen_cop1_ldst(ctx
, OPC_LDC1
, rt
, 28, u
);
21070 gen_cop1_ldst(ctx
, OPC_SWC1
, rt
, 28, u
);
21073 gen_cop1_ldst(ctx
, OPC_SDC1
, rt
, 28, u
);
21078 gen_reserved_instruction(ctx
);
21085 uint32_t u
= extract32(ctx
->opcode
, 0, 12);
21087 switch (extract32(ctx
->opcode
, 12, 4)) {
21092 * Break the TB to be able to sync copied instructions
21095 ctx
->base
.is_jmp
= DISAS_STOP
;
21098 /* Treat as NOP. */
21102 gen_ld(ctx
, OPC_LB
, rt
, rs
, u
);
21105 gen_ld(ctx
, OPC_LH
, rt
, rs
, u
);
21108 gen_ld(ctx
, OPC_LW
, rt
, rs
, u
);
21111 gen_ld(ctx
, OPC_LBU
, rt
, rs
, u
);
21114 gen_ld(ctx
, OPC_LHU
, rt
, rs
, u
);
21117 gen_st(ctx
, OPC_SB
, rt
, rs
, u
);
21120 gen_st(ctx
, OPC_SH
, rt
, rs
, u
);
21123 gen_st(ctx
, OPC_SW
, rt
, rs
, u
);
21126 gen_cop1_ldst(ctx
, OPC_LWC1
, rt
, rs
, u
);
21129 gen_cop1_ldst(ctx
, OPC_LDC1
, rt
, rs
, u
);
21132 gen_cop1_ldst(ctx
, OPC_SWC1
, rt
, rs
, u
);
21135 gen_cop1_ldst(ctx
, OPC_SDC1
, rt
, rs
, u
);
21138 gen_reserved_instruction(ctx
);
21145 int32_t s
= (sextract32(ctx
->opcode
, 15, 1) << 8) |
21146 extract32(ctx
->opcode
, 0, 8);
21148 switch (extract32(ctx
->opcode
, 8, 3)) {
21150 switch (extract32(ctx
->opcode
, 11, 4)) {
21152 gen_ld(ctx
, OPC_LB
, rt
, rs
, s
);
21155 gen_ld(ctx
, OPC_LH
, rt
, rs
, s
);
21158 gen_ld(ctx
, OPC_LW
, rt
, rs
, s
);
21161 gen_ld(ctx
, OPC_LBU
, rt
, rs
, s
);
21164 gen_ld(ctx
, OPC_LHU
, rt
, rs
, s
);
21167 gen_st(ctx
, OPC_SB
, rt
, rs
, s
);
21170 gen_st(ctx
, OPC_SH
, rt
, rs
, s
);
21173 gen_st(ctx
, OPC_SW
, rt
, rs
, s
);
21176 gen_cop1_ldst(ctx
, OPC_LWC1
, rt
, rs
, s
);
21179 gen_cop1_ldst(ctx
, OPC_LDC1
, rt
, rs
, s
);
21182 gen_cop1_ldst(ctx
, OPC_SWC1
, rt
, rs
, s
);
21185 gen_cop1_ldst(ctx
, OPC_SDC1
, rt
, rs
, s
);
21191 * Break the TB to be able to sync copied instructions
21194 ctx
->base
.is_jmp
= DISAS_STOP
;
21197 /* Treat as NOP. */
21201 gen_reserved_instruction(ctx
);
21206 switch (extract32(ctx
->opcode
, 11, 4)) {
21211 TCGv t0
= tcg_temp_new();
21212 TCGv t1
= tcg_temp_new();
21214 gen_base_offset_addr(ctx
, t0
, rs
, s
);
21216 switch (extract32(ctx
->opcode
, 11, 4)) {
21218 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESW
|
21220 gen_store_gpr(t0
, rt
);
21223 gen_load_gpr(t1
, rt
);
21224 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUW
|
21233 switch (ctx
->opcode
& 0x03) {
21235 gen_ld(ctx
, OPC_LL
, rt
, rs
, s
);
21239 gen_llwp(ctx
, rs
, 0, rt
, extract32(ctx
->opcode
, 3, 5));
21244 switch (ctx
->opcode
& 0x03) {
21246 gen_st_cond(ctx
, rt
, rs
, s
, MO_TESL
, false);
21250 gen_scwp(ctx
, rs
, 0, rt
, extract32(ctx
->opcode
, 3, 5),
21256 check_cp0_enabled(ctx
);
21257 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
21258 gen_cache_operation(ctx
, rt
, rs
, s
);
21264 switch (extract32(ctx
->opcode
, 11, 4)) {
21267 check_cp0_enabled(ctx
);
21268 gen_ld(ctx
, OPC_LBE
, rt
, rs
, s
);
21272 check_cp0_enabled(ctx
);
21273 gen_st(ctx
, OPC_SBE
, rt
, rs
, s
);
21277 check_cp0_enabled(ctx
);
21278 gen_ld(ctx
, OPC_LBUE
, rt
, rs
, s
);
21282 /* case NM_SYNCIE */
21284 check_cp0_enabled(ctx
);
21286 * Break the TB to be able to sync copied instructions
21289 ctx
->base
.is_jmp
= DISAS_STOP
;
21291 /* case NM_PREFE */
21293 check_cp0_enabled(ctx
);
21294 /* Treat as NOP. */
21299 check_cp0_enabled(ctx
);
21300 gen_ld(ctx
, OPC_LHE
, rt
, rs
, s
);
21304 check_cp0_enabled(ctx
);
21305 gen_st(ctx
, OPC_SHE
, rt
, rs
, s
);
21309 check_cp0_enabled(ctx
);
21310 gen_ld(ctx
, OPC_LHUE
, rt
, rs
, s
);
21313 check_nms_dl_il_sl_tl_l2c(ctx
);
21314 gen_cache_operation(ctx
, rt
, rs
, s
);
21318 check_cp0_enabled(ctx
);
21319 gen_ld(ctx
, OPC_LWE
, rt
, rs
, s
);
21323 check_cp0_enabled(ctx
);
21324 gen_st(ctx
, OPC_SWE
, rt
, rs
, s
);
21327 switch (extract32(ctx
->opcode
, 2, 2)) {
21331 check_cp0_enabled(ctx
);
21332 gen_ld(ctx
, OPC_LLE
, rt
, rs
, s
);
21337 check_cp0_enabled(ctx
);
21338 gen_llwp(ctx
, rs
, 0, rt
, extract32(ctx
->opcode
, 3, 5));
21341 gen_reserved_instruction(ctx
);
21346 switch (extract32(ctx
->opcode
, 2, 2)) {
21350 check_cp0_enabled(ctx
);
21351 gen_st_cond(ctx
, rt
, rs
, s
, MO_TESL
, true);
21356 check_cp0_enabled(ctx
);
21357 gen_scwp(ctx
, rs
, 0, rt
, extract32(ctx
->opcode
, 3, 5),
21361 gen_reserved_instruction(ctx
);
21371 int count
= extract32(ctx
->opcode
, 12, 3);
21374 offset
= sextract32(ctx
->opcode
, 15, 1) << 8 |
21375 extract32(ctx
->opcode
, 0, 8);
21376 TCGv va
= tcg_temp_new();
21377 TCGv t1
= tcg_temp_new();
21378 MemOp memop
= (extract32(ctx
->opcode
, 8, 3)) ==
21379 NM_P_LS_UAWM
? MO_UNALN
: 0;
21381 count
= (count
== 0) ? 8 : count
;
21382 while (counter
!= count
) {
21383 int this_rt
= ((rt
+ counter
) & 0x1f) | (rt
& 0x10);
21384 int this_offset
= offset
+ (counter
<< 2);
21386 gen_base_offset_addr(ctx
, va
, rs
, this_offset
);
21388 switch (extract32(ctx
->opcode
, 11, 1)) {
21390 tcg_gen_qemu_ld_tl(t1
, va
, ctx
->mem_idx
,
21392 gen_store_gpr(t1
, this_rt
);
21393 if ((this_rt
== rs
) &&
21394 (counter
!= (count
- 1))) {
21395 /* UNPREDICTABLE */
21399 this_rt
= (rt
== 0) ? 0 : this_rt
;
21400 gen_load_gpr(t1
, this_rt
);
21401 tcg_gen_qemu_st_tl(t1
, va
, ctx
->mem_idx
,
21412 gen_reserved_instruction(ctx
);
21420 TCGv t0
= tcg_temp_new();
21421 int32_t s
= sextract32(ctx
->opcode
, 0, 1) << 21 |
21422 extract32(ctx
->opcode
, 1, 20) << 1;
21423 rd
= (extract32(ctx
->opcode
, 24, 1)) == 0 ? 4 : 5;
21424 rt
= decode_gpr_gpr4_zero(extract32(ctx
->opcode
, 25, 1) << 3 |
21425 extract32(ctx
->opcode
, 21, 3));
21426 gen_load_gpr(t0
, rt
);
21427 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
21428 gen_compute_branch_nm(ctx
, OPC_BGEZAL
, 4, 0, 0, s
);
21434 int32_t s
= sextract32(ctx
->opcode
, 0, 1) << 25 |
21435 extract32(ctx
->opcode
, 1, 24) << 1;
21437 if ((extract32(ctx
->opcode
, 25, 1)) == 0) {
21439 gen_compute_branch_nm(ctx
, OPC_BEQ
, 4, 0, 0, s
);
21442 gen_compute_branch_nm(ctx
, OPC_BGEZAL
, 4, 0, 0, s
);
21447 switch (extract32(ctx
->opcode
, 12, 4)) {
21450 gen_compute_branch_nm(ctx
, OPC_JALR
, 4, rs
, rt
, 0);
21453 gen_compute_nanomips_pbalrsc_branch(ctx
, rs
, rt
);
21456 gen_reserved_instruction(ctx
);
21462 int32_t s
= sextract32(ctx
->opcode
, 0, 1) << 14 |
21463 extract32(ctx
->opcode
, 1, 13) << 1;
21464 switch (extract32(ctx
->opcode
, 14, 2)) {
21467 gen_compute_branch_nm(ctx
, OPC_BEQ
, 4, rs
, rt
, s
);
21470 s
= sextract32(ctx
->opcode
, 0, 1) << 14 |
21471 extract32(ctx
->opcode
, 1, 13) << 1;
21472 check_cp1_enabled(ctx
);
21473 switch (extract32(ctx
->opcode
, 16, 5)) {
21475 gen_compute_branch_cp1_nm(ctx
, OPC_BC1EQZ
, rt
, s
);
21478 gen_compute_branch_cp1_nm(ctx
, OPC_BC1NEZ
, rt
, s
);
21483 int32_t imm
= extract32(ctx
->opcode
, 1, 13) |
21484 extract32(ctx
->opcode
, 0, 1) << 13;
21486 gen_compute_branch_nm(ctx
, OPC_BPOSGE32
, 4, -1, -2,
21491 gen_reserved_instruction(ctx
);
21497 gen_compute_compact_branch_nm(ctx
, OPC_BC
, rs
, rt
, s
);
21499 gen_compute_compact_branch_nm(ctx
, OPC_BGEC
, rs
, rt
, s
);
21503 if (rs
== rt
|| rt
== 0) {
21504 gen_compute_compact_branch_nm(ctx
, OPC_BC
, 0, 0, s
);
21505 } else if (rs
== 0) {
21506 gen_compute_compact_branch_nm(ctx
, OPC_BEQZC
, rt
, 0, s
);
21508 gen_compute_compact_branch_nm(ctx
, OPC_BGEUC
, rs
, rt
, s
);
21516 int32_t s
= sextract32(ctx
->opcode
, 0, 1) << 14 |
21517 extract32(ctx
->opcode
, 1, 13) << 1;
21518 switch (extract32(ctx
->opcode
, 14, 2)) {
21521 gen_compute_branch_nm(ctx
, OPC_BNE
, 4, rs
, rt
, s
);
21524 if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
21526 ctx
->hflags
|= MIPS_HFLAG_FBNSLOT
;
21528 gen_compute_compact_branch_nm(ctx
, OPC_BLTC
, rs
, rt
, s
);
21532 if (rs
== 0 || rs
== rt
) {
21534 ctx
->hflags
|= MIPS_HFLAG_FBNSLOT
;
21536 gen_compute_compact_branch_nm(ctx
, OPC_BLTUC
, rs
, rt
, s
);
21540 gen_reserved_instruction(ctx
);
21547 int32_t s
= sextract32(ctx
->opcode
, 0, 1) << 11 |
21548 extract32(ctx
->opcode
, 1, 10) << 1;
21549 uint32_t u
= extract32(ctx
->opcode
, 11, 7);
21551 gen_compute_imm_branch(ctx
, extract32(ctx
->opcode
, 18, 3),
21556 gen_reserved_instruction(ctx
);
21562 static int decode_nanomips_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
21565 int rt
= decode_gpr_gpr3(NANOMIPS_EXTRACT_RT3(ctx
->opcode
));
21566 int rs
= decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx
->opcode
));
21567 int rd
= decode_gpr_gpr3(NANOMIPS_EXTRACT_RD3(ctx
->opcode
));
21571 /* make sure instructions are on a halfword boundary */
21572 if (ctx
->base
.pc_next
& 0x1) {
21573 TCGv tmp
= tcg_const_tl(ctx
->base
.pc_next
);
21574 tcg_gen_st_tl(tmp
, cpu_env
, offsetof(CPUMIPSState
, CP0_BadVAddr
));
21575 tcg_temp_free(tmp
);
21576 generate_exception_end(ctx
, EXCP_AdEL
);
21580 op
= extract32(ctx
->opcode
, 10, 6);
21583 rt
= NANOMIPS_EXTRACT_RD5(ctx
->opcode
);
21586 rs
= NANOMIPS_EXTRACT_RS5(ctx
->opcode
);
21587 gen_arith(ctx
, OPC_ADDU
, rt
, rs
, 0);
21590 switch (extract32(ctx
->opcode
, 3, 2)) {
21591 case NM_P16_SYSCALL
:
21592 if (extract32(ctx
->opcode
, 2, 1) == 0) {
21593 generate_exception_end(ctx
, EXCP_SYSCALL
);
21595 gen_reserved_instruction(ctx
);
21599 generate_exception_end(ctx
, EXCP_BREAK
);
21602 if (is_uhi(extract32(ctx
->opcode
, 0, 3))) {
21603 gen_helper_do_semihosting(cpu_env
);
21605 if (ctx
->hflags
& MIPS_HFLAG_SBRI
) {
21606 gen_reserved_instruction(ctx
);
21608 generate_exception_end(ctx
, EXCP_DBp
);
21613 gen_reserved_instruction(ctx
);
21620 int shift
= extract32(ctx
->opcode
, 0, 3);
21622 shift
= (shift
== 0) ? 8 : shift
;
21624 switch (extract32(ctx
->opcode
, 3, 1)) {
21632 gen_shift_imm(ctx
, opc
, rt
, rs
, shift
);
21636 switch (ctx
->opcode
& 1) {
21638 gen_pool16c_nanomips_insn(ctx
);
21641 gen_ldxs(ctx
, rt
, rs
, rd
);
21646 switch (extract32(ctx
->opcode
, 6, 1)) {
21648 imm
= extract32(ctx
->opcode
, 0, 6) << 2;
21649 gen_arith_imm(ctx
, OPC_ADDIU
, rt
, 29, imm
);
21652 gen_reserved_instruction(ctx
);
21657 switch (extract32(ctx
->opcode
, 3, 1)) {
21659 imm
= extract32(ctx
->opcode
, 0, 3) << 2;
21660 gen_arith_imm(ctx
, OPC_ADDIU
, rt
, rs
, imm
);
21662 case NM_P_ADDIURS5
:
21663 rt
= extract32(ctx
->opcode
, 5, 5);
21665 /* imm = sign_extend(s[3] . s[2:0] , from_nbits = 4) */
21666 imm
= (sextract32(ctx
->opcode
, 4, 1) << 3) |
21667 (extract32(ctx
->opcode
, 0, 3));
21668 gen_arith_imm(ctx
, OPC_ADDIU
, rt
, rt
, imm
);
21674 switch (ctx
->opcode
& 0x1) {
21676 gen_arith(ctx
, OPC_ADDU
, rd
, rs
, rt
);
21679 gen_arith(ctx
, OPC_SUBU
, rd
, rs
, rt
);
21684 rt
= (extract32(ctx
->opcode
, 9, 1) << 3) |
21685 extract32(ctx
->opcode
, 5, 3);
21686 rs
= (extract32(ctx
->opcode
, 4, 1) << 3) |
21687 extract32(ctx
->opcode
, 0, 3);
21688 rt
= decode_gpr_gpr4(rt
);
21689 rs
= decode_gpr_gpr4(rs
);
21690 switch ((extract32(ctx
->opcode
, 7, 2) & 0x2) |
21691 (extract32(ctx
->opcode
, 3, 1))) {
21694 gen_arith(ctx
, OPC_ADDU
, rt
, rs
, rt
);
21698 gen_r6_muldiv(ctx
, R6_OPC_MUL
, rt
, rs
, rt
);
21701 gen_reserved_instruction(ctx
);
21707 int imm
= extract32(ctx
->opcode
, 0, 7);
21708 imm
= (imm
== 0x7f ? -1 : imm
);
21710 tcg_gen_movi_tl(cpu_gpr
[rt
], imm
);
21716 uint32_t u
= extract32(ctx
->opcode
, 0, 4);
21717 u
= (u
== 12) ? 0xff :
21718 (u
== 13) ? 0xffff : u
;
21719 gen_logic_imm(ctx
, OPC_ANDI
, rt
, rs
, u
);
21723 offset
= extract32(ctx
->opcode
, 0, 2);
21724 switch (extract32(ctx
->opcode
, 2, 2)) {
21726 gen_ld(ctx
, OPC_LB
, rt
, rs
, offset
);
21729 rt
= decode_gpr_gpr3_src_store(
21730 NANOMIPS_EXTRACT_RT3(ctx
->opcode
));
21731 gen_st(ctx
, OPC_SB
, rt
, rs
, offset
);
21734 gen_ld(ctx
, OPC_LBU
, rt
, rs
, offset
);
21737 gen_reserved_instruction(ctx
);
21742 offset
= extract32(ctx
->opcode
, 1, 2) << 1;
21743 switch ((extract32(ctx
->opcode
, 3, 1) << 1) | (ctx
->opcode
& 1)) {
21745 gen_ld(ctx
, OPC_LH
, rt
, rs
, offset
);
21748 rt
= decode_gpr_gpr3_src_store(
21749 NANOMIPS_EXTRACT_RT3(ctx
->opcode
));
21750 gen_st(ctx
, OPC_SH
, rt
, rs
, offset
);
21753 gen_ld(ctx
, OPC_LHU
, rt
, rs
, offset
);
21756 gen_reserved_instruction(ctx
);
21761 offset
= extract32(ctx
->opcode
, 0, 4) << 2;
21762 gen_ld(ctx
, OPC_LW
, rt
, rs
, offset
);
21765 rt
= NANOMIPS_EXTRACT_RD5(ctx
->opcode
);
21766 offset
= extract32(ctx
->opcode
, 0, 5) << 2;
21767 gen_ld(ctx
, OPC_LW
, rt
, 29, offset
);
21771 rt
= (extract32(ctx
->opcode
, 9, 1) << 3) |
21772 extract32(ctx
->opcode
, 5, 3);
21773 rs
= (extract32(ctx
->opcode
, 4, 1) << 3) |
21774 extract32(ctx
->opcode
, 0, 3);
21775 offset
= (extract32(ctx
->opcode
, 3, 1) << 3) |
21776 (extract32(ctx
->opcode
, 8, 1) << 2);
21777 rt
= decode_gpr_gpr4(rt
);
21778 rs
= decode_gpr_gpr4(rs
);
21779 gen_ld(ctx
, OPC_LW
, rt
, rs
, offset
);
21783 rt
= (extract32(ctx
->opcode
, 9, 1) << 3) |
21784 extract32(ctx
->opcode
, 5, 3);
21785 rs
= (extract32(ctx
->opcode
, 4, 1) << 3) |
21786 extract32(ctx
->opcode
, 0, 3);
21787 offset
= (extract32(ctx
->opcode
, 3, 1) << 3) |
21788 (extract32(ctx
->opcode
, 8, 1) << 2);
21789 rt
= decode_gpr_gpr4_zero(rt
);
21790 rs
= decode_gpr_gpr4(rs
);
21791 gen_st(ctx
, OPC_SW
, rt
, rs
, offset
);
21794 offset
= extract32(ctx
->opcode
, 0, 7) << 2;
21795 gen_ld(ctx
, OPC_LW
, rt
, 28, offset
);
21798 rt
= NANOMIPS_EXTRACT_RD5(ctx
->opcode
);
21799 offset
= extract32(ctx
->opcode
, 0, 5) << 2;
21800 gen_st(ctx
, OPC_SW
, rt
, 29, offset
);
21803 rt
= decode_gpr_gpr3_src_store(
21804 NANOMIPS_EXTRACT_RT3(ctx
->opcode
));
21805 rs
= decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx
->opcode
));
21806 offset
= extract32(ctx
->opcode
, 0, 4) << 2;
21807 gen_st(ctx
, OPC_SW
, rt
, rs
, offset
);
21810 rt
= decode_gpr_gpr3_src_store(
21811 NANOMIPS_EXTRACT_RT3(ctx
->opcode
));
21812 offset
= extract32(ctx
->opcode
, 0, 7) << 2;
21813 gen_st(ctx
, OPC_SW
, rt
, 28, offset
);
21816 gen_compute_branch_nm(ctx
, OPC_BEQ
, 2, 0, 0,
21817 (sextract32(ctx
->opcode
, 0, 1) << 10) |
21818 (extract32(ctx
->opcode
, 1, 9) << 1));
21821 gen_compute_branch_nm(ctx
, OPC_BGEZAL
, 2, 0, 0,
21822 (sextract32(ctx
->opcode
, 0, 1) << 10) |
21823 (extract32(ctx
->opcode
, 1, 9) << 1));
21826 gen_compute_branch_nm(ctx
, OPC_BEQ
, 2, rt
, 0,
21827 (sextract32(ctx
->opcode
, 0, 1) << 7) |
21828 (extract32(ctx
->opcode
, 1, 6) << 1));
21831 gen_compute_branch_nm(ctx
, OPC_BNE
, 2, rt
, 0,
21832 (sextract32(ctx
->opcode
, 0, 1) << 7) |
21833 (extract32(ctx
->opcode
, 1, 6) << 1));
21836 switch (ctx
->opcode
& 0xf) {
21839 switch (extract32(ctx
->opcode
, 4, 1)) {
21841 gen_compute_branch_nm(ctx
, OPC_JR
, 2,
21842 extract32(ctx
->opcode
, 5, 5), 0, 0);
21845 gen_compute_branch_nm(ctx
, OPC_JALR
, 2,
21846 extract32(ctx
->opcode
, 5, 5), 31, 0);
21853 uint32_t opc
= extract32(ctx
->opcode
, 4, 3) <
21854 extract32(ctx
->opcode
, 7, 3) ? OPC_BEQ
: OPC_BNE
;
21855 gen_compute_branch_nm(ctx
, opc
, 2, rs
, rt
,
21856 extract32(ctx
->opcode
, 0, 4) << 1);
21863 int count
= extract32(ctx
->opcode
, 0, 4);
21864 int u
= extract32(ctx
->opcode
, 4, 4) << 4;
21866 rt
= 30 + extract32(ctx
->opcode
, 9, 1);
21867 switch (extract32(ctx
->opcode
, 8, 1)) {
21869 gen_save(ctx
, rt
, count
, 0, u
);
21871 case NM_RESTORE_JRC16
:
21872 gen_restore(ctx
, rt
, count
, 0, u
);
21873 gen_compute_branch_nm(ctx
, OPC_JR
, 2, 31, 0, 0);
21882 static const int gpr2reg1
[] = {4, 5, 6, 7};
21883 static const int gpr2reg2
[] = {5, 6, 7, 8};
21885 int rd2
= extract32(ctx
->opcode
, 3, 1) << 1 |
21886 extract32(ctx
->opcode
, 8, 1);
21887 int r1
= gpr2reg1
[rd2
];
21888 int r2
= gpr2reg2
[rd2
];
21889 int r3
= extract32(ctx
->opcode
, 4, 1) << 3 |
21890 extract32(ctx
->opcode
, 0, 3);
21891 int r4
= extract32(ctx
->opcode
, 9, 1) << 3 |
21892 extract32(ctx
->opcode
, 5, 3);
21893 TCGv t0
= tcg_temp_new();
21894 TCGv t1
= tcg_temp_new();
21895 if (op
== NM_MOVEP
) {
21898 rs
= decode_gpr_gpr4_zero(r3
);
21899 rt
= decode_gpr_gpr4_zero(r4
);
21901 rd
= decode_gpr_gpr4(r3
);
21902 re
= decode_gpr_gpr4(r4
);
21906 gen_load_gpr(t0
, rs
);
21907 gen_load_gpr(t1
, rt
);
21908 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
21909 tcg_gen_mov_tl(cpu_gpr
[re
], t1
);
21915 return decode_nanomips_32_48_opc(env
, ctx
);
21922 /* SmartMIPS extension to MIPS32 */
21924 #if defined(TARGET_MIPS64)
21926 /* MDMX extension to MIPS64 */
21930 /* MIPSDSP functions. */
21931 static void gen_mipsdsp_ld(DisasContext
*ctx
, uint32_t opc
,
21932 int rd
, int base
, int offset
)
21937 t0
= tcg_temp_new();
21940 gen_load_gpr(t0
, offset
);
21941 } else if (offset
== 0) {
21942 gen_load_gpr(t0
, base
);
21944 gen_op_addr_add(ctx
, t0
, cpu_gpr
[base
], cpu_gpr
[offset
]);
21949 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_UB
);
21950 gen_store_gpr(t0
, rd
);
21953 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESW
);
21954 gen_store_gpr(t0
, rd
);
21957 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESL
);
21958 gen_store_gpr(t0
, rd
);
21960 #if defined(TARGET_MIPS64)
21962 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
);
21963 gen_store_gpr(t0
, rd
);
21970 static void gen_mipsdsp_arith(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
21971 int ret
, int v1
, int v2
)
21977 /* Treat as NOP. */
21981 v1_t
= tcg_temp_new();
21982 v2_t
= tcg_temp_new();
21984 gen_load_gpr(v1_t
, v1
);
21985 gen_load_gpr(v2_t
, v2
);
21988 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
21989 case OPC_MULT_G_2E
:
21993 gen_helper_adduh_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
21995 case OPC_ADDUH_R_QB
:
21996 gen_helper_adduh_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
21999 gen_helper_addqh_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
22001 case OPC_ADDQH_R_PH
:
22002 gen_helper_addqh_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
22005 gen_helper_addqh_w(cpu_gpr
[ret
], v1_t
, v2_t
);
22007 case OPC_ADDQH_R_W
:
22008 gen_helper_addqh_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
22011 gen_helper_subuh_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
22013 case OPC_SUBUH_R_QB
:
22014 gen_helper_subuh_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
22017 gen_helper_subqh_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
22019 case OPC_SUBQH_R_PH
:
22020 gen_helper_subqh_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
22023 gen_helper_subqh_w(cpu_gpr
[ret
], v1_t
, v2_t
);
22025 case OPC_SUBQH_R_W
:
22026 gen_helper_subqh_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
22030 case OPC_ABSQ_S_PH_DSP
:
22032 case OPC_ABSQ_S_QB
:
22034 gen_helper_absq_s_qb(cpu_gpr
[ret
], v2_t
, cpu_env
);
22036 case OPC_ABSQ_S_PH
:
22038 gen_helper_absq_s_ph(cpu_gpr
[ret
], v2_t
, cpu_env
);
22042 gen_helper_absq_s_w(cpu_gpr
[ret
], v2_t
, cpu_env
);
22044 case OPC_PRECEQ_W_PHL
:
22046 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0xFFFF0000);
22047 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
22049 case OPC_PRECEQ_W_PHR
:
22051 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0x0000FFFF);
22052 tcg_gen_shli_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], 16);
22053 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
22055 case OPC_PRECEQU_PH_QBL
:
22057 gen_helper_precequ_ph_qbl(cpu_gpr
[ret
], v2_t
);
22059 case OPC_PRECEQU_PH_QBR
:
22061 gen_helper_precequ_ph_qbr(cpu_gpr
[ret
], v2_t
);
22063 case OPC_PRECEQU_PH_QBLA
:
22065 gen_helper_precequ_ph_qbla(cpu_gpr
[ret
], v2_t
);
22067 case OPC_PRECEQU_PH_QBRA
:
22069 gen_helper_precequ_ph_qbra(cpu_gpr
[ret
], v2_t
);
22071 case OPC_PRECEU_PH_QBL
:
22073 gen_helper_preceu_ph_qbl(cpu_gpr
[ret
], v2_t
);
22075 case OPC_PRECEU_PH_QBR
:
22077 gen_helper_preceu_ph_qbr(cpu_gpr
[ret
], v2_t
);
22079 case OPC_PRECEU_PH_QBLA
:
22081 gen_helper_preceu_ph_qbla(cpu_gpr
[ret
], v2_t
);
22083 case OPC_PRECEU_PH_QBRA
:
22085 gen_helper_preceu_ph_qbra(cpu_gpr
[ret
], v2_t
);
22089 case OPC_ADDU_QB_DSP
:
22093 gen_helper_addq_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22095 case OPC_ADDQ_S_PH
:
22097 gen_helper_addq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22101 gen_helper_addq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22105 gen_helper_addu_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22107 case OPC_ADDU_S_QB
:
22109 gen_helper_addu_s_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22113 gen_helper_addu_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22115 case OPC_ADDU_S_PH
:
22117 gen_helper_addu_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22121 gen_helper_subq_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22123 case OPC_SUBQ_S_PH
:
22125 gen_helper_subq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22129 gen_helper_subq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22133 gen_helper_subu_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22135 case OPC_SUBU_S_QB
:
22137 gen_helper_subu_s_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22141 gen_helper_subu_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22143 case OPC_SUBU_S_PH
:
22145 gen_helper_subu_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22149 gen_helper_addsc(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22153 gen_helper_addwc(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22157 gen_helper_modsub(cpu_gpr
[ret
], v1_t
, v2_t
);
22159 case OPC_RADDU_W_QB
:
22161 gen_helper_raddu_w_qb(cpu_gpr
[ret
], v1_t
);
22165 case OPC_CMPU_EQ_QB_DSP
:
22167 case OPC_PRECR_QB_PH
:
22169 gen_helper_precr_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
22171 case OPC_PRECRQ_QB_PH
:
22173 gen_helper_precrq_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
22175 case OPC_PRECR_SRA_PH_W
:
22178 TCGv_i32 sa_t
= tcg_const_i32(v2
);
22179 gen_helper_precr_sra_ph_w(cpu_gpr
[ret
], sa_t
, v1_t
,
22181 tcg_temp_free_i32(sa_t
);
22184 case OPC_PRECR_SRA_R_PH_W
:
22187 TCGv_i32 sa_t
= tcg_const_i32(v2
);
22188 gen_helper_precr_sra_r_ph_w(cpu_gpr
[ret
], sa_t
, v1_t
,
22190 tcg_temp_free_i32(sa_t
);
22193 case OPC_PRECRQ_PH_W
:
22195 gen_helper_precrq_ph_w(cpu_gpr
[ret
], v1_t
, v2_t
);
22197 case OPC_PRECRQ_RS_PH_W
:
22199 gen_helper_precrq_rs_ph_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22201 case OPC_PRECRQU_S_QB_PH
:
22203 gen_helper_precrqu_s_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22207 #ifdef TARGET_MIPS64
22208 case OPC_ABSQ_S_QH_DSP
:
22210 case OPC_PRECEQ_L_PWL
:
22212 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0xFFFFFFFF00000000ull
);
22214 case OPC_PRECEQ_L_PWR
:
22216 tcg_gen_shli_tl(cpu_gpr
[ret
], v2_t
, 32);
22218 case OPC_PRECEQ_PW_QHL
:
22220 gen_helper_preceq_pw_qhl(cpu_gpr
[ret
], v2_t
);
22222 case OPC_PRECEQ_PW_QHR
:
22224 gen_helper_preceq_pw_qhr(cpu_gpr
[ret
], v2_t
);
22226 case OPC_PRECEQ_PW_QHLA
:
22228 gen_helper_preceq_pw_qhla(cpu_gpr
[ret
], v2_t
);
22230 case OPC_PRECEQ_PW_QHRA
:
22232 gen_helper_preceq_pw_qhra(cpu_gpr
[ret
], v2_t
);
22234 case OPC_PRECEQU_QH_OBL
:
22236 gen_helper_precequ_qh_obl(cpu_gpr
[ret
], v2_t
);
22238 case OPC_PRECEQU_QH_OBR
:
22240 gen_helper_precequ_qh_obr(cpu_gpr
[ret
], v2_t
);
22242 case OPC_PRECEQU_QH_OBLA
:
22244 gen_helper_precequ_qh_obla(cpu_gpr
[ret
], v2_t
);
22246 case OPC_PRECEQU_QH_OBRA
:
22248 gen_helper_precequ_qh_obra(cpu_gpr
[ret
], v2_t
);
22250 case OPC_PRECEU_QH_OBL
:
22252 gen_helper_preceu_qh_obl(cpu_gpr
[ret
], v2_t
);
22254 case OPC_PRECEU_QH_OBR
:
22256 gen_helper_preceu_qh_obr(cpu_gpr
[ret
], v2_t
);
22258 case OPC_PRECEU_QH_OBLA
:
22260 gen_helper_preceu_qh_obla(cpu_gpr
[ret
], v2_t
);
22262 case OPC_PRECEU_QH_OBRA
:
22264 gen_helper_preceu_qh_obra(cpu_gpr
[ret
], v2_t
);
22266 case OPC_ABSQ_S_OB
:
22268 gen_helper_absq_s_ob(cpu_gpr
[ret
], v2_t
, cpu_env
);
22270 case OPC_ABSQ_S_PW
:
22272 gen_helper_absq_s_pw(cpu_gpr
[ret
], v2_t
, cpu_env
);
22274 case OPC_ABSQ_S_QH
:
22276 gen_helper_absq_s_qh(cpu_gpr
[ret
], v2_t
, cpu_env
);
22280 case OPC_ADDU_OB_DSP
:
22282 case OPC_RADDU_L_OB
:
22284 gen_helper_raddu_l_ob(cpu_gpr
[ret
], v1_t
);
22288 gen_helper_subq_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22290 case OPC_SUBQ_S_PW
:
22292 gen_helper_subq_s_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22296 gen_helper_subq_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22298 case OPC_SUBQ_S_QH
:
22300 gen_helper_subq_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22304 gen_helper_subu_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22306 case OPC_SUBU_S_OB
:
22308 gen_helper_subu_s_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22312 gen_helper_subu_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22314 case OPC_SUBU_S_QH
:
22316 gen_helper_subu_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22320 gen_helper_subuh_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
22322 case OPC_SUBUH_R_OB
:
22324 gen_helper_subuh_r_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
22328 gen_helper_addq_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22330 case OPC_ADDQ_S_PW
:
22332 gen_helper_addq_s_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22336 gen_helper_addq_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22338 case OPC_ADDQ_S_QH
:
22340 gen_helper_addq_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22344 gen_helper_addu_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22346 case OPC_ADDU_S_OB
:
22348 gen_helper_addu_s_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22352 gen_helper_addu_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22354 case OPC_ADDU_S_QH
:
22356 gen_helper_addu_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22360 gen_helper_adduh_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
22362 case OPC_ADDUH_R_OB
:
22364 gen_helper_adduh_r_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
22368 case OPC_CMPU_EQ_OB_DSP
:
22370 case OPC_PRECR_OB_QH
:
22372 gen_helper_precr_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
);
22374 case OPC_PRECR_SRA_QH_PW
:
22377 TCGv_i32 ret_t
= tcg_const_i32(ret
);
22378 gen_helper_precr_sra_qh_pw(v2_t
, v1_t
, v2_t
, ret_t
);
22379 tcg_temp_free_i32(ret_t
);
22382 case OPC_PRECR_SRA_R_QH_PW
:
22385 TCGv_i32 sa_v
= tcg_const_i32(ret
);
22386 gen_helper_precr_sra_r_qh_pw(v2_t
, v1_t
, v2_t
, sa_v
);
22387 tcg_temp_free_i32(sa_v
);
22390 case OPC_PRECRQ_OB_QH
:
22392 gen_helper_precrq_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
);
22394 case OPC_PRECRQ_PW_L
:
22396 gen_helper_precrq_pw_l(cpu_gpr
[ret
], v1_t
, v2_t
);
22398 case OPC_PRECRQ_QH_PW
:
22400 gen_helper_precrq_qh_pw(cpu_gpr
[ret
], v1_t
, v2_t
);
22402 case OPC_PRECRQ_RS_QH_PW
:
22404 gen_helper_precrq_rs_qh_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22406 case OPC_PRECRQU_S_OB_QH
:
22408 gen_helper_precrqu_s_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22415 tcg_temp_free(v1_t
);
22416 tcg_temp_free(v2_t
);
22419 static void gen_mipsdsp_shift(DisasContext
*ctx
, uint32_t opc
,
22420 int ret
, int v1
, int v2
)
22428 /* Treat as NOP. */
22432 t0
= tcg_temp_new();
22433 v1_t
= tcg_temp_new();
22434 v2_t
= tcg_temp_new();
22436 tcg_gen_movi_tl(t0
, v1
);
22437 gen_load_gpr(v1_t
, v1
);
22438 gen_load_gpr(v2_t
, v2
);
22441 case OPC_SHLL_QB_DSP
:
22443 op2
= MASK_SHLL_QB(ctx
->opcode
);
22447 gen_helper_shll_qb(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
22451 gen_helper_shll_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22455 gen_helper_shll_ph(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
22459 gen_helper_shll_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22461 case OPC_SHLL_S_PH
:
22463 gen_helper_shll_s_ph(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
22465 case OPC_SHLLV_S_PH
:
22467 gen_helper_shll_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22471 gen_helper_shll_s_w(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
22473 case OPC_SHLLV_S_W
:
22475 gen_helper_shll_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22479 gen_helper_shrl_qb(cpu_gpr
[ret
], t0
, v2_t
);
22483 gen_helper_shrl_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
22487 gen_helper_shrl_ph(cpu_gpr
[ret
], t0
, v2_t
);
22491 gen_helper_shrl_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
22495 gen_helper_shra_qb(cpu_gpr
[ret
], t0
, v2_t
);
22497 case OPC_SHRA_R_QB
:
22499 gen_helper_shra_r_qb(cpu_gpr
[ret
], t0
, v2_t
);
22503 gen_helper_shra_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
22505 case OPC_SHRAV_R_QB
:
22507 gen_helper_shra_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
22511 gen_helper_shra_ph(cpu_gpr
[ret
], t0
, v2_t
);
22513 case OPC_SHRA_R_PH
:
22515 gen_helper_shra_r_ph(cpu_gpr
[ret
], t0
, v2_t
);
22519 gen_helper_shra_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
22521 case OPC_SHRAV_R_PH
:
22523 gen_helper_shra_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
22527 gen_helper_shra_r_w(cpu_gpr
[ret
], t0
, v2_t
);
22529 case OPC_SHRAV_R_W
:
22531 gen_helper_shra_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
22533 default: /* Invalid */
22534 MIPS_INVAL("MASK SHLL.QB");
22535 gen_reserved_instruction(ctx
);
22540 #ifdef TARGET_MIPS64
22541 case OPC_SHLL_OB_DSP
:
22542 op2
= MASK_SHLL_OB(ctx
->opcode
);
22546 gen_helper_shll_pw(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
22550 gen_helper_shll_pw(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
22552 case OPC_SHLL_S_PW
:
22554 gen_helper_shll_s_pw(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
22556 case OPC_SHLLV_S_PW
:
22558 gen_helper_shll_s_pw(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
22562 gen_helper_shll_ob(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
22566 gen_helper_shll_ob(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
22570 gen_helper_shll_qh(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
22574 gen_helper_shll_qh(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
22576 case OPC_SHLL_S_QH
:
22578 gen_helper_shll_s_qh(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
22580 case OPC_SHLLV_S_QH
:
22582 gen_helper_shll_s_qh(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
22586 gen_helper_shra_ob(cpu_gpr
[ret
], v2_t
, t0
);
22590 gen_helper_shra_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
22592 case OPC_SHRA_R_OB
:
22594 gen_helper_shra_r_ob(cpu_gpr
[ret
], v2_t
, t0
);
22596 case OPC_SHRAV_R_OB
:
22598 gen_helper_shra_r_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
22602 gen_helper_shra_pw(cpu_gpr
[ret
], v2_t
, t0
);
22606 gen_helper_shra_pw(cpu_gpr
[ret
], v2_t
, v1_t
);
22608 case OPC_SHRA_R_PW
:
22610 gen_helper_shra_r_pw(cpu_gpr
[ret
], v2_t
, t0
);
22612 case OPC_SHRAV_R_PW
:
22614 gen_helper_shra_r_pw(cpu_gpr
[ret
], v2_t
, v1_t
);
22618 gen_helper_shra_qh(cpu_gpr
[ret
], v2_t
, t0
);
22622 gen_helper_shra_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
22624 case OPC_SHRA_R_QH
:
22626 gen_helper_shra_r_qh(cpu_gpr
[ret
], v2_t
, t0
);
22628 case OPC_SHRAV_R_QH
:
22630 gen_helper_shra_r_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
22634 gen_helper_shrl_ob(cpu_gpr
[ret
], v2_t
, t0
);
22638 gen_helper_shrl_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
22642 gen_helper_shrl_qh(cpu_gpr
[ret
], v2_t
, t0
);
22646 gen_helper_shrl_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
22648 default: /* Invalid */
22649 MIPS_INVAL("MASK SHLL.OB");
22650 gen_reserved_instruction(ctx
);
22658 tcg_temp_free(v1_t
);
22659 tcg_temp_free(v2_t
);
22662 static void gen_mipsdsp_multiply(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
22663 int ret
, int v1
, int v2
, int check_ret
)
22669 if ((ret
== 0) && (check_ret
== 1)) {
22670 /* Treat as NOP. */
22674 t0
= tcg_temp_new_i32();
22675 v1_t
= tcg_temp_new();
22676 v2_t
= tcg_temp_new();
22678 tcg_gen_movi_i32(t0
, ret
);
22679 gen_load_gpr(v1_t
, v1
);
22680 gen_load_gpr(v2_t
, v2
);
22684 * OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
22685 * the same mask and op1.
22687 case OPC_MULT_G_2E
:
22691 gen_helper_mul_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22694 gen_helper_mul_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22697 gen_helper_mulq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22699 case OPC_MULQ_RS_W
:
22700 gen_helper_mulq_rs_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22704 case OPC_DPA_W_PH_DSP
:
22706 case OPC_DPAU_H_QBL
:
22708 gen_helper_dpau_h_qbl(t0
, v1_t
, v2_t
, cpu_env
);
22710 case OPC_DPAU_H_QBR
:
22712 gen_helper_dpau_h_qbr(t0
, v1_t
, v2_t
, cpu_env
);
22714 case OPC_DPSU_H_QBL
:
22716 gen_helper_dpsu_h_qbl(t0
, v1_t
, v2_t
, cpu_env
);
22718 case OPC_DPSU_H_QBR
:
22720 gen_helper_dpsu_h_qbr(t0
, v1_t
, v2_t
, cpu_env
);
22724 gen_helper_dpa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
22726 case OPC_DPAX_W_PH
:
22728 gen_helper_dpax_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
22730 case OPC_DPAQ_S_W_PH
:
22732 gen_helper_dpaq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
22734 case OPC_DPAQX_S_W_PH
:
22736 gen_helper_dpaqx_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
22738 case OPC_DPAQX_SA_W_PH
:
22740 gen_helper_dpaqx_sa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
22744 gen_helper_dps_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
22746 case OPC_DPSX_W_PH
:
22748 gen_helper_dpsx_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
22750 case OPC_DPSQ_S_W_PH
:
22752 gen_helper_dpsq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
22754 case OPC_DPSQX_S_W_PH
:
22756 gen_helper_dpsqx_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
22758 case OPC_DPSQX_SA_W_PH
:
22760 gen_helper_dpsqx_sa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
22762 case OPC_MULSAQ_S_W_PH
:
22764 gen_helper_mulsaq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
22766 case OPC_DPAQ_SA_L_W
:
22768 gen_helper_dpaq_sa_l_w(t0
, v1_t
, v2_t
, cpu_env
);
22770 case OPC_DPSQ_SA_L_W
:
22772 gen_helper_dpsq_sa_l_w(t0
, v1_t
, v2_t
, cpu_env
);
22774 case OPC_MAQ_S_W_PHL
:
22776 gen_helper_maq_s_w_phl(t0
, v1_t
, v2_t
, cpu_env
);
22778 case OPC_MAQ_S_W_PHR
:
22780 gen_helper_maq_s_w_phr(t0
, v1_t
, v2_t
, cpu_env
);
22782 case OPC_MAQ_SA_W_PHL
:
22784 gen_helper_maq_sa_w_phl(t0
, v1_t
, v2_t
, cpu_env
);
22786 case OPC_MAQ_SA_W_PHR
:
22788 gen_helper_maq_sa_w_phr(t0
, v1_t
, v2_t
, cpu_env
);
22790 case OPC_MULSA_W_PH
:
22792 gen_helper_mulsa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
22796 #ifdef TARGET_MIPS64
22797 case OPC_DPAQ_W_QH_DSP
:
22799 int ac
= ret
& 0x03;
22800 tcg_gen_movi_i32(t0
, ac
);
22805 gen_helper_dmadd(v1_t
, v2_t
, t0
, cpu_env
);
22809 gen_helper_dmaddu(v1_t
, v2_t
, t0
, cpu_env
);
22813 gen_helper_dmsub(v1_t
, v2_t
, t0
, cpu_env
);
22817 gen_helper_dmsubu(v1_t
, v2_t
, t0
, cpu_env
);
22821 gen_helper_dpa_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
22823 case OPC_DPAQ_S_W_QH
:
22825 gen_helper_dpaq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
22827 case OPC_DPAQ_SA_L_PW
:
22829 gen_helper_dpaq_sa_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
22831 case OPC_DPAU_H_OBL
:
22833 gen_helper_dpau_h_obl(v1_t
, v2_t
, t0
, cpu_env
);
22835 case OPC_DPAU_H_OBR
:
22837 gen_helper_dpau_h_obr(v1_t
, v2_t
, t0
, cpu_env
);
22841 gen_helper_dps_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
22843 case OPC_DPSQ_S_W_QH
:
22845 gen_helper_dpsq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
22847 case OPC_DPSQ_SA_L_PW
:
22849 gen_helper_dpsq_sa_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
22851 case OPC_DPSU_H_OBL
:
22853 gen_helper_dpsu_h_obl(v1_t
, v2_t
, t0
, cpu_env
);
22855 case OPC_DPSU_H_OBR
:
22857 gen_helper_dpsu_h_obr(v1_t
, v2_t
, t0
, cpu_env
);
22859 case OPC_MAQ_S_L_PWL
:
22861 gen_helper_maq_s_l_pwl(v1_t
, v2_t
, t0
, cpu_env
);
22863 case OPC_MAQ_S_L_PWR
:
22865 gen_helper_maq_s_l_pwr(v1_t
, v2_t
, t0
, cpu_env
);
22867 case OPC_MAQ_S_W_QHLL
:
22869 gen_helper_maq_s_w_qhll(v1_t
, v2_t
, t0
, cpu_env
);
22871 case OPC_MAQ_SA_W_QHLL
:
22873 gen_helper_maq_sa_w_qhll(v1_t
, v2_t
, t0
, cpu_env
);
22875 case OPC_MAQ_S_W_QHLR
:
22877 gen_helper_maq_s_w_qhlr(v1_t
, v2_t
, t0
, cpu_env
);
22879 case OPC_MAQ_SA_W_QHLR
:
22881 gen_helper_maq_sa_w_qhlr(v1_t
, v2_t
, t0
, cpu_env
);
22883 case OPC_MAQ_S_W_QHRL
:
22885 gen_helper_maq_s_w_qhrl(v1_t
, v2_t
, t0
, cpu_env
);
22887 case OPC_MAQ_SA_W_QHRL
:
22889 gen_helper_maq_sa_w_qhrl(v1_t
, v2_t
, t0
, cpu_env
);
22891 case OPC_MAQ_S_W_QHRR
:
22893 gen_helper_maq_s_w_qhrr(v1_t
, v2_t
, t0
, cpu_env
);
22895 case OPC_MAQ_SA_W_QHRR
:
22897 gen_helper_maq_sa_w_qhrr(v1_t
, v2_t
, t0
, cpu_env
);
22899 case OPC_MULSAQ_S_L_PW
:
22901 gen_helper_mulsaq_s_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
22903 case OPC_MULSAQ_S_W_QH
:
22905 gen_helper_mulsaq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
22911 case OPC_ADDU_QB_DSP
:
22913 case OPC_MULEU_S_PH_QBL
:
22915 gen_helper_muleu_s_ph_qbl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22917 case OPC_MULEU_S_PH_QBR
:
22919 gen_helper_muleu_s_ph_qbr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22921 case OPC_MULQ_RS_PH
:
22923 gen_helper_mulq_rs_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22925 case OPC_MULEQ_S_W_PHL
:
22927 gen_helper_muleq_s_w_phl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22929 case OPC_MULEQ_S_W_PHR
:
22931 gen_helper_muleq_s_w_phr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22933 case OPC_MULQ_S_PH
:
22935 gen_helper_mulq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22939 #ifdef TARGET_MIPS64
22940 case OPC_ADDU_OB_DSP
:
22942 case OPC_MULEQ_S_PW_QHL
:
22944 gen_helper_muleq_s_pw_qhl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22946 case OPC_MULEQ_S_PW_QHR
:
22948 gen_helper_muleq_s_pw_qhr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22950 case OPC_MULEU_S_QH_OBL
:
22952 gen_helper_muleu_s_qh_obl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22954 case OPC_MULEU_S_QH_OBR
:
22956 gen_helper_muleu_s_qh_obr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22958 case OPC_MULQ_RS_QH
:
22960 gen_helper_mulq_rs_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22967 tcg_temp_free_i32(t0
);
22968 tcg_temp_free(v1_t
);
22969 tcg_temp_free(v2_t
);
22972 static void gen_mipsdsp_bitinsn(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
22980 /* Treat as NOP. */
22984 t0
= tcg_temp_new();
22985 val_t
= tcg_temp_new();
22986 gen_load_gpr(val_t
, val
);
22989 case OPC_ABSQ_S_PH_DSP
:
22993 gen_helper_bitrev(cpu_gpr
[ret
], val_t
);
22998 target_long result
;
22999 imm
= (ctx
->opcode
>> 16) & 0xFF;
23000 result
= (uint32_t)imm
<< 24 |
23001 (uint32_t)imm
<< 16 |
23002 (uint32_t)imm
<< 8 |
23004 result
= (int32_t)result
;
23005 tcg_gen_movi_tl(cpu_gpr
[ret
], result
);
23010 tcg_gen_ext8u_tl(cpu_gpr
[ret
], val_t
);
23011 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 8);
23012 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
23013 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
23014 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
23015 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
23020 imm
= (ctx
->opcode
>> 16) & 0x03FF;
23021 imm
= (int16_t)(imm
<< 6) >> 6;
23022 tcg_gen_movi_tl(cpu_gpr
[ret
], \
23023 (target_long
)((int32_t)imm
<< 16 | \
23029 tcg_gen_ext16u_tl(cpu_gpr
[ret
], val_t
);
23030 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
23031 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
23032 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
23036 #ifdef TARGET_MIPS64
23037 case OPC_ABSQ_S_QH_DSP
:
23044 imm
= (ctx
->opcode
>> 16) & 0xFF;
23045 temp
= ((uint64_t)imm
<< 8) | (uint64_t)imm
;
23046 temp
= (temp
<< 16) | temp
;
23047 temp
= (temp
<< 32) | temp
;
23048 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
23056 imm
= (ctx
->opcode
>> 16) & 0x03FF;
23057 imm
= (int16_t)(imm
<< 6) >> 6;
23058 temp
= ((target_long
)imm
<< 32) \
23059 | ((target_long
)imm
& 0xFFFFFFFF);
23060 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
23068 imm
= (ctx
->opcode
>> 16) & 0x03FF;
23069 imm
= (int16_t)(imm
<< 6) >> 6;
23071 temp
= ((uint64_t)(uint16_t)imm
<< 48) |
23072 ((uint64_t)(uint16_t)imm
<< 32) |
23073 ((uint64_t)(uint16_t)imm
<< 16) |
23074 (uint64_t)(uint16_t)imm
;
23075 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
23080 tcg_gen_ext8u_tl(cpu_gpr
[ret
], val_t
);
23081 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 8);
23082 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
23083 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
23084 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
23085 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
23086 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
23090 tcg_gen_ext32u_i64(cpu_gpr
[ret
], val_t
);
23091 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
23092 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
23096 tcg_gen_ext16u_tl(cpu_gpr
[ret
], val_t
);
23097 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
23098 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
23099 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
23100 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
23107 tcg_temp_free(val_t
);
23110 static void gen_mipsdsp_add_cmp_pick(DisasContext
*ctx
,
23111 uint32_t op1
, uint32_t op2
,
23112 int ret
, int v1
, int v2
, int check_ret
)
23118 if ((ret
== 0) && (check_ret
== 1)) {
23119 /* Treat as NOP. */
23123 t1
= tcg_temp_new();
23124 v1_t
= tcg_temp_new();
23125 v2_t
= tcg_temp_new();
23127 gen_load_gpr(v1_t
, v1
);
23128 gen_load_gpr(v2_t
, v2
);
23131 case OPC_CMPU_EQ_QB_DSP
:
23133 case OPC_CMPU_EQ_QB
:
23135 gen_helper_cmpu_eq_qb(v1_t
, v2_t
, cpu_env
);
23137 case OPC_CMPU_LT_QB
:
23139 gen_helper_cmpu_lt_qb(v1_t
, v2_t
, cpu_env
);
23141 case OPC_CMPU_LE_QB
:
23143 gen_helper_cmpu_le_qb(v1_t
, v2_t
, cpu_env
);
23145 case OPC_CMPGU_EQ_QB
:
23147 gen_helper_cmpgu_eq_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
23149 case OPC_CMPGU_LT_QB
:
23151 gen_helper_cmpgu_lt_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
23153 case OPC_CMPGU_LE_QB
:
23155 gen_helper_cmpgu_le_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
23157 case OPC_CMPGDU_EQ_QB
:
23159 gen_helper_cmpgu_eq_qb(t1
, v1_t
, v2_t
);
23160 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
23161 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
23162 tcg_gen_shli_tl(t1
, t1
, 24);
23163 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
23165 case OPC_CMPGDU_LT_QB
:
23167 gen_helper_cmpgu_lt_qb(t1
, v1_t
, v2_t
);
23168 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
23169 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
23170 tcg_gen_shli_tl(t1
, t1
, 24);
23171 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
23173 case OPC_CMPGDU_LE_QB
:
23175 gen_helper_cmpgu_le_qb(t1
, v1_t
, v2_t
);
23176 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
23177 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
23178 tcg_gen_shli_tl(t1
, t1
, 24);
23179 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
23181 case OPC_CMP_EQ_PH
:
23183 gen_helper_cmp_eq_ph(v1_t
, v2_t
, cpu_env
);
23185 case OPC_CMP_LT_PH
:
23187 gen_helper_cmp_lt_ph(v1_t
, v2_t
, cpu_env
);
23189 case OPC_CMP_LE_PH
:
23191 gen_helper_cmp_le_ph(v1_t
, v2_t
, cpu_env
);
23195 gen_helper_pick_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23199 gen_helper_pick_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23201 case OPC_PACKRL_PH
:
23203 gen_helper_packrl_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
23207 #ifdef TARGET_MIPS64
23208 case OPC_CMPU_EQ_OB_DSP
:
23210 case OPC_CMP_EQ_PW
:
23212 gen_helper_cmp_eq_pw(v1_t
, v2_t
, cpu_env
);
23214 case OPC_CMP_LT_PW
:
23216 gen_helper_cmp_lt_pw(v1_t
, v2_t
, cpu_env
);
23218 case OPC_CMP_LE_PW
:
23220 gen_helper_cmp_le_pw(v1_t
, v2_t
, cpu_env
);
23222 case OPC_CMP_EQ_QH
:
23224 gen_helper_cmp_eq_qh(v1_t
, v2_t
, cpu_env
);
23226 case OPC_CMP_LT_QH
:
23228 gen_helper_cmp_lt_qh(v1_t
, v2_t
, cpu_env
);
23230 case OPC_CMP_LE_QH
:
23232 gen_helper_cmp_le_qh(v1_t
, v2_t
, cpu_env
);
23234 case OPC_CMPGDU_EQ_OB
:
23236 gen_helper_cmpgdu_eq_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23238 case OPC_CMPGDU_LT_OB
:
23240 gen_helper_cmpgdu_lt_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23242 case OPC_CMPGDU_LE_OB
:
23244 gen_helper_cmpgdu_le_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23246 case OPC_CMPGU_EQ_OB
:
23248 gen_helper_cmpgu_eq_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
23250 case OPC_CMPGU_LT_OB
:
23252 gen_helper_cmpgu_lt_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
23254 case OPC_CMPGU_LE_OB
:
23256 gen_helper_cmpgu_le_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
23258 case OPC_CMPU_EQ_OB
:
23260 gen_helper_cmpu_eq_ob(v1_t
, v2_t
, cpu_env
);
23262 case OPC_CMPU_LT_OB
:
23264 gen_helper_cmpu_lt_ob(v1_t
, v2_t
, cpu_env
);
23266 case OPC_CMPU_LE_OB
:
23268 gen_helper_cmpu_le_ob(v1_t
, v2_t
, cpu_env
);
23270 case OPC_PACKRL_PW
:
23272 gen_helper_packrl_pw(cpu_gpr
[ret
], v1_t
, v2_t
);
23276 gen_helper_pick_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23280 gen_helper_pick_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23284 gen_helper_pick_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23292 tcg_temp_free(v1_t
);
23293 tcg_temp_free(v2_t
);
23296 static void gen_mipsdsp_append(CPUMIPSState
*env
, DisasContext
*ctx
,
23297 uint32_t op1
, int rt
, int rs
, int sa
)
23304 /* Treat as NOP. */
23308 t0
= tcg_temp_new();
23309 gen_load_gpr(t0
, rs
);
23312 case OPC_APPEND_DSP
:
23313 switch (MASK_APPEND(ctx
->opcode
)) {
23316 tcg_gen_deposit_tl(cpu_gpr
[rt
], t0
, cpu_gpr
[rt
], sa
, 32 - sa
);
23318 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
23322 tcg_gen_ext32u_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
23323 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], sa
);
23324 tcg_gen_shli_tl(t0
, t0
, 32 - sa
);
23325 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
23327 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
23331 if (sa
!= 0 && sa
!= 2) {
23332 tcg_gen_shli_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 8 * sa
);
23333 tcg_gen_ext32u_tl(t0
, t0
);
23334 tcg_gen_shri_tl(t0
, t0
, 8 * (4 - sa
));
23335 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
23337 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
23339 default: /* Invalid */
23340 MIPS_INVAL("MASK APPEND");
23341 gen_reserved_instruction(ctx
);
23345 #ifdef TARGET_MIPS64
23346 case OPC_DAPPEND_DSP
:
23347 switch (MASK_DAPPEND(ctx
->opcode
)) {
23350 tcg_gen_deposit_tl(cpu_gpr
[rt
], t0
, cpu_gpr
[rt
], sa
, 64 - sa
);
23354 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 0x20 | sa
);
23355 tcg_gen_shli_tl(t0
, t0
, 64 - (0x20 | sa
));
23356 tcg_gen_or_tl(cpu_gpr
[rt
], t0
, t0
);
23360 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], sa
);
23361 tcg_gen_shli_tl(t0
, t0
, 64 - sa
);
23362 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
23367 if (sa
!= 0 && sa
!= 2 && sa
!= 4) {
23368 tcg_gen_shli_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 8 * sa
);
23369 tcg_gen_shri_tl(t0
, t0
, 8 * (8 - sa
));
23370 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
23373 default: /* Invalid */
23374 MIPS_INVAL("MASK DAPPEND");
23375 gen_reserved_instruction(ctx
);
23384 static void gen_mipsdsp_accinsn(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
23385 int ret
, int v1
, int v2
, int check_ret
)
23394 if ((ret
== 0) && (check_ret
== 1)) {
23395 /* Treat as NOP. */
23399 t0
= tcg_temp_new();
23400 t1
= tcg_temp_new();
23401 v1_t
= tcg_temp_new();
23402 v2_t
= tcg_temp_new();
23404 gen_load_gpr(v1_t
, v1
);
23405 gen_load_gpr(v2_t
, v2
);
23408 case OPC_EXTR_W_DSP
:
23412 tcg_gen_movi_tl(t0
, v2
);
23413 tcg_gen_movi_tl(t1
, v1
);
23414 gen_helper_extr_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23417 tcg_gen_movi_tl(t0
, v2
);
23418 tcg_gen_movi_tl(t1
, v1
);
23419 gen_helper_extr_r_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23421 case OPC_EXTR_RS_W
:
23422 tcg_gen_movi_tl(t0
, v2
);
23423 tcg_gen_movi_tl(t1
, v1
);
23424 gen_helper_extr_rs_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23427 tcg_gen_movi_tl(t0
, v2
);
23428 tcg_gen_movi_tl(t1
, v1
);
23429 gen_helper_extr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23431 case OPC_EXTRV_S_H
:
23432 tcg_gen_movi_tl(t0
, v2
);
23433 gen_helper_extr_s_h(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
23436 tcg_gen_movi_tl(t0
, v2
);
23437 gen_helper_extr_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
23439 case OPC_EXTRV_R_W
:
23440 tcg_gen_movi_tl(t0
, v2
);
23441 gen_helper_extr_r_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
23443 case OPC_EXTRV_RS_W
:
23444 tcg_gen_movi_tl(t0
, v2
);
23445 gen_helper_extr_rs_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
23448 tcg_gen_movi_tl(t0
, v2
);
23449 tcg_gen_movi_tl(t1
, v1
);
23450 gen_helper_extp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23453 tcg_gen_movi_tl(t0
, v2
);
23454 gen_helper_extp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
23457 tcg_gen_movi_tl(t0
, v2
);
23458 tcg_gen_movi_tl(t1
, v1
);
23459 gen_helper_extpdp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23462 tcg_gen_movi_tl(t0
, v2
);
23463 gen_helper_extpdp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
23466 imm
= (ctx
->opcode
>> 20) & 0x3F;
23467 tcg_gen_movi_tl(t0
, ret
);
23468 tcg_gen_movi_tl(t1
, imm
);
23469 gen_helper_shilo(t0
, t1
, cpu_env
);
23472 tcg_gen_movi_tl(t0
, ret
);
23473 gen_helper_shilo(t0
, v1_t
, cpu_env
);
23476 tcg_gen_movi_tl(t0
, ret
);
23477 gen_helper_mthlip(t0
, v1_t
, cpu_env
);
23480 imm
= (ctx
->opcode
>> 11) & 0x3FF;
23481 tcg_gen_movi_tl(t0
, imm
);
23482 gen_helper_wrdsp(v1_t
, t0
, cpu_env
);
23485 imm
= (ctx
->opcode
>> 16) & 0x03FF;
23486 tcg_gen_movi_tl(t0
, imm
);
23487 gen_helper_rddsp(cpu_gpr
[ret
], t0
, cpu_env
);
23491 #ifdef TARGET_MIPS64
23492 case OPC_DEXTR_W_DSP
:
23496 tcg_gen_movi_tl(t0
, ret
);
23497 gen_helper_dmthlip(v1_t
, t0
, cpu_env
);
23501 int shift
= (ctx
->opcode
>> 19) & 0x7F;
23502 int ac
= (ctx
->opcode
>> 11) & 0x03;
23503 tcg_gen_movi_tl(t0
, shift
);
23504 tcg_gen_movi_tl(t1
, ac
);
23505 gen_helper_dshilo(t0
, t1
, cpu_env
);
23510 int ac
= (ctx
->opcode
>> 11) & 0x03;
23511 tcg_gen_movi_tl(t0
, ac
);
23512 gen_helper_dshilo(v1_t
, t0
, cpu_env
);
23516 tcg_gen_movi_tl(t0
, v2
);
23517 tcg_gen_movi_tl(t1
, v1
);
23519 gen_helper_dextp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23522 tcg_gen_movi_tl(t0
, v2
);
23523 gen_helper_dextp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
23526 tcg_gen_movi_tl(t0
, v2
);
23527 tcg_gen_movi_tl(t1
, v1
);
23528 gen_helper_dextpdp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23531 tcg_gen_movi_tl(t0
, v2
);
23532 gen_helper_dextpdp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
23535 tcg_gen_movi_tl(t0
, v2
);
23536 tcg_gen_movi_tl(t1
, v1
);
23537 gen_helper_dextr_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23539 case OPC_DEXTR_R_L
:
23540 tcg_gen_movi_tl(t0
, v2
);
23541 tcg_gen_movi_tl(t1
, v1
);
23542 gen_helper_dextr_r_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23544 case OPC_DEXTR_RS_L
:
23545 tcg_gen_movi_tl(t0
, v2
);
23546 tcg_gen_movi_tl(t1
, v1
);
23547 gen_helper_dextr_rs_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23550 tcg_gen_movi_tl(t0
, v2
);
23551 tcg_gen_movi_tl(t1
, v1
);
23552 gen_helper_dextr_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23554 case OPC_DEXTR_R_W
:
23555 tcg_gen_movi_tl(t0
, v2
);
23556 tcg_gen_movi_tl(t1
, v1
);
23557 gen_helper_dextr_r_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23559 case OPC_DEXTR_RS_W
:
23560 tcg_gen_movi_tl(t0
, v2
);
23561 tcg_gen_movi_tl(t1
, v1
);
23562 gen_helper_dextr_rs_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23564 case OPC_DEXTR_S_H
:
23565 tcg_gen_movi_tl(t0
, v2
);
23566 tcg_gen_movi_tl(t1
, v1
);
23567 gen_helper_dextr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23569 case OPC_DEXTRV_S_H
:
23570 tcg_gen_movi_tl(t0
, v2
);
23571 tcg_gen_movi_tl(t1
, v1
);
23572 gen_helper_dextr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23575 tcg_gen_movi_tl(t0
, v2
);
23576 gen_helper_dextr_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
23578 case OPC_DEXTRV_R_L
:
23579 tcg_gen_movi_tl(t0
, v2
);
23580 gen_helper_dextr_r_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
23582 case OPC_DEXTRV_RS_L
:
23583 tcg_gen_movi_tl(t0
, v2
);
23584 gen_helper_dextr_rs_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
23587 tcg_gen_movi_tl(t0
, v2
);
23588 gen_helper_dextr_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
23590 case OPC_DEXTRV_R_W
:
23591 tcg_gen_movi_tl(t0
, v2
);
23592 gen_helper_dextr_r_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
23594 case OPC_DEXTRV_RS_W
:
23595 tcg_gen_movi_tl(t0
, v2
);
23596 gen_helper_dextr_rs_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
23605 tcg_temp_free(v1_t
);
23606 tcg_temp_free(v2_t
);
23609 /* End MIPSDSP functions. */
23611 static void decode_opc_special_r6(CPUMIPSState
*env
, DisasContext
*ctx
)
23613 int rs
, rt
, rd
, sa
;
23616 rs
= (ctx
->opcode
>> 21) & 0x1f;
23617 rt
= (ctx
->opcode
>> 16) & 0x1f;
23618 rd
= (ctx
->opcode
>> 11) & 0x1f;
23619 sa
= (ctx
->opcode
>> 6) & 0x1f;
23621 op1
= MASK_SPECIAL(ctx
->opcode
);
23627 op2
= MASK_R6_MULDIV(ctx
->opcode
);
23637 gen_r6_muldiv(ctx
, op2
, rd
, rs
, rt
);
23640 MIPS_INVAL("special_r6 muldiv");
23641 gen_reserved_instruction(ctx
);
23647 gen_cond_move(ctx
, op1
, rd
, rs
, rt
);
23651 if (rt
== 0 && sa
== 1) {
23653 * Major opcode and function field is shared with preR6 MFHI/MTHI.
23654 * We need additionally to check other fields.
23656 gen_cl(ctx
, op1
, rd
, rs
);
23658 gen_reserved_instruction(ctx
);
23662 if (is_uhi(extract32(ctx
->opcode
, 6, 20))) {
23663 gen_helper_do_semihosting(cpu_env
);
23665 if (ctx
->hflags
& MIPS_HFLAG_SBRI
) {
23666 gen_reserved_instruction(ctx
);
23668 generate_exception_end(ctx
, EXCP_DBp
);
23672 #if defined(TARGET_MIPS64)
23675 if (rt
== 0 && sa
== 1) {
23677 * Major opcode and function field is shared with preR6 MFHI/MTHI.
23678 * We need additionally to check other fields.
23680 check_mips_64(ctx
);
23681 gen_cl(ctx
, op1
, rd
, rs
);
23683 gen_reserved_instruction(ctx
);
23691 op2
= MASK_R6_MULDIV(ctx
->opcode
);
23701 check_mips_64(ctx
);
23702 gen_r6_muldiv(ctx
, op2
, rd
, rs
, rt
);
23705 MIPS_INVAL("special_r6 muldiv");
23706 gen_reserved_instruction(ctx
);
23711 default: /* Invalid */
23712 MIPS_INVAL("special_r6");
23713 gen_reserved_instruction(ctx
);
23718 static void decode_opc_special_tx79(CPUMIPSState
*env
, DisasContext
*ctx
)
23720 int rs
= extract32(ctx
->opcode
, 21, 5);
23721 int rt
= extract32(ctx
->opcode
, 16, 5);
23722 int rd
= extract32(ctx
->opcode
, 11, 5);
23723 uint32_t op1
= MASK_SPECIAL(ctx
->opcode
);
23726 case OPC_MOVN
: /* Conditional move */
23728 gen_cond_move(ctx
, op1
, rd
, rs
, rt
);
23730 case OPC_MFHI
: /* Move from HI/LO */
23732 gen_HILO(ctx
, op1
, 0, rd
);
23735 case OPC_MTLO
: /* Move to HI/LO */
23736 gen_HILO(ctx
, op1
, 0, rs
);
23740 gen_mul_txx9(ctx
, op1
, rd
, rs
, rt
);
23744 gen_muldiv(ctx
, op1
, 0, rs
, rt
);
23746 #if defined(TARGET_MIPS64)
23751 check_insn_opc_user_only(ctx
, INSN_R5900
);
23752 gen_muldiv(ctx
, op1
, 0, rs
, rt
);
23756 gen_compute_branch(ctx
, op1
, 4, rs
, 0, 0, 4);
23758 default: /* Invalid */
23759 MIPS_INVAL("special_tx79");
23760 gen_reserved_instruction(ctx
);
23765 static void decode_opc_special_legacy(CPUMIPSState
*env
, DisasContext
*ctx
)
23767 int rs
, rt
, rd
, sa
;
23770 rs
= (ctx
->opcode
>> 21) & 0x1f;
23771 rt
= (ctx
->opcode
>> 16) & 0x1f;
23772 rd
= (ctx
->opcode
>> 11) & 0x1f;
23773 sa
= (ctx
->opcode
>> 6) & 0x1f;
23775 op1
= MASK_SPECIAL(ctx
->opcode
);
23777 case OPC_MOVN
: /* Conditional move */
23779 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS_R1
|
23780 INSN_LOONGSON2E
| INSN_LOONGSON2F
);
23781 gen_cond_move(ctx
, op1
, rd
, rs
, rt
);
23783 case OPC_MFHI
: /* Move from HI/LO */
23785 gen_HILO(ctx
, op1
, rs
& 3, rd
);
23788 case OPC_MTLO
: /* Move to HI/LO */
23789 gen_HILO(ctx
, op1
, rd
& 3, rs
);
23792 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS_R1
);
23793 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
23794 check_cp1_enabled(ctx
);
23795 gen_movci(ctx
, rd
, rs
, (ctx
->opcode
>> 18) & 0x7,
23796 (ctx
->opcode
>> 16) & 1);
23798 generate_exception_err(ctx
, EXCP_CpU
, 1);
23804 check_insn(ctx
, INSN_VR54XX
);
23805 op1
= MASK_MUL_VR54XX(ctx
->opcode
);
23806 gen_mul_vr54xx(ctx
, op1
, rd
, rs
, rt
);
23808 gen_muldiv(ctx
, op1
, rd
& 3, rs
, rt
);
23813 gen_muldiv(ctx
, op1
, 0, rs
, rt
);
23815 #if defined(TARGET_MIPS64)
23820 check_insn(ctx
, ISA_MIPS3
);
23821 check_mips_64(ctx
);
23822 gen_muldiv(ctx
, op1
, 0, rs
, rt
);
23826 gen_compute_branch(ctx
, op1
, 4, rs
, rd
, sa
, 4);
23829 #ifdef MIPS_STRICT_STANDARD
23830 MIPS_INVAL("SPIM");
23831 gen_reserved_instruction(ctx
);
23833 /* Implemented as RI exception for now. */
23834 MIPS_INVAL("spim (unofficial)");
23835 gen_reserved_instruction(ctx
);
23838 default: /* Invalid */
23839 MIPS_INVAL("special_legacy");
23840 gen_reserved_instruction(ctx
);
23845 static void decode_opc_special(CPUMIPSState
*env
, DisasContext
*ctx
)
23847 int rs
, rt
, rd
, sa
;
23850 rs
= (ctx
->opcode
>> 21) & 0x1f;
23851 rt
= (ctx
->opcode
>> 16) & 0x1f;
23852 rd
= (ctx
->opcode
>> 11) & 0x1f;
23853 sa
= (ctx
->opcode
>> 6) & 0x1f;
23855 op1
= MASK_SPECIAL(ctx
->opcode
);
23857 case OPC_SLL
: /* Shift with immediate */
23858 if (sa
== 5 && rd
== 0 &&
23859 rs
== 0 && rt
== 0) { /* PAUSE */
23860 if ((ctx
->insn_flags
& ISA_MIPS_R6
) &&
23861 (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
23862 gen_reserved_instruction(ctx
);
23868 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
23871 switch ((ctx
->opcode
>> 21) & 0x1f) {
23873 /* rotr is decoded as srl on non-R2 CPUs */
23874 if (ctx
->insn_flags
& ISA_MIPS_R2
) {
23879 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
23882 gen_reserved_instruction(ctx
);
23890 gen_arith(ctx
, op1
, rd
, rs
, rt
);
23892 case OPC_SLLV
: /* Shifts */
23894 gen_shift(ctx
, op1
, rd
, rs
, rt
);
23897 switch ((ctx
->opcode
>> 6) & 0x1f) {
23899 /* rotrv is decoded as srlv on non-R2 CPUs */
23900 if (ctx
->insn_flags
& ISA_MIPS_R2
) {
23905 gen_shift(ctx
, op1
, rd
, rs
, rt
);
23908 gen_reserved_instruction(ctx
);
23912 case OPC_SLT
: /* Set on less than */
23914 gen_slt(ctx
, op1
, rd
, rs
, rt
);
23916 case OPC_AND
: /* Logic*/
23920 gen_logic(ctx
, op1
, rd
, rs
, rt
);
23923 gen_compute_branch(ctx
, op1
, 4, rs
, rd
, sa
, 4);
23925 case OPC_TGE
: /* Traps */
23931 check_insn(ctx
, ISA_MIPS2
);
23932 gen_trap(ctx
, op1
, rs
, rt
, -1);
23935 /* Pmon entry point, also R4010 selsl */
23936 #ifdef MIPS_STRICT_STANDARD
23937 MIPS_INVAL("PMON / selsl");
23938 gen_reserved_instruction(ctx
);
23940 gen_helper_0e0i(pmon
, sa
);
23944 generate_exception_end(ctx
, EXCP_SYSCALL
);
23947 generate_exception_end(ctx
, EXCP_BREAK
);
23950 check_insn(ctx
, ISA_MIPS2
);
23951 gen_sync(extract32(ctx
->opcode
, 6, 5));
23954 #if defined(TARGET_MIPS64)
23955 /* MIPS64 specific opcodes */
23960 check_insn(ctx
, ISA_MIPS3
);
23961 check_mips_64(ctx
);
23962 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
23965 switch ((ctx
->opcode
>> 21) & 0x1f) {
23967 /* drotr is decoded as dsrl on non-R2 CPUs */
23968 if (ctx
->insn_flags
& ISA_MIPS_R2
) {
23973 check_insn(ctx
, ISA_MIPS3
);
23974 check_mips_64(ctx
);
23975 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
23978 gen_reserved_instruction(ctx
);
23983 switch ((ctx
->opcode
>> 21) & 0x1f) {
23985 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
23986 if (ctx
->insn_flags
& ISA_MIPS_R2
) {
23991 check_insn(ctx
, ISA_MIPS3
);
23992 check_mips_64(ctx
);
23993 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
23996 gen_reserved_instruction(ctx
);
24004 check_insn(ctx
, ISA_MIPS3
);
24005 check_mips_64(ctx
);
24006 gen_arith(ctx
, op1
, rd
, rs
, rt
);
24010 check_insn(ctx
, ISA_MIPS3
);
24011 check_mips_64(ctx
);
24012 gen_shift(ctx
, op1
, rd
, rs
, rt
);
24015 switch ((ctx
->opcode
>> 6) & 0x1f) {
24017 /* drotrv is decoded as dsrlv on non-R2 CPUs */
24018 if (ctx
->insn_flags
& ISA_MIPS_R2
) {
24023 check_insn(ctx
, ISA_MIPS3
);
24024 check_mips_64(ctx
);
24025 gen_shift(ctx
, op1
, rd
, rs
, rt
);
24028 gen_reserved_instruction(ctx
);
24034 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
24035 decode_opc_special_r6(env
, ctx
);
24036 } else if (ctx
->insn_flags
& INSN_R5900
) {
24037 decode_opc_special_tx79(env
, ctx
);
24039 decode_opc_special_legacy(env
, ctx
);
24045 #if defined(TARGET_MIPS64)
24049 * MMI (MultiMedia Interface) ASE instructions
24050 * ===========================================
24054 * MMI instructions category: data communication
24055 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
24057 * PCPYH PEXCH PEXTLB PINTH PPACB PEXT5 PREVH
24058 * PCPYLD PEXCW PEXTLH PINTEH PPACH PPAC5 PROT3W
24059 * PCPYUD PEXEH PEXTLW PPACW
24067 static void decode_opc_special2_legacy(CPUMIPSState
*env
, DisasContext
*ctx
)
24072 rs
= (ctx
->opcode
>> 21) & 0x1f;
24073 rt
= (ctx
->opcode
>> 16) & 0x1f;
24074 rd
= (ctx
->opcode
>> 11) & 0x1f;
24076 op1
= MASK_SPECIAL2(ctx
->opcode
);
24078 case OPC_MADD
: /* Multiply and add/sub */
24082 check_insn(ctx
, ISA_MIPS_R1
);
24083 gen_muldiv(ctx
, op1
, rd
& 3, rs
, rt
);
24086 gen_arith(ctx
, op1
, rd
, rs
, rt
);
24089 case OPC_DIVU_G_2F
:
24090 case OPC_MULT_G_2F
:
24091 case OPC_MULTU_G_2F
:
24093 case OPC_MODU_G_2F
:
24094 check_insn(ctx
, INSN_LOONGSON2F
| ASE_LEXT
);
24095 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
24099 check_insn(ctx
, ISA_MIPS_R1
);
24100 gen_cl(ctx
, op1
, rd
, rs
);
24103 if (is_uhi(extract32(ctx
->opcode
, 6, 20))) {
24104 gen_helper_do_semihosting(cpu_env
);
24107 * XXX: not clear which exception should be raised
24108 * when in debug mode...
24110 check_insn(ctx
, ISA_MIPS_R1
);
24111 generate_exception_end(ctx
, EXCP_DBp
);
24114 #if defined(TARGET_MIPS64)
24117 check_insn(ctx
, ISA_MIPS_R1
);
24118 check_mips_64(ctx
);
24119 gen_cl(ctx
, op1
, rd
, rs
);
24121 case OPC_DMULT_G_2F
:
24122 case OPC_DMULTU_G_2F
:
24123 case OPC_DDIV_G_2F
:
24124 case OPC_DDIVU_G_2F
:
24125 case OPC_DMOD_G_2F
:
24126 case OPC_DMODU_G_2F
:
24127 check_insn(ctx
, INSN_LOONGSON2F
| ASE_LEXT
);
24128 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
24131 default: /* Invalid */
24132 MIPS_INVAL("special2_legacy");
24133 gen_reserved_instruction(ctx
);
24138 static void decode_opc_special3_r6(CPUMIPSState
*env
, DisasContext
*ctx
)
24140 int rs
, rt
, rd
, sa
;
24144 rs
= (ctx
->opcode
>> 21) & 0x1f;
24145 rt
= (ctx
->opcode
>> 16) & 0x1f;
24146 rd
= (ctx
->opcode
>> 11) & 0x1f;
24147 sa
= (ctx
->opcode
>> 6) & 0x1f;
24148 imm
= (int16_t)ctx
->opcode
>> 7;
24150 op1
= MASK_SPECIAL3(ctx
->opcode
);
24154 /* hint codes 24-31 are reserved and signal RI */
24155 gen_reserved_instruction(ctx
);
24157 /* Treat as NOP. */
24160 check_cp0_enabled(ctx
);
24161 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
24162 gen_cache_operation(ctx
, rt
, rs
, imm
);
24166 gen_st_cond(ctx
, rt
, rs
, imm
, MO_TESL
, false);
24169 gen_ld(ctx
, op1
, rt
, rs
, imm
);
24174 /* Treat as NOP. */
24177 op2
= MASK_BSHFL(ctx
->opcode
);
24183 gen_align(ctx
, 32, rd
, rs
, rt
, sa
& 3);
24186 gen_bitswap(ctx
, op2
, rd
, rt
);
24191 #ifndef CONFIG_USER_ONLY
24193 if (unlikely(ctx
->gi
<= 1)) {
24194 gen_reserved_instruction(ctx
);
24196 check_cp0_enabled(ctx
);
24197 switch ((ctx
->opcode
>> 6) & 3) {
24198 case 0: /* GINVI */
24199 /* Treat as NOP. */
24201 case 2: /* GINVT */
24202 gen_helper_0e1i(ginvt
, cpu_gpr
[rs
], extract32(ctx
->opcode
, 8, 2));
24205 gen_reserved_instruction(ctx
);
24210 #if defined(TARGET_MIPS64)
24212 gen_st_cond(ctx
, rt
, rs
, imm
, MO_TEQ
, false);
24215 gen_ld(ctx
, op1
, rt
, rs
, imm
);
24218 check_mips_64(ctx
);
24221 /* Treat as NOP. */
24224 op2
= MASK_DBSHFL(ctx
->opcode
);
24234 gen_align(ctx
, 64, rd
, rs
, rt
, sa
& 7);
24237 gen_bitswap(ctx
, op2
, rd
, rt
);
24244 default: /* Invalid */
24245 MIPS_INVAL("special3_r6");
24246 gen_reserved_instruction(ctx
);
24251 static void decode_opc_special3_legacy(CPUMIPSState
*env
, DisasContext
*ctx
)
24256 rs
= (ctx
->opcode
>> 21) & 0x1f;
24257 rt
= (ctx
->opcode
>> 16) & 0x1f;
24258 rd
= (ctx
->opcode
>> 11) & 0x1f;
24260 op1
= MASK_SPECIAL3(ctx
->opcode
);
24263 case OPC_DIVU_G_2E
:
24265 case OPC_MODU_G_2E
:
24266 case OPC_MULT_G_2E
:
24267 case OPC_MULTU_G_2E
:
24269 * OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
24270 * the same mask and op1.
24272 if ((ctx
->insn_flags
& ASE_DSP_R2
) && (op1
== OPC_MULT_G_2E
)) {
24273 op2
= MASK_ADDUH_QB(ctx
->opcode
);
24276 case OPC_ADDUH_R_QB
:
24278 case OPC_ADDQH_R_PH
:
24280 case OPC_ADDQH_R_W
:
24282 case OPC_SUBUH_R_QB
:
24284 case OPC_SUBQH_R_PH
:
24286 case OPC_SUBQH_R_W
:
24287 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
24292 case OPC_MULQ_RS_W
:
24293 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
24296 MIPS_INVAL("MASK ADDUH.QB");
24297 gen_reserved_instruction(ctx
);
24300 } else if (ctx
->insn_flags
& INSN_LOONGSON2E
) {
24301 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
24303 gen_reserved_instruction(ctx
);
24307 op2
= MASK_LX(ctx
->opcode
);
24309 #if defined(TARGET_MIPS64)
24315 gen_mipsdsp_ld(ctx
, op2
, rd
, rs
, rt
);
24317 default: /* Invalid */
24318 MIPS_INVAL("MASK LX");
24319 gen_reserved_instruction(ctx
);
24323 case OPC_ABSQ_S_PH_DSP
:
24324 op2
= MASK_ABSQ_S_PH(ctx
->opcode
);
24326 case OPC_ABSQ_S_QB
:
24327 case OPC_ABSQ_S_PH
:
24329 case OPC_PRECEQ_W_PHL
:
24330 case OPC_PRECEQ_W_PHR
:
24331 case OPC_PRECEQU_PH_QBL
:
24332 case OPC_PRECEQU_PH_QBR
:
24333 case OPC_PRECEQU_PH_QBLA
:
24334 case OPC_PRECEQU_PH_QBRA
:
24335 case OPC_PRECEU_PH_QBL
:
24336 case OPC_PRECEU_PH_QBR
:
24337 case OPC_PRECEU_PH_QBLA
:
24338 case OPC_PRECEU_PH_QBRA
:
24339 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
24346 gen_mipsdsp_bitinsn(ctx
, op1
, op2
, rd
, rt
);
24349 MIPS_INVAL("MASK ABSQ_S.PH");
24350 gen_reserved_instruction(ctx
);
24354 case OPC_ADDU_QB_DSP
:
24355 op2
= MASK_ADDU_QB(ctx
->opcode
);
24358 case OPC_ADDQ_S_PH
:
24361 case OPC_ADDU_S_QB
:
24363 case OPC_ADDU_S_PH
:
24365 case OPC_SUBQ_S_PH
:
24368 case OPC_SUBU_S_QB
:
24370 case OPC_SUBU_S_PH
:
24374 case OPC_RADDU_W_QB
:
24375 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
24377 case OPC_MULEU_S_PH_QBL
:
24378 case OPC_MULEU_S_PH_QBR
:
24379 case OPC_MULQ_RS_PH
:
24380 case OPC_MULEQ_S_W_PHL
:
24381 case OPC_MULEQ_S_W_PHR
:
24382 case OPC_MULQ_S_PH
:
24383 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
24385 default: /* Invalid */
24386 MIPS_INVAL("MASK ADDU.QB");
24387 gen_reserved_instruction(ctx
);
24392 case OPC_CMPU_EQ_QB_DSP
:
24393 op2
= MASK_CMPU_EQ_QB(ctx
->opcode
);
24395 case OPC_PRECR_SRA_PH_W
:
24396 case OPC_PRECR_SRA_R_PH_W
:
24397 gen_mipsdsp_arith(ctx
, op1
, op2
, rt
, rs
, rd
);
24399 case OPC_PRECR_QB_PH
:
24400 case OPC_PRECRQ_QB_PH
:
24401 case OPC_PRECRQ_PH_W
:
24402 case OPC_PRECRQ_RS_PH_W
:
24403 case OPC_PRECRQU_S_QB_PH
:
24404 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
24406 case OPC_CMPU_EQ_QB
:
24407 case OPC_CMPU_LT_QB
:
24408 case OPC_CMPU_LE_QB
:
24409 case OPC_CMP_EQ_PH
:
24410 case OPC_CMP_LT_PH
:
24411 case OPC_CMP_LE_PH
:
24412 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
24414 case OPC_CMPGU_EQ_QB
:
24415 case OPC_CMPGU_LT_QB
:
24416 case OPC_CMPGU_LE_QB
:
24417 case OPC_CMPGDU_EQ_QB
:
24418 case OPC_CMPGDU_LT_QB
:
24419 case OPC_CMPGDU_LE_QB
:
24422 case OPC_PACKRL_PH
:
24423 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
24425 default: /* Invalid */
24426 MIPS_INVAL("MASK CMPU.EQ.QB");
24427 gen_reserved_instruction(ctx
);
24431 case OPC_SHLL_QB_DSP
:
24432 gen_mipsdsp_shift(ctx
, op1
, rd
, rs
, rt
);
24434 case OPC_DPA_W_PH_DSP
:
24435 op2
= MASK_DPA_W_PH(ctx
->opcode
);
24437 case OPC_DPAU_H_QBL
:
24438 case OPC_DPAU_H_QBR
:
24439 case OPC_DPSU_H_QBL
:
24440 case OPC_DPSU_H_QBR
:
24442 case OPC_DPAX_W_PH
:
24443 case OPC_DPAQ_S_W_PH
:
24444 case OPC_DPAQX_S_W_PH
:
24445 case OPC_DPAQX_SA_W_PH
:
24447 case OPC_DPSX_W_PH
:
24448 case OPC_DPSQ_S_W_PH
:
24449 case OPC_DPSQX_S_W_PH
:
24450 case OPC_DPSQX_SA_W_PH
:
24451 case OPC_MULSAQ_S_W_PH
:
24452 case OPC_DPAQ_SA_L_W
:
24453 case OPC_DPSQ_SA_L_W
:
24454 case OPC_MAQ_S_W_PHL
:
24455 case OPC_MAQ_S_W_PHR
:
24456 case OPC_MAQ_SA_W_PHL
:
24457 case OPC_MAQ_SA_W_PHR
:
24458 case OPC_MULSA_W_PH
:
24459 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
24461 default: /* Invalid */
24462 MIPS_INVAL("MASK DPAW.PH");
24463 gen_reserved_instruction(ctx
);
24468 op2
= MASK_INSV(ctx
->opcode
);
24479 t0
= tcg_temp_new();
24480 t1
= tcg_temp_new();
24482 gen_load_gpr(t0
, rt
);
24483 gen_load_gpr(t1
, rs
);
24485 gen_helper_insv(cpu_gpr
[rt
], cpu_env
, t1
, t0
);
24491 default: /* Invalid */
24492 MIPS_INVAL("MASK INSV");
24493 gen_reserved_instruction(ctx
);
24497 case OPC_APPEND_DSP
:
24498 gen_mipsdsp_append(env
, ctx
, op1
, rt
, rs
, rd
);
24500 case OPC_EXTR_W_DSP
:
24501 op2
= MASK_EXTR_W(ctx
->opcode
);
24505 case OPC_EXTR_RS_W
:
24507 case OPC_EXTRV_S_H
:
24509 case OPC_EXTRV_R_W
:
24510 case OPC_EXTRV_RS_W
:
24515 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rt
, rs
, rd
, 1);
24518 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
24524 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
24526 default: /* Invalid */
24527 MIPS_INVAL("MASK EXTR.W");
24528 gen_reserved_instruction(ctx
);
24532 #if defined(TARGET_MIPS64)
24533 case OPC_DDIV_G_2E
:
24534 case OPC_DDIVU_G_2E
:
24535 case OPC_DMULT_G_2E
:
24536 case OPC_DMULTU_G_2E
:
24537 case OPC_DMOD_G_2E
:
24538 case OPC_DMODU_G_2E
:
24539 check_insn(ctx
, INSN_LOONGSON2E
);
24540 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
24542 case OPC_ABSQ_S_QH_DSP
:
24543 op2
= MASK_ABSQ_S_QH(ctx
->opcode
);
24545 case OPC_PRECEQ_L_PWL
:
24546 case OPC_PRECEQ_L_PWR
:
24547 case OPC_PRECEQ_PW_QHL
:
24548 case OPC_PRECEQ_PW_QHR
:
24549 case OPC_PRECEQ_PW_QHLA
:
24550 case OPC_PRECEQ_PW_QHRA
:
24551 case OPC_PRECEQU_QH_OBL
:
24552 case OPC_PRECEQU_QH_OBR
:
24553 case OPC_PRECEQU_QH_OBLA
:
24554 case OPC_PRECEQU_QH_OBRA
:
24555 case OPC_PRECEU_QH_OBL
:
24556 case OPC_PRECEU_QH_OBR
:
24557 case OPC_PRECEU_QH_OBLA
:
24558 case OPC_PRECEU_QH_OBRA
:
24559 case OPC_ABSQ_S_OB
:
24560 case OPC_ABSQ_S_PW
:
24561 case OPC_ABSQ_S_QH
:
24562 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
24570 gen_mipsdsp_bitinsn(ctx
, op1
, op2
, rd
, rt
);
24572 default: /* Invalid */
24573 MIPS_INVAL("MASK ABSQ_S.QH");
24574 gen_reserved_instruction(ctx
);
24578 case OPC_ADDU_OB_DSP
:
24579 op2
= MASK_ADDU_OB(ctx
->opcode
);
24581 case OPC_RADDU_L_OB
:
24583 case OPC_SUBQ_S_PW
:
24585 case OPC_SUBQ_S_QH
:
24587 case OPC_SUBU_S_OB
:
24589 case OPC_SUBU_S_QH
:
24591 case OPC_SUBUH_R_OB
:
24593 case OPC_ADDQ_S_PW
:
24595 case OPC_ADDQ_S_QH
:
24597 case OPC_ADDU_S_OB
:
24599 case OPC_ADDU_S_QH
:
24601 case OPC_ADDUH_R_OB
:
24602 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
24604 case OPC_MULEQ_S_PW_QHL
:
24605 case OPC_MULEQ_S_PW_QHR
:
24606 case OPC_MULEU_S_QH_OBL
:
24607 case OPC_MULEU_S_QH_OBR
:
24608 case OPC_MULQ_RS_QH
:
24609 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
24611 default: /* Invalid */
24612 MIPS_INVAL("MASK ADDU.OB");
24613 gen_reserved_instruction(ctx
);
24617 case OPC_CMPU_EQ_OB_DSP
:
24618 op2
= MASK_CMPU_EQ_OB(ctx
->opcode
);
24620 case OPC_PRECR_SRA_QH_PW
:
24621 case OPC_PRECR_SRA_R_QH_PW
:
24622 /* Return value is rt. */
24623 gen_mipsdsp_arith(ctx
, op1
, op2
, rt
, rs
, rd
);
24625 case OPC_PRECR_OB_QH
:
24626 case OPC_PRECRQ_OB_QH
:
24627 case OPC_PRECRQ_PW_L
:
24628 case OPC_PRECRQ_QH_PW
:
24629 case OPC_PRECRQ_RS_QH_PW
:
24630 case OPC_PRECRQU_S_OB_QH
:
24631 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
24633 case OPC_CMPU_EQ_OB
:
24634 case OPC_CMPU_LT_OB
:
24635 case OPC_CMPU_LE_OB
:
24636 case OPC_CMP_EQ_QH
:
24637 case OPC_CMP_LT_QH
:
24638 case OPC_CMP_LE_QH
:
24639 case OPC_CMP_EQ_PW
:
24640 case OPC_CMP_LT_PW
:
24641 case OPC_CMP_LE_PW
:
24642 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
24644 case OPC_CMPGDU_EQ_OB
:
24645 case OPC_CMPGDU_LT_OB
:
24646 case OPC_CMPGDU_LE_OB
:
24647 case OPC_CMPGU_EQ_OB
:
24648 case OPC_CMPGU_LT_OB
:
24649 case OPC_CMPGU_LE_OB
:
24650 case OPC_PACKRL_PW
:
24654 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
24656 default: /* Invalid */
24657 MIPS_INVAL("MASK CMPU_EQ.OB");
24658 gen_reserved_instruction(ctx
);
24662 case OPC_DAPPEND_DSP
:
24663 gen_mipsdsp_append(env
, ctx
, op1
, rt
, rs
, rd
);
24665 case OPC_DEXTR_W_DSP
:
24666 op2
= MASK_DEXTR_W(ctx
->opcode
);
24673 case OPC_DEXTR_R_L
:
24674 case OPC_DEXTR_RS_L
:
24676 case OPC_DEXTR_R_W
:
24677 case OPC_DEXTR_RS_W
:
24678 case OPC_DEXTR_S_H
:
24680 case OPC_DEXTRV_R_L
:
24681 case OPC_DEXTRV_RS_L
:
24682 case OPC_DEXTRV_S_H
:
24684 case OPC_DEXTRV_R_W
:
24685 case OPC_DEXTRV_RS_W
:
24686 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rt
, rs
, rd
, 1);
24691 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
24693 default: /* Invalid */
24694 MIPS_INVAL("MASK EXTR.W");
24695 gen_reserved_instruction(ctx
);
24699 case OPC_DPAQ_W_QH_DSP
:
24700 op2
= MASK_DPAQ_W_QH(ctx
->opcode
);
24702 case OPC_DPAU_H_OBL
:
24703 case OPC_DPAU_H_OBR
:
24704 case OPC_DPSU_H_OBL
:
24705 case OPC_DPSU_H_OBR
:
24707 case OPC_DPAQ_S_W_QH
:
24709 case OPC_DPSQ_S_W_QH
:
24710 case OPC_MULSAQ_S_W_QH
:
24711 case OPC_DPAQ_SA_L_PW
:
24712 case OPC_DPSQ_SA_L_PW
:
24713 case OPC_MULSAQ_S_L_PW
:
24714 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
24716 case OPC_MAQ_S_W_QHLL
:
24717 case OPC_MAQ_S_W_QHLR
:
24718 case OPC_MAQ_S_W_QHRL
:
24719 case OPC_MAQ_S_W_QHRR
:
24720 case OPC_MAQ_SA_W_QHLL
:
24721 case OPC_MAQ_SA_W_QHLR
:
24722 case OPC_MAQ_SA_W_QHRL
:
24723 case OPC_MAQ_SA_W_QHRR
:
24724 case OPC_MAQ_S_L_PWL
:
24725 case OPC_MAQ_S_L_PWR
:
24730 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
24732 default: /* Invalid */
24733 MIPS_INVAL("MASK DPAQ.W.QH");
24734 gen_reserved_instruction(ctx
);
24738 case OPC_DINSV_DSP
:
24739 op2
= MASK_INSV(ctx
->opcode
);
24750 t0
= tcg_temp_new();
24751 t1
= tcg_temp_new();
24753 gen_load_gpr(t0
, rt
);
24754 gen_load_gpr(t1
, rs
);
24756 gen_helper_dinsv(cpu_gpr
[rt
], cpu_env
, t1
, t0
);
24762 default: /* Invalid */
24763 MIPS_INVAL("MASK DINSV");
24764 gen_reserved_instruction(ctx
);
24768 case OPC_SHLL_OB_DSP
:
24769 gen_mipsdsp_shift(ctx
, op1
, rd
, rs
, rt
);
24772 default: /* Invalid */
24773 MIPS_INVAL("special3_legacy");
24774 gen_reserved_instruction(ctx
);
24780 #if defined(TARGET_MIPS64)
24782 static void decode_mmi0(CPUMIPSState
*env
, DisasContext
*ctx
)
24784 uint32_t opc
= MASK_MMI0(ctx
->opcode
);
24787 case MMI_OPC_0_PADDW
: /* TODO: MMI_OPC_0_PADDW */
24788 case MMI_OPC_0_PSUBW
: /* TODO: MMI_OPC_0_PSUBW */
24789 case MMI_OPC_0_PCGTW
: /* TODO: MMI_OPC_0_PCGTW */
24790 case MMI_OPC_0_PMAXW
: /* TODO: MMI_OPC_0_PMAXW */
24791 case MMI_OPC_0_PADDH
: /* TODO: MMI_OPC_0_PADDH */
24792 case MMI_OPC_0_PSUBH
: /* TODO: MMI_OPC_0_PSUBH */
24793 case MMI_OPC_0_PCGTH
: /* TODO: MMI_OPC_0_PCGTH */
24794 case MMI_OPC_0_PMAXH
: /* TODO: MMI_OPC_0_PMAXH */
24795 case MMI_OPC_0_PADDB
: /* TODO: MMI_OPC_0_PADDB */
24796 case MMI_OPC_0_PSUBB
: /* TODO: MMI_OPC_0_PSUBB */
24797 case MMI_OPC_0_PCGTB
: /* TODO: MMI_OPC_0_PCGTB */
24798 case MMI_OPC_0_PADDSW
: /* TODO: MMI_OPC_0_PADDSW */
24799 case MMI_OPC_0_PSUBSW
: /* TODO: MMI_OPC_0_PSUBSW */
24800 case MMI_OPC_0_PEXTLW
: /* TODO: MMI_OPC_0_PEXTLW */
24801 case MMI_OPC_0_PPACW
: /* TODO: MMI_OPC_0_PPACW */
24802 case MMI_OPC_0_PADDSH
: /* TODO: MMI_OPC_0_PADDSH */
24803 case MMI_OPC_0_PSUBSH
: /* TODO: MMI_OPC_0_PSUBSH */
24804 case MMI_OPC_0_PEXTLH
: /* TODO: MMI_OPC_0_PEXTLH */
24805 case MMI_OPC_0_PPACH
: /* TODO: MMI_OPC_0_PPACH */
24806 case MMI_OPC_0_PADDSB
: /* TODO: MMI_OPC_0_PADDSB */
24807 case MMI_OPC_0_PSUBSB
: /* TODO: MMI_OPC_0_PSUBSB */
24808 case MMI_OPC_0_PEXTLB
: /* TODO: MMI_OPC_0_PEXTLB */
24809 case MMI_OPC_0_PPACB
: /* TODO: MMI_OPC_0_PPACB */
24810 case MMI_OPC_0_PEXT5
: /* TODO: MMI_OPC_0_PEXT5 */
24811 case MMI_OPC_0_PPAC5
: /* TODO: MMI_OPC_0_PPAC5 */
24812 gen_reserved_instruction(ctx
); /* TODO: MMI_OPC_CLASS_MMI0 */
24815 MIPS_INVAL("TX79 MMI class MMI0");
24816 gen_reserved_instruction(ctx
);
24821 static void decode_mmi1(CPUMIPSState
*env
, DisasContext
*ctx
)
24823 uint32_t opc
= MASK_MMI1(ctx
->opcode
);
24826 case MMI_OPC_1_PABSW
: /* TODO: MMI_OPC_1_PABSW */
24827 case MMI_OPC_1_PCEQW
: /* TODO: MMI_OPC_1_PCEQW */
24828 case MMI_OPC_1_PMINW
: /* TODO: MMI_OPC_1_PMINW */
24829 case MMI_OPC_1_PADSBH
: /* TODO: MMI_OPC_1_PADSBH */
24830 case MMI_OPC_1_PABSH
: /* TODO: MMI_OPC_1_PABSH */
24831 case MMI_OPC_1_PCEQH
: /* TODO: MMI_OPC_1_PCEQH */
24832 case MMI_OPC_1_PMINH
: /* TODO: MMI_OPC_1_PMINH */
24833 case MMI_OPC_1_PCEQB
: /* TODO: MMI_OPC_1_PCEQB */
24834 case MMI_OPC_1_PADDUW
: /* TODO: MMI_OPC_1_PADDUW */
24835 case MMI_OPC_1_PSUBUW
: /* TODO: MMI_OPC_1_PSUBUW */
24836 case MMI_OPC_1_PEXTUW
: /* TODO: MMI_OPC_1_PEXTUW */
24837 case MMI_OPC_1_PADDUH
: /* TODO: MMI_OPC_1_PADDUH */
24838 case MMI_OPC_1_PSUBUH
: /* TODO: MMI_OPC_1_PSUBUH */
24839 case MMI_OPC_1_PEXTUH
: /* TODO: MMI_OPC_1_PEXTUH */
24840 case MMI_OPC_1_PADDUB
: /* TODO: MMI_OPC_1_PADDUB */
24841 case MMI_OPC_1_PSUBUB
: /* TODO: MMI_OPC_1_PSUBUB */
24842 case MMI_OPC_1_PEXTUB
: /* TODO: MMI_OPC_1_PEXTUB */
24843 case MMI_OPC_1_QFSRV
: /* TODO: MMI_OPC_1_QFSRV */
24844 gen_reserved_instruction(ctx
); /* TODO: MMI_OPC_CLASS_MMI1 */
24847 MIPS_INVAL("TX79 MMI class MMI1");
24848 gen_reserved_instruction(ctx
);
24853 static void decode_mmi2(CPUMIPSState
*env
, DisasContext
*ctx
)
24855 uint32_t opc
= MASK_MMI2(ctx
->opcode
);
24858 case MMI_OPC_2_PMADDW
: /* TODO: MMI_OPC_2_PMADDW */
24859 case MMI_OPC_2_PSLLVW
: /* TODO: MMI_OPC_2_PSLLVW */
24860 case MMI_OPC_2_PSRLVW
: /* TODO: MMI_OPC_2_PSRLVW */
24861 case MMI_OPC_2_PMSUBW
: /* TODO: MMI_OPC_2_PMSUBW */
24862 case MMI_OPC_2_PMFHI
: /* TODO: MMI_OPC_2_PMFHI */
24863 case MMI_OPC_2_PMFLO
: /* TODO: MMI_OPC_2_PMFLO */
24864 case MMI_OPC_2_PINTH
: /* TODO: MMI_OPC_2_PINTH */
24865 case MMI_OPC_2_PMULTW
: /* TODO: MMI_OPC_2_PMULTW */
24866 case MMI_OPC_2_PDIVW
: /* TODO: MMI_OPC_2_PDIVW */
24867 case MMI_OPC_2_PMADDH
: /* TODO: MMI_OPC_2_PMADDH */
24868 case MMI_OPC_2_PHMADH
: /* TODO: MMI_OPC_2_PHMADH */
24869 case MMI_OPC_2_PAND
: /* TODO: MMI_OPC_2_PAND */
24870 case MMI_OPC_2_PXOR
: /* TODO: MMI_OPC_2_PXOR */
24871 case MMI_OPC_2_PMSUBH
: /* TODO: MMI_OPC_2_PMSUBH */
24872 case MMI_OPC_2_PHMSBH
: /* TODO: MMI_OPC_2_PHMSBH */
24873 case MMI_OPC_2_PEXEH
: /* TODO: MMI_OPC_2_PEXEH */
24874 case MMI_OPC_2_PREVH
: /* TODO: MMI_OPC_2_PREVH */
24875 case MMI_OPC_2_PMULTH
: /* TODO: MMI_OPC_2_PMULTH */
24876 case MMI_OPC_2_PDIVBW
: /* TODO: MMI_OPC_2_PDIVBW */
24877 case MMI_OPC_2_PEXEW
: /* TODO: MMI_OPC_2_PEXEW */
24878 case MMI_OPC_2_PROT3W
: /* TODO: MMI_OPC_2_PROT3W */
24879 gen_reserved_instruction(ctx
); /* TODO: MMI_OPC_CLASS_MMI2 */
24882 MIPS_INVAL("TX79 MMI class MMI2");
24883 gen_reserved_instruction(ctx
);
24888 static void decode_mmi3(CPUMIPSState
*env
, DisasContext
*ctx
)
24890 uint32_t opc
= MASK_MMI3(ctx
->opcode
);
24893 case MMI_OPC_3_PMADDUW
: /* TODO: MMI_OPC_3_PMADDUW */
24894 case MMI_OPC_3_PSRAVW
: /* TODO: MMI_OPC_3_PSRAVW */
24895 case MMI_OPC_3_PMTHI
: /* TODO: MMI_OPC_3_PMTHI */
24896 case MMI_OPC_3_PMTLO
: /* TODO: MMI_OPC_3_PMTLO */
24897 case MMI_OPC_3_PINTEH
: /* TODO: MMI_OPC_3_PINTEH */
24898 case MMI_OPC_3_PMULTUW
: /* TODO: MMI_OPC_3_PMULTUW */
24899 case MMI_OPC_3_PDIVUW
: /* TODO: MMI_OPC_3_PDIVUW */
24900 case MMI_OPC_3_POR
: /* TODO: MMI_OPC_3_POR */
24901 case MMI_OPC_3_PNOR
: /* TODO: MMI_OPC_3_PNOR */
24902 case MMI_OPC_3_PEXCH
: /* TODO: MMI_OPC_3_PEXCH */
24903 case MMI_OPC_3_PEXCW
: /* TODO: MMI_OPC_3_PEXCW */
24904 gen_reserved_instruction(ctx
); /* TODO: MMI_OPC_CLASS_MMI3 */
24907 MIPS_INVAL("TX79 MMI class MMI3");
24908 gen_reserved_instruction(ctx
);
24913 static void decode_mmi(CPUMIPSState
*env
, DisasContext
*ctx
)
24915 uint32_t opc
= MASK_MMI(ctx
->opcode
);
24916 int rs
= extract32(ctx
->opcode
, 21, 5);
24917 int rt
= extract32(ctx
->opcode
, 16, 5);
24918 int rd
= extract32(ctx
->opcode
, 11, 5);
24921 case MMI_OPC_CLASS_MMI0
:
24922 decode_mmi0(env
, ctx
);
24924 case MMI_OPC_CLASS_MMI1
:
24925 decode_mmi1(env
, ctx
);
24927 case MMI_OPC_CLASS_MMI2
:
24928 decode_mmi2(env
, ctx
);
24930 case MMI_OPC_CLASS_MMI3
:
24931 decode_mmi3(env
, ctx
);
24933 case MMI_OPC_MULT1
:
24934 case MMI_OPC_MULTU1
:
24936 case MMI_OPC_MADDU
:
24937 case MMI_OPC_MADD1
:
24938 case MMI_OPC_MADDU1
:
24939 gen_mul_txx9(ctx
, opc
, rd
, rs
, rt
);
24942 case MMI_OPC_DIVU1
:
24943 gen_div1_tx79(ctx
, opc
, rs
, rt
);
24945 case MMI_OPC_PLZCW
: /* TODO: MMI_OPC_PLZCW */
24946 case MMI_OPC_PMFHL
: /* TODO: MMI_OPC_PMFHL */
24947 case MMI_OPC_PMTHL
: /* TODO: MMI_OPC_PMTHL */
24948 case MMI_OPC_PSLLH
: /* TODO: MMI_OPC_PSLLH */
24949 case MMI_OPC_PSRLH
: /* TODO: MMI_OPC_PSRLH */
24950 case MMI_OPC_PSRAH
: /* TODO: MMI_OPC_PSRAH */
24951 case MMI_OPC_PSLLW
: /* TODO: MMI_OPC_PSLLW */
24952 case MMI_OPC_PSRLW
: /* TODO: MMI_OPC_PSRLW */
24953 case MMI_OPC_PSRAW
: /* TODO: MMI_OPC_PSRAW */
24954 gen_reserved_instruction(ctx
); /* TODO: MMI_OPC_CLASS_MMI */
24957 MIPS_INVAL("TX79 MMI class");
24958 gen_reserved_instruction(ctx
);
24963 static void gen_mmi_lq(CPUMIPSState
*env
, DisasContext
*ctx
)
24965 gen_reserved_instruction(ctx
); /* TODO: MMI_OPC_LQ */
24968 static void gen_mmi_sq(DisasContext
*ctx
, int base
, int rt
, int offset
)
24970 gen_reserved_instruction(ctx
); /* TODO: MMI_OPC_SQ */
24974 * The TX79-specific instruction Store Quadword
24976 * +--------+-------+-------+------------------------+
24977 * | 011111 | base | rt | offset | SQ
24978 * +--------+-------+-------+------------------------+
24981 * has the same opcode as the Read Hardware Register instruction
24983 * +--------+-------+-------+-------+-------+--------+
24984 * | 011111 | 00000 | rt | rd | 00000 | 111011 | RDHWR
24985 * +--------+-------+-------+-------+-------+--------+
24988 * that is required, trapped and emulated by the Linux kernel. However, all
24989 * RDHWR encodings yield address error exceptions on the TX79 since the SQ
24990 * offset is odd. Therefore all valid SQ instructions can execute normally.
24991 * In user mode, QEMU must verify the upper and lower 11 bits to distinguish
24992 * between SQ and RDHWR, as the Linux kernel does.
24994 static void decode_mmi_sq(CPUMIPSState
*env
, DisasContext
*ctx
)
24996 int base
= extract32(ctx
->opcode
, 21, 5);
24997 int rt
= extract32(ctx
->opcode
, 16, 5);
24998 int offset
= extract32(ctx
->opcode
, 0, 16);
25000 #ifdef CONFIG_USER_ONLY
25001 uint32_t op1
= MASK_SPECIAL3(ctx
->opcode
);
25002 uint32_t op2
= extract32(ctx
->opcode
, 6, 5);
25004 if (base
== 0 && op2
== 0 && op1
== OPC_RDHWR
) {
25005 int rd
= extract32(ctx
->opcode
, 11, 5);
25007 gen_rdhwr(ctx
, rt
, rd
, 0);
25012 gen_mmi_sq(ctx
, base
, rt
, offset
);
25017 static void decode_opc_special3(CPUMIPSState
*env
, DisasContext
*ctx
)
25019 int rs
, rt
, rd
, sa
;
25023 rs
= (ctx
->opcode
>> 21) & 0x1f;
25024 rt
= (ctx
->opcode
>> 16) & 0x1f;
25025 rd
= (ctx
->opcode
>> 11) & 0x1f;
25026 sa
= (ctx
->opcode
>> 6) & 0x1f;
25027 imm
= sextract32(ctx
->opcode
, 7, 9);
25029 op1
= MASK_SPECIAL3(ctx
->opcode
);
25032 * EVA loads and stores overlap Loongson 2E instructions decoded by
25033 * decode_opc_special3_legacy(), so be careful to allow their decoding when
25046 check_cp0_enabled(ctx
);
25047 gen_ld(ctx
, op1
, rt
, rs
, imm
);
25054 check_cp0_enabled(ctx
);
25055 gen_st(ctx
, op1
, rt
, rs
, imm
);
25058 check_cp0_enabled(ctx
);
25059 gen_st_cond(ctx
, rt
, rs
, imm
, MO_TESL
, true);
25062 check_cp0_enabled(ctx
);
25063 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
25064 gen_cache_operation(ctx
, rt
, rs
, imm
);
25066 /* Treat as NOP. */
25069 check_cp0_enabled(ctx
);
25070 /* Treat as NOP. */
25078 check_insn(ctx
, ISA_MIPS_R2
);
25079 gen_bitops(ctx
, op1
, rt
, rs
, sa
, rd
);
25082 op2
= MASK_BSHFL(ctx
->opcode
);
25089 check_insn(ctx
, ISA_MIPS_R6
);
25090 decode_opc_special3_r6(env
, ctx
);
25093 check_insn(ctx
, ISA_MIPS_R2
);
25094 gen_bshfl(ctx
, op2
, rt
, rd
);
25098 #if defined(TARGET_MIPS64)
25105 check_insn(ctx
, ISA_MIPS_R2
);
25106 check_mips_64(ctx
);
25107 gen_bitops(ctx
, op1
, rt
, rs
, sa
, rd
);
25110 op2
= MASK_DBSHFL(ctx
->opcode
);
25121 check_insn(ctx
, ISA_MIPS_R6
);
25122 decode_opc_special3_r6(env
, ctx
);
25125 check_insn(ctx
, ISA_MIPS_R2
);
25126 check_mips_64(ctx
);
25127 op2
= MASK_DBSHFL(ctx
->opcode
);
25128 gen_bshfl(ctx
, op2
, rt
, rd
);
25134 gen_rdhwr(ctx
, rt
, rd
, extract32(ctx
->opcode
, 6, 3));
25139 TCGv t0
= tcg_temp_new();
25140 TCGv t1
= tcg_temp_new();
25142 gen_load_gpr(t0
, rt
);
25143 gen_load_gpr(t1
, rs
);
25144 gen_helper_fork(t0
, t1
);
25152 TCGv t0
= tcg_temp_new();
25154 gen_load_gpr(t0
, rs
);
25155 gen_helper_yield(t0
, cpu_env
, t0
);
25156 gen_store_gpr(t0
, rd
);
25161 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
25162 decode_opc_special3_r6(env
, ctx
);
25164 decode_opc_special3_legacy(env
, ctx
);
25169 static bool decode_opc_legacy(CPUMIPSState
*env
, DisasContext
*ctx
)
25172 int rs
, rt
, rd
, sa
;
25176 op
= MASK_OP_MAJOR(ctx
->opcode
);
25177 rs
= (ctx
->opcode
>> 21) & 0x1f;
25178 rt
= (ctx
->opcode
>> 16) & 0x1f;
25179 rd
= (ctx
->opcode
>> 11) & 0x1f;
25180 sa
= (ctx
->opcode
>> 6) & 0x1f;
25181 imm
= (int16_t)ctx
->opcode
;
25184 decode_opc_special(env
, ctx
);
25187 #if defined(TARGET_MIPS64)
25188 if ((ctx
->insn_flags
& INSN_R5900
) && (ctx
->insn_flags
& ASE_MMI
)) {
25189 decode_mmi(env
, ctx
);
25193 if (TARGET_LONG_BITS
== 32 && (ctx
->insn_flags
& ASE_MXU
)) {
25194 if (MASK_SPECIAL2(ctx
->opcode
) == OPC_MUL
) {
25195 gen_arith(ctx
, OPC_MUL
, rd
, rs
, rt
);
25197 decode_ase_mxu(ctx
, ctx
->opcode
);
25201 decode_opc_special2_legacy(env
, ctx
);
25204 #if defined(TARGET_MIPS64)
25205 if (ctx
->insn_flags
& INSN_R5900
) {
25206 decode_mmi_sq(env
, ctx
); /* MMI_OPC_SQ */
25208 decode_opc_special3(env
, ctx
);
25211 decode_opc_special3(env
, ctx
);
25215 op1
= MASK_REGIMM(ctx
->opcode
);
25217 case OPC_BLTZL
: /* REGIMM branches */
25221 check_insn(ctx
, ISA_MIPS2
);
25222 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
25226 gen_compute_branch(ctx
, op1
, 4, rs
, -1, imm
<< 2, 4);
25230 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
25232 /* OPC_NAL, OPC_BAL */
25233 gen_compute_branch(ctx
, op1
, 4, 0, -1, imm
<< 2, 4);
25235 gen_reserved_instruction(ctx
);
25238 gen_compute_branch(ctx
, op1
, 4, rs
, -1, imm
<< 2, 4);
25241 case OPC_TGEI
: /* REGIMM traps */
25248 check_insn(ctx
, ISA_MIPS2
);
25249 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
25250 gen_trap(ctx
, op1
, rs
, -1, imm
);
25253 check_insn(ctx
, ISA_MIPS_R6
);
25254 gen_reserved_instruction(ctx
);
25257 check_insn(ctx
, ISA_MIPS_R2
);
25259 * Break the TB to be able to sync copied instructions
25262 ctx
->base
.is_jmp
= DISAS_STOP
;
25264 case OPC_BPOSGE32
: /* MIPS DSP branch */
25265 #if defined(TARGET_MIPS64)
25269 gen_compute_branch(ctx
, op1
, 4, -1, -2, (int32_t)imm
<< 2, 4);
25271 #if defined(TARGET_MIPS64)
25273 check_insn(ctx
, ISA_MIPS_R6
);
25274 check_mips_64(ctx
);
25276 tcg_gen_addi_tl(cpu_gpr
[rs
], cpu_gpr
[rs
], (int64_t)imm
<< 32);
25280 check_insn(ctx
, ISA_MIPS_R6
);
25281 check_mips_64(ctx
);
25283 tcg_gen_addi_tl(cpu_gpr
[rs
], cpu_gpr
[rs
], (int64_t)imm
<< 48);
25287 default: /* Invalid */
25288 MIPS_INVAL("regimm");
25289 gen_reserved_instruction(ctx
);
25294 check_cp0_enabled(ctx
);
25295 op1
= MASK_CP0(ctx
->opcode
);
25303 #if defined(TARGET_MIPS64)
25307 #ifndef CONFIG_USER_ONLY
25308 gen_cp0(env
, ctx
, op1
, rt
, rd
);
25309 #endif /* !CONFIG_USER_ONLY */
25327 #ifndef CONFIG_USER_ONLY
25328 gen_cp0(env
, ctx
, MASK_C0(ctx
->opcode
), rt
, rd
);
25329 #endif /* !CONFIG_USER_ONLY */
25332 #ifndef CONFIG_USER_ONLY
25335 TCGv t0
= tcg_temp_new();
25337 op2
= MASK_MFMC0(ctx
->opcode
);
25341 gen_helper_dmt(t0
);
25342 gen_store_gpr(t0
, rt
);
25346 gen_helper_emt(t0
);
25347 gen_store_gpr(t0
, rt
);
25351 gen_helper_dvpe(t0
, cpu_env
);
25352 gen_store_gpr(t0
, rt
);
25356 gen_helper_evpe(t0
, cpu_env
);
25357 gen_store_gpr(t0
, rt
);
25360 check_insn(ctx
, ISA_MIPS_R6
);
25362 gen_helper_dvp(t0
, cpu_env
);
25363 gen_store_gpr(t0
, rt
);
25367 check_insn(ctx
, ISA_MIPS_R6
);
25369 gen_helper_evp(t0
, cpu_env
);
25370 gen_store_gpr(t0
, rt
);
25374 check_insn(ctx
, ISA_MIPS_R2
);
25375 save_cpu_state(ctx
, 1);
25376 gen_helper_di(t0
, cpu_env
);
25377 gen_store_gpr(t0
, rt
);
25379 * Stop translation as we may have switched
25380 * the execution mode.
25382 ctx
->base
.is_jmp
= DISAS_STOP
;
25385 check_insn(ctx
, ISA_MIPS_R2
);
25386 save_cpu_state(ctx
, 1);
25387 gen_helper_ei(t0
, cpu_env
);
25388 gen_store_gpr(t0
, rt
);
25390 * DISAS_STOP isn't sufficient, we need to ensure we break
25391 * out of translated code to check for pending interrupts.
25393 gen_save_pc(ctx
->base
.pc_next
+ 4);
25394 ctx
->base
.is_jmp
= DISAS_EXIT
;
25396 default: /* Invalid */
25397 MIPS_INVAL("mfmc0");
25398 gen_reserved_instruction(ctx
);
25403 #endif /* !CONFIG_USER_ONLY */
25406 check_insn(ctx
, ISA_MIPS_R2
);
25407 gen_load_srsgpr(rt
, rd
);
25410 check_insn(ctx
, ISA_MIPS_R2
);
25411 gen_store_srsgpr(rt
, rd
);
25415 gen_reserved_instruction(ctx
);
25419 case OPC_BOVC
: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */
25420 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
25421 /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */
25422 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
25425 /* Arithmetic with immediate opcode */
25426 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
25430 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
25432 case OPC_SLTI
: /* Set on less than with immediate opcode */
25434 gen_slt_imm(ctx
, op
, rt
, rs
, imm
);
25436 case OPC_ANDI
: /* Arithmetic with immediate opcode */
25437 case OPC_LUI
: /* OPC_AUI */
25440 gen_logic_imm(ctx
, op
, rt
, rs
, imm
);
25442 case OPC_J
: /* Jump */
25444 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
25445 gen_compute_branch(ctx
, op
, 4, rs
, rt
, offset
, 4);
25448 case OPC_BLEZC
: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */
25449 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
25451 gen_reserved_instruction(ctx
);
25454 /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */
25455 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
25458 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
25461 case OPC_BGTZC
: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */
25462 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
25464 gen_reserved_instruction(ctx
);
25467 /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */
25468 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
25471 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
25474 case OPC_BLEZALC
: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */
25477 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
25479 check_insn(ctx
, ISA_MIPS_R6
);
25480 /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */
25481 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
25484 case OPC_BGTZALC
: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */
25487 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
25489 check_insn(ctx
, ISA_MIPS_R6
);
25490 /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */
25491 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
25496 check_insn(ctx
, ISA_MIPS2
);
25497 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
25501 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
25503 case OPC_LL
: /* Load and stores */
25504 check_insn(ctx
, ISA_MIPS2
);
25505 if (ctx
->insn_flags
& INSN_R5900
) {
25506 check_insn_opc_user_only(ctx
, INSN_R5900
);
25517 gen_ld(ctx
, op
, rt
, rs
, imm
);
25524 gen_st(ctx
, op
, rt
, rs
, imm
);
25527 check_insn(ctx
, ISA_MIPS2
);
25528 if (ctx
->insn_flags
& INSN_R5900
) {
25529 check_insn_opc_user_only(ctx
, INSN_R5900
);
25531 gen_st_cond(ctx
, rt
, rs
, imm
, MO_TESL
, false);
25534 check_cp0_enabled(ctx
);
25535 check_insn(ctx
, ISA_MIPS3
| ISA_MIPS_R1
);
25536 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
25537 gen_cache_operation(ctx
, rt
, rs
, imm
);
25539 /* Treat as NOP. */
25542 if (ctx
->insn_flags
& INSN_R5900
) {
25543 /* Treat as NOP. */
25545 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS_R1
);
25546 /* Treat as NOP. */
25550 /* Floating point (COP1). */
25555 gen_cop1_ldst(ctx
, op
, rt
, rs
, imm
);
25559 op1
= MASK_CP1(ctx
->opcode
);
25564 check_cp1_enabled(ctx
);
25565 check_insn(ctx
, ISA_MIPS_R2
);
25571 check_cp1_enabled(ctx
);
25572 gen_cp1(ctx
, op1
, rt
, rd
);
25574 #if defined(TARGET_MIPS64)
25577 check_cp1_enabled(ctx
);
25578 check_insn(ctx
, ISA_MIPS3
);
25579 check_mips_64(ctx
);
25580 gen_cp1(ctx
, op1
, rt
, rd
);
25583 case OPC_BC1EQZ
: /* OPC_BC1ANY2 */
25584 check_cp1_enabled(ctx
);
25585 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
25587 gen_compute_branch1_r6(ctx
, MASK_CP1(ctx
->opcode
),
25592 check_insn(ctx
, ASE_MIPS3D
);
25593 gen_compute_branch1(ctx
, MASK_BC1(ctx
->opcode
),
25594 (rt
>> 2) & 0x7, imm
<< 2);
25598 check_cp1_enabled(ctx
);
25599 check_insn(ctx
, ISA_MIPS_R6
);
25600 gen_compute_branch1_r6(ctx
, MASK_CP1(ctx
->opcode
),
25604 check_cp1_enabled(ctx
);
25605 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
25607 check_insn(ctx
, ASE_MIPS3D
);
25610 check_cp1_enabled(ctx
);
25611 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
25612 gen_compute_branch1(ctx
, MASK_BC1(ctx
->opcode
),
25613 (rt
>> 2) & 0x7, imm
<< 2);
25620 check_cp1_enabled(ctx
);
25621 gen_farith(ctx
, ctx
->opcode
& FOP(0x3f, 0x1f), rt
, rd
, sa
,
25627 int r6_op
= ctx
->opcode
& FOP(0x3f, 0x1f);
25628 check_cp1_enabled(ctx
);
25629 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
25631 case R6_OPC_CMP_AF_S
:
25632 case R6_OPC_CMP_UN_S
:
25633 case R6_OPC_CMP_EQ_S
:
25634 case R6_OPC_CMP_UEQ_S
:
25635 case R6_OPC_CMP_LT_S
:
25636 case R6_OPC_CMP_ULT_S
:
25637 case R6_OPC_CMP_LE_S
:
25638 case R6_OPC_CMP_ULE_S
:
25639 case R6_OPC_CMP_SAF_S
:
25640 case R6_OPC_CMP_SUN_S
:
25641 case R6_OPC_CMP_SEQ_S
:
25642 case R6_OPC_CMP_SEUQ_S
:
25643 case R6_OPC_CMP_SLT_S
:
25644 case R6_OPC_CMP_SULT_S
:
25645 case R6_OPC_CMP_SLE_S
:
25646 case R6_OPC_CMP_SULE_S
:
25647 case R6_OPC_CMP_OR_S
:
25648 case R6_OPC_CMP_UNE_S
:
25649 case R6_OPC_CMP_NE_S
:
25650 case R6_OPC_CMP_SOR_S
:
25651 case R6_OPC_CMP_SUNE_S
:
25652 case R6_OPC_CMP_SNE_S
:
25653 gen_r6_cmp_s(ctx
, ctx
->opcode
& 0x1f, rt
, rd
, sa
);
25655 case R6_OPC_CMP_AF_D
:
25656 case R6_OPC_CMP_UN_D
:
25657 case R6_OPC_CMP_EQ_D
:
25658 case R6_OPC_CMP_UEQ_D
:
25659 case R6_OPC_CMP_LT_D
:
25660 case R6_OPC_CMP_ULT_D
:
25661 case R6_OPC_CMP_LE_D
:
25662 case R6_OPC_CMP_ULE_D
:
25663 case R6_OPC_CMP_SAF_D
:
25664 case R6_OPC_CMP_SUN_D
:
25665 case R6_OPC_CMP_SEQ_D
:
25666 case R6_OPC_CMP_SEUQ_D
:
25667 case R6_OPC_CMP_SLT_D
:
25668 case R6_OPC_CMP_SULT_D
:
25669 case R6_OPC_CMP_SLE_D
:
25670 case R6_OPC_CMP_SULE_D
:
25671 case R6_OPC_CMP_OR_D
:
25672 case R6_OPC_CMP_UNE_D
:
25673 case R6_OPC_CMP_NE_D
:
25674 case R6_OPC_CMP_SOR_D
:
25675 case R6_OPC_CMP_SUNE_D
:
25676 case R6_OPC_CMP_SNE_D
:
25677 gen_r6_cmp_d(ctx
, ctx
->opcode
& 0x1f, rt
, rd
, sa
);
25680 gen_farith(ctx
, ctx
->opcode
& FOP(0x3f, 0x1f),
25681 rt
, rd
, sa
, (imm
>> 8) & 0x7);
25686 gen_farith(ctx
, ctx
->opcode
& FOP(0x3f, 0x1f), rt
, rd
, sa
,
25693 gen_reserved_instruction(ctx
);
25698 /* Compact branches [R6] and COP2 [non-R6] */
25699 case OPC_BC
: /* OPC_LWC2 */
25700 case OPC_BALC
: /* OPC_SWC2 */
25701 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
25702 /* OPC_BC, OPC_BALC */
25703 gen_compute_compact_branch(ctx
, op
, 0, 0,
25704 sextract32(ctx
->opcode
<< 2, 0, 28));
25705 } else if (ctx
->insn_flags
& ASE_LEXT
) {
25706 gen_loongson_lswc2(ctx
, rt
, rs
, rd
);
25708 /* OPC_LWC2, OPC_SWC2 */
25709 /* COP2: Not implemented. */
25710 generate_exception_err(ctx
, EXCP_CpU
, 2);
25713 case OPC_BEQZC
: /* OPC_JIC, OPC_LDC2 */
25714 case OPC_BNEZC
: /* OPC_JIALC, OPC_SDC2 */
25715 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
25717 /* OPC_BEQZC, OPC_BNEZC */
25718 gen_compute_compact_branch(ctx
, op
, rs
, 0,
25719 sextract32(ctx
->opcode
<< 2, 0, 23));
25721 /* OPC_JIC, OPC_JIALC */
25722 gen_compute_compact_branch(ctx
, op
, 0, rt
, imm
);
25724 } else if (ctx
->insn_flags
& ASE_LEXT
) {
25725 gen_loongson_lsdc2(ctx
, rt
, rs
, rd
);
25727 /* OPC_LWC2, OPC_SWC2 */
25728 /* COP2: Not implemented. */
25729 generate_exception_err(ctx
, EXCP_CpU
, 2);
25733 check_insn(ctx
, ASE_LMMI
);
25734 /* Note that these instructions use different fields. */
25735 gen_loongson_multimedia(ctx
, sa
, rd
, rt
);
25739 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
25740 check_cp1_enabled(ctx
);
25741 op1
= MASK_CP3(ctx
->opcode
);
25745 check_insn(ctx
, ISA_MIPS5
| ISA_MIPS_R2
);
25751 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS_R2
);
25752 gen_flt3_ldst(ctx
, op1
, sa
, rd
, rs
, rt
);
25755 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS_R2
);
25756 /* Treat as NOP. */
25759 check_insn(ctx
, ISA_MIPS5
| ISA_MIPS_R2
);
25773 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS_R2
);
25774 gen_flt3_arith(ctx
, op1
, sa
, rs
, rd
, rt
);
25778 gen_reserved_instruction(ctx
);
25782 generate_exception_err(ctx
, EXCP_CpU
, 1);
25786 #if defined(TARGET_MIPS64)
25787 /* MIPS64 opcodes */
25789 if (ctx
->insn_flags
& INSN_R5900
) {
25790 check_insn_opc_user_only(ctx
, INSN_R5900
);
25797 check_insn(ctx
, ISA_MIPS3
);
25798 check_mips_64(ctx
);
25799 gen_ld(ctx
, op
, rt
, rs
, imm
);
25804 check_insn(ctx
, ISA_MIPS3
);
25805 check_mips_64(ctx
);
25806 gen_st(ctx
, op
, rt
, rs
, imm
);
25809 check_insn(ctx
, ISA_MIPS3
);
25810 if (ctx
->insn_flags
& INSN_R5900
) {
25811 check_insn_opc_user_only(ctx
, INSN_R5900
);
25813 check_mips_64(ctx
);
25814 gen_st_cond(ctx
, rt
, rs
, imm
, MO_TEQ
, false);
25816 case OPC_BNVC
: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */
25817 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
25818 /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */
25819 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
25822 check_insn(ctx
, ISA_MIPS3
);
25823 check_mips_64(ctx
);
25824 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
25828 check_insn(ctx
, ISA_MIPS3
);
25829 check_mips_64(ctx
);
25830 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
25833 case OPC_BNVC
: /* OPC_BNEZALC, OPC_BNEC */
25834 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
25835 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
25837 MIPS_INVAL("major opcode");
25838 gen_reserved_instruction(ctx
);
25842 case OPC_DAUI
: /* OPC_JALX */
25843 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
25844 #if defined(TARGET_MIPS64)
25846 check_mips_64(ctx
);
25848 generate_exception(ctx
, EXCP_RI
);
25849 } else if (rt
!= 0) {
25850 TCGv t0
= tcg_temp_new();
25851 gen_load_gpr(t0
, rs
);
25852 tcg_gen_addi_tl(cpu_gpr
[rt
], t0
, imm
<< 16);
25856 gen_reserved_instruction(ctx
);
25857 MIPS_INVAL("major opcode");
25861 check_insn(ctx
, ASE_MIPS16
| ASE_MICROMIPS
);
25862 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
25863 gen_compute_branch(ctx
, op
, 4, rs
, rt
, offset
, 4);
25866 case OPC_MDMX
: /* MMI_OPC_LQ */
25867 if (ctx
->insn_flags
& INSN_R5900
) {
25868 #if defined(TARGET_MIPS64)
25869 gen_mmi_lq(env
, ctx
);
25872 /* MDMX: Not implemented. */
25876 check_insn(ctx
, ISA_MIPS_R6
);
25877 gen_pcrel(ctx
, ctx
->opcode
, ctx
->base
.pc_next
, rs
);
25879 default: /* Invalid */
25880 MIPS_INVAL("major opcode");
25886 static void decode_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
25888 /* make sure instructions are on a word boundary */
25889 if (ctx
->base
.pc_next
& 0x3) {
25890 env
->CP0_BadVAddr
= ctx
->base
.pc_next
;
25891 generate_exception_err(ctx
, EXCP_AdEL
, EXCP_INST_NOTAVAIL
);
25895 /* Handle blikely not taken case */
25896 if ((ctx
->hflags
& MIPS_HFLAG_BMASK_BASE
) == MIPS_HFLAG_BL
) {
25897 TCGLabel
*l1
= gen_new_label();
25899 tcg_gen_brcondi_tl(TCG_COND_NE
, bcond
, 0, l1
);
25900 tcg_gen_movi_i32(hflags
, ctx
->hflags
& ~MIPS_HFLAG_BMASK
);
25901 gen_goto_tb(ctx
, 1, ctx
->base
.pc_next
+ 4);
25905 /* Transition to the auto-generated decoder. */
25907 /* ISA extensions */
25908 if (ase_msa_available(env
) && decode_ase_msa(ctx
, ctx
->opcode
)) {
25912 /* ISA (from latest to oldest) */
25913 if (cpu_supports_isa(env
, ISA_MIPS_R6
) && decode_isa_rel6(ctx
, ctx
->opcode
)) {
25916 if (cpu_supports_isa(env
, INSN_R5900
) && decode_ext_txx9(ctx
, ctx
->opcode
)) {
25920 if (decode_opc_legacy(env
, ctx
)) {
25924 gen_reserved_instruction(ctx
);
25927 static void mips_tr_init_disas_context(DisasContextBase
*dcbase
, CPUState
*cs
)
25929 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
25930 CPUMIPSState
*env
= cs
->env_ptr
;
25932 ctx
->page_start
= ctx
->base
.pc_first
& TARGET_PAGE_MASK
;
25933 ctx
->saved_pc
= -1;
25934 ctx
->insn_flags
= env
->insn_flags
;
25935 ctx
->CP0_Config1
= env
->CP0_Config1
;
25936 ctx
->CP0_Config2
= env
->CP0_Config2
;
25937 ctx
->CP0_Config3
= env
->CP0_Config3
;
25938 ctx
->CP0_Config5
= env
->CP0_Config5
;
25940 ctx
->kscrexist
= (env
->CP0_Config4
>> CP0C4_KScrExist
) & 0xff;
25941 ctx
->rxi
= (env
->CP0_Config3
>> CP0C3_RXI
) & 1;
25942 ctx
->ie
= (env
->CP0_Config4
>> CP0C4_IE
) & 3;
25943 ctx
->bi
= (env
->CP0_Config3
>> CP0C3_BI
) & 1;
25944 ctx
->bp
= (env
->CP0_Config3
>> CP0C3_BP
) & 1;
25945 ctx
->PAMask
= env
->PAMask
;
25946 ctx
->mvh
= (env
->CP0_Config5
>> CP0C5_MVH
) & 1;
25947 ctx
->eva
= (env
->CP0_Config5
>> CP0C5_EVA
) & 1;
25948 ctx
->sc
= (env
->CP0_Config3
>> CP0C3_SC
) & 1;
25949 ctx
->CP0_LLAddr_shift
= env
->CP0_LLAddr_shift
;
25950 ctx
->cmgcr
= (env
->CP0_Config3
>> CP0C3_CMGCR
) & 1;
25951 /* Restore delay slot state from the tb context. */
25952 ctx
->hflags
= (uint32_t)ctx
->base
.tb
->flags
; /* FIXME: maybe use 64 bits? */
25953 ctx
->ulri
= (env
->CP0_Config3
>> CP0C3_ULRI
) & 1;
25954 ctx
->ps
= ((env
->active_fpu
.fcr0
>> FCR0_PS
) & 1) ||
25955 (env
->insn_flags
& (INSN_LOONGSON2E
| INSN_LOONGSON2F
));
25956 ctx
->vp
= (env
->CP0_Config5
>> CP0C5_VP
) & 1;
25957 ctx
->mrp
= (env
->CP0_Config5
>> CP0C5_MRP
) & 1;
25958 ctx
->nan2008
= (env
->active_fpu
.fcr31
>> FCR31_NAN2008
) & 1;
25959 ctx
->abs2008
= (env
->active_fpu
.fcr31
>> FCR31_ABS2008
) & 1;
25960 ctx
->mi
= (env
->CP0_Config5
>> CP0C5_MI
) & 1;
25961 ctx
->gi
= (env
->CP0_Config5
>> CP0C5_GI
) & 3;
25962 restore_cpu_state(env
, ctx
);
25963 #ifdef CONFIG_USER_ONLY
25964 ctx
->mem_idx
= MIPS_HFLAG_UM
;
25966 ctx
->mem_idx
= hflags_mmu_index(ctx
->hflags
);
25968 ctx
->default_tcg_memop_mask
= (ctx
->insn_flags
& (ISA_MIPS_R6
|
25969 INSN_LOONGSON3A
)) ? MO_UNALN
: MO_ALIGN
;
25971 LOG_DISAS("\ntb %p idx %d hflags %04x\n", ctx
->base
.tb
, ctx
->mem_idx
,
25975 static void mips_tr_tb_start(DisasContextBase
*dcbase
, CPUState
*cs
)
25979 static void mips_tr_insn_start(DisasContextBase
*dcbase
, CPUState
*cs
)
25981 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
25983 tcg_gen_insn_start(ctx
->base
.pc_next
, ctx
->hflags
& MIPS_HFLAG_BMASK
,
25987 static bool mips_tr_breakpoint_check(DisasContextBase
*dcbase
, CPUState
*cs
,
25988 const CPUBreakpoint
*bp
)
25990 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
25992 save_cpu_state(ctx
, 1);
25993 ctx
->base
.is_jmp
= DISAS_NORETURN
;
25994 gen_helper_raise_exception_debug(cpu_env
);
25996 * The address covered by the breakpoint must be included in
25997 * [tb->pc, tb->pc + tb->size) in order to for it to be
25998 * properly cleared -- thus we increment the PC here so that
25999 * the logic setting tb->size below does the right thing.
26001 ctx
->base
.pc_next
+= 4;
26005 static void mips_tr_translate_insn(DisasContextBase
*dcbase
, CPUState
*cs
)
26007 CPUMIPSState
*env
= cs
->env_ptr
;
26008 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
26012 is_slot
= ctx
->hflags
& MIPS_HFLAG_BMASK
;
26013 if (ctx
->insn_flags
& ISA_NANOMIPS32
) {
26014 ctx
->opcode
= translator_lduw(env
, ctx
->base
.pc_next
);
26015 insn_bytes
= decode_nanomips_opc(env
, ctx
);
26016 } else if (!(ctx
->hflags
& MIPS_HFLAG_M16
)) {
26017 ctx
->opcode
= translator_ldl(env
, ctx
->base
.pc_next
);
26019 decode_opc(env
, ctx
);
26020 } else if (ctx
->insn_flags
& ASE_MICROMIPS
) {
26021 ctx
->opcode
= translator_lduw(env
, ctx
->base
.pc_next
);
26022 insn_bytes
= decode_micromips_opc(env
, ctx
);
26023 } else if (ctx
->insn_flags
& ASE_MIPS16
) {
26024 ctx
->opcode
= translator_lduw(env
, ctx
->base
.pc_next
);
26025 insn_bytes
= decode_mips16_opc(env
, ctx
);
26027 gen_reserved_instruction(ctx
);
26028 g_assert(ctx
->base
.is_jmp
== DISAS_NORETURN
);
26032 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
26033 if (!(ctx
->hflags
& (MIPS_HFLAG_BDS16
| MIPS_HFLAG_BDS32
|
26034 MIPS_HFLAG_FBNSLOT
))) {
26036 * Force to generate branch as there is neither delay nor
26041 if ((ctx
->hflags
& MIPS_HFLAG_M16
) &&
26042 (ctx
->hflags
& MIPS_HFLAG_FBNSLOT
)) {
26044 * Force to generate branch as microMIPS R6 doesn't restrict
26045 * branches in the forbidden slot.
26051 gen_branch(ctx
, insn_bytes
);
26053 ctx
->base
.pc_next
+= insn_bytes
;
26055 if (ctx
->base
.is_jmp
!= DISAS_NEXT
) {
26059 * Execute a branch and its delay slot as a single instruction.
26060 * This is what GDB expects and is consistent with what the
26061 * hardware does (e.g. if a delay slot instruction faults, the
26062 * reported PC is the PC of the branch).
26064 if (ctx
->base
.singlestep_enabled
&&
26065 (ctx
->hflags
& MIPS_HFLAG_BMASK
) == 0) {
26066 ctx
->base
.is_jmp
= DISAS_TOO_MANY
;
26068 if (ctx
->base
.pc_next
- ctx
->page_start
>= TARGET_PAGE_SIZE
) {
26069 ctx
->base
.is_jmp
= DISAS_TOO_MANY
;
26073 static void mips_tr_tb_stop(DisasContextBase
*dcbase
, CPUState
*cs
)
26075 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
26077 if (ctx
->base
.singlestep_enabled
&& ctx
->base
.is_jmp
!= DISAS_NORETURN
) {
26078 save_cpu_state(ctx
, ctx
->base
.is_jmp
!= DISAS_EXIT
);
26079 gen_helper_raise_exception_debug(cpu_env
);
26081 switch (ctx
->base
.is_jmp
) {
26083 gen_save_pc(ctx
->base
.pc_next
);
26084 tcg_gen_lookup_and_goto_ptr();
26087 case DISAS_TOO_MANY
:
26088 save_cpu_state(ctx
, 0);
26089 gen_goto_tb(ctx
, 0, ctx
->base
.pc_next
);
26092 tcg_gen_exit_tb(NULL
, 0);
26094 case DISAS_NORETURN
:
26097 g_assert_not_reached();
26102 static void mips_tr_disas_log(const DisasContextBase
*dcbase
, CPUState
*cs
)
26104 qemu_log("IN: %s\n", lookup_symbol(dcbase
->pc_first
));
26105 log_target_disas(cs
, dcbase
->pc_first
, dcbase
->tb
->size
);
26108 static const TranslatorOps mips_tr_ops
= {
26109 .init_disas_context
= mips_tr_init_disas_context
,
26110 .tb_start
= mips_tr_tb_start
,
26111 .insn_start
= mips_tr_insn_start
,
26112 .breakpoint_check
= mips_tr_breakpoint_check
,
26113 .translate_insn
= mips_tr_translate_insn
,
26114 .tb_stop
= mips_tr_tb_stop
,
26115 .disas_log
= mips_tr_disas_log
,
26118 void gen_intermediate_code(CPUState
*cs
, TranslationBlock
*tb
, int max_insns
)
26122 translator_loop(&mips_tr_ops
, &ctx
.base
, cs
, tb
, max_insns
);
26125 static void fpu_dump_state(CPUMIPSState
*env
, FILE * f
, int flags
)
26128 int is_fpu64
= !!(env
->hflags
& MIPS_HFLAG_F64
);
26130 #define printfpr(fp) \
26133 qemu_fprintf(f, "w:%08x d:%016" PRIx64 \
26134 " fd:%13g fs:%13g psu: %13g\n", \
26135 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
26136 (double)(fp)->fd, \
26137 (double)(fp)->fs[FP_ENDIAN_IDX], \
26138 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
26141 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
26142 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
26143 qemu_fprintf(f, "w:%08x d:%016" PRIx64 \
26144 " fd:%13g fs:%13g psu:%13g\n", \
26145 tmp.w[FP_ENDIAN_IDX], tmp.d, \
26147 (double)tmp.fs[FP_ENDIAN_IDX], \
26148 (double)tmp.fs[!FP_ENDIAN_IDX]); \
26154 "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
26155 env
->active_fpu
.fcr0
, env
->active_fpu
.fcr31
, is_fpu64
,
26156 get_float_exception_flags(&env
->active_fpu
.fp_status
));
26157 for (i
= 0; i
< 32; (is_fpu64
) ? i
++ : (i
+= 2)) {
26158 qemu_fprintf(f
, "%3s: ", fregnames
[i
]);
26159 printfpr(&env
->active_fpu
.fpr
[i
]);
26165 void mips_cpu_dump_state(CPUState
*cs
, FILE *f
, int flags
)
26167 MIPSCPU
*cpu
= MIPS_CPU(cs
);
26168 CPUMIPSState
*env
= &cpu
->env
;
26171 qemu_fprintf(f
, "pc=0x" TARGET_FMT_lx
" HI=0x" TARGET_FMT_lx
26172 " LO=0x" TARGET_FMT_lx
" ds %04x "
26173 TARGET_FMT_lx
" " TARGET_FMT_ld
"\n",
26174 env
->active_tc
.PC
, env
->active_tc
.HI
[0], env
->active_tc
.LO
[0],
26175 env
->hflags
, env
->btarget
, env
->bcond
);
26176 for (i
= 0; i
< 32; i
++) {
26177 if ((i
& 3) == 0) {
26178 qemu_fprintf(f
, "GPR%02d:", i
);
26180 qemu_fprintf(f
, " %s " TARGET_FMT_lx
,
26181 regnames
[i
], env
->active_tc
.gpr
[i
]);
26182 if ((i
& 3) == 3) {
26183 qemu_fprintf(f
, "\n");
26187 qemu_fprintf(f
, "CP0 Status 0x%08x Cause 0x%08x EPC 0x"
26188 TARGET_FMT_lx
"\n",
26189 env
->CP0_Status
, env
->CP0_Cause
, env
->CP0_EPC
);
26190 qemu_fprintf(f
, " Config0 0x%08x Config1 0x%08x LLAddr 0x%016"
26192 env
->CP0_Config0
, env
->CP0_Config1
, env
->CP0_LLAddr
);
26193 qemu_fprintf(f
, " Config2 0x%08x Config3 0x%08x\n",
26194 env
->CP0_Config2
, env
->CP0_Config3
);
26195 qemu_fprintf(f
, " Config4 0x%08x Config5 0x%08x\n",
26196 env
->CP0_Config4
, env
->CP0_Config5
);
26197 if ((flags
& CPU_DUMP_FPU
) && (env
->hflags
& MIPS_HFLAG_FPU
)) {
26198 fpu_dump_state(env
, f
, flags
);
26202 void mips_tcg_init(void)
26207 for (i
= 1; i
< 32; i
++)
26208 cpu_gpr
[i
] = tcg_global_mem_new(cpu_env
,
26209 offsetof(CPUMIPSState
,
26212 #if defined(TARGET_MIPS64)
26213 cpu_gpr_hi
[0] = NULL
;
26215 for (unsigned i
= 1; i
< 32; i
++) {
26216 g_autofree
char *rname
= g_strdup_printf("%s[hi]", regnames
[i
]);
26218 cpu_gpr_hi
[i
] = tcg_global_mem_new_i64(cpu_env
,
26219 offsetof(CPUMIPSState
,
26220 active_tc
.gpr_hi
[i
]),
26223 #endif /* !TARGET_MIPS64 */
26224 for (i
= 0; i
< 32; i
++) {
26225 int off
= offsetof(CPUMIPSState
, active_fpu
.fpr
[i
].wr
.d
[0]);
26227 fpu_f64
[i
] = tcg_global_mem_new_i64(cpu_env
, off
, fregnames
[i
]);
26229 msa_translate_init();
26230 cpu_PC
= tcg_global_mem_new(cpu_env
,
26231 offsetof(CPUMIPSState
, active_tc
.PC
), "PC");
26232 for (i
= 0; i
< MIPS_DSP_ACC
; i
++) {
26233 cpu_HI
[i
] = tcg_global_mem_new(cpu_env
,
26234 offsetof(CPUMIPSState
, active_tc
.HI
[i
]),
26236 cpu_LO
[i
] = tcg_global_mem_new(cpu_env
,
26237 offsetof(CPUMIPSState
, active_tc
.LO
[i
]),
26240 cpu_dspctrl
= tcg_global_mem_new(cpu_env
,
26241 offsetof(CPUMIPSState
,
26242 active_tc
.DSPControl
),
26244 bcond
= tcg_global_mem_new(cpu_env
,
26245 offsetof(CPUMIPSState
, bcond
), "bcond");
26246 btarget
= tcg_global_mem_new(cpu_env
,
26247 offsetof(CPUMIPSState
, btarget
), "btarget");
26248 hflags
= tcg_global_mem_new_i32(cpu_env
,
26249 offsetof(CPUMIPSState
, hflags
), "hflags");
26251 fpu_fcr0
= tcg_global_mem_new_i32(cpu_env
,
26252 offsetof(CPUMIPSState
, active_fpu
.fcr0
),
26254 fpu_fcr31
= tcg_global_mem_new_i32(cpu_env
,
26255 offsetof(CPUMIPSState
, active_fpu
.fcr31
),
26257 cpu_lladdr
= tcg_global_mem_new(cpu_env
, offsetof(CPUMIPSState
, lladdr
),
26259 cpu_llval
= tcg_global_mem_new(cpu_env
, offsetof(CPUMIPSState
, llval
),
26262 if (TARGET_LONG_BITS
== 32) {
26263 mxu_translate_init();
26267 void restore_state_to_opc(CPUMIPSState
*env
, TranslationBlock
*tb
,
26268 target_ulong
*data
)
26270 env
->active_tc
.PC
= data
[0];
26271 env
->hflags
&= ~MIPS_HFLAG_BMASK
;
26272 env
->hflags
|= data
[1];
26273 switch (env
->hflags
& MIPS_HFLAG_BMASK_BASE
) {
26274 case MIPS_HFLAG_BR
:
26276 case MIPS_HFLAG_BC
:
26277 case MIPS_HFLAG_BL
:
26279 env
->btarget
= data
[2];