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 * MMI (MultiMedia Instruction) encodings
1134 * ======================================
1136 * MMI instructions encoding table keys:
1138 * * This code is reserved for future use. An attempt to execute it
1139 * causes a Reserved Instruction exception.
1140 * % This code indicates an instruction class. The instruction word
1141 * must be further decoded by examining additional tables that show
1142 * the values for other instruction fields.
1143 * # This code is reserved for the unsupported instructions DMULT,
1144 * DMULTU, DDIV, DDIVU, LL, LLD, SC, SCD, LWC2 and SWC2. An attempt
1145 * to execute it causes a Reserved Instruction exception.
1147 * MMI instructions encoded by opcode field (MMI, LQ, SQ):
1150 * +--------+----------------------------------------+
1152 * +--------+----------------------------------------+
1154 * opcode bits 28..26
1155 * bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
1156 * 31..29 | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111
1157 * -------+-------+-------+-------+-------+-------+-------+-------+-------
1158 * 0 000 |SPECIAL| REGIMM| J | JAL | BEQ | BNE | BLEZ | BGTZ
1159 * 1 001 | ADDI | ADDIU | SLTI | SLTIU | ANDI | ORI | XORI | LUI
1160 * 2 010 | COP0 | COP1 | * | * | BEQL | BNEL | BLEZL | BGTZL
1161 * 3 011 | DADDI | DADDIU| LDL | LDR | MMI% | * | LQ | SQ
1162 * 4 100 | LB | LH | LWL | LW | LBU | LHU | LWR | LWU
1163 * 5 101 | SB | SH | SWL | SW | SDL | SDR | SWR | CACHE
1164 * 6 110 | # | LWC1 | # | PREF | # | LDC1 | # | LD
1165 * 7 111 | # | SWC1 | # | * | # | SDC1 | # | SD
1169 MMI_OPC_CLASS_MMI
= 0x1C << 26, /* Same as OPC_SPECIAL2 */
1170 MMI_OPC_LQ
= 0x1E << 26, /* Same as OPC_MSA */
1171 MMI_OPC_SQ
= 0x1F << 26, /* Same as OPC_SPECIAL3 */
1175 * MMI instructions with opcode field = MMI:
1178 * +--------+-------------------------------+--------+
1179 * | MMI | |function|
1180 * +--------+-------------------------------+--------+
1182 * function bits 2..0
1183 * bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
1184 * 5..3 | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111
1185 * -------+-------+-------+-------+-------+-------+-------+-------+-------
1186 * 0 000 | MADD | MADDU | * | * | PLZCW | * | * | *
1187 * 1 001 | MMI0% | MMI2% | * | * | * | * | * | *
1188 * 2 010 | MFHI1 | MTHI1 | MFLO1 | MTLO1 | * | * | * | *
1189 * 3 011 | MULT1 | MULTU1| DIV1 | DIVU1 | * | * | * | *
1190 * 4 100 | MADD1 | MADDU1| * | * | * | * | * | *
1191 * 5 101 | MMI1% | MMI3% | * | * | * | * | * | *
1192 * 6 110 | PMFHL | PMTHL | * | * | PSLLH | * | PSRLH | PSRAH
1193 * 7 111 | * | * | * | * | PSLLW | * | PSRLW | PSRAW
1196 #define MASK_MMI(op) (MASK_OP_MAJOR(op) | ((op) & 0x3F))
1198 MMI_OPC_MADD
= 0x00 | MMI_OPC_CLASS_MMI
, /* Same as OPC_MADD */
1199 MMI_OPC_MADDU
= 0x01 | MMI_OPC_CLASS_MMI
, /* Same as OPC_MADDU */
1200 MMI_OPC_MULT1
= 0x18 | MMI_OPC_CLASS_MMI
, /* Same minor as OPC_MULT */
1201 MMI_OPC_MULTU1
= 0x19 | MMI_OPC_CLASS_MMI
, /* Same min. as OPC_MULTU */
1202 MMI_OPC_DIV1
= 0x1A | MMI_OPC_CLASS_MMI
, /* Same minor as OPC_DIV */
1203 MMI_OPC_DIVU1
= 0x1B | MMI_OPC_CLASS_MMI
, /* Same minor as OPC_DIVU */
1204 MMI_OPC_MADD1
= 0x20 | MMI_OPC_CLASS_MMI
,
1205 MMI_OPC_MADDU1
= 0x21 | MMI_OPC_CLASS_MMI
,
1208 /* global register indices */
1209 TCGv cpu_gpr
[32], cpu_PC
;
1211 * For CPUs using 128-bit GPR registers, we put the lower halves in cpu_gpr[])
1212 * and the upper halves in cpu_gpr_hi[].
1214 TCGv_i64 cpu_gpr_hi
[32];
1215 TCGv cpu_HI
[MIPS_DSP_ACC
], cpu_LO
[MIPS_DSP_ACC
];
1216 static TCGv cpu_dspctrl
, btarget
;
1218 static TCGv cpu_lladdr
, cpu_llval
;
1219 static TCGv_i32 hflags
;
1220 TCGv_i32 fpu_fcr0
, fpu_fcr31
;
1221 TCGv_i64 fpu_f64
[32];
1223 #include "exec/gen-icount.h"
1225 #define gen_helper_0e0i(name, arg) do { \
1226 TCGv_i32 helper_tmp = tcg_const_i32(arg); \
1227 gen_helper_##name(cpu_env, helper_tmp); \
1228 tcg_temp_free_i32(helper_tmp); \
1231 #define gen_helper_0e1i(name, arg1, arg2) do { \
1232 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1233 gen_helper_##name(cpu_env, arg1, helper_tmp); \
1234 tcg_temp_free_i32(helper_tmp); \
1237 #define gen_helper_1e0i(name, ret, arg1) do { \
1238 TCGv_i32 helper_tmp = tcg_const_i32(arg1); \
1239 gen_helper_##name(ret, cpu_env, helper_tmp); \
1240 tcg_temp_free_i32(helper_tmp); \
1243 #define gen_helper_1e1i(name, ret, arg1, arg2) do { \
1244 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1245 gen_helper_##name(ret, cpu_env, arg1, helper_tmp); \
1246 tcg_temp_free_i32(helper_tmp); \
1249 #define gen_helper_0e2i(name, arg1, arg2, arg3) do { \
1250 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1251 gen_helper_##name(cpu_env, arg1, arg2, helper_tmp); \
1252 tcg_temp_free_i32(helper_tmp); \
1255 #define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do { \
1256 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1257 gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp); \
1258 tcg_temp_free_i32(helper_tmp); \
1261 #define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do { \
1262 TCGv_i32 helper_tmp = tcg_const_i32(arg4); \
1263 gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp); \
1264 tcg_temp_free_i32(helper_tmp); \
1267 #define DISAS_STOP DISAS_TARGET_0
1268 #define DISAS_EXIT DISAS_TARGET_1
1270 static const char * const regnames
[] = {
1271 "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
1272 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
1273 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
1274 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
1277 static const char * const regnames_HI
[] = {
1278 "HI0", "HI1", "HI2", "HI3",
1281 static const char * const regnames_LO
[] = {
1282 "LO0", "LO1", "LO2", "LO3",
1285 static const char * const fregnames
[] = {
1286 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
1287 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
1288 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
1289 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
1292 /* General purpose registers moves. */
1293 void gen_load_gpr(TCGv t
, int reg
)
1296 tcg_gen_movi_tl(t
, 0);
1298 tcg_gen_mov_tl(t
, cpu_gpr
[reg
]);
1302 void gen_store_gpr(TCGv t
, int reg
)
1305 tcg_gen_mov_tl(cpu_gpr
[reg
], t
);
1309 #if defined(TARGET_MIPS64)
1310 void gen_load_gpr_hi(TCGv_i64 t
, int reg
)
1313 tcg_gen_movi_i64(t
, 0);
1315 tcg_gen_mov_i64(t
, cpu_gpr_hi
[reg
]);
1319 void gen_store_gpr_hi(TCGv_i64 t
, int reg
)
1322 tcg_gen_mov_i64(cpu_gpr_hi
[reg
], t
);
1325 #endif /* TARGET_MIPS64 */
1327 /* Moves to/from shadow registers. */
1328 static inline void gen_load_srsgpr(int from
, int to
)
1330 TCGv t0
= tcg_temp_new();
1333 tcg_gen_movi_tl(t0
, 0);
1335 TCGv_i32 t2
= tcg_temp_new_i32();
1336 TCGv_ptr addr
= tcg_temp_new_ptr();
1338 tcg_gen_ld_i32(t2
, cpu_env
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
1339 tcg_gen_shri_i32(t2
, t2
, CP0SRSCtl_PSS
);
1340 tcg_gen_andi_i32(t2
, t2
, 0xf);
1341 tcg_gen_muli_i32(t2
, t2
, sizeof(target_ulong
) * 32);
1342 tcg_gen_ext_i32_ptr(addr
, t2
);
1343 tcg_gen_add_ptr(addr
, cpu_env
, addr
);
1345 tcg_gen_ld_tl(t0
, addr
, sizeof(target_ulong
) * from
);
1346 tcg_temp_free_ptr(addr
);
1347 tcg_temp_free_i32(t2
);
1349 gen_store_gpr(t0
, to
);
1353 static inline void gen_store_srsgpr(int from
, int to
)
1356 TCGv t0
= tcg_temp_new();
1357 TCGv_i32 t2
= tcg_temp_new_i32();
1358 TCGv_ptr addr
= tcg_temp_new_ptr();
1360 gen_load_gpr(t0
, from
);
1361 tcg_gen_ld_i32(t2
, cpu_env
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
1362 tcg_gen_shri_i32(t2
, t2
, CP0SRSCtl_PSS
);
1363 tcg_gen_andi_i32(t2
, t2
, 0xf);
1364 tcg_gen_muli_i32(t2
, t2
, sizeof(target_ulong
) * 32);
1365 tcg_gen_ext_i32_ptr(addr
, t2
);
1366 tcg_gen_add_ptr(addr
, cpu_env
, addr
);
1368 tcg_gen_st_tl(t0
, addr
, sizeof(target_ulong
) * to
);
1369 tcg_temp_free_ptr(addr
);
1370 tcg_temp_free_i32(t2
);
1376 static inline void gen_save_pc(target_ulong pc
)
1378 tcg_gen_movi_tl(cpu_PC
, pc
);
1381 static inline void save_cpu_state(DisasContext
*ctx
, int do_save_pc
)
1383 LOG_DISAS("hflags %08x saved %08x\n", ctx
->hflags
, ctx
->saved_hflags
);
1384 if (do_save_pc
&& ctx
->base
.pc_next
!= ctx
->saved_pc
) {
1385 gen_save_pc(ctx
->base
.pc_next
);
1386 ctx
->saved_pc
= ctx
->base
.pc_next
;
1388 if (ctx
->hflags
!= ctx
->saved_hflags
) {
1389 tcg_gen_movi_i32(hflags
, ctx
->hflags
);
1390 ctx
->saved_hflags
= ctx
->hflags
;
1391 switch (ctx
->hflags
& MIPS_HFLAG_BMASK_BASE
) {
1397 tcg_gen_movi_tl(btarget
, ctx
->btarget
);
1403 static inline void restore_cpu_state(CPUMIPSState
*env
, DisasContext
*ctx
)
1405 ctx
->saved_hflags
= ctx
->hflags
;
1406 switch (ctx
->hflags
& MIPS_HFLAG_BMASK_BASE
) {
1412 ctx
->btarget
= env
->btarget
;
1417 void generate_exception_err(DisasContext
*ctx
, int excp
, int err
)
1419 TCGv_i32 texcp
= tcg_const_i32(excp
);
1420 TCGv_i32 terr
= tcg_const_i32(err
);
1421 save_cpu_state(ctx
, 1);
1422 gen_helper_raise_exception_err(cpu_env
, texcp
, terr
);
1423 tcg_temp_free_i32(terr
);
1424 tcg_temp_free_i32(texcp
);
1425 ctx
->base
.is_jmp
= DISAS_NORETURN
;
1428 void generate_exception(DisasContext
*ctx
, int excp
)
1430 gen_helper_0e0i(raise_exception
, excp
);
1433 void generate_exception_end(DisasContext
*ctx
, int excp
)
1435 generate_exception_err(ctx
, excp
, 0);
1438 void gen_reserved_instruction(DisasContext
*ctx
)
1440 generate_exception_end(ctx
, EXCP_RI
);
1443 /* Floating point register moves. */
1444 void gen_load_fpr32(DisasContext
*ctx
, TCGv_i32 t
, int reg
)
1446 if (ctx
->hflags
& MIPS_HFLAG_FRE
) {
1447 generate_exception(ctx
, EXCP_RI
);
1449 tcg_gen_extrl_i64_i32(t
, fpu_f64
[reg
]);
1452 void gen_store_fpr32(DisasContext
*ctx
, TCGv_i32 t
, int reg
)
1455 if (ctx
->hflags
& MIPS_HFLAG_FRE
) {
1456 generate_exception(ctx
, EXCP_RI
);
1458 t64
= tcg_temp_new_i64();
1459 tcg_gen_extu_i32_i64(t64
, t
);
1460 tcg_gen_deposit_i64(fpu_f64
[reg
], fpu_f64
[reg
], t64
, 0, 32);
1461 tcg_temp_free_i64(t64
);
1464 static void gen_load_fpr32h(DisasContext
*ctx
, TCGv_i32 t
, int reg
)
1466 if (ctx
->hflags
& MIPS_HFLAG_F64
) {
1467 tcg_gen_extrh_i64_i32(t
, fpu_f64
[reg
]);
1469 gen_load_fpr32(ctx
, t
, reg
| 1);
1473 static void gen_store_fpr32h(DisasContext
*ctx
, TCGv_i32 t
, int reg
)
1475 if (ctx
->hflags
& MIPS_HFLAG_F64
) {
1476 TCGv_i64 t64
= tcg_temp_new_i64();
1477 tcg_gen_extu_i32_i64(t64
, t
);
1478 tcg_gen_deposit_i64(fpu_f64
[reg
], fpu_f64
[reg
], t64
, 32, 32);
1479 tcg_temp_free_i64(t64
);
1481 gen_store_fpr32(ctx
, t
, reg
| 1);
1485 void gen_load_fpr64(DisasContext
*ctx
, TCGv_i64 t
, int reg
)
1487 if (ctx
->hflags
& MIPS_HFLAG_F64
) {
1488 tcg_gen_mov_i64(t
, fpu_f64
[reg
]);
1490 tcg_gen_concat32_i64(t
, fpu_f64
[reg
& ~1], fpu_f64
[reg
| 1]);
1494 void gen_store_fpr64(DisasContext
*ctx
, TCGv_i64 t
, int reg
)
1496 if (ctx
->hflags
& MIPS_HFLAG_F64
) {
1497 tcg_gen_mov_i64(fpu_f64
[reg
], t
);
1500 tcg_gen_deposit_i64(fpu_f64
[reg
& ~1], fpu_f64
[reg
& ~1], t
, 0, 32);
1501 t0
= tcg_temp_new_i64();
1502 tcg_gen_shri_i64(t0
, t
, 32);
1503 tcg_gen_deposit_i64(fpu_f64
[reg
| 1], fpu_f64
[reg
| 1], t0
, 0, 32);
1504 tcg_temp_free_i64(t0
);
1508 int get_fp_bit(int cc
)
1517 /* Addresses computation */
1518 void gen_op_addr_add(DisasContext
*ctx
, TCGv ret
, TCGv arg0
, TCGv arg1
)
1520 tcg_gen_add_tl(ret
, arg0
, arg1
);
1522 #if defined(TARGET_MIPS64)
1523 if (ctx
->hflags
& MIPS_HFLAG_AWRAP
) {
1524 tcg_gen_ext32s_i64(ret
, ret
);
1529 static inline void gen_op_addr_addi(DisasContext
*ctx
, TCGv ret
, TCGv base
,
1532 tcg_gen_addi_tl(ret
, base
, ofs
);
1534 #if defined(TARGET_MIPS64)
1535 if (ctx
->hflags
& MIPS_HFLAG_AWRAP
) {
1536 tcg_gen_ext32s_i64(ret
, ret
);
1541 /* Addresses computation (translation time) */
1542 static target_long
addr_add(DisasContext
*ctx
, target_long base
,
1545 target_long sum
= base
+ offset
;
1547 #if defined(TARGET_MIPS64)
1548 if (ctx
->hflags
& MIPS_HFLAG_AWRAP
) {
1555 /* Sign-extract the low 32-bits to a target_long. */
1556 void gen_move_low32(TCGv ret
, TCGv_i64 arg
)
1558 #if defined(TARGET_MIPS64)
1559 tcg_gen_ext32s_i64(ret
, arg
);
1561 tcg_gen_extrl_i64_i32(ret
, arg
);
1565 /* Sign-extract the high 32-bits to a target_long. */
1566 void gen_move_high32(TCGv ret
, TCGv_i64 arg
)
1568 #if defined(TARGET_MIPS64)
1569 tcg_gen_sari_i64(ret
, arg
, 32);
1571 tcg_gen_extrh_i64_i32(ret
, arg
);
1575 bool check_cp0_enabled(DisasContext
*ctx
)
1577 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_CP0
))) {
1578 generate_exception_end(ctx
, EXCP_CpU
);
1584 void check_cp1_enabled(DisasContext
*ctx
)
1586 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_FPU
))) {
1587 generate_exception_err(ctx
, EXCP_CpU
, 1);
1592 * Verify that the processor is running with COP1X instructions enabled.
1593 * This is associated with the nabla symbol in the MIPS32 and MIPS64
1596 void check_cop1x(DisasContext
*ctx
)
1598 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_COP1X
))) {
1599 gen_reserved_instruction(ctx
);
1604 * Verify that the processor is running with 64-bit floating-point
1605 * operations enabled.
1607 void check_cp1_64bitmode(DisasContext
*ctx
)
1609 if (unlikely(~ctx
->hflags
& (MIPS_HFLAG_F64
| MIPS_HFLAG_COP1X
))) {
1610 gen_reserved_instruction(ctx
);
1615 * Verify if floating point register is valid; an operation is not defined
1616 * if bit 0 of any register specification is set and the FR bit in the
1617 * Status register equals zero, since the register numbers specify an
1618 * even-odd pair of adjacent coprocessor general registers. When the FR bit
1619 * in the Status register equals one, both even and odd register numbers
1620 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
1622 * Multiple 64 bit wide registers can be checked by calling
1623 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
1625 void check_cp1_registers(DisasContext
*ctx
, int regs
)
1627 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_F64
) && (regs
& 1))) {
1628 gen_reserved_instruction(ctx
);
1633 * Verify that the processor is running with DSP instructions enabled.
1634 * This is enabled by CP0 Status register MX(24) bit.
1636 static inline void check_dsp(DisasContext
*ctx
)
1638 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_DSP
))) {
1639 if (ctx
->insn_flags
& ASE_DSP
) {
1640 generate_exception_end(ctx
, EXCP_DSPDIS
);
1642 gen_reserved_instruction(ctx
);
1647 static inline void check_dsp_r2(DisasContext
*ctx
)
1649 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_DSP_R2
))) {
1650 if (ctx
->insn_flags
& ASE_DSP
) {
1651 generate_exception_end(ctx
, EXCP_DSPDIS
);
1653 gen_reserved_instruction(ctx
);
1658 static inline void check_dsp_r3(DisasContext
*ctx
)
1660 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_DSP_R3
))) {
1661 if (ctx
->insn_flags
& ASE_DSP
) {
1662 generate_exception_end(ctx
, EXCP_DSPDIS
);
1664 gen_reserved_instruction(ctx
);
1670 * This code generates a "reserved instruction" exception if the
1671 * CPU does not support the instruction set corresponding to flags.
1673 void check_insn(DisasContext
*ctx
, uint64_t flags
)
1675 if (unlikely(!(ctx
->insn_flags
& flags
))) {
1676 gen_reserved_instruction(ctx
);
1681 * This code generates a "reserved instruction" exception if the
1682 * CPU has corresponding flag set which indicates that the instruction
1685 static inline void check_insn_opc_removed(DisasContext
*ctx
, uint64_t flags
)
1687 if (unlikely(ctx
->insn_flags
& flags
)) {
1688 gen_reserved_instruction(ctx
);
1693 * The Linux kernel traps certain reserved instruction exceptions to
1694 * emulate the corresponding instructions. QEMU is the kernel in user
1695 * mode, so those traps are emulated by accepting the instructions.
1697 * A reserved instruction exception is generated for flagged CPUs if
1698 * QEMU runs in system mode.
1700 static inline void check_insn_opc_user_only(DisasContext
*ctx
, uint64_t flags
)
1702 #ifndef CONFIG_USER_ONLY
1703 check_insn_opc_removed(ctx
, flags
);
1708 * This code generates a "reserved instruction" exception if the
1709 * CPU does not support 64-bit paired-single (PS) floating point data type.
1711 static inline void check_ps(DisasContext
*ctx
)
1713 if (unlikely(!ctx
->ps
)) {
1714 generate_exception(ctx
, EXCP_RI
);
1716 check_cp1_64bitmode(ctx
);
1720 * This code generates a "reserved instruction" exception if cpu is not
1721 * 64-bit or 64-bit instructions are not enabled.
1723 void check_mips_64(DisasContext
*ctx
)
1725 if (unlikely((TARGET_LONG_BITS
!= 64) || !(ctx
->hflags
& MIPS_HFLAG_64
))) {
1726 gen_reserved_instruction(ctx
);
1730 #ifndef CONFIG_USER_ONLY
1731 static inline void check_mvh(DisasContext
*ctx
)
1733 if (unlikely(!ctx
->mvh
)) {
1734 generate_exception(ctx
, EXCP_RI
);
1740 * This code generates a "reserved instruction" exception if the
1741 * Config5 XNP bit is set.
1743 static inline void check_xnp(DisasContext
*ctx
)
1745 if (unlikely(ctx
->CP0_Config5
& (1 << CP0C5_XNP
))) {
1746 gen_reserved_instruction(ctx
);
1750 #ifndef CONFIG_USER_ONLY
1752 * This code generates a "reserved instruction" exception if the
1753 * Config3 PW bit is NOT set.
1755 static inline void check_pw(DisasContext
*ctx
)
1757 if (unlikely(!(ctx
->CP0_Config3
& (1 << CP0C3_PW
)))) {
1758 gen_reserved_instruction(ctx
);
1764 * This code generates a "reserved instruction" exception if the
1765 * Config3 MT bit is NOT set.
1767 static inline void check_mt(DisasContext
*ctx
)
1769 if (unlikely(!(ctx
->CP0_Config3
& (1 << CP0C3_MT
)))) {
1770 gen_reserved_instruction(ctx
);
1774 #ifndef CONFIG_USER_ONLY
1776 * This code generates a "coprocessor unusable" exception if CP0 is not
1777 * available, and, if that is not the case, generates a "reserved instruction"
1778 * exception if the Config5 MT bit is NOT set. This is needed for availability
1779 * control of some of MT ASE instructions.
1781 static inline void check_cp0_mt(DisasContext
*ctx
)
1783 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_CP0
))) {
1784 generate_exception_end(ctx
, EXCP_CpU
);
1786 if (unlikely(!(ctx
->CP0_Config3
& (1 << CP0C3_MT
)))) {
1787 gen_reserved_instruction(ctx
);
1794 * This code generates a "reserved instruction" exception if the
1795 * Config5 NMS bit is set.
1797 static inline void check_nms(DisasContext
*ctx
)
1799 if (unlikely(ctx
->CP0_Config5
& (1 << CP0C5_NMS
))) {
1800 gen_reserved_instruction(ctx
);
1805 * This code generates a "reserved instruction" exception if the
1806 * Config5 NMS bit is set, and Config1 DL, Config1 IL, Config2 SL,
1807 * Config2 TL, and Config5 L2C are unset.
1809 static inline void check_nms_dl_il_sl_tl_l2c(DisasContext
*ctx
)
1811 if (unlikely((ctx
->CP0_Config5
& (1 << CP0C5_NMS
)) &&
1812 !(ctx
->CP0_Config1
& (1 << CP0C1_DL
)) &&
1813 !(ctx
->CP0_Config1
& (1 << CP0C1_IL
)) &&
1814 !(ctx
->CP0_Config2
& (1 << CP0C2_SL
)) &&
1815 !(ctx
->CP0_Config2
& (1 << CP0C2_TL
)) &&
1816 !(ctx
->CP0_Config5
& (1 << CP0C5_L2C
)))) {
1817 gen_reserved_instruction(ctx
);
1822 * This code generates a "reserved instruction" exception if the
1823 * Config5 EVA bit is NOT set.
1825 static inline void check_eva(DisasContext
*ctx
)
1827 if (unlikely(!(ctx
->CP0_Config5
& (1 << CP0C5_EVA
)))) {
1828 gen_reserved_instruction(ctx
);
1834 * Define small wrappers for gen_load_fpr* so that we have a uniform
1835 * calling interface for 32 and 64-bit FPRs. No sense in changing
1836 * all callers for gen_load_fpr32 when we need the CTX parameter for
1839 #define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(ctx, x, y)
1840 #define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
1841 #define FOP_CONDS(type, abs, fmt, ifmt, bits) \
1842 static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
1843 int ft, int fs, int cc) \
1845 TCGv_i##bits fp0 = tcg_temp_new_i##bits(); \
1846 TCGv_i##bits fp1 = tcg_temp_new_i##bits(); \
1855 check_cp1_registers(ctx, fs | ft); \
1863 gen_ldcmp_fpr##bits(ctx, fp0, fs); \
1864 gen_ldcmp_fpr##bits(ctx, fp1, ft); \
1867 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); \
1870 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); \
1873 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); \
1876 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); \
1879 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); \
1882 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); \
1885 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); \
1888 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); \
1891 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); \
1894 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); \
1897 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); \
1900 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); \
1903 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); \
1906 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); \
1909 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); \
1912 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); \
1917 tcg_temp_free_i##bits(fp0); \
1918 tcg_temp_free_i##bits(fp1); \
1921 FOP_CONDS(, 0, d
, FMT_D
, 64)
1922 FOP_CONDS(abs
, 1, d
, FMT_D
, 64)
1923 FOP_CONDS(, 0, s
, FMT_S
, 32)
1924 FOP_CONDS(abs
, 1, s
, FMT_S
, 32)
1925 FOP_CONDS(, 0, ps
, FMT_PS
, 64)
1926 FOP_CONDS(abs
, 1, ps
, FMT_PS
, 64)
1929 #define FOP_CONDNS(fmt, ifmt, bits, STORE) \
1930 static inline void gen_r6_cmp_ ## fmt(DisasContext *ctx, int n, \
1931 int ft, int fs, int fd) \
1933 TCGv_i ## bits fp0 = tcg_temp_new_i ## bits(); \
1934 TCGv_i ## bits fp1 = tcg_temp_new_i ## bits(); \
1935 if (ifmt == FMT_D) { \
1936 check_cp1_registers(ctx, fs | ft | fd); \
1938 gen_ldcmp_fpr ## bits(ctx, fp0, fs); \
1939 gen_ldcmp_fpr ## bits(ctx, fp1, ft); \
1942 gen_helper_r6_cmp_ ## fmt ## _af(fp0, cpu_env, fp0, fp1); \
1945 gen_helper_r6_cmp_ ## fmt ## _un(fp0, cpu_env, fp0, fp1); \
1948 gen_helper_r6_cmp_ ## fmt ## _eq(fp0, cpu_env, fp0, fp1); \
1951 gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, cpu_env, fp0, fp1); \
1954 gen_helper_r6_cmp_ ## fmt ## _lt(fp0, cpu_env, fp0, fp1); \
1957 gen_helper_r6_cmp_ ## fmt ## _ult(fp0, cpu_env, fp0, fp1); \
1960 gen_helper_r6_cmp_ ## fmt ## _le(fp0, cpu_env, fp0, fp1); \
1963 gen_helper_r6_cmp_ ## fmt ## _ule(fp0, cpu_env, fp0, fp1); \
1966 gen_helper_r6_cmp_ ## fmt ## _saf(fp0, cpu_env, fp0, fp1); \
1969 gen_helper_r6_cmp_ ## fmt ## _sun(fp0, cpu_env, fp0, fp1); \
1972 gen_helper_r6_cmp_ ## fmt ## _seq(fp0, cpu_env, fp0, fp1); \
1975 gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, cpu_env, fp0, fp1); \
1978 gen_helper_r6_cmp_ ## fmt ## _slt(fp0, cpu_env, fp0, fp1); \
1981 gen_helper_r6_cmp_ ## fmt ## _sult(fp0, cpu_env, fp0, fp1); \
1984 gen_helper_r6_cmp_ ## fmt ## _sle(fp0, cpu_env, fp0, fp1); \
1987 gen_helper_r6_cmp_ ## fmt ## _sule(fp0, cpu_env, fp0, fp1); \
1990 gen_helper_r6_cmp_ ## fmt ## _or(fp0, cpu_env, fp0, fp1); \
1993 gen_helper_r6_cmp_ ## fmt ## _une(fp0, cpu_env, fp0, fp1); \
1996 gen_helper_r6_cmp_ ## fmt ## _ne(fp0, cpu_env, fp0, fp1); \
1999 gen_helper_r6_cmp_ ## fmt ## _sor(fp0, cpu_env, fp0, fp1); \
2002 gen_helper_r6_cmp_ ## fmt ## _sune(fp0, cpu_env, fp0, fp1); \
2005 gen_helper_r6_cmp_ ## fmt ## _sne(fp0, cpu_env, fp0, fp1); \
2011 tcg_temp_free_i ## bits(fp0); \
2012 tcg_temp_free_i ## bits(fp1); \
2015 FOP_CONDNS(d
, FMT_D
, 64, gen_store_fpr64(ctx
, fp0
, fd
))
2016 FOP_CONDNS(s
, FMT_S
, 32, gen_store_fpr32(ctx
, fp0
, fd
))
2018 #undef gen_ldcmp_fpr32
2019 #undef gen_ldcmp_fpr64
2021 /* load/store instructions. */
2022 #ifdef CONFIG_USER_ONLY
2023 #define OP_LD_ATOMIC(insn, fname) \
2024 static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \
2025 DisasContext *ctx) \
2027 TCGv t0 = tcg_temp_new(); \
2028 tcg_gen_mov_tl(t0, arg1); \
2029 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
2030 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
2031 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
2032 tcg_temp_free(t0); \
2035 #define OP_LD_ATOMIC(insn, fname) \
2036 static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \
2037 DisasContext *ctx) \
2039 gen_helper_1e1i(insn, ret, arg1, mem_idx); \
2042 OP_LD_ATOMIC(ll
, ld32s
);
2043 #if defined(TARGET_MIPS64)
2044 OP_LD_ATOMIC(lld
, ld64
);
2048 void gen_base_offset_addr(DisasContext
*ctx
, TCGv addr
, int base
, int offset
)
2051 tcg_gen_movi_tl(addr
, offset
);
2052 } else if (offset
== 0) {
2053 gen_load_gpr(addr
, base
);
2055 tcg_gen_movi_tl(addr
, offset
);
2056 gen_op_addr_add(ctx
, addr
, cpu_gpr
[base
], addr
);
2060 static target_ulong
pc_relative_pc(DisasContext
*ctx
)
2062 target_ulong pc
= ctx
->base
.pc_next
;
2064 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
2065 int branch_bytes
= ctx
->hflags
& MIPS_HFLAG_BDS16
? 2 : 4;
2070 pc
&= ~(target_ulong
)3;
2075 static void gen_ld(DisasContext
*ctx
, uint32_t opc
,
2076 int rt
, int base
, int offset
)
2079 int mem_idx
= ctx
->mem_idx
;
2081 if (rt
== 0 && ctx
->insn_flags
& (INSN_LOONGSON2E
| INSN_LOONGSON2F
|
2084 * Loongson CPU uses a load to zero register for prefetch.
2085 * We emulate it as a NOP. On other CPU we must perform the
2086 * actual memory access.
2091 t0
= tcg_temp_new();
2092 gen_base_offset_addr(ctx
, t0
, base
, offset
);
2095 #if defined(TARGET_MIPS64)
2097 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEUL
|
2098 ctx
->default_tcg_memop_mask
);
2099 gen_store_gpr(t0
, rt
);
2102 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEQ
|
2103 ctx
->default_tcg_memop_mask
);
2104 gen_store_gpr(t0
, rt
);
2108 op_ld_lld(t0
, t0
, mem_idx
, ctx
);
2109 gen_store_gpr(t0
, rt
);
2112 t1
= tcg_temp_new();
2114 * Do a byte access to possibly trigger a page
2115 * fault with the unaligned address.
2117 tcg_gen_qemu_ld_tl(t1
, t0
, mem_idx
, MO_UB
);
2118 tcg_gen_andi_tl(t1
, t0
, 7);
2119 #ifndef TARGET_WORDS_BIGENDIAN
2120 tcg_gen_xori_tl(t1
, t1
, 7);
2122 tcg_gen_shli_tl(t1
, t1
, 3);
2123 tcg_gen_andi_tl(t0
, t0
, ~7);
2124 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEQ
);
2125 tcg_gen_shl_tl(t0
, t0
, t1
);
2126 t2
= tcg_const_tl(-1);
2127 tcg_gen_shl_tl(t2
, t2
, t1
);
2128 gen_load_gpr(t1
, rt
);
2129 tcg_gen_andc_tl(t1
, t1
, t2
);
2131 tcg_gen_or_tl(t0
, t0
, t1
);
2133 gen_store_gpr(t0
, rt
);
2136 t1
= tcg_temp_new();
2138 * Do a byte access to possibly trigger a page
2139 * fault with the unaligned address.
2141 tcg_gen_qemu_ld_tl(t1
, t0
, mem_idx
, MO_UB
);
2142 tcg_gen_andi_tl(t1
, t0
, 7);
2143 #ifdef TARGET_WORDS_BIGENDIAN
2144 tcg_gen_xori_tl(t1
, t1
, 7);
2146 tcg_gen_shli_tl(t1
, t1
, 3);
2147 tcg_gen_andi_tl(t0
, t0
, ~7);
2148 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEQ
);
2149 tcg_gen_shr_tl(t0
, t0
, t1
);
2150 tcg_gen_xori_tl(t1
, t1
, 63);
2151 t2
= tcg_const_tl(0xfffffffffffffffeull
);
2152 tcg_gen_shl_tl(t2
, t2
, t1
);
2153 gen_load_gpr(t1
, rt
);
2154 tcg_gen_and_tl(t1
, t1
, t2
);
2156 tcg_gen_or_tl(t0
, t0
, t1
);
2158 gen_store_gpr(t0
, rt
);
2161 t1
= tcg_const_tl(pc_relative_pc(ctx
));
2162 gen_op_addr_add(ctx
, t0
, t0
, t1
);
2164 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEQ
);
2165 gen_store_gpr(t0
, rt
);
2169 t1
= tcg_const_tl(pc_relative_pc(ctx
));
2170 gen_op_addr_add(ctx
, t0
, t0
, t1
);
2172 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TESL
);
2173 gen_store_gpr(t0
, rt
);
2176 mem_idx
= MIPS_HFLAG_UM
;
2179 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TESL
|
2180 ctx
->default_tcg_memop_mask
);
2181 gen_store_gpr(t0
, rt
);
2184 mem_idx
= MIPS_HFLAG_UM
;
2187 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TESW
|
2188 ctx
->default_tcg_memop_mask
);
2189 gen_store_gpr(t0
, rt
);
2192 mem_idx
= MIPS_HFLAG_UM
;
2195 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEUW
|
2196 ctx
->default_tcg_memop_mask
);
2197 gen_store_gpr(t0
, rt
);
2200 mem_idx
= MIPS_HFLAG_UM
;
2203 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_SB
);
2204 gen_store_gpr(t0
, rt
);
2207 mem_idx
= MIPS_HFLAG_UM
;
2210 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_UB
);
2211 gen_store_gpr(t0
, rt
);
2214 mem_idx
= MIPS_HFLAG_UM
;
2217 t1
= tcg_temp_new();
2219 * Do a byte access to possibly trigger a page
2220 * fault with the unaligned address.
2222 tcg_gen_qemu_ld_tl(t1
, t0
, mem_idx
, MO_UB
);
2223 tcg_gen_andi_tl(t1
, t0
, 3);
2224 #ifndef TARGET_WORDS_BIGENDIAN
2225 tcg_gen_xori_tl(t1
, t1
, 3);
2227 tcg_gen_shli_tl(t1
, t1
, 3);
2228 tcg_gen_andi_tl(t0
, t0
, ~3);
2229 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEUL
);
2230 tcg_gen_shl_tl(t0
, t0
, t1
);
2231 t2
= tcg_const_tl(-1);
2232 tcg_gen_shl_tl(t2
, t2
, t1
);
2233 gen_load_gpr(t1
, rt
);
2234 tcg_gen_andc_tl(t1
, t1
, t2
);
2236 tcg_gen_or_tl(t0
, t0
, t1
);
2238 tcg_gen_ext32s_tl(t0
, t0
);
2239 gen_store_gpr(t0
, rt
);
2242 mem_idx
= MIPS_HFLAG_UM
;
2245 t1
= tcg_temp_new();
2247 * Do a byte access to possibly trigger a page
2248 * fault with the unaligned address.
2250 tcg_gen_qemu_ld_tl(t1
, t0
, mem_idx
, MO_UB
);
2251 tcg_gen_andi_tl(t1
, t0
, 3);
2252 #ifdef TARGET_WORDS_BIGENDIAN
2253 tcg_gen_xori_tl(t1
, t1
, 3);
2255 tcg_gen_shli_tl(t1
, t1
, 3);
2256 tcg_gen_andi_tl(t0
, t0
, ~3);
2257 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEUL
);
2258 tcg_gen_shr_tl(t0
, t0
, t1
);
2259 tcg_gen_xori_tl(t1
, t1
, 31);
2260 t2
= tcg_const_tl(0xfffffffeull
);
2261 tcg_gen_shl_tl(t2
, t2
, t1
);
2262 gen_load_gpr(t1
, rt
);
2263 tcg_gen_and_tl(t1
, t1
, t2
);
2265 tcg_gen_or_tl(t0
, t0
, t1
);
2267 tcg_gen_ext32s_tl(t0
, t0
);
2268 gen_store_gpr(t0
, rt
);
2271 mem_idx
= MIPS_HFLAG_UM
;
2275 op_ld_ll(t0
, t0
, mem_idx
, ctx
);
2276 gen_store_gpr(t0
, rt
);
2282 static void gen_llwp(DisasContext
*ctx
, uint32_t base
, int16_t offset
,
2283 uint32_t reg1
, uint32_t reg2
)
2285 TCGv taddr
= tcg_temp_new();
2286 TCGv_i64 tval
= tcg_temp_new_i64();
2287 TCGv tmp1
= tcg_temp_new();
2288 TCGv tmp2
= tcg_temp_new();
2290 gen_base_offset_addr(ctx
, taddr
, base
, offset
);
2291 tcg_gen_qemu_ld64(tval
, taddr
, ctx
->mem_idx
);
2292 #ifdef TARGET_WORDS_BIGENDIAN
2293 tcg_gen_extr_i64_tl(tmp2
, tmp1
, tval
);
2295 tcg_gen_extr_i64_tl(tmp1
, tmp2
, tval
);
2297 gen_store_gpr(tmp1
, reg1
);
2298 tcg_temp_free(tmp1
);
2299 gen_store_gpr(tmp2
, reg2
);
2300 tcg_temp_free(tmp2
);
2301 tcg_gen_st_i64(tval
, cpu_env
, offsetof(CPUMIPSState
, llval_wp
));
2302 tcg_temp_free_i64(tval
);
2303 tcg_gen_st_tl(taddr
, cpu_env
, offsetof(CPUMIPSState
, lladdr
));
2304 tcg_temp_free(taddr
);
2308 static void gen_st(DisasContext
*ctx
, uint32_t opc
, int rt
,
2309 int base
, int offset
)
2311 TCGv t0
= tcg_temp_new();
2312 TCGv t1
= tcg_temp_new();
2313 int mem_idx
= ctx
->mem_idx
;
2315 gen_base_offset_addr(ctx
, t0
, base
, offset
);
2316 gen_load_gpr(t1
, rt
);
2318 #if defined(TARGET_MIPS64)
2320 tcg_gen_qemu_st_tl(t1
, t0
, mem_idx
, MO_TEQ
|
2321 ctx
->default_tcg_memop_mask
);
2324 gen_helper_0e2i(sdl
, t1
, t0
, mem_idx
);
2327 gen_helper_0e2i(sdr
, t1
, t0
, mem_idx
);
2331 mem_idx
= MIPS_HFLAG_UM
;
2334 tcg_gen_qemu_st_tl(t1
, t0
, mem_idx
, MO_TEUL
|
2335 ctx
->default_tcg_memop_mask
);
2338 mem_idx
= MIPS_HFLAG_UM
;
2341 tcg_gen_qemu_st_tl(t1
, t0
, mem_idx
, MO_TEUW
|
2342 ctx
->default_tcg_memop_mask
);
2345 mem_idx
= MIPS_HFLAG_UM
;
2348 tcg_gen_qemu_st_tl(t1
, t0
, mem_idx
, MO_8
);
2351 mem_idx
= MIPS_HFLAG_UM
;
2354 gen_helper_0e2i(swl
, t1
, t0
, mem_idx
);
2357 mem_idx
= MIPS_HFLAG_UM
;
2360 gen_helper_0e2i(swr
, t1
, t0
, mem_idx
);
2368 /* Store conditional */
2369 static void gen_st_cond(DisasContext
*ctx
, int rt
, int base
, int offset
,
2370 MemOp tcg_mo
, bool eva
)
2373 TCGLabel
*l1
= gen_new_label();
2374 TCGLabel
*done
= gen_new_label();
2376 t0
= tcg_temp_new();
2377 addr
= tcg_temp_new();
2378 /* compare the address against that of the preceding LL */
2379 gen_base_offset_addr(ctx
, addr
, base
, offset
);
2380 tcg_gen_brcond_tl(TCG_COND_EQ
, addr
, cpu_lladdr
, l1
);
2381 tcg_temp_free(addr
);
2382 tcg_gen_movi_tl(t0
, 0);
2383 gen_store_gpr(t0
, rt
);
2387 /* generate cmpxchg */
2388 val
= tcg_temp_new();
2389 gen_load_gpr(val
, rt
);
2390 tcg_gen_atomic_cmpxchg_tl(t0
, cpu_lladdr
, cpu_llval
, val
,
2391 eva
? MIPS_HFLAG_UM
: ctx
->mem_idx
, tcg_mo
);
2392 tcg_gen_setcond_tl(TCG_COND_EQ
, t0
, t0
, cpu_llval
);
2393 gen_store_gpr(t0
, rt
);
2396 gen_set_label(done
);
2401 static void gen_scwp(DisasContext
*ctx
, uint32_t base
, int16_t offset
,
2402 uint32_t reg1
, uint32_t reg2
, bool eva
)
2404 TCGv taddr
= tcg_temp_local_new();
2405 TCGv lladdr
= tcg_temp_local_new();
2406 TCGv_i64 tval
= tcg_temp_new_i64();
2407 TCGv_i64 llval
= tcg_temp_new_i64();
2408 TCGv_i64 val
= tcg_temp_new_i64();
2409 TCGv tmp1
= tcg_temp_new();
2410 TCGv tmp2
= tcg_temp_new();
2411 TCGLabel
*lab_fail
= gen_new_label();
2412 TCGLabel
*lab_done
= gen_new_label();
2414 gen_base_offset_addr(ctx
, taddr
, base
, offset
);
2416 tcg_gen_ld_tl(lladdr
, cpu_env
, offsetof(CPUMIPSState
, lladdr
));
2417 tcg_gen_brcond_tl(TCG_COND_NE
, taddr
, lladdr
, lab_fail
);
2419 gen_load_gpr(tmp1
, reg1
);
2420 gen_load_gpr(tmp2
, reg2
);
2422 #ifdef TARGET_WORDS_BIGENDIAN
2423 tcg_gen_concat_tl_i64(tval
, tmp2
, tmp1
);
2425 tcg_gen_concat_tl_i64(tval
, tmp1
, tmp2
);
2428 tcg_gen_ld_i64(llval
, cpu_env
, offsetof(CPUMIPSState
, llval_wp
));
2429 tcg_gen_atomic_cmpxchg_i64(val
, taddr
, llval
, tval
,
2430 eva
? MIPS_HFLAG_UM
: ctx
->mem_idx
, MO_64
);
2432 tcg_gen_movi_tl(cpu_gpr
[reg1
], 1);
2434 tcg_gen_brcond_i64(TCG_COND_EQ
, val
, llval
, lab_done
);
2436 gen_set_label(lab_fail
);
2439 tcg_gen_movi_tl(cpu_gpr
[reg1
], 0);
2441 gen_set_label(lab_done
);
2442 tcg_gen_movi_tl(lladdr
, -1);
2443 tcg_gen_st_tl(lladdr
, cpu_env
, offsetof(CPUMIPSState
, lladdr
));
2446 /* Load and store */
2447 static void gen_flt_ldst(DisasContext
*ctx
, uint32_t opc
, int ft
,
2451 * Don't do NOP if destination is zero: we must perform the actual
2457 TCGv_i32 fp0
= tcg_temp_new_i32();
2458 tcg_gen_qemu_ld_i32(fp0
, t0
, ctx
->mem_idx
, MO_TESL
|
2459 ctx
->default_tcg_memop_mask
);
2460 gen_store_fpr32(ctx
, fp0
, ft
);
2461 tcg_temp_free_i32(fp0
);
2466 TCGv_i32 fp0
= tcg_temp_new_i32();
2467 gen_load_fpr32(ctx
, fp0
, ft
);
2468 tcg_gen_qemu_st_i32(fp0
, t0
, ctx
->mem_idx
, MO_TEUL
|
2469 ctx
->default_tcg_memop_mask
);
2470 tcg_temp_free_i32(fp0
);
2475 TCGv_i64 fp0
= tcg_temp_new_i64();
2476 tcg_gen_qemu_ld_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
|
2477 ctx
->default_tcg_memop_mask
);
2478 gen_store_fpr64(ctx
, fp0
, ft
);
2479 tcg_temp_free_i64(fp0
);
2484 TCGv_i64 fp0
= tcg_temp_new_i64();
2485 gen_load_fpr64(ctx
, fp0
, ft
);
2486 tcg_gen_qemu_st_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
|
2487 ctx
->default_tcg_memop_mask
);
2488 tcg_temp_free_i64(fp0
);
2492 MIPS_INVAL("flt_ldst");
2493 gen_reserved_instruction(ctx
);
2498 static void gen_cop1_ldst(DisasContext
*ctx
, uint32_t op
, int rt
,
2499 int rs
, int16_t imm
)
2501 TCGv t0
= tcg_temp_new();
2503 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
2504 check_cp1_enabled(ctx
);
2508 check_insn(ctx
, ISA_MIPS2
);
2511 gen_base_offset_addr(ctx
, t0
, rs
, imm
);
2512 gen_flt_ldst(ctx
, op
, rt
, t0
);
2515 generate_exception_err(ctx
, EXCP_CpU
, 1);
2520 /* Arithmetic with immediate operand */
2521 static void gen_arith_imm(DisasContext
*ctx
, uint32_t opc
,
2522 int rt
, int rs
, int imm
)
2524 target_ulong uimm
= (target_long
)imm
; /* Sign extend to 32/64 bits */
2526 if (rt
== 0 && opc
!= OPC_ADDI
&& opc
!= OPC_DADDI
) {
2528 * If no destination, treat it as a NOP.
2529 * For addi, we must generate the overflow exception when needed.
2536 TCGv t0
= tcg_temp_local_new();
2537 TCGv t1
= tcg_temp_new();
2538 TCGv t2
= tcg_temp_new();
2539 TCGLabel
*l1
= gen_new_label();
2541 gen_load_gpr(t1
, rs
);
2542 tcg_gen_addi_tl(t0
, t1
, uimm
);
2543 tcg_gen_ext32s_tl(t0
, t0
);
2545 tcg_gen_xori_tl(t1
, t1
, ~uimm
);
2546 tcg_gen_xori_tl(t2
, t0
, uimm
);
2547 tcg_gen_and_tl(t1
, t1
, t2
);
2549 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2551 /* operands of same sign, result different sign */
2552 generate_exception(ctx
, EXCP_OVERFLOW
);
2554 tcg_gen_ext32s_tl(t0
, t0
);
2555 gen_store_gpr(t0
, rt
);
2561 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
2562 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
2564 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
2567 #if defined(TARGET_MIPS64)
2570 TCGv t0
= tcg_temp_local_new();
2571 TCGv t1
= tcg_temp_new();
2572 TCGv t2
= tcg_temp_new();
2573 TCGLabel
*l1
= gen_new_label();
2575 gen_load_gpr(t1
, rs
);
2576 tcg_gen_addi_tl(t0
, t1
, uimm
);
2578 tcg_gen_xori_tl(t1
, t1
, ~uimm
);
2579 tcg_gen_xori_tl(t2
, t0
, uimm
);
2580 tcg_gen_and_tl(t1
, t1
, t2
);
2582 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2584 /* operands of same sign, result different sign */
2585 generate_exception(ctx
, EXCP_OVERFLOW
);
2587 gen_store_gpr(t0
, rt
);
2593 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
2595 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
2602 /* Logic with immediate operand */
2603 static void gen_logic_imm(DisasContext
*ctx
, uint32_t opc
,
2604 int rt
, int rs
, int16_t imm
)
2609 /* If no destination, treat it as a NOP. */
2612 uimm
= (uint16_t)imm
;
2615 if (likely(rs
!= 0)) {
2616 tcg_gen_andi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
2618 tcg_gen_movi_tl(cpu_gpr
[rt
], 0);
2623 tcg_gen_ori_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
2625 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
2629 if (likely(rs
!= 0)) {
2630 tcg_gen_xori_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
2632 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
2636 if (rs
!= 0 && (ctx
->insn_flags
& ISA_MIPS_R6
)) {
2638 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], imm
<< 16);
2639 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
2641 tcg_gen_movi_tl(cpu_gpr
[rt
], imm
<< 16);
2650 /* Set on less than with immediate operand */
2651 static void gen_slt_imm(DisasContext
*ctx
, uint32_t opc
,
2652 int rt
, int rs
, int16_t imm
)
2654 target_ulong uimm
= (target_long
)imm
; /* Sign extend to 32/64 bits */
2658 /* If no destination, treat it as a NOP. */
2661 t0
= tcg_temp_new();
2662 gen_load_gpr(t0
, rs
);
2665 tcg_gen_setcondi_tl(TCG_COND_LT
, cpu_gpr
[rt
], t0
, uimm
);
2668 tcg_gen_setcondi_tl(TCG_COND_LTU
, cpu_gpr
[rt
], t0
, uimm
);
2674 /* Shifts with immediate operand */
2675 static void gen_shift_imm(DisasContext
*ctx
, uint32_t opc
,
2676 int rt
, int rs
, int16_t imm
)
2678 target_ulong uimm
= ((uint16_t)imm
) & 0x1f;
2682 /* If no destination, treat it as a NOP. */
2686 t0
= tcg_temp_new();
2687 gen_load_gpr(t0
, rs
);
2690 tcg_gen_shli_tl(t0
, t0
, uimm
);
2691 tcg_gen_ext32s_tl(cpu_gpr
[rt
], t0
);
2694 tcg_gen_sari_tl(cpu_gpr
[rt
], t0
, uimm
);
2698 tcg_gen_ext32u_tl(t0
, t0
);
2699 tcg_gen_shri_tl(cpu_gpr
[rt
], t0
, uimm
);
2701 tcg_gen_ext32s_tl(cpu_gpr
[rt
], t0
);
2706 TCGv_i32 t1
= tcg_temp_new_i32();
2708 tcg_gen_trunc_tl_i32(t1
, t0
);
2709 tcg_gen_rotri_i32(t1
, t1
, uimm
);
2710 tcg_gen_ext_i32_tl(cpu_gpr
[rt
], t1
);
2711 tcg_temp_free_i32(t1
);
2713 tcg_gen_ext32s_tl(cpu_gpr
[rt
], t0
);
2716 #if defined(TARGET_MIPS64)
2718 tcg_gen_shli_tl(cpu_gpr
[rt
], t0
, uimm
);
2721 tcg_gen_sari_tl(cpu_gpr
[rt
], t0
, uimm
);
2724 tcg_gen_shri_tl(cpu_gpr
[rt
], t0
, uimm
);
2728 tcg_gen_rotri_tl(cpu_gpr
[rt
], t0
, uimm
);
2730 tcg_gen_mov_tl(cpu_gpr
[rt
], t0
);
2734 tcg_gen_shli_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
2737 tcg_gen_sari_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
2740 tcg_gen_shri_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
2743 tcg_gen_rotri_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
2751 static void gen_arith(DisasContext
*ctx
, uint32_t opc
,
2752 int rd
, int rs
, int rt
)
2754 if (rd
== 0 && opc
!= OPC_ADD
&& opc
!= OPC_SUB
2755 && opc
!= OPC_DADD
&& opc
!= OPC_DSUB
) {
2757 * If no destination, treat it as a NOP.
2758 * For add & sub, we must generate the overflow exception when needed.
2766 TCGv t0
= tcg_temp_local_new();
2767 TCGv t1
= tcg_temp_new();
2768 TCGv t2
= tcg_temp_new();
2769 TCGLabel
*l1
= gen_new_label();
2771 gen_load_gpr(t1
, rs
);
2772 gen_load_gpr(t2
, rt
);
2773 tcg_gen_add_tl(t0
, t1
, t2
);
2774 tcg_gen_ext32s_tl(t0
, t0
);
2775 tcg_gen_xor_tl(t1
, t1
, t2
);
2776 tcg_gen_xor_tl(t2
, t0
, t2
);
2777 tcg_gen_andc_tl(t1
, t2
, t1
);
2779 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2781 /* operands of same sign, result different sign */
2782 generate_exception(ctx
, EXCP_OVERFLOW
);
2784 gen_store_gpr(t0
, rd
);
2789 if (rs
!= 0 && rt
!= 0) {
2790 tcg_gen_add_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2791 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
2792 } else if (rs
== 0 && rt
!= 0) {
2793 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2794 } else if (rs
!= 0 && rt
== 0) {
2795 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2797 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2802 TCGv t0
= tcg_temp_local_new();
2803 TCGv t1
= tcg_temp_new();
2804 TCGv t2
= tcg_temp_new();
2805 TCGLabel
*l1
= gen_new_label();
2807 gen_load_gpr(t1
, rs
);
2808 gen_load_gpr(t2
, rt
);
2809 tcg_gen_sub_tl(t0
, t1
, t2
);
2810 tcg_gen_ext32s_tl(t0
, t0
);
2811 tcg_gen_xor_tl(t2
, t1
, t2
);
2812 tcg_gen_xor_tl(t1
, t0
, t1
);
2813 tcg_gen_and_tl(t1
, t1
, t2
);
2815 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2818 * operands of different sign, first operand and the result
2821 generate_exception(ctx
, EXCP_OVERFLOW
);
2823 gen_store_gpr(t0
, rd
);
2828 if (rs
!= 0 && rt
!= 0) {
2829 tcg_gen_sub_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2830 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
2831 } else if (rs
== 0 && rt
!= 0) {
2832 tcg_gen_neg_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2833 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
2834 } else if (rs
!= 0 && rt
== 0) {
2835 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2837 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2840 #if defined(TARGET_MIPS64)
2843 TCGv t0
= tcg_temp_local_new();
2844 TCGv t1
= tcg_temp_new();
2845 TCGv t2
= tcg_temp_new();
2846 TCGLabel
*l1
= gen_new_label();
2848 gen_load_gpr(t1
, rs
);
2849 gen_load_gpr(t2
, rt
);
2850 tcg_gen_add_tl(t0
, t1
, t2
);
2851 tcg_gen_xor_tl(t1
, t1
, t2
);
2852 tcg_gen_xor_tl(t2
, t0
, t2
);
2853 tcg_gen_andc_tl(t1
, t2
, t1
);
2855 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2857 /* operands of same sign, result different sign */
2858 generate_exception(ctx
, EXCP_OVERFLOW
);
2860 gen_store_gpr(t0
, rd
);
2865 if (rs
!= 0 && rt
!= 0) {
2866 tcg_gen_add_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2867 } else if (rs
== 0 && rt
!= 0) {
2868 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2869 } else if (rs
!= 0 && rt
== 0) {
2870 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2872 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2877 TCGv t0
= tcg_temp_local_new();
2878 TCGv t1
= tcg_temp_new();
2879 TCGv t2
= tcg_temp_new();
2880 TCGLabel
*l1
= gen_new_label();
2882 gen_load_gpr(t1
, rs
);
2883 gen_load_gpr(t2
, rt
);
2884 tcg_gen_sub_tl(t0
, t1
, t2
);
2885 tcg_gen_xor_tl(t2
, t1
, t2
);
2886 tcg_gen_xor_tl(t1
, t0
, t1
);
2887 tcg_gen_and_tl(t1
, t1
, t2
);
2889 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2892 * Operands of different sign, first operand and result different
2895 generate_exception(ctx
, EXCP_OVERFLOW
);
2897 gen_store_gpr(t0
, rd
);
2902 if (rs
!= 0 && rt
!= 0) {
2903 tcg_gen_sub_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2904 } else if (rs
== 0 && rt
!= 0) {
2905 tcg_gen_neg_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2906 } else if (rs
!= 0 && rt
== 0) {
2907 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2909 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2914 if (likely(rs
!= 0 && rt
!= 0)) {
2915 tcg_gen_mul_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2916 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
2918 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2924 /* Conditional move */
2925 static void gen_cond_move(DisasContext
*ctx
, uint32_t opc
,
2926 int rd
, int rs
, int rt
)
2931 /* If no destination, treat it as a NOP. */
2935 t0
= tcg_temp_new();
2936 gen_load_gpr(t0
, rt
);
2937 t1
= tcg_const_tl(0);
2938 t2
= tcg_temp_new();
2939 gen_load_gpr(t2
, rs
);
2942 tcg_gen_movcond_tl(TCG_COND_NE
, cpu_gpr
[rd
], t0
, t1
, t2
, cpu_gpr
[rd
]);
2945 tcg_gen_movcond_tl(TCG_COND_EQ
, cpu_gpr
[rd
], t0
, t1
, t2
, cpu_gpr
[rd
]);
2948 tcg_gen_movcond_tl(TCG_COND_NE
, cpu_gpr
[rd
], t0
, t1
, t2
, t1
);
2951 tcg_gen_movcond_tl(TCG_COND_EQ
, cpu_gpr
[rd
], t0
, t1
, t2
, t1
);
2960 static void gen_logic(DisasContext
*ctx
, uint32_t opc
,
2961 int rd
, int rs
, int rt
)
2964 /* If no destination, treat it as a NOP. */
2970 if (likely(rs
!= 0 && rt
!= 0)) {
2971 tcg_gen_and_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2973 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2977 if (rs
!= 0 && rt
!= 0) {
2978 tcg_gen_nor_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2979 } else if (rs
== 0 && rt
!= 0) {
2980 tcg_gen_not_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2981 } else if (rs
!= 0 && rt
== 0) {
2982 tcg_gen_not_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2984 tcg_gen_movi_tl(cpu_gpr
[rd
], ~((target_ulong
)0));
2988 if (likely(rs
!= 0 && rt
!= 0)) {
2989 tcg_gen_or_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2990 } else if (rs
== 0 && rt
!= 0) {
2991 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2992 } else if (rs
!= 0 && rt
== 0) {
2993 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2995 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2999 if (likely(rs
!= 0 && rt
!= 0)) {
3000 tcg_gen_xor_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
3001 } else if (rs
== 0 && rt
!= 0) {
3002 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
3003 } else if (rs
!= 0 && rt
== 0) {
3004 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
3006 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3012 /* Set on lower than */
3013 static void gen_slt(DisasContext
*ctx
, uint32_t opc
,
3014 int rd
, int rs
, int rt
)
3019 /* If no destination, treat it as a NOP. */
3023 t0
= tcg_temp_new();
3024 t1
= tcg_temp_new();
3025 gen_load_gpr(t0
, rs
);
3026 gen_load_gpr(t1
, rt
);
3029 tcg_gen_setcond_tl(TCG_COND_LT
, cpu_gpr
[rd
], t0
, t1
);
3032 tcg_gen_setcond_tl(TCG_COND_LTU
, cpu_gpr
[rd
], t0
, t1
);
3040 static void gen_shift(DisasContext
*ctx
, uint32_t opc
,
3041 int rd
, int rs
, int rt
)
3047 * If no destination, treat it as a NOP.
3048 * For add & sub, we must generate the overflow exception when needed.
3053 t0
= tcg_temp_new();
3054 t1
= tcg_temp_new();
3055 gen_load_gpr(t0
, rs
);
3056 gen_load_gpr(t1
, rt
);
3059 tcg_gen_andi_tl(t0
, t0
, 0x1f);
3060 tcg_gen_shl_tl(t0
, t1
, t0
);
3061 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
3064 tcg_gen_andi_tl(t0
, t0
, 0x1f);
3065 tcg_gen_sar_tl(cpu_gpr
[rd
], t1
, t0
);
3068 tcg_gen_ext32u_tl(t1
, t1
);
3069 tcg_gen_andi_tl(t0
, t0
, 0x1f);
3070 tcg_gen_shr_tl(t0
, t1
, t0
);
3071 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
3075 TCGv_i32 t2
= tcg_temp_new_i32();
3076 TCGv_i32 t3
= tcg_temp_new_i32();
3078 tcg_gen_trunc_tl_i32(t2
, t0
);
3079 tcg_gen_trunc_tl_i32(t3
, t1
);
3080 tcg_gen_andi_i32(t2
, t2
, 0x1f);
3081 tcg_gen_rotr_i32(t2
, t3
, t2
);
3082 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
3083 tcg_temp_free_i32(t2
);
3084 tcg_temp_free_i32(t3
);
3087 #if defined(TARGET_MIPS64)
3089 tcg_gen_andi_tl(t0
, t0
, 0x3f);
3090 tcg_gen_shl_tl(cpu_gpr
[rd
], t1
, t0
);
3093 tcg_gen_andi_tl(t0
, t0
, 0x3f);
3094 tcg_gen_sar_tl(cpu_gpr
[rd
], t1
, t0
);
3097 tcg_gen_andi_tl(t0
, t0
, 0x3f);
3098 tcg_gen_shr_tl(cpu_gpr
[rd
], t1
, t0
);
3101 tcg_gen_andi_tl(t0
, t0
, 0x3f);
3102 tcg_gen_rotr_tl(cpu_gpr
[rd
], t1
, t0
);
3110 /* Arithmetic on HI/LO registers */
3111 static void gen_HILO(DisasContext
*ctx
, uint32_t opc
, int acc
, int reg
)
3113 if (reg
== 0 && (opc
== OPC_MFHI
|| opc
== OPC_MFLO
)) {
3124 #if defined(TARGET_MIPS64)
3126 tcg_gen_ext32s_tl(cpu_gpr
[reg
], cpu_HI
[acc
]);
3130 tcg_gen_mov_tl(cpu_gpr
[reg
], cpu_HI
[acc
]);
3134 #if defined(TARGET_MIPS64)
3136 tcg_gen_ext32s_tl(cpu_gpr
[reg
], cpu_LO
[acc
]);
3140 tcg_gen_mov_tl(cpu_gpr
[reg
], cpu_LO
[acc
]);
3145 #if defined(TARGET_MIPS64)
3147 tcg_gen_ext32s_tl(cpu_HI
[acc
], cpu_gpr
[reg
]);
3151 tcg_gen_mov_tl(cpu_HI
[acc
], cpu_gpr
[reg
]);
3154 tcg_gen_movi_tl(cpu_HI
[acc
], 0);
3159 #if defined(TARGET_MIPS64)
3161 tcg_gen_ext32s_tl(cpu_LO
[acc
], cpu_gpr
[reg
]);
3165 tcg_gen_mov_tl(cpu_LO
[acc
], cpu_gpr
[reg
]);
3168 tcg_gen_movi_tl(cpu_LO
[acc
], 0);
3174 static inline void gen_r6_ld(target_long addr
, int reg
, int memidx
,
3177 TCGv t0
= tcg_const_tl(addr
);
3178 tcg_gen_qemu_ld_tl(t0
, t0
, memidx
, memop
);
3179 gen_store_gpr(t0
, reg
);
3183 static inline void gen_pcrel(DisasContext
*ctx
, int opc
, target_ulong pc
,
3189 switch (MASK_OPC_PCREL_TOP2BITS(opc
)) {
3192 offset
= sextract32(ctx
->opcode
<< 2, 0, 21);
3193 addr
= addr_add(ctx
, pc
, offset
);
3194 tcg_gen_movi_tl(cpu_gpr
[rs
], addr
);
3198 offset
= sextract32(ctx
->opcode
<< 2, 0, 21);
3199 addr
= addr_add(ctx
, pc
, offset
);
3200 gen_r6_ld(addr
, rs
, ctx
->mem_idx
, MO_TESL
);
3202 #if defined(TARGET_MIPS64)
3205 offset
= sextract32(ctx
->opcode
<< 2, 0, 21);
3206 addr
= addr_add(ctx
, pc
, offset
);
3207 gen_r6_ld(addr
, rs
, ctx
->mem_idx
, MO_TEUL
);
3211 switch (MASK_OPC_PCREL_TOP5BITS(opc
)) {
3214 offset
= sextract32(ctx
->opcode
, 0, 16) << 16;
3215 addr
= addr_add(ctx
, pc
, offset
);
3216 tcg_gen_movi_tl(cpu_gpr
[rs
], addr
);
3221 offset
= sextract32(ctx
->opcode
, 0, 16) << 16;
3222 addr
= ~0xFFFF & addr_add(ctx
, pc
, offset
);
3223 tcg_gen_movi_tl(cpu_gpr
[rs
], addr
);
3226 #if defined(TARGET_MIPS64)
3227 case R6_OPC_LDPC
: /* bits 16 and 17 are part of immediate */
3228 case R6_OPC_LDPC
+ (1 << 16):
3229 case R6_OPC_LDPC
+ (2 << 16):
3230 case R6_OPC_LDPC
+ (3 << 16):
3232 offset
= sextract32(ctx
->opcode
<< 3, 0, 21);
3233 addr
= addr_add(ctx
, (pc
& ~0x7), offset
);
3234 gen_r6_ld(addr
, rs
, ctx
->mem_idx
, MO_TEQ
);
3238 MIPS_INVAL("OPC_PCREL");
3239 gen_reserved_instruction(ctx
);
3246 static void gen_r6_muldiv(DisasContext
*ctx
, int opc
, int rd
, int rs
, int rt
)
3255 t0
= tcg_temp_new();
3256 t1
= tcg_temp_new();
3258 gen_load_gpr(t0
, rs
);
3259 gen_load_gpr(t1
, rt
);
3264 TCGv t2
= tcg_temp_new();
3265 TCGv t3
= tcg_temp_new();
3266 tcg_gen_ext32s_tl(t0
, t0
);
3267 tcg_gen_ext32s_tl(t1
, t1
);
3268 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, INT_MIN
);
3269 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1);
3270 tcg_gen_and_tl(t2
, t2
, t3
);
3271 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
3272 tcg_gen_or_tl(t2
, t2
, t3
);
3273 tcg_gen_movi_tl(t3
, 0);
3274 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
3275 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
3276 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3283 TCGv t2
= tcg_temp_new();
3284 TCGv t3
= tcg_temp_new();
3285 tcg_gen_ext32s_tl(t0
, t0
);
3286 tcg_gen_ext32s_tl(t1
, t1
);
3287 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, INT_MIN
);
3288 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1);
3289 tcg_gen_and_tl(t2
, t2
, t3
);
3290 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
3291 tcg_gen_or_tl(t2
, t2
, t3
);
3292 tcg_gen_movi_tl(t3
, 0);
3293 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
3294 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
3295 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3302 TCGv t2
= tcg_const_tl(0);
3303 TCGv t3
= tcg_const_tl(1);
3304 tcg_gen_ext32u_tl(t0
, t0
);
3305 tcg_gen_ext32u_tl(t1
, t1
);
3306 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
3307 tcg_gen_divu_tl(cpu_gpr
[rd
], t0
, t1
);
3308 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3315 TCGv t2
= tcg_const_tl(0);
3316 TCGv t3
= tcg_const_tl(1);
3317 tcg_gen_ext32u_tl(t0
, t0
);
3318 tcg_gen_ext32u_tl(t1
, t1
);
3319 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
3320 tcg_gen_remu_tl(cpu_gpr
[rd
], t0
, t1
);
3321 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3328 TCGv_i32 t2
= tcg_temp_new_i32();
3329 TCGv_i32 t3
= tcg_temp_new_i32();
3330 tcg_gen_trunc_tl_i32(t2
, t0
);
3331 tcg_gen_trunc_tl_i32(t3
, t1
);
3332 tcg_gen_mul_i32(t2
, t2
, t3
);
3333 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
3334 tcg_temp_free_i32(t2
);
3335 tcg_temp_free_i32(t3
);
3340 TCGv_i32 t2
= tcg_temp_new_i32();
3341 TCGv_i32 t3
= tcg_temp_new_i32();
3342 tcg_gen_trunc_tl_i32(t2
, t0
);
3343 tcg_gen_trunc_tl_i32(t3
, t1
);
3344 tcg_gen_muls2_i32(t2
, t3
, t2
, t3
);
3345 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t3
);
3346 tcg_temp_free_i32(t2
);
3347 tcg_temp_free_i32(t3
);
3352 TCGv_i32 t2
= tcg_temp_new_i32();
3353 TCGv_i32 t3
= tcg_temp_new_i32();
3354 tcg_gen_trunc_tl_i32(t2
, t0
);
3355 tcg_gen_trunc_tl_i32(t3
, t1
);
3356 tcg_gen_mul_i32(t2
, t2
, t3
);
3357 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
3358 tcg_temp_free_i32(t2
);
3359 tcg_temp_free_i32(t3
);
3364 TCGv_i32 t2
= tcg_temp_new_i32();
3365 TCGv_i32 t3
= tcg_temp_new_i32();
3366 tcg_gen_trunc_tl_i32(t2
, t0
);
3367 tcg_gen_trunc_tl_i32(t3
, t1
);
3368 tcg_gen_mulu2_i32(t2
, t3
, t2
, t3
);
3369 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t3
);
3370 tcg_temp_free_i32(t2
);
3371 tcg_temp_free_i32(t3
);
3374 #if defined(TARGET_MIPS64)
3377 TCGv t2
= tcg_temp_new();
3378 TCGv t3
= tcg_temp_new();
3379 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, -1LL << 63);
3380 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1LL);
3381 tcg_gen_and_tl(t2
, t2
, t3
);
3382 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
3383 tcg_gen_or_tl(t2
, t2
, t3
);
3384 tcg_gen_movi_tl(t3
, 0);
3385 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
3386 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
3393 TCGv t2
= tcg_temp_new();
3394 TCGv t3
= tcg_temp_new();
3395 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, -1LL << 63);
3396 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1LL);
3397 tcg_gen_and_tl(t2
, t2
, t3
);
3398 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
3399 tcg_gen_or_tl(t2
, t2
, t3
);
3400 tcg_gen_movi_tl(t3
, 0);
3401 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
3402 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
3409 TCGv t2
= tcg_const_tl(0);
3410 TCGv t3
= tcg_const_tl(1);
3411 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
3412 tcg_gen_divu_i64(cpu_gpr
[rd
], t0
, t1
);
3419 TCGv t2
= tcg_const_tl(0);
3420 TCGv t3
= tcg_const_tl(1);
3421 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
3422 tcg_gen_remu_i64(cpu_gpr
[rd
], t0
, t1
);
3428 tcg_gen_mul_i64(cpu_gpr
[rd
], t0
, t1
);
3432 TCGv t2
= tcg_temp_new();
3433 tcg_gen_muls2_i64(t2
, cpu_gpr
[rd
], t0
, t1
);
3438 tcg_gen_mul_i64(cpu_gpr
[rd
], t0
, t1
);
3442 TCGv t2
= tcg_temp_new();
3443 tcg_gen_mulu2_i64(t2
, cpu_gpr
[rd
], t0
, t1
);
3449 MIPS_INVAL("r6 mul/div");
3450 gen_reserved_instruction(ctx
);
3458 #if defined(TARGET_MIPS64)
3459 static void gen_div1_tx79(DisasContext
*ctx
, uint32_t opc
, int rs
, int rt
)
3463 t0
= tcg_temp_new();
3464 t1
= tcg_temp_new();
3466 gen_load_gpr(t0
, rs
);
3467 gen_load_gpr(t1
, rt
);
3472 TCGv t2
= tcg_temp_new();
3473 TCGv t3
= tcg_temp_new();
3474 tcg_gen_ext32s_tl(t0
, t0
);
3475 tcg_gen_ext32s_tl(t1
, t1
);
3476 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, INT_MIN
);
3477 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1);
3478 tcg_gen_and_tl(t2
, t2
, t3
);
3479 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
3480 tcg_gen_or_tl(t2
, t2
, t3
);
3481 tcg_gen_movi_tl(t3
, 0);
3482 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
3483 tcg_gen_div_tl(cpu_LO
[1], t0
, t1
);
3484 tcg_gen_rem_tl(cpu_HI
[1], t0
, t1
);
3485 tcg_gen_ext32s_tl(cpu_LO
[1], cpu_LO
[1]);
3486 tcg_gen_ext32s_tl(cpu_HI
[1], cpu_HI
[1]);
3493 TCGv t2
= tcg_const_tl(0);
3494 TCGv t3
= tcg_const_tl(1);
3495 tcg_gen_ext32u_tl(t0
, t0
);
3496 tcg_gen_ext32u_tl(t1
, t1
);
3497 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
3498 tcg_gen_divu_tl(cpu_LO
[1], t0
, t1
);
3499 tcg_gen_remu_tl(cpu_HI
[1], t0
, t1
);
3500 tcg_gen_ext32s_tl(cpu_LO
[1], cpu_LO
[1]);
3501 tcg_gen_ext32s_tl(cpu_HI
[1], cpu_HI
[1]);
3507 MIPS_INVAL("div1 TX79");
3508 gen_reserved_instruction(ctx
);
3517 static void gen_muldiv(DisasContext
*ctx
, uint32_t opc
,
3518 int acc
, int rs
, int rt
)
3522 t0
= tcg_temp_new();
3523 t1
= tcg_temp_new();
3525 gen_load_gpr(t0
, rs
);
3526 gen_load_gpr(t1
, rt
);
3535 TCGv t2
= tcg_temp_new();
3536 TCGv t3
= tcg_temp_new();
3537 tcg_gen_ext32s_tl(t0
, t0
);
3538 tcg_gen_ext32s_tl(t1
, t1
);
3539 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, INT_MIN
);
3540 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1);
3541 tcg_gen_and_tl(t2
, t2
, t3
);
3542 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
3543 tcg_gen_or_tl(t2
, t2
, t3
);
3544 tcg_gen_movi_tl(t3
, 0);
3545 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
3546 tcg_gen_div_tl(cpu_LO
[acc
], t0
, t1
);
3547 tcg_gen_rem_tl(cpu_HI
[acc
], t0
, t1
);
3548 tcg_gen_ext32s_tl(cpu_LO
[acc
], cpu_LO
[acc
]);
3549 tcg_gen_ext32s_tl(cpu_HI
[acc
], cpu_HI
[acc
]);
3556 TCGv t2
= tcg_const_tl(0);
3557 TCGv t3
= tcg_const_tl(1);
3558 tcg_gen_ext32u_tl(t0
, t0
);
3559 tcg_gen_ext32u_tl(t1
, t1
);
3560 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
3561 tcg_gen_divu_tl(cpu_LO
[acc
], t0
, t1
);
3562 tcg_gen_remu_tl(cpu_HI
[acc
], t0
, t1
);
3563 tcg_gen_ext32s_tl(cpu_LO
[acc
], cpu_LO
[acc
]);
3564 tcg_gen_ext32s_tl(cpu_HI
[acc
], cpu_HI
[acc
]);
3571 TCGv_i32 t2
= tcg_temp_new_i32();
3572 TCGv_i32 t3
= tcg_temp_new_i32();
3573 tcg_gen_trunc_tl_i32(t2
, t0
);
3574 tcg_gen_trunc_tl_i32(t3
, t1
);
3575 tcg_gen_muls2_i32(t2
, t3
, t2
, t3
);
3576 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
3577 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
3578 tcg_temp_free_i32(t2
);
3579 tcg_temp_free_i32(t3
);
3584 TCGv_i32 t2
= tcg_temp_new_i32();
3585 TCGv_i32 t3
= tcg_temp_new_i32();
3586 tcg_gen_trunc_tl_i32(t2
, t0
);
3587 tcg_gen_trunc_tl_i32(t3
, t1
);
3588 tcg_gen_mulu2_i32(t2
, t3
, t2
, t3
);
3589 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
3590 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
3591 tcg_temp_free_i32(t2
);
3592 tcg_temp_free_i32(t3
);
3595 #if defined(TARGET_MIPS64)
3598 TCGv t2
= tcg_temp_new();
3599 TCGv t3
= tcg_temp_new();
3600 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, -1LL << 63);
3601 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1LL);
3602 tcg_gen_and_tl(t2
, t2
, t3
);
3603 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
3604 tcg_gen_or_tl(t2
, t2
, t3
);
3605 tcg_gen_movi_tl(t3
, 0);
3606 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
3607 tcg_gen_div_tl(cpu_LO
[acc
], t0
, t1
);
3608 tcg_gen_rem_tl(cpu_HI
[acc
], t0
, t1
);
3615 TCGv t2
= tcg_const_tl(0);
3616 TCGv t3
= tcg_const_tl(1);
3617 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
3618 tcg_gen_divu_i64(cpu_LO
[acc
], t0
, t1
);
3619 tcg_gen_remu_i64(cpu_HI
[acc
], t0
, t1
);
3625 tcg_gen_muls2_i64(cpu_LO
[acc
], cpu_HI
[acc
], t0
, t1
);
3628 tcg_gen_mulu2_i64(cpu_LO
[acc
], cpu_HI
[acc
], t0
, t1
);
3633 TCGv_i64 t2
= tcg_temp_new_i64();
3634 TCGv_i64 t3
= tcg_temp_new_i64();
3636 tcg_gen_ext_tl_i64(t2
, t0
);
3637 tcg_gen_ext_tl_i64(t3
, t1
);
3638 tcg_gen_mul_i64(t2
, t2
, t3
);
3639 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
3640 tcg_gen_add_i64(t2
, t2
, t3
);
3641 tcg_temp_free_i64(t3
);
3642 gen_move_low32(cpu_LO
[acc
], t2
);
3643 gen_move_high32(cpu_HI
[acc
], t2
);
3644 tcg_temp_free_i64(t2
);
3649 TCGv_i64 t2
= tcg_temp_new_i64();
3650 TCGv_i64 t3
= tcg_temp_new_i64();
3652 tcg_gen_ext32u_tl(t0
, t0
);
3653 tcg_gen_ext32u_tl(t1
, t1
);
3654 tcg_gen_extu_tl_i64(t2
, t0
);
3655 tcg_gen_extu_tl_i64(t3
, t1
);
3656 tcg_gen_mul_i64(t2
, t2
, t3
);
3657 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
3658 tcg_gen_add_i64(t2
, t2
, t3
);
3659 tcg_temp_free_i64(t3
);
3660 gen_move_low32(cpu_LO
[acc
], t2
);
3661 gen_move_high32(cpu_HI
[acc
], t2
);
3662 tcg_temp_free_i64(t2
);
3667 TCGv_i64 t2
= tcg_temp_new_i64();
3668 TCGv_i64 t3
= tcg_temp_new_i64();
3670 tcg_gen_ext_tl_i64(t2
, t0
);
3671 tcg_gen_ext_tl_i64(t3
, t1
);
3672 tcg_gen_mul_i64(t2
, t2
, t3
);
3673 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
3674 tcg_gen_sub_i64(t2
, t3
, t2
);
3675 tcg_temp_free_i64(t3
);
3676 gen_move_low32(cpu_LO
[acc
], t2
);
3677 gen_move_high32(cpu_HI
[acc
], t2
);
3678 tcg_temp_free_i64(t2
);
3683 TCGv_i64 t2
= tcg_temp_new_i64();
3684 TCGv_i64 t3
= tcg_temp_new_i64();
3686 tcg_gen_ext32u_tl(t0
, t0
);
3687 tcg_gen_ext32u_tl(t1
, t1
);
3688 tcg_gen_extu_tl_i64(t2
, t0
);
3689 tcg_gen_extu_tl_i64(t3
, t1
);
3690 tcg_gen_mul_i64(t2
, t2
, t3
);
3691 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
3692 tcg_gen_sub_i64(t2
, t3
, t2
);
3693 tcg_temp_free_i64(t3
);
3694 gen_move_low32(cpu_LO
[acc
], t2
);
3695 gen_move_high32(cpu_HI
[acc
], t2
);
3696 tcg_temp_free_i64(t2
);
3700 MIPS_INVAL("mul/div");
3701 gen_reserved_instruction(ctx
);
3710 * These MULT[U] and MADD[U] instructions implemented in for example
3711 * the Toshiba/Sony R5900 and the Toshiba TX19, TX39 and TX79 core
3712 * architectures are special three-operand variants with the syntax
3714 * MULT[U][1] rd, rs, rt
3718 * (rd, LO, HI) <- rs * rt
3722 * MADD[U][1] rd, rs, rt
3726 * (rd, LO, HI) <- (LO, HI) + rs * rt
3728 * where the low-order 32-bits of the result is placed into both the
3729 * GPR rd and the special register LO. The high-order 32-bits of the
3730 * result is placed into the special register HI.
3732 * If the GPR rd is omitted in assembly language, it is taken to be 0,
3733 * which is the zero register that always reads as 0.
3735 static void gen_mul_txx9(DisasContext
*ctx
, uint32_t opc
,
3736 int rd
, int rs
, int rt
)
3738 TCGv t0
= tcg_temp_new();
3739 TCGv t1
= tcg_temp_new();
3742 gen_load_gpr(t0
, rs
);
3743 gen_load_gpr(t1
, rt
);
3751 TCGv_i32 t2
= tcg_temp_new_i32();
3752 TCGv_i32 t3
= tcg_temp_new_i32();
3753 tcg_gen_trunc_tl_i32(t2
, t0
);
3754 tcg_gen_trunc_tl_i32(t3
, t1
);
3755 tcg_gen_muls2_i32(t2
, t3
, t2
, t3
);
3757 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
3759 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
3760 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
3761 tcg_temp_free_i32(t2
);
3762 tcg_temp_free_i32(t3
);
3765 case MMI_OPC_MULTU1
:
3770 TCGv_i32 t2
= tcg_temp_new_i32();
3771 TCGv_i32 t3
= tcg_temp_new_i32();
3772 tcg_gen_trunc_tl_i32(t2
, t0
);
3773 tcg_gen_trunc_tl_i32(t3
, t1
);
3774 tcg_gen_mulu2_i32(t2
, t3
, t2
, t3
);
3776 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
3778 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
3779 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
3780 tcg_temp_free_i32(t2
);
3781 tcg_temp_free_i32(t3
);
3789 TCGv_i64 t2
= tcg_temp_new_i64();
3790 TCGv_i64 t3
= tcg_temp_new_i64();
3792 tcg_gen_ext_tl_i64(t2
, t0
);
3793 tcg_gen_ext_tl_i64(t3
, t1
);
3794 tcg_gen_mul_i64(t2
, t2
, t3
);
3795 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
3796 tcg_gen_add_i64(t2
, t2
, t3
);
3797 tcg_temp_free_i64(t3
);
3798 gen_move_low32(cpu_LO
[acc
], t2
);
3799 gen_move_high32(cpu_HI
[acc
], t2
);
3801 gen_move_low32(cpu_gpr
[rd
], t2
);
3803 tcg_temp_free_i64(t2
);
3806 case MMI_OPC_MADDU1
:
3811 TCGv_i64 t2
= tcg_temp_new_i64();
3812 TCGv_i64 t3
= tcg_temp_new_i64();
3814 tcg_gen_ext32u_tl(t0
, t0
);
3815 tcg_gen_ext32u_tl(t1
, t1
);
3816 tcg_gen_extu_tl_i64(t2
, t0
);
3817 tcg_gen_extu_tl_i64(t3
, t1
);
3818 tcg_gen_mul_i64(t2
, t2
, t3
);
3819 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
3820 tcg_gen_add_i64(t2
, t2
, t3
);
3821 tcg_temp_free_i64(t3
);
3822 gen_move_low32(cpu_LO
[acc
], t2
);
3823 gen_move_high32(cpu_HI
[acc
], t2
);
3825 gen_move_low32(cpu_gpr
[rd
], t2
);
3827 tcg_temp_free_i64(t2
);
3831 MIPS_INVAL("mul/madd TXx9");
3832 gen_reserved_instruction(ctx
);
3841 static void gen_mul_vr54xx(DisasContext
*ctx
, uint32_t opc
,
3842 int rd
, int rs
, int rt
)
3844 TCGv t0
= tcg_temp_new();
3845 TCGv t1
= tcg_temp_new();
3847 gen_load_gpr(t0
, rs
);
3848 gen_load_gpr(t1
, rt
);
3851 case OPC_VR54XX_MULS
:
3852 gen_helper_muls(t0
, cpu_env
, t0
, t1
);
3854 case OPC_VR54XX_MULSU
:
3855 gen_helper_mulsu(t0
, cpu_env
, t0
, t1
);
3857 case OPC_VR54XX_MACC
:
3858 gen_helper_macc(t0
, cpu_env
, t0
, t1
);
3860 case OPC_VR54XX_MACCU
:
3861 gen_helper_maccu(t0
, cpu_env
, t0
, t1
);
3863 case OPC_VR54XX_MSAC
:
3864 gen_helper_msac(t0
, cpu_env
, t0
, t1
);
3866 case OPC_VR54XX_MSACU
:
3867 gen_helper_msacu(t0
, cpu_env
, t0
, t1
);
3869 case OPC_VR54XX_MULHI
:
3870 gen_helper_mulhi(t0
, cpu_env
, t0
, t1
);
3872 case OPC_VR54XX_MULHIU
:
3873 gen_helper_mulhiu(t0
, cpu_env
, t0
, t1
);
3875 case OPC_VR54XX_MULSHI
:
3876 gen_helper_mulshi(t0
, cpu_env
, t0
, t1
);
3878 case OPC_VR54XX_MULSHIU
:
3879 gen_helper_mulshiu(t0
, cpu_env
, t0
, t1
);
3881 case OPC_VR54XX_MACCHI
:
3882 gen_helper_macchi(t0
, cpu_env
, t0
, t1
);
3884 case OPC_VR54XX_MACCHIU
:
3885 gen_helper_macchiu(t0
, cpu_env
, t0
, t1
);
3887 case OPC_VR54XX_MSACHI
:
3888 gen_helper_msachi(t0
, cpu_env
, t0
, t1
);
3890 case OPC_VR54XX_MSACHIU
:
3891 gen_helper_msachiu(t0
, cpu_env
, t0
, t1
);
3894 MIPS_INVAL("mul vr54xx");
3895 gen_reserved_instruction(ctx
);
3898 gen_store_gpr(t0
, rd
);
3905 static void gen_cl(DisasContext
*ctx
, uint32_t opc
,
3915 gen_load_gpr(t0
, rs
);
3920 #if defined(TARGET_MIPS64)
3924 tcg_gen_not_tl(t0
, t0
);
3933 tcg_gen_ext32u_tl(t0
, t0
);
3934 tcg_gen_clzi_tl(t0
, t0
, TARGET_LONG_BITS
);
3935 tcg_gen_subi_tl(t0
, t0
, TARGET_LONG_BITS
- 32);
3937 #if defined(TARGET_MIPS64)
3942 tcg_gen_clzi_i64(t0
, t0
, 64);
3948 /* Godson integer instructions */
3949 static void gen_loongson_integer(DisasContext
*ctx
, uint32_t opc
,
3950 int rd
, int rs
, int rt
)
3962 case OPC_MULTU_G_2E
:
3963 case OPC_MULTU_G_2F
:
3964 #if defined(TARGET_MIPS64)
3965 case OPC_DMULT_G_2E
:
3966 case OPC_DMULT_G_2F
:
3967 case OPC_DMULTU_G_2E
:
3968 case OPC_DMULTU_G_2F
:
3970 t0
= tcg_temp_new();
3971 t1
= tcg_temp_new();
3974 t0
= tcg_temp_local_new();
3975 t1
= tcg_temp_local_new();
3979 gen_load_gpr(t0
, rs
);
3980 gen_load_gpr(t1
, rt
);
3985 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
3986 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3988 case OPC_MULTU_G_2E
:
3989 case OPC_MULTU_G_2F
:
3990 tcg_gen_ext32u_tl(t0
, t0
);
3991 tcg_gen_ext32u_tl(t1
, t1
);
3992 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
3993 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3998 TCGLabel
*l1
= gen_new_label();
3999 TCGLabel
*l2
= gen_new_label();
4000 TCGLabel
*l3
= gen_new_label();
4001 tcg_gen_ext32s_tl(t0
, t0
);
4002 tcg_gen_ext32s_tl(t1
, t1
);
4003 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
4004 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4007 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, INT_MIN
, l2
);
4008 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1, l2
);
4009 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
4012 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
4013 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
4020 TCGLabel
*l1
= gen_new_label();
4021 TCGLabel
*l2
= gen_new_label();
4022 tcg_gen_ext32u_tl(t0
, t0
);
4023 tcg_gen_ext32u_tl(t1
, t1
);
4024 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
4025 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4028 tcg_gen_divu_tl(cpu_gpr
[rd
], t0
, t1
);
4029 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
4036 TCGLabel
*l1
= gen_new_label();
4037 TCGLabel
*l2
= gen_new_label();
4038 TCGLabel
*l3
= gen_new_label();
4039 tcg_gen_ext32u_tl(t0
, t0
);
4040 tcg_gen_ext32u_tl(t1
, t1
);
4041 tcg_gen_brcondi_tl(TCG_COND_EQ
, t1
, 0, l1
);
4042 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, INT_MIN
, l2
);
4043 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1, l2
);
4045 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4048 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
4049 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
4056 TCGLabel
*l1
= gen_new_label();
4057 TCGLabel
*l2
= gen_new_label();
4058 tcg_gen_ext32u_tl(t0
, t0
);
4059 tcg_gen_ext32u_tl(t1
, t1
);
4060 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
4061 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4064 tcg_gen_remu_tl(cpu_gpr
[rd
], t0
, t1
);
4065 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
4069 #if defined(TARGET_MIPS64)
4070 case OPC_DMULT_G_2E
:
4071 case OPC_DMULT_G_2F
:
4072 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
4074 case OPC_DMULTU_G_2E
:
4075 case OPC_DMULTU_G_2F
:
4076 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
4081 TCGLabel
*l1
= gen_new_label();
4082 TCGLabel
*l2
= gen_new_label();
4083 TCGLabel
*l3
= gen_new_label();
4084 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
4085 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4088 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, -1LL << 63, l2
);
4089 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1LL, l2
);
4090 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
4093 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
4097 case OPC_DDIVU_G_2E
:
4098 case OPC_DDIVU_G_2F
:
4100 TCGLabel
*l1
= gen_new_label();
4101 TCGLabel
*l2
= gen_new_label();
4102 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
4103 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4106 tcg_gen_divu_tl(cpu_gpr
[rd
], t0
, t1
);
4113 TCGLabel
*l1
= gen_new_label();
4114 TCGLabel
*l2
= gen_new_label();
4115 TCGLabel
*l3
= gen_new_label();
4116 tcg_gen_brcondi_tl(TCG_COND_EQ
, t1
, 0, l1
);
4117 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, -1LL << 63, l2
);
4118 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1LL, l2
);
4120 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4123 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
4127 case OPC_DMODU_G_2E
:
4128 case OPC_DMODU_G_2F
:
4130 TCGLabel
*l1
= gen_new_label();
4131 TCGLabel
*l2
= gen_new_label();
4132 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
4133 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4136 tcg_gen_remu_tl(cpu_gpr
[rd
], t0
, t1
);
4147 /* Loongson multimedia instructions */
4148 static void gen_loongson_multimedia(DisasContext
*ctx
, int rd
, int rs
, int rt
)
4150 uint32_t opc
, shift_max
;
4154 opc
= MASK_LMMI(ctx
->opcode
);
4160 t0
= tcg_temp_local_new_i64();
4161 t1
= tcg_temp_local_new_i64();
4164 t0
= tcg_temp_new_i64();
4165 t1
= tcg_temp_new_i64();
4169 check_cp1_enabled(ctx
);
4170 gen_load_fpr64(ctx
, t0
, rs
);
4171 gen_load_fpr64(ctx
, t1
, rt
);
4175 gen_helper_paddsh(t0
, t0
, t1
);
4178 gen_helper_paddush(t0
, t0
, t1
);
4181 gen_helper_paddh(t0
, t0
, t1
);
4184 gen_helper_paddw(t0
, t0
, t1
);
4187 gen_helper_paddsb(t0
, t0
, t1
);
4190 gen_helper_paddusb(t0
, t0
, t1
);
4193 gen_helper_paddb(t0
, t0
, t1
);
4197 gen_helper_psubsh(t0
, t0
, t1
);
4200 gen_helper_psubush(t0
, t0
, t1
);
4203 gen_helper_psubh(t0
, t0
, t1
);
4206 gen_helper_psubw(t0
, t0
, t1
);
4209 gen_helper_psubsb(t0
, t0
, t1
);
4212 gen_helper_psubusb(t0
, t0
, t1
);
4215 gen_helper_psubb(t0
, t0
, t1
);
4219 gen_helper_pshufh(t0
, t0
, t1
);
4222 gen_helper_packsswh(t0
, t0
, t1
);
4225 gen_helper_packsshb(t0
, t0
, t1
);
4228 gen_helper_packushb(t0
, t0
, t1
);
4232 gen_helper_punpcklhw(t0
, t0
, t1
);
4235 gen_helper_punpckhhw(t0
, t0
, t1
);
4238 gen_helper_punpcklbh(t0
, t0
, t1
);
4241 gen_helper_punpckhbh(t0
, t0
, t1
);
4244 gen_helper_punpcklwd(t0
, t0
, t1
);
4247 gen_helper_punpckhwd(t0
, t0
, t1
);
4251 gen_helper_pavgh(t0
, t0
, t1
);
4254 gen_helper_pavgb(t0
, t0
, t1
);
4257 gen_helper_pmaxsh(t0
, t0
, t1
);
4260 gen_helper_pminsh(t0
, t0
, t1
);
4263 gen_helper_pmaxub(t0
, t0
, t1
);
4266 gen_helper_pminub(t0
, t0
, t1
);
4270 gen_helper_pcmpeqw(t0
, t0
, t1
);
4273 gen_helper_pcmpgtw(t0
, t0
, t1
);
4276 gen_helper_pcmpeqh(t0
, t0
, t1
);
4279 gen_helper_pcmpgth(t0
, t0
, t1
);
4282 gen_helper_pcmpeqb(t0
, t0
, t1
);
4285 gen_helper_pcmpgtb(t0
, t0
, t1
);
4289 gen_helper_psllw(t0
, t0
, t1
);
4292 gen_helper_psllh(t0
, t0
, t1
);
4295 gen_helper_psrlw(t0
, t0
, t1
);
4298 gen_helper_psrlh(t0
, t0
, t1
);
4301 gen_helper_psraw(t0
, t0
, t1
);
4304 gen_helper_psrah(t0
, t0
, t1
);
4308 gen_helper_pmullh(t0
, t0
, t1
);
4311 gen_helper_pmulhh(t0
, t0
, t1
);
4314 gen_helper_pmulhuh(t0
, t0
, t1
);
4317 gen_helper_pmaddhw(t0
, t0
, t1
);
4321 gen_helper_pasubub(t0
, t0
, t1
);
4324 gen_helper_biadd(t0
, t0
);
4327 gen_helper_pmovmskb(t0
, t0
);
4331 tcg_gen_add_i64(t0
, t0
, t1
);
4334 tcg_gen_sub_i64(t0
, t0
, t1
);
4337 tcg_gen_xor_i64(t0
, t0
, t1
);
4340 tcg_gen_nor_i64(t0
, t0
, t1
);
4343 tcg_gen_and_i64(t0
, t0
, t1
);
4346 tcg_gen_or_i64(t0
, t0
, t1
);
4350 tcg_gen_andc_i64(t0
, t1
, t0
);
4354 tcg_gen_deposit_i64(t0
, t0
, t1
, 0, 16);
4357 tcg_gen_deposit_i64(t0
, t0
, t1
, 16, 16);
4360 tcg_gen_deposit_i64(t0
, t0
, t1
, 32, 16);
4363 tcg_gen_deposit_i64(t0
, t0
, t1
, 48, 16);
4367 tcg_gen_andi_i64(t1
, t1
, 3);
4368 tcg_gen_shli_i64(t1
, t1
, 4);
4369 tcg_gen_shr_i64(t0
, t0
, t1
);
4370 tcg_gen_ext16u_i64(t0
, t0
);
4374 tcg_gen_add_i64(t0
, t0
, t1
);
4375 tcg_gen_ext32s_i64(t0
, t0
);
4378 tcg_gen_sub_i64(t0
, t0
, t1
);
4379 tcg_gen_ext32s_i64(t0
, t0
);
4401 /* Make sure shift count isn't TCG undefined behaviour. */
4402 tcg_gen_andi_i64(t1
, t1
, shift_max
- 1);
4407 tcg_gen_shl_i64(t0
, t0
, t1
);
4412 * Since SRA is UndefinedResult without sign-extended inputs,
4413 * we can treat SRA and DSRA the same.
4415 tcg_gen_sar_i64(t0
, t0
, t1
);
4418 /* We want to shift in zeros for SRL; zero-extend first. */
4419 tcg_gen_ext32u_i64(t0
, t0
);
4422 tcg_gen_shr_i64(t0
, t0
, t1
);
4426 if (shift_max
== 32) {
4427 tcg_gen_ext32s_i64(t0
, t0
);
4430 /* Shifts larger than MAX produce zero. */
4431 tcg_gen_setcondi_i64(TCG_COND_LTU
, t1
, t1
, shift_max
);
4432 tcg_gen_neg_i64(t1
, t1
);
4433 tcg_gen_and_i64(t0
, t0
, t1
);
4439 TCGv_i64 t2
= tcg_temp_new_i64();
4440 TCGLabel
*lab
= gen_new_label();
4442 tcg_gen_mov_i64(t2
, t0
);
4443 tcg_gen_add_i64(t0
, t1
, t2
);
4444 if (opc
== OPC_ADD_CP2
) {
4445 tcg_gen_ext32s_i64(t0
, t0
);
4447 tcg_gen_xor_i64(t1
, t1
, t2
);
4448 tcg_gen_xor_i64(t2
, t2
, t0
);
4449 tcg_gen_andc_i64(t1
, t2
, t1
);
4450 tcg_temp_free_i64(t2
);
4451 tcg_gen_brcondi_i64(TCG_COND_GE
, t1
, 0, lab
);
4452 generate_exception(ctx
, EXCP_OVERFLOW
);
4460 TCGv_i64 t2
= tcg_temp_new_i64();
4461 TCGLabel
*lab
= gen_new_label();
4463 tcg_gen_mov_i64(t2
, t0
);
4464 tcg_gen_sub_i64(t0
, t1
, t2
);
4465 if (opc
== OPC_SUB_CP2
) {
4466 tcg_gen_ext32s_i64(t0
, t0
);
4468 tcg_gen_xor_i64(t1
, t1
, t2
);
4469 tcg_gen_xor_i64(t2
, t2
, t0
);
4470 tcg_gen_and_i64(t1
, t1
, t2
);
4471 tcg_temp_free_i64(t2
);
4472 tcg_gen_brcondi_i64(TCG_COND_GE
, t1
, 0, lab
);
4473 generate_exception(ctx
, EXCP_OVERFLOW
);
4479 tcg_gen_ext32u_i64(t0
, t0
);
4480 tcg_gen_ext32u_i64(t1
, t1
);
4481 tcg_gen_mul_i64(t0
, t0
, t1
);
4490 cond
= TCG_COND_LTU
;
4498 cond
= TCG_COND_LEU
;
4505 int cc
= (ctx
->opcode
>> 8) & 0x7;
4506 TCGv_i64 t64
= tcg_temp_new_i64();
4507 TCGv_i32 t32
= tcg_temp_new_i32();
4509 tcg_gen_setcond_i64(cond
, t64
, t0
, t1
);
4510 tcg_gen_extrl_i64_i32(t32
, t64
);
4511 tcg_gen_deposit_i32(fpu_fcr31
, fpu_fcr31
, t32
,
4514 tcg_temp_free_i32(t32
);
4515 tcg_temp_free_i64(t64
);
4520 MIPS_INVAL("loongson_cp2");
4521 gen_reserved_instruction(ctx
);
4525 gen_store_fpr64(ctx
, t0
, rd
);
4528 tcg_temp_free_i64(t0
);
4529 tcg_temp_free_i64(t1
);
4532 static void gen_loongson_lswc2(DisasContext
*ctx
, int rt
,
4537 #if defined(TARGET_MIPS64)
4538 int lsq_rt1
= ctx
->opcode
& 0x1f;
4539 int lsq_offset
= sextract32(ctx
->opcode
, 6, 9) << 4;
4541 int shf_offset
= sextract32(ctx
->opcode
, 6, 8);
4543 t0
= tcg_temp_new();
4545 switch (MASK_LOONGSON_GSLSQ(ctx
->opcode
)) {
4546 #if defined(TARGET_MIPS64)
4548 t1
= tcg_temp_new();
4549 gen_base_offset_addr(ctx
, t0
, rs
, lsq_offset
);
4550 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
|
4551 ctx
->default_tcg_memop_mask
);
4552 gen_base_offset_addr(ctx
, t0
, rs
, lsq_offset
+ 8);
4553 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
|
4554 ctx
->default_tcg_memop_mask
);
4555 gen_store_gpr(t1
, rt
);
4556 gen_store_gpr(t0
, lsq_rt1
);
4560 check_cp1_enabled(ctx
);
4561 t1
= tcg_temp_new();
4562 gen_base_offset_addr(ctx
, t0
, rs
, lsq_offset
);
4563 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
|
4564 ctx
->default_tcg_memop_mask
);
4565 gen_base_offset_addr(ctx
, t0
, rs
, lsq_offset
+ 8);
4566 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
|
4567 ctx
->default_tcg_memop_mask
);
4568 gen_store_fpr64(ctx
, t1
, rt
);
4569 gen_store_fpr64(ctx
, t0
, lsq_rt1
);
4573 t1
= tcg_temp_new();
4574 gen_base_offset_addr(ctx
, t0
, rs
, lsq_offset
);
4575 gen_load_gpr(t1
, rt
);
4576 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
|
4577 ctx
->default_tcg_memop_mask
);
4578 gen_base_offset_addr(ctx
, t0
, rs
, lsq_offset
+ 8);
4579 gen_load_gpr(t1
, lsq_rt1
);
4580 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
|
4581 ctx
->default_tcg_memop_mask
);
4585 check_cp1_enabled(ctx
);
4586 t1
= tcg_temp_new();
4587 gen_base_offset_addr(ctx
, t0
, rs
, lsq_offset
);
4588 gen_load_fpr64(ctx
, t1
, rt
);
4589 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
|
4590 ctx
->default_tcg_memop_mask
);
4591 gen_base_offset_addr(ctx
, t0
, rs
, lsq_offset
+ 8);
4592 gen_load_fpr64(ctx
, t1
, lsq_rt1
);
4593 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
|
4594 ctx
->default_tcg_memop_mask
);
4599 switch (MASK_LOONGSON_GSSHFLS(ctx
->opcode
)) {
4601 check_cp1_enabled(ctx
);
4602 gen_base_offset_addr(ctx
, t0
, rs
, shf_offset
);
4603 t1
= tcg_temp_new();
4604 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
4605 tcg_gen_andi_tl(t1
, t0
, 3);
4606 #ifndef TARGET_WORDS_BIGENDIAN
4607 tcg_gen_xori_tl(t1
, t1
, 3);
4609 tcg_gen_shli_tl(t1
, t1
, 3);
4610 tcg_gen_andi_tl(t0
, t0
, ~3);
4611 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEUL
);
4612 tcg_gen_shl_tl(t0
, t0
, t1
);
4613 t2
= tcg_const_tl(-1);
4614 tcg_gen_shl_tl(t2
, t2
, t1
);
4615 fp0
= tcg_temp_new_i32();
4616 gen_load_fpr32(ctx
, fp0
, rt
);
4617 tcg_gen_ext_i32_tl(t1
, fp0
);
4618 tcg_gen_andc_tl(t1
, t1
, t2
);
4620 tcg_gen_or_tl(t0
, t0
, t1
);
4622 #if defined(TARGET_MIPS64)
4623 tcg_gen_extrl_i64_i32(fp0
, t0
);
4625 tcg_gen_ext32s_tl(fp0
, t0
);
4627 gen_store_fpr32(ctx
, fp0
, rt
);
4628 tcg_temp_free_i32(fp0
);
4631 check_cp1_enabled(ctx
);
4632 gen_base_offset_addr(ctx
, t0
, rs
, shf_offset
);
4633 t1
= tcg_temp_new();
4634 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
4635 tcg_gen_andi_tl(t1
, t0
, 3);
4636 #ifdef TARGET_WORDS_BIGENDIAN
4637 tcg_gen_xori_tl(t1
, t1
, 3);
4639 tcg_gen_shli_tl(t1
, t1
, 3);
4640 tcg_gen_andi_tl(t0
, t0
, ~3);
4641 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEUL
);
4642 tcg_gen_shr_tl(t0
, t0
, t1
);
4643 tcg_gen_xori_tl(t1
, t1
, 31);
4644 t2
= tcg_const_tl(0xfffffffeull
);
4645 tcg_gen_shl_tl(t2
, t2
, t1
);
4646 fp0
= tcg_temp_new_i32();
4647 gen_load_fpr32(ctx
, fp0
, rt
);
4648 tcg_gen_ext_i32_tl(t1
, fp0
);
4649 tcg_gen_and_tl(t1
, t1
, t2
);
4651 tcg_gen_or_tl(t0
, t0
, t1
);
4653 #if defined(TARGET_MIPS64)
4654 tcg_gen_extrl_i64_i32(fp0
, t0
);
4656 tcg_gen_ext32s_tl(fp0
, t0
);
4658 gen_store_fpr32(ctx
, fp0
, rt
);
4659 tcg_temp_free_i32(fp0
);
4661 #if defined(TARGET_MIPS64)
4663 check_cp1_enabled(ctx
);
4664 gen_base_offset_addr(ctx
, t0
, rs
, shf_offset
);
4665 t1
= tcg_temp_new();
4666 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
4667 tcg_gen_andi_tl(t1
, t0
, 7);
4668 #ifndef TARGET_WORDS_BIGENDIAN
4669 tcg_gen_xori_tl(t1
, t1
, 7);
4671 tcg_gen_shli_tl(t1
, t1
, 3);
4672 tcg_gen_andi_tl(t0
, t0
, ~7);
4673 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
);
4674 tcg_gen_shl_tl(t0
, t0
, t1
);
4675 t2
= tcg_const_tl(-1);
4676 tcg_gen_shl_tl(t2
, t2
, t1
);
4677 gen_load_fpr64(ctx
, t1
, rt
);
4678 tcg_gen_andc_tl(t1
, t1
, t2
);
4680 tcg_gen_or_tl(t0
, t0
, t1
);
4682 gen_store_fpr64(ctx
, t0
, rt
);
4685 check_cp1_enabled(ctx
);
4686 gen_base_offset_addr(ctx
, t0
, rs
, shf_offset
);
4687 t1
= tcg_temp_new();
4688 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
4689 tcg_gen_andi_tl(t1
, t0
, 7);
4690 #ifdef TARGET_WORDS_BIGENDIAN
4691 tcg_gen_xori_tl(t1
, t1
, 7);
4693 tcg_gen_shli_tl(t1
, t1
, 3);
4694 tcg_gen_andi_tl(t0
, t0
, ~7);
4695 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
);
4696 tcg_gen_shr_tl(t0
, t0
, t1
);
4697 tcg_gen_xori_tl(t1
, t1
, 63);
4698 t2
= tcg_const_tl(0xfffffffffffffffeull
);
4699 tcg_gen_shl_tl(t2
, t2
, t1
);
4700 gen_load_fpr64(ctx
, t1
, rt
);
4701 tcg_gen_and_tl(t1
, t1
, t2
);
4703 tcg_gen_or_tl(t0
, t0
, t1
);
4705 gen_store_fpr64(ctx
, t0
, rt
);
4709 MIPS_INVAL("loongson_gsshfl");
4710 gen_reserved_instruction(ctx
);
4715 switch (MASK_LOONGSON_GSSHFLS(ctx
->opcode
)) {
4717 check_cp1_enabled(ctx
);
4718 t1
= tcg_temp_new();
4719 gen_base_offset_addr(ctx
, t0
, rs
, shf_offset
);
4720 fp0
= tcg_temp_new_i32();
4721 gen_load_fpr32(ctx
, fp0
, rt
);
4722 tcg_gen_ext_i32_tl(t1
, fp0
);
4723 gen_helper_0e2i(swl
, t1
, t0
, ctx
->mem_idx
);
4724 tcg_temp_free_i32(fp0
);
4728 check_cp1_enabled(ctx
);
4729 t1
= tcg_temp_new();
4730 gen_base_offset_addr(ctx
, t0
, rs
, shf_offset
);
4731 fp0
= tcg_temp_new_i32();
4732 gen_load_fpr32(ctx
, fp0
, rt
);
4733 tcg_gen_ext_i32_tl(t1
, fp0
);
4734 gen_helper_0e2i(swr
, t1
, t0
, ctx
->mem_idx
);
4735 tcg_temp_free_i32(fp0
);
4738 #if defined(TARGET_MIPS64)
4740 check_cp1_enabled(ctx
);
4741 t1
= tcg_temp_new();
4742 gen_base_offset_addr(ctx
, t0
, rs
, shf_offset
);
4743 gen_load_fpr64(ctx
, t1
, rt
);
4744 gen_helper_0e2i(sdl
, t1
, t0
, ctx
->mem_idx
);
4748 check_cp1_enabled(ctx
);
4749 t1
= tcg_temp_new();
4750 gen_base_offset_addr(ctx
, t0
, rs
, shf_offset
);
4751 gen_load_fpr64(ctx
, t1
, rt
);
4752 gen_helper_0e2i(sdr
, t1
, t0
, ctx
->mem_idx
);
4757 MIPS_INVAL("loongson_gsshfs");
4758 gen_reserved_instruction(ctx
);
4763 MIPS_INVAL("loongson_gslsq");
4764 gen_reserved_instruction(ctx
);
4770 /* Loongson EXT LDC2/SDC2 */
4771 static void gen_loongson_lsdc2(DisasContext
*ctx
, int rt
,
4774 int offset
= sextract32(ctx
->opcode
, 3, 8);
4775 uint32_t opc
= MASK_LOONGSON_LSDC2(ctx
->opcode
);
4779 /* Pre-conditions */
4785 /* prefetch, implement as NOP */
4796 #if defined(TARGET_MIPS64)
4799 check_cp1_enabled(ctx
);
4800 /* prefetch, implement as NOP */
4806 #if defined(TARGET_MIPS64)
4809 check_cp1_enabled(ctx
);
4812 MIPS_INVAL("loongson_lsdc2");
4813 gen_reserved_instruction(ctx
);
4818 t0
= tcg_temp_new();
4820 gen_base_offset_addr(ctx
, t0
, rs
, offset
);
4821 gen_op_addr_add(ctx
, t0
, cpu_gpr
[rd
], t0
);
4825 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_SB
);
4826 gen_store_gpr(t0
, rt
);
4829 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESW
|
4830 ctx
->default_tcg_memop_mask
);
4831 gen_store_gpr(t0
, rt
);
4834 gen_base_offset_addr(ctx
, t0
, rs
, offset
);
4836 gen_op_addr_add(ctx
, t0
, cpu_gpr
[rd
], t0
);
4838 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESL
|
4839 ctx
->default_tcg_memop_mask
);
4840 gen_store_gpr(t0
, rt
);
4842 #if defined(TARGET_MIPS64)
4844 gen_base_offset_addr(ctx
, t0
, rs
, offset
);
4846 gen_op_addr_add(ctx
, t0
, cpu_gpr
[rd
], t0
);
4848 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
|
4849 ctx
->default_tcg_memop_mask
);
4850 gen_store_gpr(t0
, rt
);
4854 check_cp1_enabled(ctx
);
4855 gen_base_offset_addr(ctx
, t0
, rs
, offset
);
4857 gen_op_addr_add(ctx
, t0
, cpu_gpr
[rd
], t0
);
4859 fp0
= tcg_temp_new_i32();
4860 tcg_gen_qemu_ld_i32(fp0
, t0
, ctx
->mem_idx
, MO_TESL
|
4861 ctx
->default_tcg_memop_mask
);
4862 gen_store_fpr32(ctx
, fp0
, rt
);
4863 tcg_temp_free_i32(fp0
);
4865 #if defined(TARGET_MIPS64)
4867 check_cp1_enabled(ctx
);
4868 gen_base_offset_addr(ctx
, t0
, rs
, offset
);
4870 gen_op_addr_add(ctx
, t0
, cpu_gpr
[rd
], t0
);
4872 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
|
4873 ctx
->default_tcg_memop_mask
);
4874 gen_store_fpr64(ctx
, t0
, rt
);
4878 t1
= tcg_temp_new();
4879 gen_load_gpr(t1
, rt
);
4880 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_SB
);
4884 t1
= tcg_temp_new();
4885 gen_load_gpr(t1
, rt
);
4886 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUW
|
4887 ctx
->default_tcg_memop_mask
);
4891 t1
= tcg_temp_new();
4892 gen_load_gpr(t1
, rt
);
4893 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
|
4894 ctx
->default_tcg_memop_mask
);
4897 #if defined(TARGET_MIPS64)
4899 t1
= tcg_temp_new();
4900 gen_load_gpr(t1
, rt
);
4901 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
|
4902 ctx
->default_tcg_memop_mask
);
4907 fp0
= tcg_temp_new_i32();
4908 gen_load_fpr32(ctx
, fp0
, rt
);
4909 tcg_gen_qemu_st_i32(fp0
, t0
, ctx
->mem_idx
, MO_TEUL
|
4910 ctx
->default_tcg_memop_mask
);
4911 tcg_temp_free_i32(fp0
);
4913 #if defined(TARGET_MIPS64)
4915 t1
= tcg_temp_new();
4916 gen_load_fpr64(ctx
, t1
, rt
);
4917 tcg_gen_qemu_st_i64(t1
, t0
, ctx
->mem_idx
, MO_TEQ
|
4918 ctx
->default_tcg_memop_mask
);
4930 static void gen_trap(DisasContext
*ctx
, uint32_t opc
,
4931 int rs
, int rt
, int16_t imm
)
4934 TCGv t0
= tcg_temp_new();
4935 TCGv t1
= tcg_temp_new();
4938 /* Load needed operands */
4946 /* Compare two registers */
4948 gen_load_gpr(t0
, rs
);
4949 gen_load_gpr(t1
, rt
);
4959 /* Compare register to immediate */
4960 if (rs
!= 0 || imm
!= 0) {
4961 gen_load_gpr(t0
, rs
);
4962 tcg_gen_movi_tl(t1
, (int32_t)imm
);
4969 case OPC_TEQ
: /* rs == rs */
4970 case OPC_TEQI
: /* r0 == 0 */
4971 case OPC_TGE
: /* rs >= rs */
4972 case OPC_TGEI
: /* r0 >= 0 */
4973 case OPC_TGEU
: /* rs >= rs unsigned */
4974 case OPC_TGEIU
: /* r0 >= 0 unsigned */
4976 generate_exception_end(ctx
, EXCP_TRAP
);
4978 case OPC_TLT
: /* rs < rs */
4979 case OPC_TLTI
: /* r0 < 0 */
4980 case OPC_TLTU
: /* rs < rs unsigned */
4981 case OPC_TLTIU
: /* r0 < 0 unsigned */
4982 case OPC_TNE
: /* rs != rs */
4983 case OPC_TNEI
: /* r0 != 0 */
4984 /* Never trap: treat as NOP. */
4988 TCGLabel
*l1
= gen_new_label();
4993 tcg_gen_brcond_tl(TCG_COND_NE
, t0
, t1
, l1
);
4997 tcg_gen_brcond_tl(TCG_COND_LT
, t0
, t1
, l1
);
5001 tcg_gen_brcond_tl(TCG_COND_LTU
, t0
, t1
, l1
);
5005 tcg_gen_brcond_tl(TCG_COND_GE
, t0
, t1
, l1
);
5009 tcg_gen_brcond_tl(TCG_COND_GEU
, t0
, t1
, l1
);
5013 tcg_gen_brcond_tl(TCG_COND_EQ
, t0
, t1
, l1
);
5016 generate_exception(ctx
, EXCP_TRAP
);
5023 static inline bool use_goto_tb(DisasContext
*ctx
, target_ulong dest
)
5025 if (unlikely(ctx
->base
.singlestep_enabled
)) {
5029 #ifndef CONFIG_USER_ONLY
5030 return (ctx
->base
.tb
->pc
& TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
);
5036 static inline void gen_goto_tb(DisasContext
*ctx
, int n
, target_ulong dest
)
5038 if (use_goto_tb(ctx
, dest
)) {
5041 tcg_gen_exit_tb(ctx
->base
.tb
, n
);
5044 if (ctx
->base
.singlestep_enabled
) {
5045 save_cpu_state(ctx
, 0);
5046 gen_helper_raise_exception_debug(cpu_env
);
5048 tcg_gen_lookup_and_goto_ptr();
5052 /* Branches (before delay slot) */
5053 static void gen_compute_branch(DisasContext
*ctx
, uint32_t opc
,
5055 int rs
, int rt
, int32_t offset
,
5058 target_ulong btgt
= -1;
5060 int bcond_compute
= 0;
5061 TCGv t0
= tcg_temp_new();
5062 TCGv t1
= tcg_temp_new();
5064 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
5065 #ifdef MIPS_DEBUG_DISAS
5066 LOG_DISAS("Branch in delay / forbidden slot at PC 0x"
5067 TARGET_FMT_lx
"\n", ctx
->base
.pc_next
);
5069 gen_reserved_instruction(ctx
);
5073 /* Load needed operands */
5079 /* Compare two registers */
5081 gen_load_gpr(t0
, rs
);
5082 gen_load_gpr(t1
, rt
);
5085 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ offset
;
5099 /* Compare to zero */
5101 gen_load_gpr(t0
, rs
);
5104 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ offset
;
5107 #if defined(TARGET_MIPS64)
5109 tcg_gen_andi_tl(t0
, cpu_dspctrl
, 0x7F);
5111 tcg_gen_andi_tl(t0
, cpu_dspctrl
, 0x3F);
5114 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ offset
;
5119 /* Jump to immediate */
5120 btgt
= ((ctx
->base
.pc_next
+ insn_bytes
) & (int32_t)0xF0000000) |
5125 /* Jump to register */
5126 if (offset
!= 0 && offset
!= 16) {
5128 * Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
5129 * others are reserved.
5131 MIPS_INVAL("jump hint");
5132 gen_reserved_instruction(ctx
);
5135 gen_load_gpr(btarget
, rs
);
5138 MIPS_INVAL("branch/jump");
5139 gen_reserved_instruction(ctx
);
5142 if (bcond_compute
== 0) {
5143 /* No condition to be computed */
5145 case OPC_BEQ
: /* rx == rx */
5146 case OPC_BEQL
: /* rx == rx likely */
5147 case OPC_BGEZ
: /* 0 >= 0 */
5148 case OPC_BGEZL
: /* 0 >= 0 likely */
5149 case OPC_BLEZ
: /* 0 <= 0 */
5150 case OPC_BLEZL
: /* 0 <= 0 likely */
5152 ctx
->hflags
|= MIPS_HFLAG_B
;
5154 case OPC_BGEZAL
: /* 0 >= 0 */
5155 case OPC_BGEZALL
: /* 0 >= 0 likely */
5156 /* Always take and link */
5158 ctx
->hflags
|= MIPS_HFLAG_B
;
5160 case OPC_BNE
: /* rx != rx */
5161 case OPC_BGTZ
: /* 0 > 0 */
5162 case OPC_BLTZ
: /* 0 < 0 */
5165 case OPC_BLTZAL
: /* 0 < 0 */
5167 * Handle as an unconditional branch to get correct delay
5171 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ delayslot_size
;
5172 ctx
->hflags
|= MIPS_HFLAG_B
;
5174 case OPC_BLTZALL
: /* 0 < 0 likely */
5175 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 8);
5176 /* Skip the instruction in the delay slot */
5177 ctx
->base
.pc_next
+= 4;
5179 case OPC_BNEL
: /* rx != rx likely */
5180 case OPC_BGTZL
: /* 0 > 0 likely */
5181 case OPC_BLTZL
: /* 0 < 0 likely */
5182 /* Skip the instruction in the delay slot */
5183 ctx
->base
.pc_next
+= 4;
5186 ctx
->hflags
|= MIPS_HFLAG_B
;
5189 ctx
->hflags
|= MIPS_HFLAG_BX
;
5193 ctx
->hflags
|= MIPS_HFLAG_B
;
5196 ctx
->hflags
|= MIPS_HFLAG_BR
;
5200 ctx
->hflags
|= MIPS_HFLAG_BR
;
5203 MIPS_INVAL("branch/jump");
5204 gen_reserved_instruction(ctx
);
5210 tcg_gen_setcond_tl(TCG_COND_EQ
, bcond
, t0
, t1
);
5213 tcg_gen_setcond_tl(TCG_COND_EQ
, bcond
, t0
, t1
);
5216 tcg_gen_setcond_tl(TCG_COND_NE
, bcond
, t0
, t1
);
5219 tcg_gen_setcond_tl(TCG_COND_NE
, bcond
, t0
, t1
);
5222 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
5225 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
5228 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
5232 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
5236 tcg_gen_setcondi_tl(TCG_COND_GT
, bcond
, t0
, 0);
5239 tcg_gen_setcondi_tl(TCG_COND_GT
, bcond
, t0
, 0);
5242 tcg_gen_setcondi_tl(TCG_COND_LE
, bcond
, t0
, 0);
5245 tcg_gen_setcondi_tl(TCG_COND_LE
, bcond
, t0
, 0);
5248 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
5251 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
5254 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 32);
5256 #if defined(TARGET_MIPS64)
5258 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 64);
5262 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
5265 ctx
->hflags
|= MIPS_HFLAG_BC
;
5268 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
5271 ctx
->hflags
|= MIPS_HFLAG_BL
;
5274 MIPS_INVAL("conditional branch/jump");
5275 gen_reserved_instruction(ctx
);
5280 ctx
->btarget
= btgt
;
5282 switch (delayslot_size
) {
5284 ctx
->hflags
|= MIPS_HFLAG_BDS16
;
5287 ctx
->hflags
|= MIPS_HFLAG_BDS32
;
5292 int post_delay
= insn_bytes
+ delayslot_size
;
5293 int lowbit
= !!(ctx
->hflags
& MIPS_HFLAG_M16
);
5295 tcg_gen_movi_tl(cpu_gpr
[blink
],
5296 ctx
->base
.pc_next
+ post_delay
+ lowbit
);
5300 if (insn_bytes
== 2) {
5301 ctx
->hflags
|= MIPS_HFLAG_B16
;
5308 /* nanoMIPS Branches */
5309 static void gen_compute_branch_nm(DisasContext
*ctx
, uint32_t opc
,
5311 int rs
, int rt
, int32_t offset
)
5313 target_ulong btgt
= -1;
5314 int bcond_compute
= 0;
5315 TCGv t0
= tcg_temp_new();
5316 TCGv t1
= tcg_temp_new();
5318 /* Load needed operands */
5322 /* Compare two registers */
5324 gen_load_gpr(t0
, rs
);
5325 gen_load_gpr(t1
, rt
);
5328 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ offset
;
5331 /* Compare to zero */
5333 gen_load_gpr(t0
, rs
);
5336 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ offset
;
5339 tcg_gen_andi_tl(t0
, cpu_dspctrl
, 0x3F);
5341 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ offset
;
5345 /* Jump to register */
5346 if (offset
!= 0 && offset
!= 16) {
5348 * Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
5349 * others are reserved.
5351 MIPS_INVAL("jump hint");
5352 gen_reserved_instruction(ctx
);
5355 gen_load_gpr(btarget
, rs
);
5358 MIPS_INVAL("branch/jump");
5359 gen_reserved_instruction(ctx
);
5362 if (bcond_compute
== 0) {
5363 /* No condition to be computed */
5365 case OPC_BEQ
: /* rx == rx */
5367 ctx
->hflags
|= MIPS_HFLAG_B
;
5369 case OPC_BGEZAL
: /* 0 >= 0 */
5370 /* Always take and link */
5371 tcg_gen_movi_tl(cpu_gpr
[31],
5372 ctx
->base
.pc_next
+ insn_bytes
);
5373 ctx
->hflags
|= MIPS_HFLAG_B
;
5375 case OPC_BNE
: /* rx != rx */
5376 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 8);
5377 /* Skip the instruction in the delay slot */
5378 ctx
->base
.pc_next
+= 4;
5381 ctx
->hflags
|= MIPS_HFLAG_BR
;
5385 tcg_gen_movi_tl(cpu_gpr
[rt
],
5386 ctx
->base
.pc_next
+ insn_bytes
);
5388 ctx
->hflags
|= MIPS_HFLAG_BR
;
5391 MIPS_INVAL("branch/jump");
5392 gen_reserved_instruction(ctx
);
5398 tcg_gen_setcond_tl(TCG_COND_EQ
, bcond
, t0
, t1
);
5401 tcg_gen_setcond_tl(TCG_COND_NE
, bcond
, t0
, t1
);
5404 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
5405 tcg_gen_movi_tl(cpu_gpr
[31],
5406 ctx
->base
.pc_next
+ insn_bytes
);
5409 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 32);
5411 ctx
->hflags
|= MIPS_HFLAG_BC
;
5414 MIPS_INVAL("conditional branch/jump");
5415 gen_reserved_instruction(ctx
);
5420 ctx
->btarget
= btgt
;
5423 if (insn_bytes
== 2) {
5424 ctx
->hflags
|= MIPS_HFLAG_B16
;
5431 /* special3 bitfield operations */
5432 static void gen_bitops(DisasContext
*ctx
, uint32_t opc
, int rt
,
5433 int rs
, int lsb
, int msb
)
5435 TCGv t0
= tcg_temp_new();
5436 TCGv t1
= tcg_temp_new();
5438 gen_load_gpr(t1
, rs
);
5441 if (lsb
+ msb
> 31) {
5445 tcg_gen_extract_tl(t0
, t1
, lsb
, msb
+ 1);
5448 * The two checks together imply that lsb == 0,
5449 * so this is a simple sign-extension.
5451 tcg_gen_ext32s_tl(t0
, t1
);
5454 #if defined(TARGET_MIPS64)
5463 if (lsb
+ msb
> 63) {
5466 tcg_gen_extract_tl(t0
, t1
, lsb
, msb
+ 1);
5473 gen_load_gpr(t0
, rt
);
5474 tcg_gen_deposit_tl(t0
, t0
, t1
, lsb
, msb
- lsb
+ 1);
5475 tcg_gen_ext32s_tl(t0
, t0
);
5477 #if defined(TARGET_MIPS64)
5488 gen_load_gpr(t0
, rt
);
5489 tcg_gen_deposit_tl(t0
, t0
, t1
, lsb
, msb
- lsb
+ 1);
5494 MIPS_INVAL("bitops");
5495 gen_reserved_instruction(ctx
);
5500 gen_store_gpr(t0
, rt
);
5505 static void gen_bshfl(DisasContext
*ctx
, uint32_t op2
, int rt
, int rd
)
5510 /* If no destination, treat it as a NOP. */
5514 t0
= tcg_temp_new();
5515 gen_load_gpr(t0
, rt
);
5519 TCGv t1
= tcg_temp_new();
5520 TCGv t2
= tcg_const_tl(0x00FF00FF);
5522 tcg_gen_shri_tl(t1
, t0
, 8);
5523 tcg_gen_and_tl(t1
, t1
, t2
);
5524 tcg_gen_and_tl(t0
, t0
, t2
);
5525 tcg_gen_shli_tl(t0
, t0
, 8);
5526 tcg_gen_or_tl(t0
, t0
, t1
);
5529 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
5533 tcg_gen_ext8s_tl(cpu_gpr
[rd
], t0
);
5536 tcg_gen_ext16s_tl(cpu_gpr
[rd
], t0
);
5538 #if defined(TARGET_MIPS64)
5541 TCGv t1
= tcg_temp_new();
5542 TCGv t2
= tcg_const_tl(0x00FF00FF00FF00FFULL
);
5544 tcg_gen_shri_tl(t1
, t0
, 8);
5545 tcg_gen_and_tl(t1
, t1
, t2
);
5546 tcg_gen_and_tl(t0
, t0
, t2
);
5547 tcg_gen_shli_tl(t0
, t0
, 8);
5548 tcg_gen_or_tl(cpu_gpr
[rd
], t0
, t1
);
5555 TCGv t1
= tcg_temp_new();
5556 TCGv t2
= tcg_const_tl(0x0000FFFF0000FFFFULL
);
5558 tcg_gen_shri_tl(t1
, t0
, 16);
5559 tcg_gen_and_tl(t1
, t1
, t2
);
5560 tcg_gen_and_tl(t0
, t0
, t2
);
5561 tcg_gen_shli_tl(t0
, t0
, 16);
5562 tcg_gen_or_tl(t0
, t0
, t1
);
5563 tcg_gen_shri_tl(t1
, t0
, 32);
5564 tcg_gen_shli_tl(t0
, t0
, 32);
5565 tcg_gen_or_tl(cpu_gpr
[rd
], t0
, t1
);
5572 MIPS_INVAL("bsfhl");
5573 gen_reserved_instruction(ctx
);
5580 static void gen_align_bits(DisasContext
*ctx
, int wordsz
, int rd
, int rs
,
5588 t0
= tcg_temp_new();
5589 if (bits
== 0 || bits
== wordsz
) {
5591 gen_load_gpr(t0
, rt
);
5593 gen_load_gpr(t0
, rs
);
5597 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
5599 #if defined(TARGET_MIPS64)
5601 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
5606 TCGv t1
= tcg_temp_new();
5607 gen_load_gpr(t0
, rt
);
5608 gen_load_gpr(t1
, rs
);
5612 TCGv_i64 t2
= tcg_temp_new_i64();
5613 tcg_gen_concat_tl_i64(t2
, t1
, t0
);
5614 tcg_gen_shri_i64(t2
, t2
, 32 - bits
);
5615 gen_move_low32(cpu_gpr
[rd
], t2
);
5616 tcg_temp_free_i64(t2
);
5619 #if defined(TARGET_MIPS64)
5621 tcg_gen_shli_tl(t0
, t0
, bits
);
5622 tcg_gen_shri_tl(t1
, t1
, 64 - bits
);
5623 tcg_gen_or_tl(cpu_gpr
[rd
], t1
, t0
);
5633 static void gen_align(DisasContext
*ctx
, int wordsz
, int rd
, int rs
, int rt
,
5636 gen_align_bits(ctx
, wordsz
, rd
, rs
, rt
, bp
* 8);
5639 static void gen_ext(DisasContext
*ctx
, int wordsz
, int rd
, int rs
, int rt
,
5642 gen_align_bits(ctx
, wordsz
, rd
, rs
, rt
, wordsz
- shift
);
5645 static void gen_bitswap(DisasContext
*ctx
, int opc
, int rd
, int rt
)
5652 t0
= tcg_temp_new();
5653 gen_load_gpr(t0
, rt
);
5656 gen_helper_bitswap(cpu_gpr
[rd
], t0
);
5658 #if defined(TARGET_MIPS64)
5660 gen_helper_dbitswap(cpu_gpr
[rd
], t0
);
5667 #ifndef CONFIG_USER_ONLY
5668 /* CP0 (MMU and control) */
5669 static inline void gen_mthc0_entrylo(TCGv arg
, target_ulong off
)
5671 TCGv_i64 t0
= tcg_temp_new_i64();
5672 TCGv_i64 t1
= tcg_temp_new_i64();
5674 tcg_gen_ext_tl_i64(t0
, arg
);
5675 tcg_gen_ld_i64(t1
, cpu_env
, off
);
5676 #if defined(TARGET_MIPS64)
5677 tcg_gen_deposit_i64(t1
, t1
, t0
, 30, 32);
5679 tcg_gen_concat32_i64(t1
, t1
, t0
);
5681 tcg_gen_st_i64(t1
, cpu_env
, off
);
5682 tcg_temp_free_i64(t1
);
5683 tcg_temp_free_i64(t0
);
5686 static inline void gen_mthc0_store64(TCGv arg
, target_ulong off
)
5688 TCGv_i64 t0
= tcg_temp_new_i64();
5689 TCGv_i64 t1
= tcg_temp_new_i64();
5691 tcg_gen_ext_tl_i64(t0
, arg
);
5692 tcg_gen_ld_i64(t1
, cpu_env
, off
);
5693 tcg_gen_concat32_i64(t1
, t1
, t0
);
5694 tcg_gen_st_i64(t1
, cpu_env
, off
);
5695 tcg_temp_free_i64(t1
);
5696 tcg_temp_free_i64(t0
);
5699 static inline void gen_mfhc0_entrylo(TCGv arg
, target_ulong off
)
5701 TCGv_i64 t0
= tcg_temp_new_i64();
5703 tcg_gen_ld_i64(t0
, cpu_env
, off
);
5704 #if defined(TARGET_MIPS64)
5705 tcg_gen_shri_i64(t0
, t0
, 30);
5707 tcg_gen_shri_i64(t0
, t0
, 32);
5709 gen_move_low32(arg
, t0
);
5710 tcg_temp_free_i64(t0
);
5713 static inline void gen_mfhc0_load64(TCGv arg
, target_ulong off
, int shift
)
5715 TCGv_i64 t0
= tcg_temp_new_i64();
5717 tcg_gen_ld_i64(t0
, cpu_env
, off
);
5718 tcg_gen_shri_i64(t0
, t0
, 32 + shift
);
5719 gen_move_low32(arg
, t0
);
5720 tcg_temp_free_i64(t0
);
5723 static inline void gen_mfc0_load32(TCGv arg
, target_ulong off
)
5725 TCGv_i32 t0
= tcg_temp_new_i32();
5727 tcg_gen_ld_i32(t0
, cpu_env
, off
);
5728 tcg_gen_ext_i32_tl(arg
, t0
);
5729 tcg_temp_free_i32(t0
);
5732 static inline void gen_mfc0_load64(TCGv arg
, target_ulong off
)
5734 tcg_gen_ld_tl(arg
, cpu_env
, off
);
5735 tcg_gen_ext32s_tl(arg
, arg
);
5738 static inline void gen_mtc0_store32(TCGv arg
, target_ulong off
)
5740 TCGv_i32 t0
= tcg_temp_new_i32();
5742 tcg_gen_trunc_tl_i32(t0
, arg
);
5743 tcg_gen_st_i32(t0
, cpu_env
, off
);
5744 tcg_temp_free_i32(t0
);
5747 #define CP0_CHECK(c) \
5750 goto cp0_unimplemented; \
5754 static void gen_mfhc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
5756 const char *register_name
= "invalid";
5759 case CP0_REGISTER_02
:
5762 CP0_CHECK(ctx
->hflags
& MIPS_HFLAG_ELPA
);
5763 gen_mfhc0_entrylo(arg
, offsetof(CPUMIPSState
, CP0_EntryLo0
));
5764 register_name
= "EntryLo0";
5767 goto cp0_unimplemented
;
5770 case CP0_REGISTER_03
:
5772 case CP0_REG03__ENTRYLO1
:
5773 CP0_CHECK(ctx
->hflags
& MIPS_HFLAG_ELPA
);
5774 gen_mfhc0_entrylo(arg
, offsetof(CPUMIPSState
, CP0_EntryLo1
));
5775 register_name
= "EntryLo1";
5778 goto cp0_unimplemented
;
5781 case CP0_REGISTER_09
:
5783 case CP0_REG09__SAAR
:
5784 CP0_CHECK(ctx
->saar
);
5785 gen_helper_mfhc0_saar(arg
, cpu_env
);
5786 register_name
= "SAAR";
5789 goto cp0_unimplemented
;
5792 case CP0_REGISTER_17
:
5794 case CP0_REG17__LLADDR
:
5795 gen_mfhc0_load64(arg
, offsetof(CPUMIPSState
, CP0_LLAddr
),
5796 ctx
->CP0_LLAddr_shift
);
5797 register_name
= "LLAddr";
5799 case CP0_REG17__MAAR
:
5800 CP0_CHECK(ctx
->mrp
);
5801 gen_helper_mfhc0_maar(arg
, cpu_env
);
5802 register_name
= "MAAR";
5805 goto cp0_unimplemented
;
5808 case CP0_REGISTER_19
:
5810 case CP0_REG19__WATCHHI0
:
5811 case CP0_REG19__WATCHHI1
:
5812 case CP0_REG19__WATCHHI2
:
5813 case CP0_REG19__WATCHHI3
:
5814 case CP0_REG19__WATCHHI4
:
5815 case CP0_REG19__WATCHHI5
:
5816 case CP0_REG19__WATCHHI6
:
5817 case CP0_REG19__WATCHHI7
:
5818 /* upper 32 bits are only available when Config5MI != 0 */
5820 gen_mfhc0_load64(arg
, offsetof(CPUMIPSState
, CP0_WatchHi
[sel
]), 0);
5821 register_name
= "WatchHi";
5824 goto cp0_unimplemented
;
5827 case CP0_REGISTER_28
:
5833 gen_mfhc0_load64(arg
, offsetof(CPUMIPSState
, CP0_TagLo
), 0);
5834 register_name
= "TagLo";
5837 goto cp0_unimplemented
;
5841 goto cp0_unimplemented
;
5843 trace_mips_translate_c0("mfhc0", register_name
, reg
, sel
);
5847 qemu_log_mask(LOG_UNIMP
, "mfhc0 %s (reg %d sel %d)\n",
5848 register_name
, reg
, sel
);
5849 tcg_gen_movi_tl(arg
, 0);
5852 static void gen_mthc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
5854 const char *register_name
= "invalid";
5855 uint64_t mask
= ctx
->PAMask
>> 36;
5858 case CP0_REGISTER_02
:
5861 CP0_CHECK(ctx
->hflags
& MIPS_HFLAG_ELPA
);
5862 tcg_gen_andi_tl(arg
, arg
, mask
);
5863 gen_mthc0_entrylo(arg
, offsetof(CPUMIPSState
, CP0_EntryLo0
));
5864 register_name
= "EntryLo0";
5867 goto cp0_unimplemented
;
5870 case CP0_REGISTER_03
:
5872 case CP0_REG03__ENTRYLO1
:
5873 CP0_CHECK(ctx
->hflags
& MIPS_HFLAG_ELPA
);
5874 tcg_gen_andi_tl(arg
, arg
, mask
);
5875 gen_mthc0_entrylo(arg
, offsetof(CPUMIPSState
, CP0_EntryLo1
));
5876 register_name
= "EntryLo1";
5879 goto cp0_unimplemented
;
5882 case CP0_REGISTER_09
:
5884 case CP0_REG09__SAAR
:
5885 CP0_CHECK(ctx
->saar
);
5886 gen_helper_mthc0_saar(cpu_env
, arg
);
5887 register_name
= "SAAR";
5890 goto cp0_unimplemented
;
5893 case CP0_REGISTER_17
:
5895 case CP0_REG17__LLADDR
:
5897 * LLAddr is read-only (the only exception is bit 0 if LLB is
5898 * supported); the CP0_LLAddr_rw_bitmask does not seem to be
5899 * relevant for modern MIPS cores supporting MTHC0, therefore
5900 * treating MTHC0 to LLAddr as NOP.
5902 register_name
= "LLAddr";
5904 case CP0_REG17__MAAR
:
5905 CP0_CHECK(ctx
->mrp
);
5906 gen_helper_mthc0_maar(cpu_env
, arg
);
5907 register_name
= "MAAR";
5910 goto cp0_unimplemented
;
5913 case CP0_REGISTER_19
:
5915 case CP0_REG19__WATCHHI0
:
5916 case CP0_REG19__WATCHHI1
:
5917 case CP0_REG19__WATCHHI2
:
5918 case CP0_REG19__WATCHHI3
:
5919 case CP0_REG19__WATCHHI4
:
5920 case CP0_REG19__WATCHHI5
:
5921 case CP0_REG19__WATCHHI6
:
5922 case CP0_REG19__WATCHHI7
:
5923 /* upper 32 bits are only available when Config5MI != 0 */
5925 gen_helper_0e1i(mthc0_watchhi
, arg
, sel
);
5926 register_name
= "WatchHi";
5929 goto cp0_unimplemented
;
5932 case CP0_REGISTER_28
:
5938 tcg_gen_andi_tl(arg
, arg
, mask
);
5939 gen_mthc0_store64(arg
, offsetof(CPUMIPSState
, CP0_TagLo
));
5940 register_name
= "TagLo";
5943 goto cp0_unimplemented
;
5947 goto cp0_unimplemented
;
5949 trace_mips_translate_c0("mthc0", register_name
, reg
, sel
);
5953 qemu_log_mask(LOG_UNIMP
, "mthc0 %s (reg %d sel %d)\n",
5954 register_name
, reg
, sel
);
5957 static inline void gen_mfc0_unimplemented(DisasContext
*ctx
, TCGv arg
)
5959 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
5960 tcg_gen_movi_tl(arg
, 0);
5962 tcg_gen_movi_tl(arg
, ~0);
5966 static void gen_mfc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
5968 const char *register_name
= "invalid";
5971 check_insn(ctx
, ISA_MIPS_R1
);
5975 case CP0_REGISTER_00
:
5977 case CP0_REG00__INDEX
:
5978 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Index
));
5979 register_name
= "Index";
5981 case CP0_REG00__MVPCONTROL
:
5982 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5983 gen_helper_mfc0_mvpcontrol(arg
, cpu_env
);
5984 register_name
= "MVPControl";
5986 case CP0_REG00__MVPCONF0
:
5987 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5988 gen_helper_mfc0_mvpconf0(arg
, cpu_env
);
5989 register_name
= "MVPConf0";
5991 case CP0_REG00__MVPCONF1
:
5992 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5993 gen_helper_mfc0_mvpconf1(arg
, cpu_env
);
5994 register_name
= "MVPConf1";
5996 case CP0_REG00__VPCONTROL
:
5998 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPControl
));
5999 register_name
= "VPControl";
6002 goto cp0_unimplemented
;
6005 case CP0_REGISTER_01
:
6007 case CP0_REG01__RANDOM
:
6008 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS_R6
));
6009 gen_helper_mfc0_random(arg
, cpu_env
);
6010 register_name
= "Random";
6012 case CP0_REG01__VPECONTROL
:
6013 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6014 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEControl
));
6015 register_name
= "VPEControl";
6017 case CP0_REG01__VPECONF0
:
6018 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6019 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf0
));
6020 register_name
= "VPEConf0";
6022 case CP0_REG01__VPECONF1
:
6023 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6024 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf1
));
6025 register_name
= "VPEConf1";
6027 case CP0_REG01__YQMASK
:
6028 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6029 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_YQMask
));
6030 register_name
= "YQMask";
6032 case CP0_REG01__VPESCHEDULE
:
6033 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6034 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_VPESchedule
));
6035 register_name
= "VPESchedule";
6037 case CP0_REG01__VPESCHEFBACK
:
6038 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6039 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
6040 register_name
= "VPEScheFBack";
6042 case CP0_REG01__VPEOPT
:
6043 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6044 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEOpt
));
6045 register_name
= "VPEOpt";
6048 goto cp0_unimplemented
;
6051 case CP0_REGISTER_02
:
6053 case CP0_REG02__ENTRYLO0
:
6055 TCGv_i64 tmp
= tcg_temp_new_i64();
6056 tcg_gen_ld_i64(tmp
, cpu_env
,
6057 offsetof(CPUMIPSState
, CP0_EntryLo0
));
6058 #if defined(TARGET_MIPS64)
6060 /* Move RI/XI fields to bits 31:30 */
6061 tcg_gen_shri_tl(arg
, tmp
, CP0EnLo_XI
);
6062 tcg_gen_deposit_tl(tmp
, tmp
, arg
, 30, 2);
6065 gen_move_low32(arg
, tmp
);
6066 tcg_temp_free_i64(tmp
);
6068 register_name
= "EntryLo0";
6070 case CP0_REG02__TCSTATUS
:
6071 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6072 gen_helper_mfc0_tcstatus(arg
, cpu_env
);
6073 register_name
= "TCStatus";
6075 case CP0_REG02__TCBIND
:
6076 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6077 gen_helper_mfc0_tcbind(arg
, cpu_env
);
6078 register_name
= "TCBind";
6080 case CP0_REG02__TCRESTART
:
6081 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6082 gen_helper_mfc0_tcrestart(arg
, cpu_env
);
6083 register_name
= "TCRestart";
6085 case CP0_REG02__TCHALT
:
6086 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6087 gen_helper_mfc0_tchalt(arg
, cpu_env
);
6088 register_name
= "TCHalt";
6090 case CP0_REG02__TCCONTEXT
:
6091 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6092 gen_helper_mfc0_tccontext(arg
, cpu_env
);
6093 register_name
= "TCContext";
6095 case CP0_REG02__TCSCHEDULE
:
6096 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6097 gen_helper_mfc0_tcschedule(arg
, cpu_env
);
6098 register_name
= "TCSchedule";
6100 case CP0_REG02__TCSCHEFBACK
:
6101 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6102 gen_helper_mfc0_tcschefback(arg
, cpu_env
);
6103 register_name
= "TCScheFBack";
6106 goto cp0_unimplemented
;
6109 case CP0_REGISTER_03
:
6111 case CP0_REG03__ENTRYLO1
:
6113 TCGv_i64 tmp
= tcg_temp_new_i64();
6114 tcg_gen_ld_i64(tmp
, cpu_env
,
6115 offsetof(CPUMIPSState
, CP0_EntryLo1
));
6116 #if defined(TARGET_MIPS64)
6118 /* Move RI/XI fields to bits 31:30 */
6119 tcg_gen_shri_tl(arg
, tmp
, CP0EnLo_XI
);
6120 tcg_gen_deposit_tl(tmp
, tmp
, arg
, 30, 2);
6123 gen_move_low32(arg
, tmp
);
6124 tcg_temp_free_i64(tmp
);
6126 register_name
= "EntryLo1";
6128 case CP0_REG03__GLOBALNUM
:
6130 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_GlobalNumber
));
6131 register_name
= "GlobalNumber";
6134 goto cp0_unimplemented
;
6137 case CP0_REGISTER_04
:
6139 case CP0_REG04__CONTEXT
:
6140 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_Context
));
6141 tcg_gen_ext32s_tl(arg
, arg
);
6142 register_name
= "Context";
6144 case CP0_REG04__CONTEXTCONFIG
:
6146 /* gen_helper_mfc0_contextconfig(arg); */
6147 register_name
= "ContextConfig";
6148 goto cp0_unimplemented
;
6149 case CP0_REG04__USERLOCAL
:
6150 CP0_CHECK(ctx
->ulri
);
6151 tcg_gen_ld_tl(arg
, cpu_env
,
6152 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
6153 tcg_gen_ext32s_tl(arg
, arg
);
6154 register_name
= "UserLocal";
6156 case CP0_REG04__MMID
:
6158 gen_helper_mtc0_memorymapid(cpu_env
, arg
);
6159 register_name
= "MMID";
6162 goto cp0_unimplemented
;
6165 case CP0_REGISTER_05
:
6167 case CP0_REG05__PAGEMASK
:
6168 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageMask
));
6169 register_name
= "PageMask";
6171 case CP0_REG05__PAGEGRAIN
:
6172 check_insn(ctx
, ISA_MIPS_R2
);
6173 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageGrain
));
6174 register_name
= "PageGrain";
6176 case CP0_REG05__SEGCTL0
:
6178 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_SegCtl0
));
6179 tcg_gen_ext32s_tl(arg
, arg
);
6180 register_name
= "SegCtl0";
6182 case CP0_REG05__SEGCTL1
:
6184 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_SegCtl1
));
6185 tcg_gen_ext32s_tl(arg
, arg
);
6186 register_name
= "SegCtl1";
6188 case CP0_REG05__SEGCTL2
:
6190 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_SegCtl2
));
6191 tcg_gen_ext32s_tl(arg
, arg
);
6192 register_name
= "SegCtl2";
6194 case CP0_REG05__PWBASE
:
6196 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PWBase
));
6197 register_name
= "PWBase";
6199 case CP0_REG05__PWFIELD
:
6201 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PWField
));
6202 register_name
= "PWField";
6204 case CP0_REG05__PWSIZE
:
6206 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PWSize
));
6207 register_name
= "PWSize";
6210 goto cp0_unimplemented
;
6213 case CP0_REGISTER_06
:
6215 case CP0_REG06__WIRED
:
6216 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Wired
));
6217 register_name
= "Wired";
6219 case CP0_REG06__SRSCONF0
:
6220 check_insn(ctx
, ISA_MIPS_R2
);
6221 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf0
));
6222 register_name
= "SRSConf0";
6224 case CP0_REG06__SRSCONF1
:
6225 check_insn(ctx
, ISA_MIPS_R2
);
6226 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf1
));
6227 register_name
= "SRSConf1";
6229 case CP0_REG06__SRSCONF2
:
6230 check_insn(ctx
, ISA_MIPS_R2
);
6231 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf2
));
6232 register_name
= "SRSConf2";
6234 case CP0_REG06__SRSCONF3
:
6235 check_insn(ctx
, ISA_MIPS_R2
);
6236 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf3
));
6237 register_name
= "SRSConf3";
6239 case CP0_REG06__SRSCONF4
:
6240 check_insn(ctx
, ISA_MIPS_R2
);
6241 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf4
));
6242 register_name
= "SRSConf4";
6244 case CP0_REG06__PWCTL
:
6246 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PWCtl
));
6247 register_name
= "PWCtl";
6250 goto cp0_unimplemented
;
6253 case CP0_REGISTER_07
:
6255 case CP0_REG07__HWRENA
:
6256 check_insn(ctx
, ISA_MIPS_R2
);
6257 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_HWREna
));
6258 register_name
= "HWREna";
6261 goto cp0_unimplemented
;
6264 case CP0_REGISTER_08
:
6266 case CP0_REG08__BADVADDR
:
6267 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_BadVAddr
));
6268 tcg_gen_ext32s_tl(arg
, arg
);
6269 register_name
= "BadVAddr";
6271 case CP0_REG08__BADINSTR
:
6273 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstr
));
6274 register_name
= "BadInstr";
6276 case CP0_REG08__BADINSTRP
:
6278 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstrP
));
6279 register_name
= "BadInstrP";
6281 case CP0_REG08__BADINSTRX
:
6283 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstrX
));
6284 tcg_gen_andi_tl(arg
, arg
, ~0xffff);
6285 register_name
= "BadInstrX";
6288 goto cp0_unimplemented
;
6291 case CP0_REGISTER_09
:
6293 case CP0_REG09__COUNT
:
6294 /* Mark as an IO operation because we read the time. */
6295 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
6298 gen_helper_mfc0_count(arg
, cpu_env
);
6300 * Break the TB to be able to take timer interrupts immediately
6301 * after reading count. DISAS_STOP isn't sufficient, we need to
6302 * ensure we break completely out of translated code.
6304 gen_save_pc(ctx
->base
.pc_next
+ 4);
6305 ctx
->base
.is_jmp
= DISAS_EXIT
;
6306 register_name
= "Count";
6308 case CP0_REG09__SAARI
:
6309 CP0_CHECK(ctx
->saar
);
6310 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SAARI
));
6311 register_name
= "SAARI";
6313 case CP0_REG09__SAAR
:
6314 CP0_CHECK(ctx
->saar
);
6315 gen_helper_mfc0_saar(arg
, cpu_env
);
6316 register_name
= "SAAR";
6319 goto cp0_unimplemented
;
6322 case CP0_REGISTER_10
:
6324 case CP0_REG10__ENTRYHI
:
6325 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryHi
));
6326 tcg_gen_ext32s_tl(arg
, arg
);
6327 register_name
= "EntryHi";
6330 goto cp0_unimplemented
;
6333 case CP0_REGISTER_11
:
6335 case CP0_REG11__COMPARE
:
6336 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Compare
));
6337 register_name
= "Compare";
6339 /* 6,7 are implementation dependent */
6341 goto cp0_unimplemented
;
6344 case CP0_REGISTER_12
:
6346 case CP0_REG12__STATUS
:
6347 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Status
));
6348 register_name
= "Status";
6350 case CP0_REG12__INTCTL
:
6351 check_insn(ctx
, ISA_MIPS_R2
);
6352 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_IntCtl
));
6353 register_name
= "IntCtl";
6355 case CP0_REG12__SRSCTL
:
6356 check_insn(ctx
, ISA_MIPS_R2
);
6357 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
6358 register_name
= "SRSCtl";
6360 case CP0_REG12__SRSMAP
:
6361 check_insn(ctx
, ISA_MIPS_R2
);
6362 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
6363 register_name
= "SRSMap";
6366 goto cp0_unimplemented
;
6369 case CP0_REGISTER_13
:
6371 case CP0_REG13__CAUSE
:
6372 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Cause
));
6373 register_name
= "Cause";
6376 goto cp0_unimplemented
;
6379 case CP0_REGISTER_14
:
6381 case CP0_REG14__EPC
:
6382 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
6383 tcg_gen_ext32s_tl(arg
, arg
);
6384 register_name
= "EPC";
6387 goto cp0_unimplemented
;
6390 case CP0_REGISTER_15
:
6392 case CP0_REG15__PRID
:
6393 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PRid
));
6394 register_name
= "PRid";
6396 case CP0_REG15__EBASE
:
6397 check_insn(ctx
, ISA_MIPS_R2
);
6398 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EBase
));
6399 tcg_gen_ext32s_tl(arg
, arg
);
6400 register_name
= "EBase";
6402 case CP0_REG15__CMGCRBASE
:
6403 check_insn(ctx
, ISA_MIPS_R2
);
6404 CP0_CHECK(ctx
->cmgcr
);
6405 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_CMGCRBase
));
6406 tcg_gen_ext32s_tl(arg
, arg
);
6407 register_name
= "CMGCRBase";
6410 goto cp0_unimplemented
;
6413 case CP0_REGISTER_16
:
6415 case CP0_REG16__CONFIG
:
6416 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config0
));
6417 register_name
= "Config";
6419 case CP0_REG16__CONFIG1
:
6420 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config1
));
6421 register_name
= "Config1";
6423 case CP0_REG16__CONFIG2
:
6424 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config2
));
6425 register_name
= "Config2";
6427 case CP0_REG16__CONFIG3
:
6428 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config3
));
6429 register_name
= "Config3";
6431 case CP0_REG16__CONFIG4
:
6432 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config4
));
6433 register_name
= "Config4";
6435 case CP0_REG16__CONFIG5
:
6436 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config5
));
6437 register_name
= "Config5";
6439 /* 6,7 are implementation dependent */
6440 case CP0_REG16__CONFIG6
:
6441 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config6
));
6442 register_name
= "Config6";
6444 case CP0_REG16__CONFIG7
:
6445 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config7
));
6446 register_name
= "Config7";
6449 goto cp0_unimplemented
;
6452 case CP0_REGISTER_17
:
6454 case CP0_REG17__LLADDR
:
6455 gen_helper_mfc0_lladdr(arg
, cpu_env
);
6456 register_name
= "LLAddr";
6458 case CP0_REG17__MAAR
:
6459 CP0_CHECK(ctx
->mrp
);
6460 gen_helper_mfc0_maar(arg
, cpu_env
);
6461 register_name
= "MAAR";
6463 case CP0_REG17__MAARI
:
6464 CP0_CHECK(ctx
->mrp
);
6465 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_MAARI
));
6466 register_name
= "MAARI";
6469 goto cp0_unimplemented
;
6472 case CP0_REGISTER_18
:
6474 case CP0_REG18__WATCHLO0
:
6475 case CP0_REG18__WATCHLO1
:
6476 case CP0_REG18__WATCHLO2
:
6477 case CP0_REG18__WATCHLO3
:
6478 case CP0_REG18__WATCHLO4
:
6479 case CP0_REG18__WATCHLO5
:
6480 case CP0_REG18__WATCHLO6
:
6481 case CP0_REG18__WATCHLO7
:
6482 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
6483 gen_helper_1e0i(mfc0_watchlo
, arg
, sel
);
6484 register_name
= "WatchLo";
6487 goto cp0_unimplemented
;
6490 case CP0_REGISTER_19
:
6492 case CP0_REG19__WATCHHI0
:
6493 case CP0_REG19__WATCHHI1
:
6494 case CP0_REG19__WATCHHI2
:
6495 case CP0_REG19__WATCHHI3
:
6496 case CP0_REG19__WATCHHI4
:
6497 case CP0_REG19__WATCHHI5
:
6498 case CP0_REG19__WATCHHI6
:
6499 case CP0_REG19__WATCHHI7
:
6500 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
6501 gen_helper_1e0i(mfc0_watchhi
, arg
, sel
);
6502 register_name
= "WatchHi";
6505 goto cp0_unimplemented
;
6508 case CP0_REGISTER_20
:
6510 case CP0_REG20__XCONTEXT
:
6511 #if defined(TARGET_MIPS64)
6512 check_insn(ctx
, ISA_MIPS3
);
6513 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_XContext
));
6514 tcg_gen_ext32s_tl(arg
, arg
);
6515 register_name
= "XContext";
6519 goto cp0_unimplemented
;
6522 case CP0_REGISTER_21
:
6523 /* Officially reserved, but sel 0 is used for R1x000 framemask */
6524 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS_R6
));
6527 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Framemask
));
6528 register_name
= "Framemask";
6531 goto cp0_unimplemented
;
6534 case CP0_REGISTER_22
:
6535 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
6536 register_name
= "'Diagnostic"; /* implementation dependent */
6538 case CP0_REGISTER_23
:
6540 case CP0_REG23__DEBUG
:
6541 gen_helper_mfc0_debug(arg
, cpu_env
); /* EJTAG support */
6542 register_name
= "Debug";
6544 case CP0_REG23__TRACECONTROL
:
6545 /* PDtrace support */
6546 /* gen_helper_mfc0_tracecontrol(arg); */
6547 register_name
= "TraceControl";
6548 goto cp0_unimplemented
;
6549 case CP0_REG23__TRACECONTROL2
:
6550 /* PDtrace support */
6551 /* gen_helper_mfc0_tracecontrol2(arg); */
6552 register_name
= "TraceControl2";
6553 goto cp0_unimplemented
;
6554 case CP0_REG23__USERTRACEDATA1
:
6555 /* PDtrace support */
6556 /* gen_helper_mfc0_usertracedata1(arg);*/
6557 register_name
= "UserTraceData1";
6558 goto cp0_unimplemented
;
6559 case CP0_REG23__TRACEIBPC
:
6560 /* PDtrace support */
6561 /* gen_helper_mfc0_traceibpc(arg); */
6562 register_name
= "TraceIBPC";
6563 goto cp0_unimplemented
;
6564 case CP0_REG23__TRACEDBPC
:
6565 /* PDtrace support */
6566 /* gen_helper_mfc0_tracedbpc(arg); */
6567 register_name
= "TraceDBPC";
6568 goto cp0_unimplemented
;
6570 goto cp0_unimplemented
;
6573 case CP0_REGISTER_24
:
6575 case CP0_REG24__DEPC
:
6577 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
6578 tcg_gen_ext32s_tl(arg
, arg
);
6579 register_name
= "DEPC";
6582 goto cp0_unimplemented
;
6585 case CP0_REGISTER_25
:
6587 case CP0_REG25__PERFCTL0
:
6588 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Performance0
));
6589 register_name
= "Performance0";
6591 case CP0_REG25__PERFCNT0
:
6592 /* gen_helper_mfc0_performance1(arg); */
6593 register_name
= "Performance1";
6594 goto cp0_unimplemented
;
6595 case CP0_REG25__PERFCTL1
:
6596 /* gen_helper_mfc0_performance2(arg); */
6597 register_name
= "Performance2";
6598 goto cp0_unimplemented
;
6599 case CP0_REG25__PERFCNT1
:
6600 /* gen_helper_mfc0_performance3(arg); */
6601 register_name
= "Performance3";
6602 goto cp0_unimplemented
;
6603 case CP0_REG25__PERFCTL2
:
6604 /* gen_helper_mfc0_performance4(arg); */
6605 register_name
= "Performance4";
6606 goto cp0_unimplemented
;
6607 case CP0_REG25__PERFCNT2
:
6608 /* gen_helper_mfc0_performance5(arg); */
6609 register_name
= "Performance5";
6610 goto cp0_unimplemented
;
6611 case CP0_REG25__PERFCTL3
:
6612 /* gen_helper_mfc0_performance6(arg); */
6613 register_name
= "Performance6";
6614 goto cp0_unimplemented
;
6615 case CP0_REG25__PERFCNT3
:
6616 /* gen_helper_mfc0_performance7(arg); */
6617 register_name
= "Performance7";
6618 goto cp0_unimplemented
;
6620 goto cp0_unimplemented
;
6623 case CP0_REGISTER_26
:
6625 case CP0_REG26__ERRCTL
:
6626 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_ErrCtl
));
6627 register_name
= "ErrCtl";
6630 goto cp0_unimplemented
;
6633 case CP0_REGISTER_27
:
6635 case CP0_REG27__CACHERR
:
6636 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
6637 register_name
= "CacheErr";
6640 goto cp0_unimplemented
;
6643 case CP0_REGISTER_28
:
6645 case CP0_REG28__TAGLO
:
6646 case CP0_REG28__TAGLO1
:
6647 case CP0_REG28__TAGLO2
:
6648 case CP0_REG28__TAGLO3
:
6650 TCGv_i64 tmp
= tcg_temp_new_i64();
6651 tcg_gen_ld_i64(tmp
, cpu_env
, offsetof(CPUMIPSState
, CP0_TagLo
));
6652 gen_move_low32(arg
, tmp
);
6653 tcg_temp_free_i64(tmp
);
6655 register_name
= "TagLo";
6657 case CP0_REG28__DATALO
:
6658 case CP0_REG28__DATALO1
:
6659 case CP0_REG28__DATALO2
:
6660 case CP0_REG28__DATALO3
:
6661 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataLo
));
6662 register_name
= "DataLo";
6665 goto cp0_unimplemented
;
6668 case CP0_REGISTER_29
:
6670 case CP0_REG29__TAGHI
:
6671 case CP0_REG29__TAGHI1
:
6672 case CP0_REG29__TAGHI2
:
6673 case CP0_REG29__TAGHI3
:
6674 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagHi
));
6675 register_name
= "TagHi";
6677 case CP0_REG29__DATAHI
:
6678 case CP0_REG29__DATAHI1
:
6679 case CP0_REG29__DATAHI2
:
6680 case CP0_REG29__DATAHI3
:
6681 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataHi
));
6682 register_name
= "DataHi";
6685 goto cp0_unimplemented
;
6688 case CP0_REGISTER_30
:
6690 case CP0_REG30__ERROREPC
:
6691 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
6692 tcg_gen_ext32s_tl(arg
, arg
);
6693 register_name
= "ErrorEPC";
6696 goto cp0_unimplemented
;
6699 case CP0_REGISTER_31
:
6701 case CP0_REG31__DESAVE
:
6703 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
6704 register_name
= "DESAVE";
6706 case CP0_REG31__KSCRATCH1
:
6707 case CP0_REG31__KSCRATCH2
:
6708 case CP0_REG31__KSCRATCH3
:
6709 case CP0_REG31__KSCRATCH4
:
6710 case CP0_REG31__KSCRATCH5
:
6711 case CP0_REG31__KSCRATCH6
:
6712 CP0_CHECK(ctx
->kscrexist
& (1 << sel
));
6713 tcg_gen_ld_tl(arg
, cpu_env
,
6714 offsetof(CPUMIPSState
, CP0_KScratch
[sel
- 2]));
6715 tcg_gen_ext32s_tl(arg
, arg
);
6716 register_name
= "KScratch";
6719 goto cp0_unimplemented
;
6723 goto cp0_unimplemented
;
6725 trace_mips_translate_c0("mfc0", register_name
, reg
, sel
);
6729 qemu_log_mask(LOG_UNIMP
, "mfc0 %s (reg %d sel %d)\n",
6730 register_name
, reg
, sel
);
6731 gen_mfc0_unimplemented(ctx
, arg
);
6734 static void gen_mtc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
6736 const char *register_name
= "invalid";
6739 check_insn(ctx
, ISA_MIPS_R1
);
6742 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
6747 case CP0_REGISTER_00
:
6749 case CP0_REG00__INDEX
:
6750 gen_helper_mtc0_index(cpu_env
, arg
);
6751 register_name
= "Index";
6753 case CP0_REG00__MVPCONTROL
:
6754 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6755 gen_helper_mtc0_mvpcontrol(cpu_env
, arg
);
6756 register_name
= "MVPControl";
6758 case CP0_REG00__MVPCONF0
:
6759 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6761 register_name
= "MVPConf0";
6763 case CP0_REG00__MVPCONF1
:
6764 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6766 register_name
= "MVPConf1";
6768 case CP0_REG00__VPCONTROL
:
6771 register_name
= "VPControl";
6774 goto cp0_unimplemented
;
6777 case CP0_REGISTER_01
:
6779 case CP0_REG01__RANDOM
:
6781 register_name
= "Random";
6783 case CP0_REG01__VPECONTROL
:
6784 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6785 gen_helper_mtc0_vpecontrol(cpu_env
, arg
);
6786 register_name
= "VPEControl";
6788 case CP0_REG01__VPECONF0
:
6789 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6790 gen_helper_mtc0_vpeconf0(cpu_env
, arg
);
6791 register_name
= "VPEConf0";
6793 case CP0_REG01__VPECONF1
:
6794 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6795 gen_helper_mtc0_vpeconf1(cpu_env
, arg
);
6796 register_name
= "VPEConf1";
6798 case CP0_REG01__YQMASK
:
6799 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6800 gen_helper_mtc0_yqmask(cpu_env
, arg
);
6801 register_name
= "YQMask";
6803 case CP0_REG01__VPESCHEDULE
:
6804 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6805 tcg_gen_st_tl(arg
, cpu_env
,
6806 offsetof(CPUMIPSState
, CP0_VPESchedule
));
6807 register_name
= "VPESchedule";
6809 case CP0_REG01__VPESCHEFBACK
:
6810 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6811 tcg_gen_st_tl(arg
, cpu_env
,
6812 offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
6813 register_name
= "VPEScheFBack";
6815 case CP0_REG01__VPEOPT
:
6816 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6817 gen_helper_mtc0_vpeopt(cpu_env
, arg
);
6818 register_name
= "VPEOpt";
6821 goto cp0_unimplemented
;
6824 case CP0_REGISTER_02
:
6826 case CP0_REG02__ENTRYLO0
:
6827 gen_helper_mtc0_entrylo0(cpu_env
, arg
);
6828 register_name
= "EntryLo0";
6830 case CP0_REG02__TCSTATUS
:
6831 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6832 gen_helper_mtc0_tcstatus(cpu_env
, arg
);
6833 register_name
= "TCStatus";
6835 case CP0_REG02__TCBIND
:
6836 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6837 gen_helper_mtc0_tcbind(cpu_env
, arg
);
6838 register_name
= "TCBind";
6840 case CP0_REG02__TCRESTART
:
6841 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6842 gen_helper_mtc0_tcrestart(cpu_env
, arg
);
6843 register_name
= "TCRestart";
6845 case CP0_REG02__TCHALT
:
6846 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6847 gen_helper_mtc0_tchalt(cpu_env
, arg
);
6848 register_name
= "TCHalt";
6850 case CP0_REG02__TCCONTEXT
:
6851 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6852 gen_helper_mtc0_tccontext(cpu_env
, arg
);
6853 register_name
= "TCContext";
6855 case CP0_REG02__TCSCHEDULE
:
6856 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6857 gen_helper_mtc0_tcschedule(cpu_env
, arg
);
6858 register_name
= "TCSchedule";
6860 case CP0_REG02__TCSCHEFBACK
:
6861 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6862 gen_helper_mtc0_tcschefback(cpu_env
, arg
);
6863 register_name
= "TCScheFBack";
6866 goto cp0_unimplemented
;
6869 case CP0_REGISTER_03
:
6871 case CP0_REG03__ENTRYLO1
:
6872 gen_helper_mtc0_entrylo1(cpu_env
, arg
);
6873 register_name
= "EntryLo1";
6875 case CP0_REG03__GLOBALNUM
:
6878 register_name
= "GlobalNumber";
6881 goto cp0_unimplemented
;
6884 case CP0_REGISTER_04
:
6886 case CP0_REG04__CONTEXT
:
6887 gen_helper_mtc0_context(cpu_env
, arg
);
6888 register_name
= "Context";
6890 case CP0_REG04__CONTEXTCONFIG
:
6892 /* gen_helper_mtc0_contextconfig(arg); */
6893 register_name
= "ContextConfig";
6894 goto cp0_unimplemented
;
6895 case CP0_REG04__USERLOCAL
:
6896 CP0_CHECK(ctx
->ulri
);
6897 tcg_gen_st_tl(arg
, cpu_env
,
6898 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
6899 register_name
= "UserLocal";
6901 case CP0_REG04__MMID
:
6903 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_MemoryMapID
));
6904 register_name
= "MMID";
6907 goto cp0_unimplemented
;
6910 case CP0_REGISTER_05
:
6912 case CP0_REG05__PAGEMASK
:
6913 gen_helper_mtc0_pagemask(cpu_env
, arg
);
6914 register_name
= "PageMask";
6916 case CP0_REG05__PAGEGRAIN
:
6917 check_insn(ctx
, ISA_MIPS_R2
);
6918 gen_helper_mtc0_pagegrain(cpu_env
, arg
);
6919 register_name
= "PageGrain";
6920 ctx
->base
.is_jmp
= DISAS_STOP
;
6922 case CP0_REG05__SEGCTL0
:
6924 gen_helper_mtc0_segctl0(cpu_env
, arg
);
6925 register_name
= "SegCtl0";
6927 case CP0_REG05__SEGCTL1
:
6929 gen_helper_mtc0_segctl1(cpu_env
, arg
);
6930 register_name
= "SegCtl1";
6932 case CP0_REG05__SEGCTL2
:
6934 gen_helper_mtc0_segctl2(cpu_env
, arg
);
6935 register_name
= "SegCtl2";
6937 case CP0_REG05__PWBASE
:
6939 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_PWBase
));
6940 register_name
= "PWBase";
6942 case CP0_REG05__PWFIELD
:
6944 gen_helper_mtc0_pwfield(cpu_env
, arg
);
6945 register_name
= "PWField";
6947 case CP0_REG05__PWSIZE
:
6949 gen_helper_mtc0_pwsize(cpu_env
, arg
);
6950 register_name
= "PWSize";
6953 goto cp0_unimplemented
;
6956 case CP0_REGISTER_06
:
6958 case CP0_REG06__WIRED
:
6959 gen_helper_mtc0_wired(cpu_env
, arg
);
6960 register_name
= "Wired";
6962 case CP0_REG06__SRSCONF0
:
6963 check_insn(ctx
, ISA_MIPS_R2
);
6964 gen_helper_mtc0_srsconf0(cpu_env
, arg
);
6965 register_name
= "SRSConf0";
6967 case CP0_REG06__SRSCONF1
:
6968 check_insn(ctx
, ISA_MIPS_R2
);
6969 gen_helper_mtc0_srsconf1(cpu_env
, arg
);
6970 register_name
= "SRSConf1";
6972 case CP0_REG06__SRSCONF2
:
6973 check_insn(ctx
, ISA_MIPS_R2
);
6974 gen_helper_mtc0_srsconf2(cpu_env
, arg
);
6975 register_name
= "SRSConf2";
6977 case CP0_REG06__SRSCONF3
:
6978 check_insn(ctx
, ISA_MIPS_R2
);
6979 gen_helper_mtc0_srsconf3(cpu_env
, arg
);
6980 register_name
= "SRSConf3";
6982 case CP0_REG06__SRSCONF4
:
6983 check_insn(ctx
, ISA_MIPS_R2
);
6984 gen_helper_mtc0_srsconf4(cpu_env
, arg
);
6985 register_name
= "SRSConf4";
6987 case CP0_REG06__PWCTL
:
6989 gen_helper_mtc0_pwctl(cpu_env
, arg
);
6990 register_name
= "PWCtl";
6993 goto cp0_unimplemented
;
6996 case CP0_REGISTER_07
:
6998 case CP0_REG07__HWRENA
:
6999 check_insn(ctx
, ISA_MIPS_R2
);
7000 gen_helper_mtc0_hwrena(cpu_env
, arg
);
7001 ctx
->base
.is_jmp
= DISAS_STOP
;
7002 register_name
= "HWREna";
7005 goto cp0_unimplemented
;
7008 case CP0_REGISTER_08
:
7010 case CP0_REG08__BADVADDR
:
7012 register_name
= "BadVAddr";
7014 case CP0_REG08__BADINSTR
:
7016 register_name
= "BadInstr";
7018 case CP0_REG08__BADINSTRP
:
7020 register_name
= "BadInstrP";
7022 case CP0_REG08__BADINSTRX
:
7024 register_name
= "BadInstrX";
7027 goto cp0_unimplemented
;
7030 case CP0_REGISTER_09
:
7032 case CP0_REG09__COUNT
:
7033 gen_helper_mtc0_count(cpu_env
, arg
);
7034 register_name
= "Count";
7036 case CP0_REG09__SAARI
:
7037 CP0_CHECK(ctx
->saar
);
7038 gen_helper_mtc0_saari(cpu_env
, arg
);
7039 register_name
= "SAARI";
7041 case CP0_REG09__SAAR
:
7042 CP0_CHECK(ctx
->saar
);
7043 gen_helper_mtc0_saar(cpu_env
, arg
);
7044 register_name
= "SAAR";
7047 goto cp0_unimplemented
;
7050 case CP0_REGISTER_10
:
7052 case CP0_REG10__ENTRYHI
:
7053 gen_helper_mtc0_entryhi(cpu_env
, arg
);
7054 register_name
= "EntryHi";
7057 goto cp0_unimplemented
;
7060 case CP0_REGISTER_11
:
7062 case CP0_REG11__COMPARE
:
7063 gen_helper_mtc0_compare(cpu_env
, arg
);
7064 register_name
= "Compare";
7066 /* 6,7 are implementation dependent */
7068 goto cp0_unimplemented
;
7071 case CP0_REGISTER_12
:
7073 case CP0_REG12__STATUS
:
7074 save_cpu_state(ctx
, 1);
7075 gen_helper_mtc0_status(cpu_env
, arg
);
7076 /* DISAS_STOP isn't good enough here, hflags may have changed. */
7077 gen_save_pc(ctx
->base
.pc_next
+ 4);
7078 ctx
->base
.is_jmp
= DISAS_EXIT
;
7079 register_name
= "Status";
7081 case CP0_REG12__INTCTL
:
7082 check_insn(ctx
, ISA_MIPS_R2
);
7083 gen_helper_mtc0_intctl(cpu_env
, arg
);
7084 /* Stop translation as we may have switched the execution mode */
7085 ctx
->base
.is_jmp
= DISAS_STOP
;
7086 register_name
= "IntCtl";
7088 case CP0_REG12__SRSCTL
:
7089 check_insn(ctx
, ISA_MIPS_R2
);
7090 gen_helper_mtc0_srsctl(cpu_env
, arg
);
7091 /* Stop translation as we may have switched the execution mode */
7092 ctx
->base
.is_jmp
= DISAS_STOP
;
7093 register_name
= "SRSCtl";
7095 case CP0_REG12__SRSMAP
:
7096 check_insn(ctx
, ISA_MIPS_R2
);
7097 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
7098 /* Stop translation as we may have switched the execution mode */
7099 ctx
->base
.is_jmp
= DISAS_STOP
;
7100 register_name
= "SRSMap";
7103 goto cp0_unimplemented
;
7106 case CP0_REGISTER_13
:
7108 case CP0_REG13__CAUSE
:
7109 save_cpu_state(ctx
, 1);
7110 gen_helper_mtc0_cause(cpu_env
, arg
);
7112 * Stop translation as we may have triggered an interrupt.
7113 * DISAS_STOP isn't sufficient, we need to ensure we break out of
7114 * translated code to check for pending interrupts.
7116 gen_save_pc(ctx
->base
.pc_next
+ 4);
7117 ctx
->base
.is_jmp
= DISAS_EXIT
;
7118 register_name
= "Cause";
7121 goto cp0_unimplemented
;
7124 case CP0_REGISTER_14
:
7126 case CP0_REG14__EPC
:
7127 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
7128 register_name
= "EPC";
7131 goto cp0_unimplemented
;
7134 case CP0_REGISTER_15
:
7136 case CP0_REG15__PRID
:
7138 register_name
= "PRid";
7140 case CP0_REG15__EBASE
:
7141 check_insn(ctx
, ISA_MIPS_R2
);
7142 gen_helper_mtc0_ebase(cpu_env
, arg
);
7143 register_name
= "EBase";
7146 goto cp0_unimplemented
;
7149 case CP0_REGISTER_16
:
7151 case CP0_REG16__CONFIG
:
7152 gen_helper_mtc0_config0(cpu_env
, arg
);
7153 register_name
= "Config";
7154 /* Stop translation as we may have switched the execution mode */
7155 ctx
->base
.is_jmp
= DISAS_STOP
;
7157 case CP0_REG16__CONFIG1
:
7158 /* ignored, read only */
7159 register_name
= "Config1";
7161 case CP0_REG16__CONFIG2
:
7162 gen_helper_mtc0_config2(cpu_env
, arg
);
7163 register_name
= "Config2";
7164 /* Stop translation as we may have switched the execution mode */
7165 ctx
->base
.is_jmp
= DISAS_STOP
;
7167 case CP0_REG16__CONFIG3
:
7168 gen_helper_mtc0_config3(cpu_env
, arg
);
7169 register_name
= "Config3";
7170 /* Stop translation as we may have switched the execution mode */
7171 ctx
->base
.is_jmp
= DISAS_STOP
;
7173 case CP0_REG16__CONFIG4
:
7174 gen_helper_mtc0_config4(cpu_env
, arg
);
7175 register_name
= "Config4";
7176 ctx
->base
.is_jmp
= DISAS_STOP
;
7178 case CP0_REG16__CONFIG5
:
7179 gen_helper_mtc0_config5(cpu_env
, arg
);
7180 register_name
= "Config5";
7181 /* Stop translation as we may have switched the execution mode */
7182 ctx
->base
.is_jmp
= DISAS_STOP
;
7184 /* 6,7 are implementation dependent */
7185 case CP0_REG16__CONFIG6
:
7187 register_name
= "Config6";
7189 case CP0_REG16__CONFIG7
:
7191 register_name
= "Config7";
7194 register_name
= "Invalid config selector";
7195 goto cp0_unimplemented
;
7198 case CP0_REGISTER_17
:
7200 case CP0_REG17__LLADDR
:
7201 gen_helper_mtc0_lladdr(cpu_env
, arg
);
7202 register_name
= "LLAddr";
7204 case CP0_REG17__MAAR
:
7205 CP0_CHECK(ctx
->mrp
);
7206 gen_helper_mtc0_maar(cpu_env
, arg
);
7207 register_name
= "MAAR";
7209 case CP0_REG17__MAARI
:
7210 CP0_CHECK(ctx
->mrp
);
7211 gen_helper_mtc0_maari(cpu_env
, arg
);
7212 register_name
= "MAARI";
7215 goto cp0_unimplemented
;
7218 case CP0_REGISTER_18
:
7220 case CP0_REG18__WATCHLO0
:
7221 case CP0_REG18__WATCHLO1
:
7222 case CP0_REG18__WATCHLO2
:
7223 case CP0_REG18__WATCHLO3
:
7224 case CP0_REG18__WATCHLO4
:
7225 case CP0_REG18__WATCHLO5
:
7226 case CP0_REG18__WATCHLO6
:
7227 case CP0_REG18__WATCHLO7
:
7228 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
7229 gen_helper_0e1i(mtc0_watchlo
, arg
, sel
);
7230 register_name
= "WatchLo";
7233 goto cp0_unimplemented
;
7236 case CP0_REGISTER_19
:
7238 case CP0_REG19__WATCHHI0
:
7239 case CP0_REG19__WATCHHI1
:
7240 case CP0_REG19__WATCHHI2
:
7241 case CP0_REG19__WATCHHI3
:
7242 case CP0_REG19__WATCHHI4
:
7243 case CP0_REG19__WATCHHI5
:
7244 case CP0_REG19__WATCHHI6
:
7245 case CP0_REG19__WATCHHI7
:
7246 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
7247 gen_helper_0e1i(mtc0_watchhi
, arg
, sel
);
7248 register_name
= "WatchHi";
7251 goto cp0_unimplemented
;
7254 case CP0_REGISTER_20
:
7256 case CP0_REG20__XCONTEXT
:
7257 #if defined(TARGET_MIPS64)
7258 check_insn(ctx
, ISA_MIPS3
);
7259 gen_helper_mtc0_xcontext(cpu_env
, arg
);
7260 register_name
= "XContext";
7264 goto cp0_unimplemented
;
7267 case CP0_REGISTER_21
:
7268 /* Officially reserved, but sel 0 is used for R1x000 framemask */
7269 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS_R6
));
7272 gen_helper_mtc0_framemask(cpu_env
, arg
);
7273 register_name
= "Framemask";
7276 goto cp0_unimplemented
;
7279 case CP0_REGISTER_22
:
7281 register_name
= "Diagnostic"; /* implementation dependent */
7283 case CP0_REGISTER_23
:
7285 case CP0_REG23__DEBUG
:
7286 gen_helper_mtc0_debug(cpu_env
, arg
); /* EJTAG support */
7287 /* DISAS_STOP isn't good enough here, hflags may have changed. */
7288 gen_save_pc(ctx
->base
.pc_next
+ 4);
7289 ctx
->base
.is_jmp
= DISAS_EXIT
;
7290 register_name
= "Debug";
7292 case CP0_REG23__TRACECONTROL
:
7293 /* PDtrace support */
7294 /* gen_helper_mtc0_tracecontrol(cpu_env, arg); */
7295 register_name
= "TraceControl";
7296 /* Stop translation as we may have switched the execution mode */
7297 ctx
->base
.is_jmp
= DISAS_STOP
;
7298 goto cp0_unimplemented
;
7299 case CP0_REG23__TRACECONTROL2
:
7300 /* PDtrace support */
7301 /* gen_helper_mtc0_tracecontrol2(cpu_env, arg); */
7302 register_name
= "TraceControl2";
7303 /* Stop translation as we may have switched the execution mode */
7304 ctx
->base
.is_jmp
= DISAS_STOP
;
7305 goto cp0_unimplemented
;
7306 case CP0_REG23__USERTRACEDATA1
:
7307 /* Stop translation as we may have switched the execution mode */
7308 ctx
->base
.is_jmp
= DISAS_STOP
;
7309 /* PDtrace support */
7310 /* gen_helper_mtc0_usertracedata1(cpu_env, arg);*/
7311 register_name
= "UserTraceData";
7312 /* Stop translation as we may have switched the execution mode */
7313 ctx
->base
.is_jmp
= DISAS_STOP
;
7314 goto cp0_unimplemented
;
7315 case CP0_REG23__TRACEIBPC
:
7316 /* PDtrace support */
7317 /* gen_helper_mtc0_traceibpc(cpu_env, arg); */
7318 /* Stop translation as we may have switched the execution mode */
7319 ctx
->base
.is_jmp
= DISAS_STOP
;
7320 register_name
= "TraceIBPC";
7321 goto cp0_unimplemented
;
7322 case CP0_REG23__TRACEDBPC
:
7323 /* PDtrace support */
7324 /* gen_helper_mtc0_tracedbpc(cpu_env, arg); */
7325 /* Stop translation as we may have switched the execution mode */
7326 ctx
->base
.is_jmp
= DISAS_STOP
;
7327 register_name
= "TraceDBPC";
7328 goto cp0_unimplemented
;
7330 goto cp0_unimplemented
;
7333 case CP0_REGISTER_24
:
7335 case CP0_REG24__DEPC
:
7337 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
7338 register_name
= "DEPC";
7341 goto cp0_unimplemented
;
7344 case CP0_REGISTER_25
:
7346 case CP0_REG25__PERFCTL0
:
7347 gen_helper_mtc0_performance0(cpu_env
, arg
);
7348 register_name
= "Performance0";
7350 case CP0_REG25__PERFCNT0
:
7351 /* gen_helper_mtc0_performance1(arg); */
7352 register_name
= "Performance1";
7353 goto cp0_unimplemented
;
7354 case CP0_REG25__PERFCTL1
:
7355 /* gen_helper_mtc0_performance2(arg); */
7356 register_name
= "Performance2";
7357 goto cp0_unimplemented
;
7358 case CP0_REG25__PERFCNT1
:
7359 /* gen_helper_mtc0_performance3(arg); */
7360 register_name
= "Performance3";
7361 goto cp0_unimplemented
;
7362 case CP0_REG25__PERFCTL2
:
7363 /* gen_helper_mtc0_performance4(arg); */
7364 register_name
= "Performance4";
7365 goto cp0_unimplemented
;
7366 case CP0_REG25__PERFCNT2
:
7367 /* gen_helper_mtc0_performance5(arg); */
7368 register_name
= "Performance5";
7369 goto cp0_unimplemented
;
7370 case CP0_REG25__PERFCTL3
:
7371 /* gen_helper_mtc0_performance6(arg); */
7372 register_name
= "Performance6";
7373 goto cp0_unimplemented
;
7374 case CP0_REG25__PERFCNT3
:
7375 /* gen_helper_mtc0_performance7(arg); */
7376 register_name
= "Performance7";
7377 goto cp0_unimplemented
;
7379 goto cp0_unimplemented
;
7382 case CP0_REGISTER_26
:
7384 case CP0_REG26__ERRCTL
:
7385 gen_helper_mtc0_errctl(cpu_env
, arg
);
7386 ctx
->base
.is_jmp
= DISAS_STOP
;
7387 register_name
= "ErrCtl";
7390 goto cp0_unimplemented
;
7393 case CP0_REGISTER_27
:
7395 case CP0_REG27__CACHERR
:
7397 register_name
= "CacheErr";
7400 goto cp0_unimplemented
;
7403 case CP0_REGISTER_28
:
7405 case CP0_REG28__TAGLO
:
7406 case CP0_REG28__TAGLO1
:
7407 case CP0_REG28__TAGLO2
:
7408 case CP0_REG28__TAGLO3
:
7409 gen_helper_mtc0_taglo(cpu_env
, arg
);
7410 register_name
= "TagLo";
7412 case CP0_REG28__DATALO
:
7413 case CP0_REG28__DATALO1
:
7414 case CP0_REG28__DATALO2
:
7415 case CP0_REG28__DATALO3
:
7416 gen_helper_mtc0_datalo(cpu_env
, arg
);
7417 register_name
= "DataLo";
7420 goto cp0_unimplemented
;
7423 case CP0_REGISTER_29
:
7425 case CP0_REG29__TAGHI
:
7426 case CP0_REG29__TAGHI1
:
7427 case CP0_REG29__TAGHI2
:
7428 case CP0_REG29__TAGHI3
:
7429 gen_helper_mtc0_taghi(cpu_env
, arg
);
7430 register_name
= "TagHi";
7432 case CP0_REG29__DATAHI
:
7433 case CP0_REG29__DATAHI1
:
7434 case CP0_REG29__DATAHI2
:
7435 case CP0_REG29__DATAHI3
:
7436 gen_helper_mtc0_datahi(cpu_env
, arg
);
7437 register_name
= "DataHi";
7440 register_name
= "invalid sel";
7441 goto cp0_unimplemented
;
7444 case CP0_REGISTER_30
:
7446 case CP0_REG30__ERROREPC
:
7447 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
7448 register_name
= "ErrorEPC";
7451 goto cp0_unimplemented
;
7454 case CP0_REGISTER_31
:
7456 case CP0_REG31__DESAVE
:
7458 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
7459 register_name
= "DESAVE";
7461 case CP0_REG31__KSCRATCH1
:
7462 case CP0_REG31__KSCRATCH2
:
7463 case CP0_REG31__KSCRATCH3
:
7464 case CP0_REG31__KSCRATCH4
:
7465 case CP0_REG31__KSCRATCH5
:
7466 case CP0_REG31__KSCRATCH6
:
7467 CP0_CHECK(ctx
->kscrexist
& (1 << sel
));
7468 tcg_gen_st_tl(arg
, cpu_env
,
7469 offsetof(CPUMIPSState
, CP0_KScratch
[sel
- 2]));
7470 register_name
= "KScratch";
7473 goto cp0_unimplemented
;
7477 goto cp0_unimplemented
;
7479 trace_mips_translate_c0("mtc0", register_name
, reg
, sel
);
7481 /* For simplicity assume that all writes can cause interrupts. */
7482 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
7484 * DISAS_STOP isn't sufficient, we need to ensure we break out of
7485 * translated code to check for pending interrupts.
7487 gen_save_pc(ctx
->base
.pc_next
+ 4);
7488 ctx
->base
.is_jmp
= DISAS_EXIT
;
7493 qemu_log_mask(LOG_UNIMP
, "mtc0 %s (reg %d sel %d)\n",
7494 register_name
, reg
, sel
);
7497 #if defined(TARGET_MIPS64)
7498 static void gen_dmfc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
7500 const char *register_name
= "invalid";
7503 check_insn(ctx
, ISA_MIPS_R1
);
7507 case CP0_REGISTER_00
:
7509 case CP0_REG00__INDEX
:
7510 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Index
));
7511 register_name
= "Index";
7513 case CP0_REG00__MVPCONTROL
:
7514 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7515 gen_helper_mfc0_mvpcontrol(arg
, cpu_env
);
7516 register_name
= "MVPControl";
7518 case CP0_REG00__MVPCONF0
:
7519 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7520 gen_helper_mfc0_mvpconf0(arg
, cpu_env
);
7521 register_name
= "MVPConf0";
7523 case CP0_REG00__MVPCONF1
:
7524 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7525 gen_helper_mfc0_mvpconf1(arg
, cpu_env
);
7526 register_name
= "MVPConf1";
7528 case CP0_REG00__VPCONTROL
:
7530 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPControl
));
7531 register_name
= "VPControl";
7534 goto cp0_unimplemented
;
7537 case CP0_REGISTER_01
:
7539 case CP0_REG01__RANDOM
:
7540 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS_R6
));
7541 gen_helper_mfc0_random(arg
, cpu_env
);
7542 register_name
= "Random";
7544 case CP0_REG01__VPECONTROL
:
7545 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7546 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEControl
));
7547 register_name
= "VPEControl";
7549 case CP0_REG01__VPECONF0
:
7550 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7551 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf0
));
7552 register_name
= "VPEConf0";
7554 case CP0_REG01__VPECONF1
:
7555 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7556 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf1
));
7557 register_name
= "VPEConf1";
7559 case CP0_REG01__YQMASK
:
7560 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7561 tcg_gen_ld_tl(arg
, cpu_env
,
7562 offsetof(CPUMIPSState
, CP0_YQMask
));
7563 register_name
= "YQMask";
7565 case CP0_REG01__VPESCHEDULE
:
7566 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7567 tcg_gen_ld_tl(arg
, cpu_env
,
7568 offsetof(CPUMIPSState
, CP0_VPESchedule
));
7569 register_name
= "VPESchedule";
7571 case CP0_REG01__VPESCHEFBACK
:
7572 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7573 tcg_gen_ld_tl(arg
, cpu_env
,
7574 offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
7575 register_name
= "VPEScheFBack";
7577 case CP0_REG01__VPEOPT
:
7578 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7579 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEOpt
));
7580 register_name
= "VPEOpt";
7583 goto cp0_unimplemented
;
7586 case CP0_REGISTER_02
:
7588 case CP0_REG02__ENTRYLO0
:
7589 tcg_gen_ld_tl(arg
, cpu_env
,
7590 offsetof(CPUMIPSState
, CP0_EntryLo0
));
7591 register_name
= "EntryLo0";
7593 case CP0_REG02__TCSTATUS
:
7594 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7595 gen_helper_mfc0_tcstatus(arg
, cpu_env
);
7596 register_name
= "TCStatus";
7598 case CP0_REG02__TCBIND
:
7599 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7600 gen_helper_mfc0_tcbind(arg
, cpu_env
);
7601 register_name
= "TCBind";
7603 case CP0_REG02__TCRESTART
:
7604 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7605 gen_helper_dmfc0_tcrestart(arg
, cpu_env
);
7606 register_name
= "TCRestart";
7608 case CP0_REG02__TCHALT
:
7609 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7610 gen_helper_dmfc0_tchalt(arg
, cpu_env
);
7611 register_name
= "TCHalt";
7613 case CP0_REG02__TCCONTEXT
:
7614 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7615 gen_helper_dmfc0_tccontext(arg
, cpu_env
);
7616 register_name
= "TCContext";
7618 case CP0_REG02__TCSCHEDULE
:
7619 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7620 gen_helper_dmfc0_tcschedule(arg
, cpu_env
);
7621 register_name
= "TCSchedule";
7623 case CP0_REG02__TCSCHEFBACK
:
7624 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7625 gen_helper_dmfc0_tcschefback(arg
, cpu_env
);
7626 register_name
= "TCScheFBack";
7629 goto cp0_unimplemented
;
7632 case CP0_REGISTER_03
:
7634 case CP0_REG03__ENTRYLO1
:
7635 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryLo1
));
7636 register_name
= "EntryLo1";
7638 case CP0_REG03__GLOBALNUM
:
7640 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_GlobalNumber
));
7641 register_name
= "GlobalNumber";
7644 goto cp0_unimplemented
;
7647 case CP0_REGISTER_04
:
7649 case CP0_REG04__CONTEXT
:
7650 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_Context
));
7651 register_name
= "Context";
7653 case CP0_REG04__CONTEXTCONFIG
:
7655 /* gen_helper_dmfc0_contextconfig(arg); */
7656 register_name
= "ContextConfig";
7657 goto cp0_unimplemented
;
7658 case CP0_REG04__USERLOCAL
:
7659 CP0_CHECK(ctx
->ulri
);
7660 tcg_gen_ld_tl(arg
, cpu_env
,
7661 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
7662 register_name
= "UserLocal";
7664 case CP0_REG04__MMID
:
7666 gen_helper_mtc0_memorymapid(cpu_env
, arg
);
7667 register_name
= "MMID";
7670 goto cp0_unimplemented
;
7673 case CP0_REGISTER_05
:
7675 case CP0_REG05__PAGEMASK
:
7676 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageMask
));
7677 register_name
= "PageMask";
7679 case CP0_REG05__PAGEGRAIN
:
7680 check_insn(ctx
, ISA_MIPS_R2
);
7681 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageGrain
));
7682 register_name
= "PageGrain";
7684 case CP0_REG05__SEGCTL0
:
7686 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_SegCtl0
));
7687 register_name
= "SegCtl0";
7689 case CP0_REG05__SEGCTL1
:
7691 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_SegCtl1
));
7692 register_name
= "SegCtl1";
7694 case CP0_REG05__SEGCTL2
:
7696 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_SegCtl2
));
7697 register_name
= "SegCtl2";
7699 case CP0_REG05__PWBASE
:
7701 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_PWBase
));
7702 register_name
= "PWBase";
7704 case CP0_REG05__PWFIELD
:
7706 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_PWField
));
7707 register_name
= "PWField";
7709 case CP0_REG05__PWSIZE
:
7711 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_PWSize
));
7712 register_name
= "PWSize";
7715 goto cp0_unimplemented
;
7718 case CP0_REGISTER_06
:
7720 case CP0_REG06__WIRED
:
7721 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Wired
));
7722 register_name
= "Wired";
7724 case CP0_REG06__SRSCONF0
:
7725 check_insn(ctx
, ISA_MIPS_R2
);
7726 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf0
));
7727 register_name
= "SRSConf0";
7729 case CP0_REG06__SRSCONF1
:
7730 check_insn(ctx
, ISA_MIPS_R2
);
7731 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf1
));
7732 register_name
= "SRSConf1";
7734 case CP0_REG06__SRSCONF2
:
7735 check_insn(ctx
, ISA_MIPS_R2
);
7736 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf2
));
7737 register_name
= "SRSConf2";
7739 case CP0_REG06__SRSCONF3
:
7740 check_insn(ctx
, ISA_MIPS_R2
);
7741 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf3
));
7742 register_name
= "SRSConf3";
7744 case CP0_REG06__SRSCONF4
:
7745 check_insn(ctx
, ISA_MIPS_R2
);
7746 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf4
));
7747 register_name
= "SRSConf4";
7749 case CP0_REG06__PWCTL
:
7751 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PWCtl
));
7752 register_name
= "PWCtl";
7755 goto cp0_unimplemented
;
7758 case CP0_REGISTER_07
:
7760 case CP0_REG07__HWRENA
:
7761 check_insn(ctx
, ISA_MIPS_R2
);
7762 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_HWREna
));
7763 register_name
= "HWREna";
7766 goto cp0_unimplemented
;
7769 case CP0_REGISTER_08
:
7771 case CP0_REG08__BADVADDR
:
7772 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_BadVAddr
));
7773 register_name
= "BadVAddr";
7775 case CP0_REG08__BADINSTR
:
7777 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstr
));
7778 register_name
= "BadInstr";
7780 case CP0_REG08__BADINSTRP
:
7782 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstrP
));
7783 register_name
= "BadInstrP";
7785 case CP0_REG08__BADINSTRX
:
7787 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstrX
));
7788 tcg_gen_andi_tl(arg
, arg
, ~0xffff);
7789 register_name
= "BadInstrX";
7792 goto cp0_unimplemented
;
7795 case CP0_REGISTER_09
:
7797 case CP0_REG09__COUNT
:
7798 /* Mark as an IO operation because we read the time. */
7799 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
7802 gen_helper_mfc0_count(arg
, cpu_env
);
7804 * Break the TB to be able to take timer interrupts immediately
7805 * after reading count. DISAS_STOP isn't sufficient, we need to
7806 * ensure we break completely out of translated code.
7808 gen_save_pc(ctx
->base
.pc_next
+ 4);
7809 ctx
->base
.is_jmp
= DISAS_EXIT
;
7810 register_name
= "Count";
7812 case CP0_REG09__SAARI
:
7813 CP0_CHECK(ctx
->saar
);
7814 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SAARI
));
7815 register_name
= "SAARI";
7817 case CP0_REG09__SAAR
:
7818 CP0_CHECK(ctx
->saar
);
7819 gen_helper_dmfc0_saar(arg
, cpu_env
);
7820 register_name
= "SAAR";
7823 goto cp0_unimplemented
;
7826 case CP0_REGISTER_10
:
7828 case CP0_REG10__ENTRYHI
:
7829 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryHi
));
7830 register_name
= "EntryHi";
7833 goto cp0_unimplemented
;
7836 case CP0_REGISTER_11
:
7838 case CP0_REG11__COMPARE
:
7839 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Compare
));
7840 register_name
= "Compare";
7842 /* 6,7 are implementation dependent */
7844 goto cp0_unimplemented
;
7847 case CP0_REGISTER_12
:
7849 case CP0_REG12__STATUS
:
7850 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Status
));
7851 register_name
= "Status";
7853 case CP0_REG12__INTCTL
:
7854 check_insn(ctx
, ISA_MIPS_R2
);
7855 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_IntCtl
));
7856 register_name
= "IntCtl";
7858 case CP0_REG12__SRSCTL
:
7859 check_insn(ctx
, ISA_MIPS_R2
);
7860 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
7861 register_name
= "SRSCtl";
7863 case CP0_REG12__SRSMAP
:
7864 check_insn(ctx
, ISA_MIPS_R2
);
7865 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
7866 register_name
= "SRSMap";
7869 goto cp0_unimplemented
;
7872 case CP0_REGISTER_13
:
7874 case CP0_REG13__CAUSE
:
7875 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Cause
));
7876 register_name
= "Cause";
7879 goto cp0_unimplemented
;
7882 case CP0_REGISTER_14
:
7884 case CP0_REG14__EPC
:
7885 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
7886 register_name
= "EPC";
7889 goto cp0_unimplemented
;
7892 case CP0_REGISTER_15
:
7894 case CP0_REG15__PRID
:
7895 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PRid
));
7896 register_name
= "PRid";
7898 case CP0_REG15__EBASE
:
7899 check_insn(ctx
, ISA_MIPS_R2
);
7900 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EBase
));
7901 register_name
= "EBase";
7903 case CP0_REG15__CMGCRBASE
:
7904 check_insn(ctx
, ISA_MIPS_R2
);
7905 CP0_CHECK(ctx
->cmgcr
);
7906 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_CMGCRBase
));
7907 register_name
= "CMGCRBase";
7910 goto cp0_unimplemented
;
7913 case CP0_REGISTER_16
:
7915 case CP0_REG16__CONFIG
:
7916 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config0
));
7917 register_name
= "Config";
7919 case CP0_REG16__CONFIG1
:
7920 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config1
));
7921 register_name
= "Config1";
7923 case CP0_REG16__CONFIG2
:
7924 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config2
));
7925 register_name
= "Config2";
7927 case CP0_REG16__CONFIG3
:
7928 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config3
));
7929 register_name
= "Config3";
7931 case CP0_REG16__CONFIG4
:
7932 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config4
));
7933 register_name
= "Config4";
7935 case CP0_REG16__CONFIG5
:
7936 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config5
));
7937 register_name
= "Config5";
7939 /* 6,7 are implementation dependent */
7940 case CP0_REG16__CONFIG6
:
7941 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config6
));
7942 register_name
= "Config6";
7944 case CP0_REG16__CONFIG7
:
7945 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config7
));
7946 register_name
= "Config7";
7949 goto cp0_unimplemented
;
7952 case CP0_REGISTER_17
:
7954 case CP0_REG17__LLADDR
:
7955 gen_helper_dmfc0_lladdr(arg
, cpu_env
);
7956 register_name
= "LLAddr";
7958 case CP0_REG17__MAAR
:
7959 CP0_CHECK(ctx
->mrp
);
7960 gen_helper_dmfc0_maar(arg
, cpu_env
);
7961 register_name
= "MAAR";
7963 case CP0_REG17__MAARI
:
7964 CP0_CHECK(ctx
->mrp
);
7965 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_MAARI
));
7966 register_name
= "MAARI";
7969 goto cp0_unimplemented
;
7972 case CP0_REGISTER_18
:
7974 case CP0_REG18__WATCHLO0
:
7975 case CP0_REG18__WATCHLO1
:
7976 case CP0_REG18__WATCHLO2
:
7977 case CP0_REG18__WATCHLO3
:
7978 case CP0_REG18__WATCHLO4
:
7979 case CP0_REG18__WATCHLO5
:
7980 case CP0_REG18__WATCHLO6
:
7981 case CP0_REG18__WATCHLO7
:
7982 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
7983 gen_helper_1e0i(dmfc0_watchlo
, arg
, sel
);
7984 register_name
= "WatchLo";
7987 goto cp0_unimplemented
;
7990 case CP0_REGISTER_19
:
7992 case CP0_REG19__WATCHHI0
:
7993 case CP0_REG19__WATCHHI1
:
7994 case CP0_REG19__WATCHHI2
:
7995 case CP0_REG19__WATCHHI3
:
7996 case CP0_REG19__WATCHHI4
:
7997 case CP0_REG19__WATCHHI5
:
7998 case CP0_REG19__WATCHHI6
:
7999 case CP0_REG19__WATCHHI7
:
8000 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
8001 gen_helper_1e0i(dmfc0_watchhi
, arg
, sel
);
8002 register_name
= "WatchHi";
8005 goto cp0_unimplemented
;
8008 case CP0_REGISTER_20
:
8010 case CP0_REG20__XCONTEXT
:
8011 check_insn(ctx
, ISA_MIPS3
);
8012 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_XContext
));
8013 register_name
= "XContext";
8016 goto cp0_unimplemented
;
8019 case CP0_REGISTER_21
:
8020 /* Officially reserved, but sel 0 is used for R1x000 framemask */
8021 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS_R6
));
8024 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Framemask
));
8025 register_name
= "Framemask";
8028 goto cp0_unimplemented
;
8031 case CP0_REGISTER_22
:
8032 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
8033 register_name
= "'Diagnostic"; /* implementation dependent */
8035 case CP0_REGISTER_23
:
8037 case CP0_REG23__DEBUG
:
8038 gen_helper_mfc0_debug(arg
, cpu_env
); /* EJTAG support */
8039 register_name
= "Debug";
8041 case CP0_REG23__TRACECONTROL
:
8042 /* PDtrace support */
8043 /* gen_helper_dmfc0_tracecontrol(arg, cpu_env); */
8044 register_name
= "TraceControl";
8045 goto cp0_unimplemented
;
8046 case CP0_REG23__TRACECONTROL2
:
8047 /* PDtrace support */
8048 /* gen_helper_dmfc0_tracecontrol2(arg, cpu_env); */
8049 register_name
= "TraceControl2";
8050 goto cp0_unimplemented
;
8051 case CP0_REG23__USERTRACEDATA1
:
8052 /* PDtrace support */
8053 /* gen_helper_dmfc0_usertracedata1(arg, cpu_env);*/
8054 register_name
= "UserTraceData1";
8055 goto cp0_unimplemented
;
8056 case CP0_REG23__TRACEIBPC
:
8057 /* PDtrace support */
8058 /* gen_helper_dmfc0_traceibpc(arg, cpu_env); */
8059 register_name
= "TraceIBPC";
8060 goto cp0_unimplemented
;
8061 case CP0_REG23__TRACEDBPC
:
8062 /* PDtrace support */
8063 /* gen_helper_dmfc0_tracedbpc(arg, cpu_env); */
8064 register_name
= "TraceDBPC";
8065 goto cp0_unimplemented
;
8067 goto cp0_unimplemented
;
8070 case CP0_REGISTER_24
:
8072 case CP0_REG24__DEPC
:
8074 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
8075 register_name
= "DEPC";
8078 goto cp0_unimplemented
;
8081 case CP0_REGISTER_25
:
8083 case CP0_REG25__PERFCTL0
:
8084 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Performance0
));
8085 register_name
= "Performance0";
8087 case CP0_REG25__PERFCNT0
:
8088 /* gen_helper_dmfc0_performance1(arg); */
8089 register_name
= "Performance1";
8090 goto cp0_unimplemented
;
8091 case CP0_REG25__PERFCTL1
:
8092 /* gen_helper_dmfc0_performance2(arg); */
8093 register_name
= "Performance2";
8094 goto cp0_unimplemented
;
8095 case CP0_REG25__PERFCNT1
:
8096 /* gen_helper_dmfc0_performance3(arg); */
8097 register_name
= "Performance3";
8098 goto cp0_unimplemented
;
8099 case CP0_REG25__PERFCTL2
:
8100 /* gen_helper_dmfc0_performance4(arg); */
8101 register_name
= "Performance4";
8102 goto cp0_unimplemented
;
8103 case CP0_REG25__PERFCNT2
:
8104 /* gen_helper_dmfc0_performance5(arg); */
8105 register_name
= "Performance5";
8106 goto cp0_unimplemented
;
8107 case CP0_REG25__PERFCTL3
:
8108 /* gen_helper_dmfc0_performance6(arg); */
8109 register_name
= "Performance6";
8110 goto cp0_unimplemented
;
8111 case CP0_REG25__PERFCNT3
:
8112 /* gen_helper_dmfc0_performance7(arg); */
8113 register_name
= "Performance7";
8114 goto cp0_unimplemented
;
8116 goto cp0_unimplemented
;
8119 case CP0_REGISTER_26
:
8121 case CP0_REG26__ERRCTL
:
8122 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_ErrCtl
));
8123 register_name
= "ErrCtl";
8126 goto cp0_unimplemented
;
8129 case CP0_REGISTER_27
:
8132 case CP0_REG27__CACHERR
:
8133 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
8134 register_name
= "CacheErr";
8137 goto cp0_unimplemented
;
8140 case CP0_REGISTER_28
:
8142 case CP0_REG28__TAGLO
:
8143 case CP0_REG28__TAGLO1
:
8144 case CP0_REG28__TAGLO2
:
8145 case CP0_REG28__TAGLO3
:
8146 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagLo
));
8147 register_name
= "TagLo";
8149 case CP0_REG28__DATALO
:
8150 case CP0_REG28__DATALO1
:
8151 case CP0_REG28__DATALO2
:
8152 case CP0_REG28__DATALO3
:
8153 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataLo
));
8154 register_name
= "DataLo";
8157 goto cp0_unimplemented
;
8160 case CP0_REGISTER_29
:
8162 case CP0_REG29__TAGHI
:
8163 case CP0_REG29__TAGHI1
:
8164 case CP0_REG29__TAGHI2
:
8165 case CP0_REG29__TAGHI3
:
8166 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagHi
));
8167 register_name
= "TagHi";
8169 case CP0_REG29__DATAHI
:
8170 case CP0_REG29__DATAHI1
:
8171 case CP0_REG29__DATAHI2
:
8172 case CP0_REG29__DATAHI3
:
8173 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataHi
));
8174 register_name
= "DataHi";
8177 goto cp0_unimplemented
;
8180 case CP0_REGISTER_30
:
8182 case CP0_REG30__ERROREPC
:
8183 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
8184 register_name
= "ErrorEPC";
8187 goto cp0_unimplemented
;
8190 case CP0_REGISTER_31
:
8192 case CP0_REG31__DESAVE
:
8194 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
8195 register_name
= "DESAVE";
8197 case CP0_REG31__KSCRATCH1
:
8198 case CP0_REG31__KSCRATCH2
:
8199 case CP0_REG31__KSCRATCH3
:
8200 case CP0_REG31__KSCRATCH4
:
8201 case CP0_REG31__KSCRATCH5
:
8202 case CP0_REG31__KSCRATCH6
:
8203 CP0_CHECK(ctx
->kscrexist
& (1 << sel
));
8204 tcg_gen_ld_tl(arg
, cpu_env
,
8205 offsetof(CPUMIPSState
, CP0_KScratch
[sel
- 2]));
8206 register_name
= "KScratch";
8209 goto cp0_unimplemented
;
8213 goto cp0_unimplemented
;
8215 trace_mips_translate_c0("dmfc0", register_name
, reg
, sel
);
8219 qemu_log_mask(LOG_UNIMP
, "dmfc0 %s (reg %d sel %d)\n",
8220 register_name
, reg
, sel
);
8221 gen_mfc0_unimplemented(ctx
, arg
);
8224 static void gen_dmtc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
8226 const char *register_name
= "invalid";
8229 check_insn(ctx
, ISA_MIPS_R1
);
8232 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
8237 case CP0_REGISTER_00
:
8239 case CP0_REG00__INDEX
:
8240 gen_helper_mtc0_index(cpu_env
, arg
);
8241 register_name
= "Index";
8243 case CP0_REG00__MVPCONTROL
:
8244 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8245 gen_helper_mtc0_mvpcontrol(cpu_env
, arg
);
8246 register_name
= "MVPControl";
8248 case CP0_REG00__MVPCONF0
:
8249 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8251 register_name
= "MVPConf0";
8253 case CP0_REG00__MVPCONF1
:
8254 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8256 register_name
= "MVPConf1";
8258 case CP0_REG00__VPCONTROL
:
8261 register_name
= "VPControl";
8264 goto cp0_unimplemented
;
8267 case CP0_REGISTER_01
:
8269 case CP0_REG01__RANDOM
:
8271 register_name
= "Random";
8273 case CP0_REG01__VPECONTROL
:
8274 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8275 gen_helper_mtc0_vpecontrol(cpu_env
, arg
);
8276 register_name
= "VPEControl";
8278 case CP0_REG01__VPECONF0
:
8279 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8280 gen_helper_mtc0_vpeconf0(cpu_env
, arg
);
8281 register_name
= "VPEConf0";
8283 case CP0_REG01__VPECONF1
:
8284 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8285 gen_helper_mtc0_vpeconf1(cpu_env
, arg
);
8286 register_name
= "VPEConf1";
8288 case CP0_REG01__YQMASK
:
8289 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8290 gen_helper_mtc0_yqmask(cpu_env
, arg
);
8291 register_name
= "YQMask";
8293 case CP0_REG01__VPESCHEDULE
:
8294 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8295 tcg_gen_st_tl(arg
, cpu_env
,
8296 offsetof(CPUMIPSState
, CP0_VPESchedule
));
8297 register_name
= "VPESchedule";
8299 case CP0_REG01__VPESCHEFBACK
:
8300 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8301 tcg_gen_st_tl(arg
, cpu_env
,
8302 offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
8303 register_name
= "VPEScheFBack";
8305 case CP0_REG01__VPEOPT
:
8306 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8307 gen_helper_mtc0_vpeopt(cpu_env
, arg
);
8308 register_name
= "VPEOpt";
8311 goto cp0_unimplemented
;
8314 case CP0_REGISTER_02
:
8316 case CP0_REG02__ENTRYLO0
:
8317 gen_helper_dmtc0_entrylo0(cpu_env
, arg
);
8318 register_name
= "EntryLo0";
8320 case CP0_REG02__TCSTATUS
:
8321 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8322 gen_helper_mtc0_tcstatus(cpu_env
, arg
);
8323 register_name
= "TCStatus";
8325 case CP0_REG02__TCBIND
:
8326 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8327 gen_helper_mtc0_tcbind(cpu_env
, arg
);
8328 register_name
= "TCBind";
8330 case CP0_REG02__TCRESTART
:
8331 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8332 gen_helper_mtc0_tcrestart(cpu_env
, arg
);
8333 register_name
= "TCRestart";
8335 case CP0_REG02__TCHALT
:
8336 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8337 gen_helper_mtc0_tchalt(cpu_env
, arg
);
8338 register_name
= "TCHalt";
8340 case CP0_REG02__TCCONTEXT
:
8341 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8342 gen_helper_mtc0_tccontext(cpu_env
, arg
);
8343 register_name
= "TCContext";
8345 case CP0_REG02__TCSCHEDULE
:
8346 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8347 gen_helper_mtc0_tcschedule(cpu_env
, arg
);
8348 register_name
= "TCSchedule";
8350 case CP0_REG02__TCSCHEFBACK
:
8351 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8352 gen_helper_mtc0_tcschefback(cpu_env
, arg
);
8353 register_name
= "TCScheFBack";
8356 goto cp0_unimplemented
;
8359 case CP0_REGISTER_03
:
8361 case CP0_REG03__ENTRYLO1
:
8362 gen_helper_dmtc0_entrylo1(cpu_env
, arg
);
8363 register_name
= "EntryLo1";
8365 case CP0_REG03__GLOBALNUM
:
8368 register_name
= "GlobalNumber";
8371 goto cp0_unimplemented
;
8374 case CP0_REGISTER_04
:
8376 case CP0_REG04__CONTEXT
:
8377 gen_helper_mtc0_context(cpu_env
, arg
);
8378 register_name
= "Context";
8380 case CP0_REG04__CONTEXTCONFIG
:
8382 /* gen_helper_dmtc0_contextconfig(arg); */
8383 register_name
= "ContextConfig";
8384 goto cp0_unimplemented
;
8385 case CP0_REG04__USERLOCAL
:
8386 CP0_CHECK(ctx
->ulri
);
8387 tcg_gen_st_tl(arg
, cpu_env
,
8388 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
8389 register_name
= "UserLocal";
8391 case CP0_REG04__MMID
:
8393 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_MemoryMapID
));
8394 register_name
= "MMID";
8397 goto cp0_unimplemented
;
8400 case CP0_REGISTER_05
:
8402 case CP0_REG05__PAGEMASK
:
8403 gen_helper_mtc0_pagemask(cpu_env
, arg
);
8404 register_name
= "PageMask";
8406 case CP0_REG05__PAGEGRAIN
:
8407 check_insn(ctx
, ISA_MIPS_R2
);
8408 gen_helper_mtc0_pagegrain(cpu_env
, arg
);
8409 register_name
= "PageGrain";
8411 case CP0_REG05__SEGCTL0
:
8413 gen_helper_mtc0_segctl0(cpu_env
, arg
);
8414 register_name
= "SegCtl0";
8416 case CP0_REG05__SEGCTL1
:
8418 gen_helper_mtc0_segctl1(cpu_env
, arg
);
8419 register_name
= "SegCtl1";
8421 case CP0_REG05__SEGCTL2
:
8423 gen_helper_mtc0_segctl2(cpu_env
, arg
);
8424 register_name
= "SegCtl2";
8426 case CP0_REG05__PWBASE
:
8428 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_PWBase
));
8429 register_name
= "PWBase";
8431 case CP0_REG05__PWFIELD
:
8433 gen_helper_mtc0_pwfield(cpu_env
, arg
);
8434 register_name
= "PWField";
8436 case CP0_REG05__PWSIZE
:
8438 gen_helper_mtc0_pwsize(cpu_env
, arg
);
8439 register_name
= "PWSize";
8442 goto cp0_unimplemented
;
8445 case CP0_REGISTER_06
:
8447 case CP0_REG06__WIRED
:
8448 gen_helper_mtc0_wired(cpu_env
, arg
);
8449 register_name
= "Wired";
8451 case CP0_REG06__SRSCONF0
:
8452 check_insn(ctx
, ISA_MIPS_R2
);
8453 gen_helper_mtc0_srsconf0(cpu_env
, arg
);
8454 register_name
= "SRSConf0";
8456 case CP0_REG06__SRSCONF1
:
8457 check_insn(ctx
, ISA_MIPS_R2
);
8458 gen_helper_mtc0_srsconf1(cpu_env
, arg
);
8459 register_name
= "SRSConf1";
8461 case CP0_REG06__SRSCONF2
:
8462 check_insn(ctx
, ISA_MIPS_R2
);
8463 gen_helper_mtc0_srsconf2(cpu_env
, arg
);
8464 register_name
= "SRSConf2";
8466 case CP0_REG06__SRSCONF3
:
8467 check_insn(ctx
, ISA_MIPS_R2
);
8468 gen_helper_mtc0_srsconf3(cpu_env
, arg
);
8469 register_name
= "SRSConf3";
8471 case CP0_REG06__SRSCONF4
:
8472 check_insn(ctx
, ISA_MIPS_R2
);
8473 gen_helper_mtc0_srsconf4(cpu_env
, arg
);
8474 register_name
= "SRSConf4";
8476 case CP0_REG06__PWCTL
:
8478 gen_helper_mtc0_pwctl(cpu_env
, arg
);
8479 register_name
= "PWCtl";
8482 goto cp0_unimplemented
;
8485 case CP0_REGISTER_07
:
8487 case CP0_REG07__HWRENA
:
8488 check_insn(ctx
, ISA_MIPS_R2
);
8489 gen_helper_mtc0_hwrena(cpu_env
, arg
);
8490 ctx
->base
.is_jmp
= DISAS_STOP
;
8491 register_name
= "HWREna";
8494 goto cp0_unimplemented
;
8497 case CP0_REGISTER_08
:
8499 case CP0_REG08__BADVADDR
:
8501 register_name
= "BadVAddr";
8503 case CP0_REG08__BADINSTR
:
8505 register_name
= "BadInstr";
8507 case CP0_REG08__BADINSTRP
:
8509 register_name
= "BadInstrP";
8511 case CP0_REG08__BADINSTRX
:
8513 register_name
= "BadInstrX";
8516 goto cp0_unimplemented
;
8519 case CP0_REGISTER_09
:
8521 case CP0_REG09__COUNT
:
8522 gen_helper_mtc0_count(cpu_env
, arg
);
8523 register_name
= "Count";
8525 case CP0_REG09__SAARI
:
8526 CP0_CHECK(ctx
->saar
);
8527 gen_helper_mtc0_saari(cpu_env
, arg
);
8528 register_name
= "SAARI";
8530 case CP0_REG09__SAAR
:
8531 CP0_CHECK(ctx
->saar
);
8532 gen_helper_mtc0_saar(cpu_env
, arg
);
8533 register_name
= "SAAR";
8536 goto cp0_unimplemented
;
8538 /* Stop translation as we may have switched the execution mode */
8539 ctx
->base
.is_jmp
= DISAS_STOP
;
8541 case CP0_REGISTER_10
:
8543 case CP0_REG10__ENTRYHI
:
8544 gen_helper_mtc0_entryhi(cpu_env
, arg
);
8545 register_name
= "EntryHi";
8548 goto cp0_unimplemented
;
8551 case CP0_REGISTER_11
:
8553 case CP0_REG11__COMPARE
:
8554 gen_helper_mtc0_compare(cpu_env
, arg
);
8555 register_name
= "Compare";
8557 /* 6,7 are implementation dependent */
8559 goto cp0_unimplemented
;
8561 /* Stop translation as we may have switched the execution mode */
8562 ctx
->base
.is_jmp
= DISAS_STOP
;
8564 case CP0_REGISTER_12
:
8566 case CP0_REG12__STATUS
:
8567 save_cpu_state(ctx
, 1);
8568 gen_helper_mtc0_status(cpu_env
, arg
);
8569 /* DISAS_STOP isn't good enough here, hflags may have changed. */
8570 gen_save_pc(ctx
->base
.pc_next
+ 4);
8571 ctx
->base
.is_jmp
= DISAS_EXIT
;
8572 register_name
= "Status";
8574 case CP0_REG12__INTCTL
:
8575 check_insn(ctx
, ISA_MIPS_R2
);
8576 gen_helper_mtc0_intctl(cpu_env
, arg
);
8577 /* Stop translation as we may have switched the execution mode */
8578 ctx
->base
.is_jmp
= DISAS_STOP
;
8579 register_name
= "IntCtl";
8581 case CP0_REG12__SRSCTL
:
8582 check_insn(ctx
, ISA_MIPS_R2
);
8583 gen_helper_mtc0_srsctl(cpu_env
, arg
);
8584 /* Stop translation as we may have switched the execution mode */
8585 ctx
->base
.is_jmp
= DISAS_STOP
;
8586 register_name
= "SRSCtl";
8588 case CP0_REG12__SRSMAP
:
8589 check_insn(ctx
, ISA_MIPS_R2
);
8590 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
8591 /* Stop translation as we may have switched the execution mode */
8592 ctx
->base
.is_jmp
= DISAS_STOP
;
8593 register_name
= "SRSMap";
8596 goto cp0_unimplemented
;
8599 case CP0_REGISTER_13
:
8601 case CP0_REG13__CAUSE
:
8602 save_cpu_state(ctx
, 1);
8603 gen_helper_mtc0_cause(cpu_env
, arg
);
8605 * Stop translation as we may have triggered an interrupt.
8606 * DISAS_STOP isn't sufficient, we need to ensure we break out of
8607 * translated code to check for pending interrupts.
8609 gen_save_pc(ctx
->base
.pc_next
+ 4);
8610 ctx
->base
.is_jmp
= DISAS_EXIT
;
8611 register_name
= "Cause";
8614 goto cp0_unimplemented
;
8617 case CP0_REGISTER_14
:
8619 case CP0_REG14__EPC
:
8620 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
8621 register_name
= "EPC";
8624 goto cp0_unimplemented
;
8627 case CP0_REGISTER_15
:
8629 case CP0_REG15__PRID
:
8631 register_name
= "PRid";
8633 case CP0_REG15__EBASE
:
8634 check_insn(ctx
, ISA_MIPS_R2
);
8635 gen_helper_mtc0_ebase(cpu_env
, arg
);
8636 register_name
= "EBase";
8639 goto cp0_unimplemented
;
8642 case CP0_REGISTER_16
:
8644 case CP0_REG16__CONFIG
:
8645 gen_helper_mtc0_config0(cpu_env
, arg
);
8646 register_name
= "Config";
8647 /* Stop translation as we may have switched the execution mode */
8648 ctx
->base
.is_jmp
= DISAS_STOP
;
8650 case CP0_REG16__CONFIG1
:
8651 /* ignored, read only */
8652 register_name
= "Config1";
8654 case CP0_REG16__CONFIG2
:
8655 gen_helper_mtc0_config2(cpu_env
, arg
);
8656 register_name
= "Config2";
8657 /* Stop translation as we may have switched the execution mode */
8658 ctx
->base
.is_jmp
= DISAS_STOP
;
8660 case CP0_REG16__CONFIG3
:
8661 gen_helper_mtc0_config3(cpu_env
, arg
);
8662 register_name
= "Config3";
8663 /* Stop translation as we may have switched the execution mode */
8664 ctx
->base
.is_jmp
= DISAS_STOP
;
8666 case CP0_REG16__CONFIG4
:
8667 /* currently ignored */
8668 register_name
= "Config4";
8670 case CP0_REG16__CONFIG5
:
8671 gen_helper_mtc0_config5(cpu_env
, arg
);
8672 register_name
= "Config5";
8673 /* Stop translation as we may have switched the execution mode */
8674 ctx
->base
.is_jmp
= DISAS_STOP
;
8676 /* 6,7 are implementation dependent */
8678 register_name
= "Invalid config selector";
8679 goto cp0_unimplemented
;
8682 case CP0_REGISTER_17
:
8684 case CP0_REG17__LLADDR
:
8685 gen_helper_mtc0_lladdr(cpu_env
, arg
);
8686 register_name
= "LLAddr";
8688 case CP0_REG17__MAAR
:
8689 CP0_CHECK(ctx
->mrp
);
8690 gen_helper_mtc0_maar(cpu_env
, arg
);
8691 register_name
= "MAAR";
8693 case CP0_REG17__MAARI
:
8694 CP0_CHECK(ctx
->mrp
);
8695 gen_helper_mtc0_maari(cpu_env
, arg
);
8696 register_name
= "MAARI";
8699 goto cp0_unimplemented
;
8702 case CP0_REGISTER_18
:
8704 case CP0_REG18__WATCHLO0
:
8705 case CP0_REG18__WATCHLO1
:
8706 case CP0_REG18__WATCHLO2
:
8707 case CP0_REG18__WATCHLO3
:
8708 case CP0_REG18__WATCHLO4
:
8709 case CP0_REG18__WATCHLO5
:
8710 case CP0_REG18__WATCHLO6
:
8711 case CP0_REG18__WATCHLO7
:
8712 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
8713 gen_helper_0e1i(mtc0_watchlo
, arg
, sel
);
8714 register_name
= "WatchLo";
8717 goto cp0_unimplemented
;
8720 case CP0_REGISTER_19
:
8722 case CP0_REG19__WATCHHI0
:
8723 case CP0_REG19__WATCHHI1
:
8724 case CP0_REG19__WATCHHI2
:
8725 case CP0_REG19__WATCHHI3
:
8726 case CP0_REG19__WATCHHI4
:
8727 case CP0_REG19__WATCHHI5
:
8728 case CP0_REG19__WATCHHI6
:
8729 case CP0_REG19__WATCHHI7
:
8730 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
8731 gen_helper_0e1i(mtc0_watchhi
, arg
, sel
);
8732 register_name
= "WatchHi";
8735 goto cp0_unimplemented
;
8738 case CP0_REGISTER_20
:
8740 case CP0_REG20__XCONTEXT
:
8741 check_insn(ctx
, ISA_MIPS3
);
8742 gen_helper_mtc0_xcontext(cpu_env
, arg
);
8743 register_name
= "XContext";
8746 goto cp0_unimplemented
;
8749 case CP0_REGISTER_21
:
8750 /* Officially reserved, but sel 0 is used for R1x000 framemask */
8751 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS_R6
));
8754 gen_helper_mtc0_framemask(cpu_env
, arg
);
8755 register_name
= "Framemask";
8758 goto cp0_unimplemented
;
8761 case CP0_REGISTER_22
:
8763 register_name
= "Diagnostic"; /* implementation dependent */
8765 case CP0_REGISTER_23
:
8767 case CP0_REG23__DEBUG
:
8768 gen_helper_mtc0_debug(cpu_env
, arg
); /* EJTAG support */
8769 /* DISAS_STOP isn't good enough here, hflags may have changed. */
8770 gen_save_pc(ctx
->base
.pc_next
+ 4);
8771 ctx
->base
.is_jmp
= DISAS_EXIT
;
8772 register_name
= "Debug";
8774 case CP0_REG23__TRACECONTROL
:
8775 /* PDtrace support */
8776 /* gen_helper_mtc0_tracecontrol(cpu_env, arg); */
8777 /* Stop translation as we may have switched the execution mode */
8778 ctx
->base
.is_jmp
= DISAS_STOP
;
8779 register_name
= "TraceControl";
8780 goto cp0_unimplemented
;
8781 case CP0_REG23__TRACECONTROL2
:
8782 /* PDtrace support */
8783 /* gen_helper_mtc0_tracecontrol2(cpu_env, arg); */
8784 /* Stop translation as we may have switched the execution mode */
8785 ctx
->base
.is_jmp
= DISAS_STOP
;
8786 register_name
= "TraceControl2";
8787 goto cp0_unimplemented
;
8788 case CP0_REG23__USERTRACEDATA1
:
8789 /* PDtrace support */
8790 /* gen_helper_mtc0_usertracedata1(cpu_env, arg);*/
8791 /* Stop translation as we may have switched the execution mode */
8792 ctx
->base
.is_jmp
= DISAS_STOP
;
8793 register_name
= "UserTraceData1";
8794 goto cp0_unimplemented
;
8795 case CP0_REG23__TRACEIBPC
:
8796 /* PDtrace support */
8797 /* gen_helper_mtc0_traceibpc(cpu_env, arg); */
8798 /* Stop translation as we may have switched the execution mode */
8799 ctx
->base
.is_jmp
= DISAS_STOP
;
8800 register_name
= "TraceIBPC";
8801 goto cp0_unimplemented
;
8802 case CP0_REG23__TRACEDBPC
:
8803 /* PDtrace support */
8804 /* gen_helper_mtc0_tracedbpc(cpu_env, arg); */
8805 /* Stop translation as we may have switched the execution mode */
8806 ctx
->base
.is_jmp
= DISAS_STOP
;
8807 register_name
= "TraceDBPC";
8808 goto cp0_unimplemented
;
8810 goto cp0_unimplemented
;
8813 case CP0_REGISTER_24
:
8815 case CP0_REG24__DEPC
:
8817 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
8818 register_name
= "DEPC";
8821 goto cp0_unimplemented
;
8824 case CP0_REGISTER_25
:
8826 case CP0_REG25__PERFCTL0
:
8827 gen_helper_mtc0_performance0(cpu_env
, arg
);
8828 register_name
= "Performance0";
8830 case CP0_REG25__PERFCNT0
:
8831 /* gen_helper_mtc0_performance1(cpu_env, arg); */
8832 register_name
= "Performance1";
8833 goto cp0_unimplemented
;
8834 case CP0_REG25__PERFCTL1
:
8835 /* gen_helper_mtc0_performance2(cpu_env, arg); */
8836 register_name
= "Performance2";
8837 goto cp0_unimplemented
;
8838 case CP0_REG25__PERFCNT1
:
8839 /* gen_helper_mtc0_performance3(cpu_env, arg); */
8840 register_name
= "Performance3";
8841 goto cp0_unimplemented
;
8842 case CP0_REG25__PERFCTL2
:
8843 /* gen_helper_mtc0_performance4(cpu_env, arg); */
8844 register_name
= "Performance4";
8845 goto cp0_unimplemented
;
8846 case CP0_REG25__PERFCNT2
:
8847 /* gen_helper_mtc0_performance5(cpu_env, arg); */
8848 register_name
= "Performance5";
8849 goto cp0_unimplemented
;
8850 case CP0_REG25__PERFCTL3
:
8851 /* gen_helper_mtc0_performance6(cpu_env, arg); */
8852 register_name
= "Performance6";
8853 goto cp0_unimplemented
;
8854 case CP0_REG25__PERFCNT3
:
8855 /* gen_helper_mtc0_performance7(cpu_env, arg); */
8856 register_name
= "Performance7";
8857 goto cp0_unimplemented
;
8859 goto cp0_unimplemented
;
8862 case CP0_REGISTER_26
:
8864 case CP0_REG26__ERRCTL
:
8865 gen_helper_mtc0_errctl(cpu_env
, arg
);
8866 ctx
->base
.is_jmp
= DISAS_STOP
;
8867 register_name
= "ErrCtl";
8870 goto cp0_unimplemented
;
8873 case CP0_REGISTER_27
:
8875 case CP0_REG27__CACHERR
:
8877 register_name
= "CacheErr";
8880 goto cp0_unimplemented
;
8883 case CP0_REGISTER_28
:
8885 case CP0_REG28__TAGLO
:
8886 case CP0_REG28__TAGLO1
:
8887 case CP0_REG28__TAGLO2
:
8888 case CP0_REG28__TAGLO3
:
8889 gen_helper_mtc0_taglo(cpu_env
, arg
);
8890 register_name
= "TagLo";
8892 case CP0_REG28__DATALO
:
8893 case CP0_REG28__DATALO1
:
8894 case CP0_REG28__DATALO2
:
8895 case CP0_REG28__DATALO3
:
8896 gen_helper_mtc0_datalo(cpu_env
, arg
);
8897 register_name
= "DataLo";
8900 goto cp0_unimplemented
;
8903 case CP0_REGISTER_29
:
8905 case CP0_REG29__TAGHI
:
8906 case CP0_REG29__TAGHI1
:
8907 case CP0_REG29__TAGHI2
:
8908 case CP0_REG29__TAGHI3
:
8909 gen_helper_mtc0_taghi(cpu_env
, arg
);
8910 register_name
= "TagHi";
8912 case CP0_REG29__DATAHI
:
8913 case CP0_REG29__DATAHI1
:
8914 case CP0_REG29__DATAHI2
:
8915 case CP0_REG29__DATAHI3
:
8916 gen_helper_mtc0_datahi(cpu_env
, arg
);
8917 register_name
= "DataHi";
8920 register_name
= "invalid sel";
8921 goto cp0_unimplemented
;
8924 case CP0_REGISTER_30
:
8926 case CP0_REG30__ERROREPC
:
8927 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
8928 register_name
= "ErrorEPC";
8931 goto cp0_unimplemented
;
8934 case CP0_REGISTER_31
:
8936 case CP0_REG31__DESAVE
:
8938 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
8939 register_name
= "DESAVE";
8941 case CP0_REG31__KSCRATCH1
:
8942 case CP0_REG31__KSCRATCH2
:
8943 case CP0_REG31__KSCRATCH3
:
8944 case CP0_REG31__KSCRATCH4
:
8945 case CP0_REG31__KSCRATCH5
:
8946 case CP0_REG31__KSCRATCH6
:
8947 CP0_CHECK(ctx
->kscrexist
& (1 << sel
));
8948 tcg_gen_st_tl(arg
, cpu_env
,
8949 offsetof(CPUMIPSState
, CP0_KScratch
[sel
- 2]));
8950 register_name
= "KScratch";
8953 goto cp0_unimplemented
;
8957 goto cp0_unimplemented
;
8959 trace_mips_translate_c0("dmtc0", register_name
, reg
, sel
);
8961 /* For simplicity assume that all writes can cause interrupts. */
8962 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
8964 * DISAS_STOP isn't sufficient, we need to ensure we break out of
8965 * translated code to check for pending interrupts.
8967 gen_save_pc(ctx
->base
.pc_next
+ 4);
8968 ctx
->base
.is_jmp
= DISAS_EXIT
;
8973 qemu_log_mask(LOG_UNIMP
, "dmtc0 %s (reg %d sel %d)\n",
8974 register_name
, reg
, sel
);
8976 #endif /* TARGET_MIPS64 */
8978 static void gen_mftr(CPUMIPSState
*env
, DisasContext
*ctx
, int rt
, int rd
,
8979 int u
, int sel
, int h
)
8981 int other_tc
= env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
);
8982 TCGv t0
= tcg_temp_local_new();
8984 if ((env
->CP0_VPEConf0
& (1 << CP0VPEC0_MVP
)) == 0 &&
8985 ((env
->tcs
[other_tc
].CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)) !=
8986 (env
->active_tc
.CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)))) {
8987 tcg_gen_movi_tl(t0
, -1);
8988 } else if ((env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
)) >
8989 (env
->mvp
->CP0_MVPConf0
& (0xff << CP0MVPC0_PTC
))) {
8990 tcg_gen_movi_tl(t0
, -1);
8991 } else if (u
== 0) {
8996 gen_helper_mftc0_vpecontrol(t0
, cpu_env
);
8999 gen_helper_mftc0_vpeconf0(t0
, cpu_env
);
9009 gen_helper_mftc0_tcstatus(t0
, cpu_env
);
9012 gen_helper_mftc0_tcbind(t0
, cpu_env
);
9015 gen_helper_mftc0_tcrestart(t0
, cpu_env
);
9018 gen_helper_mftc0_tchalt(t0
, cpu_env
);
9021 gen_helper_mftc0_tccontext(t0
, cpu_env
);
9024 gen_helper_mftc0_tcschedule(t0
, cpu_env
);
9027 gen_helper_mftc0_tcschefback(t0
, cpu_env
);
9030 gen_mfc0(ctx
, t0
, rt
, sel
);
9037 gen_helper_mftc0_entryhi(t0
, cpu_env
);
9040 gen_mfc0(ctx
, t0
, rt
, sel
);
9047 gen_helper_mftc0_status(t0
, cpu_env
);
9050 gen_mfc0(ctx
, t0
, rt
, sel
);
9057 gen_helper_mftc0_cause(t0
, cpu_env
);
9067 gen_helper_mftc0_epc(t0
, cpu_env
);
9077 gen_helper_mftc0_ebase(t0
, cpu_env
);
9094 gen_helper_mftc0_configx(t0
, cpu_env
, tcg_const_tl(sel
));
9104 gen_helper_mftc0_debug(t0
, cpu_env
);
9107 gen_mfc0(ctx
, t0
, rt
, sel
);
9112 gen_mfc0(ctx
, t0
, rt
, sel
);
9116 /* GPR registers. */
9118 gen_helper_1e0i(mftgpr
, t0
, rt
);
9120 /* Auxiliary CPU registers */
9124 gen_helper_1e0i(mftlo
, t0
, 0);
9127 gen_helper_1e0i(mfthi
, t0
, 0);
9130 gen_helper_1e0i(mftacx
, t0
, 0);
9133 gen_helper_1e0i(mftlo
, t0
, 1);
9136 gen_helper_1e0i(mfthi
, t0
, 1);
9139 gen_helper_1e0i(mftacx
, t0
, 1);
9142 gen_helper_1e0i(mftlo
, t0
, 2);
9145 gen_helper_1e0i(mfthi
, t0
, 2);
9148 gen_helper_1e0i(mftacx
, t0
, 2);
9151 gen_helper_1e0i(mftlo
, t0
, 3);
9154 gen_helper_1e0i(mfthi
, t0
, 3);
9157 gen_helper_1e0i(mftacx
, t0
, 3);
9160 gen_helper_mftdsp(t0
, cpu_env
);
9166 /* Floating point (COP1). */
9168 /* XXX: For now we support only a single FPU context. */
9170 TCGv_i32 fp0
= tcg_temp_new_i32();
9172 gen_load_fpr32(ctx
, fp0
, rt
);
9173 tcg_gen_ext_i32_tl(t0
, fp0
);
9174 tcg_temp_free_i32(fp0
);
9176 TCGv_i32 fp0
= tcg_temp_new_i32();
9178 gen_load_fpr32h(ctx
, fp0
, rt
);
9179 tcg_gen_ext_i32_tl(t0
, fp0
);
9180 tcg_temp_free_i32(fp0
);
9184 /* XXX: For now we support only a single FPU context. */
9185 gen_helper_1e0i(cfc1
, t0
, rt
);
9187 /* COP2: Not implemented. */
9195 trace_mips_translate_tr("mftr", rt
, u
, sel
, h
);
9196 gen_store_gpr(t0
, rd
);
9202 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt
, u
, sel
, h
);
9203 gen_reserved_instruction(ctx
);
9206 static void gen_mttr(CPUMIPSState
*env
, DisasContext
*ctx
, int rd
, int rt
,
9207 int u
, int sel
, int h
)
9209 int other_tc
= env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
);
9210 TCGv t0
= tcg_temp_local_new();
9212 gen_load_gpr(t0
, rt
);
9213 if ((env
->CP0_VPEConf0
& (1 << CP0VPEC0_MVP
)) == 0 &&
9214 ((env
->tcs
[other_tc
].CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)) !=
9215 (env
->active_tc
.CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)))) {
9218 } else if ((env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
)) >
9219 (env
->mvp
->CP0_MVPConf0
& (0xff << CP0MVPC0_PTC
))) {
9222 } else if (u
== 0) {
9227 gen_helper_mttc0_vpecontrol(cpu_env
, t0
);
9230 gen_helper_mttc0_vpeconf0(cpu_env
, t0
);
9240 gen_helper_mttc0_tcstatus(cpu_env
, t0
);
9243 gen_helper_mttc0_tcbind(cpu_env
, t0
);
9246 gen_helper_mttc0_tcrestart(cpu_env
, t0
);
9249 gen_helper_mttc0_tchalt(cpu_env
, t0
);
9252 gen_helper_mttc0_tccontext(cpu_env
, t0
);
9255 gen_helper_mttc0_tcschedule(cpu_env
, t0
);
9258 gen_helper_mttc0_tcschefback(cpu_env
, t0
);
9261 gen_mtc0(ctx
, t0
, rd
, sel
);
9268 gen_helper_mttc0_entryhi(cpu_env
, t0
);
9271 gen_mtc0(ctx
, t0
, rd
, sel
);
9278 gen_helper_mttc0_status(cpu_env
, t0
);
9281 gen_mtc0(ctx
, t0
, rd
, sel
);
9288 gen_helper_mttc0_cause(cpu_env
, t0
);
9298 gen_helper_mttc0_ebase(cpu_env
, t0
);
9308 gen_helper_mttc0_debug(cpu_env
, t0
);
9311 gen_mtc0(ctx
, t0
, rd
, sel
);
9316 gen_mtc0(ctx
, t0
, rd
, sel
);
9320 /* GPR registers. */
9322 gen_helper_0e1i(mttgpr
, t0
, rd
);
9324 /* Auxiliary CPU registers */
9328 gen_helper_0e1i(mttlo
, t0
, 0);
9331 gen_helper_0e1i(mtthi
, t0
, 0);
9334 gen_helper_0e1i(mttacx
, t0
, 0);
9337 gen_helper_0e1i(mttlo
, t0
, 1);
9340 gen_helper_0e1i(mtthi
, t0
, 1);
9343 gen_helper_0e1i(mttacx
, t0
, 1);
9346 gen_helper_0e1i(mttlo
, t0
, 2);
9349 gen_helper_0e1i(mtthi
, t0
, 2);
9352 gen_helper_0e1i(mttacx
, t0
, 2);
9355 gen_helper_0e1i(mttlo
, t0
, 3);
9358 gen_helper_0e1i(mtthi
, t0
, 3);
9361 gen_helper_0e1i(mttacx
, t0
, 3);
9364 gen_helper_mttdsp(cpu_env
, t0
);
9370 /* Floating point (COP1). */
9372 /* XXX: For now we support only a single FPU context. */
9374 TCGv_i32 fp0
= tcg_temp_new_i32();
9376 tcg_gen_trunc_tl_i32(fp0
, t0
);
9377 gen_store_fpr32(ctx
, fp0
, rd
);
9378 tcg_temp_free_i32(fp0
);
9380 TCGv_i32 fp0
= tcg_temp_new_i32();
9382 tcg_gen_trunc_tl_i32(fp0
, t0
);
9383 gen_store_fpr32h(ctx
, fp0
, rd
);
9384 tcg_temp_free_i32(fp0
);
9388 /* XXX: For now we support only a single FPU context. */
9390 TCGv_i32 fs_tmp
= tcg_const_i32(rd
);
9392 gen_helper_0e2i(ctc1
, t0
, fs_tmp
, rt
);
9393 tcg_temp_free_i32(fs_tmp
);
9395 /* Stop translation as we may have changed hflags */
9396 ctx
->base
.is_jmp
= DISAS_STOP
;
9398 /* COP2: Not implemented. */
9406 trace_mips_translate_tr("mttr", rd
, u
, sel
, h
);
9412 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd
, u
, sel
, h
);
9413 gen_reserved_instruction(ctx
);
9416 static void gen_cp0(CPUMIPSState
*env
, DisasContext
*ctx
, uint32_t opc
,
9419 const char *opn
= "ldst";
9421 check_cp0_enabled(ctx
);
9428 gen_mfc0(ctx
, cpu_gpr
[rt
], rd
, ctx
->opcode
& 0x7);
9433 TCGv t0
= tcg_temp_new();
9435 gen_load_gpr(t0
, rt
);
9436 gen_mtc0(ctx
, t0
, rd
, ctx
->opcode
& 0x7);
9441 #if defined(TARGET_MIPS64)
9443 check_insn(ctx
, ISA_MIPS3
);
9448 gen_dmfc0(ctx
, cpu_gpr
[rt
], rd
, ctx
->opcode
& 0x7);
9452 check_insn(ctx
, ISA_MIPS3
);
9454 TCGv t0
= tcg_temp_new();
9456 gen_load_gpr(t0
, rt
);
9457 gen_dmtc0(ctx
, t0
, rd
, ctx
->opcode
& 0x7);
9469 gen_mfhc0(ctx
, cpu_gpr
[rt
], rd
, ctx
->opcode
& 0x7);
9475 TCGv t0
= tcg_temp_new();
9476 gen_load_gpr(t0
, rt
);
9477 gen_mthc0(ctx
, t0
, rd
, ctx
->opcode
& 0x7);
9483 check_cp0_enabled(ctx
);
9488 gen_mftr(env
, ctx
, rt
, rd
, (ctx
->opcode
>> 5) & 1,
9489 ctx
->opcode
& 0x7, (ctx
->opcode
>> 4) & 1);
9493 check_cp0_enabled(ctx
);
9494 gen_mttr(env
, ctx
, rd
, rt
, (ctx
->opcode
>> 5) & 1,
9495 ctx
->opcode
& 0x7, (ctx
->opcode
>> 4) & 1);
9500 if (!env
->tlb
->helper_tlbwi
) {
9503 gen_helper_tlbwi(cpu_env
);
9508 if (!env
->tlb
->helper_tlbinv
) {
9511 gen_helper_tlbinv(cpu_env
);
9512 } /* treat as nop if TLBINV not supported */
9517 if (!env
->tlb
->helper_tlbinvf
) {
9520 gen_helper_tlbinvf(cpu_env
);
9521 } /* treat as nop if TLBINV not supported */
9525 if (!env
->tlb
->helper_tlbwr
) {
9528 gen_helper_tlbwr(cpu_env
);
9532 if (!env
->tlb
->helper_tlbp
) {
9535 gen_helper_tlbp(cpu_env
);
9539 if (!env
->tlb
->helper_tlbr
) {
9542 gen_helper_tlbr(cpu_env
);
9544 case OPC_ERET
: /* OPC_ERETNC */
9545 if ((ctx
->insn_flags
& ISA_MIPS_R6
) &&
9546 (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
9549 int bit_shift
= (ctx
->hflags
& MIPS_HFLAG_M16
) ? 16 : 6;
9550 if (ctx
->opcode
& (1 << bit_shift
)) {
9553 check_insn(ctx
, ISA_MIPS_R5
);
9554 gen_helper_eretnc(cpu_env
);
9558 check_insn(ctx
, ISA_MIPS2
);
9559 gen_helper_eret(cpu_env
);
9561 ctx
->base
.is_jmp
= DISAS_EXIT
;
9566 check_insn(ctx
, ISA_MIPS_R1
);
9567 if ((ctx
->insn_flags
& ISA_MIPS_R6
) &&
9568 (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
9571 if (!(ctx
->hflags
& MIPS_HFLAG_DM
)) {
9573 gen_reserved_instruction(ctx
);
9575 gen_helper_deret(cpu_env
);
9576 ctx
->base
.is_jmp
= DISAS_EXIT
;
9581 check_insn(ctx
, ISA_MIPS3
| ISA_MIPS_R1
);
9582 if ((ctx
->insn_flags
& ISA_MIPS_R6
) &&
9583 (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
9586 /* If we get an exception, we want to restart at next instruction */
9587 ctx
->base
.pc_next
+= 4;
9588 save_cpu_state(ctx
, 1);
9589 ctx
->base
.pc_next
-= 4;
9590 gen_helper_wait(cpu_env
);
9591 ctx
->base
.is_jmp
= DISAS_NORETURN
;
9596 gen_reserved_instruction(ctx
);
9599 (void)opn
; /* avoid a compiler warning */
9601 #endif /* !CONFIG_USER_ONLY */
9603 /* CP1 Branches (before delay slot) */
9604 static void gen_compute_branch1(DisasContext
*ctx
, uint32_t op
,
9605 int32_t cc
, int32_t offset
)
9607 target_ulong btarget
;
9608 TCGv_i32 t0
= tcg_temp_new_i32();
9610 if ((ctx
->insn_flags
& ISA_MIPS_R6
) && (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
9611 gen_reserved_instruction(ctx
);
9616 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS_R1
);
9619 btarget
= ctx
->base
.pc_next
+ 4 + offset
;
9623 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
9624 tcg_gen_not_i32(t0
, t0
);
9625 tcg_gen_andi_i32(t0
, t0
, 1);
9626 tcg_gen_extu_i32_tl(bcond
, t0
);
9629 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
9630 tcg_gen_not_i32(t0
, t0
);
9631 tcg_gen_andi_i32(t0
, t0
, 1);
9632 tcg_gen_extu_i32_tl(bcond
, t0
);
9635 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
9636 tcg_gen_andi_i32(t0
, t0
, 1);
9637 tcg_gen_extu_i32_tl(bcond
, t0
);
9640 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
9641 tcg_gen_andi_i32(t0
, t0
, 1);
9642 tcg_gen_extu_i32_tl(bcond
, t0
);
9644 ctx
->hflags
|= MIPS_HFLAG_BL
;
9648 TCGv_i32 t1
= tcg_temp_new_i32();
9649 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
9650 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 1));
9651 tcg_gen_nand_i32(t0
, t0
, t1
);
9652 tcg_temp_free_i32(t1
);
9653 tcg_gen_andi_i32(t0
, t0
, 1);
9654 tcg_gen_extu_i32_tl(bcond
, t0
);
9659 TCGv_i32 t1
= tcg_temp_new_i32();
9660 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
9661 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 1));
9662 tcg_gen_or_i32(t0
, t0
, t1
);
9663 tcg_temp_free_i32(t1
);
9664 tcg_gen_andi_i32(t0
, t0
, 1);
9665 tcg_gen_extu_i32_tl(bcond
, t0
);
9670 TCGv_i32 t1
= tcg_temp_new_i32();
9671 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
9672 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 1));
9673 tcg_gen_and_i32(t0
, t0
, t1
);
9674 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 2));
9675 tcg_gen_and_i32(t0
, t0
, t1
);
9676 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 3));
9677 tcg_gen_nand_i32(t0
, t0
, t1
);
9678 tcg_temp_free_i32(t1
);
9679 tcg_gen_andi_i32(t0
, t0
, 1);
9680 tcg_gen_extu_i32_tl(bcond
, t0
);
9685 TCGv_i32 t1
= tcg_temp_new_i32();
9686 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
9687 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 1));
9688 tcg_gen_or_i32(t0
, t0
, t1
);
9689 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 2));
9690 tcg_gen_or_i32(t0
, t0
, t1
);
9691 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 3));
9692 tcg_gen_or_i32(t0
, t0
, t1
);
9693 tcg_temp_free_i32(t1
);
9694 tcg_gen_andi_i32(t0
, t0
, 1);
9695 tcg_gen_extu_i32_tl(bcond
, t0
);
9698 ctx
->hflags
|= MIPS_HFLAG_BC
;
9701 MIPS_INVAL("cp1 cond branch");
9702 gen_reserved_instruction(ctx
);
9705 ctx
->btarget
= btarget
;
9706 ctx
->hflags
|= MIPS_HFLAG_BDS32
;
9708 tcg_temp_free_i32(t0
);
9711 /* R6 CP1 Branches */
9712 static void gen_compute_branch1_r6(DisasContext
*ctx
, uint32_t op
,
9713 int32_t ft
, int32_t offset
,
9716 target_ulong btarget
;
9717 TCGv_i64 t0
= tcg_temp_new_i64();
9719 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
9720 #ifdef MIPS_DEBUG_DISAS
9721 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
9722 "\n", ctx
->base
.pc_next
);
9724 gen_reserved_instruction(ctx
);
9728 gen_load_fpr64(ctx
, t0
, ft
);
9729 tcg_gen_andi_i64(t0
, t0
, 1);
9731 btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
9735 tcg_gen_xori_i64(t0
, t0
, 1);
9736 ctx
->hflags
|= MIPS_HFLAG_BC
;
9739 /* t0 already set */
9740 ctx
->hflags
|= MIPS_HFLAG_BC
;
9743 MIPS_INVAL("cp1 cond branch");
9744 gen_reserved_instruction(ctx
);
9748 tcg_gen_trunc_i64_tl(bcond
, t0
);
9750 ctx
->btarget
= btarget
;
9752 switch (delayslot_size
) {
9754 ctx
->hflags
|= MIPS_HFLAG_BDS16
;
9757 ctx
->hflags
|= MIPS_HFLAG_BDS32
;
9762 tcg_temp_free_i64(t0
);
9765 /* Coprocessor 1 (FPU) */
9767 #define FOP(func, fmt) (((fmt) << 21) | (func))
9770 OPC_ADD_S
= FOP(0, FMT_S
),
9771 OPC_SUB_S
= FOP(1, FMT_S
),
9772 OPC_MUL_S
= FOP(2, FMT_S
),
9773 OPC_DIV_S
= FOP(3, FMT_S
),
9774 OPC_SQRT_S
= FOP(4, FMT_S
),
9775 OPC_ABS_S
= FOP(5, FMT_S
),
9776 OPC_MOV_S
= FOP(6, FMT_S
),
9777 OPC_NEG_S
= FOP(7, FMT_S
),
9778 OPC_ROUND_L_S
= FOP(8, FMT_S
),
9779 OPC_TRUNC_L_S
= FOP(9, FMT_S
),
9780 OPC_CEIL_L_S
= FOP(10, FMT_S
),
9781 OPC_FLOOR_L_S
= FOP(11, FMT_S
),
9782 OPC_ROUND_W_S
= FOP(12, FMT_S
),
9783 OPC_TRUNC_W_S
= FOP(13, FMT_S
),
9784 OPC_CEIL_W_S
= FOP(14, FMT_S
),
9785 OPC_FLOOR_W_S
= FOP(15, FMT_S
),
9786 OPC_SEL_S
= FOP(16, FMT_S
),
9787 OPC_MOVCF_S
= FOP(17, FMT_S
),
9788 OPC_MOVZ_S
= FOP(18, FMT_S
),
9789 OPC_MOVN_S
= FOP(19, FMT_S
),
9790 OPC_SELEQZ_S
= FOP(20, FMT_S
),
9791 OPC_RECIP_S
= FOP(21, FMT_S
),
9792 OPC_RSQRT_S
= FOP(22, FMT_S
),
9793 OPC_SELNEZ_S
= FOP(23, FMT_S
),
9794 OPC_MADDF_S
= FOP(24, FMT_S
),
9795 OPC_MSUBF_S
= FOP(25, FMT_S
),
9796 OPC_RINT_S
= FOP(26, FMT_S
),
9797 OPC_CLASS_S
= FOP(27, FMT_S
),
9798 OPC_MIN_S
= FOP(28, FMT_S
),
9799 OPC_RECIP2_S
= FOP(28, FMT_S
),
9800 OPC_MINA_S
= FOP(29, FMT_S
),
9801 OPC_RECIP1_S
= FOP(29, FMT_S
),
9802 OPC_MAX_S
= FOP(30, FMT_S
),
9803 OPC_RSQRT1_S
= FOP(30, FMT_S
),
9804 OPC_MAXA_S
= FOP(31, FMT_S
),
9805 OPC_RSQRT2_S
= FOP(31, FMT_S
),
9806 OPC_CVT_D_S
= FOP(33, FMT_S
),
9807 OPC_CVT_W_S
= FOP(36, FMT_S
),
9808 OPC_CVT_L_S
= FOP(37, FMT_S
),
9809 OPC_CVT_PS_S
= FOP(38, FMT_S
),
9810 OPC_CMP_F_S
= FOP(48, FMT_S
),
9811 OPC_CMP_UN_S
= FOP(49, FMT_S
),
9812 OPC_CMP_EQ_S
= FOP(50, FMT_S
),
9813 OPC_CMP_UEQ_S
= FOP(51, FMT_S
),
9814 OPC_CMP_OLT_S
= FOP(52, FMT_S
),
9815 OPC_CMP_ULT_S
= FOP(53, FMT_S
),
9816 OPC_CMP_OLE_S
= FOP(54, FMT_S
),
9817 OPC_CMP_ULE_S
= FOP(55, FMT_S
),
9818 OPC_CMP_SF_S
= FOP(56, FMT_S
),
9819 OPC_CMP_NGLE_S
= FOP(57, FMT_S
),
9820 OPC_CMP_SEQ_S
= FOP(58, FMT_S
),
9821 OPC_CMP_NGL_S
= FOP(59, FMT_S
),
9822 OPC_CMP_LT_S
= FOP(60, FMT_S
),
9823 OPC_CMP_NGE_S
= FOP(61, FMT_S
),
9824 OPC_CMP_LE_S
= FOP(62, FMT_S
),
9825 OPC_CMP_NGT_S
= FOP(63, FMT_S
),
9827 OPC_ADD_D
= FOP(0, FMT_D
),
9828 OPC_SUB_D
= FOP(1, FMT_D
),
9829 OPC_MUL_D
= FOP(2, FMT_D
),
9830 OPC_DIV_D
= FOP(3, FMT_D
),
9831 OPC_SQRT_D
= FOP(4, FMT_D
),
9832 OPC_ABS_D
= FOP(5, FMT_D
),
9833 OPC_MOV_D
= FOP(6, FMT_D
),
9834 OPC_NEG_D
= FOP(7, FMT_D
),
9835 OPC_ROUND_L_D
= FOP(8, FMT_D
),
9836 OPC_TRUNC_L_D
= FOP(9, FMT_D
),
9837 OPC_CEIL_L_D
= FOP(10, FMT_D
),
9838 OPC_FLOOR_L_D
= FOP(11, FMT_D
),
9839 OPC_ROUND_W_D
= FOP(12, FMT_D
),
9840 OPC_TRUNC_W_D
= FOP(13, FMT_D
),
9841 OPC_CEIL_W_D
= FOP(14, FMT_D
),
9842 OPC_FLOOR_W_D
= FOP(15, FMT_D
),
9843 OPC_SEL_D
= FOP(16, FMT_D
),
9844 OPC_MOVCF_D
= FOP(17, FMT_D
),
9845 OPC_MOVZ_D
= FOP(18, FMT_D
),
9846 OPC_MOVN_D
= FOP(19, FMT_D
),
9847 OPC_SELEQZ_D
= FOP(20, FMT_D
),
9848 OPC_RECIP_D
= FOP(21, FMT_D
),
9849 OPC_RSQRT_D
= FOP(22, FMT_D
),
9850 OPC_SELNEZ_D
= FOP(23, FMT_D
),
9851 OPC_MADDF_D
= FOP(24, FMT_D
),
9852 OPC_MSUBF_D
= FOP(25, FMT_D
),
9853 OPC_RINT_D
= FOP(26, FMT_D
),
9854 OPC_CLASS_D
= FOP(27, FMT_D
),
9855 OPC_MIN_D
= FOP(28, FMT_D
),
9856 OPC_RECIP2_D
= FOP(28, FMT_D
),
9857 OPC_MINA_D
= FOP(29, FMT_D
),
9858 OPC_RECIP1_D
= FOP(29, FMT_D
),
9859 OPC_MAX_D
= FOP(30, FMT_D
),
9860 OPC_RSQRT1_D
= FOP(30, FMT_D
),
9861 OPC_MAXA_D
= FOP(31, FMT_D
),
9862 OPC_RSQRT2_D
= FOP(31, FMT_D
),
9863 OPC_CVT_S_D
= FOP(32, FMT_D
),
9864 OPC_CVT_W_D
= FOP(36, FMT_D
),
9865 OPC_CVT_L_D
= FOP(37, FMT_D
),
9866 OPC_CMP_F_D
= FOP(48, FMT_D
),
9867 OPC_CMP_UN_D
= FOP(49, FMT_D
),
9868 OPC_CMP_EQ_D
= FOP(50, FMT_D
),
9869 OPC_CMP_UEQ_D
= FOP(51, FMT_D
),
9870 OPC_CMP_OLT_D
= FOP(52, FMT_D
),
9871 OPC_CMP_ULT_D
= FOP(53, FMT_D
),
9872 OPC_CMP_OLE_D
= FOP(54, FMT_D
),
9873 OPC_CMP_ULE_D
= FOP(55, FMT_D
),
9874 OPC_CMP_SF_D
= FOP(56, FMT_D
),
9875 OPC_CMP_NGLE_D
= FOP(57, FMT_D
),
9876 OPC_CMP_SEQ_D
= FOP(58, FMT_D
),
9877 OPC_CMP_NGL_D
= FOP(59, FMT_D
),
9878 OPC_CMP_LT_D
= FOP(60, FMT_D
),
9879 OPC_CMP_NGE_D
= FOP(61, FMT_D
),
9880 OPC_CMP_LE_D
= FOP(62, FMT_D
),
9881 OPC_CMP_NGT_D
= FOP(63, FMT_D
),
9883 OPC_CVT_S_W
= FOP(32, FMT_W
),
9884 OPC_CVT_D_W
= FOP(33, FMT_W
),
9885 OPC_CVT_S_L
= FOP(32, FMT_L
),
9886 OPC_CVT_D_L
= FOP(33, FMT_L
),
9887 OPC_CVT_PS_PW
= FOP(38, FMT_W
),
9889 OPC_ADD_PS
= FOP(0, FMT_PS
),
9890 OPC_SUB_PS
= FOP(1, FMT_PS
),
9891 OPC_MUL_PS
= FOP(2, FMT_PS
),
9892 OPC_DIV_PS
= FOP(3, FMT_PS
),
9893 OPC_ABS_PS
= FOP(5, FMT_PS
),
9894 OPC_MOV_PS
= FOP(6, FMT_PS
),
9895 OPC_NEG_PS
= FOP(7, FMT_PS
),
9896 OPC_MOVCF_PS
= FOP(17, FMT_PS
),
9897 OPC_MOVZ_PS
= FOP(18, FMT_PS
),
9898 OPC_MOVN_PS
= FOP(19, FMT_PS
),
9899 OPC_ADDR_PS
= FOP(24, FMT_PS
),
9900 OPC_MULR_PS
= FOP(26, FMT_PS
),
9901 OPC_RECIP2_PS
= FOP(28, FMT_PS
),
9902 OPC_RECIP1_PS
= FOP(29, FMT_PS
),
9903 OPC_RSQRT1_PS
= FOP(30, FMT_PS
),
9904 OPC_RSQRT2_PS
= FOP(31, FMT_PS
),
9906 OPC_CVT_S_PU
= FOP(32, FMT_PS
),
9907 OPC_CVT_PW_PS
= FOP(36, FMT_PS
),
9908 OPC_CVT_S_PL
= FOP(40, FMT_PS
),
9909 OPC_PLL_PS
= FOP(44, FMT_PS
),
9910 OPC_PLU_PS
= FOP(45, FMT_PS
),
9911 OPC_PUL_PS
= FOP(46, FMT_PS
),
9912 OPC_PUU_PS
= FOP(47, FMT_PS
),
9913 OPC_CMP_F_PS
= FOP(48, FMT_PS
),
9914 OPC_CMP_UN_PS
= FOP(49, FMT_PS
),
9915 OPC_CMP_EQ_PS
= FOP(50, FMT_PS
),
9916 OPC_CMP_UEQ_PS
= FOP(51, FMT_PS
),
9917 OPC_CMP_OLT_PS
= FOP(52, FMT_PS
),
9918 OPC_CMP_ULT_PS
= FOP(53, FMT_PS
),
9919 OPC_CMP_OLE_PS
= FOP(54, FMT_PS
),
9920 OPC_CMP_ULE_PS
= FOP(55, FMT_PS
),
9921 OPC_CMP_SF_PS
= FOP(56, FMT_PS
),
9922 OPC_CMP_NGLE_PS
= FOP(57, FMT_PS
),
9923 OPC_CMP_SEQ_PS
= FOP(58, FMT_PS
),
9924 OPC_CMP_NGL_PS
= FOP(59, FMT_PS
),
9925 OPC_CMP_LT_PS
= FOP(60, FMT_PS
),
9926 OPC_CMP_NGE_PS
= FOP(61, FMT_PS
),
9927 OPC_CMP_LE_PS
= FOP(62, FMT_PS
),
9928 OPC_CMP_NGT_PS
= FOP(63, FMT_PS
),
9932 R6_OPC_CMP_AF_S
= FOP(0, FMT_W
),
9933 R6_OPC_CMP_UN_S
= FOP(1, FMT_W
),
9934 R6_OPC_CMP_EQ_S
= FOP(2, FMT_W
),
9935 R6_OPC_CMP_UEQ_S
= FOP(3, FMT_W
),
9936 R6_OPC_CMP_LT_S
= FOP(4, FMT_W
),
9937 R6_OPC_CMP_ULT_S
= FOP(5, FMT_W
),
9938 R6_OPC_CMP_LE_S
= FOP(6, FMT_W
),
9939 R6_OPC_CMP_ULE_S
= FOP(7, FMT_W
),
9940 R6_OPC_CMP_SAF_S
= FOP(8, FMT_W
),
9941 R6_OPC_CMP_SUN_S
= FOP(9, FMT_W
),
9942 R6_OPC_CMP_SEQ_S
= FOP(10, FMT_W
),
9943 R6_OPC_CMP_SEUQ_S
= FOP(11, FMT_W
),
9944 R6_OPC_CMP_SLT_S
= FOP(12, FMT_W
),
9945 R6_OPC_CMP_SULT_S
= FOP(13, FMT_W
),
9946 R6_OPC_CMP_SLE_S
= FOP(14, FMT_W
),
9947 R6_OPC_CMP_SULE_S
= FOP(15, FMT_W
),
9948 R6_OPC_CMP_OR_S
= FOP(17, FMT_W
),
9949 R6_OPC_CMP_UNE_S
= FOP(18, FMT_W
),
9950 R6_OPC_CMP_NE_S
= FOP(19, FMT_W
),
9951 R6_OPC_CMP_SOR_S
= FOP(25, FMT_W
),
9952 R6_OPC_CMP_SUNE_S
= FOP(26, FMT_W
),
9953 R6_OPC_CMP_SNE_S
= FOP(27, FMT_W
),
9955 R6_OPC_CMP_AF_D
= FOP(0, FMT_L
),
9956 R6_OPC_CMP_UN_D
= FOP(1, FMT_L
),
9957 R6_OPC_CMP_EQ_D
= FOP(2, FMT_L
),
9958 R6_OPC_CMP_UEQ_D
= FOP(3, FMT_L
),
9959 R6_OPC_CMP_LT_D
= FOP(4, FMT_L
),
9960 R6_OPC_CMP_ULT_D
= FOP(5, FMT_L
),
9961 R6_OPC_CMP_LE_D
= FOP(6, FMT_L
),
9962 R6_OPC_CMP_ULE_D
= FOP(7, FMT_L
),
9963 R6_OPC_CMP_SAF_D
= FOP(8, FMT_L
),
9964 R6_OPC_CMP_SUN_D
= FOP(9, FMT_L
),
9965 R6_OPC_CMP_SEQ_D
= FOP(10, FMT_L
),
9966 R6_OPC_CMP_SEUQ_D
= FOP(11, FMT_L
),
9967 R6_OPC_CMP_SLT_D
= FOP(12, FMT_L
),
9968 R6_OPC_CMP_SULT_D
= FOP(13, FMT_L
),
9969 R6_OPC_CMP_SLE_D
= FOP(14, FMT_L
),
9970 R6_OPC_CMP_SULE_D
= FOP(15, FMT_L
),
9971 R6_OPC_CMP_OR_D
= FOP(17, FMT_L
),
9972 R6_OPC_CMP_UNE_D
= FOP(18, FMT_L
),
9973 R6_OPC_CMP_NE_D
= FOP(19, FMT_L
),
9974 R6_OPC_CMP_SOR_D
= FOP(25, FMT_L
),
9975 R6_OPC_CMP_SUNE_D
= FOP(26, FMT_L
),
9976 R6_OPC_CMP_SNE_D
= FOP(27, FMT_L
),
9979 static void gen_cp1(DisasContext
*ctx
, uint32_t opc
, int rt
, int fs
)
9981 TCGv t0
= tcg_temp_new();
9986 TCGv_i32 fp0
= tcg_temp_new_i32();
9988 gen_load_fpr32(ctx
, fp0
, fs
);
9989 tcg_gen_ext_i32_tl(t0
, fp0
);
9990 tcg_temp_free_i32(fp0
);
9992 gen_store_gpr(t0
, rt
);
9995 gen_load_gpr(t0
, rt
);
9997 TCGv_i32 fp0
= tcg_temp_new_i32();
9999 tcg_gen_trunc_tl_i32(fp0
, t0
);
10000 gen_store_fpr32(ctx
, fp0
, fs
);
10001 tcg_temp_free_i32(fp0
);
10005 gen_helper_1e0i(cfc1
, t0
, fs
);
10006 gen_store_gpr(t0
, rt
);
10009 gen_load_gpr(t0
, rt
);
10010 save_cpu_state(ctx
, 0);
10012 TCGv_i32 fs_tmp
= tcg_const_i32(fs
);
10014 gen_helper_0e2i(ctc1
, t0
, fs_tmp
, rt
);
10015 tcg_temp_free_i32(fs_tmp
);
10017 /* Stop translation as we may have changed hflags */
10018 ctx
->base
.is_jmp
= DISAS_STOP
;
10020 #if defined(TARGET_MIPS64)
10022 gen_load_fpr64(ctx
, t0
, fs
);
10023 gen_store_gpr(t0
, rt
);
10026 gen_load_gpr(t0
, rt
);
10027 gen_store_fpr64(ctx
, t0
, fs
);
10032 TCGv_i32 fp0
= tcg_temp_new_i32();
10034 gen_load_fpr32h(ctx
, fp0
, fs
);
10035 tcg_gen_ext_i32_tl(t0
, fp0
);
10036 tcg_temp_free_i32(fp0
);
10038 gen_store_gpr(t0
, rt
);
10041 gen_load_gpr(t0
, rt
);
10043 TCGv_i32 fp0
= tcg_temp_new_i32();
10045 tcg_gen_trunc_tl_i32(fp0
, t0
);
10046 gen_store_fpr32h(ctx
, fp0
, fs
);
10047 tcg_temp_free_i32(fp0
);
10051 MIPS_INVAL("cp1 move");
10052 gen_reserved_instruction(ctx
);
10060 static void gen_movci(DisasContext
*ctx
, int rd
, int rs
, int cc
, int tf
)
10067 /* Treat as NOP. */
10072 cond
= TCG_COND_EQ
;
10074 cond
= TCG_COND_NE
;
10077 l1
= gen_new_label();
10078 t0
= tcg_temp_new_i32();
10079 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
10080 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
10081 tcg_temp_free_i32(t0
);
10082 gen_load_gpr(cpu_gpr
[rd
], rs
);
10086 static inline void gen_movcf_s(DisasContext
*ctx
, int fs
, int fd
, int cc
,
10090 TCGv_i32 t0
= tcg_temp_new_i32();
10091 TCGLabel
*l1
= gen_new_label();
10094 cond
= TCG_COND_EQ
;
10096 cond
= TCG_COND_NE
;
10099 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
10100 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
10101 gen_load_fpr32(ctx
, t0
, fs
);
10102 gen_store_fpr32(ctx
, t0
, fd
);
10104 tcg_temp_free_i32(t0
);
10107 static inline void gen_movcf_d(DisasContext
*ctx
, int fs
, int fd
, int cc
,
10111 TCGv_i32 t0
= tcg_temp_new_i32();
10113 TCGLabel
*l1
= gen_new_label();
10116 cond
= TCG_COND_EQ
;
10118 cond
= TCG_COND_NE
;
10121 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
10122 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
10123 tcg_temp_free_i32(t0
);
10124 fp0
= tcg_temp_new_i64();
10125 gen_load_fpr64(ctx
, fp0
, fs
);
10126 gen_store_fpr64(ctx
, fp0
, fd
);
10127 tcg_temp_free_i64(fp0
);
10131 static inline void gen_movcf_ps(DisasContext
*ctx
, int fs
, int fd
,
10135 TCGv_i32 t0
= tcg_temp_new_i32();
10136 TCGLabel
*l1
= gen_new_label();
10137 TCGLabel
*l2
= gen_new_label();
10140 cond
= TCG_COND_EQ
;
10142 cond
= TCG_COND_NE
;
10145 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
10146 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
10147 gen_load_fpr32(ctx
, t0
, fs
);
10148 gen_store_fpr32(ctx
, t0
, fd
);
10151 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
+ 1));
10152 tcg_gen_brcondi_i32(cond
, t0
, 0, l2
);
10153 gen_load_fpr32h(ctx
, t0
, fs
);
10154 gen_store_fpr32h(ctx
, t0
, fd
);
10155 tcg_temp_free_i32(t0
);
10159 static void gen_sel_s(DisasContext
*ctx
, enum fopcode op1
, int fd
, int ft
,
10162 TCGv_i32 t1
= tcg_const_i32(0);
10163 TCGv_i32 fp0
= tcg_temp_new_i32();
10164 TCGv_i32 fp1
= tcg_temp_new_i32();
10165 TCGv_i32 fp2
= tcg_temp_new_i32();
10166 gen_load_fpr32(ctx
, fp0
, fd
);
10167 gen_load_fpr32(ctx
, fp1
, ft
);
10168 gen_load_fpr32(ctx
, fp2
, fs
);
10172 tcg_gen_andi_i32(fp0
, fp0
, 1);
10173 tcg_gen_movcond_i32(TCG_COND_NE
, fp0
, fp0
, t1
, fp1
, fp2
);
10176 tcg_gen_andi_i32(fp1
, fp1
, 1);
10177 tcg_gen_movcond_i32(TCG_COND_EQ
, fp0
, fp1
, t1
, fp2
, t1
);
10180 tcg_gen_andi_i32(fp1
, fp1
, 1);
10181 tcg_gen_movcond_i32(TCG_COND_NE
, fp0
, fp1
, t1
, fp2
, t1
);
10184 MIPS_INVAL("gen_sel_s");
10185 gen_reserved_instruction(ctx
);
10189 gen_store_fpr32(ctx
, fp0
, fd
);
10190 tcg_temp_free_i32(fp2
);
10191 tcg_temp_free_i32(fp1
);
10192 tcg_temp_free_i32(fp0
);
10193 tcg_temp_free_i32(t1
);
10196 static void gen_sel_d(DisasContext
*ctx
, enum fopcode op1
, int fd
, int ft
,
10199 TCGv_i64 t1
= tcg_const_i64(0);
10200 TCGv_i64 fp0
= tcg_temp_new_i64();
10201 TCGv_i64 fp1
= tcg_temp_new_i64();
10202 TCGv_i64 fp2
= tcg_temp_new_i64();
10203 gen_load_fpr64(ctx
, fp0
, fd
);
10204 gen_load_fpr64(ctx
, fp1
, ft
);
10205 gen_load_fpr64(ctx
, fp2
, fs
);
10209 tcg_gen_andi_i64(fp0
, fp0
, 1);
10210 tcg_gen_movcond_i64(TCG_COND_NE
, fp0
, fp0
, t1
, fp1
, fp2
);
10213 tcg_gen_andi_i64(fp1
, fp1
, 1);
10214 tcg_gen_movcond_i64(TCG_COND_EQ
, fp0
, fp1
, t1
, fp2
, t1
);
10217 tcg_gen_andi_i64(fp1
, fp1
, 1);
10218 tcg_gen_movcond_i64(TCG_COND_NE
, fp0
, fp1
, t1
, fp2
, t1
);
10221 MIPS_INVAL("gen_sel_d");
10222 gen_reserved_instruction(ctx
);
10226 gen_store_fpr64(ctx
, fp0
, fd
);
10227 tcg_temp_free_i64(fp2
);
10228 tcg_temp_free_i64(fp1
);
10229 tcg_temp_free_i64(fp0
);
10230 tcg_temp_free_i64(t1
);
10233 static void gen_farith(DisasContext
*ctx
, enum fopcode op1
,
10234 int ft
, int fs
, int fd
, int cc
)
10236 uint32_t func
= ctx
->opcode
& 0x3f;
10240 TCGv_i32 fp0
= tcg_temp_new_i32();
10241 TCGv_i32 fp1
= tcg_temp_new_i32();
10243 gen_load_fpr32(ctx
, fp0
, fs
);
10244 gen_load_fpr32(ctx
, fp1
, ft
);
10245 gen_helper_float_add_s(fp0
, cpu_env
, fp0
, fp1
);
10246 tcg_temp_free_i32(fp1
);
10247 gen_store_fpr32(ctx
, fp0
, fd
);
10248 tcg_temp_free_i32(fp0
);
10253 TCGv_i32 fp0
= tcg_temp_new_i32();
10254 TCGv_i32 fp1
= tcg_temp_new_i32();
10256 gen_load_fpr32(ctx
, fp0
, fs
);
10257 gen_load_fpr32(ctx
, fp1
, ft
);
10258 gen_helper_float_sub_s(fp0
, cpu_env
, fp0
, fp1
);
10259 tcg_temp_free_i32(fp1
);
10260 gen_store_fpr32(ctx
, fp0
, fd
);
10261 tcg_temp_free_i32(fp0
);
10266 TCGv_i32 fp0
= tcg_temp_new_i32();
10267 TCGv_i32 fp1
= tcg_temp_new_i32();
10269 gen_load_fpr32(ctx
, fp0
, fs
);
10270 gen_load_fpr32(ctx
, fp1
, ft
);
10271 gen_helper_float_mul_s(fp0
, cpu_env
, fp0
, fp1
);
10272 tcg_temp_free_i32(fp1
);
10273 gen_store_fpr32(ctx
, fp0
, fd
);
10274 tcg_temp_free_i32(fp0
);
10279 TCGv_i32 fp0
= tcg_temp_new_i32();
10280 TCGv_i32 fp1
= tcg_temp_new_i32();
10282 gen_load_fpr32(ctx
, fp0
, fs
);
10283 gen_load_fpr32(ctx
, fp1
, ft
);
10284 gen_helper_float_div_s(fp0
, cpu_env
, fp0
, fp1
);
10285 tcg_temp_free_i32(fp1
);
10286 gen_store_fpr32(ctx
, fp0
, fd
);
10287 tcg_temp_free_i32(fp0
);
10292 TCGv_i32 fp0
= tcg_temp_new_i32();
10294 gen_load_fpr32(ctx
, fp0
, fs
);
10295 gen_helper_float_sqrt_s(fp0
, cpu_env
, fp0
);
10296 gen_store_fpr32(ctx
, fp0
, fd
);
10297 tcg_temp_free_i32(fp0
);
10302 TCGv_i32 fp0
= tcg_temp_new_i32();
10304 gen_load_fpr32(ctx
, fp0
, fs
);
10305 if (ctx
->abs2008
) {
10306 tcg_gen_andi_i32(fp0
, fp0
, 0x7fffffffUL
);
10308 gen_helper_float_abs_s(fp0
, fp0
);
10310 gen_store_fpr32(ctx
, fp0
, fd
);
10311 tcg_temp_free_i32(fp0
);
10316 TCGv_i32 fp0
= tcg_temp_new_i32();
10318 gen_load_fpr32(ctx
, fp0
, fs
);
10319 gen_store_fpr32(ctx
, fp0
, fd
);
10320 tcg_temp_free_i32(fp0
);
10325 TCGv_i32 fp0
= tcg_temp_new_i32();
10327 gen_load_fpr32(ctx
, fp0
, fs
);
10328 if (ctx
->abs2008
) {
10329 tcg_gen_xori_i32(fp0
, fp0
, 1UL << 31);
10331 gen_helper_float_chs_s(fp0
, fp0
);
10333 gen_store_fpr32(ctx
, fp0
, fd
);
10334 tcg_temp_free_i32(fp0
);
10337 case OPC_ROUND_L_S
:
10338 check_cp1_64bitmode(ctx
);
10340 TCGv_i32 fp32
= tcg_temp_new_i32();
10341 TCGv_i64 fp64
= tcg_temp_new_i64();
10343 gen_load_fpr32(ctx
, fp32
, fs
);
10344 if (ctx
->nan2008
) {
10345 gen_helper_float_round_2008_l_s(fp64
, cpu_env
, fp32
);
10347 gen_helper_float_round_l_s(fp64
, cpu_env
, fp32
);
10349 tcg_temp_free_i32(fp32
);
10350 gen_store_fpr64(ctx
, fp64
, fd
);
10351 tcg_temp_free_i64(fp64
);
10354 case OPC_TRUNC_L_S
:
10355 check_cp1_64bitmode(ctx
);
10357 TCGv_i32 fp32
= tcg_temp_new_i32();
10358 TCGv_i64 fp64
= tcg_temp_new_i64();
10360 gen_load_fpr32(ctx
, fp32
, fs
);
10361 if (ctx
->nan2008
) {
10362 gen_helper_float_trunc_2008_l_s(fp64
, cpu_env
, fp32
);
10364 gen_helper_float_trunc_l_s(fp64
, cpu_env
, fp32
);
10366 tcg_temp_free_i32(fp32
);
10367 gen_store_fpr64(ctx
, fp64
, fd
);
10368 tcg_temp_free_i64(fp64
);
10372 check_cp1_64bitmode(ctx
);
10374 TCGv_i32 fp32
= tcg_temp_new_i32();
10375 TCGv_i64 fp64
= tcg_temp_new_i64();
10377 gen_load_fpr32(ctx
, fp32
, fs
);
10378 if (ctx
->nan2008
) {
10379 gen_helper_float_ceil_2008_l_s(fp64
, cpu_env
, fp32
);
10381 gen_helper_float_ceil_l_s(fp64
, cpu_env
, fp32
);
10383 tcg_temp_free_i32(fp32
);
10384 gen_store_fpr64(ctx
, fp64
, fd
);
10385 tcg_temp_free_i64(fp64
);
10388 case OPC_FLOOR_L_S
:
10389 check_cp1_64bitmode(ctx
);
10391 TCGv_i32 fp32
= tcg_temp_new_i32();
10392 TCGv_i64 fp64
= tcg_temp_new_i64();
10394 gen_load_fpr32(ctx
, fp32
, fs
);
10395 if (ctx
->nan2008
) {
10396 gen_helper_float_floor_2008_l_s(fp64
, cpu_env
, fp32
);
10398 gen_helper_float_floor_l_s(fp64
, cpu_env
, fp32
);
10400 tcg_temp_free_i32(fp32
);
10401 gen_store_fpr64(ctx
, fp64
, fd
);
10402 tcg_temp_free_i64(fp64
);
10405 case OPC_ROUND_W_S
:
10407 TCGv_i32 fp0
= tcg_temp_new_i32();
10409 gen_load_fpr32(ctx
, fp0
, fs
);
10410 if (ctx
->nan2008
) {
10411 gen_helper_float_round_2008_w_s(fp0
, cpu_env
, fp0
);
10413 gen_helper_float_round_w_s(fp0
, cpu_env
, fp0
);
10415 gen_store_fpr32(ctx
, fp0
, fd
);
10416 tcg_temp_free_i32(fp0
);
10419 case OPC_TRUNC_W_S
:
10421 TCGv_i32 fp0
= tcg_temp_new_i32();
10423 gen_load_fpr32(ctx
, fp0
, fs
);
10424 if (ctx
->nan2008
) {
10425 gen_helper_float_trunc_2008_w_s(fp0
, cpu_env
, fp0
);
10427 gen_helper_float_trunc_w_s(fp0
, cpu_env
, fp0
);
10429 gen_store_fpr32(ctx
, fp0
, fd
);
10430 tcg_temp_free_i32(fp0
);
10435 TCGv_i32 fp0
= tcg_temp_new_i32();
10437 gen_load_fpr32(ctx
, fp0
, fs
);
10438 if (ctx
->nan2008
) {
10439 gen_helper_float_ceil_2008_w_s(fp0
, cpu_env
, fp0
);
10441 gen_helper_float_ceil_w_s(fp0
, cpu_env
, fp0
);
10443 gen_store_fpr32(ctx
, fp0
, fd
);
10444 tcg_temp_free_i32(fp0
);
10447 case OPC_FLOOR_W_S
:
10449 TCGv_i32 fp0
= tcg_temp_new_i32();
10451 gen_load_fpr32(ctx
, fp0
, fs
);
10452 if (ctx
->nan2008
) {
10453 gen_helper_float_floor_2008_w_s(fp0
, cpu_env
, fp0
);
10455 gen_helper_float_floor_w_s(fp0
, cpu_env
, fp0
);
10457 gen_store_fpr32(ctx
, fp0
, fd
);
10458 tcg_temp_free_i32(fp0
);
10462 check_insn(ctx
, ISA_MIPS_R6
);
10463 gen_sel_s(ctx
, op1
, fd
, ft
, fs
);
10466 check_insn(ctx
, ISA_MIPS_R6
);
10467 gen_sel_s(ctx
, op1
, fd
, ft
, fs
);
10470 check_insn(ctx
, ISA_MIPS_R6
);
10471 gen_sel_s(ctx
, op1
, fd
, ft
, fs
);
10474 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
10475 gen_movcf_s(ctx
, fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
10478 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
10480 TCGLabel
*l1
= gen_new_label();
10484 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
10486 fp0
= tcg_temp_new_i32();
10487 gen_load_fpr32(ctx
, fp0
, fs
);
10488 gen_store_fpr32(ctx
, fp0
, fd
);
10489 tcg_temp_free_i32(fp0
);
10494 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
10496 TCGLabel
*l1
= gen_new_label();
10500 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
10501 fp0
= tcg_temp_new_i32();
10502 gen_load_fpr32(ctx
, fp0
, fs
);
10503 gen_store_fpr32(ctx
, fp0
, fd
);
10504 tcg_temp_free_i32(fp0
);
10511 TCGv_i32 fp0
= tcg_temp_new_i32();
10513 gen_load_fpr32(ctx
, fp0
, fs
);
10514 gen_helper_float_recip_s(fp0
, cpu_env
, fp0
);
10515 gen_store_fpr32(ctx
, fp0
, fd
);
10516 tcg_temp_free_i32(fp0
);
10521 TCGv_i32 fp0
= tcg_temp_new_i32();
10523 gen_load_fpr32(ctx
, fp0
, fs
);
10524 gen_helper_float_rsqrt_s(fp0
, cpu_env
, fp0
);
10525 gen_store_fpr32(ctx
, fp0
, fd
);
10526 tcg_temp_free_i32(fp0
);
10530 check_insn(ctx
, ISA_MIPS_R6
);
10532 TCGv_i32 fp0
= tcg_temp_new_i32();
10533 TCGv_i32 fp1
= tcg_temp_new_i32();
10534 TCGv_i32 fp2
= tcg_temp_new_i32();
10535 gen_load_fpr32(ctx
, fp0
, fs
);
10536 gen_load_fpr32(ctx
, fp1
, ft
);
10537 gen_load_fpr32(ctx
, fp2
, fd
);
10538 gen_helper_float_maddf_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
10539 gen_store_fpr32(ctx
, fp2
, fd
);
10540 tcg_temp_free_i32(fp2
);
10541 tcg_temp_free_i32(fp1
);
10542 tcg_temp_free_i32(fp0
);
10546 check_insn(ctx
, ISA_MIPS_R6
);
10548 TCGv_i32 fp0
= tcg_temp_new_i32();
10549 TCGv_i32 fp1
= tcg_temp_new_i32();
10550 TCGv_i32 fp2
= tcg_temp_new_i32();
10551 gen_load_fpr32(ctx
, fp0
, fs
);
10552 gen_load_fpr32(ctx
, fp1
, ft
);
10553 gen_load_fpr32(ctx
, fp2
, fd
);
10554 gen_helper_float_msubf_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
10555 gen_store_fpr32(ctx
, fp2
, fd
);
10556 tcg_temp_free_i32(fp2
);
10557 tcg_temp_free_i32(fp1
);
10558 tcg_temp_free_i32(fp0
);
10562 check_insn(ctx
, ISA_MIPS_R6
);
10564 TCGv_i32 fp0
= tcg_temp_new_i32();
10565 gen_load_fpr32(ctx
, fp0
, fs
);
10566 gen_helper_float_rint_s(fp0
, cpu_env
, fp0
);
10567 gen_store_fpr32(ctx
, fp0
, fd
);
10568 tcg_temp_free_i32(fp0
);
10572 check_insn(ctx
, ISA_MIPS_R6
);
10574 TCGv_i32 fp0
= tcg_temp_new_i32();
10575 gen_load_fpr32(ctx
, fp0
, fs
);
10576 gen_helper_float_class_s(fp0
, cpu_env
, fp0
);
10577 gen_store_fpr32(ctx
, fp0
, fd
);
10578 tcg_temp_free_i32(fp0
);
10581 case OPC_MIN_S
: /* OPC_RECIP2_S */
10582 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
10584 TCGv_i32 fp0
= tcg_temp_new_i32();
10585 TCGv_i32 fp1
= tcg_temp_new_i32();
10586 TCGv_i32 fp2
= tcg_temp_new_i32();
10587 gen_load_fpr32(ctx
, fp0
, fs
);
10588 gen_load_fpr32(ctx
, fp1
, ft
);
10589 gen_helper_float_min_s(fp2
, cpu_env
, fp0
, fp1
);
10590 gen_store_fpr32(ctx
, fp2
, fd
);
10591 tcg_temp_free_i32(fp2
);
10592 tcg_temp_free_i32(fp1
);
10593 tcg_temp_free_i32(fp0
);
10596 check_cp1_64bitmode(ctx
);
10598 TCGv_i32 fp0
= tcg_temp_new_i32();
10599 TCGv_i32 fp1
= tcg_temp_new_i32();
10601 gen_load_fpr32(ctx
, fp0
, fs
);
10602 gen_load_fpr32(ctx
, fp1
, ft
);
10603 gen_helper_float_recip2_s(fp0
, cpu_env
, fp0
, fp1
);
10604 tcg_temp_free_i32(fp1
);
10605 gen_store_fpr32(ctx
, fp0
, fd
);
10606 tcg_temp_free_i32(fp0
);
10610 case OPC_MINA_S
: /* OPC_RECIP1_S */
10611 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
10613 TCGv_i32 fp0
= tcg_temp_new_i32();
10614 TCGv_i32 fp1
= tcg_temp_new_i32();
10615 TCGv_i32 fp2
= tcg_temp_new_i32();
10616 gen_load_fpr32(ctx
, fp0
, fs
);
10617 gen_load_fpr32(ctx
, fp1
, ft
);
10618 gen_helper_float_mina_s(fp2
, cpu_env
, fp0
, fp1
);
10619 gen_store_fpr32(ctx
, fp2
, fd
);
10620 tcg_temp_free_i32(fp2
);
10621 tcg_temp_free_i32(fp1
);
10622 tcg_temp_free_i32(fp0
);
10625 check_cp1_64bitmode(ctx
);
10627 TCGv_i32 fp0
= tcg_temp_new_i32();
10629 gen_load_fpr32(ctx
, fp0
, fs
);
10630 gen_helper_float_recip1_s(fp0
, cpu_env
, fp0
);
10631 gen_store_fpr32(ctx
, fp0
, fd
);
10632 tcg_temp_free_i32(fp0
);
10636 case OPC_MAX_S
: /* OPC_RSQRT1_S */
10637 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
10639 TCGv_i32 fp0
= tcg_temp_new_i32();
10640 TCGv_i32 fp1
= tcg_temp_new_i32();
10641 gen_load_fpr32(ctx
, fp0
, fs
);
10642 gen_load_fpr32(ctx
, fp1
, ft
);
10643 gen_helper_float_max_s(fp1
, cpu_env
, fp0
, fp1
);
10644 gen_store_fpr32(ctx
, fp1
, fd
);
10645 tcg_temp_free_i32(fp1
);
10646 tcg_temp_free_i32(fp0
);
10649 check_cp1_64bitmode(ctx
);
10651 TCGv_i32 fp0
= tcg_temp_new_i32();
10653 gen_load_fpr32(ctx
, fp0
, fs
);
10654 gen_helper_float_rsqrt1_s(fp0
, cpu_env
, fp0
);
10655 gen_store_fpr32(ctx
, fp0
, fd
);
10656 tcg_temp_free_i32(fp0
);
10660 case OPC_MAXA_S
: /* OPC_RSQRT2_S */
10661 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
10663 TCGv_i32 fp0
= tcg_temp_new_i32();
10664 TCGv_i32 fp1
= tcg_temp_new_i32();
10665 gen_load_fpr32(ctx
, fp0
, fs
);
10666 gen_load_fpr32(ctx
, fp1
, ft
);
10667 gen_helper_float_maxa_s(fp1
, cpu_env
, fp0
, fp1
);
10668 gen_store_fpr32(ctx
, fp1
, fd
);
10669 tcg_temp_free_i32(fp1
);
10670 tcg_temp_free_i32(fp0
);
10673 check_cp1_64bitmode(ctx
);
10675 TCGv_i32 fp0
= tcg_temp_new_i32();
10676 TCGv_i32 fp1
= tcg_temp_new_i32();
10678 gen_load_fpr32(ctx
, fp0
, fs
);
10679 gen_load_fpr32(ctx
, fp1
, ft
);
10680 gen_helper_float_rsqrt2_s(fp0
, cpu_env
, fp0
, fp1
);
10681 tcg_temp_free_i32(fp1
);
10682 gen_store_fpr32(ctx
, fp0
, fd
);
10683 tcg_temp_free_i32(fp0
);
10688 check_cp1_registers(ctx
, fd
);
10690 TCGv_i32 fp32
= tcg_temp_new_i32();
10691 TCGv_i64 fp64
= tcg_temp_new_i64();
10693 gen_load_fpr32(ctx
, fp32
, fs
);
10694 gen_helper_float_cvtd_s(fp64
, cpu_env
, fp32
);
10695 tcg_temp_free_i32(fp32
);
10696 gen_store_fpr64(ctx
, fp64
, fd
);
10697 tcg_temp_free_i64(fp64
);
10702 TCGv_i32 fp0
= tcg_temp_new_i32();
10704 gen_load_fpr32(ctx
, fp0
, fs
);
10705 if (ctx
->nan2008
) {
10706 gen_helper_float_cvt_2008_w_s(fp0
, cpu_env
, fp0
);
10708 gen_helper_float_cvt_w_s(fp0
, cpu_env
, fp0
);
10710 gen_store_fpr32(ctx
, fp0
, fd
);
10711 tcg_temp_free_i32(fp0
);
10715 check_cp1_64bitmode(ctx
);
10717 TCGv_i32 fp32
= tcg_temp_new_i32();
10718 TCGv_i64 fp64
= tcg_temp_new_i64();
10720 gen_load_fpr32(ctx
, fp32
, fs
);
10721 if (ctx
->nan2008
) {
10722 gen_helper_float_cvt_2008_l_s(fp64
, cpu_env
, fp32
);
10724 gen_helper_float_cvt_l_s(fp64
, cpu_env
, fp32
);
10726 tcg_temp_free_i32(fp32
);
10727 gen_store_fpr64(ctx
, fp64
, fd
);
10728 tcg_temp_free_i64(fp64
);
10734 TCGv_i64 fp64
= tcg_temp_new_i64();
10735 TCGv_i32 fp32_0
= tcg_temp_new_i32();
10736 TCGv_i32 fp32_1
= tcg_temp_new_i32();
10738 gen_load_fpr32(ctx
, fp32_0
, fs
);
10739 gen_load_fpr32(ctx
, fp32_1
, ft
);
10740 tcg_gen_concat_i32_i64(fp64
, fp32_1
, fp32_0
);
10741 tcg_temp_free_i32(fp32_1
);
10742 tcg_temp_free_i32(fp32_0
);
10743 gen_store_fpr64(ctx
, fp64
, fd
);
10744 tcg_temp_free_i64(fp64
);
10750 case OPC_CMP_UEQ_S
:
10751 case OPC_CMP_OLT_S
:
10752 case OPC_CMP_ULT_S
:
10753 case OPC_CMP_OLE_S
:
10754 case OPC_CMP_ULE_S
:
10756 case OPC_CMP_NGLE_S
:
10757 case OPC_CMP_SEQ_S
:
10758 case OPC_CMP_NGL_S
:
10760 case OPC_CMP_NGE_S
:
10762 case OPC_CMP_NGT_S
:
10763 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
10764 if (ctx
->opcode
& (1 << 6)) {
10765 gen_cmpabs_s(ctx
, func
- 48, ft
, fs
, cc
);
10767 gen_cmp_s(ctx
, func
- 48, ft
, fs
, cc
);
10771 check_cp1_registers(ctx
, fs
| ft
| fd
);
10773 TCGv_i64 fp0
= tcg_temp_new_i64();
10774 TCGv_i64 fp1
= tcg_temp_new_i64();
10776 gen_load_fpr64(ctx
, fp0
, fs
);
10777 gen_load_fpr64(ctx
, fp1
, ft
);
10778 gen_helper_float_add_d(fp0
, cpu_env
, fp0
, fp1
);
10779 tcg_temp_free_i64(fp1
);
10780 gen_store_fpr64(ctx
, fp0
, fd
);
10781 tcg_temp_free_i64(fp0
);
10785 check_cp1_registers(ctx
, fs
| ft
| fd
);
10787 TCGv_i64 fp0
= tcg_temp_new_i64();
10788 TCGv_i64 fp1
= tcg_temp_new_i64();
10790 gen_load_fpr64(ctx
, fp0
, fs
);
10791 gen_load_fpr64(ctx
, fp1
, ft
);
10792 gen_helper_float_sub_d(fp0
, cpu_env
, fp0
, fp1
);
10793 tcg_temp_free_i64(fp1
);
10794 gen_store_fpr64(ctx
, fp0
, fd
);
10795 tcg_temp_free_i64(fp0
);
10799 check_cp1_registers(ctx
, fs
| ft
| fd
);
10801 TCGv_i64 fp0
= tcg_temp_new_i64();
10802 TCGv_i64 fp1
= tcg_temp_new_i64();
10804 gen_load_fpr64(ctx
, fp0
, fs
);
10805 gen_load_fpr64(ctx
, fp1
, ft
);
10806 gen_helper_float_mul_d(fp0
, cpu_env
, fp0
, fp1
);
10807 tcg_temp_free_i64(fp1
);
10808 gen_store_fpr64(ctx
, fp0
, fd
);
10809 tcg_temp_free_i64(fp0
);
10813 check_cp1_registers(ctx
, fs
| ft
| fd
);
10815 TCGv_i64 fp0
= tcg_temp_new_i64();
10816 TCGv_i64 fp1
= tcg_temp_new_i64();
10818 gen_load_fpr64(ctx
, fp0
, fs
);
10819 gen_load_fpr64(ctx
, fp1
, ft
);
10820 gen_helper_float_div_d(fp0
, cpu_env
, fp0
, fp1
);
10821 tcg_temp_free_i64(fp1
);
10822 gen_store_fpr64(ctx
, fp0
, fd
);
10823 tcg_temp_free_i64(fp0
);
10827 check_cp1_registers(ctx
, fs
| fd
);
10829 TCGv_i64 fp0
= tcg_temp_new_i64();
10831 gen_load_fpr64(ctx
, fp0
, fs
);
10832 gen_helper_float_sqrt_d(fp0
, cpu_env
, fp0
);
10833 gen_store_fpr64(ctx
, fp0
, fd
);
10834 tcg_temp_free_i64(fp0
);
10838 check_cp1_registers(ctx
, fs
| fd
);
10840 TCGv_i64 fp0
= tcg_temp_new_i64();
10842 gen_load_fpr64(ctx
, fp0
, fs
);
10843 if (ctx
->abs2008
) {
10844 tcg_gen_andi_i64(fp0
, fp0
, 0x7fffffffffffffffULL
);
10846 gen_helper_float_abs_d(fp0
, fp0
);
10848 gen_store_fpr64(ctx
, fp0
, fd
);
10849 tcg_temp_free_i64(fp0
);
10853 check_cp1_registers(ctx
, fs
| fd
);
10855 TCGv_i64 fp0
= tcg_temp_new_i64();
10857 gen_load_fpr64(ctx
, fp0
, fs
);
10858 gen_store_fpr64(ctx
, fp0
, fd
);
10859 tcg_temp_free_i64(fp0
);
10863 check_cp1_registers(ctx
, fs
| fd
);
10865 TCGv_i64 fp0
= tcg_temp_new_i64();
10867 gen_load_fpr64(ctx
, fp0
, fs
);
10868 if (ctx
->abs2008
) {
10869 tcg_gen_xori_i64(fp0
, fp0
, 1ULL << 63);
10871 gen_helper_float_chs_d(fp0
, fp0
);
10873 gen_store_fpr64(ctx
, fp0
, fd
);
10874 tcg_temp_free_i64(fp0
);
10877 case OPC_ROUND_L_D
:
10878 check_cp1_64bitmode(ctx
);
10880 TCGv_i64 fp0
= tcg_temp_new_i64();
10882 gen_load_fpr64(ctx
, fp0
, fs
);
10883 if (ctx
->nan2008
) {
10884 gen_helper_float_round_2008_l_d(fp0
, cpu_env
, fp0
);
10886 gen_helper_float_round_l_d(fp0
, cpu_env
, fp0
);
10888 gen_store_fpr64(ctx
, fp0
, fd
);
10889 tcg_temp_free_i64(fp0
);
10892 case OPC_TRUNC_L_D
:
10893 check_cp1_64bitmode(ctx
);
10895 TCGv_i64 fp0
= tcg_temp_new_i64();
10897 gen_load_fpr64(ctx
, fp0
, fs
);
10898 if (ctx
->nan2008
) {
10899 gen_helper_float_trunc_2008_l_d(fp0
, cpu_env
, fp0
);
10901 gen_helper_float_trunc_l_d(fp0
, cpu_env
, fp0
);
10903 gen_store_fpr64(ctx
, fp0
, fd
);
10904 tcg_temp_free_i64(fp0
);
10908 check_cp1_64bitmode(ctx
);
10910 TCGv_i64 fp0
= tcg_temp_new_i64();
10912 gen_load_fpr64(ctx
, fp0
, fs
);
10913 if (ctx
->nan2008
) {
10914 gen_helper_float_ceil_2008_l_d(fp0
, cpu_env
, fp0
);
10916 gen_helper_float_ceil_l_d(fp0
, cpu_env
, fp0
);
10918 gen_store_fpr64(ctx
, fp0
, fd
);
10919 tcg_temp_free_i64(fp0
);
10922 case OPC_FLOOR_L_D
:
10923 check_cp1_64bitmode(ctx
);
10925 TCGv_i64 fp0
= tcg_temp_new_i64();
10927 gen_load_fpr64(ctx
, fp0
, fs
);
10928 if (ctx
->nan2008
) {
10929 gen_helper_float_floor_2008_l_d(fp0
, cpu_env
, fp0
);
10931 gen_helper_float_floor_l_d(fp0
, cpu_env
, fp0
);
10933 gen_store_fpr64(ctx
, fp0
, fd
);
10934 tcg_temp_free_i64(fp0
);
10937 case OPC_ROUND_W_D
:
10938 check_cp1_registers(ctx
, fs
);
10940 TCGv_i32 fp32
= tcg_temp_new_i32();
10941 TCGv_i64 fp64
= tcg_temp_new_i64();
10943 gen_load_fpr64(ctx
, fp64
, fs
);
10944 if (ctx
->nan2008
) {
10945 gen_helper_float_round_2008_w_d(fp32
, cpu_env
, fp64
);
10947 gen_helper_float_round_w_d(fp32
, cpu_env
, fp64
);
10949 tcg_temp_free_i64(fp64
);
10950 gen_store_fpr32(ctx
, fp32
, fd
);
10951 tcg_temp_free_i32(fp32
);
10954 case OPC_TRUNC_W_D
:
10955 check_cp1_registers(ctx
, fs
);
10957 TCGv_i32 fp32
= tcg_temp_new_i32();
10958 TCGv_i64 fp64
= tcg_temp_new_i64();
10960 gen_load_fpr64(ctx
, fp64
, fs
);
10961 if (ctx
->nan2008
) {
10962 gen_helper_float_trunc_2008_w_d(fp32
, cpu_env
, fp64
);
10964 gen_helper_float_trunc_w_d(fp32
, cpu_env
, fp64
);
10966 tcg_temp_free_i64(fp64
);
10967 gen_store_fpr32(ctx
, fp32
, fd
);
10968 tcg_temp_free_i32(fp32
);
10972 check_cp1_registers(ctx
, fs
);
10974 TCGv_i32 fp32
= tcg_temp_new_i32();
10975 TCGv_i64 fp64
= tcg_temp_new_i64();
10977 gen_load_fpr64(ctx
, fp64
, fs
);
10978 if (ctx
->nan2008
) {
10979 gen_helper_float_ceil_2008_w_d(fp32
, cpu_env
, fp64
);
10981 gen_helper_float_ceil_w_d(fp32
, cpu_env
, fp64
);
10983 tcg_temp_free_i64(fp64
);
10984 gen_store_fpr32(ctx
, fp32
, fd
);
10985 tcg_temp_free_i32(fp32
);
10988 case OPC_FLOOR_W_D
:
10989 check_cp1_registers(ctx
, fs
);
10991 TCGv_i32 fp32
= tcg_temp_new_i32();
10992 TCGv_i64 fp64
= tcg_temp_new_i64();
10994 gen_load_fpr64(ctx
, fp64
, fs
);
10995 if (ctx
->nan2008
) {
10996 gen_helper_float_floor_2008_w_d(fp32
, cpu_env
, fp64
);
10998 gen_helper_float_floor_w_d(fp32
, cpu_env
, fp64
);
11000 tcg_temp_free_i64(fp64
);
11001 gen_store_fpr32(ctx
, fp32
, fd
);
11002 tcg_temp_free_i32(fp32
);
11006 check_insn(ctx
, ISA_MIPS_R6
);
11007 gen_sel_d(ctx
, op1
, fd
, ft
, fs
);
11010 check_insn(ctx
, ISA_MIPS_R6
);
11011 gen_sel_d(ctx
, op1
, fd
, ft
, fs
);
11014 check_insn(ctx
, ISA_MIPS_R6
);
11015 gen_sel_d(ctx
, op1
, fd
, ft
, fs
);
11018 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
11019 gen_movcf_d(ctx
, fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
11022 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
11024 TCGLabel
*l1
= gen_new_label();
11028 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
11030 fp0
= tcg_temp_new_i64();
11031 gen_load_fpr64(ctx
, fp0
, fs
);
11032 gen_store_fpr64(ctx
, fp0
, fd
);
11033 tcg_temp_free_i64(fp0
);
11038 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
11040 TCGLabel
*l1
= gen_new_label();
11044 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
11045 fp0
= tcg_temp_new_i64();
11046 gen_load_fpr64(ctx
, fp0
, fs
);
11047 gen_store_fpr64(ctx
, fp0
, fd
);
11048 tcg_temp_free_i64(fp0
);
11054 check_cp1_registers(ctx
, fs
| fd
);
11056 TCGv_i64 fp0
= tcg_temp_new_i64();
11058 gen_load_fpr64(ctx
, fp0
, fs
);
11059 gen_helper_float_recip_d(fp0
, cpu_env
, fp0
);
11060 gen_store_fpr64(ctx
, fp0
, fd
);
11061 tcg_temp_free_i64(fp0
);
11065 check_cp1_registers(ctx
, fs
| fd
);
11067 TCGv_i64 fp0
= tcg_temp_new_i64();
11069 gen_load_fpr64(ctx
, fp0
, fs
);
11070 gen_helper_float_rsqrt_d(fp0
, cpu_env
, fp0
);
11071 gen_store_fpr64(ctx
, fp0
, fd
);
11072 tcg_temp_free_i64(fp0
);
11076 check_insn(ctx
, ISA_MIPS_R6
);
11078 TCGv_i64 fp0
= tcg_temp_new_i64();
11079 TCGv_i64 fp1
= tcg_temp_new_i64();
11080 TCGv_i64 fp2
= tcg_temp_new_i64();
11081 gen_load_fpr64(ctx
, fp0
, fs
);
11082 gen_load_fpr64(ctx
, fp1
, ft
);
11083 gen_load_fpr64(ctx
, fp2
, fd
);
11084 gen_helper_float_maddf_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
11085 gen_store_fpr64(ctx
, fp2
, fd
);
11086 tcg_temp_free_i64(fp2
);
11087 tcg_temp_free_i64(fp1
);
11088 tcg_temp_free_i64(fp0
);
11092 check_insn(ctx
, ISA_MIPS_R6
);
11094 TCGv_i64 fp0
= tcg_temp_new_i64();
11095 TCGv_i64 fp1
= tcg_temp_new_i64();
11096 TCGv_i64 fp2
= tcg_temp_new_i64();
11097 gen_load_fpr64(ctx
, fp0
, fs
);
11098 gen_load_fpr64(ctx
, fp1
, ft
);
11099 gen_load_fpr64(ctx
, fp2
, fd
);
11100 gen_helper_float_msubf_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
11101 gen_store_fpr64(ctx
, fp2
, fd
);
11102 tcg_temp_free_i64(fp2
);
11103 tcg_temp_free_i64(fp1
);
11104 tcg_temp_free_i64(fp0
);
11108 check_insn(ctx
, ISA_MIPS_R6
);
11110 TCGv_i64 fp0
= tcg_temp_new_i64();
11111 gen_load_fpr64(ctx
, fp0
, fs
);
11112 gen_helper_float_rint_d(fp0
, cpu_env
, fp0
);
11113 gen_store_fpr64(ctx
, fp0
, fd
);
11114 tcg_temp_free_i64(fp0
);
11118 check_insn(ctx
, ISA_MIPS_R6
);
11120 TCGv_i64 fp0
= tcg_temp_new_i64();
11121 gen_load_fpr64(ctx
, fp0
, fs
);
11122 gen_helper_float_class_d(fp0
, cpu_env
, fp0
);
11123 gen_store_fpr64(ctx
, fp0
, fd
);
11124 tcg_temp_free_i64(fp0
);
11127 case OPC_MIN_D
: /* OPC_RECIP2_D */
11128 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
11130 TCGv_i64 fp0
= tcg_temp_new_i64();
11131 TCGv_i64 fp1
= tcg_temp_new_i64();
11132 gen_load_fpr64(ctx
, fp0
, fs
);
11133 gen_load_fpr64(ctx
, fp1
, ft
);
11134 gen_helper_float_min_d(fp1
, cpu_env
, fp0
, fp1
);
11135 gen_store_fpr64(ctx
, fp1
, fd
);
11136 tcg_temp_free_i64(fp1
);
11137 tcg_temp_free_i64(fp0
);
11140 check_cp1_64bitmode(ctx
);
11142 TCGv_i64 fp0
= tcg_temp_new_i64();
11143 TCGv_i64 fp1
= tcg_temp_new_i64();
11145 gen_load_fpr64(ctx
, fp0
, fs
);
11146 gen_load_fpr64(ctx
, fp1
, ft
);
11147 gen_helper_float_recip2_d(fp0
, cpu_env
, fp0
, fp1
);
11148 tcg_temp_free_i64(fp1
);
11149 gen_store_fpr64(ctx
, fp0
, fd
);
11150 tcg_temp_free_i64(fp0
);
11154 case OPC_MINA_D
: /* OPC_RECIP1_D */
11155 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
11157 TCGv_i64 fp0
= tcg_temp_new_i64();
11158 TCGv_i64 fp1
= tcg_temp_new_i64();
11159 gen_load_fpr64(ctx
, fp0
, fs
);
11160 gen_load_fpr64(ctx
, fp1
, ft
);
11161 gen_helper_float_mina_d(fp1
, cpu_env
, fp0
, fp1
);
11162 gen_store_fpr64(ctx
, fp1
, fd
);
11163 tcg_temp_free_i64(fp1
);
11164 tcg_temp_free_i64(fp0
);
11167 check_cp1_64bitmode(ctx
);
11169 TCGv_i64 fp0
= tcg_temp_new_i64();
11171 gen_load_fpr64(ctx
, fp0
, fs
);
11172 gen_helper_float_recip1_d(fp0
, cpu_env
, fp0
);
11173 gen_store_fpr64(ctx
, fp0
, fd
);
11174 tcg_temp_free_i64(fp0
);
11178 case OPC_MAX_D
: /* OPC_RSQRT1_D */
11179 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
11181 TCGv_i64 fp0
= tcg_temp_new_i64();
11182 TCGv_i64 fp1
= tcg_temp_new_i64();
11183 gen_load_fpr64(ctx
, fp0
, fs
);
11184 gen_load_fpr64(ctx
, fp1
, ft
);
11185 gen_helper_float_max_d(fp1
, cpu_env
, fp0
, fp1
);
11186 gen_store_fpr64(ctx
, fp1
, fd
);
11187 tcg_temp_free_i64(fp1
);
11188 tcg_temp_free_i64(fp0
);
11191 check_cp1_64bitmode(ctx
);
11193 TCGv_i64 fp0
= tcg_temp_new_i64();
11195 gen_load_fpr64(ctx
, fp0
, fs
);
11196 gen_helper_float_rsqrt1_d(fp0
, cpu_env
, fp0
);
11197 gen_store_fpr64(ctx
, fp0
, fd
);
11198 tcg_temp_free_i64(fp0
);
11202 case OPC_MAXA_D
: /* OPC_RSQRT2_D */
11203 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
11205 TCGv_i64 fp0
= tcg_temp_new_i64();
11206 TCGv_i64 fp1
= tcg_temp_new_i64();
11207 gen_load_fpr64(ctx
, fp0
, fs
);
11208 gen_load_fpr64(ctx
, fp1
, ft
);
11209 gen_helper_float_maxa_d(fp1
, cpu_env
, fp0
, fp1
);
11210 gen_store_fpr64(ctx
, fp1
, fd
);
11211 tcg_temp_free_i64(fp1
);
11212 tcg_temp_free_i64(fp0
);
11215 check_cp1_64bitmode(ctx
);
11217 TCGv_i64 fp0
= tcg_temp_new_i64();
11218 TCGv_i64 fp1
= tcg_temp_new_i64();
11220 gen_load_fpr64(ctx
, fp0
, fs
);
11221 gen_load_fpr64(ctx
, fp1
, ft
);
11222 gen_helper_float_rsqrt2_d(fp0
, cpu_env
, fp0
, fp1
);
11223 tcg_temp_free_i64(fp1
);
11224 gen_store_fpr64(ctx
, fp0
, fd
);
11225 tcg_temp_free_i64(fp0
);
11232 case OPC_CMP_UEQ_D
:
11233 case OPC_CMP_OLT_D
:
11234 case OPC_CMP_ULT_D
:
11235 case OPC_CMP_OLE_D
:
11236 case OPC_CMP_ULE_D
:
11238 case OPC_CMP_NGLE_D
:
11239 case OPC_CMP_SEQ_D
:
11240 case OPC_CMP_NGL_D
:
11242 case OPC_CMP_NGE_D
:
11244 case OPC_CMP_NGT_D
:
11245 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
11246 if (ctx
->opcode
& (1 << 6)) {
11247 gen_cmpabs_d(ctx
, func
- 48, ft
, fs
, cc
);
11249 gen_cmp_d(ctx
, func
- 48, ft
, fs
, cc
);
11253 check_cp1_registers(ctx
, fs
);
11255 TCGv_i32 fp32
= tcg_temp_new_i32();
11256 TCGv_i64 fp64
= tcg_temp_new_i64();
11258 gen_load_fpr64(ctx
, fp64
, fs
);
11259 gen_helper_float_cvts_d(fp32
, cpu_env
, fp64
);
11260 tcg_temp_free_i64(fp64
);
11261 gen_store_fpr32(ctx
, fp32
, fd
);
11262 tcg_temp_free_i32(fp32
);
11266 check_cp1_registers(ctx
, fs
);
11268 TCGv_i32 fp32
= tcg_temp_new_i32();
11269 TCGv_i64 fp64
= tcg_temp_new_i64();
11271 gen_load_fpr64(ctx
, fp64
, fs
);
11272 if (ctx
->nan2008
) {
11273 gen_helper_float_cvt_2008_w_d(fp32
, cpu_env
, fp64
);
11275 gen_helper_float_cvt_w_d(fp32
, cpu_env
, fp64
);
11277 tcg_temp_free_i64(fp64
);
11278 gen_store_fpr32(ctx
, fp32
, fd
);
11279 tcg_temp_free_i32(fp32
);
11283 check_cp1_64bitmode(ctx
);
11285 TCGv_i64 fp0
= tcg_temp_new_i64();
11287 gen_load_fpr64(ctx
, fp0
, fs
);
11288 if (ctx
->nan2008
) {
11289 gen_helper_float_cvt_2008_l_d(fp0
, cpu_env
, fp0
);
11291 gen_helper_float_cvt_l_d(fp0
, cpu_env
, fp0
);
11293 gen_store_fpr64(ctx
, fp0
, fd
);
11294 tcg_temp_free_i64(fp0
);
11299 TCGv_i32 fp0
= tcg_temp_new_i32();
11301 gen_load_fpr32(ctx
, fp0
, fs
);
11302 gen_helper_float_cvts_w(fp0
, cpu_env
, fp0
);
11303 gen_store_fpr32(ctx
, fp0
, fd
);
11304 tcg_temp_free_i32(fp0
);
11308 check_cp1_registers(ctx
, fd
);
11310 TCGv_i32 fp32
= tcg_temp_new_i32();
11311 TCGv_i64 fp64
= tcg_temp_new_i64();
11313 gen_load_fpr32(ctx
, fp32
, fs
);
11314 gen_helper_float_cvtd_w(fp64
, cpu_env
, fp32
);
11315 tcg_temp_free_i32(fp32
);
11316 gen_store_fpr64(ctx
, fp64
, fd
);
11317 tcg_temp_free_i64(fp64
);
11321 check_cp1_64bitmode(ctx
);
11323 TCGv_i32 fp32
= tcg_temp_new_i32();
11324 TCGv_i64 fp64
= tcg_temp_new_i64();
11326 gen_load_fpr64(ctx
, fp64
, fs
);
11327 gen_helper_float_cvts_l(fp32
, cpu_env
, fp64
);
11328 tcg_temp_free_i64(fp64
);
11329 gen_store_fpr32(ctx
, fp32
, fd
);
11330 tcg_temp_free_i32(fp32
);
11334 check_cp1_64bitmode(ctx
);
11336 TCGv_i64 fp0
= tcg_temp_new_i64();
11338 gen_load_fpr64(ctx
, fp0
, fs
);
11339 gen_helper_float_cvtd_l(fp0
, cpu_env
, fp0
);
11340 gen_store_fpr64(ctx
, fp0
, fd
);
11341 tcg_temp_free_i64(fp0
);
11344 case OPC_CVT_PS_PW
:
11347 TCGv_i64 fp0
= tcg_temp_new_i64();
11349 gen_load_fpr64(ctx
, fp0
, fs
);
11350 gen_helper_float_cvtps_pw(fp0
, cpu_env
, fp0
);
11351 gen_store_fpr64(ctx
, fp0
, fd
);
11352 tcg_temp_free_i64(fp0
);
11358 TCGv_i64 fp0
= tcg_temp_new_i64();
11359 TCGv_i64 fp1
= tcg_temp_new_i64();
11361 gen_load_fpr64(ctx
, fp0
, fs
);
11362 gen_load_fpr64(ctx
, fp1
, ft
);
11363 gen_helper_float_add_ps(fp0
, cpu_env
, fp0
, fp1
);
11364 tcg_temp_free_i64(fp1
);
11365 gen_store_fpr64(ctx
, fp0
, fd
);
11366 tcg_temp_free_i64(fp0
);
11372 TCGv_i64 fp0
= tcg_temp_new_i64();
11373 TCGv_i64 fp1
= tcg_temp_new_i64();
11375 gen_load_fpr64(ctx
, fp0
, fs
);
11376 gen_load_fpr64(ctx
, fp1
, ft
);
11377 gen_helper_float_sub_ps(fp0
, cpu_env
, fp0
, fp1
);
11378 tcg_temp_free_i64(fp1
);
11379 gen_store_fpr64(ctx
, fp0
, fd
);
11380 tcg_temp_free_i64(fp0
);
11386 TCGv_i64 fp0
= tcg_temp_new_i64();
11387 TCGv_i64 fp1
= tcg_temp_new_i64();
11389 gen_load_fpr64(ctx
, fp0
, fs
);
11390 gen_load_fpr64(ctx
, fp1
, ft
);
11391 gen_helper_float_mul_ps(fp0
, cpu_env
, fp0
, fp1
);
11392 tcg_temp_free_i64(fp1
);
11393 gen_store_fpr64(ctx
, fp0
, fd
);
11394 tcg_temp_free_i64(fp0
);
11400 TCGv_i64 fp0
= tcg_temp_new_i64();
11402 gen_load_fpr64(ctx
, fp0
, fs
);
11403 gen_helper_float_abs_ps(fp0
, fp0
);
11404 gen_store_fpr64(ctx
, fp0
, fd
);
11405 tcg_temp_free_i64(fp0
);
11411 TCGv_i64 fp0
= tcg_temp_new_i64();
11413 gen_load_fpr64(ctx
, fp0
, fs
);
11414 gen_store_fpr64(ctx
, fp0
, fd
);
11415 tcg_temp_free_i64(fp0
);
11421 TCGv_i64 fp0
= tcg_temp_new_i64();
11423 gen_load_fpr64(ctx
, fp0
, fs
);
11424 gen_helper_float_chs_ps(fp0
, fp0
);
11425 gen_store_fpr64(ctx
, fp0
, fd
);
11426 tcg_temp_free_i64(fp0
);
11431 gen_movcf_ps(ctx
, fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
11436 TCGLabel
*l1
= gen_new_label();
11440 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
11442 fp0
= tcg_temp_new_i64();
11443 gen_load_fpr64(ctx
, fp0
, fs
);
11444 gen_store_fpr64(ctx
, fp0
, fd
);
11445 tcg_temp_free_i64(fp0
);
11452 TCGLabel
*l1
= gen_new_label();
11456 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
11457 fp0
= tcg_temp_new_i64();
11458 gen_load_fpr64(ctx
, fp0
, fs
);
11459 gen_store_fpr64(ctx
, fp0
, fd
);
11460 tcg_temp_free_i64(fp0
);
11468 TCGv_i64 fp0
= tcg_temp_new_i64();
11469 TCGv_i64 fp1
= tcg_temp_new_i64();
11471 gen_load_fpr64(ctx
, fp0
, ft
);
11472 gen_load_fpr64(ctx
, fp1
, fs
);
11473 gen_helper_float_addr_ps(fp0
, cpu_env
, fp0
, fp1
);
11474 tcg_temp_free_i64(fp1
);
11475 gen_store_fpr64(ctx
, fp0
, fd
);
11476 tcg_temp_free_i64(fp0
);
11482 TCGv_i64 fp0
= tcg_temp_new_i64();
11483 TCGv_i64 fp1
= tcg_temp_new_i64();
11485 gen_load_fpr64(ctx
, fp0
, ft
);
11486 gen_load_fpr64(ctx
, fp1
, fs
);
11487 gen_helper_float_mulr_ps(fp0
, cpu_env
, fp0
, fp1
);
11488 tcg_temp_free_i64(fp1
);
11489 gen_store_fpr64(ctx
, fp0
, fd
);
11490 tcg_temp_free_i64(fp0
);
11493 case OPC_RECIP2_PS
:
11496 TCGv_i64 fp0
= tcg_temp_new_i64();
11497 TCGv_i64 fp1
= tcg_temp_new_i64();
11499 gen_load_fpr64(ctx
, fp0
, fs
);
11500 gen_load_fpr64(ctx
, fp1
, ft
);
11501 gen_helper_float_recip2_ps(fp0
, cpu_env
, fp0
, fp1
);
11502 tcg_temp_free_i64(fp1
);
11503 gen_store_fpr64(ctx
, fp0
, fd
);
11504 tcg_temp_free_i64(fp0
);
11507 case OPC_RECIP1_PS
:
11510 TCGv_i64 fp0
= tcg_temp_new_i64();
11512 gen_load_fpr64(ctx
, fp0
, fs
);
11513 gen_helper_float_recip1_ps(fp0
, cpu_env
, fp0
);
11514 gen_store_fpr64(ctx
, fp0
, fd
);
11515 tcg_temp_free_i64(fp0
);
11518 case OPC_RSQRT1_PS
:
11521 TCGv_i64 fp0
= tcg_temp_new_i64();
11523 gen_load_fpr64(ctx
, fp0
, fs
);
11524 gen_helper_float_rsqrt1_ps(fp0
, cpu_env
, fp0
);
11525 gen_store_fpr64(ctx
, fp0
, fd
);
11526 tcg_temp_free_i64(fp0
);
11529 case OPC_RSQRT2_PS
:
11532 TCGv_i64 fp0
= tcg_temp_new_i64();
11533 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_rsqrt2_ps(fp0
, cpu_env
, fp0
, fp1
);
11538 tcg_temp_free_i64(fp1
);
11539 gen_store_fpr64(ctx
, fp0
, fd
);
11540 tcg_temp_free_i64(fp0
);
11544 check_cp1_64bitmode(ctx
);
11546 TCGv_i32 fp0
= tcg_temp_new_i32();
11548 gen_load_fpr32h(ctx
, fp0
, fs
);
11549 gen_helper_float_cvts_pu(fp0
, cpu_env
, fp0
);
11550 gen_store_fpr32(ctx
, fp0
, fd
);
11551 tcg_temp_free_i32(fp0
);
11554 case OPC_CVT_PW_PS
:
11557 TCGv_i64 fp0
= tcg_temp_new_i64();
11559 gen_load_fpr64(ctx
, fp0
, fs
);
11560 gen_helper_float_cvtpw_ps(fp0
, cpu_env
, fp0
);
11561 gen_store_fpr64(ctx
, fp0
, fd
);
11562 tcg_temp_free_i64(fp0
);
11566 check_cp1_64bitmode(ctx
);
11568 TCGv_i32 fp0
= tcg_temp_new_i32();
11570 gen_load_fpr32(ctx
, fp0
, fs
);
11571 gen_helper_float_cvts_pl(fp0
, cpu_env
, fp0
);
11572 gen_store_fpr32(ctx
, fp0
, fd
);
11573 tcg_temp_free_i32(fp0
);
11579 TCGv_i32 fp0
= tcg_temp_new_i32();
11580 TCGv_i32 fp1
= tcg_temp_new_i32();
11582 gen_load_fpr32(ctx
, fp0
, fs
);
11583 gen_load_fpr32(ctx
, fp1
, ft
);
11584 gen_store_fpr32h(ctx
, fp0
, fd
);
11585 gen_store_fpr32(ctx
, fp1
, fd
);
11586 tcg_temp_free_i32(fp0
);
11587 tcg_temp_free_i32(fp1
);
11593 TCGv_i32 fp0
= tcg_temp_new_i32();
11594 TCGv_i32 fp1
= tcg_temp_new_i32();
11596 gen_load_fpr32(ctx
, fp0
, fs
);
11597 gen_load_fpr32h(ctx
, fp1
, ft
);
11598 gen_store_fpr32(ctx
, fp1
, fd
);
11599 gen_store_fpr32h(ctx
, fp0
, fd
);
11600 tcg_temp_free_i32(fp0
);
11601 tcg_temp_free_i32(fp1
);
11607 TCGv_i32 fp0
= tcg_temp_new_i32();
11608 TCGv_i32 fp1
= tcg_temp_new_i32();
11610 gen_load_fpr32h(ctx
, fp0
, fs
);
11611 gen_load_fpr32(ctx
, fp1
, ft
);
11612 gen_store_fpr32(ctx
, fp1
, fd
);
11613 gen_store_fpr32h(ctx
, fp0
, fd
);
11614 tcg_temp_free_i32(fp0
);
11615 tcg_temp_free_i32(fp1
);
11621 TCGv_i32 fp0
= tcg_temp_new_i32();
11622 TCGv_i32 fp1
= tcg_temp_new_i32();
11624 gen_load_fpr32h(ctx
, fp0
, fs
);
11625 gen_load_fpr32h(ctx
, fp1
, ft
);
11626 gen_store_fpr32(ctx
, fp1
, fd
);
11627 gen_store_fpr32h(ctx
, fp0
, fd
);
11628 tcg_temp_free_i32(fp0
);
11629 tcg_temp_free_i32(fp1
);
11633 case OPC_CMP_UN_PS
:
11634 case OPC_CMP_EQ_PS
:
11635 case OPC_CMP_UEQ_PS
:
11636 case OPC_CMP_OLT_PS
:
11637 case OPC_CMP_ULT_PS
:
11638 case OPC_CMP_OLE_PS
:
11639 case OPC_CMP_ULE_PS
:
11640 case OPC_CMP_SF_PS
:
11641 case OPC_CMP_NGLE_PS
:
11642 case OPC_CMP_SEQ_PS
:
11643 case OPC_CMP_NGL_PS
:
11644 case OPC_CMP_LT_PS
:
11645 case OPC_CMP_NGE_PS
:
11646 case OPC_CMP_LE_PS
:
11647 case OPC_CMP_NGT_PS
:
11648 if (ctx
->opcode
& (1 << 6)) {
11649 gen_cmpabs_ps(ctx
, func
- 48, ft
, fs
, cc
);
11651 gen_cmp_ps(ctx
, func
- 48, ft
, fs
, cc
);
11655 MIPS_INVAL("farith");
11656 gen_reserved_instruction(ctx
);
11661 /* Coprocessor 3 (FPU) */
11662 static void gen_flt3_ldst(DisasContext
*ctx
, uint32_t opc
,
11663 int fd
, int fs
, int base
, int index
)
11665 TCGv t0
= tcg_temp_new();
11668 gen_load_gpr(t0
, index
);
11669 } else if (index
== 0) {
11670 gen_load_gpr(t0
, base
);
11672 gen_op_addr_add(ctx
, t0
, cpu_gpr
[base
], cpu_gpr
[index
]);
11675 * Don't do NOP if destination is zero: we must perform the actual
11682 TCGv_i32 fp0
= tcg_temp_new_i32();
11684 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESL
);
11685 tcg_gen_trunc_tl_i32(fp0
, t0
);
11686 gen_store_fpr32(ctx
, fp0
, fd
);
11687 tcg_temp_free_i32(fp0
);
11692 check_cp1_registers(ctx
, fd
);
11694 TCGv_i64 fp0
= tcg_temp_new_i64();
11695 tcg_gen_qemu_ld_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
11696 gen_store_fpr64(ctx
, fp0
, fd
);
11697 tcg_temp_free_i64(fp0
);
11701 check_cp1_64bitmode(ctx
);
11702 tcg_gen_andi_tl(t0
, t0
, ~0x7);
11704 TCGv_i64 fp0
= tcg_temp_new_i64();
11706 tcg_gen_qemu_ld_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
11707 gen_store_fpr64(ctx
, fp0
, fd
);
11708 tcg_temp_free_i64(fp0
);
11714 TCGv_i32 fp0
= tcg_temp_new_i32();
11715 gen_load_fpr32(ctx
, fp0
, fs
);
11716 tcg_gen_qemu_st_i32(fp0
, t0
, ctx
->mem_idx
, MO_TEUL
);
11717 tcg_temp_free_i32(fp0
);
11722 check_cp1_registers(ctx
, fs
);
11724 TCGv_i64 fp0
= tcg_temp_new_i64();
11725 gen_load_fpr64(ctx
, fp0
, fs
);
11726 tcg_gen_qemu_st_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
11727 tcg_temp_free_i64(fp0
);
11731 check_cp1_64bitmode(ctx
);
11732 tcg_gen_andi_tl(t0
, t0
, ~0x7);
11734 TCGv_i64 fp0
= tcg_temp_new_i64();
11735 gen_load_fpr64(ctx
, fp0
, fs
);
11736 tcg_gen_qemu_st_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
11737 tcg_temp_free_i64(fp0
);
11744 static void gen_flt3_arith(DisasContext
*ctx
, uint32_t opc
,
11745 int fd
, int fr
, int fs
, int ft
)
11751 TCGv t0
= tcg_temp_local_new();
11752 TCGv_i32 fp
= tcg_temp_new_i32();
11753 TCGv_i32 fph
= tcg_temp_new_i32();
11754 TCGLabel
*l1
= gen_new_label();
11755 TCGLabel
*l2
= gen_new_label();
11757 gen_load_gpr(t0
, fr
);
11758 tcg_gen_andi_tl(t0
, t0
, 0x7);
11760 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, 0, l1
);
11761 gen_load_fpr32(ctx
, fp
, fs
);
11762 gen_load_fpr32h(ctx
, fph
, fs
);
11763 gen_store_fpr32(ctx
, fp
, fd
);
11764 gen_store_fpr32h(ctx
, fph
, fd
);
11767 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, 4, l2
);
11769 #ifdef TARGET_WORDS_BIGENDIAN
11770 gen_load_fpr32(ctx
, fp
, fs
);
11771 gen_load_fpr32h(ctx
, fph
, ft
);
11772 gen_store_fpr32h(ctx
, fp
, fd
);
11773 gen_store_fpr32(ctx
, fph
, fd
);
11775 gen_load_fpr32h(ctx
, fph
, fs
);
11776 gen_load_fpr32(ctx
, fp
, ft
);
11777 gen_store_fpr32(ctx
, fph
, fd
);
11778 gen_store_fpr32h(ctx
, fp
, fd
);
11781 tcg_temp_free_i32(fp
);
11782 tcg_temp_free_i32(fph
);
11788 TCGv_i32 fp0
= tcg_temp_new_i32();
11789 TCGv_i32 fp1
= tcg_temp_new_i32();
11790 TCGv_i32 fp2
= tcg_temp_new_i32();
11792 gen_load_fpr32(ctx
, fp0
, fs
);
11793 gen_load_fpr32(ctx
, fp1
, ft
);
11794 gen_load_fpr32(ctx
, fp2
, fr
);
11795 gen_helper_float_madd_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
11796 tcg_temp_free_i32(fp0
);
11797 tcg_temp_free_i32(fp1
);
11798 gen_store_fpr32(ctx
, fp2
, fd
);
11799 tcg_temp_free_i32(fp2
);
11804 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
11806 TCGv_i64 fp0
= tcg_temp_new_i64();
11807 TCGv_i64 fp1
= tcg_temp_new_i64();
11808 TCGv_i64 fp2
= tcg_temp_new_i64();
11810 gen_load_fpr64(ctx
, fp0
, fs
);
11811 gen_load_fpr64(ctx
, fp1
, ft
);
11812 gen_load_fpr64(ctx
, fp2
, fr
);
11813 gen_helper_float_madd_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
11814 tcg_temp_free_i64(fp0
);
11815 tcg_temp_free_i64(fp1
);
11816 gen_store_fpr64(ctx
, fp2
, fd
);
11817 tcg_temp_free_i64(fp2
);
11823 TCGv_i64 fp0
= tcg_temp_new_i64();
11824 TCGv_i64 fp1
= tcg_temp_new_i64();
11825 TCGv_i64 fp2
= tcg_temp_new_i64();
11827 gen_load_fpr64(ctx
, fp0
, fs
);
11828 gen_load_fpr64(ctx
, fp1
, ft
);
11829 gen_load_fpr64(ctx
, fp2
, fr
);
11830 gen_helper_float_madd_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
11831 tcg_temp_free_i64(fp0
);
11832 tcg_temp_free_i64(fp1
);
11833 gen_store_fpr64(ctx
, fp2
, fd
);
11834 tcg_temp_free_i64(fp2
);
11840 TCGv_i32 fp0
= tcg_temp_new_i32();
11841 TCGv_i32 fp1
= tcg_temp_new_i32();
11842 TCGv_i32 fp2
= tcg_temp_new_i32();
11844 gen_load_fpr32(ctx
, fp0
, fs
);
11845 gen_load_fpr32(ctx
, fp1
, ft
);
11846 gen_load_fpr32(ctx
, fp2
, fr
);
11847 gen_helper_float_msub_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
11848 tcg_temp_free_i32(fp0
);
11849 tcg_temp_free_i32(fp1
);
11850 gen_store_fpr32(ctx
, fp2
, fd
);
11851 tcg_temp_free_i32(fp2
);
11856 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
11858 TCGv_i64 fp0
= tcg_temp_new_i64();
11859 TCGv_i64 fp1
= tcg_temp_new_i64();
11860 TCGv_i64 fp2
= tcg_temp_new_i64();
11862 gen_load_fpr64(ctx
, fp0
, fs
);
11863 gen_load_fpr64(ctx
, fp1
, ft
);
11864 gen_load_fpr64(ctx
, fp2
, fr
);
11865 gen_helper_float_msub_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
11866 tcg_temp_free_i64(fp0
);
11867 tcg_temp_free_i64(fp1
);
11868 gen_store_fpr64(ctx
, fp2
, fd
);
11869 tcg_temp_free_i64(fp2
);
11875 TCGv_i64 fp0
= tcg_temp_new_i64();
11876 TCGv_i64 fp1
= tcg_temp_new_i64();
11877 TCGv_i64 fp2
= tcg_temp_new_i64();
11879 gen_load_fpr64(ctx
, fp0
, fs
);
11880 gen_load_fpr64(ctx
, fp1
, ft
);
11881 gen_load_fpr64(ctx
, fp2
, fr
);
11882 gen_helper_float_msub_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
11883 tcg_temp_free_i64(fp0
);
11884 tcg_temp_free_i64(fp1
);
11885 gen_store_fpr64(ctx
, fp2
, fd
);
11886 tcg_temp_free_i64(fp2
);
11892 TCGv_i32 fp0
= tcg_temp_new_i32();
11893 TCGv_i32 fp1
= tcg_temp_new_i32();
11894 TCGv_i32 fp2
= tcg_temp_new_i32();
11896 gen_load_fpr32(ctx
, fp0
, fs
);
11897 gen_load_fpr32(ctx
, fp1
, ft
);
11898 gen_load_fpr32(ctx
, fp2
, fr
);
11899 gen_helper_float_nmadd_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
11900 tcg_temp_free_i32(fp0
);
11901 tcg_temp_free_i32(fp1
);
11902 gen_store_fpr32(ctx
, fp2
, fd
);
11903 tcg_temp_free_i32(fp2
);
11908 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
11910 TCGv_i64 fp0
= tcg_temp_new_i64();
11911 TCGv_i64 fp1
= tcg_temp_new_i64();
11912 TCGv_i64 fp2
= tcg_temp_new_i64();
11914 gen_load_fpr64(ctx
, fp0
, fs
);
11915 gen_load_fpr64(ctx
, fp1
, ft
);
11916 gen_load_fpr64(ctx
, fp2
, fr
);
11917 gen_helper_float_nmadd_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
11918 tcg_temp_free_i64(fp0
);
11919 tcg_temp_free_i64(fp1
);
11920 gen_store_fpr64(ctx
, fp2
, fd
);
11921 tcg_temp_free_i64(fp2
);
11927 TCGv_i64 fp0
= tcg_temp_new_i64();
11928 TCGv_i64 fp1
= tcg_temp_new_i64();
11929 TCGv_i64 fp2
= tcg_temp_new_i64();
11931 gen_load_fpr64(ctx
, fp0
, fs
);
11932 gen_load_fpr64(ctx
, fp1
, ft
);
11933 gen_load_fpr64(ctx
, fp2
, fr
);
11934 gen_helper_float_nmadd_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
11935 tcg_temp_free_i64(fp0
);
11936 tcg_temp_free_i64(fp1
);
11937 gen_store_fpr64(ctx
, fp2
, fd
);
11938 tcg_temp_free_i64(fp2
);
11944 TCGv_i32 fp0
= tcg_temp_new_i32();
11945 TCGv_i32 fp1
= tcg_temp_new_i32();
11946 TCGv_i32 fp2
= tcg_temp_new_i32();
11948 gen_load_fpr32(ctx
, fp0
, fs
);
11949 gen_load_fpr32(ctx
, fp1
, ft
);
11950 gen_load_fpr32(ctx
, fp2
, fr
);
11951 gen_helper_float_nmsub_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
11952 tcg_temp_free_i32(fp0
);
11953 tcg_temp_free_i32(fp1
);
11954 gen_store_fpr32(ctx
, fp2
, fd
);
11955 tcg_temp_free_i32(fp2
);
11960 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
11962 TCGv_i64 fp0
= tcg_temp_new_i64();
11963 TCGv_i64 fp1
= tcg_temp_new_i64();
11964 TCGv_i64 fp2
= tcg_temp_new_i64();
11966 gen_load_fpr64(ctx
, fp0
, fs
);
11967 gen_load_fpr64(ctx
, fp1
, ft
);
11968 gen_load_fpr64(ctx
, fp2
, fr
);
11969 gen_helper_float_nmsub_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
11970 tcg_temp_free_i64(fp0
);
11971 tcg_temp_free_i64(fp1
);
11972 gen_store_fpr64(ctx
, fp2
, fd
);
11973 tcg_temp_free_i64(fp2
);
11979 TCGv_i64 fp0
= tcg_temp_new_i64();
11980 TCGv_i64 fp1
= tcg_temp_new_i64();
11981 TCGv_i64 fp2
= tcg_temp_new_i64();
11983 gen_load_fpr64(ctx
, fp0
, fs
);
11984 gen_load_fpr64(ctx
, fp1
, ft
);
11985 gen_load_fpr64(ctx
, fp2
, fr
);
11986 gen_helper_float_nmsub_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
11987 tcg_temp_free_i64(fp0
);
11988 tcg_temp_free_i64(fp1
);
11989 gen_store_fpr64(ctx
, fp2
, fd
);
11990 tcg_temp_free_i64(fp2
);
11994 MIPS_INVAL("flt3_arith");
11995 gen_reserved_instruction(ctx
);
12000 void gen_rdhwr(DisasContext
*ctx
, int rt
, int rd
, int sel
)
12004 #if !defined(CONFIG_USER_ONLY)
12006 * The Linux kernel will emulate rdhwr if it's not supported natively.
12007 * Therefore only check the ISA in system mode.
12009 check_insn(ctx
, ISA_MIPS_R2
);
12011 t0
= tcg_temp_new();
12015 gen_helper_rdhwr_cpunum(t0
, cpu_env
);
12016 gen_store_gpr(t0
, rt
);
12019 gen_helper_rdhwr_synci_step(t0
, cpu_env
);
12020 gen_store_gpr(t0
, rt
);
12023 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
12026 gen_helper_rdhwr_cc(t0
, cpu_env
);
12027 gen_store_gpr(t0
, rt
);
12029 * Break the TB to be able to take timer interrupts immediately
12030 * after reading count. DISAS_STOP isn't sufficient, we need to ensure
12031 * we break completely out of translated code.
12033 gen_save_pc(ctx
->base
.pc_next
+ 4);
12034 ctx
->base
.is_jmp
= DISAS_EXIT
;
12037 gen_helper_rdhwr_ccres(t0
, cpu_env
);
12038 gen_store_gpr(t0
, rt
);
12041 check_insn(ctx
, ISA_MIPS_R6
);
12044 * Performance counter registers are not implemented other than
12045 * control register 0.
12047 generate_exception(ctx
, EXCP_RI
);
12049 gen_helper_rdhwr_performance(t0
, cpu_env
);
12050 gen_store_gpr(t0
, rt
);
12053 check_insn(ctx
, ISA_MIPS_R6
);
12054 gen_helper_rdhwr_xnp(t0
, cpu_env
);
12055 gen_store_gpr(t0
, rt
);
12058 #if defined(CONFIG_USER_ONLY)
12059 tcg_gen_ld_tl(t0
, cpu_env
,
12060 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
12061 gen_store_gpr(t0
, rt
);
12064 if ((ctx
->hflags
& MIPS_HFLAG_CP0
) ||
12065 (ctx
->hflags
& MIPS_HFLAG_HWRENA_ULR
)) {
12066 tcg_gen_ld_tl(t0
, cpu_env
,
12067 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
12068 gen_store_gpr(t0
, rt
);
12070 gen_reserved_instruction(ctx
);
12074 default: /* Invalid */
12075 MIPS_INVAL("rdhwr");
12076 gen_reserved_instruction(ctx
);
12082 static inline void clear_branch_hflags(DisasContext
*ctx
)
12084 ctx
->hflags
&= ~MIPS_HFLAG_BMASK
;
12085 if (ctx
->base
.is_jmp
== DISAS_NEXT
) {
12086 save_cpu_state(ctx
, 0);
12089 * It is not safe to save ctx->hflags as hflags may be changed
12090 * in execution time by the instruction in delay / forbidden slot.
12092 tcg_gen_andi_i32(hflags
, hflags
, ~MIPS_HFLAG_BMASK
);
12096 static void gen_branch(DisasContext
*ctx
, int insn_bytes
)
12098 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
12099 int proc_hflags
= ctx
->hflags
& MIPS_HFLAG_BMASK
;
12100 /* Branches completion */
12101 clear_branch_hflags(ctx
);
12102 ctx
->base
.is_jmp
= DISAS_NORETURN
;
12103 /* FIXME: Need to clear can_do_io. */
12104 switch (proc_hflags
& MIPS_HFLAG_BMASK_BASE
) {
12105 case MIPS_HFLAG_FBNSLOT
:
12106 gen_goto_tb(ctx
, 0, ctx
->base
.pc_next
+ insn_bytes
);
12109 /* unconditional branch */
12110 if (proc_hflags
& MIPS_HFLAG_BX
) {
12111 tcg_gen_xori_i32(hflags
, hflags
, MIPS_HFLAG_M16
);
12113 gen_goto_tb(ctx
, 0, ctx
->btarget
);
12115 case MIPS_HFLAG_BL
:
12116 /* blikely taken case */
12117 gen_goto_tb(ctx
, 0, ctx
->btarget
);
12119 case MIPS_HFLAG_BC
:
12120 /* Conditional branch */
12122 TCGLabel
*l1
= gen_new_label();
12124 tcg_gen_brcondi_tl(TCG_COND_NE
, bcond
, 0, l1
);
12125 gen_goto_tb(ctx
, 1, ctx
->base
.pc_next
+ insn_bytes
);
12127 gen_goto_tb(ctx
, 0, ctx
->btarget
);
12130 case MIPS_HFLAG_BR
:
12131 /* unconditional branch to register */
12132 if (ctx
->insn_flags
& (ASE_MIPS16
| ASE_MICROMIPS
)) {
12133 TCGv t0
= tcg_temp_new();
12134 TCGv_i32 t1
= tcg_temp_new_i32();
12136 tcg_gen_andi_tl(t0
, btarget
, 0x1);
12137 tcg_gen_trunc_tl_i32(t1
, t0
);
12139 tcg_gen_andi_i32(hflags
, hflags
, ~(uint32_t)MIPS_HFLAG_M16
);
12140 tcg_gen_shli_i32(t1
, t1
, MIPS_HFLAG_M16_SHIFT
);
12141 tcg_gen_or_i32(hflags
, hflags
, t1
);
12142 tcg_temp_free_i32(t1
);
12144 tcg_gen_andi_tl(cpu_PC
, btarget
, ~(target_ulong
)0x1);
12146 tcg_gen_mov_tl(cpu_PC
, btarget
);
12148 if (ctx
->base
.singlestep_enabled
) {
12149 save_cpu_state(ctx
, 0);
12150 gen_helper_raise_exception_debug(cpu_env
);
12152 tcg_gen_lookup_and_goto_ptr();
12155 fprintf(stderr
, "unknown branch 0x%x\n", proc_hflags
);
12161 /* Compact Branches */
12162 static void gen_compute_compact_branch(DisasContext
*ctx
, uint32_t opc
,
12163 int rs
, int rt
, int32_t offset
)
12165 int bcond_compute
= 0;
12166 TCGv t0
= tcg_temp_new();
12167 TCGv t1
= tcg_temp_new();
12168 int m16_lowbit
= (ctx
->hflags
& MIPS_HFLAG_M16
) != 0;
12170 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
12171 #ifdef MIPS_DEBUG_DISAS
12172 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
12173 "\n", ctx
->base
.pc_next
);
12175 gen_reserved_instruction(ctx
);
12179 /* Load needed operands and calculate btarget */
12181 /* compact branch */
12182 case OPC_BOVC
: /* OPC_BEQZALC, OPC_BEQC */
12183 case OPC_BNVC
: /* OPC_BNEZALC, OPC_BNEC */
12184 gen_load_gpr(t0
, rs
);
12185 gen_load_gpr(t1
, rt
);
12187 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
12188 if (rs
<= rt
&& rs
== 0) {
12189 /* OPC_BEQZALC, OPC_BNEZALC */
12190 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 4 + m16_lowbit
);
12193 case OPC_BLEZC
: /* OPC_BGEZC, OPC_BGEC */
12194 case OPC_BGTZC
: /* OPC_BLTZC, OPC_BLTC */
12195 gen_load_gpr(t0
, rs
);
12196 gen_load_gpr(t1
, rt
);
12198 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
12200 case OPC_BLEZALC
: /* OPC_BGEZALC, OPC_BGEUC */
12201 case OPC_BGTZALC
: /* OPC_BLTZALC, OPC_BLTUC */
12202 if (rs
== 0 || rs
== rt
) {
12203 /* OPC_BLEZALC, OPC_BGEZALC */
12204 /* OPC_BGTZALC, OPC_BLTZALC */
12205 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 4 + m16_lowbit
);
12207 gen_load_gpr(t0
, rs
);
12208 gen_load_gpr(t1
, rt
);
12210 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
12214 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
12219 /* OPC_BEQZC, OPC_BNEZC */
12220 gen_load_gpr(t0
, rs
);
12222 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
12224 /* OPC_JIC, OPC_JIALC */
12225 TCGv tbase
= tcg_temp_new();
12226 TCGv toffset
= tcg_temp_new();
12228 gen_load_gpr(tbase
, rt
);
12229 tcg_gen_movi_tl(toffset
, offset
);
12230 gen_op_addr_add(ctx
, btarget
, tbase
, toffset
);
12231 tcg_temp_free(tbase
);
12232 tcg_temp_free(toffset
);
12236 MIPS_INVAL("Compact branch/jump");
12237 gen_reserved_instruction(ctx
);
12241 if (bcond_compute
== 0) {
12242 /* Uncoditional compact branch */
12245 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 4 + m16_lowbit
);
12248 ctx
->hflags
|= MIPS_HFLAG_BR
;
12251 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 4 + m16_lowbit
);
12254 ctx
->hflags
|= MIPS_HFLAG_B
;
12257 MIPS_INVAL("Compact branch/jump");
12258 gen_reserved_instruction(ctx
);
12262 /* Generating branch here as compact branches don't have delay slot */
12263 gen_branch(ctx
, 4);
12265 /* Conditional compact branch */
12266 TCGLabel
*fs
= gen_new_label();
12267 save_cpu_state(ctx
, 0);
12270 case OPC_BLEZALC
: /* OPC_BGEZALC, OPC_BGEUC */
12271 if (rs
== 0 && rt
!= 0) {
12273 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE
), t1
, 0, fs
);
12274 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
12276 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE
), t1
, 0, fs
);
12279 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU
), t0
, t1
, fs
);
12282 case OPC_BGTZALC
: /* OPC_BLTZALC, OPC_BLTUC */
12283 if (rs
== 0 && rt
!= 0) {
12285 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT
), t1
, 0, fs
);
12286 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
12288 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT
), t1
, 0, fs
);
12291 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU
), t0
, t1
, fs
);
12294 case OPC_BLEZC
: /* OPC_BGEZC, OPC_BGEC */
12295 if (rs
== 0 && rt
!= 0) {
12297 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE
), t1
, 0, fs
);
12298 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
12300 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE
), t1
, 0, fs
);
12303 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE
), t0
, t1
, fs
);
12306 case OPC_BGTZC
: /* OPC_BLTZC, OPC_BLTC */
12307 if (rs
== 0 && rt
!= 0) {
12309 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT
), t1
, 0, fs
);
12310 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
12312 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT
), t1
, 0, fs
);
12315 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT
), t0
, t1
, fs
);
12318 case OPC_BOVC
: /* OPC_BEQZALC, OPC_BEQC */
12319 case OPC_BNVC
: /* OPC_BNEZALC, OPC_BNEC */
12321 /* OPC_BOVC, OPC_BNVC */
12322 TCGv t2
= tcg_temp_new();
12323 TCGv t3
= tcg_temp_new();
12324 TCGv t4
= tcg_temp_new();
12325 TCGv input_overflow
= tcg_temp_new();
12327 gen_load_gpr(t0
, rs
);
12328 gen_load_gpr(t1
, rt
);
12329 tcg_gen_ext32s_tl(t2
, t0
);
12330 tcg_gen_setcond_tl(TCG_COND_NE
, input_overflow
, t2
, t0
);
12331 tcg_gen_ext32s_tl(t3
, t1
);
12332 tcg_gen_setcond_tl(TCG_COND_NE
, t4
, t3
, t1
);
12333 tcg_gen_or_tl(input_overflow
, input_overflow
, t4
);
12335 tcg_gen_add_tl(t4
, t2
, t3
);
12336 tcg_gen_ext32s_tl(t4
, t4
);
12337 tcg_gen_xor_tl(t2
, t2
, t3
);
12338 tcg_gen_xor_tl(t3
, t4
, t3
);
12339 tcg_gen_andc_tl(t2
, t3
, t2
);
12340 tcg_gen_setcondi_tl(TCG_COND_LT
, t4
, t2
, 0);
12341 tcg_gen_or_tl(t4
, t4
, input_overflow
);
12342 if (opc
== OPC_BOVC
) {
12344 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE
), t4
, 0, fs
);
12347 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ
), t4
, 0, fs
);
12349 tcg_temp_free(input_overflow
);
12353 } else if (rs
< rt
&& rs
== 0) {
12354 /* OPC_BEQZALC, OPC_BNEZALC */
12355 if (opc
== OPC_BEQZALC
) {
12357 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ
), t1
, 0, fs
);
12360 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE
), t1
, 0, fs
);
12363 /* OPC_BEQC, OPC_BNEC */
12364 if (opc
== OPC_BEQC
) {
12366 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ
), t0
, t1
, fs
);
12369 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE
), t0
, t1
, fs
);
12374 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ
), t0
, 0, fs
);
12377 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE
), t0
, 0, fs
);
12380 MIPS_INVAL("Compact conditional branch/jump");
12381 gen_reserved_instruction(ctx
);
12385 /* Generating branch here as compact branches don't have delay slot */
12386 gen_goto_tb(ctx
, 1, ctx
->btarget
);
12389 ctx
->hflags
|= MIPS_HFLAG_FBNSLOT
;
12397 /* ISA extensions (ASEs) */
12398 /* MIPS16 extension to MIPS32 */
12400 /* MIPS16 major opcodes */
12402 M16_OPC_ADDIUSP
= 0x00,
12403 M16_OPC_ADDIUPC
= 0x01,
12405 M16_OPC_JAL
= 0x03,
12406 M16_OPC_BEQZ
= 0x04,
12407 M16_OPC_BNEQZ
= 0x05,
12408 M16_OPC_SHIFT
= 0x06,
12410 M16_OPC_RRIA
= 0x08,
12411 M16_OPC_ADDIU8
= 0x09,
12412 M16_OPC_SLTI
= 0x0a,
12413 M16_OPC_SLTIU
= 0x0b,
12416 M16_OPC_CMPI
= 0x0e,
12420 M16_OPC_LWSP
= 0x12,
12422 M16_OPC_LBU
= 0x14,
12423 M16_OPC_LHU
= 0x15,
12424 M16_OPC_LWPC
= 0x16,
12425 M16_OPC_LWU
= 0x17,
12428 M16_OPC_SWSP
= 0x1a,
12430 M16_OPC_RRR
= 0x1c,
12432 M16_OPC_EXTEND
= 0x1e,
12436 /* I8 funct field */
12455 /* RR funct field */
12489 /* I64 funct field */
12497 I64_DADDIUPC
= 0x6,
12501 /* RR ry field for CNVT */
12503 RR_RY_CNVT_ZEB
= 0x0,
12504 RR_RY_CNVT_ZEH
= 0x1,
12505 RR_RY_CNVT_ZEW
= 0x2,
12506 RR_RY_CNVT_SEB
= 0x4,
12507 RR_RY_CNVT_SEH
= 0x5,
12508 RR_RY_CNVT_SEW
= 0x6,
12511 static int xlat(int r
)
12513 static int map
[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
12518 static void gen_mips16_save(DisasContext
*ctx
,
12519 int xsregs
, int aregs
,
12520 int do_ra
, int do_s0
, int do_s1
,
12523 TCGv t0
= tcg_temp_new();
12524 TCGv t1
= tcg_temp_new();
12525 TCGv t2
= tcg_temp_new();
12555 gen_reserved_instruction(ctx
);
12561 gen_base_offset_addr(ctx
, t0
, 29, 12);
12562 gen_load_gpr(t1
, 7);
12563 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
12566 gen_base_offset_addr(ctx
, t0
, 29, 8);
12567 gen_load_gpr(t1
, 6);
12568 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
12571 gen_base_offset_addr(ctx
, t0
, 29, 4);
12572 gen_load_gpr(t1
, 5);
12573 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
12576 gen_base_offset_addr(ctx
, t0
, 29, 0);
12577 gen_load_gpr(t1
, 4);
12578 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
12581 gen_load_gpr(t0
, 29);
12583 #define DECR_AND_STORE(reg) do { \
12584 tcg_gen_movi_tl(t2, -4); \
12585 gen_op_addr_add(ctx, t0, t0, t2); \
12586 gen_load_gpr(t1, reg); \
12587 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \
12591 DECR_AND_STORE(31);
12596 DECR_AND_STORE(30);
12599 DECR_AND_STORE(23);
12602 DECR_AND_STORE(22);
12605 DECR_AND_STORE(21);
12608 DECR_AND_STORE(20);
12611 DECR_AND_STORE(19);
12614 DECR_AND_STORE(18);
12618 DECR_AND_STORE(17);
12621 DECR_AND_STORE(16);
12651 gen_reserved_instruction(ctx
);
12667 #undef DECR_AND_STORE
12669 tcg_gen_movi_tl(t2
, -framesize
);
12670 gen_op_addr_add(ctx
, cpu_gpr
[29], cpu_gpr
[29], t2
);
12676 static void gen_mips16_restore(DisasContext
*ctx
,
12677 int xsregs
, int aregs
,
12678 int do_ra
, int do_s0
, int do_s1
,
12682 TCGv t0
= tcg_temp_new();
12683 TCGv t1
= tcg_temp_new();
12684 TCGv t2
= tcg_temp_new();
12686 tcg_gen_movi_tl(t2
, framesize
);
12687 gen_op_addr_add(ctx
, t0
, cpu_gpr
[29], t2
);
12689 #define DECR_AND_LOAD(reg) do { \
12690 tcg_gen_movi_tl(t2, -4); \
12691 gen_op_addr_add(ctx, t0, t0, t2); \
12692 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \
12693 gen_store_gpr(t1, reg); \
12757 gen_reserved_instruction(ctx
);
12773 #undef DECR_AND_LOAD
12775 tcg_gen_movi_tl(t2
, framesize
);
12776 gen_op_addr_add(ctx
, cpu_gpr
[29], cpu_gpr
[29], t2
);
12782 static void gen_addiupc(DisasContext
*ctx
, int rx
, int imm
,
12783 int is_64_bit
, int extended
)
12787 if (extended
&& (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
12788 gen_reserved_instruction(ctx
);
12792 t0
= tcg_temp_new();
12794 tcg_gen_movi_tl(t0
, pc_relative_pc(ctx
));
12795 tcg_gen_addi_tl(cpu_gpr
[rx
], t0
, imm
);
12797 tcg_gen_ext32s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
12803 static void gen_cache_operation(DisasContext
*ctx
, uint32_t op
, int base
,
12806 TCGv_i32 t0
= tcg_const_i32(op
);
12807 TCGv t1
= tcg_temp_new();
12808 gen_base_offset_addr(ctx
, t1
, base
, offset
);
12809 gen_helper_cache(cpu_env
, t1
, t0
);
12811 tcg_temp_free_i32(t0
);
12814 #if defined(TARGET_MIPS64)
12815 static void decode_i64_mips16(DisasContext
*ctx
,
12816 int ry
, int funct
, int16_t offset
,
12821 check_insn(ctx
, ISA_MIPS3
);
12822 check_mips_64(ctx
);
12823 offset
= extended
? offset
: offset
<< 3;
12824 gen_ld(ctx
, OPC_LD
, ry
, 29, offset
);
12827 check_insn(ctx
, ISA_MIPS3
);
12828 check_mips_64(ctx
);
12829 offset
= extended
? offset
: offset
<< 3;
12830 gen_st(ctx
, OPC_SD
, ry
, 29, offset
);
12833 check_insn(ctx
, ISA_MIPS3
);
12834 check_mips_64(ctx
);
12835 offset
= extended
? offset
: (ctx
->opcode
& 0xff) << 3;
12836 gen_st(ctx
, OPC_SD
, 31, 29, offset
);
12839 check_insn(ctx
, ISA_MIPS3
);
12840 check_mips_64(ctx
);
12841 offset
= extended
? offset
: ((int8_t)ctx
->opcode
) << 3;
12842 gen_arith_imm(ctx
, OPC_DADDIU
, 29, 29, offset
);
12845 check_insn(ctx
, ISA_MIPS3
);
12846 check_mips_64(ctx
);
12847 if (extended
&& (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
12848 gen_reserved_instruction(ctx
);
12850 offset
= extended
? offset
: offset
<< 3;
12851 gen_ld(ctx
, OPC_LDPC
, ry
, 0, offset
);
12855 check_insn(ctx
, ISA_MIPS3
);
12856 check_mips_64(ctx
);
12857 offset
= extended
? offset
: ((int8_t)(offset
<< 3)) >> 3;
12858 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, ry
, offset
);
12861 check_insn(ctx
, ISA_MIPS3
);
12862 check_mips_64(ctx
);
12863 offset
= extended
? offset
: offset
<< 2;
12864 gen_addiupc(ctx
, ry
, offset
, 1, extended
);
12867 check_insn(ctx
, ISA_MIPS3
);
12868 check_mips_64(ctx
);
12869 offset
= extended
? offset
: offset
<< 2;
12870 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, 29, offset
);
12876 static int decode_extended_mips16_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
12878 int extend
= translator_lduw(env
, ctx
->base
.pc_next
+ 2);
12879 int op
, rx
, ry
, funct
, sa
;
12880 int16_t imm
, offset
;
12882 ctx
->opcode
= (ctx
->opcode
<< 16) | extend
;
12883 op
= (ctx
->opcode
>> 11) & 0x1f;
12884 sa
= (ctx
->opcode
>> 22) & 0x1f;
12885 funct
= (ctx
->opcode
>> 8) & 0x7;
12886 rx
= xlat((ctx
->opcode
>> 8) & 0x7);
12887 ry
= xlat((ctx
->opcode
>> 5) & 0x7);
12888 offset
= imm
= (int16_t) (((ctx
->opcode
>> 16) & 0x1f) << 11
12889 | ((ctx
->opcode
>> 21) & 0x3f) << 5
12890 | (ctx
->opcode
& 0x1f));
12893 * The extended opcodes cleverly reuse the opcodes from their 16-bit
12897 case M16_OPC_ADDIUSP
:
12898 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 29, imm
);
12900 case M16_OPC_ADDIUPC
:
12901 gen_addiupc(ctx
, rx
, imm
, 0, 1);
12904 gen_compute_branch(ctx
, OPC_BEQ
, 4, 0, 0, offset
<< 1, 0);
12905 /* No delay slot, so just process as a normal instruction */
12908 gen_compute_branch(ctx
, OPC_BEQ
, 4, rx
, 0, offset
<< 1, 0);
12909 /* No delay slot, so just process as a normal instruction */
12911 case M16_OPC_BNEQZ
:
12912 gen_compute_branch(ctx
, OPC_BNE
, 4, rx
, 0, offset
<< 1, 0);
12913 /* No delay slot, so just process as a normal instruction */
12915 case M16_OPC_SHIFT
:
12916 switch (ctx
->opcode
& 0x3) {
12918 gen_shift_imm(ctx
, OPC_SLL
, rx
, ry
, sa
);
12921 #if defined(TARGET_MIPS64)
12922 check_mips_64(ctx
);
12923 gen_shift_imm(ctx
, OPC_DSLL
, rx
, ry
, sa
);
12925 gen_reserved_instruction(ctx
);
12929 gen_shift_imm(ctx
, OPC_SRL
, rx
, ry
, sa
);
12932 gen_shift_imm(ctx
, OPC_SRA
, rx
, ry
, sa
);
12936 #if defined(TARGET_MIPS64)
12938 check_insn(ctx
, ISA_MIPS3
);
12939 check_mips_64(ctx
);
12940 gen_ld(ctx
, OPC_LD
, ry
, rx
, offset
);
12944 imm
= ctx
->opcode
& 0xf;
12945 imm
= imm
| ((ctx
->opcode
>> 20) & 0x7f) << 4;
12946 imm
= imm
| ((ctx
->opcode
>> 16) & 0xf) << 11;
12947 imm
= (int16_t) (imm
<< 1) >> 1;
12948 if ((ctx
->opcode
>> 4) & 0x1) {
12949 #if defined(TARGET_MIPS64)
12950 check_mips_64(ctx
);
12951 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, rx
, imm
);
12953 gen_reserved_instruction(ctx
);
12956 gen_arith_imm(ctx
, OPC_ADDIU
, ry
, rx
, imm
);
12959 case M16_OPC_ADDIU8
:
12960 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, rx
, imm
);
12963 gen_slt_imm(ctx
, OPC_SLTI
, 24, rx
, imm
);
12965 case M16_OPC_SLTIU
:
12966 gen_slt_imm(ctx
, OPC_SLTIU
, 24, rx
, imm
);
12971 gen_compute_branch(ctx
, OPC_BEQ
, 4, 24, 0, offset
<< 1, 0);
12974 gen_compute_branch(ctx
, OPC_BNE
, 4, 24, 0, offset
<< 1, 0);
12977 gen_st(ctx
, OPC_SW
, 31, 29, imm
);
12980 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, imm
);
12983 check_insn(ctx
, ISA_MIPS_R1
);
12985 int xsregs
= (ctx
->opcode
>> 24) & 0x7;
12986 int aregs
= (ctx
->opcode
>> 16) & 0xf;
12987 int do_ra
= (ctx
->opcode
>> 6) & 0x1;
12988 int do_s0
= (ctx
->opcode
>> 5) & 0x1;
12989 int do_s1
= (ctx
->opcode
>> 4) & 0x1;
12990 int framesize
= (((ctx
->opcode
>> 20) & 0xf) << 4
12991 | (ctx
->opcode
& 0xf)) << 3;
12993 if (ctx
->opcode
& (1 << 7)) {
12994 gen_mips16_save(ctx
, xsregs
, aregs
,
12995 do_ra
, do_s0
, do_s1
,
12998 gen_mips16_restore(ctx
, xsregs
, aregs
,
12999 do_ra
, do_s0
, do_s1
,
13005 gen_reserved_instruction(ctx
);
13010 tcg_gen_movi_tl(cpu_gpr
[rx
], (uint16_t) imm
);
13013 tcg_gen_xori_tl(cpu_gpr
[24], cpu_gpr
[rx
], (uint16_t) imm
);
13015 #if defined(TARGET_MIPS64)
13017 check_insn(ctx
, ISA_MIPS3
);
13018 check_mips_64(ctx
);
13019 gen_st(ctx
, OPC_SD
, ry
, rx
, offset
);
13023 gen_ld(ctx
, OPC_LB
, ry
, rx
, offset
);
13026 gen_ld(ctx
, OPC_LH
, ry
, rx
, offset
);
13029 gen_ld(ctx
, OPC_LW
, rx
, 29, offset
);
13032 gen_ld(ctx
, OPC_LW
, ry
, rx
, offset
);
13035 gen_ld(ctx
, OPC_LBU
, ry
, rx
, offset
);
13038 gen_ld(ctx
, OPC_LHU
, ry
, rx
, offset
);
13041 gen_ld(ctx
, OPC_LWPC
, rx
, 0, offset
);
13043 #if defined(TARGET_MIPS64)
13045 check_insn(ctx
, ISA_MIPS3
);
13046 check_mips_64(ctx
);
13047 gen_ld(ctx
, OPC_LWU
, ry
, rx
, offset
);
13051 gen_st(ctx
, OPC_SB
, ry
, rx
, offset
);
13054 gen_st(ctx
, OPC_SH
, ry
, rx
, offset
);
13057 gen_st(ctx
, OPC_SW
, rx
, 29, offset
);
13060 gen_st(ctx
, OPC_SW
, ry
, rx
, offset
);
13062 #if defined(TARGET_MIPS64)
13064 decode_i64_mips16(ctx
, ry
, funct
, offset
, 1);
13068 gen_reserved_instruction(ctx
);
13075 static inline bool is_uhi(int sdbbp_code
)
13077 #ifdef CONFIG_USER_ONLY
13080 return semihosting_enabled() && sdbbp_code
== 1;
13084 #ifdef CONFIG_USER_ONLY
13085 /* The above should dead-code away any calls to this..*/
13086 static inline void gen_helper_do_semihosting(void *env
)
13088 g_assert_not_reached();
13092 static int decode_mips16_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
13096 int op
, cnvt_op
, op1
, offset
;
13100 op
= (ctx
->opcode
>> 11) & 0x1f;
13101 sa
= (ctx
->opcode
>> 2) & 0x7;
13102 sa
= sa
== 0 ? 8 : sa
;
13103 rx
= xlat((ctx
->opcode
>> 8) & 0x7);
13104 cnvt_op
= (ctx
->opcode
>> 5) & 0x7;
13105 ry
= xlat((ctx
->opcode
>> 5) & 0x7);
13106 op1
= offset
= ctx
->opcode
& 0x1f;
13111 case M16_OPC_ADDIUSP
:
13113 int16_t imm
= ((uint8_t) ctx
->opcode
) << 2;
13115 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 29, imm
);
13118 case M16_OPC_ADDIUPC
:
13119 gen_addiupc(ctx
, rx
, ((uint8_t) ctx
->opcode
) << 2, 0, 0);
13122 offset
= (ctx
->opcode
& 0x7ff) << 1;
13123 offset
= (int16_t)(offset
<< 4) >> 4;
13124 gen_compute_branch(ctx
, OPC_BEQ
, 2, 0, 0, offset
, 0);
13125 /* No delay slot, so just process as a normal instruction */
13128 offset
= translator_lduw(env
, ctx
->base
.pc_next
+ 2);
13129 offset
= (((ctx
->opcode
& 0x1f) << 21)
13130 | ((ctx
->opcode
>> 5) & 0x1f) << 16
13132 op
= ((ctx
->opcode
>> 10) & 0x1) ? OPC_JALX
: OPC_JAL
;
13133 gen_compute_branch(ctx
, op
, 4, rx
, ry
, offset
, 2);
13137 gen_compute_branch(ctx
, OPC_BEQ
, 2, rx
, 0,
13138 ((int8_t)ctx
->opcode
) << 1, 0);
13139 /* No delay slot, so just process as a normal instruction */
13141 case M16_OPC_BNEQZ
:
13142 gen_compute_branch(ctx
, OPC_BNE
, 2, rx
, 0,
13143 ((int8_t)ctx
->opcode
) << 1, 0);
13144 /* No delay slot, so just process as a normal instruction */
13146 case M16_OPC_SHIFT
:
13147 switch (ctx
->opcode
& 0x3) {
13149 gen_shift_imm(ctx
, OPC_SLL
, rx
, ry
, sa
);
13152 #if defined(TARGET_MIPS64)
13153 check_insn(ctx
, ISA_MIPS3
);
13154 check_mips_64(ctx
);
13155 gen_shift_imm(ctx
, OPC_DSLL
, rx
, ry
, sa
);
13157 gen_reserved_instruction(ctx
);
13161 gen_shift_imm(ctx
, OPC_SRL
, rx
, ry
, sa
);
13164 gen_shift_imm(ctx
, OPC_SRA
, rx
, ry
, sa
);
13168 #if defined(TARGET_MIPS64)
13170 check_insn(ctx
, ISA_MIPS3
);
13171 check_mips_64(ctx
);
13172 gen_ld(ctx
, OPC_LD
, ry
, rx
, offset
<< 3);
13177 int16_t imm
= (int8_t)((ctx
->opcode
& 0xf) << 4) >> 4;
13179 if ((ctx
->opcode
>> 4) & 1) {
13180 #if defined(TARGET_MIPS64)
13181 check_insn(ctx
, ISA_MIPS3
);
13182 check_mips_64(ctx
);
13183 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, rx
, imm
);
13185 gen_reserved_instruction(ctx
);
13188 gen_arith_imm(ctx
, OPC_ADDIU
, ry
, rx
, imm
);
13192 case M16_OPC_ADDIU8
:
13194 int16_t imm
= (int8_t) ctx
->opcode
;
13196 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, rx
, imm
);
13201 int16_t imm
= (uint8_t) ctx
->opcode
;
13202 gen_slt_imm(ctx
, OPC_SLTI
, 24, rx
, imm
);
13205 case M16_OPC_SLTIU
:
13207 int16_t imm
= (uint8_t) ctx
->opcode
;
13208 gen_slt_imm(ctx
, OPC_SLTIU
, 24, rx
, imm
);
13215 funct
= (ctx
->opcode
>> 8) & 0x7;
13218 gen_compute_branch(ctx
, OPC_BEQ
, 2, 24, 0,
13219 ((int8_t)ctx
->opcode
) << 1, 0);
13222 gen_compute_branch(ctx
, OPC_BNE
, 2, 24, 0,
13223 ((int8_t)ctx
->opcode
) << 1, 0);
13226 gen_st(ctx
, OPC_SW
, 31, 29, (ctx
->opcode
& 0xff) << 2);
13229 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29,
13230 ((int8_t)ctx
->opcode
) << 3);
13233 check_insn(ctx
, ISA_MIPS_R1
);
13235 int do_ra
= ctx
->opcode
& (1 << 6);
13236 int do_s0
= ctx
->opcode
& (1 << 5);
13237 int do_s1
= ctx
->opcode
& (1 << 4);
13238 int framesize
= ctx
->opcode
& 0xf;
13240 if (framesize
== 0) {
13243 framesize
= framesize
<< 3;
13246 if (ctx
->opcode
& (1 << 7)) {
13247 gen_mips16_save(ctx
, 0, 0,
13248 do_ra
, do_s0
, do_s1
, framesize
);
13250 gen_mips16_restore(ctx
, 0, 0,
13251 do_ra
, do_s0
, do_s1
, framesize
);
13257 int rz
= xlat(ctx
->opcode
& 0x7);
13259 reg32
= (((ctx
->opcode
>> 3) & 0x3) << 3) |
13260 ((ctx
->opcode
>> 5) & 0x7);
13261 gen_arith(ctx
, OPC_ADDU
, reg32
, rz
, 0);
13265 reg32
= ctx
->opcode
& 0x1f;
13266 gen_arith(ctx
, OPC_ADDU
, ry
, reg32
, 0);
13269 gen_reserved_instruction(ctx
);
13276 int16_t imm
= (uint8_t) ctx
->opcode
;
13278 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 0, imm
);
13283 int16_t imm
= (uint8_t) ctx
->opcode
;
13284 gen_logic_imm(ctx
, OPC_XORI
, 24, rx
, imm
);
13287 #if defined(TARGET_MIPS64)
13289 check_insn(ctx
, ISA_MIPS3
);
13290 check_mips_64(ctx
);
13291 gen_st(ctx
, OPC_SD
, ry
, rx
, offset
<< 3);
13295 gen_ld(ctx
, OPC_LB
, ry
, rx
, offset
);
13298 gen_ld(ctx
, OPC_LH
, ry
, rx
, offset
<< 1);
13301 gen_ld(ctx
, OPC_LW
, rx
, 29, ((uint8_t)ctx
->opcode
) << 2);
13304 gen_ld(ctx
, OPC_LW
, ry
, rx
, offset
<< 2);
13307 gen_ld(ctx
, OPC_LBU
, ry
, rx
, offset
);
13310 gen_ld(ctx
, OPC_LHU
, ry
, rx
, offset
<< 1);
13313 gen_ld(ctx
, OPC_LWPC
, rx
, 0, ((uint8_t)ctx
->opcode
) << 2);
13315 #if defined(TARGET_MIPS64)
13317 check_insn(ctx
, ISA_MIPS3
);
13318 check_mips_64(ctx
);
13319 gen_ld(ctx
, OPC_LWU
, ry
, rx
, offset
<< 2);
13323 gen_st(ctx
, OPC_SB
, ry
, rx
, offset
);
13326 gen_st(ctx
, OPC_SH
, ry
, rx
, offset
<< 1);
13329 gen_st(ctx
, OPC_SW
, rx
, 29, ((uint8_t)ctx
->opcode
) << 2);
13332 gen_st(ctx
, OPC_SW
, ry
, rx
, offset
<< 2);
13336 int rz
= xlat((ctx
->opcode
>> 2) & 0x7);
13339 switch (ctx
->opcode
& 0x3) {
13341 mips32_op
= OPC_ADDU
;
13344 mips32_op
= OPC_SUBU
;
13346 #if defined(TARGET_MIPS64)
13348 mips32_op
= OPC_DADDU
;
13349 check_insn(ctx
, ISA_MIPS3
);
13350 check_mips_64(ctx
);
13353 mips32_op
= OPC_DSUBU
;
13354 check_insn(ctx
, ISA_MIPS3
);
13355 check_mips_64(ctx
);
13359 gen_reserved_instruction(ctx
);
13363 gen_arith(ctx
, mips32_op
, rz
, rx
, ry
);
13372 int nd
= (ctx
->opcode
>> 7) & 0x1;
13373 int link
= (ctx
->opcode
>> 6) & 0x1;
13374 int ra
= (ctx
->opcode
>> 5) & 0x1;
13377 check_insn(ctx
, ISA_MIPS_R1
);
13386 gen_compute_branch(ctx
, op
, 2, ra
? 31 : rx
, 31, 0,
13391 if (is_uhi(extract32(ctx
->opcode
, 5, 6))) {
13392 gen_helper_do_semihosting(cpu_env
);
13395 * XXX: not clear which exception should be raised
13396 * when in debug mode...
13398 check_insn(ctx
, ISA_MIPS_R1
);
13399 generate_exception_end(ctx
, EXCP_DBp
);
13403 gen_slt(ctx
, OPC_SLT
, 24, rx
, ry
);
13406 gen_slt(ctx
, OPC_SLTU
, 24, rx
, ry
);
13409 generate_exception_end(ctx
, EXCP_BREAK
);
13412 gen_shift(ctx
, OPC_SLLV
, ry
, rx
, ry
);
13415 gen_shift(ctx
, OPC_SRLV
, ry
, rx
, ry
);
13418 gen_shift(ctx
, OPC_SRAV
, ry
, rx
, ry
);
13420 #if defined(TARGET_MIPS64)
13422 check_insn(ctx
, ISA_MIPS3
);
13423 check_mips_64(ctx
);
13424 gen_shift_imm(ctx
, OPC_DSRL
, ry
, ry
, sa
);
13428 gen_logic(ctx
, OPC_XOR
, 24, rx
, ry
);
13431 gen_arith(ctx
, OPC_SUBU
, rx
, 0, ry
);
13434 gen_logic(ctx
, OPC_AND
, rx
, rx
, ry
);
13437 gen_logic(ctx
, OPC_OR
, rx
, rx
, ry
);
13440 gen_logic(ctx
, OPC_XOR
, rx
, rx
, ry
);
13443 gen_logic(ctx
, OPC_NOR
, rx
, ry
, 0);
13446 gen_HILO(ctx
, OPC_MFHI
, 0, rx
);
13449 check_insn(ctx
, ISA_MIPS_R1
);
13451 case RR_RY_CNVT_ZEB
:
13452 tcg_gen_ext8u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
13454 case RR_RY_CNVT_ZEH
:
13455 tcg_gen_ext16u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
13457 case RR_RY_CNVT_SEB
:
13458 tcg_gen_ext8s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
13460 case RR_RY_CNVT_SEH
:
13461 tcg_gen_ext16s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
13463 #if defined(TARGET_MIPS64)
13464 case RR_RY_CNVT_ZEW
:
13465 check_insn(ctx
, ISA_MIPS_R1
);
13466 check_mips_64(ctx
);
13467 tcg_gen_ext32u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
13469 case RR_RY_CNVT_SEW
:
13470 check_insn(ctx
, ISA_MIPS_R1
);
13471 check_mips_64(ctx
);
13472 tcg_gen_ext32s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
13476 gen_reserved_instruction(ctx
);
13481 gen_HILO(ctx
, OPC_MFLO
, 0, rx
);
13483 #if defined(TARGET_MIPS64)
13485 check_insn(ctx
, ISA_MIPS3
);
13486 check_mips_64(ctx
);
13487 gen_shift_imm(ctx
, OPC_DSRA
, ry
, ry
, sa
);
13490 check_insn(ctx
, ISA_MIPS3
);
13491 check_mips_64(ctx
);
13492 gen_shift(ctx
, OPC_DSLLV
, ry
, rx
, ry
);
13495 check_insn(ctx
, ISA_MIPS3
);
13496 check_mips_64(ctx
);
13497 gen_shift(ctx
, OPC_DSRLV
, ry
, rx
, ry
);
13500 check_insn(ctx
, ISA_MIPS3
);
13501 check_mips_64(ctx
);
13502 gen_shift(ctx
, OPC_DSRAV
, ry
, rx
, ry
);
13506 gen_muldiv(ctx
, OPC_MULT
, 0, rx
, ry
);
13509 gen_muldiv(ctx
, OPC_MULTU
, 0, rx
, ry
);
13512 gen_muldiv(ctx
, OPC_DIV
, 0, rx
, ry
);
13515 gen_muldiv(ctx
, OPC_DIVU
, 0, rx
, ry
);
13517 #if defined(TARGET_MIPS64)
13519 check_insn(ctx
, ISA_MIPS3
);
13520 check_mips_64(ctx
);
13521 gen_muldiv(ctx
, OPC_DMULT
, 0, rx
, ry
);
13524 check_insn(ctx
, ISA_MIPS3
);
13525 check_mips_64(ctx
);
13526 gen_muldiv(ctx
, OPC_DMULTU
, 0, rx
, ry
);
13529 check_insn(ctx
, ISA_MIPS3
);
13530 check_mips_64(ctx
);
13531 gen_muldiv(ctx
, OPC_DDIV
, 0, rx
, ry
);
13534 check_insn(ctx
, ISA_MIPS3
);
13535 check_mips_64(ctx
);
13536 gen_muldiv(ctx
, OPC_DDIVU
, 0, rx
, ry
);
13540 gen_reserved_instruction(ctx
);
13544 case M16_OPC_EXTEND
:
13545 decode_extended_mips16_opc(env
, ctx
);
13548 #if defined(TARGET_MIPS64)
13550 funct
= (ctx
->opcode
>> 8) & 0x7;
13551 decode_i64_mips16(ctx
, ry
, funct
, offset
, 0);
13555 gen_reserved_instruction(ctx
);
13562 /* microMIPS extension to MIPS32/MIPS64 */
13565 * microMIPS32/microMIPS64 major opcodes
13567 * 1. MIPS Architecture for Programmers Volume II-B:
13568 * The microMIPS32 Instruction Set (Revision 3.05)
13570 * Table 6.2 microMIPS32 Encoding of Major Opcode Field
13572 * 2. MIPS Architecture For Programmers Volume II-A:
13573 * The MIPS64 Instruction Set (Revision 3.51)
13603 POOL32S
= 0x16, /* MIPS64 */
13604 DADDIU32
= 0x17, /* MIPS64 */
13633 /* 0x29 is reserved */
13646 /* 0x31 is reserved */
13659 SD32
= 0x36, /* MIPS64 */
13660 LD32
= 0x37, /* MIPS64 */
13662 /* 0x39 is reserved */
13678 /* PCREL Instructions perform PC-Relative address calculation. bits 20..16 */
13700 /* POOL32A encoding of minor opcode field */
13704 * These opcodes are distinguished only by bits 9..6; those bits are
13705 * what are recorded below.
13743 /* The following can be distinguished by their lower 6 bits. */
13753 /* POOL32AXF encoding of minor opcode field extension */
13756 * 1. MIPS Architecture for Programmers Volume II-B:
13757 * The microMIPS32 Instruction Set (Revision 3.05)
13759 * Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
13761 * 2. MIPS Architecture for Programmers VolumeIV-e:
13762 * The MIPS DSP Application-Specific Extension
13763 * to the microMIPS32 Architecture (Revision 2.34)
13765 * Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
13780 /* begin of microMIPS32 DSP */
13782 /* bits 13..12 for 0x01 */
13788 /* bits 13..12 for 0x2a */
13794 /* bits 13..12 for 0x32 */
13798 /* end of microMIPS32 DSP */
13800 /* bits 15..12 for 0x2c */
13817 /* bits 15..12 for 0x34 */
13825 /* bits 15..12 for 0x3c */
13827 JR
= 0x0, /* alias */
13835 /* bits 15..12 for 0x05 */
13839 /* bits 15..12 for 0x0d */
13851 /* bits 15..12 for 0x15 */
13857 /* bits 15..12 for 0x1d */
13861 /* bits 15..12 for 0x2d */
13866 /* bits 15..12 for 0x35 */
13873 /* POOL32B encoding of minor opcode field (bits 15..12) */
13889 /* POOL32C encoding of minor opcode field (bits 15..12) */
13910 /* POOL32C LD-EVA encoding of minor opcode field (bits 11..9) */
13923 /* POOL32C ST-EVA encoding of minor opcode field (bits 11..9) */
13936 /* POOL32F encoding of minor opcode field (bits 5..0) */
13939 /* These are the bit 7..6 values */
13948 /* These are the bit 8..6 values */
13973 MOVZ_FMT_05
= 0x05,
14007 CABS_COND_FMT
= 0x1c, /* MIPS3D */
14014 /* POOL32Fxf encoding of minor opcode extension field */
14052 /* POOL32I encoding of minor opcode field (bits 25..21) */
14082 /* These overlap and are distinguished by bit16 of the instruction */
14091 /* POOL16A encoding of minor opcode field */
14098 /* POOL16B encoding of minor opcode field */
14105 /* POOL16C encoding of minor opcode field */
14125 /* R6 POOL16C encoding of minor opcode field (bits 0..5) */
14149 /* POOL16D encoding of minor opcode field */
14156 /* POOL16E encoding of minor opcode field */
14163 static int mmreg(int r
)
14165 static const int map
[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
14170 /* Used for 16-bit store instructions. */
14171 static int mmreg2(int r
)
14173 static const int map
[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
14178 #define uMIPS_RD(op) ((op >> 7) & 0x7)
14179 #define uMIPS_RS(op) ((op >> 4) & 0x7)
14180 #define uMIPS_RS2(op) uMIPS_RS(op)
14181 #define uMIPS_RS1(op) ((op >> 1) & 0x7)
14182 #define uMIPS_RD5(op) ((op >> 5) & 0x1f)
14183 #define uMIPS_RS5(op) (op & 0x1f)
14185 /* Signed immediate */
14186 #define SIMM(op, start, width) \
14187 ((int32_t)(((op >> start) & ((~0U) >> (32 - width))) \
14190 /* Zero-extended immediate */
14191 #define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32 - width)))
14193 static void gen_addiur1sp(DisasContext
*ctx
)
14195 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
14197 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, 29, ((ctx
->opcode
>> 1) & 0x3f) << 2);
14200 static void gen_addiur2(DisasContext
*ctx
)
14202 static const int decoded_imm
[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
14203 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
14204 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
14206 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, rs
, decoded_imm
[ZIMM(ctx
->opcode
, 1, 3)]);
14209 static void gen_addiusp(DisasContext
*ctx
)
14211 int encoded
= ZIMM(ctx
->opcode
, 1, 9);
14214 if (encoded
<= 1) {
14215 decoded
= 256 + encoded
;
14216 } else if (encoded
<= 255) {
14218 } else if (encoded
<= 509) {
14219 decoded
= encoded
- 512;
14221 decoded
= encoded
- 768;
14224 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, decoded
<< 2);
14227 static void gen_addius5(DisasContext
*ctx
)
14229 int imm
= SIMM(ctx
->opcode
, 1, 4);
14230 int rd
= (ctx
->opcode
>> 5) & 0x1f;
14232 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, rd
, imm
);
14235 static void gen_andi16(DisasContext
*ctx
)
14237 static const int decoded_imm
[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
14238 31, 32, 63, 64, 255, 32768, 65535 };
14239 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
14240 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
14241 int encoded
= ZIMM(ctx
->opcode
, 0, 4);
14243 gen_logic_imm(ctx
, OPC_ANDI
, rd
, rs
, decoded_imm
[encoded
]);
14246 static void gen_ldst_multiple(DisasContext
*ctx
, uint32_t opc
, int reglist
,
14247 int base
, int16_t offset
)
14252 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
14253 gen_reserved_instruction(ctx
);
14257 t0
= tcg_temp_new();
14259 gen_base_offset_addr(ctx
, t0
, base
, offset
);
14261 t1
= tcg_const_tl(reglist
);
14262 t2
= tcg_const_i32(ctx
->mem_idx
);
14264 save_cpu_state(ctx
, 1);
14267 gen_helper_lwm(cpu_env
, t0
, t1
, t2
);
14270 gen_helper_swm(cpu_env
, t0
, t1
, t2
);
14272 #ifdef TARGET_MIPS64
14274 gen_helper_ldm(cpu_env
, t0
, t1
, t2
);
14277 gen_helper_sdm(cpu_env
, t0
, t1
, t2
);
14283 tcg_temp_free_i32(t2
);
14287 static void gen_pool16c_insn(DisasContext
*ctx
)
14289 int rd
= mmreg((ctx
->opcode
>> 3) & 0x7);
14290 int rs
= mmreg(ctx
->opcode
& 0x7);
14292 switch (((ctx
->opcode
) >> 4) & 0x3f) {
14297 gen_logic(ctx
, OPC_NOR
, rd
, rs
, 0);
14303 gen_logic(ctx
, OPC_XOR
, rd
, rd
, rs
);
14309 gen_logic(ctx
, OPC_AND
, rd
, rd
, rs
);
14315 gen_logic(ctx
, OPC_OR
, rd
, rd
, rs
);
14322 static const int lwm_convert
[] = { 0x11, 0x12, 0x13, 0x14 };
14323 int offset
= ZIMM(ctx
->opcode
, 0, 4);
14325 gen_ldst_multiple(ctx
, LWM32
, lwm_convert
[(ctx
->opcode
>> 4) & 0x3],
14334 static const int swm_convert
[] = { 0x11, 0x12, 0x13, 0x14 };
14335 int offset
= ZIMM(ctx
->opcode
, 0, 4);
14337 gen_ldst_multiple(ctx
, SWM32
, swm_convert
[(ctx
->opcode
>> 4) & 0x3],
14344 int reg
= ctx
->opcode
& 0x1f;
14346 gen_compute_branch(ctx
, OPC_JR
, 2, reg
, 0, 0, 4);
14352 int reg
= ctx
->opcode
& 0x1f;
14353 gen_compute_branch(ctx
, OPC_JR
, 2, reg
, 0, 0, 0);
14355 * Let normal delay slot handling in our caller take us
14356 * to the branch target.
14362 gen_compute_branch(ctx
, OPC_JALR
, 2, ctx
->opcode
& 0x1f, 31, 0, 4);
14363 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
14367 gen_compute_branch(ctx
, OPC_JALR
, 2, ctx
->opcode
& 0x1f, 31, 0, 2);
14368 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
14372 gen_HILO(ctx
, OPC_MFHI
, 0, uMIPS_RS5(ctx
->opcode
));
14376 gen_HILO(ctx
, OPC_MFLO
, 0, uMIPS_RS5(ctx
->opcode
));
14379 generate_exception_end(ctx
, EXCP_BREAK
);
14382 if (is_uhi(extract32(ctx
->opcode
, 0, 4))) {
14383 gen_helper_do_semihosting(cpu_env
);
14386 * XXX: not clear which exception should be raised
14387 * when in debug mode...
14389 check_insn(ctx
, ISA_MIPS_R1
);
14390 generate_exception_end(ctx
, EXCP_DBp
);
14393 case JRADDIUSP
+ 0:
14394 case JRADDIUSP
+ 1:
14396 int imm
= ZIMM(ctx
->opcode
, 0, 5);
14397 gen_compute_branch(ctx
, OPC_JR
, 2, 31, 0, 0, 0);
14398 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, imm
<< 2);
14400 * Let normal delay slot handling in our caller take us
14401 * to the branch target.
14406 gen_reserved_instruction(ctx
);
14411 static inline void gen_movep(DisasContext
*ctx
, int enc_dest
, int enc_rt
,
14415 static const int rd_enc
[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
14416 static const int re_enc
[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
14417 static const int rs_rt_enc
[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
14419 rd
= rd_enc
[enc_dest
];
14420 re
= re_enc
[enc_dest
];
14421 gen_load_gpr(cpu_gpr
[rd
], rs_rt_enc
[enc_rs
]);
14422 gen_load_gpr(cpu_gpr
[re
], rs_rt_enc
[enc_rt
]);
14425 static void gen_pool16c_r6_insn(DisasContext
*ctx
)
14427 int rt
= mmreg((ctx
->opcode
>> 7) & 0x7);
14428 int rs
= mmreg((ctx
->opcode
>> 4) & 0x7);
14430 switch (ctx
->opcode
& 0xf) {
14432 gen_logic(ctx
, OPC_NOR
, rt
, rs
, 0);
14435 gen_logic(ctx
, OPC_AND
, rt
, rt
, rs
);
14439 int lwm_converted
= 0x11 + extract32(ctx
->opcode
, 8, 2);
14440 int offset
= extract32(ctx
->opcode
, 4, 4);
14441 gen_ldst_multiple(ctx
, LWM32
, lwm_converted
, 29, offset
<< 2);
14444 case R6_JRC16
: /* JRCADDIUSP */
14445 if ((ctx
->opcode
>> 4) & 1) {
14447 int imm
= extract32(ctx
->opcode
, 5, 5);
14448 gen_compute_branch(ctx
, OPC_JR
, 2, 31, 0, 0, 0);
14449 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, imm
<< 2);
14452 rs
= extract32(ctx
->opcode
, 5, 5);
14453 gen_compute_branch(ctx
, OPC_JR
, 2, rs
, 0, 0, 0);
14465 int enc_dest
= uMIPS_RD(ctx
->opcode
);
14466 int enc_rt
= uMIPS_RS2(ctx
->opcode
);
14467 int enc_rs
= (ctx
->opcode
& 3) | ((ctx
->opcode
>> 1) & 4);
14468 gen_movep(ctx
, enc_dest
, enc_rt
, enc_rs
);
14472 gen_logic(ctx
, OPC_XOR
, rt
, rt
, rs
);
14475 gen_logic(ctx
, OPC_OR
, rt
, rt
, rs
);
14479 int swm_converted
= 0x11 + extract32(ctx
->opcode
, 8, 2);
14480 int offset
= extract32(ctx
->opcode
, 4, 4);
14481 gen_ldst_multiple(ctx
, SWM32
, swm_converted
, 29, offset
<< 2);
14484 case JALRC16
: /* BREAK16, SDBBP16 */
14485 switch (ctx
->opcode
& 0x3f) {
14487 case JALRC16
+ 0x20:
14489 gen_compute_branch(ctx
, OPC_JALR
, 2, (ctx
->opcode
>> 5) & 0x1f,
14494 generate_exception(ctx
, EXCP_BREAK
);
14498 if (is_uhi(extract32(ctx
->opcode
, 6, 4))) {
14499 gen_helper_do_semihosting(cpu_env
);
14501 if (ctx
->hflags
& MIPS_HFLAG_SBRI
) {
14502 generate_exception(ctx
, EXCP_RI
);
14504 generate_exception(ctx
, EXCP_DBp
);
14511 generate_exception(ctx
, EXCP_RI
);
14516 static void gen_ldxs(DisasContext
*ctx
, int base
, int index
, int rd
)
14518 TCGv t0
= tcg_temp_new();
14519 TCGv t1
= tcg_temp_new();
14521 gen_load_gpr(t0
, base
);
14524 gen_load_gpr(t1
, index
);
14525 tcg_gen_shli_tl(t1
, t1
, 2);
14526 gen_op_addr_add(ctx
, t0
, t1
, t0
);
14529 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TESL
);
14530 gen_store_gpr(t1
, rd
);
14536 static void gen_ldst_pair(DisasContext
*ctx
, uint32_t opc
, int rd
,
14537 int base
, int16_t offset
)
14541 if (ctx
->hflags
& MIPS_HFLAG_BMASK
|| rd
== 31) {
14542 gen_reserved_instruction(ctx
);
14546 t0
= tcg_temp_new();
14547 t1
= tcg_temp_new();
14549 gen_base_offset_addr(ctx
, t0
, base
, offset
);
14554 gen_reserved_instruction(ctx
);
14557 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TESL
);
14558 gen_store_gpr(t1
, rd
);
14559 tcg_gen_movi_tl(t1
, 4);
14560 gen_op_addr_add(ctx
, t0
, t0
, t1
);
14561 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TESL
);
14562 gen_store_gpr(t1
, rd
+ 1);
14565 gen_load_gpr(t1
, rd
);
14566 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
14567 tcg_gen_movi_tl(t1
, 4);
14568 gen_op_addr_add(ctx
, t0
, t0
, t1
);
14569 gen_load_gpr(t1
, rd
+ 1);
14570 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
14572 #ifdef TARGET_MIPS64
14575 gen_reserved_instruction(ctx
);
14578 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
14579 gen_store_gpr(t1
, rd
);
14580 tcg_gen_movi_tl(t1
, 8);
14581 gen_op_addr_add(ctx
, t0
, t0
, t1
);
14582 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
14583 gen_store_gpr(t1
, rd
+ 1);
14586 gen_load_gpr(t1
, rd
);
14587 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
14588 tcg_gen_movi_tl(t1
, 8);
14589 gen_op_addr_add(ctx
, t0
, t0
, t1
);
14590 gen_load_gpr(t1
, rd
+ 1);
14591 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
14599 static void gen_sync(int stype
)
14601 TCGBar tcg_mo
= TCG_BAR_SC
;
14604 case 0x4: /* SYNC_WMB */
14605 tcg_mo
|= TCG_MO_ST_ST
;
14607 case 0x10: /* SYNC_MB */
14608 tcg_mo
|= TCG_MO_ALL
;
14610 case 0x11: /* SYNC_ACQUIRE */
14611 tcg_mo
|= TCG_MO_LD_LD
| TCG_MO_LD_ST
;
14613 case 0x12: /* SYNC_RELEASE */
14614 tcg_mo
|= TCG_MO_ST_ST
| TCG_MO_LD_ST
;
14616 case 0x13: /* SYNC_RMB */
14617 tcg_mo
|= TCG_MO_LD_LD
;
14620 tcg_mo
|= TCG_MO_ALL
;
14624 tcg_gen_mb(tcg_mo
);
14627 static void gen_pool32axf(CPUMIPSState
*env
, DisasContext
*ctx
, int rt
, int rs
)
14629 int extension
= (ctx
->opcode
>> 6) & 0x3f;
14630 int minor
= (ctx
->opcode
>> 12) & 0xf;
14631 uint32_t mips32_op
;
14633 switch (extension
) {
14635 mips32_op
= OPC_TEQ
;
14638 mips32_op
= OPC_TGE
;
14641 mips32_op
= OPC_TGEU
;
14644 mips32_op
= OPC_TLT
;
14647 mips32_op
= OPC_TLTU
;
14650 mips32_op
= OPC_TNE
;
14652 gen_trap(ctx
, mips32_op
, rs
, rt
, -1);
14654 #ifndef CONFIG_USER_ONLY
14657 check_cp0_enabled(ctx
);
14659 /* Treat as NOP. */
14662 gen_mfc0(ctx
, cpu_gpr
[rt
], rs
, (ctx
->opcode
>> 11) & 0x7);
14666 check_cp0_enabled(ctx
);
14668 TCGv t0
= tcg_temp_new();
14670 gen_load_gpr(t0
, rt
);
14671 gen_mtc0(ctx
, t0
, rs
, (ctx
->opcode
>> 11) & 0x7);
14677 switch (minor
& 3) {
14679 gen_muldiv(ctx
, OPC_MADD
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
14682 gen_muldiv(ctx
, OPC_MADDU
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
14685 gen_muldiv(ctx
, OPC_MSUB
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
14688 gen_muldiv(ctx
, OPC_MSUBU
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
14691 goto pool32axf_invalid
;
14695 switch (minor
& 3) {
14697 gen_muldiv(ctx
, OPC_MULT
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
14700 gen_muldiv(ctx
, OPC_MULTU
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
14703 goto pool32axf_invalid
;
14709 check_insn(ctx
, ISA_MIPS_R6
);
14710 gen_bitswap(ctx
, OPC_BITSWAP
, rs
, rt
);
14713 gen_bshfl(ctx
, OPC_SEB
, rs
, rt
);
14716 gen_bshfl(ctx
, OPC_SEH
, rs
, rt
);
14719 mips32_op
= OPC_CLO
;
14722 mips32_op
= OPC_CLZ
;
14724 check_insn(ctx
, ISA_MIPS_R1
);
14725 gen_cl(ctx
, mips32_op
, rt
, rs
);
14728 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
14729 gen_rdhwr(ctx
, rt
, rs
, 0);
14732 gen_bshfl(ctx
, OPC_WSBH
, rs
, rt
);
14735 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
14736 mips32_op
= OPC_MULT
;
14739 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
14740 mips32_op
= OPC_MULTU
;
14743 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
14744 mips32_op
= OPC_DIV
;
14747 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
14748 mips32_op
= OPC_DIVU
;
14751 check_insn(ctx
, ISA_MIPS_R1
);
14752 gen_muldiv(ctx
, mips32_op
, 0, rs
, rt
);
14755 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
14756 mips32_op
= OPC_MADD
;
14759 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
14760 mips32_op
= OPC_MADDU
;
14763 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
14764 mips32_op
= OPC_MSUB
;
14767 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
14768 mips32_op
= OPC_MSUBU
;
14770 check_insn(ctx
, ISA_MIPS_R1
);
14771 gen_muldiv(ctx
, mips32_op
, 0, rs
, rt
);
14774 goto pool32axf_invalid
;
14785 generate_exception_err(ctx
, EXCP_CpU
, 2);
14788 goto pool32axf_invalid
;
14793 case JALR
: /* JALRC */
14794 case JALR_HB
: /* JALRC_HB */
14795 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
14796 /* JALRC, JALRC_HB */
14797 gen_compute_branch(ctx
, OPC_JALR
, 4, rs
, rt
, 0, 0);
14799 /* JALR, JALR_HB */
14800 gen_compute_branch(ctx
, OPC_JALR
, 4, rs
, rt
, 0, 4);
14801 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
14806 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
14807 gen_compute_branch(ctx
, OPC_JALR
, 4, rs
, rt
, 0, 2);
14808 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
14811 goto pool32axf_invalid
;
14817 check_cp0_enabled(ctx
);
14818 check_insn(ctx
, ISA_MIPS_R2
);
14819 gen_load_srsgpr(rs
, rt
);
14822 check_cp0_enabled(ctx
);
14823 check_insn(ctx
, ISA_MIPS_R2
);
14824 gen_store_srsgpr(rs
, rt
);
14827 goto pool32axf_invalid
;
14830 #ifndef CONFIG_USER_ONLY
14834 mips32_op
= OPC_TLBP
;
14837 mips32_op
= OPC_TLBR
;
14840 mips32_op
= OPC_TLBWI
;
14843 mips32_op
= OPC_TLBWR
;
14846 mips32_op
= OPC_TLBINV
;
14849 mips32_op
= OPC_TLBINVF
;
14852 mips32_op
= OPC_WAIT
;
14855 mips32_op
= OPC_DERET
;
14858 mips32_op
= OPC_ERET
;
14860 gen_cp0(env
, ctx
, mips32_op
, rt
, rs
);
14863 goto pool32axf_invalid
;
14869 check_cp0_enabled(ctx
);
14871 TCGv t0
= tcg_temp_new();
14873 save_cpu_state(ctx
, 1);
14874 gen_helper_di(t0
, cpu_env
);
14875 gen_store_gpr(t0
, rs
);
14877 * Stop translation as we may have switched the execution
14880 ctx
->base
.is_jmp
= DISAS_STOP
;
14885 check_cp0_enabled(ctx
);
14887 TCGv t0
= tcg_temp_new();
14889 save_cpu_state(ctx
, 1);
14890 gen_helper_ei(t0
, cpu_env
);
14891 gen_store_gpr(t0
, rs
);
14893 * DISAS_STOP isn't sufficient, we need to ensure we break out
14894 * of translated code to check for pending interrupts.
14896 gen_save_pc(ctx
->base
.pc_next
+ 4);
14897 ctx
->base
.is_jmp
= DISAS_EXIT
;
14902 goto pool32axf_invalid
;
14909 gen_sync(extract32(ctx
->opcode
, 16, 5));
14912 generate_exception_end(ctx
, EXCP_SYSCALL
);
14915 if (is_uhi(extract32(ctx
->opcode
, 16, 10))) {
14916 gen_helper_do_semihosting(cpu_env
);
14918 check_insn(ctx
, ISA_MIPS_R1
);
14919 if (ctx
->hflags
& MIPS_HFLAG_SBRI
) {
14920 gen_reserved_instruction(ctx
);
14922 generate_exception_end(ctx
, EXCP_DBp
);
14927 goto pool32axf_invalid
;
14931 switch (minor
& 3) {
14933 gen_HILO(ctx
, OPC_MFHI
, minor
>> 2, rs
);
14936 gen_HILO(ctx
, OPC_MFLO
, minor
>> 2, rs
);
14939 gen_HILO(ctx
, OPC_MTHI
, minor
>> 2, rs
);
14942 gen_HILO(ctx
, OPC_MTLO
, minor
>> 2, rs
);
14945 goto pool32axf_invalid
;
14949 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
14952 gen_HILO(ctx
, OPC_MFHI
, 0, rs
);
14955 gen_HILO(ctx
, OPC_MFLO
, 0, rs
);
14958 gen_HILO(ctx
, OPC_MTHI
, 0, rs
);
14961 gen_HILO(ctx
, OPC_MTLO
, 0, rs
);
14964 goto pool32axf_invalid
;
14969 MIPS_INVAL("pool32axf");
14970 gen_reserved_instruction(ctx
);
14976 * Values for microMIPS fmt field. Variable-width, depending on which
14977 * formats the instruction supports.
14996 static void gen_pool32fxf(DisasContext
*ctx
, int rt
, int rs
)
14998 int extension
= (ctx
->opcode
>> 6) & 0x3ff;
14999 uint32_t mips32_op
;
15001 #define FLOAT_1BIT_FMT(opc, fmt) ((fmt << 8) | opc)
15002 #define FLOAT_2BIT_FMT(opc, fmt) ((fmt << 7) | opc)
15003 #define COND_FLOAT_MOV(opc, cond) ((cond << 7) | opc)
15005 switch (extension
) {
15006 case FLOAT_1BIT_FMT(CFC1
, 0):
15007 mips32_op
= OPC_CFC1
;
15009 case FLOAT_1BIT_FMT(CTC1
, 0):
15010 mips32_op
= OPC_CTC1
;
15012 case FLOAT_1BIT_FMT(MFC1
, 0):
15013 mips32_op
= OPC_MFC1
;
15015 case FLOAT_1BIT_FMT(MTC1
, 0):
15016 mips32_op
= OPC_MTC1
;
15018 case FLOAT_1BIT_FMT(MFHC1
, 0):
15019 mips32_op
= OPC_MFHC1
;
15021 case FLOAT_1BIT_FMT(MTHC1
, 0):
15022 mips32_op
= OPC_MTHC1
;
15024 gen_cp1(ctx
, mips32_op
, rt
, rs
);
15027 /* Reciprocal square root */
15028 case FLOAT_1BIT_FMT(RSQRT_FMT
, FMT_SD_S
):
15029 mips32_op
= OPC_RSQRT_S
;
15031 case FLOAT_1BIT_FMT(RSQRT_FMT
, FMT_SD_D
):
15032 mips32_op
= OPC_RSQRT_D
;
15036 case FLOAT_1BIT_FMT(SQRT_FMT
, FMT_SD_S
):
15037 mips32_op
= OPC_SQRT_S
;
15039 case FLOAT_1BIT_FMT(SQRT_FMT
, FMT_SD_D
):
15040 mips32_op
= OPC_SQRT_D
;
15044 case FLOAT_1BIT_FMT(RECIP_FMT
, FMT_SD_S
):
15045 mips32_op
= OPC_RECIP_S
;
15047 case FLOAT_1BIT_FMT(RECIP_FMT
, FMT_SD_D
):
15048 mips32_op
= OPC_RECIP_D
;
15052 case FLOAT_1BIT_FMT(FLOOR_L
, FMT_SD_S
):
15053 mips32_op
= OPC_FLOOR_L_S
;
15055 case FLOAT_1BIT_FMT(FLOOR_L
, FMT_SD_D
):
15056 mips32_op
= OPC_FLOOR_L_D
;
15058 case FLOAT_1BIT_FMT(FLOOR_W
, FMT_SD_S
):
15059 mips32_op
= OPC_FLOOR_W_S
;
15061 case FLOAT_1BIT_FMT(FLOOR_W
, FMT_SD_D
):
15062 mips32_op
= OPC_FLOOR_W_D
;
15066 case FLOAT_1BIT_FMT(CEIL_L
, FMT_SD_S
):
15067 mips32_op
= OPC_CEIL_L_S
;
15069 case FLOAT_1BIT_FMT(CEIL_L
, FMT_SD_D
):
15070 mips32_op
= OPC_CEIL_L_D
;
15072 case FLOAT_1BIT_FMT(CEIL_W
, FMT_SD_S
):
15073 mips32_op
= OPC_CEIL_W_S
;
15075 case FLOAT_1BIT_FMT(CEIL_W
, FMT_SD_D
):
15076 mips32_op
= OPC_CEIL_W_D
;
15080 case FLOAT_1BIT_FMT(TRUNC_L
, FMT_SD_S
):
15081 mips32_op
= OPC_TRUNC_L_S
;
15083 case FLOAT_1BIT_FMT(TRUNC_L
, FMT_SD_D
):
15084 mips32_op
= OPC_TRUNC_L_D
;
15086 case FLOAT_1BIT_FMT(TRUNC_W
, FMT_SD_S
):
15087 mips32_op
= OPC_TRUNC_W_S
;
15089 case FLOAT_1BIT_FMT(TRUNC_W
, FMT_SD_D
):
15090 mips32_op
= OPC_TRUNC_W_D
;
15094 case FLOAT_1BIT_FMT(ROUND_L
, FMT_SD_S
):
15095 mips32_op
= OPC_ROUND_L_S
;
15097 case FLOAT_1BIT_FMT(ROUND_L
, FMT_SD_D
):
15098 mips32_op
= OPC_ROUND_L_D
;
15100 case FLOAT_1BIT_FMT(ROUND_W
, FMT_SD_S
):
15101 mips32_op
= OPC_ROUND_W_S
;
15103 case FLOAT_1BIT_FMT(ROUND_W
, FMT_SD_D
):
15104 mips32_op
= OPC_ROUND_W_D
;
15107 /* Integer to floating-point conversion */
15108 case FLOAT_1BIT_FMT(CVT_L
, FMT_SD_S
):
15109 mips32_op
= OPC_CVT_L_S
;
15111 case FLOAT_1BIT_FMT(CVT_L
, FMT_SD_D
):
15112 mips32_op
= OPC_CVT_L_D
;
15114 case FLOAT_1BIT_FMT(CVT_W
, FMT_SD_S
):
15115 mips32_op
= OPC_CVT_W_S
;
15117 case FLOAT_1BIT_FMT(CVT_W
, FMT_SD_D
):
15118 mips32_op
= OPC_CVT_W_D
;
15121 /* Paired-foo conversions */
15122 case FLOAT_1BIT_FMT(CVT_S_PL
, 0):
15123 mips32_op
= OPC_CVT_S_PL
;
15125 case FLOAT_1BIT_FMT(CVT_S_PU
, 0):
15126 mips32_op
= OPC_CVT_S_PU
;
15128 case FLOAT_1BIT_FMT(CVT_PW_PS
, 0):
15129 mips32_op
= OPC_CVT_PW_PS
;
15131 case FLOAT_1BIT_FMT(CVT_PS_PW
, 0):
15132 mips32_op
= OPC_CVT_PS_PW
;
15135 /* Floating-point moves */
15136 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_S
):
15137 mips32_op
= OPC_MOV_S
;
15139 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_D
):
15140 mips32_op
= OPC_MOV_D
;
15142 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_PS
):
15143 mips32_op
= OPC_MOV_PS
;
15146 /* Absolute value */
15147 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_S
):
15148 mips32_op
= OPC_ABS_S
;
15150 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_D
):
15151 mips32_op
= OPC_ABS_D
;
15153 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_PS
):
15154 mips32_op
= OPC_ABS_PS
;
15158 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_S
):
15159 mips32_op
= OPC_NEG_S
;
15161 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_D
):
15162 mips32_op
= OPC_NEG_D
;
15164 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_PS
):
15165 mips32_op
= OPC_NEG_PS
;
15168 /* Reciprocal square root step */
15169 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_S
):
15170 mips32_op
= OPC_RSQRT1_S
;
15172 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_D
):
15173 mips32_op
= OPC_RSQRT1_D
;
15175 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_PS
):
15176 mips32_op
= OPC_RSQRT1_PS
;
15179 /* Reciprocal step */
15180 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_S
):
15181 mips32_op
= OPC_RECIP1_S
;
15183 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_D
):
15184 mips32_op
= OPC_RECIP1_S
;
15186 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_PS
):
15187 mips32_op
= OPC_RECIP1_PS
;
15190 /* Conversions from double */
15191 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_S
):
15192 mips32_op
= OPC_CVT_D_S
;
15194 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_W
):
15195 mips32_op
= OPC_CVT_D_W
;
15197 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_L
):
15198 mips32_op
= OPC_CVT_D_L
;
15201 /* Conversions from single */
15202 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_D
):
15203 mips32_op
= OPC_CVT_S_D
;
15205 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_W
):
15206 mips32_op
= OPC_CVT_S_W
;
15208 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_L
):
15209 mips32_op
= OPC_CVT_S_L
;
15211 gen_farith(ctx
, mips32_op
, -1, rs
, rt
, 0);
15214 /* Conditional moves on floating-point codes */
15215 case COND_FLOAT_MOV(MOVT
, 0):
15216 case COND_FLOAT_MOV(MOVT
, 1):
15217 case COND_FLOAT_MOV(MOVT
, 2):
15218 case COND_FLOAT_MOV(MOVT
, 3):
15219 case COND_FLOAT_MOV(MOVT
, 4):
15220 case COND_FLOAT_MOV(MOVT
, 5):
15221 case COND_FLOAT_MOV(MOVT
, 6):
15222 case COND_FLOAT_MOV(MOVT
, 7):
15223 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15224 gen_movci(ctx
, rt
, rs
, (ctx
->opcode
>> 13) & 0x7, 1);
15226 case COND_FLOAT_MOV(MOVF
, 0):
15227 case COND_FLOAT_MOV(MOVF
, 1):
15228 case COND_FLOAT_MOV(MOVF
, 2):
15229 case COND_FLOAT_MOV(MOVF
, 3):
15230 case COND_FLOAT_MOV(MOVF
, 4):
15231 case COND_FLOAT_MOV(MOVF
, 5):
15232 case COND_FLOAT_MOV(MOVF
, 6):
15233 case COND_FLOAT_MOV(MOVF
, 7):
15234 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15235 gen_movci(ctx
, rt
, rs
, (ctx
->opcode
>> 13) & 0x7, 0);
15238 MIPS_INVAL("pool32fxf");
15239 gen_reserved_instruction(ctx
);
15244 static void decode_micromips32_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
15248 int rt
, rs
, rd
, rr
;
15250 uint32_t op
, minor
, minor2
, mips32_op
;
15251 uint32_t cond
, fmt
, cc
;
15253 insn
= translator_lduw(env
, ctx
->base
.pc_next
+ 2);
15254 ctx
->opcode
= (ctx
->opcode
<< 16) | insn
;
15256 rt
= (ctx
->opcode
>> 21) & 0x1f;
15257 rs
= (ctx
->opcode
>> 16) & 0x1f;
15258 rd
= (ctx
->opcode
>> 11) & 0x1f;
15259 rr
= (ctx
->opcode
>> 6) & 0x1f;
15260 imm
= (int16_t) ctx
->opcode
;
15262 op
= (ctx
->opcode
>> 26) & 0x3f;
15265 minor
= ctx
->opcode
& 0x3f;
15268 minor
= (ctx
->opcode
>> 6) & 0xf;
15271 mips32_op
= OPC_SLL
;
15274 mips32_op
= OPC_SRA
;
15277 mips32_op
= OPC_SRL
;
15280 mips32_op
= OPC_ROTR
;
15282 gen_shift_imm(ctx
, mips32_op
, rt
, rs
, rd
);
15285 check_insn(ctx
, ISA_MIPS_R6
);
15286 gen_cond_move(ctx
, OPC_SELEQZ
, rd
, rs
, rt
);
15289 check_insn(ctx
, ISA_MIPS_R6
);
15290 gen_cond_move(ctx
, OPC_SELNEZ
, rd
, rs
, rt
);
15293 check_insn(ctx
, ISA_MIPS_R6
);
15294 gen_rdhwr(ctx
, rt
, rs
, extract32(ctx
->opcode
, 11, 3));
15297 goto pool32a_invalid
;
15301 minor
= (ctx
->opcode
>> 6) & 0xf;
15305 mips32_op
= OPC_ADD
;
15308 mips32_op
= OPC_ADDU
;
15311 mips32_op
= OPC_SUB
;
15314 mips32_op
= OPC_SUBU
;
15317 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15318 mips32_op
= OPC_MUL
;
15320 gen_arith(ctx
, mips32_op
, rd
, rs
, rt
);
15324 mips32_op
= OPC_SLLV
;
15327 mips32_op
= OPC_SRLV
;
15330 mips32_op
= OPC_SRAV
;
15333 mips32_op
= OPC_ROTRV
;
15335 gen_shift(ctx
, mips32_op
, rd
, rs
, rt
);
15337 /* Logical operations */
15339 mips32_op
= OPC_AND
;
15342 mips32_op
= OPC_OR
;
15345 mips32_op
= OPC_NOR
;
15348 mips32_op
= OPC_XOR
;
15350 gen_logic(ctx
, mips32_op
, rd
, rs
, rt
);
15352 /* Set less than */
15354 mips32_op
= OPC_SLT
;
15357 mips32_op
= OPC_SLTU
;
15359 gen_slt(ctx
, mips32_op
, rd
, rs
, rt
);
15362 goto pool32a_invalid
;
15366 minor
= (ctx
->opcode
>> 6) & 0xf;
15368 /* Conditional moves */
15369 case MOVN
: /* MUL */
15370 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
15372 gen_r6_muldiv(ctx
, R6_OPC_MUL
, rd
, rs
, rt
);
15375 gen_cond_move(ctx
, OPC_MOVN
, rd
, rs
, rt
);
15378 case MOVZ
: /* MUH */
15379 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
15381 gen_r6_muldiv(ctx
, R6_OPC_MUH
, rd
, rs
, rt
);
15384 gen_cond_move(ctx
, OPC_MOVZ
, rd
, rs
, rt
);
15388 check_insn(ctx
, ISA_MIPS_R6
);
15389 gen_r6_muldiv(ctx
, R6_OPC_MULU
, rd
, rs
, rt
);
15392 check_insn(ctx
, ISA_MIPS_R6
);
15393 gen_r6_muldiv(ctx
, R6_OPC_MUHU
, rd
, rs
, rt
);
15395 case LWXS
: /* DIV */
15396 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
15398 gen_r6_muldiv(ctx
, R6_OPC_DIV
, rd
, rs
, rt
);
15401 gen_ldxs(ctx
, rs
, rt
, rd
);
15405 check_insn(ctx
, ISA_MIPS_R6
);
15406 gen_r6_muldiv(ctx
, R6_OPC_MOD
, rd
, rs
, rt
);
15409 check_insn(ctx
, ISA_MIPS_R6
);
15410 gen_r6_muldiv(ctx
, R6_OPC_DIVU
, rd
, rs
, rt
);
15413 check_insn(ctx
, ISA_MIPS_R6
);
15414 gen_r6_muldiv(ctx
, R6_OPC_MODU
, rd
, rs
, rt
);
15417 goto pool32a_invalid
;
15421 gen_bitops(ctx
, OPC_INS
, rt
, rs
, rr
, rd
);
15424 check_insn(ctx
, ISA_MIPS_R6
);
15425 gen_lsa(ctx
, rd
, rt
, rs
, extract32(ctx
->opcode
, 9, 2));
15428 check_insn(ctx
, ISA_MIPS_R6
);
15429 gen_align(ctx
, 32, rd
, rs
, rt
, extract32(ctx
->opcode
, 9, 2));
15432 gen_bitops(ctx
, OPC_EXT
, rt
, rs
, rr
, rd
);
15435 gen_pool32axf(env
, ctx
, rt
, rs
);
15438 generate_exception_end(ctx
, EXCP_BREAK
);
15441 check_insn(ctx
, ISA_MIPS_R6
);
15442 gen_reserved_instruction(ctx
);
15446 MIPS_INVAL("pool32a");
15447 gen_reserved_instruction(ctx
);
15452 minor
= (ctx
->opcode
>> 12) & 0xf;
15455 check_cp0_enabled(ctx
);
15456 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
15457 gen_cache_operation(ctx
, rt
, rs
, imm
);
15462 /* COP2: Not implemented. */
15463 generate_exception_err(ctx
, EXCP_CpU
, 2);
15465 #ifdef TARGET_MIPS64
15468 check_insn(ctx
, ISA_MIPS3
);
15469 check_mips_64(ctx
);
15474 gen_ldst_pair(ctx
, minor
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
15476 #ifdef TARGET_MIPS64
15479 check_insn(ctx
, ISA_MIPS3
);
15480 check_mips_64(ctx
);
15485 gen_ldst_multiple(ctx
, minor
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
15488 MIPS_INVAL("pool32b");
15489 gen_reserved_instruction(ctx
);
15494 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
15495 minor
= ctx
->opcode
& 0x3f;
15496 check_cp1_enabled(ctx
);
15499 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15500 mips32_op
= OPC_ALNV_PS
;
15503 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15504 mips32_op
= OPC_MADD_S
;
15507 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15508 mips32_op
= OPC_MADD_D
;
15511 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15512 mips32_op
= OPC_MADD_PS
;
15515 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15516 mips32_op
= OPC_MSUB_S
;
15519 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15520 mips32_op
= OPC_MSUB_D
;
15523 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15524 mips32_op
= OPC_MSUB_PS
;
15527 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15528 mips32_op
= OPC_NMADD_S
;
15531 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15532 mips32_op
= OPC_NMADD_D
;
15535 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15536 mips32_op
= OPC_NMADD_PS
;
15539 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15540 mips32_op
= OPC_NMSUB_S
;
15543 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15544 mips32_op
= OPC_NMSUB_D
;
15547 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15548 mips32_op
= OPC_NMSUB_PS
;
15550 gen_flt3_arith(ctx
, mips32_op
, rd
, rr
, rs
, rt
);
15552 case CABS_COND_FMT
:
15553 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15554 cond
= (ctx
->opcode
>> 6) & 0xf;
15555 cc
= (ctx
->opcode
>> 13) & 0x7;
15556 fmt
= (ctx
->opcode
>> 10) & 0x3;
15559 gen_cmpabs_s(ctx
, cond
, rt
, rs
, cc
);
15562 gen_cmpabs_d(ctx
, cond
, rt
, rs
, cc
);
15565 gen_cmpabs_ps(ctx
, cond
, rt
, rs
, cc
);
15568 goto pool32f_invalid
;
15572 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15573 cond
= (ctx
->opcode
>> 6) & 0xf;
15574 cc
= (ctx
->opcode
>> 13) & 0x7;
15575 fmt
= (ctx
->opcode
>> 10) & 0x3;
15578 gen_cmp_s(ctx
, cond
, rt
, rs
, cc
);
15581 gen_cmp_d(ctx
, cond
, rt
, rs
, cc
);
15584 gen_cmp_ps(ctx
, cond
, rt
, rs
, cc
);
15587 goto pool32f_invalid
;
15591 check_insn(ctx
, ISA_MIPS_R6
);
15592 gen_r6_cmp_s(ctx
, (ctx
->opcode
>> 6) & 0x1f, rt
, rs
, rd
);
15595 check_insn(ctx
, ISA_MIPS_R6
);
15596 gen_r6_cmp_d(ctx
, (ctx
->opcode
>> 6) & 0x1f, rt
, rs
, rd
);
15599 gen_pool32fxf(ctx
, rt
, rs
);
15603 switch ((ctx
->opcode
>> 6) & 0x7) {
15605 mips32_op
= OPC_PLL_PS
;
15608 mips32_op
= OPC_PLU_PS
;
15611 mips32_op
= OPC_PUL_PS
;
15614 mips32_op
= OPC_PUU_PS
;
15617 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15618 mips32_op
= OPC_CVT_PS_S
;
15620 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
15623 goto pool32f_invalid
;
15627 check_insn(ctx
, ISA_MIPS_R6
);
15628 switch ((ctx
->opcode
>> 9) & 0x3) {
15630 gen_farith(ctx
, OPC_MIN_S
, rt
, rs
, rd
, 0);
15633 gen_farith(ctx
, OPC_MIN_D
, rt
, rs
, rd
, 0);
15636 goto pool32f_invalid
;
15641 switch ((ctx
->opcode
>> 6) & 0x7) {
15643 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15644 mips32_op
= OPC_LWXC1
;
15647 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15648 mips32_op
= OPC_SWXC1
;
15651 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15652 mips32_op
= OPC_LDXC1
;
15655 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15656 mips32_op
= OPC_SDXC1
;
15659 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15660 mips32_op
= OPC_LUXC1
;
15663 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15664 mips32_op
= OPC_SUXC1
;
15666 gen_flt3_ldst(ctx
, mips32_op
, rd
, rd
, rt
, rs
);
15669 goto pool32f_invalid
;
15673 check_insn(ctx
, ISA_MIPS_R6
);
15674 switch ((ctx
->opcode
>> 9) & 0x3) {
15676 gen_farith(ctx
, OPC_MAX_S
, rt
, rs
, rd
, 0);
15679 gen_farith(ctx
, OPC_MAX_D
, rt
, rs
, rd
, 0);
15682 goto pool32f_invalid
;
15687 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15688 fmt
= (ctx
->opcode
>> 9) & 0x3;
15689 switch ((ctx
->opcode
>> 6) & 0x7) {
15693 mips32_op
= OPC_RSQRT2_S
;
15696 mips32_op
= OPC_RSQRT2_D
;
15699 mips32_op
= OPC_RSQRT2_PS
;
15702 goto pool32f_invalid
;
15708 mips32_op
= OPC_RECIP2_S
;
15711 mips32_op
= OPC_RECIP2_D
;
15714 mips32_op
= OPC_RECIP2_PS
;
15717 goto pool32f_invalid
;
15721 mips32_op
= OPC_ADDR_PS
;
15724 mips32_op
= OPC_MULR_PS
;
15726 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
15729 goto pool32f_invalid
;
15733 /* MOV[FT].fmt, PREFX, RINT.fmt, CLASS.fmt*/
15734 cc
= (ctx
->opcode
>> 13) & 0x7;
15735 fmt
= (ctx
->opcode
>> 9) & 0x3;
15736 switch ((ctx
->opcode
>> 6) & 0x7) {
15737 case MOVF_FMT
: /* RINT_FMT */
15738 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
15742 gen_farith(ctx
, OPC_RINT_S
, 0, rt
, rs
, 0);
15745 gen_farith(ctx
, OPC_RINT_D
, 0, rt
, rs
, 0);
15748 goto pool32f_invalid
;
15754 gen_movcf_s(ctx
, rs
, rt
, cc
, 0);
15757 gen_movcf_d(ctx
, rs
, rt
, cc
, 0);
15761 gen_movcf_ps(ctx
, rs
, rt
, cc
, 0);
15764 goto pool32f_invalid
;
15768 case MOVT_FMT
: /* CLASS_FMT */
15769 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
15773 gen_farith(ctx
, OPC_CLASS_S
, 0, rt
, rs
, 0);
15776 gen_farith(ctx
, OPC_CLASS_D
, 0, rt
, rs
, 0);
15779 goto pool32f_invalid
;
15785 gen_movcf_s(ctx
, rs
, rt
, cc
, 1);
15788 gen_movcf_d(ctx
, rs
, rt
, cc
, 1);
15792 gen_movcf_ps(ctx
, rs
, rt
, cc
, 1);
15795 goto pool32f_invalid
;
15800 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15803 goto pool32f_invalid
;
15806 #define FINSN_3ARG_SDPS(prfx) \
15807 switch ((ctx->opcode >> 8) & 0x3) { \
15809 mips32_op = OPC_##prfx##_S; \
15812 mips32_op = OPC_##prfx##_D; \
15814 case FMT_SDPS_PS: \
15816 mips32_op = OPC_##prfx##_PS; \
15819 goto pool32f_invalid; \
15822 check_insn(ctx
, ISA_MIPS_R6
);
15823 switch ((ctx
->opcode
>> 9) & 0x3) {
15825 gen_farith(ctx
, OPC_MINA_S
, rt
, rs
, rd
, 0);
15828 gen_farith(ctx
, OPC_MINA_D
, rt
, rs
, rd
, 0);
15831 goto pool32f_invalid
;
15835 check_insn(ctx
, ISA_MIPS_R6
);
15836 switch ((ctx
->opcode
>> 9) & 0x3) {
15838 gen_farith(ctx
, OPC_MAXA_S
, rt
, rs
, rd
, 0);
15841 gen_farith(ctx
, OPC_MAXA_D
, rt
, rs
, rd
, 0);
15844 goto pool32f_invalid
;
15848 /* regular FP ops */
15849 switch ((ctx
->opcode
>> 6) & 0x3) {
15851 FINSN_3ARG_SDPS(ADD
);
15854 FINSN_3ARG_SDPS(SUB
);
15857 FINSN_3ARG_SDPS(MUL
);
15860 fmt
= (ctx
->opcode
>> 8) & 0x3;
15862 mips32_op
= OPC_DIV_D
;
15863 } else if (fmt
== 0) {
15864 mips32_op
= OPC_DIV_S
;
15866 goto pool32f_invalid
;
15870 goto pool32f_invalid
;
15875 switch ((ctx
->opcode
>> 6) & 0x7) {
15876 case MOVN_FMT
: /* SELEQZ_FMT */
15877 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
15879 switch ((ctx
->opcode
>> 9) & 0x3) {
15881 gen_sel_s(ctx
, OPC_SELEQZ_S
, rd
, rt
, rs
);
15884 gen_sel_d(ctx
, OPC_SELEQZ_D
, rd
, rt
, rs
);
15887 goto pool32f_invalid
;
15891 FINSN_3ARG_SDPS(MOVN
);
15895 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15896 FINSN_3ARG_SDPS(MOVN
);
15898 case MOVZ_FMT
: /* SELNEZ_FMT */
15899 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
15901 switch ((ctx
->opcode
>> 9) & 0x3) {
15903 gen_sel_s(ctx
, OPC_SELNEZ_S
, rd
, rt
, rs
);
15906 gen_sel_d(ctx
, OPC_SELNEZ_D
, rd
, rt
, rs
);
15909 goto pool32f_invalid
;
15913 FINSN_3ARG_SDPS(MOVZ
);
15917 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15918 FINSN_3ARG_SDPS(MOVZ
);
15921 check_insn(ctx
, ISA_MIPS_R6
);
15922 switch ((ctx
->opcode
>> 9) & 0x3) {
15924 gen_sel_s(ctx
, OPC_SEL_S
, rd
, rt
, rs
);
15927 gen_sel_d(ctx
, OPC_SEL_D
, rd
, rt
, rs
);
15930 goto pool32f_invalid
;
15934 check_insn(ctx
, ISA_MIPS_R6
);
15935 switch ((ctx
->opcode
>> 9) & 0x3) {
15937 mips32_op
= OPC_MADDF_S
;
15940 mips32_op
= OPC_MADDF_D
;
15943 goto pool32f_invalid
;
15947 check_insn(ctx
, ISA_MIPS_R6
);
15948 switch ((ctx
->opcode
>> 9) & 0x3) {
15950 mips32_op
= OPC_MSUBF_S
;
15953 mips32_op
= OPC_MSUBF_D
;
15956 goto pool32f_invalid
;
15960 goto pool32f_invalid
;
15964 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
15968 MIPS_INVAL("pool32f");
15969 gen_reserved_instruction(ctx
);
15973 generate_exception_err(ctx
, EXCP_CpU
, 1);
15977 minor
= (ctx
->opcode
>> 21) & 0x1f;
15980 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15981 gen_compute_branch(ctx
, OPC_BLTZ
, 4, rs
, -1, imm
<< 1, 4);
15984 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15985 gen_compute_branch(ctx
, OPC_BLTZAL
, 4, rs
, -1, imm
<< 1, 4);
15986 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
15989 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15990 gen_compute_branch(ctx
, OPC_BLTZAL
, 4, rs
, -1, imm
<< 1, 2);
15991 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
15994 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15995 gen_compute_branch(ctx
, OPC_BGEZ
, 4, rs
, -1, imm
<< 1, 4);
15998 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15999 gen_compute_branch(ctx
, OPC_BGEZAL
, 4, rs
, -1, imm
<< 1, 4);
16000 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
16003 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16004 gen_compute_branch(ctx
, OPC_BGEZAL
, 4, rs
, -1, imm
<< 1, 2);
16005 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
16008 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16009 gen_compute_branch(ctx
, OPC_BLEZ
, 4, rs
, -1, imm
<< 1, 4);
16012 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16013 gen_compute_branch(ctx
, OPC_BGTZ
, 4, rs
, -1, imm
<< 1, 4);
16017 case TLTI
: /* BC1EQZC */
16018 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16020 check_cp1_enabled(ctx
);
16021 gen_compute_branch1_r6(ctx
, OPC_BC1EQZ
, rs
, imm
<< 1, 0);
16024 mips32_op
= OPC_TLTI
;
16028 case TGEI
: /* BC1NEZC */
16029 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16031 check_cp1_enabled(ctx
);
16032 gen_compute_branch1_r6(ctx
, OPC_BC1NEZ
, rs
, imm
<< 1, 0);
16035 mips32_op
= OPC_TGEI
;
16040 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16041 mips32_op
= OPC_TLTIU
;
16044 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16045 mips32_op
= OPC_TGEIU
;
16047 case TNEI
: /* SYNCI */
16048 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16051 * Break the TB to be able to sync copied instructions
16054 ctx
->base
.is_jmp
= DISAS_STOP
;
16057 mips32_op
= OPC_TNEI
;
16062 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16063 mips32_op
= OPC_TEQI
;
16065 gen_trap(ctx
, mips32_op
, rs
, -1, imm
);
16070 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16071 gen_compute_branch(ctx
, minor
== BNEZC
? OPC_BNE
: OPC_BEQ
,
16072 4, rs
, 0, imm
<< 1, 0);
16074 * Compact branches don't have a delay slot, so just let
16075 * the normal delay slot handling take us to the branch
16080 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16081 gen_logic_imm(ctx
, OPC_LUI
, rs
, 0, imm
);
16084 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16086 * Break the TB to be able to sync copied instructions
16089 ctx
->base
.is_jmp
= DISAS_STOP
;
16093 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16094 /* COP2: Not implemented. */
16095 generate_exception_err(ctx
, EXCP_CpU
, 2);
16098 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16099 mips32_op
= (ctx
->opcode
& (1 << 16)) ? OPC_BC1FANY2
: OPC_BC1F
;
16102 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16103 mips32_op
= (ctx
->opcode
& (1 << 16)) ? OPC_BC1TANY2
: OPC_BC1T
;
16106 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16107 mips32_op
= OPC_BC1FANY4
;
16110 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16111 mips32_op
= OPC_BC1TANY4
;
16114 check_insn(ctx
, ASE_MIPS3D
);
16117 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
16118 check_cp1_enabled(ctx
);
16119 gen_compute_branch1(ctx
, mips32_op
,
16120 (ctx
->opcode
>> 18) & 0x7, imm
<< 1);
16122 generate_exception_err(ctx
, EXCP_CpU
, 1);
16127 /* MIPS DSP: not implemented */
16130 MIPS_INVAL("pool32i");
16131 gen_reserved_instruction(ctx
);
16136 minor
= (ctx
->opcode
>> 12) & 0xf;
16137 offset
= sextract32(ctx
->opcode
, 0,
16138 (ctx
->insn_flags
& ISA_MIPS_R6
) ? 9 : 12);
16141 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16142 mips32_op
= OPC_LWL
;
16145 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16146 mips32_op
= OPC_SWL
;
16149 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16150 mips32_op
= OPC_LWR
;
16153 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16154 mips32_op
= OPC_SWR
;
16156 #if defined(TARGET_MIPS64)
16158 check_insn(ctx
, ISA_MIPS3
);
16159 check_mips_64(ctx
);
16160 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16161 mips32_op
= OPC_LDL
;
16164 check_insn(ctx
, ISA_MIPS3
);
16165 check_mips_64(ctx
);
16166 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16167 mips32_op
= OPC_SDL
;
16170 check_insn(ctx
, ISA_MIPS3
);
16171 check_mips_64(ctx
);
16172 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16173 mips32_op
= OPC_LDR
;
16176 check_insn(ctx
, ISA_MIPS3
);
16177 check_mips_64(ctx
);
16178 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16179 mips32_op
= OPC_SDR
;
16182 check_insn(ctx
, ISA_MIPS3
);
16183 check_mips_64(ctx
);
16184 mips32_op
= OPC_LWU
;
16187 check_insn(ctx
, ISA_MIPS3
);
16188 check_mips_64(ctx
);
16189 mips32_op
= OPC_LLD
;
16193 mips32_op
= OPC_LL
;
16196 gen_ld(ctx
, mips32_op
, rt
, rs
, offset
);
16199 gen_st(ctx
, mips32_op
, rt
, rs
, offset
);
16202 gen_st_cond(ctx
, rt
, rs
, offset
, MO_TESL
, false);
16204 #if defined(TARGET_MIPS64)
16206 check_insn(ctx
, ISA_MIPS3
);
16207 check_mips_64(ctx
);
16208 gen_st_cond(ctx
, rt
, rs
, offset
, MO_TEQ
, false);
16213 MIPS_INVAL("pool32c ld-eva");
16214 gen_reserved_instruction(ctx
);
16217 check_cp0_enabled(ctx
);
16219 minor2
= (ctx
->opcode
>> 9) & 0x7;
16220 offset
= sextract32(ctx
->opcode
, 0, 9);
16223 mips32_op
= OPC_LBUE
;
16226 mips32_op
= OPC_LHUE
;
16229 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16230 mips32_op
= OPC_LWLE
;
16233 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16234 mips32_op
= OPC_LWRE
;
16237 mips32_op
= OPC_LBE
;
16240 mips32_op
= OPC_LHE
;
16243 mips32_op
= OPC_LLE
;
16246 mips32_op
= OPC_LWE
;
16252 MIPS_INVAL("pool32c st-eva");
16253 gen_reserved_instruction(ctx
);
16256 check_cp0_enabled(ctx
);
16258 minor2
= (ctx
->opcode
>> 9) & 0x7;
16259 offset
= sextract32(ctx
->opcode
, 0, 9);
16262 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16263 mips32_op
= OPC_SWLE
;
16266 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16267 mips32_op
= OPC_SWRE
;
16270 /* Treat as no-op */
16271 if ((ctx
->insn_flags
& ISA_MIPS_R6
) && (rt
>= 24)) {
16272 /* hint codes 24-31 are reserved and signal RI */
16273 generate_exception(ctx
, EXCP_RI
);
16277 /* Treat as no-op */
16278 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
16279 gen_cache_operation(ctx
, rt
, rs
, offset
);
16283 mips32_op
= OPC_SBE
;
16286 mips32_op
= OPC_SHE
;
16289 gen_st_cond(ctx
, rt
, rs
, offset
, MO_TESL
, true);
16292 mips32_op
= OPC_SWE
;
16297 /* Treat as no-op */
16298 if ((ctx
->insn_flags
& ISA_MIPS_R6
) && (rt
>= 24)) {
16299 /* hint codes 24-31 are reserved and signal RI */
16300 generate_exception(ctx
, EXCP_RI
);
16304 MIPS_INVAL("pool32c");
16305 gen_reserved_instruction(ctx
);
16309 case ADDI32
: /* AUI, LUI */
16310 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16312 gen_logic_imm(ctx
, OPC_LUI
, rt
, rs
, imm
);
16315 mips32_op
= OPC_ADDI
;
16320 mips32_op
= OPC_ADDIU
;
16322 gen_arith_imm(ctx
, mips32_op
, rt
, rs
, imm
);
16325 /* Logical operations */
16327 mips32_op
= OPC_ORI
;
16330 mips32_op
= OPC_XORI
;
16333 mips32_op
= OPC_ANDI
;
16335 gen_logic_imm(ctx
, mips32_op
, rt
, rs
, imm
);
16338 /* Set less than immediate */
16340 mips32_op
= OPC_SLTI
;
16343 mips32_op
= OPC_SLTIU
;
16345 gen_slt_imm(ctx
, mips32_op
, rt
, rs
, imm
);
16348 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16349 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
16350 gen_compute_branch(ctx
, OPC_JALX
, 4, rt
, rs
, offset
, 4);
16351 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
16353 case JALS32
: /* BOVC, BEQC, BEQZALC */
16354 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16357 mips32_op
= OPC_BOVC
;
16358 } else if (rs
< rt
&& rs
== 0) {
16360 mips32_op
= OPC_BEQZALC
;
16363 mips32_op
= OPC_BEQC
;
16365 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
16368 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1;
16369 gen_compute_branch(ctx
, OPC_JAL
, 4, rt
, rs
, offset
, 2);
16370 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
16373 case BEQ32
: /* BC */
16374 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16376 gen_compute_compact_branch(ctx
, OPC_BC
, 0, 0,
16377 sextract32(ctx
->opcode
<< 1, 0, 27));
16380 gen_compute_branch(ctx
, OPC_BEQ
, 4, rt
, rs
, imm
<< 1, 4);
16383 case BNE32
: /* BALC */
16384 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16386 gen_compute_compact_branch(ctx
, OPC_BALC
, 0, 0,
16387 sextract32(ctx
->opcode
<< 1, 0, 27));
16390 gen_compute_branch(ctx
, OPC_BNE
, 4, rt
, rs
, imm
<< 1, 4);
16393 case J32
: /* BGTZC, BLTZC, BLTC */
16394 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16395 if (rs
== 0 && rt
!= 0) {
16397 mips32_op
= OPC_BGTZC
;
16398 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
16400 mips32_op
= OPC_BLTZC
;
16403 mips32_op
= OPC_BLTC
;
16405 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
16408 gen_compute_branch(ctx
, OPC_J
, 4, rt
, rs
,
16409 (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1, 4);
16412 case JAL32
: /* BLEZC, BGEZC, BGEC */
16413 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16414 if (rs
== 0 && rt
!= 0) {
16416 mips32_op
= OPC_BLEZC
;
16417 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
16419 mips32_op
= OPC_BGEZC
;
16422 mips32_op
= OPC_BGEC
;
16424 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
16427 gen_compute_branch(ctx
, OPC_JAL
, 4, rt
, rs
,
16428 (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1, 4);
16429 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
16432 /* Floating point (COP1) */
16434 mips32_op
= OPC_LWC1
;
16437 mips32_op
= OPC_LDC1
;
16440 mips32_op
= OPC_SWC1
;
16443 mips32_op
= OPC_SDC1
;
16445 gen_cop1_ldst(ctx
, mips32_op
, rt
, rs
, imm
);
16447 case ADDIUPC
: /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
16448 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16449 /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
16450 switch ((ctx
->opcode
>> 16) & 0x1f) {
16459 gen_pcrel(ctx
, OPC_ADDIUPC
, ctx
->base
.pc_next
& ~0x3, rt
);
16462 gen_pcrel(ctx
, OPC_AUIPC
, ctx
->base
.pc_next
, rt
);
16465 gen_pcrel(ctx
, OPC_ALUIPC
, ctx
->base
.pc_next
, rt
);
16475 gen_pcrel(ctx
, R6_OPC_LWPC
, ctx
->base
.pc_next
& ~0x3, rt
);
16478 generate_exception(ctx
, EXCP_RI
);
16483 int reg
= mmreg(ZIMM(ctx
->opcode
, 23, 3));
16484 offset
= SIMM(ctx
->opcode
, 0, 23) << 2;
16486 gen_addiupc(ctx
, reg
, offset
, 0, 0);
16489 case BNVC
: /* BNEC, BNEZALC */
16490 check_insn(ctx
, ISA_MIPS_R6
);
16493 mips32_op
= OPC_BNVC
;
16494 } else if (rs
< rt
&& rs
== 0) {
16496 mips32_op
= OPC_BNEZALC
;
16499 mips32_op
= OPC_BNEC
;
16501 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
16503 case R6_BNEZC
: /* JIALC */
16504 check_insn(ctx
, ISA_MIPS_R6
);
16507 gen_compute_compact_branch(ctx
, OPC_BNEZC
, rt
, 0,
16508 sextract32(ctx
->opcode
<< 1, 0, 22));
16511 gen_compute_compact_branch(ctx
, OPC_JIALC
, 0, rs
, imm
);
16514 case R6_BEQZC
: /* JIC */
16515 check_insn(ctx
, ISA_MIPS_R6
);
16518 gen_compute_compact_branch(ctx
, OPC_BEQZC
, rt
, 0,
16519 sextract32(ctx
->opcode
<< 1, 0, 22));
16522 gen_compute_compact_branch(ctx
, OPC_JIC
, 0, rs
, imm
);
16525 case BLEZALC
: /* BGEZALC, BGEUC */
16526 check_insn(ctx
, ISA_MIPS_R6
);
16527 if (rs
== 0 && rt
!= 0) {
16529 mips32_op
= OPC_BLEZALC
;
16530 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
16532 mips32_op
= OPC_BGEZALC
;
16535 mips32_op
= OPC_BGEUC
;
16537 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
16539 case BGTZALC
: /* BLTZALC, BLTUC */
16540 check_insn(ctx
, ISA_MIPS_R6
);
16541 if (rs
== 0 && rt
!= 0) {
16543 mips32_op
= OPC_BGTZALC
;
16544 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
16546 mips32_op
= OPC_BLTZALC
;
16549 mips32_op
= OPC_BLTUC
;
16551 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
16553 /* Loads and stores */
16555 mips32_op
= OPC_LB
;
16558 mips32_op
= OPC_LBU
;
16561 mips32_op
= OPC_LH
;
16564 mips32_op
= OPC_LHU
;
16567 mips32_op
= OPC_LW
;
16569 #ifdef TARGET_MIPS64
16571 check_insn(ctx
, ISA_MIPS3
);
16572 check_mips_64(ctx
);
16573 mips32_op
= OPC_LD
;
16576 check_insn(ctx
, ISA_MIPS3
);
16577 check_mips_64(ctx
);
16578 mips32_op
= OPC_SD
;
16582 mips32_op
= OPC_SB
;
16585 mips32_op
= OPC_SH
;
16588 mips32_op
= OPC_SW
;
16591 gen_ld(ctx
, mips32_op
, rt
, rs
, imm
);
16594 gen_st(ctx
, mips32_op
, rt
, rs
, imm
);
16597 gen_reserved_instruction(ctx
);
16602 static int decode_micromips_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
16606 /* make sure instructions are on a halfword boundary */
16607 if (ctx
->base
.pc_next
& 0x1) {
16608 env
->CP0_BadVAddr
= ctx
->base
.pc_next
;
16609 generate_exception_end(ctx
, EXCP_AdEL
);
16613 op
= (ctx
->opcode
>> 10) & 0x3f;
16614 /* Enforce properly-sized instructions in a delay slot */
16615 if (ctx
->hflags
& MIPS_HFLAG_BDS_STRICT
) {
16616 switch (op
& 0x7) { /* MSB-3..MSB-5 */
16618 /* POOL32A, POOL32B, POOL32I, POOL32C */
16620 /* ADDI32, ADDIU32, ORI32, XORI32, SLTI32, SLTIU32, ANDI32, JALX32 */
16622 /* LBU32, LHU32, POOL32F, JALS32, BEQ32, BNE32, J32, JAL32 */
16624 /* SB32, SH32, ADDIUPC, SWC132, SDC132, SW32 */
16626 /* LB32, LH32, LWC132, LDC132, LW32 */
16627 if (ctx
->hflags
& MIPS_HFLAG_BDS16
) {
16628 gen_reserved_instruction(ctx
);
16633 /* POOL16A, POOL16B, POOL16C, LWGP16, POOL16F */
16635 /* LBU16, LHU16, LWSP16, LW16, SB16, SH16, SWSP16, SW16 */
16637 /* MOVE16, ANDI16, POOL16D, POOL16E, BEQZ16, BNEZ16, B16, LI16 */
16638 if (ctx
->hflags
& MIPS_HFLAG_BDS32
) {
16639 gen_reserved_instruction(ctx
);
16649 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
16650 int rs1
= mmreg(uMIPS_RS1(ctx
->opcode
));
16651 int rs2
= mmreg(uMIPS_RS2(ctx
->opcode
));
16654 switch (ctx
->opcode
& 0x1) {
16662 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16664 * In the Release 6, the register number location in
16665 * the instruction encoding has changed.
16667 gen_arith(ctx
, opc
, rs1
, rd
, rs2
);
16669 gen_arith(ctx
, opc
, rd
, rs1
, rs2
);
16675 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
16676 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
16677 int amount
= (ctx
->opcode
>> 1) & 0x7;
16679 amount
= amount
== 0 ? 8 : amount
;
16681 switch (ctx
->opcode
& 0x1) {
16690 gen_shift_imm(ctx
, opc
, rd
, rs
, amount
);
16694 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16695 gen_pool16c_r6_insn(ctx
);
16697 gen_pool16c_insn(ctx
);
16702 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
16703 int rb
= 28; /* GP */
16704 int16_t offset
= SIMM(ctx
->opcode
, 0, 7) << 2;
16706 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
16710 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16711 if (ctx
->opcode
& 1) {
16712 gen_reserved_instruction(ctx
);
16715 int enc_dest
= uMIPS_RD(ctx
->opcode
);
16716 int enc_rt
= uMIPS_RS2(ctx
->opcode
);
16717 int enc_rs
= uMIPS_RS1(ctx
->opcode
);
16718 gen_movep(ctx
, enc_dest
, enc_rt
, enc_rs
);
16723 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
16724 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
16725 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4);
16726 offset
= (offset
== 0xf ? -1 : offset
);
16728 gen_ld(ctx
, OPC_LBU
, rd
, rb
, offset
);
16733 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
16734 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
16735 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 1;
16737 gen_ld(ctx
, OPC_LHU
, rd
, rb
, offset
);
16742 int rd
= (ctx
->opcode
>> 5) & 0x1f;
16743 int rb
= 29; /* SP */
16744 int16_t offset
= ZIMM(ctx
->opcode
, 0, 5) << 2;
16746 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
16751 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
16752 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
16753 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 2;
16755 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
16760 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
16761 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
16762 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4);
16764 gen_st(ctx
, OPC_SB
, rd
, rb
, offset
);
16769 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
16770 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
16771 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 1;
16773 gen_st(ctx
, OPC_SH
, rd
, rb
, offset
);
16778 int rd
= (ctx
->opcode
>> 5) & 0x1f;
16779 int rb
= 29; /* SP */
16780 int16_t offset
= ZIMM(ctx
->opcode
, 0, 5) << 2;
16782 gen_st(ctx
, OPC_SW
, rd
, rb
, offset
);
16787 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
16788 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
16789 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 2;
16791 gen_st(ctx
, OPC_SW
, rd
, rb
, offset
);
16796 int rd
= uMIPS_RD5(ctx
->opcode
);
16797 int rs
= uMIPS_RS5(ctx
->opcode
);
16799 gen_arith(ctx
, OPC_ADDU
, rd
, rs
, 0);
16806 switch (ctx
->opcode
& 0x1) {
16816 switch (ctx
->opcode
& 0x1) {
16821 gen_addiur1sp(ctx
);
16825 case B16
: /* BC16 */
16826 gen_compute_branch(ctx
, OPC_BEQ
, 2, 0, 0,
16827 sextract32(ctx
->opcode
, 0, 10) << 1,
16828 (ctx
->insn_flags
& ISA_MIPS_R6
) ? 0 : 4);
16830 case BNEZ16
: /* BNEZC16 */
16831 case BEQZ16
: /* BEQZC16 */
16832 gen_compute_branch(ctx
, op
== BNEZ16
? OPC_BNE
: OPC_BEQ
, 2,
16833 mmreg(uMIPS_RD(ctx
->opcode
)),
16834 0, sextract32(ctx
->opcode
, 0, 7) << 1,
16835 (ctx
->insn_flags
& ISA_MIPS_R6
) ? 0 : 4);
16840 int reg
= mmreg(uMIPS_RD(ctx
->opcode
));
16841 int imm
= ZIMM(ctx
->opcode
, 0, 7);
16843 imm
= (imm
== 0x7f ? -1 : imm
);
16844 tcg_gen_movi_tl(cpu_gpr
[reg
], imm
);
16850 gen_reserved_instruction(ctx
);
16853 decode_micromips32_opc(env
, ctx
);
16866 /* MAJOR, P16, and P32 pools opcodes */
16870 NM_MOVE_BALC
= 0x02,
16878 NM_P16_SHIFT
= 0x0c,
16896 NM_P_LS_U12
= 0x21,
16906 NM_P16_ADDU
= 0x2c,
16920 NM_MOVEPREV
= 0x3f,
16923 /* POOL32A instruction pool */
16925 NM_POOL32A0
= 0x00,
16926 NM_SPECIAL2
= 0x01,
16929 NM_POOL32A5
= 0x05,
16930 NM_POOL32A7
= 0x07,
16933 /* P.GP.W instruction pool */
16935 NM_ADDIUGP_W
= 0x00,
16940 /* P48I instruction pool */
16944 NM_ADDIUGP48
= 0x02,
16945 NM_ADDIUPC48
= 0x03,
16950 /* P.U12 instruction pool */
16959 NM_ADDIUNEG
= 0x08,
16966 /* POOL32F instruction pool */
16968 NM_POOL32F_0
= 0x00,
16969 NM_POOL32F_3
= 0x03,
16970 NM_POOL32F_5
= 0x05,
16973 /* POOL32S instruction pool */
16975 NM_POOL32S_0
= 0x00,
16976 NM_POOL32S_4
= 0x04,
16979 /* P.LUI instruction pool */
16985 /* P.GP.BH instruction pool */
16990 NM_ADDIUGP_B
= 0x03,
16993 NM_P_GP_CP1
= 0x06,
16996 /* P.LS.U12 instruction pool */
17001 NM_P_PREFU12
= 0x03,
17014 /* P.LS.S9 instruction pool */
17020 NM_P_LS_UAWM
= 0x05,
17023 /* P.BAL instruction pool */
17029 /* P.J instruction pool */
17032 NM_JALRC_HB
= 0x01,
17033 NM_P_BALRSC
= 0x08,
17036 /* P.BR1 instruction pool */
17044 /* P.BR2 instruction pool */
17051 /* P.BRI instruction pool */
17063 /* P16.SHIFT instruction pool */
17069 /* POOL16C instruction pool */
17071 NM_POOL16C_0
= 0x00,
17075 /* P16.A1 instruction pool */
17077 NM_ADDIUR1SP
= 0x01,
17080 /* P16.A2 instruction pool */
17083 NM_P_ADDIURS5
= 0x01,
17086 /* P16.ADDU instruction pool */
17092 /* P16.SR instruction pool */
17095 NM_RESTORE_JRC16
= 0x01,
17098 /* P16.4X4 instruction pool */
17104 /* P16.LB instruction pool */
17111 /* P16.LH instruction pool */
17118 /* P.RI instruction pool */
17121 NM_P_SYSCALL
= 0x01,
17126 /* POOL32A0 instruction pool */
17161 NM_D_E_MT_VPE
= 0x56,
17169 /* CRC32 instruction pool */
17179 /* POOL32A5 instruction pool */
17181 NM_CMP_EQ_PH
= 0x00,
17182 NM_CMP_LT_PH
= 0x08,
17183 NM_CMP_LE_PH
= 0x10,
17184 NM_CMPGU_EQ_QB
= 0x18,
17185 NM_CMPGU_LT_QB
= 0x20,
17186 NM_CMPGU_LE_QB
= 0x28,
17187 NM_CMPGDU_EQ_QB
= 0x30,
17188 NM_CMPGDU_LT_QB
= 0x38,
17189 NM_CMPGDU_LE_QB
= 0x40,
17190 NM_CMPU_EQ_QB
= 0x48,
17191 NM_CMPU_LT_QB
= 0x50,
17192 NM_CMPU_LE_QB
= 0x58,
17193 NM_ADDQ_S_W
= 0x60,
17194 NM_SUBQ_S_W
= 0x68,
17198 NM_ADDQ_S_PH
= 0x01,
17199 NM_ADDQH_R_PH
= 0x09,
17200 NM_ADDQH_R_W
= 0x11,
17201 NM_ADDU_S_QB
= 0x19,
17202 NM_ADDU_S_PH
= 0x21,
17203 NM_ADDUH_R_QB
= 0x29,
17204 NM_SHRAV_R_PH
= 0x31,
17205 NM_SHRAV_R_QB
= 0x39,
17206 NM_SUBQ_S_PH
= 0x41,
17207 NM_SUBQH_R_PH
= 0x49,
17208 NM_SUBQH_R_W
= 0x51,
17209 NM_SUBU_S_QB
= 0x59,
17210 NM_SUBU_S_PH
= 0x61,
17211 NM_SUBUH_R_QB
= 0x69,
17212 NM_SHLLV_S_PH
= 0x71,
17213 NM_PRECR_SRA_R_PH_W
= 0x79,
17215 NM_MULEU_S_PH_QBL
= 0x12,
17216 NM_MULEU_S_PH_QBR
= 0x1a,
17217 NM_MULQ_RS_PH
= 0x22,
17218 NM_MULQ_S_PH
= 0x2a,
17219 NM_MULQ_RS_W
= 0x32,
17220 NM_MULQ_S_W
= 0x3a,
17223 NM_SHRAV_R_W
= 0x5a,
17224 NM_SHRLV_PH
= 0x62,
17225 NM_SHRLV_QB
= 0x6a,
17226 NM_SHLLV_QB
= 0x72,
17227 NM_SHLLV_S_W
= 0x7a,
17231 NM_MULEQ_S_W_PHL
= 0x04,
17232 NM_MULEQ_S_W_PHR
= 0x0c,
17234 NM_MUL_S_PH
= 0x05,
17235 NM_PRECR_QB_PH
= 0x0d,
17236 NM_PRECRQ_QB_PH
= 0x15,
17237 NM_PRECRQ_PH_W
= 0x1d,
17238 NM_PRECRQ_RS_PH_W
= 0x25,
17239 NM_PRECRQU_S_QB_PH
= 0x2d,
17240 NM_PACKRL_PH
= 0x35,
17244 NM_SHRA_R_W
= 0x5e,
17245 NM_SHRA_R_PH
= 0x66,
17246 NM_SHLL_S_PH
= 0x76,
17247 NM_SHLL_S_W
= 0x7e,
17252 /* POOL32A7 instruction pool */
17257 NM_POOL32AXF
= 0x07,
17260 /* P.SR instruction pool */
17266 /* P.SHIFT instruction pool */
17274 /* P.ROTX instruction pool */
17279 /* P.INS instruction pool */
17284 /* P.EXT instruction pool */
17289 /* POOL32F_0 (fmt) instruction pool */
17294 NM_SELEQZ_S
= 0x07,
17295 NM_SELEQZ_D
= 0x47,
17299 NM_SELNEZ_S
= 0x0f,
17300 NM_SELNEZ_D
= 0x4f,
17315 /* POOL32F_3 instruction pool */
17319 NM_MINA_FMT
= 0x04,
17320 NM_MAXA_FMT
= 0x05,
17321 NM_POOL32FXF
= 0x07,
17324 /* POOL32F_5 instruction pool */
17326 NM_CMP_CONDN_S
= 0x00,
17327 NM_CMP_CONDN_D
= 0x02,
17330 /* P.GP.LH instruction pool */
17336 /* P.GP.SH instruction pool */
17341 /* P.GP.CP1 instruction pool */
17349 /* P.LS.S0 instruction pool */
17366 NM_P_PREFS9
= 0x03,
17372 /* P.LS.S1 instruction pool */
17374 NM_ASET_ACLR
= 0x02,
17382 /* P.LS.E0 instruction pool */
17398 /* P.PREFE instruction pool */
17404 /* P.LLE instruction pool */
17410 /* P.SCE instruction pool */
17416 /* P.LS.WM instruction pool */
17422 /* P.LS.UAWM instruction pool */
17428 /* P.BR3A instruction pool */
17434 NM_BPOSGE32C
= 0x04,
17437 /* P16.RI instruction pool */
17439 NM_P16_SYSCALL
= 0x01,
17444 /* POOL16C_0 instruction pool */
17446 NM_POOL16C_00
= 0x00,
17449 /* P16.JRC instruction pool */
17455 /* P.SYSCALL instruction pool */
17461 /* P.TRAP instruction pool */
17467 /* P.CMOVE instruction pool */
17473 /* POOL32Axf instruction pool */
17475 NM_POOL32AXF_1
= 0x01,
17476 NM_POOL32AXF_2
= 0x02,
17477 NM_POOL32AXF_4
= 0x04,
17478 NM_POOL32AXF_5
= 0x05,
17479 NM_POOL32AXF_7
= 0x07,
17482 /* POOL32Axf_1 instruction pool */
17484 NM_POOL32AXF_1_0
= 0x00,
17485 NM_POOL32AXF_1_1
= 0x01,
17486 NM_POOL32AXF_1_3
= 0x03,
17487 NM_POOL32AXF_1_4
= 0x04,
17488 NM_POOL32AXF_1_5
= 0x05,
17489 NM_POOL32AXF_1_7
= 0x07,
17492 /* POOL32Axf_2 instruction pool */
17494 NM_POOL32AXF_2_0_7
= 0x00,
17495 NM_POOL32AXF_2_8_15
= 0x01,
17496 NM_POOL32AXF_2_16_23
= 0x02,
17497 NM_POOL32AXF_2_24_31
= 0x03,
17500 /* POOL32Axf_7 instruction pool */
17502 NM_SHRA_R_QB
= 0x0,
17507 /* POOL32Axf_1_0 instruction pool */
17515 /* POOL32Axf_1_1 instruction pool */
17521 /* POOL32Axf_1_3 instruction pool */
17529 /* POOL32Axf_1_4 instruction pool */
17535 /* POOL32Axf_1_5 instruction pool */
17537 NM_MAQ_S_W_PHR
= 0x0,
17538 NM_MAQ_S_W_PHL
= 0x1,
17539 NM_MAQ_SA_W_PHR
= 0x2,
17540 NM_MAQ_SA_W_PHL
= 0x3,
17543 /* POOL32Axf_1_7 instruction pool */
17547 NM_EXTR_RS_W
= 0x2,
17551 /* POOL32Axf_2_0_7 instruction pool */
17554 NM_DPAQ_S_W_PH
= 0x1,
17556 NM_DPSQ_S_W_PH
= 0x3,
17563 /* POOL32Axf_2_8_15 instruction pool */
17565 NM_DPAX_W_PH
= 0x0,
17566 NM_DPAQ_SA_L_W
= 0x1,
17567 NM_DPSX_W_PH
= 0x2,
17568 NM_DPSQ_SA_L_W
= 0x3,
17571 NM_EXTRV_R_W
= 0x7,
17574 /* POOL32Axf_2_16_23 instruction pool */
17576 NM_DPAU_H_QBL
= 0x0,
17577 NM_DPAQX_S_W_PH
= 0x1,
17578 NM_DPSU_H_QBL
= 0x2,
17579 NM_DPSQX_S_W_PH
= 0x3,
17582 NM_MULSA_W_PH
= 0x6,
17583 NM_EXTRV_RS_W
= 0x7,
17586 /* POOL32Axf_2_24_31 instruction pool */
17588 NM_DPAU_H_QBR
= 0x0,
17589 NM_DPAQX_SA_W_PH
= 0x1,
17590 NM_DPSU_H_QBR
= 0x2,
17591 NM_DPSQX_SA_W_PH
= 0x3,
17594 NM_MULSAQ_S_W_PH
= 0x6,
17595 NM_EXTRV_S_H
= 0x7,
17598 /* POOL32Axf_{4, 5} instruction pool */
17617 /* nanoMIPS DSP instructions */
17618 NM_ABSQ_S_QB
= 0x00,
17619 NM_ABSQ_S_PH
= 0x08,
17620 NM_ABSQ_S_W
= 0x10,
17621 NM_PRECEQ_W_PHL
= 0x28,
17622 NM_PRECEQ_W_PHR
= 0x30,
17623 NM_PRECEQU_PH_QBL
= 0x38,
17624 NM_PRECEQU_PH_QBR
= 0x48,
17625 NM_PRECEU_PH_QBL
= 0x58,
17626 NM_PRECEU_PH_QBR
= 0x68,
17627 NM_PRECEQU_PH_QBLA
= 0x39,
17628 NM_PRECEQU_PH_QBRA
= 0x49,
17629 NM_PRECEU_PH_QBLA
= 0x59,
17630 NM_PRECEU_PH_QBRA
= 0x69,
17631 NM_REPLV_PH
= 0x01,
17632 NM_REPLV_QB
= 0x09,
17635 NM_RADDU_W_QB
= 0x78,
17641 /* PP.SR instruction pool */
17645 NM_RESTORE_JRC
= 0x03,
17648 /* P.SR.F instruction pool */
17651 NM_RESTOREF
= 0x01,
17654 /* P16.SYSCALL instruction pool */
17656 NM_SYSCALL16
= 0x00,
17657 NM_HYPCALL16
= 0x01,
17660 /* POOL16C_00 instruction pool */
17668 /* PP.LSX and PP.LSXS instruction pool */
17706 /* ERETx instruction pool */
17712 /* POOL32FxF_{0, 1} insturction pool */
17721 NM_CVT_S_PL
= 0x84,
17722 NM_CVT_S_PU
= 0xa4,
17724 NM_CVT_L_S
= 0x004,
17725 NM_CVT_L_D
= 0x104,
17726 NM_CVT_W_S
= 0x024,
17727 NM_CVT_W_D
= 0x124,
17729 NM_RSQRT_S
= 0x008,
17730 NM_RSQRT_D
= 0x108,
17735 NM_RECIP_S
= 0x048,
17736 NM_RECIP_D
= 0x148,
17738 NM_FLOOR_L_S
= 0x00c,
17739 NM_FLOOR_L_D
= 0x10c,
17741 NM_FLOOR_W_S
= 0x02c,
17742 NM_FLOOR_W_D
= 0x12c,
17744 NM_CEIL_L_S
= 0x04c,
17745 NM_CEIL_L_D
= 0x14c,
17746 NM_CEIL_W_S
= 0x06c,
17747 NM_CEIL_W_D
= 0x16c,
17748 NM_TRUNC_L_S
= 0x08c,
17749 NM_TRUNC_L_D
= 0x18c,
17750 NM_TRUNC_W_S
= 0x0ac,
17751 NM_TRUNC_W_D
= 0x1ac,
17752 NM_ROUND_L_S
= 0x0cc,
17753 NM_ROUND_L_D
= 0x1cc,
17754 NM_ROUND_W_S
= 0x0ec,
17755 NM_ROUND_W_D
= 0x1ec,
17763 NM_CVT_D_S
= 0x04d,
17764 NM_CVT_D_W
= 0x0cd,
17765 NM_CVT_D_L
= 0x14d,
17766 NM_CVT_S_D
= 0x06d,
17767 NM_CVT_S_W
= 0x0ed,
17768 NM_CVT_S_L
= 0x16d,
17771 /* P.LL instruction pool */
17777 /* P.SC instruction pool */
17783 /* P.DVP instruction pool */
17792 * nanoMIPS decoding engine
17797 /* extraction utilities */
17799 #define NANOMIPS_EXTRACT_RT3(op) ((op >> 7) & 0x7)
17800 #define NANOMIPS_EXTRACT_RS3(op) ((op >> 4) & 0x7)
17801 #define NANOMIPS_EXTRACT_RD3(op) ((op >> 1) & 0x7)
17802 #define NANOMIPS_EXTRACT_RD5(op) ((op >> 5) & 0x1f)
17803 #define NANOMIPS_EXTRACT_RS5(op) (op & 0x1f)
17805 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3'). */
17806 static inline int decode_gpr_gpr3(int r
)
17808 static const int map
[] = { 16, 17, 18, 19, 4, 5, 6, 7 };
17810 return map
[r
& 0x7];
17813 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3.src.store'). */
17814 static inline int decode_gpr_gpr3_src_store(int r
)
17816 static const int map
[] = { 0, 17, 18, 19, 4, 5, 6, 7 };
17818 return map
[r
& 0x7];
17821 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4'). */
17822 static inline int decode_gpr_gpr4(int r
)
17824 static const int map
[] = { 8, 9, 10, 11, 4, 5, 6, 7,
17825 16, 17, 18, 19, 20, 21, 22, 23 };
17827 return map
[r
& 0xf];
17830 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4.zero'). */
17831 static inline int decode_gpr_gpr4_zero(int r
)
17833 static const int map
[] = { 8, 9, 10, 0, 4, 5, 6, 7,
17834 16, 17, 18, 19, 20, 21, 22, 23 };
17836 return map
[r
& 0xf];
17840 static void gen_adjust_sp(DisasContext
*ctx
, int u
)
17842 gen_op_addr_addi(ctx
, cpu_gpr
[29], cpu_gpr
[29], u
);
17845 static void gen_save(DisasContext
*ctx
, uint8_t rt
, uint8_t count
,
17846 uint8_t gp
, uint16_t u
)
17849 TCGv va
= tcg_temp_new();
17850 TCGv t0
= tcg_temp_new();
17852 while (counter
!= count
) {
17853 bool use_gp
= gp
&& (counter
== count
- 1);
17854 int this_rt
= use_gp
? 28 : (rt
& 0x10) | ((rt
+ counter
) & 0x1f);
17855 int this_offset
= -((counter
+ 1) << 2);
17856 gen_base_offset_addr(ctx
, va
, 29, this_offset
);
17857 gen_load_gpr(t0
, this_rt
);
17858 tcg_gen_qemu_st_tl(t0
, va
, ctx
->mem_idx
,
17859 (MO_TEUL
| ctx
->default_tcg_memop_mask
));
17863 /* adjust stack pointer */
17864 gen_adjust_sp(ctx
, -u
);
17870 static void gen_restore(DisasContext
*ctx
, uint8_t rt
, uint8_t count
,
17871 uint8_t gp
, uint16_t u
)
17874 TCGv va
= tcg_temp_new();
17875 TCGv t0
= tcg_temp_new();
17877 while (counter
!= count
) {
17878 bool use_gp
= gp
&& (counter
== count
- 1);
17879 int this_rt
= use_gp
? 28 : (rt
& 0x10) | ((rt
+ counter
) & 0x1f);
17880 int this_offset
= u
- ((counter
+ 1) << 2);
17881 gen_base_offset_addr(ctx
, va
, 29, this_offset
);
17882 tcg_gen_qemu_ld_tl(t0
, va
, ctx
->mem_idx
, MO_TESL
|
17883 ctx
->default_tcg_memop_mask
);
17884 tcg_gen_ext32s_tl(t0
, t0
);
17885 gen_store_gpr(t0
, this_rt
);
17889 /* adjust stack pointer */
17890 gen_adjust_sp(ctx
, u
);
17896 static void gen_pool16c_nanomips_insn(DisasContext
*ctx
)
17898 int rt
= decode_gpr_gpr3(NANOMIPS_EXTRACT_RT3(ctx
->opcode
));
17899 int rs
= decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx
->opcode
));
17901 switch (extract32(ctx
->opcode
, 2, 2)) {
17903 gen_logic(ctx
, OPC_NOR
, rt
, rs
, 0);
17906 gen_logic(ctx
, OPC_AND
, rt
, rt
, rs
);
17909 gen_logic(ctx
, OPC_XOR
, rt
, rt
, rs
);
17912 gen_logic(ctx
, OPC_OR
, rt
, rt
, rs
);
17917 static void gen_pool32a0_nanomips_insn(CPUMIPSState
*env
, DisasContext
*ctx
)
17919 int rt
= extract32(ctx
->opcode
, 21, 5);
17920 int rs
= extract32(ctx
->opcode
, 16, 5);
17921 int rd
= extract32(ctx
->opcode
, 11, 5);
17923 switch (extract32(ctx
->opcode
, 3, 7)) {
17925 switch (extract32(ctx
->opcode
, 10, 1)) {
17928 gen_trap(ctx
, OPC_TEQ
, rs
, rt
, -1);
17932 gen_trap(ctx
, OPC_TNE
, rs
, rt
, -1);
17938 gen_rdhwr(ctx
, rt
, rs
, extract32(ctx
->opcode
, 11, 3));
17942 gen_bshfl(ctx
, OPC_SEB
, rs
, rt
);
17945 gen_bshfl(ctx
, OPC_SEH
, rs
, rt
);
17948 gen_shift(ctx
, OPC_SLLV
, rd
, rt
, rs
);
17951 gen_shift(ctx
, OPC_SRLV
, rd
, rt
, rs
);
17954 gen_shift(ctx
, OPC_SRAV
, rd
, rt
, rs
);
17957 gen_shift(ctx
, OPC_ROTRV
, rd
, rt
, rs
);
17960 gen_arith(ctx
, OPC_ADD
, rd
, rs
, rt
);
17963 gen_arith(ctx
, OPC_ADDU
, rd
, rs
, rt
);
17967 gen_arith(ctx
, OPC_SUB
, rd
, rs
, rt
);
17970 gen_arith(ctx
, OPC_SUBU
, rd
, rs
, rt
);
17973 switch (extract32(ctx
->opcode
, 10, 1)) {
17975 gen_cond_move(ctx
, OPC_MOVZ
, rd
, rs
, rt
);
17978 gen_cond_move(ctx
, OPC_MOVN
, rd
, rs
, rt
);
17983 gen_logic(ctx
, OPC_AND
, rd
, rs
, rt
);
17986 gen_logic(ctx
, OPC_OR
, rd
, rs
, rt
);
17989 gen_logic(ctx
, OPC_NOR
, rd
, rs
, rt
);
17992 gen_logic(ctx
, OPC_XOR
, rd
, rs
, rt
);
17995 gen_slt(ctx
, OPC_SLT
, rd
, rs
, rt
);
18000 #ifndef CONFIG_USER_ONLY
18001 TCGv t0
= tcg_temp_new();
18002 switch (extract32(ctx
->opcode
, 10, 1)) {
18005 check_cp0_enabled(ctx
);
18006 gen_helper_dvp(t0
, cpu_env
);
18007 gen_store_gpr(t0
, rt
);
18012 check_cp0_enabled(ctx
);
18013 gen_helper_evp(t0
, cpu_env
);
18014 gen_store_gpr(t0
, rt
);
18021 gen_slt(ctx
, OPC_SLTU
, rd
, rs
, rt
);
18026 TCGv t0
= tcg_temp_new();
18027 TCGv t1
= tcg_temp_new();
18028 TCGv t2
= tcg_temp_new();
18030 gen_load_gpr(t1
, rs
);
18031 gen_load_gpr(t2
, rt
);
18032 tcg_gen_add_tl(t0
, t1
, t2
);
18033 tcg_gen_ext32s_tl(t0
, t0
);
18034 tcg_gen_xor_tl(t1
, t1
, t2
);
18035 tcg_gen_xor_tl(t2
, t0
, t2
);
18036 tcg_gen_andc_tl(t1
, t2
, t1
);
18038 /* operands of same sign, result different sign */
18039 tcg_gen_setcondi_tl(TCG_COND_LT
, t0
, t1
, 0);
18040 gen_store_gpr(t0
, rd
);
18048 gen_r6_muldiv(ctx
, R6_OPC_MUL
, rd
, rs
, rt
);
18051 gen_r6_muldiv(ctx
, R6_OPC_MUH
, rd
, rs
, rt
);
18054 gen_r6_muldiv(ctx
, R6_OPC_MULU
, rd
, rs
, rt
);
18057 gen_r6_muldiv(ctx
, R6_OPC_MUHU
, rd
, rs
, rt
);
18060 gen_r6_muldiv(ctx
, R6_OPC_DIV
, rd
, rs
, rt
);
18063 gen_r6_muldiv(ctx
, R6_OPC_MOD
, rd
, rs
, rt
);
18066 gen_r6_muldiv(ctx
, R6_OPC_DIVU
, rd
, rs
, rt
);
18069 gen_r6_muldiv(ctx
, R6_OPC_MODU
, rd
, rs
, rt
);
18071 #ifndef CONFIG_USER_ONLY
18073 check_cp0_enabled(ctx
);
18075 /* Treat as NOP. */
18078 gen_mfc0(ctx
, cpu_gpr
[rt
], rs
, extract32(ctx
->opcode
, 11, 3));
18081 check_cp0_enabled(ctx
);
18083 TCGv t0
= tcg_temp_new();
18085 gen_load_gpr(t0
, rt
);
18086 gen_mtc0(ctx
, t0
, rs
, extract32(ctx
->opcode
, 11, 3));
18090 case NM_D_E_MT_VPE
:
18092 uint8_t sc
= extract32(ctx
->opcode
, 10, 1);
18093 TCGv t0
= tcg_temp_new();
18100 gen_helper_dmt(t0
);
18101 gen_store_gpr(t0
, rt
);
18102 } else if (rs
== 0) {
18105 gen_helper_dvpe(t0
, cpu_env
);
18106 gen_store_gpr(t0
, rt
);
18108 gen_reserved_instruction(ctx
);
18115 gen_helper_emt(t0
);
18116 gen_store_gpr(t0
, rt
);
18117 } else if (rs
== 0) {
18120 gen_helper_evpe(t0
, cpu_env
);
18121 gen_store_gpr(t0
, rt
);
18123 gen_reserved_instruction(ctx
);
18134 TCGv t0
= tcg_temp_new();
18135 TCGv t1
= tcg_temp_new();
18137 gen_load_gpr(t0
, rt
);
18138 gen_load_gpr(t1
, rs
);
18139 gen_helper_fork(t0
, t1
);
18146 check_cp0_enabled(ctx
);
18148 /* Treat as NOP. */
18151 gen_mftr(env
, ctx
, rs
, rt
, extract32(ctx
->opcode
, 10, 1),
18152 extract32(ctx
->opcode
, 11, 5), extract32(ctx
->opcode
, 3, 1));
18156 check_cp0_enabled(ctx
);
18157 gen_mttr(env
, ctx
, rs
, rt
, extract32(ctx
->opcode
, 10, 1),
18158 extract32(ctx
->opcode
, 11, 5), extract32(ctx
->opcode
, 3, 1));
18163 TCGv t0
= tcg_temp_new();
18165 gen_load_gpr(t0
, rs
);
18166 gen_helper_yield(t0
, cpu_env
, t0
);
18167 gen_store_gpr(t0
, rt
);
18173 gen_reserved_instruction(ctx
);
18179 static void gen_pool32axf_1_5_nanomips_insn(DisasContext
*ctx
, uint32_t opc
,
18180 int ret
, int v1
, int v2
)
18186 t0
= tcg_temp_new_i32();
18188 v0_t
= tcg_temp_new();
18189 v1_t
= tcg_temp_new();
18191 tcg_gen_movi_i32(t0
, v2
>> 3);
18193 gen_load_gpr(v0_t
, ret
);
18194 gen_load_gpr(v1_t
, v1
);
18197 case NM_MAQ_S_W_PHR
:
18199 gen_helper_maq_s_w_phr(t0
, v1_t
, v0_t
, cpu_env
);
18201 case NM_MAQ_S_W_PHL
:
18203 gen_helper_maq_s_w_phl(t0
, v1_t
, v0_t
, cpu_env
);
18205 case NM_MAQ_SA_W_PHR
:
18207 gen_helper_maq_sa_w_phr(t0
, v1_t
, v0_t
, cpu_env
);
18209 case NM_MAQ_SA_W_PHL
:
18211 gen_helper_maq_sa_w_phl(t0
, v1_t
, v0_t
, cpu_env
);
18214 gen_reserved_instruction(ctx
);
18218 tcg_temp_free_i32(t0
);
18220 tcg_temp_free(v0_t
);
18221 tcg_temp_free(v1_t
);
18225 static void gen_pool32axf_1_nanomips_insn(DisasContext
*ctx
, uint32_t opc
,
18226 int ret
, int v1
, int v2
)
18229 TCGv t0
= tcg_temp_new();
18230 TCGv t1
= tcg_temp_new();
18231 TCGv v0_t
= tcg_temp_new();
18233 gen_load_gpr(v0_t
, v1
);
18236 case NM_POOL32AXF_1_0
:
18238 switch (extract32(ctx
->opcode
, 12, 2)) {
18240 gen_HILO(ctx
, OPC_MFHI
, v2
>> 3, ret
);
18243 gen_HILO(ctx
, OPC_MFLO
, v2
>> 3, ret
);
18246 gen_HILO(ctx
, OPC_MTHI
, v2
>> 3, v1
);
18249 gen_HILO(ctx
, OPC_MTLO
, v2
>> 3, v1
);
18253 case NM_POOL32AXF_1_1
:
18255 switch (extract32(ctx
->opcode
, 12, 2)) {
18257 tcg_gen_movi_tl(t0
, v2
);
18258 gen_helper_mthlip(t0
, v0_t
, cpu_env
);
18261 tcg_gen_movi_tl(t0
, v2
>> 3);
18262 gen_helper_shilo(t0
, v0_t
, cpu_env
);
18265 gen_reserved_instruction(ctx
);
18269 case NM_POOL32AXF_1_3
:
18271 imm
= extract32(ctx
->opcode
, 14, 7);
18272 switch (extract32(ctx
->opcode
, 12, 2)) {
18274 tcg_gen_movi_tl(t0
, imm
);
18275 gen_helper_rddsp(t0
, t0
, cpu_env
);
18276 gen_store_gpr(t0
, ret
);
18279 gen_load_gpr(t0
, ret
);
18280 tcg_gen_movi_tl(t1
, imm
);
18281 gen_helper_wrdsp(t0
, t1
, cpu_env
);
18284 tcg_gen_movi_tl(t0
, v2
>> 3);
18285 tcg_gen_movi_tl(t1
, v1
);
18286 gen_helper_extp(t0
, t0
, t1
, cpu_env
);
18287 gen_store_gpr(t0
, ret
);
18290 tcg_gen_movi_tl(t0
, v2
>> 3);
18291 tcg_gen_movi_tl(t1
, v1
);
18292 gen_helper_extpdp(t0
, t0
, t1
, cpu_env
);
18293 gen_store_gpr(t0
, ret
);
18297 case NM_POOL32AXF_1_4
:
18299 tcg_gen_movi_tl(t0
, v2
>> 2);
18300 switch (extract32(ctx
->opcode
, 12, 1)) {
18302 gen_helper_shll_qb(t0
, t0
, v0_t
, cpu_env
);
18303 gen_store_gpr(t0
, ret
);
18306 gen_helper_shrl_qb(t0
, t0
, v0_t
);
18307 gen_store_gpr(t0
, ret
);
18311 case NM_POOL32AXF_1_5
:
18312 opc
= extract32(ctx
->opcode
, 12, 2);
18313 gen_pool32axf_1_5_nanomips_insn(ctx
, opc
, ret
, v1
, v2
);
18315 case NM_POOL32AXF_1_7
:
18317 tcg_gen_movi_tl(t0
, v2
>> 3);
18318 tcg_gen_movi_tl(t1
, v1
);
18319 switch (extract32(ctx
->opcode
, 12, 2)) {
18321 gen_helper_extr_w(t0
, t0
, t1
, cpu_env
);
18322 gen_store_gpr(t0
, ret
);
18325 gen_helper_extr_r_w(t0
, t0
, t1
, cpu_env
);
18326 gen_store_gpr(t0
, ret
);
18329 gen_helper_extr_rs_w(t0
, t0
, t1
, cpu_env
);
18330 gen_store_gpr(t0
, ret
);
18333 gen_helper_extr_s_h(t0
, t0
, t1
, cpu_env
);
18334 gen_store_gpr(t0
, ret
);
18339 gen_reserved_instruction(ctx
);
18345 tcg_temp_free(v0_t
);
18348 static void gen_pool32axf_2_multiply(DisasContext
*ctx
, uint32_t opc
,
18349 TCGv v0
, TCGv v1
, int rd
)
18353 t0
= tcg_temp_new_i32();
18355 tcg_gen_movi_i32(t0
, rd
>> 3);
18358 case NM_POOL32AXF_2_0_7
:
18359 switch (extract32(ctx
->opcode
, 9, 3)) {
18362 gen_helper_dpa_w_ph(t0
, v1
, v0
, cpu_env
);
18364 case NM_DPAQ_S_W_PH
:
18366 gen_helper_dpaq_s_w_ph(t0
, v1
, v0
, cpu_env
);
18370 gen_helper_dps_w_ph(t0
, v1
, v0
, cpu_env
);
18372 case NM_DPSQ_S_W_PH
:
18374 gen_helper_dpsq_s_w_ph(t0
, v1
, v0
, cpu_env
);
18377 gen_reserved_instruction(ctx
);
18381 case NM_POOL32AXF_2_8_15
:
18382 switch (extract32(ctx
->opcode
, 9, 3)) {
18385 gen_helper_dpax_w_ph(t0
, v0
, v1
, cpu_env
);
18387 case NM_DPAQ_SA_L_W
:
18389 gen_helper_dpaq_sa_l_w(t0
, v0
, v1
, cpu_env
);
18393 gen_helper_dpsx_w_ph(t0
, v0
, v1
, cpu_env
);
18395 case NM_DPSQ_SA_L_W
:
18397 gen_helper_dpsq_sa_l_w(t0
, v0
, v1
, cpu_env
);
18400 gen_reserved_instruction(ctx
);
18404 case NM_POOL32AXF_2_16_23
:
18405 switch (extract32(ctx
->opcode
, 9, 3)) {
18406 case NM_DPAU_H_QBL
:
18408 gen_helper_dpau_h_qbl(t0
, v0
, v1
, cpu_env
);
18410 case NM_DPAQX_S_W_PH
:
18412 gen_helper_dpaqx_s_w_ph(t0
, v0
, v1
, cpu_env
);
18414 case NM_DPSU_H_QBL
:
18416 gen_helper_dpsu_h_qbl(t0
, v0
, v1
, cpu_env
);
18418 case NM_DPSQX_S_W_PH
:
18420 gen_helper_dpsqx_s_w_ph(t0
, v0
, v1
, cpu_env
);
18422 case NM_MULSA_W_PH
:
18424 gen_helper_mulsa_w_ph(t0
, v0
, v1
, cpu_env
);
18427 gen_reserved_instruction(ctx
);
18431 case NM_POOL32AXF_2_24_31
:
18432 switch (extract32(ctx
->opcode
, 9, 3)) {
18433 case NM_DPAU_H_QBR
:
18435 gen_helper_dpau_h_qbr(t0
, v1
, v0
, cpu_env
);
18437 case NM_DPAQX_SA_W_PH
:
18439 gen_helper_dpaqx_sa_w_ph(t0
, v1
, v0
, cpu_env
);
18441 case NM_DPSU_H_QBR
:
18443 gen_helper_dpsu_h_qbr(t0
, v1
, v0
, cpu_env
);
18445 case NM_DPSQX_SA_W_PH
:
18447 gen_helper_dpsqx_sa_w_ph(t0
, v1
, v0
, cpu_env
);
18449 case NM_MULSAQ_S_W_PH
:
18451 gen_helper_mulsaq_s_w_ph(t0
, v1
, v0
, cpu_env
);
18454 gen_reserved_instruction(ctx
);
18459 gen_reserved_instruction(ctx
);
18463 tcg_temp_free_i32(t0
);
18466 static void gen_pool32axf_2_nanomips_insn(DisasContext
*ctx
, uint32_t opc
,
18467 int rt
, int rs
, int rd
)
18470 TCGv t0
= tcg_temp_new();
18471 TCGv t1
= tcg_temp_new();
18472 TCGv v0_t
= tcg_temp_new();
18473 TCGv v1_t
= tcg_temp_new();
18475 gen_load_gpr(v0_t
, rt
);
18476 gen_load_gpr(v1_t
, rs
);
18479 case NM_POOL32AXF_2_0_7
:
18480 switch (extract32(ctx
->opcode
, 9, 3)) {
18482 case NM_DPAQ_S_W_PH
:
18484 case NM_DPSQ_S_W_PH
:
18485 gen_pool32axf_2_multiply(ctx
, opc
, v0_t
, v1_t
, rd
);
18490 gen_load_gpr(t0
, rs
);
18492 if (rd
!= 0 && rd
!= 2) {
18493 tcg_gen_shli_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], 8 * rd
);
18494 tcg_gen_ext32u_tl(t0
, t0
);
18495 tcg_gen_shri_tl(t0
, t0
, 8 * (4 - rd
));
18496 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
18498 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
18504 int acc
= extract32(ctx
->opcode
, 14, 2);
18505 TCGv_i64 t2
= tcg_temp_new_i64();
18506 TCGv_i64 t3
= tcg_temp_new_i64();
18508 gen_load_gpr(t0
, rt
);
18509 gen_load_gpr(t1
, rs
);
18510 tcg_gen_ext_tl_i64(t2
, t0
);
18511 tcg_gen_ext_tl_i64(t3
, t1
);
18512 tcg_gen_mul_i64(t2
, t2
, t3
);
18513 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
18514 tcg_gen_add_i64(t2
, t2
, t3
);
18515 tcg_temp_free_i64(t3
);
18516 gen_move_low32(cpu_LO
[acc
], t2
);
18517 gen_move_high32(cpu_HI
[acc
], t2
);
18518 tcg_temp_free_i64(t2
);
18524 int acc
= extract32(ctx
->opcode
, 14, 2);
18525 TCGv_i32 t2
= tcg_temp_new_i32();
18526 TCGv_i32 t3
= tcg_temp_new_i32();
18528 gen_load_gpr(t0
, rs
);
18529 gen_load_gpr(t1
, rt
);
18530 tcg_gen_trunc_tl_i32(t2
, t0
);
18531 tcg_gen_trunc_tl_i32(t3
, t1
);
18532 tcg_gen_muls2_i32(t2
, t3
, t2
, t3
);
18533 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
18534 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
18535 tcg_temp_free_i32(t2
);
18536 tcg_temp_free_i32(t3
);
18541 gen_load_gpr(v1_t
, rs
);
18542 tcg_gen_movi_tl(t0
, rd
>> 3);
18543 gen_helper_extr_w(t0
, t0
, v1_t
, cpu_env
);
18544 gen_store_gpr(t0
, ret
);
18548 case NM_POOL32AXF_2_8_15
:
18549 switch (extract32(ctx
->opcode
, 9, 3)) {
18551 case NM_DPAQ_SA_L_W
:
18553 case NM_DPSQ_SA_L_W
:
18554 gen_pool32axf_2_multiply(ctx
, opc
, v0_t
, v1_t
, rd
);
18559 int acc
= extract32(ctx
->opcode
, 14, 2);
18560 TCGv_i64 t2
= tcg_temp_new_i64();
18561 TCGv_i64 t3
= tcg_temp_new_i64();
18563 gen_load_gpr(t0
, rs
);
18564 gen_load_gpr(t1
, rt
);
18565 tcg_gen_ext32u_tl(t0
, t0
);
18566 tcg_gen_ext32u_tl(t1
, t1
);
18567 tcg_gen_extu_tl_i64(t2
, t0
);
18568 tcg_gen_extu_tl_i64(t3
, t1
);
18569 tcg_gen_mul_i64(t2
, t2
, t3
);
18570 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
18571 tcg_gen_add_i64(t2
, t2
, t3
);
18572 tcg_temp_free_i64(t3
);
18573 gen_move_low32(cpu_LO
[acc
], t2
);
18574 gen_move_high32(cpu_HI
[acc
], t2
);
18575 tcg_temp_free_i64(t2
);
18581 int acc
= extract32(ctx
->opcode
, 14, 2);
18582 TCGv_i32 t2
= tcg_temp_new_i32();
18583 TCGv_i32 t3
= tcg_temp_new_i32();
18585 gen_load_gpr(t0
, rs
);
18586 gen_load_gpr(t1
, rt
);
18587 tcg_gen_trunc_tl_i32(t2
, t0
);
18588 tcg_gen_trunc_tl_i32(t3
, t1
);
18589 tcg_gen_mulu2_i32(t2
, t3
, t2
, t3
);
18590 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
18591 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
18592 tcg_temp_free_i32(t2
);
18593 tcg_temp_free_i32(t3
);
18598 tcg_gen_movi_tl(t0
, rd
>> 3);
18599 gen_helper_extr_r_w(t0
, t0
, v1_t
, cpu_env
);
18600 gen_store_gpr(t0
, ret
);
18603 gen_reserved_instruction(ctx
);
18607 case NM_POOL32AXF_2_16_23
:
18608 switch (extract32(ctx
->opcode
, 9, 3)) {
18609 case NM_DPAU_H_QBL
:
18610 case NM_DPAQX_S_W_PH
:
18611 case NM_DPSU_H_QBL
:
18612 case NM_DPSQX_S_W_PH
:
18613 case NM_MULSA_W_PH
:
18614 gen_pool32axf_2_multiply(ctx
, opc
, v0_t
, v1_t
, rd
);
18618 tcg_gen_movi_tl(t0
, rd
>> 3);
18619 gen_helper_extp(t0
, t0
, v1_t
, cpu_env
);
18620 gen_store_gpr(t0
, ret
);
18625 int acc
= extract32(ctx
->opcode
, 14, 2);
18626 TCGv_i64 t2
= tcg_temp_new_i64();
18627 TCGv_i64 t3
= tcg_temp_new_i64();
18629 gen_load_gpr(t0
, rs
);
18630 gen_load_gpr(t1
, rt
);
18631 tcg_gen_ext_tl_i64(t2
, t0
);
18632 tcg_gen_ext_tl_i64(t3
, t1
);
18633 tcg_gen_mul_i64(t2
, t2
, t3
);
18634 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
18635 tcg_gen_sub_i64(t2
, t3
, t2
);
18636 tcg_temp_free_i64(t3
);
18637 gen_move_low32(cpu_LO
[acc
], t2
);
18638 gen_move_high32(cpu_HI
[acc
], t2
);
18639 tcg_temp_free_i64(t2
);
18642 case NM_EXTRV_RS_W
:
18644 tcg_gen_movi_tl(t0
, rd
>> 3);
18645 gen_helper_extr_rs_w(t0
, t0
, v1_t
, cpu_env
);
18646 gen_store_gpr(t0
, ret
);
18650 case NM_POOL32AXF_2_24_31
:
18651 switch (extract32(ctx
->opcode
, 9, 3)) {
18652 case NM_DPAU_H_QBR
:
18653 case NM_DPAQX_SA_W_PH
:
18654 case NM_DPSU_H_QBR
:
18655 case NM_DPSQX_SA_W_PH
:
18656 case NM_MULSAQ_S_W_PH
:
18657 gen_pool32axf_2_multiply(ctx
, opc
, v0_t
, v1_t
, rd
);
18661 tcg_gen_movi_tl(t0
, rd
>> 3);
18662 gen_helper_extpdp(t0
, t0
, v1_t
, cpu_env
);
18663 gen_store_gpr(t0
, ret
);
18668 int acc
= extract32(ctx
->opcode
, 14, 2);
18669 TCGv_i64 t2
= tcg_temp_new_i64();
18670 TCGv_i64 t3
= tcg_temp_new_i64();
18672 gen_load_gpr(t0
, rs
);
18673 gen_load_gpr(t1
, rt
);
18674 tcg_gen_ext32u_tl(t0
, t0
);
18675 tcg_gen_ext32u_tl(t1
, t1
);
18676 tcg_gen_extu_tl_i64(t2
, t0
);
18677 tcg_gen_extu_tl_i64(t3
, t1
);
18678 tcg_gen_mul_i64(t2
, t2
, t3
);
18679 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
18680 tcg_gen_sub_i64(t2
, t3
, t2
);
18681 tcg_temp_free_i64(t3
);
18682 gen_move_low32(cpu_LO
[acc
], t2
);
18683 gen_move_high32(cpu_HI
[acc
], t2
);
18684 tcg_temp_free_i64(t2
);
18689 tcg_gen_movi_tl(t0
, rd
>> 3);
18690 gen_helper_extr_s_h(t0
, t0
, v0_t
, cpu_env
);
18691 gen_store_gpr(t0
, ret
);
18696 gen_reserved_instruction(ctx
);
18703 tcg_temp_free(v0_t
);
18704 tcg_temp_free(v1_t
);
18707 static void gen_pool32axf_4_nanomips_insn(DisasContext
*ctx
, uint32_t opc
,
18711 TCGv t0
= tcg_temp_new();
18712 TCGv v0_t
= tcg_temp_new();
18714 gen_load_gpr(v0_t
, rs
);
18719 gen_helper_absq_s_qb(v0_t
, v0_t
, cpu_env
);
18720 gen_store_gpr(v0_t
, ret
);
18724 gen_helper_absq_s_ph(v0_t
, v0_t
, cpu_env
);
18725 gen_store_gpr(v0_t
, ret
);
18729 gen_helper_absq_s_w(v0_t
, v0_t
, cpu_env
);
18730 gen_store_gpr(v0_t
, ret
);
18732 case NM_PRECEQ_W_PHL
:
18734 tcg_gen_andi_tl(v0_t
, v0_t
, 0xFFFF0000);
18735 tcg_gen_ext32s_tl(v0_t
, v0_t
);
18736 gen_store_gpr(v0_t
, ret
);
18738 case NM_PRECEQ_W_PHR
:
18740 tcg_gen_andi_tl(v0_t
, v0_t
, 0x0000FFFF);
18741 tcg_gen_shli_tl(v0_t
, v0_t
, 16);
18742 tcg_gen_ext32s_tl(v0_t
, v0_t
);
18743 gen_store_gpr(v0_t
, ret
);
18745 case NM_PRECEQU_PH_QBL
:
18747 gen_helper_precequ_ph_qbl(v0_t
, v0_t
);
18748 gen_store_gpr(v0_t
, ret
);
18750 case NM_PRECEQU_PH_QBR
:
18752 gen_helper_precequ_ph_qbr(v0_t
, v0_t
);
18753 gen_store_gpr(v0_t
, ret
);
18755 case NM_PRECEQU_PH_QBLA
:
18757 gen_helper_precequ_ph_qbla(v0_t
, v0_t
);
18758 gen_store_gpr(v0_t
, ret
);
18760 case NM_PRECEQU_PH_QBRA
:
18762 gen_helper_precequ_ph_qbra(v0_t
, v0_t
);
18763 gen_store_gpr(v0_t
, ret
);
18765 case NM_PRECEU_PH_QBL
:
18767 gen_helper_preceu_ph_qbl(v0_t
, v0_t
);
18768 gen_store_gpr(v0_t
, ret
);
18770 case NM_PRECEU_PH_QBR
:
18772 gen_helper_preceu_ph_qbr(v0_t
, v0_t
);
18773 gen_store_gpr(v0_t
, ret
);
18775 case NM_PRECEU_PH_QBLA
:
18777 gen_helper_preceu_ph_qbla(v0_t
, v0_t
);
18778 gen_store_gpr(v0_t
, ret
);
18780 case NM_PRECEU_PH_QBRA
:
18782 gen_helper_preceu_ph_qbra(v0_t
, v0_t
);
18783 gen_store_gpr(v0_t
, ret
);
18787 tcg_gen_ext16u_tl(v0_t
, v0_t
);
18788 tcg_gen_shli_tl(t0
, v0_t
, 16);
18789 tcg_gen_or_tl(v0_t
, v0_t
, t0
);
18790 tcg_gen_ext32s_tl(v0_t
, v0_t
);
18791 gen_store_gpr(v0_t
, ret
);
18795 tcg_gen_ext8u_tl(v0_t
, v0_t
);
18796 tcg_gen_shli_tl(t0
, v0_t
, 8);
18797 tcg_gen_or_tl(v0_t
, v0_t
, t0
);
18798 tcg_gen_shli_tl(t0
, v0_t
, 16);
18799 tcg_gen_or_tl(v0_t
, v0_t
, t0
);
18800 tcg_gen_ext32s_tl(v0_t
, v0_t
);
18801 gen_store_gpr(v0_t
, ret
);
18805 gen_helper_bitrev(v0_t
, v0_t
);
18806 gen_store_gpr(v0_t
, ret
);
18811 TCGv tv0
= tcg_temp_new();
18813 gen_load_gpr(tv0
, rt
);
18814 gen_helper_insv(v0_t
, cpu_env
, v0_t
, tv0
);
18815 gen_store_gpr(v0_t
, ret
);
18816 tcg_temp_free(tv0
);
18819 case NM_RADDU_W_QB
:
18821 gen_helper_raddu_w_qb(v0_t
, v0_t
);
18822 gen_store_gpr(v0_t
, ret
);
18825 gen_bitswap(ctx
, OPC_BITSWAP
, ret
, rs
);
18829 gen_cl(ctx
, OPC_CLO
, ret
, rs
);
18833 gen_cl(ctx
, OPC_CLZ
, ret
, rs
);
18836 gen_bshfl(ctx
, OPC_WSBH
, ret
, rs
);
18839 gen_reserved_instruction(ctx
);
18843 tcg_temp_free(v0_t
);
18847 static void gen_pool32axf_7_nanomips_insn(DisasContext
*ctx
, uint32_t opc
,
18848 int rt
, int rs
, int rd
)
18850 TCGv t0
= tcg_temp_new();
18851 TCGv rs_t
= tcg_temp_new();
18853 gen_load_gpr(rs_t
, rs
);
18858 tcg_gen_movi_tl(t0
, rd
>> 2);
18859 switch (extract32(ctx
->opcode
, 12, 1)) {
18862 gen_helper_shra_qb(t0
, t0
, rs_t
);
18863 gen_store_gpr(t0
, rt
);
18867 gen_helper_shra_r_qb(t0
, t0
, rs_t
);
18868 gen_store_gpr(t0
, rt
);
18874 tcg_gen_movi_tl(t0
, rd
>> 1);
18875 gen_helper_shrl_ph(t0
, t0
, rs_t
);
18876 gen_store_gpr(t0
, rt
);
18882 target_long result
;
18883 imm
= extract32(ctx
->opcode
, 13, 8);
18884 result
= (uint32_t)imm
<< 24 |
18885 (uint32_t)imm
<< 16 |
18886 (uint32_t)imm
<< 8 |
18888 result
= (int32_t)result
;
18889 tcg_gen_movi_tl(t0
, result
);
18890 gen_store_gpr(t0
, rt
);
18894 gen_reserved_instruction(ctx
);
18898 tcg_temp_free(rs_t
);
18902 static void gen_pool32axf_nanomips_insn(CPUMIPSState
*env
, DisasContext
*ctx
)
18904 int rt
= extract32(ctx
->opcode
, 21, 5);
18905 int rs
= extract32(ctx
->opcode
, 16, 5);
18906 int rd
= extract32(ctx
->opcode
, 11, 5);
18908 switch (extract32(ctx
->opcode
, 6, 3)) {
18909 case NM_POOL32AXF_1
:
18911 int32_t op1
= extract32(ctx
->opcode
, 9, 3);
18912 gen_pool32axf_1_nanomips_insn(ctx
, op1
, rt
, rs
, rd
);
18915 case NM_POOL32AXF_2
:
18917 int32_t op1
= extract32(ctx
->opcode
, 12, 2);
18918 gen_pool32axf_2_nanomips_insn(ctx
, op1
, rt
, rs
, rd
);
18921 case NM_POOL32AXF_4
:
18923 int32_t op1
= extract32(ctx
->opcode
, 9, 7);
18924 gen_pool32axf_4_nanomips_insn(ctx
, op1
, rt
, rs
);
18927 case NM_POOL32AXF_5
:
18928 switch (extract32(ctx
->opcode
, 9, 7)) {
18929 #ifndef CONFIG_USER_ONLY
18931 gen_cp0(env
, ctx
, OPC_TLBP
, 0, 0);
18934 gen_cp0(env
, ctx
, OPC_TLBR
, 0, 0);
18937 gen_cp0(env
, ctx
, OPC_TLBWI
, 0, 0);
18940 gen_cp0(env
, ctx
, OPC_TLBWR
, 0, 0);
18943 gen_cp0(env
, ctx
, OPC_TLBINV
, 0, 0);
18946 gen_cp0(env
, ctx
, OPC_TLBINVF
, 0, 0);
18949 check_cp0_enabled(ctx
);
18951 TCGv t0
= tcg_temp_new();
18953 save_cpu_state(ctx
, 1);
18954 gen_helper_di(t0
, cpu_env
);
18955 gen_store_gpr(t0
, rt
);
18956 /* Stop translation as we may have switched the execution mode */
18957 ctx
->base
.is_jmp
= DISAS_STOP
;
18962 check_cp0_enabled(ctx
);
18964 TCGv t0
= tcg_temp_new();
18966 save_cpu_state(ctx
, 1);
18967 gen_helper_ei(t0
, cpu_env
);
18968 gen_store_gpr(t0
, rt
);
18969 /* Stop translation as we may have switched the execution mode */
18970 ctx
->base
.is_jmp
= DISAS_STOP
;
18975 check_cp0_enabled(ctx
);
18976 gen_load_srsgpr(rs
, rt
);
18979 check_cp0_enabled(ctx
);
18980 gen_store_srsgpr(rs
, rt
);
18983 gen_cp0(env
, ctx
, OPC_WAIT
, 0, 0);
18986 gen_cp0(env
, ctx
, OPC_DERET
, 0, 0);
18989 gen_cp0(env
, ctx
, OPC_ERET
, 0, 0);
18993 gen_reserved_instruction(ctx
);
18997 case NM_POOL32AXF_7
:
18999 int32_t op1
= extract32(ctx
->opcode
, 9, 3);
19000 gen_pool32axf_7_nanomips_insn(ctx
, op1
, rt
, rs
, rd
);
19004 gen_reserved_instruction(ctx
);
19009 /* Immediate Value Compact Branches */
19010 static void gen_compute_imm_branch(DisasContext
*ctx
, uint32_t opc
,
19011 int rt
, int32_t imm
, int32_t offset
)
19013 TCGCond cond
= TCG_COND_ALWAYS
;
19014 TCGv t0
= tcg_temp_new();
19015 TCGv t1
= tcg_temp_new();
19017 gen_load_gpr(t0
, rt
);
19018 tcg_gen_movi_tl(t1
, imm
);
19019 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
19021 /* Load needed operands and calculate btarget */
19024 if (rt
== 0 && imm
== 0) {
19025 /* Unconditional branch */
19026 } else if (rt
== 0 && imm
!= 0) {
19030 cond
= TCG_COND_EQ
;
19036 if (imm
>= 32 && !(ctx
->hflags
& MIPS_HFLAG_64
)) {
19037 gen_reserved_instruction(ctx
);
19039 } else if (rt
== 0 && opc
== NM_BBEQZC
) {
19040 /* Unconditional branch */
19041 } else if (rt
== 0 && opc
== NM_BBNEZC
) {
19045 tcg_gen_shri_tl(t0
, t0
, imm
);
19046 tcg_gen_andi_tl(t0
, t0
, 1);
19047 tcg_gen_movi_tl(t1
, 0);
19048 if (opc
== NM_BBEQZC
) {
19049 cond
= TCG_COND_EQ
;
19051 cond
= TCG_COND_NE
;
19056 if (rt
== 0 && imm
== 0) {
19059 } else if (rt
== 0 && imm
!= 0) {
19060 /* Unconditional branch */
19062 cond
= TCG_COND_NE
;
19066 if (rt
== 0 && imm
== 0) {
19067 /* Unconditional branch */
19069 cond
= TCG_COND_GE
;
19073 cond
= TCG_COND_LT
;
19076 if (rt
== 0 && imm
== 0) {
19077 /* Unconditional branch */
19079 cond
= TCG_COND_GEU
;
19083 cond
= TCG_COND_LTU
;
19086 MIPS_INVAL("Immediate Value Compact branch");
19087 gen_reserved_instruction(ctx
);
19091 /* branch completion */
19092 clear_branch_hflags(ctx
);
19093 ctx
->base
.is_jmp
= DISAS_NORETURN
;
19095 if (cond
== TCG_COND_ALWAYS
) {
19096 /* Uncoditional compact branch */
19097 gen_goto_tb(ctx
, 0, ctx
->btarget
);
19099 /* Conditional compact branch */
19100 TCGLabel
*fs
= gen_new_label();
19102 tcg_gen_brcond_tl(tcg_invert_cond(cond
), t0
, t1
, fs
);
19104 gen_goto_tb(ctx
, 1, ctx
->btarget
);
19107 gen_goto_tb(ctx
, 0, ctx
->base
.pc_next
+ 4);
19115 /* P.BALRSC type nanoMIPS R6 branches: BALRSC and BRSC */
19116 static void gen_compute_nanomips_pbalrsc_branch(DisasContext
*ctx
, int rs
,
19119 TCGv t0
= tcg_temp_new();
19120 TCGv t1
= tcg_temp_new();
19123 gen_load_gpr(t0
, rs
);
19127 tcg_gen_movi_tl(cpu_gpr
[rt
], ctx
->base
.pc_next
+ 4);
19130 /* calculate btarget */
19131 tcg_gen_shli_tl(t0
, t0
, 1);
19132 tcg_gen_movi_tl(t1
, ctx
->base
.pc_next
+ 4);
19133 gen_op_addr_add(ctx
, btarget
, t1
, t0
);
19135 /* branch completion */
19136 clear_branch_hflags(ctx
);
19137 ctx
->base
.is_jmp
= DISAS_NORETURN
;
19139 /* unconditional branch to register */
19140 tcg_gen_mov_tl(cpu_PC
, btarget
);
19141 tcg_gen_lookup_and_goto_ptr();
19147 /* nanoMIPS Branches */
19148 static void gen_compute_compact_branch_nm(DisasContext
*ctx
, uint32_t opc
,
19149 int rs
, int rt
, int32_t offset
)
19151 int bcond_compute
= 0;
19152 TCGv t0
= tcg_temp_new();
19153 TCGv t1
= tcg_temp_new();
19155 /* Load needed operands and calculate btarget */
19157 /* compact branch */
19160 gen_load_gpr(t0
, rs
);
19161 gen_load_gpr(t1
, rt
);
19163 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
19167 if (rs
== 0 || rs
== rt
) {
19168 /* OPC_BLEZALC, OPC_BGEZALC */
19169 /* OPC_BGTZALC, OPC_BLTZALC */
19170 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 4);
19172 gen_load_gpr(t0
, rs
);
19173 gen_load_gpr(t1
, rt
);
19175 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
19178 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
19182 /* OPC_BEQZC, OPC_BNEZC */
19183 gen_load_gpr(t0
, rs
);
19185 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
19187 /* OPC_JIC, OPC_JIALC */
19188 TCGv tbase
= tcg_temp_new();
19189 TCGv toffset
= tcg_temp_new();
19191 gen_load_gpr(tbase
, rt
);
19192 tcg_gen_movi_tl(toffset
, offset
);
19193 gen_op_addr_add(ctx
, btarget
, tbase
, toffset
);
19194 tcg_temp_free(tbase
);
19195 tcg_temp_free(toffset
);
19199 MIPS_INVAL("Compact branch/jump");
19200 gen_reserved_instruction(ctx
);
19204 if (bcond_compute
== 0) {
19205 /* Uncoditional compact branch */
19208 gen_goto_tb(ctx
, 0, ctx
->btarget
);
19211 MIPS_INVAL("Compact branch/jump");
19212 gen_reserved_instruction(ctx
);
19216 /* Conditional compact branch */
19217 TCGLabel
*fs
= gen_new_label();
19221 if (rs
== 0 && rt
!= 0) {
19223 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE
), t1
, 0, fs
);
19224 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
19226 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE
), t1
, 0, fs
);
19229 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU
), t0
, t1
, fs
);
19233 if (rs
== 0 && rt
!= 0) {
19235 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT
), t1
, 0, fs
);
19236 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
19238 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT
), t1
, 0, fs
);
19241 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU
), t0
, t1
, fs
);
19245 if (rs
== 0 && rt
!= 0) {
19247 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE
), t1
, 0, fs
);
19248 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
19250 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE
), t1
, 0, fs
);
19253 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE
), t0
, t1
, fs
);
19257 if (rs
== 0 && rt
!= 0) {
19259 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT
), t1
, 0, fs
);
19260 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
19262 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT
), t1
, 0, fs
);
19265 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT
), t0
, t1
, fs
);
19269 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ
), t0
, 0, fs
);
19272 MIPS_INVAL("Compact conditional branch/jump");
19273 gen_reserved_instruction(ctx
);
19277 /* branch completion */
19278 clear_branch_hflags(ctx
);
19279 ctx
->base
.is_jmp
= DISAS_NORETURN
;
19281 /* Generating branch here as compact branches don't have delay slot */
19282 gen_goto_tb(ctx
, 1, ctx
->btarget
);
19285 gen_goto_tb(ctx
, 0, ctx
->base
.pc_next
+ 4);
19294 /* nanoMIPS CP1 Branches */
19295 static void gen_compute_branch_cp1_nm(DisasContext
*ctx
, uint32_t op
,
19296 int32_t ft
, int32_t offset
)
19298 target_ulong btarget
;
19299 TCGv_i64 t0
= tcg_temp_new_i64();
19301 gen_load_fpr64(ctx
, t0
, ft
);
19302 tcg_gen_andi_i64(t0
, t0
, 1);
19304 btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
19308 tcg_gen_xori_i64(t0
, t0
, 1);
19309 ctx
->hflags
|= MIPS_HFLAG_BC
;
19312 /* t0 already set */
19313 ctx
->hflags
|= MIPS_HFLAG_BC
;
19316 MIPS_INVAL("cp1 cond branch");
19317 gen_reserved_instruction(ctx
);
19321 tcg_gen_trunc_i64_tl(bcond
, t0
);
19323 ctx
->btarget
= btarget
;
19326 tcg_temp_free_i64(t0
);
19330 static void gen_p_lsx(DisasContext
*ctx
, int rd
, int rs
, int rt
)
19333 t0
= tcg_temp_new();
19334 t1
= tcg_temp_new();
19336 gen_load_gpr(t0
, rs
);
19337 gen_load_gpr(t1
, rt
);
19339 if ((extract32(ctx
->opcode
, 6, 1)) == 1) {
19340 /* PP.LSXS instructions require shifting */
19341 switch (extract32(ctx
->opcode
, 7, 4)) {
19347 tcg_gen_shli_tl(t0
, t0
, 1);
19355 tcg_gen_shli_tl(t0
, t0
, 2);
19359 tcg_gen_shli_tl(t0
, t0
, 3);
19363 gen_op_addr_add(ctx
, t0
, t0
, t1
);
19365 switch (extract32(ctx
->opcode
, 7, 4)) {
19367 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
,
19369 gen_store_gpr(t0
, rd
);
19373 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
,
19375 gen_store_gpr(t0
, rd
);
19379 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
,
19381 gen_store_gpr(t0
, rd
);
19384 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
,
19386 gen_store_gpr(t0
, rd
);
19390 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
,
19392 gen_store_gpr(t0
, rd
);
19396 gen_load_gpr(t1
, rd
);
19397 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
,
19403 gen_load_gpr(t1
, rd
);
19404 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
,
19410 gen_load_gpr(t1
, rd
);
19411 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
,
19415 /*case NM_LWC1XS:*/
19417 /*case NM_LDC1XS:*/
19419 /*case NM_SWC1XS:*/
19421 /*case NM_SDC1XS:*/
19422 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
19423 check_cp1_enabled(ctx
);
19424 switch (extract32(ctx
->opcode
, 7, 4)) {
19426 /*case NM_LWC1XS:*/
19427 gen_flt_ldst(ctx
, OPC_LWC1
, rd
, t0
);
19430 /*case NM_LDC1XS:*/
19431 gen_flt_ldst(ctx
, OPC_LDC1
, rd
, t0
);
19434 /*case NM_SWC1XS:*/
19435 gen_flt_ldst(ctx
, OPC_SWC1
, rd
, t0
);
19438 /*case NM_SDC1XS:*/
19439 gen_flt_ldst(ctx
, OPC_SDC1
, rd
, t0
);
19443 generate_exception_err(ctx
, EXCP_CpU
, 1);
19447 gen_reserved_instruction(ctx
);
19455 static void gen_pool32f_nanomips_insn(DisasContext
*ctx
)
19459 rt
= extract32(ctx
->opcode
, 21, 5);
19460 rs
= extract32(ctx
->opcode
, 16, 5);
19461 rd
= extract32(ctx
->opcode
, 11, 5);
19463 if (!(ctx
->CP0_Config1
& (1 << CP0C1_FP
))) {
19464 gen_reserved_instruction(ctx
);
19467 check_cp1_enabled(ctx
);
19468 switch (extract32(ctx
->opcode
, 0, 3)) {
19470 switch (extract32(ctx
->opcode
, 3, 7)) {
19472 gen_farith(ctx
, OPC_RINT_S
, 0, rt
, rs
, 0);
19475 gen_farith(ctx
, OPC_RINT_D
, 0, rt
, rs
, 0);
19478 gen_farith(ctx
, OPC_CLASS_S
, 0, rt
, rs
, 0);
19481 gen_farith(ctx
, OPC_CLASS_D
, 0, rt
, rs
, 0);
19484 gen_farith(ctx
, OPC_ADD_S
, rt
, rs
, rd
, 0);
19487 gen_farith(ctx
, OPC_ADD_D
, rt
, rs
, rd
, 0);
19490 gen_farith(ctx
, OPC_SUB_S
, rt
, rs
, rd
, 0);
19493 gen_farith(ctx
, OPC_SUB_D
, rt
, rs
, rd
, 0);
19496 gen_farith(ctx
, OPC_MUL_S
, rt
, rs
, rd
, 0);
19499 gen_farith(ctx
, OPC_MUL_D
, rt
, rs
, rd
, 0);
19502 gen_farith(ctx
, OPC_DIV_S
, rt
, rs
, rd
, 0);
19505 gen_farith(ctx
, OPC_DIV_D
, rt
, rs
, rd
, 0);
19508 gen_sel_s(ctx
, OPC_SELEQZ_S
, rd
, rt
, rs
);
19511 gen_sel_d(ctx
, OPC_SELEQZ_D
, rd
, rt
, rs
);
19514 gen_sel_s(ctx
, OPC_SELNEZ_S
, rd
, rt
, rs
);
19517 gen_sel_d(ctx
, OPC_SELNEZ_D
, rd
, rt
, rs
);
19520 gen_sel_s(ctx
, OPC_SEL_S
, rd
, rt
, rs
);
19523 gen_sel_d(ctx
, OPC_SEL_D
, rd
, rt
, rs
);
19526 gen_farith(ctx
, OPC_MADDF_S
, rt
, rs
, rd
, 0);
19529 gen_farith(ctx
, OPC_MADDF_D
, rt
, rs
, rd
, 0);
19532 gen_farith(ctx
, OPC_MSUBF_S
, rt
, rs
, rd
, 0);
19535 gen_farith(ctx
, OPC_MSUBF_D
, rt
, rs
, rd
, 0);
19538 gen_reserved_instruction(ctx
);
19543 switch (extract32(ctx
->opcode
, 3, 3)) {
19545 switch (extract32(ctx
->opcode
, 9, 1)) {
19547 gen_farith(ctx
, OPC_MIN_S
, rt
, rs
, rd
, 0);
19550 gen_farith(ctx
, OPC_MIN_D
, rt
, rs
, rd
, 0);
19555 switch (extract32(ctx
->opcode
, 9, 1)) {
19557 gen_farith(ctx
, OPC_MAX_S
, rt
, rs
, rd
, 0);
19560 gen_farith(ctx
, OPC_MAX_D
, rt
, rs
, rd
, 0);
19565 switch (extract32(ctx
->opcode
, 9, 1)) {
19567 gen_farith(ctx
, OPC_MINA_S
, rt
, rs
, rd
, 0);
19570 gen_farith(ctx
, OPC_MINA_D
, rt
, rs
, rd
, 0);
19575 switch (extract32(ctx
->opcode
, 9, 1)) {
19577 gen_farith(ctx
, OPC_MAXA_S
, rt
, rs
, rd
, 0);
19580 gen_farith(ctx
, OPC_MAXA_D
, rt
, rs
, rd
, 0);
19585 switch (extract32(ctx
->opcode
, 6, 8)) {
19587 gen_cp1(ctx
, OPC_CFC1
, rt
, rs
);
19590 gen_cp1(ctx
, OPC_CTC1
, rt
, rs
);
19593 gen_cp1(ctx
, OPC_MFC1
, rt
, rs
);
19596 gen_cp1(ctx
, OPC_MTC1
, rt
, rs
);
19599 gen_cp1(ctx
, OPC_MFHC1
, rt
, rs
);
19602 gen_cp1(ctx
, OPC_MTHC1
, rt
, rs
);
19605 gen_farith(ctx
, OPC_CVT_S_PL
, -1, rs
, rt
, 0);
19608 gen_farith(ctx
, OPC_CVT_S_PU
, -1, rs
, rt
, 0);
19611 switch (extract32(ctx
->opcode
, 6, 9)) {
19613 gen_farith(ctx
, OPC_CVT_L_S
, -1, rs
, rt
, 0);
19616 gen_farith(ctx
, OPC_CVT_L_D
, -1, rs
, rt
, 0);
19619 gen_farith(ctx
, OPC_CVT_W_S
, -1, rs
, rt
, 0);
19622 gen_farith(ctx
, OPC_CVT_W_D
, -1, rs
, rt
, 0);
19625 gen_farith(ctx
, OPC_RSQRT_S
, -1, rs
, rt
, 0);
19628 gen_farith(ctx
, OPC_RSQRT_D
, -1, rs
, rt
, 0);
19631 gen_farith(ctx
, OPC_SQRT_S
, -1, rs
, rt
, 0);
19634 gen_farith(ctx
, OPC_SQRT_D
, -1, rs
, rt
, 0);
19637 gen_farith(ctx
, OPC_RECIP_S
, -1, rs
, rt
, 0);
19640 gen_farith(ctx
, OPC_RECIP_D
, -1, rs
, rt
, 0);
19643 gen_farith(ctx
, OPC_FLOOR_L_S
, -1, rs
, rt
, 0);
19646 gen_farith(ctx
, OPC_FLOOR_L_D
, -1, rs
, rt
, 0);
19649 gen_farith(ctx
, OPC_FLOOR_W_S
, -1, rs
, rt
, 0);
19652 gen_farith(ctx
, OPC_FLOOR_W_D
, -1, rs
, rt
, 0);
19655 gen_farith(ctx
, OPC_CEIL_L_S
, -1, rs
, rt
, 0);
19658 gen_farith(ctx
, OPC_CEIL_L_D
, -1, rs
, rt
, 0);
19661 gen_farith(ctx
, OPC_CEIL_W_S
, -1, rs
, rt
, 0);
19664 gen_farith(ctx
, OPC_CEIL_W_D
, -1, rs
, rt
, 0);
19667 gen_farith(ctx
, OPC_TRUNC_L_S
, -1, rs
, rt
, 0);
19670 gen_farith(ctx
, OPC_TRUNC_L_D
, -1, rs
, rt
, 0);
19673 gen_farith(ctx
, OPC_TRUNC_W_S
, -1, rs
, rt
, 0);
19676 gen_farith(ctx
, OPC_TRUNC_W_D
, -1, rs
, rt
, 0);
19679 gen_farith(ctx
, OPC_ROUND_L_S
, -1, rs
, rt
, 0);
19682 gen_farith(ctx
, OPC_ROUND_L_D
, -1, rs
, rt
, 0);
19685 gen_farith(ctx
, OPC_ROUND_W_S
, -1, rs
, rt
, 0);
19688 gen_farith(ctx
, OPC_ROUND_W_D
, -1, rs
, rt
, 0);
19691 gen_farith(ctx
, OPC_MOV_S
, -1, rs
, rt
, 0);
19694 gen_farith(ctx
, OPC_MOV_D
, -1, rs
, rt
, 0);
19697 gen_farith(ctx
, OPC_ABS_S
, -1, rs
, rt
, 0);
19700 gen_farith(ctx
, OPC_ABS_D
, -1, rs
, rt
, 0);
19703 gen_farith(ctx
, OPC_NEG_S
, -1, rs
, rt
, 0);
19706 gen_farith(ctx
, OPC_NEG_D
, -1, rs
, rt
, 0);
19709 gen_farith(ctx
, OPC_CVT_D_S
, -1, rs
, rt
, 0);
19712 gen_farith(ctx
, OPC_CVT_D_W
, -1, rs
, rt
, 0);
19715 gen_farith(ctx
, OPC_CVT_D_L
, -1, rs
, rt
, 0);
19718 gen_farith(ctx
, OPC_CVT_S_D
, -1, rs
, rt
, 0);
19721 gen_farith(ctx
, OPC_CVT_S_W
, -1, rs
, rt
, 0);
19724 gen_farith(ctx
, OPC_CVT_S_L
, -1, rs
, rt
, 0);
19727 gen_reserved_instruction(ctx
);
19736 switch (extract32(ctx
->opcode
, 3, 3)) {
19737 case NM_CMP_CONDN_S
:
19738 gen_r6_cmp_s(ctx
, extract32(ctx
->opcode
, 6, 5), rt
, rs
, rd
);
19740 case NM_CMP_CONDN_D
:
19741 gen_r6_cmp_d(ctx
, extract32(ctx
->opcode
, 6, 5), rt
, rs
, rd
);
19744 gen_reserved_instruction(ctx
);
19749 gen_reserved_instruction(ctx
);
19754 static void gen_pool32a5_nanomips_insn(DisasContext
*ctx
, int opc
,
19755 int rd
, int rs
, int rt
)
19758 TCGv t0
= tcg_temp_new();
19759 TCGv v1_t
= tcg_temp_new();
19760 TCGv v2_t
= tcg_temp_new();
19762 gen_load_gpr(v1_t
, rs
);
19763 gen_load_gpr(v2_t
, rt
);
19768 gen_helper_cmp_eq_ph(v1_t
, v2_t
, cpu_env
);
19772 gen_helper_cmp_lt_ph(v1_t
, v2_t
, cpu_env
);
19776 gen_helper_cmp_le_ph(v1_t
, v2_t
, cpu_env
);
19778 case NM_CMPU_EQ_QB
:
19780 gen_helper_cmpu_eq_qb(v1_t
, v2_t
, cpu_env
);
19782 case NM_CMPU_LT_QB
:
19784 gen_helper_cmpu_lt_qb(v1_t
, v2_t
, cpu_env
);
19786 case NM_CMPU_LE_QB
:
19788 gen_helper_cmpu_le_qb(v1_t
, v2_t
, cpu_env
);
19790 case NM_CMPGU_EQ_QB
:
19792 gen_helper_cmpgu_eq_qb(v1_t
, v1_t
, v2_t
);
19793 gen_store_gpr(v1_t
, ret
);
19795 case NM_CMPGU_LT_QB
:
19797 gen_helper_cmpgu_lt_qb(v1_t
, v1_t
, v2_t
);
19798 gen_store_gpr(v1_t
, ret
);
19800 case NM_CMPGU_LE_QB
:
19802 gen_helper_cmpgu_le_qb(v1_t
, v1_t
, v2_t
);
19803 gen_store_gpr(v1_t
, ret
);
19805 case NM_CMPGDU_EQ_QB
:
19807 gen_helper_cmpgu_eq_qb(v1_t
, v1_t
, v2_t
);
19808 tcg_gen_deposit_tl(cpu_dspctrl
, cpu_dspctrl
, v1_t
, 24, 4);
19809 gen_store_gpr(v1_t
, ret
);
19811 case NM_CMPGDU_LT_QB
:
19813 gen_helper_cmpgu_lt_qb(v1_t
, v1_t
, v2_t
);
19814 tcg_gen_deposit_tl(cpu_dspctrl
, cpu_dspctrl
, v1_t
, 24, 4);
19815 gen_store_gpr(v1_t
, ret
);
19817 case NM_CMPGDU_LE_QB
:
19819 gen_helper_cmpgu_le_qb(v1_t
, v1_t
, v2_t
);
19820 tcg_gen_deposit_tl(cpu_dspctrl
, cpu_dspctrl
, v1_t
, 24, 4);
19821 gen_store_gpr(v1_t
, ret
);
19825 gen_helper_packrl_ph(v1_t
, v1_t
, v2_t
);
19826 gen_store_gpr(v1_t
, ret
);
19830 gen_helper_pick_qb(v1_t
, v1_t
, v2_t
, cpu_env
);
19831 gen_store_gpr(v1_t
, ret
);
19835 gen_helper_pick_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
19836 gen_store_gpr(v1_t
, ret
);
19840 gen_helper_addq_s_w(v1_t
, v1_t
, v2_t
, cpu_env
);
19841 gen_store_gpr(v1_t
, ret
);
19845 gen_helper_subq_s_w(v1_t
, v1_t
, v2_t
, cpu_env
);
19846 gen_store_gpr(v1_t
, ret
);
19850 gen_helper_addsc(v1_t
, v1_t
, v2_t
, cpu_env
);
19851 gen_store_gpr(v1_t
, ret
);
19855 gen_helper_addwc(v1_t
, v1_t
, v2_t
, cpu_env
);
19856 gen_store_gpr(v1_t
, ret
);
19860 switch (extract32(ctx
->opcode
, 10, 1)) {
19863 gen_helper_addq_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
19864 gen_store_gpr(v1_t
, ret
);
19868 gen_helper_addq_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
19869 gen_store_gpr(v1_t
, ret
);
19873 case NM_ADDQH_R_PH
:
19875 switch (extract32(ctx
->opcode
, 10, 1)) {
19878 gen_helper_addqh_ph(v1_t
, v1_t
, v2_t
);
19879 gen_store_gpr(v1_t
, ret
);
19883 gen_helper_addqh_r_ph(v1_t
, v1_t
, v2_t
);
19884 gen_store_gpr(v1_t
, ret
);
19890 switch (extract32(ctx
->opcode
, 10, 1)) {
19893 gen_helper_addqh_w(v1_t
, v1_t
, v2_t
);
19894 gen_store_gpr(v1_t
, ret
);
19898 gen_helper_addqh_r_w(v1_t
, v1_t
, v2_t
);
19899 gen_store_gpr(v1_t
, ret
);
19905 switch (extract32(ctx
->opcode
, 10, 1)) {
19908 gen_helper_addu_qb(v1_t
, v1_t
, v2_t
, cpu_env
);
19909 gen_store_gpr(v1_t
, ret
);
19913 gen_helper_addu_s_qb(v1_t
, v1_t
, v2_t
, cpu_env
);
19914 gen_store_gpr(v1_t
, ret
);
19920 switch (extract32(ctx
->opcode
, 10, 1)) {
19923 gen_helper_addu_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
19924 gen_store_gpr(v1_t
, ret
);
19928 gen_helper_addu_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
19929 gen_store_gpr(v1_t
, ret
);
19933 case NM_ADDUH_R_QB
:
19935 switch (extract32(ctx
->opcode
, 10, 1)) {
19938 gen_helper_adduh_qb(v1_t
, v1_t
, v2_t
);
19939 gen_store_gpr(v1_t
, ret
);
19943 gen_helper_adduh_r_qb(v1_t
, v1_t
, v2_t
);
19944 gen_store_gpr(v1_t
, ret
);
19948 case NM_SHRAV_R_PH
:
19950 switch (extract32(ctx
->opcode
, 10, 1)) {
19953 gen_helper_shra_ph(v1_t
, v1_t
, v2_t
);
19954 gen_store_gpr(v1_t
, ret
);
19958 gen_helper_shra_r_ph(v1_t
, v1_t
, v2_t
);
19959 gen_store_gpr(v1_t
, ret
);
19963 case NM_SHRAV_R_QB
:
19965 switch (extract32(ctx
->opcode
, 10, 1)) {
19968 gen_helper_shra_qb(v1_t
, v1_t
, v2_t
);
19969 gen_store_gpr(v1_t
, ret
);
19973 gen_helper_shra_r_qb(v1_t
, v1_t
, v2_t
);
19974 gen_store_gpr(v1_t
, ret
);
19980 switch (extract32(ctx
->opcode
, 10, 1)) {
19983 gen_helper_subq_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
19984 gen_store_gpr(v1_t
, ret
);
19988 gen_helper_subq_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
19989 gen_store_gpr(v1_t
, ret
);
19993 case NM_SUBQH_R_PH
:
19995 switch (extract32(ctx
->opcode
, 10, 1)) {
19998 gen_helper_subqh_ph(v1_t
, v1_t
, v2_t
);
19999 gen_store_gpr(v1_t
, ret
);
20003 gen_helper_subqh_r_ph(v1_t
, v1_t
, v2_t
);
20004 gen_store_gpr(v1_t
, ret
);
20010 switch (extract32(ctx
->opcode
, 10, 1)) {
20013 gen_helper_subqh_w(v1_t
, v1_t
, v2_t
);
20014 gen_store_gpr(v1_t
, ret
);
20018 gen_helper_subqh_r_w(v1_t
, v1_t
, v2_t
);
20019 gen_store_gpr(v1_t
, ret
);
20025 switch (extract32(ctx
->opcode
, 10, 1)) {
20028 gen_helper_subu_qb(v1_t
, v1_t
, v2_t
, cpu_env
);
20029 gen_store_gpr(v1_t
, ret
);
20033 gen_helper_subu_s_qb(v1_t
, v1_t
, v2_t
, cpu_env
);
20034 gen_store_gpr(v1_t
, ret
);
20040 switch (extract32(ctx
->opcode
, 10, 1)) {
20043 gen_helper_subu_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20044 gen_store_gpr(v1_t
, ret
);
20048 gen_helper_subu_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20049 gen_store_gpr(v1_t
, ret
);
20053 case NM_SUBUH_R_QB
:
20055 switch (extract32(ctx
->opcode
, 10, 1)) {
20058 gen_helper_subuh_qb(v1_t
, v1_t
, v2_t
);
20059 gen_store_gpr(v1_t
, ret
);
20063 gen_helper_subuh_r_qb(v1_t
, v1_t
, v2_t
);
20064 gen_store_gpr(v1_t
, ret
);
20068 case NM_SHLLV_S_PH
:
20070 switch (extract32(ctx
->opcode
, 10, 1)) {
20073 gen_helper_shll_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20074 gen_store_gpr(v1_t
, ret
);
20078 gen_helper_shll_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20079 gen_store_gpr(v1_t
, ret
);
20083 case NM_PRECR_SRA_R_PH_W
:
20085 switch (extract32(ctx
->opcode
, 10, 1)) {
20087 /* PRECR_SRA_PH_W */
20089 TCGv_i32 sa_t
= tcg_const_i32(rd
);
20090 gen_helper_precr_sra_ph_w(v1_t
, sa_t
, v1_t
,
20092 gen_store_gpr(v1_t
, rt
);
20093 tcg_temp_free_i32(sa_t
);
20097 /* PRECR_SRA_R_PH_W */
20099 TCGv_i32 sa_t
= tcg_const_i32(rd
);
20100 gen_helper_precr_sra_r_ph_w(v1_t
, sa_t
, v1_t
,
20102 gen_store_gpr(v1_t
, rt
);
20103 tcg_temp_free_i32(sa_t
);
20108 case NM_MULEU_S_PH_QBL
:
20110 gen_helper_muleu_s_ph_qbl(v1_t
, v1_t
, v2_t
, cpu_env
);
20111 gen_store_gpr(v1_t
, ret
);
20113 case NM_MULEU_S_PH_QBR
:
20115 gen_helper_muleu_s_ph_qbr(v1_t
, v1_t
, v2_t
, cpu_env
);
20116 gen_store_gpr(v1_t
, ret
);
20118 case NM_MULQ_RS_PH
:
20120 gen_helper_mulq_rs_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20121 gen_store_gpr(v1_t
, ret
);
20125 gen_helper_mulq_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20126 gen_store_gpr(v1_t
, ret
);
20130 gen_helper_mulq_rs_w(v1_t
, v1_t
, v2_t
, cpu_env
);
20131 gen_store_gpr(v1_t
, ret
);
20135 gen_helper_mulq_s_w(v1_t
, v1_t
, v2_t
, cpu_env
);
20136 gen_store_gpr(v1_t
, ret
);
20140 gen_load_gpr(t0
, rs
);
20142 tcg_gen_deposit_tl(cpu_gpr
[rt
], t0
, cpu_gpr
[rt
], rd
, 32 - rd
);
20144 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
20148 gen_helper_modsub(v1_t
, v1_t
, v2_t
);
20149 gen_store_gpr(v1_t
, ret
);
20153 gen_helper_shra_r_w(v1_t
, v1_t
, v2_t
);
20154 gen_store_gpr(v1_t
, ret
);
20158 gen_helper_shrl_ph(v1_t
, v1_t
, v2_t
);
20159 gen_store_gpr(v1_t
, ret
);
20163 gen_helper_shrl_qb(v1_t
, v1_t
, v2_t
);
20164 gen_store_gpr(v1_t
, ret
);
20168 gen_helper_shll_qb(v1_t
, v1_t
, v2_t
, cpu_env
);
20169 gen_store_gpr(v1_t
, ret
);
20173 gen_helper_shll_s_w(v1_t
, v1_t
, v2_t
, cpu_env
);
20174 gen_store_gpr(v1_t
, ret
);
20179 TCGv tv0
= tcg_temp_new();
20180 TCGv tv1
= tcg_temp_new();
20181 int16_t imm
= extract32(ctx
->opcode
, 16, 7);
20183 tcg_gen_movi_tl(tv0
, rd
>> 3);
20184 tcg_gen_movi_tl(tv1
, imm
);
20185 gen_helper_shilo(tv0
, tv1
, cpu_env
);
20188 case NM_MULEQ_S_W_PHL
:
20190 gen_helper_muleq_s_w_phl(v1_t
, v1_t
, v2_t
, cpu_env
);
20191 gen_store_gpr(v1_t
, ret
);
20193 case NM_MULEQ_S_W_PHR
:
20195 gen_helper_muleq_s_w_phr(v1_t
, v1_t
, v2_t
, cpu_env
);
20196 gen_store_gpr(v1_t
, ret
);
20200 switch (extract32(ctx
->opcode
, 10, 1)) {
20203 gen_helper_mul_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20204 gen_store_gpr(v1_t
, ret
);
20208 gen_helper_mul_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20209 gen_store_gpr(v1_t
, ret
);
20213 case NM_PRECR_QB_PH
:
20215 gen_helper_precr_qb_ph(v1_t
, v1_t
, v2_t
);
20216 gen_store_gpr(v1_t
, ret
);
20218 case NM_PRECRQ_QB_PH
:
20220 gen_helper_precrq_qb_ph(v1_t
, v1_t
, v2_t
);
20221 gen_store_gpr(v1_t
, ret
);
20223 case NM_PRECRQ_PH_W
:
20225 gen_helper_precrq_ph_w(v1_t
, v1_t
, v2_t
);
20226 gen_store_gpr(v1_t
, ret
);
20228 case NM_PRECRQ_RS_PH_W
:
20230 gen_helper_precrq_rs_ph_w(v1_t
, v1_t
, v2_t
, cpu_env
);
20231 gen_store_gpr(v1_t
, ret
);
20233 case NM_PRECRQU_S_QB_PH
:
20235 gen_helper_precrqu_s_qb_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20236 gen_store_gpr(v1_t
, ret
);
20240 tcg_gen_movi_tl(t0
, rd
);
20241 gen_helper_shra_r_w(v1_t
, t0
, v1_t
);
20242 gen_store_gpr(v1_t
, rt
);
20246 tcg_gen_movi_tl(t0
, rd
>> 1);
20247 switch (extract32(ctx
->opcode
, 10, 1)) {
20250 gen_helper_shra_ph(v1_t
, t0
, v1_t
);
20251 gen_store_gpr(v1_t
, rt
);
20255 gen_helper_shra_r_ph(v1_t
, t0
, v1_t
);
20256 gen_store_gpr(v1_t
, rt
);
20262 tcg_gen_movi_tl(t0
, rd
>> 1);
20263 switch (extract32(ctx
->opcode
, 10, 2)) {
20266 gen_helper_shll_ph(v1_t
, t0
, v1_t
, cpu_env
);
20267 gen_store_gpr(v1_t
, rt
);
20271 gen_helper_shll_s_ph(v1_t
, t0
, v1_t
, cpu_env
);
20272 gen_store_gpr(v1_t
, rt
);
20275 gen_reserved_instruction(ctx
);
20281 tcg_gen_movi_tl(t0
, rd
);
20282 gen_helper_shll_s_w(v1_t
, t0
, v1_t
, cpu_env
);
20283 gen_store_gpr(v1_t
, rt
);
20289 imm
= sextract32(ctx
->opcode
, 11, 11);
20290 imm
= (int16_t)(imm
<< 6) >> 6;
20292 tcg_gen_movi_tl(cpu_gpr
[rt
], dup_const(MO_16
, imm
));
20297 gen_reserved_instruction(ctx
);
20302 static int decode_nanomips_32_48_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
20310 insn
= translator_lduw(env
, ctx
->base
.pc_next
+ 2);
20311 ctx
->opcode
= (ctx
->opcode
<< 16) | insn
;
20313 rt
= extract32(ctx
->opcode
, 21, 5);
20314 rs
= extract32(ctx
->opcode
, 16, 5);
20315 rd
= extract32(ctx
->opcode
, 11, 5);
20317 op
= extract32(ctx
->opcode
, 26, 6);
20322 switch (extract32(ctx
->opcode
, 19, 2)) {
20325 gen_reserved_instruction(ctx
);
20328 if ((extract32(ctx
->opcode
, 18, 1)) == NM_SYSCALL
) {
20329 generate_exception_end(ctx
, EXCP_SYSCALL
);
20331 gen_reserved_instruction(ctx
);
20335 generate_exception_end(ctx
, EXCP_BREAK
);
20338 if (is_uhi(extract32(ctx
->opcode
, 0, 19))) {
20339 gen_helper_do_semihosting(cpu_env
);
20341 if (ctx
->hflags
& MIPS_HFLAG_SBRI
) {
20342 gen_reserved_instruction(ctx
);
20344 generate_exception_end(ctx
, EXCP_DBp
);
20351 imm
= extract32(ctx
->opcode
, 0, 16);
20353 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], imm
);
20355 tcg_gen_movi_tl(cpu_gpr
[rt
], imm
);
20357 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
20362 offset
= sextract32(ctx
->opcode
, 0, 1) << 21 |
20363 extract32(ctx
->opcode
, 1, 20) << 1;
20364 target_long addr
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
20365 tcg_gen_movi_tl(cpu_gpr
[rt
], addr
);
20369 switch (ctx
->opcode
& 0x07) {
20371 gen_pool32a0_nanomips_insn(env
, ctx
);
20375 int32_t op1
= extract32(ctx
->opcode
, 3, 7);
20376 gen_pool32a5_nanomips_insn(ctx
, op1
, rd
, rs
, rt
);
20380 switch (extract32(ctx
->opcode
, 3, 3)) {
20382 gen_p_lsx(ctx
, rd
, rs
, rt
);
20386 * In nanoMIPS, the shift field directly encodes the shift
20387 * amount, meaning that the supported shift values are in
20388 * the range 0 to 3 (instead of 1 to 4 in MIPSR6).
20390 gen_lsa(ctx
, rd
, rt
, rs
, extract32(ctx
->opcode
, 9, 2) - 1);
20393 gen_ext(ctx
, 32, rd
, rs
, rt
, extract32(ctx
->opcode
, 6, 5));
20396 gen_pool32axf_nanomips_insn(env
, ctx
);
20399 gen_reserved_instruction(ctx
);
20404 gen_reserved_instruction(ctx
);
20409 switch (ctx
->opcode
& 0x03) {
20412 offset
= extract32(ctx
->opcode
, 0, 21);
20413 gen_op_addr_addi(ctx
, cpu_gpr
[rt
], cpu_gpr
[28], offset
);
20417 gen_ld(ctx
, OPC_LW
, rt
, 28, extract32(ctx
->opcode
, 2, 19) << 2);
20420 gen_st(ctx
, OPC_SW
, rt
, 28, extract32(ctx
->opcode
, 2, 19) << 2);
20423 gen_reserved_instruction(ctx
);
20429 insn
= translator_lduw(env
, ctx
->base
.pc_next
+ 4);
20430 target_long addr_off
= extract32(ctx
->opcode
, 0, 16) | insn
<< 16;
20431 switch (extract32(ctx
->opcode
, 16, 5)) {
20435 tcg_gen_movi_tl(cpu_gpr
[rt
], addr_off
);
20441 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], addr_off
);
20442 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
20448 gen_op_addr_addi(ctx
, cpu_gpr
[rt
], cpu_gpr
[28], addr_off
);
20454 target_long addr
= addr_add(ctx
, ctx
->base
.pc_next
+ 6,
20457 tcg_gen_movi_tl(cpu_gpr
[rt
], addr
);
20464 t0
= tcg_temp_new();
20466 target_long addr
= addr_add(ctx
, ctx
->base
.pc_next
+ 6,
20469 tcg_gen_movi_tl(t0
, addr
);
20470 tcg_gen_qemu_ld_tl(cpu_gpr
[rt
], t0
, ctx
->mem_idx
, MO_TESL
);
20478 t0
= tcg_temp_new();
20479 t1
= tcg_temp_new();
20481 target_long addr
= addr_add(ctx
, ctx
->base
.pc_next
+ 6,
20484 tcg_gen_movi_tl(t0
, addr
);
20485 gen_load_gpr(t1
, rt
);
20487 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
20494 gen_reserved_instruction(ctx
);
20500 switch (extract32(ctx
->opcode
, 12, 4)) {
20502 gen_logic_imm(ctx
, OPC_ORI
, rt
, rs
, extract32(ctx
->opcode
, 0, 12));
20505 gen_logic_imm(ctx
, OPC_XORI
, rt
, rs
, extract32(ctx
->opcode
, 0, 12));
20508 gen_logic_imm(ctx
, OPC_ANDI
, rt
, rs
, extract32(ctx
->opcode
, 0, 12));
20511 switch (extract32(ctx
->opcode
, 20, 1)) {
20513 switch (ctx
->opcode
& 3) {
20515 gen_save(ctx
, rt
, extract32(ctx
->opcode
, 16, 4),
20516 extract32(ctx
->opcode
, 2, 1),
20517 extract32(ctx
->opcode
, 3, 9) << 3);
20520 case NM_RESTORE_JRC
:
20521 gen_restore(ctx
, rt
, extract32(ctx
->opcode
, 16, 4),
20522 extract32(ctx
->opcode
, 2, 1),
20523 extract32(ctx
->opcode
, 3, 9) << 3);
20524 if ((ctx
->opcode
& 3) == NM_RESTORE_JRC
) {
20525 gen_compute_branch_nm(ctx
, OPC_JR
, 2, 31, 0, 0);
20529 gen_reserved_instruction(ctx
);
20534 gen_reserved_instruction(ctx
);
20539 gen_slt_imm(ctx
, OPC_SLTI
, rt
, rs
, extract32(ctx
->opcode
, 0, 12));
20542 gen_slt_imm(ctx
, OPC_SLTIU
, rt
, rs
, extract32(ctx
->opcode
, 0, 12));
20546 TCGv t0
= tcg_temp_new();
20548 imm
= extract32(ctx
->opcode
, 0, 12);
20549 gen_load_gpr(t0
, rs
);
20550 tcg_gen_setcondi_tl(TCG_COND_EQ
, t0
, t0
, imm
);
20551 gen_store_gpr(t0
, rt
);
20557 imm
= (int16_t) extract32(ctx
->opcode
, 0, 12);
20558 gen_arith_imm(ctx
, OPC_ADDIU
, rt
, rs
, -imm
);
20562 int shift
= extract32(ctx
->opcode
, 0, 5);
20563 switch (extract32(ctx
->opcode
, 5, 4)) {
20565 if (rt
== 0 && shift
== 0) {
20567 } else if (rt
== 0 && shift
== 3) {
20568 /* EHB - treat as NOP */
20569 } else if (rt
== 0 && shift
== 5) {
20570 /* PAUSE - treat as NOP */
20571 } else if (rt
== 0 && shift
== 6) {
20573 gen_sync(extract32(ctx
->opcode
, 16, 5));
20576 gen_shift_imm(ctx
, OPC_SLL
, rt
, rs
,
20577 extract32(ctx
->opcode
, 0, 5));
20581 gen_shift_imm(ctx
, OPC_SRL
, rt
, rs
,
20582 extract32(ctx
->opcode
, 0, 5));
20585 gen_shift_imm(ctx
, OPC_SRA
, rt
, rs
,
20586 extract32(ctx
->opcode
, 0, 5));
20589 gen_shift_imm(ctx
, OPC_ROTR
, rt
, rs
,
20590 extract32(ctx
->opcode
, 0, 5));
20598 TCGv t0
= tcg_temp_new();
20599 TCGv_i32 shift
= tcg_const_i32(extract32(ctx
->opcode
, 0, 5));
20600 TCGv_i32 shiftx
= tcg_const_i32(extract32(ctx
->opcode
, 7, 4)
20602 TCGv_i32 stripe
= tcg_const_i32(extract32(ctx
->opcode
, 6, 1));
20604 gen_load_gpr(t0
, rs
);
20605 gen_helper_rotx(cpu_gpr
[rt
], t0
, shift
, shiftx
, stripe
);
20608 tcg_temp_free_i32(shift
);
20609 tcg_temp_free_i32(shiftx
);
20610 tcg_temp_free_i32(stripe
);
20614 switch (((ctx
->opcode
>> 10) & 2) |
20615 (extract32(ctx
->opcode
, 5, 1))) {
20618 gen_bitops(ctx
, OPC_INS
, rt
, rs
, extract32(ctx
->opcode
, 0, 5),
20619 extract32(ctx
->opcode
, 6, 5));
20622 gen_reserved_instruction(ctx
);
20627 switch (((ctx
->opcode
>> 10) & 2) |
20628 (extract32(ctx
->opcode
, 5, 1))) {
20631 gen_bitops(ctx
, OPC_EXT
, rt
, rs
, extract32(ctx
->opcode
, 0, 5),
20632 extract32(ctx
->opcode
, 6, 5));
20635 gen_reserved_instruction(ctx
);
20640 gen_reserved_instruction(ctx
);
20645 gen_pool32f_nanomips_insn(ctx
);
20650 switch (extract32(ctx
->opcode
, 1, 1)) {
20653 tcg_gen_movi_tl(cpu_gpr
[rt
],
20654 sextract32(ctx
->opcode
, 0, 1) << 31 |
20655 extract32(ctx
->opcode
, 2, 10) << 21 |
20656 extract32(ctx
->opcode
, 12, 9) << 12);
20661 offset
= sextract32(ctx
->opcode
, 0, 1) << 31 |
20662 extract32(ctx
->opcode
, 2, 10) << 21 |
20663 extract32(ctx
->opcode
, 12, 9) << 12;
20665 addr
= ~0xFFF & addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
20666 tcg_gen_movi_tl(cpu_gpr
[rt
], addr
);
20673 uint32_t u
= extract32(ctx
->opcode
, 0, 18);
20675 switch (extract32(ctx
->opcode
, 18, 3)) {
20677 gen_ld(ctx
, OPC_LB
, rt
, 28, u
);
20680 gen_st(ctx
, OPC_SB
, rt
, 28, u
);
20683 gen_ld(ctx
, OPC_LBU
, rt
, 28, u
);
20687 gen_op_addr_addi(ctx
, cpu_gpr
[rt
], cpu_gpr
[28], u
);
20692 switch (ctx
->opcode
& 1) {
20694 gen_ld(ctx
, OPC_LH
, rt
, 28, u
);
20697 gen_ld(ctx
, OPC_LHU
, rt
, 28, u
);
20703 switch (ctx
->opcode
& 1) {
20705 gen_st(ctx
, OPC_SH
, rt
, 28, u
);
20708 gen_reserved_instruction(ctx
);
20714 switch (ctx
->opcode
& 0x3) {
20716 gen_cop1_ldst(ctx
, OPC_LWC1
, rt
, 28, u
);
20719 gen_cop1_ldst(ctx
, OPC_LDC1
, rt
, 28, u
);
20722 gen_cop1_ldst(ctx
, OPC_SWC1
, rt
, 28, u
);
20725 gen_cop1_ldst(ctx
, OPC_SDC1
, rt
, 28, u
);
20730 gen_reserved_instruction(ctx
);
20737 uint32_t u
= extract32(ctx
->opcode
, 0, 12);
20739 switch (extract32(ctx
->opcode
, 12, 4)) {
20744 * Break the TB to be able to sync copied instructions
20747 ctx
->base
.is_jmp
= DISAS_STOP
;
20750 /* Treat as NOP. */
20754 gen_ld(ctx
, OPC_LB
, rt
, rs
, u
);
20757 gen_ld(ctx
, OPC_LH
, rt
, rs
, u
);
20760 gen_ld(ctx
, OPC_LW
, rt
, rs
, u
);
20763 gen_ld(ctx
, OPC_LBU
, rt
, rs
, u
);
20766 gen_ld(ctx
, OPC_LHU
, rt
, rs
, u
);
20769 gen_st(ctx
, OPC_SB
, rt
, rs
, u
);
20772 gen_st(ctx
, OPC_SH
, rt
, rs
, u
);
20775 gen_st(ctx
, OPC_SW
, rt
, rs
, u
);
20778 gen_cop1_ldst(ctx
, OPC_LWC1
, rt
, rs
, u
);
20781 gen_cop1_ldst(ctx
, OPC_LDC1
, rt
, rs
, u
);
20784 gen_cop1_ldst(ctx
, OPC_SWC1
, rt
, rs
, u
);
20787 gen_cop1_ldst(ctx
, OPC_SDC1
, rt
, rs
, u
);
20790 gen_reserved_instruction(ctx
);
20797 int32_t s
= (sextract32(ctx
->opcode
, 15, 1) << 8) |
20798 extract32(ctx
->opcode
, 0, 8);
20800 switch (extract32(ctx
->opcode
, 8, 3)) {
20802 switch (extract32(ctx
->opcode
, 11, 4)) {
20804 gen_ld(ctx
, OPC_LB
, rt
, rs
, s
);
20807 gen_ld(ctx
, OPC_LH
, rt
, rs
, s
);
20810 gen_ld(ctx
, OPC_LW
, rt
, rs
, s
);
20813 gen_ld(ctx
, OPC_LBU
, rt
, rs
, s
);
20816 gen_ld(ctx
, OPC_LHU
, rt
, rs
, s
);
20819 gen_st(ctx
, OPC_SB
, rt
, rs
, s
);
20822 gen_st(ctx
, OPC_SH
, rt
, rs
, s
);
20825 gen_st(ctx
, OPC_SW
, rt
, rs
, s
);
20828 gen_cop1_ldst(ctx
, OPC_LWC1
, rt
, rs
, s
);
20831 gen_cop1_ldst(ctx
, OPC_LDC1
, rt
, rs
, s
);
20834 gen_cop1_ldst(ctx
, OPC_SWC1
, rt
, rs
, s
);
20837 gen_cop1_ldst(ctx
, OPC_SDC1
, rt
, rs
, s
);
20843 * Break the TB to be able to sync copied instructions
20846 ctx
->base
.is_jmp
= DISAS_STOP
;
20849 /* Treat as NOP. */
20853 gen_reserved_instruction(ctx
);
20858 switch (extract32(ctx
->opcode
, 11, 4)) {
20863 TCGv t0
= tcg_temp_new();
20864 TCGv t1
= tcg_temp_new();
20866 gen_base_offset_addr(ctx
, t0
, rs
, s
);
20868 switch (extract32(ctx
->opcode
, 11, 4)) {
20870 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESW
|
20872 gen_store_gpr(t0
, rt
);
20875 gen_load_gpr(t1
, rt
);
20876 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUW
|
20885 switch (ctx
->opcode
& 0x03) {
20887 gen_ld(ctx
, OPC_LL
, rt
, rs
, s
);
20891 gen_llwp(ctx
, rs
, 0, rt
, extract32(ctx
->opcode
, 3, 5));
20896 switch (ctx
->opcode
& 0x03) {
20898 gen_st_cond(ctx
, rt
, rs
, s
, MO_TESL
, false);
20902 gen_scwp(ctx
, rs
, 0, rt
, extract32(ctx
->opcode
, 3, 5),
20908 check_cp0_enabled(ctx
);
20909 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
20910 gen_cache_operation(ctx
, rt
, rs
, s
);
20916 switch (extract32(ctx
->opcode
, 11, 4)) {
20919 check_cp0_enabled(ctx
);
20920 gen_ld(ctx
, OPC_LBE
, rt
, rs
, s
);
20924 check_cp0_enabled(ctx
);
20925 gen_st(ctx
, OPC_SBE
, rt
, rs
, s
);
20929 check_cp0_enabled(ctx
);
20930 gen_ld(ctx
, OPC_LBUE
, rt
, rs
, s
);
20934 /* case NM_SYNCIE */
20936 check_cp0_enabled(ctx
);
20938 * Break the TB to be able to sync copied instructions
20941 ctx
->base
.is_jmp
= DISAS_STOP
;
20943 /* case NM_PREFE */
20945 check_cp0_enabled(ctx
);
20946 /* Treat as NOP. */
20951 check_cp0_enabled(ctx
);
20952 gen_ld(ctx
, OPC_LHE
, rt
, rs
, s
);
20956 check_cp0_enabled(ctx
);
20957 gen_st(ctx
, OPC_SHE
, rt
, rs
, s
);
20961 check_cp0_enabled(ctx
);
20962 gen_ld(ctx
, OPC_LHUE
, rt
, rs
, s
);
20966 check_cp0_enabled(ctx
);
20967 check_nms_dl_il_sl_tl_l2c(ctx
);
20968 gen_cache_operation(ctx
, rt
, rs
, s
);
20972 check_cp0_enabled(ctx
);
20973 gen_ld(ctx
, OPC_LWE
, rt
, rs
, s
);
20977 check_cp0_enabled(ctx
);
20978 gen_st(ctx
, OPC_SWE
, rt
, rs
, s
);
20981 switch (extract32(ctx
->opcode
, 2, 2)) {
20985 check_cp0_enabled(ctx
);
20986 gen_ld(ctx
, OPC_LLE
, rt
, rs
, s
);
20991 check_cp0_enabled(ctx
);
20992 gen_llwp(ctx
, rs
, 0, rt
, extract32(ctx
->opcode
, 3, 5));
20995 gen_reserved_instruction(ctx
);
21000 switch (extract32(ctx
->opcode
, 2, 2)) {
21004 check_cp0_enabled(ctx
);
21005 gen_st_cond(ctx
, rt
, rs
, s
, MO_TESL
, true);
21010 check_cp0_enabled(ctx
);
21011 gen_scwp(ctx
, rs
, 0, rt
, extract32(ctx
->opcode
, 3, 5),
21015 gen_reserved_instruction(ctx
);
21025 int count
= extract32(ctx
->opcode
, 12, 3);
21028 offset
= sextract32(ctx
->opcode
, 15, 1) << 8 |
21029 extract32(ctx
->opcode
, 0, 8);
21030 TCGv va
= tcg_temp_new();
21031 TCGv t1
= tcg_temp_new();
21032 MemOp memop
= (extract32(ctx
->opcode
, 8, 3)) ==
21033 NM_P_LS_UAWM
? MO_UNALN
: 0;
21035 count
= (count
== 0) ? 8 : count
;
21036 while (counter
!= count
) {
21037 int this_rt
= ((rt
+ counter
) & 0x1f) | (rt
& 0x10);
21038 int this_offset
= offset
+ (counter
<< 2);
21040 gen_base_offset_addr(ctx
, va
, rs
, this_offset
);
21042 switch (extract32(ctx
->opcode
, 11, 1)) {
21044 tcg_gen_qemu_ld_tl(t1
, va
, ctx
->mem_idx
,
21046 gen_store_gpr(t1
, this_rt
);
21047 if ((this_rt
== rs
) &&
21048 (counter
!= (count
- 1))) {
21049 /* UNPREDICTABLE */
21053 this_rt
= (rt
== 0) ? 0 : this_rt
;
21054 gen_load_gpr(t1
, this_rt
);
21055 tcg_gen_qemu_st_tl(t1
, va
, ctx
->mem_idx
,
21066 gen_reserved_instruction(ctx
);
21074 TCGv t0
= tcg_temp_new();
21075 int32_t s
= sextract32(ctx
->opcode
, 0, 1) << 21 |
21076 extract32(ctx
->opcode
, 1, 20) << 1;
21077 rd
= (extract32(ctx
->opcode
, 24, 1)) == 0 ? 4 : 5;
21078 rt
= decode_gpr_gpr4_zero(extract32(ctx
->opcode
, 25, 1) << 3 |
21079 extract32(ctx
->opcode
, 21, 3));
21080 gen_load_gpr(t0
, rt
);
21081 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
21082 gen_compute_branch_nm(ctx
, OPC_BGEZAL
, 4, 0, 0, s
);
21088 int32_t s
= sextract32(ctx
->opcode
, 0, 1) << 25 |
21089 extract32(ctx
->opcode
, 1, 24) << 1;
21091 if ((extract32(ctx
->opcode
, 25, 1)) == 0) {
21093 gen_compute_branch_nm(ctx
, OPC_BEQ
, 4, 0, 0, s
);
21096 gen_compute_branch_nm(ctx
, OPC_BGEZAL
, 4, 0, 0, s
);
21101 switch (extract32(ctx
->opcode
, 12, 4)) {
21104 gen_compute_branch_nm(ctx
, OPC_JALR
, 4, rs
, rt
, 0);
21107 gen_compute_nanomips_pbalrsc_branch(ctx
, rs
, rt
);
21110 gen_reserved_instruction(ctx
);
21116 int32_t s
= sextract32(ctx
->opcode
, 0, 1) << 14 |
21117 extract32(ctx
->opcode
, 1, 13) << 1;
21118 switch (extract32(ctx
->opcode
, 14, 2)) {
21121 gen_compute_branch_nm(ctx
, OPC_BEQ
, 4, rs
, rt
, s
);
21124 s
= sextract32(ctx
->opcode
, 0, 1) << 14 |
21125 extract32(ctx
->opcode
, 1, 13) << 1;
21126 check_cp1_enabled(ctx
);
21127 switch (extract32(ctx
->opcode
, 16, 5)) {
21129 gen_compute_branch_cp1_nm(ctx
, OPC_BC1EQZ
, rt
, s
);
21132 gen_compute_branch_cp1_nm(ctx
, OPC_BC1NEZ
, rt
, s
);
21137 int32_t imm
= extract32(ctx
->opcode
, 1, 13) |
21138 extract32(ctx
->opcode
, 0, 1) << 13;
21140 gen_compute_branch_nm(ctx
, OPC_BPOSGE32
, 4, -1, -2,
21145 gen_reserved_instruction(ctx
);
21151 gen_compute_compact_branch_nm(ctx
, OPC_BC
, rs
, rt
, s
);
21153 gen_compute_compact_branch_nm(ctx
, OPC_BGEC
, rs
, rt
, s
);
21157 if (rs
== rt
|| rt
== 0) {
21158 gen_compute_compact_branch_nm(ctx
, OPC_BC
, 0, 0, s
);
21159 } else if (rs
== 0) {
21160 gen_compute_compact_branch_nm(ctx
, OPC_BEQZC
, rt
, 0, s
);
21162 gen_compute_compact_branch_nm(ctx
, OPC_BGEUC
, rs
, rt
, s
);
21170 int32_t s
= sextract32(ctx
->opcode
, 0, 1) << 14 |
21171 extract32(ctx
->opcode
, 1, 13) << 1;
21172 switch (extract32(ctx
->opcode
, 14, 2)) {
21175 gen_compute_branch_nm(ctx
, OPC_BNE
, 4, rs
, rt
, s
);
21178 if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
21180 ctx
->hflags
|= MIPS_HFLAG_FBNSLOT
;
21182 gen_compute_compact_branch_nm(ctx
, OPC_BLTC
, rs
, rt
, s
);
21186 if (rs
== 0 || rs
== rt
) {
21188 ctx
->hflags
|= MIPS_HFLAG_FBNSLOT
;
21190 gen_compute_compact_branch_nm(ctx
, OPC_BLTUC
, rs
, rt
, s
);
21194 gen_reserved_instruction(ctx
);
21201 int32_t s
= sextract32(ctx
->opcode
, 0, 1) << 11 |
21202 extract32(ctx
->opcode
, 1, 10) << 1;
21203 uint32_t u
= extract32(ctx
->opcode
, 11, 7);
21205 gen_compute_imm_branch(ctx
, extract32(ctx
->opcode
, 18, 3),
21210 gen_reserved_instruction(ctx
);
21216 static int decode_nanomips_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
21219 int rt
= decode_gpr_gpr3(NANOMIPS_EXTRACT_RT3(ctx
->opcode
));
21220 int rs
= decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx
->opcode
));
21221 int rd
= decode_gpr_gpr3(NANOMIPS_EXTRACT_RD3(ctx
->opcode
));
21225 /* make sure instructions are on a halfword boundary */
21226 if (ctx
->base
.pc_next
& 0x1) {
21227 TCGv tmp
= tcg_const_tl(ctx
->base
.pc_next
);
21228 tcg_gen_st_tl(tmp
, cpu_env
, offsetof(CPUMIPSState
, CP0_BadVAddr
));
21229 tcg_temp_free(tmp
);
21230 generate_exception_end(ctx
, EXCP_AdEL
);
21234 op
= extract32(ctx
->opcode
, 10, 6);
21237 rt
= NANOMIPS_EXTRACT_RD5(ctx
->opcode
);
21240 rs
= NANOMIPS_EXTRACT_RS5(ctx
->opcode
);
21241 gen_arith(ctx
, OPC_ADDU
, rt
, rs
, 0);
21244 switch (extract32(ctx
->opcode
, 3, 2)) {
21245 case NM_P16_SYSCALL
:
21246 if (extract32(ctx
->opcode
, 2, 1) == 0) {
21247 generate_exception_end(ctx
, EXCP_SYSCALL
);
21249 gen_reserved_instruction(ctx
);
21253 generate_exception_end(ctx
, EXCP_BREAK
);
21256 if (is_uhi(extract32(ctx
->opcode
, 0, 3))) {
21257 gen_helper_do_semihosting(cpu_env
);
21259 if (ctx
->hflags
& MIPS_HFLAG_SBRI
) {
21260 gen_reserved_instruction(ctx
);
21262 generate_exception_end(ctx
, EXCP_DBp
);
21267 gen_reserved_instruction(ctx
);
21274 int shift
= extract32(ctx
->opcode
, 0, 3);
21276 shift
= (shift
== 0) ? 8 : shift
;
21278 switch (extract32(ctx
->opcode
, 3, 1)) {
21286 gen_shift_imm(ctx
, opc
, rt
, rs
, shift
);
21290 switch (ctx
->opcode
& 1) {
21292 gen_pool16c_nanomips_insn(ctx
);
21295 gen_ldxs(ctx
, rt
, rs
, rd
);
21300 switch (extract32(ctx
->opcode
, 6, 1)) {
21302 imm
= extract32(ctx
->opcode
, 0, 6) << 2;
21303 gen_arith_imm(ctx
, OPC_ADDIU
, rt
, 29, imm
);
21306 gen_reserved_instruction(ctx
);
21311 switch (extract32(ctx
->opcode
, 3, 1)) {
21313 imm
= extract32(ctx
->opcode
, 0, 3) << 2;
21314 gen_arith_imm(ctx
, OPC_ADDIU
, rt
, rs
, imm
);
21316 case NM_P_ADDIURS5
:
21317 rt
= extract32(ctx
->opcode
, 5, 5);
21319 /* imm = sign_extend(s[3] . s[2:0] , from_nbits = 4) */
21320 imm
= (sextract32(ctx
->opcode
, 4, 1) << 3) |
21321 (extract32(ctx
->opcode
, 0, 3));
21322 gen_arith_imm(ctx
, OPC_ADDIU
, rt
, rt
, imm
);
21328 switch (ctx
->opcode
& 0x1) {
21330 gen_arith(ctx
, OPC_ADDU
, rd
, rs
, rt
);
21333 gen_arith(ctx
, OPC_SUBU
, rd
, rs
, rt
);
21338 rt
= (extract32(ctx
->opcode
, 9, 1) << 3) |
21339 extract32(ctx
->opcode
, 5, 3);
21340 rs
= (extract32(ctx
->opcode
, 4, 1) << 3) |
21341 extract32(ctx
->opcode
, 0, 3);
21342 rt
= decode_gpr_gpr4(rt
);
21343 rs
= decode_gpr_gpr4(rs
);
21344 switch ((extract32(ctx
->opcode
, 7, 2) & 0x2) |
21345 (extract32(ctx
->opcode
, 3, 1))) {
21348 gen_arith(ctx
, OPC_ADDU
, rt
, rs
, rt
);
21352 gen_r6_muldiv(ctx
, R6_OPC_MUL
, rt
, rs
, rt
);
21355 gen_reserved_instruction(ctx
);
21361 int imm
= extract32(ctx
->opcode
, 0, 7);
21362 imm
= (imm
== 0x7f ? -1 : imm
);
21364 tcg_gen_movi_tl(cpu_gpr
[rt
], imm
);
21370 uint32_t u
= extract32(ctx
->opcode
, 0, 4);
21371 u
= (u
== 12) ? 0xff :
21372 (u
== 13) ? 0xffff : u
;
21373 gen_logic_imm(ctx
, OPC_ANDI
, rt
, rs
, u
);
21377 offset
= extract32(ctx
->opcode
, 0, 2);
21378 switch (extract32(ctx
->opcode
, 2, 2)) {
21380 gen_ld(ctx
, OPC_LB
, rt
, rs
, offset
);
21383 rt
= decode_gpr_gpr3_src_store(
21384 NANOMIPS_EXTRACT_RT3(ctx
->opcode
));
21385 gen_st(ctx
, OPC_SB
, rt
, rs
, offset
);
21388 gen_ld(ctx
, OPC_LBU
, rt
, rs
, offset
);
21391 gen_reserved_instruction(ctx
);
21396 offset
= extract32(ctx
->opcode
, 1, 2) << 1;
21397 switch ((extract32(ctx
->opcode
, 3, 1) << 1) | (ctx
->opcode
& 1)) {
21399 gen_ld(ctx
, OPC_LH
, rt
, rs
, offset
);
21402 rt
= decode_gpr_gpr3_src_store(
21403 NANOMIPS_EXTRACT_RT3(ctx
->opcode
));
21404 gen_st(ctx
, OPC_SH
, rt
, rs
, offset
);
21407 gen_ld(ctx
, OPC_LHU
, rt
, rs
, offset
);
21410 gen_reserved_instruction(ctx
);
21415 offset
= extract32(ctx
->opcode
, 0, 4) << 2;
21416 gen_ld(ctx
, OPC_LW
, rt
, rs
, offset
);
21419 rt
= NANOMIPS_EXTRACT_RD5(ctx
->opcode
);
21420 offset
= extract32(ctx
->opcode
, 0, 5) << 2;
21421 gen_ld(ctx
, OPC_LW
, rt
, 29, offset
);
21425 rt
= (extract32(ctx
->opcode
, 9, 1) << 3) |
21426 extract32(ctx
->opcode
, 5, 3);
21427 rs
= (extract32(ctx
->opcode
, 4, 1) << 3) |
21428 extract32(ctx
->opcode
, 0, 3);
21429 offset
= (extract32(ctx
->opcode
, 3, 1) << 3) |
21430 (extract32(ctx
->opcode
, 8, 1) << 2);
21431 rt
= decode_gpr_gpr4(rt
);
21432 rs
= decode_gpr_gpr4(rs
);
21433 gen_ld(ctx
, OPC_LW
, rt
, rs
, offset
);
21437 rt
= (extract32(ctx
->opcode
, 9, 1) << 3) |
21438 extract32(ctx
->opcode
, 5, 3);
21439 rs
= (extract32(ctx
->opcode
, 4, 1) << 3) |
21440 extract32(ctx
->opcode
, 0, 3);
21441 offset
= (extract32(ctx
->opcode
, 3, 1) << 3) |
21442 (extract32(ctx
->opcode
, 8, 1) << 2);
21443 rt
= decode_gpr_gpr4_zero(rt
);
21444 rs
= decode_gpr_gpr4(rs
);
21445 gen_st(ctx
, OPC_SW
, rt
, rs
, offset
);
21448 offset
= extract32(ctx
->opcode
, 0, 7) << 2;
21449 gen_ld(ctx
, OPC_LW
, rt
, 28, offset
);
21452 rt
= NANOMIPS_EXTRACT_RD5(ctx
->opcode
);
21453 offset
= extract32(ctx
->opcode
, 0, 5) << 2;
21454 gen_st(ctx
, OPC_SW
, rt
, 29, offset
);
21457 rt
= decode_gpr_gpr3_src_store(
21458 NANOMIPS_EXTRACT_RT3(ctx
->opcode
));
21459 rs
= decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx
->opcode
));
21460 offset
= extract32(ctx
->opcode
, 0, 4) << 2;
21461 gen_st(ctx
, OPC_SW
, rt
, rs
, offset
);
21464 rt
= decode_gpr_gpr3_src_store(
21465 NANOMIPS_EXTRACT_RT3(ctx
->opcode
));
21466 offset
= extract32(ctx
->opcode
, 0, 7) << 2;
21467 gen_st(ctx
, OPC_SW
, rt
, 28, offset
);
21470 gen_compute_branch_nm(ctx
, OPC_BEQ
, 2, 0, 0,
21471 (sextract32(ctx
->opcode
, 0, 1) << 10) |
21472 (extract32(ctx
->opcode
, 1, 9) << 1));
21475 gen_compute_branch_nm(ctx
, OPC_BGEZAL
, 2, 0, 0,
21476 (sextract32(ctx
->opcode
, 0, 1) << 10) |
21477 (extract32(ctx
->opcode
, 1, 9) << 1));
21480 gen_compute_branch_nm(ctx
, OPC_BEQ
, 2, rt
, 0,
21481 (sextract32(ctx
->opcode
, 0, 1) << 7) |
21482 (extract32(ctx
->opcode
, 1, 6) << 1));
21485 gen_compute_branch_nm(ctx
, OPC_BNE
, 2, rt
, 0,
21486 (sextract32(ctx
->opcode
, 0, 1) << 7) |
21487 (extract32(ctx
->opcode
, 1, 6) << 1));
21490 switch (ctx
->opcode
& 0xf) {
21493 switch (extract32(ctx
->opcode
, 4, 1)) {
21495 gen_compute_branch_nm(ctx
, OPC_JR
, 2,
21496 extract32(ctx
->opcode
, 5, 5), 0, 0);
21499 gen_compute_branch_nm(ctx
, OPC_JALR
, 2,
21500 extract32(ctx
->opcode
, 5, 5), 31, 0);
21507 uint32_t opc
= extract32(ctx
->opcode
, 4, 3) <
21508 extract32(ctx
->opcode
, 7, 3) ? OPC_BEQ
: OPC_BNE
;
21509 gen_compute_branch_nm(ctx
, opc
, 2, rs
, rt
,
21510 extract32(ctx
->opcode
, 0, 4) << 1);
21517 int count
= extract32(ctx
->opcode
, 0, 4);
21518 int u
= extract32(ctx
->opcode
, 4, 4) << 4;
21520 rt
= 30 + extract32(ctx
->opcode
, 9, 1);
21521 switch (extract32(ctx
->opcode
, 8, 1)) {
21523 gen_save(ctx
, rt
, count
, 0, u
);
21525 case NM_RESTORE_JRC16
:
21526 gen_restore(ctx
, rt
, count
, 0, u
);
21527 gen_compute_branch_nm(ctx
, OPC_JR
, 2, 31, 0, 0);
21536 static const int gpr2reg1
[] = {4, 5, 6, 7};
21537 static const int gpr2reg2
[] = {5, 6, 7, 8};
21539 int rd2
= extract32(ctx
->opcode
, 3, 1) << 1 |
21540 extract32(ctx
->opcode
, 8, 1);
21541 int r1
= gpr2reg1
[rd2
];
21542 int r2
= gpr2reg2
[rd2
];
21543 int r3
= extract32(ctx
->opcode
, 4, 1) << 3 |
21544 extract32(ctx
->opcode
, 0, 3);
21545 int r4
= extract32(ctx
->opcode
, 9, 1) << 3 |
21546 extract32(ctx
->opcode
, 5, 3);
21547 TCGv t0
= tcg_temp_new();
21548 TCGv t1
= tcg_temp_new();
21549 if (op
== NM_MOVEP
) {
21552 rs
= decode_gpr_gpr4_zero(r3
);
21553 rt
= decode_gpr_gpr4_zero(r4
);
21555 rd
= decode_gpr_gpr4(r3
);
21556 re
= decode_gpr_gpr4(r4
);
21560 gen_load_gpr(t0
, rs
);
21561 gen_load_gpr(t1
, rt
);
21562 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
21563 tcg_gen_mov_tl(cpu_gpr
[re
], t1
);
21569 return decode_nanomips_32_48_opc(env
, ctx
);
21576 /* SmartMIPS extension to MIPS32 */
21578 #if defined(TARGET_MIPS64)
21580 /* MDMX extension to MIPS64 */
21584 /* MIPSDSP functions. */
21585 static void gen_mipsdsp_ld(DisasContext
*ctx
, uint32_t opc
,
21586 int rd
, int base
, int offset
)
21591 t0
= tcg_temp_new();
21594 gen_load_gpr(t0
, offset
);
21595 } else if (offset
== 0) {
21596 gen_load_gpr(t0
, base
);
21598 gen_op_addr_add(ctx
, t0
, cpu_gpr
[base
], cpu_gpr
[offset
]);
21603 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_UB
);
21604 gen_store_gpr(t0
, rd
);
21607 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESW
);
21608 gen_store_gpr(t0
, rd
);
21611 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESL
);
21612 gen_store_gpr(t0
, rd
);
21614 #if defined(TARGET_MIPS64)
21616 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
);
21617 gen_store_gpr(t0
, rd
);
21624 static void gen_mipsdsp_arith(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
21625 int ret
, int v1
, int v2
)
21631 /* Treat as NOP. */
21635 v1_t
= tcg_temp_new();
21636 v2_t
= tcg_temp_new();
21638 gen_load_gpr(v1_t
, v1
);
21639 gen_load_gpr(v2_t
, v2
);
21642 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
21643 case OPC_MULT_G_2E
:
21647 gen_helper_adduh_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
21649 case OPC_ADDUH_R_QB
:
21650 gen_helper_adduh_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
21653 gen_helper_addqh_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
21655 case OPC_ADDQH_R_PH
:
21656 gen_helper_addqh_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
21659 gen_helper_addqh_w(cpu_gpr
[ret
], v1_t
, v2_t
);
21661 case OPC_ADDQH_R_W
:
21662 gen_helper_addqh_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
21665 gen_helper_subuh_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
21667 case OPC_SUBUH_R_QB
:
21668 gen_helper_subuh_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
21671 gen_helper_subqh_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
21673 case OPC_SUBQH_R_PH
:
21674 gen_helper_subqh_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
21677 gen_helper_subqh_w(cpu_gpr
[ret
], v1_t
, v2_t
);
21679 case OPC_SUBQH_R_W
:
21680 gen_helper_subqh_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
21684 case OPC_ABSQ_S_PH_DSP
:
21686 case OPC_ABSQ_S_QB
:
21688 gen_helper_absq_s_qb(cpu_gpr
[ret
], v2_t
, cpu_env
);
21690 case OPC_ABSQ_S_PH
:
21692 gen_helper_absq_s_ph(cpu_gpr
[ret
], v2_t
, cpu_env
);
21696 gen_helper_absq_s_w(cpu_gpr
[ret
], v2_t
, cpu_env
);
21698 case OPC_PRECEQ_W_PHL
:
21700 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0xFFFF0000);
21701 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
21703 case OPC_PRECEQ_W_PHR
:
21705 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0x0000FFFF);
21706 tcg_gen_shli_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], 16);
21707 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
21709 case OPC_PRECEQU_PH_QBL
:
21711 gen_helper_precequ_ph_qbl(cpu_gpr
[ret
], v2_t
);
21713 case OPC_PRECEQU_PH_QBR
:
21715 gen_helper_precequ_ph_qbr(cpu_gpr
[ret
], v2_t
);
21717 case OPC_PRECEQU_PH_QBLA
:
21719 gen_helper_precequ_ph_qbla(cpu_gpr
[ret
], v2_t
);
21721 case OPC_PRECEQU_PH_QBRA
:
21723 gen_helper_precequ_ph_qbra(cpu_gpr
[ret
], v2_t
);
21725 case OPC_PRECEU_PH_QBL
:
21727 gen_helper_preceu_ph_qbl(cpu_gpr
[ret
], v2_t
);
21729 case OPC_PRECEU_PH_QBR
:
21731 gen_helper_preceu_ph_qbr(cpu_gpr
[ret
], v2_t
);
21733 case OPC_PRECEU_PH_QBLA
:
21735 gen_helper_preceu_ph_qbla(cpu_gpr
[ret
], v2_t
);
21737 case OPC_PRECEU_PH_QBRA
:
21739 gen_helper_preceu_ph_qbra(cpu_gpr
[ret
], v2_t
);
21743 case OPC_ADDU_QB_DSP
:
21747 gen_helper_addq_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21749 case OPC_ADDQ_S_PH
:
21751 gen_helper_addq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21755 gen_helper_addq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21759 gen_helper_addu_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21761 case OPC_ADDU_S_QB
:
21763 gen_helper_addu_s_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21767 gen_helper_addu_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21769 case OPC_ADDU_S_PH
:
21771 gen_helper_addu_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21775 gen_helper_subq_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21777 case OPC_SUBQ_S_PH
:
21779 gen_helper_subq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21783 gen_helper_subq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21787 gen_helper_subu_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21789 case OPC_SUBU_S_QB
:
21791 gen_helper_subu_s_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21795 gen_helper_subu_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21797 case OPC_SUBU_S_PH
:
21799 gen_helper_subu_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21803 gen_helper_addsc(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21807 gen_helper_addwc(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21811 gen_helper_modsub(cpu_gpr
[ret
], v1_t
, v2_t
);
21813 case OPC_RADDU_W_QB
:
21815 gen_helper_raddu_w_qb(cpu_gpr
[ret
], v1_t
);
21819 case OPC_CMPU_EQ_QB_DSP
:
21821 case OPC_PRECR_QB_PH
:
21823 gen_helper_precr_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
21825 case OPC_PRECRQ_QB_PH
:
21827 gen_helper_precrq_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
21829 case OPC_PRECR_SRA_PH_W
:
21832 TCGv_i32 sa_t
= tcg_const_i32(v2
);
21833 gen_helper_precr_sra_ph_w(cpu_gpr
[ret
], sa_t
, v1_t
,
21835 tcg_temp_free_i32(sa_t
);
21838 case OPC_PRECR_SRA_R_PH_W
:
21841 TCGv_i32 sa_t
= tcg_const_i32(v2
);
21842 gen_helper_precr_sra_r_ph_w(cpu_gpr
[ret
], sa_t
, v1_t
,
21844 tcg_temp_free_i32(sa_t
);
21847 case OPC_PRECRQ_PH_W
:
21849 gen_helper_precrq_ph_w(cpu_gpr
[ret
], v1_t
, v2_t
);
21851 case OPC_PRECRQ_RS_PH_W
:
21853 gen_helper_precrq_rs_ph_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21855 case OPC_PRECRQU_S_QB_PH
:
21857 gen_helper_precrqu_s_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21861 #ifdef TARGET_MIPS64
21862 case OPC_ABSQ_S_QH_DSP
:
21864 case OPC_PRECEQ_L_PWL
:
21866 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0xFFFFFFFF00000000ull
);
21868 case OPC_PRECEQ_L_PWR
:
21870 tcg_gen_shli_tl(cpu_gpr
[ret
], v2_t
, 32);
21872 case OPC_PRECEQ_PW_QHL
:
21874 gen_helper_preceq_pw_qhl(cpu_gpr
[ret
], v2_t
);
21876 case OPC_PRECEQ_PW_QHR
:
21878 gen_helper_preceq_pw_qhr(cpu_gpr
[ret
], v2_t
);
21880 case OPC_PRECEQ_PW_QHLA
:
21882 gen_helper_preceq_pw_qhla(cpu_gpr
[ret
], v2_t
);
21884 case OPC_PRECEQ_PW_QHRA
:
21886 gen_helper_preceq_pw_qhra(cpu_gpr
[ret
], v2_t
);
21888 case OPC_PRECEQU_QH_OBL
:
21890 gen_helper_precequ_qh_obl(cpu_gpr
[ret
], v2_t
);
21892 case OPC_PRECEQU_QH_OBR
:
21894 gen_helper_precequ_qh_obr(cpu_gpr
[ret
], v2_t
);
21896 case OPC_PRECEQU_QH_OBLA
:
21898 gen_helper_precequ_qh_obla(cpu_gpr
[ret
], v2_t
);
21900 case OPC_PRECEQU_QH_OBRA
:
21902 gen_helper_precequ_qh_obra(cpu_gpr
[ret
], v2_t
);
21904 case OPC_PRECEU_QH_OBL
:
21906 gen_helper_preceu_qh_obl(cpu_gpr
[ret
], v2_t
);
21908 case OPC_PRECEU_QH_OBR
:
21910 gen_helper_preceu_qh_obr(cpu_gpr
[ret
], v2_t
);
21912 case OPC_PRECEU_QH_OBLA
:
21914 gen_helper_preceu_qh_obla(cpu_gpr
[ret
], v2_t
);
21916 case OPC_PRECEU_QH_OBRA
:
21918 gen_helper_preceu_qh_obra(cpu_gpr
[ret
], v2_t
);
21920 case OPC_ABSQ_S_OB
:
21922 gen_helper_absq_s_ob(cpu_gpr
[ret
], v2_t
, cpu_env
);
21924 case OPC_ABSQ_S_PW
:
21926 gen_helper_absq_s_pw(cpu_gpr
[ret
], v2_t
, cpu_env
);
21928 case OPC_ABSQ_S_QH
:
21930 gen_helper_absq_s_qh(cpu_gpr
[ret
], v2_t
, cpu_env
);
21934 case OPC_ADDU_OB_DSP
:
21936 case OPC_RADDU_L_OB
:
21938 gen_helper_raddu_l_ob(cpu_gpr
[ret
], v1_t
);
21942 gen_helper_subq_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21944 case OPC_SUBQ_S_PW
:
21946 gen_helper_subq_s_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21950 gen_helper_subq_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21952 case OPC_SUBQ_S_QH
:
21954 gen_helper_subq_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21958 gen_helper_subu_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21960 case OPC_SUBU_S_OB
:
21962 gen_helper_subu_s_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21966 gen_helper_subu_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21968 case OPC_SUBU_S_QH
:
21970 gen_helper_subu_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21974 gen_helper_subuh_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
21976 case OPC_SUBUH_R_OB
:
21978 gen_helper_subuh_r_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
21982 gen_helper_addq_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21984 case OPC_ADDQ_S_PW
:
21986 gen_helper_addq_s_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21990 gen_helper_addq_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21992 case OPC_ADDQ_S_QH
:
21994 gen_helper_addq_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21998 gen_helper_addu_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22000 case OPC_ADDU_S_OB
:
22002 gen_helper_addu_s_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22006 gen_helper_addu_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22008 case OPC_ADDU_S_QH
:
22010 gen_helper_addu_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22014 gen_helper_adduh_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
22016 case OPC_ADDUH_R_OB
:
22018 gen_helper_adduh_r_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
22022 case OPC_CMPU_EQ_OB_DSP
:
22024 case OPC_PRECR_OB_QH
:
22026 gen_helper_precr_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
);
22028 case OPC_PRECR_SRA_QH_PW
:
22031 TCGv_i32 ret_t
= tcg_const_i32(ret
);
22032 gen_helper_precr_sra_qh_pw(v2_t
, v1_t
, v2_t
, ret_t
);
22033 tcg_temp_free_i32(ret_t
);
22036 case OPC_PRECR_SRA_R_QH_PW
:
22039 TCGv_i32 sa_v
= tcg_const_i32(ret
);
22040 gen_helper_precr_sra_r_qh_pw(v2_t
, v1_t
, v2_t
, sa_v
);
22041 tcg_temp_free_i32(sa_v
);
22044 case OPC_PRECRQ_OB_QH
:
22046 gen_helper_precrq_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
);
22048 case OPC_PRECRQ_PW_L
:
22050 gen_helper_precrq_pw_l(cpu_gpr
[ret
], v1_t
, v2_t
);
22052 case OPC_PRECRQ_QH_PW
:
22054 gen_helper_precrq_qh_pw(cpu_gpr
[ret
], v1_t
, v2_t
);
22056 case OPC_PRECRQ_RS_QH_PW
:
22058 gen_helper_precrq_rs_qh_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22060 case OPC_PRECRQU_S_OB_QH
:
22062 gen_helper_precrqu_s_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22069 tcg_temp_free(v1_t
);
22070 tcg_temp_free(v2_t
);
22073 static void gen_mipsdsp_shift(DisasContext
*ctx
, uint32_t opc
,
22074 int ret
, int v1
, int v2
)
22082 /* Treat as NOP. */
22086 t0
= tcg_temp_new();
22087 v1_t
= tcg_temp_new();
22088 v2_t
= tcg_temp_new();
22090 tcg_gen_movi_tl(t0
, v1
);
22091 gen_load_gpr(v1_t
, v1
);
22092 gen_load_gpr(v2_t
, v2
);
22095 case OPC_SHLL_QB_DSP
:
22097 op2
= MASK_SHLL_QB(ctx
->opcode
);
22101 gen_helper_shll_qb(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
22105 gen_helper_shll_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22109 gen_helper_shll_ph(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
22113 gen_helper_shll_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22115 case OPC_SHLL_S_PH
:
22117 gen_helper_shll_s_ph(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
22119 case OPC_SHLLV_S_PH
:
22121 gen_helper_shll_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22125 gen_helper_shll_s_w(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
22127 case OPC_SHLLV_S_W
:
22129 gen_helper_shll_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22133 gen_helper_shrl_qb(cpu_gpr
[ret
], t0
, v2_t
);
22137 gen_helper_shrl_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
22141 gen_helper_shrl_ph(cpu_gpr
[ret
], t0
, v2_t
);
22145 gen_helper_shrl_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
22149 gen_helper_shra_qb(cpu_gpr
[ret
], t0
, v2_t
);
22151 case OPC_SHRA_R_QB
:
22153 gen_helper_shra_r_qb(cpu_gpr
[ret
], t0
, v2_t
);
22157 gen_helper_shra_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
22159 case OPC_SHRAV_R_QB
:
22161 gen_helper_shra_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
22165 gen_helper_shra_ph(cpu_gpr
[ret
], t0
, v2_t
);
22167 case OPC_SHRA_R_PH
:
22169 gen_helper_shra_r_ph(cpu_gpr
[ret
], t0
, v2_t
);
22173 gen_helper_shra_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
22175 case OPC_SHRAV_R_PH
:
22177 gen_helper_shra_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
22181 gen_helper_shra_r_w(cpu_gpr
[ret
], t0
, v2_t
);
22183 case OPC_SHRAV_R_W
:
22185 gen_helper_shra_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
22187 default: /* Invalid */
22188 MIPS_INVAL("MASK SHLL.QB");
22189 gen_reserved_instruction(ctx
);
22194 #ifdef TARGET_MIPS64
22195 case OPC_SHLL_OB_DSP
:
22196 op2
= MASK_SHLL_OB(ctx
->opcode
);
22200 gen_helper_shll_pw(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
22204 gen_helper_shll_pw(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
22206 case OPC_SHLL_S_PW
:
22208 gen_helper_shll_s_pw(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
22210 case OPC_SHLLV_S_PW
:
22212 gen_helper_shll_s_pw(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
22216 gen_helper_shll_ob(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
22220 gen_helper_shll_ob(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
22224 gen_helper_shll_qh(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
22228 gen_helper_shll_qh(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
22230 case OPC_SHLL_S_QH
:
22232 gen_helper_shll_s_qh(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
22234 case OPC_SHLLV_S_QH
:
22236 gen_helper_shll_s_qh(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
22240 gen_helper_shra_ob(cpu_gpr
[ret
], v2_t
, t0
);
22244 gen_helper_shra_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
22246 case OPC_SHRA_R_OB
:
22248 gen_helper_shra_r_ob(cpu_gpr
[ret
], v2_t
, t0
);
22250 case OPC_SHRAV_R_OB
:
22252 gen_helper_shra_r_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
22256 gen_helper_shra_pw(cpu_gpr
[ret
], v2_t
, t0
);
22260 gen_helper_shra_pw(cpu_gpr
[ret
], v2_t
, v1_t
);
22262 case OPC_SHRA_R_PW
:
22264 gen_helper_shra_r_pw(cpu_gpr
[ret
], v2_t
, t0
);
22266 case OPC_SHRAV_R_PW
:
22268 gen_helper_shra_r_pw(cpu_gpr
[ret
], v2_t
, v1_t
);
22272 gen_helper_shra_qh(cpu_gpr
[ret
], v2_t
, t0
);
22276 gen_helper_shra_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
22278 case OPC_SHRA_R_QH
:
22280 gen_helper_shra_r_qh(cpu_gpr
[ret
], v2_t
, t0
);
22282 case OPC_SHRAV_R_QH
:
22284 gen_helper_shra_r_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
22288 gen_helper_shrl_ob(cpu_gpr
[ret
], v2_t
, t0
);
22292 gen_helper_shrl_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
22296 gen_helper_shrl_qh(cpu_gpr
[ret
], v2_t
, t0
);
22300 gen_helper_shrl_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
22302 default: /* Invalid */
22303 MIPS_INVAL("MASK SHLL.OB");
22304 gen_reserved_instruction(ctx
);
22312 tcg_temp_free(v1_t
);
22313 tcg_temp_free(v2_t
);
22316 static void gen_mipsdsp_multiply(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
22317 int ret
, int v1
, int v2
, int check_ret
)
22323 if ((ret
== 0) && (check_ret
== 1)) {
22324 /* Treat as NOP. */
22328 t0
= tcg_temp_new_i32();
22329 v1_t
= tcg_temp_new();
22330 v2_t
= tcg_temp_new();
22332 tcg_gen_movi_i32(t0
, ret
);
22333 gen_load_gpr(v1_t
, v1
);
22334 gen_load_gpr(v2_t
, v2
);
22338 * OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
22339 * the same mask and op1.
22341 case OPC_MULT_G_2E
:
22345 gen_helper_mul_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22348 gen_helper_mul_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22351 gen_helper_mulq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22353 case OPC_MULQ_RS_W
:
22354 gen_helper_mulq_rs_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22358 case OPC_DPA_W_PH_DSP
:
22360 case OPC_DPAU_H_QBL
:
22362 gen_helper_dpau_h_qbl(t0
, v1_t
, v2_t
, cpu_env
);
22364 case OPC_DPAU_H_QBR
:
22366 gen_helper_dpau_h_qbr(t0
, v1_t
, v2_t
, cpu_env
);
22368 case OPC_DPSU_H_QBL
:
22370 gen_helper_dpsu_h_qbl(t0
, v1_t
, v2_t
, cpu_env
);
22372 case OPC_DPSU_H_QBR
:
22374 gen_helper_dpsu_h_qbr(t0
, v1_t
, v2_t
, cpu_env
);
22378 gen_helper_dpa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
22380 case OPC_DPAX_W_PH
:
22382 gen_helper_dpax_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
22384 case OPC_DPAQ_S_W_PH
:
22386 gen_helper_dpaq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
22388 case OPC_DPAQX_S_W_PH
:
22390 gen_helper_dpaqx_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
22392 case OPC_DPAQX_SA_W_PH
:
22394 gen_helper_dpaqx_sa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
22398 gen_helper_dps_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
22400 case OPC_DPSX_W_PH
:
22402 gen_helper_dpsx_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
22404 case OPC_DPSQ_S_W_PH
:
22406 gen_helper_dpsq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
22408 case OPC_DPSQX_S_W_PH
:
22410 gen_helper_dpsqx_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
22412 case OPC_DPSQX_SA_W_PH
:
22414 gen_helper_dpsqx_sa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
22416 case OPC_MULSAQ_S_W_PH
:
22418 gen_helper_mulsaq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
22420 case OPC_DPAQ_SA_L_W
:
22422 gen_helper_dpaq_sa_l_w(t0
, v1_t
, v2_t
, cpu_env
);
22424 case OPC_DPSQ_SA_L_W
:
22426 gen_helper_dpsq_sa_l_w(t0
, v1_t
, v2_t
, cpu_env
);
22428 case OPC_MAQ_S_W_PHL
:
22430 gen_helper_maq_s_w_phl(t0
, v1_t
, v2_t
, cpu_env
);
22432 case OPC_MAQ_S_W_PHR
:
22434 gen_helper_maq_s_w_phr(t0
, v1_t
, v2_t
, cpu_env
);
22436 case OPC_MAQ_SA_W_PHL
:
22438 gen_helper_maq_sa_w_phl(t0
, v1_t
, v2_t
, cpu_env
);
22440 case OPC_MAQ_SA_W_PHR
:
22442 gen_helper_maq_sa_w_phr(t0
, v1_t
, v2_t
, cpu_env
);
22444 case OPC_MULSA_W_PH
:
22446 gen_helper_mulsa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
22450 #ifdef TARGET_MIPS64
22451 case OPC_DPAQ_W_QH_DSP
:
22453 int ac
= ret
& 0x03;
22454 tcg_gen_movi_i32(t0
, ac
);
22459 gen_helper_dmadd(v1_t
, v2_t
, t0
, cpu_env
);
22463 gen_helper_dmaddu(v1_t
, v2_t
, t0
, cpu_env
);
22467 gen_helper_dmsub(v1_t
, v2_t
, t0
, cpu_env
);
22471 gen_helper_dmsubu(v1_t
, v2_t
, t0
, cpu_env
);
22475 gen_helper_dpa_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
22477 case OPC_DPAQ_S_W_QH
:
22479 gen_helper_dpaq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
22481 case OPC_DPAQ_SA_L_PW
:
22483 gen_helper_dpaq_sa_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
22485 case OPC_DPAU_H_OBL
:
22487 gen_helper_dpau_h_obl(v1_t
, v2_t
, t0
, cpu_env
);
22489 case OPC_DPAU_H_OBR
:
22491 gen_helper_dpau_h_obr(v1_t
, v2_t
, t0
, cpu_env
);
22495 gen_helper_dps_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
22497 case OPC_DPSQ_S_W_QH
:
22499 gen_helper_dpsq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
22501 case OPC_DPSQ_SA_L_PW
:
22503 gen_helper_dpsq_sa_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
22505 case OPC_DPSU_H_OBL
:
22507 gen_helper_dpsu_h_obl(v1_t
, v2_t
, t0
, cpu_env
);
22509 case OPC_DPSU_H_OBR
:
22511 gen_helper_dpsu_h_obr(v1_t
, v2_t
, t0
, cpu_env
);
22513 case OPC_MAQ_S_L_PWL
:
22515 gen_helper_maq_s_l_pwl(v1_t
, v2_t
, t0
, cpu_env
);
22517 case OPC_MAQ_S_L_PWR
:
22519 gen_helper_maq_s_l_pwr(v1_t
, v2_t
, t0
, cpu_env
);
22521 case OPC_MAQ_S_W_QHLL
:
22523 gen_helper_maq_s_w_qhll(v1_t
, v2_t
, t0
, cpu_env
);
22525 case OPC_MAQ_SA_W_QHLL
:
22527 gen_helper_maq_sa_w_qhll(v1_t
, v2_t
, t0
, cpu_env
);
22529 case OPC_MAQ_S_W_QHLR
:
22531 gen_helper_maq_s_w_qhlr(v1_t
, v2_t
, t0
, cpu_env
);
22533 case OPC_MAQ_SA_W_QHLR
:
22535 gen_helper_maq_sa_w_qhlr(v1_t
, v2_t
, t0
, cpu_env
);
22537 case OPC_MAQ_S_W_QHRL
:
22539 gen_helper_maq_s_w_qhrl(v1_t
, v2_t
, t0
, cpu_env
);
22541 case OPC_MAQ_SA_W_QHRL
:
22543 gen_helper_maq_sa_w_qhrl(v1_t
, v2_t
, t0
, cpu_env
);
22545 case OPC_MAQ_S_W_QHRR
:
22547 gen_helper_maq_s_w_qhrr(v1_t
, v2_t
, t0
, cpu_env
);
22549 case OPC_MAQ_SA_W_QHRR
:
22551 gen_helper_maq_sa_w_qhrr(v1_t
, v2_t
, t0
, cpu_env
);
22553 case OPC_MULSAQ_S_L_PW
:
22555 gen_helper_mulsaq_s_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
22557 case OPC_MULSAQ_S_W_QH
:
22559 gen_helper_mulsaq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
22565 case OPC_ADDU_QB_DSP
:
22567 case OPC_MULEU_S_PH_QBL
:
22569 gen_helper_muleu_s_ph_qbl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22571 case OPC_MULEU_S_PH_QBR
:
22573 gen_helper_muleu_s_ph_qbr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22575 case OPC_MULQ_RS_PH
:
22577 gen_helper_mulq_rs_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22579 case OPC_MULEQ_S_W_PHL
:
22581 gen_helper_muleq_s_w_phl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22583 case OPC_MULEQ_S_W_PHR
:
22585 gen_helper_muleq_s_w_phr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22587 case OPC_MULQ_S_PH
:
22589 gen_helper_mulq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22593 #ifdef TARGET_MIPS64
22594 case OPC_ADDU_OB_DSP
:
22596 case OPC_MULEQ_S_PW_QHL
:
22598 gen_helper_muleq_s_pw_qhl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22600 case OPC_MULEQ_S_PW_QHR
:
22602 gen_helper_muleq_s_pw_qhr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22604 case OPC_MULEU_S_QH_OBL
:
22606 gen_helper_muleu_s_qh_obl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22608 case OPC_MULEU_S_QH_OBR
:
22610 gen_helper_muleu_s_qh_obr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22612 case OPC_MULQ_RS_QH
:
22614 gen_helper_mulq_rs_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22621 tcg_temp_free_i32(t0
);
22622 tcg_temp_free(v1_t
);
22623 tcg_temp_free(v2_t
);
22626 static void gen_mipsdsp_bitinsn(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
22634 /* Treat as NOP. */
22638 t0
= tcg_temp_new();
22639 val_t
= tcg_temp_new();
22640 gen_load_gpr(val_t
, val
);
22643 case OPC_ABSQ_S_PH_DSP
:
22647 gen_helper_bitrev(cpu_gpr
[ret
], val_t
);
22652 target_long result
;
22653 imm
= (ctx
->opcode
>> 16) & 0xFF;
22654 result
= (uint32_t)imm
<< 24 |
22655 (uint32_t)imm
<< 16 |
22656 (uint32_t)imm
<< 8 |
22658 result
= (int32_t)result
;
22659 tcg_gen_movi_tl(cpu_gpr
[ret
], result
);
22664 tcg_gen_ext8u_tl(cpu_gpr
[ret
], val_t
);
22665 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 8);
22666 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
22667 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
22668 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
22669 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
22674 imm
= (ctx
->opcode
>> 16) & 0x03FF;
22675 imm
= (int16_t)(imm
<< 6) >> 6;
22676 tcg_gen_movi_tl(cpu_gpr
[ret
], \
22677 (target_long
)((int32_t)imm
<< 16 | \
22683 tcg_gen_ext16u_tl(cpu_gpr
[ret
], val_t
);
22684 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
22685 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
22686 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
22690 #ifdef TARGET_MIPS64
22691 case OPC_ABSQ_S_QH_DSP
:
22698 imm
= (ctx
->opcode
>> 16) & 0xFF;
22699 temp
= ((uint64_t)imm
<< 8) | (uint64_t)imm
;
22700 temp
= (temp
<< 16) | temp
;
22701 temp
= (temp
<< 32) | temp
;
22702 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
22710 imm
= (ctx
->opcode
>> 16) & 0x03FF;
22711 imm
= (int16_t)(imm
<< 6) >> 6;
22712 temp
= ((target_long
)imm
<< 32) \
22713 | ((target_long
)imm
& 0xFFFFFFFF);
22714 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
22722 imm
= (ctx
->opcode
>> 16) & 0x03FF;
22723 imm
= (int16_t)(imm
<< 6) >> 6;
22725 temp
= ((uint64_t)(uint16_t)imm
<< 48) |
22726 ((uint64_t)(uint16_t)imm
<< 32) |
22727 ((uint64_t)(uint16_t)imm
<< 16) |
22728 (uint64_t)(uint16_t)imm
;
22729 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
22734 tcg_gen_ext8u_tl(cpu_gpr
[ret
], val_t
);
22735 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 8);
22736 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
22737 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
22738 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
22739 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
22740 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
22744 tcg_gen_ext32u_i64(cpu_gpr
[ret
], val_t
);
22745 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
22746 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
22750 tcg_gen_ext16u_tl(cpu_gpr
[ret
], val_t
);
22751 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
22752 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
22753 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
22754 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
22761 tcg_temp_free(val_t
);
22764 static void gen_mipsdsp_add_cmp_pick(DisasContext
*ctx
,
22765 uint32_t op1
, uint32_t op2
,
22766 int ret
, int v1
, int v2
, int check_ret
)
22772 if ((ret
== 0) && (check_ret
== 1)) {
22773 /* Treat as NOP. */
22777 t1
= tcg_temp_new();
22778 v1_t
= tcg_temp_new();
22779 v2_t
= tcg_temp_new();
22781 gen_load_gpr(v1_t
, v1
);
22782 gen_load_gpr(v2_t
, v2
);
22785 case OPC_CMPU_EQ_QB_DSP
:
22787 case OPC_CMPU_EQ_QB
:
22789 gen_helper_cmpu_eq_qb(v1_t
, v2_t
, cpu_env
);
22791 case OPC_CMPU_LT_QB
:
22793 gen_helper_cmpu_lt_qb(v1_t
, v2_t
, cpu_env
);
22795 case OPC_CMPU_LE_QB
:
22797 gen_helper_cmpu_le_qb(v1_t
, v2_t
, cpu_env
);
22799 case OPC_CMPGU_EQ_QB
:
22801 gen_helper_cmpgu_eq_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
22803 case OPC_CMPGU_LT_QB
:
22805 gen_helper_cmpgu_lt_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
22807 case OPC_CMPGU_LE_QB
:
22809 gen_helper_cmpgu_le_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
22811 case OPC_CMPGDU_EQ_QB
:
22813 gen_helper_cmpgu_eq_qb(t1
, v1_t
, v2_t
);
22814 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
22815 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
22816 tcg_gen_shli_tl(t1
, t1
, 24);
22817 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
22819 case OPC_CMPGDU_LT_QB
:
22821 gen_helper_cmpgu_lt_qb(t1
, v1_t
, v2_t
);
22822 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
22823 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
22824 tcg_gen_shli_tl(t1
, t1
, 24);
22825 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
22827 case OPC_CMPGDU_LE_QB
:
22829 gen_helper_cmpgu_le_qb(t1
, v1_t
, v2_t
);
22830 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
22831 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
22832 tcg_gen_shli_tl(t1
, t1
, 24);
22833 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
22835 case OPC_CMP_EQ_PH
:
22837 gen_helper_cmp_eq_ph(v1_t
, v2_t
, cpu_env
);
22839 case OPC_CMP_LT_PH
:
22841 gen_helper_cmp_lt_ph(v1_t
, v2_t
, cpu_env
);
22843 case OPC_CMP_LE_PH
:
22845 gen_helper_cmp_le_ph(v1_t
, v2_t
, cpu_env
);
22849 gen_helper_pick_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22853 gen_helper_pick_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22855 case OPC_PACKRL_PH
:
22857 gen_helper_packrl_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
22861 #ifdef TARGET_MIPS64
22862 case OPC_CMPU_EQ_OB_DSP
:
22864 case OPC_CMP_EQ_PW
:
22866 gen_helper_cmp_eq_pw(v1_t
, v2_t
, cpu_env
);
22868 case OPC_CMP_LT_PW
:
22870 gen_helper_cmp_lt_pw(v1_t
, v2_t
, cpu_env
);
22872 case OPC_CMP_LE_PW
:
22874 gen_helper_cmp_le_pw(v1_t
, v2_t
, cpu_env
);
22876 case OPC_CMP_EQ_QH
:
22878 gen_helper_cmp_eq_qh(v1_t
, v2_t
, cpu_env
);
22880 case OPC_CMP_LT_QH
:
22882 gen_helper_cmp_lt_qh(v1_t
, v2_t
, cpu_env
);
22884 case OPC_CMP_LE_QH
:
22886 gen_helper_cmp_le_qh(v1_t
, v2_t
, cpu_env
);
22888 case OPC_CMPGDU_EQ_OB
:
22890 gen_helper_cmpgdu_eq_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22892 case OPC_CMPGDU_LT_OB
:
22894 gen_helper_cmpgdu_lt_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22896 case OPC_CMPGDU_LE_OB
:
22898 gen_helper_cmpgdu_le_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22900 case OPC_CMPGU_EQ_OB
:
22902 gen_helper_cmpgu_eq_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
22904 case OPC_CMPGU_LT_OB
:
22906 gen_helper_cmpgu_lt_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
22908 case OPC_CMPGU_LE_OB
:
22910 gen_helper_cmpgu_le_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
22912 case OPC_CMPU_EQ_OB
:
22914 gen_helper_cmpu_eq_ob(v1_t
, v2_t
, cpu_env
);
22916 case OPC_CMPU_LT_OB
:
22918 gen_helper_cmpu_lt_ob(v1_t
, v2_t
, cpu_env
);
22920 case OPC_CMPU_LE_OB
:
22922 gen_helper_cmpu_le_ob(v1_t
, v2_t
, cpu_env
);
22924 case OPC_PACKRL_PW
:
22926 gen_helper_packrl_pw(cpu_gpr
[ret
], v1_t
, v2_t
);
22930 gen_helper_pick_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22934 gen_helper_pick_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22938 gen_helper_pick_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22946 tcg_temp_free(v1_t
);
22947 tcg_temp_free(v2_t
);
22950 static void gen_mipsdsp_append(CPUMIPSState
*env
, DisasContext
*ctx
,
22951 uint32_t op1
, int rt
, int rs
, int sa
)
22958 /* Treat as NOP. */
22962 t0
= tcg_temp_new();
22963 gen_load_gpr(t0
, rs
);
22966 case OPC_APPEND_DSP
:
22967 switch (MASK_APPEND(ctx
->opcode
)) {
22970 tcg_gen_deposit_tl(cpu_gpr
[rt
], t0
, cpu_gpr
[rt
], sa
, 32 - sa
);
22972 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
22976 tcg_gen_ext32u_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
22977 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], sa
);
22978 tcg_gen_shli_tl(t0
, t0
, 32 - sa
);
22979 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
22981 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
22985 if (sa
!= 0 && sa
!= 2) {
22986 tcg_gen_shli_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 8 * sa
);
22987 tcg_gen_ext32u_tl(t0
, t0
);
22988 tcg_gen_shri_tl(t0
, t0
, 8 * (4 - sa
));
22989 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
22991 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
22993 default: /* Invalid */
22994 MIPS_INVAL("MASK APPEND");
22995 gen_reserved_instruction(ctx
);
22999 #ifdef TARGET_MIPS64
23000 case OPC_DAPPEND_DSP
:
23001 switch (MASK_DAPPEND(ctx
->opcode
)) {
23004 tcg_gen_deposit_tl(cpu_gpr
[rt
], t0
, cpu_gpr
[rt
], sa
, 64 - sa
);
23008 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 0x20 | sa
);
23009 tcg_gen_shli_tl(t0
, t0
, 64 - (0x20 | sa
));
23010 tcg_gen_or_tl(cpu_gpr
[rt
], t0
, t0
);
23014 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], sa
);
23015 tcg_gen_shli_tl(t0
, t0
, 64 - sa
);
23016 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
23021 if (sa
!= 0 && sa
!= 2 && sa
!= 4) {
23022 tcg_gen_shli_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 8 * sa
);
23023 tcg_gen_shri_tl(t0
, t0
, 8 * (8 - sa
));
23024 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
23027 default: /* Invalid */
23028 MIPS_INVAL("MASK DAPPEND");
23029 gen_reserved_instruction(ctx
);
23038 static void gen_mipsdsp_accinsn(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
23039 int ret
, int v1
, int v2
, int check_ret
)
23048 if ((ret
== 0) && (check_ret
== 1)) {
23049 /* Treat as NOP. */
23053 t0
= tcg_temp_new();
23054 t1
= tcg_temp_new();
23055 v1_t
= tcg_temp_new();
23056 v2_t
= tcg_temp_new();
23058 gen_load_gpr(v1_t
, v1
);
23059 gen_load_gpr(v2_t
, v2
);
23062 case OPC_EXTR_W_DSP
:
23066 tcg_gen_movi_tl(t0
, v2
);
23067 tcg_gen_movi_tl(t1
, v1
);
23068 gen_helper_extr_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23071 tcg_gen_movi_tl(t0
, v2
);
23072 tcg_gen_movi_tl(t1
, v1
);
23073 gen_helper_extr_r_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23075 case OPC_EXTR_RS_W
:
23076 tcg_gen_movi_tl(t0
, v2
);
23077 tcg_gen_movi_tl(t1
, v1
);
23078 gen_helper_extr_rs_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23081 tcg_gen_movi_tl(t0
, v2
);
23082 tcg_gen_movi_tl(t1
, v1
);
23083 gen_helper_extr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23085 case OPC_EXTRV_S_H
:
23086 tcg_gen_movi_tl(t0
, v2
);
23087 gen_helper_extr_s_h(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
23090 tcg_gen_movi_tl(t0
, v2
);
23091 gen_helper_extr_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
23093 case OPC_EXTRV_R_W
:
23094 tcg_gen_movi_tl(t0
, v2
);
23095 gen_helper_extr_r_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
23097 case OPC_EXTRV_RS_W
:
23098 tcg_gen_movi_tl(t0
, v2
);
23099 gen_helper_extr_rs_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
23102 tcg_gen_movi_tl(t0
, v2
);
23103 tcg_gen_movi_tl(t1
, v1
);
23104 gen_helper_extp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23107 tcg_gen_movi_tl(t0
, v2
);
23108 gen_helper_extp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
23111 tcg_gen_movi_tl(t0
, v2
);
23112 tcg_gen_movi_tl(t1
, v1
);
23113 gen_helper_extpdp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23116 tcg_gen_movi_tl(t0
, v2
);
23117 gen_helper_extpdp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
23120 imm
= (ctx
->opcode
>> 20) & 0x3F;
23121 tcg_gen_movi_tl(t0
, ret
);
23122 tcg_gen_movi_tl(t1
, imm
);
23123 gen_helper_shilo(t0
, t1
, cpu_env
);
23126 tcg_gen_movi_tl(t0
, ret
);
23127 gen_helper_shilo(t0
, v1_t
, cpu_env
);
23130 tcg_gen_movi_tl(t0
, ret
);
23131 gen_helper_mthlip(t0
, v1_t
, cpu_env
);
23134 imm
= (ctx
->opcode
>> 11) & 0x3FF;
23135 tcg_gen_movi_tl(t0
, imm
);
23136 gen_helper_wrdsp(v1_t
, t0
, cpu_env
);
23139 imm
= (ctx
->opcode
>> 16) & 0x03FF;
23140 tcg_gen_movi_tl(t0
, imm
);
23141 gen_helper_rddsp(cpu_gpr
[ret
], t0
, cpu_env
);
23145 #ifdef TARGET_MIPS64
23146 case OPC_DEXTR_W_DSP
:
23150 tcg_gen_movi_tl(t0
, ret
);
23151 gen_helper_dmthlip(v1_t
, t0
, cpu_env
);
23155 int shift
= (ctx
->opcode
>> 19) & 0x7F;
23156 int ac
= (ctx
->opcode
>> 11) & 0x03;
23157 tcg_gen_movi_tl(t0
, shift
);
23158 tcg_gen_movi_tl(t1
, ac
);
23159 gen_helper_dshilo(t0
, t1
, cpu_env
);
23164 int ac
= (ctx
->opcode
>> 11) & 0x03;
23165 tcg_gen_movi_tl(t0
, ac
);
23166 gen_helper_dshilo(v1_t
, t0
, cpu_env
);
23170 tcg_gen_movi_tl(t0
, v2
);
23171 tcg_gen_movi_tl(t1
, v1
);
23173 gen_helper_dextp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23176 tcg_gen_movi_tl(t0
, v2
);
23177 gen_helper_dextp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
23180 tcg_gen_movi_tl(t0
, v2
);
23181 tcg_gen_movi_tl(t1
, v1
);
23182 gen_helper_dextpdp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23185 tcg_gen_movi_tl(t0
, v2
);
23186 gen_helper_dextpdp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
23189 tcg_gen_movi_tl(t0
, v2
);
23190 tcg_gen_movi_tl(t1
, v1
);
23191 gen_helper_dextr_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23193 case OPC_DEXTR_R_L
:
23194 tcg_gen_movi_tl(t0
, v2
);
23195 tcg_gen_movi_tl(t1
, v1
);
23196 gen_helper_dextr_r_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23198 case OPC_DEXTR_RS_L
:
23199 tcg_gen_movi_tl(t0
, v2
);
23200 tcg_gen_movi_tl(t1
, v1
);
23201 gen_helper_dextr_rs_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23204 tcg_gen_movi_tl(t0
, v2
);
23205 tcg_gen_movi_tl(t1
, v1
);
23206 gen_helper_dextr_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23208 case OPC_DEXTR_R_W
:
23209 tcg_gen_movi_tl(t0
, v2
);
23210 tcg_gen_movi_tl(t1
, v1
);
23211 gen_helper_dextr_r_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23213 case OPC_DEXTR_RS_W
:
23214 tcg_gen_movi_tl(t0
, v2
);
23215 tcg_gen_movi_tl(t1
, v1
);
23216 gen_helper_dextr_rs_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23218 case OPC_DEXTR_S_H
:
23219 tcg_gen_movi_tl(t0
, v2
);
23220 tcg_gen_movi_tl(t1
, v1
);
23221 gen_helper_dextr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23223 case OPC_DEXTRV_S_H
:
23224 tcg_gen_movi_tl(t0
, v2
);
23225 tcg_gen_movi_tl(t1
, v1
);
23226 gen_helper_dextr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23229 tcg_gen_movi_tl(t0
, v2
);
23230 gen_helper_dextr_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
23232 case OPC_DEXTRV_R_L
:
23233 tcg_gen_movi_tl(t0
, v2
);
23234 gen_helper_dextr_r_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
23236 case OPC_DEXTRV_RS_L
:
23237 tcg_gen_movi_tl(t0
, v2
);
23238 gen_helper_dextr_rs_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
23241 tcg_gen_movi_tl(t0
, v2
);
23242 gen_helper_dextr_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
23244 case OPC_DEXTRV_R_W
:
23245 tcg_gen_movi_tl(t0
, v2
);
23246 gen_helper_dextr_r_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
23248 case OPC_DEXTRV_RS_W
:
23249 tcg_gen_movi_tl(t0
, v2
);
23250 gen_helper_dextr_rs_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
23259 tcg_temp_free(v1_t
);
23260 tcg_temp_free(v2_t
);
23263 /* End MIPSDSP functions. */
23265 static void decode_opc_special_r6(CPUMIPSState
*env
, DisasContext
*ctx
)
23267 int rs
, rt
, rd
, sa
;
23270 rs
= (ctx
->opcode
>> 21) & 0x1f;
23271 rt
= (ctx
->opcode
>> 16) & 0x1f;
23272 rd
= (ctx
->opcode
>> 11) & 0x1f;
23273 sa
= (ctx
->opcode
>> 6) & 0x1f;
23275 op1
= MASK_SPECIAL(ctx
->opcode
);
23281 op2
= MASK_R6_MULDIV(ctx
->opcode
);
23291 gen_r6_muldiv(ctx
, op2
, rd
, rs
, rt
);
23294 MIPS_INVAL("special_r6 muldiv");
23295 gen_reserved_instruction(ctx
);
23301 gen_cond_move(ctx
, op1
, rd
, rs
, rt
);
23305 if (rt
== 0 && sa
== 1) {
23307 * Major opcode and function field is shared with preR6 MFHI/MTHI.
23308 * We need additionally to check other fields.
23310 gen_cl(ctx
, op1
, rd
, rs
);
23312 gen_reserved_instruction(ctx
);
23316 if (is_uhi(extract32(ctx
->opcode
, 6, 20))) {
23317 gen_helper_do_semihosting(cpu_env
);
23319 if (ctx
->hflags
& MIPS_HFLAG_SBRI
) {
23320 gen_reserved_instruction(ctx
);
23322 generate_exception_end(ctx
, EXCP_DBp
);
23326 #if defined(TARGET_MIPS64)
23329 if (rt
== 0 && sa
== 1) {
23331 * Major opcode and function field is shared with preR6 MFHI/MTHI.
23332 * We need additionally to check other fields.
23334 check_mips_64(ctx
);
23335 gen_cl(ctx
, op1
, rd
, rs
);
23337 gen_reserved_instruction(ctx
);
23345 op2
= MASK_R6_MULDIV(ctx
->opcode
);
23355 check_mips_64(ctx
);
23356 gen_r6_muldiv(ctx
, op2
, rd
, rs
, rt
);
23359 MIPS_INVAL("special_r6 muldiv");
23360 gen_reserved_instruction(ctx
);
23365 default: /* Invalid */
23366 MIPS_INVAL("special_r6");
23367 gen_reserved_instruction(ctx
);
23372 static void decode_opc_special_tx79(CPUMIPSState
*env
, DisasContext
*ctx
)
23374 int rs
= extract32(ctx
->opcode
, 21, 5);
23375 int rt
= extract32(ctx
->opcode
, 16, 5);
23376 int rd
= extract32(ctx
->opcode
, 11, 5);
23377 uint32_t op1
= MASK_SPECIAL(ctx
->opcode
);
23380 case OPC_MOVN
: /* Conditional move */
23382 gen_cond_move(ctx
, op1
, rd
, rs
, rt
);
23384 case OPC_MFHI
: /* Move from HI/LO */
23386 gen_HILO(ctx
, op1
, 0, rd
);
23389 case OPC_MTLO
: /* Move to HI/LO */
23390 gen_HILO(ctx
, op1
, 0, rs
);
23394 gen_mul_txx9(ctx
, op1
, rd
, rs
, rt
);
23398 gen_muldiv(ctx
, op1
, 0, rs
, rt
);
23400 #if defined(TARGET_MIPS64)
23405 check_insn_opc_user_only(ctx
, INSN_R5900
);
23406 gen_muldiv(ctx
, op1
, 0, rs
, rt
);
23410 gen_compute_branch(ctx
, op1
, 4, rs
, 0, 0, 4);
23412 default: /* Invalid */
23413 MIPS_INVAL("special_tx79");
23414 gen_reserved_instruction(ctx
);
23419 static void decode_opc_special_legacy(CPUMIPSState
*env
, DisasContext
*ctx
)
23421 int rs
, rt
, rd
, sa
;
23424 rs
= (ctx
->opcode
>> 21) & 0x1f;
23425 rt
= (ctx
->opcode
>> 16) & 0x1f;
23426 rd
= (ctx
->opcode
>> 11) & 0x1f;
23427 sa
= (ctx
->opcode
>> 6) & 0x1f;
23429 op1
= MASK_SPECIAL(ctx
->opcode
);
23431 case OPC_MOVN
: /* Conditional move */
23433 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS_R1
|
23434 INSN_LOONGSON2E
| INSN_LOONGSON2F
);
23435 gen_cond_move(ctx
, op1
, rd
, rs
, rt
);
23437 case OPC_MFHI
: /* Move from HI/LO */
23439 gen_HILO(ctx
, op1
, rs
& 3, rd
);
23442 case OPC_MTLO
: /* Move to HI/LO */
23443 gen_HILO(ctx
, op1
, rd
& 3, rs
);
23446 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS_R1
);
23447 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
23448 check_cp1_enabled(ctx
);
23449 gen_movci(ctx
, rd
, rs
, (ctx
->opcode
>> 18) & 0x7,
23450 (ctx
->opcode
>> 16) & 1);
23452 generate_exception_err(ctx
, EXCP_CpU
, 1);
23458 check_insn(ctx
, INSN_VR54XX
);
23459 op1
= MASK_MUL_VR54XX(ctx
->opcode
);
23460 gen_mul_vr54xx(ctx
, op1
, rd
, rs
, rt
);
23462 gen_muldiv(ctx
, op1
, rd
& 3, rs
, rt
);
23467 gen_muldiv(ctx
, op1
, 0, rs
, rt
);
23469 #if defined(TARGET_MIPS64)
23474 check_insn(ctx
, ISA_MIPS3
);
23475 check_mips_64(ctx
);
23476 gen_muldiv(ctx
, op1
, 0, rs
, rt
);
23480 gen_compute_branch(ctx
, op1
, 4, rs
, rd
, sa
, 4);
23483 #ifdef MIPS_STRICT_STANDARD
23484 MIPS_INVAL("SPIM");
23485 gen_reserved_instruction(ctx
);
23487 /* Implemented as RI exception for now. */
23488 MIPS_INVAL("spim (unofficial)");
23489 gen_reserved_instruction(ctx
);
23492 default: /* Invalid */
23493 MIPS_INVAL("special_legacy");
23494 gen_reserved_instruction(ctx
);
23499 static void decode_opc_special(CPUMIPSState
*env
, DisasContext
*ctx
)
23501 int rs
, rt
, rd
, sa
;
23504 rs
= (ctx
->opcode
>> 21) & 0x1f;
23505 rt
= (ctx
->opcode
>> 16) & 0x1f;
23506 rd
= (ctx
->opcode
>> 11) & 0x1f;
23507 sa
= (ctx
->opcode
>> 6) & 0x1f;
23509 op1
= MASK_SPECIAL(ctx
->opcode
);
23511 case OPC_SLL
: /* Shift with immediate */
23512 if (sa
== 5 && rd
== 0 &&
23513 rs
== 0 && rt
== 0) { /* PAUSE */
23514 if ((ctx
->insn_flags
& ISA_MIPS_R6
) &&
23515 (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
23516 gen_reserved_instruction(ctx
);
23522 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
23525 switch ((ctx
->opcode
>> 21) & 0x1f) {
23527 /* rotr is decoded as srl on non-R2 CPUs */
23528 if (ctx
->insn_flags
& ISA_MIPS_R2
) {
23533 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
23536 gen_reserved_instruction(ctx
);
23544 gen_arith(ctx
, op1
, rd
, rs
, rt
);
23546 case OPC_SLLV
: /* Shifts */
23548 gen_shift(ctx
, op1
, rd
, rs
, rt
);
23551 switch ((ctx
->opcode
>> 6) & 0x1f) {
23553 /* rotrv is decoded as srlv on non-R2 CPUs */
23554 if (ctx
->insn_flags
& ISA_MIPS_R2
) {
23559 gen_shift(ctx
, op1
, rd
, rs
, rt
);
23562 gen_reserved_instruction(ctx
);
23566 case OPC_SLT
: /* Set on less than */
23568 gen_slt(ctx
, op1
, rd
, rs
, rt
);
23570 case OPC_AND
: /* Logic*/
23574 gen_logic(ctx
, op1
, rd
, rs
, rt
);
23577 gen_compute_branch(ctx
, op1
, 4, rs
, rd
, sa
, 4);
23579 case OPC_TGE
: /* Traps */
23585 check_insn(ctx
, ISA_MIPS2
);
23586 gen_trap(ctx
, op1
, rs
, rt
, -1);
23589 /* Pmon entry point, also R4010 selsl */
23590 #ifdef MIPS_STRICT_STANDARD
23591 MIPS_INVAL("PMON / selsl");
23592 gen_reserved_instruction(ctx
);
23594 gen_helper_0e0i(pmon
, sa
);
23598 generate_exception_end(ctx
, EXCP_SYSCALL
);
23601 generate_exception_end(ctx
, EXCP_BREAK
);
23604 check_insn(ctx
, ISA_MIPS2
);
23605 gen_sync(extract32(ctx
->opcode
, 6, 5));
23608 #if defined(TARGET_MIPS64)
23609 /* MIPS64 specific opcodes */
23614 check_insn(ctx
, ISA_MIPS3
);
23615 check_mips_64(ctx
);
23616 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
23619 switch ((ctx
->opcode
>> 21) & 0x1f) {
23621 /* drotr is decoded as dsrl on non-R2 CPUs */
23622 if (ctx
->insn_flags
& ISA_MIPS_R2
) {
23627 check_insn(ctx
, ISA_MIPS3
);
23628 check_mips_64(ctx
);
23629 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
23632 gen_reserved_instruction(ctx
);
23637 switch ((ctx
->opcode
>> 21) & 0x1f) {
23639 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
23640 if (ctx
->insn_flags
& ISA_MIPS_R2
) {
23645 check_insn(ctx
, ISA_MIPS3
);
23646 check_mips_64(ctx
);
23647 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
23650 gen_reserved_instruction(ctx
);
23658 check_insn(ctx
, ISA_MIPS3
);
23659 check_mips_64(ctx
);
23660 gen_arith(ctx
, op1
, rd
, rs
, rt
);
23664 check_insn(ctx
, ISA_MIPS3
);
23665 check_mips_64(ctx
);
23666 gen_shift(ctx
, op1
, rd
, rs
, rt
);
23669 switch ((ctx
->opcode
>> 6) & 0x1f) {
23671 /* drotrv is decoded as dsrlv on non-R2 CPUs */
23672 if (ctx
->insn_flags
& ISA_MIPS_R2
) {
23677 check_insn(ctx
, ISA_MIPS3
);
23678 check_mips_64(ctx
);
23679 gen_shift(ctx
, op1
, rd
, rs
, rt
);
23682 gen_reserved_instruction(ctx
);
23688 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
23689 decode_opc_special_r6(env
, ctx
);
23690 } else if (ctx
->insn_flags
& INSN_R5900
) {
23691 decode_opc_special_tx79(env
, ctx
);
23693 decode_opc_special_legacy(env
, ctx
);
23699 static void decode_opc_special2_legacy(CPUMIPSState
*env
, DisasContext
*ctx
)
23704 rs
= (ctx
->opcode
>> 21) & 0x1f;
23705 rt
= (ctx
->opcode
>> 16) & 0x1f;
23706 rd
= (ctx
->opcode
>> 11) & 0x1f;
23708 op1
= MASK_SPECIAL2(ctx
->opcode
);
23710 case OPC_MADD
: /* Multiply and add/sub */
23714 check_insn(ctx
, ISA_MIPS_R1
);
23715 gen_muldiv(ctx
, op1
, rd
& 3, rs
, rt
);
23718 gen_arith(ctx
, op1
, rd
, rs
, rt
);
23721 case OPC_DIVU_G_2F
:
23722 case OPC_MULT_G_2F
:
23723 case OPC_MULTU_G_2F
:
23725 case OPC_MODU_G_2F
:
23726 check_insn(ctx
, INSN_LOONGSON2F
| ASE_LEXT
);
23727 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
23731 check_insn(ctx
, ISA_MIPS_R1
);
23732 gen_cl(ctx
, op1
, rd
, rs
);
23735 if (is_uhi(extract32(ctx
->opcode
, 6, 20))) {
23736 gen_helper_do_semihosting(cpu_env
);
23739 * XXX: not clear which exception should be raised
23740 * when in debug mode...
23742 check_insn(ctx
, ISA_MIPS_R1
);
23743 generate_exception_end(ctx
, EXCP_DBp
);
23746 #if defined(TARGET_MIPS64)
23749 check_insn(ctx
, ISA_MIPS_R1
);
23750 check_mips_64(ctx
);
23751 gen_cl(ctx
, op1
, rd
, rs
);
23753 case OPC_DMULT_G_2F
:
23754 case OPC_DMULTU_G_2F
:
23755 case OPC_DDIV_G_2F
:
23756 case OPC_DDIVU_G_2F
:
23757 case OPC_DMOD_G_2F
:
23758 case OPC_DMODU_G_2F
:
23759 check_insn(ctx
, INSN_LOONGSON2F
| ASE_LEXT
);
23760 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
23763 default: /* Invalid */
23764 MIPS_INVAL("special2_legacy");
23765 gen_reserved_instruction(ctx
);
23770 static void decode_opc_special3_r6(CPUMIPSState
*env
, DisasContext
*ctx
)
23772 int rs
, rt
, rd
, sa
;
23776 rs
= (ctx
->opcode
>> 21) & 0x1f;
23777 rt
= (ctx
->opcode
>> 16) & 0x1f;
23778 rd
= (ctx
->opcode
>> 11) & 0x1f;
23779 sa
= (ctx
->opcode
>> 6) & 0x1f;
23780 imm
= (int16_t)ctx
->opcode
>> 7;
23782 op1
= MASK_SPECIAL3(ctx
->opcode
);
23786 /* hint codes 24-31 are reserved and signal RI */
23787 gen_reserved_instruction(ctx
);
23789 /* Treat as NOP. */
23792 check_cp0_enabled(ctx
);
23793 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
23794 gen_cache_operation(ctx
, rt
, rs
, imm
);
23798 gen_st_cond(ctx
, rt
, rs
, imm
, MO_TESL
, false);
23801 gen_ld(ctx
, op1
, rt
, rs
, imm
);
23806 /* Treat as NOP. */
23809 op2
= MASK_BSHFL(ctx
->opcode
);
23815 gen_align(ctx
, 32, rd
, rs
, rt
, sa
& 3);
23818 gen_bitswap(ctx
, op2
, rd
, rt
);
23823 #ifndef CONFIG_USER_ONLY
23825 if (unlikely(ctx
->gi
<= 1)) {
23826 gen_reserved_instruction(ctx
);
23828 check_cp0_enabled(ctx
);
23829 switch ((ctx
->opcode
>> 6) & 3) {
23830 case 0: /* GINVI */
23831 /* Treat as NOP. */
23833 case 2: /* GINVT */
23834 gen_helper_0e1i(ginvt
, cpu_gpr
[rs
], extract32(ctx
->opcode
, 8, 2));
23837 gen_reserved_instruction(ctx
);
23842 #if defined(TARGET_MIPS64)
23844 gen_st_cond(ctx
, rt
, rs
, imm
, MO_TEQ
, false);
23847 gen_ld(ctx
, op1
, rt
, rs
, imm
);
23850 check_mips_64(ctx
);
23853 /* Treat as NOP. */
23856 op2
= MASK_DBSHFL(ctx
->opcode
);
23866 gen_align(ctx
, 64, rd
, rs
, rt
, sa
& 7);
23869 gen_bitswap(ctx
, op2
, rd
, rt
);
23876 default: /* Invalid */
23877 MIPS_INVAL("special3_r6");
23878 gen_reserved_instruction(ctx
);
23883 static void decode_opc_special3_legacy(CPUMIPSState
*env
, DisasContext
*ctx
)
23888 rs
= (ctx
->opcode
>> 21) & 0x1f;
23889 rt
= (ctx
->opcode
>> 16) & 0x1f;
23890 rd
= (ctx
->opcode
>> 11) & 0x1f;
23892 op1
= MASK_SPECIAL3(ctx
->opcode
);
23895 case OPC_DIVU_G_2E
:
23897 case OPC_MODU_G_2E
:
23898 case OPC_MULT_G_2E
:
23899 case OPC_MULTU_G_2E
:
23901 * OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
23902 * the same mask and op1.
23904 if ((ctx
->insn_flags
& ASE_DSP_R2
) && (op1
== OPC_MULT_G_2E
)) {
23905 op2
= MASK_ADDUH_QB(ctx
->opcode
);
23908 case OPC_ADDUH_R_QB
:
23910 case OPC_ADDQH_R_PH
:
23912 case OPC_ADDQH_R_W
:
23914 case OPC_SUBUH_R_QB
:
23916 case OPC_SUBQH_R_PH
:
23918 case OPC_SUBQH_R_W
:
23919 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
23924 case OPC_MULQ_RS_W
:
23925 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
23928 MIPS_INVAL("MASK ADDUH.QB");
23929 gen_reserved_instruction(ctx
);
23932 } else if (ctx
->insn_flags
& INSN_LOONGSON2E
) {
23933 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
23935 gen_reserved_instruction(ctx
);
23939 op2
= MASK_LX(ctx
->opcode
);
23941 #if defined(TARGET_MIPS64)
23947 gen_mipsdsp_ld(ctx
, op2
, rd
, rs
, rt
);
23949 default: /* Invalid */
23950 MIPS_INVAL("MASK LX");
23951 gen_reserved_instruction(ctx
);
23955 case OPC_ABSQ_S_PH_DSP
:
23956 op2
= MASK_ABSQ_S_PH(ctx
->opcode
);
23958 case OPC_ABSQ_S_QB
:
23959 case OPC_ABSQ_S_PH
:
23961 case OPC_PRECEQ_W_PHL
:
23962 case OPC_PRECEQ_W_PHR
:
23963 case OPC_PRECEQU_PH_QBL
:
23964 case OPC_PRECEQU_PH_QBR
:
23965 case OPC_PRECEQU_PH_QBLA
:
23966 case OPC_PRECEQU_PH_QBRA
:
23967 case OPC_PRECEU_PH_QBL
:
23968 case OPC_PRECEU_PH_QBR
:
23969 case OPC_PRECEU_PH_QBLA
:
23970 case OPC_PRECEU_PH_QBRA
:
23971 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
23978 gen_mipsdsp_bitinsn(ctx
, op1
, op2
, rd
, rt
);
23981 MIPS_INVAL("MASK ABSQ_S.PH");
23982 gen_reserved_instruction(ctx
);
23986 case OPC_ADDU_QB_DSP
:
23987 op2
= MASK_ADDU_QB(ctx
->opcode
);
23990 case OPC_ADDQ_S_PH
:
23993 case OPC_ADDU_S_QB
:
23995 case OPC_ADDU_S_PH
:
23997 case OPC_SUBQ_S_PH
:
24000 case OPC_SUBU_S_QB
:
24002 case OPC_SUBU_S_PH
:
24006 case OPC_RADDU_W_QB
:
24007 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
24009 case OPC_MULEU_S_PH_QBL
:
24010 case OPC_MULEU_S_PH_QBR
:
24011 case OPC_MULQ_RS_PH
:
24012 case OPC_MULEQ_S_W_PHL
:
24013 case OPC_MULEQ_S_W_PHR
:
24014 case OPC_MULQ_S_PH
:
24015 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
24017 default: /* Invalid */
24018 MIPS_INVAL("MASK ADDU.QB");
24019 gen_reserved_instruction(ctx
);
24024 case OPC_CMPU_EQ_QB_DSP
:
24025 op2
= MASK_CMPU_EQ_QB(ctx
->opcode
);
24027 case OPC_PRECR_SRA_PH_W
:
24028 case OPC_PRECR_SRA_R_PH_W
:
24029 gen_mipsdsp_arith(ctx
, op1
, op2
, rt
, rs
, rd
);
24031 case OPC_PRECR_QB_PH
:
24032 case OPC_PRECRQ_QB_PH
:
24033 case OPC_PRECRQ_PH_W
:
24034 case OPC_PRECRQ_RS_PH_W
:
24035 case OPC_PRECRQU_S_QB_PH
:
24036 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
24038 case OPC_CMPU_EQ_QB
:
24039 case OPC_CMPU_LT_QB
:
24040 case OPC_CMPU_LE_QB
:
24041 case OPC_CMP_EQ_PH
:
24042 case OPC_CMP_LT_PH
:
24043 case OPC_CMP_LE_PH
:
24044 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
24046 case OPC_CMPGU_EQ_QB
:
24047 case OPC_CMPGU_LT_QB
:
24048 case OPC_CMPGU_LE_QB
:
24049 case OPC_CMPGDU_EQ_QB
:
24050 case OPC_CMPGDU_LT_QB
:
24051 case OPC_CMPGDU_LE_QB
:
24054 case OPC_PACKRL_PH
:
24055 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
24057 default: /* Invalid */
24058 MIPS_INVAL("MASK CMPU.EQ.QB");
24059 gen_reserved_instruction(ctx
);
24063 case OPC_SHLL_QB_DSP
:
24064 gen_mipsdsp_shift(ctx
, op1
, rd
, rs
, rt
);
24066 case OPC_DPA_W_PH_DSP
:
24067 op2
= MASK_DPA_W_PH(ctx
->opcode
);
24069 case OPC_DPAU_H_QBL
:
24070 case OPC_DPAU_H_QBR
:
24071 case OPC_DPSU_H_QBL
:
24072 case OPC_DPSU_H_QBR
:
24074 case OPC_DPAX_W_PH
:
24075 case OPC_DPAQ_S_W_PH
:
24076 case OPC_DPAQX_S_W_PH
:
24077 case OPC_DPAQX_SA_W_PH
:
24079 case OPC_DPSX_W_PH
:
24080 case OPC_DPSQ_S_W_PH
:
24081 case OPC_DPSQX_S_W_PH
:
24082 case OPC_DPSQX_SA_W_PH
:
24083 case OPC_MULSAQ_S_W_PH
:
24084 case OPC_DPAQ_SA_L_W
:
24085 case OPC_DPSQ_SA_L_W
:
24086 case OPC_MAQ_S_W_PHL
:
24087 case OPC_MAQ_S_W_PHR
:
24088 case OPC_MAQ_SA_W_PHL
:
24089 case OPC_MAQ_SA_W_PHR
:
24090 case OPC_MULSA_W_PH
:
24091 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
24093 default: /* Invalid */
24094 MIPS_INVAL("MASK DPAW.PH");
24095 gen_reserved_instruction(ctx
);
24100 op2
= MASK_INSV(ctx
->opcode
);
24111 t0
= tcg_temp_new();
24112 t1
= tcg_temp_new();
24114 gen_load_gpr(t0
, rt
);
24115 gen_load_gpr(t1
, rs
);
24117 gen_helper_insv(cpu_gpr
[rt
], cpu_env
, t1
, t0
);
24123 default: /* Invalid */
24124 MIPS_INVAL("MASK INSV");
24125 gen_reserved_instruction(ctx
);
24129 case OPC_APPEND_DSP
:
24130 gen_mipsdsp_append(env
, ctx
, op1
, rt
, rs
, rd
);
24132 case OPC_EXTR_W_DSP
:
24133 op2
= MASK_EXTR_W(ctx
->opcode
);
24137 case OPC_EXTR_RS_W
:
24139 case OPC_EXTRV_S_H
:
24141 case OPC_EXTRV_R_W
:
24142 case OPC_EXTRV_RS_W
:
24147 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rt
, rs
, rd
, 1);
24150 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
24156 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
24158 default: /* Invalid */
24159 MIPS_INVAL("MASK EXTR.W");
24160 gen_reserved_instruction(ctx
);
24164 #if defined(TARGET_MIPS64)
24165 case OPC_DDIV_G_2E
:
24166 case OPC_DDIVU_G_2E
:
24167 case OPC_DMULT_G_2E
:
24168 case OPC_DMULTU_G_2E
:
24169 case OPC_DMOD_G_2E
:
24170 case OPC_DMODU_G_2E
:
24171 check_insn(ctx
, INSN_LOONGSON2E
);
24172 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
24174 case OPC_ABSQ_S_QH_DSP
:
24175 op2
= MASK_ABSQ_S_QH(ctx
->opcode
);
24177 case OPC_PRECEQ_L_PWL
:
24178 case OPC_PRECEQ_L_PWR
:
24179 case OPC_PRECEQ_PW_QHL
:
24180 case OPC_PRECEQ_PW_QHR
:
24181 case OPC_PRECEQ_PW_QHLA
:
24182 case OPC_PRECEQ_PW_QHRA
:
24183 case OPC_PRECEQU_QH_OBL
:
24184 case OPC_PRECEQU_QH_OBR
:
24185 case OPC_PRECEQU_QH_OBLA
:
24186 case OPC_PRECEQU_QH_OBRA
:
24187 case OPC_PRECEU_QH_OBL
:
24188 case OPC_PRECEU_QH_OBR
:
24189 case OPC_PRECEU_QH_OBLA
:
24190 case OPC_PRECEU_QH_OBRA
:
24191 case OPC_ABSQ_S_OB
:
24192 case OPC_ABSQ_S_PW
:
24193 case OPC_ABSQ_S_QH
:
24194 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
24202 gen_mipsdsp_bitinsn(ctx
, op1
, op2
, rd
, rt
);
24204 default: /* Invalid */
24205 MIPS_INVAL("MASK ABSQ_S.QH");
24206 gen_reserved_instruction(ctx
);
24210 case OPC_ADDU_OB_DSP
:
24211 op2
= MASK_ADDU_OB(ctx
->opcode
);
24213 case OPC_RADDU_L_OB
:
24215 case OPC_SUBQ_S_PW
:
24217 case OPC_SUBQ_S_QH
:
24219 case OPC_SUBU_S_OB
:
24221 case OPC_SUBU_S_QH
:
24223 case OPC_SUBUH_R_OB
:
24225 case OPC_ADDQ_S_PW
:
24227 case OPC_ADDQ_S_QH
:
24229 case OPC_ADDU_S_OB
:
24231 case OPC_ADDU_S_QH
:
24233 case OPC_ADDUH_R_OB
:
24234 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
24236 case OPC_MULEQ_S_PW_QHL
:
24237 case OPC_MULEQ_S_PW_QHR
:
24238 case OPC_MULEU_S_QH_OBL
:
24239 case OPC_MULEU_S_QH_OBR
:
24240 case OPC_MULQ_RS_QH
:
24241 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
24243 default: /* Invalid */
24244 MIPS_INVAL("MASK ADDU.OB");
24245 gen_reserved_instruction(ctx
);
24249 case OPC_CMPU_EQ_OB_DSP
:
24250 op2
= MASK_CMPU_EQ_OB(ctx
->opcode
);
24252 case OPC_PRECR_SRA_QH_PW
:
24253 case OPC_PRECR_SRA_R_QH_PW
:
24254 /* Return value is rt. */
24255 gen_mipsdsp_arith(ctx
, op1
, op2
, rt
, rs
, rd
);
24257 case OPC_PRECR_OB_QH
:
24258 case OPC_PRECRQ_OB_QH
:
24259 case OPC_PRECRQ_PW_L
:
24260 case OPC_PRECRQ_QH_PW
:
24261 case OPC_PRECRQ_RS_QH_PW
:
24262 case OPC_PRECRQU_S_OB_QH
:
24263 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
24265 case OPC_CMPU_EQ_OB
:
24266 case OPC_CMPU_LT_OB
:
24267 case OPC_CMPU_LE_OB
:
24268 case OPC_CMP_EQ_QH
:
24269 case OPC_CMP_LT_QH
:
24270 case OPC_CMP_LE_QH
:
24271 case OPC_CMP_EQ_PW
:
24272 case OPC_CMP_LT_PW
:
24273 case OPC_CMP_LE_PW
:
24274 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
24276 case OPC_CMPGDU_EQ_OB
:
24277 case OPC_CMPGDU_LT_OB
:
24278 case OPC_CMPGDU_LE_OB
:
24279 case OPC_CMPGU_EQ_OB
:
24280 case OPC_CMPGU_LT_OB
:
24281 case OPC_CMPGU_LE_OB
:
24282 case OPC_PACKRL_PW
:
24286 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
24288 default: /* Invalid */
24289 MIPS_INVAL("MASK CMPU_EQ.OB");
24290 gen_reserved_instruction(ctx
);
24294 case OPC_DAPPEND_DSP
:
24295 gen_mipsdsp_append(env
, ctx
, op1
, rt
, rs
, rd
);
24297 case OPC_DEXTR_W_DSP
:
24298 op2
= MASK_DEXTR_W(ctx
->opcode
);
24305 case OPC_DEXTR_R_L
:
24306 case OPC_DEXTR_RS_L
:
24308 case OPC_DEXTR_R_W
:
24309 case OPC_DEXTR_RS_W
:
24310 case OPC_DEXTR_S_H
:
24312 case OPC_DEXTRV_R_L
:
24313 case OPC_DEXTRV_RS_L
:
24314 case OPC_DEXTRV_S_H
:
24316 case OPC_DEXTRV_R_W
:
24317 case OPC_DEXTRV_RS_W
:
24318 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rt
, rs
, rd
, 1);
24323 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
24325 default: /* Invalid */
24326 MIPS_INVAL("MASK EXTR.W");
24327 gen_reserved_instruction(ctx
);
24331 case OPC_DPAQ_W_QH_DSP
:
24332 op2
= MASK_DPAQ_W_QH(ctx
->opcode
);
24334 case OPC_DPAU_H_OBL
:
24335 case OPC_DPAU_H_OBR
:
24336 case OPC_DPSU_H_OBL
:
24337 case OPC_DPSU_H_OBR
:
24339 case OPC_DPAQ_S_W_QH
:
24341 case OPC_DPSQ_S_W_QH
:
24342 case OPC_MULSAQ_S_W_QH
:
24343 case OPC_DPAQ_SA_L_PW
:
24344 case OPC_DPSQ_SA_L_PW
:
24345 case OPC_MULSAQ_S_L_PW
:
24346 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
24348 case OPC_MAQ_S_W_QHLL
:
24349 case OPC_MAQ_S_W_QHLR
:
24350 case OPC_MAQ_S_W_QHRL
:
24351 case OPC_MAQ_S_W_QHRR
:
24352 case OPC_MAQ_SA_W_QHLL
:
24353 case OPC_MAQ_SA_W_QHLR
:
24354 case OPC_MAQ_SA_W_QHRL
:
24355 case OPC_MAQ_SA_W_QHRR
:
24356 case OPC_MAQ_S_L_PWL
:
24357 case OPC_MAQ_S_L_PWR
:
24362 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
24364 default: /* Invalid */
24365 MIPS_INVAL("MASK DPAQ.W.QH");
24366 gen_reserved_instruction(ctx
);
24370 case OPC_DINSV_DSP
:
24371 op2
= MASK_INSV(ctx
->opcode
);
24382 t0
= tcg_temp_new();
24383 t1
= tcg_temp_new();
24385 gen_load_gpr(t0
, rt
);
24386 gen_load_gpr(t1
, rs
);
24388 gen_helper_dinsv(cpu_gpr
[rt
], cpu_env
, t1
, t0
);
24394 default: /* Invalid */
24395 MIPS_INVAL("MASK DINSV");
24396 gen_reserved_instruction(ctx
);
24400 case OPC_SHLL_OB_DSP
:
24401 gen_mipsdsp_shift(ctx
, op1
, rd
, rs
, rt
);
24404 default: /* Invalid */
24405 MIPS_INVAL("special3_legacy");
24406 gen_reserved_instruction(ctx
);
24412 #if defined(TARGET_MIPS64)
24414 static void decode_mmi(CPUMIPSState
*env
, DisasContext
*ctx
)
24416 uint32_t opc
= MASK_MMI(ctx
->opcode
);
24417 int rs
= extract32(ctx
->opcode
, 21, 5);
24418 int rt
= extract32(ctx
->opcode
, 16, 5);
24419 int rd
= extract32(ctx
->opcode
, 11, 5);
24422 case MMI_OPC_MULT1
:
24423 case MMI_OPC_MULTU1
:
24425 case MMI_OPC_MADDU
:
24426 case MMI_OPC_MADD1
:
24427 case MMI_OPC_MADDU1
:
24428 gen_mul_txx9(ctx
, opc
, rd
, rs
, rt
);
24431 case MMI_OPC_DIVU1
:
24432 gen_div1_tx79(ctx
, opc
, rs
, rt
);
24435 MIPS_INVAL("TX79 MMI class");
24436 gen_reserved_instruction(ctx
);
24441 static void gen_mmi_lq(CPUMIPSState
*env
, DisasContext
*ctx
)
24443 gen_reserved_instruction(ctx
); /* TODO: MMI_OPC_LQ */
24446 static void gen_mmi_sq(DisasContext
*ctx
, int base
, int rt
, int offset
)
24448 gen_reserved_instruction(ctx
); /* TODO: MMI_OPC_SQ */
24452 * The TX79-specific instruction Store Quadword
24454 * +--------+-------+-------+------------------------+
24455 * | 011111 | base | rt | offset | SQ
24456 * +--------+-------+-------+------------------------+
24459 * has the same opcode as the Read Hardware Register instruction
24461 * +--------+-------+-------+-------+-------+--------+
24462 * | 011111 | 00000 | rt | rd | 00000 | 111011 | RDHWR
24463 * +--------+-------+-------+-------+-------+--------+
24466 * that is required, trapped and emulated by the Linux kernel. However, all
24467 * RDHWR encodings yield address error exceptions on the TX79 since the SQ
24468 * offset is odd. Therefore all valid SQ instructions can execute normally.
24469 * In user mode, QEMU must verify the upper and lower 11 bits to distinguish
24470 * between SQ and RDHWR, as the Linux kernel does.
24472 static void decode_mmi_sq(CPUMIPSState
*env
, DisasContext
*ctx
)
24474 int base
= extract32(ctx
->opcode
, 21, 5);
24475 int rt
= extract32(ctx
->opcode
, 16, 5);
24476 int offset
= extract32(ctx
->opcode
, 0, 16);
24478 #ifdef CONFIG_USER_ONLY
24479 uint32_t op1
= MASK_SPECIAL3(ctx
->opcode
);
24480 uint32_t op2
= extract32(ctx
->opcode
, 6, 5);
24482 if (base
== 0 && op2
== 0 && op1
== OPC_RDHWR
) {
24483 int rd
= extract32(ctx
->opcode
, 11, 5);
24485 gen_rdhwr(ctx
, rt
, rd
, 0);
24490 gen_mmi_sq(ctx
, base
, rt
, offset
);
24495 static void decode_opc_special3(CPUMIPSState
*env
, DisasContext
*ctx
)
24497 int rs
, rt
, rd
, sa
;
24501 rs
= (ctx
->opcode
>> 21) & 0x1f;
24502 rt
= (ctx
->opcode
>> 16) & 0x1f;
24503 rd
= (ctx
->opcode
>> 11) & 0x1f;
24504 sa
= (ctx
->opcode
>> 6) & 0x1f;
24505 imm
= sextract32(ctx
->opcode
, 7, 9);
24507 op1
= MASK_SPECIAL3(ctx
->opcode
);
24510 * EVA loads and stores overlap Loongson 2E instructions decoded by
24511 * decode_opc_special3_legacy(), so be careful to allow their decoding when
24524 check_cp0_enabled(ctx
);
24525 gen_ld(ctx
, op1
, rt
, rs
, imm
);
24532 check_cp0_enabled(ctx
);
24533 gen_st(ctx
, op1
, rt
, rs
, imm
);
24536 check_cp0_enabled(ctx
);
24537 gen_st_cond(ctx
, rt
, rs
, imm
, MO_TESL
, true);
24541 check_cp0_enabled(ctx
);
24542 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
24543 gen_cache_operation(ctx
, rt
, rs
, imm
);
24547 check_cp0_enabled(ctx
);
24548 /* Treat as NOP. */
24556 check_insn(ctx
, ISA_MIPS_R2
);
24557 gen_bitops(ctx
, op1
, rt
, rs
, sa
, rd
);
24560 op2
= MASK_BSHFL(ctx
->opcode
);
24567 check_insn(ctx
, ISA_MIPS_R6
);
24568 decode_opc_special3_r6(env
, ctx
);
24571 check_insn(ctx
, ISA_MIPS_R2
);
24572 gen_bshfl(ctx
, op2
, rt
, rd
);
24576 #if defined(TARGET_MIPS64)
24583 check_insn(ctx
, ISA_MIPS_R2
);
24584 check_mips_64(ctx
);
24585 gen_bitops(ctx
, op1
, rt
, rs
, sa
, rd
);
24588 op2
= MASK_DBSHFL(ctx
->opcode
);
24599 check_insn(ctx
, ISA_MIPS_R6
);
24600 decode_opc_special3_r6(env
, ctx
);
24603 check_insn(ctx
, ISA_MIPS_R2
);
24604 check_mips_64(ctx
);
24605 op2
= MASK_DBSHFL(ctx
->opcode
);
24606 gen_bshfl(ctx
, op2
, rt
, rd
);
24612 gen_rdhwr(ctx
, rt
, rd
, extract32(ctx
->opcode
, 6, 3));
24617 TCGv t0
= tcg_temp_new();
24618 TCGv t1
= tcg_temp_new();
24620 gen_load_gpr(t0
, rt
);
24621 gen_load_gpr(t1
, rs
);
24622 gen_helper_fork(t0
, t1
);
24630 TCGv t0
= tcg_temp_new();
24632 gen_load_gpr(t0
, rs
);
24633 gen_helper_yield(t0
, cpu_env
, t0
);
24634 gen_store_gpr(t0
, rd
);
24639 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
24640 decode_opc_special3_r6(env
, ctx
);
24642 decode_opc_special3_legacy(env
, ctx
);
24647 static bool decode_opc_legacy(CPUMIPSState
*env
, DisasContext
*ctx
)
24650 int rs
, rt
, rd
, sa
;
24654 op
= MASK_OP_MAJOR(ctx
->opcode
);
24655 rs
= (ctx
->opcode
>> 21) & 0x1f;
24656 rt
= (ctx
->opcode
>> 16) & 0x1f;
24657 rd
= (ctx
->opcode
>> 11) & 0x1f;
24658 sa
= (ctx
->opcode
>> 6) & 0x1f;
24659 imm
= (int16_t)ctx
->opcode
;
24662 decode_opc_special(env
, ctx
);
24665 #if defined(TARGET_MIPS64)
24666 if ((ctx
->insn_flags
& INSN_R5900
) && (ctx
->insn_flags
& ASE_MMI
)) {
24667 decode_mmi(env
, ctx
);
24671 if (TARGET_LONG_BITS
== 32 && (ctx
->insn_flags
& ASE_MXU
)) {
24672 if (MASK_SPECIAL2(ctx
->opcode
) == OPC_MUL
) {
24673 gen_arith(ctx
, OPC_MUL
, rd
, rs
, rt
);
24675 decode_ase_mxu(ctx
, ctx
->opcode
);
24679 decode_opc_special2_legacy(env
, ctx
);
24682 #if defined(TARGET_MIPS64)
24683 if (ctx
->insn_flags
& INSN_R5900
) {
24684 decode_mmi_sq(env
, ctx
); /* MMI_OPC_SQ */
24686 decode_opc_special3(env
, ctx
);
24689 decode_opc_special3(env
, ctx
);
24693 op1
= MASK_REGIMM(ctx
->opcode
);
24695 case OPC_BLTZL
: /* REGIMM branches */
24699 check_insn(ctx
, ISA_MIPS2
);
24700 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
24704 gen_compute_branch(ctx
, op1
, 4, rs
, -1, imm
<< 2, 4);
24708 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
24710 /* OPC_NAL, OPC_BAL */
24711 gen_compute_branch(ctx
, op1
, 4, 0, -1, imm
<< 2, 4);
24713 gen_reserved_instruction(ctx
);
24716 gen_compute_branch(ctx
, op1
, 4, rs
, -1, imm
<< 2, 4);
24719 case OPC_TGEI
: /* REGIMM traps */
24726 check_insn(ctx
, ISA_MIPS2
);
24727 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
24728 gen_trap(ctx
, op1
, rs
, -1, imm
);
24731 check_insn(ctx
, ISA_MIPS_R6
);
24732 gen_reserved_instruction(ctx
);
24735 check_insn(ctx
, ISA_MIPS_R2
);
24737 * Break the TB to be able to sync copied instructions
24740 ctx
->base
.is_jmp
= DISAS_STOP
;
24742 case OPC_BPOSGE32
: /* MIPS DSP branch */
24743 #if defined(TARGET_MIPS64)
24747 gen_compute_branch(ctx
, op1
, 4, -1, -2, (int32_t)imm
<< 2, 4);
24749 #if defined(TARGET_MIPS64)
24751 check_insn(ctx
, ISA_MIPS_R6
);
24752 check_mips_64(ctx
);
24754 tcg_gen_addi_tl(cpu_gpr
[rs
], cpu_gpr
[rs
], (int64_t)imm
<< 32);
24758 check_insn(ctx
, ISA_MIPS_R6
);
24759 check_mips_64(ctx
);
24761 tcg_gen_addi_tl(cpu_gpr
[rs
], cpu_gpr
[rs
], (int64_t)imm
<< 48);
24765 default: /* Invalid */
24766 MIPS_INVAL("regimm");
24767 gen_reserved_instruction(ctx
);
24772 check_cp0_enabled(ctx
);
24773 op1
= MASK_CP0(ctx
->opcode
);
24781 #if defined(TARGET_MIPS64)
24785 #ifndef CONFIG_USER_ONLY
24786 gen_cp0(env
, ctx
, op1
, rt
, rd
);
24787 #endif /* !CONFIG_USER_ONLY */
24805 #ifndef CONFIG_USER_ONLY
24806 gen_cp0(env
, ctx
, MASK_C0(ctx
->opcode
), rt
, rd
);
24807 #endif /* !CONFIG_USER_ONLY */
24810 #ifndef CONFIG_USER_ONLY
24813 TCGv t0
= tcg_temp_new();
24815 op2
= MASK_MFMC0(ctx
->opcode
);
24819 gen_helper_dmt(t0
);
24820 gen_store_gpr(t0
, rt
);
24824 gen_helper_emt(t0
);
24825 gen_store_gpr(t0
, rt
);
24829 gen_helper_dvpe(t0
, cpu_env
);
24830 gen_store_gpr(t0
, rt
);
24834 gen_helper_evpe(t0
, cpu_env
);
24835 gen_store_gpr(t0
, rt
);
24838 check_insn(ctx
, ISA_MIPS_R6
);
24840 gen_helper_dvp(t0
, cpu_env
);
24841 gen_store_gpr(t0
, rt
);
24845 check_insn(ctx
, ISA_MIPS_R6
);
24847 gen_helper_evp(t0
, cpu_env
);
24848 gen_store_gpr(t0
, rt
);
24852 check_insn(ctx
, ISA_MIPS_R2
);
24853 save_cpu_state(ctx
, 1);
24854 gen_helper_di(t0
, cpu_env
);
24855 gen_store_gpr(t0
, rt
);
24857 * Stop translation as we may have switched
24858 * the execution mode.
24860 ctx
->base
.is_jmp
= DISAS_STOP
;
24863 check_insn(ctx
, ISA_MIPS_R2
);
24864 save_cpu_state(ctx
, 1);
24865 gen_helper_ei(t0
, cpu_env
);
24866 gen_store_gpr(t0
, rt
);
24868 * DISAS_STOP isn't sufficient, we need to ensure we break
24869 * out of translated code to check for pending interrupts.
24871 gen_save_pc(ctx
->base
.pc_next
+ 4);
24872 ctx
->base
.is_jmp
= DISAS_EXIT
;
24874 default: /* Invalid */
24875 MIPS_INVAL("mfmc0");
24876 gen_reserved_instruction(ctx
);
24881 #endif /* !CONFIG_USER_ONLY */
24884 check_insn(ctx
, ISA_MIPS_R2
);
24885 gen_load_srsgpr(rt
, rd
);
24888 check_insn(ctx
, ISA_MIPS_R2
);
24889 gen_store_srsgpr(rt
, rd
);
24893 gen_reserved_instruction(ctx
);
24897 case OPC_BOVC
: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */
24898 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
24899 /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */
24900 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
24903 /* Arithmetic with immediate opcode */
24904 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
24908 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
24910 case OPC_SLTI
: /* Set on less than with immediate opcode */
24912 gen_slt_imm(ctx
, op
, rt
, rs
, imm
);
24914 case OPC_ANDI
: /* Arithmetic with immediate opcode */
24915 case OPC_LUI
: /* OPC_AUI */
24918 gen_logic_imm(ctx
, op
, rt
, rs
, imm
);
24920 case OPC_J
: /* Jump */
24922 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
24923 gen_compute_branch(ctx
, op
, 4, rs
, rt
, offset
, 4);
24926 case OPC_BLEZC
: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */
24927 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
24929 gen_reserved_instruction(ctx
);
24932 /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */
24933 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
24936 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
24939 case OPC_BGTZC
: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */
24940 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
24942 gen_reserved_instruction(ctx
);
24945 /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */
24946 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
24949 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
24952 case OPC_BLEZALC
: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */
24955 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
24957 check_insn(ctx
, ISA_MIPS_R6
);
24958 /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */
24959 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
24962 case OPC_BGTZALC
: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */
24965 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
24967 check_insn(ctx
, ISA_MIPS_R6
);
24968 /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */
24969 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
24974 check_insn(ctx
, ISA_MIPS2
);
24975 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
24979 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
24981 case OPC_LL
: /* Load and stores */
24982 check_insn(ctx
, ISA_MIPS2
);
24983 if (ctx
->insn_flags
& INSN_R5900
) {
24984 check_insn_opc_user_only(ctx
, INSN_R5900
);
24995 gen_ld(ctx
, op
, rt
, rs
, imm
);
25002 gen_st(ctx
, op
, rt
, rs
, imm
);
25005 check_insn(ctx
, ISA_MIPS2
);
25006 if (ctx
->insn_flags
& INSN_R5900
) {
25007 check_insn_opc_user_only(ctx
, INSN_R5900
);
25009 gen_st_cond(ctx
, rt
, rs
, imm
, MO_TESL
, false);
25012 check_cp0_enabled(ctx
);
25013 check_insn(ctx
, ISA_MIPS3
| ISA_MIPS_R1
);
25014 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
25015 gen_cache_operation(ctx
, rt
, rs
, imm
);
25017 /* Treat as NOP. */
25020 if (ctx
->insn_flags
& INSN_R5900
) {
25021 /* Treat as NOP. */
25023 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS_R1
);
25024 /* Treat as NOP. */
25028 /* Floating point (COP1). */
25033 gen_cop1_ldst(ctx
, op
, rt
, rs
, imm
);
25037 op1
= MASK_CP1(ctx
->opcode
);
25042 check_cp1_enabled(ctx
);
25043 check_insn(ctx
, ISA_MIPS_R2
);
25049 check_cp1_enabled(ctx
);
25050 gen_cp1(ctx
, op1
, rt
, rd
);
25052 #if defined(TARGET_MIPS64)
25055 check_cp1_enabled(ctx
);
25056 check_insn(ctx
, ISA_MIPS3
);
25057 check_mips_64(ctx
);
25058 gen_cp1(ctx
, op1
, rt
, rd
);
25061 case OPC_BC1EQZ
: /* OPC_BC1ANY2 */
25062 check_cp1_enabled(ctx
);
25063 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
25065 gen_compute_branch1_r6(ctx
, MASK_CP1(ctx
->opcode
),
25070 check_insn(ctx
, ASE_MIPS3D
);
25071 gen_compute_branch1(ctx
, MASK_BC1(ctx
->opcode
),
25072 (rt
>> 2) & 0x7, imm
<< 2);
25076 check_cp1_enabled(ctx
);
25077 check_insn(ctx
, ISA_MIPS_R6
);
25078 gen_compute_branch1_r6(ctx
, MASK_CP1(ctx
->opcode
),
25082 check_cp1_enabled(ctx
);
25083 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
25085 check_insn(ctx
, ASE_MIPS3D
);
25088 check_cp1_enabled(ctx
);
25089 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
25090 gen_compute_branch1(ctx
, MASK_BC1(ctx
->opcode
),
25091 (rt
>> 2) & 0x7, imm
<< 2);
25098 check_cp1_enabled(ctx
);
25099 gen_farith(ctx
, ctx
->opcode
& FOP(0x3f, 0x1f), rt
, rd
, sa
,
25105 int r6_op
= ctx
->opcode
& FOP(0x3f, 0x1f);
25106 check_cp1_enabled(ctx
);
25107 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
25109 case R6_OPC_CMP_AF_S
:
25110 case R6_OPC_CMP_UN_S
:
25111 case R6_OPC_CMP_EQ_S
:
25112 case R6_OPC_CMP_UEQ_S
:
25113 case R6_OPC_CMP_LT_S
:
25114 case R6_OPC_CMP_ULT_S
:
25115 case R6_OPC_CMP_LE_S
:
25116 case R6_OPC_CMP_ULE_S
:
25117 case R6_OPC_CMP_SAF_S
:
25118 case R6_OPC_CMP_SUN_S
:
25119 case R6_OPC_CMP_SEQ_S
:
25120 case R6_OPC_CMP_SEUQ_S
:
25121 case R6_OPC_CMP_SLT_S
:
25122 case R6_OPC_CMP_SULT_S
:
25123 case R6_OPC_CMP_SLE_S
:
25124 case R6_OPC_CMP_SULE_S
:
25125 case R6_OPC_CMP_OR_S
:
25126 case R6_OPC_CMP_UNE_S
:
25127 case R6_OPC_CMP_NE_S
:
25128 case R6_OPC_CMP_SOR_S
:
25129 case R6_OPC_CMP_SUNE_S
:
25130 case R6_OPC_CMP_SNE_S
:
25131 gen_r6_cmp_s(ctx
, ctx
->opcode
& 0x1f, rt
, rd
, sa
);
25133 case R6_OPC_CMP_AF_D
:
25134 case R6_OPC_CMP_UN_D
:
25135 case R6_OPC_CMP_EQ_D
:
25136 case R6_OPC_CMP_UEQ_D
:
25137 case R6_OPC_CMP_LT_D
:
25138 case R6_OPC_CMP_ULT_D
:
25139 case R6_OPC_CMP_LE_D
:
25140 case R6_OPC_CMP_ULE_D
:
25141 case R6_OPC_CMP_SAF_D
:
25142 case R6_OPC_CMP_SUN_D
:
25143 case R6_OPC_CMP_SEQ_D
:
25144 case R6_OPC_CMP_SEUQ_D
:
25145 case R6_OPC_CMP_SLT_D
:
25146 case R6_OPC_CMP_SULT_D
:
25147 case R6_OPC_CMP_SLE_D
:
25148 case R6_OPC_CMP_SULE_D
:
25149 case R6_OPC_CMP_OR_D
:
25150 case R6_OPC_CMP_UNE_D
:
25151 case R6_OPC_CMP_NE_D
:
25152 case R6_OPC_CMP_SOR_D
:
25153 case R6_OPC_CMP_SUNE_D
:
25154 case R6_OPC_CMP_SNE_D
:
25155 gen_r6_cmp_d(ctx
, ctx
->opcode
& 0x1f, rt
, rd
, sa
);
25158 gen_farith(ctx
, ctx
->opcode
& FOP(0x3f, 0x1f),
25159 rt
, rd
, sa
, (imm
>> 8) & 0x7);
25164 gen_farith(ctx
, ctx
->opcode
& FOP(0x3f, 0x1f), rt
, rd
, sa
,
25171 gen_reserved_instruction(ctx
);
25176 /* Compact branches [R6] and COP2 [non-R6] */
25177 case OPC_BC
: /* OPC_LWC2 */
25178 case OPC_BALC
: /* OPC_SWC2 */
25179 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
25180 /* OPC_BC, OPC_BALC */
25181 gen_compute_compact_branch(ctx
, op
, 0, 0,
25182 sextract32(ctx
->opcode
<< 2, 0, 28));
25183 } else if (ctx
->insn_flags
& ASE_LEXT
) {
25184 gen_loongson_lswc2(ctx
, rt
, rs
, rd
);
25186 /* OPC_LWC2, OPC_SWC2 */
25187 /* COP2: Not implemented. */
25188 generate_exception_err(ctx
, EXCP_CpU
, 2);
25191 case OPC_BEQZC
: /* OPC_JIC, OPC_LDC2 */
25192 case OPC_BNEZC
: /* OPC_JIALC, OPC_SDC2 */
25193 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
25195 /* OPC_BEQZC, OPC_BNEZC */
25196 gen_compute_compact_branch(ctx
, op
, rs
, 0,
25197 sextract32(ctx
->opcode
<< 2, 0, 23));
25199 /* OPC_JIC, OPC_JIALC */
25200 gen_compute_compact_branch(ctx
, op
, 0, rt
, imm
);
25202 } else if (ctx
->insn_flags
& ASE_LEXT
) {
25203 gen_loongson_lsdc2(ctx
, rt
, rs
, rd
);
25205 /* OPC_LWC2, OPC_SWC2 */
25206 /* COP2: Not implemented. */
25207 generate_exception_err(ctx
, EXCP_CpU
, 2);
25211 check_insn(ctx
, ASE_LMMI
);
25212 /* Note that these instructions use different fields. */
25213 gen_loongson_multimedia(ctx
, sa
, rd
, rt
);
25217 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
25218 check_cp1_enabled(ctx
);
25219 op1
= MASK_CP3(ctx
->opcode
);
25223 check_insn(ctx
, ISA_MIPS5
| ISA_MIPS_R2
);
25229 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS_R2
);
25230 gen_flt3_ldst(ctx
, op1
, sa
, rd
, rs
, rt
);
25233 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS_R2
);
25234 /* Treat as NOP. */
25237 check_insn(ctx
, ISA_MIPS5
| ISA_MIPS_R2
);
25251 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS_R2
);
25252 gen_flt3_arith(ctx
, op1
, sa
, rs
, rd
, rt
);
25256 gen_reserved_instruction(ctx
);
25260 generate_exception_err(ctx
, EXCP_CpU
, 1);
25264 #if defined(TARGET_MIPS64)
25265 /* MIPS64 opcodes */
25267 if (ctx
->insn_flags
& INSN_R5900
) {
25268 check_insn_opc_user_only(ctx
, INSN_R5900
);
25275 check_insn(ctx
, ISA_MIPS3
);
25276 check_mips_64(ctx
);
25277 gen_ld(ctx
, op
, rt
, rs
, imm
);
25282 check_insn(ctx
, ISA_MIPS3
);
25283 check_mips_64(ctx
);
25284 gen_st(ctx
, op
, rt
, rs
, imm
);
25287 check_insn(ctx
, ISA_MIPS3
);
25288 if (ctx
->insn_flags
& INSN_R5900
) {
25289 check_insn_opc_user_only(ctx
, INSN_R5900
);
25291 check_mips_64(ctx
);
25292 gen_st_cond(ctx
, rt
, rs
, imm
, MO_TEQ
, false);
25294 case OPC_BNVC
: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */
25295 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
25296 /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */
25297 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
25300 check_insn(ctx
, ISA_MIPS3
);
25301 check_mips_64(ctx
);
25302 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
25306 check_insn(ctx
, ISA_MIPS3
);
25307 check_mips_64(ctx
);
25308 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
25311 case OPC_BNVC
: /* OPC_BNEZALC, OPC_BNEC */
25312 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
25313 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
25315 MIPS_INVAL("major opcode");
25316 gen_reserved_instruction(ctx
);
25320 case OPC_DAUI
: /* OPC_JALX */
25321 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
25322 #if defined(TARGET_MIPS64)
25324 check_mips_64(ctx
);
25326 generate_exception(ctx
, EXCP_RI
);
25327 } else if (rt
!= 0) {
25328 TCGv t0
= tcg_temp_new();
25329 gen_load_gpr(t0
, rs
);
25330 tcg_gen_addi_tl(cpu_gpr
[rt
], t0
, imm
<< 16);
25334 gen_reserved_instruction(ctx
);
25335 MIPS_INVAL("major opcode");
25339 check_insn(ctx
, ASE_MIPS16
| ASE_MICROMIPS
);
25340 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
25341 gen_compute_branch(ctx
, op
, 4, rs
, rt
, offset
, 4);
25344 case OPC_MDMX
: /* MMI_OPC_LQ */
25345 if (ctx
->insn_flags
& INSN_R5900
) {
25346 #if defined(TARGET_MIPS64)
25347 gen_mmi_lq(env
, ctx
);
25350 /* MDMX: Not implemented. */
25354 check_insn(ctx
, ISA_MIPS_R6
);
25355 gen_pcrel(ctx
, ctx
->opcode
, ctx
->base
.pc_next
, rs
);
25357 default: /* Invalid */
25358 MIPS_INVAL("major opcode");
25364 static void decode_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
25366 /* make sure instructions are on a word boundary */
25367 if (ctx
->base
.pc_next
& 0x3) {
25368 env
->CP0_BadVAddr
= ctx
->base
.pc_next
;
25369 generate_exception_err(ctx
, EXCP_AdEL
, EXCP_INST_NOTAVAIL
);
25373 /* Handle blikely not taken case */
25374 if ((ctx
->hflags
& MIPS_HFLAG_BMASK_BASE
) == MIPS_HFLAG_BL
) {
25375 TCGLabel
*l1
= gen_new_label();
25377 tcg_gen_brcondi_tl(TCG_COND_NE
, bcond
, 0, l1
);
25378 tcg_gen_movi_i32(hflags
, ctx
->hflags
& ~MIPS_HFLAG_BMASK
);
25379 gen_goto_tb(ctx
, 1, ctx
->base
.pc_next
+ 4);
25383 /* Transition to the auto-generated decoder. */
25385 /* ISA extensions */
25386 if (ase_msa_available(env
) && decode_ase_msa(ctx
, ctx
->opcode
)) {
25390 /* ISA (from latest to oldest) */
25391 if (cpu_supports_isa(env
, ISA_MIPS_R6
) && decode_isa_rel6(ctx
, ctx
->opcode
)) {
25394 if (cpu_supports_isa(env
, INSN_R5900
) && decode_ext_txx9(ctx
, ctx
->opcode
)) {
25398 if (decode_opc_legacy(env
, ctx
)) {
25402 gen_reserved_instruction(ctx
);
25405 static void mips_tr_init_disas_context(DisasContextBase
*dcbase
, CPUState
*cs
)
25407 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
25408 CPUMIPSState
*env
= cs
->env_ptr
;
25410 ctx
->page_start
= ctx
->base
.pc_first
& TARGET_PAGE_MASK
;
25411 ctx
->saved_pc
= -1;
25412 ctx
->insn_flags
= env
->insn_flags
;
25413 ctx
->CP0_Config1
= env
->CP0_Config1
;
25414 ctx
->CP0_Config2
= env
->CP0_Config2
;
25415 ctx
->CP0_Config3
= env
->CP0_Config3
;
25416 ctx
->CP0_Config5
= env
->CP0_Config5
;
25418 ctx
->kscrexist
= (env
->CP0_Config4
>> CP0C4_KScrExist
) & 0xff;
25419 ctx
->rxi
= (env
->CP0_Config3
>> CP0C3_RXI
) & 1;
25420 ctx
->ie
= (env
->CP0_Config4
>> CP0C4_IE
) & 3;
25421 ctx
->bi
= (env
->CP0_Config3
>> CP0C3_BI
) & 1;
25422 ctx
->bp
= (env
->CP0_Config3
>> CP0C3_BP
) & 1;
25423 ctx
->PAMask
= env
->PAMask
;
25424 ctx
->mvh
= (env
->CP0_Config5
>> CP0C5_MVH
) & 1;
25425 ctx
->eva
= (env
->CP0_Config5
>> CP0C5_EVA
) & 1;
25426 ctx
->sc
= (env
->CP0_Config3
>> CP0C3_SC
) & 1;
25427 ctx
->CP0_LLAddr_shift
= env
->CP0_LLAddr_shift
;
25428 ctx
->cmgcr
= (env
->CP0_Config3
>> CP0C3_CMGCR
) & 1;
25429 /* Restore delay slot state from the tb context. */
25430 ctx
->hflags
= (uint32_t)ctx
->base
.tb
->flags
; /* FIXME: maybe use 64 bits? */
25431 ctx
->ulri
= (env
->CP0_Config3
>> CP0C3_ULRI
) & 1;
25432 ctx
->ps
= ((env
->active_fpu
.fcr0
>> FCR0_PS
) & 1) ||
25433 (env
->insn_flags
& (INSN_LOONGSON2E
| INSN_LOONGSON2F
));
25434 ctx
->vp
= (env
->CP0_Config5
>> CP0C5_VP
) & 1;
25435 ctx
->mrp
= (env
->CP0_Config5
>> CP0C5_MRP
) & 1;
25436 ctx
->nan2008
= (env
->active_fpu
.fcr31
>> FCR31_NAN2008
) & 1;
25437 ctx
->abs2008
= (env
->active_fpu
.fcr31
>> FCR31_ABS2008
) & 1;
25438 ctx
->mi
= (env
->CP0_Config5
>> CP0C5_MI
) & 1;
25439 ctx
->gi
= (env
->CP0_Config5
>> CP0C5_GI
) & 3;
25440 restore_cpu_state(env
, ctx
);
25441 #ifdef CONFIG_USER_ONLY
25442 ctx
->mem_idx
= MIPS_HFLAG_UM
;
25444 ctx
->mem_idx
= hflags_mmu_index(ctx
->hflags
);
25446 ctx
->default_tcg_memop_mask
= (ctx
->insn_flags
& (ISA_MIPS_R6
|
25447 INSN_LOONGSON3A
)) ? MO_UNALN
: MO_ALIGN
;
25449 LOG_DISAS("\ntb %p idx %d hflags %04x\n", ctx
->base
.tb
, ctx
->mem_idx
,
25453 static void mips_tr_tb_start(DisasContextBase
*dcbase
, CPUState
*cs
)
25457 static void mips_tr_insn_start(DisasContextBase
*dcbase
, CPUState
*cs
)
25459 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
25461 tcg_gen_insn_start(ctx
->base
.pc_next
, ctx
->hflags
& MIPS_HFLAG_BMASK
,
25465 static bool mips_tr_breakpoint_check(DisasContextBase
*dcbase
, CPUState
*cs
,
25466 const CPUBreakpoint
*bp
)
25468 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
25470 save_cpu_state(ctx
, 1);
25471 ctx
->base
.is_jmp
= DISAS_NORETURN
;
25472 gen_helper_raise_exception_debug(cpu_env
);
25474 * The address covered by the breakpoint must be included in
25475 * [tb->pc, tb->pc + tb->size) in order to for it to be
25476 * properly cleared -- thus we increment the PC here so that
25477 * the logic setting tb->size below does the right thing.
25479 ctx
->base
.pc_next
+= 4;
25483 static void mips_tr_translate_insn(DisasContextBase
*dcbase
, CPUState
*cs
)
25485 CPUMIPSState
*env
= cs
->env_ptr
;
25486 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
25490 is_slot
= ctx
->hflags
& MIPS_HFLAG_BMASK
;
25491 if (ctx
->insn_flags
& ISA_NANOMIPS32
) {
25492 ctx
->opcode
= translator_lduw(env
, ctx
->base
.pc_next
);
25493 insn_bytes
= decode_nanomips_opc(env
, ctx
);
25494 } else if (!(ctx
->hflags
& MIPS_HFLAG_M16
)) {
25495 ctx
->opcode
= translator_ldl(env
, ctx
->base
.pc_next
);
25497 decode_opc(env
, ctx
);
25498 } else if (ctx
->insn_flags
& ASE_MICROMIPS
) {
25499 ctx
->opcode
= translator_lduw(env
, ctx
->base
.pc_next
);
25500 insn_bytes
= decode_micromips_opc(env
, ctx
);
25501 } else if (ctx
->insn_flags
& ASE_MIPS16
) {
25502 ctx
->opcode
= translator_lduw(env
, ctx
->base
.pc_next
);
25503 insn_bytes
= decode_mips16_opc(env
, ctx
);
25505 gen_reserved_instruction(ctx
);
25506 g_assert(ctx
->base
.is_jmp
== DISAS_NORETURN
);
25510 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
25511 if (!(ctx
->hflags
& (MIPS_HFLAG_BDS16
| MIPS_HFLAG_BDS32
|
25512 MIPS_HFLAG_FBNSLOT
))) {
25514 * Force to generate branch as there is neither delay nor
25519 if ((ctx
->hflags
& MIPS_HFLAG_M16
) &&
25520 (ctx
->hflags
& MIPS_HFLAG_FBNSLOT
)) {
25522 * Force to generate branch as microMIPS R6 doesn't restrict
25523 * branches in the forbidden slot.
25529 gen_branch(ctx
, insn_bytes
);
25531 ctx
->base
.pc_next
+= insn_bytes
;
25533 if (ctx
->base
.is_jmp
!= DISAS_NEXT
) {
25537 * Execute a branch and its delay slot as a single instruction.
25538 * This is what GDB expects and is consistent with what the
25539 * hardware does (e.g. if a delay slot instruction faults, the
25540 * reported PC is the PC of the branch).
25542 if (ctx
->base
.singlestep_enabled
&&
25543 (ctx
->hflags
& MIPS_HFLAG_BMASK
) == 0) {
25544 ctx
->base
.is_jmp
= DISAS_TOO_MANY
;
25546 if (ctx
->base
.pc_next
- ctx
->page_start
>= TARGET_PAGE_SIZE
) {
25547 ctx
->base
.is_jmp
= DISAS_TOO_MANY
;
25551 static void mips_tr_tb_stop(DisasContextBase
*dcbase
, CPUState
*cs
)
25553 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
25555 if (ctx
->base
.singlestep_enabled
&& ctx
->base
.is_jmp
!= DISAS_NORETURN
) {
25556 save_cpu_state(ctx
, ctx
->base
.is_jmp
!= DISAS_EXIT
);
25557 gen_helper_raise_exception_debug(cpu_env
);
25559 switch (ctx
->base
.is_jmp
) {
25561 gen_save_pc(ctx
->base
.pc_next
);
25562 tcg_gen_lookup_and_goto_ptr();
25565 case DISAS_TOO_MANY
:
25566 save_cpu_state(ctx
, 0);
25567 gen_goto_tb(ctx
, 0, ctx
->base
.pc_next
);
25570 tcg_gen_exit_tb(NULL
, 0);
25572 case DISAS_NORETURN
:
25575 g_assert_not_reached();
25580 static void mips_tr_disas_log(const DisasContextBase
*dcbase
, CPUState
*cs
)
25582 qemu_log("IN: %s\n", lookup_symbol(dcbase
->pc_first
));
25583 log_target_disas(cs
, dcbase
->pc_first
, dcbase
->tb
->size
);
25586 static const TranslatorOps mips_tr_ops
= {
25587 .init_disas_context
= mips_tr_init_disas_context
,
25588 .tb_start
= mips_tr_tb_start
,
25589 .insn_start
= mips_tr_insn_start
,
25590 .breakpoint_check
= mips_tr_breakpoint_check
,
25591 .translate_insn
= mips_tr_translate_insn
,
25592 .tb_stop
= mips_tr_tb_stop
,
25593 .disas_log
= mips_tr_disas_log
,
25596 void gen_intermediate_code(CPUState
*cs
, TranslationBlock
*tb
, int max_insns
)
25600 translator_loop(&mips_tr_ops
, &ctx
.base
, cs
, tb
, max_insns
);
25603 static void fpu_dump_state(CPUMIPSState
*env
, FILE * f
, int flags
)
25606 int is_fpu64
= !!(env
->hflags
& MIPS_HFLAG_F64
);
25608 #define printfpr(fp) \
25611 qemu_fprintf(f, "w:%08x d:%016" PRIx64 \
25612 " fd:%13g fs:%13g psu: %13g\n", \
25613 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
25614 (double)(fp)->fd, \
25615 (double)(fp)->fs[FP_ENDIAN_IDX], \
25616 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
25619 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
25620 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
25621 qemu_fprintf(f, "w:%08x d:%016" PRIx64 \
25622 " fd:%13g fs:%13g psu:%13g\n", \
25623 tmp.w[FP_ENDIAN_IDX], tmp.d, \
25625 (double)tmp.fs[FP_ENDIAN_IDX], \
25626 (double)tmp.fs[!FP_ENDIAN_IDX]); \
25632 "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
25633 env
->active_fpu
.fcr0
, env
->active_fpu
.fcr31
, is_fpu64
,
25634 get_float_exception_flags(&env
->active_fpu
.fp_status
));
25635 for (i
= 0; i
< 32; (is_fpu64
) ? i
++ : (i
+= 2)) {
25636 qemu_fprintf(f
, "%3s: ", fregnames
[i
]);
25637 printfpr(&env
->active_fpu
.fpr
[i
]);
25643 void mips_cpu_dump_state(CPUState
*cs
, FILE *f
, int flags
)
25645 MIPSCPU
*cpu
= MIPS_CPU(cs
);
25646 CPUMIPSState
*env
= &cpu
->env
;
25649 qemu_fprintf(f
, "pc=0x" TARGET_FMT_lx
" HI=0x" TARGET_FMT_lx
25650 " LO=0x" TARGET_FMT_lx
" ds %04x "
25651 TARGET_FMT_lx
" " TARGET_FMT_ld
"\n",
25652 env
->active_tc
.PC
, env
->active_tc
.HI
[0], env
->active_tc
.LO
[0],
25653 env
->hflags
, env
->btarget
, env
->bcond
);
25654 for (i
= 0; i
< 32; i
++) {
25655 if ((i
& 3) == 0) {
25656 qemu_fprintf(f
, "GPR%02d:", i
);
25658 qemu_fprintf(f
, " %s " TARGET_FMT_lx
,
25659 regnames
[i
], env
->active_tc
.gpr
[i
]);
25660 if ((i
& 3) == 3) {
25661 qemu_fprintf(f
, "\n");
25665 qemu_fprintf(f
, "CP0 Status 0x%08x Cause 0x%08x EPC 0x"
25666 TARGET_FMT_lx
"\n",
25667 env
->CP0_Status
, env
->CP0_Cause
, env
->CP0_EPC
);
25668 qemu_fprintf(f
, " Config0 0x%08x Config1 0x%08x LLAddr 0x%016"
25670 env
->CP0_Config0
, env
->CP0_Config1
, env
->CP0_LLAddr
);
25671 qemu_fprintf(f
, " Config2 0x%08x Config3 0x%08x\n",
25672 env
->CP0_Config2
, env
->CP0_Config3
);
25673 qemu_fprintf(f
, " Config4 0x%08x Config5 0x%08x\n",
25674 env
->CP0_Config4
, env
->CP0_Config5
);
25675 if ((flags
& CPU_DUMP_FPU
) && (env
->hflags
& MIPS_HFLAG_FPU
)) {
25676 fpu_dump_state(env
, f
, flags
);
25680 void mips_tcg_init(void)
25685 for (i
= 1; i
< 32; i
++)
25686 cpu_gpr
[i
] = tcg_global_mem_new(cpu_env
,
25687 offsetof(CPUMIPSState
,
25690 #if defined(TARGET_MIPS64)
25691 cpu_gpr_hi
[0] = NULL
;
25693 for (unsigned i
= 1; i
< 32; i
++) {
25694 g_autofree
char *rname
= g_strdup_printf("%s[hi]", regnames
[i
]);
25696 cpu_gpr_hi
[i
] = tcg_global_mem_new_i64(cpu_env
,
25697 offsetof(CPUMIPSState
,
25698 active_tc
.gpr_hi
[i
]),
25701 #endif /* !TARGET_MIPS64 */
25702 for (i
= 0; i
< 32; i
++) {
25703 int off
= offsetof(CPUMIPSState
, active_fpu
.fpr
[i
].wr
.d
[0]);
25705 fpu_f64
[i
] = tcg_global_mem_new_i64(cpu_env
, off
, fregnames
[i
]);
25707 msa_translate_init();
25708 cpu_PC
= tcg_global_mem_new(cpu_env
,
25709 offsetof(CPUMIPSState
, active_tc
.PC
), "PC");
25710 for (i
= 0; i
< MIPS_DSP_ACC
; i
++) {
25711 cpu_HI
[i
] = tcg_global_mem_new(cpu_env
,
25712 offsetof(CPUMIPSState
, active_tc
.HI
[i
]),
25714 cpu_LO
[i
] = tcg_global_mem_new(cpu_env
,
25715 offsetof(CPUMIPSState
, active_tc
.LO
[i
]),
25718 cpu_dspctrl
= tcg_global_mem_new(cpu_env
,
25719 offsetof(CPUMIPSState
,
25720 active_tc
.DSPControl
),
25722 bcond
= tcg_global_mem_new(cpu_env
,
25723 offsetof(CPUMIPSState
, bcond
), "bcond");
25724 btarget
= tcg_global_mem_new(cpu_env
,
25725 offsetof(CPUMIPSState
, btarget
), "btarget");
25726 hflags
= tcg_global_mem_new_i32(cpu_env
,
25727 offsetof(CPUMIPSState
, hflags
), "hflags");
25729 fpu_fcr0
= tcg_global_mem_new_i32(cpu_env
,
25730 offsetof(CPUMIPSState
, active_fpu
.fcr0
),
25732 fpu_fcr31
= tcg_global_mem_new_i32(cpu_env
,
25733 offsetof(CPUMIPSState
, active_fpu
.fcr31
),
25735 cpu_lladdr
= tcg_global_mem_new(cpu_env
, offsetof(CPUMIPSState
, lladdr
),
25737 cpu_llval
= tcg_global_mem_new(cpu_env
, offsetof(CPUMIPSState
, llval
),
25740 if (TARGET_LONG_BITS
== 32) {
25741 mxu_translate_init();
25745 void restore_state_to_opc(CPUMIPSState
*env
, TranslationBlock
*tb
,
25746 target_ulong
*data
)
25748 env
->active_tc
.PC
= data
[0];
25749 env
->hflags
&= ~MIPS_HFLAG_BMASK
;
25750 env
->hflags
|= data
[1];
25751 switch (env
->hflags
& MIPS_HFLAG_BMASK_BASE
) {
25752 case MIPS_HFLAG_BR
:
25754 case MIPS_HFLAG_BC
:
25755 case MIPS_HFLAG_BL
:
25757 env
->btarget
= data
[2];