2 * MIPS emulation for QEMU - main translation routines
4 * Copyright (c) 2004-2005 Jocelyn Mayer
5 * Copyright (c) 2006 Marius Groeger (FPU operations)
6 * Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support)
7 * Copyright (c) 2009 CodeSourcery (MIPS16 and microMIPS support)
8 * Copyright (c) 2012 Jia Liu & Dongxue Zhang (MIPS ASE DSP support)
9 * Copyright (c) 2020 Philippe Mathieu-Daudé
11 * This library is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public
13 * License as published by the Free Software Foundation; either
14 * version 2.1 of the License, or (at your option) any later version.
16 * This library is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
25 #include "qemu/osdep.h"
28 #include "tcg/tcg-op.h"
29 #include "exec/translator.h"
30 #include "exec/helper-proto.h"
31 #include "exec/helper-gen.h"
32 #include "semihosting/semihost.h"
34 #include "target/mips/trace.h"
35 #include "trace-tcg.h"
36 #include "exec/translator.h"
38 #include "qemu/qemu-print.h"
39 #include "fpu_helper.h"
40 #include "translate.h"
43 /* indirect opcode tables */
44 OPC_SPECIAL
= (0x00 << 26),
45 OPC_REGIMM
= (0x01 << 26),
46 OPC_CP0
= (0x10 << 26),
47 OPC_CP2
= (0x12 << 26),
48 OPC_CP3
= (0x13 << 26),
49 OPC_SPECIAL2
= (0x1C << 26),
50 OPC_SPECIAL3
= (0x1F << 26),
51 /* arithmetic with immediate */
52 OPC_ADDI
= (0x08 << 26),
53 OPC_ADDIU
= (0x09 << 26),
54 OPC_SLTI
= (0x0A << 26),
55 OPC_SLTIU
= (0x0B << 26),
56 /* logic with immediate */
57 OPC_ANDI
= (0x0C << 26),
58 OPC_ORI
= (0x0D << 26),
59 OPC_XORI
= (0x0E << 26),
60 OPC_LUI
= (0x0F << 26),
61 /* arithmetic with immediate */
62 OPC_DADDI
= (0x18 << 26),
63 OPC_DADDIU
= (0x19 << 26),
64 /* Jump and branches */
66 OPC_JAL
= (0x03 << 26),
67 OPC_BEQ
= (0x04 << 26), /* Unconditional if rs = rt = 0 (B) */
68 OPC_BEQL
= (0x14 << 26),
69 OPC_BNE
= (0x05 << 26),
70 OPC_BNEL
= (0x15 << 26),
71 OPC_BLEZ
= (0x06 << 26),
72 OPC_BLEZL
= (0x16 << 26),
73 OPC_BGTZ
= (0x07 << 26),
74 OPC_BGTZL
= (0x17 << 26),
75 OPC_JALX
= (0x1D << 26),
76 OPC_DAUI
= (0x1D << 26),
78 OPC_LDL
= (0x1A << 26),
79 OPC_LDR
= (0x1B << 26),
80 OPC_LB
= (0x20 << 26),
81 OPC_LH
= (0x21 << 26),
82 OPC_LWL
= (0x22 << 26),
83 OPC_LW
= (0x23 << 26),
84 OPC_LWPC
= OPC_LW
| 0x5,
85 OPC_LBU
= (0x24 << 26),
86 OPC_LHU
= (0x25 << 26),
87 OPC_LWR
= (0x26 << 26),
88 OPC_LWU
= (0x27 << 26),
89 OPC_SB
= (0x28 << 26),
90 OPC_SH
= (0x29 << 26),
91 OPC_SWL
= (0x2A << 26),
92 OPC_SW
= (0x2B << 26),
93 OPC_SDL
= (0x2C << 26),
94 OPC_SDR
= (0x2D << 26),
95 OPC_SWR
= (0x2E << 26),
96 OPC_LL
= (0x30 << 26),
97 OPC_LLD
= (0x34 << 26),
98 OPC_LD
= (0x37 << 26),
99 OPC_LDPC
= OPC_LD
| 0x5,
100 OPC_SC
= (0x38 << 26),
101 OPC_SCD
= (0x3C << 26),
102 OPC_SD
= (0x3F << 26),
103 /* Floating point load/store */
104 OPC_LWC1
= (0x31 << 26),
105 OPC_LWC2
= (0x32 << 26),
106 OPC_LDC1
= (0x35 << 26),
107 OPC_LDC2
= (0x36 << 26),
108 OPC_SWC1
= (0x39 << 26),
109 OPC_SWC2
= (0x3A << 26),
110 OPC_SDC1
= (0x3D << 26),
111 OPC_SDC2
= (0x3E << 26),
112 /* Compact Branches */
113 OPC_BLEZALC
= (0x06 << 26),
114 OPC_BGEZALC
= (0x06 << 26),
115 OPC_BGEUC
= (0x06 << 26),
116 OPC_BGTZALC
= (0x07 << 26),
117 OPC_BLTZALC
= (0x07 << 26),
118 OPC_BLTUC
= (0x07 << 26),
119 OPC_BOVC
= (0x08 << 26),
120 OPC_BEQZALC
= (0x08 << 26),
121 OPC_BEQC
= (0x08 << 26),
122 OPC_BLEZC
= (0x16 << 26),
123 OPC_BGEZC
= (0x16 << 26),
124 OPC_BGEC
= (0x16 << 26),
125 OPC_BGTZC
= (0x17 << 26),
126 OPC_BLTZC
= (0x17 << 26),
127 OPC_BLTC
= (0x17 << 26),
128 OPC_BNVC
= (0x18 << 26),
129 OPC_BNEZALC
= (0x18 << 26),
130 OPC_BNEC
= (0x18 << 26),
131 OPC_BC
= (0x32 << 26),
132 OPC_BEQZC
= (0x36 << 26),
133 OPC_JIC
= (0x36 << 26),
134 OPC_BALC
= (0x3A << 26),
135 OPC_BNEZC
= (0x3E << 26),
136 OPC_JIALC
= (0x3E << 26),
137 /* MDMX ASE specific */
138 OPC_MDMX
= (0x1E << 26),
139 /* Cache and prefetch */
140 OPC_CACHE
= (0x2F << 26),
141 OPC_PREF
= (0x33 << 26),
142 /* PC-relative address computation / loads */
143 OPC_PCREL
= (0x3B << 26),
146 /* PC-relative address computation / loads */
147 #define MASK_OPC_PCREL_TOP2BITS(op) (MASK_OP_MAJOR(op) | (op & (3 << 19)))
148 #define MASK_OPC_PCREL_TOP5BITS(op) (MASK_OP_MAJOR(op) | (op & (0x1f << 16)))
150 /* Instructions determined by bits 19 and 20 */
151 OPC_ADDIUPC
= OPC_PCREL
| (0 << 19),
152 R6_OPC_LWPC
= OPC_PCREL
| (1 << 19),
153 OPC_LWUPC
= OPC_PCREL
| (2 << 19),
155 /* Instructions determined by bits 16 ... 20 */
156 OPC_AUIPC
= OPC_PCREL
| (0x1e << 16),
157 OPC_ALUIPC
= OPC_PCREL
| (0x1f << 16),
160 R6_OPC_LDPC
= OPC_PCREL
| (6 << 18),
163 /* MIPS special opcodes */
164 #define MASK_SPECIAL(op) (MASK_OP_MAJOR(op) | (op & 0x3F))
168 OPC_SLL
= 0x00 | OPC_SPECIAL
,
169 /* NOP is SLL r0, r0, 0 */
170 /* SSNOP is SLL r0, r0, 1 */
171 /* EHB is SLL r0, r0, 3 */
172 OPC_SRL
= 0x02 | OPC_SPECIAL
, /* also ROTR */
173 OPC_ROTR
= OPC_SRL
| (1 << 21),
174 OPC_SRA
= 0x03 | OPC_SPECIAL
,
175 OPC_SLLV
= 0x04 | OPC_SPECIAL
,
176 OPC_SRLV
= 0x06 | OPC_SPECIAL
, /* also ROTRV */
177 OPC_ROTRV
= OPC_SRLV
| (1 << 6),
178 OPC_SRAV
= 0x07 | OPC_SPECIAL
,
179 OPC_DSLLV
= 0x14 | OPC_SPECIAL
,
180 OPC_DSRLV
= 0x16 | OPC_SPECIAL
, /* also DROTRV */
181 OPC_DROTRV
= OPC_DSRLV
| (1 << 6),
182 OPC_DSRAV
= 0x17 | OPC_SPECIAL
,
183 OPC_DSLL
= 0x38 | OPC_SPECIAL
,
184 OPC_DSRL
= 0x3A | OPC_SPECIAL
, /* also DROTR */
185 OPC_DROTR
= OPC_DSRL
| (1 << 21),
186 OPC_DSRA
= 0x3B | OPC_SPECIAL
,
187 OPC_DSLL32
= 0x3C | OPC_SPECIAL
,
188 OPC_DSRL32
= 0x3E | OPC_SPECIAL
, /* also DROTR32 */
189 OPC_DROTR32
= OPC_DSRL32
| (1 << 21),
190 OPC_DSRA32
= 0x3F | OPC_SPECIAL
,
191 /* Multiplication / division */
192 OPC_MULT
= 0x18 | OPC_SPECIAL
,
193 OPC_MULTU
= 0x19 | OPC_SPECIAL
,
194 OPC_DIV
= 0x1A | OPC_SPECIAL
,
195 OPC_DIVU
= 0x1B | OPC_SPECIAL
,
196 OPC_DMULT
= 0x1C | OPC_SPECIAL
,
197 OPC_DMULTU
= 0x1D | OPC_SPECIAL
,
198 OPC_DDIV
= 0x1E | OPC_SPECIAL
,
199 OPC_DDIVU
= 0x1F | OPC_SPECIAL
,
201 /* 2 registers arithmetic / logic */
202 OPC_ADD
= 0x20 | OPC_SPECIAL
,
203 OPC_ADDU
= 0x21 | OPC_SPECIAL
,
204 OPC_SUB
= 0x22 | OPC_SPECIAL
,
205 OPC_SUBU
= 0x23 | OPC_SPECIAL
,
206 OPC_AND
= 0x24 | OPC_SPECIAL
,
207 OPC_OR
= 0x25 | OPC_SPECIAL
,
208 OPC_XOR
= 0x26 | OPC_SPECIAL
,
209 OPC_NOR
= 0x27 | OPC_SPECIAL
,
210 OPC_SLT
= 0x2A | OPC_SPECIAL
,
211 OPC_SLTU
= 0x2B | OPC_SPECIAL
,
212 OPC_DADD
= 0x2C | OPC_SPECIAL
,
213 OPC_DADDU
= 0x2D | OPC_SPECIAL
,
214 OPC_DSUB
= 0x2E | OPC_SPECIAL
,
215 OPC_DSUBU
= 0x2F | OPC_SPECIAL
,
217 OPC_JR
= 0x08 | OPC_SPECIAL
, /* Also JR.HB */
218 OPC_JALR
= 0x09 | OPC_SPECIAL
, /* Also JALR.HB */
220 OPC_TGE
= 0x30 | OPC_SPECIAL
,
221 OPC_TGEU
= 0x31 | OPC_SPECIAL
,
222 OPC_TLT
= 0x32 | OPC_SPECIAL
,
223 OPC_TLTU
= 0x33 | OPC_SPECIAL
,
224 OPC_TEQ
= 0x34 | OPC_SPECIAL
,
225 OPC_TNE
= 0x36 | OPC_SPECIAL
,
226 /* HI / LO registers load & stores */
227 OPC_MFHI
= 0x10 | OPC_SPECIAL
,
228 OPC_MTHI
= 0x11 | OPC_SPECIAL
,
229 OPC_MFLO
= 0x12 | OPC_SPECIAL
,
230 OPC_MTLO
= 0x13 | OPC_SPECIAL
,
231 /* Conditional moves */
232 OPC_MOVZ
= 0x0A | OPC_SPECIAL
,
233 OPC_MOVN
= 0x0B | OPC_SPECIAL
,
235 OPC_SELEQZ
= 0x35 | OPC_SPECIAL
,
236 OPC_SELNEZ
= 0x37 | OPC_SPECIAL
,
238 OPC_MOVCI
= 0x01 | OPC_SPECIAL
,
241 OPC_PMON
= 0x05 | OPC_SPECIAL
, /* unofficial */
242 OPC_SYSCALL
= 0x0C | OPC_SPECIAL
,
243 OPC_BREAK
= 0x0D | OPC_SPECIAL
,
244 OPC_SPIM
= 0x0E | OPC_SPECIAL
, /* unofficial */
245 OPC_SYNC
= 0x0F | OPC_SPECIAL
,
247 OPC_SPECIAL28_RESERVED
= 0x28 | OPC_SPECIAL
,
248 OPC_SPECIAL29_RESERVED
= 0x29 | OPC_SPECIAL
,
249 OPC_SPECIAL39_RESERVED
= 0x39 | OPC_SPECIAL
,
250 OPC_SPECIAL3D_RESERVED
= 0x3D | OPC_SPECIAL
,
254 * R6 Multiply and Divide instructions have the same opcode
255 * and function field as legacy OPC_MULT[U]/OPC_DIV[U]
257 #define MASK_R6_MULDIV(op) (MASK_SPECIAL(op) | (op & (0x7ff)))
260 R6_OPC_MUL
= OPC_MULT
| (2 << 6),
261 R6_OPC_MUH
= OPC_MULT
| (3 << 6),
262 R6_OPC_MULU
= OPC_MULTU
| (2 << 6),
263 R6_OPC_MUHU
= OPC_MULTU
| (3 << 6),
264 R6_OPC_DIV
= OPC_DIV
| (2 << 6),
265 R6_OPC_MOD
= OPC_DIV
| (3 << 6),
266 R6_OPC_DIVU
= OPC_DIVU
| (2 << 6),
267 R6_OPC_MODU
= OPC_DIVU
| (3 << 6),
269 R6_OPC_DMUL
= OPC_DMULT
| (2 << 6),
270 R6_OPC_DMUH
= OPC_DMULT
| (3 << 6),
271 R6_OPC_DMULU
= OPC_DMULTU
| (2 << 6),
272 R6_OPC_DMUHU
= OPC_DMULTU
| (3 << 6),
273 R6_OPC_DDIV
= OPC_DDIV
| (2 << 6),
274 R6_OPC_DMOD
= OPC_DDIV
| (3 << 6),
275 R6_OPC_DDIVU
= OPC_DDIVU
| (2 << 6),
276 R6_OPC_DMODU
= OPC_DDIVU
| (3 << 6),
278 R6_OPC_CLZ
= 0x10 | OPC_SPECIAL
,
279 R6_OPC_CLO
= 0x11 | OPC_SPECIAL
,
280 R6_OPC_DCLZ
= 0x12 | OPC_SPECIAL
,
281 R6_OPC_DCLO
= 0x13 | OPC_SPECIAL
,
282 R6_OPC_SDBBP
= 0x0e | OPC_SPECIAL
,
285 /* Multiplication variants of the vr54xx. */
286 #define MASK_MUL_VR54XX(op) (MASK_SPECIAL(op) | (op & (0x1F << 6)))
289 OPC_VR54XX_MULS
= (0x03 << 6) | OPC_MULT
,
290 OPC_VR54XX_MULSU
= (0x03 << 6) | OPC_MULTU
,
291 OPC_VR54XX_MACC
= (0x05 << 6) | OPC_MULT
,
292 OPC_VR54XX_MACCU
= (0x05 << 6) | OPC_MULTU
,
293 OPC_VR54XX_MSAC
= (0x07 << 6) | OPC_MULT
,
294 OPC_VR54XX_MSACU
= (0x07 << 6) | OPC_MULTU
,
295 OPC_VR54XX_MULHI
= (0x09 << 6) | OPC_MULT
,
296 OPC_VR54XX_MULHIU
= (0x09 << 6) | OPC_MULTU
,
297 OPC_VR54XX_MULSHI
= (0x0B << 6) | OPC_MULT
,
298 OPC_VR54XX_MULSHIU
= (0x0B << 6) | OPC_MULTU
,
299 OPC_VR54XX_MACCHI
= (0x0D << 6) | OPC_MULT
,
300 OPC_VR54XX_MACCHIU
= (0x0D << 6) | OPC_MULTU
,
301 OPC_VR54XX_MSACHI
= (0x0F << 6) | OPC_MULT
,
302 OPC_VR54XX_MSACHIU
= (0x0F << 6) | OPC_MULTU
,
305 /* REGIMM (rt field) opcodes */
306 #define MASK_REGIMM(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 16)))
309 OPC_BLTZ
= (0x00 << 16) | OPC_REGIMM
,
310 OPC_BLTZL
= (0x02 << 16) | OPC_REGIMM
,
311 OPC_BGEZ
= (0x01 << 16) | OPC_REGIMM
,
312 OPC_BGEZL
= (0x03 << 16) | OPC_REGIMM
,
313 OPC_BLTZAL
= (0x10 << 16) | OPC_REGIMM
,
314 OPC_BLTZALL
= (0x12 << 16) | OPC_REGIMM
,
315 OPC_BGEZAL
= (0x11 << 16) | OPC_REGIMM
,
316 OPC_BGEZALL
= (0x13 << 16) | OPC_REGIMM
,
317 OPC_TGEI
= (0x08 << 16) | OPC_REGIMM
,
318 OPC_TGEIU
= (0x09 << 16) | OPC_REGIMM
,
319 OPC_TLTI
= (0x0A << 16) | OPC_REGIMM
,
320 OPC_TLTIU
= (0x0B << 16) | OPC_REGIMM
,
321 OPC_TEQI
= (0x0C << 16) | OPC_REGIMM
,
322 OPC_TNEI
= (0x0E << 16) | OPC_REGIMM
,
323 OPC_SIGRIE
= (0x17 << 16) | OPC_REGIMM
,
324 OPC_SYNCI
= (0x1F << 16) | OPC_REGIMM
,
326 OPC_DAHI
= (0x06 << 16) | OPC_REGIMM
,
327 OPC_DATI
= (0x1e << 16) | OPC_REGIMM
,
330 /* Special2 opcodes */
331 #define MASK_SPECIAL2(op) (MASK_OP_MAJOR(op) | (op & 0x3F))
334 /* Multiply & xxx operations */
335 OPC_MADD
= 0x00 | OPC_SPECIAL2
,
336 OPC_MADDU
= 0x01 | OPC_SPECIAL2
,
337 OPC_MUL
= 0x02 | OPC_SPECIAL2
,
338 OPC_MSUB
= 0x04 | OPC_SPECIAL2
,
339 OPC_MSUBU
= 0x05 | OPC_SPECIAL2
,
341 OPC_MULT_G_2F
= 0x10 | OPC_SPECIAL2
,
342 OPC_DMULT_G_2F
= 0x11 | OPC_SPECIAL2
,
343 OPC_MULTU_G_2F
= 0x12 | OPC_SPECIAL2
,
344 OPC_DMULTU_G_2F
= 0x13 | OPC_SPECIAL2
,
345 OPC_DIV_G_2F
= 0x14 | OPC_SPECIAL2
,
346 OPC_DDIV_G_2F
= 0x15 | OPC_SPECIAL2
,
347 OPC_DIVU_G_2F
= 0x16 | OPC_SPECIAL2
,
348 OPC_DDIVU_G_2F
= 0x17 | OPC_SPECIAL2
,
349 OPC_MOD_G_2F
= 0x1c | OPC_SPECIAL2
,
350 OPC_DMOD_G_2F
= 0x1d | OPC_SPECIAL2
,
351 OPC_MODU_G_2F
= 0x1e | OPC_SPECIAL2
,
352 OPC_DMODU_G_2F
= 0x1f | OPC_SPECIAL2
,
354 OPC_CLZ
= 0x20 | OPC_SPECIAL2
,
355 OPC_CLO
= 0x21 | OPC_SPECIAL2
,
356 OPC_DCLZ
= 0x24 | OPC_SPECIAL2
,
357 OPC_DCLO
= 0x25 | OPC_SPECIAL2
,
359 OPC_SDBBP
= 0x3F | OPC_SPECIAL2
,
362 /* Special3 opcodes */
363 #define MASK_SPECIAL3(op) (MASK_OP_MAJOR(op) | (op & 0x3F))
366 OPC_EXT
= 0x00 | OPC_SPECIAL3
,
367 OPC_DEXTM
= 0x01 | OPC_SPECIAL3
,
368 OPC_DEXTU
= 0x02 | OPC_SPECIAL3
,
369 OPC_DEXT
= 0x03 | OPC_SPECIAL3
,
370 OPC_INS
= 0x04 | OPC_SPECIAL3
,
371 OPC_DINSM
= 0x05 | OPC_SPECIAL3
,
372 OPC_DINSU
= 0x06 | OPC_SPECIAL3
,
373 OPC_DINS
= 0x07 | OPC_SPECIAL3
,
374 OPC_FORK
= 0x08 | OPC_SPECIAL3
,
375 OPC_YIELD
= 0x09 | OPC_SPECIAL3
,
376 OPC_BSHFL
= 0x20 | OPC_SPECIAL3
,
377 OPC_DBSHFL
= 0x24 | OPC_SPECIAL3
,
378 OPC_RDHWR
= 0x3B | OPC_SPECIAL3
,
379 OPC_GINV
= 0x3D | OPC_SPECIAL3
,
382 OPC_MULT_G_2E
= 0x18 | OPC_SPECIAL3
,
383 OPC_MULTU_G_2E
= 0x19 | OPC_SPECIAL3
,
384 OPC_DIV_G_2E
= 0x1A | OPC_SPECIAL3
,
385 OPC_DIVU_G_2E
= 0x1B | OPC_SPECIAL3
,
386 OPC_DMULT_G_2E
= 0x1C | OPC_SPECIAL3
,
387 OPC_DMULTU_G_2E
= 0x1D | OPC_SPECIAL3
,
388 OPC_DDIV_G_2E
= 0x1E | OPC_SPECIAL3
,
389 OPC_DDIVU_G_2E
= 0x1F | OPC_SPECIAL3
,
390 OPC_MOD_G_2E
= 0x22 | OPC_SPECIAL3
,
391 OPC_MODU_G_2E
= 0x23 | OPC_SPECIAL3
,
392 OPC_DMOD_G_2E
= 0x26 | OPC_SPECIAL3
,
393 OPC_DMODU_G_2E
= 0x27 | OPC_SPECIAL3
,
396 OPC_LX_DSP
= 0x0A | OPC_SPECIAL3
,
397 /* MIPS DSP Arithmetic */
398 OPC_ADDU_QB_DSP
= 0x10 | OPC_SPECIAL3
,
399 OPC_ADDU_OB_DSP
= 0x14 | OPC_SPECIAL3
,
400 OPC_ABSQ_S_PH_DSP
= 0x12 | OPC_SPECIAL3
,
401 OPC_ABSQ_S_QH_DSP
= 0x16 | OPC_SPECIAL3
,
402 /* OPC_ADDUH_QB_DSP is same as OPC_MULT_G_2E. */
403 /* OPC_ADDUH_QB_DSP = 0x18 | OPC_SPECIAL3, */
404 OPC_CMPU_EQ_QB_DSP
= 0x11 | OPC_SPECIAL3
,
405 OPC_CMPU_EQ_OB_DSP
= 0x15 | OPC_SPECIAL3
,
406 /* MIPS DSP GPR-Based Shift Sub-class */
407 OPC_SHLL_QB_DSP
= 0x13 | OPC_SPECIAL3
,
408 OPC_SHLL_OB_DSP
= 0x17 | OPC_SPECIAL3
,
409 /* MIPS DSP Multiply Sub-class insns */
410 /* OPC_MUL_PH_DSP is same as OPC_ADDUH_QB_DSP. */
411 /* OPC_MUL_PH_DSP = 0x18 | OPC_SPECIAL3, */
412 OPC_DPA_W_PH_DSP
= 0x30 | OPC_SPECIAL3
,
413 OPC_DPAQ_W_QH_DSP
= 0x34 | OPC_SPECIAL3
,
414 /* DSP Bit/Manipulation Sub-class */
415 OPC_INSV_DSP
= 0x0C | OPC_SPECIAL3
,
416 OPC_DINSV_DSP
= 0x0D | OPC_SPECIAL3
,
417 /* MIPS DSP Append Sub-class */
418 OPC_APPEND_DSP
= 0x31 | OPC_SPECIAL3
,
419 OPC_DAPPEND_DSP
= 0x35 | OPC_SPECIAL3
,
420 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
421 OPC_EXTR_W_DSP
= 0x38 | OPC_SPECIAL3
,
422 OPC_DEXTR_W_DSP
= 0x3C | OPC_SPECIAL3
,
425 OPC_LWLE
= 0x19 | OPC_SPECIAL3
,
426 OPC_LWRE
= 0x1A | OPC_SPECIAL3
,
427 OPC_CACHEE
= 0x1B | OPC_SPECIAL3
,
428 OPC_SBE
= 0x1C | OPC_SPECIAL3
,
429 OPC_SHE
= 0x1D | OPC_SPECIAL3
,
430 OPC_SCE
= 0x1E | OPC_SPECIAL3
,
431 OPC_SWE
= 0x1F | OPC_SPECIAL3
,
432 OPC_SWLE
= 0x21 | OPC_SPECIAL3
,
433 OPC_SWRE
= 0x22 | OPC_SPECIAL3
,
434 OPC_PREFE
= 0x23 | OPC_SPECIAL3
,
435 OPC_LBUE
= 0x28 | OPC_SPECIAL3
,
436 OPC_LHUE
= 0x29 | OPC_SPECIAL3
,
437 OPC_LBE
= 0x2C | OPC_SPECIAL3
,
438 OPC_LHE
= 0x2D | OPC_SPECIAL3
,
439 OPC_LLE
= 0x2E | OPC_SPECIAL3
,
440 OPC_LWE
= 0x2F | OPC_SPECIAL3
,
443 R6_OPC_PREF
= 0x35 | OPC_SPECIAL3
,
444 R6_OPC_CACHE
= 0x25 | OPC_SPECIAL3
,
445 R6_OPC_LL
= 0x36 | OPC_SPECIAL3
,
446 R6_OPC_SC
= 0x26 | OPC_SPECIAL3
,
447 R6_OPC_LLD
= 0x37 | OPC_SPECIAL3
,
448 R6_OPC_SCD
= 0x27 | OPC_SPECIAL3
,
451 /* Loongson EXT load/store quad word opcodes */
452 #define MASK_LOONGSON_GSLSQ(op) (MASK_OP_MAJOR(op) | (op & 0x8020))
454 OPC_GSLQ
= 0x0020 | OPC_LWC2
,
455 OPC_GSLQC1
= 0x8020 | OPC_LWC2
,
456 OPC_GSSHFL
= OPC_LWC2
,
457 OPC_GSSQ
= 0x0020 | OPC_SWC2
,
458 OPC_GSSQC1
= 0x8020 | OPC_SWC2
,
459 OPC_GSSHFS
= OPC_SWC2
,
462 /* Loongson EXT shifted load/store opcodes */
463 #define MASK_LOONGSON_GSSHFLS(op) (MASK_OP_MAJOR(op) | (op & 0xc03f))
465 OPC_GSLWLC1
= 0x4 | OPC_GSSHFL
,
466 OPC_GSLWRC1
= 0x5 | OPC_GSSHFL
,
467 OPC_GSLDLC1
= 0x6 | OPC_GSSHFL
,
468 OPC_GSLDRC1
= 0x7 | OPC_GSSHFL
,
469 OPC_GSSWLC1
= 0x4 | OPC_GSSHFS
,
470 OPC_GSSWRC1
= 0x5 | OPC_GSSHFS
,
471 OPC_GSSDLC1
= 0x6 | OPC_GSSHFS
,
472 OPC_GSSDRC1
= 0x7 | OPC_GSSHFS
,
475 /* Loongson EXT LDC2/SDC2 opcodes */
476 #define MASK_LOONGSON_LSDC2(op) (MASK_OP_MAJOR(op) | (op & 0x7))
479 OPC_GSLBX
= 0x0 | OPC_LDC2
,
480 OPC_GSLHX
= 0x1 | OPC_LDC2
,
481 OPC_GSLWX
= 0x2 | OPC_LDC2
,
482 OPC_GSLDX
= 0x3 | OPC_LDC2
,
483 OPC_GSLWXC1
= 0x6 | OPC_LDC2
,
484 OPC_GSLDXC1
= 0x7 | OPC_LDC2
,
485 OPC_GSSBX
= 0x0 | OPC_SDC2
,
486 OPC_GSSHX
= 0x1 | OPC_SDC2
,
487 OPC_GSSWX
= 0x2 | OPC_SDC2
,
488 OPC_GSSDX
= 0x3 | OPC_SDC2
,
489 OPC_GSSWXC1
= 0x6 | OPC_SDC2
,
490 OPC_GSSDXC1
= 0x7 | OPC_SDC2
,
494 #define MASK_BSHFL(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
497 OPC_WSBH
= (0x02 << 6) | OPC_BSHFL
,
498 OPC_SEB
= (0x10 << 6) | OPC_BSHFL
,
499 OPC_SEH
= (0x18 << 6) | OPC_BSHFL
,
500 OPC_ALIGN
= (0x08 << 6) | OPC_BSHFL
, /* 010.bp (010.00 to 010.11) */
501 OPC_ALIGN_1
= (0x09 << 6) | OPC_BSHFL
,
502 OPC_ALIGN_2
= (0x0A << 6) | OPC_BSHFL
,
503 OPC_ALIGN_3
= (0x0B << 6) | OPC_BSHFL
,
504 OPC_BITSWAP
= (0x00 << 6) | OPC_BSHFL
/* 00000 */
508 #define MASK_DBSHFL(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
511 OPC_DSBH
= (0x02 << 6) | OPC_DBSHFL
,
512 OPC_DSHD
= (0x05 << 6) | OPC_DBSHFL
,
513 OPC_DALIGN
= (0x08 << 6) | OPC_DBSHFL
, /* 01.bp (01.000 to 01.111) */
514 OPC_DALIGN_1
= (0x09 << 6) | OPC_DBSHFL
,
515 OPC_DALIGN_2
= (0x0A << 6) | OPC_DBSHFL
,
516 OPC_DALIGN_3
= (0x0B << 6) | OPC_DBSHFL
,
517 OPC_DALIGN_4
= (0x0C << 6) | OPC_DBSHFL
,
518 OPC_DALIGN_5
= (0x0D << 6) | OPC_DBSHFL
,
519 OPC_DALIGN_6
= (0x0E << 6) | OPC_DBSHFL
,
520 OPC_DALIGN_7
= (0x0F << 6) | OPC_DBSHFL
,
521 OPC_DBITSWAP
= (0x00 << 6) | OPC_DBSHFL
, /* 00000 */
524 /* MIPS DSP REGIMM opcodes */
526 OPC_BPOSGE32
= (0x1C << 16) | OPC_REGIMM
,
527 OPC_BPOSGE64
= (0x1D << 16) | OPC_REGIMM
,
530 #define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
533 OPC_LBUX
= (0x06 << 6) | OPC_LX_DSP
,
534 OPC_LHX
= (0x04 << 6) | OPC_LX_DSP
,
535 OPC_LWX
= (0x00 << 6) | OPC_LX_DSP
,
536 OPC_LDX
= (0x08 << 6) | OPC_LX_DSP
,
539 #define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
541 /* MIPS DSP Arithmetic Sub-class */
542 OPC_ADDQ_PH
= (0x0A << 6) | OPC_ADDU_QB_DSP
,
543 OPC_ADDQ_S_PH
= (0x0E << 6) | OPC_ADDU_QB_DSP
,
544 OPC_ADDQ_S_W
= (0x16 << 6) | OPC_ADDU_QB_DSP
,
545 OPC_ADDU_QB
= (0x00 << 6) | OPC_ADDU_QB_DSP
,
546 OPC_ADDU_S_QB
= (0x04 << 6) | OPC_ADDU_QB_DSP
,
547 OPC_ADDU_PH
= (0x08 << 6) | OPC_ADDU_QB_DSP
,
548 OPC_ADDU_S_PH
= (0x0C << 6) | OPC_ADDU_QB_DSP
,
549 OPC_SUBQ_PH
= (0x0B << 6) | OPC_ADDU_QB_DSP
,
550 OPC_SUBQ_S_PH
= (0x0F << 6) | OPC_ADDU_QB_DSP
,
551 OPC_SUBQ_S_W
= (0x17 << 6) | OPC_ADDU_QB_DSP
,
552 OPC_SUBU_QB
= (0x01 << 6) | OPC_ADDU_QB_DSP
,
553 OPC_SUBU_S_QB
= (0x05 << 6) | OPC_ADDU_QB_DSP
,
554 OPC_SUBU_PH
= (0x09 << 6) | OPC_ADDU_QB_DSP
,
555 OPC_SUBU_S_PH
= (0x0D << 6) | OPC_ADDU_QB_DSP
,
556 OPC_ADDSC
= (0x10 << 6) | OPC_ADDU_QB_DSP
,
557 OPC_ADDWC
= (0x11 << 6) | OPC_ADDU_QB_DSP
,
558 OPC_MODSUB
= (0x12 << 6) | OPC_ADDU_QB_DSP
,
559 OPC_RADDU_W_QB
= (0x14 << 6) | OPC_ADDU_QB_DSP
,
560 /* MIPS DSP Multiply Sub-class insns */
561 OPC_MULEU_S_PH_QBL
= (0x06 << 6) | OPC_ADDU_QB_DSP
,
562 OPC_MULEU_S_PH_QBR
= (0x07 << 6) | OPC_ADDU_QB_DSP
,
563 OPC_MULQ_RS_PH
= (0x1F << 6) | OPC_ADDU_QB_DSP
,
564 OPC_MULEQ_S_W_PHL
= (0x1C << 6) | OPC_ADDU_QB_DSP
,
565 OPC_MULEQ_S_W_PHR
= (0x1D << 6) | OPC_ADDU_QB_DSP
,
566 OPC_MULQ_S_PH
= (0x1E << 6) | OPC_ADDU_QB_DSP
,
569 #define OPC_ADDUH_QB_DSP OPC_MULT_G_2E
570 #define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
572 /* MIPS DSP Arithmetic Sub-class */
573 OPC_ADDUH_QB
= (0x00 << 6) | OPC_ADDUH_QB_DSP
,
574 OPC_ADDUH_R_QB
= (0x02 << 6) | OPC_ADDUH_QB_DSP
,
575 OPC_ADDQH_PH
= (0x08 << 6) | OPC_ADDUH_QB_DSP
,
576 OPC_ADDQH_R_PH
= (0x0A << 6) | OPC_ADDUH_QB_DSP
,
577 OPC_ADDQH_W
= (0x10 << 6) | OPC_ADDUH_QB_DSP
,
578 OPC_ADDQH_R_W
= (0x12 << 6) | OPC_ADDUH_QB_DSP
,
579 OPC_SUBUH_QB
= (0x01 << 6) | OPC_ADDUH_QB_DSP
,
580 OPC_SUBUH_R_QB
= (0x03 << 6) | OPC_ADDUH_QB_DSP
,
581 OPC_SUBQH_PH
= (0x09 << 6) | OPC_ADDUH_QB_DSP
,
582 OPC_SUBQH_R_PH
= (0x0B << 6) | OPC_ADDUH_QB_DSP
,
583 OPC_SUBQH_W
= (0x11 << 6) | OPC_ADDUH_QB_DSP
,
584 OPC_SUBQH_R_W
= (0x13 << 6) | OPC_ADDUH_QB_DSP
,
585 /* MIPS DSP Multiply Sub-class insns */
586 OPC_MUL_PH
= (0x0C << 6) | OPC_ADDUH_QB_DSP
,
587 OPC_MUL_S_PH
= (0x0E << 6) | OPC_ADDUH_QB_DSP
,
588 OPC_MULQ_S_W
= (0x16 << 6) | OPC_ADDUH_QB_DSP
,
589 OPC_MULQ_RS_W
= (0x17 << 6) | OPC_ADDUH_QB_DSP
,
592 #define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
594 /* MIPS DSP Arithmetic Sub-class */
595 OPC_ABSQ_S_QB
= (0x01 << 6) | OPC_ABSQ_S_PH_DSP
,
596 OPC_ABSQ_S_PH
= (0x09 << 6) | OPC_ABSQ_S_PH_DSP
,
597 OPC_ABSQ_S_W
= (0x11 << 6) | OPC_ABSQ_S_PH_DSP
,
598 OPC_PRECEQ_W_PHL
= (0x0C << 6) | OPC_ABSQ_S_PH_DSP
,
599 OPC_PRECEQ_W_PHR
= (0x0D << 6) | OPC_ABSQ_S_PH_DSP
,
600 OPC_PRECEQU_PH_QBL
= (0x04 << 6) | OPC_ABSQ_S_PH_DSP
,
601 OPC_PRECEQU_PH_QBR
= (0x05 << 6) | OPC_ABSQ_S_PH_DSP
,
602 OPC_PRECEQU_PH_QBLA
= (0x06 << 6) | OPC_ABSQ_S_PH_DSP
,
603 OPC_PRECEQU_PH_QBRA
= (0x07 << 6) | OPC_ABSQ_S_PH_DSP
,
604 OPC_PRECEU_PH_QBL
= (0x1C << 6) | OPC_ABSQ_S_PH_DSP
,
605 OPC_PRECEU_PH_QBR
= (0x1D << 6) | OPC_ABSQ_S_PH_DSP
,
606 OPC_PRECEU_PH_QBLA
= (0x1E << 6) | OPC_ABSQ_S_PH_DSP
,
607 OPC_PRECEU_PH_QBRA
= (0x1F << 6) | OPC_ABSQ_S_PH_DSP
,
608 /* DSP Bit/Manipulation Sub-class */
609 OPC_BITREV
= (0x1B << 6) | OPC_ABSQ_S_PH_DSP
,
610 OPC_REPL_QB
= (0x02 << 6) | OPC_ABSQ_S_PH_DSP
,
611 OPC_REPLV_QB
= (0x03 << 6) | OPC_ABSQ_S_PH_DSP
,
612 OPC_REPL_PH
= (0x0A << 6) | OPC_ABSQ_S_PH_DSP
,
613 OPC_REPLV_PH
= (0x0B << 6) | OPC_ABSQ_S_PH_DSP
,
616 #define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
618 /* MIPS DSP Arithmetic Sub-class */
619 OPC_PRECR_QB_PH
= (0x0D << 6) | OPC_CMPU_EQ_QB_DSP
,
620 OPC_PRECRQ_QB_PH
= (0x0C << 6) | OPC_CMPU_EQ_QB_DSP
,
621 OPC_PRECR_SRA_PH_W
= (0x1E << 6) | OPC_CMPU_EQ_QB_DSP
,
622 OPC_PRECR_SRA_R_PH_W
= (0x1F << 6) | OPC_CMPU_EQ_QB_DSP
,
623 OPC_PRECRQ_PH_W
= (0x14 << 6) | OPC_CMPU_EQ_QB_DSP
,
624 OPC_PRECRQ_RS_PH_W
= (0x15 << 6) | OPC_CMPU_EQ_QB_DSP
,
625 OPC_PRECRQU_S_QB_PH
= (0x0F << 6) | OPC_CMPU_EQ_QB_DSP
,
626 /* DSP Compare-Pick Sub-class */
627 OPC_CMPU_EQ_QB
= (0x00 << 6) | OPC_CMPU_EQ_QB_DSP
,
628 OPC_CMPU_LT_QB
= (0x01 << 6) | OPC_CMPU_EQ_QB_DSP
,
629 OPC_CMPU_LE_QB
= (0x02 << 6) | OPC_CMPU_EQ_QB_DSP
,
630 OPC_CMPGU_EQ_QB
= (0x04 << 6) | OPC_CMPU_EQ_QB_DSP
,
631 OPC_CMPGU_LT_QB
= (0x05 << 6) | OPC_CMPU_EQ_QB_DSP
,
632 OPC_CMPGU_LE_QB
= (0x06 << 6) | OPC_CMPU_EQ_QB_DSP
,
633 OPC_CMPGDU_EQ_QB
= (0x18 << 6) | OPC_CMPU_EQ_QB_DSP
,
634 OPC_CMPGDU_LT_QB
= (0x19 << 6) | OPC_CMPU_EQ_QB_DSP
,
635 OPC_CMPGDU_LE_QB
= (0x1A << 6) | OPC_CMPU_EQ_QB_DSP
,
636 OPC_CMP_EQ_PH
= (0x08 << 6) | OPC_CMPU_EQ_QB_DSP
,
637 OPC_CMP_LT_PH
= (0x09 << 6) | OPC_CMPU_EQ_QB_DSP
,
638 OPC_CMP_LE_PH
= (0x0A << 6) | OPC_CMPU_EQ_QB_DSP
,
639 OPC_PICK_QB
= (0x03 << 6) | OPC_CMPU_EQ_QB_DSP
,
640 OPC_PICK_PH
= (0x0B << 6) | OPC_CMPU_EQ_QB_DSP
,
641 OPC_PACKRL_PH
= (0x0E << 6) | OPC_CMPU_EQ_QB_DSP
,
644 #define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
646 /* MIPS DSP GPR-Based Shift Sub-class */
647 OPC_SHLL_QB
= (0x00 << 6) | OPC_SHLL_QB_DSP
,
648 OPC_SHLLV_QB
= (0x02 << 6) | OPC_SHLL_QB_DSP
,
649 OPC_SHLL_PH
= (0x08 << 6) | OPC_SHLL_QB_DSP
,
650 OPC_SHLLV_PH
= (0x0A << 6) | OPC_SHLL_QB_DSP
,
651 OPC_SHLL_S_PH
= (0x0C << 6) | OPC_SHLL_QB_DSP
,
652 OPC_SHLLV_S_PH
= (0x0E << 6) | OPC_SHLL_QB_DSP
,
653 OPC_SHLL_S_W
= (0x14 << 6) | OPC_SHLL_QB_DSP
,
654 OPC_SHLLV_S_W
= (0x16 << 6) | OPC_SHLL_QB_DSP
,
655 OPC_SHRL_QB
= (0x01 << 6) | OPC_SHLL_QB_DSP
,
656 OPC_SHRLV_QB
= (0x03 << 6) | OPC_SHLL_QB_DSP
,
657 OPC_SHRL_PH
= (0x19 << 6) | OPC_SHLL_QB_DSP
,
658 OPC_SHRLV_PH
= (0x1B << 6) | OPC_SHLL_QB_DSP
,
659 OPC_SHRA_QB
= (0x04 << 6) | OPC_SHLL_QB_DSP
,
660 OPC_SHRA_R_QB
= (0x05 << 6) | OPC_SHLL_QB_DSP
,
661 OPC_SHRAV_QB
= (0x06 << 6) | OPC_SHLL_QB_DSP
,
662 OPC_SHRAV_R_QB
= (0x07 << 6) | OPC_SHLL_QB_DSP
,
663 OPC_SHRA_PH
= (0x09 << 6) | OPC_SHLL_QB_DSP
,
664 OPC_SHRAV_PH
= (0x0B << 6) | OPC_SHLL_QB_DSP
,
665 OPC_SHRA_R_PH
= (0x0D << 6) | OPC_SHLL_QB_DSP
,
666 OPC_SHRAV_R_PH
= (0x0F << 6) | OPC_SHLL_QB_DSP
,
667 OPC_SHRA_R_W
= (0x15 << 6) | OPC_SHLL_QB_DSP
,
668 OPC_SHRAV_R_W
= (0x17 << 6) | OPC_SHLL_QB_DSP
,
671 #define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
673 /* MIPS DSP Multiply Sub-class insns */
674 OPC_DPAU_H_QBL
= (0x03 << 6) | OPC_DPA_W_PH_DSP
,
675 OPC_DPAU_H_QBR
= (0x07 << 6) | OPC_DPA_W_PH_DSP
,
676 OPC_DPSU_H_QBL
= (0x0B << 6) | OPC_DPA_W_PH_DSP
,
677 OPC_DPSU_H_QBR
= (0x0F << 6) | OPC_DPA_W_PH_DSP
,
678 OPC_DPA_W_PH
= (0x00 << 6) | OPC_DPA_W_PH_DSP
,
679 OPC_DPAX_W_PH
= (0x08 << 6) | OPC_DPA_W_PH_DSP
,
680 OPC_DPAQ_S_W_PH
= (0x04 << 6) | OPC_DPA_W_PH_DSP
,
681 OPC_DPAQX_S_W_PH
= (0x18 << 6) | OPC_DPA_W_PH_DSP
,
682 OPC_DPAQX_SA_W_PH
= (0x1A << 6) | OPC_DPA_W_PH_DSP
,
683 OPC_DPS_W_PH
= (0x01 << 6) | OPC_DPA_W_PH_DSP
,
684 OPC_DPSX_W_PH
= (0x09 << 6) | OPC_DPA_W_PH_DSP
,
685 OPC_DPSQ_S_W_PH
= (0x05 << 6) | OPC_DPA_W_PH_DSP
,
686 OPC_DPSQX_S_W_PH
= (0x19 << 6) | OPC_DPA_W_PH_DSP
,
687 OPC_DPSQX_SA_W_PH
= (0x1B << 6) | OPC_DPA_W_PH_DSP
,
688 OPC_MULSAQ_S_W_PH
= (0x06 << 6) | OPC_DPA_W_PH_DSP
,
689 OPC_DPAQ_SA_L_W
= (0x0C << 6) | OPC_DPA_W_PH_DSP
,
690 OPC_DPSQ_SA_L_W
= (0x0D << 6) | OPC_DPA_W_PH_DSP
,
691 OPC_MAQ_S_W_PHL
= (0x14 << 6) | OPC_DPA_W_PH_DSP
,
692 OPC_MAQ_S_W_PHR
= (0x16 << 6) | OPC_DPA_W_PH_DSP
,
693 OPC_MAQ_SA_W_PHL
= (0x10 << 6) | OPC_DPA_W_PH_DSP
,
694 OPC_MAQ_SA_W_PHR
= (0x12 << 6) | OPC_DPA_W_PH_DSP
,
695 OPC_MULSA_W_PH
= (0x02 << 6) | OPC_DPA_W_PH_DSP
,
698 #define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
700 /* DSP Bit/Manipulation Sub-class */
701 OPC_INSV
= (0x00 << 6) | OPC_INSV_DSP
,
704 #define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
706 /* MIPS DSP Append Sub-class */
707 OPC_APPEND
= (0x00 << 6) | OPC_APPEND_DSP
,
708 OPC_PREPEND
= (0x01 << 6) | OPC_APPEND_DSP
,
709 OPC_BALIGN
= (0x10 << 6) | OPC_APPEND_DSP
,
712 #define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
714 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
715 OPC_EXTR_W
= (0x00 << 6) | OPC_EXTR_W_DSP
,
716 OPC_EXTR_R_W
= (0x04 << 6) | OPC_EXTR_W_DSP
,
717 OPC_EXTR_RS_W
= (0x06 << 6) | OPC_EXTR_W_DSP
,
718 OPC_EXTR_S_H
= (0x0E << 6) | OPC_EXTR_W_DSP
,
719 OPC_EXTRV_S_H
= (0x0F << 6) | OPC_EXTR_W_DSP
,
720 OPC_EXTRV_W
= (0x01 << 6) | OPC_EXTR_W_DSP
,
721 OPC_EXTRV_R_W
= (0x05 << 6) | OPC_EXTR_W_DSP
,
722 OPC_EXTRV_RS_W
= (0x07 << 6) | OPC_EXTR_W_DSP
,
723 OPC_EXTP
= (0x02 << 6) | OPC_EXTR_W_DSP
,
724 OPC_EXTPV
= (0x03 << 6) | OPC_EXTR_W_DSP
,
725 OPC_EXTPDP
= (0x0A << 6) | OPC_EXTR_W_DSP
,
726 OPC_EXTPDPV
= (0x0B << 6) | OPC_EXTR_W_DSP
,
727 OPC_SHILO
= (0x1A << 6) | OPC_EXTR_W_DSP
,
728 OPC_SHILOV
= (0x1B << 6) | OPC_EXTR_W_DSP
,
729 OPC_MTHLIP
= (0x1F << 6) | OPC_EXTR_W_DSP
,
730 OPC_WRDSP
= (0x13 << 6) | OPC_EXTR_W_DSP
,
731 OPC_RDDSP
= (0x12 << 6) | OPC_EXTR_W_DSP
,
734 #define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
736 /* MIPS DSP Arithmetic Sub-class */
737 OPC_PRECEQ_L_PWL
= (0x14 << 6) | OPC_ABSQ_S_QH_DSP
,
738 OPC_PRECEQ_L_PWR
= (0x15 << 6) | OPC_ABSQ_S_QH_DSP
,
739 OPC_PRECEQ_PW_QHL
= (0x0C << 6) | OPC_ABSQ_S_QH_DSP
,
740 OPC_PRECEQ_PW_QHR
= (0x0D << 6) | OPC_ABSQ_S_QH_DSP
,
741 OPC_PRECEQ_PW_QHLA
= (0x0E << 6) | OPC_ABSQ_S_QH_DSP
,
742 OPC_PRECEQ_PW_QHRA
= (0x0F << 6) | OPC_ABSQ_S_QH_DSP
,
743 OPC_PRECEQU_QH_OBL
= (0x04 << 6) | OPC_ABSQ_S_QH_DSP
,
744 OPC_PRECEQU_QH_OBR
= (0x05 << 6) | OPC_ABSQ_S_QH_DSP
,
745 OPC_PRECEQU_QH_OBLA
= (0x06 << 6) | OPC_ABSQ_S_QH_DSP
,
746 OPC_PRECEQU_QH_OBRA
= (0x07 << 6) | OPC_ABSQ_S_QH_DSP
,
747 OPC_PRECEU_QH_OBL
= (0x1C << 6) | OPC_ABSQ_S_QH_DSP
,
748 OPC_PRECEU_QH_OBR
= (0x1D << 6) | OPC_ABSQ_S_QH_DSP
,
749 OPC_PRECEU_QH_OBLA
= (0x1E << 6) | OPC_ABSQ_S_QH_DSP
,
750 OPC_PRECEU_QH_OBRA
= (0x1F << 6) | OPC_ABSQ_S_QH_DSP
,
751 OPC_ABSQ_S_OB
= (0x01 << 6) | OPC_ABSQ_S_QH_DSP
,
752 OPC_ABSQ_S_PW
= (0x11 << 6) | OPC_ABSQ_S_QH_DSP
,
753 OPC_ABSQ_S_QH
= (0x09 << 6) | OPC_ABSQ_S_QH_DSP
,
754 /* DSP Bit/Manipulation Sub-class */
755 OPC_REPL_OB
= (0x02 << 6) | OPC_ABSQ_S_QH_DSP
,
756 OPC_REPL_PW
= (0x12 << 6) | OPC_ABSQ_S_QH_DSP
,
757 OPC_REPL_QH
= (0x0A << 6) | OPC_ABSQ_S_QH_DSP
,
758 OPC_REPLV_OB
= (0x03 << 6) | OPC_ABSQ_S_QH_DSP
,
759 OPC_REPLV_PW
= (0x13 << 6) | OPC_ABSQ_S_QH_DSP
,
760 OPC_REPLV_QH
= (0x0B << 6) | OPC_ABSQ_S_QH_DSP
,
763 #define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
765 /* MIPS DSP Multiply Sub-class insns */
766 OPC_MULEQ_S_PW_QHL
= (0x1C << 6) | OPC_ADDU_OB_DSP
,
767 OPC_MULEQ_S_PW_QHR
= (0x1D << 6) | OPC_ADDU_OB_DSP
,
768 OPC_MULEU_S_QH_OBL
= (0x06 << 6) | OPC_ADDU_OB_DSP
,
769 OPC_MULEU_S_QH_OBR
= (0x07 << 6) | OPC_ADDU_OB_DSP
,
770 OPC_MULQ_RS_QH
= (0x1F << 6) | OPC_ADDU_OB_DSP
,
771 /* MIPS DSP Arithmetic Sub-class */
772 OPC_RADDU_L_OB
= (0x14 << 6) | OPC_ADDU_OB_DSP
,
773 OPC_SUBQ_PW
= (0x13 << 6) | OPC_ADDU_OB_DSP
,
774 OPC_SUBQ_S_PW
= (0x17 << 6) | OPC_ADDU_OB_DSP
,
775 OPC_SUBQ_QH
= (0x0B << 6) | OPC_ADDU_OB_DSP
,
776 OPC_SUBQ_S_QH
= (0x0F << 6) | OPC_ADDU_OB_DSP
,
777 OPC_SUBU_OB
= (0x01 << 6) | OPC_ADDU_OB_DSP
,
778 OPC_SUBU_S_OB
= (0x05 << 6) | OPC_ADDU_OB_DSP
,
779 OPC_SUBU_QH
= (0x09 << 6) | OPC_ADDU_OB_DSP
,
780 OPC_SUBU_S_QH
= (0x0D << 6) | OPC_ADDU_OB_DSP
,
781 OPC_SUBUH_OB
= (0x19 << 6) | OPC_ADDU_OB_DSP
,
782 OPC_SUBUH_R_OB
= (0x1B << 6) | OPC_ADDU_OB_DSP
,
783 OPC_ADDQ_PW
= (0x12 << 6) | OPC_ADDU_OB_DSP
,
784 OPC_ADDQ_S_PW
= (0x16 << 6) | OPC_ADDU_OB_DSP
,
785 OPC_ADDQ_QH
= (0x0A << 6) | OPC_ADDU_OB_DSP
,
786 OPC_ADDQ_S_QH
= (0x0E << 6) | OPC_ADDU_OB_DSP
,
787 OPC_ADDU_OB
= (0x00 << 6) | OPC_ADDU_OB_DSP
,
788 OPC_ADDU_S_OB
= (0x04 << 6) | OPC_ADDU_OB_DSP
,
789 OPC_ADDU_QH
= (0x08 << 6) | OPC_ADDU_OB_DSP
,
790 OPC_ADDU_S_QH
= (0x0C << 6) | OPC_ADDU_OB_DSP
,
791 OPC_ADDUH_OB
= (0x18 << 6) | OPC_ADDU_OB_DSP
,
792 OPC_ADDUH_R_OB
= (0x1A << 6) | OPC_ADDU_OB_DSP
,
795 #define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
797 /* DSP Compare-Pick Sub-class */
798 OPC_CMP_EQ_PW
= (0x10 << 6) | OPC_CMPU_EQ_OB_DSP
,
799 OPC_CMP_LT_PW
= (0x11 << 6) | OPC_CMPU_EQ_OB_DSP
,
800 OPC_CMP_LE_PW
= (0x12 << 6) | OPC_CMPU_EQ_OB_DSP
,
801 OPC_CMP_EQ_QH
= (0x08 << 6) | OPC_CMPU_EQ_OB_DSP
,
802 OPC_CMP_LT_QH
= (0x09 << 6) | OPC_CMPU_EQ_OB_DSP
,
803 OPC_CMP_LE_QH
= (0x0A << 6) | OPC_CMPU_EQ_OB_DSP
,
804 OPC_CMPGDU_EQ_OB
= (0x18 << 6) | OPC_CMPU_EQ_OB_DSP
,
805 OPC_CMPGDU_LT_OB
= (0x19 << 6) | OPC_CMPU_EQ_OB_DSP
,
806 OPC_CMPGDU_LE_OB
= (0x1A << 6) | OPC_CMPU_EQ_OB_DSP
,
807 OPC_CMPGU_EQ_OB
= (0x04 << 6) | OPC_CMPU_EQ_OB_DSP
,
808 OPC_CMPGU_LT_OB
= (0x05 << 6) | OPC_CMPU_EQ_OB_DSP
,
809 OPC_CMPGU_LE_OB
= (0x06 << 6) | OPC_CMPU_EQ_OB_DSP
,
810 OPC_CMPU_EQ_OB
= (0x00 << 6) | OPC_CMPU_EQ_OB_DSP
,
811 OPC_CMPU_LT_OB
= (0x01 << 6) | OPC_CMPU_EQ_OB_DSP
,
812 OPC_CMPU_LE_OB
= (0x02 << 6) | OPC_CMPU_EQ_OB_DSP
,
813 OPC_PACKRL_PW
= (0x0E << 6) | OPC_CMPU_EQ_OB_DSP
,
814 OPC_PICK_OB
= (0x03 << 6) | OPC_CMPU_EQ_OB_DSP
,
815 OPC_PICK_PW
= (0x13 << 6) | OPC_CMPU_EQ_OB_DSP
,
816 OPC_PICK_QH
= (0x0B << 6) | OPC_CMPU_EQ_OB_DSP
,
817 /* MIPS DSP Arithmetic Sub-class */
818 OPC_PRECR_OB_QH
= (0x0D << 6) | OPC_CMPU_EQ_OB_DSP
,
819 OPC_PRECR_SRA_QH_PW
= (0x1E << 6) | OPC_CMPU_EQ_OB_DSP
,
820 OPC_PRECR_SRA_R_QH_PW
= (0x1F << 6) | OPC_CMPU_EQ_OB_DSP
,
821 OPC_PRECRQ_OB_QH
= (0x0C << 6) | OPC_CMPU_EQ_OB_DSP
,
822 OPC_PRECRQ_PW_L
= (0x1C << 6) | OPC_CMPU_EQ_OB_DSP
,
823 OPC_PRECRQ_QH_PW
= (0x14 << 6) | OPC_CMPU_EQ_OB_DSP
,
824 OPC_PRECRQ_RS_QH_PW
= (0x15 << 6) | OPC_CMPU_EQ_OB_DSP
,
825 OPC_PRECRQU_S_OB_QH
= (0x0F << 6) | OPC_CMPU_EQ_OB_DSP
,
828 #define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
830 /* DSP Append Sub-class */
831 OPC_DAPPEND
= (0x00 << 6) | OPC_DAPPEND_DSP
,
832 OPC_PREPENDD
= (0x03 << 6) | OPC_DAPPEND_DSP
,
833 OPC_PREPENDW
= (0x01 << 6) | OPC_DAPPEND_DSP
,
834 OPC_DBALIGN
= (0x10 << 6) | OPC_DAPPEND_DSP
,
837 #define MASK_DEXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
839 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
840 OPC_DMTHLIP
= (0x1F << 6) | OPC_DEXTR_W_DSP
,
841 OPC_DSHILO
= (0x1A << 6) | OPC_DEXTR_W_DSP
,
842 OPC_DEXTP
= (0x02 << 6) | OPC_DEXTR_W_DSP
,
843 OPC_DEXTPDP
= (0x0A << 6) | OPC_DEXTR_W_DSP
,
844 OPC_DEXTPDPV
= (0x0B << 6) | OPC_DEXTR_W_DSP
,
845 OPC_DEXTPV
= (0x03 << 6) | OPC_DEXTR_W_DSP
,
846 OPC_DEXTR_L
= (0x10 << 6) | OPC_DEXTR_W_DSP
,
847 OPC_DEXTR_R_L
= (0x14 << 6) | OPC_DEXTR_W_DSP
,
848 OPC_DEXTR_RS_L
= (0x16 << 6) | OPC_DEXTR_W_DSP
,
849 OPC_DEXTR_W
= (0x00 << 6) | OPC_DEXTR_W_DSP
,
850 OPC_DEXTR_R_W
= (0x04 << 6) | OPC_DEXTR_W_DSP
,
851 OPC_DEXTR_RS_W
= (0x06 << 6) | OPC_DEXTR_W_DSP
,
852 OPC_DEXTR_S_H
= (0x0E << 6) | OPC_DEXTR_W_DSP
,
853 OPC_DEXTRV_L
= (0x11 << 6) | OPC_DEXTR_W_DSP
,
854 OPC_DEXTRV_R_L
= (0x15 << 6) | OPC_DEXTR_W_DSP
,
855 OPC_DEXTRV_RS_L
= (0x17 << 6) | OPC_DEXTR_W_DSP
,
856 OPC_DEXTRV_S_H
= (0x0F << 6) | OPC_DEXTR_W_DSP
,
857 OPC_DEXTRV_W
= (0x01 << 6) | OPC_DEXTR_W_DSP
,
858 OPC_DEXTRV_R_W
= (0x05 << 6) | OPC_DEXTR_W_DSP
,
859 OPC_DEXTRV_RS_W
= (0x07 << 6) | OPC_DEXTR_W_DSP
,
860 OPC_DSHILOV
= (0x1B << 6) | OPC_DEXTR_W_DSP
,
863 #define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
865 /* DSP Bit/Manipulation Sub-class */
866 OPC_DINSV
= (0x00 << 6) | OPC_DINSV_DSP
,
869 #define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
871 /* MIPS DSP Multiply Sub-class insns */
872 OPC_DMADD
= (0x19 << 6) | OPC_DPAQ_W_QH_DSP
,
873 OPC_DMADDU
= (0x1D << 6) | OPC_DPAQ_W_QH_DSP
,
874 OPC_DMSUB
= (0x1B << 6) | OPC_DPAQ_W_QH_DSP
,
875 OPC_DMSUBU
= (0x1F << 6) | OPC_DPAQ_W_QH_DSP
,
876 OPC_DPA_W_QH
= (0x00 << 6) | OPC_DPAQ_W_QH_DSP
,
877 OPC_DPAQ_S_W_QH
= (0x04 << 6) | OPC_DPAQ_W_QH_DSP
,
878 OPC_DPAQ_SA_L_PW
= (0x0C << 6) | OPC_DPAQ_W_QH_DSP
,
879 OPC_DPAU_H_OBL
= (0x03 << 6) | OPC_DPAQ_W_QH_DSP
,
880 OPC_DPAU_H_OBR
= (0x07 << 6) | OPC_DPAQ_W_QH_DSP
,
881 OPC_DPS_W_QH
= (0x01 << 6) | OPC_DPAQ_W_QH_DSP
,
882 OPC_DPSQ_S_W_QH
= (0x05 << 6) | OPC_DPAQ_W_QH_DSP
,
883 OPC_DPSQ_SA_L_PW
= (0x0D << 6) | OPC_DPAQ_W_QH_DSP
,
884 OPC_DPSU_H_OBL
= (0x0B << 6) | OPC_DPAQ_W_QH_DSP
,
885 OPC_DPSU_H_OBR
= (0x0F << 6) | OPC_DPAQ_W_QH_DSP
,
886 OPC_MAQ_S_L_PWL
= (0x1C << 6) | OPC_DPAQ_W_QH_DSP
,
887 OPC_MAQ_S_L_PWR
= (0x1E << 6) | OPC_DPAQ_W_QH_DSP
,
888 OPC_MAQ_S_W_QHLL
= (0x14 << 6) | OPC_DPAQ_W_QH_DSP
,
889 OPC_MAQ_SA_W_QHLL
= (0x10 << 6) | OPC_DPAQ_W_QH_DSP
,
890 OPC_MAQ_S_W_QHLR
= (0x15 << 6) | OPC_DPAQ_W_QH_DSP
,
891 OPC_MAQ_SA_W_QHLR
= (0x11 << 6) | OPC_DPAQ_W_QH_DSP
,
892 OPC_MAQ_S_W_QHRL
= (0x16 << 6) | OPC_DPAQ_W_QH_DSP
,
893 OPC_MAQ_SA_W_QHRL
= (0x12 << 6) | OPC_DPAQ_W_QH_DSP
,
894 OPC_MAQ_S_W_QHRR
= (0x17 << 6) | OPC_DPAQ_W_QH_DSP
,
895 OPC_MAQ_SA_W_QHRR
= (0x13 << 6) | OPC_DPAQ_W_QH_DSP
,
896 OPC_MULSAQ_S_L_PW
= (0x0E << 6) | OPC_DPAQ_W_QH_DSP
,
897 OPC_MULSAQ_S_W_QH
= (0x06 << 6) | OPC_DPAQ_W_QH_DSP
,
900 #define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
902 /* MIPS DSP GPR-Based Shift Sub-class */
903 OPC_SHLL_PW
= (0x10 << 6) | OPC_SHLL_OB_DSP
,
904 OPC_SHLL_S_PW
= (0x14 << 6) | OPC_SHLL_OB_DSP
,
905 OPC_SHLLV_OB
= (0x02 << 6) | OPC_SHLL_OB_DSP
,
906 OPC_SHLLV_PW
= (0x12 << 6) | OPC_SHLL_OB_DSP
,
907 OPC_SHLLV_S_PW
= (0x16 << 6) | OPC_SHLL_OB_DSP
,
908 OPC_SHLLV_QH
= (0x0A << 6) | OPC_SHLL_OB_DSP
,
909 OPC_SHLLV_S_QH
= (0x0E << 6) | OPC_SHLL_OB_DSP
,
910 OPC_SHRA_PW
= (0x11 << 6) | OPC_SHLL_OB_DSP
,
911 OPC_SHRA_R_PW
= (0x15 << 6) | OPC_SHLL_OB_DSP
,
912 OPC_SHRAV_OB
= (0x06 << 6) | OPC_SHLL_OB_DSP
,
913 OPC_SHRAV_R_OB
= (0x07 << 6) | OPC_SHLL_OB_DSP
,
914 OPC_SHRAV_PW
= (0x13 << 6) | OPC_SHLL_OB_DSP
,
915 OPC_SHRAV_R_PW
= (0x17 << 6) | OPC_SHLL_OB_DSP
,
916 OPC_SHRAV_QH
= (0x0B << 6) | OPC_SHLL_OB_DSP
,
917 OPC_SHRAV_R_QH
= (0x0F << 6) | OPC_SHLL_OB_DSP
,
918 OPC_SHRLV_OB
= (0x03 << 6) | OPC_SHLL_OB_DSP
,
919 OPC_SHRLV_QH
= (0x1B << 6) | OPC_SHLL_OB_DSP
,
920 OPC_SHLL_OB
= (0x00 << 6) | OPC_SHLL_OB_DSP
,
921 OPC_SHLL_QH
= (0x08 << 6) | OPC_SHLL_OB_DSP
,
922 OPC_SHLL_S_QH
= (0x0C << 6) | OPC_SHLL_OB_DSP
,
923 OPC_SHRA_OB
= (0x04 << 6) | OPC_SHLL_OB_DSP
,
924 OPC_SHRA_R_OB
= (0x05 << 6) | OPC_SHLL_OB_DSP
,
925 OPC_SHRA_QH
= (0x09 << 6) | OPC_SHLL_OB_DSP
,
926 OPC_SHRA_R_QH
= (0x0D << 6) | OPC_SHLL_OB_DSP
,
927 OPC_SHRL_OB
= (0x01 << 6) | OPC_SHLL_OB_DSP
,
928 OPC_SHRL_QH
= (0x19 << 6) | OPC_SHLL_OB_DSP
,
931 /* Coprocessor 0 (rs field) */
932 #define MASK_CP0(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)))
935 OPC_MFC0
= (0x00 << 21) | OPC_CP0
,
936 OPC_DMFC0
= (0x01 << 21) | OPC_CP0
,
937 OPC_MFHC0
= (0x02 << 21) | OPC_CP0
,
938 OPC_MTC0
= (0x04 << 21) | OPC_CP0
,
939 OPC_DMTC0
= (0x05 << 21) | OPC_CP0
,
940 OPC_MTHC0
= (0x06 << 21) | OPC_CP0
,
941 OPC_MFTR
= (0x08 << 21) | OPC_CP0
,
942 OPC_RDPGPR
= (0x0A << 21) | OPC_CP0
,
943 OPC_MFMC0
= (0x0B << 21) | OPC_CP0
,
944 OPC_MTTR
= (0x0C << 21) | OPC_CP0
,
945 OPC_WRPGPR
= (0x0E << 21) | OPC_CP0
,
946 OPC_C0
= (0x10 << 21) | OPC_CP0
,
947 OPC_C0_1
= (0x11 << 21) | OPC_CP0
,
948 OPC_C0_2
= (0x12 << 21) | OPC_CP0
,
949 OPC_C0_3
= (0x13 << 21) | OPC_CP0
,
950 OPC_C0_4
= (0x14 << 21) | OPC_CP0
,
951 OPC_C0_5
= (0x15 << 21) | OPC_CP0
,
952 OPC_C0_6
= (0x16 << 21) | OPC_CP0
,
953 OPC_C0_7
= (0x17 << 21) | OPC_CP0
,
954 OPC_C0_8
= (0x18 << 21) | OPC_CP0
,
955 OPC_C0_9
= (0x19 << 21) | OPC_CP0
,
956 OPC_C0_A
= (0x1A << 21) | OPC_CP0
,
957 OPC_C0_B
= (0x1B << 21) | OPC_CP0
,
958 OPC_C0_C
= (0x1C << 21) | OPC_CP0
,
959 OPC_C0_D
= (0x1D << 21) | OPC_CP0
,
960 OPC_C0_E
= (0x1E << 21) | OPC_CP0
,
961 OPC_C0_F
= (0x1F << 21) | OPC_CP0
,
965 #define MASK_MFMC0(op) (MASK_CP0(op) | (op & 0xFFFF))
968 OPC_DMT
= 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0
,
969 OPC_EMT
= 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0
,
970 OPC_DVPE
= 0x01 | (0 << 5) | OPC_MFMC0
,
971 OPC_EVPE
= 0x01 | (1 << 5) | OPC_MFMC0
,
972 OPC_DI
= (0 << 5) | (0x0C << 11) | OPC_MFMC0
,
973 OPC_EI
= (1 << 5) | (0x0C << 11) | OPC_MFMC0
,
974 OPC_DVP
= 0x04 | (0 << 3) | (1 << 5) | (0 << 11) | OPC_MFMC0
,
975 OPC_EVP
= 0x04 | (0 << 3) | (0 << 5) | (0 << 11) | OPC_MFMC0
,
978 /* Coprocessor 0 (with rs == C0) */
979 #define MASK_C0(op) (MASK_CP0(op) | (op & 0x3F))
982 OPC_TLBR
= 0x01 | OPC_C0
,
983 OPC_TLBWI
= 0x02 | OPC_C0
,
984 OPC_TLBINV
= 0x03 | OPC_C0
,
985 OPC_TLBINVF
= 0x04 | OPC_C0
,
986 OPC_TLBWR
= 0x06 | OPC_C0
,
987 OPC_TLBP
= 0x08 | OPC_C0
,
988 OPC_RFE
= 0x10 | OPC_C0
,
989 OPC_ERET
= 0x18 | OPC_C0
,
990 OPC_DERET
= 0x1F | OPC_C0
,
991 OPC_WAIT
= 0x20 | OPC_C0
,
994 #define MASK_CP2(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)))
997 OPC_MFC2
= (0x00 << 21) | OPC_CP2
,
998 OPC_DMFC2
= (0x01 << 21) | OPC_CP2
,
999 OPC_CFC2
= (0x02 << 21) | OPC_CP2
,
1000 OPC_MFHC2
= (0x03 << 21) | OPC_CP2
,
1001 OPC_MTC2
= (0x04 << 21) | OPC_CP2
,
1002 OPC_DMTC2
= (0x05 << 21) | OPC_CP2
,
1003 OPC_CTC2
= (0x06 << 21) | OPC_CP2
,
1004 OPC_MTHC2
= (0x07 << 21) | OPC_CP2
,
1005 OPC_BC2
= (0x08 << 21) | OPC_CP2
,
1006 OPC_BC2EQZ
= (0x09 << 21) | OPC_CP2
,
1007 OPC_BC2NEZ
= (0x0D << 21) | OPC_CP2
,
1010 #define MASK_LMMI(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
1013 OPC_PADDSH
= (24 << 21) | (0x00) | OPC_CP2
,
1014 OPC_PADDUSH
= (25 << 21) | (0x00) | OPC_CP2
,
1015 OPC_PADDH
= (26 << 21) | (0x00) | OPC_CP2
,
1016 OPC_PADDW
= (27 << 21) | (0x00) | OPC_CP2
,
1017 OPC_PADDSB
= (28 << 21) | (0x00) | OPC_CP2
,
1018 OPC_PADDUSB
= (29 << 21) | (0x00) | OPC_CP2
,
1019 OPC_PADDB
= (30 << 21) | (0x00) | OPC_CP2
,
1020 OPC_PADDD
= (31 << 21) | (0x00) | OPC_CP2
,
1022 OPC_PSUBSH
= (24 << 21) | (0x01) | OPC_CP2
,
1023 OPC_PSUBUSH
= (25 << 21) | (0x01) | OPC_CP2
,
1024 OPC_PSUBH
= (26 << 21) | (0x01) | OPC_CP2
,
1025 OPC_PSUBW
= (27 << 21) | (0x01) | OPC_CP2
,
1026 OPC_PSUBSB
= (28 << 21) | (0x01) | OPC_CP2
,
1027 OPC_PSUBUSB
= (29 << 21) | (0x01) | OPC_CP2
,
1028 OPC_PSUBB
= (30 << 21) | (0x01) | OPC_CP2
,
1029 OPC_PSUBD
= (31 << 21) | (0x01) | OPC_CP2
,
1031 OPC_PSHUFH
= (24 << 21) | (0x02) | OPC_CP2
,
1032 OPC_PACKSSWH
= (25 << 21) | (0x02) | OPC_CP2
,
1033 OPC_PACKSSHB
= (26 << 21) | (0x02) | OPC_CP2
,
1034 OPC_PACKUSHB
= (27 << 21) | (0x02) | OPC_CP2
,
1035 OPC_XOR_CP2
= (28 << 21) | (0x02) | OPC_CP2
,
1036 OPC_NOR_CP2
= (29 << 21) | (0x02) | OPC_CP2
,
1037 OPC_AND_CP2
= (30 << 21) | (0x02) | OPC_CP2
,
1038 OPC_PANDN
= (31 << 21) | (0x02) | OPC_CP2
,
1040 OPC_PUNPCKLHW
= (24 << 21) | (0x03) | OPC_CP2
,
1041 OPC_PUNPCKHHW
= (25 << 21) | (0x03) | OPC_CP2
,
1042 OPC_PUNPCKLBH
= (26 << 21) | (0x03) | OPC_CP2
,
1043 OPC_PUNPCKHBH
= (27 << 21) | (0x03) | OPC_CP2
,
1044 OPC_PINSRH_0
= (28 << 21) | (0x03) | OPC_CP2
,
1045 OPC_PINSRH_1
= (29 << 21) | (0x03) | OPC_CP2
,
1046 OPC_PINSRH_2
= (30 << 21) | (0x03) | OPC_CP2
,
1047 OPC_PINSRH_3
= (31 << 21) | (0x03) | OPC_CP2
,
1049 OPC_PAVGH
= (24 << 21) | (0x08) | OPC_CP2
,
1050 OPC_PAVGB
= (25 << 21) | (0x08) | OPC_CP2
,
1051 OPC_PMAXSH
= (26 << 21) | (0x08) | OPC_CP2
,
1052 OPC_PMINSH
= (27 << 21) | (0x08) | OPC_CP2
,
1053 OPC_PMAXUB
= (28 << 21) | (0x08) | OPC_CP2
,
1054 OPC_PMINUB
= (29 << 21) | (0x08) | OPC_CP2
,
1056 OPC_PCMPEQW
= (24 << 21) | (0x09) | OPC_CP2
,
1057 OPC_PCMPGTW
= (25 << 21) | (0x09) | OPC_CP2
,
1058 OPC_PCMPEQH
= (26 << 21) | (0x09) | OPC_CP2
,
1059 OPC_PCMPGTH
= (27 << 21) | (0x09) | OPC_CP2
,
1060 OPC_PCMPEQB
= (28 << 21) | (0x09) | OPC_CP2
,
1061 OPC_PCMPGTB
= (29 << 21) | (0x09) | OPC_CP2
,
1063 OPC_PSLLW
= (24 << 21) | (0x0A) | OPC_CP2
,
1064 OPC_PSLLH
= (25 << 21) | (0x0A) | OPC_CP2
,
1065 OPC_PMULLH
= (26 << 21) | (0x0A) | OPC_CP2
,
1066 OPC_PMULHH
= (27 << 21) | (0x0A) | OPC_CP2
,
1067 OPC_PMULUW
= (28 << 21) | (0x0A) | OPC_CP2
,
1068 OPC_PMULHUH
= (29 << 21) | (0x0A) | OPC_CP2
,
1070 OPC_PSRLW
= (24 << 21) | (0x0B) | OPC_CP2
,
1071 OPC_PSRLH
= (25 << 21) | (0x0B) | OPC_CP2
,
1072 OPC_PSRAW
= (26 << 21) | (0x0B) | OPC_CP2
,
1073 OPC_PSRAH
= (27 << 21) | (0x0B) | OPC_CP2
,
1074 OPC_PUNPCKLWD
= (28 << 21) | (0x0B) | OPC_CP2
,
1075 OPC_PUNPCKHWD
= (29 << 21) | (0x0B) | OPC_CP2
,
1077 OPC_ADDU_CP2
= (24 << 21) | (0x0C) | OPC_CP2
,
1078 OPC_OR_CP2
= (25 << 21) | (0x0C) | OPC_CP2
,
1079 OPC_ADD_CP2
= (26 << 21) | (0x0C) | OPC_CP2
,
1080 OPC_DADD_CP2
= (27 << 21) | (0x0C) | OPC_CP2
,
1081 OPC_SEQU_CP2
= (28 << 21) | (0x0C) | OPC_CP2
,
1082 OPC_SEQ_CP2
= (29 << 21) | (0x0C) | OPC_CP2
,
1084 OPC_SUBU_CP2
= (24 << 21) | (0x0D) | OPC_CP2
,
1085 OPC_PASUBUB
= (25 << 21) | (0x0D) | OPC_CP2
,
1086 OPC_SUB_CP2
= (26 << 21) | (0x0D) | OPC_CP2
,
1087 OPC_DSUB_CP2
= (27 << 21) | (0x0D) | OPC_CP2
,
1088 OPC_SLTU_CP2
= (28 << 21) | (0x0D) | OPC_CP2
,
1089 OPC_SLT_CP2
= (29 << 21) | (0x0D) | OPC_CP2
,
1091 OPC_SLL_CP2
= (24 << 21) | (0x0E) | OPC_CP2
,
1092 OPC_DSLL_CP2
= (25 << 21) | (0x0E) | OPC_CP2
,
1093 OPC_PEXTRH
= (26 << 21) | (0x0E) | OPC_CP2
,
1094 OPC_PMADDHW
= (27 << 21) | (0x0E) | OPC_CP2
,
1095 OPC_SLEU_CP2
= (28 << 21) | (0x0E) | OPC_CP2
,
1096 OPC_SLE_CP2
= (29 << 21) | (0x0E) | OPC_CP2
,
1098 OPC_SRL_CP2
= (24 << 21) | (0x0F) | OPC_CP2
,
1099 OPC_DSRL_CP2
= (25 << 21) | (0x0F) | OPC_CP2
,
1100 OPC_SRA_CP2
= (26 << 21) | (0x0F) | OPC_CP2
,
1101 OPC_DSRA_CP2
= (27 << 21) | (0x0F) | OPC_CP2
,
1102 OPC_BIADD
= (28 << 21) | (0x0F) | OPC_CP2
,
1103 OPC_PMOVMSKB
= (29 << 21) | (0x0F) | OPC_CP2
,
1107 #define MASK_CP3(op) (MASK_OP_MAJOR(op) | (op & 0x3F))
1110 OPC_LWXC1
= 0x00 | OPC_CP3
,
1111 OPC_LDXC1
= 0x01 | OPC_CP3
,
1112 OPC_LUXC1
= 0x05 | OPC_CP3
,
1113 OPC_SWXC1
= 0x08 | OPC_CP3
,
1114 OPC_SDXC1
= 0x09 | OPC_CP3
,
1115 OPC_SUXC1
= 0x0D | OPC_CP3
,
1116 OPC_PREFX
= 0x0F | OPC_CP3
,
1117 OPC_ALNV_PS
= 0x1E | OPC_CP3
,
1118 OPC_MADD_S
= 0x20 | OPC_CP3
,
1119 OPC_MADD_D
= 0x21 | OPC_CP3
,
1120 OPC_MADD_PS
= 0x26 | OPC_CP3
,
1121 OPC_MSUB_S
= 0x28 | OPC_CP3
,
1122 OPC_MSUB_D
= 0x29 | OPC_CP3
,
1123 OPC_MSUB_PS
= 0x2E | OPC_CP3
,
1124 OPC_NMADD_S
= 0x30 | OPC_CP3
,
1125 OPC_NMADD_D
= 0x31 | OPC_CP3
,
1126 OPC_NMADD_PS
= 0x36 | OPC_CP3
,
1127 OPC_NMSUB_S
= 0x38 | OPC_CP3
,
1128 OPC_NMSUB_D
= 0x39 | OPC_CP3
,
1129 OPC_NMSUB_PS
= 0x3E | OPC_CP3
,
1133 * Overview of the TX79-specific instruction set
1134 * =============================================
1136 * The R5900 and the C790 have 128-bit wide GPRs, where the upper 64 bits
1137 * are only used by the specific quadword (128-bit) LQ/SQ load/store
1138 * instructions and certain multimedia instructions (MMIs). These MMIs
1139 * configure the 128-bit data path as two 64-bit, four 32-bit, eight 16-bit
1140 * or sixteen 8-bit paths.
1144 * The Toshiba TX System RISC TX79 Core Architecture manual,
1145 * https://wiki.qemu.org/File:C790.pdf
1147 * Three-Operand Multiply and Multiply-Add (4 instructions)
1148 * --------------------------------------------------------
1149 * MADD [rd,] rs, rt Multiply/Add
1150 * MADDU [rd,] rs, rt Multiply/Add Unsigned
1151 * MULT [rd,] rs, rt Multiply (3-operand)
1152 * MULTU [rd,] rs, rt Multiply Unsigned (3-operand)
1154 * Multiply Instructions for Pipeline 1 (10 instructions)
1155 * ------------------------------------------------------
1156 * MULT1 [rd,] rs, rt Multiply Pipeline 1
1157 * MULTU1 [rd,] rs, rt Multiply Unsigned Pipeline 1
1158 * DIV1 rs, rt Divide Pipeline 1
1159 * DIVU1 rs, rt Divide Unsigned Pipeline 1
1160 * MADD1 [rd,] rs, rt Multiply-Add Pipeline 1
1161 * MADDU1 [rd,] rs, rt Multiply-Add Unsigned Pipeline 1
1162 * MFHI1 rd Move From HI1 Register
1163 * MFLO1 rd Move From LO1 Register
1164 * MTHI1 rs Move To HI1 Register
1165 * MTLO1 rs Move To LO1 Register
1167 * Arithmetic (19 instructions)
1168 * ----------------------------
1169 * PADDB rd, rs, rt Parallel Add Byte
1170 * PSUBB rd, rs, rt Parallel Subtract Byte
1171 * PADDH rd, rs, rt Parallel Add Halfword
1172 * PSUBH rd, rs, rt Parallel Subtract Halfword
1173 * PADDW rd, rs, rt Parallel Add Word
1174 * PSUBW rd, rs, rt Parallel Subtract Word
1175 * PADSBH rd, rs, rt Parallel Add/Subtract Halfword
1176 * PADDSB rd, rs, rt Parallel Add with Signed Saturation Byte
1177 * PSUBSB rd, rs, rt Parallel Subtract with Signed Saturation Byte
1178 * PADDSH rd, rs, rt Parallel Add with Signed Saturation Halfword
1179 * PSUBSH rd, rs, rt Parallel Subtract with Signed Saturation Halfword
1180 * PADDSW rd, rs, rt Parallel Add with Signed Saturation Word
1181 * PSUBSW rd, rs, rt Parallel Subtract with Signed Saturation Word
1182 * PADDUB rd, rs, rt Parallel Add with Unsigned saturation Byte
1183 * PSUBUB rd, rs, rt Parallel Subtract with Unsigned saturation Byte
1184 * PADDUH rd, rs, rt Parallel Add with Unsigned saturation Halfword
1185 * PSUBUH rd, rs, rt Parallel Subtract with Unsigned saturation Halfword
1186 * PADDUW rd, rs, rt Parallel Add with Unsigned saturation Word
1187 * PSUBUW rd, rs, rt Parallel Subtract with Unsigned saturation Word
1189 * Min/Max (4 instructions)
1190 * ------------------------
1191 * PMAXH rd, rs, rt Parallel Maximum Halfword
1192 * PMINH rd, rs, rt Parallel Minimum Halfword
1193 * PMAXW rd, rs, rt Parallel Maximum Word
1194 * PMINW rd, rs, rt Parallel Minimum Word
1196 * Absolute (2 instructions)
1197 * -------------------------
1198 * PABSH rd, rt Parallel Absolute Halfword
1199 * PABSW rd, rt Parallel Absolute Word
1201 * Logical (4 instructions)
1202 * ------------------------
1203 * PAND rd, rs, rt Parallel AND
1204 * POR rd, rs, rt Parallel OR
1205 * PXOR rd, rs, rt Parallel XOR
1206 * PNOR rd, rs, rt Parallel NOR
1208 * Shift (9 instructions)
1209 * ----------------------
1210 * PSLLH rd, rt, sa Parallel Shift Left Logical Halfword
1211 * PSRLH rd, rt, sa Parallel Shift Right Logical Halfword
1212 * PSRAH rd, rt, sa Parallel Shift Right Arithmetic Halfword
1213 * PSLLW rd, rt, sa Parallel Shift Left Logical Word
1214 * PSRLW rd, rt, sa Parallel Shift Right Logical Word
1215 * PSRAW rd, rt, sa Parallel Shift Right Arithmetic Word
1216 * PSLLVW rd, rt, rs Parallel Shift Left Logical Variable Word
1217 * PSRLVW rd, rt, rs Parallel Shift Right Logical Variable Word
1218 * PSRAVW rd, rt, rs Parallel Shift Right Arithmetic Variable Word
1220 * Compare (6 instructions)
1221 * ------------------------
1222 * PCGTB rd, rs, rt Parallel Compare for Greater Than Byte
1223 * PCEQB rd, rs, rt Parallel Compare for Equal Byte
1224 * PCGTH rd, rs, rt Parallel Compare for Greater Than Halfword
1225 * PCEQH rd, rs, rt Parallel Compare for Equal Halfword
1226 * PCGTW rd, rs, rt Parallel Compare for Greater Than Word
1227 * PCEQW rd, rs, rt Parallel Compare for Equal Word
1229 * LZC (1 instruction)
1230 * -------------------
1231 * PLZCW rd, rs Parallel Leading Zero or One Count Word
1233 * Quadword Load and Store (2 instructions)
1234 * ----------------------------------------
1235 * LQ rt, offset(base) Load Quadword
1236 * SQ rt, offset(base) Store Quadword
1238 * Multiply and Divide (19 instructions)
1239 * -------------------------------------
1240 * PMULTW rd, rs, rt Parallel Multiply Word
1241 * PMULTUW rd, rs, rt Parallel Multiply Unsigned Word
1242 * PDIVW rs, rt Parallel Divide Word
1243 * PDIVUW rs, rt Parallel Divide Unsigned Word
1244 * PMADDW rd, rs, rt Parallel Multiply-Add Word
1245 * PMADDUW rd, rs, rt Parallel Multiply-Add Unsigned Word
1246 * PMSUBW rd, rs, rt Parallel Multiply-Subtract Word
1247 * PMULTH rd, rs, rt Parallel Multiply Halfword
1248 * PMADDH rd, rs, rt Parallel Multiply-Add Halfword
1249 * PMSUBH rd, rs, rt Parallel Multiply-Subtract Halfword
1250 * PHMADH rd, rs, rt Parallel Horizontal Multiply-Add Halfword
1251 * PHMSBH rd, rs, rt Parallel Horizontal Multiply-Subtract Halfword
1252 * PDIVBW rs, rt Parallel Divide Broadcast Word
1253 * PMFHI rd Parallel Move From HI Register
1254 * PMFLO rd Parallel Move From LO Register
1255 * PMTHI rs Parallel Move To HI Register
1256 * PMTLO rs Parallel Move To LO Register
1257 * PMFHL rd Parallel Move From HI/LO Register
1258 * PMTHL rs Parallel Move To HI/LO Register
1260 * Pack/Extend (11 instructions)
1261 * -----------------------------
1262 * PPAC5 rd, rt Parallel Pack to 5 bits
1263 * PPACB rd, rs, rt Parallel Pack to Byte
1264 * PPACH rd, rs, rt Parallel Pack to Halfword
1265 * PPACW rd, rs, rt Parallel Pack to Word
1266 * PEXT5 rd, rt Parallel Extend Upper from 5 bits
1267 * PEXTUB rd, rs, rt Parallel Extend Upper from Byte
1268 * PEXTLB rd, rs, rt Parallel Extend Lower from Byte
1269 * PEXTUH rd, rs, rt Parallel Extend Upper from Halfword
1270 * PEXTLH rd, rs, rt Parallel Extend Lower from Halfword
1271 * PEXTUW rd, rs, rt Parallel Extend Upper from Word
1272 * PEXTLW rd, rs, rt Parallel Extend Lower from Word
1274 * Others (16 instructions)
1275 * ------------------------
1276 * PCPYH rd, rt Parallel Copy Halfword
1277 * PCPYLD rd, rs, rt Parallel Copy Lower Doubleword
1278 * PCPYUD rd, rs, rt Parallel Copy Upper Doubleword
1279 * PREVH rd, rt Parallel Reverse Halfword
1280 * PINTH rd, rs, rt Parallel Interleave Halfword
1281 * PINTEH rd, rs, rt Parallel Interleave Even Halfword
1282 * PEXEH rd, rt Parallel Exchange Even Halfword
1283 * PEXCH rd, rt Parallel Exchange Center Halfword
1284 * PEXEW rd, rt Parallel Exchange Even Word
1285 * PEXCW rd, rt Parallel Exchange Center Word
1286 * QFSRV rd, rs, rt Quadword Funnel Shift Right Variable
1287 * MFSA rd Move from Shift Amount Register
1288 * MTSA rs Move to Shift Amount Register
1289 * MTSAB rs, immediate Move Byte Count to Shift Amount Register
1290 * MTSAH rs, immediate Move Halfword Count to Shift Amount Register
1291 * PROT3W rd, rt Parallel Rotate 3 Words
1293 * MMI (MultiMedia Instruction) encodings
1294 * ======================================
1296 * MMI instructions encoding table keys:
1298 * * This code is reserved for future use. An attempt to execute it
1299 * causes a Reserved Instruction exception.
1300 * % This code indicates an instruction class. The instruction word
1301 * must be further decoded by examining additional tables that show
1302 * the values for other instruction fields.
1303 * # This code is reserved for the unsupported instructions DMULT,
1304 * DMULTU, DDIV, DDIVU, LL, LLD, SC, SCD, LWC2 and SWC2. An attempt
1305 * to execute it causes a Reserved Instruction exception.
1307 * MMI instructions encoded by opcode field (MMI, LQ, SQ):
1310 * +--------+----------------------------------------+
1312 * +--------+----------------------------------------+
1314 * opcode bits 28..26
1315 * bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
1316 * 31..29 | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111
1317 * -------+-------+-------+-------+-------+-------+-------+-------+-------
1318 * 0 000 |SPECIAL| REGIMM| J | JAL | BEQ | BNE | BLEZ | BGTZ
1319 * 1 001 | ADDI | ADDIU | SLTI | SLTIU | ANDI | ORI | XORI | LUI
1320 * 2 010 | COP0 | COP1 | * | * | BEQL | BNEL | BLEZL | BGTZL
1321 * 3 011 | DADDI | DADDIU| LDL | LDR | MMI% | * | LQ | SQ
1322 * 4 100 | LB | LH | LWL | LW | LBU | LHU | LWR | LWU
1323 * 5 101 | SB | SH | SWL | SW | SDL | SDR | SWR | CACHE
1324 * 6 110 | # | LWC1 | # | PREF | # | LDC1 | # | LD
1325 * 7 111 | # | SWC1 | # | * | # | SDC1 | # | SD
1329 MMI_OPC_CLASS_MMI
= 0x1C << 26, /* Same as OPC_SPECIAL2 */
1330 MMI_OPC_LQ
= 0x1E << 26, /* Same as OPC_MSA */
1331 MMI_OPC_SQ
= 0x1F << 26, /* Same as OPC_SPECIAL3 */
1335 * MMI instructions with opcode field = MMI:
1338 * +--------+-------------------------------+--------+
1339 * | MMI | |function|
1340 * +--------+-------------------------------+--------+
1342 * function bits 2..0
1343 * bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
1344 * 5..3 | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111
1345 * -------+-------+-------+-------+-------+-------+-------+-------+-------
1346 * 0 000 | MADD | MADDU | * | * | PLZCW | * | * | *
1347 * 1 001 | MMI0% | MMI2% | * | * | * | * | * | *
1348 * 2 010 | MFHI1 | MTHI1 | MFLO1 | MTLO1 | * | * | * | *
1349 * 3 011 | MULT1 | MULTU1| DIV1 | DIVU1 | * | * | * | *
1350 * 4 100 | MADD1 | MADDU1| * | * | * | * | * | *
1351 * 5 101 | MMI1% | MMI3% | * | * | * | * | * | *
1352 * 6 110 | PMFHL | PMTHL | * | * | PSLLH | * | PSRLH | PSRAH
1353 * 7 111 | * | * | * | * | PSLLW | * | PSRLW | PSRAW
1356 #define MASK_MMI(op) (MASK_OP_MAJOR(op) | ((op) & 0x3F))
1358 MMI_OPC_MADD
= 0x00 | MMI_OPC_CLASS_MMI
, /* Same as OPC_MADD */
1359 MMI_OPC_MADDU
= 0x01 | MMI_OPC_CLASS_MMI
, /* Same as OPC_MADDU */
1360 MMI_OPC_MULT1
= 0x18 | MMI_OPC_CLASS_MMI
, /* Same minor as OPC_MULT */
1361 MMI_OPC_MULTU1
= 0x19 | MMI_OPC_CLASS_MMI
, /* Same min. as OPC_MULTU */
1362 MMI_OPC_DIV1
= 0x1A | MMI_OPC_CLASS_MMI
, /* Same minor as OPC_DIV */
1363 MMI_OPC_DIVU1
= 0x1B | MMI_OPC_CLASS_MMI
, /* Same minor as OPC_DIVU */
1364 MMI_OPC_MADD1
= 0x20 | MMI_OPC_CLASS_MMI
,
1365 MMI_OPC_MADDU1
= 0x21 | MMI_OPC_CLASS_MMI
,
1368 /* global register indices */
1369 TCGv cpu_gpr
[32], cpu_PC
;
1371 * For CPUs using 128-bit GPR registers, we put the lower halves in cpu_gpr[])
1372 * and the upper halves in cpu_gpr_hi[].
1374 TCGv_i64 cpu_gpr_hi
[32];
1375 TCGv cpu_HI
[MIPS_DSP_ACC
], cpu_LO
[MIPS_DSP_ACC
];
1376 static TCGv cpu_dspctrl
, btarget
;
1378 static TCGv cpu_lladdr
, cpu_llval
;
1379 static TCGv_i32 hflags
;
1380 TCGv_i32 fpu_fcr0
, fpu_fcr31
;
1381 TCGv_i64 fpu_f64
[32];
1383 #include "exec/gen-icount.h"
1385 #define gen_helper_0e0i(name, arg) do { \
1386 TCGv_i32 helper_tmp = tcg_const_i32(arg); \
1387 gen_helper_##name(cpu_env, helper_tmp); \
1388 tcg_temp_free_i32(helper_tmp); \
1391 #define gen_helper_0e1i(name, arg1, arg2) do { \
1392 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1393 gen_helper_##name(cpu_env, arg1, helper_tmp); \
1394 tcg_temp_free_i32(helper_tmp); \
1397 #define gen_helper_1e0i(name, ret, arg1) do { \
1398 TCGv_i32 helper_tmp = tcg_const_i32(arg1); \
1399 gen_helper_##name(ret, cpu_env, helper_tmp); \
1400 tcg_temp_free_i32(helper_tmp); \
1403 #define gen_helper_1e1i(name, ret, arg1, arg2) do { \
1404 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1405 gen_helper_##name(ret, cpu_env, arg1, helper_tmp); \
1406 tcg_temp_free_i32(helper_tmp); \
1409 #define gen_helper_0e2i(name, arg1, arg2, arg3) do { \
1410 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1411 gen_helper_##name(cpu_env, arg1, arg2, helper_tmp); \
1412 tcg_temp_free_i32(helper_tmp); \
1415 #define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do { \
1416 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1417 gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp); \
1418 tcg_temp_free_i32(helper_tmp); \
1421 #define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do { \
1422 TCGv_i32 helper_tmp = tcg_const_i32(arg4); \
1423 gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp); \
1424 tcg_temp_free_i32(helper_tmp); \
1427 #define DISAS_STOP DISAS_TARGET_0
1428 #define DISAS_EXIT DISAS_TARGET_1
1430 static const char * const regnames
[] = {
1431 "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
1432 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
1433 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
1434 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
1437 static const char * const regnames_HI
[] = {
1438 "HI0", "HI1", "HI2", "HI3",
1441 static const char * const regnames_LO
[] = {
1442 "LO0", "LO1", "LO2", "LO3",
1445 static const char * const fregnames
[] = {
1446 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
1447 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
1448 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
1449 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
1452 /* General purpose registers moves. */
1453 void gen_load_gpr(TCGv t
, int reg
)
1456 tcg_gen_movi_tl(t
, 0);
1458 tcg_gen_mov_tl(t
, cpu_gpr
[reg
]);
1462 void gen_store_gpr(TCGv t
, int reg
)
1465 tcg_gen_mov_tl(cpu_gpr
[reg
], t
);
1469 #if defined(TARGET_MIPS64)
1470 void gen_load_gpr_hi(TCGv_i64 t
, int reg
)
1473 tcg_gen_movi_i64(t
, 0);
1475 tcg_gen_mov_i64(t
, cpu_gpr_hi
[reg
]);
1479 void gen_store_gpr_hi(TCGv_i64 t
, int reg
)
1482 tcg_gen_mov_i64(cpu_gpr_hi
[reg
], t
);
1485 #endif /* TARGET_MIPS64 */
1487 /* Moves to/from shadow registers. */
1488 static inline void gen_load_srsgpr(int from
, int to
)
1490 TCGv t0
= tcg_temp_new();
1493 tcg_gen_movi_tl(t0
, 0);
1495 TCGv_i32 t2
= tcg_temp_new_i32();
1496 TCGv_ptr addr
= tcg_temp_new_ptr();
1498 tcg_gen_ld_i32(t2
, cpu_env
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
1499 tcg_gen_shri_i32(t2
, t2
, CP0SRSCtl_PSS
);
1500 tcg_gen_andi_i32(t2
, t2
, 0xf);
1501 tcg_gen_muli_i32(t2
, t2
, sizeof(target_ulong
) * 32);
1502 tcg_gen_ext_i32_ptr(addr
, t2
);
1503 tcg_gen_add_ptr(addr
, cpu_env
, addr
);
1505 tcg_gen_ld_tl(t0
, addr
, sizeof(target_ulong
) * from
);
1506 tcg_temp_free_ptr(addr
);
1507 tcg_temp_free_i32(t2
);
1509 gen_store_gpr(t0
, to
);
1513 static inline void gen_store_srsgpr(int from
, int to
)
1516 TCGv t0
= tcg_temp_new();
1517 TCGv_i32 t2
= tcg_temp_new_i32();
1518 TCGv_ptr addr
= tcg_temp_new_ptr();
1520 gen_load_gpr(t0
, from
);
1521 tcg_gen_ld_i32(t2
, cpu_env
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
1522 tcg_gen_shri_i32(t2
, t2
, CP0SRSCtl_PSS
);
1523 tcg_gen_andi_i32(t2
, t2
, 0xf);
1524 tcg_gen_muli_i32(t2
, t2
, sizeof(target_ulong
) * 32);
1525 tcg_gen_ext_i32_ptr(addr
, t2
);
1526 tcg_gen_add_ptr(addr
, cpu_env
, addr
);
1528 tcg_gen_st_tl(t0
, addr
, sizeof(target_ulong
) * to
);
1529 tcg_temp_free_ptr(addr
);
1530 tcg_temp_free_i32(t2
);
1536 static inline void gen_save_pc(target_ulong pc
)
1538 tcg_gen_movi_tl(cpu_PC
, pc
);
1541 static inline void save_cpu_state(DisasContext
*ctx
, int do_save_pc
)
1543 LOG_DISAS("hflags %08x saved %08x\n", ctx
->hflags
, ctx
->saved_hflags
);
1544 if (do_save_pc
&& ctx
->base
.pc_next
!= ctx
->saved_pc
) {
1545 gen_save_pc(ctx
->base
.pc_next
);
1546 ctx
->saved_pc
= ctx
->base
.pc_next
;
1548 if (ctx
->hflags
!= ctx
->saved_hflags
) {
1549 tcg_gen_movi_i32(hflags
, ctx
->hflags
);
1550 ctx
->saved_hflags
= ctx
->hflags
;
1551 switch (ctx
->hflags
& MIPS_HFLAG_BMASK_BASE
) {
1557 tcg_gen_movi_tl(btarget
, ctx
->btarget
);
1563 static inline void restore_cpu_state(CPUMIPSState
*env
, DisasContext
*ctx
)
1565 ctx
->saved_hflags
= ctx
->hflags
;
1566 switch (ctx
->hflags
& MIPS_HFLAG_BMASK_BASE
) {
1572 ctx
->btarget
= env
->btarget
;
1577 void generate_exception_err(DisasContext
*ctx
, int excp
, int err
)
1579 TCGv_i32 texcp
= tcg_const_i32(excp
);
1580 TCGv_i32 terr
= tcg_const_i32(err
);
1581 save_cpu_state(ctx
, 1);
1582 gen_helper_raise_exception_err(cpu_env
, texcp
, terr
);
1583 tcg_temp_free_i32(terr
);
1584 tcg_temp_free_i32(texcp
);
1585 ctx
->base
.is_jmp
= DISAS_NORETURN
;
1588 void generate_exception(DisasContext
*ctx
, int excp
)
1590 gen_helper_0e0i(raise_exception
, excp
);
1593 void generate_exception_end(DisasContext
*ctx
, int excp
)
1595 generate_exception_err(ctx
, excp
, 0);
1598 void gen_reserved_instruction(DisasContext
*ctx
)
1600 generate_exception_end(ctx
, EXCP_RI
);
1603 /* Floating point register moves. */
1604 void gen_load_fpr32(DisasContext
*ctx
, TCGv_i32 t
, int reg
)
1606 if (ctx
->hflags
& MIPS_HFLAG_FRE
) {
1607 generate_exception(ctx
, EXCP_RI
);
1609 tcg_gen_extrl_i64_i32(t
, fpu_f64
[reg
]);
1612 void gen_store_fpr32(DisasContext
*ctx
, TCGv_i32 t
, int reg
)
1615 if (ctx
->hflags
& MIPS_HFLAG_FRE
) {
1616 generate_exception(ctx
, EXCP_RI
);
1618 t64
= tcg_temp_new_i64();
1619 tcg_gen_extu_i32_i64(t64
, t
);
1620 tcg_gen_deposit_i64(fpu_f64
[reg
], fpu_f64
[reg
], t64
, 0, 32);
1621 tcg_temp_free_i64(t64
);
1624 static void gen_load_fpr32h(DisasContext
*ctx
, TCGv_i32 t
, int reg
)
1626 if (ctx
->hflags
& MIPS_HFLAG_F64
) {
1627 tcg_gen_extrh_i64_i32(t
, fpu_f64
[reg
]);
1629 gen_load_fpr32(ctx
, t
, reg
| 1);
1633 static void gen_store_fpr32h(DisasContext
*ctx
, TCGv_i32 t
, int reg
)
1635 if (ctx
->hflags
& MIPS_HFLAG_F64
) {
1636 TCGv_i64 t64
= tcg_temp_new_i64();
1637 tcg_gen_extu_i32_i64(t64
, t
);
1638 tcg_gen_deposit_i64(fpu_f64
[reg
], fpu_f64
[reg
], t64
, 32, 32);
1639 tcg_temp_free_i64(t64
);
1641 gen_store_fpr32(ctx
, t
, reg
| 1);
1645 void gen_load_fpr64(DisasContext
*ctx
, TCGv_i64 t
, int reg
)
1647 if (ctx
->hflags
& MIPS_HFLAG_F64
) {
1648 tcg_gen_mov_i64(t
, fpu_f64
[reg
]);
1650 tcg_gen_concat32_i64(t
, fpu_f64
[reg
& ~1], fpu_f64
[reg
| 1]);
1654 void gen_store_fpr64(DisasContext
*ctx
, TCGv_i64 t
, int reg
)
1656 if (ctx
->hflags
& MIPS_HFLAG_F64
) {
1657 tcg_gen_mov_i64(fpu_f64
[reg
], t
);
1660 tcg_gen_deposit_i64(fpu_f64
[reg
& ~1], fpu_f64
[reg
& ~1], t
, 0, 32);
1661 t0
= tcg_temp_new_i64();
1662 tcg_gen_shri_i64(t0
, t
, 32);
1663 tcg_gen_deposit_i64(fpu_f64
[reg
| 1], fpu_f64
[reg
| 1], t0
, 0, 32);
1664 tcg_temp_free_i64(t0
);
1668 int get_fp_bit(int cc
)
1677 /* Addresses computation */
1678 void gen_op_addr_add(DisasContext
*ctx
, TCGv ret
, TCGv arg0
, TCGv arg1
)
1680 tcg_gen_add_tl(ret
, arg0
, arg1
);
1682 #if defined(TARGET_MIPS64)
1683 if (ctx
->hflags
& MIPS_HFLAG_AWRAP
) {
1684 tcg_gen_ext32s_i64(ret
, ret
);
1689 static inline void gen_op_addr_addi(DisasContext
*ctx
, TCGv ret
, TCGv base
,
1692 tcg_gen_addi_tl(ret
, base
, ofs
);
1694 #if defined(TARGET_MIPS64)
1695 if (ctx
->hflags
& MIPS_HFLAG_AWRAP
) {
1696 tcg_gen_ext32s_i64(ret
, ret
);
1701 /* Addresses computation (translation time) */
1702 static target_long
addr_add(DisasContext
*ctx
, target_long base
,
1705 target_long sum
= base
+ offset
;
1707 #if defined(TARGET_MIPS64)
1708 if (ctx
->hflags
& MIPS_HFLAG_AWRAP
) {
1715 /* Sign-extract the low 32-bits to a target_long. */
1716 void gen_move_low32(TCGv ret
, TCGv_i64 arg
)
1718 #if defined(TARGET_MIPS64)
1719 tcg_gen_ext32s_i64(ret
, arg
);
1721 tcg_gen_extrl_i64_i32(ret
, arg
);
1725 /* Sign-extract the high 32-bits to a target_long. */
1726 void gen_move_high32(TCGv ret
, TCGv_i64 arg
)
1728 #if defined(TARGET_MIPS64)
1729 tcg_gen_sari_i64(ret
, arg
, 32);
1731 tcg_gen_extrh_i64_i32(ret
, arg
);
1735 void check_cp0_enabled(DisasContext
*ctx
)
1737 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_CP0
))) {
1738 generate_exception_end(ctx
, EXCP_CpU
);
1742 void check_cp1_enabled(DisasContext
*ctx
)
1744 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_FPU
))) {
1745 generate_exception_err(ctx
, EXCP_CpU
, 1);
1750 * Verify that the processor is running with COP1X instructions enabled.
1751 * This is associated with the nabla symbol in the MIPS32 and MIPS64
1754 void check_cop1x(DisasContext
*ctx
)
1756 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_COP1X
))) {
1757 gen_reserved_instruction(ctx
);
1762 * Verify that the processor is running with 64-bit floating-point
1763 * operations enabled.
1765 void check_cp1_64bitmode(DisasContext
*ctx
)
1767 if (unlikely(~ctx
->hflags
& (MIPS_HFLAG_F64
| MIPS_HFLAG_COP1X
))) {
1768 gen_reserved_instruction(ctx
);
1773 * Verify if floating point register is valid; an operation is not defined
1774 * if bit 0 of any register specification is set and the FR bit in the
1775 * Status register equals zero, since the register numbers specify an
1776 * even-odd pair of adjacent coprocessor general registers. When the FR bit
1777 * in the Status register equals one, both even and odd register numbers
1778 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
1780 * Multiple 64 bit wide registers can be checked by calling
1781 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
1783 void check_cp1_registers(DisasContext
*ctx
, int regs
)
1785 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_F64
) && (regs
& 1))) {
1786 gen_reserved_instruction(ctx
);
1791 * Verify that the processor is running with DSP instructions enabled.
1792 * This is enabled by CP0 Status register MX(24) bit.
1794 static inline void check_dsp(DisasContext
*ctx
)
1796 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_DSP
))) {
1797 if (ctx
->insn_flags
& ASE_DSP
) {
1798 generate_exception_end(ctx
, EXCP_DSPDIS
);
1800 gen_reserved_instruction(ctx
);
1805 static inline void check_dsp_r2(DisasContext
*ctx
)
1807 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_DSP_R2
))) {
1808 if (ctx
->insn_flags
& ASE_DSP
) {
1809 generate_exception_end(ctx
, EXCP_DSPDIS
);
1811 gen_reserved_instruction(ctx
);
1816 static inline void check_dsp_r3(DisasContext
*ctx
)
1818 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_DSP_R3
))) {
1819 if (ctx
->insn_flags
& ASE_DSP
) {
1820 generate_exception_end(ctx
, EXCP_DSPDIS
);
1822 gen_reserved_instruction(ctx
);
1828 * This code generates a "reserved instruction" exception if the
1829 * CPU does not support the instruction set corresponding to flags.
1831 void check_insn(DisasContext
*ctx
, uint64_t flags
)
1833 if (unlikely(!(ctx
->insn_flags
& flags
))) {
1834 gen_reserved_instruction(ctx
);
1839 * This code generates a "reserved instruction" exception if the
1840 * CPU has corresponding flag set which indicates that the instruction
1843 static inline void check_insn_opc_removed(DisasContext
*ctx
, uint64_t flags
)
1845 if (unlikely(ctx
->insn_flags
& flags
)) {
1846 gen_reserved_instruction(ctx
);
1851 * The Linux kernel traps certain reserved instruction exceptions to
1852 * emulate the corresponding instructions. QEMU is the kernel in user
1853 * mode, so those traps are emulated by accepting the instructions.
1855 * A reserved instruction exception is generated for flagged CPUs if
1856 * QEMU runs in system mode.
1858 static inline void check_insn_opc_user_only(DisasContext
*ctx
, uint64_t flags
)
1860 #ifndef CONFIG_USER_ONLY
1861 check_insn_opc_removed(ctx
, flags
);
1866 * This code generates a "reserved instruction" exception if the
1867 * CPU does not support 64-bit paired-single (PS) floating point data type.
1869 static inline void check_ps(DisasContext
*ctx
)
1871 if (unlikely(!ctx
->ps
)) {
1872 generate_exception(ctx
, EXCP_RI
);
1874 check_cp1_64bitmode(ctx
);
1878 * This code generates a "reserved instruction" exception if cpu is not
1879 * 64-bit or 64-bit instructions are not enabled.
1881 void check_mips_64(DisasContext
*ctx
)
1883 if (unlikely((TARGET_LONG_BITS
!= 64) || !(ctx
->hflags
& MIPS_HFLAG_64
))) {
1884 gen_reserved_instruction(ctx
);
1888 #ifndef CONFIG_USER_ONLY
1889 static inline void check_mvh(DisasContext
*ctx
)
1891 if (unlikely(!ctx
->mvh
)) {
1892 generate_exception(ctx
, EXCP_RI
);
1898 * This code generates a "reserved instruction" exception if the
1899 * Config5 XNP bit is set.
1901 static inline void check_xnp(DisasContext
*ctx
)
1903 if (unlikely(ctx
->CP0_Config5
& (1 << CP0C5_XNP
))) {
1904 gen_reserved_instruction(ctx
);
1908 #ifndef CONFIG_USER_ONLY
1910 * This code generates a "reserved instruction" exception if the
1911 * Config3 PW bit is NOT set.
1913 static inline void check_pw(DisasContext
*ctx
)
1915 if (unlikely(!(ctx
->CP0_Config3
& (1 << CP0C3_PW
)))) {
1916 gen_reserved_instruction(ctx
);
1922 * This code generates a "reserved instruction" exception if the
1923 * Config3 MT bit is NOT set.
1925 static inline void check_mt(DisasContext
*ctx
)
1927 if (unlikely(!(ctx
->CP0_Config3
& (1 << CP0C3_MT
)))) {
1928 gen_reserved_instruction(ctx
);
1932 #ifndef CONFIG_USER_ONLY
1934 * This code generates a "coprocessor unusable" exception if CP0 is not
1935 * available, and, if that is not the case, generates a "reserved instruction"
1936 * exception if the Config5 MT bit is NOT set. This is needed for availability
1937 * control of some of MT ASE instructions.
1939 static inline void check_cp0_mt(DisasContext
*ctx
)
1941 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_CP0
))) {
1942 generate_exception_end(ctx
, EXCP_CpU
);
1944 if (unlikely(!(ctx
->CP0_Config3
& (1 << CP0C3_MT
)))) {
1945 gen_reserved_instruction(ctx
);
1952 * This code generates a "reserved instruction" exception if the
1953 * Config5 NMS bit is set.
1955 static inline void check_nms(DisasContext
*ctx
)
1957 if (unlikely(ctx
->CP0_Config5
& (1 << CP0C5_NMS
))) {
1958 gen_reserved_instruction(ctx
);
1963 * This code generates a "reserved instruction" exception if the
1964 * Config5 NMS bit is set, and Config1 DL, Config1 IL, Config2 SL,
1965 * Config2 TL, and Config5 L2C are unset.
1967 static inline void check_nms_dl_il_sl_tl_l2c(DisasContext
*ctx
)
1969 if (unlikely((ctx
->CP0_Config5
& (1 << CP0C5_NMS
)) &&
1970 !(ctx
->CP0_Config1
& (1 << CP0C1_DL
)) &&
1971 !(ctx
->CP0_Config1
& (1 << CP0C1_IL
)) &&
1972 !(ctx
->CP0_Config2
& (1 << CP0C2_SL
)) &&
1973 !(ctx
->CP0_Config2
& (1 << CP0C2_TL
)) &&
1974 !(ctx
->CP0_Config5
& (1 << CP0C5_L2C
)))) {
1975 gen_reserved_instruction(ctx
);
1980 * This code generates a "reserved instruction" exception if the
1981 * Config5 EVA bit is NOT set.
1983 static inline void check_eva(DisasContext
*ctx
)
1985 if (unlikely(!(ctx
->CP0_Config5
& (1 << CP0C5_EVA
)))) {
1986 gen_reserved_instruction(ctx
);
1992 * Define small wrappers for gen_load_fpr* so that we have a uniform
1993 * calling interface for 32 and 64-bit FPRs. No sense in changing
1994 * all callers for gen_load_fpr32 when we need the CTX parameter for
1997 #define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(ctx, x, y)
1998 #define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
1999 #define FOP_CONDS(type, abs, fmt, ifmt, bits) \
2000 static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
2001 int ft, int fs, int cc) \
2003 TCGv_i##bits fp0 = tcg_temp_new_i##bits(); \
2004 TCGv_i##bits fp1 = tcg_temp_new_i##bits(); \
2013 check_cp1_registers(ctx, fs | ft); \
2021 gen_ldcmp_fpr##bits(ctx, fp0, fs); \
2022 gen_ldcmp_fpr##bits(ctx, fp1, ft); \
2025 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); \
2028 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); \
2031 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); \
2034 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); \
2037 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); \
2040 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); \
2043 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); \
2046 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); \
2049 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); \
2052 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); \
2055 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); \
2058 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); \
2061 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); \
2064 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); \
2067 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); \
2070 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); \
2075 tcg_temp_free_i##bits(fp0); \
2076 tcg_temp_free_i##bits(fp1); \
2079 FOP_CONDS(, 0, d
, FMT_D
, 64)
2080 FOP_CONDS(abs
, 1, d
, FMT_D
, 64)
2081 FOP_CONDS(, 0, s
, FMT_S
, 32)
2082 FOP_CONDS(abs
, 1, s
, FMT_S
, 32)
2083 FOP_CONDS(, 0, ps
, FMT_PS
, 64)
2084 FOP_CONDS(abs
, 1, ps
, FMT_PS
, 64)
2087 #define FOP_CONDNS(fmt, ifmt, bits, STORE) \
2088 static inline void gen_r6_cmp_ ## fmt(DisasContext *ctx, int n, \
2089 int ft, int fs, int fd) \
2091 TCGv_i ## bits fp0 = tcg_temp_new_i ## bits(); \
2092 TCGv_i ## bits fp1 = tcg_temp_new_i ## bits(); \
2093 if (ifmt == FMT_D) { \
2094 check_cp1_registers(ctx, fs | ft | fd); \
2096 gen_ldcmp_fpr ## bits(ctx, fp0, fs); \
2097 gen_ldcmp_fpr ## bits(ctx, fp1, ft); \
2100 gen_helper_r6_cmp_ ## fmt ## _af(fp0, cpu_env, fp0, fp1); \
2103 gen_helper_r6_cmp_ ## fmt ## _un(fp0, cpu_env, fp0, fp1); \
2106 gen_helper_r6_cmp_ ## fmt ## _eq(fp0, cpu_env, fp0, fp1); \
2109 gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, cpu_env, fp0, fp1); \
2112 gen_helper_r6_cmp_ ## fmt ## _lt(fp0, cpu_env, fp0, fp1); \
2115 gen_helper_r6_cmp_ ## fmt ## _ult(fp0, cpu_env, fp0, fp1); \
2118 gen_helper_r6_cmp_ ## fmt ## _le(fp0, cpu_env, fp0, fp1); \
2121 gen_helper_r6_cmp_ ## fmt ## _ule(fp0, cpu_env, fp0, fp1); \
2124 gen_helper_r6_cmp_ ## fmt ## _saf(fp0, cpu_env, fp0, fp1); \
2127 gen_helper_r6_cmp_ ## fmt ## _sun(fp0, cpu_env, fp0, fp1); \
2130 gen_helper_r6_cmp_ ## fmt ## _seq(fp0, cpu_env, fp0, fp1); \
2133 gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, cpu_env, fp0, fp1); \
2136 gen_helper_r6_cmp_ ## fmt ## _slt(fp0, cpu_env, fp0, fp1); \
2139 gen_helper_r6_cmp_ ## fmt ## _sult(fp0, cpu_env, fp0, fp1); \
2142 gen_helper_r6_cmp_ ## fmt ## _sle(fp0, cpu_env, fp0, fp1); \
2145 gen_helper_r6_cmp_ ## fmt ## _sule(fp0, cpu_env, fp0, fp1); \
2148 gen_helper_r6_cmp_ ## fmt ## _or(fp0, cpu_env, fp0, fp1); \
2151 gen_helper_r6_cmp_ ## fmt ## _une(fp0, cpu_env, fp0, fp1); \
2154 gen_helper_r6_cmp_ ## fmt ## _ne(fp0, cpu_env, fp0, fp1); \
2157 gen_helper_r6_cmp_ ## fmt ## _sor(fp0, cpu_env, fp0, fp1); \
2160 gen_helper_r6_cmp_ ## fmt ## _sune(fp0, cpu_env, fp0, fp1); \
2163 gen_helper_r6_cmp_ ## fmt ## _sne(fp0, cpu_env, fp0, fp1); \
2169 tcg_temp_free_i ## bits(fp0); \
2170 tcg_temp_free_i ## bits(fp1); \
2173 FOP_CONDNS(d
, FMT_D
, 64, gen_store_fpr64(ctx
, fp0
, fd
))
2174 FOP_CONDNS(s
, FMT_S
, 32, gen_store_fpr32(ctx
, fp0
, fd
))
2176 #undef gen_ldcmp_fpr32
2177 #undef gen_ldcmp_fpr64
2179 /* load/store instructions. */
2180 #ifdef CONFIG_USER_ONLY
2181 #define OP_LD_ATOMIC(insn, fname) \
2182 static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \
2183 DisasContext *ctx) \
2185 TCGv t0 = tcg_temp_new(); \
2186 tcg_gen_mov_tl(t0, arg1); \
2187 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
2188 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
2189 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
2190 tcg_temp_free(t0); \
2193 #define OP_LD_ATOMIC(insn, fname) \
2194 static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \
2195 DisasContext *ctx) \
2197 gen_helper_1e1i(insn, ret, arg1, mem_idx); \
2200 OP_LD_ATOMIC(ll
, ld32s
);
2201 #if defined(TARGET_MIPS64)
2202 OP_LD_ATOMIC(lld
, ld64
);
2206 void gen_base_offset_addr(DisasContext
*ctx
, TCGv addr
, int base
, int offset
)
2209 tcg_gen_movi_tl(addr
, offset
);
2210 } else if (offset
== 0) {
2211 gen_load_gpr(addr
, base
);
2213 tcg_gen_movi_tl(addr
, offset
);
2214 gen_op_addr_add(ctx
, addr
, cpu_gpr
[base
], addr
);
2218 static target_ulong
pc_relative_pc(DisasContext
*ctx
)
2220 target_ulong pc
= ctx
->base
.pc_next
;
2222 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
2223 int branch_bytes
= ctx
->hflags
& MIPS_HFLAG_BDS16
? 2 : 4;
2228 pc
&= ~(target_ulong
)3;
2233 static void gen_ld(DisasContext
*ctx
, uint32_t opc
,
2234 int rt
, int base
, int offset
)
2237 int mem_idx
= ctx
->mem_idx
;
2239 if (rt
== 0 && ctx
->insn_flags
& (INSN_LOONGSON2E
| INSN_LOONGSON2F
|
2242 * Loongson CPU uses a load to zero register for prefetch.
2243 * We emulate it as a NOP. On other CPU we must perform the
2244 * actual memory access.
2249 t0
= tcg_temp_new();
2250 gen_base_offset_addr(ctx
, t0
, base
, offset
);
2253 #if defined(TARGET_MIPS64)
2255 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEUL
|
2256 ctx
->default_tcg_memop_mask
);
2257 gen_store_gpr(t0
, rt
);
2260 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEQ
|
2261 ctx
->default_tcg_memop_mask
);
2262 gen_store_gpr(t0
, rt
);
2266 op_ld_lld(t0
, t0
, mem_idx
, ctx
);
2267 gen_store_gpr(t0
, rt
);
2270 t1
= tcg_temp_new();
2272 * Do a byte access to possibly trigger a page
2273 * fault with the unaligned address.
2275 tcg_gen_qemu_ld_tl(t1
, t0
, mem_idx
, MO_UB
);
2276 tcg_gen_andi_tl(t1
, t0
, 7);
2277 #ifndef TARGET_WORDS_BIGENDIAN
2278 tcg_gen_xori_tl(t1
, t1
, 7);
2280 tcg_gen_shli_tl(t1
, t1
, 3);
2281 tcg_gen_andi_tl(t0
, t0
, ~7);
2282 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEQ
);
2283 tcg_gen_shl_tl(t0
, t0
, t1
);
2284 t2
= tcg_const_tl(-1);
2285 tcg_gen_shl_tl(t2
, t2
, t1
);
2286 gen_load_gpr(t1
, rt
);
2287 tcg_gen_andc_tl(t1
, t1
, t2
);
2289 tcg_gen_or_tl(t0
, t0
, t1
);
2291 gen_store_gpr(t0
, rt
);
2294 t1
= tcg_temp_new();
2296 * Do a byte access to possibly trigger a page
2297 * fault with the unaligned address.
2299 tcg_gen_qemu_ld_tl(t1
, t0
, mem_idx
, MO_UB
);
2300 tcg_gen_andi_tl(t1
, t0
, 7);
2301 #ifdef TARGET_WORDS_BIGENDIAN
2302 tcg_gen_xori_tl(t1
, t1
, 7);
2304 tcg_gen_shli_tl(t1
, t1
, 3);
2305 tcg_gen_andi_tl(t0
, t0
, ~7);
2306 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEQ
);
2307 tcg_gen_shr_tl(t0
, t0
, t1
);
2308 tcg_gen_xori_tl(t1
, t1
, 63);
2309 t2
= tcg_const_tl(0xfffffffffffffffeull
);
2310 tcg_gen_shl_tl(t2
, t2
, t1
);
2311 gen_load_gpr(t1
, rt
);
2312 tcg_gen_and_tl(t1
, t1
, t2
);
2314 tcg_gen_or_tl(t0
, t0
, t1
);
2316 gen_store_gpr(t0
, rt
);
2319 t1
= tcg_const_tl(pc_relative_pc(ctx
));
2320 gen_op_addr_add(ctx
, t0
, t0
, t1
);
2322 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEQ
);
2323 gen_store_gpr(t0
, rt
);
2327 t1
= tcg_const_tl(pc_relative_pc(ctx
));
2328 gen_op_addr_add(ctx
, t0
, t0
, t1
);
2330 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TESL
);
2331 gen_store_gpr(t0
, rt
);
2334 mem_idx
= MIPS_HFLAG_UM
;
2337 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TESL
|
2338 ctx
->default_tcg_memop_mask
);
2339 gen_store_gpr(t0
, rt
);
2342 mem_idx
= MIPS_HFLAG_UM
;
2345 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TESW
|
2346 ctx
->default_tcg_memop_mask
);
2347 gen_store_gpr(t0
, rt
);
2350 mem_idx
= MIPS_HFLAG_UM
;
2353 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEUW
|
2354 ctx
->default_tcg_memop_mask
);
2355 gen_store_gpr(t0
, rt
);
2358 mem_idx
= MIPS_HFLAG_UM
;
2361 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_SB
);
2362 gen_store_gpr(t0
, rt
);
2365 mem_idx
= MIPS_HFLAG_UM
;
2368 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_UB
);
2369 gen_store_gpr(t0
, rt
);
2372 mem_idx
= MIPS_HFLAG_UM
;
2375 t1
= tcg_temp_new();
2377 * Do a byte access to possibly trigger a page
2378 * fault with the unaligned address.
2380 tcg_gen_qemu_ld_tl(t1
, t0
, mem_idx
, MO_UB
);
2381 tcg_gen_andi_tl(t1
, t0
, 3);
2382 #ifndef TARGET_WORDS_BIGENDIAN
2383 tcg_gen_xori_tl(t1
, t1
, 3);
2385 tcg_gen_shli_tl(t1
, t1
, 3);
2386 tcg_gen_andi_tl(t0
, t0
, ~3);
2387 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEUL
);
2388 tcg_gen_shl_tl(t0
, t0
, t1
);
2389 t2
= tcg_const_tl(-1);
2390 tcg_gen_shl_tl(t2
, t2
, t1
);
2391 gen_load_gpr(t1
, rt
);
2392 tcg_gen_andc_tl(t1
, t1
, t2
);
2394 tcg_gen_or_tl(t0
, t0
, t1
);
2396 tcg_gen_ext32s_tl(t0
, t0
);
2397 gen_store_gpr(t0
, rt
);
2400 mem_idx
= MIPS_HFLAG_UM
;
2403 t1
= tcg_temp_new();
2405 * Do a byte access to possibly trigger a page
2406 * fault with the unaligned address.
2408 tcg_gen_qemu_ld_tl(t1
, t0
, mem_idx
, MO_UB
);
2409 tcg_gen_andi_tl(t1
, t0
, 3);
2410 #ifdef TARGET_WORDS_BIGENDIAN
2411 tcg_gen_xori_tl(t1
, t1
, 3);
2413 tcg_gen_shli_tl(t1
, t1
, 3);
2414 tcg_gen_andi_tl(t0
, t0
, ~3);
2415 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEUL
);
2416 tcg_gen_shr_tl(t0
, t0
, t1
);
2417 tcg_gen_xori_tl(t1
, t1
, 31);
2418 t2
= tcg_const_tl(0xfffffffeull
);
2419 tcg_gen_shl_tl(t2
, t2
, t1
);
2420 gen_load_gpr(t1
, rt
);
2421 tcg_gen_and_tl(t1
, t1
, t2
);
2423 tcg_gen_or_tl(t0
, t0
, t1
);
2425 tcg_gen_ext32s_tl(t0
, t0
);
2426 gen_store_gpr(t0
, rt
);
2429 mem_idx
= MIPS_HFLAG_UM
;
2433 op_ld_ll(t0
, t0
, mem_idx
, ctx
);
2434 gen_store_gpr(t0
, rt
);
2440 static void gen_llwp(DisasContext
*ctx
, uint32_t base
, int16_t offset
,
2441 uint32_t reg1
, uint32_t reg2
)
2443 TCGv taddr
= tcg_temp_new();
2444 TCGv_i64 tval
= tcg_temp_new_i64();
2445 TCGv tmp1
= tcg_temp_new();
2446 TCGv tmp2
= tcg_temp_new();
2448 gen_base_offset_addr(ctx
, taddr
, base
, offset
);
2449 tcg_gen_qemu_ld64(tval
, taddr
, ctx
->mem_idx
);
2450 #ifdef TARGET_WORDS_BIGENDIAN
2451 tcg_gen_extr_i64_tl(tmp2
, tmp1
, tval
);
2453 tcg_gen_extr_i64_tl(tmp1
, tmp2
, tval
);
2455 gen_store_gpr(tmp1
, reg1
);
2456 tcg_temp_free(tmp1
);
2457 gen_store_gpr(tmp2
, reg2
);
2458 tcg_temp_free(tmp2
);
2459 tcg_gen_st_i64(tval
, cpu_env
, offsetof(CPUMIPSState
, llval_wp
));
2460 tcg_temp_free_i64(tval
);
2461 tcg_gen_st_tl(taddr
, cpu_env
, offsetof(CPUMIPSState
, lladdr
));
2462 tcg_temp_free(taddr
);
2466 static void gen_st(DisasContext
*ctx
, uint32_t opc
, int rt
,
2467 int base
, int offset
)
2469 TCGv t0
= tcg_temp_new();
2470 TCGv t1
= tcg_temp_new();
2471 int mem_idx
= ctx
->mem_idx
;
2473 gen_base_offset_addr(ctx
, t0
, base
, offset
);
2474 gen_load_gpr(t1
, rt
);
2476 #if defined(TARGET_MIPS64)
2478 tcg_gen_qemu_st_tl(t1
, t0
, mem_idx
, MO_TEQ
|
2479 ctx
->default_tcg_memop_mask
);
2482 gen_helper_0e2i(sdl
, t1
, t0
, mem_idx
);
2485 gen_helper_0e2i(sdr
, t1
, t0
, mem_idx
);
2489 mem_idx
= MIPS_HFLAG_UM
;
2492 tcg_gen_qemu_st_tl(t1
, t0
, mem_idx
, MO_TEUL
|
2493 ctx
->default_tcg_memop_mask
);
2496 mem_idx
= MIPS_HFLAG_UM
;
2499 tcg_gen_qemu_st_tl(t1
, t0
, mem_idx
, MO_TEUW
|
2500 ctx
->default_tcg_memop_mask
);
2503 mem_idx
= MIPS_HFLAG_UM
;
2506 tcg_gen_qemu_st_tl(t1
, t0
, mem_idx
, MO_8
);
2509 mem_idx
= MIPS_HFLAG_UM
;
2512 gen_helper_0e2i(swl
, t1
, t0
, mem_idx
);
2515 mem_idx
= MIPS_HFLAG_UM
;
2518 gen_helper_0e2i(swr
, t1
, t0
, mem_idx
);
2526 /* Store conditional */
2527 static void gen_st_cond(DisasContext
*ctx
, int rt
, int base
, int offset
,
2528 MemOp tcg_mo
, bool eva
)
2531 TCGLabel
*l1
= gen_new_label();
2532 TCGLabel
*done
= gen_new_label();
2534 t0
= tcg_temp_new();
2535 addr
= tcg_temp_new();
2536 /* compare the address against that of the preceding LL */
2537 gen_base_offset_addr(ctx
, addr
, base
, offset
);
2538 tcg_gen_brcond_tl(TCG_COND_EQ
, addr
, cpu_lladdr
, l1
);
2539 tcg_temp_free(addr
);
2540 tcg_gen_movi_tl(t0
, 0);
2541 gen_store_gpr(t0
, rt
);
2545 /* generate cmpxchg */
2546 val
= tcg_temp_new();
2547 gen_load_gpr(val
, rt
);
2548 tcg_gen_atomic_cmpxchg_tl(t0
, cpu_lladdr
, cpu_llval
, val
,
2549 eva
? MIPS_HFLAG_UM
: ctx
->mem_idx
, tcg_mo
);
2550 tcg_gen_setcond_tl(TCG_COND_EQ
, t0
, t0
, cpu_llval
);
2551 gen_store_gpr(t0
, rt
);
2554 gen_set_label(done
);
2559 static void gen_scwp(DisasContext
*ctx
, uint32_t base
, int16_t offset
,
2560 uint32_t reg1
, uint32_t reg2
, bool eva
)
2562 TCGv taddr
= tcg_temp_local_new();
2563 TCGv lladdr
= tcg_temp_local_new();
2564 TCGv_i64 tval
= tcg_temp_new_i64();
2565 TCGv_i64 llval
= tcg_temp_new_i64();
2566 TCGv_i64 val
= tcg_temp_new_i64();
2567 TCGv tmp1
= tcg_temp_new();
2568 TCGv tmp2
= tcg_temp_new();
2569 TCGLabel
*lab_fail
= gen_new_label();
2570 TCGLabel
*lab_done
= gen_new_label();
2572 gen_base_offset_addr(ctx
, taddr
, base
, offset
);
2574 tcg_gen_ld_tl(lladdr
, cpu_env
, offsetof(CPUMIPSState
, lladdr
));
2575 tcg_gen_brcond_tl(TCG_COND_NE
, taddr
, lladdr
, lab_fail
);
2577 gen_load_gpr(tmp1
, reg1
);
2578 gen_load_gpr(tmp2
, reg2
);
2580 #ifdef TARGET_WORDS_BIGENDIAN
2581 tcg_gen_concat_tl_i64(tval
, tmp2
, tmp1
);
2583 tcg_gen_concat_tl_i64(tval
, tmp1
, tmp2
);
2586 tcg_gen_ld_i64(llval
, cpu_env
, offsetof(CPUMIPSState
, llval_wp
));
2587 tcg_gen_atomic_cmpxchg_i64(val
, taddr
, llval
, tval
,
2588 eva
? MIPS_HFLAG_UM
: ctx
->mem_idx
, MO_64
);
2590 tcg_gen_movi_tl(cpu_gpr
[reg1
], 1);
2592 tcg_gen_brcond_i64(TCG_COND_EQ
, val
, llval
, lab_done
);
2594 gen_set_label(lab_fail
);
2597 tcg_gen_movi_tl(cpu_gpr
[reg1
], 0);
2599 gen_set_label(lab_done
);
2600 tcg_gen_movi_tl(lladdr
, -1);
2601 tcg_gen_st_tl(lladdr
, cpu_env
, offsetof(CPUMIPSState
, lladdr
));
2604 /* Load and store */
2605 static void gen_flt_ldst(DisasContext
*ctx
, uint32_t opc
, int ft
,
2609 * Don't do NOP if destination is zero: we must perform the actual
2615 TCGv_i32 fp0
= tcg_temp_new_i32();
2616 tcg_gen_qemu_ld_i32(fp0
, t0
, ctx
->mem_idx
, MO_TESL
|
2617 ctx
->default_tcg_memop_mask
);
2618 gen_store_fpr32(ctx
, fp0
, ft
);
2619 tcg_temp_free_i32(fp0
);
2624 TCGv_i32 fp0
= tcg_temp_new_i32();
2625 gen_load_fpr32(ctx
, fp0
, ft
);
2626 tcg_gen_qemu_st_i32(fp0
, t0
, ctx
->mem_idx
, MO_TEUL
|
2627 ctx
->default_tcg_memop_mask
);
2628 tcg_temp_free_i32(fp0
);
2633 TCGv_i64 fp0
= tcg_temp_new_i64();
2634 tcg_gen_qemu_ld_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
|
2635 ctx
->default_tcg_memop_mask
);
2636 gen_store_fpr64(ctx
, fp0
, ft
);
2637 tcg_temp_free_i64(fp0
);
2642 TCGv_i64 fp0
= tcg_temp_new_i64();
2643 gen_load_fpr64(ctx
, fp0
, ft
);
2644 tcg_gen_qemu_st_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
|
2645 ctx
->default_tcg_memop_mask
);
2646 tcg_temp_free_i64(fp0
);
2650 MIPS_INVAL("flt_ldst");
2651 gen_reserved_instruction(ctx
);
2656 static void gen_cop1_ldst(DisasContext
*ctx
, uint32_t op
, int rt
,
2657 int rs
, int16_t imm
)
2659 TCGv t0
= tcg_temp_new();
2661 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
2662 check_cp1_enabled(ctx
);
2666 check_insn(ctx
, ISA_MIPS2
);
2669 gen_base_offset_addr(ctx
, t0
, rs
, imm
);
2670 gen_flt_ldst(ctx
, op
, rt
, t0
);
2673 generate_exception_err(ctx
, EXCP_CpU
, 1);
2678 /* Arithmetic with immediate operand */
2679 static void gen_arith_imm(DisasContext
*ctx
, uint32_t opc
,
2680 int rt
, int rs
, int imm
)
2682 target_ulong uimm
= (target_long
)imm
; /* Sign extend to 32/64 bits */
2684 if (rt
== 0 && opc
!= OPC_ADDI
&& opc
!= OPC_DADDI
) {
2686 * If no destination, treat it as a NOP.
2687 * For addi, we must generate the overflow exception when needed.
2694 TCGv t0
= tcg_temp_local_new();
2695 TCGv t1
= tcg_temp_new();
2696 TCGv t2
= tcg_temp_new();
2697 TCGLabel
*l1
= gen_new_label();
2699 gen_load_gpr(t1
, rs
);
2700 tcg_gen_addi_tl(t0
, t1
, uimm
);
2701 tcg_gen_ext32s_tl(t0
, t0
);
2703 tcg_gen_xori_tl(t1
, t1
, ~uimm
);
2704 tcg_gen_xori_tl(t2
, t0
, uimm
);
2705 tcg_gen_and_tl(t1
, t1
, t2
);
2707 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2709 /* operands of same sign, result different sign */
2710 generate_exception(ctx
, EXCP_OVERFLOW
);
2712 tcg_gen_ext32s_tl(t0
, t0
);
2713 gen_store_gpr(t0
, rt
);
2719 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
2720 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
2722 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
2725 #if defined(TARGET_MIPS64)
2728 TCGv t0
= tcg_temp_local_new();
2729 TCGv t1
= tcg_temp_new();
2730 TCGv t2
= tcg_temp_new();
2731 TCGLabel
*l1
= gen_new_label();
2733 gen_load_gpr(t1
, rs
);
2734 tcg_gen_addi_tl(t0
, t1
, uimm
);
2736 tcg_gen_xori_tl(t1
, t1
, ~uimm
);
2737 tcg_gen_xori_tl(t2
, t0
, uimm
);
2738 tcg_gen_and_tl(t1
, t1
, t2
);
2740 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2742 /* operands of same sign, result different sign */
2743 generate_exception(ctx
, EXCP_OVERFLOW
);
2745 gen_store_gpr(t0
, rt
);
2751 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
2753 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
2760 /* Logic with immediate operand */
2761 static void gen_logic_imm(DisasContext
*ctx
, uint32_t opc
,
2762 int rt
, int rs
, int16_t imm
)
2767 /* If no destination, treat it as a NOP. */
2770 uimm
= (uint16_t)imm
;
2773 if (likely(rs
!= 0)) {
2774 tcg_gen_andi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
2776 tcg_gen_movi_tl(cpu_gpr
[rt
], 0);
2781 tcg_gen_ori_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
2783 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
2787 if (likely(rs
!= 0)) {
2788 tcg_gen_xori_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
2790 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
2794 if (rs
!= 0 && (ctx
->insn_flags
& ISA_MIPS_R6
)) {
2796 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], imm
<< 16);
2797 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
2799 tcg_gen_movi_tl(cpu_gpr
[rt
], imm
<< 16);
2808 /* Set on less than with immediate operand */
2809 static void gen_slt_imm(DisasContext
*ctx
, uint32_t opc
,
2810 int rt
, int rs
, int16_t imm
)
2812 target_ulong uimm
= (target_long
)imm
; /* Sign extend to 32/64 bits */
2816 /* If no destination, treat it as a NOP. */
2819 t0
= tcg_temp_new();
2820 gen_load_gpr(t0
, rs
);
2823 tcg_gen_setcondi_tl(TCG_COND_LT
, cpu_gpr
[rt
], t0
, uimm
);
2826 tcg_gen_setcondi_tl(TCG_COND_LTU
, cpu_gpr
[rt
], t0
, uimm
);
2832 /* Shifts with immediate operand */
2833 static void gen_shift_imm(DisasContext
*ctx
, uint32_t opc
,
2834 int rt
, int rs
, int16_t imm
)
2836 target_ulong uimm
= ((uint16_t)imm
) & 0x1f;
2840 /* If no destination, treat it as a NOP. */
2844 t0
= tcg_temp_new();
2845 gen_load_gpr(t0
, rs
);
2848 tcg_gen_shli_tl(t0
, t0
, uimm
);
2849 tcg_gen_ext32s_tl(cpu_gpr
[rt
], t0
);
2852 tcg_gen_sari_tl(cpu_gpr
[rt
], t0
, uimm
);
2856 tcg_gen_ext32u_tl(t0
, t0
);
2857 tcg_gen_shri_tl(cpu_gpr
[rt
], t0
, uimm
);
2859 tcg_gen_ext32s_tl(cpu_gpr
[rt
], t0
);
2864 TCGv_i32 t1
= tcg_temp_new_i32();
2866 tcg_gen_trunc_tl_i32(t1
, t0
);
2867 tcg_gen_rotri_i32(t1
, t1
, uimm
);
2868 tcg_gen_ext_i32_tl(cpu_gpr
[rt
], t1
);
2869 tcg_temp_free_i32(t1
);
2871 tcg_gen_ext32s_tl(cpu_gpr
[rt
], t0
);
2874 #if defined(TARGET_MIPS64)
2876 tcg_gen_shli_tl(cpu_gpr
[rt
], t0
, uimm
);
2879 tcg_gen_sari_tl(cpu_gpr
[rt
], t0
, uimm
);
2882 tcg_gen_shri_tl(cpu_gpr
[rt
], t0
, uimm
);
2886 tcg_gen_rotri_tl(cpu_gpr
[rt
], t0
, uimm
);
2888 tcg_gen_mov_tl(cpu_gpr
[rt
], t0
);
2892 tcg_gen_shli_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
2895 tcg_gen_sari_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
2898 tcg_gen_shri_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
2901 tcg_gen_rotri_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
2909 static void gen_arith(DisasContext
*ctx
, uint32_t opc
,
2910 int rd
, int rs
, int rt
)
2912 if (rd
== 0 && opc
!= OPC_ADD
&& opc
!= OPC_SUB
2913 && opc
!= OPC_DADD
&& opc
!= OPC_DSUB
) {
2915 * If no destination, treat it as a NOP.
2916 * For add & sub, we must generate the overflow exception when needed.
2924 TCGv t0
= tcg_temp_local_new();
2925 TCGv t1
= tcg_temp_new();
2926 TCGv t2
= tcg_temp_new();
2927 TCGLabel
*l1
= gen_new_label();
2929 gen_load_gpr(t1
, rs
);
2930 gen_load_gpr(t2
, rt
);
2931 tcg_gen_add_tl(t0
, t1
, t2
);
2932 tcg_gen_ext32s_tl(t0
, t0
);
2933 tcg_gen_xor_tl(t1
, t1
, t2
);
2934 tcg_gen_xor_tl(t2
, t0
, t2
);
2935 tcg_gen_andc_tl(t1
, t2
, t1
);
2937 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2939 /* operands of same sign, result different sign */
2940 generate_exception(ctx
, EXCP_OVERFLOW
);
2942 gen_store_gpr(t0
, rd
);
2947 if (rs
!= 0 && rt
!= 0) {
2948 tcg_gen_add_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2949 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
2950 } else if (rs
== 0 && rt
!= 0) {
2951 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2952 } else if (rs
!= 0 && rt
== 0) {
2953 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2955 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2960 TCGv t0
= tcg_temp_local_new();
2961 TCGv t1
= tcg_temp_new();
2962 TCGv t2
= tcg_temp_new();
2963 TCGLabel
*l1
= gen_new_label();
2965 gen_load_gpr(t1
, rs
);
2966 gen_load_gpr(t2
, rt
);
2967 tcg_gen_sub_tl(t0
, t1
, t2
);
2968 tcg_gen_ext32s_tl(t0
, t0
);
2969 tcg_gen_xor_tl(t2
, t1
, t2
);
2970 tcg_gen_xor_tl(t1
, t0
, t1
);
2971 tcg_gen_and_tl(t1
, t1
, t2
);
2973 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2976 * operands of different sign, first operand and the result
2979 generate_exception(ctx
, EXCP_OVERFLOW
);
2981 gen_store_gpr(t0
, rd
);
2986 if (rs
!= 0 && rt
!= 0) {
2987 tcg_gen_sub_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2988 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
2989 } else if (rs
== 0 && rt
!= 0) {
2990 tcg_gen_neg_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2991 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
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);
2998 #if defined(TARGET_MIPS64)
3001 TCGv t0
= tcg_temp_local_new();
3002 TCGv t1
= tcg_temp_new();
3003 TCGv t2
= tcg_temp_new();
3004 TCGLabel
*l1
= gen_new_label();
3006 gen_load_gpr(t1
, rs
);
3007 gen_load_gpr(t2
, rt
);
3008 tcg_gen_add_tl(t0
, t1
, t2
);
3009 tcg_gen_xor_tl(t1
, t1
, t2
);
3010 tcg_gen_xor_tl(t2
, t0
, t2
);
3011 tcg_gen_andc_tl(t1
, t2
, t1
);
3013 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
3015 /* operands of same sign, result different sign */
3016 generate_exception(ctx
, EXCP_OVERFLOW
);
3018 gen_store_gpr(t0
, rd
);
3023 if (rs
!= 0 && rt
!= 0) {
3024 tcg_gen_add_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
3025 } else if (rs
== 0 && rt
!= 0) {
3026 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
3027 } else if (rs
!= 0 && rt
== 0) {
3028 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
3030 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3035 TCGv t0
= tcg_temp_local_new();
3036 TCGv t1
= tcg_temp_new();
3037 TCGv t2
= tcg_temp_new();
3038 TCGLabel
*l1
= gen_new_label();
3040 gen_load_gpr(t1
, rs
);
3041 gen_load_gpr(t2
, rt
);
3042 tcg_gen_sub_tl(t0
, t1
, t2
);
3043 tcg_gen_xor_tl(t2
, t1
, t2
);
3044 tcg_gen_xor_tl(t1
, t0
, t1
);
3045 tcg_gen_and_tl(t1
, t1
, t2
);
3047 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
3050 * Operands of different sign, first operand and result different
3053 generate_exception(ctx
, EXCP_OVERFLOW
);
3055 gen_store_gpr(t0
, rd
);
3060 if (rs
!= 0 && rt
!= 0) {
3061 tcg_gen_sub_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
3062 } else if (rs
== 0 && rt
!= 0) {
3063 tcg_gen_neg_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
3064 } else if (rs
!= 0 && rt
== 0) {
3065 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
3067 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3072 if (likely(rs
!= 0 && rt
!= 0)) {
3073 tcg_gen_mul_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
3074 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3076 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3082 /* Conditional move */
3083 static void gen_cond_move(DisasContext
*ctx
, uint32_t opc
,
3084 int rd
, int rs
, int rt
)
3089 /* If no destination, treat it as a NOP. */
3093 t0
= tcg_temp_new();
3094 gen_load_gpr(t0
, rt
);
3095 t1
= tcg_const_tl(0);
3096 t2
= tcg_temp_new();
3097 gen_load_gpr(t2
, rs
);
3100 tcg_gen_movcond_tl(TCG_COND_NE
, cpu_gpr
[rd
], t0
, t1
, t2
, cpu_gpr
[rd
]);
3103 tcg_gen_movcond_tl(TCG_COND_EQ
, cpu_gpr
[rd
], t0
, t1
, t2
, cpu_gpr
[rd
]);
3106 tcg_gen_movcond_tl(TCG_COND_NE
, cpu_gpr
[rd
], t0
, t1
, t2
, t1
);
3109 tcg_gen_movcond_tl(TCG_COND_EQ
, cpu_gpr
[rd
], t0
, t1
, t2
, t1
);
3118 static void gen_logic(DisasContext
*ctx
, uint32_t opc
,
3119 int rd
, int rs
, int rt
)
3122 /* If no destination, treat it as a NOP. */
3128 if (likely(rs
!= 0 && rt
!= 0)) {
3129 tcg_gen_and_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
3131 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3135 if (rs
!= 0 && rt
!= 0) {
3136 tcg_gen_nor_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
3137 } else if (rs
== 0 && rt
!= 0) {
3138 tcg_gen_not_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
3139 } else if (rs
!= 0 && rt
== 0) {
3140 tcg_gen_not_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
3142 tcg_gen_movi_tl(cpu_gpr
[rd
], ~((target_ulong
)0));
3146 if (likely(rs
!= 0 && rt
!= 0)) {
3147 tcg_gen_or_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
3148 } else if (rs
== 0 && rt
!= 0) {
3149 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
3150 } else if (rs
!= 0 && rt
== 0) {
3151 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
3153 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3157 if (likely(rs
!= 0 && rt
!= 0)) {
3158 tcg_gen_xor_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
3159 } else if (rs
== 0 && rt
!= 0) {
3160 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
3161 } else if (rs
!= 0 && rt
== 0) {
3162 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
3164 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3170 /* Set on lower than */
3171 static void gen_slt(DisasContext
*ctx
, uint32_t opc
,
3172 int rd
, int rs
, int rt
)
3177 /* If no destination, treat it as a NOP. */
3181 t0
= tcg_temp_new();
3182 t1
= tcg_temp_new();
3183 gen_load_gpr(t0
, rs
);
3184 gen_load_gpr(t1
, rt
);
3187 tcg_gen_setcond_tl(TCG_COND_LT
, cpu_gpr
[rd
], t0
, t1
);
3190 tcg_gen_setcond_tl(TCG_COND_LTU
, cpu_gpr
[rd
], t0
, t1
);
3198 static void gen_shift(DisasContext
*ctx
, uint32_t opc
,
3199 int rd
, int rs
, int rt
)
3205 * If no destination, treat it as a NOP.
3206 * For add & sub, we must generate the overflow exception when needed.
3211 t0
= tcg_temp_new();
3212 t1
= tcg_temp_new();
3213 gen_load_gpr(t0
, rs
);
3214 gen_load_gpr(t1
, rt
);
3217 tcg_gen_andi_tl(t0
, t0
, 0x1f);
3218 tcg_gen_shl_tl(t0
, t1
, t0
);
3219 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
3222 tcg_gen_andi_tl(t0
, t0
, 0x1f);
3223 tcg_gen_sar_tl(cpu_gpr
[rd
], t1
, t0
);
3226 tcg_gen_ext32u_tl(t1
, t1
);
3227 tcg_gen_andi_tl(t0
, t0
, 0x1f);
3228 tcg_gen_shr_tl(t0
, t1
, t0
);
3229 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
3233 TCGv_i32 t2
= tcg_temp_new_i32();
3234 TCGv_i32 t3
= tcg_temp_new_i32();
3236 tcg_gen_trunc_tl_i32(t2
, t0
);
3237 tcg_gen_trunc_tl_i32(t3
, t1
);
3238 tcg_gen_andi_i32(t2
, t2
, 0x1f);
3239 tcg_gen_rotr_i32(t2
, t3
, t2
);
3240 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
3241 tcg_temp_free_i32(t2
);
3242 tcg_temp_free_i32(t3
);
3245 #if defined(TARGET_MIPS64)
3247 tcg_gen_andi_tl(t0
, t0
, 0x3f);
3248 tcg_gen_shl_tl(cpu_gpr
[rd
], t1
, t0
);
3251 tcg_gen_andi_tl(t0
, t0
, 0x3f);
3252 tcg_gen_sar_tl(cpu_gpr
[rd
], t1
, t0
);
3255 tcg_gen_andi_tl(t0
, t0
, 0x3f);
3256 tcg_gen_shr_tl(cpu_gpr
[rd
], t1
, t0
);
3259 tcg_gen_andi_tl(t0
, t0
, 0x3f);
3260 tcg_gen_rotr_tl(cpu_gpr
[rd
], t1
, t0
);
3268 /* Arithmetic on HI/LO registers */
3269 static void gen_HILO(DisasContext
*ctx
, uint32_t opc
, int acc
, int reg
)
3271 if (reg
== 0 && (opc
== OPC_MFHI
|| opc
== OPC_MFLO
)) {
3282 #if defined(TARGET_MIPS64)
3284 tcg_gen_ext32s_tl(cpu_gpr
[reg
], cpu_HI
[acc
]);
3288 tcg_gen_mov_tl(cpu_gpr
[reg
], cpu_HI
[acc
]);
3292 #if defined(TARGET_MIPS64)
3294 tcg_gen_ext32s_tl(cpu_gpr
[reg
], cpu_LO
[acc
]);
3298 tcg_gen_mov_tl(cpu_gpr
[reg
], cpu_LO
[acc
]);
3303 #if defined(TARGET_MIPS64)
3305 tcg_gen_ext32s_tl(cpu_HI
[acc
], cpu_gpr
[reg
]);
3309 tcg_gen_mov_tl(cpu_HI
[acc
], cpu_gpr
[reg
]);
3312 tcg_gen_movi_tl(cpu_HI
[acc
], 0);
3317 #if defined(TARGET_MIPS64)
3319 tcg_gen_ext32s_tl(cpu_LO
[acc
], cpu_gpr
[reg
]);
3323 tcg_gen_mov_tl(cpu_LO
[acc
], cpu_gpr
[reg
]);
3326 tcg_gen_movi_tl(cpu_LO
[acc
], 0);
3332 static inline void gen_r6_ld(target_long addr
, int reg
, int memidx
,
3335 TCGv t0
= tcg_const_tl(addr
);
3336 tcg_gen_qemu_ld_tl(t0
, t0
, memidx
, memop
);
3337 gen_store_gpr(t0
, reg
);
3341 static inline void gen_pcrel(DisasContext
*ctx
, int opc
, target_ulong pc
,
3347 switch (MASK_OPC_PCREL_TOP2BITS(opc
)) {
3350 offset
= sextract32(ctx
->opcode
<< 2, 0, 21);
3351 addr
= addr_add(ctx
, pc
, offset
);
3352 tcg_gen_movi_tl(cpu_gpr
[rs
], addr
);
3356 offset
= sextract32(ctx
->opcode
<< 2, 0, 21);
3357 addr
= addr_add(ctx
, pc
, offset
);
3358 gen_r6_ld(addr
, rs
, ctx
->mem_idx
, MO_TESL
);
3360 #if defined(TARGET_MIPS64)
3363 offset
= sextract32(ctx
->opcode
<< 2, 0, 21);
3364 addr
= addr_add(ctx
, pc
, offset
);
3365 gen_r6_ld(addr
, rs
, ctx
->mem_idx
, MO_TEUL
);
3369 switch (MASK_OPC_PCREL_TOP5BITS(opc
)) {
3372 offset
= sextract32(ctx
->opcode
, 0, 16) << 16;
3373 addr
= addr_add(ctx
, pc
, offset
);
3374 tcg_gen_movi_tl(cpu_gpr
[rs
], addr
);
3379 offset
= sextract32(ctx
->opcode
, 0, 16) << 16;
3380 addr
= ~0xFFFF & addr_add(ctx
, pc
, offset
);
3381 tcg_gen_movi_tl(cpu_gpr
[rs
], addr
);
3384 #if defined(TARGET_MIPS64)
3385 case R6_OPC_LDPC
: /* bits 16 and 17 are part of immediate */
3386 case R6_OPC_LDPC
+ (1 << 16):
3387 case R6_OPC_LDPC
+ (2 << 16):
3388 case R6_OPC_LDPC
+ (3 << 16):
3390 offset
= sextract32(ctx
->opcode
<< 3, 0, 21);
3391 addr
= addr_add(ctx
, (pc
& ~0x7), offset
);
3392 gen_r6_ld(addr
, rs
, ctx
->mem_idx
, MO_TEQ
);
3396 MIPS_INVAL("OPC_PCREL");
3397 gen_reserved_instruction(ctx
);
3404 static void gen_r6_muldiv(DisasContext
*ctx
, int opc
, int rd
, int rs
, int rt
)
3413 t0
= tcg_temp_new();
3414 t1
= tcg_temp_new();
3416 gen_load_gpr(t0
, rs
);
3417 gen_load_gpr(t1
, rt
);
3422 TCGv t2
= tcg_temp_new();
3423 TCGv t3
= tcg_temp_new();
3424 tcg_gen_ext32s_tl(t0
, t0
);
3425 tcg_gen_ext32s_tl(t1
, t1
);
3426 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, INT_MIN
);
3427 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1);
3428 tcg_gen_and_tl(t2
, t2
, t3
);
3429 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
3430 tcg_gen_or_tl(t2
, t2
, t3
);
3431 tcg_gen_movi_tl(t3
, 0);
3432 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
3433 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
3434 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3441 TCGv t2
= tcg_temp_new();
3442 TCGv t3
= tcg_temp_new();
3443 tcg_gen_ext32s_tl(t0
, t0
);
3444 tcg_gen_ext32s_tl(t1
, t1
);
3445 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, INT_MIN
);
3446 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1);
3447 tcg_gen_and_tl(t2
, t2
, t3
);
3448 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
3449 tcg_gen_or_tl(t2
, t2
, t3
);
3450 tcg_gen_movi_tl(t3
, 0);
3451 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
3452 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
3453 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3460 TCGv t2
= tcg_const_tl(0);
3461 TCGv t3
= tcg_const_tl(1);
3462 tcg_gen_ext32u_tl(t0
, t0
);
3463 tcg_gen_ext32u_tl(t1
, t1
);
3464 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
3465 tcg_gen_divu_tl(cpu_gpr
[rd
], t0
, t1
);
3466 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3473 TCGv t2
= tcg_const_tl(0);
3474 TCGv t3
= tcg_const_tl(1);
3475 tcg_gen_ext32u_tl(t0
, t0
);
3476 tcg_gen_ext32u_tl(t1
, t1
);
3477 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
3478 tcg_gen_remu_tl(cpu_gpr
[rd
], t0
, t1
);
3479 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3486 TCGv_i32 t2
= tcg_temp_new_i32();
3487 TCGv_i32 t3
= tcg_temp_new_i32();
3488 tcg_gen_trunc_tl_i32(t2
, t0
);
3489 tcg_gen_trunc_tl_i32(t3
, t1
);
3490 tcg_gen_mul_i32(t2
, t2
, t3
);
3491 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
3492 tcg_temp_free_i32(t2
);
3493 tcg_temp_free_i32(t3
);
3498 TCGv_i32 t2
= tcg_temp_new_i32();
3499 TCGv_i32 t3
= tcg_temp_new_i32();
3500 tcg_gen_trunc_tl_i32(t2
, t0
);
3501 tcg_gen_trunc_tl_i32(t3
, t1
);
3502 tcg_gen_muls2_i32(t2
, t3
, t2
, t3
);
3503 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t3
);
3504 tcg_temp_free_i32(t2
);
3505 tcg_temp_free_i32(t3
);
3510 TCGv_i32 t2
= tcg_temp_new_i32();
3511 TCGv_i32 t3
= tcg_temp_new_i32();
3512 tcg_gen_trunc_tl_i32(t2
, t0
);
3513 tcg_gen_trunc_tl_i32(t3
, t1
);
3514 tcg_gen_mul_i32(t2
, t2
, t3
);
3515 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
3516 tcg_temp_free_i32(t2
);
3517 tcg_temp_free_i32(t3
);
3522 TCGv_i32 t2
= tcg_temp_new_i32();
3523 TCGv_i32 t3
= tcg_temp_new_i32();
3524 tcg_gen_trunc_tl_i32(t2
, t0
);
3525 tcg_gen_trunc_tl_i32(t3
, t1
);
3526 tcg_gen_mulu2_i32(t2
, t3
, t2
, t3
);
3527 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t3
);
3528 tcg_temp_free_i32(t2
);
3529 tcg_temp_free_i32(t3
);
3532 #if defined(TARGET_MIPS64)
3535 TCGv t2
= tcg_temp_new();
3536 TCGv t3
= tcg_temp_new();
3537 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, -1LL << 63);
3538 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1LL);
3539 tcg_gen_and_tl(t2
, t2
, t3
);
3540 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
3541 tcg_gen_or_tl(t2
, t2
, t3
);
3542 tcg_gen_movi_tl(t3
, 0);
3543 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
3544 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
3551 TCGv t2
= tcg_temp_new();
3552 TCGv t3
= tcg_temp_new();
3553 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, -1LL << 63);
3554 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1LL);
3555 tcg_gen_and_tl(t2
, t2
, t3
);
3556 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
3557 tcg_gen_or_tl(t2
, t2
, t3
);
3558 tcg_gen_movi_tl(t3
, 0);
3559 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
3560 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
3567 TCGv t2
= tcg_const_tl(0);
3568 TCGv t3
= tcg_const_tl(1);
3569 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
3570 tcg_gen_divu_i64(cpu_gpr
[rd
], t0
, t1
);
3577 TCGv t2
= tcg_const_tl(0);
3578 TCGv t3
= tcg_const_tl(1);
3579 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
3580 tcg_gen_remu_i64(cpu_gpr
[rd
], t0
, t1
);
3586 tcg_gen_mul_i64(cpu_gpr
[rd
], t0
, t1
);
3590 TCGv t2
= tcg_temp_new();
3591 tcg_gen_muls2_i64(t2
, cpu_gpr
[rd
], t0
, t1
);
3596 tcg_gen_mul_i64(cpu_gpr
[rd
], t0
, t1
);
3600 TCGv t2
= tcg_temp_new();
3601 tcg_gen_mulu2_i64(t2
, cpu_gpr
[rd
], t0
, t1
);
3607 MIPS_INVAL("r6 mul/div");
3608 gen_reserved_instruction(ctx
);
3616 #if defined(TARGET_MIPS64)
3617 static void gen_div1_tx79(DisasContext
*ctx
, uint32_t opc
, int rs
, int rt
)
3621 t0
= tcg_temp_new();
3622 t1
= tcg_temp_new();
3624 gen_load_gpr(t0
, rs
);
3625 gen_load_gpr(t1
, rt
);
3630 TCGv t2
= tcg_temp_new();
3631 TCGv t3
= tcg_temp_new();
3632 tcg_gen_ext32s_tl(t0
, t0
);
3633 tcg_gen_ext32s_tl(t1
, t1
);
3634 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, INT_MIN
);
3635 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1);
3636 tcg_gen_and_tl(t2
, t2
, t3
);
3637 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
3638 tcg_gen_or_tl(t2
, t2
, t3
);
3639 tcg_gen_movi_tl(t3
, 0);
3640 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
3641 tcg_gen_div_tl(cpu_LO
[1], t0
, t1
);
3642 tcg_gen_rem_tl(cpu_HI
[1], t0
, t1
);
3643 tcg_gen_ext32s_tl(cpu_LO
[1], cpu_LO
[1]);
3644 tcg_gen_ext32s_tl(cpu_HI
[1], cpu_HI
[1]);
3651 TCGv t2
= tcg_const_tl(0);
3652 TCGv t3
= tcg_const_tl(1);
3653 tcg_gen_ext32u_tl(t0
, t0
);
3654 tcg_gen_ext32u_tl(t1
, t1
);
3655 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
3656 tcg_gen_divu_tl(cpu_LO
[1], t0
, t1
);
3657 tcg_gen_remu_tl(cpu_HI
[1], t0
, t1
);
3658 tcg_gen_ext32s_tl(cpu_LO
[1], cpu_LO
[1]);
3659 tcg_gen_ext32s_tl(cpu_HI
[1], cpu_HI
[1]);
3665 MIPS_INVAL("div1 TX79");
3666 gen_reserved_instruction(ctx
);
3675 static void gen_muldiv(DisasContext
*ctx
, uint32_t opc
,
3676 int acc
, int rs
, int rt
)
3680 t0
= tcg_temp_new();
3681 t1
= tcg_temp_new();
3683 gen_load_gpr(t0
, rs
);
3684 gen_load_gpr(t1
, rt
);
3693 TCGv t2
= tcg_temp_new();
3694 TCGv t3
= tcg_temp_new();
3695 tcg_gen_ext32s_tl(t0
, t0
);
3696 tcg_gen_ext32s_tl(t1
, t1
);
3697 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, INT_MIN
);
3698 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1);
3699 tcg_gen_and_tl(t2
, t2
, t3
);
3700 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
3701 tcg_gen_or_tl(t2
, t2
, t3
);
3702 tcg_gen_movi_tl(t3
, 0);
3703 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
3704 tcg_gen_div_tl(cpu_LO
[acc
], t0
, t1
);
3705 tcg_gen_rem_tl(cpu_HI
[acc
], t0
, t1
);
3706 tcg_gen_ext32s_tl(cpu_LO
[acc
], cpu_LO
[acc
]);
3707 tcg_gen_ext32s_tl(cpu_HI
[acc
], cpu_HI
[acc
]);
3714 TCGv t2
= tcg_const_tl(0);
3715 TCGv t3
= tcg_const_tl(1);
3716 tcg_gen_ext32u_tl(t0
, t0
);
3717 tcg_gen_ext32u_tl(t1
, t1
);
3718 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
3719 tcg_gen_divu_tl(cpu_LO
[acc
], t0
, t1
);
3720 tcg_gen_remu_tl(cpu_HI
[acc
], t0
, t1
);
3721 tcg_gen_ext32s_tl(cpu_LO
[acc
], cpu_LO
[acc
]);
3722 tcg_gen_ext32s_tl(cpu_HI
[acc
], cpu_HI
[acc
]);
3729 TCGv_i32 t2
= tcg_temp_new_i32();
3730 TCGv_i32 t3
= tcg_temp_new_i32();
3731 tcg_gen_trunc_tl_i32(t2
, t0
);
3732 tcg_gen_trunc_tl_i32(t3
, t1
);
3733 tcg_gen_muls2_i32(t2
, t3
, t2
, t3
);
3734 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
3735 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
3736 tcg_temp_free_i32(t2
);
3737 tcg_temp_free_i32(t3
);
3742 TCGv_i32 t2
= tcg_temp_new_i32();
3743 TCGv_i32 t3
= tcg_temp_new_i32();
3744 tcg_gen_trunc_tl_i32(t2
, t0
);
3745 tcg_gen_trunc_tl_i32(t3
, t1
);
3746 tcg_gen_mulu2_i32(t2
, t3
, t2
, t3
);
3747 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
3748 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
3749 tcg_temp_free_i32(t2
);
3750 tcg_temp_free_i32(t3
);
3753 #if defined(TARGET_MIPS64)
3756 TCGv t2
= tcg_temp_new();
3757 TCGv t3
= tcg_temp_new();
3758 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, -1LL << 63);
3759 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1LL);
3760 tcg_gen_and_tl(t2
, t2
, t3
);
3761 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
3762 tcg_gen_or_tl(t2
, t2
, t3
);
3763 tcg_gen_movi_tl(t3
, 0);
3764 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
3765 tcg_gen_div_tl(cpu_LO
[acc
], t0
, t1
);
3766 tcg_gen_rem_tl(cpu_HI
[acc
], t0
, t1
);
3773 TCGv t2
= tcg_const_tl(0);
3774 TCGv t3
= tcg_const_tl(1);
3775 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
3776 tcg_gen_divu_i64(cpu_LO
[acc
], t0
, t1
);
3777 tcg_gen_remu_i64(cpu_HI
[acc
], t0
, t1
);
3783 tcg_gen_muls2_i64(cpu_LO
[acc
], cpu_HI
[acc
], t0
, t1
);
3786 tcg_gen_mulu2_i64(cpu_LO
[acc
], cpu_HI
[acc
], t0
, t1
);
3791 TCGv_i64 t2
= tcg_temp_new_i64();
3792 TCGv_i64 t3
= tcg_temp_new_i64();
3794 tcg_gen_ext_tl_i64(t2
, t0
);
3795 tcg_gen_ext_tl_i64(t3
, t1
);
3796 tcg_gen_mul_i64(t2
, t2
, t3
);
3797 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
3798 tcg_gen_add_i64(t2
, t2
, t3
);
3799 tcg_temp_free_i64(t3
);
3800 gen_move_low32(cpu_LO
[acc
], t2
);
3801 gen_move_high32(cpu_HI
[acc
], t2
);
3802 tcg_temp_free_i64(t2
);
3807 TCGv_i64 t2
= tcg_temp_new_i64();
3808 TCGv_i64 t3
= tcg_temp_new_i64();
3810 tcg_gen_ext32u_tl(t0
, t0
);
3811 tcg_gen_ext32u_tl(t1
, t1
);
3812 tcg_gen_extu_tl_i64(t2
, t0
);
3813 tcg_gen_extu_tl_i64(t3
, t1
);
3814 tcg_gen_mul_i64(t2
, t2
, t3
);
3815 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
3816 tcg_gen_add_i64(t2
, t2
, t3
);
3817 tcg_temp_free_i64(t3
);
3818 gen_move_low32(cpu_LO
[acc
], t2
);
3819 gen_move_high32(cpu_HI
[acc
], t2
);
3820 tcg_temp_free_i64(t2
);
3825 TCGv_i64 t2
= tcg_temp_new_i64();
3826 TCGv_i64 t3
= tcg_temp_new_i64();
3828 tcg_gen_ext_tl_i64(t2
, t0
);
3829 tcg_gen_ext_tl_i64(t3
, t1
);
3830 tcg_gen_mul_i64(t2
, t2
, t3
);
3831 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
3832 tcg_gen_sub_i64(t2
, t3
, t2
);
3833 tcg_temp_free_i64(t3
);
3834 gen_move_low32(cpu_LO
[acc
], t2
);
3835 gen_move_high32(cpu_HI
[acc
], t2
);
3836 tcg_temp_free_i64(t2
);
3841 TCGv_i64 t2
= tcg_temp_new_i64();
3842 TCGv_i64 t3
= tcg_temp_new_i64();
3844 tcg_gen_ext32u_tl(t0
, t0
);
3845 tcg_gen_ext32u_tl(t1
, t1
);
3846 tcg_gen_extu_tl_i64(t2
, t0
);
3847 tcg_gen_extu_tl_i64(t3
, t1
);
3848 tcg_gen_mul_i64(t2
, t2
, t3
);
3849 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
3850 tcg_gen_sub_i64(t2
, t3
, t2
);
3851 tcg_temp_free_i64(t3
);
3852 gen_move_low32(cpu_LO
[acc
], t2
);
3853 gen_move_high32(cpu_HI
[acc
], t2
);
3854 tcg_temp_free_i64(t2
);
3858 MIPS_INVAL("mul/div");
3859 gen_reserved_instruction(ctx
);
3868 * These MULT[U] and MADD[U] instructions implemented in for example
3869 * the Toshiba/Sony R5900 and the Toshiba TX19, TX39 and TX79 core
3870 * architectures are special three-operand variants with the syntax
3872 * MULT[U][1] rd, rs, rt
3876 * (rd, LO, HI) <- rs * rt
3880 * MADD[U][1] rd, rs, rt
3884 * (rd, LO, HI) <- (LO, HI) + rs * rt
3886 * where the low-order 32-bits of the result is placed into both the
3887 * GPR rd and the special register LO. The high-order 32-bits of the
3888 * result is placed into the special register HI.
3890 * If the GPR rd is omitted in assembly language, it is taken to be 0,
3891 * which is the zero register that always reads as 0.
3893 static void gen_mul_txx9(DisasContext
*ctx
, uint32_t opc
,
3894 int rd
, int rs
, int rt
)
3896 TCGv t0
= tcg_temp_new();
3897 TCGv t1
= tcg_temp_new();
3900 gen_load_gpr(t0
, rs
);
3901 gen_load_gpr(t1
, rt
);
3909 TCGv_i32 t2
= tcg_temp_new_i32();
3910 TCGv_i32 t3
= tcg_temp_new_i32();
3911 tcg_gen_trunc_tl_i32(t2
, t0
);
3912 tcg_gen_trunc_tl_i32(t3
, t1
);
3913 tcg_gen_muls2_i32(t2
, t3
, t2
, t3
);
3915 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
3917 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
3918 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
3919 tcg_temp_free_i32(t2
);
3920 tcg_temp_free_i32(t3
);
3923 case MMI_OPC_MULTU1
:
3928 TCGv_i32 t2
= tcg_temp_new_i32();
3929 TCGv_i32 t3
= tcg_temp_new_i32();
3930 tcg_gen_trunc_tl_i32(t2
, t0
);
3931 tcg_gen_trunc_tl_i32(t3
, t1
);
3932 tcg_gen_mulu2_i32(t2
, t3
, t2
, t3
);
3934 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
3936 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
3937 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
3938 tcg_temp_free_i32(t2
);
3939 tcg_temp_free_i32(t3
);
3947 TCGv_i64 t2
= tcg_temp_new_i64();
3948 TCGv_i64 t3
= tcg_temp_new_i64();
3950 tcg_gen_ext_tl_i64(t2
, t0
);
3951 tcg_gen_ext_tl_i64(t3
, t1
);
3952 tcg_gen_mul_i64(t2
, t2
, t3
);
3953 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
3954 tcg_gen_add_i64(t2
, t2
, t3
);
3955 tcg_temp_free_i64(t3
);
3956 gen_move_low32(cpu_LO
[acc
], t2
);
3957 gen_move_high32(cpu_HI
[acc
], t2
);
3959 gen_move_low32(cpu_gpr
[rd
], t2
);
3961 tcg_temp_free_i64(t2
);
3964 case MMI_OPC_MADDU1
:
3969 TCGv_i64 t2
= tcg_temp_new_i64();
3970 TCGv_i64 t3
= tcg_temp_new_i64();
3972 tcg_gen_ext32u_tl(t0
, t0
);
3973 tcg_gen_ext32u_tl(t1
, t1
);
3974 tcg_gen_extu_tl_i64(t2
, t0
);
3975 tcg_gen_extu_tl_i64(t3
, t1
);
3976 tcg_gen_mul_i64(t2
, t2
, t3
);
3977 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
3978 tcg_gen_add_i64(t2
, t2
, t3
);
3979 tcg_temp_free_i64(t3
);
3980 gen_move_low32(cpu_LO
[acc
], t2
);
3981 gen_move_high32(cpu_HI
[acc
], t2
);
3983 gen_move_low32(cpu_gpr
[rd
], t2
);
3985 tcg_temp_free_i64(t2
);
3989 MIPS_INVAL("mul/madd TXx9");
3990 gen_reserved_instruction(ctx
);
3999 static void gen_mul_vr54xx(DisasContext
*ctx
, uint32_t opc
,
4000 int rd
, int rs
, int rt
)
4002 TCGv t0
= tcg_temp_new();
4003 TCGv t1
= tcg_temp_new();
4005 gen_load_gpr(t0
, rs
);
4006 gen_load_gpr(t1
, rt
);
4009 case OPC_VR54XX_MULS
:
4010 gen_helper_muls(t0
, cpu_env
, t0
, t1
);
4012 case OPC_VR54XX_MULSU
:
4013 gen_helper_mulsu(t0
, cpu_env
, t0
, t1
);
4015 case OPC_VR54XX_MACC
:
4016 gen_helper_macc(t0
, cpu_env
, t0
, t1
);
4018 case OPC_VR54XX_MACCU
:
4019 gen_helper_maccu(t0
, cpu_env
, t0
, t1
);
4021 case OPC_VR54XX_MSAC
:
4022 gen_helper_msac(t0
, cpu_env
, t0
, t1
);
4024 case OPC_VR54XX_MSACU
:
4025 gen_helper_msacu(t0
, cpu_env
, t0
, t1
);
4027 case OPC_VR54XX_MULHI
:
4028 gen_helper_mulhi(t0
, cpu_env
, t0
, t1
);
4030 case OPC_VR54XX_MULHIU
:
4031 gen_helper_mulhiu(t0
, cpu_env
, t0
, t1
);
4033 case OPC_VR54XX_MULSHI
:
4034 gen_helper_mulshi(t0
, cpu_env
, t0
, t1
);
4036 case OPC_VR54XX_MULSHIU
:
4037 gen_helper_mulshiu(t0
, cpu_env
, t0
, t1
);
4039 case OPC_VR54XX_MACCHI
:
4040 gen_helper_macchi(t0
, cpu_env
, t0
, t1
);
4042 case OPC_VR54XX_MACCHIU
:
4043 gen_helper_macchiu(t0
, cpu_env
, t0
, t1
);
4045 case OPC_VR54XX_MSACHI
:
4046 gen_helper_msachi(t0
, cpu_env
, t0
, t1
);
4048 case OPC_VR54XX_MSACHIU
:
4049 gen_helper_msachiu(t0
, cpu_env
, t0
, t1
);
4052 MIPS_INVAL("mul vr54xx");
4053 gen_reserved_instruction(ctx
);
4056 gen_store_gpr(t0
, rd
);
4063 static void gen_cl(DisasContext
*ctx
, uint32_t opc
,
4073 gen_load_gpr(t0
, rs
);
4078 #if defined(TARGET_MIPS64)
4082 tcg_gen_not_tl(t0
, t0
);
4091 tcg_gen_ext32u_tl(t0
, t0
);
4092 tcg_gen_clzi_tl(t0
, t0
, TARGET_LONG_BITS
);
4093 tcg_gen_subi_tl(t0
, t0
, TARGET_LONG_BITS
- 32);
4095 #if defined(TARGET_MIPS64)
4100 tcg_gen_clzi_i64(t0
, t0
, 64);
4106 /* Godson integer instructions */
4107 static void gen_loongson_integer(DisasContext
*ctx
, uint32_t opc
,
4108 int rd
, int rs
, int rt
)
4120 case OPC_MULTU_G_2E
:
4121 case OPC_MULTU_G_2F
:
4122 #if defined(TARGET_MIPS64)
4123 case OPC_DMULT_G_2E
:
4124 case OPC_DMULT_G_2F
:
4125 case OPC_DMULTU_G_2E
:
4126 case OPC_DMULTU_G_2F
:
4128 t0
= tcg_temp_new();
4129 t1
= tcg_temp_new();
4132 t0
= tcg_temp_local_new();
4133 t1
= tcg_temp_local_new();
4137 gen_load_gpr(t0
, rs
);
4138 gen_load_gpr(t1
, rt
);
4143 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
4144 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
4146 case OPC_MULTU_G_2E
:
4147 case OPC_MULTU_G_2F
:
4148 tcg_gen_ext32u_tl(t0
, t0
);
4149 tcg_gen_ext32u_tl(t1
, t1
);
4150 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
4151 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
4156 TCGLabel
*l1
= gen_new_label();
4157 TCGLabel
*l2
= gen_new_label();
4158 TCGLabel
*l3
= gen_new_label();
4159 tcg_gen_ext32s_tl(t0
, t0
);
4160 tcg_gen_ext32s_tl(t1
, t1
);
4161 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
4162 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4165 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, INT_MIN
, l2
);
4166 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1, l2
);
4167 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
4170 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
4171 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
4178 TCGLabel
*l1
= gen_new_label();
4179 TCGLabel
*l2
= gen_new_label();
4180 tcg_gen_ext32u_tl(t0
, t0
);
4181 tcg_gen_ext32u_tl(t1
, t1
);
4182 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
4183 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4186 tcg_gen_divu_tl(cpu_gpr
[rd
], t0
, t1
);
4187 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
4194 TCGLabel
*l1
= gen_new_label();
4195 TCGLabel
*l2
= gen_new_label();
4196 TCGLabel
*l3
= gen_new_label();
4197 tcg_gen_ext32u_tl(t0
, t0
);
4198 tcg_gen_ext32u_tl(t1
, t1
);
4199 tcg_gen_brcondi_tl(TCG_COND_EQ
, t1
, 0, l1
);
4200 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, INT_MIN
, l2
);
4201 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1, l2
);
4203 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4206 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
4207 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
4214 TCGLabel
*l1
= gen_new_label();
4215 TCGLabel
*l2
= gen_new_label();
4216 tcg_gen_ext32u_tl(t0
, t0
);
4217 tcg_gen_ext32u_tl(t1
, t1
);
4218 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
4219 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4222 tcg_gen_remu_tl(cpu_gpr
[rd
], t0
, t1
);
4223 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
4227 #if defined(TARGET_MIPS64)
4228 case OPC_DMULT_G_2E
:
4229 case OPC_DMULT_G_2F
:
4230 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
4232 case OPC_DMULTU_G_2E
:
4233 case OPC_DMULTU_G_2F
:
4234 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
4239 TCGLabel
*l1
= gen_new_label();
4240 TCGLabel
*l2
= gen_new_label();
4241 TCGLabel
*l3
= gen_new_label();
4242 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
4243 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4246 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, -1LL << 63, l2
);
4247 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1LL, l2
);
4248 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
4251 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
4255 case OPC_DDIVU_G_2E
:
4256 case OPC_DDIVU_G_2F
:
4258 TCGLabel
*l1
= gen_new_label();
4259 TCGLabel
*l2
= gen_new_label();
4260 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
4261 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4264 tcg_gen_divu_tl(cpu_gpr
[rd
], t0
, t1
);
4271 TCGLabel
*l1
= gen_new_label();
4272 TCGLabel
*l2
= gen_new_label();
4273 TCGLabel
*l3
= gen_new_label();
4274 tcg_gen_brcondi_tl(TCG_COND_EQ
, t1
, 0, l1
);
4275 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, -1LL << 63, l2
);
4276 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1LL, l2
);
4278 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4281 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
4285 case OPC_DMODU_G_2E
:
4286 case OPC_DMODU_G_2F
:
4288 TCGLabel
*l1
= gen_new_label();
4289 TCGLabel
*l2
= gen_new_label();
4290 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
4291 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4294 tcg_gen_remu_tl(cpu_gpr
[rd
], t0
, t1
);
4305 /* Loongson multimedia instructions */
4306 static void gen_loongson_multimedia(DisasContext
*ctx
, int rd
, int rs
, int rt
)
4308 uint32_t opc
, shift_max
;
4312 opc
= MASK_LMMI(ctx
->opcode
);
4318 t0
= tcg_temp_local_new_i64();
4319 t1
= tcg_temp_local_new_i64();
4322 t0
= tcg_temp_new_i64();
4323 t1
= tcg_temp_new_i64();
4327 check_cp1_enabled(ctx
);
4328 gen_load_fpr64(ctx
, t0
, rs
);
4329 gen_load_fpr64(ctx
, t1
, rt
);
4333 gen_helper_paddsh(t0
, t0
, t1
);
4336 gen_helper_paddush(t0
, t0
, t1
);
4339 gen_helper_paddh(t0
, t0
, t1
);
4342 gen_helper_paddw(t0
, t0
, t1
);
4345 gen_helper_paddsb(t0
, t0
, t1
);
4348 gen_helper_paddusb(t0
, t0
, t1
);
4351 gen_helper_paddb(t0
, t0
, t1
);
4355 gen_helper_psubsh(t0
, t0
, t1
);
4358 gen_helper_psubush(t0
, t0
, t1
);
4361 gen_helper_psubh(t0
, t0
, t1
);
4364 gen_helper_psubw(t0
, t0
, t1
);
4367 gen_helper_psubsb(t0
, t0
, t1
);
4370 gen_helper_psubusb(t0
, t0
, t1
);
4373 gen_helper_psubb(t0
, t0
, t1
);
4377 gen_helper_pshufh(t0
, t0
, t1
);
4380 gen_helper_packsswh(t0
, t0
, t1
);
4383 gen_helper_packsshb(t0
, t0
, t1
);
4386 gen_helper_packushb(t0
, t0
, t1
);
4390 gen_helper_punpcklhw(t0
, t0
, t1
);
4393 gen_helper_punpckhhw(t0
, t0
, t1
);
4396 gen_helper_punpcklbh(t0
, t0
, t1
);
4399 gen_helper_punpckhbh(t0
, t0
, t1
);
4402 gen_helper_punpcklwd(t0
, t0
, t1
);
4405 gen_helper_punpckhwd(t0
, t0
, t1
);
4409 gen_helper_pavgh(t0
, t0
, t1
);
4412 gen_helper_pavgb(t0
, t0
, t1
);
4415 gen_helper_pmaxsh(t0
, t0
, t1
);
4418 gen_helper_pminsh(t0
, t0
, t1
);
4421 gen_helper_pmaxub(t0
, t0
, t1
);
4424 gen_helper_pminub(t0
, t0
, t1
);
4428 gen_helper_pcmpeqw(t0
, t0
, t1
);
4431 gen_helper_pcmpgtw(t0
, t0
, t1
);
4434 gen_helper_pcmpeqh(t0
, t0
, t1
);
4437 gen_helper_pcmpgth(t0
, t0
, t1
);
4440 gen_helper_pcmpeqb(t0
, t0
, t1
);
4443 gen_helper_pcmpgtb(t0
, t0
, t1
);
4447 gen_helper_psllw(t0
, t0
, t1
);
4450 gen_helper_psllh(t0
, t0
, t1
);
4453 gen_helper_psrlw(t0
, t0
, t1
);
4456 gen_helper_psrlh(t0
, t0
, t1
);
4459 gen_helper_psraw(t0
, t0
, t1
);
4462 gen_helper_psrah(t0
, t0
, t1
);
4466 gen_helper_pmullh(t0
, t0
, t1
);
4469 gen_helper_pmulhh(t0
, t0
, t1
);
4472 gen_helper_pmulhuh(t0
, t0
, t1
);
4475 gen_helper_pmaddhw(t0
, t0
, t1
);
4479 gen_helper_pasubub(t0
, t0
, t1
);
4482 gen_helper_biadd(t0
, t0
);
4485 gen_helper_pmovmskb(t0
, t0
);
4489 tcg_gen_add_i64(t0
, t0
, t1
);
4492 tcg_gen_sub_i64(t0
, t0
, t1
);
4495 tcg_gen_xor_i64(t0
, t0
, t1
);
4498 tcg_gen_nor_i64(t0
, t0
, t1
);
4501 tcg_gen_and_i64(t0
, t0
, t1
);
4504 tcg_gen_or_i64(t0
, t0
, t1
);
4508 tcg_gen_andc_i64(t0
, t1
, t0
);
4512 tcg_gen_deposit_i64(t0
, t0
, t1
, 0, 16);
4515 tcg_gen_deposit_i64(t0
, t0
, t1
, 16, 16);
4518 tcg_gen_deposit_i64(t0
, t0
, t1
, 32, 16);
4521 tcg_gen_deposit_i64(t0
, t0
, t1
, 48, 16);
4525 tcg_gen_andi_i64(t1
, t1
, 3);
4526 tcg_gen_shli_i64(t1
, t1
, 4);
4527 tcg_gen_shr_i64(t0
, t0
, t1
);
4528 tcg_gen_ext16u_i64(t0
, t0
);
4532 tcg_gen_add_i64(t0
, t0
, t1
);
4533 tcg_gen_ext32s_i64(t0
, t0
);
4536 tcg_gen_sub_i64(t0
, t0
, t1
);
4537 tcg_gen_ext32s_i64(t0
, t0
);
4559 /* Make sure shift count isn't TCG undefined behaviour. */
4560 tcg_gen_andi_i64(t1
, t1
, shift_max
- 1);
4565 tcg_gen_shl_i64(t0
, t0
, t1
);
4570 * Since SRA is UndefinedResult without sign-extended inputs,
4571 * we can treat SRA and DSRA the same.
4573 tcg_gen_sar_i64(t0
, t0
, t1
);
4576 /* We want to shift in zeros for SRL; zero-extend first. */
4577 tcg_gen_ext32u_i64(t0
, t0
);
4580 tcg_gen_shr_i64(t0
, t0
, t1
);
4584 if (shift_max
== 32) {
4585 tcg_gen_ext32s_i64(t0
, t0
);
4588 /* Shifts larger than MAX produce zero. */
4589 tcg_gen_setcondi_i64(TCG_COND_LTU
, t1
, t1
, shift_max
);
4590 tcg_gen_neg_i64(t1
, t1
);
4591 tcg_gen_and_i64(t0
, t0
, t1
);
4597 TCGv_i64 t2
= tcg_temp_new_i64();
4598 TCGLabel
*lab
= gen_new_label();
4600 tcg_gen_mov_i64(t2
, t0
);
4601 tcg_gen_add_i64(t0
, t1
, t2
);
4602 if (opc
== OPC_ADD_CP2
) {
4603 tcg_gen_ext32s_i64(t0
, t0
);
4605 tcg_gen_xor_i64(t1
, t1
, t2
);
4606 tcg_gen_xor_i64(t2
, t2
, t0
);
4607 tcg_gen_andc_i64(t1
, t2
, t1
);
4608 tcg_temp_free_i64(t2
);
4609 tcg_gen_brcondi_i64(TCG_COND_GE
, t1
, 0, lab
);
4610 generate_exception(ctx
, EXCP_OVERFLOW
);
4618 TCGv_i64 t2
= tcg_temp_new_i64();
4619 TCGLabel
*lab
= gen_new_label();
4621 tcg_gen_mov_i64(t2
, t0
);
4622 tcg_gen_sub_i64(t0
, t1
, t2
);
4623 if (opc
== OPC_SUB_CP2
) {
4624 tcg_gen_ext32s_i64(t0
, t0
);
4626 tcg_gen_xor_i64(t1
, t1
, t2
);
4627 tcg_gen_xor_i64(t2
, t2
, t0
);
4628 tcg_gen_and_i64(t1
, t1
, t2
);
4629 tcg_temp_free_i64(t2
);
4630 tcg_gen_brcondi_i64(TCG_COND_GE
, t1
, 0, lab
);
4631 generate_exception(ctx
, EXCP_OVERFLOW
);
4637 tcg_gen_ext32u_i64(t0
, t0
);
4638 tcg_gen_ext32u_i64(t1
, t1
);
4639 tcg_gen_mul_i64(t0
, t0
, t1
);
4648 cond
= TCG_COND_LTU
;
4656 cond
= TCG_COND_LEU
;
4663 int cc
= (ctx
->opcode
>> 8) & 0x7;
4664 TCGv_i64 t64
= tcg_temp_new_i64();
4665 TCGv_i32 t32
= tcg_temp_new_i32();
4667 tcg_gen_setcond_i64(cond
, t64
, t0
, t1
);
4668 tcg_gen_extrl_i64_i32(t32
, t64
);
4669 tcg_gen_deposit_i32(fpu_fcr31
, fpu_fcr31
, t32
,
4672 tcg_temp_free_i32(t32
);
4673 tcg_temp_free_i64(t64
);
4678 MIPS_INVAL("loongson_cp2");
4679 gen_reserved_instruction(ctx
);
4683 gen_store_fpr64(ctx
, t0
, rd
);
4686 tcg_temp_free_i64(t0
);
4687 tcg_temp_free_i64(t1
);
4690 static void gen_loongson_lswc2(DisasContext
*ctx
, int rt
,
4695 #if defined(TARGET_MIPS64)
4696 int lsq_rt1
= ctx
->opcode
& 0x1f;
4697 int lsq_offset
= sextract32(ctx
->opcode
, 6, 9) << 4;
4699 int shf_offset
= sextract32(ctx
->opcode
, 6, 8);
4701 t0
= tcg_temp_new();
4703 switch (MASK_LOONGSON_GSLSQ(ctx
->opcode
)) {
4704 #if defined(TARGET_MIPS64)
4706 t1
= tcg_temp_new();
4707 gen_base_offset_addr(ctx
, t0
, rs
, lsq_offset
);
4708 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
|
4709 ctx
->default_tcg_memop_mask
);
4710 gen_base_offset_addr(ctx
, t0
, rs
, lsq_offset
+ 8);
4711 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
|
4712 ctx
->default_tcg_memop_mask
);
4713 gen_store_gpr(t1
, rt
);
4714 gen_store_gpr(t0
, lsq_rt1
);
4718 check_cp1_enabled(ctx
);
4719 t1
= tcg_temp_new();
4720 gen_base_offset_addr(ctx
, t0
, rs
, lsq_offset
);
4721 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
|
4722 ctx
->default_tcg_memop_mask
);
4723 gen_base_offset_addr(ctx
, t0
, rs
, lsq_offset
+ 8);
4724 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
|
4725 ctx
->default_tcg_memop_mask
);
4726 gen_store_fpr64(ctx
, t1
, rt
);
4727 gen_store_fpr64(ctx
, t0
, lsq_rt1
);
4731 t1
= tcg_temp_new();
4732 gen_base_offset_addr(ctx
, t0
, rs
, lsq_offset
);
4733 gen_load_gpr(t1
, rt
);
4734 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
|
4735 ctx
->default_tcg_memop_mask
);
4736 gen_base_offset_addr(ctx
, t0
, rs
, lsq_offset
+ 8);
4737 gen_load_gpr(t1
, lsq_rt1
);
4738 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
|
4739 ctx
->default_tcg_memop_mask
);
4743 check_cp1_enabled(ctx
);
4744 t1
= tcg_temp_new();
4745 gen_base_offset_addr(ctx
, t0
, rs
, lsq_offset
);
4746 gen_load_fpr64(ctx
, t1
, rt
);
4747 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
|
4748 ctx
->default_tcg_memop_mask
);
4749 gen_base_offset_addr(ctx
, t0
, rs
, lsq_offset
+ 8);
4750 gen_load_fpr64(ctx
, t1
, lsq_rt1
);
4751 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
|
4752 ctx
->default_tcg_memop_mask
);
4757 switch (MASK_LOONGSON_GSSHFLS(ctx
->opcode
)) {
4759 check_cp1_enabled(ctx
);
4760 gen_base_offset_addr(ctx
, t0
, rs
, shf_offset
);
4761 t1
= tcg_temp_new();
4762 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
4763 tcg_gen_andi_tl(t1
, t0
, 3);
4764 #ifndef TARGET_WORDS_BIGENDIAN
4765 tcg_gen_xori_tl(t1
, t1
, 3);
4767 tcg_gen_shli_tl(t1
, t1
, 3);
4768 tcg_gen_andi_tl(t0
, t0
, ~3);
4769 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEUL
);
4770 tcg_gen_shl_tl(t0
, t0
, t1
);
4771 t2
= tcg_const_tl(-1);
4772 tcg_gen_shl_tl(t2
, t2
, t1
);
4773 fp0
= tcg_temp_new_i32();
4774 gen_load_fpr32(ctx
, fp0
, rt
);
4775 tcg_gen_ext_i32_tl(t1
, fp0
);
4776 tcg_gen_andc_tl(t1
, t1
, t2
);
4778 tcg_gen_or_tl(t0
, t0
, t1
);
4780 #if defined(TARGET_MIPS64)
4781 tcg_gen_extrl_i64_i32(fp0
, t0
);
4783 tcg_gen_ext32s_tl(fp0
, t0
);
4785 gen_store_fpr32(ctx
, fp0
, rt
);
4786 tcg_temp_free_i32(fp0
);
4789 check_cp1_enabled(ctx
);
4790 gen_base_offset_addr(ctx
, t0
, rs
, shf_offset
);
4791 t1
= tcg_temp_new();
4792 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
4793 tcg_gen_andi_tl(t1
, t0
, 3);
4794 #ifdef TARGET_WORDS_BIGENDIAN
4795 tcg_gen_xori_tl(t1
, t1
, 3);
4797 tcg_gen_shli_tl(t1
, t1
, 3);
4798 tcg_gen_andi_tl(t0
, t0
, ~3);
4799 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEUL
);
4800 tcg_gen_shr_tl(t0
, t0
, t1
);
4801 tcg_gen_xori_tl(t1
, t1
, 31);
4802 t2
= tcg_const_tl(0xfffffffeull
);
4803 tcg_gen_shl_tl(t2
, t2
, t1
);
4804 fp0
= tcg_temp_new_i32();
4805 gen_load_fpr32(ctx
, fp0
, rt
);
4806 tcg_gen_ext_i32_tl(t1
, fp0
);
4807 tcg_gen_and_tl(t1
, t1
, t2
);
4809 tcg_gen_or_tl(t0
, t0
, t1
);
4811 #if defined(TARGET_MIPS64)
4812 tcg_gen_extrl_i64_i32(fp0
, t0
);
4814 tcg_gen_ext32s_tl(fp0
, t0
);
4816 gen_store_fpr32(ctx
, fp0
, rt
);
4817 tcg_temp_free_i32(fp0
);
4819 #if defined(TARGET_MIPS64)
4821 check_cp1_enabled(ctx
);
4822 gen_base_offset_addr(ctx
, t0
, rs
, shf_offset
);
4823 t1
= tcg_temp_new();
4824 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
4825 tcg_gen_andi_tl(t1
, t0
, 7);
4826 #ifndef TARGET_WORDS_BIGENDIAN
4827 tcg_gen_xori_tl(t1
, t1
, 7);
4829 tcg_gen_shli_tl(t1
, t1
, 3);
4830 tcg_gen_andi_tl(t0
, t0
, ~7);
4831 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
);
4832 tcg_gen_shl_tl(t0
, t0
, t1
);
4833 t2
= tcg_const_tl(-1);
4834 tcg_gen_shl_tl(t2
, t2
, t1
);
4835 gen_load_fpr64(ctx
, t1
, rt
);
4836 tcg_gen_andc_tl(t1
, t1
, t2
);
4838 tcg_gen_or_tl(t0
, t0
, t1
);
4840 gen_store_fpr64(ctx
, t0
, rt
);
4843 check_cp1_enabled(ctx
);
4844 gen_base_offset_addr(ctx
, t0
, rs
, shf_offset
);
4845 t1
= tcg_temp_new();
4846 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
4847 tcg_gen_andi_tl(t1
, t0
, 7);
4848 #ifdef TARGET_WORDS_BIGENDIAN
4849 tcg_gen_xori_tl(t1
, t1
, 7);
4851 tcg_gen_shli_tl(t1
, t1
, 3);
4852 tcg_gen_andi_tl(t0
, t0
, ~7);
4853 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
);
4854 tcg_gen_shr_tl(t0
, t0
, t1
);
4855 tcg_gen_xori_tl(t1
, t1
, 63);
4856 t2
= tcg_const_tl(0xfffffffffffffffeull
);
4857 tcg_gen_shl_tl(t2
, t2
, t1
);
4858 gen_load_fpr64(ctx
, t1
, rt
);
4859 tcg_gen_and_tl(t1
, t1
, t2
);
4861 tcg_gen_or_tl(t0
, t0
, t1
);
4863 gen_store_fpr64(ctx
, t0
, rt
);
4867 MIPS_INVAL("loongson_gsshfl");
4868 gen_reserved_instruction(ctx
);
4873 switch (MASK_LOONGSON_GSSHFLS(ctx
->opcode
)) {
4875 check_cp1_enabled(ctx
);
4876 t1
= tcg_temp_new();
4877 gen_base_offset_addr(ctx
, t0
, rs
, shf_offset
);
4878 fp0
= tcg_temp_new_i32();
4879 gen_load_fpr32(ctx
, fp0
, rt
);
4880 tcg_gen_ext_i32_tl(t1
, fp0
);
4881 gen_helper_0e2i(swl
, t1
, t0
, ctx
->mem_idx
);
4882 tcg_temp_free_i32(fp0
);
4886 check_cp1_enabled(ctx
);
4887 t1
= tcg_temp_new();
4888 gen_base_offset_addr(ctx
, t0
, rs
, shf_offset
);
4889 fp0
= tcg_temp_new_i32();
4890 gen_load_fpr32(ctx
, fp0
, rt
);
4891 tcg_gen_ext_i32_tl(t1
, fp0
);
4892 gen_helper_0e2i(swr
, t1
, t0
, ctx
->mem_idx
);
4893 tcg_temp_free_i32(fp0
);
4896 #if defined(TARGET_MIPS64)
4898 check_cp1_enabled(ctx
);
4899 t1
= tcg_temp_new();
4900 gen_base_offset_addr(ctx
, t0
, rs
, shf_offset
);
4901 gen_load_fpr64(ctx
, t1
, rt
);
4902 gen_helper_0e2i(sdl
, t1
, t0
, ctx
->mem_idx
);
4906 check_cp1_enabled(ctx
);
4907 t1
= tcg_temp_new();
4908 gen_base_offset_addr(ctx
, t0
, rs
, shf_offset
);
4909 gen_load_fpr64(ctx
, t1
, rt
);
4910 gen_helper_0e2i(sdr
, t1
, t0
, ctx
->mem_idx
);
4915 MIPS_INVAL("loongson_gsshfs");
4916 gen_reserved_instruction(ctx
);
4921 MIPS_INVAL("loongson_gslsq");
4922 gen_reserved_instruction(ctx
);
4928 /* Loongson EXT LDC2/SDC2 */
4929 static void gen_loongson_lsdc2(DisasContext
*ctx
, int rt
,
4932 int offset
= sextract32(ctx
->opcode
, 3, 8);
4933 uint32_t opc
= MASK_LOONGSON_LSDC2(ctx
->opcode
);
4937 /* Pre-conditions */
4943 /* prefetch, implement as NOP */
4954 #if defined(TARGET_MIPS64)
4957 check_cp1_enabled(ctx
);
4958 /* prefetch, implement as NOP */
4964 #if defined(TARGET_MIPS64)
4967 check_cp1_enabled(ctx
);
4970 MIPS_INVAL("loongson_lsdc2");
4971 gen_reserved_instruction(ctx
);
4976 t0
= tcg_temp_new();
4978 gen_base_offset_addr(ctx
, t0
, rs
, offset
);
4979 gen_op_addr_add(ctx
, t0
, cpu_gpr
[rd
], t0
);
4983 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_SB
);
4984 gen_store_gpr(t0
, rt
);
4987 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESW
|
4988 ctx
->default_tcg_memop_mask
);
4989 gen_store_gpr(t0
, rt
);
4992 gen_base_offset_addr(ctx
, t0
, rs
, offset
);
4994 gen_op_addr_add(ctx
, t0
, cpu_gpr
[rd
], t0
);
4996 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESL
|
4997 ctx
->default_tcg_memop_mask
);
4998 gen_store_gpr(t0
, rt
);
5000 #if defined(TARGET_MIPS64)
5002 gen_base_offset_addr(ctx
, t0
, rs
, offset
);
5004 gen_op_addr_add(ctx
, t0
, cpu_gpr
[rd
], t0
);
5006 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
|
5007 ctx
->default_tcg_memop_mask
);
5008 gen_store_gpr(t0
, rt
);
5012 check_cp1_enabled(ctx
);
5013 gen_base_offset_addr(ctx
, t0
, rs
, offset
);
5015 gen_op_addr_add(ctx
, t0
, cpu_gpr
[rd
], t0
);
5017 fp0
= tcg_temp_new_i32();
5018 tcg_gen_qemu_ld_i32(fp0
, t0
, ctx
->mem_idx
, MO_TESL
|
5019 ctx
->default_tcg_memop_mask
);
5020 gen_store_fpr32(ctx
, fp0
, rt
);
5021 tcg_temp_free_i32(fp0
);
5023 #if defined(TARGET_MIPS64)
5025 check_cp1_enabled(ctx
);
5026 gen_base_offset_addr(ctx
, t0
, rs
, offset
);
5028 gen_op_addr_add(ctx
, t0
, cpu_gpr
[rd
], t0
);
5030 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
|
5031 ctx
->default_tcg_memop_mask
);
5032 gen_store_fpr64(ctx
, t0
, rt
);
5036 t1
= tcg_temp_new();
5037 gen_load_gpr(t1
, rt
);
5038 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_SB
);
5042 t1
= tcg_temp_new();
5043 gen_load_gpr(t1
, rt
);
5044 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUW
|
5045 ctx
->default_tcg_memop_mask
);
5049 t1
= tcg_temp_new();
5050 gen_load_gpr(t1
, rt
);
5051 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
|
5052 ctx
->default_tcg_memop_mask
);
5055 #if defined(TARGET_MIPS64)
5057 t1
= tcg_temp_new();
5058 gen_load_gpr(t1
, rt
);
5059 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
|
5060 ctx
->default_tcg_memop_mask
);
5065 fp0
= tcg_temp_new_i32();
5066 gen_load_fpr32(ctx
, fp0
, rt
);
5067 tcg_gen_qemu_st_i32(fp0
, t0
, ctx
->mem_idx
, MO_TEUL
|
5068 ctx
->default_tcg_memop_mask
);
5069 tcg_temp_free_i32(fp0
);
5071 #if defined(TARGET_MIPS64)
5073 t1
= tcg_temp_new();
5074 gen_load_fpr64(ctx
, t1
, rt
);
5075 tcg_gen_qemu_st_i64(t1
, t0
, ctx
->mem_idx
, MO_TEQ
|
5076 ctx
->default_tcg_memop_mask
);
5088 static void gen_trap(DisasContext
*ctx
, uint32_t opc
,
5089 int rs
, int rt
, int16_t imm
)
5092 TCGv t0
= tcg_temp_new();
5093 TCGv t1
= tcg_temp_new();
5096 /* Load needed operands */
5104 /* Compare two registers */
5106 gen_load_gpr(t0
, rs
);
5107 gen_load_gpr(t1
, rt
);
5117 /* Compare register to immediate */
5118 if (rs
!= 0 || imm
!= 0) {
5119 gen_load_gpr(t0
, rs
);
5120 tcg_gen_movi_tl(t1
, (int32_t)imm
);
5127 case OPC_TEQ
: /* rs == rs */
5128 case OPC_TEQI
: /* r0 == 0 */
5129 case OPC_TGE
: /* rs >= rs */
5130 case OPC_TGEI
: /* r0 >= 0 */
5131 case OPC_TGEU
: /* rs >= rs unsigned */
5132 case OPC_TGEIU
: /* r0 >= 0 unsigned */
5134 generate_exception_end(ctx
, EXCP_TRAP
);
5136 case OPC_TLT
: /* rs < rs */
5137 case OPC_TLTI
: /* r0 < 0 */
5138 case OPC_TLTU
: /* rs < rs unsigned */
5139 case OPC_TLTIU
: /* r0 < 0 unsigned */
5140 case OPC_TNE
: /* rs != rs */
5141 case OPC_TNEI
: /* r0 != 0 */
5142 /* Never trap: treat as NOP. */
5146 TCGLabel
*l1
= gen_new_label();
5151 tcg_gen_brcond_tl(TCG_COND_NE
, t0
, t1
, l1
);
5155 tcg_gen_brcond_tl(TCG_COND_LT
, t0
, t1
, l1
);
5159 tcg_gen_brcond_tl(TCG_COND_LTU
, t0
, t1
, l1
);
5163 tcg_gen_brcond_tl(TCG_COND_GE
, t0
, t1
, l1
);
5167 tcg_gen_brcond_tl(TCG_COND_GEU
, t0
, t1
, l1
);
5171 tcg_gen_brcond_tl(TCG_COND_EQ
, t0
, t1
, l1
);
5174 generate_exception(ctx
, EXCP_TRAP
);
5181 static inline bool use_goto_tb(DisasContext
*ctx
, target_ulong dest
)
5183 if (unlikely(ctx
->base
.singlestep_enabled
)) {
5187 #ifndef CONFIG_USER_ONLY
5188 return (ctx
->base
.tb
->pc
& TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
);
5194 static inline void gen_goto_tb(DisasContext
*ctx
, int n
, target_ulong dest
)
5196 if (use_goto_tb(ctx
, dest
)) {
5199 tcg_gen_exit_tb(ctx
->base
.tb
, n
);
5202 if (ctx
->base
.singlestep_enabled
) {
5203 save_cpu_state(ctx
, 0);
5204 gen_helper_raise_exception_debug(cpu_env
);
5206 tcg_gen_lookup_and_goto_ptr();
5210 /* Branches (before delay slot) */
5211 static void gen_compute_branch(DisasContext
*ctx
, uint32_t opc
,
5213 int rs
, int rt
, int32_t offset
,
5216 target_ulong btgt
= -1;
5218 int bcond_compute
= 0;
5219 TCGv t0
= tcg_temp_new();
5220 TCGv t1
= tcg_temp_new();
5222 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
5223 #ifdef MIPS_DEBUG_DISAS
5224 LOG_DISAS("Branch in delay / forbidden slot at PC 0x"
5225 TARGET_FMT_lx
"\n", ctx
->base
.pc_next
);
5227 gen_reserved_instruction(ctx
);
5231 /* Load needed operands */
5237 /* Compare two registers */
5239 gen_load_gpr(t0
, rs
);
5240 gen_load_gpr(t1
, rt
);
5243 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ offset
;
5257 /* Compare to zero */
5259 gen_load_gpr(t0
, rs
);
5262 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ offset
;
5265 #if defined(TARGET_MIPS64)
5267 tcg_gen_andi_tl(t0
, cpu_dspctrl
, 0x7F);
5269 tcg_gen_andi_tl(t0
, cpu_dspctrl
, 0x3F);
5272 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ offset
;
5277 /* Jump to immediate */
5278 btgt
= ((ctx
->base
.pc_next
+ insn_bytes
) & (int32_t)0xF0000000) |
5283 /* Jump to register */
5284 if (offset
!= 0 && offset
!= 16) {
5286 * Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
5287 * others are reserved.
5289 MIPS_INVAL("jump hint");
5290 gen_reserved_instruction(ctx
);
5293 gen_load_gpr(btarget
, rs
);
5296 MIPS_INVAL("branch/jump");
5297 gen_reserved_instruction(ctx
);
5300 if (bcond_compute
== 0) {
5301 /* No condition to be computed */
5303 case OPC_BEQ
: /* rx == rx */
5304 case OPC_BEQL
: /* rx == rx likely */
5305 case OPC_BGEZ
: /* 0 >= 0 */
5306 case OPC_BGEZL
: /* 0 >= 0 likely */
5307 case OPC_BLEZ
: /* 0 <= 0 */
5308 case OPC_BLEZL
: /* 0 <= 0 likely */
5310 ctx
->hflags
|= MIPS_HFLAG_B
;
5312 case OPC_BGEZAL
: /* 0 >= 0 */
5313 case OPC_BGEZALL
: /* 0 >= 0 likely */
5314 /* Always take and link */
5316 ctx
->hflags
|= MIPS_HFLAG_B
;
5318 case OPC_BNE
: /* rx != rx */
5319 case OPC_BGTZ
: /* 0 > 0 */
5320 case OPC_BLTZ
: /* 0 < 0 */
5323 case OPC_BLTZAL
: /* 0 < 0 */
5325 * Handle as an unconditional branch to get correct delay
5329 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ delayslot_size
;
5330 ctx
->hflags
|= MIPS_HFLAG_B
;
5332 case OPC_BLTZALL
: /* 0 < 0 likely */
5333 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 8);
5334 /* Skip the instruction in the delay slot */
5335 ctx
->base
.pc_next
+= 4;
5337 case OPC_BNEL
: /* rx != rx likely */
5338 case OPC_BGTZL
: /* 0 > 0 likely */
5339 case OPC_BLTZL
: /* 0 < 0 likely */
5340 /* Skip the instruction in the delay slot */
5341 ctx
->base
.pc_next
+= 4;
5344 ctx
->hflags
|= MIPS_HFLAG_B
;
5347 ctx
->hflags
|= MIPS_HFLAG_BX
;
5351 ctx
->hflags
|= MIPS_HFLAG_B
;
5354 ctx
->hflags
|= MIPS_HFLAG_BR
;
5358 ctx
->hflags
|= MIPS_HFLAG_BR
;
5361 MIPS_INVAL("branch/jump");
5362 gen_reserved_instruction(ctx
);
5368 tcg_gen_setcond_tl(TCG_COND_EQ
, bcond
, t0
, t1
);
5371 tcg_gen_setcond_tl(TCG_COND_EQ
, bcond
, t0
, t1
);
5374 tcg_gen_setcond_tl(TCG_COND_NE
, bcond
, t0
, t1
);
5377 tcg_gen_setcond_tl(TCG_COND_NE
, bcond
, t0
, t1
);
5380 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
5383 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
5386 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
5390 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
5394 tcg_gen_setcondi_tl(TCG_COND_GT
, bcond
, t0
, 0);
5397 tcg_gen_setcondi_tl(TCG_COND_GT
, bcond
, t0
, 0);
5400 tcg_gen_setcondi_tl(TCG_COND_LE
, bcond
, t0
, 0);
5403 tcg_gen_setcondi_tl(TCG_COND_LE
, bcond
, t0
, 0);
5406 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
5409 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
5412 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 32);
5414 #if defined(TARGET_MIPS64)
5416 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 64);
5420 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
5423 ctx
->hflags
|= MIPS_HFLAG_BC
;
5426 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
5429 ctx
->hflags
|= MIPS_HFLAG_BL
;
5432 MIPS_INVAL("conditional branch/jump");
5433 gen_reserved_instruction(ctx
);
5438 ctx
->btarget
= btgt
;
5440 switch (delayslot_size
) {
5442 ctx
->hflags
|= MIPS_HFLAG_BDS16
;
5445 ctx
->hflags
|= MIPS_HFLAG_BDS32
;
5450 int post_delay
= insn_bytes
+ delayslot_size
;
5451 int lowbit
= !!(ctx
->hflags
& MIPS_HFLAG_M16
);
5453 tcg_gen_movi_tl(cpu_gpr
[blink
],
5454 ctx
->base
.pc_next
+ post_delay
+ lowbit
);
5458 if (insn_bytes
== 2) {
5459 ctx
->hflags
|= MIPS_HFLAG_B16
;
5466 /* nanoMIPS Branches */
5467 static void gen_compute_branch_nm(DisasContext
*ctx
, uint32_t opc
,
5469 int rs
, int rt
, int32_t offset
)
5471 target_ulong btgt
= -1;
5472 int bcond_compute
= 0;
5473 TCGv t0
= tcg_temp_new();
5474 TCGv t1
= tcg_temp_new();
5476 /* Load needed operands */
5480 /* Compare two registers */
5482 gen_load_gpr(t0
, rs
);
5483 gen_load_gpr(t1
, rt
);
5486 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ offset
;
5489 /* Compare to zero */
5491 gen_load_gpr(t0
, rs
);
5494 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ offset
;
5497 tcg_gen_andi_tl(t0
, cpu_dspctrl
, 0x3F);
5499 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ offset
;
5503 /* Jump to register */
5504 if (offset
!= 0 && offset
!= 16) {
5506 * Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
5507 * others are reserved.
5509 MIPS_INVAL("jump hint");
5510 gen_reserved_instruction(ctx
);
5513 gen_load_gpr(btarget
, rs
);
5516 MIPS_INVAL("branch/jump");
5517 gen_reserved_instruction(ctx
);
5520 if (bcond_compute
== 0) {
5521 /* No condition to be computed */
5523 case OPC_BEQ
: /* rx == rx */
5525 ctx
->hflags
|= MIPS_HFLAG_B
;
5527 case OPC_BGEZAL
: /* 0 >= 0 */
5528 /* Always take and link */
5529 tcg_gen_movi_tl(cpu_gpr
[31],
5530 ctx
->base
.pc_next
+ insn_bytes
);
5531 ctx
->hflags
|= MIPS_HFLAG_B
;
5533 case OPC_BNE
: /* rx != rx */
5534 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 8);
5535 /* Skip the instruction in the delay slot */
5536 ctx
->base
.pc_next
+= 4;
5539 ctx
->hflags
|= MIPS_HFLAG_BR
;
5543 tcg_gen_movi_tl(cpu_gpr
[rt
],
5544 ctx
->base
.pc_next
+ insn_bytes
);
5546 ctx
->hflags
|= MIPS_HFLAG_BR
;
5549 MIPS_INVAL("branch/jump");
5550 gen_reserved_instruction(ctx
);
5556 tcg_gen_setcond_tl(TCG_COND_EQ
, bcond
, t0
, t1
);
5559 tcg_gen_setcond_tl(TCG_COND_NE
, bcond
, t0
, t1
);
5562 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
5563 tcg_gen_movi_tl(cpu_gpr
[31],
5564 ctx
->base
.pc_next
+ insn_bytes
);
5567 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 32);
5569 ctx
->hflags
|= MIPS_HFLAG_BC
;
5572 MIPS_INVAL("conditional branch/jump");
5573 gen_reserved_instruction(ctx
);
5578 ctx
->btarget
= btgt
;
5581 if (insn_bytes
== 2) {
5582 ctx
->hflags
|= MIPS_HFLAG_B16
;
5589 /* special3 bitfield operations */
5590 static void gen_bitops(DisasContext
*ctx
, uint32_t opc
, int rt
,
5591 int rs
, int lsb
, int msb
)
5593 TCGv t0
= tcg_temp_new();
5594 TCGv t1
= tcg_temp_new();
5596 gen_load_gpr(t1
, rs
);
5599 if (lsb
+ msb
> 31) {
5603 tcg_gen_extract_tl(t0
, t1
, lsb
, msb
+ 1);
5606 * The two checks together imply that lsb == 0,
5607 * so this is a simple sign-extension.
5609 tcg_gen_ext32s_tl(t0
, t1
);
5612 #if defined(TARGET_MIPS64)
5621 if (lsb
+ msb
> 63) {
5624 tcg_gen_extract_tl(t0
, t1
, lsb
, msb
+ 1);
5631 gen_load_gpr(t0
, rt
);
5632 tcg_gen_deposit_tl(t0
, t0
, t1
, lsb
, msb
- lsb
+ 1);
5633 tcg_gen_ext32s_tl(t0
, t0
);
5635 #if defined(TARGET_MIPS64)
5646 gen_load_gpr(t0
, rt
);
5647 tcg_gen_deposit_tl(t0
, t0
, t1
, lsb
, msb
- lsb
+ 1);
5652 MIPS_INVAL("bitops");
5653 gen_reserved_instruction(ctx
);
5658 gen_store_gpr(t0
, rt
);
5663 static void gen_bshfl(DisasContext
*ctx
, uint32_t op2
, int rt
, int rd
)
5668 /* If no destination, treat it as a NOP. */
5672 t0
= tcg_temp_new();
5673 gen_load_gpr(t0
, rt
);
5677 TCGv t1
= tcg_temp_new();
5678 TCGv t2
= tcg_const_tl(0x00FF00FF);
5680 tcg_gen_shri_tl(t1
, t0
, 8);
5681 tcg_gen_and_tl(t1
, t1
, t2
);
5682 tcg_gen_and_tl(t0
, t0
, t2
);
5683 tcg_gen_shli_tl(t0
, t0
, 8);
5684 tcg_gen_or_tl(t0
, t0
, t1
);
5687 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
5691 tcg_gen_ext8s_tl(cpu_gpr
[rd
], t0
);
5694 tcg_gen_ext16s_tl(cpu_gpr
[rd
], t0
);
5696 #if defined(TARGET_MIPS64)
5699 TCGv t1
= tcg_temp_new();
5700 TCGv t2
= tcg_const_tl(0x00FF00FF00FF00FFULL
);
5702 tcg_gen_shri_tl(t1
, t0
, 8);
5703 tcg_gen_and_tl(t1
, t1
, t2
);
5704 tcg_gen_and_tl(t0
, t0
, t2
);
5705 tcg_gen_shli_tl(t0
, t0
, 8);
5706 tcg_gen_or_tl(cpu_gpr
[rd
], t0
, t1
);
5713 TCGv t1
= tcg_temp_new();
5714 TCGv t2
= tcg_const_tl(0x0000FFFF0000FFFFULL
);
5716 tcg_gen_shri_tl(t1
, t0
, 16);
5717 tcg_gen_and_tl(t1
, t1
, t2
);
5718 tcg_gen_and_tl(t0
, t0
, t2
);
5719 tcg_gen_shli_tl(t0
, t0
, 16);
5720 tcg_gen_or_tl(t0
, t0
, t1
);
5721 tcg_gen_shri_tl(t1
, t0
, 32);
5722 tcg_gen_shli_tl(t0
, t0
, 32);
5723 tcg_gen_or_tl(cpu_gpr
[rd
], t0
, t1
);
5730 MIPS_INVAL("bsfhl");
5731 gen_reserved_instruction(ctx
);
5738 static void gen_align_bits(DisasContext
*ctx
, int wordsz
, int rd
, int rs
,
5746 t0
= tcg_temp_new();
5747 if (bits
== 0 || bits
== wordsz
) {
5749 gen_load_gpr(t0
, rt
);
5751 gen_load_gpr(t0
, rs
);
5755 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
5757 #if defined(TARGET_MIPS64)
5759 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
5764 TCGv t1
= tcg_temp_new();
5765 gen_load_gpr(t0
, rt
);
5766 gen_load_gpr(t1
, rs
);
5770 TCGv_i64 t2
= tcg_temp_new_i64();
5771 tcg_gen_concat_tl_i64(t2
, t1
, t0
);
5772 tcg_gen_shri_i64(t2
, t2
, 32 - bits
);
5773 gen_move_low32(cpu_gpr
[rd
], t2
);
5774 tcg_temp_free_i64(t2
);
5777 #if defined(TARGET_MIPS64)
5779 tcg_gen_shli_tl(t0
, t0
, bits
);
5780 tcg_gen_shri_tl(t1
, t1
, 64 - bits
);
5781 tcg_gen_or_tl(cpu_gpr
[rd
], t1
, t0
);
5791 static void gen_align(DisasContext
*ctx
, int wordsz
, int rd
, int rs
, int rt
,
5794 gen_align_bits(ctx
, wordsz
, rd
, rs
, rt
, bp
* 8);
5797 static void gen_ext(DisasContext
*ctx
, int wordsz
, int rd
, int rs
, int rt
,
5800 gen_align_bits(ctx
, wordsz
, rd
, rs
, rt
, wordsz
- shift
);
5803 static void gen_bitswap(DisasContext
*ctx
, int opc
, int rd
, int rt
)
5810 t0
= tcg_temp_new();
5811 gen_load_gpr(t0
, rt
);
5814 gen_helper_bitswap(cpu_gpr
[rd
], t0
);
5816 #if defined(TARGET_MIPS64)
5818 gen_helper_dbitswap(cpu_gpr
[rd
], t0
);
5825 #ifndef CONFIG_USER_ONLY
5826 /* CP0 (MMU and control) */
5827 static inline void gen_mthc0_entrylo(TCGv arg
, target_ulong off
)
5829 TCGv_i64 t0
= tcg_temp_new_i64();
5830 TCGv_i64 t1
= tcg_temp_new_i64();
5832 tcg_gen_ext_tl_i64(t0
, arg
);
5833 tcg_gen_ld_i64(t1
, cpu_env
, off
);
5834 #if defined(TARGET_MIPS64)
5835 tcg_gen_deposit_i64(t1
, t1
, t0
, 30, 32);
5837 tcg_gen_concat32_i64(t1
, t1
, t0
);
5839 tcg_gen_st_i64(t1
, cpu_env
, off
);
5840 tcg_temp_free_i64(t1
);
5841 tcg_temp_free_i64(t0
);
5844 static inline void gen_mthc0_store64(TCGv arg
, target_ulong off
)
5846 TCGv_i64 t0
= tcg_temp_new_i64();
5847 TCGv_i64 t1
= tcg_temp_new_i64();
5849 tcg_gen_ext_tl_i64(t0
, arg
);
5850 tcg_gen_ld_i64(t1
, cpu_env
, off
);
5851 tcg_gen_concat32_i64(t1
, t1
, t0
);
5852 tcg_gen_st_i64(t1
, cpu_env
, off
);
5853 tcg_temp_free_i64(t1
);
5854 tcg_temp_free_i64(t0
);
5857 static inline void gen_mfhc0_entrylo(TCGv arg
, target_ulong off
)
5859 TCGv_i64 t0
= tcg_temp_new_i64();
5861 tcg_gen_ld_i64(t0
, cpu_env
, off
);
5862 #if defined(TARGET_MIPS64)
5863 tcg_gen_shri_i64(t0
, t0
, 30);
5865 tcg_gen_shri_i64(t0
, t0
, 32);
5867 gen_move_low32(arg
, t0
);
5868 tcg_temp_free_i64(t0
);
5871 static inline void gen_mfhc0_load64(TCGv arg
, target_ulong off
, int shift
)
5873 TCGv_i64 t0
= tcg_temp_new_i64();
5875 tcg_gen_ld_i64(t0
, cpu_env
, off
);
5876 tcg_gen_shri_i64(t0
, t0
, 32 + shift
);
5877 gen_move_low32(arg
, t0
);
5878 tcg_temp_free_i64(t0
);
5881 static inline void gen_mfc0_load32(TCGv arg
, target_ulong off
)
5883 TCGv_i32 t0
= tcg_temp_new_i32();
5885 tcg_gen_ld_i32(t0
, cpu_env
, off
);
5886 tcg_gen_ext_i32_tl(arg
, t0
);
5887 tcg_temp_free_i32(t0
);
5890 static inline void gen_mfc0_load64(TCGv arg
, target_ulong off
)
5892 tcg_gen_ld_tl(arg
, cpu_env
, off
);
5893 tcg_gen_ext32s_tl(arg
, arg
);
5896 static inline void gen_mtc0_store32(TCGv arg
, target_ulong off
)
5898 TCGv_i32 t0
= tcg_temp_new_i32();
5900 tcg_gen_trunc_tl_i32(t0
, arg
);
5901 tcg_gen_st_i32(t0
, cpu_env
, off
);
5902 tcg_temp_free_i32(t0
);
5905 #define CP0_CHECK(c) \
5908 goto cp0_unimplemented; \
5912 static void gen_mfhc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
5914 const char *register_name
= "invalid";
5917 case CP0_REGISTER_02
:
5920 CP0_CHECK(ctx
->hflags
& MIPS_HFLAG_ELPA
);
5921 gen_mfhc0_entrylo(arg
, offsetof(CPUMIPSState
, CP0_EntryLo0
));
5922 register_name
= "EntryLo0";
5925 goto cp0_unimplemented
;
5928 case CP0_REGISTER_03
:
5930 case CP0_REG03__ENTRYLO1
:
5931 CP0_CHECK(ctx
->hflags
& MIPS_HFLAG_ELPA
);
5932 gen_mfhc0_entrylo(arg
, offsetof(CPUMIPSState
, CP0_EntryLo1
));
5933 register_name
= "EntryLo1";
5936 goto cp0_unimplemented
;
5939 case CP0_REGISTER_09
:
5941 case CP0_REG09__SAAR
:
5942 CP0_CHECK(ctx
->saar
);
5943 gen_helper_mfhc0_saar(arg
, cpu_env
);
5944 register_name
= "SAAR";
5947 goto cp0_unimplemented
;
5950 case CP0_REGISTER_17
:
5952 case CP0_REG17__LLADDR
:
5953 gen_mfhc0_load64(arg
, offsetof(CPUMIPSState
, CP0_LLAddr
),
5954 ctx
->CP0_LLAddr_shift
);
5955 register_name
= "LLAddr";
5957 case CP0_REG17__MAAR
:
5958 CP0_CHECK(ctx
->mrp
);
5959 gen_helper_mfhc0_maar(arg
, cpu_env
);
5960 register_name
= "MAAR";
5963 goto cp0_unimplemented
;
5966 case CP0_REGISTER_19
:
5968 case CP0_REG19__WATCHHI0
:
5969 case CP0_REG19__WATCHHI1
:
5970 case CP0_REG19__WATCHHI2
:
5971 case CP0_REG19__WATCHHI3
:
5972 case CP0_REG19__WATCHHI4
:
5973 case CP0_REG19__WATCHHI5
:
5974 case CP0_REG19__WATCHHI6
:
5975 case CP0_REG19__WATCHHI7
:
5976 /* upper 32 bits are only available when Config5MI != 0 */
5978 gen_mfhc0_load64(arg
, offsetof(CPUMIPSState
, CP0_WatchHi
[sel
]), 0);
5979 register_name
= "WatchHi";
5982 goto cp0_unimplemented
;
5985 case CP0_REGISTER_28
:
5991 gen_mfhc0_load64(arg
, offsetof(CPUMIPSState
, CP0_TagLo
), 0);
5992 register_name
= "TagLo";
5995 goto cp0_unimplemented
;
5999 goto cp0_unimplemented
;
6001 trace_mips_translate_c0("mfhc0", register_name
, reg
, sel
);
6005 qemu_log_mask(LOG_UNIMP
, "mfhc0 %s (reg %d sel %d)\n",
6006 register_name
, reg
, sel
);
6007 tcg_gen_movi_tl(arg
, 0);
6010 static void gen_mthc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
6012 const char *register_name
= "invalid";
6013 uint64_t mask
= ctx
->PAMask
>> 36;
6016 case CP0_REGISTER_02
:
6019 CP0_CHECK(ctx
->hflags
& MIPS_HFLAG_ELPA
);
6020 tcg_gen_andi_tl(arg
, arg
, mask
);
6021 gen_mthc0_entrylo(arg
, offsetof(CPUMIPSState
, CP0_EntryLo0
));
6022 register_name
= "EntryLo0";
6025 goto cp0_unimplemented
;
6028 case CP0_REGISTER_03
:
6030 case CP0_REG03__ENTRYLO1
:
6031 CP0_CHECK(ctx
->hflags
& MIPS_HFLAG_ELPA
);
6032 tcg_gen_andi_tl(arg
, arg
, mask
);
6033 gen_mthc0_entrylo(arg
, offsetof(CPUMIPSState
, CP0_EntryLo1
));
6034 register_name
= "EntryLo1";
6037 goto cp0_unimplemented
;
6040 case CP0_REGISTER_09
:
6042 case CP0_REG09__SAAR
:
6043 CP0_CHECK(ctx
->saar
);
6044 gen_helper_mthc0_saar(cpu_env
, arg
);
6045 register_name
= "SAAR";
6048 goto cp0_unimplemented
;
6051 case CP0_REGISTER_17
:
6053 case CP0_REG17__LLADDR
:
6055 * LLAddr is read-only (the only exception is bit 0 if LLB is
6056 * supported); the CP0_LLAddr_rw_bitmask does not seem to be
6057 * relevant for modern MIPS cores supporting MTHC0, therefore
6058 * treating MTHC0 to LLAddr as NOP.
6060 register_name
= "LLAddr";
6062 case CP0_REG17__MAAR
:
6063 CP0_CHECK(ctx
->mrp
);
6064 gen_helper_mthc0_maar(cpu_env
, arg
);
6065 register_name
= "MAAR";
6068 goto cp0_unimplemented
;
6071 case CP0_REGISTER_19
:
6073 case CP0_REG19__WATCHHI0
:
6074 case CP0_REG19__WATCHHI1
:
6075 case CP0_REG19__WATCHHI2
:
6076 case CP0_REG19__WATCHHI3
:
6077 case CP0_REG19__WATCHHI4
:
6078 case CP0_REG19__WATCHHI5
:
6079 case CP0_REG19__WATCHHI6
:
6080 case CP0_REG19__WATCHHI7
:
6081 /* upper 32 bits are only available when Config5MI != 0 */
6083 gen_helper_0e1i(mthc0_watchhi
, arg
, sel
);
6084 register_name
= "WatchHi";
6087 goto cp0_unimplemented
;
6090 case CP0_REGISTER_28
:
6096 tcg_gen_andi_tl(arg
, arg
, mask
);
6097 gen_mthc0_store64(arg
, offsetof(CPUMIPSState
, CP0_TagLo
));
6098 register_name
= "TagLo";
6101 goto cp0_unimplemented
;
6105 goto cp0_unimplemented
;
6107 trace_mips_translate_c0("mthc0", register_name
, reg
, sel
);
6110 qemu_log_mask(LOG_UNIMP
, "mthc0 %s (reg %d sel %d)\n",
6111 register_name
, reg
, sel
);
6114 static inline void gen_mfc0_unimplemented(DisasContext
*ctx
, TCGv arg
)
6116 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
6117 tcg_gen_movi_tl(arg
, 0);
6119 tcg_gen_movi_tl(arg
, ~0);
6123 static void gen_mfc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
6125 const char *register_name
= "invalid";
6128 check_insn(ctx
, ISA_MIPS_R1
);
6132 case CP0_REGISTER_00
:
6134 case CP0_REG00__INDEX
:
6135 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Index
));
6136 register_name
= "Index";
6138 case CP0_REG00__MVPCONTROL
:
6139 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6140 gen_helper_mfc0_mvpcontrol(arg
, cpu_env
);
6141 register_name
= "MVPControl";
6143 case CP0_REG00__MVPCONF0
:
6144 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6145 gen_helper_mfc0_mvpconf0(arg
, cpu_env
);
6146 register_name
= "MVPConf0";
6148 case CP0_REG00__MVPCONF1
:
6149 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6150 gen_helper_mfc0_mvpconf1(arg
, cpu_env
);
6151 register_name
= "MVPConf1";
6153 case CP0_REG00__VPCONTROL
:
6155 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPControl
));
6156 register_name
= "VPControl";
6159 goto cp0_unimplemented
;
6162 case CP0_REGISTER_01
:
6164 case CP0_REG01__RANDOM
:
6165 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS_R6
));
6166 gen_helper_mfc0_random(arg
, cpu_env
);
6167 register_name
= "Random";
6169 case CP0_REG01__VPECONTROL
:
6170 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6171 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEControl
));
6172 register_name
= "VPEControl";
6174 case CP0_REG01__VPECONF0
:
6175 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6176 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf0
));
6177 register_name
= "VPEConf0";
6179 case CP0_REG01__VPECONF1
:
6180 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6181 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf1
));
6182 register_name
= "VPEConf1";
6184 case CP0_REG01__YQMASK
:
6185 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6186 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_YQMask
));
6187 register_name
= "YQMask";
6189 case CP0_REG01__VPESCHEDULE
:
6190 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6191 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_VPESchedule
));
6192 register_name
= "VPESchedule";
6194 case CP0_REG01__VPESCHEFBACK
:
6195 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6196 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
6197 register_name
= "VPEScheFBack";
6199 case CP0_REG01__VPEOPT
:
6200 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6201 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEOpt
));
6202 register_name
= "VPEOpt";
6205 goto cp0_unimplemented
;
6208 case CP0_REGISTER_02
:
6210 case CP0_REG02__ENTRYLO0
:
6212 TCGv_i64 tmp
= tcg_temp_new_i64();
6213 tcg_gen_ld_i64(tmp
, cpu_env
,
6214 offsetof(CPUMIPSState
, CP0_EntryLo0
));
6215 #if defined(TARGET_MIPS64)
6217 /* Move RI/XI fields to bits 31:30 */
6218 tcg_gen_shri_tl(arg
, tmp
, CP0EnLo_XI
);
6219 tcg_gen_deposit_tl(tmp
, tmp
, arg
, 30, 2);
6222 gen_move_low32(arg
, tmp
);
6223 tcg_temp_free_i64(tmp
);
6225 register_name
= "EntryLo0";
6227 case CP0_REG02__TCSTATUS
:
6228 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6229 gen_helper_mfc0_tcstatus(arg
, cpu_env
);
6230 register_name
= "TCStatus";
6232 case CP0_REG02__TCBIND
:
6233 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6234 gen_helper_mfc0_tcbind(arg
, cpu_env
);
6235 register_name
= "TCBind";
6237 case CP0_REG02__TCRESTART
:
6238 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6239 gen_helper_mfc0_tcrestart(arg
, cpu_env
);
6240 register_name
= "TCRestart";
6242 case CP0_REG02__TCHALT
:
6243 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6244 gen_helper_mfc0_tchalt(arg
, cpu_env
);
6245 register_name
= "TCHalt";
6247 case CP0_REG02__TCCONTEXT
:
6248 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6249 gen_helper_mfc0_tccontext(arg
, cpu_env
);
6250 register_name
= "TCContext";
6252 case CP0_REG02__TCSCHEDULE
:
6253 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6254 gen_helper_mfc0_tcschedule(arg
, cpu_env
);
6255 register_name
= "TCSchedule";
6257 case CP0_REG02__TCSCHEFBACK
:
6258 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6259 gen_helper_mfc0_tcschefback(arg
, cpu_env
);
6260 register_name
= "TCScheFBack";
6263 goto cp0_unimplemented
;
6266 case CP0_REGISTER_03
:
6268 case CP0_REG03__ENTRYLO1
:
6270 TCGv_i64 tmp
= tcg_temp_new_i64();
6271 tcg_gen_ld_i64(tmp
, cpu_env
,
6272 offsetof(CPUMIPSState
, CP0_EntryLo1
));
6273 #if defined(TARGET_MIPS64)
6275 /* Move RI/XI fields to bits 31:30 */
6276 tcg_gen_shri_tl(arg
, tmp
, CP0EnLo_XI
);
6277 tcg_gen_deposit_tl(tmp
, tmp
, arg
, 30, 2);
6280 gen_move_low32(arg
, tmp
);
6281 tcg_temp_free_i64(tmp
);
6283 register_name
= "EntryLo1";
6285 case CP0_REG03__GLOBALNUM
:
6287 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_GlobalNumber
));
6288 register_name
= "GlobalNumber";
6291 goto cp0_unimplemented
;
6294 case CP0_REGISTER_04
:
6296 case CP0_REG04__CONTEXT
:
6297 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_Context
));
6298 tcg_gen_ext32s_tl(arg
, arg
);
6299 register_name
= "Context";
6301 case CP0_REG04__CONTEXTCONFIG
:
6303 /* gen_helper_mfc0_contextconfig(arg); */
6304 register_name
= "ContextConfig";
6305 goto cp0_unimplemented
;
6306 case CP0_REG04__USERLOCAL
:
6307 CP0_CHECK(ctx
->ulri
);
6308 tcg_gen_ld_tl(arg
, cpu_env
,
6309 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
6310 tcg_gen_ext32s_tl(arg
, arg
);
6311 register_name
= "UserLocal";
6313 case CP0_REG04__MMID
:
6315 gen_helper_mtc0_memorymapid(cpu_env
, arg
);
6316 register_name
= "MMID";
6319 goto cp0_unimplemented
;
6322 case CP0_REGISTER_05
:
6324 case CP0_REG05__PAGEMASK
:
6325 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageMask
));
6326 register_name
= "PageMask";
6328 case CP0_REG05__PAGEGRAIN
:
6329 check_insn(ctx
, ISA_MIPS_R2
);
6330 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageGrain
));
6331 register_name
= "PageGrain";
6333 case CP0_REG05__SEGCTL0
:
6335 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_SegCtl0
));
6336 tcg_gen_ext32s_tl(arg
, arg
);
6337 register_name
= "SegCtl0";
6339 case CP0_REG05__SEGCTL1
:
6341 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_SegCtl1
));
6342 tcg_gen_ext32s_tl(arg
, arg
);
6343 register_name
= "SegCtl1";
6345 case CP0_REG05__SEGCTL2
:
6347 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_SegCtl2
));
6348 tcg_gen_ext32s_tl(arg
, arg
);
6349 register_name
= "SegCtl2";
6351 case CP0_REG05__PWBASE
:
6353 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PWBase
));
6354 register_name
= "PWBase";
6356 case CP0_REG05__PWFIELD
:
6358 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PWField
));
6359 register_name
= "PWField";
6361 case CP0_REG05__PWSIZE
:
6363 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PWSize
));
6364 register_name
= "PWSize";
6367 goto cp0_unimplemented
;
6370 case CP0_REGISTER_06
:
6372 case CP0_REG06__WIRED
:
6373 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Wired
));
6374 register_name
= "Wired";
6376 case CP0_REG06__SRSCONF0
:
6377 check_insn(ctx
, ISA_MIPS_R2
);
6378 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf0
));
6379 register_name
= "SRSConf0";
6381 case CP0_REG06__SRSCONF1
:
6382 check_insn(ctx
, ISA_MIPS_R2
);
6383 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf1
));
6384 register_name
= "SRSConf1";
6386 case CP0_REG06__SRSCONF2
:
6387 check_insn(ctx
, ISA_MIPS_R2
);
6388 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf2
));
6389 register_name
= "SRSConf2";
6391 case CP0_REG06__SRSCONF3
:
6392 check_insn(ctx
, ISA_MIPS_R2
);
6393 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf3
));
6394 register_name
= "SRSConf3";
6396 case CP0_REG06__SRSCONF4
:
6397 check_insn(ctx
, ISA_MIPS_R2
);
6398 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf4
));
6399 register_name
= "SRSConf4";
6401 case CP0_REG06__PWCTL
:
6403 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PWCtl
));
6404 register_name
= "PWCtl";
6407 goto cp0_unimplemented
;
6410 case CP0_REGISTER_07
:
6412 case CP0_REG07__HWRENA
:
6413 check_insn(ctx
, ISA_MIPS_R2
);
6414 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_HWREna
));
6415 register_name
= "HWREna";
6418 goto cp0_unimplemented
;
6421 case CP0_REGISTER_08
:
6423 case CP0_REG08__BADVADDR
:
6424 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_BadVAddr
));
6425 tcg_gen_ext32s_tl(arg
, arg
);
6426 register_name
= "BadVAddr";
6428 case CP0_REG08__BADINSTR
:
6430 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstr
));
6431 register_name
= "BadInstr";
6433 case CP0_REG08__BADINSTRP
:
6435 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstrP
));
6436 register_name
= "BadInstrP";
6438 case CP0_REG08__BADINSTRX
:
6440 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstrX
));
6441 tcg_gen_andi_tl(arg
, arg
, ~0xffff);
6442 register_name
= "BadInstrX";
6445 goto cp0_unimplemented
;
6448 case CP0_REGISTER_09
:
6450 case CP0_REG09__COUNT
:
6451 /* Mark as an IO operation because we read the time. */
6452 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
6455 gen_helper_mfc0_count(arg
, cpu_env
);
6457 * Break the TB to be able to take timer interrupts immediately
6458 * after reading count. DISAS_STOP isn't sufficient, we need to
6459 * ensure we break completely out of translated code.
6461 gen_save_pc(ctx
->base
.pc_next
+ 4);
6462 ctx
->base
.is_jmp
= DISAS_EXIT
;
6463 register_name
= "Count";
6465 case CP0_REG09__SAARI
:
6466 CP0_CHECK(ctx
->saar
);
6467 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SAARI
));
6468 register_name
= "SAARI";
6470 case CP0_REG09__SAAR
:
6471 CP0_CHECK(ctx
->saar
);
6472 gen_helper_mfc0_saar(arg
, cpu_env
);
6473 register_name
= "SAAR";
6476 goto cp0_unimplemented
;
6479 case CP0_REGISTER_10
:
6481 case CP0_REG10__ENTRYHI
:
6482 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryHi
));
6483 tcg_gen_ext32s_tl(arg
, arg
);
6484 register_name
= "EntryHi";
6487 goto cp0_unimplemented
;
6490 case CP0_REGISTER_11
:
6492 case CP0_REG11__COMPARE
:
6493 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Compare
));
6494 register_name
= "Compare";
6496 /* 6,7 are implementation dependent */
6498 goto cp0_unimplemented
;
6501 case CP0_REGISTER_12
:
6503 case CP0_REG12__STATUS
:
6504 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Status
));
6505 register_name
= "Status";
6507 case CP0_REG12__INTCTL
:
6508 check_insn(ctx
, ISA_MIPS_R2
);
6509 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_IntCtl
));
6510 register_name
= "IntCtl";
6512 case CP0_REG12__SRSCTL
:
6513 check_insn(ctx
, ISA_MIPS_R2
);
6514 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
6515 register_name
= "SRSCtl";
6517 case CP0_REG12__SRSMAP
:
6518 check_insn(ctx
, ISA_MIPS_R2
);
6519 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
6520 register_name
= "SRSMap";
6523 goto cp0_unimplemented
;
6526 case CP0_REGISTER_13
:
6528 case CP0_REG13__CAUSE
:
6529 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Cause
));
6530 register_name
= "Cause";
6533 goto cp0_unimplemented
;
6536 case CP0_REGISTER_14
:
6538 case CP0_REG14__EPC
:
6539 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
6540 tcg_gen_ext32s_tl(arg
, arg
);
6541 register_name
= "EPC";
6544 goto cp0_unimplemented
;
6547 case CP0_REGISTER_15
:
6549 case CP0_REG15__PRID
:
6550 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PRid
));
6551 register_name
= "PRid";
6553 case CP0_REG15__EBASE
:
6554 check_insn(ctx
, ISA_MIPS_R2
);
6555 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EBase
));
6556 tcg_gen_ext32s_tl(arg
, arg
);
6557 register_name
= "EBase";
6559 case CP0_REG15__CMGCRBASE
:
6560 check_insn(ctx
, ISA_MIPS_R2
);
6561 CP0_CHECK(ctx
->cmgcr
);
6562 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_CMGCRBase
));
6563 tcg_gen_ext32s_tl(arg
, arg
);
6564 register_name
= "CMGCRBase";
6567 goto cp0_unimplemented
;
6570 case CP0_REGISTER_16
:
6572 case CP0_REG16__CONFIG
:
6573 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config0
));
6574 register_name
= "Config";
6576 case CP0_REG16__CONFIG1
:
6577 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config1
));
6578 register_name
= "Config1";
6580 case CP0_REG16__CONFIG2
:
6581 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config2
));
6582 register_name
= "Config2";
6584 case CP0_REG16__CONFIG3
:
6585 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config3
));
6586 register_name
= "Config3";
6588 case CP0_REG16__CONFIG4
:
6589 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config4
));
6590 register_name
= "Config4";
6592 case CP0_REG16__CONFIG5
:
6593 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config5
));
6594 register_name
= "Config5";
6596 /* 6,7 are implementation dependent */
6597 case CP0_REG16__CONFIG6
:
6598 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config6
));
6599 register_name
= "Config6";
6601 case CP0_REG16__CONFIG7
:
6602 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config7
));
6603 register_name
= "Config7";
6606 goto cp0_unimplemented
;
6609 case CP0_REGISTER_17
:
6611 case CP0_REG17__LLADDR
:
6612 gen_helper_mfc0_lladdr(arg
, cpu_env
);
6613 register_name
= "LLAddr";
6615 case CP0_REG17__MAAR
:
6616 CP0_CHECK(ctx
->mrp
);
6617 gen_helper_mfc0_maar(arg
, cpu_env
);
6618 register_name
= "MAAR";
6620 case CP0_REG17__MAARI
:
6621 CP0_CHECK(ctx
->mrp
);
6622 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_MAARI
));
6623 register_name
= "MAARI";
6626 goto cp0_unimplemented
;
6629 case CP0_REGISTER_18
:
6631 case CP0_REG18__WATCHLO0
:
6632 case CP0_REG18__WATCHLO1
:
6633 case CP0_REG18__WATCHLO2
:
6634 case CP0_REG18__WATCHLO3
:
6635 case CP0_REG18__WATCHLO4
:
6636 case CP0_REG18__WATCHLO5
:
6637 case CP0_REG18__WATCHLO6
:
6638 case CP0_REG18__WATCHLO7
:
6639 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
6640 gen_helper_1e0i(mfc0_watchlo
, arg
, sel
);
6641 register_name
= "WatchLo";
6644 goto cp0_unimplemented
;
6647 case CP0_REGISTER_19
:
6649 case CP0_REG19__WATCHHI0
:
6650 case CP0_REG19__WATCHHI1
:
6651 case CP0_REG19__WATCHHI2
:
6652 case CP0_REG19__WATCHHI3
:
6653 case CP0_REG19__WATCHHI4
:
6654 case CP0_REG19__WATCHHI5
:
6655 case CP0_REG19__WATCHHI6
:
6656 case CP0_REG19__WATCHHI7
:
6657 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
6658 gen_helper_1e0i(mfc0_watchhi
, arg
, sel
);
6659 register_name
= "WatchHi";
6662 goto cp0_unimplemented
;
6665 case CP0_REGISTER_20
:
6667 case CP0_REG20__XCONTEXT
:
6668 #if defined(TARGET_MIPS64)
6669 check_insn(ctx
, ISA_MIPS3
);
6670 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_XContext
));
6671 tcg_gen_ext32s_tl(arg
, arg
);
6672 register_name
= "XContext";
6676 goto cp0_unimplemented
;
6679 case CP0_REGISTER_21
:
6680 /* Officially reserved, but sel 0 is used for R1x000 framemask */
6681 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS_R6
));
6684 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Framemask
));
6685 register_name
= "Framemask";
6688 goto cp0_unimplemented
;
6691 case CP0_REGISTER_22
:
6692 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
6693 register_name
= "'Diagnostic"; /* implementation dependent */
6695 case CP0_REGISTER_23
:
6697 case CP0_REG23__DEBUG
:
6698 gen_helper_mfc0_debug(arg
, cpu_env
); /* EJTAG support */
6699 register_name
= "Debug";
6701 case CP0_REG23__TRACECONTROL
:
6702 /* PDtrace support */
6703 /* gen_helper_mfc0_tracecontrol(arg); */
6704 register_name
= "TraceControl";
6705 goto cp0_unimplemented
;
6706 case CP0_REG23__TRACECONTROL2
:
6707 /* PDtrace support */
6708 /* gen_helper_mfc0_tracecontrol2(arg); */
6709 register_name
= "TraceControl2";
6710 goto cp0_unimplemented
;
6711 case CP0_REG23__USERTRACEDATA1
:
6712 /* PDtrace support */
6713 /* gen_helper_mfc0_usertracedata1(arg);*/
6714 register_name
= "UserTraceData1";
6715 goto cp0_unimplemented
;
6716 case CP0_REG23__TRACEIBPC
:
6717 /* PDtrace support */
6718 /* gen_helper_mfc0_traceibpc(arg); */
6719 register_name
= "TraceIBPC";
6720 goto cp0_unimplemented
;
6721 case CP0_REG23__TRACEDBPC
:
6722 /* PDtrace support */
6723 /* gen_helper_mfc0_tracedbpc(arg); */
6724 register_name
= "TraceDBPC";
6725 goto cp0_unimplemented
;
6727 goto cp0_unimplemented
;
6730 case CP0_REGISTER_24
:
6732 case CP0_REG24__DEPC
:
6734 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
6735 tcg_gen_ext32s_tl(arg
, arg
);
6736 register_name
= "DEPC";
6739 goto cp0_unimplemented
;
6742 case CP0_REGISTER_25
:
6744 case CP0_REG25__PERFCTL0
:
6745 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Performance0
));
6746 register_name
= "Performance0";
6748 case CP0_REG25__PERFCNT0
:
6749 /* gen_helper_mfc0_performance1(arg); */
6750 register_name
= "Performance1";
6751 goto cp0_unimplemented
;
6752 case CP0_REG25__PERFCTL1
:
6753 /* gen_helper_mfc0_performance2(arg); */
6754 register_name
= "Performance2";
6755 goto cp0_unimplemented
;
6756 case CP0_REG25__PERFCNT1
:
6757 /* gen_helper_mfc0_performance3(arg); */
6758 register_name
= "Performance3";
6759 goto cp0_unimplemented
;
6760 case CP0_REG25__PERFCTL2
:
6761 /* gen_helper_mfc0_performance4(arg); */
6762 register_name
= "Performance4";
6763 goto cp0_unimplemented
;
6764 case CP0_REG25__PERFCNT2
:
6765 /* gen_helper_mfc0_performance5(arg); */
6766 register_name
= "Performance5";
6767 goto cp0_unimplemented
;
6768 case CP0_REG25__PERFCTL3
:
6769 /* gen_helper_mfc0_performance6(arg); */
6770 register_name
= "Performance6";
6771 goto cp0_unimplemented
;
6772 case CP0_REG25__PERFCNT3
:
6773 /* gen_helper_mfc0_performance7(arg); */
6774 register_name
= "Performance7";
6775 goto cp0_unimplemented
;
6777 goto cp0_unimplemented
;
6780 case CP0_REGISTER_26
:
6782 case CP0_REG26__ERRCTL
:
6783 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_ErrCtl
));
6784 register_name
= "ErrCtl";
6787 goto cp0_unimplemented
;
6790 case CP0_REGISTER_27
:
6792 case CP0_REG27__CACHERR
:
6793 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
6794 register_name
= "CacheErr";
6797 goto cp0_unimplemented
;
6800 case CP0_REGISTER_28
:
6802 case CP0_REG28__TAGLO
:
6803 case CP0_REG28__TAGLO1
:
6804 case CP0_REG28__TAGLO2
:
6805 case CP0_REG28__TAGLO3
:
6807 TCGv_i64 tmp
= tcg_temp_new_i64();
6808 tcg_gen_ld_i64(tmp
, cpu_env
, offsetof(CPUMIPSState
, CP0_TagLo
));
6809 gen_move_low32(arg
, tmp
);
6810 tcg_temp_free_i64(tmp
);
6812 register_name
= "TagLo";
6814 case CP0_REG28__DATALO
:
6815 case CP0_REG28__DATALO1
:
6816 case CP0_REG28__DATALO2
:
6817 case CP0_REG28__DATALO3
:
6818 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataLo
));
6819 register_name
= "DataLo";
6822 goto cp0_unimplemented
;
6825 case CP0_REGISTER_29
:
6827 case CP0_REG29__TAGHI
:
6828 case CP0_REG29__TAGHI1
:
6829 case CP0_REG29__TAGHI2
:
6830 case CP0_REG29__TAGHI3
:
6831 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagHi
));
6832 register_name
= "TagHi";
6834 case CP0_REG29__DATAHI
:
6835 case CP0_REG29__DATAHI1
:
6836 case CP0_REG29__DATAHI2
:
6837 case CP0_REG29__DATAHI3
:
6838 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataHi
));
6839 register_name
= "DataHi";
6842 goto cp0_unimplemented
;
6845 case CP0_REGISTER_30
:
6847 case CP0_REG30__ERROREPC
:
6848 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
6849 tcg_gen_ext32s_tl(arg
, arg
);
6850 register_name
= "ErrorEPC";
6853 goto cp0_unimplemented
;
6856 case CP0_REGISTER_31
:
6858 case CP0_REG31__DESAVE
:
6860 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
6861 register_name
= "DESAVE";
6863 case CP0_REG31__KSCRATCH1
:
6864 case CP0_REG31__KSCRATCH2
:
6865 case CP0_REG31__KSCRATCH3
:
6866 case CP0_REG31__KSCRATCH4
:
6867 case CP0_REG31__KSCRATCH5
:
6868 case CP0_REG31__KSCRATCH6
:
6869 CP0_CHECK(ctx
->kscrexist
& (1 << sel
));
6870 tcg_gen_ld_tl(arg
, cpu_env
,
6871 offsetof(CPUMIPSState
, CP0_KScratch
[sel
- 2]));
6872 tcg_gen_ext32s_tl(arg
, arg
);
6873 register_name
= "KScratch";
6876 goto cp0_unimplemented
;
6880 goto cp0_unimplemented
;
6882 trace_mips_translate_c0("mfc0", register_name
, reg
, sel
);
6886 qemu_log_mask(LOG_UNIMP
, "mfc0 %s (reg %d sel %d)\n",
6887 register_name
, reg
, sel
);
6888 gen_mfc0_unimplemented(ctx
, arg
);
6891 static void gen_mtc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
6893 const char *register_name
= "invalid";
6896 check_insn(ctx
, ISA_MIPS_R1
);
6899 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
6904 case CP0_REGISTER_00
:
6906 case CP0_REG00__INDEX
:
6907 gen_helper_mtc0_index(cpu_env
, arg
);
6908 register_name
= "Index";
6910 case CP0_REG00__MVPCONTROL
:
6911 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6912 gen_helper_mtc0_mvpcontrol(cpu_env
, arg
);
6913 register_name
= "MVPControl";
6915 case CP0_REG00__MVPCONF0
:
6916 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6918 register_name
= "MVPConf0";
6920 case CP0_REG00__MVPCONF1
:
6921 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6923 register_name
= "MVPConf1";
6925 case CP0_REG00__VPCONTROL
:
6928 register_name
= "VPControl";
6931 goto cp0_unimplemented
;
6934 case CP0_REGISTER_01
:
6936 case CP0_REG01__RANDOM
:
6938 register_name
= "Random";
6940 case CP0_REG01__VPECONTROL
:
6941 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6942 gen_helper_mtc0_vpecontrol(cpu_env
, arg
);
6943 register_name
= "VPEControl";
6945 case CP0_REG01__VPECONF0
:
6946 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6947 gen_helper_mtc0_vpeconf0(cpu_env
, arg
);
6948 register_name
= "VPEConf0";
6950 case CP0_REG01__VPECONF1
:
6951 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6952 gen_helper_mtc0_vpeconf1(cpu_env
, arg
);
6953 register_name
= "VPEConf1";
6955 case CP0_REG01__YQMASK
:
6956 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6957 gen_helper_mtc0_yqmask(cpu_env
, arg
);
6958 register_name
= "YQMask";
6960 case CP0_REG01__VPESCHEDULE
:
6961 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6962 tcg_gen_st_tl(arg
, cpu_env
,
6963 offsetof(CPUMIPSState
, CP0_VPESchedule
));
6964 register_name
= "VPESchedule";
6966 case CP0_REG01__VPESCHEFBACK
:
6967 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6968 tcg_gen_st_tl(arg
, cpu_env
,
6969 offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
6970 register_name
= "VPEScheFBack";
6972 case CP0_REG01__VPEOPT
:
6973 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6974 gen_helper_mtc0_vpeopt(cpu_env
, arg
);
6975 register_name
= "VPEOpt";
6978 goto cp0_unimplemented
;
6981 case CP0_REGISTER_02
:
6983 case CP0_REG02__ENTRYLO0
:
6984 gen_helper_mtc0_entrylo0(cpu_env
, arg
);
6985 register_name
= "EntryLo0";
6987 case CP0_REG02__TCSTATUS
:
6988 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6989 gen_helper_mtc0_tcstatus(cpu_env
, arg
);
6990 register_name
= "TCStatus";
6992 case CP0_REG02__TCBIND
:
6993 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6994 gen_helper_mtc0_tcbind(cpu_env
, arg
);
6995 register_name
= "TCBind";
6997 case CP0_REG02__TCRESTART
:
6998 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6999 gen_helper_mtc0_tcrestart(cpu_env
, arg
);
7000 register_name
= "TCRestart";
7002 case CP0_REG02__TCHALT
:
7003 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7004 gen_helper_mtc0_tchalt(cpu_env
, arg
);
7005 register_name
= "TCHalt";
7007 case CP0_REG02__TCCONTEXT
:
7008 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7009 gen_helper_mtc0_tccontext(cpu_env
, arg
);
7010 register_name
= "TCContext";
7012 case CP0_REG02__TCSCHEDULE
:
7013 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7014 gen_helper_mtc0_tcschedule(cpu_env
, arg
);
7015 register_name
= "TCSchedule";
7017 case CP0_REG02__TCSCHEFBACK
:
7018 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7019 gen_helper_mtc0_tcschefback(cpu_env
, arg
);
7020 register_name
= "TCScheFBack";
7023 goto cp0_unimplemented
;
7026 case CP0_REGISTER_03
:
7028 case CP0_REG03__ENTRYLO1
:
7029 gen_helper_mtc0_entrylo1(cpu_env
, arg
);
7030 register_name
= "EntryLo1";
7032 case CP0_REG03__GLOBALNUM
:
7035 register_name
= "GlobalNumber";
7038 goto cp0_unimplemented
;
7041 case CP0_REGISTER_04
:
7043 case CP0_REG04__CONTEXT
:
7044 gen_helper_mtc0_context(cpu_env
, arg
);
7045 register_name
= "Context";
7047 case CP0_REG04__CONTEXTCONFIG
:
7049 /* gen_helper_mtc0_contextconfig(arg); */
7050 register_name
= "ContextConfig";
7051 goto cp0_unimplemented
;
7052 case CP0_REG04__USERLOCAL
:
7053 CP0_CHECK(ctx
->ulri
);
7054 tcg_gen_st_tl(arg
, cpu_env
,
7055 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
7056 register_name
= "UserLocal";
7058 case CP0_REG04__MMID
:
7060 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_MemoryMapID
));
7061 register_name
= "MMID";
7064 goto cp0_unimplemented
;
7067 case CP0_REGISTER_05
:
7069 case CP0_REG05__PAGEMASK
:
7070 gen_helper_mtc0_pagemask(cpu_env
, arg
);
7071 register_name
= "PageMask";
7073 case CP0_REG05__PAGEGRAIN
:
7074 check_insn(ctx
, ISA_MIPS_R2
);
7075 gen_helper_mtc0_pagegrain(cpu_env
, arg
);
7076 register_name
= "PageGrain";
7077 ctx
->base
.is_jmp
= DISAS_STOP
;
7079 case CP0_REG05__SEGCTL0
:
7081 gen_helper_mtc0_segctl0(cpu_env
, arg
);
7082 register_name
= "SegCtl0";
7084 case CP0_REG05__SEGCTL1
:
7086 gen_helper_mtc0_segctl1(cpu_env
, arg
);
7087 register_name
= "SegCtl1";
7089 case CP0_REG05__SEGCTL2
:
7091 gen_helper_mtc0_segctl2(cpu_env
, arg
);
7092 register_name
= "SegCtl2";
7094 case CP0_REG05__PWBASE
:
7096 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_PWBase
));
7097 register_name
= "PWBase";
7099 case CP0_REG05__PWFIELD
:
7101 gen_helper_mtc0_pwfield(cpu_env
, arg
);
7102 register_name
= "PWField";
7104 case CP0_REG05__PWSIZE
:
7106 gen_helper_mtc0_pwsize(cpu_env
, arg
);
7107 register_name
= "PWSize";
7110 goto cp0_unimplemented
;
7113 case CP0_REGISTER_06
:
7115 case CP0_REG06__WIRED
:
7116 gen_helper_mtc0_wired(cpu_env
, arg
);
7117 register_name
= "Wired";
7119 case CP0_REG06__SRSCONF0
:
7120 check_insn(ctx
, ISA_MIPS_R2
);
7121 gen_helper_mtc0_srsconf0(cpu_env
, arg
);
7122 register_name
= "SRSConf0";
7124 case CP0_REG06__SRSCONF1
:
7125 check_insn(ctx
, ISA_MIPS_R2
);
7126 gen_helper_mtc0_srsconf1(cpu_env
, arg
);
7127 register_name
= "SRSConf1";
7129 case CP0_REG06__SRSCONF2
:
7130 check_insn(ctx
, ISA_MIPS_R2
);
7131 gen_helper_mtc0_srsconf2(cpu_env
, arg
);
7132 register_name
= "SRSConf2";
7134 case CP0_REG06__SRSCONF3
:
7135 check_insn(ctx
, ISA_MIPS_R2
);
7136 gen_helper_mtc0_srsconf3(cpu_env
, arg
);
7137 register_name
= "SRSConf3";
7139 case CP0_REG06__SRSCONF4
:
7140 check_insn(ctx
, ISA_MIPS_R2
);
7141 gen_helper_mtc0_srsconf4(cpu_env
, arg
);
7142 register_name
= "SRSConf4";
7144 case CP0_REG06__PWCTL
:
7146 gen_helper_mtc0_pwctl(cpu_env
, arg
);
7147 register_name
= "PWCtl";
7150 goto cp0_unimplemented
;
7153 case CP0_REGISTER_07
:
7155 case CP0_REG07__HWRENA
:
7156 check_insn(ctx
, ISA_MIPS_R2
);
7157 gen_helper_mtc0_hwrena(cpu_env
, arg
);
7158 ctx
->base
.is_jmp
= DISAS_STOP
;
7159 register_name
= "HWREna";
7162 goto cp0_unimplemented
;
7165 case CP0_REGISTER_08
:
7167 case CP0_REG08__BADVADDR
:
7169 register_name
= "BadVAddr";
7171 case CP0_REG08__BADINSTR
:
7173 register_name
= "BadInstr";
7175 case CP0_REG08__BADINSTRP
:
7177 register_name
= "BadInstrP";
7179 case CP0_REG08__BADINSTRX
:
7181 register_name
= "BadInstrX";
7184 goto cp0_unimplemented
;
7187 case CP0_REGISTER_09
:
7189 case CP0_REG09__COUNT
:
7190 gen_helper_mtc0_count(cpu_env
, arg
);
7191 register_name
= "Count";
7193 case CP0_REG09__SAARI
:
7194 CP0_CHECK(ctx
->saar
);
7195 gen_helper_mtc0_saari(cpu_env
, arg
);
7196 register_name
= "SAARI";
7198 case CP0_REG09__SAAR
:
7199 CP0_CHECK(ctx
->saar
);
7200 gen_helper_mtc0_saar(cpu_env
, arg
);
7201 register_name
= "SAAR";
7204 goto cp0_unimplemented
;
7207 case CP0_REGISTER_10
:
7209 case CP0_REG10__ENTRYHI
:
7210 gen_helper_mtc0_entryhi(cpu_env
, arg
);
7211 register_name
= "EntryHi";
7214 goto cp0_unimplemented
;
7217 case CP0_REGISTER_11
:
7219 case CP0_REG11__COMPARE
:
7220 gen_helper_mtc0_compare(cpu_env
, arg
);
7221 register_name
= "Compare";
7223 /* 6,7 are implementation dependent */
7225 goto cp0_unimplemented
;
7228 case CP0_REGISTER_12
:
7230 case CP0_REG12__STATUS
:
7231 save_cpu_state(ctx
, 1);
7232 gen_helper_mtc0_status(cpu_env
, arg
);
7233 /* DISAS_STOP isn't good enough here, hflags may have changed. */
7234 gen_save_pc(ctx
->base
.pc_next
+ 4);
7235 ctx
->base
.is_jmp
= DISAS_EXIT
;
7236 register_name
= "Status";
7238 case CP0_REG12__INTCTL
:
7239 check_insn(ctx
, ISA_MIPS_R2
);
7240 gen_helper_mtc0_intctl(cpu_env
, arg
);
7241 /* Stop translation as we may have switched the execution mode */
7242 ctx
->base
.is_jmp
= DISAS_STOP
;
7243 register_name
= "IntCtl";
7245 case CP0_REG12__SRSCTL
:
7246 check_insn(ctx
, ISA_MIPS_R2
);
7247 gen_helper_mtc0_srsctl(cpu_env
, arg
);
7248 /* Stop translation as we may have switched the execution mode */
7249 ctx
->base
.is_jmp
= DISAS_STOP
;
7250 register_name
= "SRSCtl";
7252 case CP0_REG12__SRSMAP
:
7253 check_insn(ctx
, ISA_MIPS_R2
);
7254 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
7255 /* Stop translation as we may have switched the execution mode */
7256 ctx
->base
.is_jmp
= DISAS_STOP
;
7257 register_name
= "SRSMap";
7260 goto cp0_unimplemented
;
7263 case CP0_REGISTER_13
:
7265 case CP0_REG13__CAUSE
:
7266 save_cpu_state(ctx
, 1);
7267 gen_helper_mtc0_cause(cpu_env
, arg
);
7269 * Stop translation as we may have triggered an interrupt.
7270 * DISAS_STOP isn't sufficient, we need to ensure we break out of
7271 * translated code to check for pending interrupts.
7273 gen_save_pc(ctx
->base
.pc_next
+ 4);
7274 ctx
->base
.is_jmp
= DISAS_EXIT
;
7275 register_name
= "Cause";
7278 goto cp0_unimplemented
;
7281 case CP0_REGISTER_14
:
7283 case CP0_REG14__EPC
:
7284 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
7285 register_name
= "EPC";
7288 goto cp0_unimplemented
;
7291 case CP0_REGISTER_15
:
7293 case CP0_REG15__PRID
:
7295 register_name
= "PRid";
7297 case CP0_REG15__EBASE
:
7298 check_insn(ctx
, ISA_MIPS_R2
);
7299 gen_helper_mtc0_ebase(cpu_env
, arg
);
7300 register_name
= "EBase";
7303 goto cp0_unimplemented
;
7306 case CP0_REGISTER_16
:
7308 case CP0_REG16__CONFIG
:
7309 gen_helper_mtc0_config0(cpu_env
, arg
);
7310 register_name
= "Config";
7311 /* Stop translation as we may have switched the execution mode */
7312 ctx
->base
.is_jmp
= DISAS_STOP
;
7314 case CP0_REG16__CONFIG1
:
7315 /* ignored, read only */
7316 register_name
= "Config1";
7318 case CP0_REG16__CONFIG2
:
7319 gen_helper_mtc0_config2(cpu_env
, arg
);
7320 register_name
= "Config2";
7321 /* Stop translation as we may have switched the execution mode */
7322 ctx
->base
.is_jmp
= DISAS_STOP
;
7324 case CP0_REG16__CONFIG3
:
7325 gen_helper_mtc0_config3(cpu_env
, arg
);
7326 register_name
= "Config3";
7327 /* Stop translation as we may have switched the execution mode */
7328 ctx
->base
.is_jmp
= DISAS_STOP
;
7330 case CP0_REG16__CONFIG4
:
7331 gen_helper_mtc0_config4(cpu_env
, arg
);
7332 register_name
= "Config4";
7333 ctx
->base
.is_jmp
= DISAS_STOP
;
7335 case CP0_REG16__CONFIG5
:
7336 gen_helper_mtc0_config5(cpu_env
, arg
);
7337 register_name
= "Config5";
7338 /* Stop translation as we may have switched the execution mode */
7339 ctx
->base
.is_jmp
= DISAS_STOP
;
7341 /* 6,7 are implementation dependent */
7342 case CP0_REG16__CONFIG6
:
7344 register_name
= "Config6";
7346 case CP0_REG16__CONFIG7
:
7348 register_name
= "Config7";
7351 register_name
= "Invalid config selector";
7352 goto cp0_unimplemented
;
7355 case CP0_REGISTER_17
:
7357 case CP0_REG17__LLADDR
:
7358 gen_helper_mtc0_lladdr(cpu_env
, arg
);
7359 register_name
= "LLAddr";
7361 case CP0_REG17__MAAR
:
7362 CP0_CHECK(ctx
->mrp
);
7363 gen_helper_mtc0_maar(cpu_env
, arg
);
7364 register_name
= "MAAR";
7366 case CP0_REG17__MAARI
:
7367 CP0_CHECK(ctx
->mrp
);
7368 gen_helper_mtc0_maari(cpu_env
, arg
);
7369 register_name
= "MAARI";
7372 goto cp0_unimplemented
;
7375 case CP0_REGISTER_18
:
7377 case CP0_REG18__WATCHLO0
:
7378 case CP0_REG18__WATCHLO1
:
7379 case CP0_REG18__WATCHLO2
:
7380 case CP0_REG18__WATCHLO3
:
7381 case CP0_REG18__WATCHLO4
:
7382 case CP0_REG18__WATCHLO5
:
7383 case CP0_REG18__WATCHLO6
:
7384 case CP0_REG18__WATCHLO7
:
7385 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
7386 gen_helper_0e1i(mtc0_watchlo
, arg
, sel
);
7387 register_name
= "WatchLo";
7390 goto cp0_unimplemented
;
7393 case CP0_REGISTER_19
:
7395 case CP0_REG19__WATCHHI0
:
7396 case CP0_REG19__WATCHHI1
:
7397 case CP0_REG19__WATCHHI2
:
7398 case CP0_REG19__WATCHHI3
:
7399 case CP0_REG19__WATCHHI4
:
7400 case CP0_REG19__WATCHHI5
:
7401 case CP0_REG19__WATCHHI6
:
7402 case CP0_REG19__WATCHHI7
:
7403 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
7404 gen_helper_0e1i(mtc0_watchhi
, arg
, sel
);
7405 register_name
= "WatchHi";
7408 goto cp0_unimplemented
;
7411 case CP0_REGISTER_20
:
7413 case CP0_REG20__XCONTEXT
:
7414 #if defined(TARGET_MIPS64)
7415 check_insn(ctx
, ISA_MIPS3
);
7416 gen_helper_mtc0_xcontext(cpu_env
, arg
);
7417 register_name
= "XContext";
7421 goto cp0_unimplemented
;
7424 case CP0_REGISTER_21
:
7425 /* Officially reserved, but sel 0 is used for R1x000 framemask */
7426 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS_R6
));
7429 gen_helper_mtc0_framemask(cpu_env
, arg
);
7430 register_name
= "Framemask";
7433 goto cp0_unimplemented
;
7436 case CP0_REGISTER_22
:
7438 register_name
= "Diagnostic"; /* implementation dependent */
7440 case CP0_REGISTER_23
:
7442 case CP0_REG23__DEBUG
:
7443 gen_helper_mtc0_debug(cpu_env
, arg
); /* EJTAG support */
7444 /* DISAS_STOP isn't good enough here, hflags may have changed. */
7445 gen_save_pc(ctx
->base
.pc_next
+ 4);
7446 ctx
->base
.is_jmp
= DISAS_EXIT
;
7447 register_name
= "Debug";
7449 case CP0_REG23__TRACECONTROL
:
7450 /* PDtrace support */
7451 /* gen_helper_mtc0_tracecontrol(cpu_env, arg); */
7452 register_name
= "TraceControl";
7453 /* Stop translation as we may have switched the execution mode */
7454 ctx
->base
.is_jmp
= DISAS_STOP
;
7455 goto cp0_unimplemented
;
7456 case CP0_REG23__TRACECONTROL2
:
7457 /* PDtrace support */
7458 /* gen_helper_mtc0_tracecontrol2(cpu_env, arg); */
7459 register_name
= "TraceControl2";
7460 /* Stop translation as we may have switched the execution mode */
7461 ctx
->base
.is_jmp
= DISAS_STOP
;
7462 goto cp0_unimplemented
;
7463 case CP0_REG23__USERTRACEDATA1
:
7464 /* Stop translation as we may have switched the execution mode */
7465 ctx
->base
.is_jmp
= DISAS_STOP
;
7466 /* PDtrace support */
7467 /* gen_helper_mtc0_usertracedata1(cpu_env, arg);*/
7468 register_name
= "UserTraceData";
7469 /* Stop translation as we may have switched the execution mode */
7470 ctx
->base
.is_jmp
= DISAS_STOP
;
7471 goto cp0_unimplemented
;
7472 case CP0_REG23__TRACEIBPC
:
7473 /* PDtrace support */
7474 /* gen_helper_mtc0_traceibpc(cpu_env, arg); */
7475 /* Stop translation as we may have switched the execution mode */
7476 ctx
->base
.is_jmp
= DISAS_STOP
;
7477 register_name
= "TraceIBPC";
7478 goto cp0_unimplemented
;
7479 case CP0_REG23__TRACEDBPC
:
7480 /* PDtrace support */
7481 /* gen_helper_mtc0_tracedbpc(cpu_env, arg); */
7482 /* Stop translation as we may have switched the execution mode */
7483 ctx
->base
.is_jmp
= DISAS_STOP
;
7484 register_name
= "TraceDBPC";
7485 goto cp0_unimplemented
;
7487 goto cp0_unimplemented
;
7490 case CP0_REGISTER_24
:
7492 case CP0_REG24__DEPC
:
7494 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
7495 register_name
= "DEPC";
7498 goto cp0_unimplemented
;
7501 case CP0_REGISTER_25
:
7503 case CP0_REG25__PERFCTL0
:
7504 gen_helper_mtc0_performance0(cpu_env
, arg
);
7505 register_name
= "Performance0";
7507 case CP0_REG25__PERFCNT0
:
7508 /* gen_helper_mtc0_performance1(arg); */
7509 register_name
= "Performance1";
7510 goto cp0_unimplemented
;
7511 case CP0_REG25__PERFCTL1
:
7512 /* gen_helper_mtc0_performance2(arg); */
7513 register_name
= "Performance2";
7514 goto cp0_unimplemented
;
7515 case CP0_REG25__PERFCNT1
:
7516 /* gen_helper_mtc0_performance3(arg); */
7517 register_name
= "Performance3";
7518 goto cp0_unimplemented
;
7519 case CP0_REG25__PERFCTL2
:
7520 /* gen_helper_mtc0_performance4(arg); */
7521 register_name
= "Performance4";
7522 goto cp0_unimplemented
;
7523 case CP0_REG25__PERFCNT2
:
7524 /* gen_helper_mtc0_performance5(arg); */
7525 register_name
= "Performance5";
7526 goto cp0_unimplemented
;
7527 case CP0_REG25__PERFCTL3
:
7528 /* gen_helper_mtc0_performance6(arg); */
7529 register_name
= "Performance6";
7530 goto cp0_unimplemented
;
7531 case CP0_REG25__PERFCNT3
:
7532 /* gen_helper_mtc0_performance7(arg); */
7533 register_name
= "Performance7";
7534 goto cp0_unimplemented
;
7536 goto cp0_unimplemented
;
7539 case CP0_REGISTER_26
:
7541 case CP0_REG26__ERRCTL
:
7542 gen_helper_mtc0_errctl(cpu_env
, arg
);
7543 ctx
->base
.is_jmp
= DISAS_STOP
;
7544 register_name
= "ErrCtl";
7547 goto cp0_unimplemented
;
7550 case CP0_REGISTER_27
:
7552 case CP0_REG27__CACHERR
:
7554 register_name
= "CacheErr";
7557 goto cp0_unimplemented
;
7560 case CP0_REGISTER_28
:
7562 case CP0_REG28__TAGLO
:
7563 case CP0_REG28__TAGLO1
:
7564 case CP0_REG28__TAGLO2
:
7565 case CP0_REG28__TAGLO3
:
7566 gen_helper_mtc0_taglo(cpu_env
, arg
);
7567 register_name
= "TagLo";
7569 case CP0_REG28__DATALO
:
7570 case CP0_REG28__DATALO1
:
7571 case CP0_REG28__DATALO2
:
7572 case CP0_REG28__DATALO3
:
7573 gen_helper_mtc0_datalo(cpu_env
, arg
);
7574 register_name
= "DataLo";
7577 goto cp0_unimplemented
;
7580 case CP0_REGISTER_29
:
7582 case CP0_REG29__TAGHI
:
7583 case CP0_REG29__TAGHI1
:
7584 case CP0_REG29__TAGHI2
:
7585 case CP0_REG29__TAGHI3
:
7586 gen_helper_mtc0_taghi(cpu_env
, arg
);
7587 register_name
= "TagHi";
7589 case CP0_REG29__DATAHI
:
7590 case CP0_REG29__DATAHI1
:
7591 case CP0_REG29__DATAHI2
:
7592 case CP0_REG29__DATAHI3
:
7593 gen_helper_mtc0_datahi(cpu_env
, arg
);
7594 register_name
= "DataHi";
7597 register_name
= "invalid sel";
7598 goto cp0_unimplemented
;
7601 case CP0_REGISTER_30
:
7603 case CP0_REG30__ERROREPC
:
7604 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
7605 register_name
= "ErrorEPC";
7608 goto cp0_unimplemented
;
7611 case CP0_REGISTER_31
:
7613 case CP0_REG31__DESAVE
:
7615 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
7616 register_name
= "DESAVE";
7618 case CP0_REG31__KSCRATCH1
:
7619 case CP0_REG31__KSCRATCH2
:
7620 case CP0_REG31__KSCRATCH3
:
7621 case CP0_REG31__KSCRATCH4
:
7622 case CP0_REG31__KSCRATCH5
:
7623 case CP0_REG31__KSCRATCH6
:
7624 CP0_CHECK(ctx
->kscrexist
& (1 << sel
));
7625 tcg_gen_st_tl(arg
, cpu_env
,
7626 offsetof(CPUMIPSState
, CP0_KScratch
[sel
- 2]));
7627 register_name
= "KScratch";
7630 goto cp0_unimplemented
;
7634 goto cp0_unimplemented
;
7636 trace_mips_translate_c0("mtc0", register_name
, reg
, sel
);
7638 /* For simplicity assume that all writes can cause interrupts. */
7639 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
7641 * DISAS_STOP isn't sufficient, we need to ensure we break out of
7642 * translated code to check for pending interrupts.
7644 gen_save_pc(ctx
->base
.pc_next
+ 4);
7645 ctx
->base
.is_jmp
= DISAS_EXIT
;
7650 qemu_log_mask(LOG_UNIMP
, "mtc0 %s (reg %d sel %d)\n",
7651 register_name
, reg
, sel
);
7654 #if defined(TARGET_MIPS64)
7655 static void gen_dmfc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
7657 const char *register_name
= "invalid";
7660 check_insn(ctx
, ISA_MIPS_R1
);
7664 case CP0_REGISTER_00
:
7666 case CP0_REG00__INDEX
:
7667 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Index
));
7668 register_name
= "Index";
7670 case CP0_REG00__MVPCONTROL
:
7671 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7672 gen_helper_mfc0_mvpcontrol(arg
, cpu_env
);
7673 register_name
= "MVPControl";
7675 case CP0_REG00__MVPCONF0
:
7676 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7677 gen_helper_mfc0_mvpconf0(arg
, cpu_env
);
7678 register_name
= "MVPConf0";
7680 case CP0_REG00__MVPCONF1
:
7681 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7682 gen_helper_mfc0_mvpconf1(arg
, cpu_env
);
7683 register_name
= "MVPConf1";
7685 case CP0_REG00__VPCONTROL
:
7687 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPControl
));
7688 register_name
= "VPControl";
7691 goto cp0_unimplemented
;
7694 case CP0_REGISTER_01
:
7696 case CP0_REG01__RANDOM
:
7697 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS_R6
));
7698 gen_helper_mfc0_random(arg
, cpu_env
);
7699 register_name
= "Random";
7701 case CP0_REG01__VPECONTROL
:
7702 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7703 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEControl
));
7704 register_name
= "VPEControl";
7706 case CP0_REG01__VPECONF0
:
7707 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7708 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf0
));
7709 register_name
= "VPEConf0";
7711 case CP0_REG01__VPECONF1
:
7712 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7713 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf1
));
7714 register_name
= "VPEConf1";
7716 case CP0_REG01__YQMASK
:
7717 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7718 tcg_gen_ld_tl(arg
, cpu_env
,
7719 offsetof(CPUMIPSState
, CP0_YQMask
));
7720 register_name
= "YQMask";
7722 case CP0_REG01__VPESCHEDULE
:
7723 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7724 tcg_gen_ld_tl(arg
, cpu_env
,
7725 offsetof(CPUMIPSState
, CP0_VPESchedule
));
7726 register_name
= "VPESchedule";
7728 case CP0_REG01__VPESCHEFBACK
:
7729 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7730 tcg_gen_ld_tl(arg
, cpu_env
,
7731 offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
7732 register_name
= "VPEScheFBack";
7734 case CP0_REG01__VPEOPT
:
7735 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7736 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEOpt
));
7737 register_name
= "VPEOpt";
7740 goto cp0_unimplemented
;
7743 case CP0_REGISTER_02
:
7745 case CP0_REG02__ENTRYLO0
:
7746 tcg_gen_ld_tl(arg
, cpu_env
,
7747 offsetof(CPUMIPSState
, CP0_EntryLo0
));
7748 register_name
= "EntryLo0";
7750 case CP0_REG02__TCSTATUS
:
7751 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7752 gen_helper_mfc0_tcstatus(arg
, cpu_env
);
7753 register_name
= "TCStatus";
7755 case CP0_REG02__TCBIND
:
7756 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7757 gen_helper_mfc0_tcbind(arg
, cpu_env
);
7758 register_name
= "TCBind";
7760 case CP0_REG02__TCRESTART
:
7761 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7762 gen_helper_dmfc0_tcrestart(arg
, cpu_env
);
7763 register_name
= "TCRestart";
7765 case CP0_REG02__TCHALT
:
7766 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7767 gen_helper_dmfc0_tchalt(arg
, cpu_env
);
7768 register_name
= "TCHalt";
7770 case CP0_REG02__TCCONTEXT
:
7771 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7772 gen_helper_dmfc0_tccontext(arg
, cpu_env
);
7773 register_name
= "TCContext";
7775 case CP0_REG02__TCSCHEDULE
:
7776 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7777 gen_helper_dmfc0_tcschedule(arg
, cpu_env
);
7778 register_name
= "TCSchedule";
7780 case CP0_REG02__TCSCHEFBACK
:
7781 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7782 gen_helper_dmfc0_tcschefback(arg
, cpu_env
);
7783 register_name
= "TCScheFBack";
7786 goto cp0_unimplemented
;
7789 case CP0_REGISTER_03
:
7791 case CP0_REG03__ENTRYLO1
:
7792 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryLo1
));
7793 register_name
= "EntryLo1";
7795 case CP0_REG03__GLOBALNUM
:
7797 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_GlobalNumber
));
7798 register_name
= "GlobalNumber";
7801 goto cp0_unimplemented
;
7804 case CP0_REGISTER_04
:
7806 case CP0_REG04__CONTEXT
:
7807 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_Context
));
7808 register_name
= "Context";
7810 case CP0_REG04__CONTEXTCONFIG
:
7812 /* gen_helper_dmfc0_contextconfig(arg); */
7813 register_name
= "ContextConfig";
7814 goto cp0_unimplemented
;
7815 case CP0_REG04__USERLOCAL
:
7816 CP0_CHECK(ctx
->ulri
);
7817 tcg_gen_ld_tl(arg
, cpu_env
,
7818 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
7819 register_name
= "UserLocal";
7821 case CP0_REG04__MMID
:
7823 gen_helper_mtc0_memorymapid(cpu_env
, arg
);
7824 register_name
= "MMID";
7827 goto cp0_unimplemented
;
7830 case CP0_REGISTER_05
:
7832 case CP0_REG05__PAGEMASK
:
7833 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageMask
));
7834 register_name
= "PageMask";
7836 case CP0_REG05__PAGEGRAIN
:
7837 check_insn(ctx
, ISA_MIPS_R2
);
7838 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageGrain
));
7839 register_name
= "PageGrain";
7841 case CP0_REG05__SEGCTL0
:
7843 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_SegCtl0
));
7844 register_name
= "SegCtl0";
7846 case CP0_REG05__SEGCTL1
:
7848 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_SegCtl1
));
7849 register_name
= "SegCtl1";
7851 case CP0_REG05__SEGCTL2
:
7853 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_SegCtl2
));
7854 register_name
= "SegCtl2";
7856 case CP0_REG05__PWBASE
:
7858 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_PWBase
));
7859 register_name
= "PWBase";
7861 case CP0_REG05__PWFIELD
:
7863 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_PWField
));
7864 register_name
= "PWField";
7866 case CP0_REG05__PWSIZE
:
7868 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_PWSize
));
7869 register_name
= "PWSize";
7872 goto cp0_unimplemented
;
7875 case CP0_REGISTER_06
:
7877 case CP0_REG06__WIRED
:
7878 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Wired
));
7879 register_name
= "Wired";
7881 case CP0_REG06__SRSCONF0
:
7882 check_insn(ctx
, ISA_MIPS_R2
);
7883 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf0
));
7884 register_name
= "SRSConf0";
7886 case CP0_REG06__SRSCONF1
:
7887 check_insn(ctx
, ISA_MIPS_R2
);
7888 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf1
));
7889 register_name
= "SRSConf1";
7891 case CP0_REG06__SRSCONF2
:
7892 check_insn(ctx
, ISA_MIPS_R2
);
7893 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf2
));
7894 register_name
= "SRSConf2";
7896 case CP0_REG06__SRSCONF3
:
7897 check_insn(ctx
, ISA_MIPS_R2
);
7898 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf3
));
7899 register_name
= "SRSConf3";
7901 case CP0_REG06__SRSCONF4
:
7902 check_insn(ctx
, ISA_MIPS_R2
);
7903 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf4
));
7904 register_name
= "SRSConf4";
7906 case CP0_REG06__PWCTL
:
7908 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PWCtl
));
7909 register_name
= "PWCtl";
7912 goto cp0_unimplemented
;
7915 case CP0_REGISTER_07
:
7917 case CP0_REG07__HWRENA
:
7918 check_insn(ctx
, ISA_MIPS_R2
);
7919 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_HWREna
));
7920 register_name
= "HWREna";
7923 goto cp0_unimplemented
;
7926 case CP0_REGISTER_08
:
7928 case CP0_REG08__BADVADDR
:
7929 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_BadVAddr
));
7930 register_name
= "BadVAddr";
7932 case CP0_REG08__BADINSTR
:
7934 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstr
));
7935 register_name
= "BadInstr";
7937 case CP0_REG08__BADINSTRP
:
7939 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstrP
));
7940 register_name
= "BadInstrP";
7942 case CP0_REG08__BADINSTRX
:
7944 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstrX
));
7945 tcg_gen_andi_tl(arg
, arg
, ~0xffff);
7946 register_name
= "BadInstrX";
7949 goto cp0_unimplemented
;
7952 case CP0_REGISTER_09
:
7954 case CP0_REG09__COUNT
:
7955 /* Mark as an IO operation because we read the time. */
7956 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
7959 gen_helper_mfc0_count(arg
, cpu_env
);
7961 * Break the TB to be able to take timer interrupts immediately
7962 * after reading count. DISAS_STOP isn't sufficient, we need to
7963 * ensure we break completely out of translated code.
7965 gen_save_pc(ctx
->base
.pc_next
+ 4);
7966 ctx
->base
.is_jmp
= DISAS_EXIT
;
7967 register_name
= "Count";
7969 case CP0_REG09__SAARI
:
7970 CP0_CHECK(ctx
->saar
);
7971 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SAARI
));
7972 register_name
= "SAARI";
7974 case CP0_REG09__SAAR
:
7975 CP0_CHECK(ctx
->saar
);
7976 gen_helper_dmfc0_saar(arg
, cpu_env
);
7977 register_name
= "SAAR";
7980 goto cp0_unimplemented
;
7983 case CP0_REGISTER_10
:
7985 case CP0_REG10__ENTRYHI
:
7986 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryHi
));
7987 register_name
= "EntryHi";
7990 goto cp0_unimplemented
;
7993 case CP0_REGISTER_11
:
7995 case CP0_REG11__COMPARE
:
7996 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Compare
));
7997 register_name
= "Compare";
7999 /* 6,7 are implementation dependent */
8001 goto cp0_unimplemented
;
8004 case CP0_REGISTER_12
:
8006 case CP0_REG12__STATUS
:
8007 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Status
));
8008 register_name
= "Status";
8010 case CP0_REG12__INTCTL
:
8011 check_insn(ctx
, ISA_MIPS_R2
);
8012 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_IntCtl
));
8013 register_name
= "IntCtl";
8015 case CP0_REG12__SRSCTL
:
8016 check_insn(ctx
, ISA_MIPS_R2
);
8017 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
8018 register_name
= "SRSCtl";
8020 case CP0_REG12__SRSMAP
:
8021 check_insn(ctx
, ISA_MIPS_R2
);
8022 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
8023 register_name
= "SRSMap";
8026 goto cp0_unimplemented
;
8029 case CP0_REGISTER_13
:
8031 case CP0_REG13__CAUSE
:
8032 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Cause
));
8033 register_name
= "Cause";
8036 goto cp0_unimplemented
;
8039 case CP0_REGISTER_14
:
8041 case CP0_REG14__EPC
:
8042 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
8043 register_name
= "EPC";
8046 goto cp0_unimplemented
;
8049 case CP0_REGISTER_15
:
8051 case CP0_REG15__PRID
:
8052 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PRid
));
8053 register_name
= "PRid";
8055 case CP0_REG15__EBASE
:
8056 check_insn(ctx
, ISA_MIPS_R2
);
8057 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EBase
));
8058 register_name
= "EBase";
8060 case CP0_REG15__CMGCRBASE
:
8061 check_insn(ctx
, ISA_MIPS_R2
);
8062 CP0_CHECK(ctx
->cmgcr
);
8063 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_CMGCRBase
));
8064 register_name
= "CMGCRBase";
8067 goto cp0_unimplemented
;
8070 case CP0_REGISTER_16
:
8072 case CP0_REG16__CONFIG
:
8073 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config0
));
8074 register_name
= "Config";
8076 case CP0_REG16__CONFIG1
:
8077 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config1
));
8078 register_name
= "Config1";
8080 case CP0_REG16__CONFIG2
:
8081 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config2
));
8082 register_name
= "Config2";
8084 case CP0_REG16__CONFIG3
:
8085 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config3
));
8086 register_name
= "Config3";
8088 case CP0_REG16__CONFIG4
:
8089 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config4
));
8090 register_name
= "Config4";
8092 case CP0_REG16__CONFIG5
:
8093 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config5
));
8094 register_name
= "Config5";
8096 /* 6,7 are implementation dependent */
8097 case CP0_REG16__CONFIG6
:
8098 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config6
));
8099 register_name
= "Config6";
8101 case CP0_REG16__CONFIG7
:
8102 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config7
));
8103 register_name
= "Config7";
8106 goto cp0_unimplemented
;
8109 case CP0_REGISTER_17
:
8111 case CP0_REG17__LLADDR
:
8112 gen_helper_dmfc0_lladdr(arg
, cpu_env
);
8113 register_name
= "LLAddr";
8115 case CP0_REG17__MAAR
:
8116 CP0_CHECK(ctx
->mrp
);
8117 gen_helper_dmfc0_maar(arg
, cpu_env
);
8118 register_name
= "MAAR";
8120 case CP0_REG17__MAARI
:
8121 CP0_CHECK(ctx
->mrp
);
8122 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_MAARI
));
8123 register_name
= "MAARI";
8126 goto cp0_unimplemented
;
8129 case CP0_REGISTER_18
:
8131 case CP0_REG18__WATCHLO0
:
8132 case CP0_REG18__WATCHLO1
:
8133 case CP0_REG18__WATCHLO2
:
8134 case CP0_REG18__WATCHLO3
:
8135 case CP0_REG18__WATCHLO4
:
8136 case CP0_REG18__WATCHLO5
:
8137 case CP0_REG18__WATCHLO6
:
8138 case CP0_REG18__WATCHLO7
:
8139 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
8140 gen_helper_1e0i(dmfc0_watchlo
, arg
, sel
);
8141 register_name
= "WatchLo";
8144 goto cp0_unimplemented
;
8147 case CP0_REGISTER_19
:
8149 case CP0_REG19__WATCHHI0
:
8150 case CP0_REG19__WATCHHI1
:
8151 case CP0_REG19__WATCHHI2
:
8152 case CP0_REG19__WATCHHI3
:
8153 case CP0_REG19__WATCHHI4
:
8154 case CP0_REG19__WATCHHI5
:
8155 case CP0_REG19__WATCHHI6
:
8156 case CP0_REG19__WATCHHI7
:
8157 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
8158 gen_helper_1e0i(dmfc0_watchhi
, arg
, sel
);
8159 register_name
= "WatchHi";
8162 goto cp0_unimplemented
;
8165 case CP0_REGISTER_20
:
8167 case CP0_REG20__XCONTEXT
:
8168 check_insn(ctx
, ISA_MIPS3
);
8169 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_XContext
));
8170 register_name
= "XContext";
8173 goto cp0_unimplemented
;
8176 case CP0_REGISTER_21
:
8177 /* Officially reserved, but sel 0 is used for R1x000 framemask */
8178 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS_R6
));
8181 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Framemask
));
8182 register_name
= "Framemask";
8185 goto cp0_unimplemented
;
8188 case CP0_REGISTER_22
:
8189 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
8190 register_name
= "'Diagnostic"; /* implementation dependent */
8192 case CP0_REGISTER_23
:
8194 case CP0_REG23__DEBUG
:
8195 gen_helper_mfc0_debug(arg
, cpu_env
); /* EJTAG support */
8196 register_name
= "Debug";
8198 case CP0_REG23__TRACECONTROL
:
8199 /* PDtrace support */
8200 /* gen_helper_dmfc0_tracecontrol(arg, cpu_env); */
8201 register_name
= "TraceControl";
8202 goto cp0_unimplemented
;
8203 case CP0_REG23__TRACECONTROL2
:
8204 /* PDtrace support */
8205 /* gen_helper_dmfc0_tracecontrol2(arg, cpu_env); */
8206 register_name
= "TraceControl2";
8207 goto cp0_unimplemented
;
8208 case CP0_REG23__USERTRACEDATA1
:
8209 /* PDtrace support */
8210 /* gen_helper_dmfc0_usertracedata1(arg, cpu_env);*/
8211 register_name
= "UserTraceData1";
8212 goto cp0_unimplemented
;
8213 case CP0_REG23__TRACEIBPC
:
8214 /* PDtrace support */
8215 /* gen_helper_dmfc0_traceibpc(arg, cpu_env); */
8216 register_name
= "TraceIBPC";
8217 goto cp0_unimplemented
;
8218 case CP0_REG23__TRACEDBPC
:
8219 /* PDtrace support */
8220 /* gen_helper_dmfc0_tracedbpc(arg, cpu_env); */
8221 register_name
= "TraceDBPC";
8222 goto cp0_unimplemented
;
8224 goto cp0_unimplemented
;
8227 case CP0_REGISTER_24
:
8229 case CP0_REG24__DEPC
:
8231 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
8232 register_name
= "DEPC";
8235 goto cp0_unimplemented
;
8238 case CP0_REGISTER_25
:
8240 case CP0_REG25__PERFCTL0
:
8241 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Performance0
));
8242 register_name
= "Performance0";
8244 case CP0_REG25__PERFCNT0
:
8245 /* gen_helper_dmfc0_performance1(arg); */
8246 register_name
= "Performance1";
8247 goto cp0_unimplemented
;
8248 case CP0_REG25__PERFCTL1
:
8249 /* gen_helper_dmfc0_performance2(arg); */
8250 register_name
= "Performance2";
8251 goto cp0_unimplemented
;
8252 case CP0_REG25__PERFCNT1
:
8253 /* gen_helper_dmfc0_performance3(arg); */
8254 register_name
= "Performance3";
8255 goto cp0_unimplemented
;
8256 case CP0_REG25__PERFCTL2
:
8257 /* gen_helper_dmfc0_performance4(arg); */
8258 register_name
= "Performance4";
8259 goto cp0_unimplemented
;
8260 case CP0_REG25__PERFCNT2
:
8261 /* gen_helper_dmfc0_performance5(arg); */
8262 register_name
= "Performance5";
8263 goto cp0_unimplemented
;
8264 case CP0_REG25__PERFCTL3
:
8265 /* gen_helper_dmfc0_performance6(arg); */
8266 register_name
= "Performance6";
8267 goto cp0_unimplemented
;
8268 case CP0_REG25__PERFCNT3
:
8269 /* gen_helper_dmfc0_performance7(arg); */
8270 register_name
= "Performance7";
8271 goto cp0_unimplemented
;
8273 goto cp0_unimplemented
;
8276 case CP0_REGISTER_26
:
8278 case CP0_REG26__ERRCTL
:
8279 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_ErrCtl
));
8280 register_name
= "ErrCtl";
8283 goto cp0_unimplemented
;
8286 case CP0_REGISTER_27
:
8289 case CP0_REG27__CACHERR
:
8290 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
8291 register_name
= "CacheErr";
8294 goto cp0_unimplemented
;
8297 case CP0_REGISTER_28
:
8299 case CP0_REG28__TAGLO
:
8300 case CP0_REG28__TAGLO1
:
8301 case CP0_REG28__TAGLO2
:
8302 case CP0_REG28__TAGLO3
:
8303 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagLo
));
8304 register_name
= "TagLo";
8306 case CP0_REG28__DATALO
:
8307 case CP0_REG28__DATALO1
:
8308 case CP0_REG28__DATALO2
:
8309 case CP0_REG28__DATALO3
:
8310 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataLo
));
8311 register_name
= "DataLo";
8314 goto cp0_unimplemented
;
8317 case CP0_REGISTER_29
:
8319 case CP0_REG29__TAGHI
:
8320 case CP0_REG29__TAGHI1
:
8321 case CP0_REG29__TAGHI2
:
8322 case CP0_REG29__TAGHI3
:
8323 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagHi
));
8324 register_name
= "TagHi";
8326 case CP0_REG29__DATAHI
:
8327 case CP0_REG29__DATAHI1
:
8328 case CP0_REG29__DATAHI2
:
8329 case CP0_REG29__DATAHI3
:
8330 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataHi
));
8331 register_name
= "DataHi";
8334 goto cp0_unimplemented
;
8337 case CP0_REGISTER_30
:
8339 case CP0_REG30__ERROREPC
:
8340 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
8341 register_name
= "ErrorEPC";
8344 goto cp0_unimplemented
;
8347 case CP0_REGISTER_31
:
8349 case CP0_REG31__DESAVE
:
8351 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
8352 register_name
= "DESAVE";
8354 case CP0_REG31__KSCRATCH1
:
8355 case CP0_REG31__KSCRATCH2
:
8356 case CP0_REG31__KSCRATCH3
:
8357 case CP0_REG31__KSCRATCH4
:
8358 case CP0_REG31__KSCRATCH5
:
8359 case CP0_REG31__KSCRATCH6
:
8360 CP0_CHECK(ctx
->kscrexist
& (1 << sel
));
8361 tcg_gen_ld_tl(arg
, cpu_env
,
8362 offsetof(CPUMIPSState
, CP0_KScratch
[sel
- 2]));
8363 register_name
= "KScratch";
8366 goto cp0_unimplemented
;
8370 goto cp0_unimplemented
;
8372 trace_mips_translate_c0("dmfc0", register_name
, reg
, sel
);
8376 qemu_log_mask(LOG_UNIMP
, "dmfc0 %s (reg %d sel %d)\n",
8377 register_name
, reg
, sel
);
8378 gen_mfc0_unimplemented(ctx
, arg
);
8381 static void gen_dmtc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
8383 const char *register_name
= "invalid";
8386 check_insn(ctx
, ISA_MIPS_R1
);
8389 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
8394 case CP0_REGISTER_00
:
8396 case CP0_REG00__INDEX
:
8397 gen_helper_mtc0_index(cpu_env
, arg
);
8398 register_name
= "Index";
8400 case CP0_REG00__MVPCONTROL
:
8401 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8402 gen_helper_mtc0_mvpcontrol(cpu_env
, arg
);
8403 register_name
= "MVPControl";
8405 case CP0_REG00__MVPCONF0
:
8406 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8408 register_name
= "MVPConf0";
8410 case CP0_REG00__MVPCONF1
:
8411 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8413 register_name
= "MVPConf1";
8415 case CP0_REG00__VPCONTROL
:
8418 register_name
= "VPControl";
8421 goto cp0_unimplemented
;
8424 case CP0_REGISTER_01
:
8426 case CP0_REG01__RANDOM
:
8428 register_name
= "Random";
8430 case CP0_REG01__VPECONTROL
:
8431 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8432 gen_helper_mtc0_vpecontrol(cpu_env
, arg
);
8433 register_name
= "VPEControl";
8435 case CP0_REG01__VPECONF0
:
8436 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8437 gen_helper_mtc0_vpeconf0(cpu_env
, arg
);
8438 register_name
= "VPEConf0";
8440 case CP0_REG01__VPECONF1
:
8441 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8442 gen_helper_mtc0_vpeconf1(cpu_env
, arg
);
8443 register_name
= "VPEConf1";
8445 case CP0_REG01__YQMASK
:
8446 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8447 gen_helper_mtc0_yqmask(cpu_env
, arg
);
8448 register_name
= "YQMask";
8450 case CP0_REG01__VPESCHEDULE
:
8451 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8452 tcg_gen_st_tl(arg
, cpu_env
,
8453 offsetof(CPUMIPSState
, CP0_VPESchedule
));
8454 register_name
= "VPESchedule";
8456 case CP0_REG01__VPESCHEFBACK
:
8457 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8458 tcg_gen_st_tl(arg
, cpu_env
,
8459 offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
8460 register_name
= "VPEScheFBack";
8462 case CP0_REG01__VPEOPT
:
8463 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8464 gen_helper_mtc0_vpeopt(cpu_env
, arg
);
8465 register_name
= "VPEOpt";
8468 goto cp0_unimplemented
;
8471 case CP0_REGISTER_02
:
8473 case CP0_REG02__ENTRYLO0
:
8474 gen_helper_dmtc0_entrylo0(cpu_env
, arg
);
8475 register_name
= "EntryLo0";
8477 case CP0_REG02__TCSTATUS
:
8478 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8479 gen_helper_mtc0_tcstatus(cpu_env
, arg
);
8480 register_name
= "TCStatus";
8482 case CP0_REG02__TCBIND
:
8483 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8484 gen_helper_mtc0_tcbind(cpu_env
, arg
);
8485 register_name
= "TCBind";
8487 case CP0_REG02__TCRESTART
:
8488 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8489 gen_helper_mtc0_tcrestart(cpu_env
, arg
);
8490 register_name
= "TCRestart";
8492 case CP0_REG02__TCHALT
:
8493 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8494 gen_helper_mtc0_tchalt(cpu_env
, arg
);
8495 register_name
= "TCHalt";
8497 case CP0_REG02__TCCONTEXT
:
8498 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8499 gen_helper_mtc0_tccontext(cpu_env
, arg
);
8500 register_name
= "TCContext";
8502 case CP0_REG02__TCSCHEDULE
:
8503 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8504 gen_helper_mtc0_tcschedule(cpu_env
, arg
);
8505 register_name
= "TCSchedule";
8507 case CP0_REG02__TCSCHEFBACK
:
8508 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8509 gen_helper_mtc0_tcschefback(cpu_env
, arg
);
8510 register_name
= "TCScheFBack";
8513 goto cp0_unimplemented
;
8516 case CP0_REGISTER_03
:
8518 case CP0_REG03__ENTRYLO1
:
8519 gen_helper_dmtc0_entrylo1(cpu_env
, arg
);
8520 register_name
= "EntryLo1";
8522 case CP0_REG03__GLOBALNUM
:
8525 register_name
= "GlobalNumber";
8528 goto cp0_unimplemented
;
8531 case CP0_REGISTER_04
:
8533 case CP0_REG04__CONTEXT
:
8534 gen_helper_mtc0_context(cpu_env
, arg
);
8535 register_name
= "Context";
8537 case CP0_REG04__CONTEXTCONFIG
:
8539 /* gen_helper_dmtc0_contextconfig(arg); */
8540 register_name
= "ContextConfig";
8541 goto cp0_unimplemented
;
8542 case CP0_REG04__USERLOCAL
:
8543 CP0_CHECK(ctx
->ulri
);
8544 tcg_gen_st_tl(arg
, cpu_env
,
8545 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
8546 register_name
= "UserLocal";
8548 case CP0_REG04__MMID
:
8550 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_MemoryMapID
));
8551 register_name
= "MMID";
8554 goto cp0_unimplemented
;
8557 case CP0_REGISTER_05
:
8559 case CP0_REG05__PAGEMASK
:
8560 gen_helper_mtc0_pagemask(cpu_env
, arg
);
8561 register_name
= "PageMask";
8563 case CP0_REG05__PAGEGRAIN
:
8564 check_insn(ctx
, ISA_MIPS_R2
);
8565 gen_helper_mtc0_pagegrain(cpu_env
, arg
);
8566 register_name
= "PageGrain";
8568 case CP0_REG05__SEGCTL0
:
8570 gen_helper_mtc0_segctl0(cpu_env
, arg
);
8571 register_name
= "SegCtl0";
8573 case CP0_REG05__SEGCTL1
:
8575 gen_helper_mtc0_segctl1(cpu_env
, arg
);
8576 register_name
= "SegCtl1";
8578 case CP0_REG05__SEGCTL2
:
8580 gen_helper_mtc0_segctl2(cpu_env
, arg
);
8581 register_name
= "SegCtl2";
8583 case CP0_REG05__PWBASE
:
8585 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_PWBase
));
8586 register_name
= "PWBase";
8588 case CP0_REG05__PWFIELD
:
8590 gen_helper_mtc0_pwfield(cpu_env
, arg
);
8591 register_name
= "PWField";
8593 case CP0_REG05__PWSIZE
:
8595 gen_helper_mtc0_pwsize(cpu_env
, arg
);
8596 register_name
= "PWSize";
8599 goto cp0_unimplemented
;
8602 case CP0_REGISTER_06
:
8604 case CP0_REG06__WIRED
:
8605 gen_helper_mtc0_wired(cpu_env
, arg
);
8606 register_name
= "Wired";
8608 case CP0_REG06__SRSCONF0
:
8609 check_insn(ctx
, ISA_MIPS_R2
);
8610 gen_helper_mtc0_srsconf0(cpu_env
, arg
);
8611 register_name
= "SRSConf0";
8613 case CP0_REG06__SRSCONF1
:
8614 check_insn(ctx
, ISA_MIPS_R2
);
8615 gen_helper_mtc0_srsconf1(cpu_env
, arg
);
8616 register_name
= "SRSConf1";
8618 case CP0_REG06__SRSCONF2
:
8619 check_insn(ctx
, ISA_MIPS_R2
);
8620 gen_helper_mtc0_srsconf2(cpu_env
, arg
);
8621 register_name
= "SRSConf2";
8623 case CP0_REG06__SRSCONF3
:
8624 check_insn(ctx
, ISA_MIPS_R2
);
8625 gen_helper_mtc0_srsconf3(cpu_env
, arg
);
8626 register_name
= "SRSConf3";
8628 case CP0_REG06__SRSCONF4
:
8629 check_insn(ctx
, ISA_MIPS_R2
);
8630 gen_helper_mtc0_srsconf4(cpu_env
, arg
);
8631 register_name
= "SRSConf4";
8633 case CP0_REG06__PWCTL
:
8635 gen_helper_mtc0_pwctl(cpu_env
, arg
);
8636 register_name
= "PWCtl";
8639 goto cp0_unimplemented
;
8642 case CP0_REGISTER_07
:
8644 case CP0_REG07__HWRENA
:
8645 check_insn(ctx
, ISA_MIPS_R2
);
8646 gen_helper_mtc0_hwrena(cpu_env
, arg
);
8647 ctx
->base
.is_jmp
= DISAS_STOP
;
8648 register_name
= "HWREna";
8651 goto cp0_unimplemented
;
8654 case CP0_REGISTER_08
:
8656 case CP0_REG08__BADVADDR
:
8658 register_name
= "BadVAddr";
8660 case CP0_REG08__BADINSTR
:
8662 register_name
= "BadInstr";
8664 case CP0_REG08__BADINSTRP
:
8666 register_name
= "BadInstrP";
8668 case CP0_REG08__BADINSTRX
:
8670 register_name
= "BadInstrX";
8673 goto cp0_unimplemented
;
8676 case CP0_REGISTER_09
:
8678 case CP0_REG09__COUNT
:
8679 gen_helper_mtc0_count(cpu_env
, arg
);
8680 register_name
= "Count";
8682 case CP0_REG09__SAARI
:
8683 CP0_CHECK(ctx
->saar
);
8684 gen_helper_mtc0_saari(cpu_env
, arg
);
8685 register_name
= "SAARI";
8687 case CP0_REG09__SAAR
:
8688 CP0_CHECK(ctx
->saar
);
8689 gen_helper_mtc0_saar(cpu_env
, arg
);
8690 register_name
= "SAAR";
8693 goto cp0_unimplemented
;
8695 /* Stop translation as we may have switched the execution mode */
8696 ctx
->base
.is_jmp
= DISAS_STOP
;
8698 case CP0_REGISTER_10
:
8700 case CP0_REG10__ENTRYHI
:
8701 gen_helper_mtc0_entryhi(cpu_env
, arg
);
8702 register_name
= "EntryHi";
8705 goto cp0_unimplemented
;
8708 case CP0_REGISTER_11
:
8710 case CP0_REG11__COMPARE
:
8711 gen_helper_mtc0_compare(cpu_env
, arg
);
8712 register_name
= "Compare";
8714 /* 6,7 are implementation dependent */
8716 goto cp0_unimplemented
;
8718 /* Stop translation as we may have switched the execution mode */
8719 ctx
->base
.is_jmp
= DISAS_STOP
;
8721 case CP0_REGISTER_12
:
8723 case CP0_REG12__STATUS
:
8724 save_cpu_state(ctx
, 1);
8725 gen_helper_mtc0_status(cpu_env
, arg
);
8726 /* DISAS_STOP isn't good enough here, hflags may have changed. */
8727 gen_save_pc(ctx
->base
.pc_next
+ 4);
8728 ctx
->base
.is_jmp
= DISAS_EXIT
;
8729 register_name
= "Status";
8731 case CP0_REG12__INTCTL
:
8732 check_insn(ctx
, ISA_MIPS_R2
);
8733 gen_helper_mtc0_intctl(cpu_env
, arg
);
8734 /* Stop translation as we may have switched the execution mode */
8735 ctx
->base
.is_jmp
= DISAS_STOP
;
8736 register_name
= "IntCtl";
8738 case CP0_REG12__SRSCTL
:
8739 check_insn(ctx
, ISA_MIPS_R2
);
8740 gen_helper_mtc0_srsctl(cpu_env
, arg
);
8741 /* Stop translation as we may have switched the execution mode */
8742 ctx
->base
.is_jmp
= DISAS_STOP
;
8743 register_name
= "SRSCtl";
8745 case CP0_REG12__SRSMAP
:
8746 check_insn(ctx
, ISA_MIPS_R2
);
8747 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
8748 /* Stop translation as we may have switched the execution mode */
8749 ctx
->base
.is_jmp
= DISAS_STOP
;
8750 register_name
= "SRSMap";
8753 goto cp0_unimplemented
;
8756 case CP0_REGISTER_13
:
8758 case CP0_REG13__CAUSE
:
8759 save_cpu_state(ctx
, 1);
8760 gen_helper_mtc0_cause(cpu_env
, arg
);
8762 * Stop translation as we may have triggered an interrupt.
8763 * DISAS_STOP isn't sufficient, we need to ensure we break out of
8764 * translated code to check for pending interrupts.
8766 gen_save_pc(ctx
->base
.pc_next
+ 4);
8767 ctx
->base
.is_jmp
= DISAS_EXIT
;
8768 register_name
= "Cause";
8771 goto cp0_unimplemented
;
8774 case CP0_REGISTER_14
:
8776 case CP0_REG14__EPC
:
8777 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
8778 register_name
= "EPC";
8781 goto cp0_unimplemented
;
8784 case CP0_REGISTER_15
:
8786 case CP0_REG15__PRID
:
8788 register_name
= "PRid";
8790 case CP0_REG15__EBASE
:
8791 check_insn(ctx
, ISA_MIPS_R2
);
8792 gen_helper_mtc0_ebase(cpu_env
, arg
);
8793 register_name
= "EBase";
8796 goto cp0_unimplemented
;
8799 case CP0_REGISTER_16
:
8801 case CP0_REG16__CONFIG
:
8802 gen_helper_mtc0_config0(cpu_env
, arg
);
8803 register_name
= "Config";
8804 /* Stop translation as we may have switched the execution mode */
8805 ctx
->base
.is_jmp
= DISAS_STOP
;
8807 case CP0_REG16__CONFIG1
:
8808 /* ignored, read only */
8809 register_name
= "Config1";
8811 case CP0_REG16__CONFIG2
:
8812 gen_helper_mtc0_config2(cpu_env
, arg
);
8813 register_name
= "Config2";
8814 /* Stop translation as we may have switched the execution mode */
8815 ctx
->base
.is_jmp
= DISAS_STOP
;
8817 case CP0_REG16__CONFIG3
:
8818 gen_helper_mtc0_config3(cpu_env
, arg
);
8819 register_name
= "Config3";
8820 /* Stop translation as we may have switched the execution mode */
8821 ctx
->base
.is_jmp
= DISAS_STOP
;
8823 case CP0_REG16__CONFIG4
:
8824 /* currently ignored */
8825 register_name
= "Config4";
8827 case CP0_REG16__CONFIG5
:
8828 gen_helper_mtc0_config5(cpu_env
, arg
);
8829 register_name
= "Config5";
8830 /* Stop translation as we may have switched the execution mode */
8831 ctx
->base
.is_jmp
= DISAS_STOP
;
8833 /* 6,7 are implementation dependent */
8835 register_name
= "Invalid config selector";
8836 goto cp0_unimplemented
;
8839 case CP0_REGISTER_17
:
8841 case CP0_REG17__LLADDR
:
8842 gen_helper_mtc0_lladdr(cpu_env
, arg
);
8843 register_name
= "LLAddr";
8845 case CP0_REG17__MAAR
:
8846 CP0_CHECK(ctx
->mrp
);
8847 gen_helper_mtc0_maar(cpu_env
, arg
);
8848 register_name
= "MAAR";
8850 case CP0_REG17__MAARI
:
8851 CP0_CHECK(ctx
->mrp
);
8852 gen_helper_mtc0_maari(cpu_env
, arg
);
8853 register_name
= "MAARI";
8856 goto cp0_unimplemented
;
8859 case CP0_REGISTER_18
:
8861 case CP0_REG18__WATCHLO0
:
8862 case CP0_REG18__WATCHLO1
:
8863 case CP0_REG18__WATCHLO2
:
8864 case CP0_REG18__WATCHLO3
:
8865 case CP0_REG18__WATCHLO4
:
8866 case CP0_REG18__WATCHLO5
:
8867 case CP0_REG18__WATCHLO6
:
8868 case CP0_REG18__WATCHLO7
:
8869 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
8870 gen_helper_0e1i(mtc0_watchlo
, arg
, sel
);
8871 register_name
= "WatchLo";
8874 goto cp0_unimplemented
;
8877 case CP0_REGISTER_19
:
8879 case CP0_REG19__WATCHHI0
:
8880 case CP0_REG19__WATCHHI1
:
8881 case CP0_REG19__WATCHHI2
:
8882 case CP0_REG19__WATCHHI3
:
8883 case CP0_REG19__WATCHHI4
:
8884 case CP0_REG19__WATCHHI5
:
8885 case CP0_REG19__WATCHHI6
:
8886 case CP0_REG19__WATCHHI7
:
8887 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
8888 gen_helper_0e1i(mtc0_watchhi
, arg
, sel
);
8889 register_name
= "WatchHi";
8892 goto cp0_unimplemented
;
8895 case CP0_REGISTER_20
:
8897 case CP0_REG20__XCONTEXT
:
8898 check_insn(ctx
, ISA_MIPS3
);
8899 gen_helper_mtc0_xcontext(cpu_env
, arg
);
8900 register_name
= "XContext";
8903 goto cp0_unimplemented
;
8906 case CP0_REGISTER_21
:
8907 /* Officially reserved, but sel 0 is used for R1x000 framemask */
8908 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS_R6
));
8911 gen_helper_mtc0_framemask(cpu_env
, arg
);
8912 register_name
= "Framemask";
8915 goto cp0_unimplemented
;
8918 case CP0_REGISTER_22
:
8920 register_name
= "Diagnostic"; /* implementation dependent */
8922 case CP0_REGISTER_23
:
8924 case CP0_REG23__DEBUG
:
8925 gen_helper_mtc0_debug(cpu_env
, arg
); /* EJTAG support */
8926 /* DISAS_STOP isn't good enough here, hflags may have changed. */
8927 gen_save_pc(ctx
->base
.pc_next
+ 4);
8928 ctx
->base
.is_jmp
= DISAS_EXIT
;
8929 register_name
= "Debug";
8931 case CP0_REG23__TRACECONTROL
:
8932 /* PDtrace support */
8933 /* gen_helper_mtc0_tracecontrol(cpu_env, arg); */
8934 /* Stop translation as we may have switched the execution mode */
8935 ctx
->base
.is_jmp
= DISAS_STOP
;
8936 register_name
= "TraceControl";
8937 goto cp0_unimplemented
;
8938 case CP0_REG23__TRACECONTROL2
:
8939 /* PDtrace support */
8940 /* gen_helper_mtc0_tracecontrol2(cpu_env, arg); */
8941 /* Stop translation as we may have switched the execution mode */
8942 ctx
->base
.is_jmp
= DISAS_STOP
;
8943 register_name
= "TraceControl2";
8944 goto cp0_unimplemented
;
8945 case CP0_REG23__USERTRACEDATA1
:
8946 /* PDtrace support */
8947 /* gen_helper_mtc0_usertracedata1(cpu_env, arg);*/
8948 /* Stop translation as we may have switched the execution mode */
8949 ctx
->base
.is_jmp
= DISAS_STOP
;
8950 register_name
= "UserTraceData1";
8951 goto cp0_unimplemented
;
8952 case CP0_REG23__TRACEIBPC
:
8953 /* PDtrace support */
8954 /* gen_helper_mtc0_traceibpc(cpu_env, arg); */
8955 /* Stop translation as we may have switched the execution mode */
8956 ctx
->base
.is_jmp
= DISAS_STOP
;
8957 register_name
= "TraceIBPC";
8958 goto cp0_unimplemented
;
8959 case CP0_REG23__TRACEDBPC
:
8960 /* PDtrace support */
8961 /* gen_helper_mtc0_tracedbpc(cpu_env, arg); */
8962 /* Stop translation as we may have switched the execution mode */
8963 ctx
->base
.is_jmp
= DISAS_STOP
;
8964 register_name
= "TraceDBPC";
8965 goto cp0_unimplemented
;
8967 goto cp0_unimplemented
;
8970 case CP0_REGISTER_24
:
8972 case CP0_REG24__DEPC
:
8974 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
8975 register_name
= "DEPC";
8978 goto cp0_unimplemented
;
8981 case CP0_REGISTER_25
:
8983 case CP0_REG25__PERFCTL0
:
8984 gen_helper_mtc0_performance0(cpu_env
, arg
);
8985 register_name
= "Performance0";
8987 case CP0_REG25__PERFCNT0
:
8988 /* gen_helper_mtc0_performance1(cpu_env, arg); */
8989 register_name
= "Performance1";
8990 goto cp0_unimplemented
;
8991 case CP0_REG25__PERFCTL1
:
8992 /* gen_helper_mtc0_performance2(cpu_env, arg); */
8993 register_name
= "Performance2";
8994 goto cp0_unimplemented
;
8995 case CP0_REG25__PERFCNT1
:
8996 /* gen_helper_mtc0_performance3(cpu_env, arg); */
8997 register_name
= "Performance3";
8998 goto cp0_unimplemented
;
8999 case CP0_REG25__PERFCTL2
:
9000 /* gen_helper_mtc0_performance4(cpu_env, arg); */
9001 register_name
= "Performance4";
9002 goto cp0_unimplemented
;
9003 case CP0_REG25__PERFCNT2
:
9004 /* gen_helper_mtc0_performance5(cpu_env, arg); */
9005 register_name
= "Performance5";
9006 goto cp0_unimplemented
;
9007 case CP0_REG25__PERFCTL3
:
9008 /* gen_helper_mtc0_performance6(cpu_env, arg); */
9009 register_name
= "Performance6";
9010 goto cp0_unimplemented
;
9011 case CP0_REG25__PERFCNT3
:
9012 /* gen_helper_mtc0_performance7(cpu_env, arg); */
9013 register_name
= "Performance7";
9014 goto cp0_unimplemented
;
9016 goto cp0_unimplemented
;
9019 case CP0_REGISTER_26
:
9021 case CP0_REG26__ERRCTL
:
9022 gen_helper_mtc0_errctl(cpu_env
, arg
);
9023 ctx
->base
.is_jmp
= DISAS_STOP
;
9024 register_name
= "ErrCtl";
9027 goto cp0_unimplemented
;
9030 case CP0_REGISTER_27
:
9032 case CP0_REG27__CACHERR
:
9034 register_name
= "CacheErr";
9037 goto cp0_unimplemented
;
9040 case CP0_REGISTER_28
:
9042 case CP0_REG28__TAGLO
:
9043 case CP0_REG28__TAGLO1
:
9044 case CP0_REG28__TAGLO2
:
9045 case CP0_REG28__TAGLO3
:
9046 gen_helper_mtc0_taglo(cpu_env
, arg
);
9047 register_name
= "TagLo";
9049 case CP0_REG28__DATALO
:
9050 case CP0_REG28__DATALO1
:
9051 case CP0_REG28__DATALO2
:
9052 case CP0_REG28__DATALO3
:
9053 gen_helper_mtc0_datalo(cpu_env
, arg
);
9054 register_name
= "DataLo";
9057 goto cp0_unimplemented
;
9060 case CP0_REGISTER_29
:
9062 case CP0_REG29__TAGHI
:
9063 case CP0_REG29__TAGHI1
:
9064 case CP0_REG29__TAGHI2
:
9065 case CP0_REG29__TAGHI3
:
9066 gen_helper_mtc0_taghi(cpu_env
, arg
);
9067 register_name
= "TagHi";
9069 case CP0_REG29__DATAHI
:
9070 case CP0_REG29__DATAHI1
:
9071 case CP0_REG29__DATAHI2
:
9072 case CP0_REG29__DATAHI3
:
9073 gen_helper_mtc0_datahi(cpu_env
, arg
);
9074 register_name
= "DataHi";
9077 register_name
= "invalid sel";
9078 goto cp0_unimplemented
;
9081 case CP0_REGISTER_30
:
9083 case CP0_REG30__ERROREPC
:
9084 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
9085 register_name
= "ErrorEPC";
9088 goto cp0_unimplemented
;
9091 case CP0_REGISTER_31
:
9093 case CP0_REG31__DESAVE
:
9095 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
9096 register_name
= "DESAVE";
9098 case CP0_REG31__KSCRATCH1
:
9099 case CP0_REG31__KSCRATCH2
:
9100 case CP0_REG31__KSCRATCH3
:
9101 case CP0_REG31__KSCRATCH4
:
9102 case CP0_REG31__KSCRATCH5
:
9103 case CP0_REG31__KSCRATCH6
:
9104 CP0_CHECK(ctx
->kscrexist
& (1 << sel
));
9105 tcg_gen_st_tl(arg
, cpu_env
,
9106 offsetof(CPUMIPSState
, CP0_KScratch
[sel
- 2]));
9107 register_name
= "KScratch";
9110 goto cp0_unimplemented
;
9114 goto cp0_unimplemented
;
9116 trace_mips_translate_c0("dmtc0", register_name
, reg
, sel
);
9118 /* For simplicity assume that all writes can cause interrupts. */
9119 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
9121 * DISAS_STOP isn't sufficient, we need to ensure we break out of
9122 * translated code to check for pending interrupts.
9124 gen_save_pc(ctx
->base
.pc_next
+ 4);
9125 ctx
->base
.is_jmp
= DISAS_EXIT
;
9130 qemu_log_mask(LOG_UNIMP
, "dmtc0 %s (reg %d sel %d)\n",
9131 register_name
, reg
, sel
);
9133 #endif /* TARGET_MIPS64 */
9135 static void gen_mftr(CPUMIPSState
*env
, DisasContext
*ctx
, int rt
, int rd
,
9136 int u
, int sel
, int h
)
9138 int other_tc
= env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
);
9139 TCGv t0
= tcg_temp_local_new();
9141 if ((env
->CP0_VPEConf0
& (1 << CP0VPEC0_MVP
)) == 0 &&
9142 ((env
->tcs
[other_tc
].CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)) !=
9143 (env
->active_tc
.CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)))) {
9144 tcg_gen_movi_tl(t0
, -1);
9145 } else if ((env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
)) >
9146 (env
->mvp
->CP0_MVPConf0
& (0xff << CP0MVPC0_PTC
))) {
9147 tcg_gen_movi_tl(t0
, -1);
9148 } else if (u
== 0) {
9153 gen_helper_mftc0_vpecontrol(t0
, cpu_env
);
9156 gen_helper_mftc0_vpeconf0(t0
, cpu_env
);
9166 gen_helper_mftc0_tcstatus(t0
, cpu_env
);
9169 gen_helper_mftc0_tcbind(t0
, cpu_env
);
9172 gen_helper_mftc0_tcrestart(t0
, cpu_env
);
9175 gen_helper_mftc0_tchalt(t0
, cpu_env
);
9178 gen_helper_mftc0_tccontext(t0
, cpu_env
);
9181 gen_helper_mftc0_tcschedule(t0
, cpu_env
);
9184 gen_helper_mftc0_tcschefback(t0
, cpu_env
);
9187 gen_mfc0(ctx
, t0
, rt
, sel
);
9194 gen_helper_mftc0_entryhi(t0
, cpu_env
);
9197 gen_mfc0(ctx
, t0
, rt
, sel
);
9204 gen_helper_mftc0_status(t0
, cpu_env
);
9207 gen_mfc0(ctx
, t0
, rt
, sel
);
9214 gen_helper_mftc0_cause(t0
, cpu_env
);
9224 gen_helper_mftc0_epc(t0
, cpu_env
);
9234 gen_helper_mftc0_ebase(t0
, cpu_env
);
9251 gen_helper_mftc0_configx(t0
, cpu_env
, tcg_const_tl(sel
));
9261 gen_helper_mftc0_debug(t0
, cpu_env
);
9264 gen_mfc0(ctx
, t0
, rt
, sel
);
9269 gen_mfc0(ctx
, t0
, rt
, sel
);
9273 /* GPR registers. */
9275 gen_helper_1e0i(mftgpr
, t0
, rt
);
9277 /* Auxiliary CPU registers */
9281 gen_helper_1e0i(mftlo
, t0
, 0);
9284 gen_helper_1e0i(mfthi
, t0
, 0);
9287 gen_helper_1e0i(mftacx
, t0
, 0);
9290 gen_helper_1e0i(mftlo
, t0
, 1);
9293 gen_helper_1e0i(mfthi
, t0
, 1);
9296 gen_helper_1e0i(mftacx
, t0
, 1);
9299 gen_helper_1e0i(mftlo
, t0
, 2);
9302 gen_helper_1e0i(mfthi
, t0
, 2);
9305 gen_helper_1e0i(mftacx
, t0
, 2);
9308 gen_helper_1e0i(mftlo
, t0
, 3);
9311 gen_helper_1e0i(mfthi
, t0
, 3);
9314 gen_helper_1e0i(mftacx
, t0
, 3);
9317 gen_helper_mftdsp(t0
, cpu_env
);
9323 /* Floating point (COP1). */
9325 /* XXX: For now we support only a single FPU context. */
9327 TCGv_i32 fp0
= tcg_temp_new_i32();
9329 gen_load_fpr32(ctx
, fp0
, rt
);
9330 tcg_gen_ext_i32_tl(t0
, fp0
);
9331 tcg_temp_free_i32(fp0
);
9333 TCGv_i32 fp0
= tcg_temp_new_i32();
9335 gen_load_fpr32h(ctx
, fp0
, rt
);
9336 tcg_gen_ext_i32_tl(t0
, fp0
);
9337 tcg_temp_free_i32(fp0
);
9341 /* XXX: For now we support only a single FPU context. */
9342 gen_helper_1e0i(cfc1
, t0
, rt
);
9344 /* COP2: Not implemented. */
9352 trace_mips_translate_tr("mftr", rt
, u
, sel
, h
);
9353 gen_store_gpr(t0
, rd
);
9359 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt
, u
, sel
, h
);
9360 gen_reserved_instruction(ctx
);
9363 static void gen_mttr(CPUMIPSState
*env
, DisasContext
*ctx
, int rd
, int rt
,
9364 int u
, int sel
, int h
)
9366 int other_tc
= env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
);
9367 TCGv t0
= tcg_temp_local_new();
9369 gen_load_gpr(t0
, rt
);
9370 if ((env
->CP0_VPEConf0
& (1 << CP0VPEC0_MVP
)) == 0 &&
9371 ((env
->tcs
[other_tc
].CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)) !=
9372 (env
->active_tc
.CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)))) {
9375 } else if ((env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
)) >
9376 (env
->mvp
->CP0_MVPConf0
& (0xff << CP0MVPC0_PTC
))) {
9379 } else if (u
== 0) {
9384 gen_helper_mttc0_vpecontrol(cpu_env
, t0
);
9387 gen_helper_mttc0_vpeconf0(cpu_env
, t0
);
9397 gen_helper_mttc0_tcstatus(cpu_env
, t0
);
9400 gen_helper_mttc0_tcbind(cpu_env
, t0
);
9403 gen_helper_mttc0_tcrestart(cpu_env
, t0
);
9406 gen_helper_mttc0_tchalt(cpu_env
, t0
);
9409 gen_helper_mttc0_tccontext(cpu_env
, t0
);
9412 gen_helper_mttc0_tcschedule(cpu_env
, t0
);
9415 gen_helper_mttc0_tcschefback(cpu_env
, t0
);
9418 gen_mtc0(ctx
, t0
, rd
, sel
);
9425 gen_helper_mttc0_entryhi(cpu_env
, t0
);
9428 gen_mtc0(ctx
, t0
, rd
, sel
);
9435 gen_helper_mttc0_status(cpu_env
, t0
);
9438 gen_mtc0(ctx
, t0
, rd
, sel
);
9445 gen_helper_mttc0_cause(cpu_env
, t0
);
9455 gen_helper_mttc0_ebase(cpu_env
, t0
);
9465 gen_helper_mttc0_debug(cpu_env
, t0
);
9468 gen_mtc0(ctx
, t0
, rd
, sel
);
9473 gen_mtc0(ctx
, t0
, rd
, sel
);
9477 /* GPR registers. */
9479 gen_helper_0e1i(mttgpr
, t0
, rd
);
9481 /* Auxiliary CPU registers */
9485 gen_helper_0e1i(mttlo
, t0
, 0);
9488 gen_helper_0e1i(mtthi
, t0
, 0);
9491 gen_helper_0e1i(mttacx
, t0
, 0);
9494 gen_helper_0e1i(mttlo
, t0
, 1);
9497 gen_helper_0e1i(mtthi
, t0
, 1);
9500 gen_helper_0e1i(mttacx
, t0
, 1);
9503 gen_helper_0e1i(mttlo
, t0
, 2);
9506 gen_helper_0e1i(mtthi
, t0
, 2);
9509 gen_helper_0e1i(mttacx
, t0
, 2);
9512 gen_helper_0e1i(mttlo
, t0
, 3);
9515 gen_helper_0e1i(mtthi
, t0
, 3);
9518 gen_helper_0e1i(mttacx
, t0
, 3);
9521 gen_helper_mttdsp(cpu_env
, t0
);
9527 /* Floating point (COP1). */
9529 /* XXX: For now we support only a single FPU context. */
9531 TCGv_i32 fp0
= tcg_temp_new_i32();
9533 tcg_gen_trunc_tl_i32(fp0
, t0
);
9534 gen_store_fpr32(ctx
, fp0
, rd
);
9535 tcg_temp_free_i32(fp0
);
9537 TCGv_i32 fp0
= tcg_temp_new_i32();
9539 tcg_gen_trunc_tl_i32(fp0
, t0
);
9540 gen_store_fpr32h(ctx
, fp0
, rd
);
9541 tcg_temp_free_i32(fp0
);
9545 /* XXX: For now we support only a single FPU context. */
9547 TCGv_i32 fs_tmp
= tcg_const_i32(rd
);
9549 gen_helper_0e2i(ctc1
, t0
, fs_tmp
, rt
);
9550 tcg_temp_free_i32(fs_tmp
);
9552 /* Stop translation as we may have changed hflags */
9553 ctx
->base
.is_jmp
= DISAS_STOP
;
9555 /* COP2: Not implemented. */
9563 trace_mips_translate_tr("mttr", rd
, u
, sel
, h
);
9569 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd
, u
, sel
, h
);
9570 gen_reserved_instruction(ctx
);
9573 static void gen_cp0(CPUMIPSState
*env
, DisasContext
*ctx
, uint32_t opc
,
9576 const char *opn
= "ldst";
9578 check_cp0_enabled(ctx
);
9585 gen_mfc0(ctx
, cpu_gpr
[rt
], rd
, ctx
->opcode
& 0x7);
9590 TCGv t0
= tcg_temp_new();
9592 gen_load_gpr(t0
, rt
);
9593 gen_mtc0(ctx
, t0
, rd
, ctx
->opcode
& 0x7);
9598 #if defined(TARGET_MIPS64)
9600 check_insn(ctx
, ISA_MIPS3
);
9605 gen_dmfc0(ctx
, cpu_gpr
[rt
], rd
, ctx
->opcode
& 0x7);
9609 check_insn(ctx
, ISA_MIPS3
);
9611 TCGv t0
= tcg_temp_new();
9613 gen_load_gpr(t0
, rt
);
9614 gen_dmtc0(ctx
, t0
, rd
, ctx
->opcode
& 0x7);
9626 gen_mfhc0(ctx
, cpu_gpr
[rt
], rd
, ctx
->opcode
& 0x7);
9632 TCGv t0
= tcg_temp_new();
9633 gen_load_gpr(t0
, rt
);
9634 gen_mthc0(ctx
, t0
, rd
, ctx
->opcode
& 0x7);
9640 check_cp0_enabled(ctx
);
9645 gen_mftr(env
, ctx
, rt
, rd
, (ctx
->opcode
>> 5) & 1,
9646 ctx
->opcode
& 0x7, (ctx
->opcode
>> 4) & 1);
9650 check_cp0_enabled(ctx
);
9651 gen_mttr(env
, ctx
, rd
, rt
, (ctx
->opcode
>> 5) & 1,
9652 ctx
->opcode
& 0x7, (ctx
->opcode
>> 4) & 1);
9657 if (!env
->tlb
->helper_tlbwi
) {
9660 gen_helper_tlbwi(cpu_env
);
9665 if (!env
->tlb
->helper_tlbinv
) {
9668 gen_helper_tlbinv(cpu_env
);
9669 } /* treat as nop if TLBINV not supported */
9674 if (!env
->tlb
->helper_tlbinvf
) {
9677 gen_helper_tlbinvf(cpu_env
);
9678 } /* treat as nop if TLBINV not supported */
9682 if (!env
->tlb
->helper_tlbwr
) {
9685 gen_helper_tlbwr(cpu_env
);
9689 if (!env
->tlb
->helper_tlbp
) {
9692 gen_helper_tlbp(cpu_env
);
9696 if (!env
->tlb
->helper_tlbr
) {
9699 gen_helper_tlbr(cpu_env
);
9701 case OPC_ERET
: /* OPC_ERETNC */
9702 if ((ctx
->insn_flags
& ISA_MIPS_R6
) &&
9703 (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
9706 int bit_shift
= (ctx
->hflags
& MIPS_HFLAG_M16
) ? 16 : 6;
9707 if (ctx
->opcode
& (1 << bit_shift
)) {
9710 check_insn(ctx
, ISA_MIPS_R5
);
9711 gen_helper_eretnc(cpu_env
);
9715 check_insn(ctx
, ISA_MIPS2
);
9716 gen_helper_eret(cpu_env
);
9718 ctx
->base
.is_jmp
= DISAS_EXIT
;
9723 check_insn(ctx
, ISA_MIPS_R1
);
9724 if ((ctx
->insn_flags
& ISA_MIPS_R6
) &&
9725 (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
9728 if (!(ctx
->hflags
& MIPS_HFLAG_DM
)) {
9730 gen_reserved_instruction(ctx
);
9732 gen_helper_deret(cpu_env
);
9733 ctx
->base
.is_jmp
= DISAS_EXIT
;
9738 check_insn(ctx
, ISA_MIPS3
| ISA_MIPS_R1
);
9739 if ((ctx
->insn_flags
& ISA_MIPS_R6
) &&
9740 (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
9743 /* If we get an exception, we want to restart at next instruction */
9744 ctx
->base
.pc_next
+= 4;
9745 save_cpu_state(ctx
, 1);
9746 ctx
->base
.pc_next
-= 4;
9747 gen_helper_wait(cpu_env
);
9748 ctx
->base
.is_jmp
= DISAS_NORETURN
;
9753 gen_reserved_instruction(ctx
);
9756 (void)opn
; /* avoid a compiler warning */
9758 #endif /* !CONFIG_USER_ONLY */
9760 /* CP1 Branches (before delay slot) */
9761 static void gen_compute_branch1(DisasContext
*ctx
, uint32_t op
,
9762 int32_t cc
, int32_t offset
)
9764 target_ulong btarget
;
9765 TCGv_i32 t0
= tcg_temp_new_i32();
9767 if ((ctx
->insn_flags
& ISA_MIPS_R6
) && (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
9768 gen_reserved_instruction(ctx
);
9773 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS_R1
);
9776 btarget
= ctx
->base
.pc_next
+ 4 + offset
;
9780 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
9781 tcg_gen_not_i32(t0
, t0
);
9782 tcg_gen_andi_i32(t0
, t0
, 1);
9783 tcg_gen_extu_i32_tl(bcond
, t0
);
9786 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
9787 tcg_gen_not_i32(t0
, t0
);
9788 tcg_gen_andi_i32(t0
, t0
, 1);
9789 tcg_gen_extu_i32_tl(bcond
, t0
);
9792 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
9793 tcg_gen_andi_i32(t0
, t0
, 1);
9794 tcg_gen_extu_i32_tl(bcond
, t0
);
9797 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
9798 tcg_gen_andi_i32(t0
, t0
, 1);
9799 tcg_gen_extu_i32_tl(bcond
, t0
);
9801 ctx
->hflags
|= MIPS_HFLAG_BL
;
9805 TCGv_i32 t1
= tcg_temp_new_i32();
9806 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
9807 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 1));
9808 tcg_gen_nand_i32(t0
, t0
, t1
);
9809 tcg_temp_free_i32(t1
);
9810 tcg_gen_andi_i32(t0
, t0
, 1);
9811 tcg_gen_extu_i32_tl(bcond
, t0
);
9816 TCGv_i32 t1
= tcg_temp_new_i32();
9817 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
9818 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 1));
9819 tcg_gen_or_i32(t0
, t0
, t1
);
9820 tcg_temp_free_i32(t1
);
9821 tcg_gen_andi_i32(t0
, t0
, 1);
9822 tcg_gen_extu_i32_tl(bcond
, t0
);
9827 TCGv_i32 t1
= tcg_temp_new_i32();
9828 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
9829 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 1));
9830 tcg_gen_and_i32(t0
, t0
, t1
);
9831 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 2));
9832 tcg_gen_and_i32(t0
, t0
, t1
);
9833 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 3));
9834 tcg_gen_nand_i32(t0
, t0
, t1
);
9835 tcg_temp_free_i32(t1
);
9836 tcg_gen_andi_i32(t0
, t0
, 1);
9837 tcg_gen_extu_i32_tl(bcond
, t0
);
9842 TCGv_i32 t1
= tcg_temp_new_i32();
9843 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
9844 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 1));
9845 tcg_gen_or_i32(t0
, t0
, t1
);
9846 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 2));
9847 tcg_gen_or_i32(t0
, t0
, t1
);
9848 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 3));
9849 tcg_gen_or_i32(t0
, t0
, t1
);
9850 tcg_temp_free_i32(t1
);
9851 tcg_gen_andi_i32(t0
, t0
, 1);
9852 tcg_gen_extu_i32_tl(bcond
, t0
);
9855 ctx
->hflags
|= MIPS_HFLAG_BC
;
9858 MIPS_INVAL("cp1 cond branch");
9859 gen_reserved_instruction(ctx
);
9862 ctx
->btarget
= btarget
;
9863 ctx
->hflags
|= MIPS_HFLAG_BDS32
;
9865 tcg_temp_free_i32(t0
);
9868 /* R6 CP1 Branches */
9869 static void gen_compute_branch1_r6(DisasContext
*ctx
, uint32_t op
,
9870 int32_t ft
, int32_t offset
,
9873 target_ulong btarget
;
9874 TCGv_i64 t0
= tcg_temp_new_i64();
9876 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
9877 #ifdef MIPS_DEBUG_DISAS
9878 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
9879 "\n", ctx
->base
.pc_next
);
9881 gen_reserved_instruction(ctx
);
9885 gen_load_fpr64(ctx
, t0
, ft
);
9886 tcg_gen_andi_i64(t0
, t0
, 1);
9888 btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
9892 tcg_gen_xori_i64(t0
, t0
, 1);
9893 ctx
->hflags
|= MIPS_HFLAG_BC
;
9896 /* t0 already set */
9897 ctx
->hflags
|= MIPS_HFLAG_BC
;
9900 MIPS_INVAL("cp1 cond branch");
9901 gen_reserved_instruction(ctx
);
9905 tcg_gen_trunc_i64_tl(bcond
, t0
);
9907 ctx
->btarget
= btarget
;
9909 switch (delayslot_size
) {
9911 ctx
->hflags
|= MIPS_HFLAG_BDS16
;
9914 ctx
->hflags
|= MIPS_HFLAG_BDS32
;
9919 tcg_temp_free_i64(t0
);
9922 /* Coprocessor 1 (FPU) */
9924 #define FOP(func, fmt) (((fmt) << 21) | (func))
9927 OPC_ADD_S
= FOP(0, FMT_S
),
9928 OPC_SUB_S
= FOP(1, FMT_S
),
9929 OPC_MUL_S
= FOP(2, FMT_S
),
9930 OPC_DIV_S
= FOP(3, FMT_S
),
9931 OPC_SQRT_S
= FOP(4, FMT_S
),
9932 OPC_ABS_S
= FOP(5, FMT_S
),
9933 OPC_MOV_S
= FOP(6, FMT_S
),
9934 OPC_NEG_S
= FOP(7, FMT_S
),
9935 OPC_ROUND_L_S
= FOP(8, FMT_S
),
9936 OPC_TRUNC_L_S
= FOP(9, FMT_S
),
9937 OPC_CEIL_L_S
= FOP(10, FMT_S
),
9938 OPC_FLOOR_L_S
= FOP(11, FMT_S
),
9939 OPC_ROUND_W_S
= FOP(12, FMT_S
),
9940 OPC_TRUNC_W_S
= FOP(13, FMT_S
),
9941 OPC_CEIL_W_S
= FOP(14, FMT_S
),
9942 OPC_FLOOR_W_S
= FOP(15, FMT_S
),
9943 OPC_SEL_S
= FOP(16, FMT_S
),
9944 OPC_MOVCF_S
= FOP(17, FMT_S
),
9945 OPC_MOVZ_S
= FOP(18, FMT_S
),
9946 OPC_MOVN_S
= FOP(19, FMT_S
),
9947 OPC_SELEQZ_S
= FOP(20, FMT_S
),
9948 OPC_RECIP_S
= FOP(21, FMT_S
),
9949 OPC_RSQRT_S
= FOP(22, FMT_S
),
9950 OPC_SELNEZ_S
= FOP(23, FMT_S
),
9951 OPC_MADDF_S
= FOP(24, FMT_S
),
9952 OPC_MSUBF_S
= FOP(25, FMT_S
),
9953 OPC_RINT_S
= FOP(26, FMT_S
),
9954 OPC_CLASS_S
= FOP(27, FMT_S
),
9955 OPC_MIN_S
= FOP(28, FMT_S
),
9956 OPC_RECIP2_S
= FOP(28, FMT_S
),
9957 OPC_MINA_S
= FOP(29, FMT_S
),
9958 OPC_RECIP1_S
= FOP(29, FMT_S
),
9959 OPC_MAX_S
= FOP(30, FMT_S
),
9960 OPC_RSQRT1_S
= FOP(30, FMT_S
),
9961 OPC_MAXA_S
= FOP(31, FMT_S
),
9962 OPC_RSQRT2_S
= FOP(31, FMT_S
),
9963 OPC_CVT_D_S
= FOP(33, FMT_S
),
9964 OPC_CVT_W_S
= FOP(36, FMT_S
),
9965 OPC_CVT_L_S
= FOP(37, FMT_S
),
9966 OPC_CVT_PS_S
= FOP(38, FMT_S
),
9967 OPC_CMP_F_S
= FOP(48, FMT_S
),
9968 OPC_CMP_UN_S
= FOP(49, FMT_S
),
9969 OPC_CMP_EQ_S
= FOP(50, FMT_S
),
9970 OPC_CMP_UEQ_S
= FOP(51, FMT_S
),
9971 OPC_CMP_OLT_S
= FOP(52, FMT_S
),
9972 OPC_CMP_ULT_S
= FOP(53, FMT_S
),
9973 OPC_CMP_OLE_S
= FOP(54, FMT_S
),
9974 OPC_CMP_ULE_S
= FOP(55, FMT_S
),
9975 OPC_CMP_SF_S
= FOP(56, FMT_S
),
9976 OPC_CMP_NGLE_S
= FOP(57, FMT_S
),
9977 OPC_CMP_SEQ_S
= FOP(58, FMT_S
),
9978 OPC_CMP_NGL_S
= FOP(59, FMT_S
),
9979 OPC_CMP_LT_S
= FOP(60, FMT_S
),
9980 OPC_CMP_NGE_S
= FOP(61, FMT_S
),
9981 OPC_CMP_LE_S
= FOP(62, FMT_S
),
9982 OPC_CMP_NGT_S
= FOP(63, FMT_S
),
9984 OPC_ADD_D
= FOP(0, FMT_D
),
9985 OPC_SUB_D
= FOP(1, FMT_D
),
9986 OPC_MUL_D
= FOP(2, FMT_D
),
9987 OPC_DIV_D
= FOP(3, FMT_D
),
9988 OPC_SQRT_D
= FOP(4, FMT_D
),
9989 OPC_ABS_D
= FOP(5, FMT_D
),
9990 OPC_MOV_D
= FOP(6, FMT_D
),
9991 OPC_NEG_D
= FOP(7, FMT_D
),
9992 OPC_ROUND_L_D
= FOP(8, FMT_D
),
9993 OPC_TRUNC_L_D
= FOP(9, FMT_D
),
9994 OPC_CEIL_L_D
= FOP(10, FMT_D
),
9995 OPC_FLOOR_L_D
= FOP(11, FMT_D
),
9996 OPC_ROUND_W_D
= FOP(12, FMT_D
),
9997 OPC_TRUNC_W_D
= FOP(13, FMT_D
),
9998 OPC_CEIL_W_D
= FOP(14, FMT_D
),
9999 OPC_FLOOR_W_D
= FOP(15, FMT_D
),
10000 OPC_SEL_D
= FOP(16, FMT_D
),
10001 OPC_MOVCF_D
= FOP(17, FMT_D
),
10002 OPC_MOVZ_D
= FOP(18, FMT_D
),
10003 OPC_MOVN_D
= FOP(19, FMT_D
),
10004 OPC_SELEQZ_D
= FOP(20, FMT_D
),
10005 OPC_RECIP_D
= FOP(21, FMT_D
),
10006 OPC_RSQRT_D
= FOP(22, FMT_D
),
10007 OPC_SELNEZ_D
= FOP(23, FMT_D
),
10008 OPC_MADDF_D
= FOP(24, FMT_D
),
10009 OPC_MSUBF_D
= FOP(25, FMT_D
),
10010 OPC_RINT_D
= FOP(26, FMT_D
),
10011 OPC_CLASS_D
= FOP(27, FMT_D
),
10012 OPC_MIN_D
= FOP(28, FMT_D
),
10013 OPC_RECIP2_D
= FOP(28, FMT_D
),
10014 OPC_MINA_D
= FOP(29, FMT_D
),
10015 OPC_RECIP1_D
= FOP(29, FMT_D
),
10016 OPC_MAX_D
= FOP(30, FMT_D
),
10017 OPC_RSQRT1_D
= FOP(30, FMT_D
),
10018 OPC_MAXA_D
= FOP(31, FMT_D
),
10019 OPC_RSQRT2_D
= FOP(31, FMT_D
),
10020 OPC_CVT_S_D
= FOP(32, FMT_D
),
10021 OPC_CVT_W_D
= FOP(36, FMT_D
),
10022 OPC_CVT_L_D
= FOP(37, FMT_D
),
10023 OPC_CMP_F_D
= FOP(48, FMT_D
),
10024 OPC_CMP_UN_D
= FOP(49, FMT_D
),
10025 OPC_CMP_EQ_D
= FOP(50, FMT_D
),
10026 OPC_CMP_UEQ_D
= FOP(51, FMT_D
),
10027 OPC_CMP_OLT_D
= FOP(52, FMT_D
),
10028 OPC_CMP_ULT_D
= FOP(53, FMT_D
),
10029 OPC_CMP_OLE_D
= FOP(54, FMT_D
),
10030 OPC_CMP_ULE_D
= FOP(55, FMT_D
),
10031 OPC_CMP_SF_D
= FOP(56, FMT_D
),
10032 OPC_CMP_NGLE_D
= FOP(57, FMT_D
),
10033 OPC_CMP_SEQ_D
= FOP(58, FMT_D
),
10034 OPC_CMP_NGL_D
= FOP(59, FMT_D
),
10035 OPC_CMP_LT_D
= FOP(60, FMT_D
),
10036 OPC_CMP_NGE_D
= FOP(61, FMT_D
),
10037 OPC_CMP_LE_D
= FOP(62, FMT_D
),
10038 OPC_CMP_NGT_D
= FOP(63, FMT_D
),
10040 OPC_CVT_S_W
= FOP(32, FMT_W
),
10041 OPC_CVT_D_W
= FOP(33, FMT_W
),
10042 OPC_CVT_S_L
= FOP(32, FMT_L
),
10043 OPC_CVT_D_L
= FOP(33, FMT_L
),
10044 OPC_CVT_PS_PW
= FOP(38, FMT_W
),
10046 OPC_ADD_PS
= FOP(0, FMT_PS
),
10047 OPC_SUB_PS
= FOP(1, FMT_PS
),
10048 OPC_MUL_PS
= FOP(2, FMT_PS
),
10049 OPC_DIV_PS
= FOP(3, FMT_PS
),
10050 OPC_ABS_PS
= FOP(5, FMT_PS
),
10051 OPC_MOV_PS
= FOP(6, FMT_PS
),
10052 OPC_NEG_PS
= FOP(7, FMT_PS
),
10053 OPC_MOVCF_PS
= FOP(17, FMT_PS
),
10054 OPC_MOVZ_PS
= FOP(18, FMT_PS
),
10055 OPC_MOVN_PS
= FOP(19, FMT_PS
),
10056 OPC_ADDR_PS
= FOP(24, FMT_PS
),
10057 OPC_MULR_PS
= FOP(26, FMT_PS
),
10058 OPC_RECIP2_PS
= FOP(28, FMT_PS
),
10059 OPC_RECIP1_PS
= FOP(29, FMT_PS
),
10060 OPC_RSQRT1_PS
= FOP(30, FMT_PS
),
10061 OPC_RSQRT2_PS
= FOP(31, FMT_PS
),
10063 OPC_CVT_S_PU
= FOP(32, FMT_PS
),
10064 OPC_CVT_PW_PS
= FOP(36, FMT_PS
),
10065 OPC_CVT_S_PL
= FOP(40, FMT_PS
),
10066 OPC_PLL_PS
= FOP(44, FMT_PS
),
10067 OPC_PLU_PS
= FOP(45, FMT_PS
),
10068 OPC_PUL_PS
= FOP(46, FMT_PS
),
10069 OPC_PUU_PS
= FOP(47, FMT_PS
),
10070 OPC_CMP_F_PS
= FOP(48, FMT_PS
),
10071 OPC_CMP_UN_PS
= FOP(49, FMT_PS
),
10072 OPC_CMP_EQ_PS
= FOP(50, FMT_PS
),
10073 OPC_CMP_UEQ_PS
= FOP(51, FMT_PS
),
10074 OPC_CMP_OLT_PS
= FOP(52, FMT_PS
),
10075 OPC_CMP_ULT_PS
= FOP(53, FMT_PS
),
10076 OPC_CMP_OLE_PS
= FOP(54, FMT_PS
),
10077 OPC_CMP_ULE_PS
= FOP(55, FMT_PS
),
10078 OPC_CMP_SF_PS
= FOP(56, FMT_PS
),
10079 OPC_CMP_NGLE_PS
= FOP(57, FMT_PS
),
10080 OPC_CMP_SEQ_PS
= FOP(58, FMT_PS
),
10081 OPC_CMP_NGL_PS
= FOP(59, FMT_PS
),
10082 OPC_CMP_LT_PS
= FOP(60, FMT_PS
),
10083 OPC_CMP_NGE_PS
= FOP(61, FMT_PS
),
10084 OPC_CMP_LE_PS
= FOP(62, FMT_PS
),
10085 OPC_CMP_NGT_PS
= FOP(63, FMT_PS
),
10089 R6_OPC_CMP_AF_S
= FOP(0, FMT_W
),
10090 R6_OPC_CMP_UN_S
= FOP(1, FMT_W
),
10091 R6_OPC_CMP_EQ_S
= FOP(2, FMT_W
),
10092 R6_OPC_CMP_UEQ_S
= FOP(3, FMT_W
),
10093 R6_OPC_CMP_LT_S
= FOP(4, FMT_W
),
10094 R6_OPC_CMP_ULT_S
= FOP(5, FMT_W
),
10095 R6_OPC_CMP_LE_S
= FOP(6, FMT_W
),
10096 R6_OPC_CMP_ULE_S
= FOP(7, FMT_W
),
10097 R6_OPC_CMP_SAF_S
= FOP(8, FMT_W
),
10098 R6_OPC_CMP_SUN_S
= FOP(9, FMT_W
),
10099 R6_OPC_CMP_SEQ_S
= FOP(10, FMT_W
),
10100 R6_OPC_CMP_SEUQ_S
= FOP(11, FMT_W
),
10101 R6_OPC_CMP_SLT_S
= FOP(12, FMT_W
),
10102 R6_OPC_CMP_SULT_S
= FOP(13, FMT_W
),
10103 R6_OPC_CMP_SLE_S
= FOP(14, FMT_W
),
10104 R6_OPC_CMP_SULE_S
= FOP(15, FMT_W
),
10105 R6_OPC_CMP_OR_S
= FOP(17, FMT_W
),
10106 R6_OPC_CMP_UNE_S
= FOP(18, FMT_W
),
10107 R6_OPC_CMP_NE_S
= FOP(19, FMT_W
),
10108 R6_OPC_CMP_SOR_S
= FOP(25, FMT_W
),
10109 R6_OPC_CMP_SUNE_S
= FOP(26, FMT_W
),
10110 R6_OPC_CMP_SNE_S
= FOP(27, FMT_W
),
10112 R6_OPC_CMP_AF_D
= FOP(0, FMT_L
),
10113 R6_OPC_CMP_UN_D
= FOP(1, FMT_L
),
10114 R6_OPC_CMP_EQ_D
= FOP(2, FMT_L
),
10115 R6_OPC_CMP_UEQ_D
= FOP(3, FMT_L
),
10116 R6_OPC_CMP_LT_D
= FOP(4, FMT_L
),
10117 R6_OPC_CMP_ULT_D
= FOP(5, FMT_L
),
10118 R6_OPC_CMP_LE_D
= FOP(6, FMT_L
),
10119 R6_OPC_CMP_ULE_D
= FOP(7, FMT_L
),
10120 R6_OPC_CMP_SAF_D
= FOP(8, FMT_L
),
10121 R6_OPC_CMP_SUN_D
= FOP(9, FMT_L
),
10122 R6_OPC_CMP_SEQ_D
= FOP(10, FMT_L
),
10123 R6_OPC_CMP_SEUQ_D
= FOP(11, FMT_L
),
10124 R6_OPC_CMP_SLT_D
= FOP(12, FMT_L
),
10125 R6_OPC_CMP_SULT_D
= FOP(13, FMT_L
),
10126 R6_OPC_CMP_SLE_D
= FOP(14, FMT_L
),
10127 R6_OPC_CMP_SULE_D
= FOP(15, FMT_L
),
10128 R6_OPC_CMP_OR_D
= FOP(17, FMT_L
),
10129 R6_OPC_CMP_UNE_D
= FOP(18, FMT_L
),
10130 R6_OPC_CMP_NE_D
= FOP(19, FMT_L
),
10131 R6_OPC_CMP_SOR_D
= FOP(25, FMT_L
),
10132 R6_OPC_CMP_SUNE_D
= FOP(26, FMT_L
),
10133 R6_OPC_CMP_SNE_D
= FOP(27, FMT_L
),
10136 static void gen_cp1(DisasContext
*ctx
, uint32_t opc
, int rt
, int fs
)
10138 TCGv t0
= tcg_temp_new();
10143 TCGv_i32 fp0
= tcg_temp_new_i32();
10145 gen_load_fpr32(ctx
, fp0
, fs
);
10146 tcg_gen_ext_i32_tl(t0
, fp0
);
10147 tcg_temp_free_i32(fp0
);
10149 gen_store_gpr(t0
, rt
);
10152 gen_load_gpr(t0
, rt
);
10154 TCGv_i32 fp0
= tcg_temp_new_i32();
10156 tcg_gen_trunc_tl_i32(fp0
, t0
);
10157 gen_store_fpr32(ctx
, fp0
, fs
);
10158 tcg_temp_free_i32(fp0
);
10162 gen_helper_1e0i(cfc1
, t0
, fs
);
10163 gen_store_gpr(t0
, rt
);
10166 gen_load_gpr(t0
, rt
);
10167 save_cpu_state(ctx
, 0);
10169 TCGv_i32 fs_tmp
= tcg_const_i32(fs
);
10171 gen_helper_0e2i(ctc1
, t0
, fs_tmp
, rt
);
10172 tcg_temp_free_i32(fs_tmp
);
10174 /* Stop translation as we may have changed hflags */
10175 ctx
->base
.is_jmp
= DISAS_STOP
;
10177 #if defined(TARGET_MIPS64)
10179 gen_load_fpr64(ctx
, t0
, fs
);
10180 gen_store_gpr(t0
, rt
);
10183 gen_load_gpr(t0
, rt
);
10184 gen_store_fpr64(ctx
, t0
, fs
);
10189 TCGv_i32 fp0
= tcg_temp_new_i32();
10191 gen_load_fpr32h(ctx
, fp0
, fs
);
10192 tcg_gen_ext_i32_tl(t0
, fp0
);
10193 tcg_temp_free_i32(fp0
);
10195 gen_store_gpr(t0
, rt
);
10198 gen_load_gpr(t0
, rt
);
10200 TCGv_i32 fp0
= tcg_temp_new_i32();
10202 tcg_gen_trunc_tl_i32(fp0
, t0
);
10203 gen_store_fpr32h(ctx
, fp0
, fs
);
10204 tcg_temp_free_i32(fp0
);
10208 MIPS_INVAL("cp1 move");
10209 gen_reserved_instruction(ctx
);
10217 static void gen_movci(DisasContext
*ctx
, int rd
, int rs
, int cc
, int tf
)
10224 /* Treat as NOP. */
10229 cond
= TCG_COND_EQ
;
10231 cond
= TCG_COND_NE
;
10234 l1
= gen_new_label();
10235 t0
= tcg_temp_new_i32();
10236 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
10237 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
10238 tcg_temp_free_i32(t0
);
10239 gen_load_gpr(cpu_gpr
[rd
], rs
);
10243 static inline void gen_movcf_s(DisasContext
*ctx
, int fs
, int fd
, int cc
,
10247 TCGv_i32 t0
= tcg_temp_new_i32();
10248 TCGLabel
*l1
= gen_new_label();
10251 cond
= TCG_COND_EQ
;
10253 cond
= TCG_COND_NE
;
10256 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
10257 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
10258 gen_load_fpr32(ctx
, t0
, fs
);
10259 gen_store_fpr32(ctx
, t0
, fd
);
10261 tcg_temp_free_i32(t0
);
10264 static inline void gen_movcf_d(DisasContext
*ctx
, int fs
, int fd
, int cc
,
10268 TCGv_i32 t0
= tcg_temp_new_i32();
10270 TCGLabel
*l1
= gen_new_label();
10273 cond
= TCG_COND_EQ
;
10275 cond
= TCG_COND_NE
;
10278 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
10279 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
10280 tcg_temp_free_i32(t0
);
10281 fp0
= tcg_temp_new_i64();
10282 gen_load_fpr64(ctx
, fp0
, fs
);
10283 gen_store_fpr64(ctx
, fp0
, fd
);
10284 tcg_temp_free_i64(fp0
);
10288 static inline void gen_movcf_ps(DisasContext
*ctx
, int fs
, int fd
,
10292 TCGv_i32 t0
= tcg_temp_new_i32();
10293 TCGLabel
*l1
= gen_new_label();
10294 TCGLabel
*l2
= gen_new_label();
10297 cond
= TCG_COND_EQ
;
10299 cond
= TCG_COND_NE
;
10302 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
10303 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
10304 gen_load_fpr32(ctx
, t0
, fs
);
10305 gen_store_fpr32(ctx
, t0
, fd
);
10308 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
+ 1));
10309 tcg_gen_brcondi_i32(cond
, t0
, 0, l2
);
10310 gen_load_fpr32h(ctx
, t0
, fs
);
10311 gen_store_fpr32h(ctx
, t0
, fd
);
10312 tcg_temp_free_i32(t0
);
10316 static void gen_sel_s(DisasContext
*ctx
, enum fopcode op1
, int fd
, int ft
,
10319 TCGv_i32 t1
= tcg_const_i32(0);
10320 TCGv_i32 fp0
= tcg_temp_new_i32();
10321 TCGv_i32 fp1
= tcg_temp_new_i32();
10322 TCGv_i32 fp2
= tcg_temp_new_i32();
10323 gen_load_fpr32(ctx
, fp0
, fd
);
10324 gen_load_fpr32(ctx
, fp1
, ft
);
10325 gen_load_fpr32(ctx
, fp2
, fs
);
10329 tcg_gen_andi_i32(fp0
, fp0
, 1);
10330 tcg_gen_movcond_i32(TCG_COND_NE
, fp0
, fp0
, t1
, fp1
, fp2
);
10333 tcg_gen_andi_i32(fp1
, fp1
, 1);
10334 tcg_gen_movcond_i32(TCG_COND_EQ
, fp0
, fp1
, t1
, fp2
, t1
);
10337 tcg_gen_andi_i32(fp1
, fp1
, 1);
10338 tcg_gen_movcond_i32(TCG_COND_NE
, fp0
, fp1
, t1
, fp2
, t1
);
10341 MIPS_INVAL("gen_sel_s");
10342 gen_reserved_instruction(ctx
);
10346 gen_store_fpr32(ctx
, fp0
, fd
);
10347 tcg_temp_free_i32(fp2
);
10348 tcg_temp_free_i32(fp1
);
10349 tcg_temp_free_i32(fp0
);
10350 tcg_temp_free_i32(t1
);
10353 static void gen_sel_d(DisasContext
*ctx
, enum fopcode op1
, int fd
, int ft
,
10356 TCGv_i64 t1
= tcg_const_i64(0);
10357 TCGv_i64 fp0
= tcg_temp_new_i64();
10358 TCGv_i64 fp1
= tcg_temp_new_i64();
10359 TCGv_i64 fp2
= tcg_temp_new_i64();
10360 gen_load_fpr64(ctx
, fp0
, fd
);
10361 gen_load_fpr64(ctx
, fp1
, ft
);
10362 gen_load_fpr64(ctx
, fp2
, fs
);
10366 tcg_gen_andi_i64(fp0
, fp0
, 1);
10367 tcg_gen_movcond_i64(TCG_COND_NE
, fp0
, fp0
, t1
, fp1
, fp2
);
10370 tcg_gen_andi_i64(fp1
, fp1
, 1);
10371 tcg_gen_movcond_i64(TCG_COND_EQ
, fp0
, fp1
, t1
, fp2
, t1
);
10374 tcg_gen_andi_i64(fp1
, fp1
, 1);
10375 tcg_gen_movcond_i64(TCG_COND_NE
, fp0
, fp1
, t1
, fp2
, t1
);
10378 MIPS_INVAL("gen_sel_d");
10379 gen_reserved_instruction(ctx
);
10383 gen_store_fpr64(ctx
, fp0
, fd
);
10384 tcg_temp_free_i64(fp2
);
10385 tcg_temp_free_i64(fp1
);
10386 tcg_temp_free_i64(fp0
);
10387 tcg_temp_free_i64(t1
);
10390 static void gen_farith(DisasContext
*ctx
, enum fopcode op1
,
10391 int ft
, int fs
, int fd
, int cc
)
10393 uint32_t func
= ctx
->opcode
& 0x3f;
10397 TCGv_i32 fp0
= tcg_temp_new_i32();
10398 TCGv_i32 fp1
= tcg_temp_new_i32();
10400 gen_load_fpr32(ctx
, fp0
, fs
);
10401 gen_load_fpr32(ctx
, fp1
, ft
);
10402 gen_helper_float_add_s(fp0
, cpu_env
, fp0
, fp1
);
10403 tcg_temp_free_i32(fp1
);
10404 gen_store_fpr32(ctx
, fp0
, fd
);
10405 tcg_temp_free_i32(fp0
);
10410 TCGv_i32 fp0
= tcg_temp_new_i32();
10411 TCGv_i32 fp1
= tcg_temp_new_i32();
10413 gen_load_fpr32(ctx
, fp0
, fs
);
10414 gen_load_fpr32(ctx
, fp1
, ft
);
10415 gen_helper_float_sub_s(fp0
, cpu_env
, fp0
, fp1
);
10416 tcg_temp_free_i32(fp1
);
10417 gen_store_fpr32(ctx
, fp0
, fd
);
10418 tcg_temp_free_i32(fp0
);
10423 TCGv_i32 fp0
= tcg_temp_new_i32();
10424 TCGv_i32 fp1
= tcg_temp_new_i32();
10426 gen_load_fpr32(ctx
, fp0
, fs
);
10427 gen_load_fpr32(ctx
, fp1
, ft
);
10428 gen_helper_float_mul_s(fp0
, cpu_env
, fp0
, fp1
);
10429 tcg_temp_free_i32(fp1
);
10430 gen_store_fpr32(ctx
, fp0
, fd
);
10431 tcg_temp_free_i32(fp0
);
10436 TCGv_i32 fp0
= tcg_temp_new_i32();
10437 TCGv_i32 fp1
= tcg_temp_new_i32();
10439 gen_load_fpr32(ctx
, fp0
, fs
);
10440 gen_load_fpr32(ctx
, fp1
, ft
);
10441 gen_helper_float_div_s(fp0
, cpu_env
, fp0
, fp1
);
10442 tcg_temp_free_i32(fp1
);
10443 gen_store_fpr32(ctx
, fp0
, fd
);
10444 tcg_temp_free_i32(fp0
);
10449 TCGv_i32 fp0
= tcg_temp_new_i32();
10451 gen_load_fpr32(ctx
, fp0
, fs
);
10452 gen_helper_float_sqrt_s(fp0
, cpu_env
, fp0
);
10453 gen_store_fpr32(ctx
, fp0
, fd
);
10454 tcg_temp_free_i32(fp0
);
10459 TCGv_i32 fp0
= tcg_temp_new_i32();
10461 gen_load_fpr32(ctx
, fp0
, fs
);
10462 if (ctx
->abs2008
) {
10463 tcg_gen_andi_i32(fp0
, fp0
, 0x7fffffffUL
);
10465 gen_helper_float_abs_s(fp0
, fp0
);
10467 gen_store_fpr32(ctx
, fp0
, fd
);
10468 tcg_temp_free_i32(fp0
);
10473 TCGv_i32 fp0
= tcg_temp_new_i32();
10475 gen_load_fpr32(ctx
, fp0
, fs
);
10476 gen_store_fpr32(ctx
, fp0
, fd
);
10477 tcg_temp_free_i32(fp0
);
10482 TCGv_i32 fp0
= tcg_temp_new_i32();
10484 gen_load_fpr32(ctx
, fp0
, fs
);
10485 if (ctx
->abs2008
) {
10486 tcg_gen_xori_i32(fp0
, fp0
, 1UL << 31);
10488 gen_helper_float_chs_s(fp0
, fp0
);
10490 gen_store_fpr32(ctx
, fp0
, fd
);
10491 tcg_temp_free_i32(fp0
);
10494 case OPC_ROUND_L_S
:
10495 check_cp1_64bitmode(ctx
);
10497 TCGv_i32 fp32
= tcg_temp_new_i32();
10498 TCGv_i64 fp64
= tcg_temp_new_i64();
10500 gen_load_fpr32(ctx
, fp32
, fs
);
10501 if (ctx
->nan2008
) {
10502 gen_helper_float_round_2008_l_s(fp64
, cpu_env
, fp32
);
10504 gen_helper_float_round_l_s(fp64
, cpu_env
, fp32
);
10506 tcg_temp_free_i32(fp32
);
10507 gen_store_fpr64(ctx
, fp64
, fd
);
10508 tcg_temp_free_i64(fp64
);
10511 case OPC_TRUNC_L_S
:
10512 check_cp1_64bitmode(ctx
);
10514 TCGv_i32 fp32
= tcg_temp_new_i32();
10515 TCGv_i64 fp64
= tcg_temp_new_i64();
10517 gen_load_fpr32(ctx
, fp32
, fs
);
10518 if (ctx
->nan2008
) {
10519 gen_helper_float_trunc_2008_l_s(fp64
, cpu_env
, fp32
);
10521 gen_helper_float_trunc_l_s(fp64
, cpu_env
, fp32
);
10523 tcg_temp_free_i32(fp32
);
10524 gen_store_fpr64(ctx
, fp64
, fd
);
10525 tcg_temp_free_i64(fp64
);
10529 check_cp1_64bitmode(ctx
);
10531 TCGv_i32 fp32
= tcg_temp_new_i32();
10532 TCGv_i64 fp64
= tcg_temp_new_i64();
10534 gen_load_fpr32(ctx
, fp32
, fs
);
10535 if (ctx
->nan2008
) {
10536 gen_helper_float_ceil_2008_l_s(fp64
, cpu_env
, fp32
);
10538 gen_helper_float_ceil_l_s(fp64
, cpu_env
, fp32
);
10540 tcg_temp_free_i32(fp32
);
10541 gen_store_fpr64(ctx
, fp64
, fd
);
10542 tcg_temp_free_i64(fp64
);
10545 case OPC_FLOOR_L_S
:
10546 check_cp1_64bitmode(ctx
);
10548 TCGv_i32 fp32
= tcg_temp_new_i32();
10549 TCGv_i64 fp64
= tcg_temp_new_i64();
10551 gen_load_fpr32(ctx
, fp32
, fs
);
10552 if (ctx
->nan2008
) {
10553 gen_helper_float_floor_2008_l_s(fp64
, cpu_env
, fp32
);
10555 gen_helper_float_floor_l_s(fp64
, cpu_env
, fp32
);
10557 tcg_temp_free_i32(fp32
);
10558 gen_store_fpr64(ctx
, fp64
, fd
);
10559 tcg_temp_free_i64(fp64
);
10562 case OPC_ROUND_W_S
:
10564 TCGv_i32 fp0
= tcg_temp_new_i32();
10566 gen_load_fpr32(ctx
, fp0
, fs
);
10567 if (ctx
->nan2008
) {
10568 gen_helper_float_round_2008_w_s(fp0
, cpu_env
, fp0
);
10570 gen_helper_float_round_w_s(fp0
, cpu_env
, fp0
);
10572 gen_store_fpr32(ctx
, fp0
, fd
);
10573 tcg_temp_free_i32(fp0
);
10576 case OPC_TRUNC_W_S
:
10578 TCGv_i32 fp0
= tcg_temp_new_i32();
10580 gen_load_fpr32(ctx
, fp0
, fs
);
10581 if (ctx
->nan2008
) {
10582 gen_helper_float_trunc_2008_w_s(fp0
, cpu_env
, fp0
);
10584 gen_helper_float_trunc_w_s(fp0
, cpu_env
, fp0
);
10586 gen_store_fpr32(ctx
, fp0
, fd
);
10587 tcg_temp_free_i32(fp0
);
10592 TCGv_i32 fp0
= tcg_temp_new_i32();
10594 gen_load_fpr32(ctx
, fp0
, fs
);
10595 if (ctx
->nan2008
) {
10596 gen_helper_float_ceil_2008_w_s(fp0
, cpu_env
, fp0
);
10598 gen_helper_float_ceil_w_s(fp0
, cpu_env
, fp0
);
10600 gen_store_fpr32(ctx
, fp0
, fd
);
10601 tcg_temp_free_i32(fp0
);
10604 case OPC_FLOOR_W_S
:
10606 TCGv_i32 fp0
= tcg_temp_new_i32();
10608 gen_load_fpr32(ctx
, fp0
, fs
);
10609 if (ctx
->nan2008
) {
10610 gen_helper_float_floor_2008_w_s(fp0
, cpu_env
, fp0
);
10612 gen_helper_float_floor_w_s(fp0
, cpu_env
, fp0
);
10614 gen_store_fpr32(ctx
, fp0
, fd
);
10615 tcg_temp_free_i32(fp0
);
10619 check_insn(ctx
, ISA_MIPS_R6
);
10620 gen_sel_s(ctx
, op1
, fd
, ft
, fs
);
10623 check_insn(ctx
, ISA_MIPS_R6
);
10624 gen_sel_s(ctx
, op1
, fd
, ft
, fs
);
10627 check_insn(ctx
, ISA_MIPS_R6
);
10628 gen_sel_s(ctx
, op1
, fd
, ft
, fs
);
10631 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
10632 gen_movcf_s(ctx
, fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
10635 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
10637 TCGLabel
*l1
= gen_new_label();
10641 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
10643 fp0
= tcg_temp_new_i32();
10644 gen_load_fpr32(ctx
, fp0
, fs
);
10645 gen_store_fpr32(ctx
, fp0
, fd
);
10646 tcg_temp_free_i32(fp0
);
10651 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
10653 TCGLabel
*l1
= gen_new_label();
10657 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
10658 fp0
= tcg_temp_new_i32();
10659 gen_load_fpr32(ctx
, fp0
, fs
);
10660 gen_store_fpr32(ctx
, fp0
, fd
);
10661 tcg_temp_free_i32(fp0
);
10668 TCGv_i32 fp0
= tcg_temp_new_i32();
10670 gen_load_fpr32(ctx
, fp0
, fs
);
10671 gen_helper_float_recip_s(fp0
, cpu_env
, fp0
);
10672 gen_store_fpr32(ctx
, fp0
, fd
);
10673 tcg_temp_free_i32(fp0
);
10678 TCGv_i32 fp0
= tcg_temp_new_i32();
10680 gen_load_fpr32(ctx
, fp0
, fs
);
10681 gen_helper_float_rsqrt_s(fp0
, cpu_env
, fp0
);
10682 gen_store_fpr32(ctx
, fp0
, fd
);
10683 tcg_temp_free_i32(fp0
);
10687 check_insn(ctx
, ISA_MIPS_R6
);
10689 TCGv_i32 fp0
= tcg_temp_new_i32();
10690 TCGv_i32 fp1
= tcg_temp_new_i32();
10691 TCGv_i32 fp2
= tcg_temp_new_i32();
10692 gen_load_fpr32(ctx
, fp0
, fs
);
10693 gen_load_fpr32(ctx
, fp1
, ft
);
10694 gen_load_fpr32(ctx
, fp2
, fd
);
10695 gen_helper_float_maddf_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
10696 gen_store_fpr32(ctx
, fp2
, fd
);
10697 tcg_temp_free_i32(fp2
);
10698 tcg_temp_free_i32(fp1
);
10699 tcg_temp_free_i32(fp0
);
10703 check_insn(ctx
, ISA_MIPS_R6
);
10705 TCGv_i32 fp0
= tcg_temp_new_i32();
10706 TCGv_i32 fp1
= tcg_temp_new_i32();
10707 TCGv_i32 fp2
= tcg_temp_new_i32();
10708 gen_load_fpr32(ctx
, fp0
, fs
);
10709 gen_load_fpr32(ctx
, fp1
, ft
);
10710 gen_load_fpr32(ctx
, fp2
, fd
);
10711 gen_helper_float_msubf_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
10712 gen_store_fpr32(ctx
, fp2
, fd
);
10713 tcg_temp_free_i32(fp2
);
10714 tcg_temp_free_i32(fp1
);
10715 tcg_temp_free_i32(fp0
);
10719 check_insn(ctx
, ISA_MIPS_R6
);
10721 TCGv_i32 fp0
= tcg_temp_new_i32();
10722 gen_load_fpr32(ctx
, fp0
, fs
);
10723 gen_helper_float_rint_s(fp0
, cpu_env
, fp0
);
10724 gen_store_fpr32(ctx
, fp0
, fd
);
10725 tcg_temp_free_i32(fp0
);
10729 check_insn(ctx
, ISA_MIPS_R6
);
10731 TCGv_i32 fp0
= tcg_temp_new_i32();
10732 gen_load_fpr32(ctx
, fp0
, fs
);
10733 gen_helper_float_class_s(fp0
, cpu_env
, fp0
);
10734 gen_store_fpr32(ctx
, fp0
, fd
);
10735 tcg_temp_free_i32(fp0
);
10738 case OPC_MIN_S
: /* OPC_RECIP2_S */
10739 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
10741 TCGv_i32 fp0
= tcg_temp_new_i32();
10742 TCGv_i32 fp1
= tcg_temp_new_i32();
10743 TCGv_i32 fp2
= tcg_temp_new_i32();
10744 gen_load_fpr32(ctx
, fp0
, fs
);
10745 gen_load_fpr32(ctx
, fp1
, ft
);
10746 gen_helper_float_min_s(fp2
, cpu_env
, fp0
, fp1
);
10747 gen_store_fpr32(ctx
, fp2
, fd
);
10748 tcg_temp_free_i32(fp2
);
10749 tcg_temp_free_i32(fp1
);
10750 tcg_temp_free_i32(fp0
);
10753 check_cp1_64bitmode(ctx
);
10755 TCGv_i32 fp0
= tcg_temp_new_i32();
10756 TCGv_i32 fp1
= tcg_temp_new_i32();
10758 gen_load_fpr32(ctx
, fp0
, fs
);
10759 gen_load_fpr32(ctx
, fp1
, ft
);
10760 gen_helper_float_recip2_s(fp0
, cpu_env
, fp0
, fp1
);
10761 tcg_temp_free_i32(fp1
);
10762 gen_store_fpr32(ctx
, fp0
, fd
);
10763 tcg_temp_free_i32(fp0
);
10767 case OPC_MINA_S
: /* OPC_RECIP1_S */
10768 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
10770 TCGv_i32 fp0
= tcg_temp_new_i32();
10771 TCGv_i32 fp1
= tcg_temp_new_i32();
10772 TCGv_i32 fp2
= tcg_temp_new_i32();
10773 gen_load_fpr32(ctx
, fp0
, fs
);
10774 gen_load_fpr32(ctx
, fp1
, ft
);
10775 gen_helper_float_mina_s(fp2
, cpu_env
, fp0
, fp1
);
10776 gen_store_fpr32(ctx
, fp2
, fd
);
10777 tcg_temp_free_i32(fp2
);
10778 tcg_temp_free_i32(fp1
);
10779 tcg_temp_free_i32(fp0
);
10782 check_cp1_64bitmode(ctx
);
10784 TCGv_i32 fp0
= tcg_temp_new_i32();
10786 gen_load_fpr32(ctx
, fp0
, fs
);
10787 gen_helper_float_recip1_s(fp0
, cpu_env
, fp0
);
10788 gen_store_fpr32(ctx
, fp0
, fd
);
10789 tcg_temp_free_i32(fp0
);
10793 case OPC_MAX_S
: /* OPC_RSQRT1_S */
10794 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
10796 TCGv_i32 fp0
= tcg_temp_new_i32();
10797 TCGv_i32 fp1
= tcg_temp_new_i32();
10798 gen_load_fpr32(ctx
, fp0
, fs
);
10799 gen_load_fpr32(ctx
, fp1
, ft
);
10800 gen_helper_float_max_s(fp1
, cpu_env
, fp0
, fp1
);
10801 gen_store_fpr32(ctx
, fp1
, fd
);
10802 tcg_temp_free_i32(fp1
);
10803 tcg_temp_free_i32(fp0
);
10806 check_cp1_64bitmode(ctx
);
10808 TCGv_i32 fp0
= tcg_temp_new_i32();
10810 gen_load_fpr32(ctx
, fp0
, fs
);
10811 gen_helper_float_rsqrt1_s(fp0
, cpu_env
, fp0
);
10812 gen_store_fpr32(ctx
, fp0
, fd
);
10813 tcg_temp_free_i32(fp0
);
10817 case OPC_MAXA_S
: /* OPC_RSQRT2_S */
10818 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
10820 TCGv_i32 fp0
= tcg_temp_new_i32();
10821 TCGv_i32 fp1
= tcg_temp_new_i32();
10822 gen_load_fpr32(ctx
, fp0
, fs
);
10823 gen_load_fpr32(ctx
, fp1
, ft
);
10824 gen_helper_float_maxa_s(fp1
, cpu_env
, fp0
, fp1
);
10825 gen_store_fpr32(ctx
, fp1
, fd
);
10826 tcg_temp_free_i32(fp1
);
10827 tcg_temp_free_i32(fp0
);
10830 check_cp1_64bitmode(ctx
);
10832 TCGv_i32 fp0
= tcg_temp_new_i32();
10833 TCGv_i32 fp1
= tcg_temp_new_i32();
10835 gen_load_fpr32(ctx
, fp0
, fs
);
10836 gen_load_fpr32(ctx
, fp1
, ft
);
10837 gen_helper_float_rsqrt2_s(fp0
, cpu_env
, fp0
, fp1
);
10838 tcg_temp_free_i32(fp1
);
10839 gen_store_fpr32(ctx
, fp0
, fd
);
10840 tcg_temp_free_i32(fp0
);
10845 check_cp1_registers(ctx
, fd
);
10847 TCGv_i32 fp32
= tcg_temp_new_i32();
10848 TCGv_i64 fp64
= tcg_temp_new_i64();
10850 gen_load_fpr32(ctx
, fp32
, fs
);
10851 gen_helper_float_cvtd_s(fp64
, cpu_env
, fp32
);
10852 tcg_temp_free_i32(fp32
);
10853 gen_store_fpr64(ctx
, fp64
, fd
);
10854 tcg_temp_free_i64(fp64
);
10859 TCGv_i32 fp0
= tcg_temp_new_i32();
10861 gen_load_fpr32(ctx
, fp0
, fs
);
10862 if (ctx
->nan2008
) {
10863 gen_helper_float_cvt_2008_w_s(fp0
, cpu_env
, fp0
);
10865 gen_helper_float_cvt_w_s(fp0
, cpu_env
, fp0
);
10867 gen_store_fpr32(ctx
, fp0
, fd
);
10868 tcg_temp_free_i32(fp0
);
10872 check_cp1_64bitmode(ctx
);
10874 TCGv_i32 fp32
= tcg_temp_new_i32();
10875 TCGv_i64 fp64
= tcg_temp_new_i64();
10877 gen_load_fpr32(ctx
, fp32
, fs
);
10878 if (ctx
->nan2008
) {
10879 gen_helper_float_cvt_2008_l_s(fp64
, cpu_env
, fp32
);
10881 gen_helper_float_cvt_l_s(fp64
, cpu_env
, fp32
);
10883 tcg_temp_free_i32(fp32
);
10884 gen_store_fpr64(ctx
, fp64
, fd
);
10885 tcg_temp_free_i64(fp64
);
10891 TCGv_i64 fp64
= tcg_temp_new_i64();
10892 TCGv_i32 fp32_0
= tcg_temp_new_i32();
10893 TCGv_i32 fp32_1
= tcg_temp_new_i32();
10895 gen_load_fpr32(ctx
, fp32_0
, fs
);
10896 gen_load_fpr32(ctx
, fp32_1
, ft
);
10897 tcg_gen_concat_i32_i64(fp64
, fp32_1
, fp32_0
);
10898 tcg_temp_free_i32(fp32_1
);
10899 tcg_temp_free_i32(fp32_0
);
10900 gen_store_fpr64(ctx
, fp64
, fd
);
10901 tcg_temp_free_i64(fp64
);
10907 case OPC_CMP_UEQ_S
:
10908 case OPC_CMP_OLT_S
:
10909 case OPC_CMP_ULT_S
:
10910 case OPC_CMP_OLE_S
:
10911 case OPC_CMP_ULE_S
:
10913 case OPC_CMP_NGLE_S
:
10914 case OPC_CMP_SEQ_S
:
10915 case OPC_CMP_NGL_S
:
10917 case OPC_CMP_NGE_S
:
10919 case OPC_CMP_NGT_S
:
10920 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
10921 if (ctx
->opcode
& (1 << 6)) {
10922 gen_cmpabs_s(ctx
, func
- 48, ft
, fs
, cc
);
10924 gen_cmp_s(ctx
, func
- 48, ft
, fs
, cc
);
10928 check_cp1_registers(ctx
, fs
| ft
| fd
);
10930 TCGv_i64 fp0
= tcg_temp_new_i64();
10931 TCGv_i64 fp1
= tcg_temp_new_i64();
10933 gen_load_fpr64(ctx
, fp0
, fs
);
10934 gen_load_fpr64(ctx
, fp1
, ft
);
10935 gen_helper_float_add_d(fp0
, cpu_env
, fp0
, fp1
);
10936 tcg_temp_free_i64(fp1
);
10937 gen_store_fpr64(ctx
, fp0
, fd
);
10938 tcg_temp_free_i64(fp0
);
10942 check_cp1_registers(ctx
, fs
| ft
| fd
);
10944 TCGv_i64 fp0
= tcg_temp_new_i64();
10945 TCGv_i64 fp1
= tcg_temp_new_i64();
10947 gen_load_fpr64(ctx
, fp0
, fs
);
10948 gen_load_fpr64(ctx
, fp1
, ft
);
10949 gen_helper_float_sub_d(fp0
, cpu_env
, fp0
, fp1
);
10950 tcg_temp_free_i64(fp1
);
10951 gen_store_fpr64(ctx
, fp0
, fd
);
10952 tcg_temp_free_i64(fp0
);
10956 check_cp1_registers(ctx
, fs
| ft
| fd
);
10958 TCGv_i64 fp0
= tcg_temp_new_i64();
10959 TCGv_i64 fp1
= tcg_temp_new_i64();
10961 gen_load_fpr64(ctx
, fp0
, fs
);
10962 gen_load_fpr64(ctx
, fp1
, ft
);
10963 gen_helper_float_mul_d(fp0
, cpu_env
, fp0
, fp1
);
10964 tcg_temp_free_i64(fp1
);
10965 gen_store_fpr64(ctx
, fp0
, fd
);
10966 tcg_temp_free_i64(fp0
);
10970 check_cp1_registers(ctx
, fs
| ft
| fd
);
10972 TCGv_i64 fp0
= tcg_temp_new_i64();
10973 TCGv_i64 fp1
= tcg_temp_new_i64();
10975 gen_load_fpr64(ctx
, fp0
, fs
);
10976 gen_load_fpr64(ctx
, fp1
, ft
);
10977 gen_helper_float_div_d(fp0
, cpu_env
, fp0
, fp1
);
10978 tcg_temp_free_i64(fp1
);
10979 gen_store_fpr64(ctx
, fp0
, fd
);
10980 tcg_temp_free_i64(fp0
);
10984 check_cp1_registers(ctx
, fs
| fd
);
10986 TCGv_i64 fp0
= tcg_temp_new_i64();
10988 gen_load_fpr64(ctx
, fp0
, fs
);
10989 gen_helper_float_sqrt_d(fp0
, cpu_env
, fp0
);
10990 gen_store_fpr64(ctx
, fp0
, fd
);
10991 tcg_temp_free_i64(fp0
);
10995 check_cp1_registers(ctx
, fs
| fd
);
10997 TCGv_i64 fp0
= tcg_temp_new_i64();
10999 gen_load_fpr64(ctx
, fp0
, fs
);
11000 if (ctx
->abs2008
) {
11001 tcg_gen_andi_i64(fp0
, fp0
, 0x7fffffffffffffffULL
);
11003 gen_helper_float_abs_d(fp0
, fp0
);
11005 gen_store_fpr64(ctx
, fp0
, fd
);
11006 tcg_temp_free_i64(fp0
);
11010 check_cp1_registers(ctx
, fs
| fd
);
11012 TCGv_i64 fp0
= tcg_temp_new_i64();
11014 gen_load_fpr64(ctx
, fp0
, fs
);
11015 gen_store_fpr64(ctx
, fp0
, fd
);
11016 tcg_temp_free_i64(fp0
);
11020 check_cp1_registers(ctx
, fs
| fd
);
11022 TCGv_i64 fp0
= tcg_temp_new_i64();
11024 gen_load_fpr64(ctx
, fp0
, fs
);
11025 if (ctx
->abs2008
) {
11026 tcg_gen_xori_i64(fp0
, fp0
, 1ULL << 63);
11028 gen_helper_float_chs_d(fp0
, fp0
);
11030 gen_store_fpr64(ctx
, fp0
, fd
);
11031 tcg_temp_free_i64(fp0
);
11034 case OPC_ROUND_L_D
:
11035 check_cp1_64bitmode(ctx
);
11037 TCGv_i64 fp0
= tcg_temp_new_i64();
11039 gen_load_fpr64(ctx
, fp0
, fs
);
11040 if (ctx
->nan2008
) {
11041 gen_helper_float_round_2008_l_d(fp0
, cpu_env
, fp0
);
11043 gen_helper_float_round_l_d(fp0
, cpu_env
, fp0
);
11045 gen_store_fpr64(ctx
, fp0
, fd
);
11046 tcg_temp_free_i64(fp0
);
11049 case OPC_TRUNC_L_D
:
11050 check_cp1_64bitmode(ctx
);
11052 TCGv_i64 fp0
= tcg_temp_new_i64();
11054 gen_load_fpr64(ctx
, fp0
, fs
);
11055 if (ctx
->nan2008
) {
11056 gen_helper_float_trunc_2008_l_d(fp0
, cpu_env
, fp0
);
11058 gen_helper_float_trunc_l_d(fp0
, cpu_env
, fp0
);
11060 gen_store_fpr64(ctx
, fp0
, fd
);
11061 tcg_temp_free_i64(fp0
);
11065 check_cp1_64bitmode(ctx
);
11067 TCGv_i64 fp0
= tcg_temp_new_i64();
11069 gen_load_fpr64(ctx
, fp0
, fs
);
11070 if (ctx
->nan2008
) {
11071 gen_helper_float_ceil_2008_l_d(fp0
, cpu_env
, fp0
);
11073 gen_helper_float_ceil_l_d(fp0
, cpu_env
, fp0
);
11075 gen_store_fpr64(ctx
, fp0
, fd
);
11076 tcg_temp_free_i64(fp0
);
11079 case OPC_FLOOR_L_D
:
11080 check_cp1_64bitmode(ctx
);
11082 TCGv_i64 fp0
= tcg_temp_new_i64();
11084 gen_load_fpr64(ctx
, fp0
, fs
);
11085 if (ctx
->nan2008
) {
11086 gen_helper_float_floor_2008_l_d(fp0
, cpu_env
, fp0
);
11088 gen_helper_float_floor_l_d(fp0
, cpu_env
, fp0
);
11090 gen_store_fpr64(ctx
, fp0
, fd
);
11091 tcg_temp_free_i64(fp0
);
11094 case OPC_ROUND_W_D
:
11095 check_cp1_registers(ctx
, fs
);
11097 TCGv_i32 fp32
= tcg_temp_new_i32();
11098 TCGv_i64 fp64
= tcg_temp_new_i64();
11100 gen_load_fpr64(ctx
, fp64
, fs
);
11101 if (ctx
->nan2008
) {
11102 gen_helper_float_round_2008_w_d(fp32
, cpu_env
, fp64
);
11104 gen_helper_float_round_w_d(fp32
, cpu_env
, fp64
);
11106 tcg_temp_free_i64(fp64
);
11107 gen_store_fpr32(ctx
, fp32
, fd
);
11108 tcg_temp_free_i32(fp32
);
11111 case OPC_TRUNC_W_D
:
11112 check_cp1_registers(ctx
, fs
);
11114 TCGv_i32 fp32
= tcg_temp_new_i32();
11115 TCGv_i64 fp64
= tcg_temp_new_i64();
11117 gen_load_fpr64(ctx
, fp64
, fs
);
11118 if (ctx
->nan2008
) {
11119 gen_helper_float_trunc_2008_w_d(fp32
, cpu_env
, fp64
);
11121 gen_helper_float_trunc_w_d(fp32
, cpu_env
, fp64
);
11123 tcg_temp_free_i64(fp64
);
11124 gen_store_fpr32(ctx
, fp32
, fd
);
11125 tcg_temp_free_i32(fp32
);
11129 check_cp1_registers(ctx
, fs
);
11131 TCGv_i32 fp32
= tcg_temp_new_i32();
11132 TCGv_i64 fp64
= tcg_temp_new_i64();
11134 gen_load_fpr64(ctx
, fp64
, fs
);
11135 if (ctx
->nan2008
) {
11136 gen_helper_float_ceil_2008_w_d(fp32
, cpu_env
, fp64
);
11138 gen_helper_float_ceil_w_d(fp32
, cpu_env
, fp64
);
11140 tcg_temp_free_i64(fp64
);
11141 gen_store_fpr32(ctx
, fp32
, fd
);
11142 tcg_temp_free_i32(fp32
);
11145 case OPC_FLOOR_W_D
:
11146 check_cp1_registers(ctx
, fs
);
11148 TCGv_i32 fp32
= tcg_temp_new_i32();
11149 TCGv_i64 fp64
= tcg_temp_new_i64();
11151 gen_load_fpr64(ctx
, fp64
, fs
);
11152 if (ctx
->nan2008
) {
11153 gen_helper_float_floor_2008_w_d(fp32
, cpu_env
, fp64
);
11155 gen_helper_float_floor_w_d(fp32
, cpu_env
, fp64
);
11157 tcg_temp_free_i64(fp64
);
11158 gen_store_fpr32(ctx
, fp32
, fd
);
11159 tcg_temp_free_i32(fp32
);
11163 check_insn(ctx
, ISA_MIPS_R6
);
11164 gen_sel_d(ctx
, op1
, fd
, ft
, fs
);
11167 check_insn(ctx
, ISA_MIPS_R6
);
11168 gen_sel_d(ctx
, op1
, fd
, ft
, fs
);
11171 check_insn(ctx
, ISA_MIPS_R6
);
11172 gen_sel_d(ctx
, op1
, fd
, ft
, fs
);
11175 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
11176 gen_movcf_d(ctx
, fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
11179 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
11181 TCGLabel
*l1
= gen_new_label();
11185 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
11187 fp0
= tcg_temp_new_i64();
11188 gen_load_fpr64(ctx
, fp0
, fs
);
11189 gen_store_fpr64(ctx
, fp0
, fd
);
11190 tcg_temp_free_i64(fp0
);
11195 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
11197 TCGLabel
*l1
= gen_new_label();
11201 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
11202 fp0
= tcg_temp_new_i64();
11203 gen_load_fpr64(ctx
, fp0
, fs
);
11204 gen_store_fpr64(ctx
, fp0
, fd
);
11205 tcg_temp_free_i64(fp0
);
11211 check_cp1_registers(ctx
, fs
| fd
);
11213 TCGv_i64 fp0
= tcg_temp_new_i64();
11215 gen_load_fpr64(ctx
, fp0
, fs
);
11216 gen_helper_float_recip_d(fp0
, cpu_env
, fp0
);
11217 gen_store_fpr64(ctx
, fp0
, fd
);
11218 tcg_temp_free_i64(fp0
);
11222 check_cp1_registers(ctx
, fs
| fd
);
11224 TCGv_i64 fp0
= tcg_temp_new_i64();
11226 gen_load_fpr64(ctx
, fp0
, fs
);
11227 gen_helper_float_rsqrt_d(fp0
, cpu_env
, fp0
);
11228 gen_store_fpr64(ctx
, fp0
, fd
);
11229 tcg_temp_free_i64(fp0
);
11233 check_insn(ctx
, ISA_MIPS_R6
);
11235 TCGv_i64 fp0
= tcg_temp_new_i64();
11236 TCGv_i64 fp1
= tcg_temp_new_i64();
11237 TCGv_i64 fp2
= tcg_temp_new_i64();
11238 gen_load_fpr64(ctx
, fp0
, fs
);
11239 gen_load_fpr64(ctx
, fp1
, ft
);
11240 gen_load_fpr64(ctx
, fp2
, fd
);
11241 gen_helper_float_maddf_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
11242 gen_store_fpr64(ctx
, fp2
, fd
);
11243 tcg_temp_free_i64(fp2
);
11244 tcg_temp_free_i64(fp1
);
11245 tcg_temp_free_i64(fp0
);
11249 check_insn(ctx
, ISA_MIPS_R6
);
11251 TCGv_i64 fp0
= tcg_temp_new_i64();
11252 TCGv_i64 fp1
= tcg_temp_new_i64();
11253 TCGv_i64 fp2
= tcg_temp_new_i64();
11254 gen_load_fpr64(ctx
, fp0
, fs
);
11255 gen_load_fpr64(ctx
, fp1
, ft
);
11256 gen_load_fpr64(ctx
, fp2
, fd
);
11257 gen_helper_float_msubf_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
11258 gen_store_fpr64(ctx
, fp2
, fd
);
11259 tcg_temp_free_i64(fp2
);
11260 tcg_temp_free_i64(fp1
);
11261 tcg_temp_free_i64(fp0
);
11265 check_insn(ctx
, ISA_MIPS_R6
);
11267 TCGv_i64 fp0
= tcg_temp_new_i64();
11268 gen_load_fpr64(ctx
, fp0
, fs
);
11269 gen_helper_float_rint_d(fp0
, cpu_env
, fp0
);
11270 gen_store_fpr64(ctx
, fp0
, fd
);
11271 tcg_temp_free_i64(fp0
);
11275 check_insn(ctx
, ISA_MIPS_R6
);
11277 TCGv_i64 fp0
= tcg_temp_new_i64();
11278 gen_load_fpr64(ctx
, fp0
, fs
);
11279 gen_helper_float_class_d(fp0
, cpu_env
, fp0
);
11280 gen_store_fpr64(ctx
, fp0
, fd
);
11281 tcg_temp_free_i64(fp0
);
11284 case OPC_MIN_D
: /* OPC_RECIP2_D */
11285 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
11287 TCGv_i64 fp0
= tcg_temp_new_i64();
11288 TCGv_i64 fp1
= tcg_temp_new_i64();
11289 gen_load_fpr64(ctx
, fp0
, fs
);
11290 gen_load_fpr64(ctx
, fp1
, ft
);
11291 gen_helper_float_min_d(fp1
, cpu_env
, fp0
, fp1
);
11292 gen_store_fpr64(ctx
, fp1
, fd
);
11293 tcg_temp_free_i64(fp1
);
11294 tcg_temp_free_i64(fp0
);
11297 check_cp1_64bitmode(ctx
);
11299 TCGv_i64 fp0
= tcg_temp_new_i64();
11300 TCGv_i64 fp1
= tcg_temp_new_i64();
11302 gen_load_fpr64(ctx
, fp0
, fs
);
11303 gen_load_fpr64(ctx
, fp1
, ft
);
11304 gen_helper_float_recip2_d(fp0
, cpu_env
, fp0
, fp1
);
11305 tcg_temp_free_i64(fp1
);
11306 gen_store_fpr64(ctx
, fp0
, fd
);
11307 tcg_temp_free_i64(fp0
);
11311 case OPC_MINA_D
: /* OPC_RECIP1_D */
11312 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
11314 TCGv_i64 fp0
= tcg_temp_new_i64();
11315 TCGv_i64 fp1
= tcg_temp_new_i64();
11316 gen_load_fpr64(ctx
, fp0
, fs
);
11317 gen_load_fpr64(ctx
, fp1
, ft
);
11318 gen_helper_float_mina_d(fp1
, cpu_env
, fp0
, fp1
);
11319 gen_store_fpr64(ctx
, fp1
, fd
);
11320 tcg_temp_free_i64(fp1
);
11321 tcg_temp_free_i64(fp0
);
11324 check_cp1_64bitmode(ctx
);
11326 TCGv_i64 fp0
= tcg_temp_new_i64();
11328 gen_load_fpr64(ctx
, fp0
, fs
);
11329 gen_helper_float_recip1_d(fp0
, cpu_env
, fp0
);
11330 gen_store_fpr64(ctx
, fp0
, fd
);
11331 tcg_temp_free_i64(fp0
);
11335 case OPC_MAX_D
: /* OPC_RSQRT1_D */
11336 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
11338 TCGv_i64 fp0
= tcg_temp_new_i64();
11339 TCGv_i64 fp1
= tcg_temp_new_i64();
11340 gen_load_fpr64(ctx
, fp0
, fs
);
11341 gen_load_fpr64(ctx
, fp1
, ft
);
11342 gen_helper_float_max_d(fp1
, cpu_env
, fp0
, fp1
);
11343 gen_store_fpr64(ctx
, fp1
, fd
);
11344 tcg_temp_free_i64(fp1
);
11345 tcg_temp_free_i64(fp0
);
11348 check_cp1_64bitmode(ctx
);
11350 TCGv_i64 fp0
= tcg_temp_new_i64();
11352 gen_load_fpr64(ctx
, fp0
, fs
);
11353 gen_helper_float_rsqrt1_d(fp0
, cpu_env
, fp0
);
11354 gen_store_fpr64(ctx
, fp0
, fd
);
11355 tcg_temp_free_i64(fp0
);
11359 case OPC_MAXA_D
: /* OPC_RSQRT2_D */
11360 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
11362 TCGv_i64 fp0
= tcg_temp_new_i64();
11363 TCGv_i64 fp1
= tcg_temp_new_i64();
11364 gen_load_fpr64(ctx
, fp0
, fs
);
11365 gen_load_fpr64(ctx
, fp1
, ft
);
11366 gen_helper_float_maxa_d(fp1
, cpu_env
, fp0
, fp1
);
11367 gen_store_fpr64(ctx
, fp1
, fd
);
11368 tcg_temp_free_i64(fp1
);
11369 tcg_temp_free_i64(fp0
);
11372 check_cp1_64bitmode(ctx
);
11374 TCGv_i64 fp0
= tcg_temp_new_i64();
11375 TCGv_i64 fp1
= tcg_temp_new_i64();
11377 gen_load_fpr64(ctx
, fp0
, fs
);
11378 gen_load_fpr64(ctx
, fp1
, ft
);
11379 gen_helper_float_rsqrt2_d(fp0
, cpu_env
, fp0
, fp1
);
11380 tcg_temp_free_i64(fp1
);
11381 gen_store_fpr64(ctx
, fp0
, fd
);
11382 tcg_temp_free_i64(fp0
);
11389 case OPC_CMP_UEQ_D
:
11390 case OPC_CMP_OLT_D
:
11391 case OPC_CMP_ULT_D
:
11392 case OPC_CMP_OLE_D
:
11393 case OPC_CMP_ULE_D
:
11395 case OPC_CMP_NGLE_D
:
11396 case OPC_CMP_SEQ_D
:
11397 case OPC_CMP_NGL_D
:
11399 case OPC_CMP_NGE_D
:
11401 case OPC_CMP_NGT_D
:
11402 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
11403 if (ctx
->opcode
& (1 << 6)) {
11404 gen_cmpabs_d(ctx
, func
- 48, ft
, fs
, cc
);
11406 gen_cmp_d(ctx
, func
- 48, ft
, fs
, cc
);
11410 check_cp1_registers(ctx
, fs
);
11412 TCGv_i32 fp32
= tcg_temp_new_i32();
11413 TCGv_i64 fp64
= tcg_temp_new_i64();
11415 gen_load_fpr64(ctx
, fp64
, fs
);
11416 gen_helper_float_cvts_d(fp32
, cpu_env
, fp64
);
11417 tcg_temp_free_i64(fp64
);
11418 gen_store_fpr32(ctx
, fp32
, fd
);
11419 tcg_temp_free_i32(fp32
);
11423 check_cp1_registers(ctx
, fs
);
11425 TCGv_i32 fp32
= tcg_temp_new_i32();
11426 TCGv_i64 fp64
= tcg_temp_new_i64();
11428 gen_load_fpr64(ctx
, fp64
, fs
);
11429 if (ctx
->nan2008
) {
11430 gen_helper_float_cvt_2008_w_d(fp32
, cpu_env
, fp64
);
11432 gen_helper_float_cvt_w_d(fp32
, cpu_env
, fp64
);
11434 tcg_temp_free_i64(fp64
);
11435 gen_store_fpr32(ctx
, fp32
, fd
);
11436 tcg_temp_free_i32(fp32
);
11440 check_cp1_64bitmode(ctx
);
11442 TCGv_i64 fp0
= tcg_temp_new_i64();
11444 gen_load_fpr64(ctx
, fp0
, fs
);
11445 if (ctx
->nan2008
) {
11446 gen_helper_float_cvt_2008_l_d(fp0
, cpu_env
, fp0
);
11448 gen_helper_float_cvt_l_d(fp0
, cpu_env
, fp0
);
11450 gen_store_fpr64(ctx
, fp0
, fd
);
11451 tcg_temp_free_i64(fp0
);
11456 TCGv_i32 fp0
= tcg_temp_new_i32();
11458 gen_load_fpr32(ctx
, fp0
, fs
);
11459 gen_helper_float_cvts_w(fp0
, cpu_env
, fp0
);
11460 gen_store_fpr32(ctx
, fp0
, fd
);
11461 tcg_temp_free_i32(fp0
);
11465 check_cp1_registers(ctx
, fd
);
11467 TCGv_i32 fp32
= tcg_temp_new_i32();
11468 TCGv_i64 fp64
= tcg_temp_new_i64();
11470 gen_load_fpr32(ctx
, fp32
, fs
);
11471 gen_helper_float_cvtd_w(fp64
, cpu_env
, fp32
);
11472 tcg_temp_free_i32(fp32
);
11473 gen_store_fpr64(ctx
, fp64
, fd
);
11474 tcg_temp_free_i64(fp64
);
11478 check_cp1_64bitmode(ctx
);
11480 TCGv_i32 fp32
= tcg_temp_new_i32();
11481 TCGv_i64 fp64
= tcg_temp_new_i64();
11483 gen_load_fpr64(ctx
, fp64
, fs
);
11484 gen_helper_float_cvts_l(fp32
, cpu_env
, fp64
);
11485 tcg_temp_free_i64(fp64
);
11486 gen_store_fpr32(ctx
, fp32
, fd
);
11487 tcg_temp_free_i32(fp32
);
11491 check_cp1_64bitmode(ctx
);
11493 TCGv_i64 fp0
= tcg_temp_new_i64();
11495 gen_load_fpr64(ctx
, fp0
, fs
);
11496 gen_helper_float_cvtd_l(fp0
, cpu_env
, fp0
);
11497 gen_store_fpr64(ctx
, fp0
, fd
);
11498 tcg_temp_free_i64(fp0
);
11501 case OPC_CVT_PS_PW
:
11504 TCGv_i64 fp0
= tcg_temp_new_i64();
11506 gen_load_fpr64(ctx
, fp0
, fs
);
11507 gen_helper_float_cvtps_pw(fp0
, cpu_env
, fp0
);
11508 gen_store_fpr64(ctx
, fp0
, fd
);
11509 tcg_temp_free_i64(fp0
);
11515 TCGv_i64 fp0
= tcg_temp_new_i64();
11516 TCGv_i64 fp1
= tcg_temp_new_i64();
11518 gen_load_fpr64(ctx
, fp0
, fs
);
11519 gen_load_fpr64(ctx
, fp1
, ft
);
11520 gen_helper_float_add_ps(fp0
, cpu_env
, fp0
, fp1
);
11521 tcg_temp_free_i64(fp1
);
11522 gen_store_fpr64(ctx
, fp0
, fd
);
11523 tcg_temp_free_i64(fp0
);
11529 TCGv_i64 fp0
= tcg_temp_new_i64();
11530 TCGv_i64 fp1
= tcg_temp_new_i64();
11532 gen_load_fpr64(ctx
, fp0
, fs
);
11533 gen_load_fpr64(ctx
, fp1
, ft
);
11534 gen_helper_float_sub_ps(fp0
, cpu_env
, fp0
, fp1
);
11535 tcg_temp_free_i64(fp1
);
11536 gen_store_fpr64(ctx
, fp0
, fd
);
11537 tcg_temp_free_i64(fp0
);
11543 TCGv_i64 fp0
= tcg_temp_new_i64();
11544 TCGv_i64 fp1
= tcg_temp_new_i64();
11546 gen_load_fpr64(ctx
, fp0
, fs
);
11547 gen_load_fpr64(ctx
, fp1
, ft
);
11548 gen_helper_float_mul_ps(fp0
, cpu_env
, fp0
, fp1
);
11549 tcg_temp_free_i64(fp1
);
11550 gen_store_fpr64(ctx
, fp0
, fd
);
11551 tcg_temp_free_i64(fp0
);
11557 TCGv_i64 fp0
= tcg_temp_new_i64();
11559 gen_load_fpr64(ctx
, fp0
, fs
);
11560 gen_helper_float_abs_ps(fp0
, fp0
);
11561 gen_store_fpr64(ctx
, fp0
, fd
);
11562 tcg_temp_free_i64(fp0
);
11568 TCGv_i64 fp0
= tcg_temp_new_i64();
11570 gen_load_fpr64(ctx
, fp0
, fs
);
11571 gen_store_fpr64(ctx
, fp0
, fd
);
11572 tcg_temp_free_i64(fp0
);
11578 TCGv_i64 fp0
= tcg_temp_new_i64();
11580 gen_load_fpr64(ctx
, fp0
, fs
);
11581 gen_helper_float_chs_ps(fp0
, fp0
);
11582 gen_store_fpr64(ctx
, fp0
, fd
);
11583 tcg_temp_free_i64(fp0
);
11588 gen_movcf_ps(ctx
, fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
11593 TCGLabel
*l1
= gen_new_label();
11597 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
11599 fp0
= tcg_temp_new_i64();
11600 gen_load_fpr64(ctx
, fp0
, fs
);
11601 gen_store_fpr64(ctx
, fp0
, fd
);
11602 tcg_temp_free_i64(fp0
);
11609 TCGLabel
*l1
= gen_new_label();
11613 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
11614 fp0
= tcg_temp_new_i64();
11615 gen_load_fpr64(ctx
, fp0
, fs
);
11616 gen_store_fpr64(ctx
, fp0
, fd
);
11617 tcg_temp_free_i64(fp0
);
11625 TCGv_i64 fp0
= tcg_temp_new_i64();
11626 TCGv_i64 fp1
= tcg_temp_new_i64();
11628 gen_load_fpr64(ctx
, fp0
, ft
);
11629 gen_load_fpr64(ctx
, fp1
, fs
);
11630 gen_helper_float_addr_ps(fp0
, cpu_env
, fp0
, fp1
);
11631 tcg_temp_free_i64(fp1
);
11632 gen_store_fpr64(ctx
, fp0
, fd
);
11633 tcg_temp_free_i64(fp0
);
11639 TCGv_i64 fp0
= tcg_temp_new_i64();
11640 TCGv_i64 fp1
= tcg_temp_new_i64();
11642 gen_load_fpr64(ctx
, fp0
, ft
);
11643 gen_load_fpr64(ctx
, fp1
, fs
);
11644 gen_helper_float_mulr_ps(fp0
, cpu_env
, fp0
, fp1
);
11645 tcg_temp_free_i64(fp1
);
11646 gen_store_fpr64(ctx
, fp0
, fd
);
11647 tcg_temp_free_i64(fp0
);
11650 case OPC_RECIP2_PS
:
11653 TCGv_i64 fp0
= tcg_temp_new_i64();
11654 TCGv_i64 fp1
= tcg_temp_new_i64();
11656 gen_load_fpr64(ctx
, fp0
, fs
);
11657 gen_load_fpr64(ctx
, fp1
, ft
);
11658 gen_helper_float_recip2_ps(fp0
, cpu_env
, fp0
, fp1
);
11659 tcg_temp_free_i64(fp1
);
11660 gen_store_fpr64(ctx
, fp0
, fd
);
11661 tcg_temp_free_i64(fp0
);
11664 case OPC_RECIP1_PS
:
11667 TCGv_i64 fp0
= tcg_temp_new_i64();
11669 gen_load_fpr64(ctx
, fp0
, fs
);
11670 gen_helper_float_recip1_ps(fp0
, cpu_env
, fp0
);
11671 gen_store_fpr64(ctx
, fp0
, fd
);
11672 tcg_temp_free_i64(fp0
);
11675 case OPC_RSQRT1_PS
:
11678 TCGv_i64 fp0
= tcg_temp_new_i64();
11680 gen_load_fpr64(ctx
, fp0
, fs
);
11681 gen_helper_float_rsqrt1_ps(fp0
, cpu_env
, fp0
);
11682 gen_store_fpr64(ctx
, fp0
, fd
);
11683 tcg_temp_free_i64(fp0
);
11686 case OPC_RSQRT2_PS
:
11689 TCGv_i64 fp0
= tcg_temp_new_i64();
11690 TCGv_i64 fp1
= tcg_temp_new_i64();
11692 gen_load_fpr64(ctx
, fp0
, fs
);
11693 gen_load_fpr64(ctx
, fp1
, ft
);
11694 gen_helper_float_rsqrt2_ps(fp0
, cpu_env
, fp0
, fp1
);
11695 tcg_temp_free_i64(fp1
);
11696 gen_store_fpr64(ctx
, fp0
, fd
);
11697 tcg_temp_free_i64(fp0
);
11701 check_cp1_64bitmode(ctx
);
11703 TCGv_i32 fp0
= tcg_temp_new_i32();
11705 gen_load_fpr32h(ctx
, fp0
, fs
);
11706 gen_helper_float_cvts_pu(fp0
, cpu_env
, fp0
);
11707 gen_store_fpr32(ctx
, fp0
, fd
);
11708 tcg_temp_free_i32(fp0
);
11711 case OPC_CVT_PW_PS
:
11714 TCGv_i64 fp0
= tcg_temp_new_i64();
11716 gen_load_fpr64(ctx
, fp0
, fs
);
11717 gen_helper_float_cvtpw_ps(fp0
, cpu_env
, fp0
);
11718 gen_store_fpr64(ctx
, fp0
, fd
);
11719 tcg_temp_free_i64(fp0
);
11723 check_cp1_64bitmode(ctx
);
11725 TCGv_i32 fp0
= tcg_temp_new_i32();
11727 gen_load_fpr32(ctx
, fp0
, fs
);
11728 gen_helper_float_cvts_pl(fp0
, cpu_env
, fp0
);
11729 gen_store_fpr32(ctx
, fp0
, fd
);
11730 tcg_temp_free_i32(fp0
);
11736 TCGv_i32 fp0
= tcg_temp_new_i32();
11737 TCGv_i32 fp1
= tcg_temp_new_i32();
11739 gen_load_fpr32(ctx
, fp0
, fs
);
11740 gen_load_fpr32(ctx
, fp1
, ft
);
11741 gen_store_fpr32h(ctx
, fp0
, fd
);
11742 gen_store_fpr32(ctx
, fp1
, fd
);
11743 tcg_temp_free_i32(fp0
);
11744 tcg_temp_free_i32(fp1
);
11750 TCGv_i32 fp0
= tcg_temp_new_i32();
11751 TCGv_i32 fp1
= tcg_temp_new_i32();
11753 gen_load_fpr32(ctx
, fp0
, fs
);
11754 gen_load_fpr32h(ctx
, fp1
, ft
);
11755 gen_store_fpr32(ctx
, fp1
, fd
);
11756 gen_store_fpr32h(ctx
, fp0
, fd
);
11757 tcg_temp_free_i32(fp0
);
11758 tcg_temp_free_i32(fp1
);
11764 TCGv_i32 fp0
= tcg_temp_new_i32();
11765 TCGv_i32 fp1
= tcg_temp_new_i32();
11767 gen_load_fpr32h(ctx
, fp0
, fs
);
11768 gen_load_fpr32(ctx
, fp1
, ft
);
11769 gen_store_fpr32(ctx
, fp1
, fd
);
11770 gen_store_fpr32h(ctx
, fp0
, fd
);
11771 tcg_temp_free_i32(fp0
);
11772 tcg_temp_free_i32(fp1
);
11778 TCGv_i32 fp0
= tcg_temp_new_i32();
11779 TCGv_i32 fp1
= tcg_temp_new_i32();
11781 gen_load_fpr32h(ctx
, fp0
, fs
);
11782 gen_load_fpr32h(ctx
, fp1
, ft
);
11783 gen_store_fpr32(ctx
, fp1
, fd
);
11784 gen_store_fpr32h(ctx
, fp0
, fd
);
11785 tcg_temp_free_i32(fp0
);
11786 tcg_temp_free_i32(fp1
);
11790 case OPC_CMP_UN_PS
:
11791 case OPC_CMP_EQ_PS
:
11792 case OPC_CMP_UEQ_PS
:
11793 case OPC_CMP_OLT_PS
:
11794 case OPC_CMP_ULT_PS
:
11795 case OPC_CMP_OLE_PS
:
11796 case OPC_CMP_ULE_PS
:
11797 case OPC_CMP_SF_PS
:
11798 case OPC_CMP_NGLE_PS
:
11799 case OPC_CMP_SEQ_PS
:
11800 case OPC_CMP_NGL_PS
:
11801 case OPC_CMP_LT_PS
:
11802 case OPC_CMP_NGE_PS
:
11803 case OPC_CMP_LE_PS
:
11804 case OPC_CMP_NGT_PS
:
11805 if (ctx
->opcode
& (1 << 6)) {
11806 gen_cmpabs_ps(ctx
, func
- 48, ft
, fs
, cc
);
11808 gen_cmp_ps(ctx
, func
- 48, ft
, fs
, cc
);
11812 MIPS_INVAL("farith");
11813 gen_reserved_instruction(ctx
);
11818 /* Coprocessor 3 (FPU) */
11819 static void gen_flt3_ldst(DisasContext
*ctx
, uint32_t opc
,
11820 int fd
, int fs
, int base
, int index
)
11822 TCGv t0
= tcg_temp_new();
11825 gen_load_gpr(t0
, index
);
11826 } else if (index
== 0) {
11827 gen_load_gpr(t0
, base
);
11829 gen_op_addr_add(ctx
, t0
, cpu_gpr
[base
], cpu_gpr
[index
]);
11832 * Don't do NOP if destination is zero: we must perform the actual
11839 TCGv_i32 fp0
= tcg_temp_new_i32();
11841 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESL
);
11842 tcg_gen_trunc_tl_i32(fp0
, t0
);
11843 gen_store_fpr32(ctx
, fp0
, fd
);
11844 tcg_temp_free_i32(fp0
);
11849 check_cp1_registers(ctx
, fd
);
11851 TCGv_i64 fp0
= tcg_temp_new_i64();
11852 tcg_gen_qemu_ld_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
11853 gen_store_fpr64(ctx
, fp0
, fd
);
11854 tcg_temp_free_i64(fp0
);
11858 check_cp1_64bitmode(ctx
);
11859 tcg_gen_andi_tl(t0
, t0
, ~0x7);
11861 TCGv_i64 fp0
= tcg_temp_new_i64();
11863 tcg_gen_qemu_ld_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
11864 gen_store_fpr64(ctx
, fp0
, fd
);
11865 tcg_temp_free_i64(fp0
);
11871 TCGv_i32 fp0
= tcg_temp_new_i32();
11872 gen_load_fpr32(ctx
, fp0
, fs
);
11873 tcg_gen_qemu_st_i32(fp0
, t0
, ctx
->mem_idx
, MO_TEUL
);
11874 tcg_temp_free_i32(fp0
);
11879 check_cp1_registers(ctx
, fs
);
11881 TCGv_i64 fp0
= tcg_temp_new_i64();
11882 gen_load_fpr64(ctx
, fp0
, fs
);
11883 tcg_gen_qemu_st_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
11884 tcg_temp_free_i64(fp0
);
11888 check_cp1_64bitmode(ctx
);
11889 tcg_gen_andi_tl(t0
, t0
, ~0x7);
11891 TCGv_i64 fp0
= tcg_temp_new_i64();
11892 gen_load_fpr64(ctx
, fp0
, fs
);
11893 tcg_gen_qemu_st_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
11894 tcg_temp_free_i64(fp0
);
11901 static void gen_flt3_arith(DisasContext
*ctx
, uint32_t opc
,
11902 int fd
, int fr
, int fs
, int ft
)
11908 TCGv t0
= tcg_temp_local_new();
11909 TCGv_i32 fp
= tcg_temp_new_i32();
11910 TCGv_i32 fph
= tcg_temp_new_i32();
11911 TCGLabel
*l1
= gen_new_label();
11912 TCGLabel
*l2
= gen_new_label();
11914 gen_load_gpr(t0
, fr
);
11915 tcg_gen_andi_tl(t0
, t0
, 0x7);
11917 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, 0, l1
);
11918 gen_load_fpr32(ctx
, fp
, fs
);
11919 gen_load_fpr32h(ctx
, fph
, fs
);
11920 gen_store_fpr32(ctx
, fp
, fd
);
11921 gen_store_fpr32h(ctx
, fph
, fd
);
11924 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, 4, l2
);
11926 #ifdef TARGET_WORDS_BIGENDIAN
11927 gen_load_fpr32(ctx
, fp
, fs
);
11928 gen_load_fpr32h(ctx
, fph
, ft
);
11929 gen_store_fpr32h(ctx
, fp
, fd
);
11930 gen_store_fpr32(ctx
, fph
, fd
);
11932 gen_load_fpr32h(ctx
, fph
, fs
);
11933 gen_load_fpr32(ctx
, fp
, ft
);
11934 gen_store_fpr32(ctx
, fph
, fd
);
11935 gen_store_fpr32h(ctx
, fp
, fd
);
11938 tcg_temp_free_i32(fp
);
11939 tcg_temp_free_i32(fph
);
11945 TCGv_i32 fp0
= tcg_temp_new_i32();
11946 TCGv_i32 fp1
= tcg_temp_new_i32();
11947 TCGv_i32 fp2
= tcg_temp_new_i32();
11949 gen_load_fpr32(ctx
, fp0
, fs
);
11950 gen_load_fpr32(ctx
, fp1
, ft
);
11951 gen_load_fpr32(ctx
, fp2
, fr
);
11952 gen_helper_float_madd_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
11953 tcg_temp_free_i32(fp0
);
11954 tcg_temp_free_i32(fp1
);
11955 gen_store_fpr32(ctx
, fp2
, fd
);
11956 tcg_temp_free_i32(fp2
);
11961 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
11963 TCGv_i64 fp0
= tcg_temp_new_i64();
11964 TCGv_i64 fp1
= tcg_temp_new_i64();
11965 TCGv_i64 fp2
= tcg_temp_new_i64();
11967 gen_load_fpr64(ctx
, fp0
, fs
);
11968 gen_load_fpr64(ctx
, fp1
, ft
);
11969 gen_load_fpr64(ctx
, fp2
, fr
);
11970 gen_helper_float_madd_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
11971 tcg_temp_free_i64(fp0
);
11972 tcg_temp_free_i64(fp1
);
11973 gen_store_fpr64(ctx
, fp2
, fd
);
11974 tcg_temp_free_i64(fp2
);
11980 TCGv_i64 fp0
= tcg_temp_new_i64();
11981 TCGv_i64 fp1
= tcg_temp_new_i64();
11982 TCGv_i64 fp2
= tcg_temp_new_i64();
11984 gen_load_fpr64(ctx
, fp0
, fs
);
11985 gen_load_fpr64(ctx
, fp1
, ft
);
11986 gen_load_fpr64(ctx
, fp2
, fr
);
11987 gen_helper_float_madd_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
11988 tcg_temp_free_i64(fp0
);
11989 tcg_temp_free_i64(fp1
);
11990 gen_store_fpr64(ctx
, fp2
, fd
);
11991 tcg_temp_free_i64(fp2
);
11997 TCGv_i32 fp0
= tcg_temp_new_i32();
11998 TCGv_i32 fp1
= tcg_temp_new_i32();
11999 TCGv_i32 fp2
= tcg_temp_new_i32();
12001 gen_load_fpr32(ctx
, fp0
, fs
);
12002 gen_load_fpr32(ctx
, fp1
, ft
);
12003 gen_load_fpr32(ctx
, fp2
, fr
);
12004 gen_helper_float_msub_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12005 tcg_temp_free_i32(fp0
);
12006 tcg_temp_free_i32(fp1
);
12007 gen_store_fpr32(ctx
, fp2
, fd
);
12008 tcg_temp_free_i32(fp2
);
12013 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
12015 TCGv_i64 fp0
= tcg_temp_new_i64();
12016 TCGv_i64 fp1
= tcg_temp_new_i64();
12017 TCGv_i64 fp2
= tcg_temp_new_i64();
12019 gen_load_fpr64(ctx
, fp0
, fs
);
12020 gen_load_fpr64(ctx
, fp1
, ft
);
12021 gen_load_fpr64(ctx
, fp2
, fr
);
12022 gen_helper_float_msub_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12023 tcg_temp_free_i64(fp0
);
12024 tcg_temp_free_i64(fp1
);
12025 gen_store_fpr64(ctx
, fp2
, fd
);
12026 tcg_temp_free_i64(fp2
);
12032 TCGv_i64 fp0
= tcg_temp_new_i64();
12033 TCGv_i64 fp1
= tcg_temp_new_i64();
12034 TCGv_i64 fp2
= tcg_temp_new_i64();
12036 gen_load_fpr64(ctx
, fp0
, fs
);
12037 gen_load_fpr64(ctx
, fp1
, ft
);
12038 gen_load_fpr64(ctx
, fp2
, fr
);
12039 gen_helper_float_msub_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12040 tcg_temp_free_i64(fp0
);
12041 tcg_temp_free_i64(fp1
);
12042 gen_store_fpr64(ctx
, fp2
, fd
);
12043 tcg_temp_free_i64(fp2
);
12049 TCGv_i32 fp0
= tcg_temp_new_i32();
12050 TCGv_i32 fp1
= tcg_temp_new_i32();
12051 TCGv_i32 fp2
= tcg_temp_new_i32();
12053 gen_load_fpr32(ctx
, fp0
, fs
);
12054 gen_load_fpr32(ctx
, fp1
, ft
);
12055 gen_load_fpr32(ctx
, fp2
, fr
);
12056 gen_helper_float_nmadd_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12057 tcg_temp_free_i32(fp0
);
12058 tcg_temp_free_i32(fp1
);
12059 gen_store_fpr32(ctx
, fp2
, fd
);
12060 tcg_temp_free_i32(fp2
);
12065 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
12067 TCGv_i64 fp0
= tcg_temp_new_i64();
12068 TCGv_i64 fp1
= tcg_temp_new_i64();
12069 TCGv_i64 fp2
= tcg_temp_new_i64();
12071 gen_load_fpr64(ctx
, fp0
, fs
);
12072 gen_load_fpr64(ctx
, fp1
, ft
);
12073 gen_load_fpr64(ctx
, fp2
, fr
);
12074 gen_helper_float_nmadd_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12075 tcg_temp_free_i64(fp0
);
12076 tcg_temp_free_i64(fp1
);
12077 gen_store_fpr64(ctx
, fp2
, fd
);
12078 tcg_temp_free_i64(fp2
);
12084 TCGv_i64 fp0
= tcg_temp_new_i64();
12085 TCGv_i64 fp1
= tcg_temp_new_i64();
12086 TCGv_i64 fp2
= tcg_temp_new_i64();
12088 gen_load_fpr64(ctx
, fp0
, fs
);
12089 gen_load_fpr64(ctx
, fp1
, ft
);
12090 gen_load_fpr64(ctx
, fp2
, fr
);
12091 gen_helper_float_nmadd_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12092 tcg_temp_free_i64(fp0
);
12093 tcg_temp_free_i64(fp1
);
12094 gen_store_fpr64(ctx
, fp2
, fd
);
12095 tcg_temp_free_i64(fp2
);
12101 TCGv_i32 fp0
= tcg_temp_new_i32();
12102 TCGv_i32 fp1
= tcg_temp_new_i32();
12103 TCGv_i32 fp2
= tcg_temp_new_i32();
12105 gen_load_fpr32(ctx
, fp0
, fs
);
12106 gen_load_fpr32(ctx
, fp1
, ft
);
12107 gen_load_fpr32(ctx
, fp2
, fr
);
12108 gen_helper_float_nmsub_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12109 tcg_temp_free_i32(fp0
);
12110 tcg_temp_free_i32(fp1
);
12111 gen_store_fpr32(ctx
, fp2
, fd
);
12112 tcg_temp_free_i32(fp2
);
12117 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
12119 TCGv_i64 fp0
= tcg_temp_new_i64();
12120 TCGv_i64 fp1
= tcg_temp_new_i64();
12121 TCGv_i64 fp2
= tcg_temp_new_i64();
12123 gen_load_fpr64(ctx
, fp0
, fs
);
12124 gen_load_fpr64(ctx
, fp1
, ft
);
12125 gen_load_fpr64(ctx
, fp2
, fr
);
12126 gen_helper_float_nmsub_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12127 tcg_temp_free_i64(fp0
);
12128 tcg_temp_free_i64(fp1
);
12129 gen_store_fpr64(ctx
, fp2
, fd
);
12130 tcg_temp_free_i64(fp2
);
12136 TCGv_i64 fp0
= tcg_temp_new_i64();
12137 TCGv_i64 fp1
= tcg_temp_new_i64();
12138 TCGv_i64 fp2
= tcg_temp_new_i64();
12140 gen_load_fpr64(ctx
, fp0
, fs
);
12141 gen_load_fpr64(ctx
, fp1
, ft
);
12142 gen_load_fpr64(ctx
, fp2
, fr
);
12143 gen_helper_float_nmsub_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12144 tcg_temp_free_i64(fp0
);
12145 tcg_temp_free_i64(fp1
);
12146 gen_store_fpr64(ctx
, fp2
, fd
);
12147 tcg_temp_free_i64(fp2
);
12151 MIPS_INVAL("flt3_arith");
12152 gen_reserved_instruction(ctx
);
12157 void gen_rdhwr(DisasContext
*ctx
, int rt
, int rd
, int sel
)
12161 #if !defined(CONFIG_USER_ONLY)
12163 * The Linux kernel will emulate rdhwr if it's not supported natively.
12164 * Therefore only check the ISA in system mode.
12166 check_insn(ctx
, ISA_MIPS_R2
);
12168 t0
= tcg_temp_new();
12172 gen_helper_rdhwr_cpunum(t0
, cpu_env
);
12173 gen_store_gpr(t0
, rt
);
12176 gen_helper_rdhwr_synci_step(t0
, cpu_env
);
12177 gen_store_gpr(t0
, rt
);
12180 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
12183 gen_helper_rdhwr_cc(t0
, cpu_env
);
12184 gen_store_gpr(t0
, rt
);
12186 * Break the TB to be able to take timer interrupts immediately
12187 * after reading count. DISAS_STOP isn't sufficient, we need to ensure
12188 * we break completely out of translated code.
12190 gen_save_pc(ctx
->base
.pc_next
+ 4);
12191 ctx
->base
.is_jmp
= DISAS_EXIT
;
12194 gen_helper_rdhwr_ccres(t0
, cpu_env
);
12195 gen_store_gpr(t0
, rt
);
12198 check_insn(ctx
, ISA_MIPS_R6
);
12201 * Performance counter registers are not implemented other than
12202 * control register 0.
12204 generate_exception(ctx
, EXCP_RI
);
12206 gen_helper_rdhwr_performance(t0
, cpu_env
);
12207 gen_store_gpr(t0
, rt
);
12210 check_insn(ctx
, ISA_MIPS_R6
);
12211 gen_helper_rdhwr_xnp(t0
, cpu_env
);
12212 gen_store_gpr(t0
, rt
);
12215 #if defined(CONFIG_USER_ONLY)
12216 tcg_gen_ld_tl(t0
, cpu_env
,
12217 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
12218 gen_store_gpr(t0
, rt
);
12221 if ((ctx
->hflags
& MIPS_HFLAG_CP0
) ||
12222 (ctx
->hflags
& MIPS_HFLAG_HWRENA_ULR
)) {
12223 tcg_gen_ld_tl(t0
, cpu_env
,
12224 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
12225 gen_store_gpr(t0
, rt
);
12227 gen_reserved_instruction(ctx
);
12231 default: /* Invalid */
12232 MIPS_INVAL("rdhwr");
12233 gen_reserved_instruction(ctx
);
12239 static inline void clear_branch_hflags(DisasContext
*ctx
)
12241 ctx
->hflags
&= ~MIPS_HFLAG_BMASK
;
12242 if (ctx
->base
.is_jmp
== DISAS_NEXT
) {
12243 save_cpu_state(ctx
, 0);
12246 * It is not safe to save ctx->hflags as hflags may be changed
12247 * in execution time by the instruction in delay / forbidden slot.
12249 tcg_gen_andi_i32(hflags
, hflags
, ~MIPS_HFLAG_BMASK
);
12253 static void gen_branch(DisasContext
*ctx
, int insn_bytes
)
12255 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
12256 int proc_hflags
= ctx
->hflags
& MIPS_HFLAG_BMASK
;
12257 /* Branches completion */
12258 clear_branch_hflags(ctx
);
12259 ctx
->base
.is_jmp
= DISAS_NORETURN
;
12260 /* FIXME: Need to clear can_do_io. */
12261 switch (proc_hflags
& MIPS_HFLAG_BMASK_BASE
) {
12262 case MIPS_HFLAG_FBNSLOT
:
12263 gen_goto_tb(ctx
, 0, ctx
->base
.pc_next
+ insn_bytes
);
12266 /* unconditional branch */
12267 if (proc_hflags
& MIPS_HFLAG_BX
) {
12268 tcg_gen_xori_i32(hflags
, hflags
, MIPS_HFLAG_M16
);
12270 gen_goto_tb(ctx
, 0, ctx
->btarget
);
12272 case MIPS_HFLAG_BL
:
12273 /* blikely taken case */
12274 gen_goto_tb(ctx
, 0, ctx
->btarget
);
12276 case MIPS_HFLAG_BC
:
12277 /* Conditional branch */
12279 TCGLabel
*l1
= gen_new_label();
12281 tcg_gen_brcondi_tl(TCG_COND_NE
, bcond
, 0, l1
);
12282 gen_goto_tb(ctx
, 1, ctx
->base
.pc_next
+ insn_bytes
);
12284 gen_goto_tb(ctx
, 0, ctx
->btarget
);
12287 case MIPS_HFLAG_BR
:
12288 /* unconditional branch to register */
12289 if (ctx
->insn_flags
& (ASE_MIPS16
| ASE_MICROMIPS
)) {
12290 TCGv t0
= tcg_temp_new();
12291 TCGv_i32 t1
= tcg_temp_new_i32();
12293 tcg_gen_andi_tl(t0
, btarget
, 0x1);
12294 tcg_gen_trunc_tl_i32(t1
, t0
);
12296 tcg_gen_andi_i32(hflags
, hflags
, ~(uint32_t)MIPS_HFLAG_M16
);
12297 tcg_gen_shli_i32(t1
, t1
, MIPS_HFLAG_M16_SHIFT
);
12298 tcg_gen_or_i32(hflags
, hflags
, t1
);
12299 tcg_temp_free_i32(t1
);
12301 tcg_gen_andi_tl(cpu_PC
, btarget
, ~(target_ulong
)0x1);
12303 tcg_gen_mov_tl(cpu_PC
, btarget
);
12305 if (ctx
->base
.singlestep_enabled
) {
12306 save_cpu_state(ctx
, 0);
12307 gen_helper_raise_exception_debug(cpu_env
);
12309 tcg_gen_lookup_and_goto_ptr();
12312 fprintf(stderr
, "unknown branch 0x%x\n", proc_hflags
);
12318 /* Compact Branches */
12319 static void gen_compute_compact_branch(DisasContext
*ctx
, uint32_t opc
,
12320 int rs
, int rt
, int32_t offset
)
12322 int bcond_compute
= 0;
12323 TCGv t0
= tcg_temp_new();
12324 TCGv t1
= tcg_temp_new();
12325 int m16_lowbit
= (ctx
->hflags
& MIPS_HFLAG_M16
) != 0;
12327 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
12328 #ifdef MIPS_DEBUG_DISAS
12329 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
12330 "\n", ctx
->base
.pc_next
);
12332 gen_reserved_instruction(ctx
);
12336 /* Load needed operands and calculate btarget */
12338 /* compact branch */
12339 case OPC_BOVC
: /* OPC_BEQZALC, OPC_BEQC */
12340 case OPC_BNVC
: /* OPC_BNEZALC, OPC_BNEC */
12341 gen_load_gpr(t0
, rs
);
12342 gen_load_gpr(t1
, rt
);
12344 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
12345 if (rs
<= rt
&& rs
== 0) {
12346 /* OPC_BEQZALC, OPC_BNEZALC */
12347 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 4 + m16_lowbit
);
12350 case OPC_BLEZC
: /* OPC_BGEZC, OPC_BGEC */
12351 case OPC_BGTZC
: /* OPC_BLTZC, OPC_BLTC */
12352 gen_load_gpr(t0
, rs
);
12353 gen_load_gpr(t1
, rt
);
12355 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
12357 case OPC_BLEZALC
: /* OPC_BGEZALC, OPC_BGEUC */
12358 case OPC_BGTZALC
: /* OPC_BLTZALC, OPC_BLTUC */
12359 if (rs
== 0 || rs
== rt
) {
12360 /* OPC_BLEZALC, OPC_BGEZALC */
12361 /* OPC_BGTZALC, OPC_BLTZALC */
12362 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 4 + m16_lowbit
);
12364 gen_load_gpr(t0
, rs
);
12365 gen_load_gpr(t1
, rt
);
12367 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
12371 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
12376 /* OPC_BEQZC, OPC_BNEZC */
12377 gen_load_gpr(t0
, rs
);
12379 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
12381 /* OPC_JIC, OPC_JIALC */
12382 TCGv tbase
= tcg_temp_new();
12383 TCGv toffset
= tcg_temp_new();
12385 gen_load_gpr(tbase
, rt
);
12386 tcg_gen_movi_tl(toffset
, offset
);
12387 gen_op_addr_add(ctx
, btarget
, tbase
, toffset
);
12388 tcg_temp_free(tbase
);
12389 tcg_temp_free(toffset
);
12393 MIPS_INVAL("Compact branch/jump");
12394 gen_reserved_instruction(ctx
);
12398 if (bcond_compute
== 0) {
12399 /* Uncoditional compact branch */
12402 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 4 + m16_lowbit
);
12405 ctx
->hflags
|= MIPS_HFLAG_BR
;
12408 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 4 + m16_lowbit
);
12411 ctx
->hflags
|= MIPS_HFLAG_B
;
12414 MIPS_INVAL("Compact branch/jump");
12415 gen_reserved_instruction(ctx
);
12419 /* Generating branch here as compact branches don't have delay slot */
12420 gen_branch(ctx
, 4);
12422 /* Conditional compact branch */
12423 TCGLabel
*fs
= gen_new_label();
12424 save_cpu_state(ctx
, 0);
12427 case OPC_BLEZALC
: /* OPC_BGEZALC, OPC_BGEUC */
12428 if (rs
== 0 && rt
!= 0) {
12430 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE
), t1
, 0, fs
);
12431 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
12433 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE
), t1
, 0, fs
);
12436 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU
), t0
, t1
, fs
);
12439 case OPC_BGTZALC
: /* OPC_BLTZALC, OPC_BLTUC */
12440 if (rs
== 0 && rt
!= 0) {
12442 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT
), t1
, 0, fs
);
12443 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
12445 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT
), t1
, 0, fs
);
12448 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU
), t0
, t1
, fs
);
12451 case OPC_BLEZC
: /* OPC_BGEZC, OPC_BGEC */
12452 if (rs
== 0 && rt
!= 0) {
12454 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE
), t1
, 0, fs
);
12455 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
12457 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE
), t1
, 0, fs
);
12460 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE
), t0
, t1
, fs
);
12463 case OPC_BGTZC
: /* OPC_BLTZC, OPC_BLTC */
12464 if (rs
== 0 && rt
!= 0) {
12466 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT
), t1
, 0, fs
);
12467 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
12469 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT
), t1
, 0, fs
);
12472 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT
), t0
, t1
, fs
);
12475 case OPC_BOVC
: /* OPC_BEQZALC, OPC_BEQC */
12476 case OPC_BNVC
: /* OPC_BNEZALC, OPC_BNEC */
12478 /* OPC_BOVC, OPC_BNVC */
12479 TCGv t2
= tcg_temp_new();
12480 TCGv t3
= tcg_temp_new();
12481 TCGv t4
= tcg_temp_new();
12482 TCGv input_overflow
= tcg_temp_new();
12484 gen_load_gpr(t0
, rs
);
12485 gen_load_gpr(t1
, rt
);
12486 tcg_gen_ext32s_tl(t2
, t0
);
12487 tcg_gen_setcond_tl(TCG_COND_NE
, input_overflow
, t2
, t0
);
12488 tcg_gen_ext32s_tl(t3
, t1
);
12489 tcg_gen_setcond_tl(TCG_COND_NE
, t4
, t3
, t1
);
12490 tcg_gen_or_tl(input_overflow
, input_overflow
, t4
);
12492 tcg_gen_add_tl(t4
, t2
, t3
);
12493 tcg_gen_ext32s_tl(t4
, t4
);
12494 tcg_gen_xor_tl(t2
, t2
, t3
);
12495 tcg_gen_xor_tl(t3
, t4
, t3
);
12496 tcg_gen_andc_tl(t2
, t3
, t2
);
12497 tcg_gen_setcondi_tl(TCG_COND_LT
, t4
, t2
, 0);
12498 tcg_gen_or_tl(t4
, t4
, input_overflow
);
12499 if (opc
== OPC_BOVC
) {
12501 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE
), t4
, 0, fs
);
12504 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ
), t4
, 0, fs
);
12506 tcg_temp_free(input_overflow
);
12510 } else if (rs
< rt
&& rs
== 0) {
12511 /* OPC_BEQZALC, OPC_BNEZALC */
12512 if (opc
== OPC_BEQZALC
) {
12514 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ
), t1
, 0, fs
);
12517 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE
), t1
, 0, fs
);
12520 /* OPC_BEQC, OPC_BNEC */
12521 if (opc
== OPC_BEQC
) {
12523 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ
), t0
, t1
, fs
);
12526 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE
), t0
, t1
, fs
);
12531 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ
), t0
, 0, fs
);
12534 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE
), t0
, 0, fs
);
12537 MIPS_INVAL("Compact conditional branch/jump");
12538 gen_reserved_instruction(ctx
);
12542 /* Generating branch here as compact branches don't have delay slot */
12543 gen_goto_tb(ctx
, 1, ctx
->btarget
);
12546 ctx
->hflags
|= MIPS_HFLAG_FBNSLOT
;
12554 /* ISA extensions (ASEs) */
12555 /* MIPS16 extension to MIPS32 */
12557 /* MIPS16 major opcodes */
12559 M16_OPC_ADDIUSP
= 0x00,
12560 M16_OPC_ADDIUPC
= 0x01,
12562 M16_OPC_JAL
= 0x03,
12563 M16_OPC_BEQZ
= 0x04,
12564 M16_OPC_BNEQZ
= 0x05,
12565 M16_OPC_SHIFT
= 0x06,
12567 M16_OPC_RRIA
= 0x08,
12568 M16_OPC_ADDIU8
= 0x09,
12569 M16_OPC_SLTI
= 0x0a,
12570 M16_OPC_SLTIU
= 0x0b,
12573 M16_OPC_CMPI
= 0x0e,
12577 M16_OPC_LWSP
= 0x12,
12579 M16_OPC_LBU
= 0x14,
12580 M16_OPC_LHU
= 0x15,
12581 M16_OPC_LWPC
= 0x16,
12582 M16_OPC_LWU
= 0x17,
12585 M16_OPC_SWSP
= 0x1a,
12587 M16_OPC_RRR
= 0x1c,
12589 M16_OPC_EXTEND
= 0x1e,
12593 /* I8 funct field */
12612 /* RR funct field */
12646 /* I64 funct field */
12654 I64_DADDIUPC
= 0x6,
12658 /* RR ry field for CNVT */
12660 RR_RY_CNVT_ZEB
= 0x0,
12661 RR_RY_CNVT_ZEH
= 0x1,
12662 RR_RY_CNVT_ZEW
= 0x2,
12663 RR_RY_CNVT_SEB
= 0x4,
12664 RR_RY_CNVT_SEH
= 0x5,
12665 RR_RY_CNVT_SEW
= 0x6,
12668 static int xlat(int r
)
12670 static int map
[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
12675 static void gen_mips16_save(DisasContext
*ctx
,
12676 int xsregs
, int aregs
,
12677 int do_ra
, int do_s0
, int do_s1
,
12680 TCGv t0
= tcg_temp_new();
12681 TCGv t1
= tcg_temp_new();
12682 TCGv t2
= tcg_temp_new();
12712 gen_reserved_instruction(ctx
);
12718 gen_base_offset_addr(ctx
, t0
, 29, 12);
12719 gen_load_gpr(t1
, 7);
12720 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
12723 gen_base_offset_addr(ctx
, t0
, 29, 8);
12724 gen_load_gpr(t1
, 6);
12725 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
12728 gen_base_offset_addr(ctx
, t0
, 29, 4);
12729 gen_load_gpr(t1
, 5);
12730 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
12733 gen_base_offset_addr(ctx
, t0
, 29, 0);
12734 gen_load_gpr(t1
, 4);
12735 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
12738 gen_load_gpr(t0
, 29);
12740 #define DECR_AND_STORE(reg) do { \
12741 tcg_gen_movi_tl(t2, -4); \
12742 gen_op_addr_add(ctx, t0, t0, t2); \
12743 gen_load_gpr(t1, reg); \
12744 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \
12748 DECR_AND_STORE(31);
12753 DECR_AND_STORE(30);
12756 DECR_AND_STORE(23);
12759 DECR_AND_STORE(22);
12762 DECR_AND_STORE(21);
12765 DECR_AND_STORE(20);
12768 DECR_AND_STORE(19);
12771 DECR_AND_STORE(18);
12775 DECR_AND_STORE(17);
12778 DECR_AND_STORE(16);
12808 gen_reserved_instruction(ctx
);
12824 #undef DECR_AND_STORE
12826 tcg_gen_movi_tl(t2
, -framesize
);
12827 gen_op_addr_add(ctx
, cpu_gpr
[29], cpu_gpr
[29], t2
);
12833 static void gen_mips16_restore(DisasContext
*ctx
,
12834 int xsregs
, int aregs
,
12835 int do_ra
, int do_s0
, int do_s1
,
12839 TCGv t0
= tcg_temp_new();
12840 TCGv t1
= tcg_temp_new();
12841 TCGv t2
= tcg_temp_new();
12843 tcg_gen_movi_tl(t2
, framesize
);
12844 gen_op_addr_add(ctx
, t0
, cpu_gpr
[29], t2
);
12846 #define DECR_AND_LOAD(reg) do { \
12847 tcg_gen_movi_tl(t2, -4); \
12848 gen_op_addr_add(ctx, t0, t0, t2); \
12849 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \
12850 gen_store_gpr(t1, reg); \
12914 gen_reserved_instruction(ctx
);
12930 #undef DECR_AND_LOAD
12932 tcg_gen_movi_tl(t2
, framesize
);
12933 gen_op_addr_add(ctx
, cpu_gpr
[29], cpu_gpr
[29], t2
);
12939 static void gen_addiupc(DisasContext
*ctx
, int rx
, int imm
,
12940 int is_64_bit
, int extended
)
12944 if (extended
&& (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
12945 gen_reserved_instruction(ctx
);
12949 t0
= tcg_temp_new();
12951 tcg_gen_movi_tl(t0
, pc_relative_pc(ctx
));
12952 tcg_gen_addi_tl(cpu_gpr
[rx
], t0
, imm
);
12954 tcg_gen_ext32s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
12960 static void gen_cache_operation(DisasContext
*ctx
, uint32_t op
, int base
,
12963 TCGv_i32 t0
= tcg_const_i32(op
);
12964 TCGv t1
= tcg_temp_new();
12965 gen_base_offset_addr(ctx
, t1
, base
, offset
);
12966 gen_helper_cache(cpu_env
, t1
, t0
);
12969 #if defined(TARGET_MIPS64)
12970 static void decode_i64_mips16(DisasContext
*ctx
,
12971 int ry
, int funct
, int16_t offset
,
12976 check_insn(ctx
, ISA_MIPS3
);
12977 check_mips_64(ctx
);
12978 offset
= extended
? offset
: offset
<< 3;
12979 gen_ld(ctx
, OPC_LD
, ry
, 29, offset
);
12982 check_insn(ctx
, ISA_MIPS3
);
12983 check_mips_64(ctx
);
12984 offset
= extended
? offset
: offset
<< 3;
12985 gen_st(ctx
, OPC_SD
, ry
, 29, offset
);
12988 check_insn(ctx
, ISA_MIPS3
);
12989 check_mips_64(ctx
);
12990 offset
= extended
? offset
: (ctx
->opcode
& 0xff) << 3;
12991 gen_st(ctx
, OPC_SD
, 31, 29, offset
);
12994 check_insn(ctx
, ISA_MIPS3
);
12995 check_mips_64(ctx
);
12996 offset
= extended
? offset
: ((int8_t)ctx
->opcode
) << 3;
12997 gen_arith_imm(ctx
, OPC_DADDIU
, 29, 29, offset
);
13000 check_insn(ctx
, ISA_MIPS3
);
13001 check_mips_64(ctx
);
13002 if (extended
&& (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
13003 gen_reserved_instruction(ctx
);
13005 offset
= extended
? offset
: offset
<< 3;
13006 gen_ld(ctx
, OPC_LDPC
, ry
, 0, offset
);
13010 check_insn(ctx
, ISA_MIPS3
);
13011 check_mips_64(ctx
);
13012 offset
= extended
? offset
: ((int8_t)(offset
<< 3)) >> 3;
13013 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, ry
, offset
);
13016 check_insn(ctx
, ISA_MIPS3
);
13017 check_mips_64(ctx
);
13018 offset
= extended
? offset
: offset
<< 2;
13019 gen_addiupc(ctx
, ry
, offset
, 1, extended
);
13022 check_insn(ctx
, ISA_MIPS3
);
13023 check_mips_64(ctx
);
13024 offset
= extended
? offset
: offset
<< 2;
13025 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, 29, offset
);
13031 static int decode_extended_mips16_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
13033 int extend
= translator_lduw(env
, ctx
->base
.pc_next
+ 2);
13034 int op
, rx
, ry
, funct
, sa
;
13035 int16_t imm
, offset
;
13037 ctx
->opcode
= (ctx
->opcode
<< 16) | extend
;
13038 op
= (ctx
->opcode
>> 11) & 0x1f;
13039 sa
= (ctx
->opcode
>> 22) & 0x1f;
13040 funct
= (ctx
->opcode
>> 8) & 0x7;
13041 rx
= xlat((ctx
->opcode
>> 8) & 0x7);
13042 ry
= xlat((ctx
->opcode
>> 5) & 0x7);
13043 offset
= imm
= (int16_t) (((ctx
->opcode
>> 16) & 0x1f) << 11
13044 | ((ctx
->opcode
>> 21) & 0x3f) << 5
13045 | (ctx
->opcode
& 0x1f));
13048 * The extended opcodes cleverly reuse the opcodes from their 16-bit
13052 case M16_OPC_ADDIUSP
:
13053 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 29, imm
);
13055 case M16_OPC_ADDIUPC
:
13056 gen_addiupc(ctx
, rx
, imm
, 0, 1);
13059 gen_compute_branch(ctx
, OPC_BEQ
, 4, 0, 0, offset
<< 1, 0);
13060 /* No delay slot, so just process as a normal instruction */
13063 gen_compute_branch(ctx
, OPC_BEQ
, 4, rx
, 0, offset
<< 1, 0);
13064 /* No delay slot, so just process as a normal instruction */
13066 case M16_OPC_BNEQZ
:
13067 gen_compute_branch(ctx
, OPC_BNE
, 4, rx
, 0, offset
<< 1, 0);
13068 /* No delay slot, so just process as a normal instruction */
13070 case M16_OPC_SHIFT
:
13071 switch (ctx
->opcode
& 0x3) {
13073 gen_shift_imm(ctx
, OPC_SLL
, rx
, ry
, sa
);
13076 #if defined(TARGET_MIPS64)
13077 check_mips_64(ctx
);
13078 gen_shift_imm(ctx
, OPC_DSLL
, rx
, ry
, sa
);
13080 gen_reserved_instruction(ctx
);
13084 gen_shift_imm(ctx
, OPC_SRL
, rx
, ry
, sa
);
13087 gen_shift_imm(ctx
, OPC_SRA
, rx
, ry
, sa
);
13091 #if defined(TARGET_MIPS64)
13093 check_insn(ctx
, ISA_MIPS3
);
13094 check_mips_64(ctx
);
13095 gen_ld(ctx
, OPC_LD
, ry
, rx
, offset
);
13099 imm
= ctx
->opcode
& 0xf;
13100 imm
= imm
| ((ctx
->opcode
>> 20) & 0x7f) << 4;
13101 imm
= imm
| ((ctx
->opcode
>> 16) & 0xf) << 11;
13102 imm
= (int16_t) (imm
<< 1) >> 1;
13103 if ((ctx
->opcode
>> 4) & 0x1) {
13104 #if defined(TARGET_MIPS64)
13105 check_mips_64(ctx
);
13106 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, rx
, imm
);
13108 gen_reserved_instruction(ctx
);
13111 gen_arith_imm(ctx
, OPC_ADDIU
, ry
, rx
, imm
);
13114 case M16_OPC_ADDIU8
:
13115 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, rx
, imm
);
13118 gen_slt_imm(ctx
, OPC_SLTI
, 24, rx
, imm
);
13120 case M16_OPC_SLTIU
:
13121 gen_slt_imm(ctx
, OPC_SLTIU
, 24, rx
, imm
);
13126 gen_compute_branch(ctx
, OPC_BEQ
, 4, 24, 0, offset
<< 1, 0);
13129 gen_compute_branch(ctx
, OPC_BNE
, 4, 24, 0, offset
<< 1, 0);
13132 gen_st(ctx
, OPC_SW
, 31, 29, imm
);
13135 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, imm
);
13138 check_insn(ctx
, ISA_MIPS_R1
);
13140 int xsregs
= (ctx
->opcode
>> 24) & 0x7;
13141 int aregs
= (ctx
->opcode
>> 16) & 0xf;
13142 int do_ra
= (ctx
->opcode
>> 6) & 0x1;
13143 int do_s0
= (ctx
->opcode
>> 5) & 0x1;
13144 int do_s1
= (ctx
->opcode
>> 4) & 0x1;
13145 int framesize
= (((ctx
->opcode
>> 20) & 0xf) << 4
13146 | (ctx
->opcode
& 0xf)) << 3;
13148 if (ctx
->opcode
& (1 << 7)) {
13149 gen_mips16_save(ctx
, xsregs
, aregs
,
13150 do_ra
, do_s0
, do_s1
,
13153 gen_mips16_restore(ctx
, xsregs
, aregs
,
13154 do_ra
, do_s0
, do_s1
,
13160 gen_reserved_instruction(ctx
);
13165 tcg_gen_movi_tl(cpu_gpr
[rx
], (uint16_t) imm
);
13168 tcg_gen_xori_tl(cpu_gpr
[24], cpu_gpr
[rx
], (uint16_t) imm
);
13170 #if defined(TARGET_MIPS64)
13172 check_insn(ctx
, ISA_MIPS3
);
13173 check_mips_64(ctx
);
13174 gen_st(ctx
, OPC_SD
, ry
, rx
, offset
);
13178 gen_ld(ctx
, OPC_LB
, ry
, rx
, offset
);
13181 gen_ld(ctx
, OPC_LH
, ry
, rx
, offset
);
13184 gen_ld(ctx
, OPC_LW
, rx
, 29, offset
);
13187 gen_ld(ctx
, OPC_LW
, ry
, rx
, offset
);
13190 gen_ld(ctx
, OPC_LBU
, ry
, rx
, offset
);
13193 gen_ld(ctx
, OPC_LHU
, ry
, rx
, offset
);
13196 gen_ld(ctx
, OPC_LWPC
, rx
, 0, offset
);
13198 #if defined(TARGET_MIPS64)
13200 check_insn(ctx
, ISA_MIPS3
);
13201 check_mips_64(ctx
);
13202 gen_ld(ctx
, OPC_LWU
, ry
, rx
, offset
);
13206 gen_st(ctx
, OPC_SB
, ry
, rx
, offset
);
13209 gen_st(ctx
, OPC_SH
, ry
, rx
, offset
);
13212 gen_st(ctx
, OPC_SW
, rx
, 29, offset
);
13215 gen_st(ctx
, OPC_SW
, ry
, rx
, offset
);
13217 #if defined(TARGET_MIPS64)
13219 decode_i64_mips16(ctx
, ry
, funct
, offset
, 1);
13223 gen_reserved_instruction(ctx
);
13230 static inline bool is_uhi(int sdbbp_code
)
13232 #ifdef CONFIG_USER_ONLY
13235 return semihosting_enabled() && sdbbp_code
== 1;
13239 #ifdef CONFIG_USER_ONLY
13240 /* The above should dead-code away any calls to this..*/
13241 static inline void gen_helper_do_semihosting(void *env
)
13243 g_assert_not_reached();
13247 static int decode_mips16_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
13251 int op
, cnvt_op
, op1
, offset
;
13255 op
= (ctx
->opcode
>> 11) & 0x1f;
13256 sa
= (ctx
->opcode
>> 2) & 0x7;
13257 sa
= sa
== 0 ? 8 : sa
;
13258 rx
= xlat((ctx
->opcode
>> 8) & 0x7);
13259 cnvt_op
= (ctx
->opcode
>> 5) & 0x7;
13260 ry
= xlat((ctx
->opcode
>> 5) & 0x7);
13261 op1
= offset
= ctx
->opcode
& 0x1f;
13266 case M16_OPC_ADDIUSP
:
13268 int16_t imm
= ((uint8_t) ctx
->opcode
) << 2;
13270 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 29, imm
);
13273 case M16_OPC_ADDIUPC
:
13274 gen_addiupc(ctx
, rx
, ((uint8_t) ctx
->opcode
) << 2, 0, 0);
13277 offset
= (ctx
->opcode
& 0x7ff) << 1;
13278 offset
= (int16_t)(offset
<< 4) >> 4;
13279 gen_compute_branch(ctx
, OPC_BEQ
, 2, 0, 0, offset
, 0);
13280 /* No delay slot, so just process as a normal instruction */
13283 offset
= translator_lduw(env
, ctx
->base
.pc_next
+ 2);
13284 offset
= (((ctx
->opcode
& 0x1f) << 21)
13285 | ((ctx
->opcode
>> 5) & 0x1f) << 16
13287 op
= ((ctx
->opcode
>> 10) & 0x1) ? OPC_JALX
: OPC_JAL
;
13288 gen_compute_branch(ctx
, op
, 4, rx
, ry
, offset
, 2);
13292 gen_compute_branch(ctx
, OPC_BEQ
, 2, rx
, 0,
13293 ((int8_t)ctx
->opcode
) << 1, 0);
13294 /* No delay slot, so just process as a normal instruction */
13296 case M16_OPC_BNEQZ
:
13297 gen_compute_branch(ctx
, OPC_BNE
, 2, rx
, 0,
13298 ((int8_t)ctx
->opcode
) << 1, 0);
13299 /* No delay slot, so just process as a normal instruction */
13301 case M16_OPC_SHIFT
:
13302 switch (ctx
->opcode
& 0x3) {
13304 gen_shift_imm(ctx
, OPC_SLL
, rx
, ry
, sa
);
13307 #if defined(TARGET_MIPS64)
13308 check_insn(ctx
, ISA_MIPS3
);
13309 check_mips_64(ctx
);
13310 gen_shift_imm(ctx
, OPC_DSLL
, rx
, ry
, sa
);
13312 gen_reserved_instruction(ctx
);
13316 gen_shift_imm(ctx
, OPC_SRL
, rx
, ry
, sa
);
13319 gen_shift_imm(ctx
, OPC_SRA
, rx
, ry
, sa
);
13323 #if defined(TARGET_MIPS64)
13325 check_insn(ctx
, ISA_MIPS3
);
13326 check_mips_64(ctx
);
13327 gen_ld(ctx
, OPC_LD
, ry
, rx
, offset
<< 3);
13332 int16_t imm
= (int8_t)((ctx
->opcode
& 0xf) << 4) >> 4;
13334 if ((ctx
->opcode
>> 4) & 1) {
13335 #if defined(TARGET_MIPS64)
13336 check_insn(ctx
, ISA_MIPS3
);
13337 check_mips_64(ctx
);
13338 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, rx
, imm
);
13340 gen_reserved_instruction(ctx
);
13343 gen_arith_imm(ctx
, OPC_ADDIU
, ry
, rx
, imm
);
13347 case M16_OPC_ADDIU8
:
13349 int16_t imm
= (int8_t) ctx
->opcode
;
13351 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, rx
, imm
);
13356 int16_t imm
= (uint8_t) ctx
->opcode
;
13357 gen_slt_imm(ctx
, OPC_SLTI
, 24, rx
, imm
);
13360 case M16_OPC_SLTIU
:
13362 int16_t imm
= (uint8_t) ctx
->opcode
;
13363 gen_slt_imm(ctx
, OPC_SLTIU
, 24, rx
, imm
);
13370 funct
= (ctx
->opcode
>> 8) & 0x7;
13373 gen_compute_branch(ctx
, OPC_BEQ
, 2, 24, 0,
13374 ((int8_t)ctx
->opcode
) << 1, 0);
13377 gen_compute_branch(ctx
, OPC_BNE
, 2, 24, 0,
13378 ((int8_t)ctx
->opcode
) << 1, 0);
13381 gen_st(ctx
, OPC_SW
, 31, 29, (ctx
->opcode
& 0xff) << 2);
13384 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29,
13385 ((int8_t)ctx
->opcode
) << 3);
13388 check_insn(ctx
, ISA_MIPS_R1
);
13390 int do_ra
= ctx
->opcode
& (1 << 6);
13391 int do_s0
= ctx
->opcode
& (1 << 5);
13392 int do_s1
= ctx
->opcode
& (1 << 4);
13393 int framesize
= ctx
->opcode
& 0xf;
13395 if (framesize
== 0) {
13398 framesize
= framesize
<< 3;
13401 if (ctx
->opcode
& (1 << 7)) {
13402 gen_mips16_save(ctx
, 0, 0,
13403 do_ra
, do_s0
, do_s1
, framesize
);
13405 gen_mips16_restore(ctx
, 0, 0,
13406 do_ra
, do_s0
, do_s1
, framesize
);
13412 int rz
= xlat(ctx
->opcode
& 0x7);
13414 reg32
= (((ctx
->opcode
>> 3) & 0x3) << 3) |
13415 ((ctx
->opcode
>> 5) & 0x7);
13416 gen_arith(ctx
, OPC_ADDU
, reg32
, rz
, 0);
13420 reg32
= ctx
->opcode
& 0x1f;
13421 gen_arith(ctx
, OPC_ADDU
, ry
, reg32
, 0);
13424 gen_reserved_instruction(ctx
);
13431 int16_t imm
= (uint8_t) ctx
->opcode
;
13433 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 0, imm
);
13438 int16_t imm
= (uint8_t) ctx
->opcode
;
13439 gen_logic_imm(ctx
, OPC_XORI
, 24, rx
, imm
);
13442 #if defined(TARGET_MIPS64)
13444 check_insn(ctx
, ISA_MIPS3
);
13445 check_mips_64(ctx
);
13446 gen_st(ctx
, OPC_SD
, ry
, rx
, offset
<< 3);
13450 gen_ld(ctx
, OPC_LB
, ry
, rx
, offset
);
13453 gen_ld(ctx
, OPC_LH
, ry
, rx
, offset
<< 1);
13456 gen_ld(ctx
, OPC_LW
, rx
, 29, ((uint8_t)ctx
->opcode
) << 2);
13459 gen_ld(ctx
, OPC_LW
, ry
, rx
, offset
<< 2);
13462 gen_ld(ctx
, OPC_LBU
, ry
, rx
, offset
);
13465 gen_ld(ctx
, OPC_LHU
, ry
, rx
, offset
<< 1);
13468 gen_ld(ctx
, OPC_LWPC
, rx
, 0, ((uint8_t)ctx
->opcode
) << 2);
13470 #if defined(TARGET_MIPS64)
13472 check_insn(ctx
, ISA_MIPS3
);
13473 check_mips_64(ctx
);
13474 gen_ld(ctx
, OPC_LWU
, ry
, rx
, offset
<< 2);
13478 gen_st(ctx
, OPC_SB
, ry
, rx
, offset
);
13481 gen_st(ctx
, OPC_SH
, ry
, rx
, offset
<< 1);
13484 gen_st(ctx
, OPC_SW
, rx
, 29, ((uint8_t)ctx
->opcode
) << 2);
13487 gen_st(ctx
, OPC_SW
, ry
, rx
, offset
<< 2);
13491 int rz
= xlat((ctx
->opcode
>> 2) & 0x7);
13494 switch (ctx
->opcode
& 0x3) {
13496 mips32_op
= OPC_ADDU
;
13499 mips32_op
= OPC_SUBU
;
13501 #if defined(TARGET_MIPS64)
13503 mips32_op
= OPC_DADDU
;
13504 check_insn(ctx
, ISA_MIPS3
);
13505 check_mips_64(ctx
);
13508 mips32_op
= OPC_DSUBU
;
13509 check_insn(ctx
, ISA_MIPS3
);
13510 check_mips_64(ctx
);
13514 gen_reserved_instruction(ctx
);
13518 gen_arith(ctx
, mips32_op
, rz
, rx
, ry
);
13527 int nd
= (ctx
->opcode
>> 7) & 0x1;
13528 int link
= (ctx
->opcode
>> 6) & 0x1;
13529 int ra
= (ctx
->opcode
>> 5) & 0x1;
13532 check_insn(ctx
, ISA_MIPS_R1
);
13541 gen_compute_branch(ctx
, op
, 2, ra
? 31 : rx
, 31, 0,
13546 if (is_uhi(extract32(ctx
->opcode
, 5, 6))) {
13547 gen_helper_do_semihosting(cpu_env
);
13550 * XXX: not clear which exception should be raised
13551 * when in debug mode...
13553 check_insn(ctx
, ISA_MIPS_R1
);
13554 generate_exception_end(ctx
, EXCP_DBp
);
13558 gen_slt(ctx
, OPC_SLT
, 24, rx
, ry
);
13561 gen_slt(ctx
, OPC_SLTU
, 24, rx
, ry
);
13564 generate_exception_end(ctx
, EXCP_BREAK
);
13567 gen_shift(ctx
, OPC_SLLV
, ry
, rx
, ry
);
13570 gen_shift(ctx
, OPC_SRLV
, ry
, rx
, ry
);
13573 gen_shift(ctx
, OPC_SRAV
, ry
, rx
, ry
);
13575 #if defined(TARGET_MIPS64)
13577 check_insn(ctx
, ISA_MIPS3
);
13578 check_mips_64(ctx
);
13579 gen_shift_imm(ctx
, OPC_DSRL
, ry
, ry
, sa
);
13583 gen_logic(ctx
, OPC_XOR
, 24, rx
, ry
);
13586 gen_arith(ctx
, OPC_SUBU
, rx
, 0, ry
);
13589 gen_logic(ctx
, OPC_AND
, rx
, rx
, ry
);
13592 gen_logic(ctx
, OPC_OR
, rx
, rx
, ry
);
13595 gen_logic(ctx
, OPC_XOR
, rx
, rx
, ry
);
13598 gen_logic(ctx
, OPC_NOR
, rx
, ry
, 0);
13601 gen_HILO(ctx
, OPC_MFHI
, 0, rx
);
13604 check_insn(ctx
, ISA_MIPS_R1
);
13606 case RR_RY_CNVT_ZEB
:
13607 tcg_gen_ext8u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
13609 case RR_RY_CNVT_ZEH
:
13610 tcg_gen_ext16u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
13612 case RR_RY_CNVT_SEB
:
13613 tcg_gen_ext8s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
13615 case RR_RY_CNVT_SEH
:
13616 tcg_gen_ext16s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
13618 #if defined(TARGET_MIPS64)
13619 case RR_RY_CNVT_ZEW
:
13620 check_insn(ctx
, ISA_MIPS_R1
);
13621 check_mips_64(ctx
);
13622 tcg_gen_ext32u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
13624 case RR_RY_CNVT_SEW
:
13625 check_insn(ctx
, ISA_MIPS_R1
);
13626 check_mips_64(ctx
);
13627 tcg_gen_ext32s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
13631 gen_reserved_instruction(ctx
);
13636 gen_HILO(ctx
, OPC_MFLO
, 0, rx
);
13638 #if defined(TARGET_MIPS64)
13640 check_insn(ctx
, ISA_MIPS3
);
13641 check_mips_64(ctx
);
13642 gen_shift_imm(ctx
, OPC_DSRA
, ry
, ry
, sa
);
13645 check_insn(ctx
, ISA_MIPS3
);
13646 check_mips_64(ctx
);
13647 gen_shift(ctx
, OPC_DSLLV
, ry
, rx
, ry
);
13650 check_insn(ctx
, ISA_MIPS3
);
13651 check_mips_64(ctx
);
13652 gen_shift(ctx
, OPC_DSRLV
, ry
, rx
, ry
);
13655 check_insn(ctx
, ISA_MIPS3
);
13656 check_mips_64(ctx
);
13657 gen_shift(ctx
, OPC_DSRAV
, ry
, rx
, ry
);
13661 gen_muldiv(ctx
, OPC_MULT
, 0, rx
, ry
);
13664 gen_muldiv(ctx
, OPC_MULTU
, 0, rx
, ry
);
13667 gen_muldiv(ctx
, OPC_DIV
, 0, rx
, ry
);
13670 gen_muldiv(ctx
, OPC_DIVU
, 0, rx
, ry
);
13672 #if defined(TARGET_MIPS64)
13674 check_insn(ctx
, ISA_MIPS3
);
13675 check_mips_64(ctx
);
13676 gen_muldiv(ctx
, OPC_DMULT
, 0, rx
, ry
);
13679 check_insn(ctx
, ISA_MIPS3
);
13680 check_mips_64(ctx
);
13681 gen_muldiv(ctx
, OPC_DMULTU
, 0, rx
, ry
);
13684 check_insn(ctx
, ISA_MIPS3
);
13685 check_mips_64(ctx
);
13686 gen_muldiv(ctx
, OPC_DDIV
, 0, rx
, ry
);
13689 check_insn(ctx
, ISA_MIPS3
);
13690 check_mips_64(ctx
);
13691 gen_muldiv(ctx
, OPC_DDIVU
, 0, rx
, ry
);
13695 gen_reserved_instruction(ctx
);
13699 case M16_OPC_EXTEND
:
13700 decode_extended_mips16_opc(env
, ctx
);
13703 #if defined(TARGET_MIPS64)
13705 funct
= (ctx
->opcode
>> 8) & 0x7;
13706 decode_i64_mips16(ctx
, ry
, funct
, offset
, 0);
13710 gen_reserved_instruction(ctx
);
13717 /* microMIPS extension to MIPS32/MIPS64 */
13720 * microMIPS32/microMIPS64 major opcodes
13722 * 1. MIPS Architecture for Programmers Volume II-B:
13723 * The microMIPS32 Instruction Set (Revision 3.05)
13725 * Table 6.2 microMIPS32 Encoding of Major Opcode Field
13727 * 2. MIPS Architecture For Programmers Volume II-A:
13728 * The MIPS64 Instruction Set (Revision 3.51)
13758 POOL32S
= 0x16, /* MIPS64 */
13759 DADDIU32
= 0x17, /* MIPS64 */
13788 /* 0x29 is reserved */
13801 /* 0x31 is reserved */
13814 SD32
= 0x36, /* MIPS64 */
13815 LD32
= 0x37, /* MIPS64 */
13817 /* 0x39 is reserved */
13833 /* PCREL Instructions perform PC-Relative address calculation. bits 20..16 */
13855 /* POOL32A encoding of minor opcode field */
13859 * These opcodes are distinguished only by bits 9..6; those bits are
13860 * what are recorded below.
13898 /* The following can be distinguished by their lower 6 bits. */
13908 /* POOL32AXF encoding of minor opcode field extension */
13911 * 1. MIPS Architecture for Programmers Volume II-B:
13912 * The microMIPS32 Instruction Set (Revision 3.05)
13914 * Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
13916 * 2. MIPS Architecture for Programmers VolumeIV-e:
13917 * The MIPS DSP Application-Specific Extension
13918 * to the microMIPS32 Architecture (Revision 2.34)
13920 * Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
13935 /* begin of microMIPS32 DSP */
13937 /* bits 13..12 for 0x01 */
13943 /* bits 13..12 for 0x2a */
13949 /* bits 13..12 for 0x32 */
13953 /* end of microMIPS32 DSP */
13955 /* bits 15..12 for 0x2c */
13972 /* bits 15..12 for 0x34 */
13980 /* bits 15..12 for 0x3c */
13982 JR
= 0x0, /* alias */
13990 /* bits 15..12 for 0x05 */
13994 /* bits 15..12 for 0x0d */
14006 /* bits 15..12 for 0x15 */
14012 /* bits 15..12 for 0x1d */
14016 /* bits 15..12 for 0x2d */
14021 /* bits 15..12 for 0x35 */
14028 /* POOL32B encoding of minor opcode field (bits 15..12) */
14044 /* POOL32C encoding of minor opcode field (bits 15..12) */
14065 /* POOL32C LD-EVA encoding of minor opcode field (bits 11..9) */
14078 /* POOL32C ST-EVA encoding of minor opcode field (bits 11..9) */
14091 /* POOL32F encoding of minor opcode field (bits 5..0) */
14094 /* These are the bit 7..6 values */
14103 /* These are the bit 8..6 values */
14128 MOVZ_FMT_05
= 0x05,
14162 CABS_COND_FMT
= 0x1c, /* MIPS3D */
14169 /* POOL32Fxf encoding of minor opcode extension field */
14207 /* POOL32I encoding of minor opcode field (bits 25..21) */
14237 /* These overlap and are distinguished by bit16 of the instruction */
14246 /* POOL16A encoding of minor opcode field */
14253 /* POOL16B encoding of minor opcode field */
14260 /* POOL16C encoding of minor opcode field */
14280 /* R6 POOL16C encoding of minor opcode field (bits 0..5) */
14304 /* POOL16D encoding of minor opcode field */
14311 /* POOL16E encoding of minor opcode field */
14318 static int mmreg(int r
)
14320 static const int map
[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
14325 /* Used for 16-bit store instructions. */
14326 static int mmreg2(int r
)
14328 static const int map
[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
14333 #define uMIPS_RD(op) ((op >> 7) & 0x7)
14334 #define uMIPS_RS(op) ((op >> 4) & 0x7)
14335 #define uMIPS_RS2(op) uMIPS_RS(op)
14336 #define uMIPS_RS1(op) ((op >> 1) & 0x7)
14337 #define uMIPS_RD5(op) ((op >> 5) & 0x1f)
14338 #define uMIPS_RS5(op) (op & 0x1f)
14340 /* Signed immediate */
14341 #define SIMM(op, start, width) \
14342 ((int32_t)(((op >> start) & ((~0U) >> (32 - width))) \
14345 /* Zero-extended immediate */
14346 #define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32 - width)))
14348 static void gen_addiur1sp(DisasContext
*ctx
)
14350 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
14352 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, 29, ((ctx
->opcode
>> 1) & 0x3f) << 2);
14355 static void gen_addiur2(DisasContext
*ctx
)
14357 static const int decoded_imm
[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
14358 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
14359 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
14361 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, rs
, decoded_imm
[ZIMM(ctx
->opcode
, 1, 3)]);
14364 static void gen_addiusp(DisasContext
*ctx
)
14366 int encoded
= ZIMM(ctx
->opcode
, 1, 9);
14369 if (encoded
<= 1) {
14370 decoded
= 256 + encoded
;
14371 } else if (encoded
<= 255) {
14373 } else if (encoded
<= 509) {
14374 decoded
= encoded
- 512;
14376 decoded
= encoded
- 768;
14379 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, decoded
<< 2);
14382 static void gen_addius5(DisasContext
*ctx
)
14384 int imm
= SIMM(ctx
->opcode
, 1, 4);
14385 int rd
= (ctx
->opcode
>> 5) & 0x1f;
14387 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, rd
, imm
);
14390 static void gen_andi16(DisasContext
*ctx
)
14392 static const int decoded_imm
[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
14393 31, 32, 63, 64, 255, 32768, 65535 };
14394 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
14395 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
14396 int encoded
= ZIMM(ctx
->opcode
, 0, 4);
14398 gen_logic_imm(ctx
, OPC_ANDI
, rd
, rs
, decoded_imm
[encoded
]);
14401 static void gen_ldst_multiple(DisasContext
*ctx
, uint32_t opc
, int reglist
,
14402 int base
, int16_t offset
)
14407 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
14408 gen_reserved_instruction(ctx
);
14412 t0
= tcg_temp_new();
14414 gen_base_offset_addr(ctx
, t0
, base
, offset
);
14416 t1
= tcg_const_tl(reglist
);
14417 t2
= tcg_const_i32(ctx
->mem_idx
);
14419 save_cpu_state(ctx
, 1);
14422 gen_helper_lwm(cpu_env
, t0
, t1
, t2
);
14425 gen_helper_swm(cpu_env
, t0
, t1
, t2
);
14427 #ifdef TARGET_MIPS64
14429 gen_helper_ldm(cpu_env
, t0
, t1
, t2
);
14432 gen_helper_sdm(cpu_env
, t0
, t1
, t2
);
14438 tcg_temp_free_i32(t2
);
14442 static void gen_pool16c_insn(DisasContext
*ctx
)
14444 int rd
= mmreg((ctx
->opcode
>> 3) & 0x7);
14445 int rs
= mmreg(ctx
->opcode
& 0x7);
14447 switch (((ctx
->opcode
) >> 4) & 0x3f) {
14452 gen_logic(ctx
, OPC_NOR
, rd
, rs
, 0);
14458 gen_logic(ctx
, OPC_XOR
, rd
, rd
, rs
);
14464 gen_logic(ctx
, OPC_AND
, rd
, rd
, rs
);
14470 gen_logic(ctx
, OPC_OR
, rd
, rd
, rs
);
14477 static const int lwm_convert
[] = { 0x11, 0x12, 0x13, 0x14 };
14478 int offset
= ZIMM(ctx
->opcode
, 0, 4);
14480 gen_ldst_multiple(ctx
, LWM32
, lwm_convert
[(ctx
->opcode
>> 4) & 0x3],
14489 static const int swm_convert
[] = { 0x11, 0x12, 0x13, 0x14 };
14490 int offset
= ZIMM(ctx
->opcode
, 0, 4);
14492 gen_ldst_multiple(ctx
, SWM32
, swm_convert
[(ctx
->opcode
>> 4) & 0x3],
14499 int reg
= ctx
->opcode
& 0x1f;
14501 gen_compute_branch(ctx
, OPC_JR
, 2, reg
, 0, 0, 4);
14507 int reg
= ctx
->opcode
& 0x1f;
14508 gen_compute_branch(ctx
, OPC_JR
, 2, reg
, 0, 0, 0);
14510 * Let normal delay slot handling in our caller take us
14511 * to the branch target.
14517 gen_compute_branch(ctx
, OPC_JALR
, 2, ctx
->opcode
& 0x1f, 31, 0, 4);
14518 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
14522 gen_compute_branch(ctx
, OPC_JALR
, 2, ctx
->opcode
& 0x1f, 31, 0, 2);
14523 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
14527 gen_HILO(ctx
, OPC_MFHI
, 0, uMIPS_RS5(ctx
->opcode
));
14531 gen_HILO(ctx
, OPC_MFLO
, 0, uMIPS_RS5(ctx
->opcode
));
14534 generate_exception_end(ctx
, EXCP_BREAK
);
14537 if (is_uhi(extract32(ctx
->opcode
, 0, 4))) {
14538 gen_helper_do_semihosting(cpu_env
);
14541 * XXX: not clear which exception should be raised
14542 * when in debug mode...
14544 check_insn(ctx
, ISA_MIPS_R1
);
14545 generate_exception_end(ctx
, EXCP_DBp
);
14548 case JRADDIUSP
+ 0:
14549 case JRADDIUSP
+ 1:
14551 int imm
= ZIMM(ctx
->opcode
, 0, 5);
14552 gen_compute_branch(ctx
, OPC_JR
, 2, 31, 0, 0, 0);
14553 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, imm
<< 2);
14555 * Let normal delay slot handling in our caller take us
14556 * to the branch target.
14561 gen_reserved_instruction(ctx
);
14566 static inline void gen_movep(DisasContext
*ctx
, int enc_dest
, int enc_rt
,
14570 static const int rd_enc
[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
14571 static const int re_enc
[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
14572 static const int rs_rt_enc
[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
14574 rd
= rd_enc
[enc_dest
];
14575 re
= re_enc
[enc_dest
];
14576 gen_load_gpr(cpu_gpr
[rd
], rs_rt_enc
[enc_rs
]);
14577 gen_load_gpr(cpu_gpr
[re
], rs_rt_enc
[enc_rt
]);
14580 static void gen_pool16c_r6_insn(DisasContext
*ctx
)
14582 int rt
= mmreg((ctx
->opcode
>> 7) & 0x7);
14583 int rs
= mmreg((ctx
->opcode
>> 4) & 0x7);
14585 switch (ctx
->opcode
& 0xf) {
14587 gen_logic(ctx
, OPC_NOR
, rt
, rs
, 0);
14590 gen_logic(ctx
, OPC_AND
, rt
, rt
, rs
);
14594 int lwm_converted
= 0x11 + extract32(ctx
->opcode
, 8, 2);
14595 int offset
= extract32(ctx
->opcode
, 4, 4);
14596 gen_ldst_multiple(ctx
, LWM32
, lwm_converted
, 29, offset
<< 2);
14599 case R6_JRC16
: /* JRCADDIUSP */
14600 if ((ctx
->opcode
>> 4) & 1) {
14602 int imm
= extract32(ctx
->opcode
, 5, 5);
14603 gen_compute_branch(ctx
, OPC_JR
, 2, 31, 0, 0, 0);
14604 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, imm
<< 2);
14607 rs
= extract32(ctx
->opcode
, 5, 5);
14608 gen_compute_branch(ctx
, OPC_JR
, 2, rs
, 0, 0, 0);
14620 int enc_dest
= uMIPS_RD(ctx
->opcode
);
14621 int enc_rt
= uMIPS_RS2(ctx
->opcode
);
14622 int enc_rs
= (ctx
->opcode
& 3) | ((ctx
->opcode
>> 1) & 4);
14623 gen_movep(ctx
, enc_dest
, enc_rt
, enc_rs
);
14627 gen_logic(ctx
, OPC_XOR
, rt
, rt
, rs
);
14630 gen_logic(ctx
, OPC_OR
, rt
, rt
, rs
);
14634 int swm_converted
= 0x11 + extract32(ctx
->opcode
, 8, 2);
14635 int offset
= extract32(ctx
->opcode
, 4, 4);
14636 gen_ldst_multiple(ctx
, SWM32
, swm_converted
, 29, offset
<< 2);
14639 case JALRC16
: /* BREAK16, SDBBP16 */
14640 switch (ctx
->opcode
& 0x3f) {
14642 case JALRC16
+ 0x20:
14644 gen_compute_branch(ctx
, OPC_JALR
, 2, (ctx
->opcode
>> 5) & 0x1f,
14649 generate_exception(ctx
, EXCP_BREAK
);
14653 if (is_uhi(extract32(ctx
->opcode
, 6, 4))) {
14654 gen_helper_do_semihosting(cpu_env
);
14656 if (ctx
->hflags
& MIPS_HFLAG_SBRI
) {
14657 generate_exception(ctx
, EXCP_RI
);
14659 generate_exception(ctx
, EXCP_DBp
);
14666 generate_exception(ctx
, EXCP_RI
);
14671 static void gen_ldxs(DisasContext
*ctx
, int base
, int index
, int rd
)
14673 TCGv t0
= tcg_temp_new();
14674 TCGv t1
= tcg_temp_new();
14676 gen_load_gpr(t0
, base
);
14679 gen_load_gpr(t1
, index
);
14680 tcg_gen_shli_tl(t1
, t1
, 2);
14681 gen_op_addr_add(ctx
, t0
, t1
, t0
);
14684 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TESL
);
14685 gen_store_gpr(t1
, rd
);
14691 static void gen_ldst_pair(DisasContext
*ctx
, uint32_t opc
, int rd
,
14692 int base
, int16_t offset
)
14696 if (ctx
->hflags
& MIPS_HFLAG_BMASK
|| rd
== 31) {
14697 gen_reserved_instruction(ctx
);
14701 t0
= tcg_temp_new();
14702 t1
= tcg_temp_new();
14704 gen_base_offset_addr(ctx
, t0
, base
, offset
);
14709 gen_reserved_instruction(ctx
);
14712 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TESL
);
14713 gen_store_gpr(t1
, rd
);
14714 tcg_gen_movi_tl(t1
, 4);
14715 gen_op_addr_add(ctx
, t0
, t0
, t1
);
14716 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TESL
);
14717 gen_store_gpr(t1
, rd
+ 1);
14720 gen_load_gpr(t1
, rd
);
14721 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
14722 tcg_gen_movi_tl(t1
, 4);
14723 gen_op_addr_add(ctx
, t0
, t0
, t1
);
14724 gen_load_gpr(t1
, rd
+ 1);
14725 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
14727 #ifdef TARGET_MIPS64
14730 gen_reserved_instruction(ctx
);
14733 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
14734 gen_store_gpr(t1
, rd
);
14735 tcg_gen_movi_tl(t1
, 8);
14736 gen_op_addr_add(ctx
, t0
, t0
, t1
);
14737 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
14738 gen_store_gpr(t1
, rd
+ 1);
14741 gen_load_gpr(t1
, rd
);
14742 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
14743 tcg_gen_movi_tl(t1
, 8);
14744 gen_op_addr_add(ctx
, t0
, t0
, t1
);
14745 gen_load_gpr(t1
, rd
+ 1);
14746 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
14754 static void gen_sync(int stype
)
14756 TCGBar tcg_mo
= TCG_BAR_SC
;
14759 case 0x4: /* SYNC_WMB */
14760 tcg_mo
|= TCG_MO_ST_ST
;
14762 case 0x10: /* SYNC_MB */
14763 tcg_mo
|= TCG_MO_ALL
;
14765 case 0x11: /* SYNC_ACQUIRE */
14766 tcg_mo
|= TCG_MO_LD_LD
| TCG_MO_LD_ST
;
14768 case 0x12: /* SYNC_RELEASE */
14769 tcg_mo
|= TCG_MO_ST_ST
| TCG_MO_LD_ST
;
14771 case 0x13: /* SYNC_RMB */
14772 tcg_mo
|= TCG_MO_LD_LD
;
14775 tcg_mo
|= TCG_MO_ALL
;
14779 tcg_gen_mb(tcg_mo
);
14782 static void gen_pool32axf(CPUMIPSState
*env
, DisasContext
*ctx
, int rt
, int rs
)
14784 int extension
= (ctx
->opcode
>> 6) & 0x3f;
14785 int minor
= (ctx
->opcode
>> 12) & 0xf;
14786 uint32_t mips32_op
;
14788 switch (extension
) {
14790 mips32_op
= OPC_TEQ
;
14793 mips32_op
= OPC_TGE
;
14796 mips32_op
= OPC_TGEU
;
14799 mips32_op
= OPC_TLT
;
14802 mips32_op
= OPC_TLTU
;
14805 mips32_op
= OPC_TNE
;
14807 gen_trap(ctx
, mips32_op
, rs
, rt
, -1);
14809 #ifndef CONFIG_USER_ONLY
14812 check_cp0_enabled(ctx
);
14814 /* Treat as NOP. */
14817 gen_mfc0(ctx
, cpu_gpr
[rt
], rs
, (ctx
->opcode
>> 11) & 0x7);
14821 check_cp0_enabled(ctx
);
14823 TCGv t0
= tcg_temp_new();
14825 gen_load_gpr(t0
, rt
);
14826 gen_mtc0(ctx
, t0
, rs
, (ctx
->opcode
>> 11) & 0x7);
14832 switch (minor
& 3) {
14834 gen_muldiv(ctx
, OPC_MADD
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
14837 gen_muldiv(ctx
, OPC_MADDU
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
14840 gen_muldiv(ctx
, OPC_MSUB
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
14843 gen_muldiv(ctx
, OPC_MSUBU
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
14846 goto pool32axf_invalid
;
14850 switch (minor
& 3) {
14852 gen_muldiv(ctx
, OPC_MULT
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
14855 gen_muldiv(ctx
, OPC_MULTU
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
14858 goto pool32axf_invalid
;
14864 check_insn(ctx
, ISA_MIPS_R6
);
14865 gen_bitswap(ctx
, OPC_BITSWAP
, rs
, rt
);
14868 gen_bshfl(ctx
, OPC_SEB
, rs
, rt
);
14871 gen_bshfl(ctx
, OPC_SEH
, rs
, rt
);
14874 mips32_op
= OPC_CLO
;
14877 mips32_op
= OPC_CLZ
;
14879 check_insn(ctx
, ISA_MIPS_R1
);
14880 gen_cl(ctx
, mips32_op
, rt
, rs
);
14883 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
14884 gen_rdhwr(ctx
, rt
, rs
, 0);
14887 gen_bshfl(ctx
, OPC_WSBH
, rs
, rt
);
14890 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
14891 mips32_op
= OPC_MULT
;
14894 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
14895 mips32_op
= OPC_MULTU
;
14898 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
14899 mips32_op
= OPC_DIV
;
14902 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
14903 mips32_op
= OPC_DIVU
;
14906 check_insn(ctx
, ISA_MIPS_R1
);
14907 gen_muldiv(ctx
, mips32_op
, 0, rs
, rt
);
14910 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
14911 mips32_op
= OPC_MADD
;
14914 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
14915 mips32_op
= OPC_MADDU
;
14918 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
14919 mips32_op
= OPC_MSUB
;
14922 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
14923 mips32_op
= OPC_MSUBU
;
14925 check_insn(ctx
, ISA_MIPS_R1
);
14926 gen_muldiv(ctx
, mips32_op
, 0, rs
, rt
);
14929 goto pool32axf_invalid
;
14940 generate_exception_err(ctx
, EXCP_CpU
, 2);
14943 goto pool32axf_invalid
;
14948 case JALR
: /* JALRC */
14949 case JALR_HB
: /* JALRC_HB */
14950 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
14951 /* JALRC, JALRC_HB */
14952 gen_compute_branch(ctx
, OPC_JALR
, 4, rs
, rt
, 0, 0);
14954 /* JALR, JALR_HB */
14955 gen_compute_branch(ctx
, OPC_JALR
, 4, rs
, rt
, 0, 4);
14956 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
14961 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
14962 gen_compute_branch(ctx
, OPC_JALR
, 4, rs
, rt
, 0, 2);
14963 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
14966 goto pool32axf_invalid
;
14972 check_cp0_enabled(ctx
);
14973 check_insn(ctx
, ISA_MIPS_R2
);
14974 gen_load_srsgpr(rs
, rt
);
14977 check_cp0_enabled(ctx
);
14978 check_insn(ctx
, ISA_MIPS_R2
);
14979 gen_store_srsgpr(rs
, rt
);
14982 goto pool32axf_invalid
;
14985 #ifndef CONFIG_USER_ONLY
14989 mips32_op
= OPC_TLBP
;
14992 mips32_op
= OPC_TLBR
;
14995 mips32_op
= OPC_TLBWI
;
14998 mips32_op
= OPC_TLBWR
;
15001 mips32_op
= OPC_TLBINV
;
15004 mips32_op
= OPC_TLBINVF
;
15007 mips32_op
= OPC_WAIT
;
15010 mips32_op
= OPC_DERET
;
15013 mips32_op
= OPC_ERET
;
15015 gen_cp0(env
, ctx
, mips32_op
, rt
, rs
);
15018 goto pool32axf_invalid
;
15024 check_cp0_enabled(ctx
);
15026 TCGv t0
= tcg_temp_new();
15028 save_cpu_state(ctx
, 1);
15029 gen_helper_di(t0
, cpu_env
);
15030 gen_store_gpr(t0
, rs
);
15032 * Stop translation as we may have switched the execution
15035 ctx
->base
.is_jmp
= DISAS_STOP
;
15040 check_cp0_enabled(ctx
);
15042 TCGv t0
= tcg_temp_new();
15044 save_cpu_state(ctx
, 1);
15045 gen_helper_ei(t0
, cpu_env
);
15046 gen_store_gpr(t0
, rs
);
15048 * DISAS_STOP isn't sufficient, we need to ensure we break out
15049 * of translated code to check for pending interrupts.
15051 gen_save_pc(ctx
->base
.pc_next
+ 4);
15052 ctx
->base
.is_jmp
= DISAS_EXIT
;
15057 goto pool32axf_invalid
;
15064 gen_sync(extract32(ctx
->opcode
, 16, 5));
15067 generate_exception_end(ctx
, EXCP_SYSCALL
);
15070 if (is_uhi(extract32(ctx
->opcode
, 16, 10))) {
15071 gen_helper_do_semihosting(cpu_env
);
15073 check_insn(ctx
, ISA_MIPS_R1
);
15074 if (ctx
->hflags
& MIPS_HFLAG_SBRI
) {
15075 gen_reserved_instruction(ctx
);
15077 generate_exception_end(ctx
, EXCP_DBp
);
15082 goto pool32axf_invalid
;
15086 switch (minor
& 3) {
15088 gen_HILO(ctx
, OPC_MFHI
, minor
>> 2, rs
);
15091 gen_HILO(ctx
, OPC_MFLO
, minor
>> 2, rs
);
15094 gen_HILO(ctx
, OPC_MTHI
, minor
>> 2, rs
);
15097 gen_HILO(ctx
, OPC_MTLO
, minor
>> 2, rs
);
15100 goto pool32axf_invalid
;
15104 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15107 gen_HILO(ctx
, OPC_MFHI
, 0, rs
);
15110 gen_HILO(ctx
, OPC_MFLO
, 0, rs
);
15113 gen_HILO(ctx
, OPC_MTHI
, 0, rs
);
15116 gen_HILO(ctx
, OPC_MTLO
, 0, rs
);
15119 goto pool32axf_invalid
;
15124 MIPS_INVAL("pool32axf");
15125 gen_reserved_instruction(ctx
);
15131 * Values for microMIPS fmt field. Variable-width, depending on which
15132 * formats the instruction supports.
15151 static void gen_pool32fxf(DisasContext
*ctx
, int rt
, int rs
)
15153 int extension
= (ctx
->opcode
>> 6) & 0x3ff;
15154 uint32_t mips32_op
;
15156 #define FLOAT_1BIT_FMT(opc, fmt) ((fmt << 8) | opc)
15157 #define FLOAT_2BIT_FMT(opc, fmt) ((fmt << 7) | opc)
15158 #define COND_FLOAT_MOV(opc, cond) ((cond << 7) | opc)
15160 switch (extension
) {
15161 case FLOAT_1BIT_FMT(CFC1
, 0):
15162 mips32_op
= OPC_CFC1
;
15164 case FLOAT_1BIT_FMT(CTC1
, 0):
15165 mips32_op
= OPC_CTC1
;
15167 case FLOAT_1BIT_FMT(MFC1
, 0):
15168 mips32_op
= OPC_MFC1
;
15170 case FLOAT_1BIT_FMT(MTC1
, 0):
15171 mips32_op
= OPC_MTC1
;
15173 case FLOAT_1BIT_FMT(MFHC1
, 0):
15174 mips32_op
= OPC_MFHC1
;
15176 case FLOAT_1BIT_FMT(MTHC1
, 0):
15177 mips32_op
= OPC_MTHC1
;
15179 gen_cp1(ctx
, mips32_op
, rt
, rs
);
15182 /* Reciprocal square root */
15183 case FLOAT_1BIT_FMT(RSQRT_FMT
, FMT_SD_S
):
15184 mips32_op
= OPC_RSQRT_S
;
15186 case FLOAT_1BIT_FMT(RSQRT_FMT
, FMT_SD_D
):
15187 mips32_op
= OPC_RSQRT_D
;
15191 case FLOAT_1BIT_FMT(SQRT_FMT
, FMT_SD_S
):
15192 mips32_op
= OPC_SQRT_S
;
15194 case FLOAT_1BIT_FMT(SQRT_FMT
, FMT_SD_D
):
15195 mips32_op
= OPC_SQRT_D
;
15199 case FLOAT_1BIT_FMT(RECIP_FMT
, FMT_SD_S
):
15200 mips32_op
= OPC_RECIP_S
;
15202 case FLOAT_1BIT_FMT(RECIP_FMT
, FMT_SD_D
):
15203 mips32_op
= OPC_RECIP_D
;
15207 case FLOAT_1BIT_FMT(FLOOR_L
, FMT_SD_S
):
15208 mips32_op
= OPC_FLOOR_L_S
;
15210 case FLOAT_1BIT_FMT(FLOOR_L
, FMT_SD_D
):
15211 mips32_op
= OPC_FLOOR_L_D
;
15213 case FLOAT_1BIT_FMT(FLOOR_W
, FMT_SD_S
):
15214 mips32_op
= OPC_FLOOR_W_S
;
15216 case FLOAT_1BIT_FMT(FLOOR_W
, FMT_SD_D
):
15217 mips32_op
= OPC_FLOOR_W_D
;
15221 case FLOAT_1BIT_FMT(CEIL_L
, FMT_SD_S
):
15222 mips32_op
= OPC_CEIL_L_S
;
15224 case FLOAT_1BIT_FMT(CEIL_L
, FMT_SD_D
):
15225 mips32_op
= OPC_CEIL_L_D
;
15227 case FLOAT_1BIT_FMT(CEIL_W
, FMT_SD_S
):
15228 mips32_op
= OPC_CEIL_W_S
;
15230 case FLOAT_1BIT_FMT(CEIL_W
, FMT_SD_D
):
15231 mips32_op
= OPC_CEIL_W_D
;
15235 case FLOAT_1BIT_FMT(TRUNC_L
, FMT_SD_S
):
15236 mips32_op
= OPC_TRUNC_L_S
;
15238 case FLOAT_1BIT_FMT(TRUNC_L
, FMT_SD_D
):
15239 mips32_op
= OPC_TRUNC_L_D
;
15241 case FLOAT_1BIT_FMT(TRUNC_W
, FMT_SD_S
):
15242 mips32_op
= OPC_TRUNC_W_S
;
15244 case FLOAT_1BIT_FMT(TRUNC_W
, FMT_SD_D
):
15245 mips32_op
= OPC_TRUNC_W_D
;
15249 case FLOAT_1BIT_FMT(ROUND_L
, FMT_SD_S
):
15250 mips32_op
= OPC_ROUND_L_S
;
15252 case FLOAT_1BIT_FMT(ROUND_L
, FMT_SD_D
):
15253 mips32_op
= OPC_ROUND_L_D
;
15255 case FLOAT_1BIT_FMT(ROUND_W
, FMT_SD_S
):
15256 mips32_op
= OPC_ROUND_W_S
;
15258 case FLOAT_1BIT_FMT(ROUND_W
, FMT_SD_D
):
15259 mips32_op
= OPC_ROUND_W_D
;
15262 /* Integer to floating-point conversion */
15263 case FLOAT_1BIT_FMT(CVT_L
, FMT_SD_S
):
15264 mips32_op
= OPC_CVT_L_S
;
15266 case FLOAT_1BIT_FMT(CVT_L
, FMT_SD_D
):
15267 mips32_op
= OPC_CVT_L_D
;
15269 case FLOAT_1BIT_FMT(CVT_W
, FMT_SD_S
):
15270 mips32_op
= OPC_CVT_W_S
;
15272 case FLOAT_1BIT_FMT(CVT_W
, FMT_SD_D
):
15273 mips32_op
= OPC_CVT_W_D
;
15276 /* Paired-foo conversions */
15277 case FLOAT_1BIT_FMT(CVT_S_PL
, 0):
15278 mips32_op
= OPC_CVT_S_PL
;
15280 case FLOAT_1BIT_FMT(CVT_S_PU
, 0):
15281 mips32_op
= OPC_CVT_S_PU
;
15283 case FLOAT_1BIT_FMT(CVT_PW_PS
, 0):
15284 mips32_op
= OPC_CVT_PW_PS
;
15286 case FLOAT_1BIT_FMT(CVT_PS_PW
, 0):
15287 mips32_op
= OPC_CVT_PS_PW
;
15290 /* Floating-point moves */
15291 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_S
):
15292 mips32_op
= OPC_MOV_S
;
15294 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_D
):
15295 mips32_op
= OPC_MOV_D
;
15297 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_PS
):
15298 mips32_op
= OPC_MOV_PS
;
15301 /* Absolute value */
15302 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_S
):
15303 mips32_op
= OPC_ABS_S
;
15305 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_D
):
15306 mips32_op
= OPC_ABS_D
;
15308 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_PS
):
15309 mips32_op
= OPC_ABS_PS
;
15313 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_S
):
15314 mips32_op
= OPC_NEG_S
;
15316 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_D
):
15317 mips32_op
= OPC_NEG_D
;
15319 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_PS
):
15320 mips32_op
= OPC_NEG_PS
;
15323 /* Reciprocal square root step */
15324 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_S
):
15325 mips32_op
= OPC_RSQRT1_S
;
15327 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_D
):
15328 mips32_op
= OPC_RSQRT1_D
;
15330 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_PS
):
15331 mips32_op
= OPC_RSQRT1_PS
;
15334 /* Reciprocal step */
15335 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_S
):
15336 mips32_op
= OPC_RECIP1_S
;
15338 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_D
):
15339 mips32_op
= OPC_RECIP1_S
;
15341 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_PS
):
15342 mips32_op
= OPC_RECIP1_PS
;
15345 /* Conversions from double */
15346 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_S
):
15347 mips32_op
= OPC_CVT_D_S
;
15349 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_W
):
15350 mips32_op
= OPC_CVT_D_W
;
15352 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_L
):
15353 mips32_op
= OPC_CVT_D_L
;
15356 /* Conversions from single */
15357 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_D
):
15358 mips32_op
= OPC_CVT_S_D
;
15360 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_W
):
15361 mips32_op
= OPC_CVT_S_W
;
15363 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_L
):
15364 mips32_op
= OPC_CVT_S_L
;
15366 gen_farith(ctx
, mips32_op
, -1, rs
, rt
, 0);
15369 /* Conditional moves on floating-point codes */
15370 case COND_FLOAT_MOV(MOVT
, 0):
15371 case COND_FLOAT_MOV(MOVT
, 1):
15372 case COND_FLOAT_MOV(MOVT
, 2):
15373 case COND_FLOAT_MOV(MOVT
, 3):
15374 case COND_FLOAT_MOV(MOVT
, 4):
15375 case COND_FLOAT_MOV(MOVT
, 5):
15376 case COND_FLOAT_MOV(MOVT
, 6):
15377 case COND_FLOAT_MOV(MOVT
, 7):
15378 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15379 gen_movci(ctx
, rt
, rs
, (ctx
->opcode
>> 13) & 0x7, 1);
15381 case COND_FLOAT_MOV(MOVF
, 0):
15382 case COND_FLOAT_MOV(MOVF
, 1):
15383 case COND_FLOAT_MOV(MOVF
, 2):
15384 case COND_FLOAT_MOV(MOVF
, 3):
15385 case COND_FLOAT_MOV(MOVF
, 4):
15386 case COND_FLOAT_MOV(MOVF
, 5):
15387 case COND_FLOAT_MOV(MOVF
, 6):
15388 case COND_FLOAT_MOV(MOVF
, 7):
15389 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15390 gen_movci(ctx
, rt
, rs
, (ctx
->opcode
>> 13) & 0x7, 0);
15393 MIPS_INVAL("pool32fxf");
15394 gen_reserved_instruction(ctx
);
15399 static void decode_micromips32_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
15403 int rt
, rs
, rd
, rr
;
15405 uint32_t op
, minor
, minor2
, mips32_op
;
15406 uint32_t cond
, fmt
, cc
;
15408 insn
= translator_lduw(env
, ctx
->base
.pc_next
+ 2);
15409 ctx
->opcode
= (ctx
->opcode
<< 16) | insn
;
15411 rt
= (ctx
->opcode
>> 21) & 0x1f;
15412 rs
= (ctx
->opcode
>> 16) & 0x1f;
15413 rd
= (ctx
->opcode
>> 11) & 0x1f;
15414 rr
= (ctx
->opcode
>> 6) & 0x1f;
15415 imm
= (int16_t) ctx
->opcode
;
15417 op
= (ctx
->opcode
>> 26) & 0x3f;
15420 minor
= ctx
->opcode
& 0x3f;
15423 minor
= (ctx
->opcode
>> 6) & 0xf;
15426 mips32_op
= OPC_SLL
;
15429 mips32_op
= OPC_SRA
;
15432 mips32_op
= OPC_SRL
;
15435 mips32_op
= OPC_ROTR
;
15437 gen_shift_imm(ctx
, mips32_op
, rt
, rs
, rd
);
15440 check_insn(ctx
, ISA_MIPS_R6
);
15441 gen_cond_move(ctx
, OPC_SELEQZ
, rd
, rs
, rt
);
15444 check_insn(ctx
, ISA_MIPS_R6
);
15445 gen_cond_move(ctx
, OPC_SELNEZ
, rd
, rs
, rt
);
15448 check_insn(ctx
, ISA_MIPS_R6
);
15449 gen_rdhwr(ctx
, rt
, rs
, extract32(ctx
->opcode
, 11, 3));
15452 goto pool32a_invalid
;
15456 minor
= (ctx
->opcode
>> 6) & 0xf;
15460 mips32_op
= OPC_ADD
;
15463 mips32_op
= OPC_ADDU
;
15466 mips32_op
= OPC_SUB
;
15469 mips32_op
= OPC_SUBU
;
15472 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15473 mips32_op
= OPC_MUL
;
15475 gen_arith(ctx
, mips32_op
, rd
, rs
, rt
);
15479 mips32_op
= OPC_SLLV
;
15482 mips32_op
= OPC_SRLV
;
15485 mips32_op
= OPC_SRAV
;
15488 mips32_op
= OPC_ROTRV
;
15490 gen_shift(ctx
, mips32_op
, rd
, rs
, rt
);
15492 /* Logical operations */
15494 mips32_op
= OPC_AND
;
15497 mips32_op
= OPC_OR
;
15500 mips32_op
= OPC_NOR
;
15503 mips32_op
= OPC_XOR
;
15505 gen_logic(ctx
, mips32_op
, rd
, rs
, rt
);
15507 /* Set less than */
15509 mips32_op
= OPC_SLT
;
15512 mips32_op
= OPC_SLTU
;
15514 gen_slt(ctx
, mips32_op
, rd
, rs
, rt
);
15517 goto pool32a_invalid
;
15521 minor
= (ctx
->opcode
>> 6) & 0xf;
15523 /* Conditional moves */
15524 case MOVN
: /* MUL */
15525 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
15527 gen_r6_muldiv(ctx
, R6_OPC_MUL
, rd
, rs
, rt
);
15530 gen_cond_move(ctx
, OPC_MOVN
, rd
, rs
, rt
);
15533 case MOVZ
: /* MUH */
15534 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
15536 gen_r6_muldiv(ctx
, R6_OPC_MUH
, rd
, rs
, rt
);
15539 gen_cond_move(ctx
, OPC_MOVZ
, rd
, rs
, rt
);
15543 check_insn(ctx
, ISA_MIPS_R6
);
15544 gen_r6_muldiv(ctx
, R6_OPC_MULU
, rd
, rs
, rt
);
15547 check_insn(ctx
, ISA_MIPS_R6
);
15548 gen_r6_muldiv(ctx
, R6_OPC_MUHU
, rd
, rs
, rt
);
15550 case LWXS
: /* DIV */
15551 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
15553 gen_r6_muldiv(ctx
, R6_OPC_DIV
, rd
, rs
, rt
);
15556 gen_ldxs(ctx
, rs
, rt
, rd
);
15560 check_insn(ctx
, ISA_MIPS_R6
);
15561 gen_r6_muldiv(ctx
, R6_OPC_MOD
, rd
, rs
, rt
);
15564 check_insn(ctx
, ISA_MIPS_R6
);
15565 gen_r6_muldiv(ctx
, R6_OPC_DIVU
, rd
, rs
, rt
);
15568 check_insn(ctx
, ISA_MIPS_R6
);
15569 gen_r6_muldiv(ctx
, R6_OPC_MODU
, rd
, rs
, rt
);
15572 goto pool32a_invalid
;
15576 gen_bitops(ctx
, OPC_INS
, rt
, rs
, rr
, rd
);
15579 check_insn(ctx
, ISA_MIPS_R6
);
15580 gen_lsa(ctx
, rd
, rt
, rs
, extract32(ctx
->opcode
, 9, 2));
15583 check_insn(ctx
, ISA_MIPS_R6
);
15584 gen_align(ctx
, 32, rd
, rs
, rt
, extract32(ctx
->opcode
, 9, 2));
15587 gen_bitops(ctx
, OPC_EXT
, rt
, rs
, rr
, rd
);
15590 gen_pool32axf(env
, ctx
, rt
, rs
);
15593 generate_exception_end(ctx
, EXCP_BREAK
);
15596 check_insn(ctx
, ISA_MIPS_R6
);
15597 gen_reserved_instruction(ctx
);
15601 MIPS_INVAL("pool32a");
15602 gen_reserved_instruction(ctx
);
15607 minor
= (ctx
->opcode
>> 12) & 0xf;
15610 check_cp0_enabled(ctx
);
15611 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
15612 gen_cache_operation(ctx
, rt
, rs
, imm
);
15617 /* COP2: Not implemented. */
15618 generate_exception_err(ctx
, EXCP_CpU
, 2);
15620 #ifdef TARGET_MIPS64
15623 check_insn(ctx
, ISA_MIPS3
);
15624 check_mips_64(ctx
);
15629 gen_ldst_pair(ctx
, minor
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
15631 #ifdef TARGET_MIPS64
15634 check_insn(ctx
, ISA_MIPS3
);
15635 check_mips_64(ctx
);
15640 gen_ldst_multiple(ctx
, minor
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
15643 MIPS_INVAL("pool32b");
15644 gen_reserved_instruction(ctx
);
15649 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
15650 minor
= ctx
->opcode
& 0x3f;
15651 check_cp1_enabled(ctx
);
15654 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15655 mips32_op
= OPC_ALNV_PS
;
15658 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15659 mips32_op
= OPC_MADD_S
;
15662 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15663 mips32_op
= OPC_MADD_D
;
15666 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15667 mips32_op
= OPC_MADD_PS
;
15670 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15671 mips32_op
= OPC_MSUB_S
;
15674 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15675 mips32_op
= OPC_MSUB_D
;
15678 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15679 mips32_op
= OPC_MSUB_PS
;
15682 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15683 mips32_op
= OPC_NMADD_S
;
15686 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15687 mips32_op
= OPC_NMADD_D
;
15690 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15691 mips32_op
= OPC_NMADD_PS
;
15694 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15695 mips32_op
= OPC_NMSUB_S
;
15698 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15699 mips32_op
= OPC_NMSUB_D
;
15702 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15703 mips32_op
= OPC_NMSUB_PS
;
15705 gen_flt3_arith(ctx
, mips32_op
, rd
, rr
, rs
, rt
);
15707 case CABS_COND_FMT
:
15708 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15709 cond
= (ctx
->opcode
>> 6) & 0xf;
15710 cc
= (ctx
->opcode
>> 13) & 0x7;
15711 fmt
= (ctx
->opcode
>> 10) & 0x3;
15714 gen_cmpabs_s(ctx
, cond
, rt
, rs
, cc
);
15717 gen_cmpabs_d(ctx
, cond
, rt
, rs
, cc
);
15720 gen_cmpabs_ps(ctx
, cond
, rt
, rs
, cc
);
15723 goto pool32f_invalid
;
15727 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15728 cond
= (ctx
->opcode
>> 6) & 0xf;
15729 cc
= (ctx
->opcode
>> 13) & 0x7;
15730 fmt
= (ctx
->opcode
>> 10) & 0x3;
15733 gen_cmp_s(ctx
, cond
, rt
, rs
, cc
);
15736 gen_cmp_d(ctx
, cond
, rt
, rs
, cc
);
15739 gen_cmp_ps(ctx
, cond
, rt
, rs
, cc
);
15742 goto pool32f_invalid
;
15746 check_insn(ctx
, ISA_MIPS_R6
);
15747 gen_r6_cmp_s(ctx
, (ctx
->opcode
>> 6) & 0x1f, rt
, rs
, rd
);
15750 check_insn(ctx
, ISA_MIPS_R6
);
15751 gen_r6_cmp_d(ctx
, (ctx
->opcode
>> 6) & 0x1f, rt
, rs
, rd
);
15754 gen_pool32fxf(ctx
, rt
, rs
);
15758 switch ((ctx
->opcode
>> 6) & 0x7) {
15760 mips32_op
= OPC_PLL_PS
;
15763 mips32_op
= OPC_PLU_PS
;
15766 mips32_op
= OPC_PUL_PS
;
15769 mips32_op
= OPC_PUU_PS
;
15772 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15773 mips32_op
= OPC_CVT_PS_S
;
15775 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
15778 goto pool32f_invalid
;
15782 check_insn(ctx
, ISA_MIPS_R6
);
15783 switch ((ctx
->opcode
>> 9) & 0x3) {
15785 gen_farith(ctx
, OPC_MIN_S
, rt
, rs
, rd
, 0);
15788 gen_farith(ctx
, OPC_MIN_D
, rt
, rs
, rd
, 0);
15791 goto pool32f_invalid
;
15796 switch ((ctx
->opcode
>> 6) & 0x7) {
15798 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15799 mips32_op
= OPC_LWXC1
;
15802 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15803 mips32_op
= OPC_SWXC1
;
15806 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15807 mips32_op
= OPC_LDXC1
;
15810 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15811 mips32_op
= OPC_SDXC1
;
15814 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15815 mips32_op
= OPC_LUXC1
;
15818 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15819 mips32_op
= OPC_SUXC1
;
15821 gen_flt3_ldst(ctx
, mips32_op
, rd
, rd
, rt
, rs
);
15824 goto pool32f_invalid
;
15828 check_insn(ctx
, ISA_MIPS_R6
);
15829 switch ((ctx
->opcode
>> 9) & 0x3) {
15831 gen_farith(ctx
, OPC_MAX_S
, rt
, rs
, rd
, 0);
15834 gen_farith(ctx
, OPC_MAX_D
, rt
, rs
, rd
, 0);
15837 goto pool32f_invalid
;
15842 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15843 fmt
= (ctx
->opcode
>> 9) & 0x3;
15844 switch ((ctx
->opcode
>> 6) & 0x7) {
15848 mips32_op
= OPC_RSQRT2_S
;
15851 mips32_op
= OPC_RSQRT2_D
;
15854 mips32_op
= OPC_RSQRT2_PS
;
15857 goto pool32f_invalid
;
15863 mips32_op
= OPC_RECIP2_S
;
15866 mips32_op
= OPC_RECIP2_D
;
15869 mips32_op
= OPC_RECIP2_PS
;
15872 goto pool32f_invalid
;
15876 mips32_op
= OPC_ADDR_PS
;
15879 mips32_op
= OPC_MULR_PS
;
15881 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
15884 goto pool32f_invalid
;
15888 /* MOV[FT].fmt, PREFX, RINT.fmt, CLASS.fmt*/
15889 cc
= (ctx
->opcode
>> 13) & 0x7;
15890 fmt
= (ctx
->opcode
>> 9) & 0x3;
15891 switch ((ctx
->opcode
>> 6) & 0x7) {
15892 case MOVF_FMT
: /* RINT_FMT */
15893 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
15897 gen_farith(ctx
, OPC_RINT_S
, 0, rt
, rs
, 0);
15900 gen_farith(ctx
, OPC_RINT_D
, 0, rt
, rs
, 0);
15903 goto pool32f_invalid
;
15909 gen_movcf_s(ctx
, rs
, rt
, cc
, 0);
15912 gen_movcf_d(ctx
, rs
, rt
, cc
, 0);
15916 gen_movcf_ps(ctx
, rs
, rt
, cc
, 0);
15919 goto pool32f_invalid
;
15923 case MOVT_FMT
: /* CLASS_FMT */
15924 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
15928 gen_farith(ctx
, OPC_CLASS_S
, 0, rt
, rs
, 0);
15931 gen_farith(ctx
, OPC_CLASS_D
, 0, rt
, rs
, 0);
15934 goto pool32f_invalid
;
15940 gen_movcf_s(ctx
, rs
, rt
, cc
, 1);
15943 gen_movcf_d(ctx
, rs
, rt
, cc
, 1);
15947 gen_movcf_ps(ctx
, rs
, rt
, cc
, 1);
15950 goto pool32f_invalid
;
15955 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15958 goto pool32f_invalid
;
15961 #define FINSN_3ARG_SDPS(prfx) \
15962 switch ((ctx->opcode >> 8) & 0x3) { \
15964 mips32_op = OPC_##prfx##_S; \
15967 mips32_op = OPC_##prfx##_D; \
15969 case FMT_SDPS_PS: \
15971 mips32_op = OPC_##prfx##_PS; \
15974 goto pool32f_invalid; \
15977 check_insn(ctx
, ISA_MIPS_R6
);
15978 switch ((ctx
->opcode
>> 9) & 0x3) {
15980 gen_farith(ctx
, OPC_MINA_S
, rt
, rs
, rd
, 0);
15983 gen_farith(ctx
, OPC_MINA_D
, rt
, rs
, rd
, 0);
15986 goto pool32f_invalid
;
15990 check_insn(ctx
, ISA_MIPS_R6
);
15991 switch ((ctx
->opcode
>> 9) & 0x3) {
15993 gen_farith(ctx
, OPC_MAXA_S
, rt
, rs
, rd
, 0);
15996 gen_farith(ctx
, OPC_MAXA_D
, rt
, rs
, rd
, 0);
15999 goto pool32f_invalid
;
16003 /* regular FP ops */
16004 switch ((ctx
->opcode
>> 6) & 0x3) {
16006 FINSN_3ARG_SDPS(ADD
);
16009 FINSN_3ARG_SDPS(SUB
);
16012 FINSN_3ARG_SDPS(MUL
);
16015 fmt
= (ctx
->opcode
>> 8) & 0x3;
16017 mips32_op
= OPC_DIV_D
;
16018 } else if (fmt
== 0) {
16019 mips32_op
= OPC_DIV_S
;
16021 goto pool32f_invalid
;
16025 goto pool32f_invalid
;
16030 switch ((ctx
->opcode
>> 6) & 0x7) {
16031 case MOVN_FMT
: /* SELEQZ_FMT */
16032 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16034 switch ((ctx
->opcode
>> 9) & 0x3) {
16036 gen_sel_s(ctx
, OPC_SELEQZ_S
, rd
, rt
, rs
);
16039 gen_sel_d(ctx
, OPC_SELEQZ_D
, rd
, rt
, rs
);
16042 goto pool32f_invalid
;
16046 FINSN_3ARG_SDPS(MOVN
);
16050 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16051 FINSN_3ARG_SDPS(MOVN
);
16053 case MOVZ_FMT
: /* SELNEZ_FMT */
16054 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16056 switch ((ctx
->opcode
>> 9) & 0x3) {
16058 gen_sel_s(ctx
, OPC_SELNEZ_S
, rd
, rt
, rs
);
16061 gen_sel_d(ctx
, OPC_SELNEZ_D
, rd
, rt
, rs
);
16064 goto pool32f_invalid
;
16068 FINSN_3ARG_SDPS(MOVZ
);
16072 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16073 FINSN_3ARG_SDPS(MOVZ
);
16076 check_insn(ctx
, ISA_MIPS_R6
);
16077 switch ((ctx
->opcode
>> 9) & 0x3) {
16079 gen_sel_s(ctx
, OPC_SEL_S
, rd
, rt
, rs
);
16082 gen_sel_d(ctx
, OPC_SEL_D
, rd
, rt
, rs
);
16085 goto pool32f_invalid
;
16089 check_insn(ctx
, ISA_MIPS_R6
);
16090 switch ((ctx
->opcode
>> 9) & 0x3) {
16092 mips32_op
= OPC_MADDF_S
;
16095 mips32_op
= OPC_MADDF_D
;
16098 goto pool32f_invalid
;
16102 check_insn(ctx
, ISA_MIPS_R6
);
16103 switch ((ctx
->opcode
>> 9) & 0x3) {
16105 mips32_op
= OPC_MSUBF_S
;
16108 mips32_op
= OPC_MSUBF_D
;
16111 goto pool32f_invalid
;
16115 goto pool32f_invalid
;
16119 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
16123 MIPS_INVAL("pool32f");
16124 gen_reserved_instruction(ctx
);
16128 generate_exception_err(ctx
, EXCP_CpU
, 1);
16132 minor
= (ctx
->opcode
>> 21) & 0x1f;
16135 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16136 gen_compute_branch(ctx
, OPC_BLTZ
, 4, rs
, -1, imm
<< 1, 4);
16139 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16140 gen_compute_branch(ctx
, OPC_BLTZAL
, 4, rs
, -1, imm
<< 1, 4);
16141 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
16144 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16145 gen_compute_branch(ctx
, OPC_BLTZAL
, 4, rs
, -1, imm
<< 1, 2);
16146 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
16149 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16150 gen_compute_branch(ctx
, OPC_BGEZ
, 4, rs
, -1, imm
<< 1, 4);
16153 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16154 gen_compute_branch(ctx
, OPC_BGEZAL
, 4, rs
, -1, imm
<< 1, 4);
16155 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
16158 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16159 gen_compute_branch(ctx
, OPC_BGEZAL
, 4, rs
, -1, imm
<< 1, 2);
16160 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
16163 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16164 gen_compute_branch(ctx
, OPC_BLEZ
, 4, rs
, -1, imm
<< 1, 4);
16167 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16168 gen_compute_branch(ctx
, OPC_BGTZ
, 4, rs
, -1, imm
<< 1, 4);
16172 case TLTI
: /* BC1EQZC */
16173 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16175 check_cp1_enabled(ctx
);
16176 gen_compute_branch1_r6(ctx
, OPC_BC1EQZ
, rs
, imm
<< 1, 0);
16179 mips32_op
= OPC_TLTI
;
16183 case TGEI
: /* BC1NEZC */
16184 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16186 check_cp1_enabled(ctx
);
16187 gen_compute_branch1_r6(ctx
, OPC_BC1NEZ
, rs
, imm
<< 1, 0);
16190 mips32_op
= OPC_TGEI
;
16195 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16196 mips32_op
= OPC_TLTIU
;
16199 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16200 mips32_op
= OPC_TGEIU
;
16202 case TNEI
: /* SYNCI */
16203 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16206 * Break the TB to be able to sync copied instructions
16209 ctx
->base
.is_jmp
= DISAS_STOP
;
16212 mips32_op
= OPC_TNEI
;
16217 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16218 mips32_op
= OPC_TEQI
;
16220 gen_trap(ctx
, mips32_op
, rs
, -1, imm
);
16225 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16226 gen_compute_branch(ctx
, minor
== BNEZC
? OPC_BNE
: OPC_BEQ
,
16227 4, rs
, 0, imm
<< 1, 0);
16229 * Compact branches don't have a delay slot, so just let
16230 * the normal delay slot handling take us to the branch
16235 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16236 gen_logic_imm(ctx
, OPC_LUI
, rs
, 0, imm
);
16239 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16241 * Break the TB to be able to sync copied instructions
16244 ctx
->base
.is_jmp
= DISAS_STOP
;
16248 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16249 /* COP2: Not implemented. */
16250 generate_exception_err(ctx
, EXCP_CpU
, 2);
16253 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16254 mips32_op
= (ctx
->opcode
& (1 << 16)) ? OPC_BC1FANY2
: OPC_BC1F
;
16257 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16258 mips32_op
= (ctx
->opcode
& (1 << 16)) ? OPC_BC1TANY2
: OPC_BC1T
;
16261 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16262 mips32_op
= OPC_BC1FANY4
;
16265 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16266 mips32_op
= OPC_BC1TANY4
;
16269 check_insn(ctx
, ASE_MIPS3D
);
16272 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
16273 check_cp1_enabled(ctx
);
16274 gen_compute_branch1(ctx
, mips32_op
,
16275 (ctx
->opcode
>> 18) & 0x7, imm
<< 1);
16277 generate_exception_err(ctx
, EXCP_CpU
, 1);
16282 /* MIPS DSP: not implemented */
16285 MIPS_INVAL("pool32i");
16286 gen_reserved_instruction(ctx
);
16291 minor
= (ctx
->opcode
>> 12) & 0xf;
16292 offset
= sextract32(ctx
->opcode
, 0,
16293 (ctx
->insn_flags
& ISA_MIPS_R6
) ? 9 : 12);
16296 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16297 mips32_op
= OPC_LWL
;
16300 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16301 mips32_op
= OPC_SWL
;
16304 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16305 mips32_op
= OPC_LWR
;
16308 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16309 mips32_op
= OPC_SWR
;
16311 #if defined(TARGET_MIPS64)
16313 check_insn(ctx
, ISA_MIPS3
);
16314 check_mips_64(ctx
);
16315 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16316 mips32_op
= OPC_LDL
;
16319 check_insn(ctx
, ISA_MIPS3
);
16320 check_mips_64(ctx
);
16321 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16322 mips32_op
= OPC_SDL
;
16325 check_insn(ctx
, ISA_MIPS3
);
16326 check_mips_64(ctx
);
16327 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16328 mips32_op
= OPC_LDR
;
16331 check_insn(ctx
, ISA_MIPS3
);
16332 check_mips_64(ctx
);
16333 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16334 mips32_op
= OPC_SDR
;
16337 check_insn(ctx
, ISA_MIPS3
);
16338 check_mips_64(ctx
);
16339 mips32_op
= OPC_LWU
;
16342 check_insn(ctx
, ISA_MIPS3
);
16343 check_mips_64(ctx
);
16344 mips32_op
= OPC_LLD
;
16348 mips32_op
= OPC_LL
;
16351 gen_ld(ctx
, mips32_op
, rt
, rs
, offset
);
16354 gen_st(ctx
, mips32_op
, rt
, rs
, offset
);
16357 gen_st_cond(ctx
, rt
, rs
, offset
, MO_TESL
, false);
16359 #if defined(TARGET_MIPS64)
16361 check_insn(ctx
, ISA_MIPS3
);
16362 check_mips_64(ctx
);
16363 gen_st_cond(ctx
, rt
, rs
, offset
, MO_TEQ
, false);
16368 MIPS_INVAL("pool32c ld-eva");
16369 gen_reserved_instruction(ctx
);
16372 check_cp0_enabled(ctx
);
16374 minor2
= (ctx
->opcode
>> 9) & 0x7;
16375 offset
= sextract32(ctx
->opcode
, 0, 9);
16378 mips32_op
= OPC_LBUE
;
16381 mips32_op
= OPC_LHUE
;
16384 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16385 mips32_op
= OPC_LWLE
;
16388 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16389 mips32_op
= OPC_LWRE
;
16392 mips32_op
= OPC_LBE
;
16395 mips32_op
= OPC_LHE
;
16398 mips32_op
= OPC_LLE
;
16401 mips32_op
= OPC_LWE
;
16407 MIPS_INVAL("pool32c st-eva");
16408 gen_reserved_instruction(ctx
);
16411 check_cp0_enabled(ctx
);
16413 minor2
= (ctx
->opcode
>> 9) & 0x7;
16414 offset
= sextract32(ctx
->opcode
, 0, 9);
16417 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16418 mips32_op
= OPC_SWLE
;
16421 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16422 mips32_op
= OPC_SWRE
;
16425 /* Treat as no-op */
16426 if ((ctx
->insn_flags
& ISA_MIPS_R6
) && (rt
>= 24)) {
16427 /* hint codes 24-31 are reserved and signal RI */
16428 generate_exception(ctx
, EXCP_RI
);
16432 /* Treat as no-op */
16433 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
16434 gen_cache_operation(ctx
, rt
, rs
, offset
);
16438 mips32_op
= OPC_SBE
;
16441 mips32_op
= OPC_SHE
;
16444 gen_st_cond(ctx
, rt
, rs
, offset
, MO_TESL
, true);
16447 mips32_op
= OPC_SWE
;
16452 /* Treat as no-op */
16453 if ((ctx
->insn_flags
& ISA_MIPS_R6
) && (rt
>= 24)) {
16454 /* hint codes 24-31 are reserved and signal RI */
16455 generate_exception(ctx
, EXCP_RI
);
16459 MIPS_INVAL("pool32c");
16460 gen_reserved_instruction(ctx
);
16464 case ADDI32
: /* AUI, LUI */
16465 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16467 gen_logic_imm(ctx
, OPC_LUI
, rt
, rs
, imm
);
16470 mips32_op
= OPC_ADDI
;
16475 mips32_op
= OPC_ADDIU
;
16477 gen_arith_imm(ctx
, mips32_op
, rt
, rs
, imm
);
16480 /* Logical operations */
16482 mips32_op
= OPC_ORI
;
16485 mips32_op
= OPC_XORI
;
16488 mips32_op
= OPC_ANDI
;
16490 gen_logic_imm(ctx
, mips32_op
, rt
, rs
, imm
);
16493 /* Set less than immediate */
16495 mips32_op
= OPC_SLTI
;
16498 mips32_op
= OPC_SLTIU
;
16500 gen_slt_imm(ctx
, mips32_op
, rt
, rs
, imm
);
16503 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16504 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
16505 gen_compute_branch(ctx
, OPC_JALX
, 4, rt
, rs
, offset
, 4);
16506 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
16508 case JALS32
: /* BOVC, BEQC, BEQZALC */
16509 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16512 mips32_op
= OPC_BOVC
;
16513 } else if (rs
< rt
&& rs
== 0) {
16515 mips32_op
= OPC_BEQZALC
;
16518 mips32_op
= OPC_BEQC
;
16520 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
16523 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1;
16524 gen_compute_branch(ctx
, OPC_JAL
, 4, rt
, rs
, offset
, 2);
16525 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
16528 case BEQ32
: /* BC */
16529 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16531 gen_compute_compact_branch(ctx
, OPC_BC
, 0, 0,
16532 sextract32(ctx
->opcode
<< 1, 0, 27));
16535 gen_compute_branch(ctx
, OPC_BEQ
, 4, rt
, rs
, imm
<< 1, 4);
16538 case BNE32
: /* BALC */
16539 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16541 gen_compute_compact_branch(ctx
, OPC_BALC
, 0, 0,
16542 sextract32(ctx
->opcode
<< 1, 0, 27));
16545 gen_compute_branch(ctx
, OPC_BNE
, 4, rt
, rs
, imm
<< 1, 4);
16548 case J32
: /* BGTZC, BLTZC, BLTC */
16549 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16550 if (rs
== 0 && rt
!= 0) {
16552 mips32_op
= OPC_BGTZC
;
16553 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
16555 mips32_op
= OPC_BLTZC
;
16558 mips32_op
= OPC_BLTC
;
16560 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
16563 gen_compute_branch(ctx
, OPC_J
, 4, rt
, rs
,
16564 (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1, 4);
16567 case JAL32
: /* BLEZC, BGEZC, BGEC */
16568 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16569 if (rs
== 0 && rt
!= 0) {
16571 mips32_op
= OPC_BLEZC
;
16572 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
16574 mips32_op
= OPC_BGEZC
;
16577 mips32_op
= OPC_BGEC
;
16579 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
16582 gen_compute_branch(ctx
, OPC_JAL
, 4, rt
, rs
,
16583 (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1, 4);
16584 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
16587 /* Floating point (COP1) */
16589 mips32_op
= OPC_LWC1
;
16592 mips32_op
= OPC_LDC1
;
16595 mips32_op
= OPC_SWC1
;
16598 mips32_op
= OPC_SDC1
;
16600 gen_cop1_ldst(ctx
, mips32_op
, rt
, rs
, imm
);
16602 case ADDIUPC
: /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
16603 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16604 /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
16605 switch ((ctx
->opcode
>> 16) & 0x1f) {
16614 gen_pcrel(ctx
, OPC_ADDIUPC
, ctx
->base
.pc_next
& ~0x3, rt
);
16617 gen_pcrel(ctx
, OPC_AUIPC
, ctx
->base
.pc_next
, rt
);
16620 gen_pcrel(ctx
, OPC_ALUIPC
, ctx
->base
.pc_next
, rt
);
16630 gen_pcrel(ctx
, R6_OPC_LWPC
, ctx
->base
.pc_next
& ~0x3, rt
);
16633 generate_exception(ctx
, EXCP_RI
);
16638 int reg
= mmreg(ZIMM(ctx
->opcode
, 23, 3));
16639 offset
= SIMM(ctx
->opcode
, 0, 23) << 2;
16641 gen_addiupc(ctx
, reg
, offset
, 0, 0);
16644 case BNVC
: /* BNEC, BNEZALC */
16645 check_insn(ctx
, ISA_MIPS_R6
);
16648 mips32_op
= OPC_BNVC
;
16649 } else if (rs
< rt
&& rs
== 0) {
16651 mips32_op
= OPC_BNEZALC
;
16654 mips32_op
= OPC_BNEC
;
16656 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
16658 case R6_BNEZC
: /* JIALC */
16659 check_insn(ctx
, ISA_MIPS_R6
);
16662 gen_compute_compact_branch(ctx
, OPC_BNEZC
, rt
, 0,
16663 sextract32(ctx
->opcode
<< 1, 0, 22));
16666 gen_compute_compact_branch(ctx
, OPC_JIALC
, 0, rs
, imm
);
16669 case R6_BEQZC
: /* JIC */
16670 check_insn(ctx
, ISA_MIPS_R6
);
16673 gen_compute_compact_branch(ctx
, OPC_BEQZC
, rt
, 0,
16674 sextract32(ctx
->opcode
<< 1, 0, 22));
16677 gen_compute_compact_branch(ctx
, OPC_JIC
, 0, rs
, imm
);
16680 case BLEZALC
: /* BGEZALC, BGEUC */
16681 check_insn(ctx
, ISA_MIPS_R6
);
16682 if (rs
== 0 && rt
!= 0) {
16684 mips32_op
= OPC_BLEZALC
;
16685 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
16687 mips32_op
= OPC_BGEZALC
;
16690 mips32_op
= OPC_BGEUC
;
16692 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
16694 case BGTZALC
: /* BLTZALC, BLTUC */
16695 check_insn(ctx
, ISA_MIPS_R6
);
16696 if (rs
== 0 && rt
!= 0) {
16698 mips32_op
= OPC_BGTZALC
;
16699 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
16701 mips32_op
= OPC_BLTZALC
;
16704 mips32_op
= OPC_BLTUC
;
16706 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
16708 /* Loads and stores */
16710 mips32_op
= OPC_LB
;
16713 mips32_op
= OPC_LBU
;
16716 mips32_op
= OPC_LH
;
16719 mips32_op
= OPC_LHU
;
16722 mips32_op
= OPC_LW
;
16724 #ifdef TARGET_MIPS64
16726 check_insn(ctx
, ISA_MIPS3
);
16727 check_mips_64(ctx
);
16728 mips32_op
= OPC_LD
;
16731 check_insn(ctx
, ISA_MIPS3
);
16732 check_mips_64(ctx
);
16733 mips32_op
= OPC_SD
;
16737 mips32_op
= OPC_SB
;
16740 mips32_op
= OPC_SH
;
16743 mips32_op
= OPC_SW
;
16746 gen_ld(ctx
, mips32_op
, rt
, rs
, imm
);
16749 gen_st(ctx
, mips32_op
, rt
, rs
, imm
);
16752 gen_reserved_instruction(ctx
);
16757 static int decode_micromips_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
16761 /* make sure instructions are on a halfword boundary */
16762 if (ctx
->base
.pc_next
& 0x1) {
16763 env
->CP0_BadVAddr
= ctx
->base
.pc_next
;
16764 generate_exception_end(ctx
, EXCP_AdEL
);
16768 op
= (ctx
->opcode
>> 10) & 0x3f;
16769 /* Enforce properly-sized instructions in a delay slot */
16770 if (ctx
->hflags
& MIPS_HFLAG_BDS_STRICT
) {
16771 switch (op
& 0x7) { /* MSB-3..MSB-5 */
16773 /* POOL32A, POOL32B, POOL32I, POOL32C */
16775 /* ADDI32, ADDIU32, ORI32, XORI32, SLTI32, SLTIU32, ANDI32, JALX32 */
16777 /* LBU32, LHU32, POOL32F, JALS32, BEQ32, BNE32, J32, JAL32 */
16779 /* SB32, SH32, ADDIUPC, SWC132, SDC132, SW32 */
16781 /* LB32, LH32, LWC132, LDC132, LW32 */
16782 if (ctx
->hflags
& MIPS_HFLAG_BDS16
) {
16783 gen_reserved_instruction(ctx
);
16788 /* POOL16A, POOL16B, POOL16C, LWGP16, POOL16F */
16790 /* LBU16, LHU16, LWSP16, LW16, SB16, SH16, SWSP16, SW16 */
16792 /* MOVE16, ANDI16, POOL16D, POOL16E, BEQZ16, BNEZ16, B16, LI16 */
16793 if (ctx
->hflags
& MIPS_HFLAG_BDS32
) {
16794 gen_reserved_instruction(ctx
);
16804 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
16805 int rs1
= mmreg(uMIPS_RS1(ctx
->opcode
));
16806 int rs2
= mmreg(uMIPS_RS2(ctx
->opcode
));
16809 switch (ctx
->opcode
& 0x1) {
16817 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16819 * In the Release 6, the register number location in
16820 * the instruction encoding has changed.
16822 gen_arith(ctx
, opc
, rs1
, rd
, rs2
);
16824 gen_arith(ctx
, opc
, rd
, rs1
, rs2
);
16830 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
16831 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
16832 int amount
= (ctx
->opcode
>> 1) & 0x7;
16834 amount
= amount
== 0 ? 8 : amount
;
16836 switch (ctx
->opcode
& 0x1) {
16845 gen_shift_imm(ctx
, opc
, rd
, rs
, amount
);
16849 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16850 gen_pool16c_r6_insn(ctx
);
16852 gen_pool16c_insn(ctx
);
16857 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
16858 int rb
= 28; /* GP */
16859 int16_t offset
= SIMM(ctx
->opcode
, 0, 7) << 2;
16861 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
16865 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16866 if (ctx
->opcode
& 1) {
16867 gen_reserved_instruction(ctx
);
16870 int enc_dest
= uMIPS_RD(ctx
->opcode
);
16871 int enc_rt
= uMIPS_RS2(ctx
->opcode
);
16872 int enc_rs
= uMIPS_RS1(ctx
->opcode
);
16873 gen_movep(ctx
, enc_dest
, enc_rt
, enc_rs
);
16878 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
16879 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
16880 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4);
16881 offset
= (offset
== 0xf ? -1 : offset
);
16883 gen_ld(ctx
, OPC_LBU
, rd
, rb
, offset
);
16888 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
16889 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
16890 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 1;
16892 gen_ld(ctx
, OPC_LHU
, rd
, rb
, offset
);
16897 int rd
= (ctx
->opcode
>> 5) & 0x1f;
16898 int rb
= 29; /* SP */
16899 int16_t offset
= ZIMM(ctx
->opcode
, 0, 5) << 2;
16901 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
16906 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
16907 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
16908 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 2;
16910 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
16915 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
16916 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
16917 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4);
16919 gen_st(ctx
, OPC_SB
, rd
, rb
, offset
);
16924 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
16925 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
16926 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 1;
16928 gen_st(ctx
, OPC_SH
, rd
, rb
, offset
);
16933 int rd
= (ctx
->opcode
>> 5) & 0x1f;
16934 int rb
= 29; /* SP */
16935 int16_t offset
= ZIMM(ctx
->opcode
, 0, 5) << 2;
16937 gen_st(ctx
, OPC_SW
, rd
, rb
, offset
);
16942 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
16943 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
16944 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 2;
16946 gen_st(ctx
, OPC_SW
, rd
, rb
, offset
);
16951 int rd
= uMIPS_RD5(ctx
->opcode
);
16952 int rs
= uMIPS_RS5(ctx
->opcode
);
16954 gen_arith(ctx
, OPC_ADDU
, rd
, rs
, 0);
16961 switch (ctx
->opcode
& 0x1) {
16971 switch (ctx
->opcode
& 0x1) {
16976 gen_addiur1sp(ctx
);
16980 case B16
: /* BC16 */
16981 gen_compute_branch(ctx
, OPC_BEQ
, 2, 0, 0,
16982 sextract32(ctx
->opcode
, 0, 10) << 1,
16983 (ctx
->insn_flags
& ISA_MIPS_R6
) ? 0 : 4);
16985 case BNEZ16
: /* BNEZC16 */
16986 case BEQZ16
: /* BEQZC16 */
16987 gen_compute_branch(ctx
, op
== BNEZ16
? OPC_BNE
: OPC_BEQ
, 2,
16988 mmreg(uMIPS_RD(ctx
->opcode
)),
16989 0, sextract32(ctx
->opcode
, 0, 7) << 1,
16990 (ctx
->insn_flags
& ISA_MIPS_R6
) ? 0 : 4);
16995 int reg
= mmreg(uMIPS_RD(ctx
->opcode
));
16996 int imm
= ZIMM(ctx
->opcode
, 0, 7);
16998 imm
= (imm
== 0x7f ? -1 : imm
);
16999 tcg_gen_movi_tl(cpu_gpr
[reg
], imm
);
17005 gen_reserved_instruction(ctx
);
17008 decode_micromips32_opc(env
, ctx
);
17021 /* MAJOR, P16, and P32 pools opcodes */
17025 NM_MOVE_BALC
= 0x02,
17033 NM_P16_SHIFT
= 0x0c,
17051 NM_P_LS_U12
= 0x21,
17061 NM_P16_ADDU
= 0x2c,
17075 NM_MOVEPREV
= 0x3f,
17078 /* POOL32A instruction pool */
17080 NM_POOL32A0
= 0x00,
17081 NM_SPECIAL2
= 0x01,
17084 NM_POOL32A5
= 0x05,
17085 NM_POOL32A7
= 0x07,
17088 /* P.GP.W instruction pool */
17090 NM_ADDIUGP_W
= 0x00,
17095 /* P48I instruction pool */
17099 NM_ADDIUGP48
= 0x02,
17100 NM_ADDIUPC48
= 0x03,
17105 /* P.U12 instruction pool */
17114 NM_ADDIUNEG
= 0x08,
17121 /* POOL32F instruction pool */
17123 NM_POOL32F_0
= 0x00,
17124 NM_POOL32F_3
= 0x03,
17125 NM_POOL32F_5
= 0x05,
17128 /* POOL32S instruction pool */
17130 NM_POOL32S_0
= 0x00,
17131 NM_POOL32S_4
= 0x04,
17134 /* P.LUI instruction pool */
17140 /* P.GP.BH instruction pool */
17145 NM_ADDIUGP_B
= 0x03,
17148 NM_P_GP_CP1
= 0x06,
17151 /* P.LS.U12 instruction pool */
17156 NM_P_PREFU12
= 0x03,
17169 /* P.LS.S9 instruction pool */
17175 NM_P_LS_UAWM
= 0x05,
17178 /* P.BAL instruction pool */
17184 /* P.J instruction pool */
17187 NM_JALRC_HB
= 0x01,
17188 NM_P_BALRSC
= 0x08,
17191 /* P.BR1 instruction pool */
17199 /* P.BR2 instruction pool */
17206 /* P.BRI instruction pool */
17218 /* P16.SHIFT instruction pool */
17224 /* POOL16C instruction pool */
17226 NM_POOL16C_0
= 0x00,
17230 /* P16.A1 instruction pool */
17232 NM_ADDIUR1SP
= 0x01,
17235 /* P16.A2 instruction pool */
17238 NM_P_ADDIURS5
= 0x01,
17241 /* P16.ADDU instruction pool */
17247 /* P16.SR instruction pool */
17250 NM_RESTORE_JRC16
= 0x01,
17253 /* P16.4X4 instruction pool */
17259 /* P16.LB instruction pool */
17266 /* P16.LH instruction pool */
17273 /* P.RI instruction pool */
17276 NM_P_SYSCALL
= 0x01,
17281 /* POOL32A0 instruction pool */
17316 NM_D_E_MT_VPE
= 0x56,
17324 /* CRC32 instruction pool */
17334 /* POOL32A5 instruction pool */
17336 NM_CMP_EQ_PH
= 0x00,
17337 NM_CMP_LT_PH
= 0x08,
17338 NM_CMP_LE_PH
= 0x10,
17339 NM_CMPGU_EQ_QB
= 0x18,
17340 NM_CMPGU_LT_QB
= 0x20,
17341 NM_CMPGU_LE_QB
= 0x28,
17342 NM_CMPGDU_EQ_QB
= 0x30,
17343 NM_CMPGDU_LT_QB
= 0x38,
17344 NM_CMPGDU_LE_QB
= 0x40,
17345 NM_CMPU_EQ_QB
= 0x48,
17346 NM_CMPU_LT_QB
= 0x50,
17347 NM_CMPU_LE_QB
= 0x58,
17348 NM_ADDQ_S_W
= 0x60,
17349 NM_SUBQ_S_W
= 0x68,
17353 NM_ADDQ_S_PH
= 0x01,
17354 NM_ADDQH_R_PH
= 0x09,
17355 NM_ADDQH_R_W
= 0x11,
17356 NM_ADDU_S_QB
= 0x19,
17357 NM_ADDU_S_PH
= 0x21,
17358 NM_ADDUH_R_QB
= 0x29,
17359 NM_SHRAV_R_PH
= 0x31,
17360 NM_SHRAV_R_QB
= 0x39,
17361 NM_SUBQ_S_PH
= 0x41,
17362 NM_SUBQH_R_PH
= 0x49,
17363 NM_SUBQH_R_W
= 0x51,
17364 NM_SUBU_S_QB
= 0x59,
17365 NM_SUBU_S_PH
= 0x61,
17366 NM_SUBUH_R_QB
= 0x69,
17367 NM_SHLLV_S_PH
= 0x71,
17368 NM_PRECR_SRA_R_PH_W
= 0x79,
17370 NM_MULEU_S_PH_QBL
= 0x12,
17371 NM_MULEU_S_PH_QBR
= 0x1a,
17372 NM_MULQ_RS_PH
= 0x22,
17373 NM_MULQ_S_PH
= 0x2a,
17374 NM_MULQ_RS_W
= 0x32,
17375 NM_MULQ_S_W
= 0x3a,
17378 NM_SHRAV_R_W
= 0x5a,
17379 NM_SHRLV_PH
= 0x62,
17380 NM_SHRLV_QB
= 0x6a,
17381 NM_SHLLV_QB
= 0x72,
17382 NM_SHLLV_S_W
= 0x7a,
17386 NM_MULEQ_S_W_PHL
= 0x04,
17387 NM_MULEQ_S_W_PHR
= 0x0c,
17389 NM_MUL_S_PH
= 0x05,
17390 NM_PRECR_QB_PH
= 0x0d,
17391 NM_PRECRQ_QB_PH
= 0x15,
17392 NM_PRECRQ_PH_W
= 0x1d,
17393 NM_PRECRQ_RS_PH_W
= 0x25,
17394 NM_PRECRQU_S_QB_PH
= 0x2d,
17395 NM_PACKRL_PH
= 0x35,
17399 NM_SHRA_R_W
= 0x5e,
17400 NM_SHRA_R_PH
= 0x66,
17401 NM_SHLL_S_PH
= 0x76,
17402 NM_SHLL_S_W
= 0x7e,
17407 /* POOL32A7 instruction pool */
17412 NM_POOL32AXF
= 0x07,
17415 /* P.SR instruction pool */
17421 /* P.SHIFT instruction pool */
17429 /* P.ROTX instruction pool */
17434 /* P.INS instruction pool */
17439 /* P.EXT instruction pool */
17444 /* POOL32F_0 (fmt) instruction pool */
17449 NM_SELEQZ_S
= 0x07,
17450 NM_SELEQZ_D
= 0x47,
17454 NM_SELNEZ_S
= 0x0f,
17455 NM_SELNEZ_D
= 0x4f,
17470 /* POOL32F_3 instruction pool */
17474 NM_MINA_FMT
= 0x04,
17475 NM_MAXA_FMT
= 0x05,
17476 NM_POOL32FXF
= 0x07,
17479 /* POOL32F_5 instruction pool */
17481 NM_CMP_CONDN_S
= 0x00,
17482 NM_CMP_CONDN_D
= 0x02,
17485 /* P.GP.LH instruction pool */
17491 /* P.GP.SH instruction pool */
17496 /* P.GP.CP1 instruction pool */
17504 /* P.LS.S0 instruction pool */
17521 NM_P_PREFS9
= 0x03,
17527 /* P.LS.S1 instruction pool */
17529 NM_ASET_ACLR
= 0x02,
17537 /* P.LS.E0 instruction pool */
17553 /* P.PREFE instruction pool */
17559 /* P.LLE instruction pool */
17565 /* P.SCE instruction pool */
17571 /* P.LS.WM instruction pool */
17577 /* P.LS.UAWM instruction pool */
17583 /* P.BR3A instruction pool */
17589 NM_BPOSGE32C
= 0x04,
17592 /* P16.RI instruction pool */
17594 NM_P16_SYSCALL
= 0x01,
17599 /* POOL16C_0 instruction pool */
17601 NM_POOL16C_00
= 0x00,
17604 /* P16.JRC instruction pool */
17610 /* P.SYSCALL instruction pool */
17616 /* P.TRAP instruction pool */
17622 /* P.CMOVE instruction pool */
17628 /* POOL32Axf instruction pool */
17630 NM_POOL32AXF_1
= 0x01,
17631 NM_POOL32AXF_2
= 0x02,
17632 NM_POOL32AXF_4
= 0x04,
17633 NM_POOL32AXF_5
= 0x05,
17634 NM_POOL32AXF_7
= 0x07,
17637 /* POOL32Axf_1 instruction pool */
17639 NM_POOL32AXF_1_0
= 0x00,
17640 NM_POOL32AXF_1_1
= 0x01,
17641 NM_POOL32AXF_1_3
= 0x03,
17642 NM_POOL32AXF_1_4
= 0x04,
17643 NM_POOL32AXF_1_5
= 0x05,
17644 NM_POOL32AXF_1_7
= 0x07,
17647 /* POOL32Axf_2 instruction pool */
17649 NM_POOL32AXF_2_0_7
= 0x00,
17650 NM_POOL32AXF_2_8_15
= 0x01,
17651 NM_POOL32AXF_2_16_23
= 0x02,
17652 NM_POOL32AXF_2_24_31
= 0x03,
17655 /* POOL32Axf_7 instruction pool */
17657 NM_SHRA_R_QB
= 0x0,
17662 /* POOL32Axf_1_0 instruction pool */
17670 /* POOL32Axf_1_1 instruction pool */
17676 /* POOL32Axf_1_3 instruction pool */
17684 /* POOL32Axf_1_4 instruction pool */
17690 /* POOL32Axf_1_5 instruction pool */
17692 NM_MAQ_S_W_PHR
= 0x0,
17693 NM_MAQ_S_W_PHL
= 0x1,
17694 NM_MAQ_SA_W_PHR
= 0x2,
17695 NM_MAQ_SA_W_PHL
= 0x3,
17698 /* POOL32Axf_1_7 instruction pool */
17702 NM_EXTR_RS_W
= 0x2,
17706 /* POOL32Axf_2_0_7 instruction pool */
17709 NM_DPAQ_S_W_PH
= 0x1,
17711 NM_DPSQ_S_W_PH
= 0x3,
17718 /* POOL32Axf_2_8_15 instruction pool */
17720 NM_DPAX_W_PH
= 0x0,
17721 NM_DPAQ_SA_L_W
= 0x1,
17722 NM_DPSX_W_PH
= 0x2,
17723 NM_DPSQ_SA_L_W
= 0x3,
17726 NM_EXTRV_R_W
= 0x7,
17729 /* POOL32Axf_2_16_23 instruction pool */
17731 NM_DPAU_H_QBL
= 0x0,
17732 NM_DPAQX_S_W_PH
= 0x1,
17733 NM_DPSU_H_QBL
= 0x2,
17734 NM_DPSQX_S_W_PH
= 0x3,
17737 NM_MULSA_W_PH
= 0x6,
17738 NM_EXTRV_RS_W
= 0x7,
17741 /* POOL32Axf_2_24_31 instruction pool */
17743 NM_DPAU_H_QBR
= 0x0,
17744 NM_DPAQX_SA_W_PH
= 0x1,
17745 NM_DPSU_H_QBR
= 0x2,
17746 NM_DPSQX_SA_W_PH
= 0x3,
17749 NM_MULSAQ_S_W_PH
= 0x6,
17750 NM_EXTRV_S_H
= 0x7,
17753 /* POOL32Axf_{4, 5} instruction pool */
17772 /* nanoMIPS DSP instructions */
17773 NM_ABSQ_S_QB
= 0x00,
17774 NM_ABSQ_S_PH
= 0x08,
17775 NM_ABSQ_S_W
= 0x10,
17776 NM_PRECEQ_W_PHL
= 0x28,
17777 NM_PRECEQ_W_PHR
= 0x30,
17778 NM_PRECEQU_PH_QBL
= 0x38,
17779 NM_PRECEQU_PH_QBR
= 0x48,
17780 NM_PRECEU_PH_QBL
= 0x58,
17781 NM_PRECEU_PH_QBR
= 0x68,
17782 NM_PRECEQU_PH_QBLA
= 0x39,
17783 NM_PRECEQU_PH_QBRA
= 0x49,
17784 NM_PRECEU_PH_QBLA
= 0x59,
17785 NM_PRECEU_PH_QBRA
= 0x69,
17786 NM_REPLV_PH
= 0x01,
17787 NM_REPLV_QB
= 0x09,
17790 NM_RADDU_W_QB
= 0x78,
17796 /* PP.SR instruction pool */
17800 NM_RESTORE_JRC
= 0x03,
17803 /* P.SR.F instruction pool */
17806 NM_RESTOREF
= 0x01,
17809 /* P16.SYSCALL instruction pool */
17811 NM_SYSCALL16
= 0x00,
17812 NM_HYPCALL16
= 0x01,
17815 /* POOL16C_00 instruction pool */
17823 /* PP.LSX and PP.LSXS instruction pool */
17861 /* ERETx instruction pool */
17867 /* POOL32FxF_{0, 1} insturction pool */
17876 NM_CVT_S_PL
= 0x84,
17877 NM_CVT_S_PU
= 0xa4,
17879 NM_CVT_L_S
= 0x004,
17880 NM_CVT_L_D
= 0x104,
17881 NM_CVT_W_S
= 0x024,
17882 NM_CVT_W_D
= 0x124,
17884 NM_RSQRT_S
= 0x008,
17885 NM_RSQRT_D
= 0x108,
17890 NM_RECIP_S
= 0x048,
17891 NM_RECIP_D
= 0x148,
17893 NM_FLOOR_L_S
= 0x00c,
17894 NM_FLOOR_L_D
= 0x10c,
17896 NM_FLOOR_W_S
= 0x02c,
17897 NM_FLOOR_W_D
= 0x12c,
17899 NM_CEIL_L_S
= 0x04c,
17900 NM_CEIL_L_D
= 0x14c,
17901 NM_CEIL_W_S
= 0x06c,
17902 NM_CEIL_W_D
= 0x16c,
17903 NM_TRUNC_L_S
= 0x08c,
17904 NM_TRUNC_L_D
= 0x18c,
17905 NM_TRUNC_W_S
= 0x0ac,
17906 NM_TRUNC_W_D
= 0x1ac,
17907 NM_ROUND_L_S
= 0x0cc,
17908 NM_ROUND_L_D
= 0x1cc,
17909 NM_ROUND_W_S
= 0x0ec,
17910 NM_ROUND_W_D
= 0x1ec,
17918 NM_CVT_D_S
= 0x04d,
17919 NM_CVT_D_W
= 0x0cd,
17920 NM_CVT_D_L
= 0x14d,
17921 NM_CVT_S_D
= 0x06d,
17922 NM_CVT_S_W
= 0x0ed,
17923 NM_CVT_S_L
= 0x16d,
17926 /* P.LL instruction pool */
17932 /* P.SC instruction pool */
17938 /* P.DVP instruction pool */
17947 * nanoMIPS decoding engine
17952 /* extraction utilities */
17954 #define NANOMIPS_EXTRACT_RT3(op) ((op >> 7) & 0x7)
17955 #define NANOMIPS_EXTRACT_RS3(op) ((op >> 4) & 0x7)
17956 #define NANOMIPS_EXTRACT_RD3(op) ((op >> 1) & 0x7)
17957 #define NANOMIPS_EXTRACT_RD5(op) ((op >> 5) & 0x1f)
17958 #define NANOMIPS_EXTRACT_RS5(op) (op & 0x1f)
17960 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3'). */
17961 static inline int decode_gpr_gpr3(int r
)
17963 static const int map
[] = { 16, 17, 18, 19, 4, 5, 6, 7 };
17965 return map
[r
& 0x7];
17968 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3.src.store'). */
17969 static inline int decode_gpr_gpr3_src_store(int r
)
17971 static const int map
[] = { 0, 17, 18, 19, 4, 5, 6, 7 };
17973 return map
[r
& 0x7];
17976 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4'). */
17977 static inline int decode_gpr_gpr4(int r
)
17979 static const int map
[] = { 8, 9, 10, 11, 4, 5, 6, 7,
17980 16, 17, 18, 19, 20, 21, 22, 23 };
17982 return map
[r
& 0xf];
17985 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4.zero'). */
17986 static inline int decode_gpr_gpr4_zero(int r
)
17988 static const int map
[] = { 8, 9, 10, 0, 4, 5, 6, 7,
17989 16, 17, 18, 19, 20, 21, 22, 23 };
17991 return map
[r
& 0xf];
17995 static void gen_adjust_sp(DisasContext
*ctx
, int u
)
17997 gen_op_addr_addi(ctx
, cpu_gpr
[29], cpu_gpr
[29], u
);
18000 static void gen_save(DisasContext
*ctx
, uint8_t rt
, uint8_t count
,
18001 uint8_t gp
, uint16_t u
)
18004 TCGv va
= tcg_temp_new();
18005 TCGv t0
= tcg_temp_new();
18007 while (counter
!= count
) {
18008 bool use_gp
= gp
&& (counter
== count
- 1);
18009 int this_rt
= use_gp
? 28 : (rt
& 0x10) | ((rt
+ counter
) & 0x1f);
18010 int this_offset
= -((counter
+ 1) << 2);
18011 gen_base_offset_addr(ctx
, va
, 29, this_offset
);
18012 gen_load_gpr(t0
, this_rt
);
18013 tcg_gen_qemu_st_tl(t0
, va
, ctx
->mem_idx
,
18014 (MO_TEUL
| ctx
->default_tcg_memop_mask
));
18018 /* adjust stack pointer */
18019 gen_adjust_sp(ctx
, -u
);
18025 static void gen_restore(DisasContext
*ctx
, uint8_t rt
, uint8_t count
,
18026 uint8_t gp
, uint16_t u
)
18029 TCGv va
= tcg_temp_new();
18030 TCGv t0
= tcg_temp_new();
18032 while (counter
!= count
) {
18033 bool use_gp
= gp
&& (counter
== count
- 1);
18034 int this_rt
= use_gp
? 28 : (rt
& 0x10) | ((rt
+ counter
) & 0x1f);
18035 int this_offset
= u
- ((counter
+ 1) << 2);
18036 gen_base_offset_addr(ctx
, va
, 29, this_offset
);
18037 tcg_gen_qemu_ld_tl(t0
, va
, ctx
->mem_idx
, MO_TESL
|
18038 ctx
->default_tcg_memop_mask
);
18039 tcg_gen_ext32s_tl(t0
, t0
);
18040 gen_store_gpr(t0
, this_rt
);
18044 /* adjust stack pointer */
18045 gen_adjust_sp(ctx
, u
);
18051 static void gen_pool16c_nanomips_insn(DisasContext
*ctx
)
18053 int rt
= decode_gpr_gpr3(NANOMIPS_EXTRACT_RT3(ctx
->opcode
));
18054 int rs
= decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx
->opcode
));
18056 switch (extract32(ctx
->opcode
, 2, 2)) {
18058 gen_logic(ctx
, OPC_NOR
, rt
, rs
, 0);
18061 gen_logic(ctx
, OPC_AND
, rt
, rt
, rs
);
18064 gen_logic(ctx
, OPC_XOR
, rt
, rt
, rs
);
18067 gen_logic(ctx
, OPC_OR
, rt
, rt
, rs
);
18072 static void gen_pool32a0_nanomips_insn(CPUMIPSState
*env
, DisasContext
*ctx
)
18074 int rt
= extract32(ctx
->opcode
, 21, 5);
18075 int rs
= extract32(ctx
->opcode
, 16, 5);
18076 int rd
= extract32(ctx
->opcode
, 11, 5);
18078 switch (extract32(ctx
->opcode
, 3, 7)) {
18080 switch (extract32(ctx
->opcode
, 10, 1)) {
18083 gen_trap(ctx
, OPC_TEQ
, rs
, rt
, -1);
18087 gen_trap(ctx
, OPC_TNE
, rs
, rt
, -1);
18093 gen_rdhwr(ctx
, rt
, rs
, extract32(ctx
->opcode
, 11, 3));
18097 gen_bshfl(ctx
, OPC_SEB
, rs
, rt
);
18100 gen_bshfl(ctx
, OPC_SEH
, rs
, rt
);
18103 gen_shift(ctx
, OPC_SLLV
, rd
, rt
, rs
);
18106 gen_shift(ctx
, OPC_SRLV
, rd
, rt
, rs
);
18109 gen_shift(ctx
, OPC_SRAV
, rd
, rt
, rs
);
18112 gen_shift(ctx
, OPC_ROTRV
, rd
, rt
, rs
);
18115 gen_arith(ctx
, OPC_ADD
, rd
, rs
, rt
);
18118 gen_arith(ctx
, OPC_ADDU
, rd
, rs
, rt
);
18122 gen_arith(ctx
, OPC_SUB
, rd
, rs
, rt
);
18125 gen_arith(ctx
, OPC_SUBU
, rd
, rs
, rt
);
18128 switch (extract32(ctx
->opcode
, 10, 1)) {
18130 gen_cond_move(ctx
, OPC_MOVZ
, rd
, rs
, rt
);
18133 gen_cond_move(ctx
, OPC_MOVN
, rd
, rs
, rt
);
18138 gen_logic(ctx
, OPC_AND
, rd
, rs
, rt
);
18141 gen_logic(ctx
, OPC_OR
, rd
, rs
, rt
);
18144 gen_logic(ctx
, OPC_NOR
, rd
, rs
, rt
);
18147 gen_logic(ctx
, OPC_XOR
, rd
, rs
, rt
);
18150 gen_slt(ctx
, OPC_SLT
, rd
, rs
, rt
);
18155 #ifndef CONFIG_USER_ONLY
18156 TCGv t0
= tcg_temp_new();
18157 switch (extract32(ctx
->opcode
, 10, 1)) {
18160 check_cp0_enabled(ctx
);
18161 gen_helper_dvp(t0
, cpu_env
);
18162 gen_store_gpr(t0
, rt
);
18167 check_cp0_enabled(ctx
);
18168 gen_helper_evp(t0
, cpu_env
);
18169 gen_store_gpr(t0
, rt
);
18176 gen_slt(ctx
, OPC_SLTU
, rd
, rs
, rt
);
18181 TCGv t0
= tcg_temp_new();
18182 TCGv t1
= tcg_temp_new();
18183 TCGv t2
= tcg_temp_new();
18185 gen_load_gpr(t1
, rs
);
18186 gen_load_gpr(t2
, rt
);
18187 tcg_gen_add_tl(t0
, t1
, t2
);
18188 tcg_gen_ext32s_tl(t0
, t0
);
18189 tcg_gen_xor_tl(t1
, t1
, t2
);
18190 tcg_gen_xor_tl(t2
, t0
, t2
);
18191 tcg_gen_andc_tl(t1
, t2
, t1
);
18193 /* operands of same sign, result different sign */
18194 tcg_gen_setcondi_tl(TCG_COND_LT
, t0
, t1
, 0);
18195 gen_store_gpr(t0
, rd
);
18203 gen_r6_muldiv(ctx
, R6_OPC_MUL
, rd
, rs
, rt
);
18206 gen_r6_muldiv(ctx
, R6_OPC_MUH
, rd
, rs
, rt
);
18209 gen_r6_muldiv(ctx
, R6_OPC_MULU
, rd
, rs
, rt
);
18212 gen_r6_muldiv(ctx
, R6_OPC_MUHU
, rd
, rs
, rt
);
18215 gen_r6_muldiv(ctx
, R6_OPC_DIV
, rd
, rs
, rt
);
18218 gen_r6_muldiv(ctx
, R6_OPC_MOD
, rd
, rs
, rt
);
18221 gen_r6_muldiv(ctx
, R6_OPC_DIVU
, rd
, rs
, rt
);
18224 gen_r6_muldiv(ctx
, R6_OPC_MODU
, rd
, rs
, rt
);
18226 #ifndef CONFIG_USER_ONLY
18228 check_cp0_enabled(ctx
);
18230 /* Treat as NOP. */
18233 gen_mfc0(ctx
, cpu_gpr
[rt
], rs
, extract32(ctx
->opcode
, 11, 3));
18236 check_cp0_enabled(ctx
);
18238 TCGv t0
= tcg_temp_new();
18240 gen_load_gpr(t0
, rt
);
18241 gen_mtc0(ctx
, t0
, rs
, extract32(ctx
->opcode
, 11, 3));
18245 case NM_D_E_MT_VPE
:
18247 uint8_t sc
= extract32(ctx
->opcode
, 10, 1);
18248 TCGv t0
= tcg_temp_new();
18255 gen_helper_dmt(t0
);
18256 gen_store_gpr(t0
, rt
);
18257 } else if (rs
== 0) {
18260 gen_helper_dvpe(t0
, cpu_env
);
18261 gen_store_gpr(t0
, rt
);
18263 gen_reserved_instruction(ctx
);
18270 gen_helper_emt(t0
);
18271 gen_store_gpr(t0
, rt
);
18272 } else if (rs
== 0) {
18275 gen_helper_evpe(t0
, cpu_env
);
18276 gen_store_gpr(t0
, rt
);
18278 gen_reserved_instruction(ctx
);
18289 TCGv t0
= tcg_temp_new();
18290 TCGv t1
= tcg_temp_new();
18292 gen_load_gpr(t0
, rt
);
18293 gen_load_gpr(t1
, rs
);
18294 gen_helper_fork(t0
, t1
);
18301 check_cp0_enabled(ctx
);
18303 /* Treat as NOP. */
18306 gen_mftr(env
, ctx
, rs
, rt
, extract32(ctx
->opcode
, 10, 1),
18307 extract32(ctx
->opcode
, 11, 5), extract32(ctx
->opcode
, 3, 1));
18311 check_cp0_enabled(ctx
);
18312 gen_mttr(env
, ctx
, rs
, rt
, extract32(ctx
->opcode
, 10, 1),
18313 extract32(ctx
->opcode
, 11, 5), extract32(ctx
->opcode
, 3, 1));
18318 TCGv t0
= tcg_temp_new();
18320 gen_load_gpr(t0
, rs
);
18321 gen_helper_yield(t0
, cpu_env
, t0
);
18322 gen_store_gpr(t0
, rt
);
18328 gen_reserved_instruction(ctx
);
18334 static void gen_pool32axf_1_5_nanomips_insn(DisasContext
*ctx
, uint32_t opc
,
18335 int ret
, int v1
, int v2
)
18341 t0
= tcg_temp_new_i32();
18343 v0_t
= tcg_temp_new();
18344 v1_t
= tcg_temp_new();
18346 tcg_gen_movi_i32(t0
, v2
>> 3);
18348 gen_load_gpr(v0_t
, ret
);
18349 gen_load_gpr(v1_t
, v1
);
18352 case NM_MAQ_S_W_PHR
:
18354 gen_helper_maq_s_w_phr(t0
, v1_t
, v0_t
, cpu_env
);
18356 case NM_MAQ_S_W_PHL
:
18358 gen_helper_maq_s_w_phl(t0
, v1_t
, v0_t
, cpu_env
);
18360 case NM_MAQ_SA_W_PHR
:
18362 gen_helper_maq_sa_w_phr(t0
, v1_t
, v0_t
, cpu_env
);
18364 case NM_MAQ_SA_W_PHL
:
18366 gen_helper_maq_sa_w_phl(t0
, v1_t
, v0_t
, cpu_env
);
18369 gen_reserved_instruction(ctx
);
18373 tcg_temp_free_i32(t0
);
18375 tcg_temp_free(v0_t
);
18376 tcg_temp_free(v1_t
);
18380 static void gen_pool32axf_1_nanomips_insn(DisasContext
*ctx
, uint32_t opc
,
18381 int ret
, int v1
, int v2
)
18384 TCGv t0
= tcg_temp_new();
18385 TCGv t1
= tcg_temp_new();
18386 TCGv v0_t
= tcg_temp_new();
18388 gen_load_gpr(v0_t
, v1
);
18391 case NM_POOL32AXF_1_0
:
18393 switch (extract32(ctx
->opcode
, 12, 2)) {
18395 gen_HILO(ctx
, OPC_MFHI
, v2
>> 3, ret
);
18398 gen_HILO(ctx
, OPC_MFLO
, v2
>> 3, ret
);
18401 gen_HILO(ctx
, OPC_MTHI
, v2
>> 3, v1
);
18404 gen_HILO(ctx
, OPC_MTLO
, v2
>> 3, v1
);
18408 case NM_POOL32AXF_1_1
:
18410 switch (extract32(ctx
->opcode
, 12, 2)) {
18412 tcg_gen_movi_tl(t0
, v2
);
18413 gen_helper_mthlip(t0
, v0_t
, cpu_env
);
18416 tcg_gen_movi_tl(t0
, v2
>> 3);
18417 gen_helper_shilo(t0
, v0_t
, cpu_env
);
18420 gen_reserved_instruction(ctx
);
18424 case NM_POOL32AXF_1_3
:
18426 imm
= extract32(ctx
->opcode
, 14, 7);
18427 switch (extract32(ctx
->opcode
, 12, 2)) {
18429 tcg_gen_movi_tl(t0
, imm
);
18430 gen_helper_rddsp(t0
, t0
, cpu_env
);
18431 gen_store_gpr(t0
, ret
);
18434 gen_load_gpr(t0
, ret
);
18435 tcg_gen_movi_tl(t1
, imm
);
18436 gen_helper_wrdsp(t0
, t1
, cpu_env
);
18439 tcg_gen_movi_tl(t0
, v2
>> 3);
18440 tcg_gen_movi_tl(t1
, v1
);
18441 gen_helper_extp(t0
, t0
, t1
, cpu_env
);
18442 gen_store_gpr(t0
, ret
);
18445 tcg_gen_movi_tl(t0
, v2
>> 3);
18446 tcg_gen_movi_tl(t1
, v1
);
18447 gen_helper_extpdp(t0
, t0
, t1
, cpu_env
);
18448 gen_store_gpr(t0
, ret
);
18452 case NM_POOL32AXF_1_4
:
18454 tcg_gen_movi_tl(t0
, v2
>> 2);
18455 switch (extract32(ctx
->opcode
, 12, 1)) {
18457 gen_helper_shll_qb(t0
, t0
, v0_t
, cpu_env
);
18458 gen_store_gpr(t0
, ret
);
18461 gen_helper_shrl_qb(t0
, t0
, v0_t
);
18462 gen_store_gpr(t0
, ret
);
18466 case NM_POOL32AXF_1_5
:
18467 opc
= extract32(ctx
->opcode
, 12, 2);
18468 gen_pool32axf_1_5_nanomips_insn(ctx
, opc
, ret
, v1
, v2
);
18470 case NM_POOL32AXF_1_7
:
18472 tcg_gen_movi_tl(t0
, v2
>> 3);
18473 tcg_gen_movi_tl(t1
, v1
);
18474 switch (extract32(ctx
->opcode
, 12, 2)) {
18476 gen_helper_extr_w(t0
, t0
, t1
, cpu_env
);
18477 gen_store_gpr(t0
, ret
);
18480 gen_helper_extr_r_w(t0
, t0
, t1
, cpu_env
);
18481 gen_store_gpr(t0
, ret
);
18484 gen_helper_extr_rs_w(t0
, t0
, t1
, cpu_env
);
18485 gen_store_gpr(t0
, ret
);
18488 gen_helper_extr_s_h(t0
, t0
, t1
, cpu_env
);
18489 gen_store_gpr(t0
, ret
);
18494 gen_reserved_instruction(ctx
);
18500 tcg_temp_free(v0_t
);
18503 static void gen_pool32axf_2_multiply(DisasContext
*ctx
, uint32_t opc
,
18504 TCGv v0
, TCGv v1
, int rd
)
18508 t0
= tcg_temp_new_i32();
18510 tcg_gen_movi_i32(t0
, rd
>> 3);
18513 case NM_POOL32AXF_2_0_7
:
18514 switch (extract32(ctx
->opcode
, 9, 3)) {
18517 gen_helper_dpa_w_ph(t0
, v1
, v0
, cpu_env
);
18519 case NM_DPAQ_S_W_PH
:
18521 gen_helper_dpaq_s_w_ph(t0
, v1
, v0
, cpu_env
);
18525 gen_helper_dps_w_ph(t0
, v1
, v0
, cpu_env
);
18527 case NM_DPSQ_S_W_PH
:
18529 gen_helper_dpsq_s_w_ph(t0
, v1
, v0
, cpu_env
);
18532 gen_reserved_instruction(ctx
);
18536 case NM_POOL32AXF_2_8_15
:
18537 switch (extract32(ctx
->opcode
, 9, 3)) {
18540 gen_helper_dpax_w_ph(t0
, v0
, v1
, cpu_env
);
18542 case NM_DPAQ_SA_L_W
:
18544 gen_helper_dpaq_sa_l_w(t0
, v0
, v1
, cpu_env
);
18548 gen_helper_dpsx_w_ph(t0
, v0
, v1
, cpu_env
);
18550 case NM_DPSQ_SA_L_W
:
18552 gen_helper_dpsq_sa_l_w(t0
, v0
, v1
, cpu_env
);
18555 gen_reserved_instruction(ctx
);
18559 case NM_POOL32AXF_2_16_23
:
18560 switch (extract32(ctx
->opcode
, 9, 3)) {
18561 case NM_DPAU_H_QBL
:
18563 gen_helper_dpau_h_qbl(t0
, v0
, v1
, cpu_env
);
18565 case NM_DPAQX_S_W_PH
:
18567 gen_helper_dpaqx_s_w_ph(t0
, v0
, v1
, cpu_env
);
18569 case NM_DPSU_H_QBL
:
18571 gen_helper_dpsu_h_qbl(t0
, v0
, v1
, cpu_env
);
18573 case NM_DPSQX_S_W_PH
:
18575 gen_helper_dpsqx_s_w_ph(t0
, v0
, v1
, cpu_env
);
18577 case NM_MULSA_W_PH
:
18579 gen_helper_mulsa_w_ph(t0
, v0
, v1
, cpu_env
);
18582 gen_reserved_instruction(ctx
);
18586 case NM_POOL32AXF_2_24_31
:
18587 switch (extract32(ctx
->opcode
, 9, 3)) {
18588 case NM_DPAU_H_QBR
:
18590 gen_helper_dpau_h_qbr(t0
, v1
, v0
, cpu_env
);
18592 case NM_DPAQX_SA_W_PH
:
18594 gen_helper_dpaqx_sa_w_ph(t0
, v1
, v0
, cpu_env
);
18596 case NM_DPSU_H_QBR
:
18598 gen_helper_dpsu_h_qbr(t0
, v1
, v0
, cpu_env
);
18600 case NM_DPSQX_SA_W_PH
:
18602 gen_helper_dpsqx_sa_w_ph(t0
, v1
, v0
, cpu_env
);
18604 case NM_MULSAQ_S_W_PH
:
18606 gen_helper_mulsaq_s_w_ph(t0
, v1
, v0
, cpu_env
);
18609 gen_reserved_instruction(ctx
);
18614 gen_reserved_instruction(ctx
);
18618 tcg_temp_free_i32(t0
);
18621 static void gen_pool32axf_2_nanomips_insn(DisasContext
*ctx
, uint32_t opc
,
18622 int rt
, int rs
, int rd
)
18625 TCGv t0
= tcg_temp_new();
18626 TCGv t1
= tcg_temp_new();
18627 TCGv v0_t
= tcg_temp_new();
18628 TCGv v1_t
= tcg_temp_new();
18630 gen_load_gpr(v0_t
, rt
);
18631 gen_load_gpr(v1_t
, rs
);
18634 case NM_POOL32AXF_2_0_7
:
18635 switch (extract32(ctx
->opcode
, 9, 3)) {
18637 case NM_DPAQ_S_W_PH
:
18639 case NM_DPSQ_S_W_PH
:
18640 gen_pool32axf_2_multiply(ctx
, opc
, v0_t
, v1_t
, rd
);
18645 gen_load_gpr(t0
, rs
);
18647 if (rd
!= 0 && rd
!= 2) {
18648 tcg_gen_shli_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], 8 * rd
);
18649 tcg_gen_ext32u_tl(t0
, t0
);
18650 tcg_gen_shri_tl(t0
, t0
, 8 * (4 - rd
));
18651 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
18653 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
18659 int acc
= extract32(ctx
->opcode
, 14, 2);
18660 TCGv_i64 t2
= tcg_temp_new_i64();
18661 TCGv_i64 t3
= tcg_temp_new_i64();
18663 gen_load_gpr(t0
, rt
);
18664 gen_load_gpr(t1
, rs
);
18665 tcg_gen_ext_tl_i64(t2
, t0
);
18666 tcg_gen_ext_tl_i64(t3
, t1
);
18667 tcg_gen_mul_i64(t2
, t2
, t3
);
18668 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
18669 tcg_gen_add_i64(t2
, t2
, t3
);
18670 tcg_temp_free_i64(t3
);
18671 gen_move_low32(cpu_LO
[acc
], t2
);
18672 gen_move_high32(cpu_HI
[acc
], t2
);
18673 tcg_temp_free_i64(t2
);
18679 int acc
= extract32(ctx
->opcode
, 14, 2);
18680 TCGv_i32 t2
= tcg_temp_new_i32();
18681 TCGv_i32 t3
= tcg_temp_new_i32();
18683 gen_load_gpr(t0
, rs
);
18684 gen_load_gpr(t1
, rt
);
18685 tcg_gen_trunc_tl_i32(t2
, t0
);
18686 tcg_gen_trunc_tl_i32(t3
, t1
);
18687 tcg_gen_muls2_i32(t2
, t3
, t2
, t3
);
18688 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
18689 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
18690 tcg_temp_free_i32(t2
);
18691 tcg_temp_free_i32(t3
);
18696 gen_load_gpr(v1_t
, rs
);
18697 tcg_gen_movi_tl(t0
, rd
>> 3);
18698 gen_helper_extr_w(t0
, t0
, v1_t
, cpu_env
);
18699 gen_store_gpr(t0
, ret
);
18703 case NM_POOL32AXF_2_8_15
:
18704 switch (extract32(ctx
->opcode
, 9, 3)) {
18706 case NM_DPAQ_SA_L_W
:
18708 case NM_DPSQ_SA_L_W
:
18709 gen_pool32axf_2_multiply(ctx
, opc
, v0_t
, v1_t
, rd
);
18714 int acc
= extract32(ctx
->opcode
, 14, 2);
18715 TCGv_i64 t2
= tcg_temp_new_i64();
18716 TCGv_i64 t3
= tcg_temp_new_i64();
18718 gen_load_gpr(t0
, rs
);
18719 gen_load_gpr(t1
, rt
);
18720 tcg_gen_ext32u_tl(t0
, t0
);
18721 tcg_gen_ext32u_tl(t1
, t1
);
18722 tcg_gen_extu_tl_i64(t2
, t0
);
18723 tcg_gen_extu_tl_i64(t3
, t1
);
18724 tcg_gen_mul_i64(t2
, t2
, t3
);
18725 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
18726 tcg_gen_add_i64(t2
, t2
, t3
);
18727 tcg_temp_free_i64(t3
);
18728 gen_move_low32(cpu_LO
[acc
], t2
);
18729 gen_move_high32(cpu_HI
[acc
], t2
);
18730 tcg_temp_free_i64(t2
);
18736 int acc
= extract32(ctx
->opcode
, 14, 2);
18737 TCGv_i32 t2
= tcg_temp_new_i32();
18738 TCGv_i32 t3
= tcg_temp_new_i32();
18740 gen_load_gpr(t0
, rs
);
18741 gen_load_gpr(t1
, rt
);
18742 tcg_gen_trunc_tl_i32(t2
, t0
);
18743 tcg_gen_trunc_tl_i32(t3
, t1
);
18744 tcg_gen_mulu2_i32(t2
, t3
, t2
, t3
);
18745 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
18746 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
18747 tcg_temp_free_i32(t2
);
18748 tcg_temp_free_i32(t3
);
18753 tcg_gen_movi_tl(t0
, rd
>> 3);
18754 gen_helper_extr_r_w(t0
, t0
, v1_t
, cpu_env
);
18755 gen_store_gpr(t0
, ret
);
18758 gen_reserved_instruction(ctx
);
18762 case NM_POOL32AXF_2_16_23
:
18763 switch (extract32(ctx
->opcode
, 9, 3)) {
18764 case NM_DPAU_H_QBL
:
18765 case NM_DPAQX_S_W_PH
:
18766 case NM_DPSU_H_QBL
:
18767 case NM_DPSQX_S_W_PH
:
18768 case NM_MULSA_W_PH
:
18769 gen_pool32axf_2_multiply(ctx
, opc
, v0_t
, v1_t
, rd
);
18773 tcg_gen_movi_tl(t0
, rd
>> 3);
18774 gen_helper_extp(t0
, t0
, v1_t
, cpu_env
);
18775 gen_store_gpr(t0
, ret
);
18780 int acc
= extract32(ctx
->opcode
, 14, 2);
18781 TCGv_i64 t2
= tcg_temp_new_i64();
18782 TCGv_i64 t3
= tcg_temp_new_i64();
18784 gen_load_gpr(t0
, rs
);
18785 gen_load_gpr(t1
, rt
);
18786 tcg_gen_ext_tl_i64(t2
, t0
);
18787 tcg_gen_ext_tl_i64(t3
, t1
);
18788 tcg_gen_mul_i64(t2
, t2
, t3
);
18789 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
18790 tcg_gen_sub_i64(t2
, t3
, t2
);
18791 tcg_temp_free_i64(t3
);
18792 gen_move_low32(cpu_LO
[acc
], t2
);
18793 gen_move_high32(cpu_HI
[acc
], t2
);
18794 tcg_temp_free_i64(t2
);
18797 case NM_EXTRV_RS_W
:
18799 tcg_gen_movi_tl(t0
, rd
>> 3);
18800 gen_helper_extr_rs_w(t0
, t0
, v1_t
, cpu_env
);
18801 gen_store_gpr(t0
, ret
);
18805 case NM_POOL32AXF_2_24_31
:
18806 switch (extract32(ctx
->opcode
, 9, 3)) {
18807 case NM_DPAU_H_QBR
:
18808 case NM_DPAQX_SA_W_PH
:
18809 case NM_DPSU_H_QBR
:
18810 case NM_DPSQX_SA_W_PH
:
18811 case NM_MULSAQ_S_W_PH
:
18812 gen_pool32axf_2_multiply(ctx
, opc
, v0_t
, v1_t
, rd
);
18816 tcg_gen_movi_tl(t0
, rd
>> 3);
18817 gen_helper_extpdp(t0
, t0
, v1_t
, cpu_env
);
18818 gen_store_gpr(t0
, ret
);
18823 int acc
= extract32(ctx
->opcode
, 14, 2);
18824 TCGv_i64 t2
= tcg_temp_new_i64();
18825 TCGv_i64 t3
= tcg_temp_new_i64();
18827 gen_load_gpr(t0
, rs
);
18828 gen_load_gpr(t1
, rt
);
18829 tcg_gen_ext32u_tl(t0
, t0
);
18830 tcg_gen_ext32u_tl(t1
, t1
);
18831 tcg_gen_extu_tl_i64(t2
, t0
);
18832 tcg_gen_extu_tl_i64(t3
, t1
);
18833 tcg_gen_mul_i64(t2
, t2
, t3
);
18834 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
18835 tcg_gen_sub_i64(t2
, t3
, t2
);
18836 tcg_temp_free_i64(t3
);
18837 gen_move_low32(cpu_LO
[acc
], t2
);
18838 gen_move_high32(cpu_HI
[acc
], t2
);
18839 tcg_temp_free_i64(t2
);
18844 tcg_gen_movi_tl(t0
, rd
>> 3);
18845 gen_helper_extr_s_h(t0
, t0
, v0_t
, cpu_env
);
18846 gen_store_gpr(t0
, ret
);
18851 gen_reserved_instruction(ctx
);
18858 tcg_temp_free(v0_t
);
18859 tcg_temp_free(v1_t
);
18862 static void gen_pool32axf_4_nanomips_insn(DisasContext
*ctx
, uint32_t opc
,
18866 TCGv t0
= tcg_temp_new();
18867 TCGv v0_t
= tcg_temp_new();
18869 gen_load_gpr(v0_t
, rs
);
18874 gen_helper_absq_s_qb(v0_t
, v0_t
, cpu_env
);
18875 gen_store_gpr(v0_t
, ret
);
18879 gen_helper_absq_s_ph(v0_t
, v0_t
, cpu_env
);
18880 gen_store_gpr(v0_t
, ret
);
18884 gen_helper_absq_s_w(v0_t
, v0_t
, cpu_env
);
18885 gen_store_gpr(v0_t
, ret
);
18887 case NM_PRECEQ_W_PHL
:
18889 tcg_gen_andi_tl(v0_t
, v0_t
, 0xFFFF0000);
18890 tcg_gen_ext32s_tl(v0_t
, v0_t
);
18891 gen_store_gpr(v0_t
, ret
);
18893 case NM_PRECEQ_W_PHR
:
18895 tcg_gen_andi_tl(v0_t
, v0_t
, 0x0000FFFF);
18896 tcg_gen_shli_tl(v0_t
, v0_t
, 16);
18897 tcg_gen_ext32s_tl(v0_t
, v0_t
);
18898 gen_store_gpr(v0_t
, ret
);
18900 case NM_PRECEQU_PH_QBL
:
18902 gen_helper_precequ_ph_qbl(v0_t
, v0_t
);
18903 gen_store_gpr(v0_t
, ret
);
18905 case NM_PRECEQU_PH_QBR
:
18907 gen_helper_precequ_ph_qbr(v0_t
, v0_t
);
18908 gen_store_gpr(v0_t
, ret
);
18910 case NM_PRECEQU_PH_QBLA
:
18912 gen_helper_precequ_ph_qbla(v0_t
, v0_t
);
18913 gen_store_gpr(v0_t
, ret
);
18915 case NM_PRECEQU_PH_QBRA
:
18917 gen_helper_precequ_ph_qbra(v0_t
, v0_t
);
18918 gen_store_gpr(v0_t
, ret
);
18920 case NM_PRECEU_PH_QBL
:
18922 gen_helper_preceu_ph_qbl(v0_t
, v0_t
);
18923 gen_store_gpr(v0_t
, ret
);
18925 case NM_PRECEU_PH_QBR
:
18927 gen_helper_preceu_ph_qbr(v0_t
, v0_t
);
18928 gen_store_gpr(v0_t
, ret
);
18930 case NM_PRECEU_PH_QBLA
:
18932 gen_helper_preceu_ph_qbla(v0_t
, v0_t
);
18933 gen_store_gpr(v0_t
, ret
);
18935 case NM_PRECEU_PH_QBRA
:
18937 gen_helper_preceu_ph_qbra(v0_t
, v0_t
);
18938 gen_store_gpr(v0_t
, ret
);
18942 tcg_gen_ext16u_tl(v0_t
, v0_t
);
18943 tcg_gen_shli_tl(t0
, v0_t
, 16);
18944 tcg_gen_or_tl(v0_t
, v0_t
, t0
);
18945 tcg_gen_ext32s_tl(v0_t
, v0_t
);
18946 gen_store_gpr(v0_t
, ret
);
18950 tcg_gen_ext8u_tl(v0_t
, v0_t
);
18951 tcg_gen_shli_tl(t0
, v0_t
, 8);
18952 tcg_gen_or_tl(v0_t
, v0_t
, t0
);
18953 tcg_gen_shli_tl(t0
, v0_t
, 16);
18954 tcg_gen_or_tl(v0_t
, v0_t
, t0
);
18955 tcg_gen_ext32s_tl(v0_t
, v0_t
);
18956 gen_store_gpr(v0_t
, ret
);
18960 gen_helper_bitrev(v0_t
, v0_t
);
18961 gen_store_gpr(v0_t
, ret
);
18966 TCGv tv0
= tcg_temp_new();
18968 gen_load_gpr(tv0
, rt
);
18969 gen_helper_insv(v0_t
, cpu_env
, v0_t
, tv0
);
18970 gen_store_gpr(v0_t
, ret
);
18971 tcg_temp_free(tv0
);
18974 case NM_RADDU_W_QB
:
18976 gen_helper_raddu_w_qb(v0_t
, v0_t
);
18977 gen_store_gpr(v0_t
, ret
);
18980 gen_bitswap(ctx
, OPC_BITSWAP
, ret
, rs
);
18984 gen_cl(ctx
, OPC_CLO
, ret
, rs
);
18988 gen_cl(ctx
, OPC_CLZ
, ret
, rs
);
18991 gen_bshfl(ctx
, OPC_WSBH
, ret
, rs
);
18994 gen_reserved_instruction(ctx
);
18998 tcg_temp_free(v0_t
);
19002 static void gen_pool32axf_7_nanomips_insn(DisasContext
*ctx
, uint32_t opc
,
19003 int rt
, int rs
, int rd
)
19005 TCGv t0
= tcg_temp_new();
19006 TCGv rs_t
= tcg_temp_new();
19008 gen_load_gpr(rs_t
, rs
);
19013 tcg_gen_movi_tl(t0
, rd
>> 2);
19014 switch (extract32(ctx
->opcode
, 12, 1)) {
19017 gen_helper_shra_qb(t0
, t0
, rs_t
);
19018 gen_store_gpr(t0
, rt
);
19022 gen_helper_shra_r_qb(t0
, t0
, rs_t
);
19023 gen_store_gpr(t0
, rt
);
19029 tcg_gen_movi_tl(t0
, rd
>> 1);
19030 gen_helper_shrl_ph(t0
, t0
, rs_t
);
19031 gen_store_gpr(t0
, rt
);
19037 target_long result
;
19038 imm
= extract32(ctx
->opcode
, 13, 8);
19039 result
= (uint32_t)imm
<< 24 |
19040 (uint32_t)imm
<< 16 |
19041 (uint32_t)imm
<< 8 |
19043 result
= (int32_t)result
;
19044 tcg_gen_movi_tl(t0
, result
);
19045 gen_store_gpr(t0
, rt
);
19049 gen_reserved_instruction(ctx
);
19053 tcg_temp_free(rs_t
);
19057 static void gen_pool32axf_nanomips_insn(CPUMIPSState
*env
, DisasContext
*ctx
)
19059 int rt
= extract32(ctx
->opcode
, 21, 5);
19060 int rs
= extract32(ctx
->opcode
, 16, 5);
19061 int rd
= extract32(ctx
->opcode
, 11, 5);
19063 switch (extract32(ctx
->opcode
, 6, 3)) {
19064 case NM_POOL32AXF_1
:
19066 int32_t op1
= extract32(ctx
->opcode
, 9, 3);
19067 gen_pool32axf_1_nanomips_insn(ctx
, op1
, rt
, rs
, rd
);
19070 case NM_POOL32AXF_2
:
19072 int32_t op1
= extract32(ctx
->opcode
, 12, 2);
19073 gen_pool32axf_2_nanomips_insn(ctx
, op1
, rt
, rs
, rd
);
19076 case NM_POOL32AXF_4
:
19078 int32_t op1
= extract32(ctx
->opcode
, 9, 7);
19079 gen_pool32axf_4_nanomips_insn(ctx
, op1
, rt
, rs
);
19082 case NM_POOL32AXF_5
:
19083 switch (extract32(ctx
->opcode
, 9, 7)) {
19084 #ifndef CONFIG_USER_ONLY
19086 gen_cp0(env
, ctx
, OPC_TLBP
, 0, 0);
19089 gen_cp0(env
, ctx
, OPC_TLBR
, 0, 0);
19092 gen_cp0(env
, ctx
, OPC_TLBWI
, 0, 0);
19095 gen_cp0(env
, ctx
, OPC_TLBWR
, 0, 0);
19098 gen_cp0(env
, ctx
, OPC_TLBINV
, 0, 0);
19101 gen_cp0(env
, ctx
, OPC_TLBINVF
, 0, 0);
19104 check_cp0_enabled(ctx
);
19106 TCGv t0
= tcg_temp_new();
19108 save_cpu_state(ctx
, 1);
19109 gen_helper_di(t0
, cpu_env
);
19110 gen_store_gpr(t0
, rt
);
19111 /* Stop translation as we may have switched the execution mode */
19112 ctx
->base
.is_jmp
= DISAS_STOP
;
19117 check_cp0_enabled(ctx
);
19119 TCGv t0
= tcg_temp_new();
19121 save_cpu_state(ctx
, 1);
19122 gen_helper_ei(t0
, cpu_env
);
19123 gen_store_gpr(t0
, rt
);
19124 /* Stop translation as we may have switched the execution mode */
19125 ctx
->base
.is_jmp
= DISAS_STOP
;
19130 gen_load_srsgpr(rs
, rt
);
19133 gen_store_srsgpr(rs
, rt
);
19136 gen_cp0(env
, ctx
, OPC_WAIT
, 0, 0);
19139 gen_cp0(env
, ctx
, OPC_DERET
, 0, 0);
19142 gen_cp0(env
, ctx
, OPC_ERET
, 0, 0);
19146 gen_reserved_instruction(ctx
);
19150 case NM_POOL32AXF_7
:
19152 int32_t op1
= extract32(ctx
->opcode
, 9, 3);
19153 gen_pool32axf_7_nanomips_insn(ctx
, op1
, rt
, rs
, rd
);
19157 gen_reserved_instruction(ctx
);
19162 /* Immediate Value Compact Branches */
19163 static void gen_compute_imm_branch(DisasContext
*ctx
, uint32_t opc
,
19164 int rt
, int32_t imm
, int32_t offset
)
19166 TCGCond cond
= TCG_COND_ALWAYS
;
19167 TCGv t0
= tcg_temp_new();
19168 TCGv t1
= tcg_temp_new();
19170 gen_load_gpr(t0
, rt
);
19171 tcg_gen_movi_tl(t1
, imm
);
19172 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
19174 /* Load needed operands and calculate btarget */
19177 if (rt
== 0 && imm
== 0) {
19178 /* Unconditional branch */
19179 } else if (rt
== 0 && imm
!= 0) {
19183 cond
= TCG_COND_EQ
;
19189 if (imm
>= 32 && !(ctx
->hflags
& MIPS_HFLAG_64
)) {
19190 gen_reserved_instruction(ctx
);
19192 } else if (rt
== 0 && opc
== NM_BBEQZC
) {
19193 /* Unconditional branch */
19194 } else if (rt
== 0 && opc
== NM_BBNEZC
) {
19198 tcg_gen_shri_tl(t0
, t0
, imm
);
19199 tcg_gen_andi_tl(t0
, t0
, 1);
19200 tcg_gen_movi_tl(t1
, 0);
19201 if (opc
== NM_BBEQZC
) {
19202 cond
= TCG_COND_EQ
;
19204 cond
= TCG_COND_NE
;
19209 if (rt
== 0 && imm
== 0) {
19212 } else if (rt
== 0 && imm
!= 0) {
19213 /* Unconditional branch */
19215 cond
= TCG_COND_NE
;
19219 if (rt
== 0 && imm
== 0) {
19220 /* Unconditional branch */
19222 cond
= TCG_COND_GE
;
19226 cond
= TCG_COND_LT
;
19229 if (rt
== 0 && imm
== 0) {
19230 /* Unconditional branch */
19232 cond
= TCG_COND_GEU
;
19236 cond
= TCG_COND_LTU
;
19239 MIPS_INVAL("Immediate Value Compact branch");
19240 gen_reserved_instruction(ctx
);
19244 /* branch completion */
19245 clear_branch_hflags(ctx
);
19246 ctx
->base
.is_jmp
= DISAS_NORETURN
;
19248 if (cond
== TCG_COND_ALWAYS
) {
19249 /* Uncoditional compact branch */
19250 gen_goto_tb(ctx
, 0, ctx
->btarget
);
19252 /* Conditional compact branch */
19253 TCGLabel
*fs
= gen_new_label();
19255 tcg_gen_brcond_tl(tcg_invert_cond(cond
), t0
, t1
, fs
);
19257 gen_goto_tb(ctx
, 1, ctx
->btarget
);
19260 gen_goto_tb(ctx
, 0, ctx
->base
.pc_next
+ 4);
19268 /* P.BALRSC type nanoMIPS R6 branches: BALRSC and BRSC */
19269 static void gen_compute_nanomips_pbalrsc_branch(DisasContext
*ctx
, int rs
,
19272 TCGv t0
= tcg_temp_new();
19273 TCGv t1
= tcg_temp_new();
19276 gen_load_gpr(t0
, rs
);
19280 tcg_gen_movi_tl(cpu_gpr
[rt
], ctx
->base
.pc_next
+ 4);
19283 /* calculate btarget */
19284 tcg_gen_shli_tl(t0
, t0
, 1);
19285 tcg_gen_movi_tl(t1
, ctx
->base
.pc_next
+ 4);
19286 gen_op_addr_add(ctx
, btarget
, t1
, t0
);
19288 /* branch completion */
19289 clear_branch_hflags(ctx
);
19290 ctx
->base
.is_jmp
= DISAS_NORETURN
;
19292 /* unconditional branch to register */
19293 tcg_gen_mov_tl(cpu_PC
, btarget
);
19294 tcg_gen_lookup_and_goto_ptr();
19300 /* nanoMIPS Branches */
19301 static void gen_compute_compact_branch_nm(DisasContext
*ctx
, uint32_t opc
,
19302 int rs
, int rt
, int32_t offset
)
19304 int bcond_compute
= 0;
19305 TCGv t0
= tcg_temp_new();
19306 TCGv t1
= tcg_temp_new();
19308 /* Load needed operands and calculate btarget */
19310 /* compact branch */
19313 gen_load_gpr(t0
, rs
);
19314 gen_load_gpr(t1
, rt
);
19316 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
19320 if (rs
== 0 || rs
== rt
) {
19321 /* OPC_BLEZALC, OPC_BGEZALC */
19322 /* OPC_BGTZALC, OPC_BLTZALC */
19323 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 4);
19325 gen_load_gpr(t0
, rs
);
19326 gen_load_gpr(t1
, rt
);
19328 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
19331 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
19335 /* OPC_BEQZC, OPC_BNEZC */
19336 gen_load_gpr(t0
, rs
);
19338 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
19340 /* OPC_JIC, OPC_JIALC */
19341 TCGv tbase
= tcg_temp_new();
19342 TCGv toffset
= tcg_temp_new();
19344 gen_load_gpr(tbase
, rt
);
19345 tcg_gen_movi_tl(toffset
, offset
);
19346 gen_op_addr_add(ctx
, btarget
, tbase
, toffset
);
19347 tcg_temp_free(tbase
);
19348 tcg_temp_free(toffset
);
19352 MIPS_INVAL("Compact branch/jump");
19353 gen_reserved_instruction(ctx
);
19357 if (bcond_compute
== 0) {
19358 /* Uncoditional compact branch */
19361 gen_goto_tb(ctx
, 0, ctx
->btarget
);
19364 MIPS_INVAL("Compact branch/jump");
19365 gen_reserved_instruction(ctx
);
19369 /* Conditional compact branch */
19370 TCGLabel
*fs
= gen_new_label();
19374 if (rs
== 0 && rt
!= 0) {
19376 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE
), t1
, 0, fs
);
19377 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
19379 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE
), t1
, 0, fs
);
19382 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU
), t0
, t1
, fs
);
19386 if (rs
== 0 && rt
!= 0) {
19388 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT
), t1
, 0, fs
);
19389 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
19391 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT
), t1
, 0, fs
);
19394 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU
), t0
, t1
, fs
);
19398 if (rs
== 0 && rt
!= 0) {
19400 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE
), t1
, 0, fs
);
19401 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
19403 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE
), t1
, 0, fs
);
19406 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE
), t0
, t1
, fs
);
19410 if (rs
== 0 && rt
!= 0) {
19412 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT
), t1
, 0, fs
);
19413 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
19415 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT
), t1
, 0, fs
);
19418 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT
), t0
, t1
, fs
);
19422 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ
), t0
, 0, fs
);
19425 MIPS_INVAL("Compact conditional branch/jump");
19426 gen_reserved_instruction(ctx
);
19430 /* branch completion */
19431 clear_branch_hflags(ctx
);
19432 ctx
->base
.is_jmp
= DISAS_NORETURN
;
19434 /* Generating branch here as compact branches don't have delay slot */
19435 gen_goto_tb(ctx
, 1, ctx
->btarget
);
19438 gen_goto_tb(ctx
, 0, ctx
->base
.pc_next
+ 4);
19447 /* nanoMIPS CP1 Branches */
19448 static void gen_compute_branch_cp1_nm(DisasContext
*ctx
, uint32_t op
,
19449 int32_t ft
, int32_t offset
)
19451 target_ulong btarget
;
19452 TCGv_i64 t0
= tcg_temp_new_i64();
19454 gen_load_fpr64(ctx
, t0
, ft
);
19455 tcg_gen_andi_i64(t0
, t0
, 1);
19457 btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
19461 tcg_gen_xori_i64(t0
, t0
, 1);
19462 ctx
->hflags
|= MIPS_HFLAG_BC
;
19465 /* t0 already set */
19466 ctx
->hflags
|= MIPS_HFLAG_BC
;
19469 MIPS_INVAL("cp1 cond branch");
19470 gen_reserved_instruction(ctx
);
19474 tcg_gen_trunc_i64_tl(bcond
, t0
);
19476 ctx
->btarget
= btarget
;
19479 tcg_temp_free_i64(t0
);
19483 static void gen_p_lsx(DisasContext
*ctx
, int rd
, int rs
, int rt
)
19486 t0
= tcg_temp_new();
19487 t1
= tcg_temp_new();
19489 gen_load_gpr(t0
, rs
);
19490 gen_load_gpr(t1
, rt
);
19492 if ((extract32(ctx
->opcode
, 6, 1)) == 1) {
19493 /* PP.LSXS instructions require shifting */
19494 switch (extract32(ctx
->opcode
, 7, 4)) {
19500 tcg_gen_shli_tl(t0
, t0
, 1);
19508 tcg_gen_shli_tl(t0
, t0
, 2);
19512 tcg_gen_shli_tl(t0
, t0
, 3);
19516 gen_op_addr_add(ctx
, t0
, t0
, t1
);
19518 switch (extract32(ctx
->opcode
, 7, 4)) {
19520 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
,
19522 gen_store_gpr(t0
, rd
);
19526 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
,
19528 gen_store_gpr(t0
, rd
);
19532 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
,
19534 gen_store_gpr(t0
, rd
);
19537 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
,
19539 gen_store_gpr(t0
, rd
);
19543 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
,
19545 gen_store_gpr(t0
, rd
);
19549 gen_load_gpr(t1
, rd
);
19550 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
,
19556 gen_load_gpr(t1
, rd
);
19557 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
,
19563 gen_load_gpr(t1
, rd
);
19564 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
,
19568 /*case NM_LWC1XS:*/
19570 /*case NM_LDC1XS:*/
19572 /*case NM_SWC1XS:*/
19574 /*case NM_SDC1XS:*/
19575 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
19576 check_cp1_enabled(ctx
);
19577 switch (extract32(ctx
->opcode
, 7, 4)) {
19579 /*case NM_LWC1XS:*/
19580 gen_flt_ldst(ctx
, OPC_LWC1
, rd
, t0
);
19583 /*case NM_LDC1XS:*/
19584 gen_flt_ldst(ctx
, OPC_LDC1
, rd
, t0
);
19587 /*case NM_SWC1XS:*/
19588 gen_flt_ldst(ctx
, OPC_SWC1
, rd
, t0
);
19591 /*case NM_SDC1XS:*/
19592 gen_flt_ldst(ctx
, OPC_SDC1
, rd
, t0
);
19596 generate_exception_err(ctx
, EXCP_CpU
, 1);
19600 gen_reserved_instruction(ctx
);
19608 static void gen_pool32f_nanomips_insn(DisasContext
*ctx
)
19612 rt
= extract32(ctx
->opcode
, 21, 5);
19613 rs
= extract32(ctx
->opcode
, 16, 5);
19614 rd
= extract32(ctx
->opcode
, 11, 5);
19616 if (!(ctx
->CP0_Config1
& (1 << CP0C1_FP
))) {
19617 gen_reserved_instruction(ctx
);
19620 check_cp1_enabled(ctx
);
19621 switch (extract32(ctx
->opcode
, 0, 3)) {
19623 switch (extract32(ctx
->opcode
, 3, 7)) {
19625 gen_farith(ctx
, OPC_RINT_S
, 0, rt
, rs
, 0);
19628 gen_farith(ctx
, OPC_RINT_D
, 0, rt
, rs
, 0);
19631 gen_farith(ctx
, OPC_CLASS_S
, 0, rt
, rs
, 0);
19634 gen_farith(ctx
, OPC_CLASS_D
, 0, rt
, rs
, 0);
19637 gen_farith(ctx
, OPC_ADD_S
, rt
, rs
, rd
, 0);
19640 gen_farith(ctx
, OPC_ADD_D
, rt
, rs
, rd
, 0);
19643 gen_farith(ctx
, OPC_SUB_S
, rt
, rs
, rd
, 0);
19646 gen_farith(ctx
, OPC_SUB_D
, rt
, rs
, rd
, 0);
19649 gen_farith(ctx
, OPC_MUL_S
, rt
, rs
, rd
, 0);
19652 gen_farith(ctx
, OPC_MUL_D
, rt
, rs
, rd
, 0);
19655 gen_farith(ctx
, OPC_DIV_S
, rt
, rs
, rd
, 0);
19658 gen_farith(ctx
, OPC_DIV_D
, rt
, rs
, rd
, 0);
19661 gen_sel_s(ctx
, OPC_SELEQZ_S
, rd
, rt
, rs
);
19664 gen_sel_d(ctx
, OPC_SELEQZ_D
, rd
, rt
, rs
);
19667 gen_sel_s(ctx
, OPC_SELNEZ_S
, rd
, rt
, rs
);
19670 gen_sel_d(ctx
, OPC_SELNEZ_D
, rd
, rt
, rs
);
19673 gen_sel_s(ctx
, OPC_SEL_S
, rd
, rt
, rs
);
19676 gen_sel_d(ctx
, OPC_SEL_D
, rd
, rt
, rs
);
19679 gen_farith(ctx
, OPC_MADDF_S
, rt
, rs
, rd
, 0);
19682 gen_farith(ctx
, OPC_MADDF_D
, rt
, rs
, rd
, 0);
19685 gen_farith(ctx
, OPC_MSUBF_S
, rt
, rs
, rd
, 0);
19688 gen_farith(ctx
, OPC_MSUBF_D
, rt
, rs
, rd
, 0);
19691 gen_reserved_instruction(ctx
);
19696 switch (extract32(ctx
->opcode
, 3, 3)) {
19698 switch (extract32(ctx
->opcode
, 9, 1)) {
19700 gen_farith(ctx
, OPC_MIN_S
, rt
, rs
, rd
, 0);
19703 gen_farith(ctx
, OPC_MIN_D
, rt
, rs
, rd
, 0);
19708 switch (extract32(ctx
->opcode
, 9, 1)) {
19710 gen_farith(ctx
, OPC_MAX_S
, rt
, rs
, rd
, 0);
19713 gen_farith(ctx
, OPC_MAX_D
, rt
, rs
, rd
, 0);
19718 switch (extract32(ctx
->opcode
, 9, 1)) {
19720 gen_farith(ctx
, OPC_MINA_S
, rt
, rs
, rd
, 0);
19723 gen_farith(ctx
, OPC_MINA_D
, rt
, rs
, rd
, 0);
19728 switch (extract32(ctx
->opcode
, 9, 1)) {
19730 gen_farith(ctx
, OPC_MAXA_S
, rt
, rs
, rd
, 0);
19733 gen_farith(ctx
, OPC_MAXA_D
, rt
, rs
, rd
, 0);
19738 switch (extract32(ctx
->opcode
, 6, 8)) {
19740 gen_cp1(ctx
, OPC_CFC1
, rt
, rs
);
19743 gen_cp1(ctx
, OPC_CTC1
, rt
, rs
);
19746 gen_cp1(ctx
, OPC_MFC1
, rt
, rs
);
19749 gen_cp1(ctx
, OPC_MTC1
, rt
, rs
);
19752 gen_cp1(ctx
, OPC_MFHC1
, rt
, rs
);
19755 gen_cp1(ctx
, OPC_MTHC1
, rt
, rs
);
19758 gen_farith(ctx
, OPC_CVT_S_PL
, -1, rs
, rt
, 0);
19761 gen_farith(ctx
, OPC_CVT_S_PU
, -1, rs
, rt
, 0);
19764 switch (extract32(ctx
->opcode
, 6, 9)) {
19766 gen_farith(ctx
, OPC_CVT_L_S
, -1, rs
, rt
, 0);
19769 gen_farith(ctx
, OPC_CVT_L_D
, -1, rs
, rt
, 0);
19772 gen_farith(ctx
, OPC_CVT_W_S
, -1, rs
, rt
, 0);
19775 gen_farith(ctx
, OPC_CVT_W_D
, -1, rs
, rt
, 0);
19778 gen_farith(ctx
, OPC_RSQRT_S
, -1, rs
, rt
, 0);
19781 gen_farith(ctx
, OPC_RSQRT_D
, -1, rs
, rt
, 0);
19784 gen_farith(ctx
, OPC_SQRT_S
, -1, rs
, rt
, 0);
19787 gen_farith(ctx
, OPC_SQRT_D
, -1, rs
, rt
, 0);
19790 gen_farith(ctx
, OPC_RECIP_S
, -1, rs
, rt
, 0);
19793 gen_farith(ctx
, OPC_RECIP_D
, -1, rs
, rt
, 0);
19796 gen_farith(ctx
, OPC_FLOOR_L_S
, -1, rs
, rt
, 0);
19799 gen_farith(ctx
, OPC_FLOOR_L_D
, -1, rs
, rt
, 0);
19802 gen_farith(ctx
, OPC_FLOOR_W_S
, -1, rs
, rt
, 0);
19805 gen_farith(ctx
, OPC_FLOOR_W_D
, -1, rs
, rt
, 0);
19808 gen_farith(ctx
, OPC_CEIL_L_S
, -1, rs
, rt
, 0);
19811 gen_farith(ctx
, OPC_CEIL_L_D
, -1, rs
, rt
, 0);
19814 gen_farith(ctx
, OPC_CEIL_W_S
, -1, rs
, rt
, 0);
19817 gen_farith(ctx
, OPC_CEIL_W_D
, -1, rs
, rt
, 0);
19820 gen_farith(ctx
, OPC_TRUNC_L_S
, -1, rs
, rt
, 0);
19823 gen_farith(ctx
, OPC_TRUNC_L_D
, -1, rs
, rt
, 0);
19826 gen_farith(ctx
, OPC_TRUNC_W_S
, -1, rs
, rt
, 0);
19829 gen_farith(ctx
, OPC_TRUNC_W_D
, -1, rs
, rt
, 0);
19832 gen_farith(ctx
, OPC_ROUND_L_S
, -1, rs
, rt
, 0);
19835 gen_farith(ctx
, OPC_ROUND_L_D
, -1, rs
, rt
, 0);
19838 gen_farith(ctx
, OPC_ROUND_W_S
, -1, rs
, rt
, 0);
19841 gen_farith(ctx
, OPC_ROUND_W_D
, -1, rs
, rt
, 0);
19844 gen_farith(ctx
, OPC_MOV_S
, -1, rs
, rt
, 0);
19847 gen_farith(ctx
, OPC_MOV_D
, -1, rs
, rt
, 0);
19850 gen_farith(ctx
, OPC_ABS_S
, -1, rs
, rt
, 0);
19853 gen_farith(ctx
, OPC_ABS_D
, -1, rs
, rt
, 0);
19856 gen_farith(ctx
, OPC_NEG_S
, -1, rs
, rt
, 0);
19859 gen_farith(ctx
, OPC_NEG_D
, -1, rs
, rt
, 0);
19862 gen_farith(ctx
, OPC_CVT_D_S
, -1, rs
, rt
, 0);
19865 gen_farith(ctx
, OPC_CVT_D_W
, -1, rs
, rt
, 0);
19868 gen_farith(ctx
, OPC_CVT_D_L
, -1, rs
, rt
, 0);
19871 gen_farith(ctx
, OPC_CVT_S_D
, -1, rs
, rt
, 0);
19874 gen_farith(ctx
, OPC_CVT_S_W
, -1, rs
, rt
, 0);
19877 gen_farith(ctx
, OPC_CVT_S_L
, -1, rs
, rt
, 0);
19880 gen_reserved_instruction(ctx
);
19889 switch (extract32(ctx
->opcode
, 3, 3)) {
19890 case NM_CMP_CONDN_S
:
19891 gen_r6_cmp_s(ctx
, extract32(ctx
->opcode
, 6, 5), rt
, rs
, rd
);
19893 case NM_CMP_CONDN_D
:
19894 gen_r6_cmp_d(ctx
, extract32(ctx
->opcode
, 6, 5), rt
, rs
, rd
);
19897 gen_reserved_instruction(ctx
);
19902 gen_reserved_instruction(ctx
);
19907 static void gen_pool32a5_nanomips_insn(DisasContext
*ctx
, int opc
,
19908 int rd
, int rs
, int rt
)
19911 TCGv t0
= tcg_temp_new();
19912 TCGv v1_t
= tcg_temp_new();
19913 TCGv v2_t
= tcg_temp_new();
19915 gen_load_gpr(v1_t
, rs
);
19916 gen_load_gpr(v2_t
, rt
);
19921 gen_helper_cmp_eq_ph(v1_t
, v2_t
, cpu_env
);
19925 gen_helper_cmp_lt_ph(v1_t
, v2_t
, cpu_env
);
19929 gen_helper_cmp_le_ph(v1_t
, v2_t
, cpu_env
);
19931 case NM_CMPU_EQ_QB
:
19933 gen_helper_cmpu_eq_qb(v1_t
, v2_t
, cpu_env
);
19935 case NM_CMPU_LT_QB
:
19937 gen_helper_cmpu_lt_qb(v1_t
, v2_t
, cpu_env
);
19939 case NM_CMPU_LE_QB
:
19941 gen_helper_cmpu_le_qb(v1_t
, v2_t
, cpu_env
);
19943 case NM_CMPGU_EQ_QB
:
19945 gen_helper_cmpgu_eq_qb(v1_t
, v1_t
, v2_t
);
19946 gen_store_gpr(v1_t
, ret
);
19948 case NM_CMPGU_LT_QB
:
19950 gen_helper_cmpgu_lt_qb(v1_t
, v1_t
, v2_t
);
19951 gen_store_gpr(v1_t
, ret
);
19953 case NM_CMPGU_LE_QB
:
19955 gen_helper_cmpgu_le_qb(v1_t
, v1_t
, v2_t
);
19956 gen_store_gpr(v1_t
, ret
);
19958 case NM_CMPGDU_EQ_QB
:
19960 gen_helper_cmpgu_eq_qb(v1_t
, v1_t
, v2_t
);
19961 tcg_gen_deposit_tl(cpu_dspctrl
, cpu_dspctrl
, v1_t
, 24, 4);
19962 gen_store_gpr(v1_t
, ret
);
19964 case NM_CMPGDU_LT_QB
:
19966 gen_helper_cmpgu_lt_qb(v1_t
, v1_t
, v2_t
);
19967 tcg_gen_deposit_tl(cpu_dspctrl
, cpu_dspctrl
, v1_t
, 24, 4);
19968 gen_store_gpr(v1_t
, ret
);
19970 case NM_CMPGDU_LE_QB
:
19972 gen_helper_cmpgu_le_qb(v1_t
, v1_t
, v2_t
);
19973 tcg_gen_deposit_tl(cpu_dspctrl
, cpu_dspctrl
, v1_t
, 24, 4);
19974 gen_store_gpr(v1_t
, ret
);
19978 gen_helper_packrl_ph(v1_t
, v1_t
, v2_t
);
19979 gen_store_gpr(v1_t
, ret
);
19983 gen_helper_pick_qb(v1_t
, v1_t
, v2_t
, cpu_env
);
19984 gen_store_gpr(v1_t
, ret
);
19988 gen_helper_pick_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
19989 gen_store_gpr(v1_t
, ret
);
19993 gen_helper_addq_s_w(v1_t
, v1_t
, v2_t
, cpu_env
);
19994 gen_store_gpr(v1_t
, ret
);
19998 gen_helper_subq_s_w(v1_t
, v1_t
, v2_t
, cpu_env
);
19999 gen_store_gpr(v1_t
, ret
);
20003 gen_helper_addsc(v1_t
, v1_t
, v2_t
, cpu_env
);
20004 gen_store_gpr(v1_t
, ret
);
20008 gen_helper_addwc(v1_t
, v1_t
, v2_t
, cpu_env
);
20009 gen_store_gpr(v1_t
, ret
);
20013 switch (extract32(ctx
->opcode
, 10, 1)) {
20016 gen_helper_addq_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20017 gen_store_gpr(v1_t
, ret
);
20021 gen_helper_addq_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20022 gen_store_gpr(v1_t
, ret
);
20026 case NM_ADDQH_R_PH
:
20028 switch (extract32(ctx
->opcode
, 10, 1)) {
20031 gen_helper_addqh_ph(v1_t
, v1_t
, v2_t
);
20032 gen_store_gpr(v1_t
, ret
);
20036 gen_helper_addqh_r_ph(v1_t
, v1_t
, v2_t
);
20037 gen_store_gpr(v1_t
, ret
);
20043 switch (extract32(ctx
->opcode
, 10, 1)) {
20046 gen_helper_addqh_w(v1_t
, v1_t
, v2_t
);
20047 gen_store_gpr(v1_t
, ret
);
20051 gen_helper_addqh_r_w(v1_t
, v1_t
, v2_t
);
20052 gen_store_gpr(v1_t
, ret
);
20058 switch (extract32(ctx
->opcode
, 10, 1)) {
20061 gen_helper_addu_qb(v1_t
, v1_t
, v2_t
, cpu_env
);
20062 gen_store_gpr(v1_t
, ret
);
20066 gen_helper_addu_s_qb(v1_t
, v1_t
, v2_t
, cpu_env
);
20067 gen_store_gpr(v1_t
, ret
);
20073 switch (extract32(ctx
->opcode
, 10, 1)) {
20076 gen_helper_addu_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20077 gen_store_gpr(v1_t
, ret
);
20081 gen_helper_addu_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20082 gen_store_gpr(v1_t
, ret
);
20086 case NM_ADDUH_R_QB
:
20088 switch (extract32(ctx
->opcode
, 10, 1)) {
20091 gen_helper_adduh_qb(v1_t
, v1_t
, v2_t
);
20092 gen_store_gpr(v1_t
, ret
);
20096 gen_helper_adduh_r_qb(v1_t
, v1_t
, v2_t
);
20097 gen_store_gpr(v1_t
, ret
);
20101 case NM_SHRAV_R_PH
:
20103 switch (extract32(ctx
->opcode
, 10, 1)) {
20106 gen_helper_shra_ph(v1_t
, v1_t
, v2_t
);
20107 gen_store_gpr(v1_t
, ret
);
20111 gen_helper_shra_r_ph(v1_t
, v1_t
, v2_t
);
20112 gen_store_gpr(v1_t
, ret
);
20116 case NM_SHRAV_R_QB
:
20118 switch (extract32(ctx
->opcode
, 10, 1)) {
20121 gen_helper_shra_qb(v1_t
, v1_t
, v2_t
);
20122 gen_store_gpr(v1_t
, ret
);
20126 gen_helper_shra_r_qb(v1_t
, v1_t
, v2_t
);
20127 gen_store_gpr(v1_t
, ret
);
20133 switch (extract32(ctx
->opcode
, 10, 1)) {
20136 gen_helper_subq_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20137 gen_store_gpr(v1_t
, ret
);
20141 gen_helper_subq_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20142 gen_store_gpr(v1_t
, ret
);
20146 case NM_SUBQH_R_PH
:
20148 switch (extract32(ctx
->opcode
, 10, 1)) {
20151 gen_helper_subqh_ph(v1_t
, v1_t
, v2_t
);
20152 gen_store_gpr(v1_t
, ret
);
20156 gen_helper_subqh_r_ph(v1_t
, v1_t
, v2_t
);
20157 gen_store_gpr(v1_t
, ret
);
20163 switch (extract32(ctx
->opcode
, 10, 1)) {
20166 gen_helper_subqh_w(v1_t
, v1_t
, v2_t
);
20167 gen_store_gpr(v1_t
, ret
);
20171 gen_helper_subqh_r_w(v1_t
, v1_t
, v2_t
);
20172 gen_store_gpr(v1_t
, ret
);
20178 switch (extract32(ctx
->opcode
, 10, 1)) {
20181 gen_helper_subu_qb(v1_t
, v1_t
, v2_t
, cpu_env
);
20182 gen_store_gpr(v1_t
, ret
);
20186 gen_helper_subu_s_qb(v1_t
, v1_t
, v2_t
, cpu_env
);
20187 gen_store_gpr(v1_t
, ret
);
20193 switch (extract32(ctx
->opcode
, 10, 1)) {
20196 gen_helper_subu_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20197 gen_store_gpr(v1_t
, ret
);
20201 gen_helper_subu_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20202 gen_store_gpr(v1_t
, ret
);
20206 case NM_SUBUH_R_QB
:
20208 switch (extract32(ctx
->opcode
, 10, 1)) {
20211 gen_helper_subuh_qb(v1_t
, v1_t
, v2_t
);
20212 gen_store_gpr(v1_t
, ret
);
20216 gen_helper_subuh_r_qb(v1_t
, v1_t
, v2_t
);
20217 gen_store_gpr(v1_t
, ret
);
20221 case NM_SHLLV_S_PH
:
20223 switch (extract32(ctx
->opcode
, 10, 1)) {
20226 gen_helper_shll_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20227 gen_store_gpr(v1_t
, ret
);
20231 gen_helper_shll_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20232 gen_store_gpr(v1_t
, ret
);
20236 case NM_PRECR_SRA_R_PH_W
:
20238 switch (extract32(ctx
->opcode
, 10, 1)) {
20240 /* PRECR_SRA_PH_W */
20242 TCGv_i32 sa_t
= tcg_const_i32(rd
);
20243 gen_helper_precr_sra_ph_w(v1_t
, sa_t
, v1_t
,
20245 gen_store_gpr(v1_t
, rt
);
20246 tcg_temp_free_i32(sa_t
);
20250 /* PRECR_SRA_R_PH_W */
20252 TCGv_i32 sa_t
= tcg_const_i32(rd
);
20253 gen_helper_precr_sra_r_ph_w(v1_t
, sa_t
, v1_t
,
20255 gen_store_gpr(v1_t
, rt
);
20256 tcg_temp_free_i32(sa_t
);
20261 case NM_MULEU_S_PH_QBL
:
20263 gen_helper_muleu_s_ph_qbl(v1_t
, v1_t
, v2_t
, cpu_env
);
20264 gen_store_gpr(v1_t
, ret
);
20266 case NM_MULEU_S_PH_QBR
:
20268 gen_helper_muleu_s_ph_qbr(v1_t
, v1_t
, v2_t
, cpu_env
);
20269 gen_store_gpr(v1_t
, ret
);
20271 case NM_MULQ_RS_PH
:
20273 gen_helper_mulq_rs_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20274 gen_store_gpr(v1_t
, ret
);
20278 gen_helper_mulq_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20279 gen_store_gpr(v1_t
, ret
);
20283 gen_helper_mulq_rs_w(v1_t
, v1_t
, v2_t
, cpu_env
);
20284 gen_store_gpr(v1_t
, ret
);
20288 gen_helper_mulq_s_w(v1_t
, v1_t
, v2_t
, cpu_env
);
20289 gen_store_gpr(v1_t
, ret
);
20293 gen_load_gpr(t0
, rs
);
20295 tcg_gen_deposit_tl(cpu_gpr
[rt
], t0
, cpu_gpr
[rt
], rd
, 32 - rd
);
20297 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
20301 gen_helper_modsub(v1_t
, v1_t
, v2_t
);
20302 gen_store_gpr(v1_t
, ret
);
20306 gen_helper_shra_r_w(v1_t
, v1_t
, v2_t
);
20307 gen_store_gpr(v1_t
, ret
);
20311 gen_helper_shrl_ph(v1_t
, v1_t
, v2_t
);
20312 gen_store_gpr(v1_t
, ret
);
20316 gen_helper_shrl_qb(v1_t
, v1_t
, v2_t
);
20317 gen_store_gpr(v1_t
, ret
);
20321 gen_helper_shll_qb(v1_t
, v1_t
, v2_t
, cpu_env
);
20322 gen_store_gpr(v1_t
, ret
);
20326 gen_helper_shll_s_w(v1_t
, v1_t
, v2_t
, cpu_env
);
20327 gen_store_gpr(v1_t
, ret
);
20332 TCGv tv0
= tcg_temp_new();
20333 TCGv tv1
= tcg_temp_new();
20334 int16_t imm
= extract32(ctx
->opcode
, 16, 7);
20336 tcg_gen_movi_tl(tv0
, rd
>> 3);
20337 tcg_gen_movi_tl(tv1
, imm
);
20338 gen_helper_shilo(tv0
, tv1
, cpu_env
);
20341 case NM_MULEQ_S_W_PHL
:
20343 gen_helper_muleq_s_w_phl(v1_t
, v1_t
, v2_t
, cpu_env
);
20344 gen_store_gpr(v1_t
, ret
);
20346 case NM_MULEQ_S_W_PHR
:
20348 gen_helper_muleq_s_w_phr(v1_t
, v1_t
, v2_t
, cpu_env
);
20349 gen_store_gpr(v1_t
, ret
);
20353 switch (extract32(ctx
->opcode
, 10, 1)) {
20356 gen_helper_mul_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20357 gen_store_gpr(v1_t
, ret
);
20361 gen_helper_mul_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20362 gen_store_gpr(v1_t
, ret
);
20366 case NM_PRECR_QB_PH
:
20368 gen_helper_precr_qb_ph(v1_t
, v1_t
, v2_t
);
20369 gen_store_gpr(v1_t
, ret
);
20371 case NM_PRECRQ_QB_PH
:
20373 gen_helper_precrq_qb_ph(v1_t
, v1_t
, v2_t
);
20374 gen_store_gpr(v1_t
, ret
);
20376 case NM_PRECRQ_PH_W
:
20378 gen_helper_precrq_ph_w(v1_t
, v1_t
, v2_t
);
20379 gen_store_gpr(v1_t
, ret
);
20381 case NM_PRECRQ_RS_PH_W
:
20383 gen_helper_precrq_rs_ph_w(v1_t
, v1_t
, v2_t
, cpu_env
);
20384 gen_store_gpr(v1_t
, ret
);
20386 case NM_PRECRQU_S_QB_PH
:
20388 gen_helper_precrqu_s_qb_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20389 gen_store_gpr(v1_t
, ret
);
20393 tcg_gen_movi_tl(t0
, rd
);
20394 gen_helper_shra_r_w(v1_t
, t0
, v1_t
);
20395 gen_store_gpr(v1_t
, rt
);
20399 tcg_gen_movi_tl(t0
, rd
>> 1);
20400 switch (extract32(ctx
->opcode
, 10, 1)) {
20403 gen_helper_shra_ph(v1_t
, t0
, v1_t
);
20404 gen_store_gpr(v1_t
, rt
);
20408 gen_helper_shra_r_ph(v1_t
, t0
, v1_t
);
20409 gen_store_gpr(v1_t
, rt
);
20415 tcg_gen_movi_tl(t0
, rd
>> 1);
20416 switch (extract32(ctx
->opcode
, 10, 2)) {
20419 gen_helper_shll_ph(v1_t
, t0
, v1_t
, cpu_env
);
20420 gen_store_gpr(v1_t
, rt
);
20424 gen_helper_shll_s_ph(v1_t
, t0
, v1_t
, cpu_env
);
20425 gen_store_gpr(v1_t
, rt
);
20428 gen_reserved_instruction(ctx
);
20434 tcg_gen_movi_tl(t0
, rd
);
20435 gen_helper_shll_s_w(v1_t
, t0
, v1_t
, cpu_env
);
20436 gen_store_gpr(v1_t
, rt
);
20442 imm
= sextract32(ctx
->opcode
, 11, 11);
20443 imm
= (int16_t)(imm
<< 6) >> 6;
20445 tcg_gen_movi_tl(cpu_gpr
[rt
], dup_const(MO_16
, imm
));
20450 gen_reserved_instruction(ctx
);
20455 static int decode_nanomips_32_48_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
20463 insn
= translator_lduw(env
, ctx
->base
.pc_next
+ 2);
20464 ctx
->opcode
= (ctx
->opcode
<< 16) | insn
;
20466 rt
= extract32(ctx
->opcode
, 21, 5);
20467 rs
= extract32(ctx
->opcode
, 16, 5);
20468 rd
= extract32(ctx
->opcode
, 11, 5);
20470 op
= extract32(ctx
->opcode
, 26, 6);
20475 switch (extract32(ctx
->opcode
, 19, 2)) {
20478 gen_reserved_instruction(ctx
);
20481 if ((extract32(ctx
->opcode
, 18, 1)) == NM_SYSCALL
) {
20482 generate_exception_end(ctx
, EXCP_SYSCALL
);
20484 gen_reserved_instruction(ctx
);
20488 generate_exception_end(ctx
, EXCP_BREAK
);
20491 if (is_uhi(extract32(ctx
->opcode
, 0, 19))) {
20492 gen_helper_do_semihosting(cpu_env
);
20494 if (ctx
->hflags
& MIPS_HFLAG_SBRI
) {
20495 gen_reserved_instruction(ctx
);
20497 generate_exception_end(ctx
, EXCP_DBp
);
20504 imm
= extract32(ctx
->opcode
, 0, 16);
20506 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], imm
);
20508 tcg_gen_movi_tl(cpu_gpr
[rt
], imm
);
20510 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
20515 offset
= sextract32(ctx
->opcode
, 0, 1) << 21 |
20516 extract32(ctx
->opcode
, 1, 20) << 1;
20517 target_long addr
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
20518 tcg_gen_movi_tl(cpu_gpr
[rt
], addr
);
20522 switch (ctx
->opcode
& 0x07) {
20524 gen_pool32a0_nanomips_insn(env
, ctx
);
20528 int32_t op1
= extract32(ctx
->opcode
, 3, 7);
20529 gen_pool32a5_nanomips_insn(ctx
, op1
, rd
, rs
, rt
);
20533 switch (extract32(ctx
->opcode
, 3, 3)) {
20535 gen_p_lsx(ctx
, rd
, rs
, rt
);
20539 * In nanoMIPS, the shift field directly encodes the shift
20540 * amount, meaning that the supported shift values are in
20541 * the range 0 to 3 (instead of 1 to 4 in MIPSR6).
20543 gen_lsa(ctx
, rd
, rt
, rs
, extract32(ctx
->opcode
, 9, 2) - 1);
20546 gen_ext(ctx
, 32, rd
, rs
, rt
, extract32(ctx
->opcode
, 6, 5));
20549 gen_pool32axf_nanomips_insn(env
, ctx
);
20552 gen_reserved_instruction(ctx
);
20557 gen_reserved_instruction(ctx
);
20562 switch (ctx
->opcode
& 0x03) {
20565 offset
= extract32(ctx
->opcode
, 0, 21);
20566 gen_op_addr_addi(ctx
, cpu_gpr
[rt
], cpu_gpr
[28], offset
);
20570 gen_ld(ctx
, OPC_LW
, rt
, 28, extract32(ctx
->opcode
, 2, 19) << 2);
20573 gen_st(ctx
, OPC_SW
, rt
, 28, extract32(ctx
->opcode
, 2, 19) << 2);
20576 gen_reserved_instruction(ctx
);
20582 insn
= translator_lduw(env
, ctx
->base
.pc_next
+ 4);
20583 target_long addr_off
= extract32(ctx
->opcode
, 0, 16) | insn
<< 16;
20584 switch (extract32(ctx
->opcode
, 16, 5)) {
20588 tcg_gen_movi_tl(cpu_gpr
[rt
], addr_off
);
20594 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], addr_off
);
20595 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
20601 gen_op_addr_addi(ctx
, cpu_gpr
[rt
], cpu_gpr
[28], addr_off
);
20607 target_long addr
= addr_add(ctx
, ctx
->base
.pc_next
+ 6,
20610 tcg_gen_movi_tl(cpu_gpr
[rt
], addr
);
20617 t0
= tcg_temp_new();
20619 target_long addr
= addr_add(ctx
, ctx
->base
.pc_next
+ 6,
20622 tcg_gen_movi_tl(t0
, addr
);
20623 tcg_gen_qemu_ld_tl(cpu_gpr
[rt
], t0
, ctx
->mem_idx
, MO_TESL
);
20631 t0
= tcg_temp_new();
20632 t1
= tcg_temp_new();
20634 target_long addr
= addr_add(ctx
, ctx
->base
.pc_next
+ 6,
20637 tcg_gen_movi_tl(t0
, addr
);
20638 gen_load_gpr(t1
, rt
);
20640 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
20647 gen_reserved_instruction(ctx
);
20653 switch (extract32(ctx
->opcode
, 12, 4)) {
20655 gen_logic_imm(ctx
, OPC_ORI
, rt
, rs
, extract32(ctx
->opcode
, 0, 12));
20658 gen_logic_imm(ctx
, OPC_XORI
, rt
, rs
, extract32(ctx
->opcode
, 0, 12));
20661 gen_logic_imm(ctx
, OPC_ANDI
, rt
, rs
, extract32(ctx
->opcode
, 0, 12));
20664 switch (extract32(ctx
->opcode
, 20, 1)) {
20666 switch (ctx
->opcode
& 3) {
20668 gen_save(ctx
, rt
, extract32(ctx
->opcode
, 16, 4),
20669 extract32(ctx
->opcode
, 2, 1),
20670 extract32(ctx
->opcode
, 3, 9) << 3);
20673 case NM_RESTORE_JRC
:
20674 gen_restore(ctx
, rt
, extract32(ctx
->opcode
, 16, 4),
20675 extract32(ctx
->opcode
, 2, 1),
20676 extract32(ctx
->opcode
, 3, 9) << 3);
20677 if ((ctx
->opcode
& 3) == NM_RESTORE_JRC
) {
20678 gen_compute_branch_nm(ctx
, OPC_JR
, 2, 31, 0, 0);
20682 gen_reserved_instruction(ctx
);
20687 gen_reserved_instruction(ctx
);
20692 gen_slt_imm(ctx
, OPC_SLTI
, rt
, rs
, extract32(ctx
->opcode
, 0, 12));
20695 gen_slt_imm(ctx
, OPC_SLTIU
, rt
, rs
, extract32(ctx
->opcode
, 0, 12));
20699 TCGv t0
= tcg_temp_new();
20701 imm
= extract32(ctx
->opcode
, 0, 12);
20702 gen_load_gpr(t0
, rs
);
20703 tcg_gen_setcondi_tl(TCG_COND_EQ
, t0
, t0
, imm
);
20704 gen_store_gpr(t0
, rt
);
20710 imm
= (int16_t) extract32(ctx
->opcode
, 0, 12);
20711 gen_arith_imm(ctx
, OPC_ADDIU
, rt
, rs
, -imm
);
20715 int shift
= extract32(ctx
->opcode
, 0, 5);
20716 switch (extract32(ctx
->opcode
, 5, 4)) {
20718 if (rt
== 0 && shift
== 0) {
20720 } else if (rt
== 0 && shift
== 3) {
20721 /* EHB - treat as NOP */
20722 } else if (rt
== 0 && shift
== 5) {
20723 /* PAUSE - treat as NOP */
20724 } else if (rt
== 0 && shift
== 6) {
20726 gen_sync(extract32(ctx
->opcode
, 16, 5));
20729 gen_shift_imm(ctx
, OPC_SLL
, rt
, rs
,
20730 extract32(ctx
->opcode
, 0, 5));
20734 gen_shift_imm(ctx
, OPC_SRL
, rt
, rs
,
20735 extract32(ctx
->opcode
, 0, 5));
20738 gen_shift_imm(ctx
, OPC_SRA
, rt
, rs
,
20739 extract32(ctx
->opcode
, 0, 5));
20742 gen_shift_imm(ctx
, OPC_ROTR
, rt
, rs
,
20743 extract32(ctx
->opcode
, 0, 5));
20751 TCGv t0
= tcg_temp_new();
20752 TCGv_i32 shift
= tcg_const_i32(extract32(ctx
->opcode
, 0, 5));
20753 TCGv_i32 shiftx
= tcg_const_i32(extract32(ctx
->opcode
, 7, 4)
20755 TCGv_i32 stripe
= tcg_const_i32(extract32(ctx
->opcode
, 6, 1));
20757 gen_load_gpr(t0
, rs
);
20758 gen_helper_rotx(cpu_gpr
[rt
], t0
, shift
, shiftx
, stripe
);
20761 tcg_temp_free_i32(shift
);
20762 tcg_temp_free_i32(shiftx
);
20763 tcg_temp_free_i32(stripe
);
20767 switch (((ctx
->opcode
>> 10) & 2) |
20768 (extract32(ctx
->opcode
, 5, 1))) {
20771 gen_bitops(ctx
, OPC_INS
, rt
, rs
, extract32(ctx
->opcode
, 0, 5),
20772 extract32(ctx
->opcode
, 6, 5));
20775 gen_reserved_instruction(ctx
);
20780 switch (((ctx
->opcode
>> 10) & 2) |
20781 (extract32(ctx
->opcode
, 5, 1))) {
20784 gen_bitops(ctx
, OPC_EXT
, rt
, rs
, extract32(ctx
->opcode
, 0, 5),
20785 extract32(ctx
->opcode
, 6, 5));
20788 gen_reserved_instruction(ctx
);
20793 gen_reserved_instruction(ctx
);
20798 gen_pool32f_nanomips_insn(ctx
);
20803 switch (extract32(ctx
->opcode
, 1, 1)) {
20806 tcg_gen_movi_tl(cpu_gpr
[rt
],
20807 sextract32(ctx
->opcode
, 0, 1) << 31 |
20808 extract32(ctx
->opcode
, 2, 10) << 21 |
20809 extract32(ctx
->opcode
, 12, 9) << 12);
20814 offset
= sextract32(ctx
->opcode
, 0, 1) << 31 |
20815 extract32(ctx
->opcode
, 2, 10) << 21 |
20816 extract32(ctx
->opcode
, 12, 9) << 12;
20818 addr
= ~0xFFF & addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
20819 tcg_gen_movi_tl(cpu_gpr
[rt
], addr
);
20826 uint32_t u
= extract32(ctx
->opcode
, 0, 18);
20828 switch (extract32(ctx
->opcode
, 18, 3)) {
20830 gen_ld(ctx
, OPC_LB
, rt
, 28, u
);
20833 gen_st(ctx
, OPC_SB
, rt
, 28, u
);
20836 gen_ld(ctx
, OPC_LBU
, rt
, 28, u
);
20840 gen_op_addr_addi(ctx
, cpu_gpr
[rt
], cpu_gpr
[28], u
);
20845 switch (ctx
->opcode
& 1) {
20847 gen_ld(ctx
, OPC_LH
, rt
, 28, u
);
20850 gen_ld(ctx
, OPC_LHU
, rt
, 28, u
);
20856 switch (ctx
->opcode
& 1) {
20858 gen_st(ctx
, OPC_SH
, rt
, 28, u
);
20861 gen_reserved_instruction(ctx
);
20867 switch (ctx
->opcode
& 0x3) {
20869 gen_cop1_ldst(ctx
, OPC_LWC1
, rt
, 28, u
);
20872 gen_cop1_ldst(ctx
, OPC_LDC1
, rt
, 28, u
);
20875 gen_cop1_ldst(ctx
, OPC_SWC1
, rt
, 28, u
);
20878 gen_cop1_ldst(ctx
, OPC_SDC1
, rt
, 28, u
);
20883 gen_reserved_instruction(ctx
);
20890 uint32_t u
= extract32(ctx
->opcode
, 0, 12);
20892 switch (extract32(ctx
->opcode
, 12, 4)) {
20897 * Break the TB to be able to sync copied instructions
20900 ctx
->base
.is_jmp
= DISAS_STOP
;
20903 /* Treat as NOP. */
20907 gen_ld(ctx
, OPC_LB
, rt
, rs
, u
);
20910 gen_ld(ctx
, OPC_LH
, rt
, rs
, u
);
20913 gen_ld(ctx
, OPC_LW
, rt
, rs
, u
);
20916 gen_ld(ctx
, OPC_LBU
, rt
, rs
, u
);
20919 gen_ld(ctx
, OPC_LHU
, rt
, rs
, u
);
20922 gen_st(ctx
, OPC_SB
, rt
, rs
, u
);
20925 gen_st(ctx
, OPC_SH
, rt
, rs
, u
);
20928 gen_st(ctx
, OPC_SW
, rt
, rs
, u
);
20931 gen_cop1_ldst(ctx
, OPC_LWC1
, rt
, rs
, u
);
20934 gen_cop1_ldst(ctx
, OPC_LDC1
, rt
, rs
, u
);
20937 gen_cop1_ldst(ctx
, OPC_SWC1
, rt
, rs
, u
);
20940 gen_cop1_ldst(ctx
, OPC_SDC1
, rt
, rs
, u
);
20943 gen_reserved_instruction(ctx
);
20950 int32_t s
= (sextract32(ctx
->opcode
, 15, 1) << 8) |
20951 extract32(ctx
->opcode
, 0, 8);
20953 switch (extract32(ctx
->opcode
, 8, 3)) {
20955 switch (extract32(ctx
->opcode
, 11, 4)) {
20957 gen_ld(ctx
, OPC_LB
, rt
, rs
, s
);
20960 gen_ld(ctx
, OPC_LH
, rt
, rs
, s
);
20963 gen_ld(ctx
, OPC_LW
, rt
, rs
, s
);
20966 gen_ld(ctx
, OPC_LBU
, rt
, rs
, s
);
20969 gen_ld(ctx
, OPC_LHU
, rt
, rs
, s
);
20972 gen_st(ctx
, OPC_SB
, rt
, rs
, s
);
20975 gen_st(ctx
, OPC_SH
, rt
, rs
, s
);
20978 gen_st(ctx
, OPC_SW
, rt
, rs
, s
);
20981 gen_cop1_ldst(ctx
, OPC_LWC1
, rt
, rs
, s
);
20984 gen_cop1_ldst(ctx
, OPC_LDC1
, rt
, rs
, s
);
20987 gen_cop1_ldst(ctx
, OPC_SWC1
, rt
, rs
, s
);
20990 gen_cop1_ldst(ctx
, OPC_SDC1
, rt
, rs
, s
);
20996 * Break the TB to be able to sync copied instructions
20999 ctx
->base
.is_jmp
= DISAS_STOP
;
21002 /* Treat as NOP. */
21006 gen_reserved_instruction(ctx
);
21011 switch (extract32(ctx
->opcode
, 11, 4)) {
21016 TCGv t0
= tcg_temp_new();
21017 TCGv t1
= tcg_temp_new();
21019 gen_base_offset_addr(ctx
, t0
, rs
, s
);
21021 switch (extract32(ctx
->opcode
, 11, 4)) {
21023 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESW
|
21025 gen_store_gpr(t0
, rt
);
21028 gen_load_gpr(t1
, rt
);
21029 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUW
|
21038 switch (ctx
->opcode
& 0x03) {
21040 gen_ld(ctx
, OPC_LL
, rt
, rs
, s
);
21044 gen_llwp(ctx
, rs
, 0, rt
, extract32(ctx
->opcode
, 3, 5));
21049 switch (ctx
->opcode
& 0x03) {
21051 gen_st_cond(ctx
, rt
, rs
, s
, MO_TESL
, false);
21055 gen_scwp(ctx
, rs
, 0, rt
, extract32(ctx
->opcode
, 3, 5),
21061 check_cp0_enabled(ctx
);
21062 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
21063 gen_cache_operation(ctx
, rt
, rs
, s
);
21069 switch (extract32(ctx
->opcode
, 11, 4)) {
21072 check_cp0_enabled(ctx
);
21073 gen_ld(ctx
, OPC_LBE
, rt
, rs
, s
);
21077 check_cp0_enabled(ctx
);
21078 gen_st(ctx
, OPC_SBE
, rt
, rs
, s
);
21082 check_cp0_enabled(ctx
);
21083 gen_ld(ctx
, OPC_LBUE
, rt
, rs
, s
);
21087 /* case NM_SYNCIE */
21089 check_cp0_enabled(ctx
);
21091 * Break the TB to be able to sync copied instructions
21094 ctx
->base
.is_jmp
= DISAS_STOP
;
21096 /* case NM_PREFE */
21098 check_cp0_enabled(ctx
);
21099 /* Treat as NOP. */
21104 check_cp0_enabled(ctx
);
21105 gen_ld(ctx
, OPC_LHE
, rt
, rs
, s
);
21109 check_cp0_enabled(ctx
);
21110 gen_st(ctx
, OPC_SHE
, rt
, rs
, s
);
21114 check_cp0_enabled(ctx
);
21115 gen_ld(ctx
, OPC_LHUE
, rt
, rs
, s
);
21118 check_nms_dl_il_sl_tl_l2c(ctx
);
21119 gen_cache_operation(ctx
, rt
, rs
, s
);
21123 check_cp0_enabled(ctx
);
21124 gen_ld(ctx
, OPC_LWE
, rt
, rs
, s
);
21128 check_cp0_enabled(ctx
);
21129 gen_st(ctx
, OPC_SWE
, rt
, rs
, s
);
21132 switch (extract32(ctx
->opcode
, 2, 2)) {
21136 check_cp0_enabled(ctx
);
21137 gen_ld(ctx
, OPC_LLE
, rt
, rs
, s
);
21142 check_cp0_enabled(ctx
);
21143 gen_llwp(ctx
, rs
, 0, rt
, extract32(ctx
->opcode
, 3, 5));
21146 gen_reserved_instruction(ctx
);
21151 switch (extract32(ctx
->opcode
, 2, 2)) {
21155 check_cp0_enabled(ctx
);
21156 gen_st_cond(ctx
, rt
, rs
, s
, MO_TESL
, true);
21161 check_cp0_enabled(ctx
);
21162 gen_scwp(ctx
, rs
, 0, rt
, extract32(ctx
->opcode
, 3, 5),
21166 gen_reserved_instruction(ctx
);
21176 int count
= extract32(ctx
->opcode
, 12, 3);
21179 offset
= sextract32(ctx
->opcode
, 15, 1) << 8 |
21180 extract32(ctx
->opcode
, 0, 8);
21181 TCGv va
= tcg_temp_new();
21182 TCGv t1
= tcg_temp_new();
21183 MemOp memop
= (extract32(ctx
->opcode
, 8, 3)) ==
21184 NM_P_LS_UAWM
? MO_UNALN
: 0;
21186 count
= (count
== 0) ? 8 : count
;
21187 while (counter
!= count
) {
21188 int this_rt
= ((rt
+ counter
) & 0x1f) | (rt
& 0x10);
21189 int this_offset
= offset
+ (counter
<< 2);
21191 gen_base_offset_addr(ctx
, va
, rs
, this_offset
);
21193 switch (extract32(ctx
->opcode
, 11, 1)) {
21195 tcg_gen_qemu_ld_tl(t1
, va
, ctx
->mem_idx
,
21197 gen_store_gpr(t1
, this_rt
);
21198 if ((this_rt
== rs
) &&
21199 (counter
!= (count
- 1))) {
21200 /* UNPREDICTABLE */
21204 this_rt
= (rt
== 0) ? 0 : this_rt
;
21205 gen_load_gpr(t1
, this_rt
);
21206 tcg_gen_qemu_st_tl(t1
, va
, ctx
->mem_idx
,
21217 gen_reserved_instruction(ctx
);
21225 TCGv t0
= tcg_temp_new();
21226 int32_t s
= sextract32(ctx
->opcode
, 0, 1) << 21 |
21227 extract32(ctx
->opcode
, 1, 20) << 1;
21228 rd
= (extract32(ctx
->opcode
, 24, 1)) == 0 ? 4 : 5;
21229 rt
= decode_gpr_gpr4_zero(extract32(ctx
->opcode
, 25, 1) << 3 |
21230 extract32(ctx
->opcode
, 21, 3));
21231 gen_load_gpr(t0
, rt
);
21232 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
21233 gen_compute_branch_nm(ctx
, OPC_BGEZAL
, 4, 0, 0, s
);
21239 int32_t s
= sextract32(ctx
->opcode
, 0, 1) << 25 |
21240 extract32(ctx
->opcode
, 1, 24) << 1;
21242 if ((extract32(ctx
->opcode
, 25, 1)) == 0) {
21244 gen_compute_branch_nm(ctx
, OPC_BEQ
, 4, 0, 0, s
);
21247 gen_compute_branch_nm(ctx
, OPC_BGEZAL
, 4, 0, 0, s
);
21252 switch (extract32(ctx
->opcode
, 12, 4)) {
21255 gen_compute_branch_nm(ctx
, OPC_JALR
, 4, rs
, rt
, 0);
21258 gen_compute_nanomips_pbalrsc_branch(ctx
, rs
, rt
);
21261 gen_reserved_instruction(ctx
);
21267 int32_t s
= sextract32(ctx
->opcode
, 0, 1) << 14 |
21268 extract32(ctx
->opcode
, 1, 13) << 1;
21269 switch (extract32(ctx
->opcode
, 14, 2)) {
21272 gen_compute_branch_nm(ctx
, OPC_BEQ
, 4, rs
, rt
, s
);
21275 s
= sextract32(ctx
->opcode
, 0, 1) << 14 |
21276 extract32(ctx
->opcode
, 1, 13) << 1;
21277 check_cp1_enabled(ctx
);
21278 switch (extract32(ctx
->opcode
, 16, 5)) {
21280 gen_compute_branch_cp1_nm(ctx
, OPC_BC1EQZ
, rt
, s
);
21283 gen_compute_branch_cp1_nm(ctx
, OPC_BC1NEZ
, rt
, s
);
21288 int32_t imm
= extract32(ctx
->opcode
, 1, 13) |
21289 extract32(ctx
->opcode
, 0, 1) << 13;
21291 gen_compute_branch_nm(ctx
, OPC_BPOSGE32
, 4, -1, -2,
21296 gen_reserved_instruction(ctx
);
21302 gen_compute_compact_branch_nm(ctx
, OPC_BC
, rs
, rt
, s
);
21304 gen_compute_compact_branch_nm(ctx
, OPC_BGEC
, rs
, rt
, s
);
21308 if (rs
== rt
|| rt
== 0) {
21309 gen_compute_compact_branch_nm(ctx
, OPC_BC
, 0, 0, s
);
21310 } else if (rs
== 0) {
21311 gen_compute_compact_branch_nm(ctx
, OPC_BEQZC
, rt
, 0, s
);
21313 gen_compute_compact_branch_nm(ctx
, OPC_BGEUC
, rs
, rt
, s
);
21321 int32_t s
= sextract32(ctx
->opcode
, 0, 1) << 14 |
21322 extract32(ctx
->opcode
, 1, 13) << 1;
21323 switch (extract32(ctx
->opcode
, 14, 2)) {
21326 gen_compute_branch_nm(ctx
, OPC_BNE
, 4, rs
, rt
, s
);
21329 if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
21331 ctx
->hflags
|= MIPS_HFLAG_FBNSLOT
;
21333 gen_compute_compact_branch_nm(ctx
, OPC_BLTC
, rs
, rt
, s
);
21337 if (rs
== 0 || rs
== rt
) {
21339 ctx
->hflags
|= MIPS_HFLAG_FBNSLOT
;
21341 gen_compute_compact_branch_nm(ctx
, OPC_BLTUC
, rs
, rt
, s
);
21345 gen_reserved_instruction(ctx
);
21352 int32_t s
= sextract32(ctx
->opcode
, 0, 1) << 11 |
21353 extract32(ctx
->opcode
, 1, 10) << 1;
21354 uint32_t u
= extract32(ctx
->opcode
, 11, 7);
21356 gen_compute_imm_branch(ctx
, extract32(ctx
->opcode
, 18, 3),
21361 gen_reserved_instruction(ctx
);
21367 static int decode_nanomips_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
21370 int rt
= decode_gpr_gpr3(NANOMIPS_EXTRACT_RT3(ctx
->opcode
));
21371 int rs
= decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx
->opcode
));
21372 int rd
= decode_gpr_gpr3(NANOMIPS_EXTRACT_RD3(ctx
->opcode
));
21376 /* make sure instructions are on a halfword boundary */
21377 if (ctx
->base
.pc_next
& 0x1) {
21378 TCGv tmp
= tcg_const_tl(ctx
->base
.pc_next
);
21379 tcg_gen_st_tl(tmp
, cpu_env
, offsetof(CPUMIPSState
, CP0_BadVAddr
));
21380 tcg_temp_free(tmp
);
21381 generate_exception_end(ctx
, EXCP_AdEL
);
21385 op
= extract32(ctx
->opcode
, 10, 6);
21388 rt
= NANOMIPS_EXTRACT_RD5(ctx
->opcode
);
21391 rs
= NANOMIPS_EXTRACT_RS5(ctx
->opcode
);
21392 gen_arith(ctx
, OPC_ADDU
, rt
, rs
, 0);
21395 switch (extract32(ctx
->opcode
, 3, 2)) {
21396 case NM_P16_SYSCALL
:
21397 if (extract32(ctx
->opcode
, 2, 1) == 0) {
21398 generate_exception_end(ctx
, EXCP_SYSCALL
);
21400 gen_reserved_instruction(ctx
);
21404 generate_exception_end(ctx
, EXCP_BREAK
);
21407 if (is_uhi(extract32(ctx
->opcode
, 0, 3))) {
21408 gen_helper_do_semihosting(cpu_env
);
21410 if (ctx
->hflags
& MIPS_HFLAG_SBRI
) {
21411 gen_reserved_instruction(ctx
);
21413 generate_exception_end(ctx
, EXCP_DBp
);
21418 gen_reserved_instruction(ctx
);
21425 int shift
= extract32(ctx
->opcode
, 0, 3);
21427 shift
= (shift
== 0) ? 8 : shift
;
21429 switch (extract32(ctx
->opcode
, 3, 1)) {
21437 gen_shift_imm(ctx
, opc
, rt
, rs
, shift
);
21441 switch (ctx
->opcode
& 1) {
21443 gen_pool16c_nanomips_insn(ctx
);
21446 gen_ldxs(ctx
, rt
, rs
, rd
);
21451 switch (extract32(ctx
->opcode
, 6, 1)) {
21453 imm
= extract32(ctx
->opcode
, 0, 6) << 2;
21454 gen_arith_imm(ctx
, OPC_ADDIU
, rt
, 29, imm
);
21457 gen_reserved_instruction(ctx
);
21462 switch (extract32(ctx
->opcode
, 3, 1)) {
21464 imm
= extract32(ctx
->opcode
, 0, 3) << 2;
21465 gen_arith_imm(ctx
, OPC_ADDIU
, rt
, rs
, imm
);
21467 case NM_P_ADDIURS5
:
21468 rt
= extract32(ctx
->opcode
, 5, 5);
21470 /* imm = sign_extend(s[3] . s[2:0] , from_nbits = 4) */
21471 imm
= (sextract32(ctx
->opcode
, 4, 1) << 3) |
21472 (extract32(ctx
->opcode
, 0, 3));
21473 gen_arith_imm(ctx
, OPC_ADDIU
, rt
, rt
, imm
);
21479 switch (ctx
->opcode
& 0x1) {
21481 gen_arith(ctx
, OPC_ADDU
, rd
, rs
, rt
);
21484 gen_arith(ctx
, OPC_SUBU
, rd
, rs
, rt
);
21489 rt
= (extract32(ctx
->opcode
, 9, 1) << 3) |
21490 extract32(ctx
->opcode
, 5, 3);
21491 rs
= (extract32(ctx
->opcode
, 4, 1) << 3) |
21492 extract32(ctx
->opcode
, 0, 3);
21493 rt
= decode_gpr_gpr4(rt
);
21494 rs
= decode_gpr_gpr4(rs
);
21495 switch ((extract32(ctx
->opcode
, 7, 2) & 0x2) |
21496 (extract32(ctx
->opcode
, 3, 1))) {
21499 gen_arith(ctx
, OPC_ADDU
, rt
, rs
, rt
);
21503 gen_r6_muldiv(ctx
, R6_OPC_MUL
, rt
, rs
, rt
);
21506 gen_reserved_instruction(ctx
);
21512 int imm
= extract32(ctx
->opcode
, 0, 7);
21513 imm
= (imm
== 0x7f ? -1 : imm
);
21515 tcg_gen_movi_tl(cpu_gpr
[rt
], imm
);
21521 uint32_t u
= extract32(ctx
->opcode
, 0, 4);
21522 u
= (u
== 12) ? 0xff :
21523 (u
== 13) ? 0xffff : u
;
21524 gen_logic_imm(ctx
, OPC_ANDI
, rt
, rs
, u
);
21528 offset
= extract32(ctx
->opcode
, 0, 2);
21529 switch (extract32(ctx
->opcode
, 2, 2)) {
21531 gen_ld(ctx
, OPC_LB
, rt
, rs
, offset
);
21534 rt
= decode_gpr_gpr3_src_store(
21535 NANOMIPS_EXTRACT_RT3(ctx
->opcode
));
21536 gen_st(ctx
, OPC_SB
, rt
, rs
, offset
);
21539 gen_ld(ctx
, OPC_LBU
, rt
, rs
, offset
);
21542 gen_reserved_instruction(ctx
);
21547 offset
= extract32(ctx
->opcode
, 1, 2) << 1;
21548 switch ((extract32(ctx
->opcode
, 3, 1) << 1) | (ctx
->opcode
& 1)) {
21550 gen_ld(ctx
, OPC_LH
, rt
, rs
, offset
);
21553 rt
= decode_gpr_gpr3_src_store(
21554 NANOMIPS_EXTRACT_RT3(ctx
->opcode
));
21555 gen_st(ctx
, OPC_SH
, rt
, rs
, offset
);
21558 gen_ld(ctx
, OPC_LHU
, rt
, rs
, offset
);
21561 gen_reserved_instruction(ctx
);
21566 offset
= extract32(ctx
->opcode
, 0, 4) << 2;
21567 gen_ld(ctx
, OPC_LW
, rt
, rs
, offset
);
21570 rt
= NANOMIPS_EXTRACT_RD5(ctx
->opcode
);
21571 offset
= extract32(ctx
->opcode
, 0, 5) << 2;
21572 gen_ld(ctx
, OPC_LW
, rt
, 29, offset
);
21576 rt
= (extract32(ctx
->opcode
, 9, 1) << 3) |
21577 extract32(ctx
->opcode
, 5, 3);
21578 rs
= (extract32(ctx
->opcode
, 4, 1) << 3) |
21579 extract32(ctx
->opcode
, 0, 3);
21580 offset
= (extract32(ctx
->opcode
, 3, 1) << 3) |
21581 (extract32(ctx
->opcode
, 8, 1) << 2);
21582 rt
= decode_gpr_gpr4(rt
);
21583 rs
= decode_gpr_gpr4(rs
);
21584 gen_ld(ctx
, OPC_LW
, rt
, rs
, offset
);
21588 rt
= (extract32(ctx
->opcode
, 9, 1) << 3) |
21589 extract32(ctx
->opcode
, 5, 3);
21590 rs
= (extract32(ctx
->opcode
, 4, 1) << 3) |
21591 extract32(ctx
->opcode
, 0, 3);
21592 offset
= (extract32(ctx
->opcode
, 3, 1) << 3) |
21593 (extract32(ctx
->opcode
, 8, 1) << 2);
21594 rt
= decode_gpr_gpr4_zero(rt
);
21595 rs
= decode_gpr_gpr4(rs
);
21596 gen_st(ctx
, OPC_SW
, rt
, rs
, offset
);
21599 offset
= extract32(ctx
->opcode
, 0, 7) << 2;
21600 gen_ld(ctx
, OPC_LW
, rt
, 28, offset
);
21603 rt
= NANOMIPS_EXTRACT_RD5(ctx
->opcode
);
21604 offset
= extract32(ctx
->opcode
, 0, 5) << 2;
21605 gen_st(ctx
, OPC_SW
, rt
, 29, offset
);
21608 rt
= decode_gpr_gpr3_src_store(
21609 NANOMIPS_EXTRACT_RT3(ctx
->opcode
));
21610 rs
= decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx
->opcode
));
21611 offset
= extract32(ctx
->opcode
, 0, 4) << 2;
21612 gen_st(ctx
, OPC_SW
, rt
, rs
, offset
);
21615 rt
= decode_gpr_gpr3_src_store(
21616 NANOMIPS_EXTRACT_RT3(ctx
->opcode
));
21617 offset
= extract32(ctx
->opcode
, 0, 7) << 2;
21618 gen_st(ctx
, OPC_SW
, rt
, 28, offset
);
21621 gen_compute_branch_nm(ctx
, OPC_BEQ
, 2, 0, 0,
21622 (sextract32(ctx
->opcode
, 0, 1) << 10) |
21623 (extract32(ctx
->opcode
, 1, 9) << 1));
21626 gen_compute_branch_nm(ctx
, OPC_BGEZAL
, 2, 0, 0,
21627 (sextract32(ctx
->opcode
, 0, 1) << 10) |
21628 (extract32(ctx
->opcode
, 1, 9) << 1));
21631 gen_compute_branch_nm(ctx
, OPC_BEQ
, 2, rt
, 0,
21632 (sextract32(ctx
->opcode
, 0, 1) << 7) |
21633 (extract32(ctx
->opcode
, 1, 6) << 1));
21636 gen_compute_branch_nm(ctx
, OPC_BNE
, 2, rt
, 0,
21637 (sextract32(ctx
->opcode
, 0, 1) << 7) |
21638 (extract32(ctx
->opcode
, 1, 6) << 1));
21641 switch (ctx
->opcode
& 0xf) {
21644 switch (extract32(ctx
->opcode
, 4, 1)) {
21646 gen_compute_branch_nm(ctx
, OPC_JR
, 2,
21647 extract32(ctx
->opcode
, 5, 5), 0, 0);
21650 gen_compute_branch_nm(ctx
, OPC_JALR
, 2,
21651 extract32(ctx
->opcode
, 5, 5), 31, 0);
21658 uint32_t opc
= extract32(ctx
->opcode
, 4, 3) <
21659 extract32(ctx
->opcode
, 7, 3) ? OPC_BEQ
: OPC_BNE
;
21660 gen_compute_branch_nm(ctx
, opc
, 2, rs
, rt
,
21661 extract32(ctx
->opcode
, 0, 4) << 1);
21668 int count
= extract32(ctx
->opcode
, 0, 4);
21669 int u
= extract32(ctx
->opcode
, 4, 4) << 4;
21671 rt
= 30 + extract32(ctx
->opcode
, 9, 1);
21672 switch (extract32(ctx
->opcode
, 8, 1)) {
21674 gen_save(ctx
, rt
, count
, 0, u
);
21676 case NM_RESTORE_JRC16
:
21677 gen_restore(ctx
, rt
, count
, 0, u
);
21678 gen_compute_branch_nm(ctx
, OPC_JR
, 2, 31, 0, 0);
21687 static const int gpr2reg1
[] = {4, 5, 6, 7};
21688 static const int gpr2reg2
[] = {5, 6, 7, 8};
21690 int rd2
= extract32(ctx
->opcode
, 3, 1) << 1 |
21691 extract32(ctx
->opcode
, 8, 1);
21692 int r1
= gpr2reg1
[rd2
];
21693 int r2
= gpr2reg2
[rd2
];
21694 int r3
= extract32(ctx
->opcode
, 4, 1) << 3 |
21695 extract32(ctx
->opcode
, 0, 3);
21696 int r4
= extract32(ctx
->opcode
, 9, 1) << 3 |
21697 extract32(ctx
->opcode
, 5, 3);
21698 TCGv t0
= tcg_temp_new();
21699 TCGv t1
= tcg_temp_new();
21700 if (op
== NM_MOVEP
) {
21703 rs
= decode_gpr_gpr4_zero(r3
);
21704 rt
= decode_gpr_gpr4_zero(r4
);
21706 rd
= decode_gpr_gpr4(r3
);
21707 re
= decode_gpr_gpr4(r4
);
21711 gen_load_gpr(t0
, rs
);
21712 gen_load_gpr(t1
, rt
);
21713 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
21714 tcg_gen_mov_tl(cpu_gpr
[re
], t1
);
21720 return decode_nanomips_32_48_opc(env
, ctx
);
21727 /* SmartMIPS extension to MIPS32 */
21729 #if defined(TARGET_MIPS64)
21731 /* MDMX extension to MIPS64 */
21735 /* MIPSDSP functions. */
21736 static void gen_mipsdsp_ld(DisasContext
*ctx
, uint32_t opc
,
21737 int rd
, int base
, int offset
)
21742 t0
= tcg_temp_new();
21745 gen_load_gpr(t0
, offset
);
21746 } else if (offset
== 0) {
21747 gen_load_gpr(t0
, base
);
21749 gen_op_addr_add(ctx
, t0
, cpu_gpr
[base
], cpu_gpr
[offset
]);
21754 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_UB
);
21755 gen_store_gpr(t0
, rd
);
21758 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESW
);
21759 gen_store_gpr(t0
, rd
);
21762 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESL
);
21763 gen_store_gpr(t0
, rd
);
21765 #if defined(TARGET_MIPS64)
21767 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
);
21768 gen_store_gpr(t0
, rd
);
21775 static void gen_mipsdsp_arith(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
21776 int ret
, int v1
, int v2
)
21782 /* Treat as NOP. */
21786 v1_t
= tcg_temp_new();
21787 v2_t
= tcg_temp_new();
21789 gen_load_gpr(v1_t
, v1
);
21790 gen_load_gpr(v2_t
, v2
);
21793 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
21794 case OPC_MULT_G_2E
:
21798 gen_helper_adduh_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
21800 case OPC_ADDUH_R_QB
:
21801 gen_helper_adduh_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
21804 gen_helper_addqh_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
21806 case OPC_ADDQH_R_PH
:
21807 gen_helper_addqh_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
21810 gen_helper_addqh_w(cpu_gpr
[ret
], v1_t
, v2_t
);
21812 case OPC_ADDQH_R_W
:
21813 gen_helper_addqh_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
21816 gen_helper_subuh_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
21818 case OPC_SUBUH_R_QB
:
21819 gen_helper_subuh_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
21822 gen_helper_subqh_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
21824 case OPC_SUBQH_R_PH
:
21825 gen_helper_subqh_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
21828 gen_helper_subqh_w(cpu_gpr
[ret
], v1_t
, v2_t
);
21830 case OPC_SUBQH_R_W
:
21831 gen_helper_subqh_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
21835 case OPC_ABSQ_S_PH_DSP
:
21837 case OPC_ABSQ_S_QB
:
21839 gen_helper_absq_s_qb(cpu_gpr
[ret
], v2_t
, cpu_env
);
21841 case OPC_ABSQ_S_PH
:
21843 gen_helper_absq_s_ph(cpu_gpr
[ret
], v2_t
, cpu_env
);
21847 gen_helper_absq_s_w(cpu_gpr
[ret
], v2_t
, cpu_env
);
21849 case OPC_PRECEQ_W_PHL
:
21851 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0xFFFF0000);
21852 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
21854 case OPC_PRECEQ_W_PHR
:
21856 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0x0000FFFF);
21857 tcg_gen_shli_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], 16);
21858 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
21860 case OPC_PRECEQU_PH_QBL
:
21862 gen_helper_precequ_ph_qbl(cpu_gpr
[ret
], v2_t
);
21864 case OPC_PRECEQU_PH_QBR
:
21866 gen_helper_precequ_ph_qbr(cpu_gpr
[ret
], v2_t
);
21868 case OPC_PRECEQU_PH_QBLA
:
21870 gen_helper_precequ_ph_qbla(cpu_gpr
[ret
], v2_t
);
21872 case OPC_PRECEQU_PH_QBRA
:
21874 gen_helper_precequ_ph_qbra(cpu_gpr
[ret
], v2_t
);
21876 case OPC_PRECEU_PH_QBL
:
21878 gen_helper_preceu_ph_qbl(cpu_gpr
[ret
], v2_t
);
21880 case OPC_PRECEU_PH_QBR
:
21882 gen_helper_preceu_ph_qbr(cpu_gpr
[ret
], v2_t
);
21884 case OPC_PRECEU_PH_QBLA
:
21886 gen_helper_preceu_ph_qbla(cpu_gpr
[ret
], v2_t
);
21888 case OPC_PRECEU_PH_QBRA
:
21890 gen_helper_preceu_ph_qbra(cpu_gpr
[ret
], v2_t
);
21894 case OPC_ADDU_QB_DSP
:
21898 gen_helper_addq_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21900 case OPC_ADDQ_S_PH
:
21902 gen_helper_addq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21906 gen_helper_addq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21910 gen_helper_addu_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21912 case OPC_ADDU_S_QB
:
21914 gen_helper_addu_s_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21918 gen_helper_addu_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21920 case OPC_ADDU_S_PH
:
21922 gen_helper_addu_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21926 gen_helper_subq_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21928 case OPC_SUBQ_S_PH
:
21930 gen_helper_subq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21934 gen_helper_subq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21938 gen_helper_subu_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21940 case OPC_SUBU_S_QB
:
21942 gen_helper_subu_s_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21946 gen_helper_subu_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21948 case OPC_SUBU_S_PH
:
21950 gen_helper_subu_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21954 gen_helper_addsc(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21958 gen_helper_addwc(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21962 gen_helper_modsub(cpu_gpr
[ret
], v1_t
, v2_t
);
21964 case OPC_RADDU_W_QB
:
21966 gen_helper_raddu_w_qb(cpu_gpr
[ret
], v1_t
);
21970 case OPC_CMPU_EQ_QB_DSP
:
21972 case OPC_PRECR_QB_PH
:
21974 gen_helper_precr_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
21976 case OPC_PRECRQ_QB_PH
:
21978 gen_helper_precrq_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
21980 case OPC_PRECR_SRA_PH_W
:
21983 TCGv_i32 sa_t
= tcg_const_i32(v2
);
21984 gen_helper_precr_sra_ph_w(cpu_gpr
[ret
], sa_t
, v1_t
,
21986 tcg_temp_free_i32(sa_t
);
21989 case OPC_PRECR_SRA_R_PH_W
:
21992 TCGv_i32 sa_t
= tcg_const_i32(v2
);
21993 gen_helper_precr_sra_r_ph_w(cpu_gpr
[ret
], sa_t
, v1_t
,
21995 tcg_temp_free_i32(sa_t
);
21998 case OPC_PRECRQ_PH_W
:
22000 gen_helper_precrq_ph_w(cpu_gpr
[ret
], v1_t
, v2_t
);
22002 case OPC_PRECRQ_RS_PH_W
:
22004 gen_helper_precrq_rs_ph_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22006 case OPC_PRECRQU_S_QB_PH
:
22008 gen_helper_precrqu_s_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22012 #ifdef TARGET_MIPS64
22013 case OPC_ABSQ_S_QH_DSP
:
22015 case OPC_PRECEQ_L_PWL
:
22017 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0xFFFFFFFF00000000ull
);
22019 case OPC_PRECEQ_L_PWR
:
22021 tcg_gen_shli_tl(cpu_gpr
[ret
], v2_t
, 32);
22023 case OPC_PRECEQ_PW_QHL
:
22025 gen_helper_preceq_pw_qhl(cpu_gpr
[ret
], v2_t
);
22027 case OPC_PRECEQ_PW_QHR
:
22029 gen_helper_preceq_pw_qhr(cpu_gpr
[ret
], v2_t
);
22031 case OPC_PRECEQ_PW_QHLA
:
22033 gen_helper_preceq_pw_qhla(cpu_gpr
[ret
], v2_t
);
22035 case OPC_PRECEQ_PW_QHRA
:
22037 gen_helper_preceq_pw_qhra(cpu_gpr
[ret
], v2_t
);
22039 case OPC_PRECEQU_QH_OBL
:
22041 gen_helper_precequ_qh_obl(cpu_gpr
[ret
], v2_t
);
22043 case OPC_PRECEQU_QH_OBR
:
22045 gen_helper_precequ_qh_obr(cpu_gpr
[ret
], v2_t
);
22047 case OPC_PRECEQU_QH_OBLA
:
22049 gen_helper_precequ_qh_obla(cpu_gpr
[ret
], v2_t
);
22051 case OPC_PRECEQU_QH_OBRA
:
22053 gen_helper_precequ_qh_obra(cpu_gpr
[ret
], v2_t
);
22055 case OPC_PRECEU_QH_OBL
:
22057 gen_helper_preceu_qh_obl(cpu_gpr
[ret
], v2_t
);
22059 case OPC_PRECEU_QH_OBR
:
22061 gen_helper_preceu_qh_obr(cpu_gpr
[ret
], v2_t
);
22063 case OPC_PRECEU_QH_OBLA
:
22065 gen_helper_preceu_qh_obla(cpu_gpr
[ret
], v2_t
);
22067 case OPC_PRECEU_QH_OBRA
:
22069 gen_helper_preceu_qh_obra(cpu_gpr
[ret
], v2_t
);
22071 case OPC_ABSQ_S_OB
:
22073 gen_helper_absq_s_ob(cpu_gpr
[ret
], v2_t
, cpu_env
);
22075 case OPC_ABSQ_S_PW
:
22077 gen_helper_absq_s_pw(cpu_gpr
[ret
], v2_t
, cpu_env
);
22079 case OPC_ABSQ_S_QH
:
22081 gen_helper_absq_s_qh(cpu_gpr
[ret
], v2_t
, cpu_env
);
22085 case OPC_ADDU_OB_DSP
:
22087 case OPC_RADDU_L_OB
:
22089 gen_helper_raddu_l_ob(cpu_gpr
[ret
], v1_t
);
22093 gen_helper_subq_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22095 case OPC_SUBQ_S_PW
:
22097 gen_helper_subq_s_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22101 gen_helper_subq_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22103 case OPC_SUBQ_S_QH
:
22105 gen_helper_subq_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22109 gen_helper_subu_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22111 case OPC_SUBU_S_OB
:
22113 gen_helper_subu_s_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22117 gen_helper_subu_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22119 case OPC_SUBU_S_QH
:
22121 gen_helper_subu_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22125 gen_helper_subuh_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
22127 case OPC_SUBUH_R_OB
:
22129 gen_helper_subuh_r_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
22133 gen_helper_addq_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22135 case OPC_ADDQ_S_PW
:
22137 gen_helper_addq_s_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22141 gen_helper_addq_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22143 case OPC_ADDQ_S_QH
:
22145 gen_helper_addq_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22149 gen_helper_addu_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22151 case OPC_ADDU_S_OB
:
22153 gen_helper_addu_s_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22157 gen_helper_addu_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22159 case OPC_ADDU_S_QH
:
22161 gen_helper_addu_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22165 gen_helper_adduh_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
22167 case OPC_ADDUH_R_OB
:
22169 gen_helper_adduh_r_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
22173 case OPC_CMPU_EQ_OB_DSP
:
22175 case OPC_PRECR_OB_QH
:
22177 gen_helper_precr_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
);
22179 case OPC_PRECR_SRA_QH_PW
:
22182 TCGv_i32 ret_t
= tcg_const_i32(ret
);
22183 gen_helper_precr_sra_qh_pw(v2_t
, v1_t
, v2_t
, ret_t
);
22184 tcg_temp_free_i32(ret_t
);
22187 case OPC_PRECR_SRA_R_QH_PW
:
22190 TCGv_i32 sa_v
= tcg_const_i32(ret
);
22191 gen_helper_precr_sra_r_qh_pw(v2_t
, v1_t
, v2_t
, sa_v
);
22192 tcg_temp_free_i32(sa_v
);
22195 case OPC_PRECRQ_OB_QH
:
22197 gen_helper_precrq_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
);
22199 case OPC_PRECRQ_PW_L
:
22201 gen_helper_precrq_pw_l(cpu_gpr
[ret
], v1_t
, v2_t
);
22203 case OPC_PRECRQ_QH_PW
:
22205 gen_helper_precrq_qh_pw(cpu_gpr
[ret
], v1_t
, v2_t
);
22207 case OPC_PRECRQ_RS_QH_PW
:
22209 gen_helper_precrq_rs_qh_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22211 case OPC_PRECRQU_S_OB_QH
:
22213 gen_helper_precrqu_s_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22220 tcg_temp_free(v1_t
);
22221 tcg_temp_free(v2_t
);
22224 static void gen_mipsdsp_shift(DisasContext
*ctx
, uint32_t opc
,
22225 int ret
, int v1
, int v2
)
22233 /* Treat as NOP. */
22237 t0
= tcg_temp_new();
22238 v1_t
= tcg_temp_new();
22239 v2_t
= tcg_temp_new();
22241 tcg_gen_movi_tl(t0
, v1
);
22242 gen_load_gpr(v1_t
, v1
);
22243 gen_load_gpr(v2_t
, v2
);
22246 case OPC_SHLL_QB_DSP
:
22248 op2
= MASK_SHLL_QB(ctx
->opcode
);
22252 gen_helper_shll_qb(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
22256 gen_helper_shll_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22260 gen_helper_shll_ph(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
22264 gen_helper_shll_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22266 case OPC_SHLL_S_PH
:
22268 gen_helper_shll_s_ph(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
22270 case OPC_SHLLV_S_PH
:
22272 gen_helper_shll_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22276 gen_helper_shll_s_w(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
22278 case OPC_SHLLV_S_W
:
22280 gen_helper_shll_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22284 gen_helper_shrl_qb(cpu_gpr
[ret
], t0
, v2_t
);
22288 gen_helper_shrl_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
22292 gen_helper_shrl_ph(cpu_gpr
[ret
], t0
, v2_t
);
22296 gen_helper_shrl_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
22300 gen_helper_shra_qb(cpu_gpr
[ret
], t0
, v2_t
);
22302 case OPC_SHRA_R_QB
:
22304 gen_helper_shra_r_qb(cpu_gpr
[ret
], t0
, v2_t
);
22308 gen_helper_shra_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
22310 case OPC_SHRAV_R_QB
:
22312 gen_helper_shra_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
22316 gen_helper_shra_ph(cpu_gpr
[ret
], t0
, v2_t
);
22318 case OPC_SHRA_R_PH
:
22320 gen_helper_shra_r_ph(cpu_gpr
[ret
], t0
, v2_t
);
22324 gen_helper_shra_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
22326 case OPC_SHRAV_R_PH
:
22328 gen_helper_shra_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
22332 gen_helper_shra_r_w(cpu_gpr
[ret
], t0
, v2_t
);
22334 case OPC_SHRAV_R_W
:
22336 gen_helper_shra_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
22338 default: /* Invalid */
22339 MIPS_INVAL("MASK SHLL.QB");
22340 gen_reserved_instruction(ctx
);
22345 #ifdef TARGET_MIPS64
22346 case OPC_SHLL_OB_DSP
:
22347 op2
= MASK_SHLL_OB(ctx
->opcode
);
22351 gen_helper_shll_pw(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
22355 gen_helper_shll_pw(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
22357 case OPC_SHLL_S_PW
:
22359 gen_helper_shll_s_pw(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
22361 case OPC_SHLLV_S_PW
:
22363 gen_helper_shll_s_pw(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
22367 gen_helper_shll_ob(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
22371 gen_helper_shll_ob(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
22375 gen_helper_shll_qh(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
22379 gen_helper_shll_qh(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
22381 case OPC_SHLL_S_QH
:
22383 gen_helper_shll_s_qh(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
22385 case OPC_SHLLV_S_QH
:
22387 gen_helper_shll_s_qh(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
22391 gen_helper_shra_ob(cpu_gpr
[ret
], v2_t
, t0
);
22395 gen_helper_shra_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
22397 case OPC_SHRA_R_OB
:
22399 gen_helper_shra_r_ob(cpu_gpr
[ret
], v2_t
, t0
);
22401 case OPC_SHRAV_R_OB
:
22403 gen_helper_shra_r_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
22407 gen_helper_shra_pw(cpu_gpr
[ret
], v2_t
, t0
);
22411 gen_helper_shra_pw(cpu_gpr
[ret
], v2_t
, v1_t
);
22413 case OPC_SHRA_R_PW
:
22415 gen_helper_shra_r_pw(cpu_gpr
[ret
], v2_t
, t0
);
22417 case OPC_SHRAV_R_PW
:
22419 gen_helper_shra_r_pw(cpu_gpr
[ret
], v2_t
, v1_t
);
22423 gen_helper_shra_qh(cpu_gpr
[ret
], v2_t
, t0
);
22427 gen_helper_shra_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
22429 case OPC_SHRA_R_QH
:
22431 gen_helper_shra_r_qh(cpu_gpr
[ret
], v2_t
, t0
);
22433 case OPC_SHRAV_R_QH
:
22435 gen_helper_shra_r_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
22439 gen_helper_shrl_ob(cpu_gpr
[ret
], v2_t
, t0
);
22443 gen_helper_shrl_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
22447 gen_helper_shrl_qh(cpu_gpr
[ret
], v2_t
, t0
);
22451 gen_helper_shrl_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
22453 default: /* Invalid */
22454 MIPS_INVAL("MASK SHLL.OB");
22455 gen_reserved_instruction(ctx
);
22463 tcg_temp_free(v1_t
);
22464 tcg_temp_free(v2_t
);
22467 static void gen_mipsdsp_multiply(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
22468 int ret
, int v1
, int v2
, int check_ret
)
22474 if ((ret
== 0) && (check_ret
== 1)) {
22475 /* Treat as NOP. */
22479 t0
= tcg_temp_new_i32();
22480 v1_t
= tcg_temp_new();
22481 v2_t
= tcg_temp_new();
22483 tcg_gen_movi_i32(t0
, ret
);
22484 gen_load_gpr(v1_t
, v1
);
22485 gen_load_gpr(v2_t
, v2
);
22489 * OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
22490 * the same mask and op1.
22492 case OPC_MULT_G_2E
:
22496 gen_helper_mul_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22499 gen_helper_mul_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22502 gen_helper_mulq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22504 case OPC_MULQ_RS_W
:
22505 gen_helper_mulq_rs_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22509 case OPC_DPA_W_PH_DSP
:
22511 case OPC_DPAU_H_QBL
:
22513 gen_helper_dpau_h_qbl(t0
, v1_t
, v2_t
, cpu_env
);
22515 case OPC_DPAU_H_QBR
:
22517 gen_helper_dpau_h_qbr(t0
, v1_t
, v2_t
, cpu_env
);
22519 case OPC_DPSU_H_QBL
:
22521 gen_helper_dpsu_h_qbl(t0
, v1_t
, v2_t
, cpu_env
);
22523 case OPC_DPSU_H_QBR
:
22525 gen_helper_dpsu_h_qbr(t0
, v1_t
, v2_t
, cpu_env
);
22529 gen_helper_dpa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
22531 case OPC_DPAX_W_PH
:
22533 gen_helper_dpax_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
22535 case OPC_DPAQ_S_W_PH
:
22537 gen_helper_dpaq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
22539 case OPC_DPAQX_S_W_PH
:
22541 gen_helper_dpaqx_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
22543 case OPC_DPAQX_SA_W_PH
:
22545 gen_helper_dpaqx_sa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
22549 gen_helper_dps_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
22551 case OPC_DPSX_W_PH
:
22553 gen_helper_dpsx_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
22555 case OPC_DPSQ_S_W_PH
:
22557 gen_helper_dpsq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
22559 case OPC_DPSQX_S_W_PH
:
22561 gen_helper_dpsqx_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
22563 case OPC_DPSQX_SA_W_PH
:
22565 gen_helper_dpsqx_sa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
22567 case OPC_MULSAQ_S_W_PH
:
22569 gen_helper_mulsaq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
22571 case OPC_DPAQ_SA_L_W
:
22573 gen_helper_dpaq_sa_l_w(t0
, v1_t
, v2_t
, cpu_env
);
22575 case OPC_DPSQ_SA_L_W
:
22577 gen_helper_dpsq_sa_l_w(t0
, v1_t
, v2_t
, cpu_env
);
22579 case OPC_MAQ_S_W_PHL
:
22581 gen_helper_maq_s_w_phl(t0
, v1_t
, v2_t
, cpu_env
);
22583 case OPC_MAQ_S_W_PHR
:
22585 gen_helper_maq_s_w_phr(t0
, v1_t
, v2_t
, cpu_env
);
22587 case OPC_MAQ_SA_W_PHL
:
22589 gen_helper_maq_sa_w_phl(t0
, v1_t
, v2_t
, cpu_env
);
22591 case OPC_MAQ_SA_W_PHR
:
22593 gen_helper_maq_sa_w_phr(t0
, v1_t
, v2_t
, cpu_env
);
22595 case OPC_MULSA_W_PH
:
22597 gen_helper_mulsa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
22601 #ifdef TARGET_MIPS64
22602 case OPC_DPAQ_W_QH_DSP
:
22604 int ac
= ret
& 0x03;
22605 tcg_gen_movi_i32(t0
, ac
);
22610 gen_helper_dmadd(v1_t
, v2_t
, t0
, cpu_env
);
22614 gen_helper_dmaddu(v1_t
, v2_t
, t0
, cpu_env
);
22618 gen_helper_dmsub(v1_t
, v2_t
, t0
, cpu_env
);
22622 gen_helper_dmsubu(v1_t
, v2_t
, t0
, cpu_env
);
22626 gen_helper_dpa_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
22628 case OPC_DPAQ_S_W_QH
:
22630 gen_helper_dpaq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
22632 case OPC_DPAQ_SA_L_PW
:
22634 gen_helper_dpaq_sa_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
22636 case OPC_DPAU_H_OBL
:
22638 gen_helper_dpau_h_obl(v1_t
, v2_t
, t0
, cpu_env
);
22640 case OPC_DPAU_H_OBR
:
22642 gen_helper_dpau_h_obr(v1_t
, v2_t
, t0
, cpu_env
);
22646 gen_helper_dps_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
22648 case OPC_DPSQ_S_W_QH
:
22650 gen_helper_dpsq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
22652 case OPC_DPSQ_SA_L_PW
:
22654 gen_helper_dpsq_sa_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
22656 case OPC_DPSU_H_OBL
:
22658 gen_helper_dpsu_h_obl(v1_t
, v2_t
, t0
, cpu_env
);
22660 case OPC_DPSU_H_OBR
:
22662 gen_helper_dpsu_h_obr(v1_t
, v2_t
, t0
, cpu_env
);
22664 case OPC_MAQ_S_L_PWL
:
22666 gen_helper_maq_s_l_pwl(v1_t
, v2_t
, t0
, cpu_env
);
22668 case OPC_MAQ_S_L_PWR
:
22670 gen_helper_maq_s_l_pwr(v1_t
, v2_t
, t0
, cpu_env
);
22672 case OPC_MAQ_S_W_QHLL
:
22674 gen_helper_maq_s_w_qhll(v1_t
, v2_t
, t0
, cpu_env
);
22676 case OPC_MAQ_SA_W_QHLL
:
22678 gen_helper_maq_sa_w_qhll(v1_t
, v2_t
, t0
, cpu_env
);
22680 case OPC_MAQ_S_W_QHLR
:
22682 gen_helper_maq_s_w_qhlr(v1_t
, v2_t
, t0
, cpu_env
);
22684 case OPC_MAQ_SA_W_QHLR
:
22686 gen_helper_maq_sa_w_qhlr(v1_t
, v2_t
, t0
, cpu_env
);
22688 case OPC_MAQ_S_W_QHRL
:
22690 gen_helper_maq_s_w_qhrl(v1_t
, v2_t
, t0
, cpu_env
);
22692 case OPC_MAQ_SA_W_QHRL
:
22694 gen_helper_maq_sa_w_qhrl(v1_t
, v2_t
, t0
, cpu_env
);
22696 case OPC_MAQ_S_W_QHRR
:
22698 gen_helper_maq_s_w_qhrr(v1_t
, v2_t
, t0
, cpu_env
);
22700 case OPC_MAQ_SA_W_QHRR
:
22702 gen_helper_maq_sa_w_qhrr(v1_t
, v2_t
, t0
, cpu_env
);
22704 case OPC_MULSAQ_S_L_PW
:
22706 gen_helper_mulsaq_s_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
22708 case OPC_MULSAQ_S_W_QH
:
22710 gen_helper_mulsaq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
22716 case OPC_ADDU_QB_DSP
:
22718 case OPC_MULEU_S_PH_QBL
:
22720 gen_helper_muleu_s_ph_qbl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22722 case OPC_MULEU_S_PH_QBR
:
22724 gen_helper_muleu_s_ph_qbr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22726 case OPC_MULQ_RS_PH
:
22728 gen_helper_mulq_rs_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22730 case OPC_MULEQ_S_W_PHL
:
22732 gen_helper_muleq_s_w_phl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22734 case OPC_MULEQ_S_W_PHR
:
22736 gen_helper_muleq_s_w_phr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22738 case OPC_MULQ_S_PH
:
22740 gen_helper_mulq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22744 #ifdef TARGET_MIPS64
22745 case OPC_ADDU_OB_DSP
:
22747 case OPC_MULEQ_S_PW_QHL
:
22749 gen_helper_muleq_s_pw_qhl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22751 case OPC_MULEQ_S_PW_QHR
:
22753 gen_helper_muleq_s_pw_qhr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22755 case OPC_MULEU_S_QH_OBL
:
22757 gen_helper_muleu_s_qh_obl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22759 case OPC_MULEU_S_QH_OBR
:
22761 gen_helper_muleu_s_qh_obr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22763 case OPC_MULQ_RS_QH
:
22765 gen_helper_mulq_rs_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22772 tcg_temp_free_i32(t0
);
22773 tcg_temp_free(v1_t
);
22774 tcg_temp_free(v2_t
);
22777 static void gen_mipsdsp_bitinsn(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
22785 /* Treat as NOP. */
22789 t0
= tcg_temp_new();
22790 val_t
= tcg_temp_new();
22791 gen_load_gpr(val_t
, val
);
22794 case OPC_ABSQ_S_PH_DSP
:
22798 gen_helper_bitrev(cpu_gpr
[ret
], val_t
);
22803 target_long result
;
22804 imm
= (ctx
->opcode
>> 16) & 0xFF;
22805 result
= (uint32_t)imm
<< 24 |
22806 (uint32_t)imm
<< 16 |
22807 (uint32_t)imm
<< 8 |
22809 result
= (int32_t)result
;
22810 tcg_gen_movi_tl(cpu_gpr
[ret
], result
);
22815 tcg_gen_ext8u_tl(cpu_gpr
[ret
], val_t
);
22816 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 8);
22817 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
22818 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
22819 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
22820 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
22825 imm
= (ctx
->opcode
>> 16) & 0x03FF;
22826 imm
= (int16_t)(imm
<< 6) >> 6;
22827 tcg_gen_movi_tl(cpu_gpr
[ret
], \
22828 (target_long
)((int32_t)imm
<< 16 | \
22834 tcg_gen_ext16u_tl(cpu_gpr
[ret
], val_t
);
22835 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
22836 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
22837 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
22841 #ifdef TARGET_MIPS64
22842 case OPC_ABSQ_S_QH_DSP
:
22849 imm
= (ctx
->opcode
>> 16) & 0xFF;
22850 temp
= ((uint64_t)imm
<< 8) | (uint64_t)imm
;
22851 temp
= (temp
<< 16) | temp
;
22852 temp
= (temp
<< 32) | temp
;
22853 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
22861 imm
= (ctx
->opcode
>> 16) & 0x03FF;
22862 imm
= (int16_t)(imm
<< 6) >> 6;
22863 temp
= ((target_long
)imm
<< 32) \
22864 | ((target_long
)imm
& 0xFFFFFFFF);
22865 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
22873 imm
= (ctx
->opcode
>> 16) & 0x03FF;
22874 imm
= (int16_t)(imm
<< 6) >> 6;
22876 temp
= ((uint64_t)(uint16_t)imm
<< 48) |
22877 ((uint64_t)(uint16_t)imm
<< 32) |
22878 ((uint64_t)(uint16_t)imm
<< 16) |
22879 (uint64_t)(uint16_t)imm
;
22880 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
22885 tcg_gen_ext8u_tl(cpu_gpr
[ret
], val_t
);
22886 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 8);
22887 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
22888 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
22889 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
22890 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
22891 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
22895 tcg_gen_ext32u_i64(cpu_gpr
[ret
], val_t
);
22896 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
22897 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
22901 tcg_gen_ext16u_tl(cpu_gpr
[ret
], val_t
);
22902 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
22903 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
22904 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
22905 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
22912 tcg_temp_free(val_t
);
22915 static void gen_mipsdsp_add_cmp_pick(DisasContext
*ctx
,
22916 uint32_t op1
, uint32_t op2
,
22917 int ret
, int v1
, int v2
, int check_ret
)
22923 if ((ret
== 0) && (check_ret
== 1)) {
22924 /* Treat as NOP. */
22928 t1
= tcg_temp_new();
22929 v1_t
= tcg_temp_new();
22930 v2_t
= tcg_temp_new();
22932 gen_load_gpr(v1_t
, v1
);
22933 gen_load_gpr(v2_t
, v2
);
22936 case OPC_CMPU_EQ_QB_DSP
:
22938 case OPC_CMPU_EQ_QB
:
22940 gen_helper_cmpu_eq_qb(v1_t
, v2_t
, cpu_env
);
22942 case OPC_CMPU_LT_QB
:
22944 gen_helper_cmpu_lt_qb(v1_t
, v2_t
, cpu_env
);
22946 case OPC_CMPU_LE_QB
:
22948 gen_helper_cmpu_le_qb(v1_t
, v2_t
, cpu_env
);
22950 case OPC_CMPGU_EQ_QB
:
22952 gen_helper_cmpgu_eq_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
22954 case OPC_CMPGU_LT_QB
:
22956 gen_helper_cmpgu_lt_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
22958 case OPC_CMPGU_LE_QB
:
22960 gen_helper_cmpgu_le_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
22962 case OPC_CMPGDU_EQ_QB
:
22964 gen_helper_cmpgu_eq_qb(t1
, v1_t
, v2_t
);
22965 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
22966 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
22967 tcg_gen_shli_tl(t1
, t1
, 24);
22968 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
22970 case OPC_CMPGDU_LT_QB
:
22972 gen_helper_cmpgu_lt_qb(t1
, v1_t
, v2_t
);
22973 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
22974 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
22975 tcg_gen_shli_tl(t1
, t1
, 24);
22976 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
22978 case OPC_CMPGDU_LE_QB
:
22980 gen_helper_cmpgu_le_qb(t1
, v1_t
, v2_t
);
22981 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
22982 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
22983 tcg_gen_shli_tl(t1
, t1
, 24);
22984 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
22986 case OPC_CMP_EQ_PH
:
22988 gen_helper_cmp_eq_ph(v1_t
, v2_t
, cpu_env
);
22990 case OPC_CMP_LT_PH
:
22992 gen_helper_cmp_lt_ph(v1_t
, v2_t
, cpu_env
);
22994 case OPC_CMP_LE_PH
:
22996 gen_helper_cmp_le_ph(v1_t
, v2_t
, cpu_env
);
23000 gen_helper_pick_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23004 gen_helper_pick_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23006 case OPC_PACKRL_PH
:
23008 gen_helper_packrl_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
23012 #ifdef TARGET_MIPS64
23013 case OPC_CMPU_EQ_OB_DSP
:
23015 case OPC_CMP_EQ_PW
:
23017 gen_helper_cmp_eq_pw(v1_t
, v2_t
, cpu_env
);
23019 case OPC_CMP_LT_PW
:
23021 gen_helper_cmp_lt_pw(v1_t
, v2_t
, cpu_env
);
23023 case OPC_CMP_LE_PW
:
23025 gen_helper_cmp_le_pw(v1_t
, v2_t
, cpu_env
);
23027 case OPC_CMP_EQ_QH
:
23029 gen_helper_cmp_eq_qh(v1_t
, v2_t
, cpu_env
);
23031 case OPC_CMP_LT_QH
:
23033 gen_helper_cmp_lt_qh(v1_t
, v2_t
, cpu_env
);
23035 case OPC_CMP_LE_QH
:
23037 gen_helper_cmp_le_qh(v1_t
, v2_t
, cpu_env
);
23039 case OPC_CMPGDU_EQ_OB
:
23041 gen_helper_cmpgdu_eq_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23043 case OPC_CMPGDU_LT_OB
:
23045 gen_helper_cmpgdu_lt_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23047 case OPC_CMPGDU_LE_OB
:
23049 gen_helper_cmpgdu_le_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23051 case OPC_CMPGU_EQ_OB
:
23053 gen_helper_cmpgu_eq_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
23055 case OPC_CMPGU_LT_OB
:
23057 gen_helper_cmpgu_lt_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
23059 case OPC_CMPGU_LE_OB
:
23061 gen_helper_cmpgu_le_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
23063 case OPC_CMPU_EQ_OB
:
23065 gen_helper_cmpu_eq_ob(v1_t
, v2_t
, cpu_env
);
23067 case OPC_CMPU_LT_OB
:
23069 gen_helper_cmpu_lt_ob(v1_t
, v2_t
, cpu_env
);
23071 case OPC_CMPU_LE_OB
:
23073 gen_helper_cmpu_le_ob(v1_t
, v2_t
, cpu_env
);
23075 case OPC_PACKRL_PW
:
23077 gen_helper_packrl_pw(cpu_gpr
[ret
], v1_t
, v2_t
);
23081 gen_helper_pick_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23085 gen_helper_pick_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23089 gen_helper_pick_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23097 tcg_temp_free(v1_t
);
23098 tcg_temp_free(v2_t
);
23101 static void gen_mipsdsp_append(CPUMIPSState
*env
, DisasContext
*ctx
,
23102 uint32_t op1
, int rt
, int rs
, int sa
)
23109 /* Treat as NOP. */
23113 t0
= tcg_temp_new();
23114 gen_load_gpr(t0
, rs
);
23117 case OPC_APPEND_DSP
:
23118 switch (MASK_APPEND(ctx
->opcode
)) {
23121 tcg_gen_deposit_tl(cpu_gpr
[rt
], t0
, cpu_gpr
[rt
], sa
, 32 - sa
);
23123 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
23127 tcg_gen_ext32u_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
23128 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], sa
);
23129 tcg_gen_shli_tl(t0
, t0
, 32 - sa
);
23130 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
23132 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
23136 if (sa
!= 0 && sa
!= 2) {
23137 tcg_gen_shli_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 8 * sa
);
23138 tcg_gen_ext32u_tl(t0
, t0
);
23139 tcg_gen_shri_tl(t0
, t0
, 8 * (4 - sa
));
23140 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
23142 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
23144 default: /* Invalid */
23145 MIPS_INVAL("MASK APPEND");
23146 gen_reserved_instruction(ctx
);
23150 #ifdef TARGET_MIPS64
23151 case OPC_DAPPEND_DSP
:
23152 switch (MASK_DAPPEND(ctx
->opcode
)) {
23155 tcg_gen_deposit_tl(cpu_gpr
[rt
], t0
, cpu_gpr
[rt
], sa
, 64 - sa
);
23159 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 0x20 | sa
);
23160 tcg_gen_shli_tl(t0
, t0
, 64 - (0x20 | sa
));
23161 tcg_gen_or_tl(cpu_gpr
[rt
], t0
, t0
);
23165 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], sa
);
23166 tcg_gen_shli_tl(t0
, t0
, 64 - sa
);
23167 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
23172 if (sa
!= 0 && sa
!= 2 && sa
!= 4) {
23173 tcg_gen_shli_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 8 * sa
);
23174 tcg_gen_shri_tl(t0
, t0
, 8 * (8 - sa
));
23175 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
23178 default: /* Invalid */
23179 MIPS_INVAL("MASK DAPPEND");
23180 gen_reserved_instruction(ctx
);
23189 static void gen_mipsdsp_accinsn(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
23190 int ret
, int v1
, int v2
, int check_ret
)
23199 if ((ret
== 0) && (check_ret
== 1)) {
23200 /* Treat as NOP. */
23204 t0
= tcg_temp_new();
23205 t1
= tcg_temp_new();
23206 v1_t
= tcg_temp_new();
23207 v2_t
= tcg_temp_new();
23209 gen_load_gpr(v1_t
, v1
);
23210 gen_load_gpr(v2_t
, v2
);
23213 case OPC_EXTR_W_DSP
:
23217 tcg_gen_movi_tl(t0
, v2
);
23218 tcg_gen_movi_tl(t1
, v1
);
23219 gen_helper_extr_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23222 tcg_gen_movi_tl(t0
, v2
);
23223 tcg_gen_movi_tl(t1
, v1
);
23224 gen_helper_extr_r_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23226 case OPC_EXTR_RS_W
:
23227 tcg_gen_movi_tl(t0
, v2
);
23228 tcg_gen_movi_tl(t1
, v1
);
23229 gen_helper_extr_rs_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23232 tcg_gen_movi_tl(t0
, v2
);
23233 tcg_gen_movi_tl(t1
, v1
);
23234 gen_helper_extr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23236 case OPC_EXTRV_S_H
:
23237 tcg_gen_movi_tl(t0
, v2
);
23238 gen_helper_extr_s_h(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
23241 tcg_gen_movi_tl(t0
, v2
);
23242 gen_helper_extr_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
23244 case OPC_EXTRV_R_W
:
23245 tcg_gen_movi_tl(t0
, v2
);
23246 gen_helper_extr_r_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
23248 case OPC_EXTRV_RS_W
:
23249 tcg_gen_movi_tl(t0
, v2
);
23250 gen_helper_extr_rs_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
23253 tcg_gen_movi_tl(t0
, v2
);
23254 tcg_gen_movi_tl(t1
, v1
);
23255 gen_helper_extp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23258 tcg_gen_movi_tl(t0
, v2
);
23259 gen_helper_extp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
23262 tcg_gen_movi_tl(t0
, v2
);
23263 tcg_gen_movi_tl(t1
, v1
);
23264 gen_helper_extpdp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23267 tcg_gen_movi_tl(t0
, v2
);
23268 gen_helper_extpdp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
23271 imm
= (ctx
->opcode
>> 20) & 0x3F;
23272 tcg_gen_movi_tl(t0
, ret
);
23273 tcg_gen_movi_tl(t1
, imm
);
23274 gen_helper_shilo(t0
, t1
, cpu_env
);
23277 tcg_gen_movi_tl(t0
, ret
);
23278 gen_helper_shilo(t0
, v1_t
, cpu_env
);
23281 tcg_gen_movi_tl(t0
, ret
);
23282 gen_helper_mthlip(t0
, v1_t
, cpu_env
);
23285 imm
= (ctx
->opcode
>> 11) & 0x3FF;
23286 tcg_gen_movi_tl(t0
, imm
);
23287 gen_helper_wrdsp(v1_t
, t0
, cpu_env
);
23290 imm
= (ctx
->opcode
>> 16) & 0x03FF;
23291 tcg_gen_movi_tl(t0
, imm
);
23292 gen_helper_rddsp(cpu_gpr
[ret
], t0
, cpu_env
);
23296 #ifdef TARGET_MIPS64
23297 case OPC_DEXTR_W_DSP
:
23301 tcg_gen_movi_tl(t0
, ret
);
23302 gen_helper_dmthlip(v1_t
, t0
, cpu_env
);
23306 int shift
= (ctx
->opcode
>> 19) & 0x7F;
23307 int ac
= (ctx
->opcode
>> 11) & 0x03;
23308 tcg_gen_movi_tl(t0
, shift
);
23309 tcg_gen_movi_tl(t1
, ac
);
23310 gen_helper_dshilo(t0
, t1
, cpu_env
);
23315 int ac
= (ctx
->opcode
>> 11) & 0x03;
23316 tcg_gen_movi_tl(t0
, ac
);
23317 gen_helper_dshilo(v1_t
, t0
, cpu_env
);
23321 tcg_gen_movi_tl(t0
, v2
);
23322 tcg_gen_movi_tl(t1
, v1
);
23324 gen_helper_dextp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23327 tcg_gen_movi_tl(t0
, v2
);
23328 gen_helper_dextp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
23331 tcg_gen_movi_tl(t0
, v2
);
23332 tcg_gen_movi_tl(t1
, v1
);
23333 gen_helper_dextpdp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23336 tcg_gen_movi_tl(t0
, v2
);
23337 gen_helper_dextpdp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
23340 tcg_gen_movi_tl(t0
, v2
);
23341 tcg_gen_movi_tl(t1
, v1
);
23342 gen_helper_dextr_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23344 case OPC_DEXTR_R_L
:
23345 tcg_gen_movi_tl(t0
, v2
);
23346 tcg_gen_movi_tl(t1
, v1
);
23347 gen_helper_dextr_r_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23349 case OPC_DEXTR_RS_L
:
23350 tcg_gen_movi_tl(t0
, v2
);
23351 tcg_gen_movi_tl(t1
, v1
);
23352 gen_helper_dextr_rs_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23355 tcg_gen_movi_tl(t0
, v2
);
23356 tcg_gen_movi_tl(t1
, v1
);
23357 gen_helper_dextr_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23359 case OPC_DEXTR_R_W
:
23360 tcg_gen_movi_tl(t0
, v2
);
23361 tcg_gen_movi_tl(t1
, v1
);
23362 gen_helper_dextr_r_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23364 case OPC_DEXTR_RS_W
:
23365 tcg_gen_movi_tl(t0
, v2
);
23366 tcg_gen_movi_tl(t1
, v1
);
23367 gen_helper_dextr_rs_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23369 case OPC_DEXTR_S_H
:
23370 tcg_gen_movi_tl(t0
, v2
);
23371 tcg_gen_movi_tl(t1
, v1
);
23372 gen_helper_dextr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23374 case OPC_DEXTRV_S_H
:
23375 tcg_gen_movi_tl(t0
, v2
);
23376 tcg_gen_movi_tl(t1
, v1
);
23377 gen_helper_dextr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23380 tcg_gen_movi_tl(t0
, v2
);
23381 gen_helper_dextr_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
23383 case OPC_DEXTRV_R_L
:
23384 tcg_gen_movi_tl(t0
, v2
);
23385 gen_helper_dextr_r_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
23387 case OPC_DEXTRV_RS_L
:
23388 tcg_gen_movi_tl(t0
, v2
);
23389 gen_helper_dextr_rs_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
23392 tcg_gen_movi_tl(t0
, v2
);
23393 gen_helper_dextr_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
23395 case OPC_DEXTRV_R_W
:
23396 tcg_gen_movi_tl(t0
, v2
);
23397 gen_helper_dextr_r_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
23399 case OPC_DEXTRV_RS_W
:
23400 tcg_gen_movi_tl(t0
, v2
);
23401 gen_helper_dextr_rs_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
23410 tcg_temp_free(v1_t
);
23411 tcg_temp_free(v2_t
);
23414 /* End MIPSDSP functions. */
23416 static void decode_opc_special_r6(CPUMIPSState
*env
, DisasContext
*ctx
)
23418 int rs
, rt
, rd
, sa
;
23421 rs
= (ctx
->opcode
>> 21) & 0x1f;
23422 rt
= (ctx
->opcode
>> 16) & 0x1f;
23423 rd
= (ctx
->opcode
>> 11) & 0x1f;
23424 sa
= (ctx
->opcode
>> 6) & 0x1f;
23426 op1
= MASK_SPECIAL(ctx
->opcode
);
23432 op2
= MASK_R6_MULDIV(ctx
->opcode
);
23442 gen_r6_muldiv(ctx
, op2
, rd
, rs
, rt
);
23445 MIPS_INVAL("special_r6 muldiv");
23446 gen_reserved_instruction(ctx
);
23452 gen_cond_move(ctx
, op1
, rd
, rs
, rt
);
23456 if (rt
== 0 && sa
== 1) {
23458 * Major opcode and function field is shared with preR6 MFHI/MTHI.
23459 * We need additionally to check other fields.
23461 gen_cl(ctx
, op1
, rd
, rs
);
23463 gen_reserved_instruction(ctx
);
23467 if (is_uhi(extract32(ctx
->opcode
, 6, 20))) {
23468 gen_helper_do_semihosting(cpu_env
);
23470 if (ctx
->hflags
& MIPS_HFLAG_SBRI
) {
23471 gen_reserved_instruction(ctx
);
23473 generate_exception_end(ctx
, EXCP_DBp
);
23477 #if defined(TARGET_MIPS64)
23480 if (rt
== 0 && sa
== 1) {
23482 * Major opcode and function field is shared with preR6 MFHI/MTHI.
23483 * We need additionally to check other fields.
23485 check_mips_64(ctx
);
23486 gen_cl(ctx
, op1
, rd
, rs
);
23488 gen_reserved_instruction(ctx
);
23496 op2
= MASK_R6_MULDIV(ctx
->opcode
);
23506 check_mips_64(ctx
);
23507 gen_r6_muldiv(ctx
, op2
, rd
, rs
, rt
);
23510 MIPS_INVAL("special_r6 muldiv");
23511 gen_reserved_instruction(ctx
);
23516 default: /* Invalid */
23517 MIPS_INVAL("special_r6");
23518 gen_reserved_instruction(ctx
);
23523 static void decode_opc_special_tx79(CPUMIPSState
*env
, DisasContext
*ctx
)
23525 int rs
= extract32(ctx
->opcode
, 21, 5);
23526 int rt
= extract32(ctx
->opcode
, 16, 5);
23527 int rd
= extract32(ctx
->opcode
, 11, 5);
23528 uint32_t op1
= MASK_SPECIAL(ctx
->opcode
);
23531 case OPC_MOVN
: /* Conditional move */
23533 gen_cond_move(ctx
, op1
, rd
, rs
, rt
);
23535 case OPC_MFHI
: /* Move from HI/LO */
23537 gen_HILO(ctx
, op1
, 0, rd
);
23540 case OPC_MTLO
: /* Move to HI/LO */
23541 gen_HILO(ctx
, op1
, 0, rs
);
23545 gen_mul_txx9(ctx
, op1
, rd
, rs
, rt
);
23549 gen_muldiv(ctx
, op1
, 0, rs
, rt
);
23551 #if defined(TARGET_MIPS64)
23556 check_insn_opc_user_only(ctx
, INSN_R5900
);
23557 gen_muldiv(ctx
, op1
, 0, rs
, rt
);
23561 gen_compute_branch(ctx
, op1
, 4, rs
, 0, 0, 4);
23563 default: /* Invalid */
23564 MIPS_INVAL("special_tx79");
23565 gen_reserved_instruction(ctx
);
23570 static void decode_opc_special_legacy(CPUMIPSState
*env
, DisasContext
*ctx
)
23572 int rs
, rt
, rd
, sa
;
23575 rs
= (ctx
->opcode
>> 21) & 0x1f;
23576 rt
= (ctx
->opcode
>> 16) & 0x1f;
23577 rd
= (ctx
->opcode
>> 11) & 0x1f;
23578 sa
= (ctx
->opcode
>> 6) & 0x1f;
23580 op1
= MASK_SPECIAL(ctx
->opcode
);
23582 case OPC_MOVN
: /* Conditional move */
23584 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS_R1
|
23585 INSN_LOONGSON2E
| INSN_LOONGSON2F
);
23586 gen_cond_move(ctx
, op1
, rd
, rs
, rt
);
23588 case OPC_MFHI
: /* Move from HI/LO */
23590 gen_HILO(ctx
, op1
, rs
& 3, rd
);
23593 case OPC_MTLO
: /* Move to HI/LO */
23594 gen_HILO(ctx
, op1
, rd
& 3, rs
);
23597 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS_R1
);
23598 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
23599 check_cp1_enabled(ctx
);
23600 gen_movci(ctx
, rd
, rs
, (ctx
->opcode
>> 18) & 0x7,
23601 (ctx
->opcode
>> 16) & 1);
23603 generate_exception_err(ctx
, EXCP_CpU
, 1);
23609 check_insn(ctx
, INSN_VR54XX
);
23610 op1
= MASK_MUL_VR54XX(ctx
->opcode
);
23611 gen_mul_vr54xx(ctx
, op1
, rd
, rs
, rt
);
23613 gen_muldiv(ctx
, op1
, rd
& 3, rs
, rt
);
23618 gen_muldiv(ctx
, op1
, 0, rs
, rt
);
23620 #if defined(TARGET_MIPS64)
23625 check_insn(ctx
, ISA_MIPS3
);
23626 check_mips_64(ctx
);
23627 gen_muldiv(ctx
, op1
, 0, rs
, rt
);
23631 gen_compute_branch(ctx
, op1
, 4, rs
, rd
, sa
, 4);
23634 #ifdef MIPS_STRICT_STANDARD
23635 MIPS_INVAL("SPIM");
23636 gen_reserved_instruction(ctx
);
23638 /* Implemented as RI exception for now. */
23639 MIPS_INVAL("spim (unofficial)");
23640 gen_reserved_instruction(ctx
);
23643 default: /* Invalid */
23644 MIPS_INVAL("special_legacy");
23645 gen_reserved_instruction(ctx
);
23650 static void decode_opc_special(CPUMIPSState
*env
, DisasContext
*ctx
)
23652 int rs
, rt
, rd
, sa
;
23655 rs
= (ctx
->opcode
>> 21) & 0x1f;
23656 rt
= (ctx
->opcode
>> 16) & 0x1f;
23657 rd
= (ctx
->opcode
>> 11) & 0x1f;
23658 sa
= (ctx
->opcode
>> 6) & 0x1f;
23660 op1
= MASK_SPECIAL(ctx
->opcode
);
23662 case OPC_SLL
: /* Shift with immediate */
23663 if (sa
== 5 && rd
== 0 &&
23664 rs
== 0 && rt
== 0) { /* PAUSE */
23665 if ((ctx
->insn_flags
& ISA_MIPS_R6
) &&
23666 (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
23667 gen_reserved_instruction(ctx
);
23673 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
23676 switch ((ctx
->opcode
>> 21) & 0x1f) {
23678 /* rotr is decoded as srl on non-R2 CPUs */
23679 if (ctx
->insn_flags
& ISA_MIPS_R2
) {
23684 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
23687 gen_reserved_instruction(ctx
);
23695 gen_arith(ctx
, op1
, rd
, rs
, rt
);
23697 case OPC_SLLV
: /* Shifts */
23699 gen_shift(ctx
, op1
, rd
, rs
, rt
);
23702 switch ((ctx
->opcode
>> 6) & 0x1f) {
23704 /* rotrv is decoded as srlv on non-R2 CPUs */
23705 if (ctx
->insn_flags
& ISA_MIPS_R2
) {
23710 gen_shift(ctx
, op1
, rd
, rs
, rt
);
23713 gen_reserved_instruction(ctx
);
23717 case OPC_SLT
: /* Set on less than */
23719 gen_slt(ctx
, op1
, rd
, rs
, rt
);
23721 case OPC_AND
: /* Logic*/
23725 gen_logic(ctx
, op1
, rd
, rs
, rt
);
23728 gen_compute_branch(ctx
, op1
, 4, rs
, rd
, sa
, 4);
23730 case OPC_TGE
: /* Traps */
23736 check_insn(ctx
, ISA_MIPS2
);
23737 gen_trap(ctx
, op1
, rs
, rt
, -1);
23740 /* Pmon entry point, also R4010 selsl */
23741 #ifdef MIPS_STRICT_STANDARD
23742 MIPS_INVAL("PMON / selsl");
23743 gen_reserved_instruction(ctx
);
23745 gen_helper_0e0i(pmon
, sa
);
23749 generate_exception_end(ctx
, EXCP_SYSCALL
);
23752 generate_exception_end(ctx
, EXCP_BREAK
);
23755 check_insn(ctx
, ISA_MIPS2
);
23756 gen_sync(extract32(ctx
->opcode
, 6, 5));
23759 #if defined(TARGET_MIPS64)
23760 /* MIPS64 specific opcodes */
23765 check_insn(ctx
, ISA_MIPS3
);
23766 check_mips_64(ctx
);
23767 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
23770 switch ((ctx
->opcode
>> 21) & 0x1f) {
23772 /* drotr is decoded as dsrl on non-R2 CPUs */
23773 if (ctx
->insn_flags
& ISA_MIPS_R2
) {
23778 check_insn(ctx
, ISA_MIPS3
);
23779 check_mips_64(ctx
);
23780 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
23783 gen_reserved_instruction(ctx
);
23788 switch ((ctx
->opcode
>> 21) & 0x1f) {
23790 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
23791 if (ctx
->insn_flags
& ISA_MIPS_R2
) {
23796 check_insn(ctx
, ISA_MIPS3
);
23797 check_mips_64(ctx
);
23798 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
23801 gen_reserved_instruction(ctx
);
23809 check_insn(ctx
, ISA_MIPS3
);
23810 check_mips_64(ctx
);
23811 gen_arith(ctx
, op1
, rd
, rs
, rt
);
23815 check_insn(ctx
, ISA_MIPS3
);
23816 check_mips_64(ctx
);
23817 gen_shift(ctx
, op1
, rd
, rs
, rt
);
23820 switch ((ctx
->opcode
>> 6) & 0x1f) {
23822 /* drotrv is decoded as dsrlv on non-R2 CPUs */
23823 if (ctx
->insn_flags
& ISA_MIPS_R2
) {
23828 check_insn(ctx
, ISA_MIPS3
);
23829 check_mips_64(ctx
);
23830 gen_shift(ctx
, op1
, rd
, rs
, rt
);
23833 gen_reserved_instruction(ctx
);
23839 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
23840 decode_opc_special_r6(env
, ctx
);
23841 } else if (ctx
->insn_flags
& INSN_R5900
) {
23842 decode_opc_special_tx79(env
, ctx
);
23844 decode_opc_special_legacy(env
, ctx
);
23850 static void decode_opc_special2_legacy(CPUMIPSState
*env
, DisasContext
*ctx
)
23855 rs
= (ctx
->opcode
>> 21) & 0x1f;
23856 rt
= (ctx
->opcode
>> 16) & 0x1f;
23857 rd
= (ctx
->opcode
>> 11) & 0x1f;
23859 op1
= MASK_SPECIAL2(ctx
->opcode
);
23861 case OPC_MADD
: /* Multiply and add/sub */
23865 check_insn(ctx
, ISA_MIPS_R1
);
23866 gen_muldiv(ctx
, op1
, rd
& 3, rs
, rt
);
23869 gen_arith(ctx
, op1
, rd
, rs
, rt
);
23872 case OPC_DIVU_G_2F
:
23873 case OPC_MULT_G_2F
:
23874 case OPC_MULTU_G_2F
:
23876 case OPC_MODU_G_2F
:
23877 check_insn(ctx
, INSN_LOONGSON2F
| ASE_LEXT
);
23878 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
23882 check_insn(ctx
, ISA_MIPS_R1
);
23883 gen_cl(ctx
, op1
, rd
, rs
);
23886 if (is_uhi(extract32(ctx
->opcode
, 6, 20))) {
23887 gen_helper_do_semihosting(cpu_env
);
23890 * XXX: not clear which exception should be raised
23891 * when in debug mode...
23893 check_insn(ctx
, ISA_MIPS_R1
);
23894 generate_exception_end(ctx
, EXCP_DBp
);
23897 #if defined(TARGET_MIPS64)
23900 check_insn(ctx
, ISA_MIPS_R1
);
23901 check_mips_64(ctx
);
23902 gen_cl(ctx
, op1
, rd
, rs
);
23904 case OPC_DMULT_G_2F
:
23905 case OPC_DMULTU_G_2F
:
23906 case OPC_DDIV_G_2F
:
23907 case OPC_DDIVU_G_2F
:
23908 case OPC_DMOD_G_2F
:
23909 case OPC_DMODU_G_2F
:
23910 check_insn(ctx
, INSN_LOONGSON2F
| ASE_LEXT
);
23911 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
23914 default: /* Invalid */
23915 MIPS_INVAL("special2_legacy");
23916 gen_reserved_instruction(ctx
);
23921 static void decode_opc_special3_r6(CPUMIPSState
*env
, DisasContext
*ctx
)
23923 int rs
, rt
, rd
, sa
;
23927 rs
= (ctx
->opcode
>> 21) & 0x1f;
23928 rt
= (ctx
->opcode
>> 16) & 0x1f;
23929 rd
= (ctx
->opcode
>> 11) & 0x1f;
23930 sa
= (ctx
->opcode
>> 6) & 0x1f;
23931 imm
= (int16_t)ctx
->opcode
>> 7;
23933 op1
= MASK_SPECIAL3(ctx
->opcode
);
23937 /* hint codes 24-31 are reserved and signal RI */
23938 gen_reserved_instruction(ctx
);
23940 /* Treat as NOP. */
23943 check_cp0_enabled(ctx
);
23944 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
23945 gen_cache_operation(ctx
, rt
, rs
, imm
);
23949 gen_st_cond(ctx
, rt
, rs
, imm
, MO_TESL
, false);
23952 gen_ld(ctx
, op1
, rt
, rs
, imm
);
23957 /* Treat as NOP. */
23960 op2
= MASK_BSHFL(ctx
->opcode
);
23966 gen_align(ctx
, 32, rd
, rs
, rt
, sa
& 3);
23969 gen_bitswap(ctx
, op2
, rd
, rt
);
23974 #ifndef CONFIG_USER_ONLY
23976 if (unlikely(ctx
->gi
<= 1)) {
23977 gen_reserved_instruction(ctx
);
23979 check_cp0_enabled(ctx
);
23980 switch ((ctx
->opcode
>> 6) & 3) {
23981 case 0: /* GINVI */
23982 /* Treat as NOP. */
23984 case 2: /* GINVT */
23985 gen_helper_0e1i(ginvt
, cpu_gpr
[rs
], extract32(ctx
->opcode
, 8, 2));
23988 gen_reserved_instruction(ctx
);
23993 #if defined(TARGET_MIPS64)
23995 gen_st_cond(ctx
, rt
, rs
, imm
, MO_TEQ
, false);
23998 gen_ld(ctx
, op1
, rt
, rs
, imm
);
24001 check_mips_64(ctx
);
24004 /* Treat as NOP. */
24007 op2
= MASK_DBSHFL(ctx
->opcode
);
24017 gen_align(ctx
, 64, rd
, rs
, rt
, sa
& 7);
24020 gen_bitswap(ctx
, op2
, rd
, rt
);
24027 default: /* Invalid */
24028 MIPS_INVAL("special3_r6");
24029 gen_reserved_instruction(ctx
);
24034 static void decode_opc_special3_legacy(CPUMIPSState
*env
, DisasContext
*ctx
)
24039 rs
= (ctx
->opcode
>> 21) & 0x1f;
24040 rt
= (ctx
->opcode
>> 16) & 0x1f;
24041 rd
= (ctx
->opcode
>> 11) & 0x1f;
24043 op1
= MASK_SPECIAL3(ctx
->opcode
);
24046 case OPC_DIVU_G_2E
:
24048 case OPC_MODU_G_2E
:
24049 case OPC_MULT_G_2E
:
24050 case OPC_MULTU_G_2E
:
24052 * OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
24053 * the same mask and op1.
24055 if ((ctx
->insn_flags
& ASE_DSP_R2
) && (op1
== OPC_MULT_G_2E
)) {
24056 op2
= MASK_ADDUH_QB(ctx
->opcode
);
24059 case OPC_ADDUH_R_QB
:
24061 case OPC_ADDQH_R_PH
:
24063 case OPC_ADDQH_R_W
:
24065 case OPC_SUBUH_R_QB
:
24067 case OPC_SUBQH_R_PH
:
24069 case OPC_SUBQH_R_W
:
24070 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
24075 case OPC_MULQ_RS_W
:
24076 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
24079 MIPS_INVAL("MASK ADDUH.QB");
24080 gen_reserved_instruction(ctx
);
24083 } else if (ctx
->insn_flags
& INSN_LOONGSON2E
) {
24084 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
24086 gen_reserved_instruction(ctx
);
24090 op2
= MASK_LX(ctx
->opcode
);
24092 #if defined(TARGET_MIPS64)
24098 gen_mipsdsp_ld(ctx
, op2
, rd
, rs
, rt
);
24100 default: /* Invalid */
24101 MIPS_INVAL("MASK LX");
24102 gen_reserved_instruction(ctx
);
24106 case OPC_ABSQ_S_PH_DSP
:
24107 op2
= MASK_ABSQ_S_PH(ctx
->opcode
);
24109 case OPC_ABSQ_S_QB
:
24110 case OPC_ABSQ_S_PH
:
24112 case OPC_PRECEQ_W_PHL
:
24113 case OPC_PRECEQ_W_PHR
:
24114 case OPC_PRECEQU_PH_QBL
:
24115 case OPC_PRECEQU_PH_QBR
:
24116 case OPC_PRECEQU_PH_QBLA
:
24117 case OPC_PRECEQU_PH_QBRA
:
24118 case OPC_PRECEU_PH_QBL
:
24119 case OPC_PRECEU_PH_QBR
:
24120 case OPC_PRECEU_PH_QBLA
:
24121 case OPC_PRECEU_PH_QBRA
:
24122 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
24129 gen_mipsdsp_bitinsn(ctx
, op1
, op2
, rd
, rt
);
24132 MIPS_INVAL("MASK ABSQ_S.PH");
24133 gen_reserved_instruction(ctx
);
24137 case OPC_ADDU_QB_DSP
:
24138 op2
= MASK_ADDU_QB(ctx
->opcode
);
24141 case OPC_ADDQ_S_PH
:
24144 case OPC_ADDU_S_QB
:
24146 case OPC_ADDU_S_PH
:
24148 case OPC_SUBQ_S_PH
:
24151 case OPC_SUBU_S_QB
:
24153 case OPC_SUBU_S_PH
:
24157 case OPC_RADDU_W_QB
:
24158 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
24160 case OPC_MULEU_S_PH_QBL
:
24161 case OPC_MULEU_S_PH_QBR
:
24162 case OPC_MULQ_RS_PH
:
24163 case OPC_MULEQ_S_W_PHL
:
24164 case OPC_MULEQ_S_W_PHR
:
24165 case OPC_MULQ_S_PH
:
24166 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
24168 default: /* Invalid */
24169 MIPS_INVAL("MASK ADDU.QB");
24170 gen_reserved_instruction(ctx
);
24175 case OPC_CMPU_EQ_QB_DSP
:
24176 op2
= MASK_CMPU_EQ_QB(ctx
->opcode
);
24178 case OPC_PRECR_SRA_PH_W
:
24179 case OPC_PRECR_SRA_R_PH_W
:
24180 gen_mipsdsp_arith(ctx
, op1
, op2
, rt
, rs
, rd
);
24182 case OPC_PRECR_QB_PH
:
24183 case OPC_PRECRQ_QB_PH
:
24184 case OPC_PRECRQ_PH_W
:
24185 case OPC_PRECRQ_RS_PH_W
:
24186 case OPC_PRECRQU_S_QB_PH
:
24187 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
24189 case OPC_CMPU_EQ_QB
:
24190 case OPC_CMPU_LT_QB
:
24191 case OPC_CMPU_LE_QB
:
24192 case OPC_CMP_EQ_PH
:
24193 case OPC_CMP_LT_PH
:
24194 case OPC_CMP_LE_PH
:
24195 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
24197 case OPC_CMPGU_EQ_QB
:
24198 case OPC_CMPGU_LT_QB
:
24199 case OPC_CMPGU_LE_QB
:
24200 case OPC_CMPGDU_EQ_QB
:
24201 case OPC_CMPGDU_LT_QB
:
24202 case OPC_CMPGDU_LE_QB
:
24205 case OPC_PACKRL_PH
:
24206 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
24208 default: /* Invalid */
24209 MIPS_INVAL("MASK CMPU.EQ.QB");
24210 gen_reserved_instruction(ctx
);
24214 case OPC_SHLL_QB_DSP
:
24215 gen_mipsdsp_shift(ctx
, op1
, rd
, rs
, rt
);
24217 case OPC_DPA_W_PH_DSP
:
24218 op2
= MASK_DPA_W_PH(ctx
->opcode
);
24220 case OPC_DPAU_H_QBL
:
24221 case OPC_DPAU_H_QBR
:
24222 case OPC_DPSU_H_QBL
:
24223 case OPC_DPSU_H_QBR
:
24225 case OPC_DPAX_W_PH
:
24226 case OPC_DPAQ_S_W_PH
:
24227 case OPC_DPAQX_S_W_PH
:
24228 case OPC_DPAQX_SA_W_PH
:
24230 case OPC_DPSX_W_PH
:
24231 case OPC_DPSQ_S_W_PH
:
24232 case OPC_DPSQX_S_W_PH
:
24233 case OPC_DPSQX_SA_W_PH
:
24234 case OPC_MULSAQ_S_W_PH
:
24235 case OPC_DPAQ_SA_L_W
:
24236 case OPC_DPSQ_SA_L_W
:
24237 case OPC_MAQ_S_W_PHL
:
24238 case OPC_MAQ_S_W_PHR
:
24239 case OPC_MAQ_SA_W_PHL
:
24240 case OPC_MAQ_SA_W_PHR
:
24241 case OPC_MULSA_W_PH
:
24242 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
24244 default: /* Invalid */
24245 MIPS_INVAL("MASK DPAW.PH");
24246 gen_reserved_instruction(ctx
);
24251 op2
= MASK_INSV(ctx
->opcode
);
24262 t0
= tcg_temp_new();
24263 t1
= tcg_temp_new();
24265 gen_load_gpr(t0
, rt
);
24266 gen_load_gpr(t1
, rs
);
24268 gen_helper_insv(cpu_gpr
[rt
], cpu_env
, t1
, t0
);
24274 default: /* Invalid */
24275 MIPS_INVAL("MASK INSV");
24276 gen_reserved_instruction(ctx
);
24280 case OPC_APPEND_DSP
:
24281 gen_mipsdsp_append(env
, ctx
, op1
, rt
, rs
, rd
);
24283 case OPC_EXTR_W_DSP
:
24284 op2
= MASK_EXTR_W(ctx
->opcode
);
24288 case OPC_EXTR_RS_W
:
24290 case OPC_EXTRV_S_H
:
24292 case OPC_EXTRV_R_W
:
24293 case OPC_EXTRV_RS_W
:
24298 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rt
, rs
, rd
, 1);
24301 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
24307 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
24309 default: /* Invalid */
24310 MIPS_INVAL("MASK EXTR.W");
24311 gen_reserved_instruction(ctx
);
24315 #if defined(TARGET_MIPS64)
24316 case OPC_DDIV_G_2E
:
24317 case OPC_DDIVU_G_2E
:
24318 case OPC_DMULT_G_2E
:
24319 case OPC_DMULTU_G_2E
:
24320 case OPC_DMOD_G_2E
:
24321 case OPC_DMODU_G_2E
:
24322 check_insn(ctx
, INSN_LOONGSON2E
);
24323 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
24325 case OPC_ABSQ_S_QH_DSP
:
24326 op2
= MASK_ABSQ_S_QH(ctx
->opcode
);
24328 case OPC_PRECEQ_L_PWL
:
24329 case OPC_PRECEQ_L_PWR
:
24330 case OPC_PRECEQ_PW_QHL
:
24331 case OPC_PRECEQ_PW_QHR
:
24332 case OPC_PRECEQ_PW_QHLA
:
24333 case OPC_PRECEQ_PW_QHRA
:
24334 case OPC_PRECEQU_QH_OBL
:
24335 case OPC_PRECEQU_QH_OBR
:
24336 case OPC_PRECEQU_QH_OBLA
:
24337 case OPC_PRECEQU_QH_OBRA
:
24338 case OPC_PRECEU_QH_OBL
:
24339 case OPC_PRECEU_QH_OBR
:
24340 case OPC_PRECEU_QH_OBLA
:
24341 case OPC_PRECEU_QH_OBRA
:
24342 case OPC_ABSQ_S_OB
:
24343 case OPC_ABSQ_S_PW
:
24344 case OPC_ABSQ_S_QH
:
24345 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
24353 gen_mipsdsp_bitinsn(ctx
, op1
, op2
, rd
, rt
);
24355 default: /* Invalid */
24356 MIPS_INVAL("MASK ABSQ_S.QH");
24357 gen_reserved_instruction(ctx
);
24361 case OPC_ADDU_OB_DSP
:
24362 op2
= MASK_ADDU_OB(ctx
->opcode
);
24364 case OPC_RADDU_L_OB
:
24366 case OPC_SUBQ_S_PW
:
24368 case OPC_SUBQ_S_QH
:
24370 case OPC_SUBU_S_OB
:
24372 case OPC_SUBU_S_QH
:
24374 case OPC_SUBUH_R_OB
:
24376 case OPC_ADDQ_S_PW
:
24378 case OPC_ADDQ_S_QH
:
24380 case OPC_ADDU_S_OB
:
24382 case OPC_ADDU_S_QH
:
24384 case OPC_ADDUH_R_OB
:
24385 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
24387 case OPC_MULEQ_S_PW_QHL
:
24388 case OPC_MULEQ_S_PW_QHR
:
24389 case OPC_MULEU_S_QH_OBL
:
24390 case OPC_MULEU_S_QH_OBR
:
24391 case OPC_MULQ_RS_QH
:
24392 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
24394 default: /* Invalid */
24395 MIPS_INVAL("MASK ADDU.OB");
24396 gen_reserved_instruction(ctx
);
24400 case OPC_CMPU_EQ_OB_DSP
:
24401 op2
= MASK_CMPU_EQ_OB(ctx
->opcode
);
24403 case OPC_PRECR_SRA_QH_PW
:
24404 case OPC_PRECR_SRA_R_QH_PW
:
24405 /* Return value is rt. */
24406 gen_mipsdsp_arith(ctx
, op1
, op2
, rt
, rs
, rd
);
24408 case OPC_PRECR_OB_QH
:
24409 case OPC_PRECRQ_OB_QH
:
24410 case OPC_PRECRQ_PW_L
:
24411 case OPC_PRECRQ_QH_PW
:
24412 case OPC_PRECRQ_RS_QH_PW
:
24413 case OPC_PRECRQU_S_OB_QH
:
24414 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
24416 case OPC_CMPU_EQ_OB
:
24417 case OPC_CMPU_LT_OB
:
24418 case OPC_CMPU_LE_OB
:
24419 case OPC_CMP_EQ_QH
:
24420 case OPC_CMP_LT_QH
:
24421 case OPC_CMP_LE_QH
:
24422 case OPC_CMP_EQ_PW
:
24423 case OPC_CMP_LT_PW
:
24424 case OPC_CMP_LE_PW
:
24425 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
24427 case OPC_CMPGDU_EQ_OB
:
24428 case OPC_CMPGDU_LT_OB
:
24429 case OPC_CMPGDU_LE_OB
:
24430 case OPC_CMPGU_EQ_OB
:
24431 case OPC_CMPGU_LT_OB
:
24432 case OPC_CMPGU_LE_OB
:
24433 case OPC_PACKRL_PW
:
24437 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
24439 default: /* Invalid */
24440 MIPS_INVAL("MASK CMPU_EQ.OB");
24441 gen_reserved_instruction(ctx
);
24445 case OPC_DAPPEND_DSP
:
24446 gen_mipsdsp_append(env
, ctx
, op1
, rt
, rs
, rd
);
24448 case OPC_DEXTR_W_DSP
:
24449 op2
= MASK_DEXTR_W(ctx
->opcode
);
24456 case OPC_DEXTR_R_L
:
24457 case OPC_DEXTR_RS_L
:
24459 case OPC_DEXTR_R_W
:
24460 case OPC_DEXTR_RS_W
:
24461 case OPC_DEXTR_S_H
:
24463 case OPC_DEXTRV_R_L
:
24464 case OPC_DEXTRV_RS_L
:
24465 case OPC_DEXTRV_S_H
:
24467 case OPC_DEXTRV_R_W
:
24468 case OPC_DEXTRV_RS_W
:
24469 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rt
, rs
, rd
, 1);
24474 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
24476 default: /* Invalid */
24477 MIPS_INVAL("MASK EXTR.W");
24478 gen_reserved_instruction(ctx
);
24482 case OPC_DPAQ_W_QH_DSP
:
24483 op2
= MASK_DPAQ_W_QH(ctx
->opcode
);
24485 case OPC_DPAU_H_OBL
:
24486 case OPC_DPAU_H_OBR
:
24487 case OPC_DPSU_H_OBL
:
24488 case OPC_DPSU_H_OBR
:
24490 case OPC_DPAQ_S_W_QH
:
24492 case OPC_DPSQ_S_W_QH
:
24493 case OPC_MULSAQ_S_W_QH
:
24494 case OPC_DPAQ_SA_L_PW
:
24495 case OPC_DPSQ_SA_L_PW
:
24496 case OPC_MULSAQ_S_L_PW
:
24497 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
24499 case OPC_MAQ_S_W_QHLL
:
24500 case OPC_MAQ_S_W_QHLR
:
24501 case OPC_MAQ_S_W_QHRL
:
24502 case OPC_MAQ_S_W_QHRR
:
24503 case OPC_MAQ_SA_W_QHLL
:
24504 case OPC_MAQ_SA_W_QHLR
:
24505 case OPC_MAQ_SA_W_QHRL
:
24506 case OPC_MAQ_SA_W_QHRR
:
24507 case OPC_MAQ_S_L_PWL
:
24508 case OPC_MAQ_S_L_PWR
:
24513 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
24515 default: /* Invalid */
24516 MIPS_INVAL("MASK DPAQ.W.QH");
24517 gen_reserved_instruction(ctx
);
24521 case OPC_DINSV_DSP
:
24522 op2
= MASK_INSV(ctx
->opcode
);
24533 t0
= tcg_temp_new();
24534 t1
= tcg_temp_new();
24536 gen_load_gpr(t0
, rt
);
24537 gen_load_gpr(t1
, rs
);
24539 gen_helper_dinsv(cpu_gpr
[rt
], cpu_env
, t1
, t0
);
24545 default: /* Invalid */
24546 MIPS_INVAL("MASK DINSV");
24547 gen_reserved_instruction(ctx
);
24551 case OPC_SHLL_OB_DSP
:
24552 gen_mipsdsp_shift(ctx
, op1
, rd
, rs
, rt
);
24555 default: /* Invalid */
24556 MIPS_INVAL("special3_legacy");
24557 gen_reserved_instruction(ctx
);
24563 #if defined(TARGET_MIPS64)
24565 static void decode_mmi(CPUMIPSState
*env
, DisasContext
*ctx
)
24567 uint32_t opc
= MASK_MMI(ctx
->opcode
);
24568 int rs
= extract32(ctx
->opcode
, 21, 5);
24569 int rt
= extract32(ctx
->opcode
, 16, 5);
24570 int rd
= extract32(ctx
->opcode
, 11, 5);
24573 case MMI_OPC_MULT1
:
24574 case MMI_OPC_MULTU1
:
24576 case MMI_OPC_MADDU
:
24577 case MMI_OPC_MADD1
:
24578 case MMI_OPC_MADDU1
:
24579 gen_mul_txx9(ctx
, opc
, rd
, rs
, rt
);
24582 case MMI_OPC_DIVU1
:
24583 gen_div1_tx79(ctx
, opc
, rs
, rt
);
24586 MIPS_INVAL("TX79 MMI class");
24587 gen_reserved_instruction(ctx
);
24592 static void gen_mmi_lq(CPUMIPSState
*env
, DisasContext
*ctx
)
24594 gen_reserved_instruction(ctx
); /* TODO: MMI_OPC_LQ */
24597 static void gen_mmi_sq(DisasContext
*ctx
, int base
, int rt
, int offset
)
24599 gen_reserved_instruction(ctx
); /* TODO: MMI_OPC_SQ */
24603 * The TX79-specific instruction Store Quadword
24605 * +--------+-------+-------+------------------------+
24606 * | 011111 | base | rt | offset | SQ
24607 * +--------+-------+-------+------------------------+
24610 * has the same opcode as the Read Hardware Register instruction
24612 * +--------+-------+-------+-------+-------+--------+
24613 * | 011111 | 00000 | rt | rd | 00000 | 111011 | RDHWR
24614 * +--------+-------+-------+-------+-------+--------+
24617 * that is required, trapped and emulated by the Linux kernel. However, all
24618 * RDHWR encodings yield address error exceptions on the TX79 since the SQ
24619 * offset is odd. Therefore all valid SQ instructions can execute normally.
24620 * In user mode, QEMU must verify the upper and lower 11 bits to distinguish
24621 * between SQ and RDHWR, as the Linux kernel does.
24623 static void decode_mmi_sq(CPUMIPSState
*env
, DisasContext
*ctx
)
24625 int base
= extract32(ctx
->opcode
, 21, 5);
24626 int rt
= extract32(ctx
->opcode
, 16, 5);
24627 int offset
= extract32(ctx
->opcode
, 0, 16);
24629 #ifdef CONFIG_USER_ONLY
24630 uint32_t op1
= MASK_SPECIAL3(ctx
->opcode
);
24631 uint32_t op2
= extract32(ctx
->opcode
, 6, 5);
24633 if (base
== 0 && op2
== 0 && op1
== OPC_RDHWR
) {
24634 int rd
= extract32(ctx
->opcode
, 11, 5);
24636 gen_rdhwr(ctx
, rt
, rd
, 0);
24641 gen_mmi_sq(ctx
, base
, rt
, offset
);
24646 static void decode_opc_special3(CPUMIPSState
*env
, DisasContext
*ctx
)
24648 int rs
, rt
, rd
, sa
;
24652 rs
= (ctx
->opcode
>> 21) & 0x1f;
24653 rt
= (ctx
->opcode
>> 16) & 0x1f;
24654 rd
= (ctx
->opcode
>> 11) & 0x1f;
24655 sa
= (ctx
->opcode
>> 6) & 0x1f;
24656 imm
= sextract32(ctx
->opcode
, 7, 9);
24658 op1
= MASK_SPECIAL3(ctx
->opcode
);
24661 * EVA loads and stores overlap Loongson 2E instructions decoded by
24662 * decode_opc_special3_legacy(), so be careful to allow their decoding when
24675 check_cp0_enabled(ctx
);
24676 gen_ld(ctx
, op1
, rt
, rs
, imm
);
24683 check_cp0_enabled(ctx
);
24684 gen_st(ctx
, op1
, rt
, rs
, imm
);
24687 check_cp0_enabled(ctx
);
24688 gen_st_cond(ctx
, rt
, rs
, imm
, MO_TESL
, true);
24691 check_cp0_enabled(ctx
);
24692 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
24693 gen_cache_operation(ctx
, rt
, rs
, imm
);
24695 /* Treat as NOP. */
24698 check_cp0_enabled(ctx
);
24699 /* Treat as NOP. */
24707 check_insn(ctx
, ISA_MIPS_R2
);
24708 gen_bitops(ctx
, op1
, rt
, rs
, sa
, rd
);
24711 op2
= MASK_BSHFL(ctx
->opcode
);
24718 check_insn(ctx
, ISA_MIPS_R6
);
24719 decode_opc_special3_r6(env
, ctx
);
24722 check_insn(ctx
, ISA_MIPS_R2
);
24723 gen_bshfl(ctx
, op2
, rt
, rd
);
24727 #if defined(TARGET_MIPS64)
24734 check_insn(ctx
, ISA_MIPS_R2
);
24735 check_mips_64(ctx
);
24736 gen_bitops(ctx
, op1
, rt
, rs
, sa
, rd
);
24739 op2
= MASK_DBSHFL(ctx
->opcode
);
24750 check_insn(ctx
, ISA_MIPS_R6
);
24751 decode_opc_special3_r6(env
, ctx
);
24754 check_insn(ctx
, ISA_MIPS_R2
);
24755 check_mips_64(ctx
);
24756 op2
= MASK_DBSHFL(ctx
->opcode
);
24757 gen_bshfl(ctx
, op2
, rt
, rd
);
24763 gen_rdhwr(ctx
, rt
, rd
, extract32(ctx
->opcode
, 6, 3));
24768 TCGv t0
= tcg_temp_new();
24769 TCGv t1
= tcg_temp_new();
24771 gen_load_gpr(t0
, rt
);
24772 gen_load_gpr(t1
, rs
);
24773 gen_helper_fork(t0
, t1
);
24781 TCGv t0
= tcg_temp_new();
24783 gen_load_gpr(t0
, rs
);
24784 gen_helper_yield(t0
, cpu_env
, t0
);
24785 gen_store_gpr(t0
, rd
);
24790 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
24791 decode_opc_special3_r6(env
, ctx
);
24793 decode_opc_special3_legacy(env
, ctx
);
24798 static bool decode_opc_legacy(CPUMIPSState
*env
, DisasContext
*ctx
)
24801 int rs
, rt
, rd
, sa
;
24805 op
= MASK_OP_MAJOR(ctx
->opcode
);
24806 rs
= (ctx
->opcode
>> 21) & 0x1f;
24807 rt
= (ctx
->opcode
>> 16) & 0x1f;
24808 rd
= (ctx
->opcode
>> 11) & 0x1f;
24809 sa
= (ctx
->opcode
>> 6) & 0x1f;
24810 imm
= (int16_t)ctx
->opcode
;
24813 decode_opc_special(env
, ctx
);
24816 #if defined(TARGET_MIPS64)
24817 if ((ctx
->insn_flags
& INSN_R5900
) && (ctx
->insn_flags
& ASE_MMI
)) {
24818 decode_mmi(env
, ctx
);
24822 if (TARGET_LONG_BITS
== 32 && (ctx
->insn_flags
& ASE_MXU
)) {
24823 if (MASK_SPECIAL2(ctx
->opcode
) == OPC_MUL
) {
24824 gen_arith(ctx
, OPC_MUL
, rd
, rs
, rt
);
24826 decode_ase_mxu(ctx
, ctx
->opcode
);
24830 decode_opc_special2_legacy(env
, ctx
);
24833 #if defined(TARGET_MIPS64)
24834 if (ctx
->insn_flags
& INSN_R5900
) {
24835 decode_mmi_sq(env
, ctx
); /* MMI_OPC_SQ */
24837 decode_opc_special3(env
, ctx
);
24840 decode_opc_special3(env
, ctx
);
24844 op1
= MASK_REGIMM(ctx
->opcode
);
24846 case OPC_BLTZL
: /* REGIMM branches */
24850 check_insn(ctx
, ISA_MIPS2
);
24851 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
24855 gen_compute_branch(ctx
, op1
, 4, rs
, -1, imm
<< 2, 4);
24859 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
24861 /* OPC_NAL, OPC_BAL */
24862 gen_compute_branch(ctx
, op1
, 4, 0, -1, imm
<< 2, 4);
24864 gen_reserved_instruction(ctx
);
24867 gen_compute_branch(ctx
, op1
, 4, rs
, -1, imm
<< 2, 4);
24870 case OPC_TGEI
: /* REGIMM traps */
24877 check_insn(ctx
, ISA_MIPS2
);
24878 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
24879 gen_trap(ctx
, op1
, rs
, -1, imm
);
24882 check_insn(ctx
, ISA_MIPS_R6
);
24883 gen_reserved_instruction(ctx
);
24886 check_insn(ctx
, ISA_MIPS_R2
);
24888 * Break the TB to be able to sync copied instructions
24891 ctx
->base
.is_jmp
= DISAS_STOP
;
24893 case OPC_BPOSGE32
: /* MIPS DSP branch */
24894 #if defined(TARGET_MIPS64)
24898 gen_compute_branch(ctx
, op1
, 4, -1, -2, (int32_t)imm
<< 2, 4);
24900 #if defined(TARGET_MIPS64)
24902 check_insn(ctx
, ISA_MIPS_R6
);
24903 check_mips_64(ctx
);
24905 tcg_gen_addi_tl(cpu_gpr
[rs
], cpu_gpr
[rs
], (int64_t)imm
<< 32);
24909 check_insn(ctx
, ISA_MIPS_R6
);
24910 check_mips_64(ctx
);
24912 tcg_gen_addi_tl(cpu_gpr
[rs
], cpu_gpr
[rs
], (int64_t)imm
<< 48);
24916 default: /* Invalid */
24917 MIPS_INVAL("regimm");
24918 gen_reserved_instruction(ctx
);
24923 check_cp0_enabled(ctx
);
24924 op1
= MASK_CP0(ctx
->opcode
);
24932 #if defined(TARGET_MIPS64)
24936 #ifndef CONFIG_USER_ONLY
24937 gen_cp0(env
, ctx
, op1
, rt
, rd
);
24938 #endif /* !CONFIG_USER_ONLY */
24956 #ifndef CONFIG_USER_ONLY
24957 gen_cp0(env
, ctx
, MASK_C0(ctx
->opcode
), rt
, rd
);
24958 #endif /* !CONFIG_USER_ONLY */
24961 #ifndef CONFIG_USER_ONLY
24964 TCGv t0
= tcg_temp_new();
24966 op2
= MASK_MFMC0(ctx
->opcode
);
24970 gen_helper_dmt(t0
);
24971 gen_store_gpr(t0
, rt
);
24975 gen_helper_emt(t0
);
24976 gen_store_gpr(t0
, rt
);
24980 gen_helper_dvpe(t0
, cpu_env
);
24981 gen_store_gpr(t0
, rt
);
24985 gen_helper_evpe(t0
, cpu_env
);
24986 gen_store_gpr(t0
, rt
);
24989 check_insn(ctx
, ISA_MIPS_R6
);
24991 gen_helper_dvp(t0
, cpu_env
);
24992 gen_store_gpr(t0
, rt
);
24996 check_insn(ctx
, ISA_MIPS_R6
);
24998 gen_helper_evp(t0
, cpu_env
);
24999 gen_store_gpr(t0
, rt
);
25003 check_insn(ctx
, ISA_MIPS_R2
);
25004 save_cpu_state(ctx
, 1);
25005 gen_helper_di(t0
, cpu_env
);
25006 gen_store_gpr(t0
, rt
);
25008 * Stop translation as we may have switched
25009 * the execution mode.
25011 ctx
->base
.is_jmp
= DISAS_STOP
;
25014 check_insn(ctx
, ISA_MIPS_R2
);
25015 save_cpu_state(ctx
, 1);
25016 gen_helper_ei(t0
, cpu_env
);
25017 gen_store_gpr(t0
, rt
);
25019 * DISAS_STOP isn't sufficient, we need to ensure we break
25020 * out of translated code to check for pending interrupts.
25022 gen_save_pc(ctx
->base
.pc_next
+ 4);
25023 ctx
->base
.is_jmp
= DISAS_EXIT
;
25025 default: /* Invalid */
25026 MIPS_INVAL("mfmc0");
25027 gen_reserved_instruction(ctx
);
25032 #endif /* !CONFIG_USER_ONLY */
25035 check_insn(ctx
, ISA_MIPS_R2
);
25036 gen_load_srsgpr(rt
, rd
);
25039 check_insn(ctx
, ISA_MIPS_R2
);
25040 gen_store_srsgpr(rt
, rd
);
25044 gen_reserved_instruction(ctx
);
25048 case OPC_BOVC
: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */
25049 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
25050 /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */
25051 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
25054 /* Arithmetic with immediate opcode */
25055 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
25059 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
25061 case OPC_SLTI
: /* Set on less than with immediate opcode */
25063 gen_slt_imm(ctx
, op
, rt
, rs
, imm
);
25065 case OPC_ANDI
: /* Arithmetic with immediate opcode */
25066 case OPC_LUI
: /* OPC_AUI */
25069 gen_logic_imm(ctx
, op
, rt
, rs
, imm
);
25071 case OPC_J
: /* Jump */
25073 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
25074 gen_compute_branch(ctx
, op
, 4, rs
, rt
, offset
, 4);
25077 case OPC_BLEZC
: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */
25078 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
25080 gen_reserved_instruction(ctx
);
25083 /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */
25084 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
25087 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
25090 case OPC_BGTZC
: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */
25091 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
25093 gen_reserved_instruction(ctx
);
25096 /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */
25097 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
25100 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
25103 case OPC_BLEZALC
: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */
25106 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
25108 check_insn(ctx
, ISA_MIPS_R6
);
25109 /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */
25110 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
25113 case OPC_BGTZALC
: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */
25116 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
25118 check_insn(ctx
, ISA_MIPS_R6
);
25119 /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */
25120 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
25125 check_insn(ctx
, ISA_MIPS2
);
25126 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
25130 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
25132 case OPC_LL
: /* Load and stores */
25133 check_insn(ctx
, ISA_MIPS2
);
25134 if (ctx
->insn_flags
& INSN_R5900
) {
25135 check_insn_opc_user_only(ctx
, INSN_R5900
);
25146 gen_ld(ctx
, op
, rt
, rs
, imm
);
25153 gen_st(ctx
, op
, rt
, rs
, imm
);
25156 check_insn(ctx
, ISA_MIPS2
);
25157 if (ctx
->insn_flags
& INSN_R5900
) {
25158 check_insn_opc_user_only(ctx
, INSN_R5900
);
25160 gen_st_cond(ctx
, rt
, rs
, imm
, MO_TESL
, false);
25163 check_cp0_enabled(ctx
);
25164 check_insn(ctx
, ISA_MIPS3
| ISA_MIPS_R1
);
25165 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
25166 gen_cache_operation(ctx
, rt
, rs
, imm
);
25168 /* Treat as NOP. */
25171 if (ctx
->insn_flags
& INSN_R5900
) {
25172 /* Treat as NOP. */
25174 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS_R1
);
25175 /* Treat as NOP. */
25179 /* Floating point (COP1). */
25184 gen_cop1_ldst(ctx
, op
, rt
, rs
, imm
);
25188 op1
= MASK_CP1(ctx
->opcode
);
25193 check_cp1_enabled(ctx
);
25194 check_insn(ctx
, ISA_MIPS_R2
);
25200 check_cp1_enabled(ctx
);
25201 gen_cp1(ctx
, op1
, rt
, rd
);
25203 #if defined(TARGET_MIPS64)
25206 check_cp1_enabled(ctx
);
25207 check_insn(ctx
, ISA_MIPS3
);
25208 check_mips_64(ctx
);
25209 gen_cp1(ctx
, op1
, rt
, rd
);
25212 case OPC_BC1EQZ
: /* OPC_BC1ANY2 */
25213 check_cp1_enabled(ctx
);
25214 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
25216 gen_compute_branch1_r6(ctx
, MASK_CP1(ctx
->opcode
),
25221 check_insn(ctx
, ASE_MIPS3D
);
25222 gen_compute_branch1(ctx
, MASK_BC1(ctx
->opcode
),
25223 (rt
>> 2) & 0x7, imm
<< 2);
25227 check_cp1_enabled(ctx
);
25228 check_insn(ctx
, ISA_MIPS_R6
);
25229 gen_compute_branch1_r6(ctx
, MASK_CP1(ctx
->opcode
),
25233 check_cp1_enabled(ctx
);
25234 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
25236 check_insn(ctx
, ASE_MIPS3D
);
25239 check_cp1_enabled(ctx
);
25240 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
25241 gen_compute_branch1(ctx
, MASK_BC1(ctx
->opcode
),
25242 (rt
>> 2) & 0x7, imm
<< 2);
25249 check_cp1_enabled(ctx
);
25250 gen_farith(ctx
, ctx
->opcode
& FOP(0x3f, 0x1f), rt
, rd
, sa
,
25256 int r6_op
= ctx
->opcode
& FOP(0x3f, 0x1f);
25257 check_cp1_enabled(ctx
);
25258 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
25260 case R6_OPC_CMP_AF_S
:
25261 case R6_OPC_CMP_UN_S
:
25262 case R6_OPC_CMP_EQ_S
:
25263 case R6_OPC_CMP_UEQ_S
:
25264 case R6_OPC_CMP_LT_S
:
25265 case R6_OPC_CMP_ULT_S
:
25266 case R6_OPC_CMP_LE_S
:
25267 case R6_OPC_CMP_ULE_S
:
25268 case R6_OPC_CMP_SAF_S
:
25269 case R6_OPC_CMP_SUN_S
:
25270 case R6_OPC_CMP_SEQ_S
:
25271 case R6_OPC_CMP_SEUQ_S
:
25272 case R6_OPC_CMP_SLT_S
:
25273 case R6_OPC_CMP_SULT_S
:
25274 case R6_OPC_CMP_SLE_S
:
25275 case R6_OPC_CMP_SULE_S
:
25276 case R6_OPC_CMP_OR_S
:
25277 case R6_OPC_CMP_UNE_S
:
25278 case R6_OPC_CMP_NE_S
:
25279 case R6_OPC_CMP_SOR_S
:
25280 case R6_OPC_CMP_SUNE_S
:
25281 case R6_OPC_CMP_SNE_S
:
25282 gen_r6_cmp_s(ctx
, ctx
->opcode
& 0x1f, rt
, rd
, sa
);
25284 case R6_OPC_CMP_AF_D
:
25285 case R6_OPC_CMP_UN_D
:
25286 case R6_OPC_CMP_EQ_D
:
25287 case R6_OPC_CMP_UEQ_D
:
25288 case R6_OPC_CMP_LT_D
:
25289 case R6_OPC_CMP_ULT_D
:
25290 case R6_OPC_CMP_LE_D
:
25291 case R6_OPC_CMP_ULE_D
:
25292 case R6_OPC_CMP_SAF_D
:
25293 case R6_OPC_CMP_SUN_D
:
25294 case R6_OPC_CMP_SEQ_D
:
25295 case R6_OPC_CMP_SEUQ_D
:
25296 case R6_OPC_CMP_SLT_D
:
25297 case R6_OPC_CMP_SULT_D
:
25298 case R6_OPC_CMP_SLE_D
:
25299 case R6_OPC_CMP_SULE_D
:
25300 case R6_OPC_CMP_OR_D
:
25301 case R6_OPC_CMP_UNE_D
:
25302 case R6_OPC_CMP_NE_D
:
25303 case R6_OPC_CMP_SOR_D
:
25304 case R6_OPC_CMP_SUNE_D
:
25305 case R6_OPC_CMP_SNE_D
:
25306 gen_r6_cmp_d(ctx
, ctx
->opcode
& 0x1f, rt
, rd
, sa
);
25309 gen_farith(ctx
, ctx
->opcode
& FOP(0x3f, 0x1f),
25310 rt
, rd
, sa
, (imm
>> 8) & 0x7);
25315 gen_farith(ctx
, ctx
->opcode
& FOP(0x3f, 0x1f), rt
, rd
, sa
,
25322 gen_reserved_instruction(ctx
);
25327 /* Compact branches [R6] and COP2 [non-R6] */
25328 case OPC_BC
: /* OPC_LWC2 */
25329 case OPC_BALC
: /* OPC_SWC2 */
25330 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
25331 /* OPC_BC, OPC_BALC */
25332 gen_compute_compact_branch(ctx
, op
, 0, 0,
25333 sextract32(ctx
->opcode
<< 2, 0, 28));
25334 } else if (ctx
->insn_flags
& ASE_LEXT
) {
25335 gen_loongson_lswc2(ctx
, rt
, rs
, rd
);
25337 /* OPC_LWC2, OPC_SWC2 */
25338 /* COP2: Not implemented. */
25339 generate_exception_err(ctx
, EXCP_CpU
, 2);
25342 case OPC_BEQZC
: /* OPC_JIC, OPC_LDC2 */
25343 case OPC_BNEZC
: /* OPC_JIALC, OPC_SDC2 */
25344 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
25346 /* OPC_BEQZC, OPC_BNEZC */
25347 gen_compute_compact_branch(ctx
, op
, rs
, 0,
25348 sextract32(ctx
->opcode
<< 2, 0, 23));
25350 /* OPC_JIC, OPC_JIALC */
25351 gen_compute_compact_branch(ctx
, op
, 0, rt
, imm
);
25353 } else if (ctx
->insn_flags
& ASE_LEXT
) {
25354 gen_loongson_lsdc2(ctx
, rt
, rs
, rd
);
25356 /* OPC_LWC2, OPC_SWC2 */
25357 /* COP2: Not implemented. */
25358 generate_exception_err(ctx
, EXCP_CpU
, 2);
25362 check_insn(ctx
, ASE_LMMI
);
25363 /* Note that these instructions use different fields. */
25364 gen_loongson_multimedia(ctx
, sa
, rd
, rt
);
25368 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
25369 check_cp1_enabled(ctx
);
25370 op1
= MASK_CP3(ctx
->opcode
);
25374 check_insn(ctx
, ISA_MIPS5
| ISA_MIPS_R2
);
25380 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS_R2
);
25381 gen_flt3_ldst(ctx
, op1
, sa
, rd
, rs
, rt
);
25384 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS_R2
);
25385 /* Treat as NOP. */
25388 check_insn(ctx
, ISA_MIPS5
| ISA_MIPS_R2
);
25402 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS_R2
);
25403 gen_flt3_arith(ctx
, op1
, sa
, rs
, rd
, rt
);
25407 gen_reserved_instruction(ctx
);
25411 generate_exception_err(ctx
, EXCP_CpU
, 1);
25415 #if defined(TARGET_MIPS64)
25416 /* MIPS64 opcodes */
25418 if (ctx
->insn_flags
& INSN_R5900
) {
25419 check_insn_opc_user_only(ctx
, INSN_R5900
);
25426 check_insn(ctx
, ISA_MIPS3
);
25427 check_mips_64(ctx
);
25428 gen_ld(ctx
, op
, rt
, rs
, imm
);
25433 check_insn(ctx
, ISA_MIPS3
);
25434 check_mips_64(ctx
);
25435 gen_st(ctx
, op
, rt
, rs
, imm
);
25438 check_insn(ctx
, ISA_MIPS3
);
25439 if (ctx
->insn_flags
& INSN_R5900
) {
25440 check_insn_opc_user_only(ctx
, INSN_R5900
);
25442 check_mips_64(ctx
);
25443 gen_st_cond(ctx
, rt
, rs
, imm
, MO_TEQ
, false);
25445 case OPC_BNVC
: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */
25446 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
25447 /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */
25448 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
25451 check_insn(ctx
, ISA_MIPS3
);
25452 check_mips_64(ctx
);
25453 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
25457 check_insn(ctx
, ISA_MIPS3
);
25458 check_mips_64(ctx
);
25459 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
25462 case OPC_BNVC
: /* OPC_BNEZALC, OPC_BNEC */
25463 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
25464 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
25466 MIPS_INVAL("major opcode");
25467 gen_reserved_instruction(ctx
);
25471 case OPC_DAUI
: /* OPC_JALX */
25472 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
25473 #if defined(TARGET_MIPS64)
25475 check_mips_64(ctx
);
25477 generate_exception(ctx
, EXCP_RI
);
25478 } else if (rt
!= 0) {
25479 TCGv t0
= tcg_temp_new();
25480 gen_load_gpr(t0
, rs
);
25481 tcg_gen_addi_tl(cpu_gpr
[rt
], t0
, imm
<< 16);
25485 gen_reserved_instruction(ctx
);
25486 MIPS_INVAL("major opcode");
25490 check_insn(ctx
, ASE_MIPS16
| ASE_MICROMIPS
);
25491 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
25492 gen_compute_branch(ctx
, op
, 4, rs
, rt
, offset
, 4);
25495 case OPC_MDMX
: /* MMI_OPC_LQ */
25496 if (ctx
->insn_flags
& INSN_R5900
) {
25497 #if defined(TARGET_MIPS64)
25498 gen_mmi_lq(env
, ctx
);
25501 /* MDMX: Not implemented. */
25505 check_insn(ctx
, ISA_MIPS_R6
);
25506 gen_pcrel(ctx
, ctx
->opcode
, ctx
->base
.pc_next
, rs
);
25508 default: /* Invalid */
25509 MIPS_INVAL("major opcode");
25515 static void decode_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
25517 /* make sure instructions are on a word boundary */
25518 if (ctx
->base
.pc_next
& 0x3) {
25519 env
->CP0_BadVAddr
= ctx
->base
.pc_next
;
25520 generate_exception_err(ctx
, EXCP_AdEL
, EXCP_INST_NOTAVAIL
);
25524 /* Handle blikely not taken case */
25525 if ((ctx
->hflags
& MIPS_HFLAG_BMASK_BASE
) == MIPS_HFLAG_BL
) {
25526 TCGLabel
*l1
= gen_new_label();
25528 tcg_gen_brcondi_tl(TCG_COND_NE
, bcond
, 0, l1
);
25529 tcg_gen_movi_i32(hflags
, ctx
->hflags
& ~MIPS_HFLAG_BMASK
);
25530 gen_goto_tb(ctx
, 1, ctx
->base
.pc_next
+ 4);
25534 /* Transition to the auto-generated decoder. */
25536 /* ISA extensions */
25537 if (ase_msa_available(env
) && decode_ase_msa(ctx
, ctx
->opcode
)) {
25541 /* ISA (from latest to oldest) */
25542 if (cpu_supports_isa(env
, ISA_MIPS_R6
) && decode_isa_rel6(ctx
, ctx
->opcode
)) {
25545 if (cpu_supports_isa(env
, INSN_R5900
) && decode_ext_txx9(ctx
, ctx
->opcode
)) {
25549 if (decode_opc_legacy(env
, ctx
)) {
25553 gen_reserved_instruction(ctx
);
25556 static void mips_tr_init_disas_context(DisasContextBase
*dcbase
, CPUState
*cs
)
25558 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
25559 CPUMIPSState
*env
= cs
->env_ptr
;
25561 ctx
->page_start
= ctx
->base
.pc_first
& TARGET_PAGE_MASK
;
25562 ctx
->saved_pc
= -1;
25563 ctx
->insn_flags
= env
->insn_flags
;
25564 ctx
->CP0_Config1
= env
->CP0_Config1
;
25565 ctx
->CP0_Config2
= env
->CP0_Config2
;
25566 ctx
->CP0_Config3
= env
->CP0_Config3
;
25567 ctx
->CP0_Config5
= env
->CP0_Config5
;
25569 ctx
->kscrexist
= (env
->CP0_Config4
>> CP0C4_KScrExist
) & 0xff;
25570 ctx
->rxi
= (env
->CP0_Config3
>> CP0C3_RXI
) & 1;
25571 ctx
->ie
= (env
->CP0_Config4
>> CP0C4_IE
) & 3;
25572 ctx
->bi
= (env
->CP0_Config3
>> CP0C3_BI
) & 1;
25573 ctx
->bp
= (env
->CP0_Config3
>> CP0C3_BP
) & 1;
25574 ctx
->PAMask
= env
->PAMask
;
25575 ctx
->mvh
= (env
->CP0_Config5
>> CP0C5_MVH
) & 1;
25576 ctx
->eva
= (env
->CP0_Config5
>> CP0C5_EVA
) & 1;
25577 ctx
->sc
= (env
->CP0_Config3
>> CP0C3_SC
) & 1;
25578 ctx
->CP0_LLAddr_shift
= env
->CP0_LLAddr_shift
;
25579 ctx
->cmgcr
= (env
->CP0_Config3
>> CP0C3_CMGCR
) & 1;
25580 /* Restore delay slot state from the tb context. */
25581 ctx
->hflags
= (uint32_t)ctx
->base
.tb
->flags
; /* FIXME: maybe use 64 bits? */
25582 ctx
->ulri
= (env
->CP0_Config3
>> CP0C3_ULRI
) & 1;
25583 ctx
->ps
= ((env
->active_fpu
.fcr0
>> FCR0_PS
) & 1) ||
25584 (env
->insn_flags
& (INSN_LOONGSON2E
| INSN_LOONGSON2F
));
25585 ctx
->vp
= (env
->CP0_Config5
>> CP0C5_VP
) & 1;
25586 ctx
->mrp
= (env
->CP0_Config5
>> CP0C5_MRP
) & 1;
25587 ctx
->nan2008
= (env
->active_fpu
.fcr31
>> FCR31_NAN2008
) & 1;
25588 ctx
->abs2008
= (env
->active_fpu
.fcr31
>> FCR31_ABS2008
) & 1;
25589 ctx
->mi
= (env
->CP0_Config5
>> CP0C5_MI
) & 1;
25590 ctx
->gi
= (env
->CP0_Config5
>> CP0C5_GI
) & 3;
25591 restore_cpu_state(env
, ctx
);
25592 #ifdef CONFIG_USER_ONLY
25593 ctx
->mem_idx
= MIPS_HFLAG_UM
;
25595 ctx
->mem_idx
= hflags_mmu_index(ctx
->hflags
);
25597 ctx
->default_tcg_memop_mask
= (ctx
->insn_flags
& (ISA_MIPS_R6
|
25598 INSN_LOONGSON3A
)) ? MO_UNALN
: MO_ALIGN
;
25600 LOG_DISAS("\ntb %p idx %d hflags %04x\n", ctx
->base
.tb
, ctx
->mem_idx
,
25604 static void mips_tr_tb_start(DisasContextBase
*dcbase
, CPUState
*cs
)
25608 static void mips_tr_insn_start(DisasContextBase
*dcbase
, CPUState
*cs
)
25610 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
25612 tcg_gen_insn_start(ctx
->base
.pc_next
, ctx
->hflags
& MIPS_HFLAG_BMASK
,
25616 static bool mips_tr_breakpoint_check(DisasContextBase
*dcbase
, CPUState
*cs
,
25617 const CPUBreakpoint
*bp
)
25619 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
25621 save_cpu_state(ctx
, 1);
25622 ctx
->base
.is_jmp
= DISAS_NORETURN
;
25623 gen_helper_raise_exception_debug(cpu_env
);
25625 * The address covered by the breakpoint must be included in
25626 * [tb->pc, tb->pc + tb->size) in order to for it to be
25627 * properly cleared -- thus we increment the PC here so that
25628 * the logic setting tb->size below does the right thing.
25630 ctx
->base
.pc_next
+= 4;
25634 static void mips_tr_translate_insn(DisasContextBase
*dcbase
, CPUState
*cs
)
25636 CPUMIPSState
*env
= cs
->env_ptr
;
25637 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
25641 is_slot
= ctx
->hflags
& MIPS_HFLAG_BMASK
;
25642 if (ctx
->insn_flags
& ISA_NANOMIPS32
) {
25643 ctx
->opcode
= translator_lduw(env
, ctx
->base
.pc_next
);
25644 insn_bytes
= decode_nanomips_opc(env
, ctx
);
25645 } else if (!(ctx
->hflags
& MIPS_HFLAG_M16
)) {
25646 ctx
->opcode
= translator_ldl(env
, ctx
->base
.pc_next
);
25648 decode_opc(env
, ctx
);
25649 } else if (ctx
->insn_flags
& ASE_MICROMIPS
) {
25650 ctx
->opcode
= translator_lduw(env
, ctx
->base
.pc_next
);
25651 insn_bytes
= decode_micromips_opc(env
, ctx
);
25652 } else if (ctx
->insn_flags
& ASE_MIPS16
) {
25653 ctx
->opcode
= translator_lduw(env
, ctx
->base
.pc_next
);
25654 insn_bytes
= decode_mips16_opc(env
, ctx
);
25656 gen_reserved_instruction(ctx
);
25657 g_assert(ctx
->base
.is_jmp
== DISAS_NORETURN
);
25661 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
25662 if (!(ctx
->hflags
& (MIPS_HFLAG_BDS16
| MIPS_HFLAG_BDS32
|
25663 MIPS_HFLAG_FBNSLOT
))) {
25665 * Force to generate branch as there is neither delay nor
25670 if ((ctx
->hflags
& MIPS_HFLAG_M16
) &&
25671 (ctx
->hflags
& MIPS_HFLAG_FBNSLOT
)) {
25673 * Force to generate branch as microMIPS R6 doesn't restrict
25674 * branches in the forbidden slot.
25680 gen_branch(ctx
, insn_bytes
);
25682 ctx
->base
.pc_next
+= insn_bytes
;
25684 if (ctx
->base
.is_jmp
!= DISAS_NEXT
) {
25688 * Execute a branch and its delay slot as a single instruction.
25689 * This is what GDB expects and is consistent with what the
25690 * hardware does (e.g. if a delay slot instruction faults, the
25691 * reported PC is the PC of the branch).
25693 if (ctx
->base
.singlestep_enabled
&&
25694 (ctx
->hflags
& MIPS_HFLAG_BMASK
) == 0) {
25695 ctx
->base
.is_jmp
= DISAS_TOO_MANY
;
25697 if (ctx
->base
.pc_next
- ctx
->page_start
>= TARGET_PAGE_SIZE
) {
25698 ctx
->base
.is_jmp
= DISAS_TOO_MANY
;
25702 static void mips_tr_tb_stop(DisasContextBase
*dcbase
, CPUState
*cs
)
25704 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
25706 if (ctx
->base
.singlestep_enabled
&& ctx
->base
.is_jmp
!= DISAS_NORETURN
) {
25707 save_cpu_state(ctx
, ctx
->base
.is_jmp
!= DISAS_EXIT
);
25708 gen_helper_raise_exception_debug(cpu_env
);
25710 switch (ctx
->base
.is_jmp
) {
25712 gen_save_pc(ctx
->base
.pc_next
);
25713 tcg_gen_lookup_and_goto_ptr();
25716 case DISAS_TOO_MANY
:
25717 save_cpu_state(ctx
, 0);
25718 gen_goto_tb(ctx
, 0, ctx
->base
.pc_next
);
25721 tcg_gen_exit_tb(NULL
, 0);
25723 case DISAS_NORETURN
:
25726 g_assert_not_reached();
25731 static void mips_tr_disas_log(const DisasContextBase
*dcbase
, CPUState
*cs
)
25733 qemu_log("IN: %s\n", lookup_symbol(dcbase
->pc_first
));
25734 log_target_disas(cs
, dcbase
->pc_first
, dcbase
->tb
->size
);
25737 static const TranslatorOps mips_tr_ops
= {
25738 .init_disas_context
= mips_tr_init_disas_context
,
25739 .tb_start
= mips_tr_tb_start
,
25740 .insn_start
= mips_tr_insn_start
,
25741 .breakpoint_check
= mips_tr_breakpoint_check
,
25742 .translate_insn
= mips_tr_translate_insn
,
25743 .tb_stop
= mips_tr_tb_stop
,
25744 .disas_log
= mips_tr_disas_log
,
25747 void gen_intermediate_code(CPUState
*cs
, TranslationBlock
*tb
, int max_insns
)
25751 translator_loop(&mips_tr_ops
, &ctx
.base
, cs
, tb
, max_insns
);
25754 static void fpu_dump_state(CPUMIPSState
*env
, FILE * f
, int flags
)
25757 int is_fpu64
= !!(env
->hflags
& MIPS_HFLAG_F64
);
25759 #define printfpr(fp) \
25762 qemu_fprintf(f, "w:%08x d:%016" PRIx64 \
25763 " fd:%13g fs:%13g psu: %13g\n", \
25764 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
25765 (double)(fp)->fd, \
25766 (double)(fp)->fs[FP_ENDIAN_IDX], \
25767 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
25770 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
25771 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
25772 qemu_fprintf(f, "w:%08x d:%016" PRIx64 \
25773 " fd:%13g fs:%13g psu:%13g\n", \
25774 tmp.w[FP_ENDIAN_IDX], tmp.d, \
25776 (double)tmp.fs[FP_ENDIAN_IDX], \
25777 (double)tmp.fs[!FP_ENDIAN_IDX]); \
25783 "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
25784 env
->active_fpu
.fcr0
, env
->active_fpu
.fcr31
, is_fpu64
,
25785 get_float_exception_flags(&env
->active_fpu
.fp_status
));
25786 for (i
= 0; i
< 32; (is_fpu64
) ? i
++ : (i
+= 2)) {
25787 qemu_fprintf(f
, "%3s: ", fregnames
[i
]);
25788 printfpr(&env
->active_fpu
.fpr
[i
]);
25794 void mips_cpu_dump_state(CPUState
*cs
, FILE *f
, int flags
)
25796 MIPSCPU
*cpu
= MIPS_CPU(cs
);
25797 CPUMIPSState
*env
= &cpu
->env
;
25800 qemu_fprintf(f
, "pc=0x" TARGET_FMT_lx
" HI=0x" TARGET_FMT_lx
25801 " LO=0x" TARGET_FMT_lx
" ds %04x "
25802 TARGET_FMT_lx
" " TARGET_FMT_ld
"\n",
25803 env
->active_tc
.PC
, env
->active_tc
.HI
[0], env
->active_tc
.LO
[0],
25804 env
->hflags
, env
->btarget
, env
->bcond
);
25805 for (i
= 0; i
< 32; i
++) {
25806 if ((i
& 3) == 0) {
25807 qemu_fprintf(f
, "GPR%02d:", i
);
25809 qemu_fprintf(f
, " %s " TARGET_FMT_lx
,
25810 regnames
[i
], env
->active_tc
.gpr
[i
]);
25811 if ((i
& 3) == 3) {
25812 qemu_fprintf(f
, "\n");
25816 qemu_fprintf(f
, "CP0 Status 0x%08x Cause 0x%08x EPC 0x"
25817 TARGET_FMT_lx
"\n",
25818 env
->CP0_Status
, env
->CP0_Cause
, env
->CP0_EPC
);
25819 qemu_fprintf(f
, " Config0 0x%08x Config1 0x%08x LLAddr 0x%016"
25821 env
->CP0_Config0
, env
->CP0_Config1
, env
->CP0_LLAddr
);
25822 qemu_fprintf(f
, " Config2 0x%08x Config3 0x%08x\n",
25823 env
->CP0_Config2
, env
->CP0_Config3
);
25824 qemu_fprintf(f
, " Config4 0x%08x Config5 0x%08x\n",
25825 env
->CP0_Config4
, env
->CP0_Config5
);
25826 if ((flags
& CPU_DUMP_FPU
) && (env
->hflags
& MIPS_HFLAG_FPU
)) {
25827 fpu_dump_state(env
, f
, flags
);
25831 void mips_tcg_init(void)
25836 for (i
= 1; i
< 32; i
++)
25837 cpu_gpr
[i
] = tcg_global_mem_new(cpu_env
,
25838 offsetof(CPUMIPSState
,
25841 #if defined(TARGET_MIPS64)
25842 cpu_gpr_hi
[0] = NULL
;
25844 for (unsigned i
= 1; i
< 32; i
++) {
25845 g_autofree
char *rname
= g_strdup_printf("%s[hi]", regnames
[i
]);
25847 cpu_gpr_hi
[i
] = tcg_global_mem_new_i64(cpu_env
,
25848 offsetof(CPUMIPSState
,
25849 active_tc
.gpr_hi
[i
]),
25852 #endif /* !TARGET_MIPS64 */
25853 for (i
= 0; i
< 32; i
++) {
25854 int off
= offsetof(CPUMIPSState
, active_fpu
.fpr
[i
].wr
.d
[0]);
25856 fpu_f64
[i
] = tcg_global_mem_new_i64(cpu_env
, off
, fregnames
[i
]);
25858 msa_translate_init();
25859 cpu_PC
= tcg_global_mem_new(cpu_env
,
25860 offsetof(CPUMIPSState
, active_tc
.PC
), "PC");
25861 for (i
= 0; i
< MIPS_DSP_ACC
; i
++) {
25862 cpu_HI
[i
] = tcg_global_mem_new(cpu_env
,
25863 offsetof(CPUMIPSState
, active_tc
.HI
[i
]),
25865 cpu_LO
[i
] = tcg_global_mem_new(cpu_env
,
25866 offsetof(CPUMIPSState
, active_tc
.LO
[i
]),
25869 cpu_dspctrl
= tcg_global_mem_new(cpu_env
,
25870 offsetof(CPUMIPSState
,
25871 active_tc
.DSPControl
),
25873 bcond
= tcg_global_mem_new(cpu_env
,
25874 offsetof(CPUMIPSState
, bcond
), "bcond");
25875 btarget
= tcg_global_mem_new(cpu_env
,
25876 offsetof(CPUMIPSState
, btarget
), "btarget");
25877 hflags
= tcg_global_mem_new_i32(cpu_env
,
25878 offsetof(CPUMIPSState
, hflags
), "hflags");
25880 fpu_fcr0
= tcg_global_mem_new_i32(cpu_env
,
25881 offsetof(CPUMIPSState
, active_fpu
.fcr0
),
25883 fpu_fcr31
= tcg_global_mem_new_i32(cpu_env
,
25884 offsetof(CPUMIPSState
, active_fpu
.fcr31
),
25886 cpu_lladdr
= tcg_global_mem_new(cpu_env
, offsetof(CPUMIPSState
, lladdr
),
25888 cpu_llval
= tcg_global_mem_new(cpu_env
, offsetof(CPUMIPSState
, llval
),
25891 if (TARGET_LONG_BITS
== 32) {
25892 mxu_translate_init();
25896 void restore_state_to_opc(CPUMIPSState
*env
, TranslationBlock
*tb
,
25897 target_ulong
*data
)
25899 env
->active_tc
.PC
= data
[0];
25900 env
->hflags
&= ~MIPS_HFLAG_BMASK
;
25901 env
->hflags
|= data
[1];
25902 switch (env
->hflags
& MIPS_HFLAG_BMASK_BASE
) {
25903 case MIPS_HFLAG_BR
:
25905 case MIPS_HFLAG_BC
:
25906 case MIPS_HFLAG_BL
:
25908 env
->btarget
= data
[2];