2 * MIPS emulation for QEMU - main translation routines
4 * Copyright (c) 2004-2005 Jocelyn Mayer
5 * Copyright (c) 2006 Marius Groeger (FPU operations)
6 * Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support)
7 * Copyright (c) 2009 CodeSourcery (MIPS16 and microMIPS support)
8 * Copyright (c) 2012 Jia Liu & Dongxue Zhang (MIPS ASE DSP support)
9 * Copyright (c) 2020 Philippe Mathieu-Daudé
11 * This library is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public
13 * License as published by the Free Software Foundation; either
14 * version 2.1 of the License, or (at your option) any later version.
16 * This library is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
25 #include "qemu/osdep.h"
28 #include "tcg/tcg-op.h"
29 #include "exec/translator.h"
30 #include "exec/helper-proto.h"
31 #include "exec/helper-gen.h"
32 #include "semihosting/semihost.h"
34 #include "target/mips/trace.h"
35 #include "trace-tcg.h"
36 #include "exec/translator.h"
38 #include "qemu/qemu-print.h"
39 #include "fpu_helper.h"
40 #include "translate.h"
43 /* indirect opcode tables */
44 OPC_SPECIAL
= (0x00 << 26),
45 OPC_REGIMM
= (0x01 << 26),
46 OPC_CP0
= (0x10 << 26),
47 OPC_CP2
= (0x12 << 26),
48 OPC_CP3
= (0x13 << 26),
49 OPC_SPECIAL2
= (0x1C << 26),
50 OPC_SPECIAL3
= (0x1F << 26),
51 /* arithmetic with immediate */
52 OPC_ADDI
= (0x08 << 26),
53 OPC_ADDIU
= (0x09 << 26),
54 OPC_SLTI
= (0x0A << 26),
55 OPC_SLTIU
= (0x0B << 26),
56 /* logic with immediate */
57 OPC_ANDI
= (0x0C << 26),
58 OPC_ORI
= (0x0D << 26),
59 OPC_XORI
= (0x0E << 26),
60 OPC_LUI
= (0x0F << 26),
61 /* arithmetic with immediate */
62 OPC_DADDI
= (0x18 << 26),
63 OPC_DADDIU
= (0x19 << 26),
64 /* Jump and branches */
66 OPC_JAL
= (0x03 << 26),
67 OPC_BEQ
= (0x04 << 26), /* Unconditional if rs = rt = 0 (B) */
68 OPC_BEQL
= (0x14 << 26),
69 OPC_BNE
= (0x05 << 26),
70 OPC_BNEL
= (0x15 << 26),
71 OPC_BLEZ
= (0x06 << 26),
72 OPC_BLEZL
= (0x16 << 26),
73 OPC_BGTZ
= (0x07 << 26),
74 OPC_BGTZL
= (0x17 << 26),
75 OPC_JALX
= (0x1D << 26),
76 OPC_DAUI
= (0x1D << 26),
78 OPC_LDL
= (0x1A << 26),
79 OPC_LDR
= (0x1B << 26),
80 OPC_LB
= (0x20 << 26),
81 OPC_LH
= (0x21 << 26),
82 OPC_LWL
= (0x22 << 26),
83 OPC_LW
= (0x23 << 26),
84 OPC_LWPC
= OPC_LW
| 0x5,
85 OPC_LBU
= (0x24 << 26),
86 OPC_LHU
= (0x25 << 26),
87 OPC_LWR
= (0x26 << 26),
88 OPC_LWU
= (0x27 << 26),
89 OPC_SB
= (0x28 << 26),
90 OPC_SH
= (0x29 << 26),
91 OPC_SWL
= (0x2A << 26),
92 OPC_SW
= (0x2B << 26),
93 OPC_SDL
= (0x2C << 26),
94 OPC_SDR
= (0x2D << 26),
95 OPC_SWR
= (0x2E << 26),
96 OPC_LL
= (0x30 << 26),
97 OPC_LLD
= (0x34 << 26),
98 OPC_LD
= (0x37 << 26),
99 OPC_LDPC
= OPC_LD
| 0x5,
100 OPC_SC
= (0x38 << 26),
101 OPC_SCD
= (0x3C << 26),
102 OPC_SD
= (0x3F << 26),
103 /* Floating point load/store */
104 OPC_LWC1
= (0x31 << 26),
105 OPC_LWC2
= (0x32 << 26),
106 OPC_LDC1
= (0x35 << 26),
107 OPC_LDC2
= (0x36 << 26),
108 OPC_SWC1
= (0x39 << 26),
109 OPC_SWC2
= (0x3A << 26),
110 OPC_SDC1
= (0x3D << 26),
111 OPC_SDC2
= (0x3E << 26),
112 /* Compact Branches */
113 OPC_BLEZALC
= (0x06 << 26),
114 OPC_BGEZALC
= (0x06 << 26),
115 OPC_BGEUC
= (0x06 << 26),
116 OPC_BGTZALC
= (0x07 << 26),
117 OPC_BLTZALC
= (0x07 << 26),
118 OPC_BLTUC
= (0x07 << 26),
119 OPC_BOVC
= (0x08 << 26),
120 OPC_BEQZALC
= (0x08 << 26),
121 OPC_BEQC
= (0x08 << 26),
122 OPC_BLEZC
= (0x16 << 26),
123 OPC_BGEZC
= (0x16 << 26),
124 OPC_BGEC
= (0x16 << 26),
125 OPC_BGTZC
= (0x17 << 26),
126 OPC_BLTZC
= (0x17 << 26),
127 OPC_BLTC
= (0x17 << 26),
128 OPC_BNVC
= (0x18 << 26),
129 OPC_BNEZALC
= (0x18 << 26),
130 OPC_BNEC
= (0x18 << 26),
131 OPC_BC
= (0x32 << 26),
132 OPC_BEQZC
= (0x36 << 26),
133 OPC_JIC
= (0x36 << 26),
134 OPC_BALC
= (0x3A << 26),
135 OPC_BNEZC
= (0x3E << 26),
136 OPC_JIALC
= (0x3E << 26),
137 /* MDMX ASE specific */
138 OPC_MDMX
= (0x1E << 26),
139 /* Cache and prefetch */
140 OPC_CACHE
= (0x2F << 26),
141 OPC_PREF
= (0x33 << 26),
142 /* PC-relative address computation / loads */
143 OPC_PCREL
= (0x3B << 26),
146 /* PC-relative address computation / loads */
147 #define MASK_OPC_PCREL_TOP2BITS(op) (MASK_OP_MAJOR(op) | (op & (3 << 19)))
148 #define MASK_OPC_PCREL_TOP5BITS(op) (MASK_OP_MAJOR(op) | (op & (0x1f << 16)))
150 /* Instructions determined by bits 19 and 20 */
151 OPC_ADDIUPC
= OPC_PCREL
| (0 << 19),
152 R6_OPC_LWPC
= OPC_PCREL
| (1 << 19),
153 OPC_LWUPC
= OPC_PCREL
| (2 << 19),
155 /* Instructions determined by bits 16 ... 20 */
156 OPC_AUIPC
= OPC_PCREL
| (0x1e << 16),
157 OPC_ALUIPC
= OPC_PCREL
| (0x1f << 16),
160 R6_OPC_LDPC
= OPC_PCREL
| (6 << 18),
163 /* MIPS special opcodes */
164 #define MASK_SPECIAL(op) (MASK_OP_MAJOR(op) | (op & 0x3F))
168 OPC_SLL
= 0x00 | OPC_SPECIAL
,
169 /* NOP is SLL r0, r0, 0 */
170 /* SSNOP is SLL r0, r0, 1 */
171 /* EHB is SLL r0, r0, 3 */
172 OPC_SRL
= 0x02 | OPC_SPECIAL
, /* also ROTR */
173 OPC_ROTR
= OPC_SRL
| (1 << 21),
174 OPC_SRA
= 0x03 | OPC_SPECIAL
,
175 OPC_SLLV
= 0x04 | OPC_SPECIAL
,
176 OPC_SRLV
= 0x06 | OPC_SPECIAL
, /* also ROTRV */
177 OPC_ROTRV
= OPC_SRLV
| (1 << 6),
178 OPC_SRAV
= 0x07 | OPC_SPECIAL
,
179 OPC_DSLLV
= 0x14 | OPC_SPECIAL
,
180 OPC_DSRLV
= 0x16 | OPC_SPECIAL
, /* also DROTRV */
181 OPC_DROTRV
= OPC_DSRLV
| (1 << 6),
182 OPC_DSRAV
= 0x17 | OPC_SPECIAL
,
183 OPC_DSLL
= 0x38 | OPC_SPECIAL
,
184 OPC_DSRL
= 0x3A | OPC_SPECIAL
, /* also DROTR */
185 OPC_DROTR
= OPC_DSRL
| (1 << 21),
186 OPC_DSRA
= 0x3B | OPC_SPECIAL
,
187 OPC_DSLL32
= 0x3C | OPC_SPECIAL
,
188 OPC_DSRL32
= 0x3E | OPC_SPECIAL
, /* also DROTR32 */
189 OPC_DROTR32
= OPC_DSRL32
| (1 << 21),
190 OPC_DSRA32
= 0x3F | OPC_SPECIAL
,
191 /* Multiplication / division */
192 OPC_MULT
= 0x18 | OPC_SPECIAL
,
193 OPC_MULTU
= 0x19 | OPC_SPECIAL
,
194 OPC_DIV
= 0x1A | OPC_SPECIAL
,
195 OPC_DIVU
= 0x1B | OPC_SPECIAL
,
196 OPC_DMULT
= 0x1C | OPC_SPECIAL
,
197 OPC_DMULTU
= 0x1D | OPC_SPECIAL
,
198 OPC_DDIV
= 0x1E | OPC_SPECIAL
,
199 OPC_DDIVU
= 0x1F | OPC_SPECIAL
,
201 /* 2 registers arithmetic / logic */
202 OPC_ADD
= 0x20 | OPC_SPECIAL
,
203 OPC_ADDU
= 0x21 | OPC_SPECIAL
,
204 OPC_SUB
= 0x22 | OPC_SPECIAL
,
205 OPC_SUBU
= 0x23 | OPC_SPECIAL
,
206 OPC_AND
= 0x24 | OPC_SPECIAL
,
207 OPC_OR
= 0x25 | OPC_SPECIAL
,
208 OPC_XOR
= 0x26 | OPC_SPECIAL
,
209 OPC_NOR
= 0x27 | OPC_SPECIAL
,
210 OPC_SLT
= 0x2A | OPC_SPECIAL
,
211 OPC_SLTU
= 0x2B | OPC_SPECIAL
,
212 OPC_DADD
= 0x2C | OPC_SPECIAL
,
213 OPC_DADDU
= 0x2D | OPC_SPECIAL
,
214 OPC_DSUB
= 0x2E | OPC_SPECIAL
,
215 OPC_DSUBU
= 0x2F | OPC_SPECIAL
,
217 OPC_JR
= 0x08 | OPC_SPECIAL
, /* Also JR.HB */
218 OPC_JALR
= 0x09 | OPC_SPECIAL
, /* Also JALR.HB */
220 OPC_TGE
= 0x30 | OPC_SPECIAL
,
221 OPC_TGEU
= 0x31 | OPC_SPECIAL
,
222 OPC_TLT
= 0x32 | OPC_SPECIAL
,
223 OPC_TLTU
= 0x33 | OPC_SPECIAL
,
224 OPC_TEQ
= 0x34 | OPC_SPECIAL
,
225 OPC_TNE
= 0x36 | OPC_SPECIAL
,
226 /* HI / LO registers load & stores */
227 OPC_MFHI
= 0x10 | OPC_SPECIAL
,
228 OPC_MTHI
= 0x11 | OPC_SPECIAL
,
229 OPC_MFLO
= 0x12 | OPC_SPECIAL
,
230 OPC_MTLO
= 0x13 | OPC_SPECIAL
,
231 /* Conditional moves */
232 OPC_MOVZ
= 0x0A | OPC_SPECIAL
,
233 OPC_MOVN
= 0x0B | OPC_SPECIAL
,
235 OPC_SELEQZ
= 0x35 | OPC_SPECIAL
,
236 OPC_SELNEZ
= 0x37 | OPC_SPECIAL
,
238 OPC_MOVCI
= 0x01 | OPC_SPECIAL
,
241 OPC_PMON
= 0x05 | OPC_SPECIAL
, /* unofficial */
242 OPC_SYSCALL
= 0x0C | OPC_SPECIAL
,
243 OPC_BREAK
= 0x0D | OPC_SPECIAL
,
244 OPC_SPIM
= 0x0E | OPC_SPECIAL
, /* unofficial */
245 OPC_SYNC
= 0x0F | OPC_SPECIAL
,
247 OPC_SPECIAL28_RESERVED
= 0x28 | OPC_SPECIAL
,
248 OPC_SPECIAL29_RESERVED
= 0x29 | OPC_SPECIAL
,
249 OPC_SPECIAL39_RESERVED
= 0x39 | OPC_SPECIAL
,
250 OPC_SPECIAL3D_RESERVED
= 0x3D | OPC_SPECIAL
,
254 * R6 Multiply and Divide instructions have the same opcode
255 * and function field as legacy OPC_MULT[U]/OPC_DIV[U]
257 #define MASK_R6_MULDIV(op) (MASK_SPECIAL(op) | (op & (0x7ff)))
260 R6_OPC_MUL
= OPC_MULT
| (2 << 6),
261 R6_OPC_MUH
= OPC_MULT
| (3 << 6),
262 R6_OPC_MULU
= OPC_MULTU
| (2 << 6),
263 R6_OPC_MUHU
= OPC_MULTU
| (3 << 6),
264 R6_OPC_DIV
= OPC_DIV
| (2 << 6),
265 R6_OPC_MOD
= OPC_DIV
| (3 << 6),
266 R6_OPC_DIVU
= OPC_DIVU
| (2 << 6),
267 R6_OPC_MODU
= OPC_DIVU
| (3 << 6),
269 R6_OPC_DMUL
= OPC_DMULT
| (2 << 6),
270 R6_OPC_DMUH
= OPC_DMULT
| (3 << 6),
271 R6_OPC_DMULU
= OPC_DMULTU
| (2 << 6),
272 R6_OPC_DMUHU
= OPC_DMULTU
| (3 << 6),
273 R6_OPC_DDIV
= OPC_DDIV
| (2 << 6),
274 R6_OPC_DMOD
= OPC_DDIV
| (3 << 6),
275 R6_OPC_DDIVU
= OPC_DDIVU
| (2 << 6),
276 R6_OPC_DMODU
= OPC_DDIVU
| (3 << 6),
278 R6_OPC_CLZ
= 0x10 | OPC_SPECIAL
,
279 R6_OPC_CLO
= 0x11 | OPC_SPECIAL
,
280 R6_OPC_DCLZ
= 0x12 | OPC_SPECIAL
,
281 R6_OPC_DCLO
= 0x13 | OPC_SPECIAL
,
282 R6_OPC_SDBBP
= 0x0e | OPC_SPECIAL
,
285 /* Multiplication variants of the vr54xx. */
286 #define MASK_MUL_VR54XX(op) (MASK_SPECIAL(op) | (op & (0x1F << 6)))
289 OPC_VR54XX_MULS
= (0x03 << 6) | OPC_MULT
,
290 OPC_VR54XX_MULSU
= (0x03 << 6) | OPC_MULTU
,
291 OPC_VR54XX_MACC
= (0x05 << 6) | OPC_MULT
,
292 OPC_VR54XX_MACCU
= (0x05 << 6) | OPC_MULTU
,
293 OPC_VR54XX_MSAC
= (0x07 << 6) | OPC_MULT
,
294 OPC_VR54XX_MSACU
= (0x07 << 6) | OPC_MULTU
,
295 OPC_VR54XX_MULHI
= (0x09 << 6) | OPC_MULT
,
296 OPC_VR54XX_MULHIU
= (0x09 << 6) | OPC_MULTU
,
297 OPC_VR54XX_MULSHI
= (0x0B << 6) | OPC_MULT
,
298 OPC_VR54XX_MULSHIU
= (0x0B << 6) | OPC_MULTU
,
299 OPC_VR54XX_MACCHI
= (0x0D << 6) | OPC_MULT
,
300 OPC_VR54XX_MACCHIU
= (0x0D << 6) | OPC_MULTU
,
301 OPC_VR54XX_MSACHI
= (0x0F << 6) | OPC_MULT
,
302 OPC_VR54XX_MSACHIU
= (0x0F << 6) | OPC_MULTU
,
305 /* REGIMM (rt field) opcodes */
306 #define MASK_REGIMM(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 16)))
309 OPC_BLTZ
= (0x00 << 16) | OPC_REGIMM
,
310 OPC_BLTZL
= (0x02 << 16) | OPC_REGIMM
,
311 OPC_BGEZ
= (0x01 << 16) | OPC_REGIMM
,
312 OPC_BGEZL
= (0x03 << 16) | OPC_REGIMM
,
313 OPC_BLTZAL
= (0x10 << 16) | OPC_REGIMM
,
314 OPC_BLTZALL
= (0x12 << 16) | OPC_REGIMM
,
315 OPC_BGEZAL
= (0x11 << 16) | OPC_REGIMM
,
316 OPC_BGEZALL
= (0x13 << 16) | OPC_REGIMM
,
317 OPC_TGEI
= (0x08 << 16) | OPC_REGIMM
,
318 OPC_TGEIU
= (0x09 << 16) | OPC_REGIMM
,
319 OPC_TLTI
= (0x0A << 16) | OPC_REGIMM
,
320 OPC_TLTIU
= (0x0B << 16) | OPC_REGIMM
,
321 OPC_TEQI
= (0x0C << 16) | OPC_REGIMM
,
322 OPC_TNEI
= (0x0E << 16) | OPC_REGIMM
,
323 OPC_SIGRIE
= (0x17 << 16) | OPC_REGIMM
,
324 OPC_SYNCI
= (0x1F << 16) | OPC_REGIMM
,
326 OPC_DAHI
= (0x06 << 16) | OPC_REGIMM
,
327 OPC_DATI
= (0x1e << 16) | OPC_REGIMM
,
330 /* Special2 opcodes */
331 #define MASK_SPECIAL2(op) (MASK_OP_MAJOR(op) | (op & 0x3F))
334 /* Multiply & xxx operations */
335 OPC_MADD
= 0x00 | OPC_SPECIAL2
,
336 OPC_MADDU
= 0x01 | OPC_SPECIAL2
,
337 OPC_MUL
= 0x02 | OPC_SPECIAL2
,
338 OPC_MSUB
= 0x04 | OPC_SPECIAL2
,
339 OPC_MSUBU
= 0x05 | OPC_SPECIAL2
,
341 OPC_MULT_G_2F
= 0x10 | OPC_SPECIAL2
,
342 OPC_DMULT_G_2F
= 0x11 | OPC_SPECIAL2
,
343 OPC_MULTU_G_2F
= 0x12 | OPC_SPECIAL2
,
344 OPC_DMULTU_G_2F
= 0x13 | OPC_SPECIAL2
,
345 OPC_DIV_G_2F
= 0x14 | OPC_SPECIAL2
,
346 OPC_DDIV_G_2F
= 0x15 | OPC_SPECIAL2
,
347 OPC_DIVU_G_2F
= 0x16 | OPC_SPECIAL2
,
348 OPC_DDIVU_G_2F
= 0x17 | OPC_SPECIAL2
,
349 OPC_MOD_G_2F
= 0x1c | OPC_SPECIAL2
,
350 OPC_DMOD_G_2F
= 0x1d | OPC_SPECIAL2
,
351 OPC_MODU_G_2F
= 0x1e | OPC_SPECIAL2
,
352 OPC_DMODU_G_2F
= 0x1f | OPC_SPECIAL2
,
354 OPC_CLZ
= 0x20 | OPC_SPECIAL2
,
355 OPC_CLO
= 0x21 | OPC_SPECIAL2
,
356 OPC_DCLZ
= 0x24 | OPC_SPECIAL2
,
357 OPC_DCLO
= 0x25 | OPC_SPECIAL2
,
359 OPC_SDBBP
= 0x3F | OPC_SPECIAL2
,
362 /* Special3 opcodes */
363 #define MASK_SPECIAL3(op) (MASK_OP_MAJOR(op) | (op & 0x3F))
366 OPC_EXT
= 0x00 | OPC_SPECIAL3
,
367 OPC_DEXTM
= 0x01 | OPC_SPECIAL3
,
368 OPC_DEXTU
= 0x02 | OPC_SPECIAL3
,
369 OPC_DEXT
= 0x03 | OPC_SPECIAL3
,
370 OPC_INS
= 0x04 | OPC_SPECIAL3
,
371 OPC_DINSM
= 0x05 | OPC_SPECIAL3
,
372 OPC_DINSU
= 0x06 | OPC_SPECIAL3
,
373 OPC_DINS
= 0x07 | OPC_SPECIAL3
,
374 OPC_FORK
= 0x08 | OPC_SPECIAL3
,
375 OPC_YIELD
= 0x09 | OPC_SPECIAL3
,
376 OPC_BSHFL
= 0x20 | OPC_SPECIAL3
,
377 OPC_DBSHFL
= 0x24 | OPC_SPECIAL3
,
378 OPC_RDHWR
= 0x3B | OPC_SPECIAL3
,
379 OPC_GINV
= 0x3D | OPC_SPECIAL3
,
382 OPC_MULT_G_2E
= 0x18 | OPC_SPECIAL3
,
383 OPC_MULTU_G_2E
= 0x19 | OPC_SPECIAL3
,
384 OPC_DIV_G_2E
= 0x1A | OPC_SPECIAL3
,
385 OPC_DIVU_G_2E
= 0x1B | OPC_SPECIAL3
,
386 OPC_DMULT_G_2E
= 0x1C | OPC_SPECIAL3
,
387 OPC_DMULTU_G_2E
= 0x1D | OPC_SPECIAL3
,
388 OPC_DDIV_G_2E
= 0x1E | OPC_SPECIAL3
,
389 OPC_DDIVU_G_2E
= 0x1F | OPC_SPECIAL3
,
390 OPC_MOD_G_2E
= 0x22 | OPC_SPECIAL3
,
391 OPC_MODU_G_2E
= 0x23 | OPC_SPECIAL3
,
392 OPC_DMOD_G_2E
= 0x26 | OPC_SPECIAL3
,
393 OPC_DMODU_G_2E
= 0x27 | OPC_SPECIAL3
,
396 OPC_LX_DSP
= 0x0A | OPC_SPECIAL3
,
397 /* MIPS DSP Arithmetic */
398 OPC_ADDU_QB_DSP
= 0x10 | OPC_SPECIAL3
,
399 OPC_ADDU_OB_DSP
= 0x14 | OPC_SPECIAL3
,
400 OPC_ABSQ_S_PH_DSP
= 0x12 | OPC_SPECIAL3
,
401 OPC_ABSQ_S_QH_DSP
= 0x16 | OPC_SPECIAL3
,
402 /* OPC_ADDUH_QB_DSP is same as OPC_MULT_G_2E. */
403 /* OPC_ADDUH_QB_DSP = 0x18 | OPC_SPECIAL3, */
404 OPC_CMPU_EQ_QB_DSP
= 0x11 | OPC_SPECIAL3
,
405 OPC_CMPU_EQ_OB_DSP
= 0x15 | OPC_SPECIAL3
,
406 /* MIPS DSP GPR-Based Shift Sub-class */
407 OPC_SHLL_QB_DSP
= 0x13 | OPC_SPECIAL3
,
408 OPC_SHLL_OB_DSP
= 0x17 | OPC_SPECIAL3
,
409 /* MIPS DSP Multiply Sub-class insns */
410 /* OPC_MUL_PH_DSP is same as OPC_ADDUH_QB_DSP. */
411 /* OPC_MUL_PH_DSP = 0x18 | OPC_SPECIAL3, */
412 OPC_DPA_W_PH_DSP
= 0x30 | OPC_SPECIAL3
,
413 OPC_DPAQ_W_QH_DSP
= 0x34 | OPC_SPECIAL3
,
414 /* DSP Bit/Manipulation Sub-class */
415 OPC_INSV_DSP
= 0x0C | OPC_SPECIAL3
,
416 OPC_DINSV_DSP
= 0x0D | OPC_SPECIAL3
,
417 /* MIPS DSP Append Sub-class */
418 OPC_APPEND_DSP
= 0x31 | OPC_SPECIAL3
,
419 OPC_DAPPEND_DSP
= 0x35 | OPC_SPECIAL3
,
420 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
421 OPC_EXTR_W_DSP
= 0x38 | OPC_SPECIAL3
,
422 OPC_DEXTR_W_DSP
= 0x3C | OPC_SPECIAL3
,
425 OPC_LWLE
= 0x19 | OPC_SPECIAL3
,
426 OPC_LWRE
= 0x1A | OPC_SPECIAL3
,
427 OPC_CACHEE
= 0x1B | OPC_SPECIAL3
,
428 OPC_SBE
= 0x1C | OPC_SPECIAL3
,
429 OPC_SHE
= 0x1D | OPC_SPECIAL3
,
430 OPC_SCE
= 0x1E | OPC_SPECIAL3
,
431 OPC_SWE
= 0x1F | OPC_SPECIAL3
,
432 OPC_SWLE
= 0x21 | OPC_SPECIAL3
,
433 OPC_SWRE
= 0x22 | OPC_SPECIAL3
,
434 OPC_PREFE
= 0x23 | OPC_SPECIAL3
,
435 OPC_LBUE
= 0x28 | OPC_SPECIAL3
,
436 OPC_LHUE
= 0x29 | OPC_SPECIAL3
,
437 OPC_LBE
= 0x2C | OPC_SPECIAL3
,
438 OPC_LHE
= 0x2D | OPC_SPECIAL3
,
439 OPC_LLE
= 0x2E | OPC_SPECIAL3
,
440 OPC_LWE
= 0x2F | OPC_SPECIAL3
,
443 R6_OPC_PREF
= 0x35 | OPC_SPECIAL3
,
444 R6_OPC_CACHE
= 0x25 | OPC_SPECIAL3
,
445 R6_OPC_LL
= 0x36 | OPC_SPECIAL3
,
446 R6_OPC_SC
= 0x26 | OPC_SPECIAL3
,
447 R6_OPC_LLD
= 0x37 | OPC_SPECIAL3
,
448 R6_OPC_SCD
= 0x27 | OPC_SPECIAL3
,
451 /* Loongson EXT load/store quad word opcodes */
452 #define MASK_LOONGSON_GSLSQ(op) (MASK_OP_MAJOR(op) | (op & 0x8020))
454 OPC_GSLQ
= 0x0020 | OPC_LWC2
,
455 OPC_GSLQC1
= 0x8020 | OPC_LWC2
,
456 OPC_GSSHFL
= OPC_LWC2
,
457 OPC_GSSQ
= 0x0020 | OPC_SWC2
,
458 OPC_GSSQC1
= 0x8020 | OPC_SWC2
,
459 OPC_GSSHFS
= OPC_SWC2
,
462 /* Loongson EXT shifted load/store opcodes */
463 #define MASK_LOONGSON_GSSHFLS(op) (MASK_OP_MAJOR(op) | (op & 0xc03f))
465 OPC_GSLWLC1
= 0x4 | OPC_GSSHFL
,
466 OPC_GSLWRC1
= 0x5 | OPC_GSSHFL
,
467 OPC_GSLDLC1
= 0x6 | OPC_GSSHFL
,
468 OPC_GSLDRC1
= 0x7 | OPC_GSSHFL
,
469 OPC_GSSWLC1
= 0x4 | OPC_GSSHFS
,
470 OPC_GSSWRC1
= 0x5 | OPC_GSSHFS
,
471 OPC_GSSDLC1
= 0x6 | OPC_GSSHFS
,
472 OPC_GSSDRC1
= 0x7 | OPC_GSSHFS
,
475 /* Loongson EXT LDC2/SDC2 opcodes */
476 #define MASK_LOONGSON_LSDC2(op) (MASK_OP_MAJOR(op) | (op & 0x7))
479 OPC_GSLBX
= 0x0 | OPC_LDC2
,
480 OPC_GSLHX
= 0x1 | OPC_LDC2
,
481 OPC_GSLWX
= 0x2 | OPC_LDC2
,
482 OPC_GSLDX
= 0x3 | OPC_LDC2
,
483 OPC_GSLWXC1
= 0x6 | OPC_LDC2
,
484 OPC_GSLDXC1
= 0x7 | OPC_LDC2
,
485 OPC_GSSBX
= 0x0 | OPC_SDC2
,
486 OPC_GSSHX
= 0x1 | OPC_SDC2
,
487 OPC_GSSWX
= 0x2 | OPC_SDC2
,
488 OPC_GSSDX
= 0x3 | OPC_SDC2
,
489 OPC_GSSWXC1
= 0x6 | OPC_SDC2
,
490 OPC_GSSDXC1
= 0x7 | OPC_SDC2
,
494 #define MASK_BSHFL(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
497 OPC_WSBH
= (0x02 << 6) | OPC_BSHFL
,
498 OPC_SEB
= (0x10 << 6) | OPC_BSHFL
,
499 OPC_SEH
= (0x18 << 6) | OPC_BSHFL
,
500 OPC_ALIGN
= (0x08 << 6) | OPC_BSHFL
, /* 010.bp (010.00 to 010.11) */
501 OPC_ALIGN_1
= (0x09 << 6) | OPC_BSHFL
,
502 OPC_ALIGN_2
= (0x0A << 6) | OPC_BSHFL
,
503 OPC_ALIGN_3
= (0x0B << 6) | OPC_BSHFL
,
504 OPC_BITSWAP
= (0x00 << 6) | OPC_BSHFL
/* 00000 */
508 #define MASK_DBSHFL(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
511 OPC_DSBH
= (0x02 << 6) | OPC_DBSHFL
,
512 OPC_DSHD
= (0x05 << 6) | OPC_DBSHFL
,
513 OPC_DALIGN
= (0x08 << 6) | OPC_DBSHFL
, /* 01.bp (01.000 to 01.111) */
514 OPC_DALIGN_1
= (0x09 << 6) | OPC_DBSHFL
,
515 OPC_DALIGN_2
= (0x0A << 6) | OPC_DBSHFL
,
516 OPC_DALIGN_3
= (0x0B << 6) | OPC_DBSHFL
,
517 OPC_DALIGN_4
= (0x0C << 6) | OPC_DBSHFL
,
518 OPC_DALIGN_5
= (0x0D << 6) | OPC_DBSHFL
,
519 OPC_DALIGN_6
= (0x0E << 6) | OPC_DBSHFL
,
520 OPC_DALIGN_7
= (0x0F << 6) | OPC_DBSHFL
,
521 OPC_DBITSWAP
= (0x00 << 6) | OPC_DBSHFL
, /* 00000 */
524 /* MIPS DSP REGIMM opcodes */
526 OPC_BPOSGE32
= (0x1C << 16) | OPC_REGIMM
,
527 OPC_BPOSGE64
= (0x1D << 16) | OPC_REGIMM
,
530 #define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
533 OPC_LBUX
= (0x06 << 6) | OPC_LX_DSP
,
534 OPC_LHX
= (0x04 << 6) | OPC_LX_DSP
,
535 OPC_LWX
= (0x00 << 6) | OPC_LX_DSP
,
536 OPC_LDX
= (0x08 << 6) | OPC_LX_DSP
,
539 #define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
541 /* MIPS DSP Arithmetic Sub-class */
542 OPC_ADDQ_PH
= (0x0A << 6) | OPC_ADDU_QB_DSP
,
543 OPC_ADDQ_S_PH
= (0x0E << 6) | OPC_ADDU_QB_DSP
,
544 OPC_ADDQ_S_W
= (0x16 << 6) | OPC_ADDU_QB_DSP
,
545 OPC_ADDU_QB
= (0x00 << 6) | OPC_ADDU_QB_DSP
,
546 OPC_ADDU_S_QB
= (0x04 << 6) | OPC_ADDU_QB_DSP
,
547 OPC_ADDU_PH
= (0x08 << 6) | OPC_ADDU_QB_DSP
,
548 OPC_ADDU_S_PH
= (0x0C << 6) | OPC_ADDU_QB_DSP
,
549 OPC_SUBQ_PH
= (0x0B << 6) | OPC_ADDU_QB_DSP
,
550 OPC_SUBQ_S_PH
= (0x0F << 6) | OPC_ADDU_QB_DSP
,
551 OPC_SUBQ_S_W
= (0x17 << 6) | OPC_ADDU_QB_DSP
,
552 OPC_SUBU_QB
= (0x01 << 6) | OPC_ADDU_QB_DSP
,
553 OPC_SUBU_S_QB
= (0x05 << 6) | OPC_ADDU_QB_DSP
,
554 OPC_SUBU_PH
= (0x09 << 6) | OPC_ADDU_QB_DSP
,
555 OPC_SUBU_S_PH
= (0x0D << 6) | OPC_ADDU_QB_DSP
,
556 OPC_ADDSC
= (0x10 << 6) | OPC_ADDU_QB_DSP
,
557 OPC_ADDWC
= (0x11 << 6) | OPC_ADDU_QB_DSP
,
558 OPC_MODSUB
= (0x12 << 6) | OPC_ADDU_QB_DSP
,
559 OPC_RADDU_W_QB
= (0x14 << 6) | OPC_ADDU_QB_DSP
,
560 /* MIPS DSP Multiply Sub-class insns */
561 OPC_MULEU_S_PH_QBL
= (0x06 << 6) | OPC_ADDU_QB_DSP
,
562 OPC_MULEU_S_PH_QBR
= (0x07 << 6) | OPC_ADDU_QB_DSP
,
563 OPC_MULQ_RS_PH
= (0x1F << 6) | OPC_ADDU_QB_DSP
,
564 OPC_MULEQ_S_W_PHL
= (0x1C << 6) | OPC_ADDU_QB_DSP
,
565 OPC_MULEQ_S_W_PHR
= (0x1D << 6) | OPC_ADDU_QB_DSP
,
566 OPC_MULQ_S_PH
= (0x1E << 6) | OPC_ADDU_QB_DSP
,
569 #define OPC_ADDUH_QB_DSP OPC_MULT_G_2E
570 #define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
572 /* MIPS DSP Arithmetic Sub-class */
573 OPC_ADDUH_QB
= (0x00 << 6) | OPC_ADDUH_QB_DSP
,
574 OPC_ADDUH_R_QB
= (0x02 << 6) | OPC_ADDUH_QB_DSP
,
575 OPC_ADDQH_PH
= (0x08 << 6) | OPC_ADDUH_QB_DSP
,
576 OPC_ADDQH_R_PH
= (0x0A << 6) | OPC_ADDUH_QB_DSP
,
577 OPC_ADDQH_W
= (0x10 << 6) | OPC_ADDUH_QB_DSP
,
578 OPC_ADDQH_R_W
= (0x12 << 6) | OPC_ADDUH_QB_DSP
,
579 OPC_SUBUH_QB
= (0x01 << 6) | OPC_ADDUH_QB_DSP
,
580 OPC_SUBUH_R_QB
= (0x03 << 6) | OPC_ADDUH_QB_DSP
,
581 OPC_SUBQH_PH
= (0x09 << 6) | OPC_ADDUH_QB_DSP
,
582 OPC_SUBQH_R_PH
= (0x0B << 6) | OPC_ADDUH_QB_DSP
,
583 OPC_SUBQH_W
= (0x11 << 6) | OPC_ADDUH_QB_DSP
,
584 OPC_SUBQH_R_W
= (0x13 << 6) | OPC_ADDUH_QB_DSP
,
585 /* MIPS DSP Multiply Sub-class insns */
586 OPC_MUL_PH
= (0x0C << 6) | OPC_ADDUH_QB_DSP
,
587 OPC_MUL_S_PH
= (0x0E << 6) | OPC_ADDUH_QB_DSP
,
588 OPC_MULQ_S_W
= (0x16 << 6) | OPC_ADDUH_QB_DSP
,
589 OPC_MULQ_RS_W
= (0x17 << 6) | OPC_ADDUH_QB_DSP
,
592 #define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
594 /* MIPS DSP Arithmetic Sub-class */
595 OPC_ABSQ_S_QB
= (0x01 << 6) | OPC_ABSQ_S_PH_DSP
,
596 OPC_ABSQ_S_PH
= (0x09 << 6) | OPC_ABSQ_S_PH_DSP
,
597 OPC_ABSQ_S_W
= (0x11 << 6) | OPC_ABSQ_S_PH_DSP
,
598 OPC_PRECEQ_W_PHL
= (0x0C << 6) | OPC_ABSQ_S_PH_DSP
,
599 OPC_PRECEQ_W_PHR
= (0x0D << 6) | OPC_ABSQ_S_PH_DSP
,
600 OPC_PRECEQU_PH_QBL
= (0x04 << 6) | OPC_ABSQ_S_PH_DSP
,
601 OPC_PRECEQU_PH_QBR
= (0x05 << 6) | OPC_ABSQ_S_PH_DSP
,
602 OPC_PRECEQU_PH_QBLA
= (0x06 << 6) | OPC_ABSQ_S_PH_DSP
,
603 OPC_PRECEQU_PH_QBRA
= (0x07 << 6) | OPC_ABSQ_S_PH_DSP
,
604 OPC_PRECEU_PH_QBL
= (0x1C << 6) | OPC_ABSQ_S_PH_DSP
,
605 OPC_PRECEU_PH_QBR
= (0x1D << 6) | OPC_ABSQ_S_PH_DSP
,
606 OPC_PRECEU_PH_QBLA
= (0x1E << 6) | OPC_ABSQ_S_PH_DSP
,
607 OPC_PRECEU_PH_QBRA
= (0x1F << 6) | OPC_ABSQ_S_PH_DSP
,
608 /* DSP Bit/Manipulation Sub-class */
609 OPC_BITREV
= (0x1B << 6) | OPC_ABSQ_S_PH_DSP
,
610 OPC_REPL_QB
= (0x02 << 6) | OPC_ABSQ_S_PH_DSP
,
611 OPC_REPLV_QB
= (0x03 << 6) | OPC_ABSQ_S_PH_DSP
,
612 OPC_REPL_PH
= (0x0A << 6) | OPC_ABSQ_S_PH_DSP
,
613 OPC_REPLV_PH
= (0x0B << 6) | OPC_ABSQ_S_PH_DSP
,
616 #define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
618 /* MIPS DSP Arithmetic Sub-class */
619 OPC_PRECR_QB_PH
= (0x0D << 6) | OPC_CMPU_EQ_QB_DSP
,
620 OPC_PRECRQ_QB_PH
= (0x0C << 6) | OPC_CMPU_EQ_QB_DSP
,
621 OPC_PRECR_SRA_PH_W
= (0x1E << 6) | OPC_CMPU_EQ_QB_DSP
,
622 OPC_PRECR_SRA_R_PH_W
= (0x1F << 6) | OPC_CMPU_EQ_QB_DSP
,
623 OPC_PRECRQ_PH_W
= (0x14 << 6) | OPC_CMPU_EQ_QB_DSP
,
624 OPC_PRECRQ_RS_PH_W
= (0x15 << 6) | OPC_CMPU_EQ_QB_DSP
,
625 OPC_PRECRQU_S_QB_PH
= (0x0F << 6) | OPC_CMPU_EQ_QB_DSP
,
626 /* DSP Compare-Pick Sub-class */
627 OPC_CMPU_EQ_QB
= (0x00 << 6) | OPC_CMPU_EQ_QB_DSP
,
628 OPC_CMPU_LT_QB
= (0x01 << 6) | OPC_CMPU_EQ_QB_DSP
,
629 OPC_CMPU_LE_QB
= (0x02 << 6) | OPC_CMPU_EQ_QB_DSP
,
630 OPC_CMPGU_EQ_QB
= (0x04 << 6) | OPC_CMPU_EQ_QB_DSP
,
631 OPC_CMPGU_LT_QB
= (0x05 << 6) | OPC_CMPU_EQ_QB_DSP
,
632 OPC_CMPGU_LE_QB
= (0x06 << 6) | OPC_CMPU_EQ_QB_DSP
,
633 OPC_CMPGDU_EQ_QB
= (0x18 << 6) | OPC_CMPU_EQ_QB_DSP
,
634 OPC_CMPGDU_LT_QB
= (0x19 << 6) | OPC_CMPU_EQ_QB_DSP
,
635 OPC_CMPGDU_LE_QB
= (0x1A << 6) | OPC_CMPU_EQ_QB_DSP
,
636 OPC_CMP_EQ_PH
= (0x08 << 6) | OPC_CMPU_EQ_QB_DSP
,
637 OPC_CMP_LT_PH
= (0x09 << 6) | OPC_CMPU_EQ_QB_DSP
,
638 OPC_CMP_LE_PH
= (0x0A << 6) | OPC_CMPU_EQ_QB_DSP
,
639 OPC_PICK_QB
= (0x03 << 6) | OPC_CMPU_EQ_QB_DSP
,
640 OPC_PICK_PH
= (0x0B << 6) | OPC_CMPU_EQ_QB_DSP
,
641 OPC_PACKRL_PH
= (0x0E << 6) | OPC_CMPU_EQ_QB_DSP
,
644 #define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
646 /* MIPS DSP GPR-Based Shift Sub-class */
647 OPC_SHLL_QB
= (0x00 << 6) | OPC_SHLL_QB_DSP
,
648 OPC_SHLLV_QB
= (0x02 << 6) | OPC_SHLL_QB_DSP
,
649 OPC_SHLL_PH
= (0x08 << 6) | OPC_SHLL_QB_DSP
,
650 OPC_SHLLV_PH
= (0x0A << 6) | OPC_SHLL_QB_DSP
,
651 OPC_SHLL_S_PH
= (0x0C << 6) | OPC_SHLL_QB_DSP
,
652 OPC_SHLLV_S_PH
= (0x0E << 6) | OPC_SHLL_QB_DSP
,
653 OPC_SHLL_S_W
= (0x14 << 6) | OPC_SHLL_QB_DSP
,
654 OPC_SHLLV_S_W
= (0x16 << 6) | OPC_SHLL_QB_DSP
,
655 OPC_SHRL_QB
= (0x01 << 6) | OPC_SHLL_QB_DSP
,
656 OPC_SHRLV_QB
= (0x03 << 6) | OPC_SHLL_QB_DSP
,
657 OPC_SHRL_PH
= (0x19 << 6) | OPC_SHLL_QB_DSP
,
658 OPC_SHRLV_PH
= (0x1B << 6) | OPC_SHLL_QB_DSP
,
659 OPC_SHRA_QB
= (0x04 << 6) | OPC_SHLL_QB_DSP
,
660 OPC_SHRA_R_QB
= (0x05 << 6) | OPC_SHLL_QB_DSP
,
661 OPC_SHRAV_QB
= (0x06 << 6) | OPC_SHLL_QB_DSP
,
662 OPC_SHRAV_R_QB
= (0x07 << 6) | OPC_SHLL_QB_DSP
,
663 OPC_SHRA_PH
= (0x09 << 6) | OPC_SHLL_QB_DSP
,
664 OPC_SHRAV_PH
= (0x0B << 6) | OPC_SHLL_QB_DSP
,
665 OPC_SHRA_R_PH
= (0x0D << 6) | OPC_SHLL_QB_DSP
,
666 OPC_SHRAV_R_PH
= (0x0F << 6) | OPC_SHLL_QB_DSP
,
667 OPC_SHRA_R_W
= (0x15 << 6) | OPC_SHLL_QB_DSP
,
668 OPC_SHRAV_R_W
= (0x17 << 6) | OPC_SHLL_QB_DSP
,
671 #define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
673 /* MIPS DSP Multiply Sub-class insns */
674 OPC_DPAU_H_QBL
= (0x03 << 6) | OPC_DPA_W_PH_DSP
,
675 OPC_DPAU_H_QBR
= (0x07 << 6) | OPC_DPA_W_PH_DSP
,
676 OPC_DPSU_H_QBL
= (0x0B << 6) | OPC_DPA_W_PH_DSP
,
677 OPC_DPSU_H_QBR
= (0x0F << 6) | OPC_DPA_W_PH_DSP
,
678 OPC_DPA_W_PH
= (0x00 << 6) | OPC_DPA_W_PH_DSP
,
679 OPC_DPAX_W_PH
= (0x08 << 6) | OPC_DPA_W_PH_DSP
,
680 OPC_DPAQ_S_W_PH
= (0x04 << 6) | OPC_DPA_W_PH_DSP
,
681 OPC_DPAQX_S_W_PH
= (0x18 << 6) | OPC_DPA_W_PH_DSP
,
682 OPC_DPAQX_SA_W_PH
= (0x1A << 6) | OPC_DPA_W_PH_DSP
,
683 OPC_DPS_W_PH
= (0x01 << 6) | OPC_DPA_W_PH_DSP
,
684 OPC_DPSX_W_PH
= (0x09 << 6) | OPC_DPA_W_PH_DSP
,
685 OPC_DPSQ_S_W_PH
= (0x05 << 6) | OPC_DPA_W_PH_DSP
,
686 OPC_DPSQX_S_W_PH
= (0x19 << 6) | OPC_DPA_W_PH_DSP
,
687 OPC_DPSQX_SA_W_PH
= (0x1B << 6) | OPC_DPA_W_PH_DSP
,
688 OPC_MULSAQ_S_W_PH
= (0x06 << 6) | OPC_DPA_W_PH_DSP
,
689 OPC_DPAQ_SA_L_W
= (0x0C << 6) | OPC_DPA_W_PH_DSP
,
690 OPC_DPSQ_SA_L_W
= (0x0D << 6) | OPC_DPA_W_PH_DSP
,
691 OPC_MAQ_S_W_PHL
= (0x14 << 6) | OPC_DPA_W_PH_DSP
,
692 OPC_MAQ_S_W_PHR
= (0x16 << 6) | OPC_DPA_W_PH_DSP
,
693 OPC_MAQ_SA_W_PHL
= (0x10 << 6) | OPC_DPA_W_PH_DSP
,
694 OPC_MAQ_SA_W_PHR
= (0x12 << 6) | OPC_DPA_W_PH_DSP
,
695 OPC_MULSA_W_PH
= (0x02 << 6) | OPC_DPA_W_PH_DSP
,
698 #define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
700 /* DSP Bit/Manipulation Sub-class */
701 OPC_INSV
= (0x00 << 6) | OPC_INSV_DSP
,
704 #define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
706 /* MIPS DSP Append Sub-class */
707 OPC_APPEND
= (0x00 << 6) | OPC_APPEND_DSP
,
708 OPC_PREPEND
= (0x01 << 6) | OPC_APPEND_DSP
,
709 OPC_BALIGN
= (0x10 << 6) | OPC_APPEND_DSP
,
712 #define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
714 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
715 OPC_EXTR_W
= (0x00 << 6) | OPC_EXTR_W_DSP
,
716 OPC_EXTR_R_W
= (0x04 << 6) | OPC_EXTR_W_DSP
,
717 OPC_EXTR_RS_W
= (0x06 << 6) | OPC_EXTR_W_DSP
,
718 OPC_EXTR_S_H
= (0x0E << 6) | OPC_EXTR_W_DSP
,
719 OPC_EXTRV_S_H
= (0x0F << 6) | OPC_EXTR_W_DSP
,
720 OPC_EXTRV_W
= (0x01 << 6) | OPC_EXTR_W_DSP
,
721 OPC_EXTRV_R_W
= (0x05 << 6) | OPC_EXTR_W_DSP
,
722 OPC_EXTRV_RS_W
= (0x07 << 6) | OPC_EXTR_W_DSP
,
723 OPC_EXTP
= (0x02 << 6) | OPC_EXTR_W_DSP
,
724 OPC_EXTPV
= (0x03 << 6) | OPC_EXTR_W_DSP
,
725 OPC_EXTPDP
= (0x0A << 6) | OPC_EXTR_W_DSP
,
726 OPC_EXTPDPV
= (0x0B << 6) | OPC_EXTR_W_DSP
,
727 OPC_SHILO
= (0x1A << 6) | OPC_EXTR_W_DSP
,
728 OPC_SHILOV
= (0x1B << 6) | OPC_EXTR_W_DSP
,
729 OPC_MTHLIP
= (0x1F << 6) | OPC_EXTR_W_DSP
,
730 OPC_WRDSP
= (0x13 << 6) | OPC_EXTR_W_DSP
,
731 OPC_RDDSP
= (0x12 << 6) | OPC_EXTR_W_DSP
,
734 #define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
736 /* MIPS DSP Arithmetic Sub-class */
737 OPC_PRECEQ_L_PWL
= (0x14 << 6) | OPC_ABSQ_S_QH_DSP
,
738 OPC_PRECEQ_L_PWR
= (0x15 << 6) | OPC_ABSQ_S_QH_DSP
,
739 OPC_PRECEQ_PW_QHL
= (0x0C << 6) | OPC_ABSQ_S_QH_DSP
,
740 OPC_PRECEQ_PW_QHR
= (0x0D << 6) | OPC_ABSQ_S_QH_DSP
,
741 OPC_PRECEQ_PW_QHLA
= (0x0E << 6) | OPC_ABSQ_S_QH_DSP
,
742 OPC_PRECEQ_PW_QHRA
= (0x0F << 6) | OPC_ABSQ_S_QH_DSP
,
743 OPC_PRECEQU_QH_OBL
= (0x04 << 6) | OPC_ABSQ_S_QH_DSP
,
744 OPC_PRECEQU_QH_OBR
= (0x05 << 6) | OPC_ABSQ_S_QH_DSP
,
745 OPC_PRECEQU_QH_OBLA
= (0x06 << 6) | OPC_ABSQ_S_QH_DSP
,
746 OPC_PRECEQU_QH_OBRA
= (0x07 << 6) | OPC_ABSQ_S_QH_DSP
,
747 OPC_PRECEU_QH_OBL
= (0x1C << 6) | OPC_ABSQ_S_QH_DSP
,
748 OPC_PRECEU_QH_OBR
= (0x1D << 6) | OPC_ABSQ_S_QH_DSP
,
749 OPC_PRECEU_QH_OBLA
= (0x1E << 6) | OPC_ABSQ_S_QH_DSP
,
750 OPC_PRECEU_QH_OBRA
= (0x1F << 6) | OPC_ABSQ_S_QH_DSP
,
751 OPC_ABSQ_S_OB
= (0x01 << 6) | OPC_ABSQ_S_QH_DSP
,
752 OPC_ABSQ_S_PW
= (0x11 << 6) | OPC_ABSQ_S_QH_DSP
,
753 OPC_ABSQ_S_QH
= (0x09 << 6) | OPC_ABSQ_S_QH_DSP
,
754 /* DSP Bit/Manipulation Sub-class */
755 OPC_REPL_OB
= (0x02 << 6) | OPC_ABSQ_S_QH_DSP
,
756 OPC_REPL_PW
= (0x12 << 6) | OPC_ABSQ_S_QH_DSP
,
757 OPC_REPL_QH
= (0x0A << 6) | OPC_ABSQ_S_QH_DSP
,
758 OPC_REPLV_OB
= (0x03 << 6) | OPC_ABSQ_S_QH_DSP
,
759 OPC_REPLV_PW
= (0x13 << 6) | OPC_ABSQ_S_QH_DSP
,
760 OPC_REPLV_QH
= (0x0B << 6) | OPC_ABSQ_S_QH_DSP
,
763 #define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
765 /* MIPS DSP Multiply Sub-class insns */
766 OPC_MULEQ_S_PW_QHL
= (0x1C << 6) | OPC_ADDU_OB_DSP
,
767 OPC_MULEQ_S_PW_QHR
= (0x1D << 6) | OPC_ADDU_OB_DSP
,
768 OPC_MULEU_S_QH_OBL
= (0x06 << 6) | OPC_ADDU_OB_DSP
,
769 OPC_MULEU_S_QH_OBR
= (0x07 << 6) | OPC_ADDU_OB_DSP
,
770 OPC_MULQ_RS_QH
= (0x1F << 6) | OPC_ADDU_OB_DSP
,
771 /* MIPS DSP Arithmetic Sub-class */
772 OPC_RADDU_L_OB
= (0x14 << 6) | OPC_ADDU_OB_DSP
,
773 OPC_SUBQ_PW
= (0x13 << 6) | OPC_ADDU_OB_DSP
,
774 OPC_SUBQ_S_PW
= (0x17 << 6) | OPC_ADDU_OB_DSP
,
775 OPC_SUBQ_QH
= (0x0B << 6) | OPC_ADDU_OB_DSP
,
776 OPC_SUBQ_S_QH
= (0x0F << 6) | OPC_ADDU_OB_DSP
,
777 OPC_SUBU_OB
= (0x01 << 6) | OPC_ADDU_OB_DSP
,
778 OPC_SUBU_S_OB
= (0x05 << 6) | OPC_ADDU_OB_DSP
,
779 OPC_SUBU_QH
= (0x09 << 6) | OPC_ADDU_OB_DSP
,
780 OPC_SUBU_S_QH
= (0x0D << 6) | OPC_ADDU_OB_DSP
,
781 OPC_SUBUH_OB
= (0x19 << 6) | OPC_ADDU_OB_DSP
,
782 OPC_SUBUH_R_OB
= (0x1B << 6) | OPC_ADDU_OB_DSP
,
783 OPC_ADDQ_PW
= (0x12 << 6) | OPC_ADDU_OB_DSP
,
784 OPC_ADDQ_S_PW
= (0x16 << 6) | OPC_ADDU_OB_DSP
,
785 OPC_ADDQ_QH
= (0x0A << 6) | OPC_ADDU_OB_DSP
,
786 OPC_ADDQ_S_QH
= (0x0E << 6) | OPC_ADDU_OB_DSP
,
787 OPC_ADDU_OB
= (0x00 << 6) | OPC_ADDU_OB_DSP
,
788 OPC_ADDU_S_OB
= (0x04 << 6) | OPC_ADDU_OB_DSP
,
789 OPC_ADDU_QH
= (0x08 << 6) | OPC_ADDU_OB_DSP
,
790 OPC_ADDU_S_QH
= (0x0C << 6) | OPC_ADDU_OB_DSP
,
791 OPC_ADDUH_OB
= (0x18 << 6) | OPC_ADDU_OB_DSP
,
792 OPC_ADDUH_R_OB
= (0x1A << 6) | OPC_ADDU_OB_DSP
,
795 #define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
797 /* DSP Compare-Pick Sub-class */
798 OPC_CMP_EQ_PW
= (0x10 << 6) | OPC_CMPU_EQ_OB_DSP
,
799 OPC_CMP_LT_PW
= (0x11 << 6) | OPC_CMPU_EQ_OB_DSP
,
800 OPC_CMP_LE_PW
= (0x12 << 6) | OPC_CMPU_EQ_OB_DSP
,
801 OPC_CMP_EQ_QH
= (0x08 << 6) | OPC_CMPU_EQ_OB_DSP
,
802 OPC_CMP_LT_QH
= (0x09 << 6) | OPC_CMPU_EQ_OB_DSP
,
803 OPC_CMP_LE_QH
= (0x0A << 6) | OPC_CMPU_EQ_OB_DSP
,
804 OPC_CMPGDU_EQ_OB
= (0x18 << 6) | OPC_CMPU_EQ_OB_DSP
,
805 OPC_CMPGDU_LT_OB
= (0x19 << 6) | OPC_CMPU_EQ_OB_DSP
,
806 OPC_CMPGDU_LE_OB
= (0x1A << 6) | OPC_CMPU_EQ_OB_DSP
,
807 OPC_CMPGU_EQ_OB
= (0x04 << 6) | OPC_CMPU_EQ_OB_DSP
,
808 OPC_CMPGU_LT_OB
= (0x05 << 6) | OPC_CMPU_EQ_OB_DSP
,
809 OPC_CMPGU_LE_OB
= (0x06 << 6) | OPC_CMPU_EQ_OB_DSP
,
810 OPC_CMPU_EQ_OB
= (0x00 << 6) | OPC_CMPU_EQ_OB_DSP
,
811 OPC_CMPU_LT_OB
= (0x01 << 6) | OPC_CMPU_EQ_OB_DSP
,
812 OPC_CMPU_LE_OB
= (0x02 << 6) | OPC_CMPU_EQ_OB_DSP
,
813 OPC_PACKRL_PW
= (0x0E << 6) | OPC_CMPU_EQ_OB_DSP
,
814 OPC_PICK_OB
= (0x03 << 6) | OPC_CMPU_EQ_OB_DSP
,
815 OPC_PICK_PW
= (0x13 << 6) | OPC_CMPU_EQ_OB_DSP
,
816 OPC_PICK_QH
= (0x0B << 6) | OPC_CMPU_EQ_OB_DSP
,
817 /* MIPS DSP Arithmetic Sub-class */
818 OPC_PRECR_OB_QH
= (0x0D << 6) | OPC_CMPU_EQ_OB_DSP
,
819 OPC_PRECR_SRA_QH_PW
= (0x1E << 6) | OPC_CMPU_EQ_OB_DSP
,
820 OPC_PRECR_SRA_R_QH_PW
= (0x1F << 6) | OPC_CMPU_EQ_OB_DSP
,
821 OPC_PRECRQ_OB_QH
= (0x0C << 6) | OPC_CMPU_EQ_OB_DSP
,
822 OPC_PRECRQ_PW_L
= (0x1C << 6) | OPC_CMPU_EQ_OB_DSP
,
823 OPC_PRECRQ_QH_PW
= (0x14 << 6) | OPC_CMPU_EQ_OB_DSP
,
824 OPC_PRECRQ_RS_QH_PW
= (0x15 << 6) | OPC_CMPU_EQ_OB_DSP
,
825 OPC_PRECRQU_S_OB_QH
= (0x0F << 6) | OPC_CMPU_EQ_OB_DSP
,
828 #define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
830 /* DSP Append Sub-class */
831 OPC_DAPPEND
= (0x00 << 6) | OPC_DAPPEND_DSP
,
832 OPC_PREPENDD
= (0x03 << 6) | OPC_DAPPEND_DSP
,
833 OPC_PREPENDW
= (0x01 << 6) | OPC_DAPPEND_DSP
,
834 OPC_DBALIGN
= (0x10 << 6) | OPC_DAPPEND_DSP
,
837 #define MASK_DEXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
839 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
840 OPC_DMTHLIP
= (0x1F << 6) | OPC_DEXTR_W_DSP
,
841 OPC_DSHILO
= (0x1A << 6) | OPC_DEXTR_W_DSP
,
842 OPC_DEXTP
= (0x02 << 6) | OPC_DEXTR_W_DSP
,
843 OPC_DEXTPDP
= (0x0A << 6) | OPC_DEXTR_W_DSP
,
844 OPC_DEXTPDPV
= (0x0B << 6) | OPC_DEXTR_W_DSP
,
845 OPC_DEXTPV
= (0x03 << 6) | OPC_DEXTR_W_DSP
,
846 OPC_DEXTR_L
= (0x10 << 6) | OPC_DEXTR_W_DSP
,
847 OPC_DEXTR_R_L
= (0x14 << 6) | OPC_DEXTR_W_DSP
,
848 OPC_DEXTR_RS_L
= (0x16 << 6) | OPC_DEXTR_W_DSP
,
849 OPC_DEXTR_W
= (0x00 << 6) | OPC_DEXTR_W_DSP
,
850 OPC_DEXTR_R_W
= (0x04 << 6) | OPC_DEXTR_W_DSP
,
851 OPC_DEXTR_RS_W
= (0x06 << 6) | OPC_DEXTR_W_DSP
,
852 OPC_DEXTR_S_H
= (0x0E << 6) | OPC_DEXTR_W_DSP
,
853 OPC_DEXTRV_L
= (0x11 << 6) | OPC_DEXTR_W_DSP
,
854 OPC_DEXTRV_R_L
= (0x15 << 6) | OPC_DEXTR_W_DSP
,
855 OPC_DEXTRV_RS_L
= (0x17 << 6) | OPC_DEXTR_W_DSP
,
856 OPC_DEXTRV_S_H
= (0x0F << 6) | OPC_DEXTR_W_DSP
,
857 OPC_DEXTRV_W
= (0x01 << 6) | OPC_DEXTR_W_DSP
,
858 OPC_DEXTRV_R_W
= (0x05 << 6) | OPC_DEXTR_W_DSP
,
859 OPC_DEXTRV_RS_W
= (0x07 << 6) | OPC_DEXTR_W_DSP
,
860 OPC_DSHILOV
= (0x1B << 6) | OPC_DEXTR_W_DSP
,
863 #define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
865 /* DSP Bit/Manipulation Sub-class */
866 OPC_DINSV
= (0x00 << 6) | OPC_DINSV_DSP
,
869 #define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
871 /* MIPS DSP Multiply Sub-class insns */
872 OPC_DMADD
= (0x19 << 6) | OPC_DPAQ_W_QH_DSP
,
873 OPC_DMADDU
= (0x1D << 6) | OPC_DPAQ_W_QH_DSP
,
874 OPC_DMSUB
= (0x1B << 6) | OPC_DPAQ_W_QH_DSP
,
875 OPC_DMSUBU
= (0x1F << 6) | OPC_DPAQ_W_QH_DSP
,
876 OPC_DPA_W_QH
= (0x00 << 6) | OPC_DPAQ_W_QH_DSP
,
877 OPC_DPAQ_S_W_QH
= (0x04 << 6) | OPC_DPAQ_W_QH_DSP
,
878 OPC_DPAQ_SA_L_PW
= (0x0C << 6) | OPC_DPAQ_W_QH_DSP
,
879 OPC_DPAU_H_OBL
= (0x03 << 6) | OPC_DPAQ_W_QH_DSP
,
880 OPC_DPAU_H_OBR
= (0x07 << 6) | OPC_DPAQ_W_QH_DSP
,
881 OPC_DPS_W_QH
= (0x01 << 6) | OPC_DPAQ_W_QH_DSP
,
882 OPC_DPSQ_S_W_QH
= (0x05 << 6) | OPC_DPAQ_W_QH_DSP
,
883 OPC_DPSQ_SA_L_PW
= (0x0D << 6) | OPC_DPAQ_W_QH_DSP
,
884 OPC_DPSU_H_OBL
= (0x0B << 6) | OPC_DPAQ_W_QH_DSP
,
885 OPC_DPSU_H_OBR
= (0x0F << 6) | OPC_DPAQ_W_QH_DSP
,
886 OPC_MAQ_S_L_PWL
= (0x1C << 6) | OPC_DPAQ_W_QH_DSP
,
887 OPC_MAQ_S_L_PWR
= (0x1E << 6) | OPC_DPAQ_W_QH_DSP
,
888 OPC_MAQ_S_W_QHLL
= (0x14 << 6) | OPC_DPAQ_W_QH_DSP
,
889 OPC_MAQ_SA_W_QHLL
= (0x10 << 6) | OPC_DPAQ_W_QH_DSP
,
890 OPC_MAQ_S_W_QHLR
= (0x15 << 6) | OPC_DPAQ_W_QH_DSP
,
891 OPC_MAQ_SA_W_QHLR
= (0x11 << 6) | OPC_DPAQ_W_QH_DSP
,
892 OPC_MAQ_S_W_QHRL
= (0x16 << 6) | OPC_DPAQ_W_QH_DSP
,
893 OPC_MAQ_SA_W_QHRL
= (0x12 << 6) | OPC_DPAQ_W_QH_DSP
,
894 OPC_MAQ_S_W_QHRR
= (0x17 << 6) | OPC_DPAQ_W_QH_DSP
,
895 OPC_MAQ_SA_W_QHRR
= (0x13 << 6) | OPC_DPAQ_W_QH_DSP
,
896 OPC_MULSAQ_S_L_PW
= (0x0E << 6) | OPC_DPAQ_W_QH_DSP
,
897 OPC_MULSAQ_S_W_QH
= (0x06 << 6) | OPC_DPAQ_W_QH_DSP
,
900 #define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
902 /* MIPS DSP GPR-Based Shift Sub-class */
903 OPC_SHLL_PW
= (0x10 << 6) | OPC_SHLL_OB_DSP
,
904 OPC_SHLL_S_PW
= (0x14 << 6) | OPC_SHLL_OB_DSP
,
905 OPC_SHLLV_OB
= (0x02 << 6) | OPC_SHLL_OB_DSP
,
906 OPC_SHLLV_PW
= (0x12 << 6) | OPC_SHLL_OB_DSP
,
907 OPC_SHLLV_S_PW
= (0x16 << 6) | OPC_SHLL_OB_DSP
,
908 OPC_SHLLV_QH
= (0x0A << 6) | OPC_SHLL_OB_DSP
,
909 OPC_SHLLV_S_QH
= (0x0E << 6) | OPC_SHLL_OB_DSP
,
910 OPC_SHRA_PW
= (0x11 << 6) | OPC_SHLL_OB_DSP
,
911 OPC_SHRA_R_PW
= (0x15 << 6) | OPC_SHLL_OB_DSP
,
912 OPC_SHRAV_OB
= (0x06 << 6) | OPC_SHLL_OB_DSP
,
913 OPC_SHRAV_R_OB
= (0x07 << 6) | OPC_SHLL_OB_DSP
,
914 OPC_SHRAV_PW
= (0x13 << 6) | OPC_SHLL_OB_DSP
,
915 OPC_SHRAV_R_PW
= (0x17 << 6) | OPC_SHLL_OB_DSP
,
916 OPC_SHRAV_QH
= (0x0B << 6) | OPC_SHLL_OB_DSP
,
917 OPC_SHRAV_R_QH
= (0x0F << 6) | OPC_SHLL_OB_DSP
,
918 OPC_SHRLV_OB
= (0x03 << 6) | OPC_SHLL_OB_DSP
,
919 OPC_SHRLV_QH
= (0x1B << 6) | OPC_SHLL_OB_DSP
,
920 OPC_SHLL_OB
= (0x00 << 6) | OPC_SHLL_OB_DSP
,
921 OPC_SHLL_QH
= (0x08 << 6) | OPC_SHLL_OB_DSP
,
922 OPC_SHLL_S_QH
= (0x0C << 6) | OPC_SHLL_OB_DSP
,
923 OPC_SHRA_OB
= (0x04 << 6) | OPC_SHLL_OB_DSP
,
924 OPC_SHRA_R_OB
= (0x05 << 6) | OPC_SHLL_OB_DSP
,
925 OPC_SHRA_QH
= (0x09 << 6) | OPC_SHLL_OB_DSP
,
926 OPC_SHRA_R_QH
= (0x0D << 6) | OPC_SHLL_OB_DSP
,
927 OPC_SHRL_OB
= (0x01 << 6) | OPC_SHLL_OB_DSP
,
928 OPC_SHRL_QH
= (0x19 << 6) | OPC_SHLL_OB_DSP
,
931 /* Coprocessor 0 (rs field) */
932 #define MASK_CP0(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)))
935 OPC_MFC0
= (0x00 << 21) | OPC_CP0
,
936 OPC_DMFC0
= (0x01 << 21) | OPC_CP0
,
937 OPC_MFHC0
= (0x02 << 21) | OPC_CP0
,
938 OPC_MTC0
= (0x04 << 21) | OPC_CP0
,
939 OPC_DMTC0
= (0x05 << 21) | OPC_CP0
,
940 OPC_MTHC0
= (0x06 << 21) | OPC_CP0
,
941 OPC_MFTR
= (0x08 << 21) | OPC_CP0
,
942 OPC_RDPGPR
= (0x0A << 21) | OPC_CP0
,
943 OPC_MFMC0
= (0x0B << 21) | OPC_CP0
,
944 OPC_MTTR
= (0x0C << 21) | OPC_CP0
,
945 OPC_WRPGPR
= (0x0E << 21) | OPC_CP0
,
946 OPC_C0
= (0x10 << 21) | OPC_CP0
,
947 OPC_C0_1
= (0x11 << 21) | OPC_CP0
,
948 OPC_C0_2
= (0x12 << 21) | OPC_CP0
,
949 OPC_C0_3
= (0x13 << 21) | OPC_CP0
,
950 OPC_C0_4
= (0x14 << 21) | OPC_CP0
,
951 OPC_C0_5
= (0x15 << 21) | OPC_CP0
,
952 OPC_C0_6
= (0x16 << 21) | OPC_CP0
,
953 OPC_C0_7
= (0x17 << 21) | OPC_CP0
,
954 OPC_C0_8
= (0x18 << 21) | OPC_CP0
,
955 OPC_C0_9
= (0x19 << 21) | OPC_CP0
,
956 OPC_C0_A
= (0x1A << 21) | OPC_CP0
,
957 OPC_C0_B
= (0x1B << 21) | OPC_CP0
,
958 OPC_C0_C
= (0x1C << 21) | OPC_CP0
,
959 OPC_C0_D
= (0x1D << 21) | OPC_CP0
,
960 OPC_C0_E
= (0x1E << 21) | OPC_CP0
,
961 OPC_C0_F
= (0x1F << 21) | OPC_CP0
,
965 #define MASK_MFMC0(op) (MASK_CP0(op) | (op & 0xFFFF))
968 OPC_DMT
= 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0
,
969 OPC_EMT
= 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0
,
970 OPC_DVPE
= 0x01 | (0 << 5) | OPC_MFMC0
,
971 OPC_EVPE
= 0x01 | (1 << 5) | OPC_MFMC0
,
972 OPC_DI
= (0 << 5) | (0x0C << 11) | OPC_MFMC0
,
973 OPC_EI
= (1 << 5) | (0x0C << 11) | OPC_MFMC0
,
974 OPC_DVP
= 0x04 | (0 << 3) | (1 << 5) | (0 << 11) | OPC_MFMC0
,
975 OPC_EVP
= 0x04 | (0 << 3) | (0 << 5) | (0 << 11) | OPC_MFMC0
,
978 /* Coprocessor 0 (with rs == C0) */
979 #define MASK_C0(op) (MASK_CP0(op) | (op & 0x3F))
982 OPC_TLBR
= 0x01 | OPC_C0
,
983 OPC_TLBWI
= 0x02 | OPC_C0
,
984 OPC_TLBINV
= 0x03 | OPC_C0
,
985 OPC_TLBINVF
= 0x04 | OPC_C0
,
986 OPC_TLBWR
= 0x06 | OPC_C0
,
987 OPC_TLBP
= 0x08 | OPC_C0
,
988 OPC_RFE
= 0x10 | OPC_C0
,
989 OPC_ERET
= 0x18 | OPC_C0
,
990 OPC_DERET
= 0x1F | OPC_C0
,
991 OPC_WAIT
= 0x20 | OPC_C0
,
994 #define MASK_CP2(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)))
997 OPC_MFC2
= (0x00 << 21) | OPC_CP2
,
998 OPC_DMFC2
= (0x01 << 21) | OPC_CP2
,
999 OPC_CFC2
= (0x02 << 21) | OPC_CP2
,
1000 OPC_MFHC2
= (0x03 << 21) | OPC_CP2
,
1001 OPC_MTC2
= (0x04 << 21) | OPC_CP2
,
1002 OPC_DMTC2
= (0x05 << 21) | OPC_CP2
,
1003 OPC_CTC2
= (0x06 << 21) | OPC_CP2
,
1004 OPC_MTHC2
= (0x07 << 21) | OPC_CP2
,
1005 OPC_BC2
= (0x08 << 21) | OPC_CP2
,
1006 OPC_BC2EQZ
= (0x09 << 21) | OPC_CP2
,
1007 OPC_BC2NEZ
= (0x0D << 21) | OPC_CP2
,
1010 #define MASK_LMMI(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
1013 OPC_PADDSH
= (24 << 21) | (0x00) | OPC_CP2
,
1014 OPC_PADDUSH
= (25 << 21) | (0x00) | OPC_CP2
,
1015 OPC_PADDH
= (26 << 21) | (0x00) | OPC_CP2
,
1016 OPC_PADDW
= (27 << 21) | (0x00) | OPC_CP2
,
1017 OPC_PADDSB
= (28 << 21) | (0x00) | OPC_CP2
,
1018 OPC_PADDUSB
= (29 << 21) | (0x00) | OPC_CP2
,
1019 OPC_PADDB
= (30 << 21) | (0x00) | OPC_CP2
,
1020 OPC_PADDD
= (31 << 21) | (0x00) | OPC_CP2
,
1022 OPC_PSUBSH
= (24 << 21) | (0x01) | OPC_CP2
,
1023 OPC_PSUBUSH
= (25 << 21) | (0x01) | OPC_CP2
,
1024 OPC_PSUBH
= (26 << 21) | (0x01) | OPC_CP2
,
1025 OPC_PSUBW
= (27 << 21) | (0x01) | OPC_CP2
,
1026 OPC_PSUBSB
= (28 << 21) | (0x01) | OPC_CP2
,
1027 OPC_PSUBUSB
= (29 << 21) | (0x01) | OPC_CP2
,
1028 OPC_PSUBB
= (30 << 21) | (0x01) | OPC_CP2
,
1029 OPC_PSUBD
= (31 << 21) | (0x01) | OPC_CP2
,
1031 OPC_PSHUFH
= (24 << 21) | (0x02) | OPC_CP2
,
1032 OPC_PACKSSWH
= (25 << 21) | (0x02) | OPC_CP2
,
1033 OPC_PACKSSHB
= (26 << 21) | (0x02) | OPC_CP2
,
1034 OPC_PACKUSHB
= (27 << 21) | (0x02) | OPC_CP2
,
1035 OPC_XOR_CP2
= (28 << 21) | (0x02) | OPC_CP2
,
1036 OPC_NOR_CP2
= (29 << 21) | (0x02) | OPC_CP2
,
1037 OPC_AND_CP2
= (30 << 21) | (0x02) | OPC_CP2
,
1038 OPC_PANDN
= (31 << 21) | (0x02) | OPC_CP2
,
1040 OPC_PUNPCKLHW
= (24 << 21) | (0x03) | OPC_CP2
,
1041 OPC_PUNPCKHHW
= (25 << 21) | (0x03) | OPC_CP2
,
1042 OPC_PUNPCKLBH
= (26 << 21) | (0x03) | OPC_CP2
,
1043 OPC_PUNPCKHBH
= (27 << 21) | (0x03) | OPC_CP2
,
1044 OPC_PINSRH_0
= (28 << 21) | (0x03) | OPC_CP2
,
1045 OPC_PINSRH_1
= (29 << 21) | (0x03) | OPC_CP2
,
1046 OPC_PINSRH_2
= (30 << 21) | (0x03) | OPC_CP2
,
1047 OPC_PINSRH_3
= (31 << 21) | (0x03) | OPC_CP2
,
1049 OPC_PAVGH
= (24 << 21) | (0x08) | OPC_CP2
,
1050 OPC_PAVGB
= (25 << 21) | (0x08) | OPC_CP2
,
1051 OPC_PMAXSH
= (26 << 21) | (0x08) | OPC_CP2
,
1052 OPC_PMINSH
= (27 << 21) | (0x08) | OPC_CP2
,
1053 OPC_PMAXUB
= (28 << 21) | (0x08) | OPC_CP2
,
1054 OPC_PMINUB
= (29 << 21) | (0x08) | OPC_CP2
,
1056 OPC_PCMPEQW
= (24 << 21) | (0x09) | OPC_CP2
,
1057 OPC_PCMPGTW
= (25 << 21) | (0x09) | OPC_CP2
,
1058 OPC_PCMPEQH
= (26 << 21) | (0x09) | OPC_CP2
,
1059 OPC_PCMPGTH
= (27 << 21) | (0x09) | OPC_CP2
,
1060 OPC_PCMPEQB
= (28 << 21) | (0x09) | OPC_CP2
,
1061 OPC_PCMPGTB
= (29 << 21) | (0x09) | OPC_CP2
,
1063 OPC_PSLLW
= (24 << 21) | (0x0A) | OPC_CP2
,
1064 OPC_PSLLH
= (25 << 21) | (0x0A) | OPC_CP2
,
1065 OPC_PMULLH
= (26 << 21) | (0x0A) | OPC_CP2
,
1066 OPC_PMULHH
= (27 << 21) | (0x0A) | OPC_CP2
,
1067 OPC_PMULUW
= (28 << 21) | (0x0A) | OPC_CP2
,
1068 OPC_PMULHUH
= (29 << 21) | (0x0A) | OPC_CP2
,
1070 OPC_PSRLW
= (24 << 21) | (0x0B) | OPC_CP2
,
1071 OPC_PSRLH
= (25 << 21) | (0x0B) | OPC_CP2
,
1072 OPC_PSRAW
= (26 << 21) | (0x0B) | OPC_CP2
,
1073 OPC_PSRAH
= (27 << 21) | (0x0B) | OPC_CP2
,
1074 OPC_PUNPCKLWD
= (28 << 21) | (0x0B) | OPC_CP2
,
1075 OPC_PUNPCKHWD
= (29 << 21) | (0x0B) | OPC_CP2
,
1077 OPC_ADDU_CP2
= (24 << 21) | (0x0C) | OPC_CP2
,
1078 OPC_OR_CP2
= (25 << 21) | (0x0C) | OPC_CP2
,
1079 OPC_ADD_CP2
= (26 << 21) | (0x0C) | OPC_CP2
,
1080 OPC_DADD_CP2
= (27 << 21) | (0x0C) | OPC_CP2
,
1081 OPC_SEQU_CP2
= (28 << 21) | (0x0C) | OPC_CP2
,
1082 OPC_SEQ_CP2
= (29 << 21) | (0x0C) | OPC_CP2
,
1084 OPC_SUBU_CP2
= (24 << 21) | (0x0D) | OPC_CP2
,
1085 OPC_PASUBUB
= (25 << 21) | (0x0D) | OPC_CP2
,
1086 OPC_SUB_CP2
= (26 << 21) | (0x0D) | OPC_CP2
,
1087 OPC_DSUB_CP2
= (27 << 21) | (0x0D) | OPC_CP2
,
1088 OPC_SLTU_CP2
= (28 << 21) | (0x0D) | OPC_CP2
,
1089 OPC_SLT_CP2
= (29 << 21) | (0x0D) | OPC_CP2
,
1091 OPC_SLL_CP2
= (24 << 21) | (0x0E) | OPC_CP2
,
1092 OPC_DSLL_CP2
= (25 << 21) | (0x0E) | OPC_CP2
,
1093 OPC_PEXTRH
= (26 << 21) | (0x0E) | OPC_CP2
,
1094 OPC_PMADDHW
= (27 << 21) | (0x0E) | OPC_CP2
,
1095 OPC_SLEU_CP2
= (28 << 21) | (0x0E) | OPC_CP2
,
1096 OPC_SLE_CP2
= (29 << 21) | (0x0E) | OPC_CP2
,
1098 OPC_SRL_CP2
= (24 << 21) | (0x0F) | OPC_CP2
,
1099 OPC_DSRL_CP2
= (25 << 21) | (0x0F) | OPC_CP2
,
1100 OPC_SRA_CP2
= (26 << 21) | (0x0F) | OPC_CP2
,
1101 OPC_DSRA_CP2
= (27 << 21) | (0x0F) | OPC_CP2
,
1102 OPC_BIADD
= (28 << 21) | (0x0F) | OPC_CP2
,
1103 OPC_PMOVMSKB
= (29 << 21) | (0x0F) | OPC_CP2
,
1107 #define MASK_CP3(op) (MASK_OP_MAJOR(op) | (op & 0x3F))
1110 OPC_LWXC1
= 0x00 | OPC_CP3
,
1111 OPC_LDXC1
= 0x01 | OPC_CP3
,
1112 OPC_LUXC1
= 0x05 | OPC_CP3
,
1113 OPC_SWXC1
= 0x08 | OPC_CP3
,
1114 OPC_SDXC1
= 0x09 | OPC_CP3
,
1115 OPC_SUXC1
= 0x0D | OPC_CP3
,
1116 OPC_PREFX
= 0x0F | OPC_CP3
,
1117 OPC_ALNV_PS
= 0x1E | OPC_CP3
,
1118 OPC_MADD_S
= 0x20 | OPC_CP3
,
1119 OPC_MADD_D
= 0x21 | OPC_CP3
,
1120 OPC_MADD_PS
= 0x26 | OPC_CP3
,
1121 OPC_MSUB_S
= 0x28 | OPC_CP3
,
1122 OPC_MSUB_D
= 0x29 | OPC_CP3
,
1123 OPC_MSUB_PS
= 0x2E | OPC_CP3
,
1124 OPC_NMADD_S
= 0x30 | OPC_CP3
,
1125 OPC_NMADD_D
= 0x31 | OPC_CP3
,
1126 OPC_NMADD_PS
= 0x36 | OPC_CP3
,
1127 OPC_NMSUB_S
= 0x38 | OPC_CP3
,
1128 OPC_NMSUB_D
= 0x39 | OPC_CP3
,
1129 OPC_NMSUB_PS
= 0x3E | OPC_CP3
,
1133 * MMI (MultiMedia Instruction) encodings
1134 * ======================================
1136 * MMI instructions encoding table keys:
1138 * * This code is reserved for future use. An attempt to execute it
1139 * causes a Reserved Instruction exception.
1140 * % This code indicates an instruction class. The instruction word
1141 * must be further decoded by examining additional tables that show
1142 * the values for other instruction fields.
1143 * # This code is reserved for the unsupported instructions DMULT,
1144 * DMULTU, DDIV, DDIVU, LL, LLD, SC, SCD, LWC2 and SWC2. An attempt
1145 * to execute it causes a Reserved Instruction exception.
1147 * MMI instructions encoded by opcode field (MMI, LQ, SQ):
1150 * +--------+----------------------------------------+
1152 * +--------+----------------------------------------+
1154 * opcode bits 28..26
1155 * bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
1156 * 31..29 | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111
1157 * -------+-------+-------+-------+-------+-------+-------+-------+-------
1158 * 0 000 |SPECIAL| REGIMM| J | JAL | BEQ | BNE | BLEZ | BGTZ
1159 * 1 001 | ADDI | ADDIU | SLTI | SLTIU | ANDI | ORI | XORI | LUI
1160 * 2 010 | COP0 | COP1 | * | * | BEQL | BNEL | BLEZL | BGTZL
1161 * 3 011 | DADDI | DADDIU| LDL | LDR | MMI% | * | LQ | SQ
1162 * 4 100 | LB | LH | LWL | LW | LBU | LHU | LWR | LWU
1163 * 5 101 | SB | SH | SWL | SW | SDL | SDR | SWR | CACHE
1164 * 6 110 | # | LWC1 | # | PREF | # | LDC1 | # | LD
1165 * 7 111 | # | SWC1 | # | * | # | SDC1 | # | SD
1169 MMI_OPC_CLASS_MMI
= 0x1C << 26, /* Same as OPC_SPECIAL2 */
1170 MMI_OPC_LQ
= 0x1E << 26, /* Same as OPC_MSA */
1171 MMI_OPC_SQ
= 0x1F << 26, /* Same as OPC_SPECIAL3 */
1175 * MMI instructions with opcode field = MMI:
1178 * +--------+-------------------------------+--------+
1179 * | MMI | |function|
1180 * +--------+-------------------------------+--------+
1182 * function bits 2..0
1183 * bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
1184 * 5..3 | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111
1185 * -------+-------+-------+-------+-------+-------+-------+-------+-------
1186 * 0 000 | MADD | MADDU | * | * | PLZCW | * | * | *
1187 * 1 001 | MMI0% | MMI2% | * | * | * | * | * | *
1188 * 2 010 | MFHI1 | MTHI1 | MFLO1 | MTLO1 | * | * | * | *
1189 * 3 011 | MULT1 | MULTU1| DIV1 | DIVU1 | * | * | * | *
1190 * 4 100 | MADD1 | MADDU1| * | * | * | * | * | *
1191 * 5 101 | MMI1% | MMI3% | * | * | * | * | * | *
1192 * 6 110 | PMFHL | PMTHL | * | * | PSLLH | * | PSRLH | PSRAH
1193 * 7 111 | * | * | * | * | PSLLW | * | PSRLW | PSRAW
1196 #define MASK_MMI(op) (MASK_OP_MAJOR(op) | ((op) & 0x3F))
1198 MMI_OPC_MADD
= 0x00 | MMI_OPC_CLASS_MMI
, /* Same as OPC_MADD */
1199 MMI_OPC_MADDU
= 0x01 | MMI_OPC_CLASS_MMI
, /* Same as OPC_MADDU */
1200 MMI_OPC_MULT1
= 0x18 | MMI_OPC_CLASS_MMI
, /* Same minor as OPC_MULT */
1201 MMI_OPC_MULTU1
= 0x19 | MMI_OPC_CLASS_MMI
, /* Same min. as OPC_MULTU */
1202 MMI_OPC_DIV1
= 0x1A | MMI_OPC_CLASS_MMI
, /* Same minor as OPC_DIV */
1203 MMI_OPC_DIVU1
= 0x1B | MMI_OPC_CLASS_MMI
, /* Same minor as OPC_DIVU */
1204 MMI_OPC_MADD1
= 0x20 | MMI_OPC_CLASS_MMI
,
1205 MMI_OPC_MADDU1
= 0x21 | MMI_OPC_CLASS_MMI
,
1208 /* global register indices */
1209 TCGv cpu_gpr
[32], cpu_PC
;
1211 * For CPUs using 128-bit GPR registers, we put the lower halves in cpu_gpr[])
1212 * and the upper halves in cpu_gpr_hi[].
1214 TCGv_i64 cpu_gpr_hi
[32];
1215 TCGv cpu_HI
[MIPS_DSP_ACC
], cpu_LO
[MIPS_DSP_ACC
];
1216 static TCGv cpu_dspctrl
, btarget
;
1218 static TCGv cpu_lladdr
, cpu_llval
;
1219 static TCGv_i32 hflags
;
1220 TCGv_i32 fpu_fcr0
, fpu_fcr31
;
1221 TCGv_i64 fpu_f64
[32];
1223 #include "exec/gen-icount.h"
1225 #define gen_helper_0e0i(name, arg) do { \
1226 TCGv_i32 helper_tmp = tcg_const_i32(arg); \
1227 gen_helper_##name(cpu_env, helper_tmp); \
1228 tcg_temp_free_i32(helper_tmp); \
1231 #define gen_helper_0e1i(name, arg1, arg2) do { \
1232 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1233 gen_helper_##name(cpu_env, arg1, helper_tmp); \
1234 tcg_temp_free_i32(helper_tmp); \
1237 #define gen_helper_1e0i(name, ret, arg1) do { \
1238 TCGv_i32 helper_tmp = tcg_const_i32(arg1); \
1239 gen_helper_##name(ret, cpu_env, helper_tmp); \
1240 tcg_temp_free_i32(helper_tmp); \
1243 #define gen_helper_1e1i(name, ret, arg1, arg2) do { \
1244 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1245 gen_helper_##name(ret, cpu_env, arg1, helper_tmp); \
1246 tcg_temp_free_i32(helper_tmp); \
1249 #define gen_helper_0e2i(name, arg1, arg2, arg3) do { \
1250 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1251 gen_helper_##name(cpu_env, arg1, arg2, helper_tmp); \
1252 tcg_temp_free_i32(helper_tmp); \
1255 #define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do { \
1256 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1257 gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp); \
1258 tcg_temp_free_i32(helper_tmp); \
1261 #define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do { \
1262 TCGv_i32 helper_tmp = tcg_const_i32(arg4); \
1263 gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp); \
1264 tcg_temp_free_i32(helper_tmp); \
1267 #define DISAS_STOP DISAS_TARGET_0
1268 #define DISAS_EXIT DISAS_TARGET_1
1270 static const char * const regnames
[] = {
1271 "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
1272 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
1273 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
1274 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
1277 static const char * const regnames_HI
[] = {
1278 "HI0", "HI1", "HI2", "HI3",
1281 static const char * const regnames_LO
[] = {
1282 "LO0", "LO1", "LO2", "LO3",
1285 static const char * const fregnames
[] = {
1286 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
1287 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
1288 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
1289 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
1292 /* General purpose registers moves. */
1293 void gen_load_gpr(TCGv t
, int reg
)
1296 tcg_gen_movi_tl(t
, 0);
1298 tcg_gen_mov_tl(t
, cpu_gpr
[reg
]);
1302 void gen_store_gpr(TCGv t
, int reg
)
1305 tcg_gen_mov_tl(cpu_gpr
[reg
], t
);
1309 #if defined(TARGET_MIPS64)
1310 void gen_load_gpr_hi(TCGv_i64 t
, int reg
)
1313 tcg_gen_movi_i64(t
, 0);
1315 tcg_gen_mov_i64(t
, cpu_gpr_hi
[reg
]);
1319 void gen_store_gpr_hi(TCGv_i64 t
, int reg
)
1322 tcg_gen_mov_i64(cpu_gpr_hi
[reg
], t
);
1325 #endif /* TARGET_MIPS64 */
1327 /* Moves to/from shadow registers. */
1328 static inline void gen_load_srsgpr(int from
, int to
)
1330 TCGv t0
= tcg_temp_new();
1333 tcg_gen_movi_tl(t0
, 0);
1335 TCGv_i32 t2
= tcg_temp_new_i32();
1336 TCGv_ptr addr
= tcg_temp_new_ptr();
1338 tcg_gen_ld_i32(t2
, cpu_env
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
1339 tcg_gen_shri_i32(t2
, t2
, CP0SRSCtl_PSS
);
1340 tcg_gen_andi_i32(t2
, t2
, 0xf);
1341 tcg_gen_muli_i32(t2
, t2
, sizeof(target_ulong
) * 32);
1342 tcg_gen_ext_i32_ptr(addr
, t2
);
1343 tcg_gen_add_ptr(addr
, cpu_env
, addr
);
1345 tcg_gen_ld_tl(t0
, addr
, sizeof(target_ulong
) * from
);
1346 tcg_temp_free_ptr(addr
);
1347 tcg_temp_free_i32(t2
);
1349 gen_store_gpr(t0
, to
);
1353 static inline void gen_store_srsgpr(int from
, int to
)
1356 TCGv t0
= tcg_temp_new();
1357 TCGv_i32 t2
= tcg_temp_new_i32();
1358 TCGv_ptr addr
= tcg_temp_new_ptr();
1360 gen_load_gpr(t0
, from
);
1361 tcg_gen_ld_i32(t2
, cpu_env
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
1362 tcg_gen_shri_i32(t2
, t2
, CP0SRSCtl_PSS
);
1363 tcg_gen_andi_i32(t2
, t2
, 0xf);
1364 tcg_gen_muli_i32(t2
, t2
, sizeof(target_ulong
) * 32);
1365 tcg_gen_ext_i32_ptr(addr
, t2
);
1366 tcg_gen_add_ptr(addr
, cpu_env
, addr
);
1368 tcg_gen_st_tl(t0
, addr
, sizeof(target_ulong
) * to
);
1369 tcg_temp_free_ptr(addr
);
1370 tcg_temp_free_i32(t2
);
1376 static inline void gen_save_pc(target_ulong pc
)
1378 tcg_gen_movi_tl(cpu_PC
, pc
);
1381 static inline void save_cpu_state(DisasContext
*ctx
, int do_save_pc
)
1383 LOG_DISAS("hflags %08x saved %08x\n", ctx
->hflags
, ctx
->saved_hflags
);
1384 if (do_save_pc
&& ctx
->base
.pc_next
!= ctx
->saved_pc
) {
1385 gen_save_pc(ctx
->base
.pc_next
);
1386 ctx
->saved_pc
= ctx
->base
.pc_next
;
1388 if (ctx
->hflags
!= ctx
->saved_hflags
) {
1389 tcg_gen_movi_i32(hflags
, ctx
->hflags
);
1390 ctx
->saved_hflags
= ctx
->hflags
;
1391 switch (ctx
->hflags
& MIPS_HFLAG_BMASK_BASE
) {
1397 tcg_gen_movi_tl(btarget
, ctx
->btarget
);
1403 static inline void restore_cpu_state(CPUMIPSState
*env
, DisasContext
*ctx
)
1405 ctx
->saved_hflags
= ctx
->hflags
;
1406 switch (ctx
->hflags
& MIPS_HFLAG_BMASK_BASE
) {
1412 ctx
->btarget
= env
->btarget
;
1417 void generate_exception_err(DisasContext
*ctx
, int excp
, int err
)
1419 TCGv_i32 texcp
= tcg_const_i32(excp
);
1420 TCGv_i32 terr
= tcg_const_i32(err
);
1421 save_cpu_state(ctx
, 1);
1422 gen_helper_raise_exception_err(cpu_env
, texcp
, terr
);
1423 tcg_temp_free_i32(terr
);
1424 tcg_temp_free_i32(texcp
);
1425 ctx
->base
.is_jmp
= DISAS_NORETURN
;
1428 void generate_exception(DisasContext
*ctx
, int excp
)
1430 gen_helper_0e0i(raise_exception
, excp
);
1433 void generate_exception_end(DisasContext
*ctx
, int excp
)
1435 generate_exception_err(ctx
, excp
, 0);
1438 void gen_reserved_instruction(DisasContext
*ctx
)
1440 generate_exception_end(ctx
, EXCP_RI
);
1443 /* Floating point register moves. */
1444 void gen_load_fpr32(DisasContext
*ctx
, TCGv_i32 t
, int reg
)
1446 if (ctx
->hflags
& MIPS_HFLAG_FRE
) {
1447 generate_exception(ctx
, EXCP_RI
);
1449 tcg_gen_extrl_i64_i32(t
, fpu_f64
[reg
]);
1452 void gen_store_fpr32(DisasContext
*ctx
, TCGv_i32 t
, int reg
)
1455 if (ctx
->hflags
& MIPS_HFLAG_FRE
) {
1456 generate_exception(ctx
, EXCP_RI
);
1458 t64
= tcg_temp_new_i64();
1459 tcg_gen_extu_i32_i64(t64
, t
);
1460 tcg_gen_deposit_i64(fpu_f64
[reg
], fpu_f64
[reg
], t64
, 0, 32);
1461 tcg_temp_free_i64(t64
);
1464 static void gen_load_fpr32h(DisasContext
*ctx
, TCGv_i32 t
, int reg
)
1466 if (ctx
->hflags
& MIPS_HFLAG_F64
) {
1467 tcg_gen_extrh_i64_i32(t
, fpu_f64
[reg
]);
1469 gen_load_fpr32(ctx
, t
, reg
| 1);
1473 static void gen_store_fpr32h(DisasContext
*ctx
, TCGv_i32 t
, int reg
)
1475 if (ctx
->hflags
& MIPS_HFLAG_F64
) {
1476 TCGv_i64 t64
= tcg_temp_new_i64();
1477 tcg_gen_extu_i32_i64(t64
, t
);
1478 tcg_gen_deposit_i64(fpu_f64
[reg
], fpu_f64
[reg
], t64
, 32, 32);
1479 tcg_temp_free_i64(t64
);
1481 gen_store_fpr32(ctx
, t
, reg
| 1);
1485 void gen_load_fpr64(DisasContext
*ctx
, TCGv_i64 t
, int reg
)
1487 if (ctx
->hflags
& MIPS_HFLAG_F64
) {
1488 tcg_gen_mov_i64(t
, fpu_f64
[reg
]);
1490 tcg_gen_concat32_i64(t
, fpu_f64
[reg
& ~1], fpu_f64
[reg
| 1]);
1494 void gen_store_fpr64(DisasContext
*ctx
, TCGv_i64 t
, int reg
)
1496 if (ctx
->hflags
& MIPS_HFLAG_F64
) {
1497 tcg_gen_mov_i64(fpu_f64
[reg
], t
);
1500 tcg_gen_deposit_i64(fpu_f64
[reg
& ~1], fpu_f64
[reg
& ~1], t
, 0, 32);
1501 t0
= tcg_temp_new_i64();
1502 tcg_gen_shri_i64(t0
, t
, 32);
1503 tcg_gen_deposit_i64(fpu_f64
[reg
| 1], fpu_f64
[reg
| 1], t0
, 0, 32);
1504 tcg_temp_free_i64(t0
);
1508 int get_fp_bit(int cc
)
1517 /* Addresses computation */
1518 void gen_op_addr_add(DisasContext
*ctx
, TCGv ret
, TCGv arg0
, TCGv arg1
)
1520 tcg_gen_add_tl(ret
, arg0
, arg1
);
1522 #if defined(TARGET_MIPS64)
1523 if (ctx
->hflags
& MIPS_HFLAG_AWRAP
) {
1524 tcg_gen_ext32s_i64(ret
, ret
);
1529 static inline void gen_op_addr_addi(DisasContext
*ctx
, TCGv ret
, TCGv base
,
1532 tcg_gen_addi_tl(ret
, base
, ofs
);
1534 #if defined(TARGET_MIPS64)
1535 if (ctx
->hflags
& MIPS_HFLAG_AWRAP
) {
1536 tcg_gen_ext32s_i64(ret
, ret
);
1541 /* Addresses computation (translation time) */
1542 static target_long
addr_add(DisasContext
*ctx
, target_long base
,
1545 target_long sum
= base
+ offset
;
1547 #if defined(TARGET_MIPS64)
1548 if (ctx
->hflags
& MIPS_HFLAG_AWRAP
) {
1555 /* Sign-extract the low 32-bits to a target_long. */
1556 void gen_move_low32(TCGv ret
, TCGv_i64 arg
)
1558 #if defined(TARGET_MIPS64)
1559 tcg_gen_ext32s_i64(ret
, arg
);
1561 tcg_gen_extrl_i64_i32(ret
, arg
);
1565 /* Sign-extract the high 32-bits to a target_long. */
1566 void gen_move_high32(TCGv ret
, TCGv_i64 arg
)
1568 #if defined(TARGET_MIPS64)
1569 tcg_gen_sari_i64(ret
, arg
, 32);
1571 tcg_gen_extrh_i64_i32(ret
, arg
);
1575 void check_cp0_enabled(DisasContext
*ctx
)
1577 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_CP0
))) {
1578 generate_exception_end(ctx
, EXCP_CpU
);
1582 void check_cp1_enabled(DisasContext
*ctx
)
1584 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_FPU
))) {
1585 generate_exception_err(ctx
, EXCP_CpU
, 1);
1590 * Verify that the processor is running with COP1X instructions enabled.
1591 * This is associated with the nabla symbol in the MIPS32 and MIPS64
1594 void check_cop1x(DisasContext
*ctx
)
1596 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_COP1X
))) {
1597 gen_reserved_instruction(ctx
);
1602 * Verify that the processor is running with 64-bit floating-point
1603 * operations enabled.
1605 void check_cp1_64bitmode(DisasContext
*ctx
)
1607 if (unlikely(~ctx
->hflags
& (MIPS_HFLAG_F64
| MIPS_HFLAG_COP1X
))) {
1608 gen_reserved_instruction(ctx
);
1613 * Verify if floating point register is valid; an operation is not defined
1614 * if bit 0 of any register specification is set and the FR bit in the
1615 * Status register equals zero, since the register numbers specify an
1616 * even-odd pair of adjacent coprocessor general registers. When the FR bit
1617 * in the Status register equals one, both even and odd register numbers
1618 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
1620 * Multiple 64 bit wide registers can be checked by calling
1621 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
1623 void check_cp1_registers(DisasContext
*ctx
, int regs
)
1625 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_F64
) && (regs
& 1))) {
1626 gen_reserved_instruction(ctx
);
1631 * Verify that the processor is running with DSP instructions enabled.
1632 * This is enabled by CP0 Status register MX(24) bit.
1634 static inline void check_dsp(DisasContext
*ctx
)
1636 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_DSP
))) {
1637 if (ctx
->insn_flags
& ASE_DSP
) {
1638 generate_exception_end(ctx
, EXCP_DSPDIS
);
1640 gen_reserved_instruction(ctx
);
1645 static inline void check_dsp_r2(DisasContext
*ctx
)
1647 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_DSP_R2
))) {
1648 if (ctx
->insn_flags
& ASE_DSP
) {
1649 generate_exception_end(ctx
, EXCP_DSPDIS
);
1651 gen_reserved_instruction(ctx
);
1656 static inline void check_dsp_r3(DisasContext
*ctx
)
1658 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_DSP_R3
))) {
1659 if (ctx
->insn_flags
& ASE_DSP
) {
1660 generate_exception_end(ctx
, EXCP_DSPDIS
);
1662 gen_reserved_instruction(ctx
);
1668 * This code generates a "reserved instruction" exception if the
1669 * CPU does not support the instruction set corresponding to flags.
1671 void check_insn(DisasContext
*ctx
, uint64_t flags
)
1673 if (unlikely(!(ctx
->insn_flags
& flags
))) {
1674 gen_reserved_instruction(ctx
);
1679 * This code generates a "reserved instruction" exception if the
1680 * CPU has corresponding flag set which indicates that the instruction
1683 static inline void check_insn_opc_removed(DisasContext
*ctx
, uint64_t flags
)
1685 if (unlikely(ctx
->insn_flags
& flags
)) {
1686 gen_reserved_instruction(ctx
);
1691 * The Linux kernel traps certain reserved instruction exceptions to
1692 * emulate the corresponding instructions. QEMU is the kernel in user
1693 * mode, so those traps are emulated by accepting the instructions.
1695 * A reserved instruction exception is generated for flagged CPUs if
1696 * QEMU runs in system mode.
1698 static inline void check_insn_opc_user_only(DisasContext
*ctx
, uint64_t flags
)
1700 #ifndef CONFIG_USER_ONLY
1701 check_insn_opc_removed(ctx
, flags
);
1706 * This code generates a "reserved instruction" exception if the
1707 * CPU does not support 64-bit paired-single (PS) floating point data type.
1709 static inline void check_ps(DisasContext
*ctx
)
1711 if (unlikely(!ctx
->ps
)) {
1712 generate_exception(ctx
, EXCP_RI
);
1714 check_cp1_64bitmode(ctx
);
1718 * This code generates a "reserved instruction" exception if cpu is not
1719 * 64-bit or 64-bit instructions are not enabled.
1721 void check_mips_64(DisasContext
*ctx
)
1723 if (unlikely((TARGET_LONG_BITS
!= 64) || !(ctx
->hflags
& MIPS_HFLAG_64
))) {
1724 gen_reserved_instruction(ctx
);
1728 #ifndef CONFIG_USER_ONLY
1729 static inline void check_mvh(DisasContext
*ctx
)
1731 if (unlikely(!ctx
->mvh
)) {
1732 generate_exception(ctx
, EXCP_RI
);
1738 * This code generates a "reserved instruction" exception if the
1739 * Config5 XNP bit is set.
1741 static inline void check_xnp(DisasContext
*ctx
)
1743 if (unlikely(ctx
->CP0_Config5
& (1 << CP0C5_XNP
))) {
1744 gen_reserved_instruction(ctx
);
1748 #ifndef CONFIG_USER_ONLY
1750 * This code generates a "reserved instruction" exception if the
1751 * Config3 PW bit is NOT set.
1753 static inline void check_pw(DisasContext
*ctx
)
1755 if (unlikely(!(ctx
->CP0_Config3
& (1 << CP0C3_PW
)))) {
1756 gen_reserved_instruction(ctx
);
1762 * This code generates a "reserved instruction" exception if the
1763 * Config3 MT bit is NOT set.
1765 static inline void check_mt(DisasContext
*ctx
)
1767 if (unlikely(!(ctx
->CP0_Config3
& (1 << CP0C3_MT
)))) {
1768 gen_reserved_instruction(ctx
);
1772 #ifndef CONFIG_USER_ONLY
1774 * This code generates a "coprocessor unusable" exception if CP0 is not
1775 * available, and, if that is not the case, generates a "reserved instruction"
1776 * exception if the Config5 MT bit is NOT set. This is needed for availability
1777 * control of some of MT ASE instructions.
1779 static inline void check_cp0_mt(DisasContext
*ctx
)
1781 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_CP0
))) {
1782 generate_exception_end(ctx
, EXCP_CpU
);
1784 if (unlikely(!(ctx
->CP0_Config3
& (1 << CP0C3_MT
)))) {
1785 gen_reserved_instruction(ctx
);
1792 * This code generates a "reserved instruction" exception if the
1793 * Config5 NMS bit is set.
1795 static inline void check_nms(DisasContext
*ctx
)
1797 if (unlikely(ctx
->CP0_Config5
& (1 << CP0C5_NMS
))) {
1798 gen_reserved_instruction(ctx
);
1803 * This code generates a "reserved instruction" exception if the
1804 * Config5 NMS bit is set, and Config1 DL, Config1 IL, Config2 SL,
1805 * Config2 TL, and Config5 L2C are unset.
1807 static inline void check_nms_dl_il_sl_tl_l2c(DisasContext
*ctx
)
1809 if (unlikely((ctx
->CP0_Config5
& (1 << CP0C5_NMS
)) &&
1810 !(ctx
->CP0_Config1
& (1 << CP0C1_DL
)) &&
1811 !(ctx
->CP0_Config1
& (1 << CP0C1_IL
)) &&
1812 !(ctx
->CP0_Config2
& (1 << CP0C2_SL
)) &&
1813 !(ctx
->CP0_Config2
& (1 << CP0C2_TL
)) &&
1814 !(ctx
->CP0_Config5
& (1 << CP0C5_L2C
)))) {
1815 gen_reserved_instruction(ctx
);
1820 * This code generates a "reserved instruction" exception if the
1821 * Config5 EVA bit is NOT set.
1823 static inline void check_eva(DisasContext
*ctx
)
1825 if (unlikely(!(ctx
->CP0_Config5
& (1 << CP0C5_EVA
)))) {
1826 gen_reserved_instruction(ctx
);
1832 * Define small wrappers for gen_load_fpr* so that we have a uniform
1833 * calling interface for 32 and 64-bit FPRs. No sense in changing
1834 * all callers for gen_load_fpr32 when we need the CTX parameter for
1837 #define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(ctx, x, y)
1838 #define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
1839 #define FOP_CONDS(type, abs, fmt, ifmt, bits) \
1840 static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
1841 int ft, int fs, int cc) \
1843 TCGv_i##bits fp0 = tcg_temp_new_i##bits(); \
1844 TCGv_i##bits fp1 = tcg_temp_new_i##bits(); \
1853 check_cp1_registers(ctx, fs | ft); \
1861 gen_ldcmp_fpr##bits(ctx, fp0, fs); \
1862 gen_ldcmp_fpr##bits(ctx, fp1, ft); \
1865 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); \
1868 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); \
1871 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); \
1874 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); \
1877 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); \
1880 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); \
1883 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); \
1886 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); \
1889 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); \
1892 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); \
1895 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); \
1898 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); \
1901 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); \
1904 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); \
1907 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); \
1910 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); \
1915 tcg_temp_free_i##bits(fp0); \
1916 tcg_temp_free_i##bits(fp1); \
1919 FOP_CONDS(, 0, d
, FMT_D
, 64)
1920 FOP_CONDS(abs
, 1, d
, FMT_D
, 64)
1921 FOP_CONDS(, 0, s
, FMT_S
, 32)
1922 FOP_CONDS(abs
, 1, s
, FMT_S
, 32)
1923 FOP_CONDS(, 0, ps
, FMT_PS
, 64)
1924 FOP_CONDS(abs
, 1, ps
, FMT_PS
, 64)
1927 #define FOP_CONDNS(fmt, ifmt, bits, STORE) \
1928 static inline void gen_r6_cmp_ ## fmt(DisasContext *ctx, int n, \
1929 int ft, int fs, int fd) \
1931 TCGv_i ## bits fp0 = tcg_temp_new_i ## bits(); \
1932 TCGv_i ## bits fp1 = tcg_temp_new_i ## bits(); \
1933 if (ifmt == FMT_D) { \
1934 check_cp1_registers(ctx, fs | ft | fd); \
1936 gen_ldcmp_fpr ## bits(ctx, fp0, fs); \
1937 gen_ldcmp_fpr ## bits(ctx, fp1, ft); \
1940 gen_helper_r6_cmp_ ## fmt ## _af(fp0, cpu_env, fp0, fp1); \
1943 gen_helper_r6_cmp_ ## fmt ## _un(fp0, cpu_env, fp0, fp1); \
1946 gen_helper_r6_cmp_ ## fmt ## _eq(fp0, cpu_env, fp0, fp1); \
1949 gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, cpu_env, fp0, fp1); \
1952 gen_helper_r6_cmp_ ## fmt ## _lt(fp0, cpu_env, fp0, fp1); \
1955 gen_helper_r6_cmp_ ## fmt ## _ult(fp0, cpu_env, fp0, fp1); \
1958 gen_helper_r6_cmp_ ## fmt ## _le(fp0, cpu_env, fp0, fp1); \
1961 gen_helper_r6_cmp_ ## fmt ## _ule(fp0, cpu_env, fp0, fp1); \
1964 gen_helper_r6_cmp_ ## fmt ## _saf(fp0, cpu_env, fp0, fp1); \
1967 gen_helper_r6_cmp_ ## fmt ## _sun(fp0, cpu_env, fp0, fp1); \
1970 gen_helper_r6_cmp_ ## fmt ## _seq(fp0, cpu_env, fp0, fp1); \
1973 gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, cpu_env, fp0, fp1); \
1976 gen_helper_r6_cmp_ ## fmt ## _slt(fp0, cpu_env, fp0, fp1); \
1979 gen_helper_r6_cmp_ ## fmt ## _sult(fp0, cpu_env, fp0, fp1); \
1982 gen_helper_r6_cmp_ ## fmt ## _sle(fp0, cpu_env, fp0, fp1); \
1985 gen_helper_r6_cmp_ ## fmt ## _sule(fp0, cpu_env, fp0, fp1); \
1988 gen_helper_r6_cmp_ ## fmt ## _or(fp0, cpu_env, fp0, fp1); \
1991 gen_helper_r6_cmp_ ## fmt ## _une(fp0, cpu_env, fp0, fp1); \
1994 gen_helper_r6_cmp_ ## fmt ## _ne(fp0, cpu_env, fp0, fp1); \
1997 gen_helper_r6_cmp_ ## fmt ## _sor(fp0, cpu_env, fp0, fp1); \
2000 gen_helper_r6_cmp_ ## fmt ## _sune(fp0, cpu_env, fp0, fp1); \
2003 gen_helper_r6_cmp_ ## fmt ## _sne(fp0, cpu_env, fp0, fp1); \
2009 tcg_temp_free_i ## bits(fp0); \
2010 tcg_temp_free_i ## bits(fp1); \
2013 FOP_CONDNS(d
, FMT_D
, 64, gen_store_fpr64(ctx
, fp0
, fd
))
2014 FOP_CONDNS(s
, FMT_S
, 32, gen_store_fpr32(ctx
, fp0
, fd
))
2016 #undef gen_ldcmp_fpr32
2017 #undef gen_ldcmp_fpr64
2019 /* load/store instructions. */
2020 #ifdef CONFIG_USER_ONLY
2021 #define OP_LD_ATOMIC(insn, fname) \
2022 static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \
2023 DisasContext *ctx) \
2025 TCGv t0 = tcg_temp_new(); \
2026 tcg_gen_mov_tl(t0, arg1); \
2027 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
2028 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
2029 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
2030 tcg_temp_free(t0); \
2033 #define OP_LD_ATOMIC(insn, fname) \
2034 static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \
2035 DisasContext *ctx) \
2037 gen_helper_1e1i(insn, ret, arg1, mem_idx); \
2040 OP_LD_ATOMIC(ll
, ld32s
);
2041 #if defined(TARGET_MIPS64)
2042 OP_LD_ATOMIC(lld
, ld64
);
2046 void gen_base_offset_addr(DisasContext
*ctx
, TCGv addr
, int base
, int offset
)
2049 tcg_gen_movi_tl(addr
, offset
);
2050 } else if (offset
== 0) {
2051 gen_load_gpr(addr
, base
);
2053 tcg_gen_movi_tl(addr
, offset
);
2054 gen_op_addr_add(ctx
, addr
, cpu_gpr
[base
], addr
);
2058 static target_ulong
pc_relative_pc(DisasContext
*ctx
)
2060 target_ulong pc
= ctx
->base
.pc_next
;
2062 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
2063 int branch_bytes
= ctx
->hflags
& MIPS_HFLAG_BDS16
? 2 : 4;
2068 pc
&= ~(target_ulong
)3;
2073 static void gen_ld(DisasContext
*ctx
, uint32_t opc
,
2074 int rt
, int base
, int offset
)
2077 int mem_idx
= ctx
->mem_idx
;
2079 if (rt
== 0 && ctx
->insn_flags
& (INSN_LOONGSON2E
| INSN_LOONGSON2F
|
2082 * Loongson CPU uses a load to zero register for prefetch.
2083 * We emulate it as a NOP. On other CPU we must perform the
2084 * actual memory access.
2089 t0
= tcg_temp_new();
2090 gen_base_offset_addr(ctx
, t0
, base
, offset
);
2093 #if defined(TARGET_MIPS64)
2095 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEUL
|
2096 ctx
->default_tcg_memop_mask
);
2097 gen_store_gpr(t0
, rt
);
2100 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEQ
|
2101 ctx
->default_tcg_memop_mask
);
2102 gen_store_gpr(t0
, rt
);
2106 op_ld_lld(t0
, t0
, mem_idx
, ctx
);
2107 gen_store_gpr(t0
, rt
);
2110 t1
= tcg_temp_new();
2112 * Do a byte access to possibly trigger a page
2113 * fault with the unaligned address.
2115 tcg_gen_qemu_ld_tl(t1
, t0
, mem_idx
, MO_UB
);
2116 tcg_gen_andi_tl(t1
, t0
, 7);
2117 #ifndef TARGET_WORDS_BIGENDIAN
2118 tcg_gen_xori_tl(t1
, t1
, 7);
2120 tcg_gen_shli_tl(t1
, t1
, 3);
2121 tcg_gen_andi_tl(t0
, t0
, ~7);
2122 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEQ
);
2123 tcg_gen_shl_tl(t0
, t0
, t1
);
2124 t2
= tcg_const_tl(-1);
2125 tcg_gen_shl_tl(t2
, t2
, t1
);
2126 gen_load_gpr(t1
, rt
);
2127 tcg_gen_andc_tl(t1
, t1
, t2
);
2129 tcg_gen_or_tl(t0
, t0
, t1
);
2131 gen_store_gpr(t0
, rt
);
2134 t1
= tcg_temp_new();
2136 * Do a byte access to possibly trigger a page
2137 * fault with the unaligned address.
2139 tcg_gen_qemu_ld_tl(t1
, t0
, mem_idx
, MO_UB
);
2140 tcg_gen_andi_tl(t1
, t0
, 7);
2141 #ifdef TARGET_WORDS_BIGENDIAN
2142 tcg_gen_xori_tl(t1
, t1
, 7);
2144 tcg_gen_shli_tl(t1
, t1
, 3);
2145 tcg_gen_andi_tl(t0
, t0
, ~7);
2146 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEQ
);
2147 tcg_gen_shr_tl(t0
, t0
, t1
);
2148 tcg_gen_xori_tl(t1
, t1
, 63);
2149 t2
= tcg_const_tl(0xfffffffffffffffeull
);
2150 tcg_gen_shl_tl(t2
, t2
, t1
);
2151 gen_load_gpr(t1
, rt
);
2152 tcg_gen_and_tl(t1
, t1
, t2
);
2154 tcg_gen_or_tl(t0
, t0
, t1
);
2156 gen_store_gpr(t0
, rt
);
2159 t1
= tcg_const_tl(pc_relative_pc(ctx
));
2160 gen_op_addr_add(ctx
, t0
, t0
, t1
);
2162 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEQ
);
2163 gen_store_gpr(t0
, rt
);
2167 t1
= tcg_const_tl(pc_relative_pc(ctx
));
2168 gen_op_addr_add(ctx
, t0
, t0
, t1
);
2170 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TESL
);
2171 gen_store_gpr(t0
, rt
);
2174 mem_idx
= MIPS_HFLAG_UM
;
2177 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TESL
|
2178 ctx
->default_tcg_memop_mask
);
2179 gen_store_gpr(t0
, rt
);
2182 mem_idx
= MIPS_HFLAG_UM
;
2185 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TESW
|
2186 ctx
->default_tcg_memop_mask
);
2187 gen_store_gpr(t0
, rt
);
2190 mem_idx
= MIPS_HFLAG_UM
;
2193 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEUW
|
2194 ctx
->default_tcg_memop_mask
);
2195 gen_store_gpr(t0
, rt
);
2198 mem_idx
= MIPS_HFLAG_UM
;
2201 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_SB
);
2202 gen_store_gpr(t0
, rt
);
2205 mem_idx
= MIPS_HFLAG_UM
;
2208 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_UB
);
2209 gen_store_gpr(t0
, rt
);
2212 mem_idx
= MIPS_HFLAG_UM
;
2215 t1
= tcg_temp_new();
2217 * Do a byte access to possibly trigger a page
2218 * fault with the unaligned address.
2220 tcg_gen_qemu_ld_tl(t1
, t0
, mem_idx
, MO_UB
);
2221 tcg_gen_andi_tl(t1
, t0
, 3);
2222 #ifndef TARGET_WORDS_BIGENDIAN
2223 tcg_gen_xori_tl(t1
, t1
, 3);
2225 tcg_gen_shli_tl(t1
, t1
, 3);
2226 tcg_gen_andi_tl(t0
, t0
, ~3);
2227 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEUL
);
2228 tcg_gen_shl_tl(t0
, t0
, t1
);
2229 t2
= tcg_const_tl(-1);
2230 tcg_gen_shl_tl(t2
, t2
, t1
);
2231 gen_load_gpr(t1
, rt
);
2232 tcg_gen_andc_tl(t1
, t1
, t2
);
2234 tcg_gen_or_tl(t0
, t0
, t1
);
2236 tcg_gen_ext32s_tl(t0
, t0
);
2237 gen_store_gpr(t0
, rt
);
2240 mem_idx
= MIPS_HFLAG_UM
;
2243 t1
= tcg_temp_new();
2245 * Do a byte access to possibly trigger a page
2246 * fault with the unaligned address.
2248 tcg_gen_qemu_ld_tl(t1
, t0
, mem_idx
, MO_UB
);
2249 tcg_gen_andi_tl(t1
, t0
, 3);
2250 #ifdef TARGET_WORDS_BIGENDIAN
2251 tcg_gen_xori_tl(t1
, t1
, 3);
2253 tcg_gen_shli_tl(t1
, t1
, 3);
2254 tcg_gen_andi_tl(t0
, t0
, ~3);
2255 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEUL
);
2256 tcg_gen_shr_tl(t0
, t0
, t1
);
2257 tcg_gen_xori_tl(t1
, t1
, 31);
2258 t2
= tcg_const_tl(0xfffffffeull
);
2259 tcg_gen_shl_tl(t2
, t2
, t1
);
2260 gen_load_gpr(t1
, rt
);
2261 tcg_gen_and_tl(t1
, t1
, t2
);
2263 tcg_gen_or_tl(t0
, t0
, t1
);
2265 tcg_gen_ext32s_tl(t0
, t0
);
2266 gen_store_gpr(t0
, rt
);
2269 mem_idx
= MIPS_HFLAG_UM
;
2273 op_ld_ll(t0
, t0
, mem_idx
, ctx
);
2274 gen_store_gpr(t0
, rt
);
2280 static void gen_llwp(DisasContext
*ctx
, uint32_t base
, int16_t offset
,
2281 uint32_t reg1
, uint32_t reg2
)
2283 TCGv taddr
= tcg_temp_new();
2284 TCGv_i64 tval
= tcg_temp_new_i64();
2285 TCGv tmp1
= tcg_temp_new();
2286 TCGv tmp2
= tcg_temp_new();
2288 gen_base_offset_addr(ctx
, taddr
, base
, offset
);
2289 tcg_gen_qemu_ld64(tval
, taddr
, ctx
->mem_idx
);
2290 #ifdef TARGET_WORDS_BIGENDIAN
2291 tcg_gen_extr_i64_tl(tmp2
, tmp1
, tval
);
2293 tcg_gen_extr_i64_tl(tmp1
, tmp2
, tval
);
2295 gen_store_gpr(tmp1
, reg1
);
2296 tcg_temp_free(tmp1
);
2297 gen_store_gpr(tmp2
, reg2
);
2298 tcg_temp_free(tmp2
);
2299 tcg_gen_st_i64(tval
, cpu_env
, offsetof(CPUMIPSState
, llval_wp
));
2300 tcg_temp_free_i64(tval
);
2301 tcg_gen_st_tl(taddr
, cpu_env
, offsetof(CPUMIPSState
, lladdr
));
2302 tcg_temp_free(taddr
);
2306 static void gen_st(DisasContext
*ctx
, uint32_t opc
, int rt
,
2307 int base
, int offset
)
2309 TCGv t0
= tcg_temp_new();
2310 TCGv t1
= tcg_temp_new();
2311 int mem_idx
= ctx
->mem_idx
;
2313 gen_base_offset_addr(ctx
, t0
, base
, offset
);
2314 gen_load_gpr(t1
, rt
);
2316 #if defined(TARGET_MIPS64)
2318 tcg_gen_qemu_st_tl(t1
, t0
, mem_idx
, MO_TEQ
|
2319 ctx
->default_tcg_memop_mask
);
2322 gen_helper_0e2i(sdl
, t1
, t0
, mem_idx
);
2325 gen_helper_0e2i(sdr
, t1
, t0
, mem_idx
);
2329 mem_idx
= MIPS_HFLAG_UM
;
2332 tcg_gen_qemu_st_tl(t1
, t0
, mem_idx
, MO_TEUL
|
2333 ctx
->default_tcg_memop_mask
);
2336 mem_idx
= MIPS_HFLAG_UM
;
2339 tcg_gen_qemu_st_tl(t1
, t0
, mem_idx
, MO_TEUW
|
2340 ctx
->default_tcg_memop_mask
);
2343 mem_idx
= MIPS_HFLAG_UM
;
2346 tcg_gen_qemu_st_tl(t1
, t0
, mem_idx
, MO_8
);
2349 mem_idx
= MIPS_HFLAG_UM
;
2352 gen_helper_0e2i(swl
, t1
, t0
, mem_idx
);
2355 mem_idx
= MIPS_HFLAG_UM
;
2358 gen_helper_0e2i(swr
, t1
, t0
, mem_idx
);
2366 /* Store conditional */
2367 static void gen_st_cond(DisasContext
*ctx
, int rt
, int base
, int offset
,
2368 MemOp tcg_mo
, bool eva
)
2371 TCGLabel
*l1
= gen_new_label();
2372 TCGLabel
*done
= gen_new_label();
2374 t0
= tcg_temp_new();
2375 addr
= tcg_temp_new();
2376 /* compare the address against that of the preceding LL */
2377 gen_base_offset_addr(ctx
, addr
, base
, offset
);
2378 tcg_gen_brcond_tl(TCG_COND_EQ
, addr
, cpu_lladdr
, l1
);
2379 tcg_temp_free(addr
);
2380 tcg_gen_movi_tl(t0
, 0);
2381 gen_store_gpr(t0
, rt
);
2385 /* generate cmpxchg */
2386 val
= tcg_temp_new();
2387 gen_load_gpr(val
, rt
);
2388 tcg_gen_atomic_cmpxchg_tl(t0
, cpu_lladdr
, cpu_llval
, val
,
2389 eva
? MIPS_HFLAG_UM
: ctx
->mem_idx
, tcg_mo
);
2390 tcg_gen_setcond_tl(TCG_COND_EQ
, t0
, t0
, cpu_llval
);
2391 gen_store_gpr(t0
, rt
);
2394 gen_set_label(done
);
2399 static void gen_scwp(DisasContext
*ctx
, uint32_t base
, int16_t offset
,
2400 uint32_t reg1
, uint32_t reg2
, bool eva
)
2402 TCGv taddr
= tcg_temp_local_new();
2403 TCGv lladdr
= tcg_temp_local_new();
2404 TCGv_i64 tval
= tcg_temp_new_i64();
2405 TCGv_i64 llval
= tcg_temp_new_i64();
2406 TCGv_i64 val
= tcg_temp_new_i64();
2407 TCGv tmp1
= tcg_temp_new();
2408 TCGv tmp2
= tcg_temp_new();
2409 TCGLabel
*lab_fail
= gen_new_label();
2410 TCGLabel
*lab_done
= gen_new_label();
2412 gen_base_offset_addr(ctx
, taddr
, base
, offset
);
2414 tcg_gen_ld_tl(lladdr
, cpu_env
, offsetof(CPUMIPSState
, lladdr
));
2415 tcg_gen_brcond_tl(TCG_COND_NE
, taddr
, lladdr
, lab_fail
);
2417 gen_load_gpr(tmp1
, reg1
);
2418 gen_load_gpr(tmp2
, reg2
);
2420 #ifdef TARGET_WORDS_BIGENDIAN
2421 tcg_gen_concat_tl_i64(tval
, tmp2
, tmp1
);
2423 tcg_gen_concat_tl_i64(tval
, tmp1
, tmp2
);
2426 tcg_gen_ld_i64(llval
, cpu_env
, offsetof(CPUMIPSState
, llval_wp
));
2427 tcg_gen_atomic_cmpxchg_i64(val
, taddr
, llval
, tval
,
2428 eva
? MIPS_HFLAG_UM
: ctx
->mem_idx
, MO_64
);
2430 tcg_gen_movi_tl(cpu_gpr
[reg1
], 1);
2432 tcg_gen_brcond_i64(TCG_COND_EQ
, val
, llval
, lab_done
);
2434 gen_set_label(lab_fail
);
2437 tcg_gen_movi_tl(cpu_gpr
[reg1
], 0);
2439 gen_set_label(lab_done
);
2440 tcg_gen_movi_tl(lladdr
, -1);
2441 tcg_gen_st_tl(lladdr
, cpu_env
, offsetof(CPUMIPSState
, lladdr
));
2444 /* Load and store */
2445 static void gen_flt_ldst(DisasContext
*ctx
, uint32_t opc
, int ft
,
2449 * Don't do NOP if destination is zero: we must perform the actual
2455 TCGv_i32 fp0
= tcg_temp_new_i32();
2456 tcg_gen_qemu_ld_i32(fp0
, t0
, ctx
->mem_idx
, MO_TESL
|
2457 ctx
->default_tcg_memop_mask
);
2458 gen_store_fpr32(ctx
, fp0
, ft
);
2459 tcg_temp_free_i32(fp0
);
2464 TCGv_i32 fp0
= tcg_temp_new_i32();
2465 gen_load_fpr32(ctx
, fp0
, ft
);
2466 tcg_gen_qemu_st_i32(fp0
, t0
, ctx
->mem_idx
, MO_TEUL
|
2467 ctx
->default_tcg_memop_mask
);
2468 tcg_temp_free_i32(fp0
);
2473 TCGv_i64 fp0
= tcg_temp_new_i64();
2474 tcg_gen_qemu_ld_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
|
2475 ctx
->default_tcg_memop_mask
);
2476 gen_store_fpr64(ctx
, fp0
, ft
);
2477 tcg_temp_free_i64(fp0
);
2482 TCGv_i64 fp0
= tcg_temp_new_i64();
2483 gen_load_fpr64(ctx
, fp0
, ft
);
2484 tcg_gen_qemu_st_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
|
2485 ctx
->default_tcg_memop_mask
);
2486 tcg_temp_free_i64(fp0
);
2490 MIPS_INVAL("flt_ldst");
2491 gen_reserved_instruction(ctx
);
2496 static void gen_cop1_ldst(DisasContext
*ctx
, uint32_t op
, int rt
,
2497 int rs
, int16_t imm
)
2499 TCGv t0
= tcg_temp_new();
2501 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
2502 check_cp1_enabled(ctx
);
2506 check_insn(ctx
, ISA_MIPS2
);
2509 gen_base_offset_addr(ctx
, t0
, rs
, imm
);
2510 gen_flt_ldst(ctx
, op
, rt
, t0
);
2513 generate_exception_err(ctx
, EXCP_CpU
, 1);
2518 /* Arithmetic with immediate operand */
2519 static void gen_arith_imm(DisasContext
*ctx
, uint32_t opc
,
2520 int rt
, int rs
, int imm
)
2522 target_ulong uimm
= (target_long
)imm
; /* Sign extend to 32/64 bits */
2524 if (rt
== 0 && opc
!= OPC_ADDI
&& opc
!= OPC_DADDI
) {
2526 * If no destination, treat it as a NOP.
2527 * For addi, we must generate the overflow exception when needed.
2534 TCGv t0
= tcg_temp_local_new();
2535 TCGv t1
= tcg_temp_new();
2536 TCGv t2
= tcg_temp_new();
2537 TCGLabel
*l1
= gen_new_label();
2539 gen_load_gpr(t1
, rs
);
2540 tcg_gen_addi_tl(t0
, t1
, uimm
);
2541 tcg_gen_ext32s_tl(t0
, t0
);
2543 tcg_gen_xori_tl(t1
, t1
, ~uimm
);
2544 tcg_gen_xori_tl(t2
, t0
, uimm
);
2545 tcg_gen_and_tl(t1
, t1
, t2
);
2547 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2549 /* operands of same sign, result different sign */
2550 generate_exception(ctx
, EXCP_OVERFLOW
);
2552 tcg_gen_ext32s_tl(t0
, t0
);
2553 gen_store_gpr(t0
, rt
);
2559 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
2560 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
2562 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
2565 #if defined(TARGET_MIPS64)
2568 TCGv t0
= tcg_temp_local_new();
2569 TCGv t1
= tcg_temp_new();
2570 TCGv t2
= tcg_temp_new();
2571 TCGLabel
*l1
= gen_new_label();
2573 gen_load_gpr(t1
, rs
);
2574 tcg_gen_addi_tl(t0
, t1
, uimm
);
2576 tcg_gen_xori_tl(t1
, t1
, ~uimm
);
2577 tcg_gen_xori_tl(t2
, t0
, uimm
);
2578 tcg_gen_and_tl(t1
, t1
, t2
);
2580 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2582 /* operands of same sign, result different sign */
2583 generate_exception(ctx
, EXCP_OVERFLOW
);
2585 gen_store_gpr(t0
, rt
);
2591 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
2593 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
2600 /* Logic with immediate operand */
2601 static void gen_logic_imm(DisasContext
*ctx
, uint32_t opc
,
2602 int rt
, int rs
, int16_t imm
)
2607 /* If no destination, treat it as a NOP. */
2610 uimm
= (uint16_t)imm
;
2613 if (likely(rs
!= 0)) {
2614 tcg_gen_andi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
2616 tcg_gen_movi_tl(cpu_gpr
[rt
], 0);
2621 tcg_gen_ori_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
2623 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
2627 if (likely(rs
!= 0)) {
2628 tcg_gen_xori_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
2630 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
2634 if (rs
!= 0 && (ctx
->insn_flags
& ISA_MIPS_R6
)) {
2636 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], imm
<< 16);
2637 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
2639 tcg_gen_movi_tl(cpu_gpr
[rt
], imm
<< 16);
2648 /* Set on less than with immediate operand */
2649 static void gen_slt_imm(DisasContext
*ctx
, uint32_t opc
,
2650 int rt
, int rs
, int16_t imm
)
2652 target_ulong uimm
= (target_long
)imm
; /* Sign extend to 32/64 bits */
2656 /* If no destination, treat it as a NOP. */
2659 t0
= tcg_temp_new();
2660 gen_load_gpr(t0
, rs
);
2663 tcg_gen_setcondi_tl(TCG_COND_LT
, cpu_gpr
[rt
], t0
, uimm
);
2666 tcg_gen_setcondi_tl(TCG_COND_LTU
, cpu_gpr
[rt
], t0
, uimm
);
2672 /* Shifts with immediate operand */
2673 static void gen_shift_imm(DisasContext
*ctx
, uint32_t opc
,
2674 int rt
, int rs
, int16_t imm
)
2676 target_ulong uimm
= ((uint16_t)imm
) & 0x1f;
2680 /* If no destination, treat it as a NOP. */
2684 t0
= tcg_temp_new();
2685 gen_load_gpr(t0
, rs
);
2688 tcg_gen_shli_tl(t0
, t0
, uimm
);
2689 tcg_gen_ext32s_tl(cpu_gpr
[rt
], t0
);
2692 tcg_gen_sari_tl(cpu_gpr
[rt
], t0
, uimm
);
2696 tcg_gen_ext32u_tl(t0
, t0
);
2697 tcg_gen_shri_tl(cpu_gpr
[rt
], t0
, uimm
);
2699 tcg_gen_ext32s_tl(cpu_gpr
[rt
], t0
);
2704 TCGv_i32 t1
= tcg_temp_new_i32();
2706 tcg_gen_trunc_tl_i32(t1
, t0
);
2707 tcg_gen_rotri_i32(t1
, t1
, uimm
);
2708 tcg_gen_ext_i32_tl(cpu_gpr
[rt
], t1
);
2709 tcg_temp_free_i32(t1
);
2711 tcg_gen_ext32s_tl(cpu_gpr
[rt
], t0
);
2714 #if defined(TARGET_MIPS64)
2716 tcg_gen_shli_tl(cpu_gpr
[rt
], t0
, uimm
);
2719 tcg_gen_sari_tl(cpu_gpr
[rt
], t0
, uimm
);
2722 tcg_gen_shri_tl(cpu_gpr
[rt
], t0
, uimm
);
2726 tcg_gen_rotri_tl(cpu_gpr
[rt
], t0
, uimm
);
2728 tcg_gen_mov_tl(cpu_gpr
[rt
], t0
);
2732 tcg_gen_shli_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
2735 tcg_gen_sari_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
2738 tcg_gen_shri_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
2741 tcg_gen_rotri_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
2749 static void gen_arith(DisasContext
*ctx
, uint32_t opc
,
2750 int rd
, int rs
, int rt
)
2752 if (rd
== 0 && opc
!= OPC_ADD
&& opc
!= OPC_SUB
2753 && opc
!= OPC_DADD
&& opc
!= OPC_DSUB
) {
2755 * If no destination, treat it as a NOP.
2756 * For add & sub, we must generate the overflow exception when needed.
2764 TCGv t0
= tcg_temp_local_new();
2765 TCGv t1
= tcg_temp_new();
2766 TCGv t2
= tcg_temp_new();
2767 TCGLabel
*l1
= gen_new_label();
2769 gen_load_gpr(t1
, rs
);
2770 gen_load_gpr(t2
, rt
);
2771 tcg_gen_add_tl(t0
, t1
, t2
);
2772 tcg_gen_ext32s_tl(t0
, t0
);
2773 tcg_gen_xor_tl(t1
, t1
, t2
);
2774 tcg_gen_xor_tl(t2
, t0
, t2
);
2775 tcg_gen_andc_tl(t1
, t2
, t1
);
2777 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2779 /* operands of same sign, result different sign */
2780 generate_exception(ctx
, EXCP_OVERFLOW
);
2782 gen_store_gpr(t0
, rd
);
2787 if (rs
!= 0 && rt
!= 0) {
2788 tcg_gen_add_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2789 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
2790 } else if (rs
== 0 && rt
!= 0) {
2791 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2792 } else if (rs
!= 0 && rt
== 0) {
2793 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2795 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2800 TCGv t0
= tcg_temp_local_new();
2801 TCGv t1
= tcg_temp_new();
2802 TCGv t2
= tcg_temp_new();
2803 TCGLabel
*l1
= gen_new_label();
2805 gen_load_gpr(t1
, rs
);
2806 gen_load_gpr(t2
, rt
);
2807 tcg_gen_sub_tl(t0
, t1
, t2
);
2808 tcg_gen_ext32s_tl(t0
, t0
);
2809 tcg_gen_xor_tl(t2
, t1
, t2
);
2810 tcg_gen_xor_tl(t1
, t0
, t1
);
2811 tcg_gen_and_tl(t1
, t1
, t2
);
2813 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2816 * operands of different sign, first operand and the result
2819 generate_exception(ctx
, EXCP_OVERFLOW
);
2821 gen_store_gpr(t0
, rd
);
2826 if (rs
!= 0 && rt
!= 0) {
2827 tcg_gen_sub_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2828 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
2829 } else if (rs
== 0 && rt
!= 0) {
2830 tcg_gen_neg_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2831 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
2832 } else if (rs
!= 0 && rt
== 0) {
2833 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2835 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2838 #if defined(TARGET_MIPS64)
2841 TCGv t0
= tcg_temp_local_new();
2842 TCGv t1
= tcg_temp_new();
2843 TCGv t2
= tcg_temp_new();
2844 TCGLabel
*l1
= gen_new_label();
2846 gen_load_gpr(t1
, rs
);
2847 gen_load_gpr(t2
, rt
);
2848 tcg_gen_add_tl(t0
, t1
, t2
);
2849 tcg_gen_xor_tl(t1
, t1
, t2
);
2850 tcg_gen_xor_tl(t2
, t0
, t2
);
2851 tcg_gen_andc_tl(t1
, t2
, t1
);
2853 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2855 /* operands of same sign, result different sign */
2856 generate_exception(ctx
, EXCP_OVERFLOW
);
2858 gen_store_gpr(t0
, rd
);
2863 if (rs
!= 0 && rt
!= 0) {
2864 tcg_gen_add_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2865 } else if (rs
== 0 && rt
!= 0) {
2866 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2867 } else if (rs
!= 0 && rt
== 0) {
2868 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2870 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2875 TCGv t0
= tcg_temp_local_new();
2876 TCGv t1
= tcg_temp_new();
2877 TCGv t2
= tcg_temp_new();
2878 TCGLabel
*l1
= gen_new_label();
2880 gen_load_gpr(t1
, rs
);
2881 gen_load_gpr(t2
, rt
);
2882 tcg_gen_sub_tl(t0
, t1
, t2
);
2883 tcg_gen_xor_tl(t2
, t1
, t2
);
2884 tcg_gen_xor_tl(t1
, t0
, t1
);
2885 tcg_gen_and_tl(t1
, t1
, t2
);
2887 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2890 * Operands of different sign, first operand and result different
2893 generate_exception(ctx
, EXCP_OVERFLOW
);
2895 gen_store_gpr(t0
, rd
);
2900 if (rs
!= 0 && rt
!= 0) {
2901 tcg_gen_sub_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2902 } else if (rs
== 0 && rt
!= 0) {
2903 tcg_gen_neg_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2904 } else if (rs
!= 0 && rt
== 0) {
2905 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2907 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2912 if (likely(rs
!= 0 && rt
!= 0)) {
2913 tcg_gen_mul_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2914 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
2916 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2922 /* Conditional move */
2923 static void gen_cond_move(DisasContext
*ctx
, uint32_t opc
,
2924 int rd
, int rs
, int rt
)
2929 /* If no destination, treat it as a NOP. */
2933 t0
= tcg_temp_new();
2934 gen_load_gpr(t0
, rt
);
2935 t1
= tcg_const_tl(0);
2936 t2
= tcg_temp_new();
2937 gen_load_gpr(t2
, rs
);
2940 tcg_gen_movcond_tl(TCG_COND_NE
, cpu_gpr
[rd
], t0
, t1
, t2
, cpu_gpr
[rd
]);
2943 tcg_gen_movcond_tl(TCG_COND_EQ
, cpu_gpr
[rd
], t0
, t1
, t2
, cpu_gpr
[rd
]);
2946 tcg_gen_movcond_tl(TCG_COND_NE
, cpu_gpr
[rd
], t0
, t1
, t2
, t1
);
2949 tcg_gen_movcond_tl(TCG_COND_EQ
, cpu_gpr
[rd
], t0
, t1
, t2
, t1
);
2958 static void gen_logic(DisasContext
*ctx
, uint32_t opc
,
2959 int rd
, int rs
, int rt
)
2962 /* If no destination, treat it as a NOP. */
2968 if (likely(rs
!= 0 && rt
!= 0)) {
2969 tcg_gen_and_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2971 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2975 if (rs
!= 0 && rt
!= 0) {
2976 tcg_gen_nor_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2977 } else if (rs
== 0 && rt
!= 0) {
2978 tcg_gen_not_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2979 } else if (rs
!= 0 && rt
== 0) {
2980 tcg_gen_not_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2982 tcg_gen_movi_tl(cpu_gpr
[rd
], ~((target_ulong
)0));
2986 if (likely(rs
!= 0 && rt
!= 0)) {
2987 tcg_gen_or_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2988 } else if (rs
== 0 && rt
!= 0) {
2989 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2990 } else if (rs
!= 0 && rt
== 0) {
2991 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2993 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2997 if (likely(rs
!= 0 && rt
!= 0)) {
2998 tcg_gen_xor_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2999 } else if (rs
== 0 && rt
!= 0) {
3000 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
3001 } else if (rs
!= 0 && rt
== 0) {
3002 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
3004 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3010 /* Set on lower than */
3011 static void gen_slt(DisasContext
*ctx
, uint32_t opc
,
3012 int rd
, int rs
, int rt
)
3017 /* If no destination, treat it as a NOP. */
3021 t0
= tcg_temp_new();
3022 t1
= tcg_temp_new();
3023 gen_load_gpr(t0
, rs
);
3024 gen_load_gpr(t1
, rt
);
3027 tcg_gen_setcond_tl(TCG_COND_LT
, cpu_gpr
[rd
], t0
, t1
);
3030 tcg_gen_setcond_tl(TCG_COND_LTU
, cpu_gpr
[rd
], t0
, t1
);
3038 static void gen_shift(DisasContext
*ctx
, uint32_t opc
,
3039 int rd
, int rs
, int rt
)
3045 * If no destination, treat it as a NOP.
3046 * For add & sub, we must generate the overflow exception when needed.
3051 t0
= tcg_temp_new();
3052 t1
= tcg_temp_new();
3053 gen_load_gpr(t0
, rs
);
3054 gen_load_gpr(t1
, rt
);
3057 tcg_gen_andi_tl(t0
, t0
, 0x1f);
3058 tcg_gen_shl_tl(t0
, t1
, t0
);
3059 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
3062 tcg_gen_andi_tl(t0
, t0
, 0x1f);
3063 tcg_gen_sar_tl(cpu_gpr
[rd
], t1
, t0
);
3066 tcg_gen_ext32u_tl(t1
, t1
);
3067 tcg_gen_andi_tl(t0
, t0
, 0x1f);
3068 tcg_gen_shr_tl(t0
, t1
, t0
);
3069 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
3073 TCGv_i32 t2
= tcg_temp_new_i32();
3074 TCGv_i32 t3
= tcg_temp_new_i32();
3076 tcg_gen_trunc_tl_i32(t2
, t0
);
3077 tcg_gen_trunc_tl_i32(t3
, t1
);
3078 tcg_gen_andi_i32(t2
, t2
, 0x1f);
3079 tcg_gen_rotr_i32(t2
, t3
, t2
);
3080 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
3081 tcg_temp_free_i32(t2
);
3082 tcg_temp_free_i32(t3
);
3085 #if defined(TARGET_MIPS64)
3087 tcg_gen_andi_tl(t0
, t0
, 0x3f);
3088 tcg_gen_shl_tl(cpu_gpr
[rd
], t1
, t0
);
3091 tcg_gen_andi_tl(t0
, t0
, 0x3f);
3092 tcg_gen_sar_tl(cpu_gpr
[rd
], t1
, t0
);
3095 tcg_gen_andi_tl(t0
, t0
, 0x3f);
3096 tcg_gen_shr_tl(cpu_gpr
[rd
], t1
, t0
);
3099 tcg_gen_andi_tl(t0
, t0
, 0x3f);
3100 tcg_gen_rotr_tl(cpu_gpr
[rd
], t1
, t0
);
3108 /* Arithmetic on HI/LO registers */
3109 static void gen_HILO(DisasContext
*ctx
, uint32_t opc
, int acc
, int reg
)
3111 if (reg
== 0 && (opc
== OPC_MFHI
|| opc
== OPC_MFLO
)) {
3122 #if defined(TARGET_MIPS64)
3124 tcg_gen_ext32s_tl(cpu_gpr
[reg
], cpu_HI
[acc
]);
3128 tcg_gen_mov_tl(cpu_gpr
[reg
], cpu_HI
[acc
]);
3132 #if defined(TARGET_MIPS64)
3134 tcg_gen_ext32s_tl(cpu_gpr
[reg
], cpu_LO
[acc
]);
3138 tcg_gen_mov_tl(cpu_gpr
[reg
], cpu_LO
[acc
]);
3143 #if defined(TARGET_MIPS64)
3145 tcg_gen_ext32s_tl(cpu_HI
[acc
], cpu_gpr
[reg
]);
3149 tcg_gen_mov_tl(cpu_HI
[acc
], cpu_gpr
[reg
]);
3152 tcg_gen_movi_tl(cpu_HI
[acc
], 0);
3157 #if defined(TARGET_MIPS64)
3159 tcg_gen_ext32s_tl(cpu_LO
[acc
], cpu_gpr
[reg
]);
3163 tcg_gen_mov_tl(cpu_LO
[acc
], cpu_gpr
[reg
]);
3166 tcg_gen_movi_tl(cpu_LO
[acc
], 0);
3172 static inline void gen_r6_ld(target_long addr
, int reg
, int memidx
,
3175 TCGv t0
= tcg_const_tl(addr
);
3176 tcg_gen_qemu_ld_tl(t0
, t0
, memidx
, memop
);
3177 gen_store_gpr(t0
, reg
);
3181 static inline void gen_pcrel(DisasContext
*ctx
, int opc
, target_ulong pc
,
3187 switch (MASK_OPC_PCREL_TOP2BITS(opc
)) {
3190 offset
= sextract32(ctx
->opcode
<< 2, 0, 21);
3191 addr
= addr_add(ctx
, pc
, offset
);
3192 tcg_gen_movi_tl(cpu_gpr
[rs
], addr
);
3196 offset
= sextract32(ctx
->opcode
<< 2, 0, 21);
3197 addr
= addr_add(ctx
, pc
, offset
);
3198 gen_r6_ld(addr
, rs
, ctx
->mem_idx
, MO_TESL
);
3200 #if defined(TARGET_MIPS64)
3203 offset
= sextract32(ctx
->opcode
<< 2, 0, 21);
3204 addr
= addr_add(ctx
, pc
, offset
);
3205 gen_r6_ld(addr
, rs
, ctx
->mem_idx
, MO_TEUL
);
3209 switch (MASK_OPC_PCREL_TOP5BITS(opc
)) {
3212 offset
= sextract32(ctx
->opcode
, 0, 16) << 16;
3213 addr
= addr_add(ctx
, pc
, offset
);
3214 tcg_gen_movi_tl(cpu_gpr
[rs
], addr
);
3219 offset
= sextract32(ctx
->opcode
, 0, 16) << 16;
3220 addr
= ~0xFFFF & addr_add(ctx
, pc
, offset
);
3221 tcg_gen_movi_tl(cpu_gpr
[rs
], addr
);
3224 #if defined(TARGET_MIPS64)
3225 case R6_OPC_LDPC
: /* bits 16 and 17 are part of immediate */
3226 case R6_OPC_LDPC
+ (1 << 16):
3227 case R6_OPC_LDPC
+ (2 << 16):
3228 case R6_OPC_LDPC
+ (3 << 16):
3230 offset
= sextract32(ctx
->opcode
<< 3, 0, 21);
3231 addr
= addr_add(ctx
, (pc
& ~0x7), offset
);
3232 gen_r6_ld(addr
, rs
, ctx
->mem_idx
, MO_TEQ
);
3236 MIPS_INVAL("OPC_PCREL");
3237 gen_reserved_instruction(ctx
);
3244 static void gen_r6_muldiv(DisasContext
*ctx
, int opc
, int rd
, int rs
, int rt
)
3253 t0
= tcg_temp_new();
3254 t1
= tcg_temp_new();
3256 gen_load_gpr(t0
, rs
);
3257 gen_load_gpr(t1
, rt
);
3262 TCGv t2
= tcg_temp_new();
3263 TCGv t3
= tcg_temp_new();
3264 tcg_gen_ext32s_tl(t0
, t0
);
3265 tcg_gen_ext32s_tl(t1
, t1
);
3266 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, INT_MIN
);
3267 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1);
3268 tcg_gen_and_tl(t2
, t2
, t3
);
3269 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
3270 tcg_gen_or_tl(t2
, t2
, t3
);
3271 tcg_gen_movi_tl(t3
, 0);
3272 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
3273 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
3274 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3281 TCGv t2
= tcg_temp_new();
3282 TCGv t3
= tcg_temp_new();
3283 tcg_gen_ext32s_tl(t0
, t0
);
3284 tcg_gen_ext32s_tl(t1
, t1
);
3285 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, INT_MIN
);
3286 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1);
3287 tcg_gen_and_tl(t2
, t2
, t3
);
3288 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
3289 tcg_gen_or_tl(t2
, t2
, t3
);
3290 tcg_gen_movi_tl(t3
, 0);
3291 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
3292 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
3293 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3300 TCGv t2
= tcg_const_tl(0);
3301 TCGv t3
= tcg_const_tl(1);
3302 tcg_gen_ext32u_tl(t0
, t0
);
3303 tcg_gen_ext32u_tl(t1
, t1
);
3304 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
3305 tcg_gen_divu_tl(cpu_gpr
[rd
], t0
, t1
);
3306 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3313 TCGv t2
= tcg_const_tl(0);
3314 TCGv t3
= tcg_const_tl(1);
3315 tcg_gen_ext32u_tl(t0
, t0
);
3316 tcg_gen_ext32u_tl(t1
, t1
);
3317 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
3318 tcg_gen_remu_tl(cpu_gpr
[rd
], t0
, t1
);
3319 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3326 TCGv_i32 t2
= tcg_temp_new_i32();
3327 TCGv_i32 t3
= tcg_temp_new_i32();
3328 tcg_gen_trunc_tl_i32(t2
, t0
);
3329 tcg_gen_trunc_tl_i32(t3
, t1
);
3330 tcg_gen_mul_i32(t2
, t2
, t3
);
3331 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
3332 tcg_temp_free_i32(t2
);
3333 tcg_temp_free_i32(t3
);
3338 TCGv_i32 t2
= tcg_temp_new_i32();
3339 TCGv_i32 t3
= tcg_temp_new_i32();
3340 tcg_gen_trunc_tl_i32(t2
, t0
);
3341 tcg_gen_trunc_tl_i32(t3
, t1
);
3342 tcg_gen_muls2_i32(t2
, t3
, t2
, t3
);
3343 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t3
);
3344 tcg_temp_free_i32(t2
);
3345 tcg_temp_free_i32(t3
);
3350 TCGv_i32 t2
= tcg_temp_new_i32();
3351 TCGv_i32 t3
= tcg_temp_new_i32();
3352 tcg_gen_trunc_tl_i32(t2
, t0
);
3353 tcg_gen_trunc_tl_i32(t3
, t1
);
3354 tcg_gen_mul_i32(t2
, t2
, t3
);
3355 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
3356 tcg_temp_free_i32(t2
);
3357 tcg_temp_free_i32(t3
);
3362 TCGv_i32 t2
= tcg_temp_new_i32();
3363 TCGv_i32 t3
= tcg_temp_new_i32();
3364 tcg_gen_trunc_tl_i32(t2
, t0
);
3365 tcg_gen_trunc_tl_i32(t3
, t1
);
3366 tcg_gen_mulu2_i32(t2
, t3
, t2
, t3
);
3367 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t3
);
3368 tcg_temp_free_i32(t2
);
3369 tcg_temp_free_i32(t3
);
3372 #if defined(TARGET_MIPS64)
3375 TCGv t2
= tcg_temp_new();
3376 TCGv t3
= tcg_temp_new();
3377 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, -1LL << 63);
3378 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1LL);
3379 tcg_gen_and_tl(t2
, t2
, t3
);
3380 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
3381 tcg_gen_or_tl(t2
, t2
, t3
);
3382 tcg_gen_movi_tl(t3
, 0);
3383 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
3384 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
3391 TCGv t2
= tcg_temp_new();
3392 TCGv t3
= tcg_temp_new();
3393 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, -1LL << 63);
3394 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1LL);
3395 tcg_gen_and_tl(t2
, t2
, t3
);
3396 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
3397 tcg_gen_or_tl(t2
, t2
, t3
);
3398 tcg_gen_movi_tl(t3
, 0);
3399 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
3400 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
3407 TCGv t2
= tcg_const_tl(0);
3408 TCGv t3
= tcg_const_tl(1);
3409 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
3410 tcg_gen_divu_i64(cpu_gpr
[rd
], t0
, t1
);
3417 TCGv t2
= tcg_const_tl(0);
3418 TCGv t3
= tcg_const_tl(1);
3419 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
3420 tcg_gen_remu_i64(cpu_gpr
[rd
], t0
, t1
);
3426 tcg_gen_mul_i64(cpu_gpr
[rd
], t0
, t1
);
3430 TCGv t2
= tcg_temp_new();
3431 tcg_gen_muls2_i64(t2
, cpu_gpr
[rd
], t0
, t1
);
3436 tcg_gen_mul_i64(cpu_gpr
[rd
], t0
, t1
);
3440 TCGv t2
= tcg_temp_new();
3441 tcg_gen_mulu2_i64(t2
, cpu_gpr
[rd
], t0
, t1
);
3447 MIPS_INVAL("r6 mul/div");
3448 gen_reserved_instruction(ctx
);
3456 #if defined(TARGET_MIPS64)
3457 static void gen_div1_tx79(DisasContext
*ctx
, uint32_t opc
, int rs
, int rt
)
3461 t0
= tcg_temp_new();
3462 t1
= tcg_temp_new();
3464 gen_load_gpr(t0
, rs
);
3465 gen_load_gpr(t1
, rt
);
3470 TCGv t2
= tcg_temp_new();
3471 TCGv t3
= tcg_temp_new();
3472 tcg_gen_ext32s_tl(t0
, t0
);
3473 tcg_gen_ext32s_tl(t1
, t1
);
3474 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, INT_MIN
);
3475 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1);
3476 tcg_gen_and_tl(t2
, t2
, t3
);
3477 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
3478 tcg_gen_or_tl(t2
, t2
, t3
);
3479 tcg_gen_movi_tl(t3
, 0);
3480 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
3481 tcg_gen_div_tl(cpu_LO
[1], t0
, t1
);
3482 tcg_gen_rem_tl(cpu_HI
[1], t0
, t1
);
3483 tcg_gen_ext32s_tl(cpu_LO
[1], cpu_LO
[1]);
3484 tcg_gen_ext32s_tl(cpu_HI
[1], cpu_HI
[1]);
3491 TCGv t2
= tcg_const_tl(0);
3492 TCGv t3
= tcg_const_tl(1);
3493 tcg_gen_ext32u_tl(t0
, t0
);
3494 tcg_gen_ext32u_tl(t1
, t1
);
3495 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
3496 tcg_gen_divu_tl(cpu_LO
[1], t0
, t1
);
3497 tcg_gen_remu_tl(cpu_HI
[1], t0
, t1
);
3498 tcg_gen_ext32s_tl(cpu_LO
[1], cpu_LO
[1]);
3499 tcg_gen_ext32s_tl(cpu_HI
[1], cpu_HI
[1]);
3505 MIPS_INVAL("div1 TX79");
3506 gen_reserved_instruction(ctx
);
3515 static void gen_muldiv(DisasContext
*ctx
, uint32_t opc
,
3516 int acc
, int rs
, int rt
)
3520 t0
= tcg_temp_new();
3521 t1
= tcg_temp_new();
3523 gen_load_gpr(t0
, rs
);
3524 gen_load_gpr(t1
, rt
);
3533 TCGv t2
= tcg_temp_new();
3534 TCGv t3
= tcg_temp_new();
3535 tcg_gen_ext32s_tl(t0
, t0
);
3536 tcg_gen_ext32s_tl(t1
, t1
);
3537 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, INT_MIN
);
3538 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1);
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_LO
[acc
], t0
, t1
);
3545 tcg_gen_rem_tl(cpu_HI
[acc
], t0
, t1
);
3546 tcg_gen_ext32s_tl(cpu_LO
[acc
], cpu_LO
[acc
]);
3547 tcg_gen_ext32s_tl(cpu_HI
[acc
], cpu_HI
[acc
]);
3554 TCGv t2
= tcg_const_tl(0);
3555 TCGv t3
= tcg_const_tl(1);
3556 tcg_gen_ext32u_tl(t0
, t0
);
3557 tcg_gen_ext32u_tl(t1
, t1
);
3558 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
3559 tcg_gen_divu_tl(cpu_LO
[acc
], t0
, t1
);
3560 tcg_gen_remu_tl(cpu_HI
[acc
], t0
, t1
);
3561 tcg_gen_ext32s_tl(cpu_LO
[acc
], cpu_LO
[acc
]);
3562 tcg_gen_ext32s_tl(cpu_HI
[acc
], cpu_HI
[acc
]);
3569 TCGv_i32 t2
= tcg_temp_new_i32();
3570 TCGv_i32 t3
= tcg_temp_new_i32();
3571 tcg_gen_trunc_tl_i32(t2
, t0
);
3572 tcg_gen_trunc_tl_i32(t3
, t1
);
3573 tcg_gen_muls2_i32(t2
, t3
, t2
, t3
);
3574 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
3575 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
3576 tcg_temp_free_i32(t2
);
3577 tcg_temp_free_i32(t3
);
3582 TCGv_i32 t2
= tcg_temp_new_i32();
3583 TCGv_i32 t3
= tcg_temp_new_i32();
3584 tcg_gen_trunc_tl_i32(t2
, t0
);
3585 tcg_gen_trunc_tl_i32(t3
, t1
);
3586 tcg_gen_mulu2_i32(t2
, t3
, t2
, t3
);
3587 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
3588 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
3589 tcg_temp_free_i32(t2
);
3590 tcg_temp_free_i32(t3
);
3593 #if defined(TARGET_MIPS64)
3596 TCGv t2
= tcg_temp_new();
3597 TCGv t3
= tcg_temp_new();
3598 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, -1LL << 63);
3599 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1LL);
3600 tcg_gen_and_tl(t2
, t2
, t3
);
3601 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
3602 tcg_gen_or_tl(t2
, t2
, t3
);
3603 tcg_gen_movi_tl(t3
, 0);
3604 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
3605 tcg_gen_div_tl(cpu_LO
[acc
], t0
, t1
);
3606 tcg_gen_rem_tl(cpu_HI
[acc
], t0
, t1
);
3613 TCGv t2
= tcg_const_tl(0);
3614 TCGv t3
= tcg_const_tl(1);
3615 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
3616 tcg_gen_divu_i64(cpu_LO
[acc
], t0
, t1
);
3617 tcg_gen_remu_i64(cpu_HI
[acc
], t0
, t1
);
3623 tcg_gen_muls2_i64(cpu_LO
[acc
], cpu_HI
[acc
], t0
, t1
);
3626 tcg_gen_mulu2_i64(cpu_LO
[acc
], cpu_HI
[acc
], t0
, t1
);
3631 TCGv_i64 t2
= tcg_temp_new_i64();
3632 TCGv_i64 t3
= tcg_temp_new_i64();
3634 tcg_gen_ext_tl_i64(t2
, t0
);
3635 tcg_gen_ext_tl_i64(t3
, t1
);
3636 tcg_gen_mul_i64(t2
, t2
, t3
);
3637 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
3638 tcg_gen_add_i64(t2
, t2
, t3
);
3639 tcg_temp_free_i64(t3
);
3640 gen_move_low32(cpu_LO
[acc
], t2
);
3641 gen_move_high32(cpu_HI
[acc
], t2
);
3642 tcg_temp_free_i64(t2
);
3647 TCGv_i64 t2
= tcg_temp_new_i64();
3648 TCGv_i64 t3
= tcg_temp_new_i64();
3650 tcg_gen_ext32u_tl(t0
, t0
);
3651 tcg_gen_ext32u_tl(t1
, t1
);
3652 tcg_gen_extu_tl_i64(t2
, t0
);
3653 tcg_gen_extu_tl_i64(t3
, t1
);
3654 tcg_gen_mul_i64(t2
, t2
, t3
);
3655 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
3656 tcg_gen_add_i64(t2
, t2
, t3
);
3657 tcg_temp_free_i64(t3
);
3658 gen_move_low32(cpu_LO
[acc
], t2
);
3659 gen_move_high32(cpu_HI
[acc
], t2
);
3660 tcg_temp_free_i64(t2
);
3665 TCGv_i64 t2
= tcg_temp_new_i64();
3666 TCGv_i64 t3
= tcg_temp_new_i64();
3668 tcg_gen_ext_tl_i64(t2
, t0
);
3669 tcg_gen_ext_tl_i64(t3
, t1
);
3670 tcg_gen_mul_i64(t2
, t2
, t3
);
3671 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
3672 tcg_gen_sub_i64(t2
, t3
, t2
);
3673 tcg_temp_free_i64(t3
);
3674 gen_move_low32(cpu_LO
[acc
], t2
);
3675 gen_move_high32(cpu_HI
[acc
], t2
);
3676 tcg_temp_free_i64(t2
);
3681 TCGv_i64 t2
= tcg_temp_new_i64();
3682 TCGv_i64 t3
= tcg_temp_new_i64();
3684 tcg_gen_ext32u_tl(t0
, t0
);
3685 tcg_gen_ext32u_tl(t1
, t1
);
3686 tcg_gen_extu_tl_i64(t2
, t0
);
3687 tcg_gen_extu_tl_i64(t3
, t1
);
3688 tcg_gen_mul_i64(t2
, t2
, t3
);
3689 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
3690 tcg_gen_sub_i64(t2
, t3
, t2
);
3691 tcg_temp_free_i64(t3
);
3692 gen_move_low32(cpu_LO
[acc
], t2
);
3693 gen_move_high32(cpu_HI
[acc
], t2
);
3694 tcg_temp_free_i64(t2
);
3698 MIPS_INVAL("mul/div");
3699 gen_reserved_instruction(ctx
);
3708 * These MULT[U] and MADD[U] instructions implemented in for example
3709 * the Toshiba/Sony R5900 and the Toshiba TX19, TX39 and TX79 core
3710 * architectures are special three-operand variants with the syntax
3712 * MULT[U][1] rd, rs, rt
3716 * (rd, LO, HI) <- rs * rt
3720 * MADD[U][1] rd, rs, rt
3724 * (rd, LO, HI) <- (LO, HI) + rs * rt
3726 * where the low-order 32-bits of the result is placed into both the
3727 * GPR rd and the special register LO. The high-order 32-bits of the
3728 * result is placed into the special register HI.
3730 * If the GPR rd is omitted in assembly language, it is taken to be 0,
3731 * which is the zero register that always reads as 0.
3733 static void gen_mul_txx9(DisasContext
*ctx
, uint32_t opc
,
3734 int rd
, int rs
, int rt
)
3736 TCGv t0
= tcg_temp_new();
3737 TCGv t1
= tcg_temp_new();
3740 gen_load_gpr(t0
, rs
);
3741 gen_load_gpr(t1
, rt
);
3749 TCGv_i32 t2
= tcg_temp_new_i32();
3750 TCGv_i32 t3
= tcg_temp_new_i32();
3751 tcg_gen_trunc_tl_i32(t2
, t0
);
3752 tcg_gen_trunc_tl_i32(t3
, t1
);
3753 tcg_gen_muls2_i32(t2
, t3
, t2
, t3
);
3755 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
3757 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
3758 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
3759 tcg_temp_free_i32(t2
);
3760 tcg_temp_free_i32(t3
);
3763 case MMI_OPC_MULTU1
:
3768 TCGv_i32 t2
= tcg_temp_new_i32();
3769 TCGv_i32 t3
= tcg_temp_new_i32();
3770 tcg_gen_trunc_tl_i32(t2
, t0
);
3771 tcg_gen_trunc_tl_i32(t3
, t1
);
3772 tcg_gen_mulu2_i32(t2
, t3
, t2
, t3
);
3774 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
3776 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
3777 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
3778 tcg_temp_free_i32(t2
);
3779 tcg_temp_free_i32(t3
);
3787 TCGv_i64 t2
= tcg_temp_new_i64();
3788 TCGv_i64 t3
= tcg_temp_new_i64();
3790 tcg_gen_ext_tl_i64(t2
, t0
);
3791 tcg_gen_ext_tl_i64(t3
, t1
);
3792 tcg_gen_mul_i64(t2
, t2
, t3
);
3793 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
3794 tcg_gen_add_i64(t2
, t2
, t3
);
3795 tcg_temp_free_i64(t3
);
3796 gen_move_low32(cpu_LO
[acc
], t2
);
3797 gen_move_high32(cpu_HI
[acc
], t2
);
3799 gen_move_low32(cpu_gpr
[rd
], t2
);
3801 tcg_temp_free_i64(t2
);
3804 case MMI_OPC_MADDU1
:
3809 TCGv_i64 t2
= tcg_temp_new_i64();
3810 TCGv_i64 t3
= tcg_temp_new_i64();
3812 tcg_gen_ext32u_tl(t0
, t0
);
3813 tcg_gen_ext32u_tl(t1
, t1
);
3814 tcg_gen_extu_tl_i64(t2
, t0
);
3815 tcg_gen_extu_tl_i64(t3
, t1
);
3816 tcg_gen_mul_i64(t2
, t2
, t3
);
3817 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
3818 tcg_gen_add_i64(t2
, t2
, t3
);
3819 tcg_temp_free_i64(t3
);
3820 gen_move_low32(cpu_LO
[acc
], t2
);
3821 gen_move_high32(cpu_HI
[acc
], t2
);
3823 gen_move_low32(cpu_gpr
[rd
], t2
);
3825 tcg_temp_free_i64(t2
);
3829 MIPS_INVAL("mul/madd TXx9");
3830 gen_reserved_instruction(ctx
);
3839 static void gen_mul_vr54xx(DisasContext
*ctx
, uint32_t opc
,
3840 int rd
, int rs
, int rt
)
3842 TCGv t0
= tcg_temp_new();
3843 TCGv t1
= tcg_temp_new();
3845 gen_load_gpr(t0
, rs
);
3846 gen_load_gpr(t1
, rt
);
3849 case OPC_VR54XX_MULS
:
3850 gen_helper_muls(t0
, cpu_env
, t0
, t1
);
3852 case OPC_VR54XX_MULSU
:
3853 gen_helper_mulsu(t0
, cpu_env
, t0
, t1
);
3855 case OPC_VR54XX_MACC
:
3856 gen_helper_macc(t0
, cpu_env
, t0
, t1
);
3858 case OPC_VR54XX_MACCU
:
3859 gen_helper_maccu(t0
, cpu_env
, t0
, t1
);
3861 case OPC_VR54XX_MSAC
:
3862 gen_helper_msac(t0
, cpu_env
, t0
, t1
);
3864 case OPC_VR54XX_MSACU
:
3865 gen_helper_msacu(t0
, cpu_env
, t0
, t1
);
3867 case OPC_VR54XX_MULHI
:
3868 gen_helper_mulhi(t0
, cpu_env
, t0
, t1
);
3870 case OPC_VR54XX_MULHIU
:
3871 gen_helper_mulhiu(t0
, cpu_env
, t0
, t1
);
3873 case OPC_VR54XX_MULSHI
:
3874 gen_helper_mulshi(t0
, cpu_env
, t0
, t1
);
3876 case OPC_VR54XX_MULSHIU
:
3877 gen_helper_mulshiu(t0
, cpu_env
, t0
, t1
);
3879 case OPC_VR54XX_MACCHI
:
3880 gen_helper_macchi(t0
, cpu_env
, t0
, t1
);
3882 case OPC_VR54XX_MACCHIU
:
3883 gen_helper_macchiu(t0
, cpu_env
, t0
, t1
);
3885 case OPC_VR54XX_MSACHI
:
3886 gen_helper_msachi(t0
, cpu_env
, t0
, t1
);
3888 case OPC_VR54XX_MSACHIU
:
3889 gen_helper_msachiu(t0
, cpu_env
, t0
, t1
);
3892 MIPS_INVAL("mul vr54xx");
3893 gen_reserved_instruction(ctx
);
3896 gen_store_gpr(t0
, rd
);
3903 static void gen_cl(DisasContext
*ctx
, uint32_t opc
,
3913 gen_load_gpr(t0
, rs
);
3918 #if defined(TARGET_MIPS64)
3922 tcg_gen_not_tl(t0
, t0
);
3931 tcg_gen_ext32u_tl(t0
, t0
);
3932 tcg_gen_clzi_tl(t0
, t0
, TARGET_LONG_BITS
);
3933 tcg_gen_subi_tl(t0
, t0
, TARGET_LONG_BITS
- 32);
3935 #if defined(TARGET_MIPS64)
3940 tcg_gen_clzi_i64(t0
, t0
, 64);
3946 /* Godson integer instructions */
3947 static void gen_loongson_integer(DisasContext
*ctx
, uint32_t opc
,
3948 int rd
, int rs
, int rt
)
3960 case OPC_MULTU_G_2E
:
3961 case OPC_MULTU_G_2F
:
3962 #if defined(TARGET_MIPS64)
3963 case OPC_DMULT_G_2E
:
3964 case OPC_DMULT_G_2F
:
3965 case OPC_DMULTU_G_2E
:
3966 case OPC_DMULTU_G_2F
:
3968 t0
= tcg_temp_new();
3969 t1
= tcg_temp_new();
3972 t0
= tcg_temp_local_new();
3973 t1
= tcg_temp_local_new();
3977 gen_load_gpr(t0
, rs
);
3978 gen_load_gpr(t1
, rt
);
3983 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
3984 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3986 case OPC_MULTU_G_2E
:
3987 case OPC_MULTU_G_2F
:
3988 tcg_gen_ext32u_tl(t0
, t0
);
3989 tcg_gen_ext32u_tl(t1
, t1
);
3990 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
3991 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3996 TCGLabel
*l1
= gen_new_label();
3997 TCGLabel
*l2
= gen_new_label();
3998 TCGLabel
*l3
= gen_new_label();
3999 tcg_gen_ext32s_tl(t0
, t0
);
4000 tcg_gen_ext32s_tl(t1
, t1
);
4001 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
4002 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4005 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, INT_MIN
, l2
);
4006 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1, l2
);
4007 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
4010 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
4011 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
4018 TCGLabel
*l1
= gen_new_label();
4019 TCGLabel
*l2
= gen_new_label();
4020 tcg_gen_ext32u_tl(t0
, t0
);
4021 tcg_gen_ext32u_tl(t1
, t1
);
4022 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
4023 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4026 tcg_gen_divu_tl(cpu_gpr
[rd
], t0
, t1
);
4027 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
4034 TCGLabel
*l1
= gen_new_label();
4035 TCGLabel
*l2
= gen_new_label();
4036 TCGLabel
*l3
= gen_new_label();
4037 tcg_gen_ext32u_tl(t0
, t0
);
4038 tcg_gen_ext32u_tl(t1
, t1
);
4039 tcg_gen_brcondi_tl(TCG_COND_EQ
, t1
, 0, l1
);
4040 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, INT_MIN
, l2
);
4041 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1, l2
);
4043 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4046 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
4047 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
4054 TCGLabel
*l1
= gen_new_label();
4055 TCGLabel
*l2
= gen_new_label();
4056 tcg_gen_ext32u_tl(t0
, t0
);
4057 tcg_gen_ext32u_tl(t1
, t1
);
4058 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
4059 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4062 tcg_gen_remu_tl(cpu_gpr
[rd
], t0
, t1
);
4063 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
4067 #if defined(TARGET_MIPS64)
4068 case OPC_DMULT_G_2E
:
4069 case OPC_DMULT_G_2F
:
4070 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
4072 case OPC_DMULTU_G_2E
:
4073 case OPC_DMULTU_G_2F
:
4074 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
4079 TCGLabel
*l1
= gen_new_label();
4080 TCGLabel
*l2
= gen_new_label();
4081 TCGLabel
*l3
= gen_new_label();
4082 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
4083 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4086 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, -1LL << 63, l2
);
4087 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1LL, l2
);
4088 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
4091 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
4095 case OPC_DDIVU_G_2E
:
4096 case OPC_DDIVU_G_2F
:
4098 TCGLabel
*l1
= gen_new_label();
4099 TCGLabel
*l2
= gen_new_label();
4100 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
4101 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4104 tcg_gen_divu_tl(cpu_gpr
[rd
], t0
, t1
);
4111 TCGLabel
*l1
= gen_new_label();
4112 TCGLabel
*l2
= gen_new_label();
4113 TCGLabel
*l3
= gen_new_label();
4114 tcg_gen_brcondi_tl(TCG_COND_EQ
, t1
, 0, l1
);
4115 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, -1LL << 63, l2
);
4116 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1LL, l2
);
4118 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4121 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
4125 case OPC_DMODU_G_2E
:
4126 case OPC_DMODU_G_2F
:
4128 TCGLabel
*l1
= gen_new_label();
4129 TCGLabel
*l2
= gen_new_label();
4130 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
4131 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4134 tcg_gen_remu_tl(cpu_gpr
[rd
], t0
, t1
);
4145 /* Loongson multimedia instructions */
4146 static void gen_loongson_multimedia(DisasContext
*ctx
, int rd
, int rs
, int rt
)
4148 uint32_t opc
, shift_max
;
4152 opc
= MASK_LMMI(ctx
->opcode
);
4158 t0
= tcg_temp_local_new_i64();
4159 t1
= tcg_temp_local_new_i64();
4162 t0
= tcg_temp_new_i64();
4163 t1
= tcg_temp_new_i64();
4167 check_cp1_enabled(ctx
);
4168 gen_load_fpr64(ctx
, t0
, rs
);
4169 gen_load_fpr64(ctx
, t1
, rt
);
4173 gen_helper_paddsh(t0
, t0
, t1
);
4176 gen_helper_paddush(t0
, t0
, t1
);
4179 gen_helper_paddh(t0
, t0
, t1
);
4182 gen_helper_paddw(t0
, t0
, t1
);
4185 gen_helper_paddsb(t0
, t0
, t1
);
4188 gen_helper_paddusb(t0
, t0
, t1
);
4191 gen_helper_paddb(t0
, t0
, t1
);
4195 gen_helper_psubsh(t0
, t0
, t1
);
4198 gen_helper_psubush(t0
, t0
, t1
);
4201 gen_helper_psubh(t0
, t0
, t1
);
4204 gen_helper_psubw(t0
, t0
, t1
);
4207 gen_helper_psubsb(t0
, t0
, t1
);
4210 gen_helper_psubusb(t0
, t0
, t1
);
4213 gen_helper_psubb(t0
, t0
, t1
);
4217 gen_helper_pshufh(t0
, t0
, t1
);
4220 gen_helper_packsswh(t0
, t0
, t1
);
4223 gen_helper_packsshb(t0
, t0
, t1
);
4226 gen_helper_packushb(t0
, t0
, t1
);
4230 gen_helper_punpcklhw(t0
, t0
, t1
);
4233 gen_helper_punpckhhw(t0
, t0
, t1
);
4236 gen_helper_punpcklbh(t0
, t0
, t1
);
4239 gen_helper_punpckhbh(t0
, t0
, t1
);
4242 gen_helper_punpcklwd(t0
, t0
, t1
);
4245 gen_helper_punpckhwd(t0
, t0
, t1
);
4249 gen_helper_pavgh(t0
, t0
, t1
);
4252 gen_helper_pavgb(t0
, t0
, t1
);
4255 gen_helper_pmaxsh(t0
, t0
, t1
);
4258 gen_helper_pminsh(t0
, t0
, t1
);
4261 gen_helper_pmaxub(t0
, t0
, t1
);
4264 gen_helper_pminub(t0
, t0
, t1
);
4268 gen_helper_pcmpeqw(t0
, t0
, t1
);
4271 gen_helper_pcmpgtw(t0
, t0
, t1
);
4274 gen_helper_pcmpeqh(t0
, t0
, t1
);
4277 gen_helper_pcmpgth(t0
, t0
, t1
);
4280 gen_helper_pcmpeqb(t0
, t0
, t1
);
4283 gen_helper_pcmpgtb(t0
, t0
, t1
);
4287 gen_helper_psllw(t0
, t0
, t1
);
4290 gen_helper_psllh(t0
, t0
, t1
);
4293 gen_helper_psrlw(t0
, t0
, t1
);
4296 gen_helper_psrlh(t0
, t0
, t1
);
4299 gen_helper_psraw(t0
, t0
, t1
);
4302 gen_helper_psrah(t0
, t0
, t1
);
4306 gen_helper_pmullh(t0
, t0
, t1
);
4309 gen_helper_pmulhh(t0
, t0
, t1
);
4312 gen_helper_pmulhuh(t0
, t0
, t1
);
4315 gen_helper_pmaddhw(t0
, t0
, t1
);
4319 gen_helper_pasubub(t0
, t0
, t1
);
4322 gen_helper_biadd(t0
, t0
);
4325 gen_helper_pmovmskb(t0
, t0
);
4329 tcg_gen_add_i64(t0
, t0
, t1
);
4332 tcg_gen_sub_i64(t0
, t0
, t1
);
4335 tcg_gen_xor_i64(t0
, t0
, t1
);
4338 tcg_gen_nor_i64(t0
, t0
, t1
);
4341 tcg_gen_and_i64(t0
, t0
, t1
);
4344 tcg_gen_or_i64(t0
, t0
, t1
);
4348 tcg_gen_andc_i64(t0
, t1
, t0
);
4352 tcg_gen_deposit_i64(t0
, t0
, t1
, 0, 16);
4355 tcg_gen_deposit_i64(t0
, t0
, t1
, 16, 16);
4358 tcg_gen_deposit_i64(t0
, t0
, t1
, 32, 16);
4361 tcg_gen_deposit_i64(t0
, t0
, t1
, 48, 16);
4365 tcg_gen_andi_i64(t1
, t1
, 3);
4366 tcg_gen_shli_i64(t1
, t1
, 4);
4367 tcg_gen_shr_i64(t0
, t0
, t1
);
4368 tcg_gen_ext16u_i64(t0
, t0
);
4372 tcg_gen_add_i64(t0
, t0
, t1
);
4373 tcg_gen_ext32s_i64(t0
, t0
);
4376 tcg_gen_sub_i64(t0
, t0
, t1
);
4377 tcg_gen_ext32s_i64(t0
, t0
);
4399 /* Make sure shift count isn't TCG undefined behaviour. */
4400 tcg_gen_andi_i64(t1
, t1
, shift_max
- 1);
4405 tcg_gen_shl_i64(t0
, t0
, t1
);
4410 * Since SRA is UndefinedResult without sign-extended inputs,
4411 * we can treat SRA and DSRA the same.
4413 tcg_gen_sar_i64(t0
, t0
, t1
);
4416 /* We want to shift in zeros for SRL; zero-extend first. */
4417 tcg_gen_ext32u_i64(t0
, t0
);
4420 tcg_gen_shr_i64(t0
, t0
, t1
);
4424 if (shift_max
== 32) {
4425 tcg_gen_ext32s_i64(t0
, t0
);
4428 /* Shifts larger than MAX produce zero. */
4429 tcg_gen_setcondi_i64(TCG_COND_LTU
, t1
, t1
, shift_max
);
4430 tcg_gen_neg_i64(t1
, t1
);
4431 tcg_gen_and_i64(t0
, t0
, t1
);
4437 TCGv_i64 t2
= tcg_temp_new_i64();
4438 TCGLabel
*lab
= gen_new_label();
4440 tcg_gen_mov_i64(t2
, t0
);
4441 tcg_gen_add_i64(t0
, t1
, t2
);
4442 if (opc
== OPC_ADD_CP2
) {
4443 tcg_gen_ext32s_i64(t0
, t0
);
4445 tcg_gen_xor_i64(t1
, t1
, t2
);
4446 tcg_gen_xor_i64(t2
, t2
, t0
);
4447 tcg_gen_andc_i64(t1
, t2
, t1
);
4448 tcg_temp_free_i64(t2
);
4449 tcg_gen_brcondi_i64(TCG_COND_GE
, t1
, 0, lab
);
4450 generate_exception(ctx
, EXCP_OVERFLOW
);
4458 TCGv_i64 t2
= tcg_temp_new_i64();
4459 TCGLabel
*lab
= gen_new_label();
4461 tcg_gen_mov_i64(t2
, t0
);
4462 tcg_gen_sub_i64(t0
, t1
, t2
);
4463 if (opc
== OPC_SUB_CP2
) {
4464 tcg_gen_ext32s_i64(t0
, t0
);
4466 tcg_gen_xor_i64(t1
, t1
, t2
);
4467 tcg_gen_xor_i64(t2
, t2
, t0
);
4468 tcg_gen_and_i64(t1
, t1
, t2
);
4469 tcg_temp_free_i64(t2
);
4470 tcg_gen_brcondi_i64(TCG_COND_GE
, t1
, 0, lab
);
4471 generate_exception(ctx
, EXCP_OVERFLOW
);
4477 tcg_gen_ext32u_i64(t0
, t0
);
4478 tcg_gen_ext32u_i64(t1
, t1
);
4479 tcg_gen_mul_i64(t0
, t0
, t1
);
4488 cond
= TCG_COND_LTU
;
4496 cond
= TCG_COND_LEU
;
4503 int cc
= (ctx
->opcode
>> 8) & 0x7;
4504 TCGv_i64 t64
= tcg_temp_new_i64();
4505 TCGv_i32 t32
= tcg_temp_new_i32();
4507 tcg_gen_setcond_i64(cond
, t64
, t0
, t1
);
4508 tcg_gen_extrl_i64_i32(t32
, t64
);
4509 tcg_gen_deposit_i32(fpu_fcr31
, fpu_fcr31
, t32
,
4512 tcg_temp_free_i32(t32
);
4513 tcg_temp_free_i64(t64
);
4518 MIPS_INVAL("loongson_cp2");
4519 gen_reserved_instruction(ctx
);
4523 gen_store_fpr64(ctx
, t0
, rd
);
4526 tcg_temp_free_i64(t0
);
4527 tcg_temp_free_i64(t1
);
4530 static void gen_loongson_lswc2(DisasContext
*ctx
, int rt
,
4535 #if defined(TARGET_MIPS64)
4536 int lsq_rt1
= ctx
->opcode
& 0x1f;
4537 int lsq_offset
= sextract32(ctx
->opcode
, 6, 9) << 4;
4539 int shf_offset
= sextract32(ctx
->opcode
, 6, 8);
4541 t0
= tcg_temp_new();
4543 switch (MASK_LOONGSON_GSLSQ(ctx
->opcode
)) {
4544 #if defined(TARGET_MIPS64)
4546 t1
= tcg_temp_new();
4547 gen_base_offset_addr(ctx
, t0
, rs
, lsq_offset
);
4548 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
|
4549 ctx
->default_tcg_memop_mask
);
4550 gen_base_offset_addr(ctx
, t0
, rs
, lsq_offset
+ 8);
4551 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
|
4552 ctx
->default_tcg_memop_mask
);
4553 gen_store_gpr(t1
, rt
);
4554 gen_store_gpr(t0
, lsq_rt1
);
4558 check_cp1_enabled(ctx
);
4559 t1
= tcg_temp_new();
4560 gen_base_offset_addr(ctx
, t0
, rs
, lsq_offset
);
4561 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
|
4562 ctx
->default_tcg_memop_mask
);
4563 gen_base_offset_addr(ctx
, t0
, rs
, lsq_offset
+ 8);
4564 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
|
4565 ctx
->default_tcg_memop_mask
);
4566 gen_store_fpr64(ctx
, t1
, rt
);
4567 gen_store_fpr64(ctx
, t0
, lsq_rt1
);
4571 t1
= tcg_temp_new();
4572 gen_base_offset_addr(ctx
, t0
, rs
, lsq_offset
);
4573 gen_load_gpr(t1
, rt
);
4574 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
|
4575 ctx
->default_tcg_memop_mask
);
4576 gen_base_offset_addr(ctx
, t0
, rs
, lsq_offset
+ 8);
4577 gen_load_gpr(t1
, lsq_rt1
);
4578 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
|
4579 ctx
->default_tcg_memop_mask
);
4583 check_cp1_enabled(ctx
);
4584 t1
= tcg_temp_new();
4585 gen_base_offset_addr(ctx
, t0
, rs
, lsq_offset
);
4586 gen_load_fpr64(ctx
, t1
, rt
);
4587 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
|
4588 ctx
->default_tcg_memop_mask
);
4589 gen_base_offset_addr(ctx
, t0
, rs
, lsq_offset
+ 8);
4590 gen_load_fpr64(ctx
, t1
, lsq_rt1
);
4591 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
|
4592 ctx
->default_tcg_memop_mask
);
4597 switch (MASK_LOONGSON_GSSHFLS(ctx
->opcode
)) {
4599 check_cp1_enabled(ctx
);
4600 gen_base_offset_addr(ctx
, t0
, rs
, shf_offset
);
4601 t1
= tcg_temp_new();
4602 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
4603 tcg_gen_andi_tl(t1
, t0
, 3);
4604 #ifndef TARGET_WORDS_BIGENDIAN
4605 tcg_gen_xori_tl(t1
, t1
, 3);
4607 tcg_gen_shli_tl(t1
, t1
, 3);
4608 tcg_gen_andi_tl(t0
, t0
, ~3);
4609 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEUL
);
4610 tcg_gen_shl_tl(t0
, t0
, t1
);
4611 t2
= tcg_const_tl(-1);
4612 tcg_gen_shl_tl(t2
, t2
, t1
);
4613 fp0
= tcg_temp_new_i32();
4614 gen_load_fpr32(ctx
, fp0
, rt
);
4615 tcg_gen_ext_i32_tl(t1
, fp0
);
4616 tcg_gen_andc_tl(t1
, t1
, t2
);
4618 tcg_gen_or_tl(t0
, t0
, t1
);
4620 #if defined(TARGET_MIPS64)
4621 tcg_gen_extrl_i64_i32(fp0
, t0
);
4623 tcg_gen_ext32s_tl(fp0
, t0
);
4625 gen_store_fpr32(ctx
, fp0
, rt
);
4626 tcg_temp_free_i32(fp0
);
4629 check_cp1_enabled(ctx
);
4630 gen_base_offset_addr(ctx
, t0
, rs
, shf_offset
);
4631 t1
= tcg_temp_new();
4632 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
4633 tcg_gen_andi_tl(t1
, t0
, 3);
4634 #ifdef TARGET_WORDS_BIGENDIAN
4635 tcg_gen_xori_tl(t1
, t1
, 3);
4637 tcg_gen_shli_tl(t1
, t1
, 3);
4638 tcg_gen_andi_tl(t0
, t0
, ~3);
4639 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEUL
);
4640 tcg_gen_shr_tl(t0
, t0
, t1
);
4641 tcg_gen_xori_tl(t1
, t1
, 31);
4642 t2
= tcg_const_tl(0xfffffffeull
);
4643 tcg_gen_shl_tl(t2
, t2
, t1
);
4644 fp0
= tcg_temp_new_i32();
4645 gen_load_fpr32(ctx
, fp0
, rt
);
4646 tcg_gen_ext_i32_tl(t1
, fp0
);
4647 tcg_gen_and_tl(t1
, t1
, t2
);
4649 tcg_gen_or_tl(t0
, t0
, t1
);
4651 #if defined(TARGET_MIPS64)
4652 tcg_gen_extrl_i64_i32(fp0
, t0
);
4654 tcg_gen_ext32s_tl(fp0
, t0
);
4656 gen_store_fpr32(ctx
, fp0
, rt
);
4657 tcg_temp_free_i32(fp0
);
4659 #if defined(TARGET_MIPS64)
4661 check_cp1_enabled(ctx
);
4662 gen_base_offset_addr(ctx
, t0
, rs
, shf_offset
);
4663 t1
= tcg_temp_new();
4664 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
4665 tcg_gen_andi_tl(t1
, t0
, 7);
4666 #ifndef TARGET_WORDS_BIGENDIAN
4667 tcg_gen_xori_tl(t1
, t1
, 7);
4669 tcg_gen_shli_tl(t1
, t1
, 3);
4670 tcg_gen_andi_tl(t0
, t0
, ~7);
4671 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
);
4672 tcg_gen_shl_tl(t0
, t0
, t1
);
4673 t2
= tcg_const_tl(-1);
4674 tcg_gen_shl_tl(t2
, t2
, t1
);
4675 gen_load_fpr64(ctx
, t1
, rt
);
4676 tcg_gen_andc_tl(t1
, t1
, t2
);
4678 tcg_gen_or_tl(t0
, t0
, t1
);
4680 gen_store_fpr64(ctx
, t0
, rt
);
4683 check_cp1_enabled(ctx
);
4684 gen_base_offset_addr(ctx
, t0
, rs
, shf_offset
);
4685 t1
= tcg_temp_new();
4686 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
4687 tcg_gen_andi_tl(t1
, t0
, 7);
4688 #ifdef TARGET_WORDS_BIGENDIAN
4689 tcg_gen_xori_tl(t1
, t1
, 7);
4691 tcg_gen_shli_tl(t1
, t1
, 3);
4692 tcg_gen_andi_tl(t0
, t0
, ~7);
4693 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
);
4694 tcg_gen_shr_tl(t0
, t0
, t1
);
4695 tcg_gen_xori_tl(t1
, t1
, 63);
4696 t2
= tcg_const_tl(0xfffffffffffffffeull
);
4697 tcg_gen_shl_tl(t2
, t2
, t1
);
4698 gen_load_fpr64(ctx
, t1
, rt
);
4699 tcg_gen_and_tl(t1
, t1
, t2
);
4701 tcg_gen_or_tl(t0
, t0
, t1
);
4703 gen_store_fpr64(ctx
, t0
, rt
);
4707 MIPS_INVAL("loongson_gsshfl");
4708 gen_reserved_instruction(ctx
);
4713 switch (MASK_LOONGSON_GSSHFLS(ctx
->opcode
)) {
4715 check_cp1_enabled(ctx
);
4716 t1
= tcg_temp_new();
4717 gen_base_offset_addr(ctx
, t0
, rs
, shf_offset
);
4718 fp0
= tcg_temp_new_i32();
4719 gen_load_fpr32(ctx
, fp0
, rt
);
4720 tcg_gen_ext_i32_tl(t1
, fp0
);
4721 gen_helper_0e2i(swl
, t1
, t0
, ctx
->mem_idx
);
4722 tcg_temp_free_i32(fp0
);
4726 check_cp1_enabled(ctx
);
4727 t1
= tcg_temp_new();
4728 gen_base_offset_addr(ctx
, t0
, rs
, shf_offset
);
4729 fp0
= tcg_temp_new_i32();
4730 gen_load_fpr32(ctx
, fp0
, rt
);
4731 tcg_gen_ext_i32_tl(t1
, fp0
);
4732 gen_helper_0e2i(swr
, t1
, t0
, ctx
->mem_idx
);
4733 tcg_temp_free_i32(fp0
);
4736 #if defined(TARGET_MIPS64)
4738 check_cp1_enabled(ctx
);
4739 t1
= tcg_temp_new();
4740 gen_base_offset_addr(ctx
, t0
, rs
, shf_offset
);
4741 gen_load_fpr64(ctx
, t1
, rt
);
4742 gen_helper_0e2i(sdl
, t1
, t0
, ctx
->mem_idx
);
4746 check_cp1_enabled(ctx
);
4747 t1
= tcg_temp_new();
4748 gen_base_offset_addr(ctx
, t0
, rs
, shf_offset
);
4749 gen_load_fpr64(ctx
, t1
, rt
);
4750 gen_helper_0e2i(sdr
, t1
, t0
, ctx
->mem_idx
);
4755 MIPS_INVAL("loongson_gsshfs");
4756 gen_reserved_instruction(ctx
);
4761 MIPS_INVAL("loongson_gslsq");
4762 gen_reserved_instruction(ctx
);
4768 /* Loongson EXT LDC2/SDC2 */
4769 static void gen_loongson_lsdc2(DisasContext
*ctx
, int rt
,
4772 int offset
= sextract32(ctx
->opcode
, 3, 8);
4773 uint32_t opc
= MASK_LOONGSON_LSDC2(ctx
->opcode
);
4777 /* Pre-conditions */
4783 /* prefetch, implement as NOP */
4794 #if defined(TARGET_MIPS64)
4797 check_cp1_enabled(ctx
);
4798 /* prefetch, implement as NOP */
4804 #if defined(TARGET_MIPS64)
4807 check_cp1_enabled(ctx
);
4810 MIPS_INVAL("loongson_lsdc2");
4811 gen_reserved_instruction(ctx
);
4816 t0
= tcg_temp_new();
4818 gen_base_offset_addr(ctx
, t0
, rs
, offset
);
4819 gen_op_addr_add(ctx
, t0
, cpu_gpr
[rd
], t0
);
4823 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_SB
);
4824 gen_store_gpr(t0
, rt
);
4827 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESW
|
4828 ctx
->default_tcg_memop_mask
);
4829 gen_store_gpr(t0
, rt
);
4832 gen_base_offset_addr(ctx
, t0
, rs
, offset
);
4834 gen_op_addr_add(ctx
, t0
, cpu_gpr
[rd
], t0
);
4836 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESL
|
4837 ctx
->default_tcg_memop_mask
);
4838 gen_store_gpr(t0
, rt
);
4840 #if defined(TARGET_MIPS64)
4842 gen_base_offset_addr(ctx
, t0
, rs
, offset
);
4844 gen_op_addr_add(ctx
, t0
, cpu_gpr
[rd
], t0
);
4846 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
|
4847 ctx
->default_tcg_memop_mask
);
4848 gen_store_gpr(t0
, rt
);
4852 check_cp1_enabled(ctx
);
4853 gen_base_offset_addr(ctx
, t0
, rs
, offset
);
4855 gen_op_addr_add(ctx
, t0
, cpu_gpr
[rd
], t0
);
4857 fp0
= tcg_temp_new_i32();
4858 tcg_gen_qemu_ld_i32(fp0
, t0
, ctx
->mem_idx
, MO_TESL
|
4859 ctx
->default_tcg_memop_mask
);
4860 gen_store_fpr32(ctx
, fp0
, rt
);
4861 tcg_temp_free_i32(fp0
);
4863 #if defined(TARGET_MIPS64)
4865 check_cp1_enabled(ctx
);
4866 gen_base_offset_addr(ctx
, t0
, rs
, offset
);
4868 gen_op_addr_add(ctx
, t0
, cpu_gpr
[rd
], t0
);
4870 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
|
4871 ctx
->default_tcg_memop_mask
);
4872 gen_store_fpr64(ctx
, t0
, rt
);
4876 t1
= tcg_temp_new();
4877 gen_load_gpr(t1
, rt
);
4878 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_SB
);
4882 t1
= tcg_temp_new();
4883 gen_load_gpr(t1
, rt
);
4884 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUW
|
4885 ctx
->default_tcg_memop_mask
);
4889 t1
= tcg_temp_new();
4890 gen_load_gpr(t1
, rt
);
4891 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
|
4892 ctx
->default_tcg_memop_mask
);
4895 #if defined(TARGET_MIPS64)
4897 t1
= tcg_temp_new();
4898 gen_load_gpr(t1
, rt
);
4899 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
|
4900 ctx
->default_tcg_memop_mask
);
4905 fp0
= tcg_temp_new_i32();
4906 gen_load_fpr32(ctx
, fp0
, rt
);
4907 tcg_gen_qemu_st_i32(fp0
, t0
, ctx
->mem_idx
, MO_TEUL
|
4908 ctx
->default_tcg_memop_mask
);
4909 tcg_temp_free_i32(fp0
);
4911 #if defined(TARGET_MIPS64)
4913 t1
= tcg_temp_new();
4914 gen_load_fpr64(ctx
, t1
, rt
);
4915 tcg_gen_qemu_st_i64(t1
, t0
, ctx
->mem_idx
, MO_TEQ
|
4916 ctx
->default_tcg_memop_mask
);
4928 static void gen_trap(DisasContext
*ctx
, uint32_t opc
,
4929 int rs
, int rt
, int16_t imm
)
4932 TCGv t0
= tcg_temp_new();
4933 TCGv t1
= tcg_temp_new();
4936 /* Load needed operands */
4944 /* Compare two registers */
4946 gen_load_gpr(t0
, rs
);
4947 gen_load_gpr(t1
, rt
);
4957 /* Compare register to immediate */
4958 if (rs
!= 0 || imm
!= 0) {
4959 gen_load_gpr(t0
, rs
);
4960 tcg_gen_movi_tl(t1
, (int32_t)imm
);
4967 case OPC_TEQ
: /* rs == rs */
4968 case OPC_TEQI
: /* r0 == 0 */
4969 case OPC_TGE
: /* rs >= rs */
4970 case OPC_TGEI
: /* r0 >= 0 */
4971 case OPC_TGEU
: /* rs >= rs unsigned */
4972 case OPC_TGEIU
: /* r0 >= 0 unsigned */
4974 generate_exception_end(ctx
, EXCP_TRAP
);
4976 case OPC_TLT
: /* rs < rs */
4977 case OPC_TLTI
: /* r0 < 0 */
4978 case OPC_TLTU
: /* rs < rs unsigned */
4979 case OPC_TLTIU
: /* r0 < 0 unsigned */
4980 case OPC_TNE
: /* rs != rs */
4981 case OPC_TNEI
: /* r0 != 0 */
4982 /* Never trap: treat as NOP. */
4986 TCGLabel
*l1
= gen_new_label();
4991 tcg_gen_brcond_tl(TCG_COND_NE
, t0
, t1
, l1
);
4995 tcg_gen_brcond_tl(TCG_COND_LT
, t0
, t1
, l1
);
4999 tcg_gen_brcond_tl(TCG_COND_LTU
, t0
, t1
, l1
);
5003 tcg_gen_brcond_tl(TCG_COND_GE
, t0
, t1
, l1
);
5007 tcg_gen_brcond_tl(TCG_COND_GEU
, t0
, t1
, l1
);
5011 tcg_gen_brcond_tl(TCG_COND_EQ
, t0
, t1
, l1
);
5014 generate_exception(ctx
, EXCP_TRAP
);
5021 static inline bool use_goto_tb(DisasContext
*ctx
, target_ulong dest
)
5023 if (unlikely(ctx
->base
.singlestep_enabled
)) {
5027 #ifndef CONFIG_USER_ONLY
5028 return (ctx
->base
.tb
->pc
& TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
);
5034 static inline void gen_goto_tb(DisasContext
*ctx
, int n
, target_ulong dest
)
5036 if (use_goto_tb(ctx
, dest
)) {
5039 tcg_gen_exit_tb(ctx
->base
.tb
, n
);
5042 if (ctx
->base
.singlestep_enabled
) {
5043 save_cpu_state(ctx
, 0);
5044 gen_helper_raise_exception_debug(cpu_env
);
5046 tcg_gen_lookup_and_goto_ptr();
5050 /* Branches (before delay slot) */
5051 static void gen_compute_branch(DisasContext
*ctx
, uint32_t opc
,
5053 int rs
, int rt
, int32_t offset
,
5056 target_ulong btgt
= -1;
5058 int bcond_compute
= 0;
5059 TCGv t0
= tcg_temp_new();
5060 TCGv t1
= tcg_temp_new();
5062 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
5063 #ifdef MIPS_DEBUG_DISAS
5064 LOG_DISAS("Branch in delay / forbidden slot at PC 0x"
5065 TARGET_FMT_lx
"\n", ctx
->base
.pc_next
);
5067 gen_reserved_instruction(ctx
);
5071 /* Load needed operands */
5077 /* Compare two registers */
5079 gen_load_gpr(t0
, rs
);
5080 gen_load_gpr(t1
, rt
);
5083 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ offset
;
5097 /* Compare to zero */
5099 gen_load_gpr(t0
, rs
);
5102 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ offset
;
5105 #if defined(TARGET_MIPS64)
5107 tcg_gen_andi_tl(t0
, cpu_dspctrl
, 0x7F);
5109 tcg_gen_andi_tl(t0
, cpu_dspctrl
, 0x3F);
5112 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ offset
;
5117 /* Jump to immediate */
5118 btgt
= ((ctx
->base
.pc_next
+ insn_bytes
) & (int32_t)0xF0000000) |
5123 /* Jump to register */
5124 if (offset
!= 0 && offset
!= 16) {
5126 * Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
5127 * others are reserved.
5129 MIPS_INVAL("jump hint");
5130 gen_reserved_instruction(ctx
);
5133 gen_load_gpr(btarget
, rs
);
5136 MIPS_INVAL("branch/jump");
5137 gen_reserved_instruction(ctx
);
5140 if (bcond_compute
== 0) {
5141 /* No condition to be computed */
5143 case OPC_BEQ
: /* rx == rx */
5144 case OPC_BEQL
: /* rx == rx likely */
5145 case OPC_BGEZ
: /* 0 >= 0 */
5146 case OPC_BGEZL
: /* 0 >= 0 likely */
5147 case OPC_BLEZ
: /* 0 <= 0 */
5148 case OPC_BLEZL
: /* 0 <= 0 likely */
5150 ctx
->hflags
|= MIPS_HFLAG_B
;
5152 case OPC_BGEZAL
: /* 0 >= 0 */
5153 case OPC_BGEZALL
: /* 0 >= 0 likely */
5154 /* Always take and link */
5156 ctx
->hflags
|= MIPS_HFLAG_B
;
5158 case OPC_BNE
: /* rx != rx */
5159 case OPC_BGTZ
: /* 0 > 0 */
5160 case OPC_BLTZ
: /* 0 < 0 */
5163 case OPC_BLTZAL
: /* 0 < 0 */
5165 * Handle as an unconditional branch to get correct delay
5169 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ delayslot_size
;
5170 ctx
->hflags
|= MIPS_HFLAG_B
;
5172 case OPC_BLTZALL
: /* 0 < 0 likely */
5173 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 8);
5174 /* Skip the instruction in the delay slot */
5175 ctx
->base
.pc_next
+= 4;
5177 case OPC_BNEL
: /* rx != rx likely */
5178 case OPC_BGTZL
: /* 0 > 0 likely */
5179 case OPC_BLTZL
: /* 0 < 0 likely */
5180 /* Skip the instruction in the delay slot */
5181 ctx
->base
.pc_next
+= 4;
5184 ctx
->hflags
|= MIPS_HFLAG_B
;
5187 ctx
->hflags
|= MIPS_HFLAG_BX
;
5191 ctx
->hflags
|= MIPS_HFLAG_B
;
5194 ctx
->hflags
|= MIPS_HFLAG_BR
;
5198 ctx
->hflags
|= MIPS_HFLAG_BR
;
5201 MIPS_INVAL("branch/jump");
5202 gen_reserved_instruction(ctx
);
5208 tcg_gen_setcond_tl(TCG_COND_EQ
, bcond
, t0
, t1
);
5211 tcg_gen_setcond_tl(TCG_COND_EQ
, bcond
, t0
, t1
);
5214 tcg_gen_setcond_tl(TCG_COND_NE
, bcond
, t0
, t1
);
5217 tcg_gen_setcond_tl(TCG_COND_NE
, bcond
, t0
, t1
);
5220 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
5223 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
5226 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
5230 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
5234 tcg_gen_setcondi_tl(TCG_COND_GT
, bcond
, t0
, 0);
5237 tcg_gen_setcondi_tl(TCG_COND_GT
, bcond
, t0
, 0);
5240 tcg_gen_setcondi_tl(TCG_COND_LE
, bcond
, t0
, 0);
5243 tcg_gen_setcondi_tl(TCG_COND_LE
, bcond
, t0
, 0);
5246 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
5249 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
5252 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 32);
5254 #if defined(TARGET_MIPS64)
5256 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 64);
5260 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
5263 ctx
->hflags
|= MIPS_HFLAG_BC
;
5266 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
5269 ctx
->hflags
|= MIPS_HFLAG_BL
;
5272 MIPS_INVAL("conditional branch/jump");
5273 gen_reserved_instruction(ctx
);
5278 ctx
->btarget
= btgt
;
5280 switch (delayslot_size
) {
5282 ctx
->hflags
|= MIPS_HFLAG_BDS16
;
5285 ctx
->hflags
|= MIPS_HFLAG_BDS32
;
5290 int post_delay
= insn_bytes
+ delayslot_size
;
5291 int lowbit
= !!(ctx
->hflags
& MIPS_HFLAG_M16
);
5293 tcg_gen_movi_tl(cpu_gpr
[blink
],
5294 ctx
->base
.pc_next
+ post_delay
+ lowbit
);
5298 if (insn_bytes
== 2) {
5299 ctx
->hflags
|= MIPS_HFLAG_B16
;
5306 /* nanoMIPS Branches */
5307 static void gen_compute_branch_nm(DisasContext
*ctx
, uint32_t opc
,
5309 int rs
, int rt
, int32_t offset
)
5311 target_ulong btgt
= -1;
5312 int bcond_compute
= 0;
5313 TCGv t0
= tcg_temp_new();
5314 TCGv t1
= tcg_temp_new();
5316 /* Load needed operands */
5320 /* Compare two registers */
5322 gen_load_gpr(t0
, rs
);
5323 gen_load_gpr(t1
, rt
);
5326 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ offset
;
5329 /* Compare to zero */
5331 gen_load_gpr(t0
, rs
);
5334 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ offset
;
5337 tcg_gen_andi_tl(t0
, cpu_dspctrl
, 0x3F);
5339 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ offset
;
5343 /* Jump to register */
5344 if (offset
!= 0 && offset
!= 16) {
5346 * Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
5347 * others are reserved.
5349 MIPS_INVAL("jump hint");
5350 gen_reserved_instruction(ctx
);
5353 gen_load_gpr(btarget
, rs
);
5356 MIPS_INVAL("branch/jump");
5357 gen_reserved_instruction(ctx
);
5360 if (bcond_compute
== 0) {
5361 /* No condition to be computed */
5363 case OPC_BEQ
: /* rx == rx */
5365 ctx
->hflags
|= MIPS_HFLAG_B
;
5367 case OPC_BGEZAL
: /* 0 >= 0 */
5368 /* Always take and link */
5369 tcg_gen_movi_tl(cpu_gpr
[31],
5370 ctx
->base
.pc_next
+ insn_bytes
);
5371 ctx
->hflags
|= MIPS_HFLAG_B
;
5373 case OPC_BNE
: /* rx != rx */
5374 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 8);
5375 /* Skip the instruction in the delay slot */
5376 ctx
->base
.pc_next
+= 4;
5379 ctx
->hflags
|= MIPS_HFLAG_BR
;
5383 tcg_gen_movi_tl(cpu_gpr
[rt
],
5384 ctx
->base
.pc_next
+ insn_bytes
);
5386 ctx
->hflags
|= MIPS_HFLAG_BR
;
5389 MIPS_INVAL("branch/jump");
5390 gen_reserved_instruction(ctx
);
5396 tcg_gen_setcond_tl(TCG_COND_EQ
, bcond
, t0
, t1
);
5399 tcg_gen_setcond_tl(TCG_COND_NE
, bcond
, t0
, t1
);
5402 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
5403 tcg_gen_movi_tl(cpu_gpr
[31],
5404 ctx
->base
.pc_next
+ insn_bytes
);
5407 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 32);
5409 ctx
->hflags
|= MIPS_HFLAG_BC
;
5412 MIPS_INVAL("conditional branch/jump");
5413 gen_reserved_instruction(ctx
);
5418 ctx
->btarget
= btgt
;
5421 if (insn_bytes
== 2) {
5422 ctx
->hflags
|= MIPS_HFLAG_B16
;
5429 /* special3 bitfield operations */
5430 static void gen_bitops(DisasContext
*ctx
, uint32_t opc
, int rt
,
5431 int rs
, int lsb
, int msb
)
5433 TCGv t0
= tcg_temp_new();
5434 TCGv t1
= tcg_temp_new();
5436 gen_load_gpr(t1
, rs
);
5439 if (lsb
+ msb
> 31) {
5443 tcg_gen_extract_tl(t0
, t1
, lsb
, msb
+ 1);
5446 * The two checks together imply that lsb == 0,
5447 * so this is a simple sign-extension.
5449 tcg_gen_ext32s_tl(t0
, t1
);
5452 #if defined(TARGET_MIPS64)
5461 if (lsb
+ msb
> 63) {
5464 tcg_gen_extract_tl(t0
, t1
, lsb
, msb
+ 1);
5471 gen_load_gpr(t0
, rt
);
5472 tcg_gen_deposit_tl(t0
, t0
, t1
, lsb
, msb
- lsb
+ 1);
5473 tcg_gen_ext32s_tl(t0
, t0
);
5475 #if defined(TARGET_MIPS64)
5486 gen_load_gpr(t0
, rt
);
5487 tcg_gen_deposit_tl(t0
, t0
, t1
, lsb
, msb
- lsb
+ 1);
5492 MIPS_INVAL("bitops");
5493 gen_reserved_instruction(ctx
);
5498 gen_store_gpr(t0
, rt
);
5503 static void gen_bshfl(DisasContext
*ctx
, uint32_t op2
, int rt
, int rd
)
5508 /* If no destination, treat it as a NOP. */
5512 t0
= tcg_temp_new();
5513 gen_load_gpr(t0
, rt
);
5517 TCGv t1
= tcg_temp_new();
5518 TCGv t2
= tcg_const_tl(0x00FF00FF);
5520 tcg_gen_shri_tl(t1
, t0
, 8);
5521 tcg_gen_and_tl(t1
, t1
, t2
);
5522 tcg_gen_and_tl(t0
, t0
, t2
);
5523 tcg_gen_shli_tl(t0
, t0
, 8);
5524 tcg_gen_or_tl(t0
, t0
, t1
);
5527 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
5531 tcg_gen_ext8s_tl(cpu_gpr
[rd
], t0
);
5534 tcg_gen_ext16s_tl(cpu_gpr
[rd
], t0
);
5536 #if defined(TARGET_MIPS64)
5539 TCGv t1
= tcg_temp_new();
5540 TCGv t2
= tcg_const_tl(0x00FF00FF00FF00FFULL
);
5542 tcg_gen_shri_tl(t1
, t0
, 8);
5543 tcg_gen_and_tl(t1
, t1
, t2
);
5544 tcg_gen_and_tl(t0
, t0
, t2
);
5545 tcg_gen_shli_tl(t0
, t0
, 8);
5546 tcg_gen_or_tl(cpu_gpr
[rd
], t0
, t1
);
5553 TCGv t1
= tcg_temp_new();
5554 TCGv t2
= tcg_const_tl(0x0000FFFF0000FFFFULL
);
5556 tcg_gen_shri_tl(t1
, t0
, 16);
5557 tcg_gen_and_tl(t1
, t1
, t2
);
5558 tcg_gen_and_tl(t0
, t0
, t2
);
5559 tcg_gen_shli_tl(t0
, t0
, 16);
5560 tcg_gen_or_tl(t0
, t0
, t1
);
5561 tcg_gen_shri_tl(t1
, t0
, 32);
5562 tcg_gen_shli_tl(t0
, t0
, 32);
5563 tcg_gen_or_tl(cpu_gpr
[rd
], t0
, t1
);
5570 MIPS_INVAL("bsfhl");
5571 gen_reserved_instruction(ctx
);
5578 static void gen_align_bits(DisasContext
*ctx
, int wordsz
, int rd
, int rs
,
5586 t0
= tcg_temp_new();
5587 if (bits
== 0 || bits
== wordsz
) {
5589 gen_load_gpr(t0
, rt
);
5591 gen_load_gpr(t0
, rs
);
5595 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
5597 #if defined(TARGET_MIPS64)
5599 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
5604 TCGv t1
= tcg_temp_new();
5605 gen_load_gpr(t0
, rt
);
5606 gen_load_gpr(t1
, rs
);
5610 TCGv_i64 t2
= tcg_temp_new_i64();
5611 tcg_gen_concat_tl_i64(t2
, t1
, t0
);
5612 tcg_gen_shri_i64(t2
, t2
, 32 - bits
);
5613 gen_move_low32(cpu_gpr
[rd
], t2
);
5614 tcg_temp_free_i64(t2
);
5617 #if defined(TARGET_MIPS64)
5619 tcg_gen_shli_tl(t0
, t0
, bits
);
5620 tcg_gen_shri_tl(t1
, t1
, 64 - bits
);
5621 tcg_gen_or_tl(cpu_gpr
[rd
], t1
, t0
);
5631 static void gen_align(DisasContext
*ctx
, int wordsz
, int rd
, int rs
, int rt
,
5634 gen_align_bits(ctx
, wordsz
, rd
, rs
, rt
, bp
* 8);
5637 static void gen_ext(DisasContext
*ctx
, int wordsz
, int rd
, int rs
, int rt
,
5640 gen_align_bits(ctx
, wordsz
, rd
, rs
, rt
, wordsz
- shift
);
5643 static void gen_bitswap(DisasContext
*ctx
, int opc
, int rd
, int rt
)
5650 t0
= tcg_temp_new();
5651 gen_load_gpr(t0
, rt
);
5654 gen_helper_bitswap(cpu_gpr
[rd
], t0
);
5656 #if defined(TARGET_MIPS64)
5658 gen_helper_dbitswap(cpu_gpr
[rd
], t0
);
5665 #ifndef CONFIG_USER_ONLY
5666 /* CP0 (MMU and control) */
5667 static inline void gen_mthc0_entrylo(TCGv arg
, target_ulong off
)
5669 TCGv_i64 t0
= tcg_temp_new_i64();
5670 TCGv_i64 t1
= tcg_temp_new_i64();
5672 tcg_gen_ext_tl_i64(t0
, arg
);
5673 tcg_gen_ld_i64(t1
, cpu_env
, off
);
5674 #if defined(TARGET_MIPS64)
5675 tcg_gen_deposit_i64(t1
, t1
, t0
, 30, 32);
5677 tcg_gen_concat32_i64(t1
, t1
, t0
);
5679 tcg_gen_st_i64(t1
, cpu_env
, off
);
5680 tcg_temp_free_i64(t1
);
5681 tcg_temp_free_i64(t0
);
5684 static inline void gen_mthc0_store64(TCGv arg
, target_ulong off
)
5686 TCGv_i64 t0
= tcg_temp_new_i64();
5687 TCGv_i64 t1
= tcg_temp_new_i64();
5689 tcg_gen_ext_tl_i64(t0
, arg
);
5690 tcg_gen_ld_i64(t1
, cpu_env
, off
);
5691 tcg_gen_concat32_i64(t1
, t1
, t0
);
5692 tcg_gen_st_i64(t1
, cpu_env
, off
);
5693 tcg_temp_free_i64(t1
);
5694 tcg_temp_free_i64(t0
);
5697 static inline void gen_mfhc0_entrylo(TCGv arg
, target_ulong off
)
5699 TCGv_i64 t0
= tcg_temp_new_i64();
5701 tcg_gen_ld_i64(t0
, cpu_env
, off
);
5702 #if defined(TARGET_MIPS64)
5703 tcg_gen_shri_i64(t0
, t0
, 30);
5705 tcg_gen_shri_i64(t0
, t0
, 32);
5707 gen_move_low32(arg
, t0
);
5708 tcg_temp_free_i64(t0
);
5711 static inline void gen_mfhc0_load64(TCGv arg
, target_ulong off
, int shift
)
5713 TCGv_i64 t0
= tcg_temp_new_i64();
5715 tcg_gen_ld_i64(t0
, cpu_env
, off
);
5716 tcg_gen_shri_i64(t0
, t0
, 32 + shift
);
5717 gen_move_low32(arg
, t0
);
5718 tcg_temp_free_i64(t0
);
5721 static inline void gen_mfc0_load32(TCGv arg
, target_ulong off
)
5723 TCGv_i32 t0
= tcg_temp_new_i32();
5725 tcg_gen_ld_i32(t0
, cpu_env
, off
);
5726 tcg_gen_ext_i32_tl(arg
, t0
);
5727 tcg_temp_free_i32(t0
);
5730 static inline void gen_mfc0_load64(TCGv arg
, target_ulong off
)
5732 tcg_gen_ld_tl(arg
, cpu_env
, off
);
5733 tcg_gen_ext32s_tl(arg
, arg
);
5736 static inline void gen_mtc0_store32(TCGv arg
, target_ulong off
)
5738 TCGv_i32 t0
= tcg_temp_new_i32();
5740 tcg_gen_trunc_tl_i32(t0
, arg
);
5741 tcg_gen_st_i32(t0
, cpu_env
, off
);
5742 tcg_temp_free_i32(t0
);
5745 #define CP0_CHECK(c) \
5748 goto cp0_unimplemented; \
5752 static void gen_mfhc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
5754 const char *register_name
= "invalid";
5757 case CP0_REGISTER_02
:
5760 CP0_CHECK(ctx
->hflags
& MIPS_HFLAG_ELPA
);
5761 gen_mfhc0_entrylo(arg
, offsetof(CPUMIPSState
, CP0_EntryLo0
));
5762 register_name
= "EntryLo0";
5765 goto cp0_unimplemented
;
5768 case CP0_REGISTER_03
:
5770 case CP0_REG03__ENTRYLO1
:
5771 CP0_CHECK(ctx
->hflags
& MIPS_HFLAG_ELPA
);
5772 gen_mfhc0_entrylo(arg
, offsetof(CPUMIPSState
, CP0_EntryLo1
));
5773 register_name
= "EntryLo1";
5776 goto cp0_unimplemented
;
5779 case CP0_REGISTER_09
:
5781 case CP0_REG09__SAAR
:
5782 CP0_CHECK(ctx
->saar
);
5783 gen_helper_mfhc0_saar(arg
, cpu_env
);
5784 register_name
= "SAAR";
5787 goto cp0_unimplemented
;
5790 case CP0_REGISTER_17
:
5792 case CP0_REG17__LLADDR
:
5793 gen_mfhc0_load64(arg
, offsetof(CPUMIPSState
, CP0_LLAddr
),
5794 ctx
->CP0_LLAddr_shift
);
5795 register_name
= "LLAddr";
5797 case CP0_REG17__MAAR
:
5798 CP0_CHECK(ctx
->mrp
);
5799 gen_helper_mfhc0_maar(arg
, cpu_env
);
5800 register_name
= "MAAR";
5803 goto cp0_unimplemented
;
5806 case CP0_REGISTER_19
:
5808 case CP0_REG19__WATCHHI0
:
5809 case CP0_REG19__WATCHHI1
:
5810 case CP0_REG19__WATCHHI2
:
5811 case CP0_REG19__WATCHHI3
:
5812 case CP0_REG19__WATCHHI4
:
5813 case CP0_REG19__WATCHHI5
:
5814 case CP0_REG19__WATCHHI6
:
5815 case CP0_REG19__WATCHHI7
:
5816 /* upper 32 bits are only available when Config5MI != 0 */
5818 gen_mfhc0_load64(arg
, offsetof(CPUMIPSState
, CP0_WatchHi
[sel
]), 0);
5819 register_name
= "WatchHi";
5822 goto cp0_unimplemented
;
5825 case CP0_REGISTER_28
:
5831 gen_mfhc0_load64(arg
, offsetof(CPUMIPSState
, CP0_TagLo
), 0);
5832 register_name
= "TagLo";
5835 goto cp0_unimplemented
;
5839 goto cp0_unimplemented
;
5841 trace_mips_translate_c0("mfhc0", register_name
, reg
, sel
);
5845 qemu_log_mask(LOG_UNIMP
, "mfhc0 %s (reg %d sel %d)\n",
5846 register_name
, reg
, sel
);
5847 tcg_gen_movi_tl(arg
, 0);
5850 static void gen_mthc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
5852 const char *register_name
= "invalid";
5853 uint64_t mask
= ctx
->PAMask
>> 36;
5856 case CP0_REGISTER_02
:
5859 CP0_CHECK(ctx
->hflags
& MIPS_HFLAG_ELPA
);
5860 tcg_gen_andi_tl(arg
, arg
, mask
);
5861 gen_mthc0_entrylo(arg
, offsetof(CPUMIPSState
, CP0_EntryLo0
));
5862 register_name
= "EntryLo0";
5865 goto cp0_unimplemented
;
5868 case CP0_REGISTER_03
:
5870 case CP0_REG03__ENTRYLO1
:
5871 CP0_CHECK(ctx
->hflags
& MIPS_HFLAG_ELPA
);
5872 tcg_gen_andi_tl(arg
, arg
, mask
);
5873 gen_mthc0_entrylo(arg
, offsetof(CPUMIPSState
, CP0_EntryLo1
));
5874 register_name
= "EntryLo1";
5877 goto cp0_unimplemented
;
5880 case CP0_REGISTER_09
:
5882 case CP0_REG09__SAAR
:
5883 CP0_CHECK(ctx
->saar
);
5884 gen_helper_mthc0_saar(cpu_env
, arg
);
5885 register_name
= "SAAR";
5888 goto cp0_unimplemented
;
5891 case CP0_REGISTER_17
:
5893 case CP0_REG17__LLADDR
:
5895 * LLAddr is read-only (the only exception is bit 0 if LLB is
5896 * supported); the CP0_LLAddr_rw_bitmask does not seem to be
5897 * relevant for modern MIPS cores supporting MTHC0, therefore
5898 * treating MTHC0 to LLAddr as NOP.
5900 register_name
= "LLAddr";
5902 case CP0_REG17__MAAR
:
5903 CP0_CHECK(ctx
->mrp
);
5904 gen_helper_mthc0_maar(cpu_env
, arg
);
5905 register_name
= "MAAR";
5908 goto cp0_unimplemented
;
5911 case CP0_REGISTER_19
:
5913 case CP0_REG19__WATCHHI0
:
5914 case CP0_REG19__WATCHHI1
:
5915 case CP0_REG19__WATCHHI2
:
5916 case CP0_REG19__WATCHHI3
:
5917 case CP0_REG19__WATCHHI4
:
5918 case CP0_REG19__WATCHHI5
:
5919 case CP0_REG19__WATCHHI6
:
5920 case CP0_REG19__WATCHHI7
:
5921 /* upper 32 bits are only available when Config5MI != 0 */
5923 gen_helper_0e1i(mthc0_watchhi
, arg
, sel
);
5924 register_name
= "WatchHi";
5927 goto cp0_unimplemented
;
5930 case CP0_REGISTER_28
:
5936 tcg_gen_andi_tl(arg
, arg
, mask
);
5937 gen_mthc0_store64(arg
, offsetof(CPUMIPSState
, CP0_TagLo
));
5938 register_name
= "TagLo";
5941 goto cp0_unimplemented
;
5945 goto cp0_unimplemented
;
5947 trace_mips_translate_c0("mthc0", register_name
, reg
, sel
);
5950 qemu_log_mask(LOG_UNIMP
, "mthc0 %s (reg %d sel %d)\n",
5951 register_name
, reg
, sel
);
5954 static inline void gen_mfc0_unimplemented(DisasContext
*ctx
, TCGv arg
)
5956 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
5957 tcg_gen_movi_tl(arg
, 0);
5959 tcg_gen_movi_tl(arg
, ~0);
5963 static void gen_mfc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
5965 const char *register_name
= "invalid";
5968 check_insn(ctx
, ISA_MIPS_R1
);
5972 case CP0_REGISTER_00
:
5974 case CP0_REG00__INDEX
:
5975 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Index
));
5976 register_name
= "Index";
5978 case CP0_REG00__MVPCONTROL
:
5979 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5980 gen_helper_mfc0_mvpcontrol(arg
, cpu_env
);
5981 register_name
= "MVPControl";
5983 case CP0_REG00__MVPCONF0
:
5984 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5985 gen_helper_mfc0_mvpconf0(arg
, cpu_env
);
5986 register_name
= "MVPConf0";
5988 case CP0_REG00__MVPCONF1
:
5989 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5990 gen_helper_mfc0_mvpconf1(arg
, cpu_env
);
5991 register_name
= "MVPConf1";
5993 case CP0_REG00__VPCONTROL
:
5995 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPControl
));
5996 register_name
= "VPControl";
5999 goto cp0_unimplemented
;
6002 case CP0_REGISTER_01
:
6004 case CP0_REG01__RANDOM
:
6005 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS_R6
));
6006 gen_helper_mfc0_random(arg
, cpu_env
);
6007 register_name
= "Random";
6009 case CP0_REG01__VPECONTROL
:
6010 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6011 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEControl
));
6012 register_name
= "VPEControl";
6014 case CP0_REG01__VPECONF0
:
6015 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6016 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf0
));
6017 register_name
= "VPEConf0";
6019 case CP0_REG01__VPECONF1
:
6020 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6021 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf1
));
6022 register_name
= "VPEConf1";
6024 case CP0_REG01__YQMASK
:
6025 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6026 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_YQMask
));
6027 register_name
= "YQMask";
6029 case CP0_REG01__VPESCHEDULE
:
6030 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6031 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_VPESchedule
));
6032 register_name
= "VPESchedule";
6034 case CP0_REG01__VPESCHEFBACK
:
6035 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6036 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
6037 register_name
= "VPEScheFBack";
6039 case CP0_REG01__VPEOPT
:
6040 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6041 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEOpt
));
6042 register_name
= "VPEOpt";
6045 goto cp0_unimplemented
;
6048 case CP0_REGISTER_02
:
6050 case CP0_REG02__ENTRYLO0
:
6052 TCGv_i64 tmp
= tcg_temp_new_i64();
6053 tcg_gen_ld_i64(tmp
, cpu_env
,
6054 offsetof(CPUMIPSState
, CP0_EntryLo0
));
6055 #if defined(TARGET_MIPS64)
6057 /* Move RI/XI fields to bits 31:30 */
6058 tcg_gen_shri_tl(arg
, tmp
, CP0EnLo_XI
);
6059 tcg_gen_deposit_tl(tmp
, tmp
, arg
, 30, 2);
6062 gen_move_low32(arg
, tmp
);
6063 tcg_temp_free_i64(tmp
);
6065 register_name
= "EntryLo0";
6067 case CP0_REG02__TCSTATUS
:
6068 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6069 gen_helper_mfc0_tcstatus(arg
, cpu_env
);
6070 register_name
= "TCStatus";
6072 case CP0_REG02__TCBIND
:
6073 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6074 gen_helper_mfc0_tcbind(arg
, cpu_env
);
6075 register_name
= "TCBind";
6077 case CP0_REG02__TCRESTART
:
6078 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6079 gen_helper_mfc0_tcrestart(arg
, cpu_env
);
6080 register_name
= "TCRestart";
6082 case CP0_REG02__TCHALT
:
6083 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6084 gen_helper_mfc0_tchalt(arg
, cpu_env
);
6085 register_name
= "TCHalt";
6087 case CP0_REG02__TCCONTEXT
:
6088 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6089 gen_helper_mfc0_tccontext(arg
, cpu_env
);
6090 register_name
= "TCContext";
6092 case CP0_REG02__TCSCHEDULE
:
6093 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6094 gen_helper_mfc0_tcschedule(arg
, cpu_env
);
6095 register_name
= "TCSchedule";
6097 case CP0_REG02__TCSCHEFBACK
:
6098 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6099 gen_helper_mfc0_tcschefback(arg
, cpu_env
);
6100 register_name
= "TCScheFBack";
6103 goto cp0_unimplemented
;
6106 case CP0_REGISTER_03
:
6108 case CP0_REG03__ENTRYLO1
:
6110 TCGv_i64 tmp
= tcg_temp_new_i64();
6111 tcg_gen_ld_i64(tmp
, cpu_env
,
6112 offsetof(CPUMIPSState
, CP0_EntryLo1
));
6113 #if defined(TARGET_MIPS64)
6115 /* Move RI/XI fields to bits 31:30 */
6116 tcg_gen_shri_tl(arg
, tmp
, CP0EnLo_XI
);
6117 tcg_gen_deposit_tl(tmp
, tmp
, arg
, 30, 2);
6120 gen_move_low32(arg
, tmp
);
6121 tcg_temp_free_i64(tmp
);
6123 register_name
= "EntryLo1";
6125 case CP0_REG03__GLOBALNUM
:
6127 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_GlobalNumber
));
6128 register_name
= "GlobalNumber";
6131 goto cp0_unimplemented
;
6134 case CP0_REGISTER_04
:
6136 case CP0_REG04__CONTEXT
:
6137 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_Context
));
6138 tcg_gen_ext32s_tl(arg
, arg
);
6139 register_name
= "Context";
6141 case CP0_REG04__CONTEXTCONFIG
:
6143 /* gen_helper_mfc0_contextconfig(arg); */
6144 register_name
= "ContextConfig";
6145 goto cp0_unimplemented
;
6146 case CP0_REG04__USERLOCAL
:
6147 CP0_CHECK(ctx
->ulri
);
6148 tcg_gen_ld_tl(arg
, cpu_env
,
6149 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
6150 tcg_gen_ext32s_tl(arg
, arg
);
6151 register_name
= "UserLocal";
6153 case CP0_REG04__MMID
:
6155 gen_helper_mtc0_memorymapid(cpu_env
, arg
);
6156 register_name
= "MMID";
6159 goto cp0_unimplemented
;
6162 case CP0_REGISTER_05
:
6164 case CP0_REG05__PAGEMASK
:
6165 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageMask
));
6166 register_name
= "PageMask";
6168 case CP0_REG05__PAGEGRAIN
:
6169 check_insn(ctx
, ISA_MIPS_R2
);
6170 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageGrain
));
6171 register_name
= "PageGrain";
6173 case CP0_REG05__SEGCTL0
:
6175 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_SegCtl0
));
6176 tcg_gen_ext32s_tl(arg
, arg
);
6177 register_name
= "SegCtl0";
6179 case CP0_REG05__SEGCTL1
:
6181 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_SegCtl1
));
6182 tcg_gen_ext32s_tl(arg
, arg
);
6183 register_name
= "SegCtl1";
6185 case CP0_REG05__SEGCTL2
:
6187 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_SegCtl2
));
6188 tcg_gen_ext32s_tl(arg
, arg
);
6189 register_name
= "SegCtl2";
6191 case CP0_REG05__PWBASE
:
6193 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PWBase
));
6194 register_name
= "PWBase";
6196 case CP0_REG05__PWFIELD
:
6198 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PWField
));
6199 register_name
= "PWField";
6201 case CP0_REG05__PWSIZE
:
6203 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PWSize
));
6204 register_name
= "PWSize";
6207 goto cp0_unimplemented
;
6210 case CP0_REGISTER_06
:
6212 case CP0_REG06__WIRED
:
6213 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Wired
));
6214 register_name
= "Wired";
6216 case CP0_REG06__SRSCONF0
:
6217 check_insn(ctx
, ISA_MIPS_R2
);
6218 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf0
));
6219 register_name
= "SRSConf0";
6221 case CP0_REG06__SRSCONF1
:
6222 check_insn(ctx
, ISA_MIPS_R2
);
6223 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf1
));
6224 register_name
= "SRSConf1";
6226 case CP0_REG06__SRSCONF2
:
6227 check_insn(ctx
, ISA_MIPS_R2
);
6228 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf2
));
6229 register_name
= "SRSConf2";
6231 case CP0_REG06__SRSCONF3
:
6232 check_insn(ctx
, ISA_MIPS_R2
);
6233 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf3
));
6234 register_name
= "SRSConf3";
6236 case CP0_REG06__SRSCONF4
:
6237 check_insn(ctx
, ISA_MIPS_R2
);
6238 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf4
));
6239 register_name
= "SRSConf4";
6241 case CP0_REG06__PWCTL
:
6243 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PWCtl
));
6244 register_name
= "PWCtl";
6247 goto cp0_unimplemented
;
6250 case CP0_REGISTER_07
:
6252 case CP0_REG07__HWRENA
:
6253 check_insn(ctx
, ISA_MIPS_R2
);
6254 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_HWREna
));
6255 register_name
= "HWREna";
6258 goto cp0_unimplemented
;
6261 case CP0_REGISTER_08
:
6263 case CP0_REG08__BADVADDR
:
6264 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_BadVAddr
));
6265 tcg_gen_ext32s_tl(arg
, arg
);
6266 register_name
= "BadVAddr";
6268 case CP0_REG08__BADINSTR
:
6270 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstr
));
6271 register_name
= "BadInstr";
6273 case CP0_REG08__BADINSTRP
:
6275 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstrP
));
6276 register_name
= "BadInstrP";
6278 case CP0_REG08__BADINSTRX
:
6280 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstrX
));
6281 tcg_gen_andi_tl(arg
, arg
, ~0xffff);
6282 register_name
= "BadInstrX";
6285 goto cp0_unimplemented
;
6288 case CP0_REGISTER_09
:
6290 case CP0_REG09__COUNT
:
6291 /* Mark as an IO operation because we read the time. */
6292 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
6295 gen_helper_mfc0_count(arg
, cpu_env
);
6297 * Break the TB to be able to take timer interrupts immediately
6298 * after reading count. DISAS_STOP isn't sufficient, we need to
6299 * ensure we break completely out of translated code.
6301 gen_save_pc(ctx
->base
.pc_next
+ 4);
6302 ctx
->base
.is_jmp
= DISAS_EXIT
;
6303 register_name
= "Count";
6305 case CP0_REG09__SAARI
:
6306 CP0_CHECK(ctx
->saar
);
6307 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SAARI
));
6308 register_name
= "SAARI";
6310 case CP0_REG09__SAAR
:
6311 CP0_CHECK(ctx
->saar
);
6312 gen_helper_mfc0_saar(arg
, cpu_env
);
6313 register_name
= "SAAR";
6316 goto cp0_unimplemented
;
6319 case CP0_REGISTER_10
:
6321 case CP0_REG10__ENTRYHI
:
6322 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryHi
));
6323 tcg_gen_ext32s_tl(arg
, arg
);
6324 register_name
= "EntryHi";
6327 goto cp0_unimplemented
;
6330 case CP0_REGISTER_11
:
6332 case CP0_REG11__COMPARE
:
6333 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Compare
));
6334 register_name
= "Compare";
6336 /* 6,7 are implementation dependent */
6338 goto cp0_unimplemented
;
6341 case CP0_REGISTER_12
:
6343 case CP0_REG12__STATUS
:
6344 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Status
));
6345 register_name
= "Status";
6347 case CP0_REG12__INTCTL
:
6348 check_insn(ctx
, ISA_MIPS_R2
);
6349 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_IntCtl
));
6350 register_name
= "IntCtl";
6352 case CP0_REG12__SRSCTL
:
6353 check_insn(ctx
, ISA_MIPS_R2
);
6354 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
6355 register_name
= "SRSCtl";
6357 case CP0_REG12__SRSMAP
:
6358 check_insn(ctx
, ISA_MIPS_R2
);
6359 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
6360 register_name
= "SRSMap";
6363 goto cp0_unimplemented
;
6366 case CP0_REGISTER_13
:
6368 case CP0_REG13__CAUSE
:
6369 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Cause
));
6370 register_name
= "Cause";
6373 goto cp0_unimplemented
;
6376 case CP0_REGISTER_14
:
6378 case CP0_REG14__EPC
:
6379 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
6380 tcg_gen_ext32s_tl(arg
, arg
);
6381 register_name
= "EPC";
6384 goto cp0_unimplemented
;
6387 case CP0_REGISTER_15
:
6389 case CP0_REG15__PRID
:
6390 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PRid
));
6391 register_name
= "PRid";
6393 case CP0_REG15__EBASE
:
6394 check_insn(ctx
, ISA_MIPS_R2
);
6395 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EBase
));
6396 tcg_gen_ext32s_tl(arg
, arg
);
6397 register_name
= "EBase";
6399 case CP0_REG15__CMGCRBASE
:
6400 check_insn(ctx
, ISA_MIPS_R2
);
6401 CP0_CHECK(ctx
->cmgcr
);
6402 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_CMGCRBase
));
6403 tcg_gen_ext32s_tl(arg
, arg
);
6404 register_name
= "CMGCRBase";
6407 goto cp0_unimplemented
;
6410 case CP0_REGISTER_16
:
6412 case CP0_REG16__CONFIG
:
6413 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config0
));
6414 register_name
= "Config";
6416 case CP0_REG16__CONFIG1
:
6417 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config1
));
6418 register_name
= "Config1";
6420 case CP0_REG16__CONFIG2
:
6421 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config2
));
6422 register_name
= "Config2";
6424 case CP0_REG16__CONFIG3
:
6425 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config3
));
6426 register_name
= "Config3";
6428 case CP0_REG16__CONFIG4
:
6429 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config4
));
6430 register_name
= "Config4";
6432 case CP0_REG16__CONFIG5
:
6433 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config5
));
6434 register_name
= "Config5";
6436 /* 6,7 are implementation dependent */
6437 case CP0_REG16__CONFIG6
:
6438 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config6
));
6439 register_name
= "Config6";
6441 case CP0_REG16__CONFIG7
:
6442 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config7
));
6443 register_name
= "Config7";
6446 goto cp0_unimplemented
;
6449 case CP0_REGISTER_17
:
6451 case CP0_REG17__LLADDR
:
6452 gen_helper_mfc0_lladdr(arg
, cpu_env
);
6453 register_name
= "LLAddr";
6455 case CP0_REG17__MAAR
:
6456 CP0_CHECK(ctx
->mrp
);
6457 gen_helper_mfc0_maar(arg
, cpu_env
);
6458 register_name
= "MAAR";
6460 case CP0_REG17__MAARI
:
6461 CP0_CHECK(ctx
->mrp
);
6462 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_MAARI
));
6463 register_name
= "MAARI";
6466 goto cp0_unimplemented
;
6469 case CP0_REGISTER_18
:
6471 case CP0_REG18__WATCHLO0
:
6472 case CP0_REG18__WATCHLO1
:
6473 case CP0_REG18__WATCHLO2
:
6474 case CP0_REG18__WATCHLO3
:
6475 case CP0_REG18__WATCHLO4
:
6476 case CP0_REG18__WATCHLO5
:
6477 case CP0_REG18__WATCHLO6
:
6478 case CP0_REG18__WATCHLO7
:
6479 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
6480 gen_helper_1e0i(mfc0_watchlo
, arg
, sel
);
6481 register_name
= "WatchLo";
6484 goto cp0_unimplemented
;
6487 case CP0_REGISTER_19
:
6489 case CP0_REG19__WATCHHI0
:
6490 case CP0_REG19__WATCHHI1
:
6491 case CP0_REG19__WATCHHI2
:
6492 case CP0_REG19__WATCHHI3
:
6493 case CP0_REG19__WATCHHI4
:
6494 case CP0_REG19__WATCHHI5
:
6495 case CP0_REG19__WATCHHI6
:
6496 case CP0_REG19__WATCHHI7
:
6497 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
6498 gen_helper_1e0i(mfc0_watchhi
, arg
, sel
);
6499 register_name
= "WatchHi";
6502 goto cp0_unimplemented
;
6505 case CP0_REGISTER_20
:
6507 case CP0_REG20__XCONTEXT
:
6508 #if defined(TARGET_MIPS64)
6509 check_insn(ctx
, ISA_MIPS3
);
6510 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_XContext
));
6511 tcg_gen_ext32s_tl(arg
, arg
);
6512 register_name
= "XContext";
6516 goto cp0_unimplemented
;
6519 case CP0_REGISTER_21
:
6520 /* Officially reserved, but sel 0 is used for R1x000 framemask */
6521 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS_R6
));
6524 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Framemask
));
6525 register_name
= "Framemask";
6528 goto cp0_unimplemented
;
6531 case CP0_REGISTER_22
:
6532 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
6533 register_name
= "'Diagnostic"; /* implementation dependent */
6535 case CP0_REGISTER_23
:
6537 case CP0_REG23__DEBUG
:
6538 gen_helper_mfc0_debug(arg
, cpu_env
); /* EJTAG support */
6539 register_name
= "Debug";
6541 case CP0_REG23__TRACECONTROL
:
6542 /* PDtrace support */
6543 /* gen_helper_mfc0_tracecontrol(arg); */
6544 register_name
= "TraceControl";
6545 goto cp0_unimplemented
;
6546 case CP0_REG23__TRACECONTROL2
:
6547 /* PDtrace support */
6548 /* gen_helper_mfc0_tracecontrol2(arg); */
6549 register_name
= "TraceControl2";
6550 goto cp0_unimplemented
;
6551 case CP0_REG23__USERTRACEDATA1
:
6552 /* PDtrace support */
6553 /* gen_helper_mfc0_usertracedata1(arg);*/
6554 register_name
= "UserTraceData1";
6555 goto cp0_unimplemented
;
6556 case CP0_REG23__TRACEIBPC
:
6557 /* PDtrace support */
6558 /* gen_helper_mfc0_traceibpc(arg); */
6559 register_name
= "TraceIBPC";
6560 goto cp0_unimplemented
;
6561 case CP0_REG23__TRACEDBPC
:
6562 /* PDtrace support */
6563 /* gen_helper_mfc0_tracedbpc(arg); */
6564 register_name
= "TraceDBPC";
6565 goto cp0_unimplemented
;
6567 goto cp0_unimplemented
;
6570 case CP0_REGISTER_24
:
6572 case CP0_REG24__DEPC
:
6574 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
6575 tcg_gen_ext32s_tl(arg
, arg
);
6576 register_name
= "DEPC";
6579 goto cp0_unimplemented
;
6582 case CP0_REGISTER_25
:
6584 case CP0_REG25__PERFCTL0
:
6585 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Performance0
));
6586 register_name
= "Performance0";
6588 case CP0_REG25__PERFCNT0
:
6589 /* gen_helper_mfc0_performance1(arg); */
6590 register_name
= "Performance1";
6591 goto cp0_unimplemented
;
6592 case CP0_REG25__PERFCTL1
:
6593 /* gen_helper_mfc0_performance2(arg); */
6594 register_name
= "Performance2";
6595 goto cp0_unimplemented
;
6596 case CP0_REG25__PERFCNT1
:
6597 /* gen_helper_mfc0_performance3(arg); */
6598 register_name
= "Performance3";
6599 goto cp0_unimplemented
;
6600 case CP0_REG25__PERFCTL2
:
6601 /* gen_helper_mfc0_performance4(arg); */
6602 register_name
= "Performance4";
6603 goto cp0_unimplemented
;
6604 case CP0_REG25__PERFCNT2
:
6605 /* gen_helper_mfc0_performance5(arg); */
6606 register_name
= "Performance5";
6607 goto cp0_unimplemented
;
6608 case CP0_REG25__PERFCTL3
:
6609 /* gen_helper_mfc0_performance6(arg); */
6610 register_name
= "Performance6";
6611 goto cp0_unimplemented
;
6612 case CP0_REG25__PERFCNT3
:
6613 /* gen_helper_mfc0_performance7(arg); */
6614 register_name
= "Performance7";
6615 goto cp0_unimplemented
;
6617 goto cp0_unimplemented
;
6620 case CP0_REGISTER_26
:
6622 case CP0_REG26__ERRCTL
:
6623 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_ErrCtl
));
6624 register_name
= "ErrCtl";
6627 goto cp0_unimplemented
;
6630 case CP0_REGISTER_27
:
6632 case CP0_REG27__CACHERR
:
6633 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
6634 register_name
= "CacheErr";
6637 goto cp0_unimplemented
;
6640 case CP0_REGISTER_28
:
6642 case CP0_REG28__TAGLO
:
6643 case CP0_REG28__TAGLO1
:
6644 case CP0_REG28__TAGLO2
:
6645 case CP0_REG28__TAGLO3
:
6647 TCGv_i64 tmp
= tcg_temp_new_i64();
6648 tcg_gen_ld_i64(tmp
, cpu_env
, offsetof(CPUMIPSState
, CP0_TagLo
));
6649 gen_move_low32(arg
, tmp
);
6650 tcg_temp_free_i64(tmp
);
6652 register_name
= "TagLo";
6654 case CP0_REG28__DATALO
:
6655 case CP0_REG28__DATALO1
:
6656 case CP0_REG28__DATALO2
:
6657 case CP0_REG28__DATALO3
:
6658 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataLo
));
6659 register_name
= "DataLo";
6662 goto cp0_unimplemented
;
6665 case CP0_REGISTER_29
:
6667 case CP0_REG29__TAGHI
:
6668 case CP0_REG29__TAGHI1
:
6669 case CP0_REG29__TAGHI2
:
6670 case CP0_REG29__TAGHI3
:
6671 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagHi
));
6672 register_name
= "TagHi";
6674 case CP0_REG29__DATAHI
:
6675 case CP0_REG29__DATAHI1
:
6676 case CP0_REG29__DATAHI2
:
6677 case CP0_REG29__DATAHI3
:
6678 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataHi
));
6679 register_name
= "DataHi";
6682 goto cp0_unimplemented
;
6685 case CP0_REGISTER_30
:
6687 case CP0_REG30__ERROREPC
:
6688 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
6689 tcg_gen_ext32s_tl(arg
, arg
);
6690 register_name
= "ErrorEPC";
6693 goto cp0_unimplemented
;
6696 case CP0_REGISTER_31
:
6698 case CP0_REG31__DESAVE
:
6700 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
6701 register_name
= "DESAVE";
6703 case CP0_REG31__KSCRATCH1
:
6704 case CP0_REG31__KSCRATCH2
:
6705 case CP0_REG31__KSCRATCH3
:
6706 case CP0_REG31__KSCRATCH4
:
6707 case CP0_REG31__KSCRATCH5
:
6708 case CP0_REG31__KSCRATCH6
:
6709 CP0_CHECK(ctx
->kscrexist
& (1 << sel
));
6710 tcg_gen_ld_tl(arg
, cpu_env
,
6711 offsetof(CPUMIPSState
, CP0_KScratch
[sel
- 2]));
6712 tcg_gen_ext32s_tl(arg
, arg
);
6713 register_name
= "KScratch";
6716 goto cp0_unimplemented
;
6720 goto cp0_unimplemented
;
6722 trace_mips_translate_c0("mfc0", register_name
, reg
, sel
);
6726 qemu_log_mask(LOG_UNIMP
, "mfc0 %s (reg %d sel %d)\n",
6727 register_name
, reg
, sel
);
6728 gen_mfc0_unimplemented(ctx
, arg
);
6731 static void gen_mtc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
6733 const char *register_name
= "invalid";
6736 check_insn(ctx
, ISA_MIPS_R1
);
6739 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
6744 case CP0_REGISTER_00
:
6746 case CP0_REG00__INDEX
:
6747 gen_helper_mtc0_index(cpu_env
, arg
);
6748 register_name
= "Index";
6750 case CP0_REG00__MVPCONTROL
:
6751 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6752 gen_helper_mtc0_mvpcontrol(cpu_env
, arg
);
6753 register_name
= "MVPControl";
6755 case CP0_REG00__MVPCONF0
:
6756 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6758 register_name
= "MVPConf0";
6760 case CP0_REG00__MVPCONF1
:
6761 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6763 register_name
= "MVPConf1";
6765 case CP0_REG00__VPCONTROL
:
6768 register_name
= "VPControl";
6771 goto cp0_unimplemented
;
6774 case CP0_REGISTER_01
:
6776 case CP0_REG01__RANDOM
:
6778 register_name
= "Random";
6780 case CP0_REG01__VPECONTROL
:
6781 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6782 gen_helper_mtc0_vpecontrol(cpu_env
, arg
);
6783 register_name
= "VPEControl";
6785 case CP0_REG01__VPECONF0
:
6786 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6787 gen_helper_mtc0_vpeconf0(cpu_env
, arg
);
6788 register_name
= "VPEConf0";
6790 case CP0_REG01__VPECONF1
:
6791 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6792 gen_helper_mtc0_vpeconf1(cpu_env
, arg
);
6793 register_name
= "VPEConf1";
6795 case CP0_REG01__YQMASK
:
6796 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6797 gen_helper_mtc0_yqmask(cpu_env
, arg
);
6798 register_name
= "YQMask";
6800 case CP0_REG01__VPESCHEDULE
:
6801 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6802 tcg_gen_st_tl(arg
, cpu_env
,
6803 offsetof(CPUMIPSState
, CP0_VPESchedule
));
6804 register_name
= "VPESchedule";
6806 case CP0_REG01__VPESCHEFBACK
:
6807 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6808 tcg_gen_st_tl(arg
, cpu_env
,
6809 offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
6810 register_name
= "VPEScheFBack";
6812 case CP0_REG01__VPEOPT
:
6813 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6814 gen_helper_mtc0_vpeopt(cpu_env
, arg
);
6815 register_name
= "VPEOpt";
6818 goto cp0_unimplemented
;
6821 case CP0_REGISTER_02
:
6823 case CP0_REG02__ENTRYLO0
:
6824 gen_helper_mtc0_entrylo0(cpu_env
, arg
);
6825 register_name
= "EntryLo0";
6827 case CP0_REG02__TCSTATUS
:
6828 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6829 gen_helper_mtc0_tcstatus(cpu_env
, arg
);
6830 register_name
= "TCStatus";
6832 case CP0_REG02__TCBIND
:
6833 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6834 gen_helper_mtc0_tcbind(cpu_env
, arg
);
6835 register_name
= "TCBind";
6837 case CP0_REG02__TCRESTART
:
6838 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6839 gen_helper_mtc0_tcrestart(cpu_env
, arg
);
6840 register_name
= "TCRestart";
6842 case CP0_REG02__TCHALT
:
6843 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6844 gen_helper_mtc0_tchalt(cpu_env
, arg
);
6845 register_name
= "TCHalt";
6847 case CP0_REG02__TCCONTEXT
:
6848 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6849 gen_helper_mtc0_tccontext(cpu_env
, arg
);
6850 register_name
= "TCContext";
6852 case CP0_REG02__TCSCHEDULE
:
6853 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6854 gen_helper_mtc0_tcschedule(cpu_env
, arg
);
6855 register_name
= "TCSchedule";
6857 case CP0_REG02__TCSCHEFBACK
:
6858 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6859 gen_helper_mtc0_tcschefback(cpu_env
, arg
);
6860 register_name
= "TCScheFBack";
6863 goto cp0_unimplemented
;
6866 case CP0_REGISTER_03
:
6868 case CP0_REG03__ENTRYLO1
:
6869 gen_helper_mtc0_entrylo1(cpu_env
, arg
);
6870 register_name
= "EntryLo1";
6872 case CP0_REG03__GLOBALNUM
:
6875 register_name
= "GlobalNumber";
6878 goto cp0_unimplemented
;
6881 case CP0_REGISTER_04
:
6883 case CP0_REG04__CONTEXT
:
6884 gen_helper_mtc0_context(cpu_env
, arg
);
6885 register_name
= "Context";
6887 case CP0_REG04__CONTEXTCONFIG
:
6889 /* gen_helper_mtc0_contextconfig(arg); */
6890 register_name
= "ContextConfig";
6891 goto cp0_unimplemented
;
6892 case CP0_REG04__USERLOCAL
:
6893 CP0_CHECK(ctx
->ulri
);
6894 tcg_gen_st_tl(arg
, cpu_env
,
6895 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
6896 register_name
= "UserLocal";
6898 case CP0_REG04__MMID
:
6900 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_MemoryMapID
));
6901 register_name
= "MMID";
6904 goto cp0_unimplemented
;
6907 case CP0_REGISTER_05
:
6909 case CP0_REG05__PAGEMASK
:
6910 gen_helper_mtc0_pagemask(cpu_env
, arg
);
6911 register_name
= "PageMask";
6913 case CP0_REG05__PAGEGRAIN
:
6914 check_insn(ctx
, ISA_MIPS_R2
);
6915 gen_helper_mtc0_pagegrain(cpu_env
, arg
);
6916 register_name
= "PageGrain";
6917 ctx
->base
.is_jmp
= DISAS_STOP
;
6919 case CP0_REG05__SEGCTL0
:
6921 gen_helper_mtc0_segctl0(cpu_env
, arg
);
6922 register_name
= "SegCtl0";
6924 case CP0_REG05__SEGCTL1
:
6926 gen_helper_mtc0_segctl1(cpu_env
, arg
);
6927 register_name
= "SegCtl1";
6929 case CP0_REG05__SEGCTL2
:
6931 gen_helper_mtc0_segctl2(cpu_env
, arg
);
6932 register_name
= "SegCtl2";
6934 case CP0_REG05__PWBASE
:
6936 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_PWBase
));
6937 register_name
= "PWBase";
6939 case CP0_REG05__PWFIELD
:
6941 gen_helper_mtc0_pwfield(cpu_env
, arg
);
6942 register_name
= "PWField";
6944 case CP0_REG05__PWSIZE
:
6946 gen_helper_mtc0_pwsize(cpu_env
, arg
);
6947 register_name
= "PWSize";
6950 goto cp0_unimplemented
;
6953 case CP0_REGISTER_06
:
6955 case CP0_REG06__WIRED
:
6956 gen_helper_mtc0_wired(cpu_env
, arg
);
6957 register_name
= "Wired";
6959 case CP0_REG06__SRSCONF0
:
6960 check_insn(ctx
, ISA_MIPS_R2
);
6961 gen_helper_mtc0_srsconf0(cpu_env
, arg
);
6962 register_name
= "SRSConf0";
6964 case CP0_REG06__SRSCONF1
:
6965 check_insn(ctx
, ISA_MIPS_R2
);
6966 gen_helper_mtc0_srsconf1(cpu_env
, arg
);
6967 register_name
= "SRSConf1";
6969 case CP0_REG06__SRSCONF2
:
6970 check_insn(ctx
, ISA_MIPS_R2
);
6971 gen_helper_mtc0_srsconf2(cpu_env
, arg
);
6972 register_name
= "SRSConf2";
6974 case CP0_REG06__SRSCONF3
:
6975 check_insn(ctx
, ISA_MIPS_R2
);
6976 gen_helper_mtc0_srsconf3(cpu_env
, arg
);
6977 register_name
= "SRSConf3";
6979 case CP0_REG06__SRSCONF4
:
6980 check_insn(ctx
, ISA_MIPS_R2
);
6981 gen_helper_mtc0_srsconf4(cpu_env
, arg
);
6982 register_name
= "SRSConf4";
6984 case CP0_REG06__PWCTL
:
6986 gen_helper_mtc0_pwctl(cpu_env
, arg
);
6987 register_name
= "PWCtl";
6990 goto cp0_unimplemented
;
6993 case CP0_REGISTER_07
:
6995 case CP0_REG07__HWRENA
:
6996 check_insn(ctx
, ISA_MIPS_R2
);
6997 gen_helper_mtc0_hwrena(cpu_env
, arg
);
6998 ctx
->base
.is_jmp
= DISAS_STOP
;
6999 register_name
= "HWREna";
7002 goto cp0_unimplemented
;
7005 case CP0_REGISTER_08
:
7007 case CP0_REG08__BADVADDR
:
7009 register_name
= "BadVAddr";
7011 case CP0_REG08__BADINSTR
:
7013 register_name
= "BadInstr";
7015 case CP0_REG08__BADINSTRP
:
7017 register_name
= "BadInstrP";
7019 case CP0_REG08__BADINSTRX
:
7021 register_name
= "BadInstrX";
7024 goto cp0_unimplemented
;
7027 case CP0_REGISTER_09
:
7029 case CP0_REG09__COUNT
:
7030 gen_helper_mtc0_count(cpu_env
, arg
);
7031 register_name
= "Count";
7033 case CP0_REG09__SAARI
:
7034 CP0_CHECK(ctx
->saar
);
7035 gen_helper_mtc0_saari(cpu_env
, arg
);
7036 register_name
= "SAARI";
7038 case CP0_REG09__SAAR
:
7039 CP0_CHECK(ctx
->saar
);
7040 gen_helper_mtc0_saar(cpu_env
, arg
);
7041 register_name
= "SAAR";
7044 goto cp0_unimplemented
;
7047 case CP0_REGISTER_10
:
7049 case CP0_REG10__ENTRYHI
:
7050 gen_helper_mtc0_entryhi(cpu_env
, arg
);
7051 register_name
= "EntryHi";
7054 goto cp0_unimplemented
;
7057 case CP0_REGISTER_11
:
7059 case CP0_REG11__COMPARE
:
7060 gen_helper_mtc0_compare(cpu_env
, arg
);
7061 register_name
= "Compare";
7063 /* 6,7 are implementation dependent */
7065 goto cp0_unimplemented
;
7068 case CP0_REGISTER_12
:
7070 case CP0_REG12__STATUS
:
7071 save_cpu_state(ctx
, 1);
7072 gen_helper_mtc0_status(cpu_env
, arg
);
7073 /* DISAS_STOP isn't good enough here, hflags may have changed. */
7074 gen_save_pc(ctx
->base
.pc_next
+ 4);
7075 ctx
->base
.is_jmp
= DISAS_EXIT
;
7076 register_name
= "Status";
7078 case CP0_REG12__INTCTL
:
7079 check_insn(ctx
, ISA_MIPS_R2
);
7080 gen_helper_mtc0_intctl(cpu_env
, arg
);
7081 /* Stop translation as we may have switched the execution mode */
7082 ctx
->base
.is_jmp
= DISAS_STOP
;
7083 register_name
= "IntCtl";
7085 case CP0_REG12__SRSCTL
:
7086 check_insn(ctx
, ISA_MIPS_R2
);
7087 gen_helper_mtc0_srsctl(cpu_env
, arg
);
7088 /* Stop translation as we may have switched the execution mode */
7089 ctx
->base
.is_jmp
= DISAS_STOP
;
7090 register_name
= "SRSCtl";
7092 case CP0_REG12__SRSMAP
:
7093 check_insn(ctx
, ISA_MIPS_R2
);
7094 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
7095 /* Stop translation as we may have switched the execution mode */
7096 ctx
->base
.is_jmp
= DISAS_STOP
;
7097 register_name
= "SRSMap";
7100 goto cp0_unimplemented
;
7103 case CP0_REGISTER_13
:
7105 case CP0_REG13__CAUSE
:
7106 save_cpu_state(ctx
, 1);
7107 gen_helper_mtc0_cause(cpu_env
, arg
);
7109 * Stop translation as we may have triggered an interrupt.
7110 * DISAS_STOP isn't sufficient, we need to ensure we break out of
7111 * translated code to check for pending interrupts.
7113 gen_save_pc(ctx
->base
.pc_next
+ 4);
7114 ctx
->base
.is_jmp
= DISAS_EXIT
;
7115 register_name
= "Cause";
7118 goto cp0_unimplemented
;
7121 case CP0_REGISTER_14
:
7123 case CP0_REG14__EPC
:
7124 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
7125 register_name
= "EPC";
7128 goto cp0_unimplemented
;
7131 case CP0_REGISTER_15
:
7133 case CP0_REG15__PRID
:
7135 register_name
= "PRid";
7137 case CP0_REG15__EBASE
:
7138 check_insn(ctx
, ISA_MIPS_R2
);
7139 gen_helper_mtc0_ebase(cpu_env
, arg
);
7140 register_name
= "EBase";
7143 goto cp0_unimplemented
;
7146 case CP0_REGISTER_16
:
7148 case CP0_REG16__CONFIG
:
7149 gen_helper_mtc0_config0(cpu_env
, arg
);
7150 register_name
= "Config";
7151 /* Stop translation as we may have switched the execution mode */
7152 ctx
->base
.is_jmp
= DISAS_STOP
;
7154 case CP0_REG16__CONFIG1
:
7155 /* ignored, read only */
7156 register_name
= "Config1";
7158 case CP0_REG16__CONFIG2
:
7159 gen_helper_mtc0_config2(cpu_env
, arg
);
7160 register_name
= "Config2";
7161 /* Stop translation as we may have switched the execution mode */
7162 ctx
->base
.is_jmp
= DISAS_STOP
;
7164 case CP0_REG16__CONFIG3
:
7165 gen_helper_mtc0_config3(cpu_env
, arg
);
7166 register_name
= "Config3";
7167 /* Stop translation as we may have switched the execution mode */
7168 ctx
->base
.is_jmp
= DISAS_STOP
;
7170 case CP0_REG16__CONFIG4
:
7171 gen_helper_mtc0_config4(cpu_env
, arg
);
7172 register_name
= "Config4";
7173 ctx
->base
.is_jmp
= DISAS_STOP
;
7175 case CP0_REG16__CONFIG5
:
7176 gen_helper_mtc0_config5(cpu_env
, arg
);
7177 register_name
= "Config5";
7178 /* Stop translation as we may have switched the execution mode */
7179 ctx
->base
.is_jmp
= DISAS_STOP
;
7181 /* 6,7 are implementation dependent */
7182 case CP0_REG16__CONFIG6
:
7184 register_name
= "Config6";
7186 case CP0_REG16__CONFIG7
:
7188 register_name
= "Config7";
7191 register_name
= "Invalid config selector";
7192 goto cp0_unimplemented
;
7195 case CP0_REGISTER_17
:
7197 case CP0_REG17__LLADDR
:
7198 gen_helper_mtc0_lladdr(cpu_env
, arg
);
7199 register_name
= "LLAddr";
7201 case CP0_REG17__MAAR
:
7202 CP0_CHECK(ctx
->mrp
);
7203 gen_helper_mtc0_maar(cpu_env
, arg
);
7204 register_name
= "MAAR";
7206 case CP0_REG17__MAARI
:
7207 CP0_CHECK(ctx
->mrp
);
7208 gen_helper_mtc0_maari(cpu_env
, arg
);
7209 register_name
= "MAARI";
7212 goto cp0_unimplemented
;
7215 case CP0_REGISTER_18
:
7217 case CP0_REG18__WATCHLO0
:
7218 case CP0_REG18__WATCHLO1
:
7219 case CP0_REG18__WATCHLO2
:
7220 case CP0_REG18__WATCHLO3
:
7221 case CP0_REG18__WATCHLO4
:
7222 case CP0_REG18__WATCHLO5
:
7223 case CP0_REG18__WATCHLO6
:
7224 case CP0_REG18__WATCHLO7
:
7225 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
7226 gen_helper_0e1i(mtc0_watchlo
, arg
, sel
);
7227 register_name
= "WatchLo";
7230 goto cp0_unimplemented
;
7233 case CP0_REGISTER_19
:
7235 case CP0_REG19__WATCHHI0
:
7236 case CP0_REG19__WATCHHI1
:
7237 case CP0_REG19__WATCHHI2
:
7238 case CP0_REG19__WATCHHI3
:
7239 case CP0_REG19__WATCHHI4
:
7240 case CP0_REG19__WATCHHI5
:
7241 case CP0_REG19__WATCHHI6
:
7242 case CP0_REG19__WATCHHI7
:
7243 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
7244 gen_helper_0e1i(mtc0_watchhi
, arg
, sel
);
7245 register_name
= "WatchHi";
7248 goto cp0_unimplemented
;
7251 case CP0_REGISTER_20
:
7253 case CP0_REG20__XCONTEXT
:
7254 #if defined(TARGET_MIPS64)
7255 check_insn(ctx
, ISA_MIPS3
);
7256 gen_helper_mtc0_xcontext(cpu_env
, arg
);
7257 register_name
= "XContext";
7261 goto cp0_unimplemented
;
7264 case CP0_REGISTER_21
:
7265 /* Officially reserved, but sel 0 is used for R1x000 framemask */
7266 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS_R6
));
7269 gen_helper_mtc0_framemask(cpu_env
, arg
);
7270 register_name
= "Framemask";
7273 goto cp0_unimplemented
;
7276 case CP0_REGISTER_22
:
7278 register_name
= "Diagnostic"; /* implementation dependent */
7280 case CP0_REGISTER_23
:
7282 case CP0_REG23__DEBUG
:
7283 gen_helper_mtc0_debug(cpu_env
, arg
); /* EJTAG support */
7284 /* DISAS_STOP isn't good enough here, hflags may have changed. */
7285 gen_save_pc(ctx
->base
.pc_next
+ 4);
7286 ctx
->base
.is_jmp
= DISAS_EXIT
;
7287 register_name
= "Debug";
7289 case CP0_REG23__TRACECONTROL
:
7290 /* PDtrace support */
7291 /* gen_helper_mtc0_tracecontrol(cpu_env, arg); */
7292 register_name
= "TraceControl";
7293 /* Stop translation as we may have switched the execution mode */
7294 ctx
->base
.is_jmp
= DISAS_STOP
;
7295 goto cp0_unimplemented
;
7296 case CP0_REG23__TRACECONTROL2
:
7297 /* PDtrace support */
7298 /* gen_helper_mtc0_tracecontrol2(cpu_env, arg); */
7299 register_name
= "TraceControl2";
7300 /* Stop translation as we may have switched the execution mode */
7301 ctx
->base
.is_jmp
= DISAS_STOP
;
7302 goto cp0_unimplemented
;
7303 case CP0_REG23__USERTRACEDATA1
:
7304 /* Stop translation as we may have switched the execution mode */
7305 ctx
->base
.is_jmp
= DISAS_STOP
;
7306 /* PDtrace support */
7307 /* gen_helper_mtc0_usertracedata1(cpu_env, arg);*/
7308 register_name
= "UserTraceData";
7309 /* Stop translation as we may have switched the execution mode */
7310 ctx
->base
.is_jmp
= DISAS_STOP
;
7311 goto cp0_unimplemented
;
7312 case CP0_REG23__TRACEIBPC
:
7313 /* PDtrace support */
7314 /* gen_helper_mtc0_traceibpc(cpu_env, arg); */
7315 /* Stop translation as we may have switched the execution mode */
7316 ctx
->base
.is_jmp
= DISAS_STOP
;
7317 register_name
= "TraceIBPC";
7318 goto cp0_unimplemented
;
7319 case CP0_REG23__TRACEDBPC
:
7320 /* PDtrace support */
7321 /* gen_helper_mtc0_tracedbpc(cpu_env, arg); */
7322 /* Stop translation as we may have switched the execution mode */
7323 ctx
->base
.is_jmp
= DISAS_STOP
;
7324 register_name
= "TraceDBPC";
7325 goto cp0_unimplemented
;
7327 goto cp0_unimplemented
;
7330 case CP0_REGISTER_24
:
7332 case CP0_REG24__DEPC
:
7334 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
7335 register_name
= "DEPC";
7338 goto cp0_unimplemented
;
7341 case CP0_REGISTER_25
:
7343 case CP0_REG25__PERFCTL0
:
7344 gen_helper_mtc0_performance0(cpu_env
, arg
);
7345 register_name
= "Performance0";
7347 case CP0_REG25__PERFCNT0
:
7348 /* gen_helper_mtc0_performance1(arg); */
7349 register_name
= "Performance1";
7350 goto cp0_unimplemented
;
7351 case CP0_REG25__PERFCTL1
:
7352 /* gen_helper_mtc0_performance2(arg); */
7353 register_name
= "Performance2";
7354 goto cp0_unimplemented
;
7355 case CP0_REG25__PERFCNT1
:
7356 /* gen_helper_mtc0_performance3(arg); */
7357 register_name
= "Performance3";
7358 goto cp0_unimplemented
;
7359 case CP0_REG25__PERFCTL2
:
7360 /* gen_helper_mtc0_performance4(arg); */
7361 register_name
= "Performance4";
7362 goto cp0_unimplemented
;
7363 case CP0_REG25__PERFCNT2
:
7364 /* gen_helper_mtc0_performance5(arg); */
7365 register_name
= "Performance5";
7366 goto cp0_unimplemented
;
7367 case CP0_REG25__PERFCTL3
:
7368 /* gen_helper_mtc0_performance6(arg); */
7369 register_name
= "Performance6";
7370 goto cp0_unimplemented
;
7371 case CP0_REG25__PERFCNT3
:
7372 /* gen_helper_mtc0_performance7(arg); */
7373 register_name
= "Performance7";
7374 goto cp0_unimplemented
;
7376 goto cp0_unimplemented
;
7379 case CP0_REGISTER_26
:
7381 case CP0_REG26__ERRCTL
:
7382 gen_helper_mtc0_errctl(cpu_env
, arg
);
7383 ctx
->base
.is_jmp
= DISAS_STOP
;
7384 register_name
= "ErrCtl";
7387 goto cp0_unimplemented
;
7390 case CP0_REGISTER_27
:
7392 case CP0_REG27__CACHERR
:
7394 register_name
= "CacheErr";
7397 goto cp0_unimplemented
;
7400 case CP0_REGISTER_28
:
7402 case CP0_REG28__TAGLO
:
7403 case CP0_REG28__TAGLO1
:
7404 case CP0_REG28__TAGLO2
:
7405 case CP0_REG28__TAGLO3
:
7406 gen_helper_mtc0_taglo(cpu_env
, arg
);
7407 register_name
= "TagLo";
7409 case CP0_REG28__DATALO
:
7410 case CP0_REG28__DATALO1
:
7411 case CP0_REG28__DATALO2
:
7412 case CP0_REG28__DATALO3
:
7413 gen_helper_mtc0_datalo(cpu_env
, arg
);
7414 register_name
= "DataLo";
7417 goto cp0_unimplemented
;
7420 case CP0_REGISTER_29
:
7422 case CP0_REG29__TAGHI
:
7423 case CP0_REG29__TAGHI1
:
7424 case CP0_REG29__TAGHI2
:
7425 case CP0_REG29__TAGHI3
:
7426 gen_helper_mtc0_taghi(cpu_env
, arg
);
7427 register_name
= "TagHi";
7429 case CP0_REG29__DATAHI
:
7430 case CP0_REG29__DATAHI1
:
7431 case CP0_REG29__DATAHI2
:
7432 case CP0_REG29__DATAHI3
:
7433 gen_helper_mtc0_datahi(cpu_env
, arg
);
7434 register_name
= "DataHi";
7437 register_name
= "invalid sel";
7438 goto cp0_unimplemented
;
7441 case CP0_REGISTER_30
:
7443 case CP0_REG30__ERROREPC
:
7444 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
7445 register_name
= "ErrorEPC";
7448 goto cp0_unimplemented
;
7451 case CP0_REGISTER_31
:
7453 case CP0_REG31__DESAVE
:
7455 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
7456 register_name
= "DESAVE";
7458 case CP0_REG31__KSCRATCH1
:
7459 case CP0_REG31__KSCRATCH2
:
7460 case CP0_REG31__KSCRATCH3
:
7461 case CP0_REG31__KSCRATCH4
:
7462 case CP0_REG31__KSCRATCH5
:
7463 case CP0_REG31__KSCRATCH6
:
7464 CP0_CHECK(ctx
->kscrexist
& (1 << sel
));
7465 tcg_gen_st_tl(arg
, cpu_env
,
7466 offsetof(CPUMIPSState
, CP0_KScratch
[sel
- 2]));
7467 register_name
= "KScratch";
7470 goto cp0_unimplemented
;
7474 goto cp0_unimplemented
;
7476 trace_mips_translate_c0("mtc0", register_name
, reg
, sel
);
7478 /* For simplicity assume that all writes can cause interrupts. */
7479 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
7481 * DISAS_STOP isn't sufficient, we need to ensure we break out of
7482 * translated code to check for pending interrupts.
7484 gen_save_pc(ctx
->base
.pc_next
+ 4);
7485 ctx
->base
.is_jmp
= DISAS_EXIT
;
7490 qemu_log_mask(LOG_UNIMP
, "mtc0 %s (reg %d sel %d)\n",
7491 register_name
, reg
, sel
);
7494 #if defined(TARGET_MIPS64)
7495 static void gen_dmfc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
7497 const char *register_name
= "invalid";
7500 check_insn(ctx
, ISA_MIPS_R1
);
7504 case CP0_REGISTER_00
:
7506 case CP0_REG00__INDEX
:
7507 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Index
));
7508 register_name
= "Index";
7510 case CP0_REG00__MVPCONTROL
:
7511 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7512 gen_helper_mfc0_mvpcontrol(arg
, cpu_env
);
7513 register_name
= "MVPControl";
7515 case CP0_REG00__MVPCONF0
:
7516 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7517 gen_helper_mfc0_mvpconf0(arg
, cpu_env
);
7518 register_name
= "MVPConf0";
7520 case CP0_REG00__MVPCONF1
:
7521 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7522 gen_helper_mfc0_mvpconf1(arg
, cpu_env
);
7523 register_name
= "MVPConf1";
7525 case CP0_REG00__VPCONTROL
:
7527 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPControl
));
7528 register_name
= "VPControl";
7531 goto cp0_unimplemented
;
7534 case CP0_REGISTER_01
:
7536 case CP0_REG01__RANDOM
:
7537 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS_R6
));
7538 gen_helper_mfc0_random(arg
, cpu_env
);
7539 register_name
= "Random";
7541 case CP0_REG01__VPECONTROL
:
7542 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7543 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEControl
));
7544 register_name
= "VPEControl";
7546 case CP0_REG01__VPECONF0
:
7547 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7548 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf0
));
7549 register_name
= "VPEConf0";
7551 case CP0_REG01__VPECONF1
:
7552 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7553 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf1
));
7554 register_name
= "VPEConf1";
7556 case CP0_REG01__YQMASK
:
7557 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7558 tcg_gen_ld_tl(arg
, cpu_env
,
7559 offsetof(CPUMIPSState
, CP0_YQMask
));
7560 register_name
= "YQMask";
7562 case CP0_REG01__VPESCHEDULE
:
7563 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7564 tcg_gen_ld_tl(arg
, cpu_env
,
7565 offsetof(CPUMIPSState
, CP0_VPESchedule
));
7566 register_name
= "VPESchedule";
7568 case CP0_REG01__VPESCHEFBACK
:
7569 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7570 tcg_gen_ld_tl(arg
, cpu_env
,
7571 offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
7572 register_name
= "VPEScheFBack";
7574 case CP0_REG01__VPEOPT
:
7575 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7576 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEOpt
));
7577 register_name
= "VPEOpt";
7580 goto cp0_unimplemented
;
7583 case CP0_REGISTER_02
:
7585 case CP0_REG02__ENTRYLO0
:
7586 tcg_gen_ld_tl(arg
, cpu_env
,
7587 offsetof(CPUMIPSState
, CP0_EntryLo0
));
7588 register_name
= "EntryLo0";
7590 case CP0_REG02__TCSTATUS
:
7591 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7592 gen_helper_mfc0_tcstatus(arg
, cpu_env
);
7593 register_name
= "TCStatus";
7595 case CP0_REG02__TCBIND
:
7596 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7597 gen_helper_mfc0_tcbind(arg
, cpu_env
);
7598 register_name
= "TCBind";
7600 case CP0_REG02__TCRESTART
:
7601 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7602 gen_helper_dmfc0_tcrestart(arg
, cpu_env
);
7603 register_name
= "TCRestart";
7605 case CP0_REG02__TCHALT
:
7606 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7607 gen_helper_dmfc0_tchalt(arg
, cpu_env
);
7608 register_name
= "TCHalt";
7610 case CP0_REG02__TCCONTEXT
:
7611 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7612 gen_helper_dmfc0_tccontext(arg
, cpu_env
);
7613 register_name
= "TCContext";
7615 case CP0_REG02__TCSCHEDULE
:
7616 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7617 gen_helper_dmfc0_tcschedule(arg
, cpu_env
);
7618 register_name
= "TCSchedule";
7620 case CP0_REG02__TCSCHEFBACK
:
7621 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7622 gen_helper_dmfc0_tcschefback(arg
, cpu_env
);
7623 register_name
= "TCScheFBack";
7626 goto cp0_unimplemented
;
7629 case CP0_REGISTER_03
:
7631 case CP0_REG03__ENTRYLO1
:
7632 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryLo1
));
7633 register_name
= "EntryLo1";
7635 case CP0_REG03__GLOBALNUM
:
7637 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_GlobalNumber
));
7638 register_name
= "GlobalNumber";
7641 goto cp0_unimplemented
;
7644 case CP0_REGISTER_04
:
7646 case CP0_REG04__CONTEXT
:
7647 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_Context
));
7648 register_name
= "Context";
7650 case CP0_REG04__CONTEXTCONFIG
:
7652 /* gen_helper_dmfc0_contextconfig(arg); */
7653 register_name
= "ContextConfig";
7654 goto cp0_unimplemented
;
7655 case CP0_REG04__USERLOCAL
:
7656 CP0_CHECK(ctx
->ulri
);
7657 tcg_gen_ld_tl(arg
, cpu_env
,
7658 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
7659 register_name
= "UserLocal";
7661 case CP0_REG04__MMID
:
7663 gen_helper_mtc0_memorymapid(cpu_env
, arg
);
7664 register_name
= "MMID";
7667 goto cp0_unimplemented
;
7670 case CP0_REGISTER_05
:
7672 case CP0_REG05__PAGEMASK
:
7673 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageMask
));
7674 register_name
= "PageMask";
7676 case CP0_REG05__PAGEGRAIN
:
7677 check_insn(ctx
, ISA_MIPS_R2
);
7678 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageGrain
));
7679 register_name
= "PageGrain";
7681 case CP0_REG05__SEGCTL0
:
7683 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_SegCtl0
));
7684 register_name
= "SegCtl0";
7686 case CP0_REG05__SEGCTL1
:
7688 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_SegCtl1
));
7689 register_name
= "SegCtl1";
7691 case CP0_REG05__SEGCTL2
:
7693 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_SegCtl2
));
7694 register_name
= "SegCtl2";
7696 case CP0_REG05__PWBASE
:
7698 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_PWBase
));
7699 register_name
= "PWBase";
7701 case CP0_REG05__PWFIELD
:
7703 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_PWField
));
7704 register_name
= "PWField";
7706 case CP0_REG05__PWSIZE
:
7708 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_PWSize
));
7709 register_name
= "PWSize";
7712 goto cp0_unimplemented
;
7715 case CP0_REGISTER_06
:
7717 case CP0_REG06__WIRED
:
7718 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Wired
));
7719 register_name
= "Wired";
7721 case CP0_REG06__SRSCONF0
:
7722 check_insn(ctx
, ISA_MIPS_R2
);
7723 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf0
));
7724 register_name
= "SRSConf0";
7726 case CP0_REG06__SRSCONF1
:
7727 check_insn(ctx
, ISA_MIPS_R2
);
7728 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf1
));
7729 register_name
= "SRSConf1";
7731 case CP0_REG06__SRSCONF2
:
7732 check_insn(ctx
, ISA_MIPS_R2
);
7733 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf2
));
7734 register_name
= "SRSConf2";
7736 case CP0_REG06__SRSCONF3
:
7737 check_insn(ctx
, ISA_MIPS_R2
);
7738 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf3
));
7739 register_name
= "SRSConf3";
7741 case CP0_REG06__SRSCONF4
:
7742 check_insn(ctx
, ISA_MIPS_R2
);
7743 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf4
));
7744 register_name
= "SRSConf4";
7746 case CP0_REG06__PWCTL
:
7748 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PWCtl
));
7749 register_name
= "PWCtl";
7752 goto cp0_unimplemented
;
7755 case CP0_REGISTER_07
:
7757 case CP0_REG07__HWRENA
:
7758 check_insn(ctx
, ISA_MIPS_R2
);
7759 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_HWREna
));
7760 register_name
= "HWREna";
7763 goto cp0_unimplemented
;
7766 case CP0_REGISTER_08
:
7768 case CP0_REG08__BADVADDR
:
7769 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_BadVAddr
));
7770 register_name
= "BadVAddr";
7772 case CP0_REG08__BADINSTR
:
7774 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstr
));
7775 register_name
= "BadInstr";
7777 case CP0_REG08__BADINSTRP
:
7779 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstrP
));
7780 register_name
= "BadInstrP";
7782 case CP0_REG08__BADINSTRX
:
7784 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstrX
));
7785 tcg_gen_andi_tl(arg
, arg
, ~0xffff);
7786 register_name
= "BadInstrX";
7789 goto cp0_unimplemented
;
7792 case CP0_REGISTER_09
:
7794 case CP0_REG09__COUNT
:
7795 /* Mark as an IO operation because we read the time. */
7796 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
7799 gen_helper_mfc0_count(arg
, cpu_env
);
7801 * Break the TB to be able to take timer interrupts immediately
7802 * after reading count. DISAS_STOP isn't sufficient, we need to
7803 * ensure we break completely out of translated code.
7805 gen_save_pc(ctx
->base
.pc_next
+ 4);
7806 ctx
->base
.is_jmp
= DISAS_EXIT
;
7807 register_name
= "Count";
7809 case CP0_REG09__SAARI
:
7810 CP0_CHECK(ctx
->saar
);
7811 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SAARI
));
7812 register_name
= "SAARI";
7814 case CP0_REG09__SAAR
:
7815 CP0_CHECK(ctx
->saar
);
7816 gen_helper_dmfc0_saar(arg
, cpu_env
);
7817 register_name
= "SAAR";
7820 goto cp0_unimplemented
;
7823 case CP0_REGISTER_10
:
7825 case CP0_REG10__ENTRYHI
:
7826 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryHi
));
7827 register_name
= "EntryHi";
7830 goto cp0_unimplemented
;
7833 case CP0_REGISTER_11
:
7835 case CP0_REG11__COMPARE
:
7836 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Compare
));
7837 register_name
= "Compare";
7839 /* 6,7 are implementation dependent */
7841 goto cp0_unimplemented
;
7844 case CP0_REGISTER_12
:
7846 case CP0_REG12__STATUS
:
7847 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Status
));
7848 register_name
= "Status";
7850 case CP0_REG12__INTCTL
:
7851 check_insn(ctx
, ISA_MIPS_R2
);
7852 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_IntCtl
));
7853 register_name
= "IntCtl";
7855 case CP0_REG12__SRSCTL
:
7856 check_insn(ctx
, ISA_MIPS_R2
);
7857 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
7858 register_name
= "SRSCtl";
7860 case CP0_REG12__SRSMAP
:
7861 check_insn(ctx
, ISA_MIPS_R2
);
7862 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
7863 register_name
= "SRSMap";
7866 goto cp0_unimplemented
;
7869 case CP0_REGISTER_13
:
7871 case CP0_REG13__CAUSE
:
7872 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Cause
));
7873 register_name
= "Cause";
7876 goto cp0_unimplemented
;
7879 case CP0_REGISTER_14
:
7881 case CP0_REG14__EPC
:
7882 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
7883 register_name
= "EPC";
7886 goto cp0_unimplemented
;
7889 case CP0_REGISTER_15
:
7891 case CP0_REG15__PRID
:
7892 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PRid
));
7893 register_name
= "PRid";
7895 case CP0_REG15__EBASE
:
7896 check_insn(ctx
, ISA_MIPS_R2
);
7897 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EBase
));
7898 register_name
= "EBase";
7900 case CP0_REG15__CMGCRBASE
:
7901 check_insn(ctx
, ISA_MIPS_R2
);
7902 CP0_CHECK(ctx
->cmgcr
);
7903 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_CMGCRBase
));
7904 register_name
= "CMGCRBase";
7907 goto cp0_unimplemented
;
7910 case CP0_REGISTER_16
:
7912 case CP0_REG16__CONFIG
:
7913 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config0
));
7914 register_name
= "Config";
7916 case CP0_REG16__CONFIG1
:
7917 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config1
));
7918 register_name
= "Config1";
7920 case CP0_REG16__CONFIG2
:
7921 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config2
));
7922 register_name
= "Config2";
7924 case CP0_REG16__CONFIG3
:
7925 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config3
));
7926 register_name
= "Config3";
7928 case CP0_REG16__CONFIG4
:
7929 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config4
));
7930 register_name
= "Config4";
7932 case CP0_REG16__CONFIG5
:
7933 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config5
));
7934 register_name
= "Config5";
7936 /* 6,7 are implementation dependent */
7937 case CP0_REG16__CONFIG6
:
7938 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config6
));
7939 register_name
= "Config6";
7941 case CP0_REG16__CONFIG7
:
7942 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config7
));
7943 register_name
= "Config7";
7946 goto cp0_unimplemented
;
7949 case CP0_REGISTER_17
:
7951 case CP0_REG17__LLADDR
:
7952 gen_helper_dmfc0_lladdr(arg
, cpu_env
);
7953 register_name
= "LLAddr";
7955 case CP0_REG17__MAAR
:
7956 CP0_CHECK(ctx
->mrp
);
7957 gen_helper_dmfc0_maar(arg
, cpu_env
);
7958 register_name
= "MAAR";
7960 case CP0_REG17__MAARI
:
7961 CP0_CHECK(ctx
->mrp
);
7962 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_MAARI
));
7963 register_name
= "MAARI";
7966 goto cp0_unimplemented
;
7969 case CP0_REGISTER_18
:
7971 case CP0_REG18__WATCHLO0
:
7972 case CP0_REG18__WATCHLO1
:
7973 case CP0_REG18__WATCHLO2
:
7974 case CP0_REG18__WATCHLO3
:
7975 case CP0_REG18__WATCHLO4
:
7976 case CP0_REG18__WATCHLO5
:
7977 case CP0_REG18__WATCHLO6
:
7978 case CP0_REG18__WATCHLO7
:
7979 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
7980 gen_helper_1e0i(dmfc0_watchlo
, arg
, sel
);
7981 register_name
= "WatchLo";
7984 goto cp0_unimplemented
;
7987 case CP0_REGISTER_19
:
7989 case CP0_REG19__WATCHHI0
:
7990 case CP0_REG19__WATCHHI1
:
7991 case CP0_REG19__WATCHHI2
:
7992 case CP0_REG19__WATCHHI3
:
7993 case CP0_REG19__WATCHHI4
:
7994 case CP0_REG19__WATCHHI5
:
7995 case CP0_REG19__WATCHHI6
:
7996 case CP0_REG19__WATCHHI7
:
7997 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
7998 gen_helper_1e0i(dmfc0_watchhi
, arg
, sel
);
7999 register_name
= "WatchHi";
8002 goto cp0_unimplemented
;
8005 case CP0_REGISTER_20
:
8007 case CP0_REG20__XCONTEXT
:
8008 check_insn(ctx
, ISA_MIPS3
);
8009 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_XContext
));
8010 register_name
= "XContext";
8013 goto cp0_unimplemented
;
8016 case CP0_REGISTER_21
:
8017 /* Officially reserved, but sel 0 is used for R1x000 framemask */
8018 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS_R6
));
8021 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Framemask
));
8022 register_name
= "Framemask";
8025 goto cp0_unimplemented
;
8028 case CP0_REGISTER_22
:
8029 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
8030 register_name
= "'Diagnostic"; /* implementation dependent */
8032 case CP0_REGISTER_23
:
8034 case CP0_REG23__DEBUG
:
8035 gen_helper_mfc0_debug(arg
, cpu_env
); /* EJTAG support */
8036 register_name
= "Debug";
8038 case CP0_REG23__TRACECONTROL
:
8039 /* PDtrace support */
8040 /* gen_helper_dmfc0_tracecontrol(arg, cpu_env); */
8041 register_name
= "TraceControl";
8042 goto cp0_unimplemented
;
8043 case CP0_REG23__TRACECONTROL2
:
8044 /* PDtrace support */
8045 /* gen_helper_dmfc0_tracecontrol2(arg, cpu_env); */
8046 register_name
= "TraceControl2";
8047 goto cp0_unimplemented
;
8048 case CP0_REG23__USERTRACEDATA1
:
8049 /* PDtrace support */
8050 /* gen_helper_dmfc0_usertracedata1(arg, cpu_env);*/
8051 register_name
= "UserTraceData1";
8052 goto cp0_unimplemented
;
8053 case CP0_REG23__TRACEIBPC
:
8054 /* PDtrace support */
8055 /* gen_helper_dmfc0_traceibpc(arg, cpu_env); */
8056 register_name
= "TraceIBPC";
8057 goto cp0_unimplemented
;
8058 case CP0_REG23__TRACEDBPC
:
8059 /* PDtrace support */
8060 /* gen_helper_dmfc0_tracedbpc(arg, cpu_env); */
8061 register_name
= "TraceDBPC";
8062 goto cp0_unimplemented
;
8064 goto cp0_unimplemented
;
8067 case CP0_REGISTER_24
:
8069 case CP0_REG24__DEPC
:
8071 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
8072 register_name
= "DEPC";
8075 goto cp0_unimplemented
;
8078 case CP0_REGISTER_25
:
8080 case CP0_REG25__PERFCTL0
:
8081 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Performance0
));
8082 register_name
= "Performance0";
8084 case CP0_REG25__PERFCNT0
:
8085 /* gen_helper_dmfc0_performance1(arg); */
8086 register_name
= "Performance1";
8087 goto cp0_unimplemented
;
8088 case CP0_REG25__PERFCTL1
:
8089 /* gen_helper_dmfc0_performance2(arg); */
8090 register_name
= "Performance2";
8091 goto cp0_unimplemented
;
8092 case CP0_REG25__PERFCNT1
:
8093 /* gen_helper_dmfc0_performance3(arg); */
8094 register_name
= "Performance3";
8095 goto cp0_unimplemented
;
8096 case CP0_REG25__PERFCTL2
:
8097 /* gen_helper_dmfc0_performance4(arg); */
8098 register_name
= "Performance4";
8099 goto cp0_unimplemented
;
8100 case CP0_REG25__PERFCNT2
:
8101 /* gen_helper_dmfc0_performance5(arg); */
8102 register_name
= "Performance5";
8103 goto cp0_unimplemented
;
8104 case CP0_REG25__PERFCTL3
:
8105 /* gen_helper_dmfc0_performance6(arg); */
8106 register_name
= "Performance6";
8107 goto cp0_unimplemented
;
8108 case CP0_REG25__PERFCNT3
:
8109 /* gen_helper_dmfc0_performance7(arg); */
8110 register_name
= "Performance7";
8111 goto cp0_unimplemented
;
8113 goto cp0_unimplemented
;
8116 case CP0_REGISTER_26
:
8118 case CP0_REG26__ERRCTL
:
8119 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_ErrCtl
));
8120 register_name
= "ErrCtl";
8123 goto cp0_unimplemented
;
8126 case CP0_REGISTER_27
:
8129 case CP0_REG27__CACHERR
:
8130 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
8131 register_name
= "CacheErr";
8134 goto cp0_unimplemented
;
8137 case CP0_REGISTER_28
:
8139 case CP0_REG28__TAGLO
:
8140 case CP0_REG28__TAGLO1
:
8141 case CP0_REG28__TAGLO2
:
8142 case CP0_REG28__TAGLO3
:
8143 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagLo
));
8144 register_name
= "TagLo";
8146 case CP0_REG28__DATALO
:
8147 case CP0_REG28__DATALO1
:
8148 case CP0_REG28__DATALO2
:
8149 case CP0_REG28__DATALO3
:
8150 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataLo
));
8151 register_name
= "DataLo";
8154 goto cp0_unimplemented
;
8157 case CP0_REGISTER_29
:
8159 case CP0_REG29__TAGHI
:
8160 case CP0_REG29__TAGHI1
:
8161 case CP0_REG29__TAGHI2
:
8162 case CP0_REG29__TAGHI3
:
8163 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagHi
));
8164 register_name
= "TagHi";
8166 case CP0_REG29__DATAHI
:
8167 case CP0_REG29__DATAHI1
:
8168 case CP0_REG29__DATAHI2
:
8169 case CP0_REG29__DATAHI3
:
8170 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataHi
));
8171 register_name
= "DataHi";
8174 goto cp0_unimplemented
;
8177 case CP0_REGISTER_30
:
8179 case CP0_REG30__ERROREPC
:
8180 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
8181 register_name
= "ErrorEPC";
8184 goto cp0_unimplemented
;
8187 case CP0_REGISTER_31
:
8189 case CP0_REG31__DESAVE
:
8191 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
8192 register_name
= "DESAVE";
8194 case CP0_REG31__KSCRATCH1
:
8195 case CP0_REG31__KSCRATCH2
:
8196 case CP0_REG31__KSCRATCH3
:
8197 case CP0_REG31__KSCRATCH4
:
8198 case CP0_REG31__KSCRATCH5
:
8199 case CP0_REG31__KSCRATCH6
:
8200 CP0_CHECK(ctx
->kscrexist
& (1 << sel
));
8201 tcg_gen_ld_tl(arg
, cpu_env
,
8202 offsetof(CPUMIPSState
, CP0_KScratch
[sel
- 2]));
8203 register_name
= "KScratch";
8206 goto cp0_unimplemented
;
8210 goto cp0_unimplemented
;
8212 trace_mips_translate_c0("dmfc0", register_name
, reg
, sel
);
8216 qemu_log_mask(LOG_UNIMP
, "dmfc0 %s (reg %d sel %d)\n",
8217 register_name
, reg
, sel
);
8218 gen_mfc0_unimplemented(ctx
, arg
);
8221 static void gen_dmtc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
8223 const char *register_name
= "invalid";
8226 check_insn(ctx
, ISA_MIPS_R1
);
8229 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
8234 case CP0_REGISTER_00
:
8236 case CP0_REG00__INDEX
:
8237 gen_helper_mtc0_index(cpu_env
, arg
);
8238 register_name
= "Index";
8240 case CP0_REG00__MVPCONTROL
:
8241 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8242 gen_helper_mtc0_mvpcontrol(cpu_env
, arg
);
8243 register_name
= "MVPControl";
8245 case CP0_REG00__MVPCONF0
:
8246 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8248 register_name
= "MVPConf0";
8250 case CP0_REG00__MVPCONF1
:
8251 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8253 register_name
= "MVPConf1";
8255 case CP0_REG00__VPCONTROL
:
8258 register_name
= "VPControl";
8261 goto cp0_unimplemented
;
8264 case CP0_REGISTER_01
:
8266 case CP0_REG01__RANDOM
:
8268 register_name
= "Random";
8270 case CP0_REG01__VPECONTROL
:
8271 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8272 gen_helper_mtc0_vpecontrol(cpu_env
, arg
);
8273 register_name
= "VPEControl";
8275 case CP0_REG01__VPECONF0
:
8276 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8277 gen_helper_mtc0_vpeconf0(cpu_env
, arg
);
8278 register_name
= "VPEConf0";
8280 case CP0_REG01__VPECONF1
:
8281 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8282 gen_helper_mtc0_vpeconf1(cpu_env
, arg
);
8283 register_name
= "VPEConf1";
8285 case CP0_REG01__YQMASK
:
8286 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8287 gen_helper_mtc0_yqmask(cpu_env
, arg
);
8288 register_name
= "YQMask";
8290 case CP0_REG01__VPESCHEDULE
:
8291 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8292 tcg_gen_st_tl(arg
, cpu_env
,
8293 offsetof(CPUMIPSState
, CP0_VPESchedule
));
8294 register_name
= "VPESchedule";
8296 case CP0_REG01__VPESCHEFBACK
:
8297 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8298 tcg_gen_st_tl(arg
, cpu_env
,
8299 offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
8300 register_name
= "VPEScheFBack";
8302 case CP0_REG01__VPEOPT
:
8303 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8304 gen_helper_mtc0_vpeopt(cpu_env
, arg
);
8305 register_name
= "VPEOpt";
8308 goto cp0_unimplemented
;
8311 case CP0_REGISTER_02
:
8313 case CP0_REG02__ENTRYLO0
:
8314 gen_helper_dmtc0_entrylo0(cpu_env
, arg
);
8315 register_name
= "EntryLo0";
8317 case CP0_REG02__TCSTATUS
:
8318 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8319 gen_helper_mtc0_tcstatus(cpu_env
, arg
);
8320 register_name
= "TCStatus";
8322 case CP0_REG02__TCBIND
:
8323 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8324 gen_helper_mtc0_tcbind(cpu_env
, arg
);
8325 register_name
= "TCBind";
8327 case CP0_REG02__TCRESTART
:
8328 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8329 gen_helper_mtc0_tcrestart(cpu_env
, arg
);
8330 register_name
= "TCRestart";
8332 case CP0_REG02__TCHALT
:
8333 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8334 gen_helper_mtc0_tchalt(cpu_env
, arg
);
8335 register_name
= "TCHalt";
8337 case CP0_REG02__TCCONTEXT
:
8338 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8339 gen_helper_mtc0_tccontext(cpu_env
, arg
);
8340 register_name
= "TCContext";
8342 case CP0_REG02__TCSCHEDULE
:
8343 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8344 gen_helper_mtc0_tcschedule(cpu_env
, arg
);
8345 register_name
= "TCSchedule";
8347 case CP0_REG02__TCSCHEFBACK
:
8348 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8349 gen_helper_mtc0_tcschefback(cpu_env
, arg
);
8350 register_name
= "TCScheFBack";
8353 goto cp0_unimplemented
;
8356 case CP0_REGISTER_03
:
8358 case CP0_REG03__ENTRYLO1
:
8359 gen_helper_dmtc0_entrylo1(cpu_env
, arg
);
8360 register_name
= "EntryLo1";
8362 case CP0_REG03__GLOBALNUM
:
8365 register_name
= "GlobalNumber";
8368 goto cp0_unimplemented
;
8371 case CP0_REGISTER_04
:
8373 case CP0_REG04__CONTEXT
:
8374 gen_helper_mtc0_context(cpu_env
, arg
);
8375 register_name
= "Context";
8377 case CP0_REG04__CONTEXTCONFIG
:
8379 /* gen_helper_dmtc0_contextconfig(arg); */
8380 register_name
= "ContextConfig";
8381 goto cp0_unimplemented
;
8382 case CP0_REG04__USERLOCAL
:
8383 CP0_CHECK(ctx
->ulri
);
8384 tcg_gen_st_tl(arg
, cpu_env
,
8385 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
8386 register_name
= "UserLocal";
8388 case CP0_REG04__MMID
:
8390 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_MemoryMapID
));
8391 register_name
= "MMID";
8394 goto cp0_unimplemented
;
8397 case CP0_REGISTER_05
:
8399 case CP0_REG05__PAGEMASK
:
8400 gen_helper_mtc0_pagemask(cpu_env
, arg
);
8401 register_name
= "PageMask";
8403 case CP0_REG05__PAGEGRAIN
:
8404 check_insn(ctx
, ISA_MIPS_R2
);
8405 gen_helper_mtc0_pagegrain(cpu_env
, arg
);
8406 register_name
= "PageGrain";
8408 case CP0_REG05__SEGCTL0
:
8410 gen_helper_mtc0_segctl0(cpu_env
, arg
);
8411 register_name
= "SegCtl0";
8413 case CP0_REG05__SEGCTL1
:
8415 gen_helper_mtc0_segctl1(cpu_env
, arg
);
8416 register_name
= "SegCtl1";
8418 case CP0_REG05__SEGCTL2
:
8420 gen_helper_mtc0_segctl2(cpu_env
, arg
);
8421 register_name
= "SegCtl2";
8423 case CP0_REG05__PWBASE
:
8425 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_PWBase
));
8426 register_name
= "PWBase";
8428 case CP0_REG05__PWFIELD
:
8430 gen_helper_mtc0_pwfield(cpu_env
, arg
);
8431 register_name
= "PWField";
8433 case CP0_REG05__PWSIZE
:
8435 gen_helper_mtc0_pwsize(cpu_env
, arg
);
8436 register_name
= "PWSize";
8439 goto cp0_unimplemented
;
8442 case CP0_REGISTER_06
:
8444 case CP0_REG06__WIRED
:
8445 gen_helper_mtc0_wired(cpu_env
, arg
);
8446 register_name
= "Wired";
8448 case CP0_REG06__SRSCONF0
:
8449 check_insn(ctx
, ISA_MIPS_R2
);
8450 gen_helper_mtc0_srsconf0(cpu_env
, arg
);
8451 register_name
= "SRSConf0";
8453 case CP0_REG06__SRSCONF1
:
8454 check_insn(ctx
, ISA_MIPS_R2
);
8455 gen_helper_mtc0_srsconf1(cpu_env
, arg
);
8456 register_name
= "SRSConf1";
8458 case CP0_REG06__SRSCONF2
:
8459 check_insn(ctx
, ISA_MIPS_R2
);
8460 gen_helper_mtc0_srsconf2(cpu_env
, arg
);
8461 register_name
= "SRSConf2";
8463 case CP0_REG06__SRSCONF3
:
8464 check_insn(ctx
, ISA_MIPS_R2
);
8465 gen_helper_mtc0_srsconf3(cpu_env
, arg
);
8466 register_name
= "SRSConf3";
8468 case CP0_REG06__SRSCONF4
:
8469 check_insn(ctx
, ISA_MIPS_R2
);
8470 gen_helper_mtc0_srsconf4(cpu_env
, arg
);
8471 register_name
= "SRSConf4";
8473 case CP0_REG06__PWCTL
:
8475 gen_helper_mtc0_pwctl(cpu_env
, arg
);
8476 register_name
= "PWCtl";
8479 goto cp0_unimplemented
;
8482 case CP0_REGISTER_07
:
8484 case CP0_REG07__HWRENA
:
8485 check_insn(ctx
, ISA_MIPS_R2
);
8486 gen_helper_mtc0_hwrena(cpu_env
, arg
);
8487 ctx
->base
.is_jmp
= DISAS_STOP
;
8488 register_name
= "HWREna";
8491 goto cp0_unimplemented
;
8494 case CP0_REGISTER_08
:
8496 case CP0_REG08__BADVADDR
:
8498 register_name
= "BadVAddr";
8500 case CP0_REG08__BADINSTR
:
8502 register_name
= "BadInstr";
8504 case CP0_REG08__BADINSTRP
:
8506 register_name
= "BadInstrP";
8508 case CP0_REG08__BADINSTRX
:
8510 register_name
= "BadInstrX";
8513 goto cp0_unimplemented
;
8516 case CP0_REGISTER_09
:
8518 case CP0_REG09__COUNT
:
8519 gen_helper_mtc0_count(cpu_env
, arg
);
8520 register_name
= "Count";
8522 case CP0_REG09__SAARI
:
8523 CP0_CHECK(ctx
->saar
);
8524 gen_helper_mtc0_saari(cpu_env
, arg
);
8525 register_name
= "SAARI";
8527 case CP0_REG09__SAAR
:
8528 CP0_CHECK(ctx
->saar
);
8529 gen_helper_mtc0_saar(cpu_env
, arg
);
8530 register_name
= "SAAR";
8533 goto cp0_unimplemented
;
8535 /* Stop translation as we may have switched the execution mode */
8536 ctx
->base
.is_jmp
= DISAS_STOP
;
8538 case CP0_REGISTER_10
:
8540 case CP0_REG10__ENTRYHI
:
8541 gen_helper_mtc0_entryhi(cpu_env
, arg
);
8542 register_name
= "EntryHi";
8545 goto cp0_unimplemented
;
8548 case CP0_REGISTER_11
:
8550 case CP0_REG11__COMPARE
:
8551 gen_helper_mtc0_compare(cpu_env
, arg
);
8552 register_name
= "Compare";
8554 /* 6,7 are implementation dependent */
8556 goto cp0_unimplemented
;
8558 /* Stop translation as we may have switched the execution mode */
8559 ctx
->base
.is_jmp
= DISAS_STOP
;
8561 case CP0_REGISTER_12
:
8563 case CP0_REG12__STATUS
:
8564 save_cpu_state(ctx
, 1);
8565 gen_helper_mtc0_status(cpu_env
, arg
);
8566 /* DISAS_STOP isn't good enough here, hflags may have changed. */
8567 gen_save_pc(ctx
->base
.pc_next
+ 4);
8568 ctx
->base
.is_jmp
= DISAS_EXIT
;
8569 register_name
= "Status";
8571 case CP0_REG12__INTCTL
:
8572 check_insn(ctx
, ISA_MIPS_R2
);
8573 gen_helper_mtc0_intctl(cpu_env
, arg
);
8574 /* Stop translation as we may have switched the execution mode */
8575 ctx
->base
.is_jmp
= DISAS_STOP
;
8576 register_name
= "IntCtl";
8578 case CP0_REG12__SRSCTL
:
8579 check_insn(ctx
, ISA_MIPS_R2
);
8580 gen_helper_mtc0_srsctl(cpu_env
, arg
);
8581 /* Stop translation as we may have switched the execution mode */
8582 ctx
->base
.is_jmp
= DISAS_STOP
;
8583 register_name
= "SRSCtl";
8585 case CP0_REG12__SRSMAP
:
8586 check_insn(ctx
, ISA_MIPS_R2
);
8587 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
8588 /* Stop translation as we may have switched the execution mode */
8589 ctx
->base
.is_jmp
= DISAS_STOP
;
8590 register_name
= "SRSMap";
8593 goto cp0_unimplemented
;
8596 case CP0_REGISTER_13
:
8598 case CP0_REG13__CAUSE
:
8599 save_cpu_state(ctx
, 1);
8600 gen_helper_mtc0_cause(cpu_env
, arg
);
8602 * Stop translation as we may have triggered an interrupt.
8603 * DISAS_STOP isn't sufficient, we need to ensure we break out of
8604 * translated code to check for pending interrupts.
8606 gen_save_pc(ctx
->base
.pc_next
+ 4);
8607 ctx
->base
.is_jmp
= DISAS_EXIT
;
8608 register_name
= "Cause";
8611 goto cp0_unimplemented
;
8614 case CP0_REGISTER_14
:
8616 case CP0_REG14__EPC
:
8617 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
8618 register_name
= "EPC";
8621 goto cp0_unimplemented
;
8624 case CP0_REGISTER_15
:
8626 case CP0_REG15__PRID
:
8628 register_name
= "PRid";
8630 case CP0_REG15__EBASE
:
8631 check_insn(ctx
, ISA_MIPS_R2
);
8632 gen_helper_mtc0_ebase(cpu_env
, arg
);
8633 register_name
= "EBase";
8636 goto cp0_unimplemented
;
8639 case CP0_REGISTER_16
:
8641 case CP0_REG16__CONFIG
:
8642 gen_helper_mtc0_config0(cpu_env
, arg
);
8643 register_name
= "Config";
8644 /* Stop translation as we may have switched the execution mode */
8645 ctx
->base
.is_jmp
= DISAS_STOP
;
8647 case CP0_REG16__CONFIG1
:
8648 /* ignored, read only */
8649 register_name
= "Config1";
8651 case CP0_REG16__CONFIG2
:
8652 gen_helper_mtc0_config2(cpu_env
, arg
);
8653 register_name
= "Config2";
8654 /* Stop translation as we may have switched the execution mode */
8655 ctx
->base
.is_jmp
= DISAS_STOP
;
8657 case CP0_REG16__CONFIG3
:
8658 gen_helper_mtc0_config3(cpu_env
, arg
);
8659 register_name
= "Config3";
8660 /* Stop translation as we may have switched the execution mode */
8661 ctx
->base
.is_jmp
= DISAS_STOP
;
8663 case CP0_REG16__CONFIG4
:
8664 /* currently ignored */
8665 register_name
= "Config4";
8667 case CP0_REG16__CONFIG5
:
8668 gen_helper_mtc0_config5(cpu_env
, arg
);
8669 register_name
= "Config5";
8670 /* Stop translation as we may have switched the execution mode */
8671 ctx
->base
.is_jmp
= DISAS_STOP
;
8673 /* 6,7 are implementation dependent */
8675 register_name
= "Invalid config selector";
8676 goto cp0_unimplemented
;
8679 case CP0_REGISTER_17
:
8681 case CP0_REG17__LLADDR
:
8682 gen_helper_mtc0_lladdr(cpu_env
, arg
);
8683 register_name
= "LLAddr";
8685 case CP0_REG17__MAAR
:
8686 CP0_CHECK(ctx
->mrp
);
8687 gen_helper_mtc0_maar(cpu_env
, arg
);
8688 register_name
= "MAAR";
8690 case CP0_REG17__MAARI
:
8691 CP0_CHECK(ctx
->mrp
);
8692 gen_helper_mtc0_maari(cpu_env
, arg
);
8693 register_name
= "MAARI";
8696 goto cp0_unimplemented
;
8699 case CP0_REGISTER_18
:
8701 case CP0_REG18__WATCHLO0
:
8702 case CP0_REG18__WATCHLO1
:
8703 case CP0_REG18__WATCHLO2
:
8704 case CP0_REG18__WATCHLO3
:
8705 case CP0_REG18__WATCHLO4
:
8706 case CP0_REG18__WATCHLO5
:
8707 case CP0_REG18__WATCHLO6
:
8708 case CP0_REG18__WATCHLO7
:
8709 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
8710 gen_helper_0e1i(mtc0_watchlo
, arg
, sel
);
8711 register_name
= "WatchLo";
8714 goto cp0_unimplemented
;
8717 case CP0_REGISTER_19
:
8719 case CP0_REG19__WATCHHI0
:
8720 case CP0_REG19__WATCHHI1
:
8721 case CP0_REG19__WATCHHI2
:
8722 case CP0_REG19__WATCHHI3
:
8723 case CP0_REG19__WATCHHI4
:
8724 case CP0_REG19__WATCHHI5
:
8725 case CP0_REG19__WATCHHI6
:
8726 case CP0_REG19__WATCHHI7
:
8727 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
8728 gen_helper_0e1i(mtc0_watchhi
, arg
, sel
);
8729 register_name
= "WatchHi";
8732 goto cp0_unimplemented
;
8735 case CP0_REGISTER_20
:
8737 case CP0_REG20__XCONTEXT
:
8738 check_insn(ctx
, ISA_MIPS3
);
8739 gen_helper_mtc0_xcontext(cpu_env
, arg
);
8740 register_name
= "XContext";
8743 goto cp0_unimplemented
;
8746 case CP0_REGISTER_21
:
8747 /* Officially reserved, but sel 0 is used for R1x000 framemask */
8748 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS_R6
));
8751 gen_helper_mtc0_framemask(cpu_env
, arg
);
8752 register_name
= "Framemask";
8755 goto cp0_unimplemented
;
8758 case CP0_REGISTER_22
:
8760 register_name
= "Diagnostic"; /* implementation dependent */
8762 case CP0_REGISTER_23
:
8764 case CP0_REG23__DEBUG
:
8765 gen_helper_mtc0_debug(cpu_env
, arg
); /* EJTAG support */
8766 /* DISAS_STOP isn't good enough here, hflags may have changed. */
8767 gen_save_pc(ctx
->base
.pc_next
+ 4);
8768 ctx
->base
.is_jmp
= DISAS_EXIT
;
8769 register_name
= "Debug";
8771 case CP0_REG23__TRACECONTROL
:
8772 /* PDtrace support */
8773 /* gen_helper_mtc0_tracecontrol(cpu_env, arg); */
8774 /* Stop translation as we may have switched the execution mode */
8775 ctx
->base
.is_jmp
= DISAS_STOP
;
8776 register_name
= "TraceControl";
8777 goto cp0_unimplemented
;
8778 case CP0_REG23__TRACECONTROL2
:
8779 /* PDtrace support */
8780 /* gen_helper_mtc0_tracecontrol2(cpu_env, arg); */
8781 /* Stop translation as we may have switched the execution mode */
8782 ctx
->base
.is_jmp
= DISAS_STOP
;
8783 register_name
= "TraceControl2";
8784 goto cp0_unimplemented
;
8785 case CP0_REG23__USERTRACEDATA1
:
8786 /* PDtrace support */
8787 /* gen_helper_mtc0_usertracedata1(cpu_env, arg);*/
8788 /* Stop translation as we may have switched the execution mode */
8789 ctx
->base
.is_jmp
= DISAS_STOP
;
8790 register_name
= "UserTraceData1";
8791 goto cp0_unimplemented
;
8792 case CP0_REG23__TRACEIBPC
:
8793 /* PDtrace support */
8794 /* gen_helper_mtc0_traceibpc(cpu_env, arg); */
8795 /* Stop translation as we may have switched the execution mode */
8796 ctx
->base
.is_jmp
= DISAS_STOP
;
8797 register_name
= "TraceIBPC";
8798 goto cp0_unimplemented
;
8799 case CP0_REG23__TRACEDBPC
:
8800 /* PDtrace support */
8801 /* gen_helper_mtc0_tracedbpc(cpu_env, arg); */
8802 /* Stop translation as we may have switched the execution mode */
8803 ctx
->base
.is_jmp
= DISAS_STOP
;
8804 register_name
= "TraceDBPC";
8805 goto cp0_unimplemented
;
8807 goto cp0_unimplemented
;
8810 case CP0_REGISTER_24
:
8812 case CP0_REG24__DEPC
:
8814 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
8815 register_name
= "DEPC";
8818 goto cp0_unimplemented
;
8821 case CP0_REGISTER_25
:
8823 case CP0_REG25__PERFCTL0
:
8824 gen_helper_mtc0_performance0(cpu_env
, arg
);
8825 register_name
= "Performance0";
8827 case CP0_REG25__PERFCNT0
:
8828 /* gen_helper_mtc0_performance1(cpu_env, arg); */
8829 register_name
= "Performance1";
8830 goto cp0_unimplemented
;
8831 case CP0_REG25__PERFCTL1
:
8832 /* gen_helper_mtc0_performance2(cpu_env, arg); */
8833 register_name
= "Performance2";
8834 goto cp0_unimplemented
;
8835 case CP0_REG25__PERFCNT1
:
8836 /* gen_helper_mtc0_performance3(cpu_env, arg); */
8837 register_name
= "Performance3";
8838 goto cp0_unimplemented
;
8839 case CP0_REG25__PERFCTL2
:
8840 /* gen_helper_mtc0_performance4(cpu_env, arg); */
8841 register_name
= "Performance4";
8842 goto cp0_unimplemented
;
8843 case CP0_REG25__PERFCNT2
:
8844 /* gen_helper_mtc0_performance5(cpu_env, arg); */
8845 register_name
= "Performance5";
8846 goto cp0_unimplemented
;
8847 case CP0_REG25__PERFCTL3
:
8848 /* gen_helper_mtc0_performance6(cpu_env, arg); */
8849 register_name
= "Performance6";
8850 goto cp0_unimplemented
;
8851 case CP0_REG25__PERFCNT3
:
8852 /* gen_helper_mtc0_performance7(cpu_env, arg); */
8853 register_name
= "Performance7";
8854 goto cp0_unimplemented
;
8856 goto cp0_unimplemented
;
8859 case CP0_REGISTER_26
:
8861 case CP0_REG26__ERRCTL
:
8862 gen_helper_mtc0_errctl(cpu_env
, arg
);
8863 ctx
->base
.is_jmp
= DISAS_STOP
;
8864 register_name
= "ErrCtl";
8867 goto cp0_unimplemented
;
8870 case CP0_REGISTER_27
:
8872 case CP0_REG27__CACHERR
:
8874 register_name
= "CacheErr";
8877 goto cp0_unimplemented
;
8880 case CP0_REGISTER_28
:
8882 case CP0_REG28__TAGLO
:
8883 case CP0_REG28__TAGLO1
:
8884 case CP0_REG28__TAGLO2
:
8885 case CP0_REG28__TAGLO3
:
8886 gen_helper_mtc0_taglo(cpu_env
, arg
);
8887 register_name
= "TagLo";
8889 case CP0_REG28__DATALO
:
8890 case CP0_REG28__DATALO1
:
8891 case CP0_REG28__DATALO2
:
8892 case CP0_REG28__DATALO3
:
8893 gen_helper_mtc0_datalo(cpu_env
, arg
);
8894 register_name
= "DataLo";
8897 goto cp0_unimplemented
;
8900 case CP0_REGISTER_29
:
8902 case CP0_REG29__TAGHI
:
8903 case CP0_REG29__TAGHI1
:
8904 case CP0_REG29__TAGHI2
:
8905 case CP0_REG29__TAGHI3
:
8906 gen_helper_mtc0_taghi(cpu_env
, arg
);
8907 register_name
= "TagHi";
8909 case CP0_REG29__DATAHI
:
8910 case CP0_REG29__DATAHI1
:
8911 case CP0_REG29__DATAHI2
:
8912 case CP0_REG29__DATAHI3
:
8913 gen_helper_mtc0_datahi(cpu_env
, arg
);
8914 register_name
= "DataHi";
8917 register_name
= "invalid sel";
8918 goto cp0_unimplemented
;
8921 case CP0_REGISTER_30
:
8923 case CP0_REG30__ERROREPC
:
8924 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
8925 register_name
= "ErrorEPC";
8928 goto cp0_unimplemented
;
8931 case CP0_REGISTER_31
:
8933 case CP0_REG31__DESAVE
:
8935 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
8936 register_name
= "DESAVE";
8938 case CP0_REG31__KSCRATCH1
:
8939 case CP0_REG31__KSCRATCH2
:
8940 case CP0_REG31__KSCRATCH3
:
8941 case CP0_REG31__KSCRATCH4
:
8942 case CP0_REG31__KSCRATCH5
:
8943 case CP0_REG31__KSCRATCH6
:
8944 CP0_CHECK(ctx
->kscrexist
& (1 << sel
));
8945 tcg_gen_st_tl(arg
, cpu_env
,
8946 offsetof(CPUMIPSState
, CP0_KScratch
[sel
- 2]));
8947 register_name
= "KScratch";
8950 goto cp0_unimplemented
;
8954 goto cp0_unimplemented
;
8956 trace_mips_translate_c0("dmtc0", register_name
, reg
, sel
);
8958 /* For simplicity assume that all writes can cause interrupts. */
8959 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
8961 * DISAS_STOP isn't sufficient, we need to ensure we break out of
8962 * translated code to check for pending interrupts.
8964 gen_save_pc(ctx
->base
.pc_next
+ 4);
8965 ctx
->base
.is_jmp
= DISAS_EXIT
;
8970 qemu_log_mask(LOG_UNIMP
, "dmtc0 %s (reg %d sel %d)\n",
8971 register_name
, reg
, sel
);
8973 #endif /* TARGET_MIPS64 */
8975 static void gen_mftr(CPUMIPSState
*env
, DisasContext
*ctx
, int rt
, int rd
,
8976 int u
, int sel
, int h
)
8978 int other_tc
= env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
);
8979 TCGv t0
= tcg_temp_local_new();
8981 if ((env
->CP0_VPEConf0
& (1 << CP0VPEC0_MVP
)) == 0 &&
8982 ((env
->tcs
[other_tc
].CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)) !=
8983 (env
->active_tc
.CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)))) {
8984 tcg_gen_movi_tl(t0
, -1);
8985 } else if ((env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
)) >
8986 (env
->mvp
->CP0_MVPConf0
& (0xff << CP0MVPC0_PTC
))) {
8987 tcg_gen_movi_tl(t0
, -1);
8988 } else if (u
== 0) {
8993 gen_helper_mftc0_vpecontrol(t0
, cpu_env
);
8996 gen_helper_mftc0_vpeconf0(t0
, cpu_env
);
9006 gen_helper_mftc0_tcstatus(t0
, cpu_env
);
9009 gen_helper_mftc0_tcbind(t0
, cpu_env
);
9012 gen_helper_mftc0_tcrestart(t0
, cpu_env
);
9015 gen_helper_mftc0_tchalt(t0
, cpu_env
);
9018 gen_helper_mftc0_tccontext(t0
, cpu_env
);
9021 gen_helper_mftc0_tcschedule(t0
, cpu_env
);
9024 gen_helper_mftc0_tcschefback(t0
, cpu_env
);
9027 gen_mfc0(ctx
, t0
, rt
, sel
);
9034 gen_helper_mftc0_entryhi(t0
, cpu_env
);
9037 gen_mfc0(ctx
, t0
, rt
, sel
);
9044 gen_helper_mftc0_status(t0
, cpu_env
);
9047 gen_mfc0(ctx
, t0
, rt
, sel
);
9054 gen_helper_mftc0_cause(t0
, cpu_env
);
9064 gen_helper_mftc0_epc(t0
, cpu_env
);
9074 gen_helper_mftc0_ebase(t0
, cpu_env
);
9091 gen_helper_mftc0_configx(t0
, cpu_env
, tcg_const_tl(sel
));
9101 gen_helper_mftc0_debug(t0
, cpu_env
);
9104 gen_mfc0(ctx
, t0
, rt
, sel
);
9109 gen_mfc0(ctx
, t0
, rt
, sel
);
9113 /* GPR registers. */
9115 gen_helper_1e0i(mftgpr
, t0
, rt
);
9117 /* Auxiliary CPU registers */
9121 gen_helper_1e0i(mftlo
, t0
, 0);
9124 gen_helper_1e0i(mfthi
, t0
, 0);
9127 gen_helper_1e0i(mftacx
, t0
, 0);
9130 gen_helper_1e0i(mftlo
, t0
, 1);
9133 gen_helper_1e0i(mfthi
, t0
, 1);
9136 gen_helper_1e0i(mftacx
, t0
, 1);
9139 gen_helper_1e0i(mftlo
, t0
, 2);
9142 gen_helper_1e0i(mfthi
, t0
, 2);
9145 gen_helper_1e0i(mftacx
, t0
, 2);
9148 gen_helper_1e0i(mftlo
, t0
, 3);
9151 gen_helper_1e0i(mfthi
, t0
, 3);
9154 gen_helper_1e0i(mftacx
, t0
, 3);
9157 gen_helper_mftdsp(t0
, cpu_env
);
9163 /* Floating point (COP1). */
9165 /* XXX: For now we support only a single FPU context. */
9167 TCGv_i32 fp0
= tcg_temp_new_i32();
9169 gen_load_fpr32(ctx
, fp0
, rt
);
9170 tcg_gen_ext_i32_tl(t0
, fp0
);
9171 tcg_temp_free_i32(fp0
);
9173 TCGv_i32 fp0
= tcg_temp_new_i32();
9175 gen_load_fpr32h(ctx
, fp0
, rt
);
9176 tcg_gen_ext_i32_tl(t0
, fp0
);
9177 tcg_temp_free_i32(fp0
);
9181 /* XXX: For now we support only a single FPU context. */
9182 gen_helper_1e0i(cfc1
, t0
, rt
);
9184 /* COP2: Not implemented. */
9192 trace_mips_translate_tr("mftr", rt
, u
, sel
, h
);
9193 gen_store_gpr(t0
, rd
);
9199 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt
, u
, sel
, h
);
9200 gen_reserved_instruction(ctx
);
9203 static void gen_mttr(CPUMIPSState
*env
, DisasContext
*ctx
, int rd
, int rt
,
9204 int u
, int sel
, int h
)
9206 int other_tc
= env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
);
9207 TCGv t0
= tcg_temp_local_new();
9209 gen_load_gpr(t0
, rt
);
9210 if ((env
->CP0_VPEConf0
& (1 << CP0VPEC0_MVP
)) == 0 &&
9211 ((env
->tcs
[other_tc
].CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)) !=
9212 (env
->active_tc
.CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)))) {
9215 } else if ((env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
)) >
9216 (env
->mvp
->CP0_MVPConf0
& (0xff << CP0MVPC0_PTC
))) {
9219 } else if (u
== 0) {
9224 gen_helper_mttc0_vpecontrol(cpu_env
, t0
);
9227 gen_helper_mttc0_vpeconf0(cpu_env
, t0
);
9237 gen_helper_mttc0_tcstatus(cpu_env
, t0
);
9240 gen_helper_mttc0_tcbind(cpu_env
, t0
);
9243 gen_helper_mttc0_tcrestart(cpu_env
, t0
);
9246 gen_helper_mttc0_tchalt(cpu_env
, t0
);
9249 gen_helper_mttc0_tccontext(cpu_env
, t0
);
9252 gen_helper_mttc0_tcschedule(cpu_env
, t0
);
9255 gen_helper_mttc0_tcschefback(cpu_env
, t0
);
9258 gen_mtc0(ctx
, t0
, rd
, sel
);
9265 gen_helper_mttc0_entryhi(cpu_env
, t0
);
9268 gen_mtc0(ctx
, t0
, rd
, sel
);
9275 gen_helper_mttc0_status(cpu_env
, t0
);
9278 gen_mtc0(ctx
, t0
, rd
, sel
);
9285 gen_helper_mttc0_cause(cpu_env
, t0
);
9295 gen_helper_mttc0_ebase(cpu_env
, t0
);
9305 gen_helper_mttc0_debug(cpu_env
, t0
);
9308 gen_mtc0(ctx
, t0
, rd
, sel
);
9313 gen_mtc0(ctx
, t0
, rd
, sel
);
9317 /* GPR registers. */
9319 gen_helper_0e1i(mttgpr
, t0
, rd
);
9321 /* Auxiliary CPU registers */
9325 gen_helper_0e1i(mttlo
, t0
, 0);
9328 gen_helper_0e1i(mtthi
, t0
, 0);
9331 gen_helper_0e1i(mttacx
, t0
, 0);
9334 gen_helper_0e1i(mttlo
, t0
, 1);
9337 gen_helper_0e1i(mtthi
, t0
, 1);
9340 gen_helper_0e1i(mttacx
, t0
, 1);
9343 gen_helper_0e1i(mttlo
, t0
, 2);
9346 gen_helper_0e1i(mtthi
, t0
, 2);
9349 gen_helper_0e1i(mttacx
, t0
, 2);
9352 gen_helper_0e1i(mttlo
, t0
, 3);
9355 gen_helper_0e1i(mtthi
, t0
, 3);
9358 gen_helper_0e1i(mttacx
, t0
, 3);
9361 gen_helper_mttdsp(cpu_env
, t0
);
9367 /* Floating point (COP1). */
9369 /* XXX: For now we support only a single FPU context. */
9371 TCGv_i32 fp0
= tcg_temp_new_i32();
9373 tcg_gen_trunc_tl_i32(fp0
, t0
);
9374 gen_store_fpr32(ctx
, fp0
, rd
);
9375 tcg_temp_free_i32(fp0
);
9377 TCGv_i32 fp0
= tcg_temp_new_i32();
9379 tcg_gen_trunc_tl_i32(fp0
, t0
);
9380 gen_store_fpr32h(ctx
, fp0
, rd
);
9381 tcg_temp_free_i32(fp0
);
9385 /* XXX: For now we support only a single FPU context. */
9387 TCGv_i32 fs_tmp
= tcg_const_i32(rd
);
9389 gen_helper_0e2i(ctc1
, t0
, fs_tmp
, rt
);
9390 tcg_temp_free_i32(fs_tmp
);
9392 /* Stop translation as we may have changed hflags */
9393 ctx
->base
.is_jmp
= DISAS_STOP
;
9395 /* COP2: Not implemented. */
9403 trace_mips_translate_tr("mttr", rd
, u
, sel
, h
);
9409 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd
, u
, sel
, h
);
9410 gen_reserved_instruction(ctx
);
9413 static void gen_cp0(CPUMIPSState
*env
, DisasContext
*ctx
, uint32_t opc
,
9416 const char *opn
= "ldst";
9418 check_cp0_enabled(ctx
);
9425 gen_mfc0(ctx
, cpu_gpr
[rt
], rd
, ctx
->opcode
& 0x7);
9430 TCGv t0
= tcg_temp_new();
9432 gen_load_gpr(t0
, rt
);
9433 gen_mtc0(ctx
, t0
, rd
, ctx
->opcode
& 0x7);
9438 #if defined(TARGET_MIPS64)
9440 check_insn(ctx
, ISA_MIPS3
);
9445 gen_dmfc0(ctx
, cpu_gpr
[rt
], rd
, ctx
->opcode
& 0x7);
9449 check_insn(ctx
, ISA_MIPS3
);
9451 TCGv t0
= tcg_temp_new();
9453 gen_load_gpr(t0
, rt
);
9454 gen_dmtc0(ctx
, t0
, rd
, ctx
->opcode
& 0x7);
9466 gen_mfhc0(ctx
, cpu_gpr
[rt
], rd
, ctx
->opcode
& 0x7);
9472 TCGv t0
= tcg_temp_new();
9473 gen_load_gpr(t0
, rt
);
9474 gen_mthc0(ctx
, t0
, rd
, ctx
->opcode
& 0x7);
9480 check_cp0_enabled(ctx
);
9485 gen_mftr(env
, ctx
, rt
, rd
, (ctx
->opcode
>> 5) & 1,
9486 ctx
->opcode
& 0x7, (ctx
->opcode
>> 4) & 1);
9490 check_cp0_enabled(ctx
);
9491 gen_mttr(env
, ctx
, rd
, rt
, (ctx
->opcode
>> 5) & 1,
9492 ctx
->opcode
& 0x7, (ctx
->opcode
>> 4) & 1);
9497 if (!env
->tlb
->helper_tlbwi
) {
9500 gen_helper_tlbwi(cpu_env
);
9505 if (!env
->tlb
->helper_tlbinv
) {
9508 gen_helper_tlbinv(cpu_env
);
9509 } /* treat as nop if TLBINV not supported */
9514 if (!env
->tlb
->helper_tlbinvf
) {
9517 gen_helper_tlbinvf(cpu_env
);
9518 } /* treat as nop if TLBINV not supported */
9522 if (!env
->tlb
->helper_tlbwr
) {
9525 gen_helper_tlbwr(cpu_env
);
9529 if (!env
->tlb
->helper_tlbp
) {
9532 gen_helper_tlbp(cpu_env
);
9536 if (!env
->tlb
->helper_tlbr
) {
9539 gen_helper_tlbr(cpu_env
);
9541 case OPC_ERET
: /* OPC_ERETNC */
9542 if ((ctx
->insn_flags
& ISA_MIPS_R6
) &&
9543 (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
9546 int bit_shift
= (ctx
->hflags
& MIPS_HFLAG_M16
) ? 16 : 6;
9547 if (ctx
->opcode
& (1 << bit_shift
)) {
9550 check_insn(ctx
, ISA_MIPS_R5
);
9551 gen_helper_eretnc(cpu_env
);
9555 check_insn(ctx
, ISA_MIPS2
);
9556 gen_helper_eret(cpu_env
);
9558 ctx
->base
.is_jmp
= DISAS_EXIT
;
9563 check_insn(ctx
, ISA_MIPS_R1
);
9564 if ((ctx
->insn_flags
& ISA_MIPS_R6
) &&
9565 (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
9568 if (!(ctx
->hflags
& MIPS_HFLAG_DM
)) {
9570 gen_reserved_instruction(ctx
);
9572 gen_helper_deret(cpu_env
);
9573 ctx
->base
.is_jmp
= DISAS_EXIT
;
9578 check_insn(ctx
, ISA_MIPS3
| ISA_MIPS_R1
);
9579 if ((ctx
->insn_flags
& ISA_MIPS_R6
) &&
9580 (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
9583 /* If we get an exception, we want to restart at next instruction */
9584 ctx
->base
.pc_next
+= 4;
9585 save_cpu_state(ctx
, 1);
9586 ctx
->base
.pc_next
-= 4;
9587 gen_helper_wait(cpu_env
);
9588 ctx
->base
.is_jmp
= DISAS_NORETURN
;
9593 gen_reserved_instruction(ctx
);
9596 (void)opn
; /* avoid a compiler warning */
9598 #endif /* !CONFIG_USER_ONLY */
9600 /* CP1 Branches (before delay slot) */
9601 static void gen_compute_branch1(DisasContext
*ctx
, uint32_t op
,
9602 int32_t cc
, int32_t offset
)
9604 target_ulong btarget
;
9605 TCGv_i32 t0
= tcg_temp_new_i32();
9607 if ((ctx
->insn_flags
& ISA_MIPS_R6
) && (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
9608 gen_reserved_instruction(ctx
);
9613 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS_R1
);
9616 btarget
= ctx
->base
.pc_next
+ 4 + offset
;
9620 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
9621 tcg_gen_not_i32(t0
, t0
);
9622 tcg_gen_andi_i32(t0
, t0
, 1);
9623 tcg_gen_extu_i32_tl(bcond
, t0
);
9626 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
9627 tcg_gen_not_i32(t0
, t0
);
9628 tcg_gen_andi_i32(t0
, t0
, 1);
9629 tcg_gen_extu_i32_tl(bcond
, t0
);
9632 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
9633 tcg_gen_andi_i32(t0
, t0
, 1);
9634 tcg_gen_extu_i32_tl(bcond
, t0
);
9637 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
9638 tcg_gen_andi_i32(t0
, t0
, 1);
9639 tcg_gen_extu_i32_tl(bcond
, t0
);
9641 ctx
->hflags
|= MIPS_HFLAG_BL
;
9645 TCGv_i32 t1
= tcg_temp_new_i32();
9646 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
9647 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 1));
9648 tcg_gen_nand_i32(t0
, t0
, t1
);
9649 tcg_temp_free_i32(t1
);
9650 tcg_gen_andi_i32(t0
, t0
, 1);
9651 tcg_gen_extu_i32_tl(bcond
, t0
);
9656 TCGv_i32 t1
= tcg_temp_new_i32();
9657 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
9658 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 1));
9659 tcg_gen_or_i32(t0
, t0
, t1
);
9660 tcg_temp_free_i32(t1
);
9661 tcg_gen_andi_i32(t0
, t0
, 1);
9662 tcg_gen_extu_i32_tl(bcond
, t0
);
9667 TCGv_i32 t1
= tcg_temp_new_i32();
9668 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
9669 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 1));
9670 tcg_gen_and_i32(t0
, t0
, t1
);
9671 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 2));
9672 tcg_gen_and_i32(t0
, t0
, t1
);
9673 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 3));
9674 tcg_gen_nand_i32(t0
, t0
, t1
);
9675 tcg_temp_free_i32(t1
);
9676 tcg_gen_andi_i32(t0
, t0
, 1);
9677 tcg_gen_extu_i32_tl(bcond
, t0
);
9682 TCGv_i32 t1
= tcg_temp_new_i32();
9683 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
9684 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 1));
9685 tcg_gen_or_i32(t0
, t0
, t1
);
9686 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 2));
9687 tcg_gen_or_i32(t0
, t0
, t1
);
9688 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 3));
9689 tcg_gen_or_i32(t0
, t0
, t1
);
9690 tcg_temp_free_i32(t1
);
9691 tcg_gen_andi_i32(t0
, t0
, 1);
9692 tcg_gen_extu_i32_tl(bcond
, t0
);
9695 ctx
->hflags
|= MIPS_HFLAG_BC
;
9698 MIPS_INVAL("cp1 cond branch");
9699 gen_reserved_instruction(ctx
);
9702 ctx
->btarget
= btarget
;
9703 ctx
->hflags
|= MIPS_HFLAG_BDS32
;
9705 tcg_temp_free_i32(t0
);
9708 /* R6 CP1 Branches */
9709 static void gen_compute_branch1_r6(DisasContext
*ctx
, uint32_t op
,
9710 int32_t ft
, int32_t offset
,
9713 target_ulong btarget
;
9714 TCGv_i64 t0
= tcg_temp_new_i64();
9716 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
9717 #ifdef MIPS_DEBUG_DISAS
9718 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
9719 "\n", ctx
->base
.pc_next
);
9721 gen_reserved_instruction(ctx
);
9725 gen_load_fpr64(ctx
, t0
, ft
);
9726 tcg_gen_andi_i64(t0
, t0
, 1);
9728 btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
9732 tcg_gen_xori_i64(t0
, t0
, 1);
9733 ctx
->hflags
|= MIPS_HFLAG_BC
;
9736 /* t0 already set */
9737 ctx
->hflags
|= MIPS_HFLAG_BC
;
9740 MIPS_INVAL("cp1 cond branch");
9741 gen_reserved_instruction(ctx
);
9745 tcg_gen_trunc_i64_tl(bcond
, t0
);
9747 ctx
->btarget
= btarget
;
9749 switch (delayslot_size
) {
9751 ctx
->hflags
|= MIPS_HFLAG_BDS16
;
9754 ctx
->hflags
|= MIPS_HFLAG_BDS32
;
9759 tcg_temp_free_i64(t0
);
9762 /* Coprocessor 1 (FPU) */
9764 #define FOP(func, fmt) (((fmt) << 21) | (func))
9767 OPC_ADD_S
= FOP(0, FMT_S
),
9768 OPC_SUB_S
= FOP(1, FMT_S
),
9769 OPC_MUL_S
= FOP(2, FMT_S
),
9770 OPC_DIV_S
= FOP(3, FMT_S
),
9771 OPC_SQRT_S
= FOP(4, FMT_S
),
9772 OPC_ABS_S
= FOP(5, FMT_S
),
9773 OPC_MOV_S
= FOP(6, FMT_S
),
9774 OPC_NEG_S
= FOP(7, FMT_S
),
9775 OPC_ROUND_L_S
= FOP(8, FMT_S
),
9776 OPC_TRUNC_L_S
= FOP(9, FMT_S
),
9777 OPC_CEIL_L_S
= FOP(10, FMT_S
),
9778 OPC_FLOOR_L_S
= FOP(11, FMT_S
),
9779 OPC_ROUND_W_S
= FOP(12, FMT_S
),
9780 OPC_TRUNC_W_S
= FOP(13, FMT_S
),
9781 OPC_CEIL_W_S
= FOP(14, FMT_S
),
9782 OPC_FLOOR_W_S
= FOP(15, FMT_S
),
9783 OPC_SEL_S
= FOP(16, FMT_S
),
9784 OPC_MOVCF_S
= FOP(17, FMT_S
),
9785 OPC_MOVZ_S
= FOP(18, FMT_S
),
9786 OPC_MOVN_S
= FOP(19, FMT_S
),
9787 OPC_SELEQZ_S
= FOP(20, FMT_S
),
9788 OPC_RECIP_S
= FOP(21, FMT_S
),
9789 OPC_RSQRT_S
= FOP(22, FMT_S
),
9790 OPC_SELNEZ_S
= FOP(23, FMT_S
),
9791 OPC_MADDF_S
= FOP(24, FMT_S
),
9792 OPC_MSUBF_S
= FOP(25, FMT_S
),
9793 OPC_RINT_S
= FOP(26, FMT_S
),
9794 OPC_CLASS_S
= FOP(27, FMT_S
),
9795 OPC_MIN_S
= FOP(28, FMT_S
),
9796 OPC_RECIP2_S
= FOP(28, FMT_S
),
9797 OPC_MINA_S
= FOP(29, FMT_S
),
9798 OPC_RECIP1_S
= FOP(29, FMT_S
),
9799 OPC_MAX_S
= FOP(30, FMT_S
),
9800 OPC_RSQRT1_S
= FOP(30, FMT_S
),
9801 OPC_MAXA_S
= FOP(31, FMT_S
),
9802 OPC_RSQRT2_S
= FOP(31, FMT_S
),
9803 OPC_CVT_D_S
= FOP(33, FMT_S
),
9804 OPC_CVT_W_S
= FOP(36, FMT_S
),
9805 OPC_CVT_L_S
= FOP(37, FMT_S
),
9806 OPC_CVT_PS_S
= FOP(38, FMT_S
),
9807 OPC_CMP_F_S
= FOP(48, FMT_S
),
9808 OPC_CMP_UN_S
= FOP(49, FMT_S
),
9809 OPC_CMP_EQ_S
= FOP(50, FMT_S
),
9810 OPC_CMP_UEQ_S
= FOP(51, FMT_S
),
9811 OPC_CMP_OLT_S
= FOP(52, FMT_S
),
9812 OPC_CMP_ULT_S
= FOP(53, FMT_S
),
9813 OPC_CMP_OLE_S
= FOP(54, FMT_S
),
9814 OPC_CMP_ULE_S
= FOP(55, FMT_S
),
9815 OPC_CMP_SF_S
= FOP(56, FMT_S
),
9816 OPC_CMP_NGLE_S
= FOP(57, FMT_S
),
9817 OPC_CMP_SEQ_S
= FOP(58, FMT_S
),
9818 OPC_CMP_NGL_S
= FOP(59, FMT_S
),
9819 OPC_CMP_LT_S
= FOP(60, FMT_S
),
9820 OPC_CMP_NGE_S
= FOP(61, FMT_S
),
9821 OPC_CMP_LE_S
= FOP(62, FMT_S
),
9822 OPC_CMP_NGT_S
= FOP(63, FMT_S
),
9824 OPC_ADD_D
= FOP(0, FMT_D
),
9825 OPC_SUB_D
= FOP(1, FMT_D
),
9826 OPC_MUL_D
= FOP(2, FMT_D
),
9827 OPC_DIV_D
= FOP(3, FMT_D
),
9828 OPC_SQRT_D
= FOP(4, FMT_D
),
9829 OPC_ABS_D
= FOP(5, FMT_D
),
9830 OPC_MOV_D
= FOP(6, FMT_D
),
9831 OPC_NEG_D
= FOP(7, FMT_D
),
9832 OPC_ROUND_L_D
= FOP(8, FMT_D
),
9833 OPC_TRUNC_L_D
= FOP(9, FMT_D
),
9834 OPC_CEIL_L_D
= FOP(10, FMT_D
),
9835 OPC_FLOOR_L_D
= FOP(11, FMT_D
),
9836 OPC_ROUND_W_D
= FOP(12, FMT_D
),
9837 OPC_TRUNC_W_D
= FOP(13, FMT_D
),
9838 OPC_CEIL_W_D
= FOP(14, FMT_D
),
9839 OPC_FLOOR_W_D
= FOP(15, FMT_D
),
9840 OPC_SEL_D
= FOP(16, FMT_D
),
9841 OPC_MOVCF_D
= FOP(17, FMT_D
),
9842 OPC_MOVZ_D
= FOP(18, FMT_D
),
9843 OPC_MOVN_D
= FOP(19, FMT_D
),
9844 OPC_SELEQZ_D
= FOP(20, FMT_D
),
9845 OPC_RECIP_D
= FOP(21, FMT_D
),
9846 OPC_RSQRT_D
= FOP(22, FMT_D
),
9847 OPC_SELNEZ_D
= FOP(23, FMT_D
),
9848 OPC_MADDF_D
= FOP(24, FMT_D
),
9849 OPC_MSUBF_D
= FOP(25, FMT_D
),
9850 OPC_RINT_D
= FOP(26, FMT_D
),
9851 OPC_CLASS_D
= FOP(27, FMT_D
),
9852 OPC_MIN_D
= FOP(28, FMT_D
),
9853 OPC_RECIP2_D
= FOP(28, FMT_D
),
9854 OPC_MINA_D
= FOP(29, FMT_D
),
9855 OPC_RECIP1_D
= FOP(29, FMT_D
),
9856 OPC_MAX_D
= FOP(30, FMT_D
),
9857 OPC_RSQRT1_D
= FOP(30, FMT_D
),
9858 OPC_MAXA_D
= FOP(31, FMT_D
),
9859 OPC_RSQRT2_D
= FOP(31, FMT_D
),
9860 OPC_CVT_S_D
= FOP(32, FMT_D
),
9861 OPC_CVT_W_D
= FOP(36, FMT_D
),
9862 OPC_CVT_L_D
= FOP(37, FMT_D
),
9863 OPC_CMP_F_D
= FOP(48, FMT_D
),
9864 OPC_CMP_UN_D
= FOP(49, FMT_D
),
9865 OPC_CMP_EQ_D
= FOP(50, FMT_D
),
9866 OPC_CMP_UEQ_D
= FOP(51, FMT_D
),
9867 OPC_CMP_OLT_D
= FOP(52, FMT_D
),
9868 OPC_CMP_ULT_D
= FOP(53, FMT_D
),
9869 OPC_CMP_OLE_D
= FOP(54, FMT_D
),
9870 OPC_CMP_ULE_D
= FOP(55, FMT_D
),
9871 OPC_CMP_SF_D
= FOP(56, FMT_D
),
9872 OPC_CMP_NGLE_D
= FOP(57, FMT_D
),
9873 OPC_CMP_SEQ_D
= FOP(58, FMT_D
),
9874 OPC_CMP_NGL_D
= FOP(59, FMT_D
),
9875 OPC_CMP_LT_D
= FOP(60, FMT_D
),
9876 OPC_CMP_NGE_D
= FOP(61, FMT_D
),
9877 OPC_CMP_LE_D
= FOP(62, FMT_D
),
9878 OPC_CMP_NGT_D
= FOP(63, FMT_D
),
9880 OPC_CVT_S_W
= FOP(32, FMT_W
),
9881 OPC_CVT_D_W
= FOP(33, FMT_W
),
9882 OPC_CVT_S_L
= FOP(32, FMT_L
),
9883 OPC_CVT_D_L
= FOP(33, FMT_L
),
9884 OPC_CVT_PS_PW
= FOP(38, FMT_W
),
9886 OPC_ADD_PS
= FOP(0, FMT_PS
),
9887 OPC_SUB_PS
= FOP(1, FMT_PS
),
9888 OPC_MUL_PS
= FOP(2, FMT_PS
),
9889 OPC_DIV_PS
= FOP(3, FMT_PS
),
9890 OPC_ABS_PS
= FOP(5, FMT_PS
),
9891 OPC_MOV_PS
= FOP(6, FMT_PS
),
9892 OPC_NEG_PS
= FOP(7, FMT_PS
),
9893 OPC_MOVCF_PS
= FOP(17, FMT_PS
),
9894 OPC_MOVZ_PS
= FOP(18, FMT_PS
),
9895 OPC_MOVN_PS
= FOP(19, FMT_PS
),
9896 OPC_ADDR_PS
= FOP(24, FMT_PS
),
9897 OPC_MULR_PS
= FOP(26, FMT_PS
),
9898 OPC_RECIP2_PS
= FOP(28, FMT_PS
),
9899 OPC_RECIP1_PS
= FOP(29, FMT_PS
),
9900 OPC_RSQRT1_PS
= FOP(30, FMT_PS
),
9901 OPC_RSQRT2_PS
= FOP(31, FMT_PS
),
9903 OPC_CVT_S_PU
= FOP(32, FMT_PS
),
9904 OPC_CVT_PW_PS
= FOP(36, FMT_PS
),
9905 OPC_CVT_S_PL
= FOP(40, FMT_PS
),
9906 OPC_PLL_PS
= FOP(44, FMT_PS
),
9907 OPC_PLU_PS
= FOP(45, FMT_PS
),
9908 OPC_PUL_PS
= FOP(46, FMT_PS
),
9909 OPC_PUU_PS
= FOP(47, FMT_PS
),
9910 OPC_CMP_F_PS
= FOP(48, FMT_PS
),
9911 OPC_CMP_UN_PS
= FOP(49, FMT_PS
),
9912 OPC_CMP_EQ_PS
= FOP(50, FMT_PS
),
9913 OPC_CMP_UEQ_PS
= FOP(51, FMT_PS
),
9914 OPC_CMP_OLT_PS
= FOP(52, FMT_PS
),
9915 OPC_CMP_ULT_PS
= FOP(53, FMT_PS
),
9916 OPC_CMP_OLE_PS
= FOP(54, FMT_PS
),
9917 OPC_CMP_ULE_PS
= FOP(55, FMT_PS
),
9918 OPC_CMP_SF_PS
= FOP(56, FMT_PS
),
9919 OPC_CMP_NGLE_PS
= FOP(57, FMT_PS
),
9920 OPC_CMP_SEQ_PS
= FOP(58, FMT_PS
),
9921 OPC_CMP_NGL_PS
= FOP(59, FMT_PS
),
9922 OPC_CMP_LT_PS
= FOP(60, FMT_PS
),
9923 OPC_CMP_NGE_PS
= FOP(61, FMT_PS
),
9924 OPC_CMP_LE_PS
= FOP(62, FMT_PS
),
9925 OPC_CMP_NGT_PS
= FOP(63, FMT_PS
),
9929 R6_OPC_CMP_AF_S
= FOP(0, FMT_W
),
9930 R6_OPC_CMP_UN_S
= FOP(1, FMT_W
),
9931 R6_OPC_CMP_EQ_S
= FOP(2, FMT_W
),
9932 R6_OPC_CMP_UEQ_S
= FOP(3, FMT_W
),
9933 R6_OPC_CMP_LT_S
= FOP(4, FMT_W
),
9934 R6_OPC_CMP_ULT_S
= FOP(5, FMT_W
),
9935 R6_OPC_CMP_LE_S
= FOP(6, FMT_W
),
9936 R6_OPC_CMP_ULE_S
= FOP(7, FMT_W
),
9937 R6_OPC_CMP_SAF_S
= FOP(8, FMT_W
),
9938 R6_OPC_CMP_SUN_S
= FOP(9, FMT_W
),
9939 R6_OPC_CMP_SEQ_S
= FOP(10, FMT_W
),
9940 R6_OPC_CMP_SEUQ_S
= FOP(11, FMT_W
),
9941 R6_OPC_CMP_SLT_S
= FOP(12, FMT_W
),
9942 R6_OPC_CMP_SULT_S
= FOP(13, FMT_W
),
9943 R6_OPC_CMP_SLE_S
= FOP(14, FMT_W
),
9944 R6_OPC_CMP_SULE_S
= FOP(15, FMT_W
),
9945 R6_OPC_CMP_OR_S
= FOP(17, FMT_W
),
9946 R6_OPC_CMP_UNE_S
= FOP(18, FMT_W
),
9947 R6_OPC_CMP_NE_S
= FOP(19, FMT_W
),
9948 R6_OPC_CMP_SOR_S
= FOP(25, FMT_W
),
9949 R6_OPC_CMP_SUNE_S
= FOP(26, FMT_W
),
9950 R6_OPC_CMP_SNE_S
= FOP(27, FMT_W
),
9952 R6_OPC_CMP_AF_D
= FOP(0, FMT_L
),
9953 R6_OPC_CMP_UN_D
= FOP(1, FMT_L
),
9954 R6_OPC_CMP_EQ_D
= FOP(2, FMT_L
),
9955 R6_OPC_CMP_UEQ_D
= FOP(3, FMT_L
),
9956 R6_OPC_CMP_LT_D
= FOP(4, FMT_L
),
9957 R6_OPC_CMP_ULT_D
= FOP(5, FMT_L
),
9958 R6_OPC_CMP_LE_D
= FOP(6, FMT_L
),
9959 R6_OPC_CMP_ULE_D
= FOP(7, FMT_L
),
9960 R6_OPC_CMP_SAF_D
= FOP(8, FMT_L
),
9961 R6_OPC_CMP_SUN_D
= FOP(9, FMT_L
),
9962 R6_OPC_CMP_SEQ_D
= FOP(10, FMT_L
),
9963 R6_OPC_CMP_SEUQ_D
= FOP(11, FMT_L
),
9964 R6_OPC_CMP_SLT_D
= FOP(12, FMT_L
),
9965 R6_OPC_CMP_SULT_D
= FOP(13, FMT_L
),
9966 R6_OPC_CMP_SLE_D
= FOP(14, FMT_L
),
9967 R6_OPC_CMP_SULE_D
= FOP(15, FMT_L
),
9968 R6_OPC_CMP_OR_D
= FOP(17, FMT_L
),
9969 R6_OPC_CMP_UNE_D
= FOP(18, FMT_L
),
9970 R6_OPC_CMP_NE_D
= FOP(19, FMT_L
),
9971 R6_OPC_CMP_SOR_D
= FOP(25, FMT_L
),
9972 R6_OPC_CMP_SUNE_D
= FOP(26, FMT_L
),
9973 R6_OPC_CMP_SNE_D
= FOP(27, FMT_L
),
9976 static void gen_cp1(DisasContext
*ctx
, uint32_t opc
, int rt
, int fs
)
9978 TCGv t0
= tcg_temp_new();
9983 TCGv_i32 fp0
= tcg_temp_new_i32();
9985 gen_load_fpr32(ctx
, fp0
, fs
);
9986 tcg_gen_ext_i32_tl(t0
, fp0
);
9987 tcg_temp_free_i32(fp0
);
9989 gen_store_gpr(t0
, rt
);
9992 gen_load_gpr(t0
, rt
);
9994 TCGv_i32 fp0
= tcg_temp_new_i32();
9996 tcg_gen_trunc_tl_i32(fp0
, t0
);
9997 gen_store_fpr32(ctx
, fp0
, fs
);
9998 tcg_temp_free_i32(fp0
);
10002 gen_helper_1e0i(cfc1
, t0
, fs
);
10003 gen_store_gpr(t0
, rt
);
10006 gen_load_gpr(t0
, rt
);
10007 save_cpu_state(ctx
, 0);
10009 TCGv_i32 fs_tmp
= tcg_const_i32(fs
);
10011 gen_helper_0e2i(ctc1
, t0
, fs_tmp
, rt
);
10012 tcg_temp_free_i32(fs_tmp
);
10014 /* Stop translation as we may have changed hflags */
10015 ctx
->base
.is_jmp
= DISAS_STOP
;
10017 #if defined(TARGET_MIPS64)
10019 gen_load_fpr64(ctx
, t0
, fs
);
10020 gen_store_gpr(t0
, rt
);
10023 gen_load_gpr(t0
, rt
);
10024 gen_store_fpr64(ctx
, t0
, fs
);
10029 TCGv_i32 fp0
= tcg_temp_new_i32();
10031 gen_load_fpr32h(ctx
, fp0
, fs
);
10032 tcg_gen_ext_i32_tl(t0
, fp0
);
10033 tcg_temp_free_i32(fp0
);
10035 gen_store_gpr(t0
, rt
);
10038 gen_load_gpr(t0
, rt
);
10040 TCGv_i32 fp0
= tcg_temp_new_i32();
10042 tcg_gen_trunc_tl_i32(fp0
, t0
);
10043 gen_store_fpr32h(ctx
, fp0
, fs
);
10044 tcg_temp_free_i32(fp0
);
10048 MIPS_INVAL("cp1 move");
10049 gen_reserved_instruction(ctx
);
10057 static void gen_movci(DisasContext
*ctx
, int rd
, int rs
, int cc
, int tf
)
10064 /* Treat as NOP. */
10069 cond
= TCG_COND_EQ
;
10071 cond
= TCG_COND_NE
;
10074 l1
= gen_new_label();
10075 t0
= tcg_temp_new_i32();
10076 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
10077 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
10078 tcg_temp_free_i32(t0
);
10079 gen_load_gpr(cpu_gpr
[rd
], rs
);
10083 static inline void gen_movcf_s(DisasContext
*ctx
, int fs
, int fd
, int cc
,
10087 TCGv_i32 t0
= tcg_temp_new_i32();
10088 TCGLabel
*l1
= gen_new_label();
10091 cond
= TCG_COND_EQ
;
10093 cond
= TCG_COND_NE
;
10096 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
10097 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
10098 gen_load_fpr32(ctx
, t0
, fs
);
10099 gen_store_fpr32(ctx
, t0
, fd
);
10101 tcg_temp_free_i32(t0
);
10104 static inline void gen_movcf_d(DisasContext
*ctx
, int fs
, int fd
, int cc
,
10108 TCGv_i32 t0
= tcg_temp_new_i32();
10110 TCGLabel
*l1
= gen_new_label();
10113 cond
= TCG_COND_EQ
;
10115 cond
= TCG_COND_NE
;
10118 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
10119 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
10120 tcg_temp_free_i32(t0
);
10121 fp0
= tcg_temp_new_i64();
10122 gen_load_fpr64(ctx
, fp0
, fs
);
10123 gen_store_fpr64(ctx
, fp0
, fd
);
10124 tcg_temp_free_i64(fp0
);
10128 static inline void gen_movcf_ps(DisasContext
*ctx
, int fs
, int fd
,
10132 TCGv_i32 t0
= tcg_temp_new_i32();
10133 TCGLabel
*l1
= gen_new_label();
10134 TCGLabel
*l2
= gen_new_label();
10137 cond
= TCG_COND_EQ
;
10139 cond
= TCG_COND_NE
;
10142 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
10143 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
10144 gen_load_fpr32(ctx
, t0
, fs
);
10145 gen_store_fpr32(ctx
, t0
, fd
);
10148 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
+ 1));
10149 tcg_gen_brcondi_i32(cond
, t0
, 0, l2
);
10150 gen_load_fpr32h(ctx
, t0
, fs
);
10151 gen_store_fpr32h(ctx
, t0
, fd
);
10152 tcg_temp_free_i32(t0
);
10156 static void gen_sel_s(DisasContext
*ctx
, enum fopcode op1
, int fd
, int ft
,
10159 TCGv_i32 t1
= tcg_const_i32(0);
10160 TCGv_i32 fp0
= tcg_temp_new_i32();
10161 TCGv_i32 fp1
= tcg_temp_new_i32();
10162 TCGv_i32 fp2
= tcg_temp_new_i32();
10163 gen_load_fpr32(ctx
, fp0
, fd
);
10164 gen_load_fpr32(ctx
, fp1
, ft
);
10165 gen_load_fpr32(ctx
, fp2
, fs
);
10169 tcg_gen_andi_i32(fp0
, fp0
, 1);
10170 tcg_gen_movcond_i32(TCG_COND_NE
, fp0
, fp0
, t1
, fp1
, fp2
);
10173 tcg_gen_andi_i32(fp1
, fp1
, 1);
10174 tcg_gen_movcond_i32(TCG_COND_EQ
, fp0
, fp1
, t1
, fp2
, t1
);
10177 tcg_gen_andi_i32(fp1
, fp1
, 1);
10178 tcg_gen_movcond_i32(TCG_COND_NE
, fp0
, fp1
, t1
, fp2
, t1
);
10181 MIPS_INVAL("gen_sel_s");
10182 gen_reserved_instruction(ctx
);
10186 gen_store_fpr32(ctx
, fp0
, fd
);
10187 tcg_temp_free_i32(fp2
);
10188 tcg_temp_free_i32(fp1
);
10189 tcg_temp_free_i32(fp0
);
10190 tcg_temp_free_i32(t1
);
10193 static void gen_sel_d(DisasContext
*ctx
, enum fopcode op1
, int fd
, int ft
,
10196 TCGv_i64 t1
= tcg_const_i64(0);
10197 TCGv_i64 fp0
= tcg_temp_new_i64();
10198 TCGv_i64 fp1
= tcg_temp_new_i64();
10199 TCGv_i64 fp2
= tcg_temp_new_i64();
10200 gen_load_fpr64(ctx
, fp0
, fd
);
10201 gen_load_fpr64(ctx
, fp1
, ft
);
10202 gen_load_fpr64(ctx
, fp2
, fs
);
10206 tcg_gen_andi_i64(fp0
, fp0
, 1);
10207 tcg_gen_movcond_i64(TCG_COND_NE
, fp0
, fp0
, t1
, fp1
, fp2
);
10210 tcg_gen_andi_i64(fp1
, fp1
, 1);
10211 tcg_gen_movcond_i64(TCG_COND_EQ
, fp0
, fp1
, t1
, fp2
, t1
);
10214 tcg_gen_andi_i64(fp1
, fp1
, 1);
10215 tcg_gen_movcond_i64(TCG_COND_NE
, fp0
, fp1
, t1
, fp2
, t1
);
10218 MIPS_INVAL("gen_sel_d");
10219 gen_reserved_instruction(ctx
);
10223 gen_store_fpr64(ctx
, fp0
, fd
);
10224 tcg_temp_free_i64(fp2
);
10225 tcg_temp_free_i64(fp1
);
10226 tcg_temp_free_i64(fp0
);
10227 tcg_temp_free_i64(t1
);
10230 static void gen_farith(DisasContext
*ctx
, enum fopcode op1
,
10231 int ft
, int fs
, int fd
, int cc
)
10233 uint32_t func
= ctx
->opcode
& 0x3f;
10237 TCGv_i32 fp0
= tcg_temp_new_i32();
10238 TCGv_i32 fp1
= tcg_temp_new_i32();
10240 gen_load_fpr32(ctx
, fp0
, fs
);
10241 gen_load_fpr32(ctx
, fp1
, ft
);
10242 gen_helper_float_add_s(fp0
, cpu_env
, fp0
, fp1
);
10243 tcg_temp_free_i32(fp1
);
10244 gen_store_fpr32(ctx
, fp0
, fd
);
10245 tcg_temp_free_i32(fp0
);
10250 TCGv_i32 fp0
= tcg_temp_new_i32();
10251 TCGv_i32 fp1
= tcg_temp_new_i32();
10253 gen_load_fpr32(ctx
, fp0
, fs
);
10254 gen_load_fpr32(ctx
, fp1
, ft
);
10255 gen_helper_float_sub_s(fp0
, cpu_env
, fp0
, fp1
);
10256 tcg_temp_free_i32(fp1
);
10257 gen_store_fpr32(ctx
, fp0
, fd
);
10258 tcg_temp_free_i32(fp0
);
10263 TCGv_i32 fp0
= tcg_temp_new_i32();
10264 TCGv_i32 fp1
= tcg_temp_new_i32();
10266 gen_load_fpr32(ctx
, fp0
, fs
);
10267 gen_load_fpr32(ctx
, fp1
, ft
);
10268 gen_helper_float_mul_s(fp0
, cpu_env
, fp0
, fp1
);
10269 tcg_temp_free_i32(fp1
);
10270 gen_store_fpr32(ctx
, fp0
, fd
);
10271 tcg_temp_free_i32(fp0
);
10276 TCGv_i32 fp0
= tcg_temp_new_i32();
10277 TCGv_i32 fp1
= tcg_temp_new_i32();
10279 gen_load_fpr32(ctx
, fp0
, fs
);
10280 gen_load_fpr32(ctx
, fp1
, ft
);
10281 gen_helper_float_div_s(fp0
, cpu_env
, fp0
, fp1
);
10282 tcg_temp_free_i32(fp1
);
10283 gen_store_fpr32(ctx
, fp0
, fd
);
10284 tcg_temp_free_i32(fp0
);
10289 TCGv_i32 fp0
= tcg_temp_new_i32();
10291 gen_load_fpr32(ctx
, fp0
, fs
);
10292 gen_helper_float_sqrt_s(fp0
, cpu_env
, fp0
);
10293 gen_store_fpr32(ctx
, fp0
, fd
);
10294 tcg_temp_free_i32(fp0
);
10299 TCGv_i32 fp0
= tcg_temp_new_i32();
10301 gen_load_fpr32(ctx
, fp0
, fs
);
10302 if (ctx
->abs2008
) {
10303 tcg_gen_andi_i32(fp0
, fp0
, 0x7fffffffUL
);
10305 gen_helper_float_abs_s(fp0
, fp0
);
10307 gen_store_fpr32(ctx
, fp0
, fd
);
10308 tcg_temp_free_i32(fp0
);
10313 TCGv_i32 fp0
= tcg_temp_new_i32();
10315 gen_load_fpr32(ctx
, fp0
, fs
);
10316 gen_store_fpr32(ctx
, fp0
, fd
);
10317 tcg_temp_free_i32(fp0
);
10322 TCGv_i32 fp0
= tcg_temp_new_i32();
10324 gen_load_fpr32(ctx
, fp0
, fs
);
10325 if (ctx
->abs2008
) {
10326 tcg_gen_xori_i32(fp0
, fp0
, 1UL << 31);
10328 gen_helper_float_chs_s(fp0
, fp0
);
10330 gen_store_fpr32(ctx
, fp0
, fd
);
10331 tcg_temp_free_i32(fp0
);
10334 case OPC_ROUND_L_S
:
10335 check_cp1_64bitmode(ctx
);
10337 TCGv_i32 fp32
= tcg_temp_new_i32();
10338 TCGv_i64 fp64
= tcg_temp_new_i64();
10340 gen_load_fpr32(ctx
, fp32
, fs
);
10341 if (ctx
->nan2008
) {
10342 gen_helper_float_round_2008_l_s(fp64
, cpu_env
, fp32
);
10344 gen_helper_float_round_l_s(fp64
, cpu_env
, fp32
);
10346 tcg_temp_free_i32(fp32
);
10347 gen_store_fpr64(ctx
, fp64
, fd
);
10348 tcg_temp_free_i64(fp64
);
10351 case OPC_TRUNC_L_S
:
10352 check_cp1_64bitmode(ctx
);
10354 TCGv_i32 fp32
= tcg_temp_new_i32();
10355 TCGv_i64 fp64
= tcg_temp_new_i64();
10357 gen_load_fpr32(ctx
, fp32
, fs
);
10358 if (ctx
->nan2008
) {
10359 gen_helper_float_trunc_2008_l_s(fp64
, cpu_env
, fp32
);
10361 gen_helper_float_trunc_l_s(fp64
, cpu_env
, fp32
);
10363 tcg_temp_free_i32(fp32
);
10364 gen_store_fpr64(ctx
, fp64
, fd
);
10365 tcg_temp_free_i64(fp64
);
10369 check_cp1_64bitmode(ctx
);
10371 TCGv_i32 fp32
= tcg_temp_new_i32();
10372 TCGv_i64 fp64
= tcg_temp_new_i64();
10374 gen_load_fpr32(ctx
, fp32
, fs
);
10375 if (ctx
->nan2008
) {
10376 gen_helper_float_ceil_2008_l_s(fp64
, cpu_env
, fp32
);
10378 gen_helper_float_ceil_l_s(fp64
, cpu_env
, fp32
);
10380 tcg_temp_free_i32(fp32
);
10381 gen_store_fpr64(ctx
, fp64
, fd
);
10382 tcg_temp_free_i64(fp64
);
10385 case OPC_FLOOR_L_S
:
10386 check_cp1_64bitmode(ctx
);
10388 TCGv_i32 fp32
= tcg_temp_new_i32();
10389 TCGv_i64 fp64
= tcg_temp_new_i64();
10391 gen_load_fpr32(ctx
, fp32
, fs
);
10392 if (ctx
->nan2008
) {
10393 gen_helper_float_floor_2008_l_s(fp64
, cpu_env
, fp32
);
10395 gen_helper_float_floor_l_s(fp64
, cpu_env
, fp32
);
10397 tcg_temp_free_i32(fp32
);
10398 gen_store_fpr64(ctx
, fp64
, fd
);
10399 tcg_temp_free_i64(fp64
);
10402 case OPC_ROUND_W_S
:
10404 TCGv_i32 fp0
= tcg_temp_new_i32();
10406 gen_load_fpr32(ctx
, fp0
, fs
);
10407 if (ctx
->nan2008
) {
10408 gen_helper_float_round_2008_w_s(fp0
, cpu_env
, fp0
);
10410 gen_helper_float_round_w_s(fp0
, cpu_env
, fp0
);
10412 gen_store_fpr32(ctx
, fp0
, fd
);
10413 tcg_temp_free_i32(fp0
);
10416 case OPC_TRUNC_W_S
:
10418 TCGv_i32 fp0
= tcg_temp_new_i32();
10420 gen_load_fpr32(ctx
, fp0
, fs
);
10421 if (ctx
->nan2008
) {
10422 gen_helper_float_trunc_2008_w_s(fp0
, cpu_env
, fp0
);
10424 gen_helper_float_trunc_w_s(fp0
, cpu_env
, fp0
);
10426 gen_store_fpr32(ctx
, fp0
, fd
);
10427 tcg_temp_free_i32(fp0
);
10432 TCGv_i32 fp0
= tcg_temp_new_i32();
10434 gen_load_fpr32(ctx
, fp0
, fs
);
10435 if (ctx
->nan2008
) {
10436 gen_helper_float_ceil_2008_w_s(fp0
, cpu_env
, fp0
);
10438 gen_helper_float_ceil_w_s(fp0
, cpu_env
, fp0
);
10440 gen_store_fpr32(ctx
, fp0
, fd
);
10441 tcg_temp_free_i32(fp0
);
10444 case OPC_FLOOR_W_S
:
10446 TCGv_i32 fp0
= tcg_temp_new_i32();
10448 gen_load_fpr32(ctx
, fp0
, fs
);
10449 if (ctx
->nan2008
) {
10450 gen_helper_float_floor_2008_w_s(fp0
, cpu_env
, fp0
);
10452 gen_helper_float_floor_w_s(fp0
, cpu_env
, fp0
);
10454 gen_store_fpr32(ctx
, fp0
, fd
);
10455 tcg_temp_free_i32(fp0
);
10459 check_insn(ctx
, ISA_MIPS_R6
);
10460 gen_sel_s(ctx
, op1
, fd
, ft
, fs
);
10463 check_insn(ctx
, ISA_MIPS_R6
);
10464 gen_sel_s(ctx
, op1
, fd
, ft
, fs
);
10467 check_insn(ctx
, ISA_MIPS_R6
);
10468 gen_sel_s(ctx
, op1
, fd
, ft
, fs
);
10471 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
10472 gen_movcf_s(ctx
, fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
10475 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
10477 TCGLabel
*l1
= gen_new_label();
10481 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
10483 fp0
= tcg_temp_new_i32();
10484 gen_load_fpr32(ctx
, fp0
, fs
);
10485 gen_store_fpr32(ctx
, fp0
, fd
);
10486 tcg_temp_free_i32(fp0
);
10491 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
10493 TCGLabel
*l1
= gen_new_label();
10497 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
10498 fp0
= tcg_temp_new_i32();
10499 gen_load_fpr32(ctx
, fp0
, fs
);
10500 gen_store_fpr32(ctx
, fp0
, fd
);
10501 tcg_temp_free_i32(fp0
);
10508 TCGv_i32 fp0
= tcg_temp_new_i32();
10510 gen_load_fpr32(ctx
, fp0
, fs
);
10511 gen_helper_float_recip_s(fp0
, cpu_env
, fp0
);
10512 gen_store_fpr32(ctx
, fp0
, fd
);
10513 tcg_temp_free_i32(fp0
);
10518 TCGv_i32 fp0
= tcg_temp_new_i32();
10520 gen_load_fpr32(ctx
, fp0
, fs
);
10521 gen_helper_float_rsqrt_s(fp0
, cpu_env
, fp0
);
10522 gen_store_fpr32(ctx
, fp0
, fd
);
10523 tcg_temp_free_i32(fp0
);
10527 check_insn(ctx
, ISA_MIPS_R6
);
10529 TCGv_i32 fp0
= tcg_temp_new_i32();
10530 TCGv_i32 fp1
= tcg_temp_new_i32();
10531 TCGv_i32 fp2
= tcg_temp_new_i32();
10532 gen_load_fpr32(ctx
, fp0
, fs
);
10533 gen_load_fpr32(ctx
, fp1
, ft
);
10534 gen_load_fpr32(ctx
, fp2
, fd
);
10535 gen_helper_float_maddf_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
10536 gen_store_fpr32(ctx
, fp2
, fd
);
10537 tcg_temp_free_i32(fp2
);
10538 tcg_temp_free_i32(fp1
);
10539 tcg_temp_free_i32(fp0
);
10543 check_insn(ctx
, ISA_MIPS_R6
);
10545 TCGv_i32 fp0
= tcg_temp_new_i32();
10546 TCGv_i32 fp1
= tcg_temp_new_i32();
10547 TCGv_i32 fp2
= tcg_temp_new_i32();
10548 gen_load_fpr32(ctx
, fp0
, fs
);
10549 gen_load_fpr32(ctx
, fp1
, ft
);
10550 gen_load_fpr32(ctx
, fp2
, fd
);
10551 gen_helper_float_msubf_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
10552 gen_store_fpr32(ctx
, fp2
, fd
);
10553 tcg_temp_free_i32(fp2
);
10554 tcg_temp_free_i32(fp1
);
10555 tcg_temp_free_i32(fp0
);
10559 check_insn(ctx
, ISA_MIPS_R6
);
10561 TCGv_i32 fp0
= tcg_temp_new_i32();
10562 gen_load_fpr32(ctx
, fp0
, fs
);
10563 gen_helper_float_rint_s(fp0
, cpu_env
, fp0
);
10564 gen_store_fpr32(ctx
, fp0
, fd
);
10565 tcg_temp_free_i32(fp0
);
10569 check_insn(ctx
, ISA_MIPS_R6
);
10571 TCGv_i32 fp0
= tcg_temp_new_i32();
10572 gen_load_fpr32(ctx
, fp0
, fs
);
10573 gen_helper_float_class_s(fp0
, cpu_env
, fp0
);
10574 gen_store_fpr32(ctx
, fp0
, fd
);
10575 tcg_temp_free_i32(fp0
);
10578 case OPC_MIN_S
: /* OPC_RECIP2_S */
10579 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
10581 TCGv_i32 fp0
= tcg_temp_new_i32();
10582 TCGv_i32 fp1
= tcg_temp_new_i32();
10583 TCGv_i32 fp2
= tcg_temp_new_i32();
10584 gen_load_fpr32(ctx
, fp0
, fs
);
10585 gen_load_fpr32(ctx
, fp1
, ft
);
10586 gen_helper_float_min_s(fp2
, cpu_env
, fp0
, fp1
);
10587 gen_store_fpr32(ctx
, fp2
, fd
);
10588 tcg_temp_free_i32(fp2
);
10589 tcg_temp_free_i32(fp1
);
10590 tcg_temp_free_i32(fp0
);
10593 check_cp1_64bitmode(ctx
);
10595 TCGv_i32 fp0
= tcg_temp_new_i32();
10596 TCGv_i32 fp1
= tcg_temp_new_i32();
10598 gen_load_fpr32(ctx
, fp0
, fs
);
10599 gen_load_fpr32(ctx
, fp1
, ft
);
10600 gen_helper_float_recip2_s(fp0
, cpu_env
, fp0
, fp1
);
10601 tcg_temp_free_i32(fp1
);
10602 gen_store_fpr32(ctx
, fp0
, fd
);
10603 tcg_temp_free_i32(fp0
);
10607 case OPC_MINA_S
: /* OPC_RECIP1_S */
10608 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
10610 TCGv_i32 fp0
= tcg_temp_new_i32();
10611 TCGv_i32 fp1
= tcg_temp_new_i32();
10612 TCGv_i32 fp2
= tcg_temp_new_i32();
10613 gen_load_fpr32(ctx
, fp0
, fs
);
10614 gen_load_fpr32(ctx
, fp1
, ft
);
10615 gen_helper_float_mina_s(fp2
, cpu_env
, fp0
, fp1
);
10616 gen_store_fpr32(ctx
, fp2
, fd
);
10617 tcg_temp_free_i32(fp2
);
10618 tcg_temp_free_i32(fp1
);
10619 tcg_temp_free_i32(fp0
);
10622 check_cp1_64bitmode(ctx
);
10624 TCGv_i32 fp0
= tcg_temp_new_i32();
10626 gen_load_fpr32(ctx
, fp0
, fs
);
10627 gen_helper_float_recip1_s(fp0
, cpu_env
, fp0
);
10628 gen_store_fpr32(ctx
, fp0
, fd
);
10629 tcg_temp_free_i32(fp0
);
10633 case OPC_MAX_S
: /* OPC_RSQRT1_S */
10634 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
10636 TCGv_i32 fp0
= tcg_temp_new_i32();
10637 TCGv_i32 fp1
= tcg_temp_new_i32();
10638 gen_load_fpr32(ctx
, fp0
, fs
);
10639 gen_load_fpr32(ctx
, fp1
, ft
);
10640 gen_helper_float_max_s(fp1
, cpu_env
, fp0
, fp1
);
10641 gen_store_fpr32(ctx
, fp1
, fd
);
10642 tcg_temp_free_i32(fp1
);
10643 tcg_temp_free_i32(fp0
);
10646 check_cp1_64bitmode(ctx
);
10648 TCGv_i32 fp0
= tcg_temp_new_i32();
10650 gen_load_fpr32(ctx
, fp0
, fs
);
10651 gen_helper_float_rsqrt1_s(fp0
, cpu_env
, fp0
);
10652 gen_store_fpr32(ctx
, fp0
, fd
);
10653 tcg_temp_free_i32(fp0
);
10657 case OPC_MAXA_S
: /* OPC_RSQRT2_S */
10658 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
10660 TCGv_i32 fp0
= tcg_temp_new_i32();
10661 TCGv_i32 fp1
= tcg_temp_new_i32();
10662 gen_load_fpr32(ctx
, fp0
, fs
);
10663 gen_load_fpr32(ctx
, fp1
, ft
);
10664 gen_helper_float_maxa_s(fp1
, cpu_env
, fp0
, fp1
);
10665 gen_store_fpr32(ctx
, fp1
, fd
);
10666 tcg_temp_free_i32(fp1
);
10667 tcg_temp_free_i32(fp0
);
10670 check_cp1_64bitmode(ctx
);
10672 TCGv_i32 fp0
= tcg_temp_new_i32();
10673 TCGv_i32 fp1
= tcg_temp_new_i32();
10675 gen_load_fpr32(ctx
, fp0
, fs
);
10676 gen_load_fpr32(ctx
, fp1
, ft
);
10677 gen_helper_float_rsqrt2_s(fp0
, cpu_env
, fp0
, fp1
);
10678 tcg_temp_free_i32(fp1
);
10679 gen_store_fpr32(ctx
, fp0
, fd
);
10680 tcg_temp_free_i32(fp0
);
10685 check_cp1_registers(ctx
, fd
);
10687 TCGv_i32 fp32
= tcg_temp_new_i32();
10688 TCGv_i64 fp64
= tcg_temp_new_i64();
10690 gen_load_fpr32(ctx
, fp32
, fs
);
10691 gen_helper_float_cvtd_s(fp64
, cpu_env
, fp32
);
10692 tcg_temp_free_i32(fp32
);
10693 gen_store_fpr64(ctx
, fp64
, fd
);
10694 tcg_temp_free_i64(fp64
);
10699 TCGv_i32 fp0
= tcg_temp_new_i32();
10701 gen_load_fpr32(ctx
, fp0
, fs
);
10702 if (ctx
->nan2008
) {
10703 gen_helper_float_cvt_2008_w_s(fp0
, cpu_env
, fp0
);
10705 gen_helper_float_cvt_w_s(fp0
, cpu_env
, fp0
);
10707 gen_store_fpr32(ctx
, fp0
, fd
);
10708 tcg_temp_free_i32(fp0
);
10712 check_cp1_64bitmode(ctx
);
10714 TCGv_i32 fp32
= tcg_temp_new_i32();
10715 TCGv_i64 fp64
= tcg_temp_new_i64();
10717 gen_load_fpr32(ctx
, fp32
, fs
);
10718 if (ctx
->nan2008
) {
10719 gen_helper_float_cvt_2008_l_s(fp64
, cpu_env
, fp32
);
10721 gen_helper_float_cvt_l_s(fp64
, cpu_env
, fp32
);
10723 tcg_temp_free_i32(fp32
);
10724 gen_store_fpr64(ctx
, fp64
, fd
);
10725 tcg_temp_free_i64(fp64
);
10731 TCGv_i64 fp64
= tcg_temp_new_i64();
10732 TCGv_i32 fp32_0
= tcg_temp_new_i32();
10733 TCGv_i32 fp32_1
= tcg_temp_new_i32();
10735 gen_load_fpr32(ctx
, fp32_0
, fs
);
10736 gen_load_fpr32(ctx
, fp32_1
, ft
);
10737 tcg_gen_concat_i32_i64(fp64
, fp32_1
, fp32_0
);
10738 tcg_temp_free_i32(fp32_1
);
10739 tcg_temp_free_i32(fp32_0
);
10740 gen_store_fpr64(ctx
, fp64
, fd
);
10741 tcg_temp_free_i64(fp64
);
10747 case OPC_CMP_UEQ_S
:
10748 case OPC_CMP_OLT_S
:
10749 case OPC_CMP_ULT_S
:
10750 case OPC_CMP_OLE_S
:
10751 case OPC_CMP_ULE_S
:
10753 case OPC_CMP_NGLE_S
:
10754 case OPC_CMP_SEQ_S
:
10755 case OPC_CMP_NGL_S
:
10757 case OPC_CMP_NGE_S
:
10759 case OPC_CMP_NGT_S
:
10760 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
10761 if (ctx
->opcode
& (1 << 6)) {
10762 gen_cmpabs_s(ctx
, func
- 48, ft
, fs
, cc
);
10764 gen_cmp_s(ctx
, func
- 48, ft
, fs
, cc
);
10768 check_cp1_registers(ctx
, fs
| ft
| fd
);
10770 TCGv_i64 fp0
= tcg_temp_new_i64();
10771 TCGv_i64 fp1
= tcg_temp_new_i64();
10773 gen_load_fpr64(ctx
, fp0
, fs
);
10774 gen_load_fpr64(ctx
, fp1
, ft
);
10775 gen_helper_float_add_d(fp0
, cpu_env
, fp0
, fp1
);
10776 tcg_temp_free_i64(fp1
);
10777 gen_store_fpr64(ctx
, fp0
, fd
);
10778 tcg_temp_free_i64(fp0
);
10782 check_cp1_registers(ctx
, fs
| ft
| fd
);
10784 TCGv_i64 fp0
= tcg_temp_new_i64();
10785 TCGv_i64 fp1
= tcg_temp_new_i64();
10787 gen_load_fpr64(ctx
, fp0
, fs
);
10788 gen_load_fpr64(ctx
, fp1
, ft
);
10789 gen_helper_float_sub_d(fp0
, cpu_env
, fp0
, fp1
);
10790 tcg_temp_free_i64(fp1
);
10791 gen_store_fpr64(ctx
, fp0
, fd
);
10792 tcg_temp_free_i64(fp0
);
10796 check_cp1_registers(ctx
, fs
| ft
| fd
);
10798 TCGv_i64 fp0
= tcg_temp_new_i64();
10799 TCGv_i64 fp1
= tcg_temp_new_i64();
10801 gen_load_fpr64(ctx
, fp0
, fs
);
10802 gen_load_fpr64(ctx
, fp1
, ft
);
10803 gen_helper_float_mul_d(fp0
, cpu_env
, fp0
, fp1
);
10804 tcg_temp_free_i64(fp1
);
10805 gen_store_fpr64(ctx
, fp0
, fd
);
10806 tcg_temp_free_i64(fp0
);
10810 check_cp1_registers(ctx
, fs
| ft
| fd
);
10812 TCGv_i64 fp0
= tcg_temp_new_i64();
10813 TCGv_i64 fp1
= tcg_temp_new_i64();
10815 gen_load_fpr64(ctx
, fp0
, fs
);
10816 gen_load_fpr64(ctx
, fp1
, ft
);
10817 gen_helper_float_div_d(fp0
, cpu_env
, fp0
, fp1
);
10818 tcg_temp_free_i64(fp1
);
10819 gen_store_fpr64(ctx
, fp0
, fd
);
10820 tcg_temp_free_i64(fp0
);
10824 check_cp1_registers(ctx
, fs
| fd
);
10826 TCGv_i64 fp0
= tcg_temp_new_i64();
10828 gen_load_fpr64(ctx
, fp0
, fs
);
10829 gen_helper_float_sqrt_d(fp0
, cpu_env
, fp0
);
10830 gen_store_fpr64(ctx
, fp0
, fd
);
10831 tcg_temp_free_i64(fp0
);
10835 check_cp1_registers(ctx
, fs
| fd
);
10837 TCGv_i64 fp0
= tcg_temp_new_i64();
10839 gen_load_fpr64(ctx
, fp0
, fs
);
10840 if (ctx
->abs2008
) {
10841 tcg_gen_andi_i64(fp0
, fp0
, 0x7fffffffffffffffULL
);
10843 gen_helper_float_abs_d(fp0
, fp0
);
10845 gen_store_fpr64(ctx
, fp0
, fd
);
10846 tcg_temp_free_i64(fp0
);
10850 check_cp1_registers(ctx
, fs
| fd
);
10852 TCGv_i64 fp0
= tcg_temp_new_i64();
10854 gen_load_fpr64(ctx
, fp0
, fs
);
10855 gen_store_fpr64(ctx
, fp0
, fd
);
10856 tcg_temp_free_i64(fp0
);
10860 check_cp1_registers(ctx
, fs
| fd
);
10862 TCGv_i64 fp0
= tcg_temp_new_i64();
10864 gen_load_fpr64(ctx
, fp0
, fs
);
10865 if (ctx
->abs2008
) {
10866 tcg_gen_xori_i64(fp0
, fp0
, 1ULL << 63);
10868 gen_helper_float_chs_d(fp0
, fp0
);
10870 gen_store_fpr64(ctx
, fp0
, fd
);
10871 tcg_temp_free_i64(fp0
);
10874 case OPC_ROUND_L_D
:
10875 check_cp1_64bitmode(ctx
);
10877 TCGv_i64 fp0
= tcg_temp_new_i64();
10879 gen_load_fpr64(ctx
, fp0
, fs
);
10880 if (ctx
->nan2008
) {
10881 gen_helper_float_round_2008_l_d(fp0
, cpu_env
, fp0
);
10883 gen_helper_float_round_l_d(fp0
, cpu_env
, fp0
);
10885 gen_store_fpr64(ctx
, fp0
, fd
);
10886 tcg_temp_free_i64(fp0
);
10889 case OPC_TRUNC_L_D
:
10890 check_cp1_64bitmode(ctx
);
10892 TCGv_i64 fp0
= tcg_temp_new_i64();
10894 gen_load_fpr64(ctx
, fp0
, fs
);
10895 if (ctx
->nan2008
) {
10896 gen_helper_float_trunc_2008_l_d(fp0
, cpu_env
, fp0
);
10898 gen_helper_float_trunc_l_d(fp0
, cpu_env
, fp0
);
10900 gen_store_fpr64(ctx
, fp0
, fd
);
10901 tcg_temp_free_i64(fp0
);
10905 check_cp1_64bitmode(ctx
);
10907 TCGv_i64 fp0
= tcg_temp_new_i64();
10909 gen_load_fpr64(ctx
, fp0
, fs
);
10910 if (ctx
->nan2008
) {
10911 gen_helper_float_ceil_2008_l_d(fp0
, cpu_env
, fp0
);
10913 gen_helper_float_ceil_l_d(fp0
, cpu_env
, fp0
);
10915 gen_store_fpr64(ctx
, fp0
, fd
);
10916 tcg_temp_free_i64(fp0
);
10919 case OPC_FLOOR_L_D
:
10920 check_cp1_64bitmode(ctx
);
10922 TCGv_i64 fp0
= tcg_temp_new_i64();
10924 gen_load_fpr64(ctx
, fp0
, fs
);
10925 if (ctx
->nan2008
) {
10926 gen_helper_float_floor_2008_l_d(fp0
, cpu_env
, fp0
);
10928 gen_helper_float_floor_l_d(fp0
, cpu_env
, fp0
);
10930 gen_store_fpr64(ctx
, fp0
, fd
);
10931 tcg_temp_free_i64(fp0
);
10934 case OPC_ROUND_W_D
:
10935 check_cp1_registers(ctx
, fs
);
10937 TCGv_i32 fp32
= tcg_temp_new_i32();
10938 TCGv_i64 fp64
= tcg_temp_new_i64();
10940 gen_load_fpr64(ctx
, fp64
, fs
);
10941 if (ctx
->nan2008
) {
10942 gen_helper_float_round_2008_w_d(fp32
, cpu_env
, fp64
);
10944 gen_helper_float_round_w_d(fp32
, cpu_env
, fp64
);
10946 tcg_temp_free_i64(fp64
);
10947 gen_store_fpr32(ctx
, fp32
, fd
);
10948 tcg_temp_free_i32(fp32
);
10951 case OPC_TRUNC_W_D
:
10952 check_cp1_registers(ctx
, fs
);
10954 TCGv_i32 fp32
= tcg_temp_new_i32();
10955 TCGv_i64 fp64
= tcg_temp_new_i64();
10957 gen_load_fpr64(ctx
, fp64
, fs
);
10958 if (ctx
->nan2008
) {
10959 gen_helper_float_trunc_2008_w_d(fp32
, cpu_env
, fp64
);
10961 gen_helper_float_trunc_w_d(fp32
, cpu_env
, fp64
);
10963 tcg_temp_free_i64(fp64
);
10964 gen_store_fpr32(ctx
, fp32
, fd
);
10965 tcg_temp_free_i32(fp32
);
10969 check_cp1_registers(ctx
, fs
);
10971 TCGv_i32 fp32
= tcg_temp_new_i32();
10972 TCGv_i64 fp64
= tcg_temp_new_i64();
10974 gen_load_fpr64(ctx
, fp64
, fs
);
10975 if (ctx
->nan2008
) {
10976 gen_helper_float_ceil_2008_w_d(fp32
, cpu_env
, fp64
);
10978 gen_helper_float_ceil_w_d(fp32
, cpu_env
, fp64
);
10980 tcg_temp_free_i64(fp64
);
10981 gen_store_fpr32(ctx
, fp32
, fd
);
10982 tcg_temp_free_i32(fp32
);
10985 case OPC_FLOOR_W_D
:
10986 check_cp1_registers(ctx
, fs
);
10988 TCGv_i32 fp32
= tcg_temp_new_i32();
10989 TCGv_i64 fp64
= tcg_temp_new_i64();
10991 gen_load_fpr64(ctx
, fp64
, fs
);
10992 if (ctx
->nan2008
) {
10993 gen_helper_float_floor_2008_w_d(fp32
, cpu_env
, fp64
);
10995 gen_helper_float_floor_w_d(fp32
, cpu_env
, fp64
);
10997 tcg_temp_free_i64(fp64
);
10998 gen_store_fpr32(ctx
, fp32
, fd
);
10999 tcg_temp_free_i32(fp32
);
11003 check_insn(ctx
, ISA_MIPS_R6
);
11004 gen_sel_d(ctx
, op1
, fd
, ft
, fs
);
11007 check_insn(ctx
, ISA_MIPS_R6
);
11008 gen_sel_d(ctx
, op1
, fd
, ft
, fs
);
11011 check_insn(ctx
, ISA_MIPS_R6
);
11012 gen_sel_d(ctx
, op1
, fd
, ft
, fs
);
11015 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
11016 gen_movcf_d(ctx
, fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
11019 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
11021 TCGLabel
*l1
= gen_new_label();
11025 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
11027 fp0
= tcg_temp_new_i64();
11028 gen_load_fpr64(ctx
, fp0
, fs
);
11029 gen_store_fpr64(ctx
, fp0
, fd
);
11030 tcg_temp_free_i64(fp0
);
11035 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
11037 TCGLabel
*l1
= gen_new_label();
11041 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
11042 fp0
= tcg_temp_new_i64();
11043 gen_load_fpr64(ctx
, fp0
, fs
);
11044 gen_store_fpr64(ctx
, fp0
, fd
);
11045 tcg_temp_free_i64(fp0
);
11051 check_cp1_registers(ctx
, fs
| fd
);
11053 TCGv_i64 fp0
= tcg_temp_new_i64();
11055 gen_load_fpr64(ctx
, fp0
, fs
);
11056 gen_helper_float_recip_d(fp0
, cpu_env
, fp0
);
11057 gen_store_fpr64(ctx
, fp0
, fd
);
11058 tcg_temp_free_i64(fp0
);
11062 check_cp1_registers(ctx
, fs
| fd
);
11064 TCGv_i64 fp0
= tcg_temp_new_i64();
11066 gen_load_fpr64(ctx
, fp0
, fs
);
11067 gen_helper_float_rsqrt_d(fp0
, cpu_env
, fp0
);
11068 gen_store_fpr64(ctx
, fp0
, fd
);
11069 tcg_temp_free_i64(fp0
);
11073 check_insn(ctx
, ISA_MIPS_R6
);
11075 TCGv_i64 fp0
= tcg_temp_new_i64();
11076 TCGv_i64 fp1
= tcg_temp_new_i64();
11077 TCGv_i64 fp2
= tcg_temp_new_i64();
11078 gen_load_fpr64(ctx
, fp0
, fs
);
11079 gen_load_fpr64(ctx
, fp1
, ft
);
11080 gen_load_fpr64(ctx
, fp2
, fd
);
11081 gen_helper_float_maddf_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
11082 gen_store_fpr64(ctx
, fp2
, fd
);
11083 tcg_temp_free_i64(fp2
);
11084 tcg_temp_free_i64(fp1
);
11085 tcg_temp_free_i64(fp0
);
11089 check_insn(ctx
, ISA_MIPS_R6
);
11091 TCGv_i64 fp0
= tcg_temp_new_i64();
11092 TCGv_i64 fp1
= tcg_temp_new_i64();
11093 TCGv_i64 fp2
= tcg_temp_new_i64();
11094 gen_load_fpr64(ctx
, fp0
, fs
);
11095 gen_load_fpr64(ctx
, fp1
, ft
);
11096 gen_load_fpr64(ctx
, fp2
, fd
);
11097 gen_helper_float_msubf_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
11098 gen_store_fpr64(ctx
, fp2
, fd
);
11099 tcg_temp_free_i64(fp2
);
11100 tcg_temp_free_i64(fp1
);
11101 tcg_temp_free_i64(fp0
);
11105 check_insn(ctx
, ISA_MIPS_R6
);
11107 TCGv_i64 fp0
= tcg_temp_new_i64();
11108 gen_load_fpr64(ctx
, fp0
, fs
);
11109 gen_helper_float_rint_d(fp0
, cpu_env
, fp0
);
11110 gen_store_fpr64(ctx
, fp0
, fd
);
11111 tcg_temp_free_i64(fp0
);
11115 check_insn(ctx
, ISA_MIPS_R6
);
11117 TCGv_i64 fp0
= tcg_temp_new_i64();
11118 gen_load_fpr64(ctx
, fp0
, fs
);
11119 gen_helper_float_class_d(fp0
, cpu_env
, fp0
);
11120 gen_store_fpr64(ctx
, fp0
, fd
);
11121 tcg_temp_free_i64(fp0
);
11124 case OPC_MIN_D
: /* OPC_RECIP2_D */
11125 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
11127 TCGv_i64 fp0
= tcg_temp_new_i64();
11128 TCGv_i64 fp1
= tcg_temp_new_i64();
11129 gen_load_fpr64(ctx
, fp0
, fs
);
11130 gen_load_fpr64(ctx
, fp1
, ft
);
11131 gen_helper_float_min_d(fp1
, cpu_env
, fp0
, fp1
);
11132 gen_store_fpr64(ctx
, fp1
, fd
);
11133 tcg_temp_free_i64(fp1
);
11134 tcg_temp_free_i64(fp0
);
11137 check_cp1_64bitmode(ctx
);
11139 TCGv_i64 fp0
= tcg_temp_new_i64();
11140 TCGv_i64 fp1
= tcg_temp_new_i64();
11142 gen_load_fpr64(ctx
, fp0
, fs
);
11143 gen_load_fpr64(ctx
, fp1
, ft
);
11144 gen_helper_float_recip2_d(fp0
, cpu_env
, fp0
, fp1
);
11145 tcg_temp_free_i64(fp1
);
11146 gen_store_fpr64(ctx
, fp0
, fd
);
11147 tcg_temp_free_i64(fp0
);
11151 case OPC_MINA_D
: /* OPC_RECIP1_D */
11152 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
11154 TCGv_i64 fp0
= tcg_temp_new_i64();
11155 TCGv_i64 fp1
= tcg_temp_new_i64();
11156 gen_load_fpr64(ctx
, fp0
, fs
);
11157 gen_load_fpr64(ctx
, fp1
, ft
);
11158 gen_helper_float_mina_d(fp1
, cpu_env
, fp0
, fp1
);
11159 gen_store_fpr64(ctx
, fp1
, fd
);
11160 tcg_temp_free_i64(fp1
);
11161 tcg_temp_free_i64(fp0
);
11164 check_cp1_64bitmode(ctx
);
11166 TCGv_i64 fp0
= tcg_temp_new_i64();
11168 gen_load_fpr64(ctx
, fp0
, fs
);
11169 gen_helper_float_recip1_d(fp0
, cpu_env
, fp0
);
11170 gen_store_fpr64(ctx
, fp0
, fd
);
11171 tcg_temp_free_i64(fp0
);
11175 case OPC_MAX_D
: /* OPC_RSQRT1_D */
11176 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
11178 TCGv_i64 fp0
= tcg_temp_new_i64();
11179 TCGv_i64 fp1
= tcg_temp_new_i64();
11180 gen_load_fpr64(ctx
, fp0
, fs
);
11181 gen_load_fpr64(ctx
, fp1
, ft
);
11182 gen_helper_float_max_d(fp1
, cpu_env
, fp0
, fp1
);
11183 gen_store_fpr64(ctx
, fp1
, fd
);
11184 tcg_temp_free_i64(fp1
);
11185 tcg_temp_free_i64(fp0
);
11188 check_cp1_64bitmode(ctx
);
11190 TCGv_i64 fp0
= tcg_temp_new_i64();
11192 gen_load_fpr64(ctx
, fp0
, fs
);
11193 gen_helper_float_rsqrt1_d(fp0
, cpu_env
, fp0
);
11194 gen_store_fpr64(ctx
, fp0
, fd
);
11195 tcg_temp_free_i64(fp0
);
11199 case OPC_MAXA_D
: /* OPC_RSQRT2_D */
11200 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
11202 TCGv_i64 fp0
= tcg_temp_new_i64();
11203 TCGv_i64 fp1
= tcg_temp_new_i64();
11204 gen_load_fpr64(ctx
, fp0
, fs
);
11205 gen_load_fpr64(ctx
, fp1
, ft
);
11206 gen_helper_float_maxa_d(fp1
, cpu_env
, fp0
, fp1
);
11207 gen_store_fpr64(ctx
, fp1
, fd
);
11208 tcg_temp_free_i64(fp1
);
11209 tcg_temp_free_i64(fp0
);
11212 check_cp1_64bitmode(ctx
);
11214 TCGv_i64 fp0
= tcg_temp_new_i64();
11215 TCGv_i64 fp1
= tcg_temp_new_i64();
11217 gen_load_fpr64(ctx
, fp0
, fs
);
11218 gen_load_fpr64(ctx
, fp1
, ft
);
11219 gen_helper_float_rsqrt2_d(fp0
, cpu_env
, fp0
, fp1
);
11220 tcg_temp_free_i64(fp1
);
11221 gen_store_fpr64(ctx
, fp0
, fd
);
11222 tcg_temp_free_i64(fp0
);
11229 case OPC_CMP_UEQ_D
:
11230 case OPC_CMP_OLT_D
:
11231 case OPC_CMP_ULT_D
:
11232 case OPC_CMP_OLE_D
:
11233 case OPC_CMP_ULE_D
:
11235 case OPC_CMP_NGLE_D
:
11236 case OPC_CMP_SEQ_D
:
11237 case OPC_CMP_NGL_D
:
11239 case OPC_CMP_NGE_D
:
11241 case OPC_CMP_NGT_D
:
11242 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
11243 if (ctx
->opcode
& (1 << 6)) {
11244 gen_cmpabs_d(ctx
, func
- 48, ft
, fs
, cc
);
11246 gen_cmp_d(ctx
, func
- 48, ft
, fs
, cc
);
11250 check_cp1_registers(ctx
, fs
);
11252 TCGv_i32 fp32
= tcg_temp_new_i32();
11253 TCGv_i64 fp64
= tcg_temp_new_i64();
11255 gen_load_fpr64(ctx
, fp64
, fs
);
11256 gen_helper_float_cvts_d(fp32
, cpu_env
, fp64
);
11257 tcg_temp_free_i64(fp64
);
11258 gen_store_fpr32(ctx
, fp32
, fd
);
11259 tcg_temp_free_i32(fp32
);
11263 check_cp1_registers(ctx
, fs
);
11265 TCGv_i32 fp32
= tcg_temp_new_i32();
11266 TCGv_i64 fp64
= tcg_temp_new_i64();
11268 gen_load_fpr64(ctx
, fp64
, fs
);
11269 if (ctx
->nan2008
) {
11270 gen_helper_float_cvt_2008_w_d(fp32
, cpu_env
, fp64
);
11272 gen_helper_float_cvt_w_d(fp32
, cpu_env
, fp64
);
11274 tcg_temp_free_i64(fp64
);
11275 gen_store_fpr32(ctx
, fp32
, fd
);
11276 tcg_temp_free_i32(fp32
);
11280 check_cp1_64bitmode(ctx
);
11282 TCGv_i64 fp0
= tcg_temp_new_i64();
11284 gen_load_fpr64(ctx
, fp0
, fs
);
11285 if (ctx
->nan2008
) {
11286 gen_helper_float_cvt_2008_l_d(fp0
, cpu_env
, fp0
);
11288 gen_helper_float_cvt_l_d(fp0
, cpu_env
, fp0
);
11290 gen_store_fpr64(ctx
, fp0
, fd
);
11291 tcg_temp_free_i64(fp0
);
11296 TCGv_i32 fp0
= tcg_temp_new_i32();
11298 gen_load_fpr32(ctx
, fp0
, fs
);
11299 gen_helper_float_cvts_w(fp0
, cpu_env
, fp0
);
11300 gen_store_fpr32(ctx
, fp0
, fd
);
11301 tcg_temp_free_i32(fp0
);
11305 check_cp1_registers(ctx
, fd
);
11307 TCGv_i32 fp32
= tcg_temp_new_i32();
11308 TCGv_i64 fp64
= tcg_temp_new_i64();
11310 gen_load_fpr32(ctx
, fp32
, fs
);
11311 gen_helper_float_cvtd_w(fp64
, cpu_env
, fp32
);
11312 tcg_temp_free_i32(fp32
);
11313 gen_store_fpr64(ctx
, fp64
, fd
);
11314 tcg_temp_free_i64(fp64
);
11318 check_cp1_64bitmode(ctx
);
11320 TCGv_i32 fp32
= tcg_temp_new_i32();
11321 TCGv_i64 fp64
= tcg_temp_new_i64();
11323 gen_load_fpr64(ctx
, fp64
, fs
);
11324 gen_helper_float_cvts_l(fp32
, cpu_env
, fp64
);
11325 tcg_temp_free_i64(fp64
);
11326 gen_store_fpr32(ctx
, fp32
, fd
);
11327 tcg_temp_free_i32(fp32
);
11331 check_cp1_64bitmode(ctx
);
11333 TCGv_i64 fp0
= tcg_temp_new_i64();
11335 gen_load_fpr64(ctx
, fp0
, fs
);
11336 gen_helper_float_cvtd_l(fp0
, cpu_env
, fp0
);
11337 gen_store_fpr64(ctx
, fp0
, fd
);
11338 tcg_temp_free_i64(fp0
);
11341 case OPC_CVT_PS_PW
:
11344 TCGv_i64 fp0
= tcg_temp_new_i64();
11346 gen_load_fpr64(ctx
, fp0
, fs
);
11347 gen_helper_float_cvtps_pw(fp0
, cpu_env
, fp0
);
11348 gen_store_fpr64(ctx
, fp0
, fd
);
11349 tcg_temp_free_i64(fp0
);
11355 TCGv_i64 fp0
= tcg_temp_new_i64();
11356 TCGv_i64 fp1
= tcg_temp_new_i64();
11358 gen_load_fpr64(ctx
, fp0
, fs
);
11359 gen_load_fpr64(ctx
, fp1
, ft
);
11360 gen_helper_float_add_ps(fp0
, cpu_env
, fp0
, fp1
);
11361 tcg_temp_free_i64(fp1
);
11362 gen_store_fpr64(ctx
, fp0
, fd
);
11363 tcg_temp_free_i64(fp0
);
11369 TCGv_i64 fp0
= tcg_temp_new_i64();
11370 TCGv_i64 fp1
= tcg_temp_new_i64();
11372 gen_load_fpr64(ctx
, fp0
, fs
);
11373 gen_load_fpr64(ctx
, fp1
, ft
);
11374 gen_helper_float_sub_ps(fp0
, cpu_env
, fp0
, fp1
);
11375 tcg_temp_free_i64(fp1
);
11376 gen_store_fpr64(ctx
, fp0
, fd
);
11377 tcg_temp_free_i64(fp0
);
11383 TCGv_i64 fp0
= tcg_temp_new_i64();
11384 TCGv_i64 fp1
= tcg_temp_new_i64();
11386 gen_load_fpr64(ctx
, fp0
, fs
);
11387 gen_load_fpr64(ctx
, fp1
, ft
);
11388 gen_helper_float_mul_ps(fp0
, cpu_env
, fp0
, fp1
);
11389 tcg_temp_free_i64(fp1
);
11390 gen_store_fpr64(ctx
, fp0
, fd
);
11391 tcg_temp_free_i64(fp0
);
11397 TCGv_i64 fp0
= tcg_temp_new_i64();
11399 gen_load_fpr64(ctx
, fp0
, fs
);
11400 gen_helper_float_abs_ps(fp0
, fp0
);
11401 gen_store_fpr64(ctx
, fp0
, fd
);
11402 tcg_temp_free_i64(fp0
);
11408 TCGv_i64 fp0
= tcg_temp_new_i64();
11410 gen_load_fpr64(ctx
, fp0
, fs
);
11411 gen_store_fpr64(ctx
, fp0
, fd
);
11412 tcg_temp_free_i64(fp0
);
11418 TCGv_i64 fp0
= tcg_temp_new_i64();
11420 gen_load_fpr64(ctx
, fp0
, fs
);
11421 gen_helper_float_chs_ps(fp0
, fp0
);
11422 gen_store_fpr64(ctx
, fp0
, fd
);
11423 tcg_temp_free_i64(fp0
);
11428 gen_movcf_ps(ctx
, fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
11433 TCGLabel
*l1
= gen_new_label();
11437 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
11439 fp0
= tcg_temp_new_i64();
11440 gen_load_fpr64(ctx
, fp0
, fs
);
11441 gen_store_fpr64(ctx
, fp0
, fd
);
11442 tcg_temp_free_i64(fp0
);
11449 TCGLabel
*l1
= gen_new_label();
11453 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
11454 fp0
= tcg_temp_new_i64();
11455 gen_load_fpr64(ctx
, fp0
, fs
);
11456 gen_store_fpr64(ctx
, fp0
, fd
);
11457 tcg_temp_free_i64(fp0
);
11465 TCGv_i64 fp0
= tcg_temp_new_i64();
11466 TCGv_i64 fp1
= tcg_temp_new_i64();
11468 gen_load_fpr64(ctx
, fp0
, ft
);
11469 gen_load_fpr64(ctx
, fp1
, fs
);
11470 gen_helper_float_addr_ps(fp0
, cpu_env
, fp0
, fp1
);
11471 tcg_temp_free_i64(fp1
);
11472 gen_store_fpr64(ctx
, fp0
, fd
);
11473 tcg_temp_free_i64(fp0
);
11479 TCGv_i64 fp0
= tcg_temp_new_i64();
11480 TCGv_i64 fp1
= tcg_temp_new_i64();
11482 gen_load_fpr64(ctx
, fp0
, ft
);
11483 gen_load_fpr64(ctx
, fp1
, fs
);
11484 gen_helper_float_mulr_ps(fp0
, cpu_env
, fp0
, fp1
);
11485 tcg_temp_free_i64(fp1
);
11486 gen_store_fpr64(ctx
, fp0
, fd
);
11487 tcg_temp_free_i64(fp0
);
11490 case OPC_RECIP2_PS
:
11493 TCGv_i64 fp0
= tcg_temp_new_i64();
11494 TCGv_i64 fp1
= tcg_temp_new_i64();
11496 gen_load_fpr64(ctx
, fp0
, fs
);
11497 gen_load_fpr64(ctx
, fp1
, ft
);
11498 gen_helper_float_recip2_ps(fp0
, cpu_env
, fp0
, fp1
);
11499 tcg_temp_free_i64(fp1
);
11500 gen_store_fpr64(ctx
, fp0
, fd
);
11501 tcg_temp_free_i64(fp0
);
11504 case OPC_RECIP1_PS
:
11507 TCGv_i64 fp0
= tcg_temp_new_i64();
11509 gen_load_fpr64(ctx
, fp0
, fs
);
11510 gen_helper_float_recip1_ps(fp0
, cpu_env
, fp0
);
11511 gen_store_fpr64(ctx
, fp0
, fd
);
11512 tcg_temp_free_i64(fp0
);
11515 case OPC_RSQRT1_PS
:
11518 TCGv_i64 fp0
= tcg_temp_new_i64();
11520 gen_load_fpr64(ctx
, fp0
, fs
);
11521 gen_helper_float_rsqrt1_ps(fp0
, cpu_env
, fp0
);
11522 gen_store_fpr64(ctx
, fp0
, fd
);
11523 tcg_temp_free_i64(fp0
);
11526 case OPC_RSQRT2_PS
:
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_rsqrt2_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
);
11541 check_cp1_64bitmode(ctx
);
11543 TCGv_i32 fp0
= tcg_temp_new_i32();
11545 gen_load_fpr32h(ctx
, fp0
, fs
);
11546 gen_helper_float_cvts_pu(fp0
, cpu_env
, fp0
);
11547 gen_store_fpr32(ctx
, fp0
, fd
);
11548 tcg_temp_free_i32(fp0
);
11551 case OPC_CVT_PW_PS
:
11554 TCGv_i64 fp0
= tcg_temp_new_i64();
11556 gen_load_fpr64(ctx
, fp0
, fs
);
11557 gen_helper_float_cvtpw_ps(fp0
, cpu_env
, fp0
);
11558 gen_store_fpr64(ctx
, fp0
, fd
);
11559 tcg_temp_free_i64(fp0
);
11563 check_cp1_64bitmode(ctx
);
11565 TCGv_i32 fp0
= tcg_temp_new_i32();
11567 gen_load_fpr32(ctx
, fp0
, fs
);
11568 gen_helper_float_cvts_pl(fp0
, cpu_env
, fp0
);
11569 gen_store_fpr32(ctx
, fp0
, fd
);
11570 tcg_temp_free_i32(fp0
);
11576 TCGv_i32 fp0
= tcg_temp_new_i32();
11577 TCGv_i32 fp1
= tcg_temp_new_i32();
11579 gen_load_fpr32(ctx
, fp0
, fs
);
11580 gen_load_fpr32(ctx
, fp1
, ft
);
11581 gen_store_fpr32h(ctx
, fp0
, fd
);
11582 gen_store_fpr32(ctx
, fp1
, fd
);
11583 tcg_temp_free_i32(fp0
);
11584 tcg_temp_free_i32(fp1
);
11590 TCGv_i32 fp0
= tcg_temp_new_i32();
11591 TCGv_i32 fp1
= tcg_temp_new_i32();
11593 gen_load_fpr32(ctx
, fp0
, fs
);
11594 gen_load_fpr32h(ctx
, fp1
, ft
);
11595 gen_store_fpr32(ctx
, fp1
, fd
);
11596 gen_store_fpr32h(ctx
, fp0
, fd
);
11597 tcg_temp_free_i32(fp0
);
11598 tcg_temp_free_i32(fp1
);
11604 TCGv_i32 fp0
= tcg_temp_new_i32();
11605 TCGv_i32 fp1
= tcg_temp_new_i32();
11607 gen_load_fpr32h(ctx
, fp0
, fs
);
11608 gen_load_fpr32(ctx
, fp1
, ft
);
11609 gen_store_fpr32(ctx
, fp1
, fd
);
11610 gen_store_fpr32h(ctx
, fp0
, fd
);
11611 tcg_temp_free_i32(fp0
);
11612 tcg_temp_free_i32(fp1
);
11618 TCGv_i32 fp0
= tcg_temp_new_i32();
11619 TCGv_i32 fp1
= tcg_temp_new_i32();
11621 gen_load_fpr32h(ctx
, fp0
, fs
);
11622 gen_load_fpr32h(ctx
, fp1
, ft
);
11623 gen_store_fpr32(ctx
, fp1
, fd
);
11624 gen_store_fpr32h(ctx
, fp0
, fd
);
11625 tcg_temp_free_i32(fp0
);
11626 tcg_temp_free_i32(fp1
);
11630 case OPC_CMP_UN_PS
:
11631 case OPC_CMP_EQ_PS
:
11632 case OPC_CMP_UEQ_PS
:
11633 case OPC_CMP_OLT_PS
:
11634 case OPC_CMP_ULT_PS
:
11635 case OPC_CMP_OLE_PS
:
11636 case OPC_CMP_ULE_PS
:
11637 case OPC_CMP_SF_PS
:
11638 case OPC_CMP_NGLE_PS
:
11639 case OPC_CMP_SEQ_PS
:
11640 case OPC_CMP_NGL_PS
:
11641 case OPC_CMP_LT_PS
:
11642 case OPC_CMP_NGE_PS
:
11643 case OPC_CMP_LE_PS
:
11644 case OPC_CMP_NGT_PS
:
11645 if (ctx
->opcode
& (1 << 6)) {
11646 gen_cmpabs_ps(ctx
, func
- 48, ft
, fs
, cc
);
11648 gen_cmp_ps(ctx
, func
- 48, ft
, fs
, cc
);
11652 MIPS_INVAL("farith");
11653 gen_reserved_instruction(ctx
);
11658 /* Coprocessor 3 (FPU) */
11659 static void gen_flt3_ldst(DisasContext
*ctx
, uint32_t opc
,
11660 int fd
, int fs
, int base
, int index
)
11662 TCGv t0
= tcg_temp_new();
11665 gen_load_gpr(t0
, index
);
11666 } else if (index
== 0) {
11667 gen_load_gpr(t0
, base
);
11669 gen_op_addr_add(ctx
, t0
, cpu_gpr
[base
], cpu_gpr
[index
]);
11672 * Don't do NOP if destination is zero: we must perform the actual
11679 TCGv_i32 fp0
= tcg_temp_new_i32();
11681 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESL
);
11682 tcg_gen_trunc_tl_i32(fp0
, t0
);
11683 gen_store_fpr32(ctx
, fp0
, fd
);
11684 tcg_temp_free_i32(fp0
);
11689 check_cp1_registers(ctx
, fd
);
11691 TCGv_i64 fp0
= tcg_temp_new_i64();
11692 tcg_gen_qemu_ld_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
11693 gen_store_fpr64(ctx
, fp0
, fd
);
11694 tcg_temp_free_i64(fp0
);
11698 check_cp1_64bitmode(ctx
);
11699 tcg_gen_andi_tl(t0
, t0
, ~0x7);
11701 TCGv_i64 fp0
= tcg_temp_new_i64();
11703 tcg_gen_qemu_ld_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
11704 gen_store_fpr64(ctx
, fp0
, fd
);
11705 tcg_temp_free_i64(fp0
);
11711 TCGv_i32 fp0
= tcg_temp_new_i32();
11712 gen_load_fpr32(ctx
, fp0
, fs
);
11713 tcg_gen_qemu_st_i32(fp0
, t0
, ctx
->mem_idx
, MO_TEUL
);
11714 tcg_temp_free_i32(fp0
);
11719 check_cp1_registers(ctx
, fs
);
11721 TCGv_i64 fp0
= tcg_temp_new_i64();
11722 gen_load_fpr64(ctx
, fp0
, fs
);
11723 tcg_gen_qemu_st_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
11724 tcg_temp_free_i64(fp0
);
11728 check_cp1_64bitmode(ctx
);
11729 tcg_gen_andi_tl(t0
, t0
, ~0x7);
11731 TCGv_i64 fp0
= tcg_temp_new_i64();
11732 gen_load_fpr64(ctx
, fp0
, fs
);
11733 tcg_gen_qemu_st_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
11734 tcg_temp_free_i64(fp0
);
11741 static void gen_flt3_arith(DisasContext
*ctx
, uint32_t opc
,
11742 int fd
, int fr
, int fs
, int ft
)
11748 TCGv t0
= tcg_temp_local_new();
11749 TCGv_i32 fp
= tcg_temp_new_i32();
11750 TCGv_i32 fph
= tcg_temp_new_i32();
11751 TCGLabel
*l1
= gen_new_label();
11752 TCGLabel
*l2
= gen_new_label();
11754 gen_load_gpr(t0
, fr
);
11755 tcg_gen_andi_tl(t0
, t0
, 0x7);
11757 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, 0, l1
);
11758 gen_load_fpr32(ctx
, fp
, fs
);
11759 gen_load_fpr32h(ctx
, fph
, fs
);
11760 gen_store_fpr32(ctx
, fp
, fd
);
11761 gen_store_fpr32h(ctx
, fph
, fd
);
11764 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, 4, l2
);
11766 #ifdef TARGET_WORDS_BIGENDIAN
11767 gen_load_fpr32(ctx
, fp
, fs
);
11768 gen_load_fpr32h(ctx
, fph
, ft
);
11769 gen_store_fpr32h(ctx
, fp
, fd
);
11770 gen_store_fpr32(ctx
, fph
, fd
);
11772 gen_load_fpr32h(ctx
, fph
, fs
);
11773 gen_load_fpr32(ctx
, fp
, ft
);
11774 gen_store_fpr32(ctx
, fph
, fd
);
11775 gen_store_fpr32h(ctx
, fp
, fd
);
11778 tcg_temp_free_i32(fp
);
11779 tcg_temp_free_i32(fph
);
11785 TCGv_i32 fp0
= tcg_temp_new_i32();
11786 TCGv_i32 fp1
= tcg_temp_new_i32();
11787 TCGv_i32 fp2
= tcg_temp_new_i32();
11789 gen_load_fpr32(ctx
, fp0
, fs
);
11790 gen_load_fpr32(ctx
, fp1
, ft
);
11791 gen_load_fpr32(ctx
, fp2
, fr
);
11792 gen_helper_float_madd_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
11793 tcg_temp_free_i32(fp0
);
11794 tcg_temp_free_i32(fp1
);
11795 gen_store_fpr32(ctx
, fp2
, fd
);
11796 tcg_temp_free_i32(fp2
);
11801 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
11803 TCGv_i64 fp0
= tcg_temp_new_i64();
11804 TCGv_i64 fp1
= tcg_temp_new_i64();
11805 TCGv_i64 fp2
= tcg_temp_new_i64();
11807 gen_load_fpr64(ctx
, fp0
, fs
);
11808 gen_load_fpr64(ctx
, fp1
, ft
);
11809 gen_load_fpr64(ctx
, fp2
, fr
);
11810 gen_helper_float_madd_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
11811 tcg_temp_free_i64(fp0
);
11812 tcg_temp_free_i64(fp1
);
11813 gen_store_fpr64(ctx
, fp2
, fd
);
11814 tcg_temp_free_i64(fp2
);
11820 TCGv_i64 fp0
= tcg_temp_new_i64();
11821 TCGv_i64 fp1
= tcg_temp_new_i64();
11822 TCGv_i64 fp2
= tcg_temp_new_i64();
11824 gen_load_fpr64(ctx
, fp0
, fs
);
11825 gen_load_fpr64(ctx
, fp1
, ft
);
11826 gen_load_fpr64(ctx
, fp2
, fr
);
11827 gen_helper_float_madd_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
11828 tcg_temp_free_i64(fp0
);
11829 tcg_temp_free_i64(fp1
);
11830 gen_store_fpr64(ctx
, fp2
, fd
);
11831 tcg_temp_free_i64(fp2
);
11837 TCGv_i32 fp0
= tcg_temp_new_i32();
11838 TCGv_i32 fp1
= tcg_temp_new_i32();
11839 TCGv_i32 fp2
= tcg_temp_new_i32();
11841 gen_load_fpr32(ctx
, fp0
, fs
);
11842 gen_load_fpr32(ctx
, fp1
, ft
);
11843 gen_load_fpr32(ctx
, fp2
, fr
);
11844 gen_helper_float_msub_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
11845 tcg_temp_free_i32(fp0
);
11846 tcg_temp_free_i32(fp1
);
11847 gen_store_fpr32(ctx
, fp2
, fd
);
11848 tcg_temp_free_i32(fp2
);
11853 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
11855 TCGv_i64 fp0
= tcg_temp_new_i64();
11856 TCGv_i64 fp1
= tcg_temp_new_i64();
11857 TCGv_i64 fp2
= tcg_temp_new_i64();
11859 gen_load_fpr64(ctx
, fp0
, fs
);
11860 gen_load_fpr64(ctx
, fp1
, ft
);
11861 gen_load_fpr64(ctx
, fp2
, fr
);
11862 gen_helper_float_msub_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
11863 tcg_temp_free_i64(fp0
);
11864 tcg_temp_free_i64(fp1
);
11865 gen_store_fpr64(ctx
, fp2
, fd
);
11866 tcg_temp_free_i64(fp2
);
11872 TCGv_i64 fp0
= tcg_temp_new_i64();
11873 TCGv_i64 fp1
= tcg_temp_new_i64();
11874 TCGv_i64 fp2
= tcg_temp_new_i64();
11876 gen_load_fpr64(ctx
, fp0
, fs
);
11877 gen_load_fpr64(ctx
, fp1
, ft
);
11878 gen_load_fpr64(ctx
, fp2
, fr
);
11879 gen_helper_float_msub_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
11880 tcg_temp_free_i64(fp0
);
11881 tcg_temp_free_i64(fp1
);
11882 gen_store_fpr64(ctx
, fp2
, fd
);
11883 tcg_temp_free_i64(fp2
);
11889 TCGv_i32 fp0
= tcg_temp_new_i32();
11890 TCGv_i32 fp1
= tcg_temp_new_i32();
11891 TCGv_i32 fp2
= tcg_temp_new_i32();
11893 gen_load_fpr32(ctx
, fp0
, fs
);
11894 gen_load_fpr32(ctx
, fp1
, ft
);
11895 gen_load_fpr32(ctx
, fp2
, fr
);
11896 gen_helper_float_nmadd_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
11897 tcg_temp_free_i32(fp0
);
11898 tcg_temp_free_i32(fp1
);
11899 gen_store_fpr32(ctx
, fp2
, fd
);
11900 tcg_temp_free_i32(fp2
);
11905 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
11907 TCGv_i64 fp0
= tcg_temp_new_i64();
11908 TCGv_i64 fp1
= tcg_temp_new_i64();
11909 TCGv_i64 fp2
= tcg_temp_new_i64();
11911 gen_load_fpr64(ctx
, fp0
, fs
);
11912 gen_load_fpr64(ctx
, fp1
, ft
);
11913 gen_load_fpr64(ctx
, fp2
, fr
);
11914 gen_helper_float_nmadd_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
11915 tcg_temp_free_i64(fp0
);
11916 tcg_temp_free_i64(fp1
);
11917 gen_store_fpr64(ctx
, fp2
, fd
);
11918 tcg_temp_free_i64(fp2
);
11924 TCGv_i64 fp0
= tcg_temp_new_i64();
11925 TCGv_i64 fp1
= tcg_temp_new_i64();
11926 TCGv_i64 fp2
= tcg_temp_new_i64();
11928 gen_load_fpr64(ctx
, fp0
, fs
);
11929 gen_load_fpr64(ctx
, fp1
, ft
);
11930 gen_load_fpr64(ctx
, fp2
, fr
);
11931 gen_helper_float_nmadd_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
11932 tcg_temp_free_i64(fp0
);
11933 tcg_temp_free_i64(fp1
);
11934 gen_store_fpr64(ctx
, fp2
, fd
);
11935 tcg_temp_free_i64(fp2
);
11941 TCGv_i32 fp0
= tcg_temp_new_i32();
11942 TCGv_i32 fp1
= tcg_temp_new_i32();
11943 TCGv_i32 fp2
= tcg_temp_new_i32();
11945 gen_load_fpr32(ctx
, fp0
, fs
);
11946 gen_load_fpr32(ctx
, fp1
, ft
);
11947 gen_load_fpr32(ctx
, fp2
, fr
);
11948 gen_helper_float_nmsub_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
11949 tcg_temp_free_i32(fp0
);
11950 tcg_temp_free_i32(fp1
);
11951 gen_store_fpr32(ctx
, fp2
, fd
);
11952 tcg_temp_free_i32(fp2
);
11957 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
11959 TCGv_i64 fp0
= tcg_temp_new_i64();
11960 TCGv_i64 fp1
= tcg_temp_new_i64();
11961 TCGv_i64 fp2
= tcg_temp_new_i64();
11963 gen_load_fpr64(ctx
, fp0
, fs
);
11964 gen_load_fpr64(ctx
, fp1
, ft
);
11965 gen_load_fpr64(ctx
, fp2
, fr
);
11966 gen_helper_float_nmsub_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
11967 tcg_temp_free_i64(fp0
);
11968 tcg_temp_free_i64(fp1
);
11969 gen_store_fpr64(ctx
, fp2
, fd
);
11970 tcg_temp_free_i64(fp2
);
11976 TCGv_i64 fp0
= tcg_temp_new_i64();
11977 TCGv_i64 fp1
= tcg_temp_new_i64();
11978 TCGv_i64 fp2
= tcg_temp_new_i64();
11980 gen_load_fpr64(ctx
, fp0
, fs
);
11981 gen_load_fpr64(ctx
, fp1
, ft
);
11982 gen_load_fpr64(ctx
, fp2
, fr
);
11983 gen_helper_float_nmsub_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
11984 tcg_temp_free_i64(fp0
);
11985 tcg_temp_free_i64(fp1
);
11986 gen_store_fpr64(ctx
, fp2
, fd
);
11987 tcg_temp_free_i64(fp2
);
11991 MIPS_INVAL("flt3_arith");
11992 gen_reserved_instruction(ctx
);
11997 void gen_rdhwr(DisasContext
*ctx
, int rt
, int rd
, int sel
)
12001 #if !defined(CONFIG_USER_ONLY)
12003 * The Linux kernel will emulate rdhwr if it's not supported natively.
12004 * Therefore only check the ISA in system mode.
12006 check_insn(ctx
, ISA_MIPS_R2
);
12008 t0
= tcg_temp_new();
12012 gen_helper_rdhwr_cpunum(t0
, cpu_env
);
12013 gen_store_gpr(t0
, rt
);
12016 gen_helper_rdhwr_synci_step(t0
, cpu_env
);
12017 gen_store_gpr(t0
, rt
);
12020 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
12023 gen_helper_rdhwr_cc(t0
, cpu_env
);
12024 gen_store_gpr(t0
, rt
);
12026 * Break the TB to be able to take timer interrupts immediately
12027 * after reading count. DISAS_STOP isn't sufficient, we need to ensure
12028 * we break completely out of translated code.
12030 gen_save_pc(ctx
->base
.pc_next
+ 4);
12031 ctx
->base
.is_jmp
= DISAS_EXIT
;
12034 gen_helper_rdhwr_ccres(t0
, cpu_env
);
12035 gen_store_gpr(t0
, rt
);
12038 check_insn(ctx
, ISA_MIPS_R6
);
12041 * Performance counter registers are not implemented other than
12042 * control register 0.
12044 generate_exception(ctx
, EXCP_RI
);
12046 gen_helper_rdhwr_performance(t0
, cpu_env
);
12047 gen_store_gpr(t0
, rt
);
12050 check_insn(ctx
, ISA_MIPS_R6
);
12051 gen_helper_rdhwr_xnp(t0
, cpu_env
);
12052 gen_store_gpr(t0
, rt
);
12055 #if defined(CONFIG_USER_ONLY)
12056 tcg_gen_ld_tl(t0
, cpu_env
,
12057 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
12058 gen_store_gpr(t0
, rt
);
12061 if ((ctx
->hflags
& MIPS_HFLAG_CP0
) ||
12062 (ctx
->hflags
& MIPS_HFLAG_HWRENA_ULR
)) {
12063 tcg_gen_ld_tl(t0
, cpu_env
,
12064 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
12065 gen_store_gpr(t0
, rt
);
12067 gen_reserved_instruction(ctx
);
12071 default: /* Invalid */
12072 MIPS_INVAL("rdhwr");
12073 gen_reserved_instruction(ctx
);
12079 static inline void clear_branch_hflags(DisasContext
*ctx
)
12081 ctx
->hflags
&= ~MIPS_HFLAG_BMASK
;
12082 if (ctx
->base
.is_jmp
== DISAS_NEXT
) {
12083 save_cpu_state(ctx
, 0);
12086 * It is not safe to save ctx->hflags as hflags may be changed
12087 * in execution time by the instruction in delay / forbidden slot.
12089 tcg_gen_andi_i32(hflags
, hflags
, ~MIPS_HFLAG_BMASK
);
12093 static void gen_branch(DisasContext
*ctx
, int insn_bytes
)
12095 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
12096 int proc_hflags
= ctx
->hflags
& MIPS_HFLAG_BMASK
;
12097 /* Branches completion */
12098 clear_branch_hflags(ctx
);
12099 ctx
->base
.is_jmp
= DISAS_NORETURN
;
12100 /* FIXME: Need to clear can_do_io. */
12101 switch (proc_hflags
& MIPS_HFLAG_BMASK_BASE
) {
12102 case MIPS_HFLAG_FBNSLOT
:
12103 gen_goto_tb(ctx
, 0, ctx
->base
.pc_next
+ insn_bytes
);
12106 /* unconditional branch */
12107 if (proc_hflags
& MIPS_HFLAG_BX
) {
12108 tcg_gen_xori_i32(hflags
, hflags
, MIPS_HFLAG_M16
);
12110 gen_goto_tb(ctx
, 0, ctx
->btarget
);
12112 case MIPS_HFLAG_BL
:
12113 /* blikely taken case */
12114 gen_goto_tb(ctx
, 0, ctx
->btarget
);
12116 case MIPS_HFLAG_BC
:
12117 /* Conditional branch */
12119 TCGLabel
*l1
= gen_new_label();
12121 tcg_gen_brcondi_tl(TCG_COND_NE
, bcond
, 0, l1
);
12122 gen_goto_tb(ctx
, 1, ctx
->base
.pc_next
+ insn_bytes
);
12124 gen_goto_tb(ctx
, 0, ctx
->btarget
);
12127 case MIPS_HFLAG_BR
:
12128 /* unconditional branch to register */
12129 if (ctx
->insn_flags
& (ASE_MIPS16
| ASE_MICROMIPS
)) {
12130 TCGv t0
= tcg_temp_new();
12131 TCGv_i32 t1
= tcg_temp_new_i32();
12133 tcg_gen_andi_tl(t0
, btarget
, 0x1);
12134 tcg_gen_trunc_tl_i32(t1
, t0
);
12136 tcg_gen_andi_i32(hflags
, hflags
, ~(uint32_t)MIPS_HFLAG_M16
);
12137 tcg_gen_shli_i32(t1
, t1
, MIPS_HFLAG_M16_SHIFT
);
12138 tcg_gen_or_i32(hflags
, hflags
, t1
);
12139 tcg_temp_free_i32(t1
);
12141 tcg_gen_andi_tl(cpu_PC
, btarget
, ~(target_ulong
)0x1);
12143 tcg_gen_mov_tl(cpu_PC
, btarget
);
12145 if (ctx
->base
.singlestep_enabled
) {
12146 save_cpu_state(ctx
, 0);
12147 gen_helper_raise_exception_debug(cpu_env
);
12149 tcg_gen_lookup_and_goto_ptr();
12152 fprintf(stderr
, "unknown branch 0x%x\n", proc_hflags
);
12158 /* Compact Branches */
12159 static void gen_compute_compact_branch(DisasContext
*ctx
, uint32_t opc
,
12160 int rs
, int rt
, int32_t offset
)
12162 int bcond_compute
= 0;
12163 TCGv t0
= tcg_temp_new();
12164 TCGv t1
= tcg_temp_new();
12165 int m16_lowbit
= (ctx
->hflags
& MIPS_HFLAG_M16
) != 0;
12167 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
12168 #ifdef MIPS_DEBUG_DISAS
12169 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
12170 "\n", ctx
->base
.pc_next
);
12172 gen_reserved_instruction(ctx
);
12176 /* Load needed operands and calculate btarget */
12178 /* compact branch */
12179 case OPC_BOVC
: /* OPC_BEQZALC, OPC_BEQC */
12180 case OPC_BNVC
: /* OPC_BNEZALC, OPC_BNEC */
12181 gen_load_gpr(t0
, rs
);
12182 gen_load_gpr(t1
, rt
);
12184 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
12185 if (rs
<= rt
&& rs
== 0) {
12186 /* OPC_BEQZALC, OPC_BNEZALC */
12187 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 4 + m16_lowbit
);
12190 case OPC_BLEZC
: /* OPC_BGEZC, OPC_BGEC */
12191 case OPC_BGTZC
: /* OPC_BLTZC, OPC_BLTC */
12192 gen_load_gpr(t0
, rs
);
12193 gen_load_gpr(t1
, rt
);
12195 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
12197 case OPC_BLEZALC
: /* OPC_BGEZALC, OPC_BGEUC */
12198 case OPC_BGTZALC
: /* OPC_BLTZALC, OPC_BLTUC */
12199 if (rs
== 0 || rs
== rt
) {
12200 /* OPC_BLEZALC, OPC_BGEZALC */
12201 /* OPC_BGTZALC, OPC_BLTZALC */
12202 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 4 + m16_lowbit
);
12204 gen_load_gpr(t0
, rs
);
12205 gen_load_gpr(t1
, rt
);
12207 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
12211 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
12216 /* OPC_BEQZC, OPC_BNEZC */
12217 gen_load_gpr(t0
, rs
);
12219 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
12221 /* OPC_JIC, OPC_JIALC */
12222 TCGv tbase
= tcg_temp_new();
12223 TCGv toffset
= tcg_temp_new();
12225 gen_load_gpr(tbase
, rt
);
12226 tcg_gen_movi_tl(toffset
, offset
);
12227 gen_op_addr_add(ctx
, btarget
, tbase
, toffset
);
12228 tcg_temp_free(tbase
);
12229 tcg_temp_free(toffset
);
12233 MIPS_INVAL("Compact branch/jump");
12234 gen_reserved_instruction(ctx
);
12238 if (bcond_compute
== 0) {
12239 /* Uncoditional compact branch */
12242 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 4 + m16_lowbit
);
12245 ctx
->hflags
|= MIPS_HFLAG_BR
;
12248 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 4 + m16_lowbit
);
12251 ctx
->hflags
|= MIPS_HFLAG_B
;
12254 MIPS_INVAL("Compact branch/jump");
12255 gen_reserved_instruction(ctx
);
12259 /* Generating branch here as compact branches don't have delay slot */
12260 gen_branch(ctx
, 4);
12262 /* Conditional compact branch */
12263 TCGLabel
*fs
= gen_new_label();
12264 save_cpu_state(ctx
, 0);
12267 case OPC_BLEZALC
: /* OPC_BGEZALC, OPC_BGEUC */
12268 if (rs
== 0 && rt
!= 0) {
12270 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE
), t1
, 0, fs
);
12271 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
12273 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE
), t1
, 0, fs
);
12276 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU
), t0
, t1
, fs
);
12279 case OPC_BGTZALC
: /* OPC_BLTZALC, OPC_BLTUC */
12280 if (rs
== 0 && rt
!= 0) {
12282 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT
), t1
, 0, fs
);
12283 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
12285 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT
), t1
, 0, fs
);
12288 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU
), t0
, t1
, fs
);
12291 case OPC_BLEZC
: /* OPC_BGEZC, OPC_BGEC */
12292 if (rs
== 0 && rt
!= 0) {
12294 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE
), t1
, 0, fs
);
12295 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
12297 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE
), t1
, 0, fs
);
12300 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE
), t0
, t1
, fs
);
12303 case OPC_BGTZC
: /* OPC_BLTZC, OPC_BLTC */
12304 if (rs
== 0 && rt
!= 0) {
12306 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT
), t1
, 0, fs
);
12307 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
12309 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT
), t1
, 0, fs
);
12312 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT
), t0
, t1
, fs
);
12315 case OPC_BOVC
: /* OPC_BEQZALC, OPC_BEQC */
12316 case OPC_BNVC
: /* OPC_BNEZALC, OPC_BNEC */
12318 /* OPC_BOVC, OPC_BNVC */
12319 TCGv t2
= tcg_temp_new();
12320 TCGv t3
= tcg_temp_new();
12321 TCGv t4
= tcg_temp_new();
12322 TCGv input_overflow
= tcg_temp_new();
12324 gen_load_gpr(t0
, rs
);
12325 gen_load_gpr(t1
, rt
);
12326 tcg_gen_ext32s_tl(t2
, t0
);
12327 tcg_gen_setcond_tl(TCG_COND_NE
, input_overflow
, t2
, t0
);
12328 tcg_gen_ext32s_tl(t3
, t1
);
12329 tcg_gen_setcond_tl(TCG_COND_NE
, t4
, t3
, t1
);
12330 tcg_gen_or_tl(input_overflow
, input_overflow
, t4
);
12332 tcg_gen_add_tl(t4
, t2
, t3
);
12333 tcg_gen_ext32s_tl(t4
, t4
);
12334 tcg_gen_xor_tl(t2
, t2
, t3
);
12335 tcg_gen_xor_tl(t3
, t4
, t3
);
12336 tcg_gen_andc_tl(t2
, t3
, t2
);
12337 tcg_gen_setcondi_tl(TCG_COND_LT
, t4
, t2
, 0);
12338 tcg_gen_or_tl(t4
, t4
, input_overflow
);
12339 if (opc
== OPC_BOVC
) {
12341 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE
), t4
, 0, fs
);
12344 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ
), t4
, 0, fs
);
12346 tcg_temp_free(input_overflow
);
12350 } else if (rs
< rt
&& rs
== 0) {
12351 /* OPC_BEQZALC, OPC_BNEZALC */
12352 if (opc
== OPC_BEQZALC
) {
12354 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ
), t1
, 0, fs
);
12357 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE
), t1
, 0, fs
);
12360 /* OPC_BEQC, OPC_BNEC */
12361 if (opc
== OPC_BEQC
) {
12363 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ
), t0
, t1
, fs
);
12366 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE
), t0
, t1
, fs
);
12371 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ
), t0
, 0, fs
);
12374 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE
), t0
, 0, fs
);
12377 MIPS_INVAL("Compact conditional branch/jump");
12378 gen_reserved_instruction(ctx
);
12382 /* Generating branch here as compact branches don't have delay slot */
12383 gen_goto_tb(ctx
, 1, ctx
->btarget
);
12386 ctx
->hflags
|= MIPS_HFLAG_FBNSLOT
;
12394 /* ISA extensions (ASEs) */
12395 /* MIPS16 extension to MIPS32 */
12397 /* MIPS16 major opcodes */
12399 M16_OPC_ADDIUSP
= 0x00,
12400 M16_OPC_ADDIUPC
= 0x01,
12402 M16_OPC_JAL
= 0x03,
12403 M16_OPC_BEQZ
= 0x04,
12404 M16_OPC_BNEQZ
= 0x05,
12405 M16_OPC_SHIFT
= 0x06,
12407 M16_OPC_RRIA
= 0x08,
12408 M16_OPC_ADDIU8
= 0x09,
12409 M16_OPC_SLTI
= 0x0a,
12410 M16_OPC_SLTIU
= 0x0b,
12413 M16_OPC_CMPI
= 0x0e,
12417 M16_OPC_LWSP
= 0x12,
12419 M16_OPC_LBU
= 0x14,
12420 M16_OPC_LHU
= 0x15,
12421 M16_OPC_LWPC
= 0x16,
12422 M16_OPC_LWU
= 0x17,
12425 M16_OPC_SWSP
= 0x1a,
12427 M16_OPC_RRR
= 0x1c,
12429 M16_OPC_EXTEND
= 0x1e,
12433 /* I8 funct field */
12452 /* RR funct field */
12486 /* I64 funct field */
12494 I64_DADDIUPC
= 0x6,
12498 /* RR ry field for CNVT */
12500 RR_RY_CNVT_ZEB
= 0x0,
12501 RR_RY_CNVT_ZEH
= 0x1,
12502 RR_RY_CNVT_ZEW
= 0x2,
12503 RR_RY_CNVT_SEB
= 0x4,
12504 RR_RY_CNVT_SEH
= 0x5,
12505 RR_RY_CNVT_SEW
= 0x6,
12508 static int xlat(int r
)
12510 static int map
[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
12515 static void gen_mips16_save(DisasContext
*ctx
,
12516 int xsregs
, int aregs
,
12517 int do_ra
, int do_s0
, int do_s1
,
12520 TCGv t0
= tcg_temp_new();
12521 TCGv t1
= tcg_temp_new();
12522 TCGv t2
= tcg_temp_new();
12552 gen_reserved_instruction(ctx
);
12558 gen_base_offset_addr(ctx
, t0
, 29, 12);
12559 gen_load_gpr(t1
, 7);
12560 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
12563 gen_base_offset_addr(ctx
, t0
, 29, 8);
12564 gen_load_gpr(t1
, 6);
12565 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
12568 gen_base_offset_addr(ctx
, t0
, 29, 4);
12569 gen_load_gpr(t1
, 5);
12570 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
12573 gen_base_offset_addr(ctx
, t0
, 29, 0);
12574 gen_load_gpr(t1
, 4);
12575 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
12578 gen_load_gpr(t0
, 29);
12580 #define DECR_AND_STORE(reg) do { \
12581 tcg_gen_movi_tl(t2, -4); \
12582 gen_op_addr_add(ctx, t0, t0, t2); \
12583 gen_load_gpr(t1, reg); \
12584 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \
12588 DECR_AND_STORE(31);
12593 DECR_AND_STORE(30);
12596 DECR_AND_STORE(23);
12599 DECR_AND_STORE(22);
12602 DECR_AND_STORE(21);
12605 DECR_AND_STORE(20);
12608 DECR_AND_STORE(19);
12611 DECR_AND_STORE(18);
12615 DECR_AND_STORE(17);
12618 DECR_AND_STORE(16);
12648 gen_reserved_instruction(ctx
);
12664 #undef DECR_AND_STORE
12666 tcg_gen_movi_tl(t2
, -framesize
);
12667 gen_op_addr_add(ctx
, cpu_gpr
[29], cpu_gpr
[29], t2
);
12673 static void gen_mips16_restore(DisasContext
*ctx
,
12674 int xsregs
, int aregs
,
12675 int do_ra
, int do_s0
, int do_s1
,
12679 TCGv t0
= tcg_temp_new();
12680 TCGv t1
= tcg_temp_new();
12681 TCGv t2
= tcg_temp_new();
12683 tcg_gen_movi_tl(t2
, framesize
);
12684 gen_op_addr_add(ctx
, t0
, cpu_gpr
[29], t2
);
12686 #define DECR_AND_LOAD(reg) do { \
12687 tcg_gen_movi_tl(t2, -4); \
12688 gen_op_addr_add(ctx, t0, t0, t2); \
12689 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \
12690 gen_store_gpr(t1, reg); \
12754 gen_reserved_instruction(ctx
);
12770 #undef DECR_AND_LOAD
12772 tcg_gen_movi_tl(t2
, framesize
);
12773 gen_op_addr_add(ctx
, cpu_gpr
[29], cpu_gpr
[29], t2
);
12779 static void gen_addiupc(DisasContext
*ctx
, int rx
, int imm
,
12780 int is_64_bit
, int extended
)
12784 if (extended
&& (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
12785 gen_reserved_instruction(ctx
);
12789 t0
= tcg_temp_new();
12791 tcg_gen_movi_tl(t0
, pc_relative_pc(ctx
));
12792 tcg_gen_addi_tl(cpu_gpr
[rx
], t0
, imm
);
12794 tcg_gen_ext32s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
12800 static void gen_cache_operation(DisasContext
*ctx
, uint32_t op
, int base
,
12803 TCGv_i32 t0
= tcg_const_i32(op
);
12804 TCGv t1
= tcg_temp_new();
12805 gen_base_offset_addr(ctx
, t1
, base
, offset
);
12806 gen_helper_cache(cpu_env
, t1
, t0
);
12809 #if defined(TARGET_MIPS64)
12810 static void decode_i64_mips16(DisasContext
*ctx
,
12811 int ry
, int funct
, int16_t offset
,
12816 check_insn(ctx
, ISA_MIPS3
);
12817 check_mips_64(ctx
);
12818 offset
= extended
? offset
: offset
<< 3;
12819 gen_ld(ctx
, OPC_LD
, ry
, 29, offset
);
12822 check_insn(ctx
, ISA_MIPS3
);
12823 check_mips_64(ctx
);
12824 offset
= extended
? offset
: offset
<< 3;
12825 gen_st(ctx
, OPC_SD
, ry
, 29, offset
);
12828 check_insn(ctx
, ISA_MIPS3
);
12829 check_mips_64(ctx
);
12830 offset
= extended
? offset
: (ctx
->opcode
& 0xff) << 3;
12831 gen_st(ctx
, OPC_SD
, 31, 29, offset
);
12834 check_insn(ctx
, ISA_MIPS3
);
12835 check_mips_64(ctx
);
12836 offset
= extended
? offset
: ((int8_t)ctx
->opcode
) << 3;
12837 gen_arith_imm(ctx
, OPC_DADDIU
, 29, 29, offset
);
12840 check_insn(ctx
, ISA_MIPS3
);
12841 check_mips_64(ctx
);
12842 if (extended
&& (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
12843 gen_reserved_instruction(ctx
);
12845 offset
= extended
? offset
: offset
<< 3;
12846 gen_ld(ctx
, OPC_LDPC
, ry
, 0, offset
);
12850 check_insn(ctx
, ISA_MIPS3
);
12851 check_mips_64(ctx
);
12852 offset
= extended
? offset
: ((int8_t)(offset
<< 3)) >> 3;
12853 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, ry
, offset
);
12856 check_insn(ctx
, ISA_MIPS3
);
12857 check_mips_64(ctx
);
12858 offset
= extended
? offset
: offset
<< 2;
12859 gen_addiupc(ctx
, ry
, offset
, 1, extended
);
12862 check_insn(ctx
, ISA_MIPS3
);
12863 check_mips_64(ctx
);
12864 offset
= extended
? offset
: offset
<< 2;
12865 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, 29, offset
);
12871 static int decode_extended_mips16_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
12873 int extend
= translator_lduw(env
, ctx
->base
.pc_next
+ 2);
12874 int op
, rx
, ry
, funct
, sa
;
12875 int16_t imm
, offset
;
12877 ctx
->opcode
= (ctx
->opcode
<< 16) | extend
;
12878 op
= (ctx
->opcode
>> 11) & 0x1f;
12879 sa
= (ctx
->opcode
>> 22) & 0x1f;
12880 funct
= (ctx
->opcode
>> 8) & 0x7;
12881 rx
= xlat((ctx
->opcode
>> 8) & 0x7);
12882 ry
= xlat((ctx
->opcode
>> 5) & 0x7);
12883 offset
= imm
= (int16_t) (((ctx
->opcode
>> 16) & 0x1f) << 11
12884 | ((ctx
->opcode
>> 21) & 0x3f) << 5
12885 | (ctx
->opcode
& 0x1f));
12888 * The extended opcodes cleverly reuse the opcodes from their 16-bit
12892 case M16_OPC_ADDIUSP
:
12893 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 29, imm
);
12895 case M16_OPC_ADDIUPC
:
12896 gen_addiupc(ctx
, rx
, imm
, 0, 1);
12899 gen_compute_branch(ctx
, OPC_BEQ
, 4, 0, 0, offset
<< 1, 0);
12900 /* No delay slot, so just process as a normal instruction */
12903 gen_compute_branch(ctx
, OPC_BEQ
, 4, rx
, 0, offset
<< 1, 0);
12904 /* No delay slot, so just process as a normal instruction */
12906 case M16_OPC_BNEQZ
:
12907 gen_compute_branch(ctx
, OPC_BNE
, 4, rx
, 0, offset
<< 1, 0);
12908 /* No delay slot, so just process as a normal instruction */
12910 case M16_OPC_SHIFT
:
12911 switch (ctx
->opcode
& 0x3) {
12913 gen_shift_imm(ctx
, OPC_SLL
, rx
, ry
, sa
);
12916 #if defined(TARGET_MIPS64)
12917 check_mips_64(ctx
);
12918 gen_shift_imm(ctx
, OPC_DSLL
, rx
, ry
, sa
);
12920 gen_reserved_instruction(ctx
);
12924 gen_shift_imm(ctx
, OPC_SRL
, rx
, ry
, sa
);
12927 gen_shift_imm(ctx
, OPC_SRA
, rx
, ry
, sa
);
12931 #if defined(TARGET_MIPS64)
12933 check_insn(ctx
, ISA_MIPS3
);
12934 check_mips_64(ctx
);
12935 gen_ld(ctx
, OPC_LD
, ry
, rx
, offset
);
12939 imm
= ctx
->opcode
& 0xf;
12940 imm
= imm
| ((ctx
->opcode
>> 20) & 0x7f) << 4;
12941 imm
= imm
| ((ctx
->opcode
>> 16) & 0xf) << 11;
12942 imm
= (int16_t) (imm
<< 1) >> 1;
12943 if ((ctx
->opcode
>> 4) & 0x1) {
12944 #if defined(TARGET_MIPS64)
12945 check_mips_64(ctx
);
12946 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, rx
, imm
);
12948 gen_reserved_instruction(ctx
);
12951 gen_arith_imm(ctx
, OPC_ADDIU
, ry
, rx
, imm
);
12954 case M16_OPC_ADDIU8
:
12955 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, rx
, imm
);
12958 gen_slt_imm(ctx
, OPC_SLTI
, 24, rx
, imm
);
12960 case M16_OPC_SLTIU
:
12961 gen_slt_imm(ctx
, OPC_SLTIU
, 24, rx
, imm
);
12966 gen_compute_branch(ctx
, OPC_BEQ
, 4, 24, 0, offset
<< 1, 0);
12969 gen_compute_branch(ctx
, OPC_BNE
, 4, 24, 0, offset
<< 1, 0);
12972 gen_st(ctx
, OPC_SW
, 31, 29, imm
);
12975 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, imm
);
12978 check_insn(ctx
, ISA_MIPS_R1
);
12980 int xsregs
= (ctx
->opcode
>> 24) & 0x7;
12981 int aregs
= (ctx
->opcode
>> 16) & 0xf;
12982 int do_ra
= (ctx
->opcode
>> 6) & 0x1;
12983 int do_s0
= (ctx
->opcode
>> 5) & 0x1;
12984 int do_s1
= (ctx
->opcode
>> 4) & 0x1;
12985 int framesize
= (((ctx
->opcode
>> 20) & 0xf) << 4
12986 | (ctx
->opcode
& 0xf)) << 3;
12988 if (ctx
->opcode
& (1 << 7)) {
12989 gen_mips16_save(ctx
, xsregs
, aregs
,
12990 do_ra
, do_s0
, do_s1
,
12993 gen_mips16_restore(ctx
, xsregs
, aregs
,
12994 do_ra
, do_s0
, do_s1
,
13000 gen_reserved_instruction(ctx
);
13005 tcg_gen_movi_tl(cpu_gpr
[rx
], (uint16_t) imm
);
13008 tcg_gen_xori_tl(cpu_gpr
[24], cpu_gpr
[rx
], (uint16_t) imm
);
13010 #if defined(TARGET_MIPS64)
13012 check_insn(ctx
, ISA_MIPS3
);
13013 check_mips_64(ctx
);
13014 gen_st(ctx
, OPC_SD
, ry
, rx
, offset
);
13018 gen_ld(ctx
, OPC_LB
, ry
, rx
, offset
);
13021 gen_ld(ctx
, OPC_LH
, ry
, rx
, offset
);
13024 gen_ld(ctx
, OPC_LW
, rx
, 29, offset
);
13027 gen_ld(ctx
, OPC_LW
, ry
, rx
, offset
);
13030 gen_ld(ctx
, OPC_LBU
, ry
, rx
, offset
);
13033 gen_ld(ctx
, OPC_LHU
, ry
, rx
, offset
);
13036 gen_ld(ctx
, OPC_LWPC
, rx
, 0, offset
);
13038 #if defined(TARGET_MIPS64)
13040 check_insn(ctx
, ISA_MIPS3
);
13041 check_mips_64(ctx
);
13042 gen_ld(ctx
, OPC_LWU
, ry
, rx
, offset
);
13046 gen_st(ctx
, OPC_SB
, ry
, rx
, offset
);
13049 gen_st(ctx
, OPC_SH
, ry
, rx
, offset
);
13052 gen_st(ctx
, OPC_SW
, rx
, 29, offset
);
13055 gen_st(ctx
, OPC_SW
, ry
, rx
, offset
);
13057 #if defined(TARGET_MIPS64)
13059 decode_i64_mips16(ctx
, ry
, funct
, offset
, 1);
13063 gen_reserved_instruction(ctx
);
13070 static inline bool is_uhi(int sdbbp_code
)
13072 #ifdef CONFIG_USER_ONLY
13075 return semihosting_enabled() && sdbbp_code
== 1;
13079 #ifdef CONFIG_USER_ONLY
13080 /* The above should dead-code away any calls to this..*/
13081 static inline void gen_helper_do_semihosting(void *env
)
13083 g_assert_not_reached();
13087 static int decode_mips16_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
13091 int op
, cnvt_op
, op1
, offset
;
13095 op
= (ctx
->opcode
>> 11) & 0x1f;
13096 sa
= (ctx
->opcode
>> 2) & 0x7;
13097 sa
= sa
== 0 ? 8 : sa
;
13098 rx
= xlat((ctx
->opcode
>> 8) & 0x7);
13099 cnvt_op
= (ctx
->opcode
>> 5) & 0x7;
13100 ry
= xlat((ctx
->opcode
>> 5) & 0x7);
13101 op1
= offset
= ctx
->opcode
& 0x1f;
13106 case M16_OPC_ADDIUSP
:
13108 int16_t imm
= ((uint8_t) ctx
->opcode
) << 2;
13110 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 29, imm
);
13113 case M16_OPC_ADDIUPC
:
13114 gen_addiupc(ctx
, rx
, ((uint8_t) ctx
->opcode
) << 2, 0, 0);
13117 offset
= (ctx
->opcode
& 0x7ff) << 1;
13118 offset
= (int16_t)(offset
<< 4) >> 4;
13119 gen_compute_branch(ctx
, OPC_BEQ
, 2, 0, 0, offset
, 0);
13120 /* No delay slot, so just process as a normal instruction */
13123 offset
= translator_lduw(env
, ctx
->base
.pc_next
+ 2);
13124 offset
= (((ctx
->opcode
& 0x1f) << 21)
13125 | ((ctx
->opcode
>> 5) & 0x1f) << 16
13127 op
= ((ctx
->opcode
>> 10) & 0x1) ? OPC_JALX
: OPC_JAL
;
13128 gen_compute_branch(ctx
, op
, 4, rx
, ry
, offset
, 2);
13132 gen_compute_branch(ctx
, OPC_BEQ
, 2, rx
, 0,
13133 ((int8_t)ctx
->opcode
) << 1, 0);
13134 /* No delay slot, so just process as a normal instruction */
13136 case M16_OPC_BNEQZ
:
13137 gen_compute_branch(ctx
, OPC_BNE
, 2, rx
, 0,
13138 ((int8_t)ctx
->opcode
) << 1, 0);
13139 /* No delay slot, so just process as a normal instruction */
13141 case M16_OPC_SHIFT
:
13142 switch (ctx
->opcode
& 0x3) {
13144 gen_shift_imm(ctx
, OPC_SLL
, rx
, ry
, sa
);
13147 #if defined(TARGET_MIPS64)
13148 check_insn(ctx
, ISA_MIPS3
);
13149 check_mips_64(ctx
);
13150 gen_shift_imm(ctx
, OPC_DSLL
, rx
, ry
, sa
);
13152 gen_reserved_instruction(ctx
);
13156 gen_shift_imm(ctx
, OPC_SRL
, rx
, ry
, sa
);
13159 gen_shift_imm(ctx
, OPC_SRA
, rx
, ry
, sa
);
13163 #if defined(TARGET_MIPS64)
13165 check_insn(ctx
, ISA_MIPS3
);
13166 check_mips_64(ctx
);
13167 gen_ld(ctx
, OPC_LD
, ry
, rx
, offset
<< 3);
13172 int16_t imm
= (int8_t)((ctx
->opcode
& 0xf) << 4) >> 4;
13174 if ((ctx
->opcode
>> 4) & 1) {
13175 #if defined(TARGET_MIPS64)
13176 check_insn(ctx
, ISA_MIPS3
);
13177 check_mips_64(ctx
);
13178 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, rx
, imm
);
13180 gen_reserved_instruction(ctx
);
13183 gen_arith_imm(ctx
, OPC_ADDIU
, ry
, rx
, imm
);
13187 case M16_OPC_ADDIU8
:
13189 int16_t imm
= (int8_t) ctx
->opcode
;
13191 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, rx
, imm
);
13196 int16_t imm
= (uint8_t) ctx
->opcode
;
13197 gen_slt_imm(ctx
, OPC_SLTI
, 24, rx
, imm
);
13200 case M16_OPC_SLTIU
:
13202 int16_t imm
= (uint8_t) ctx
->opcode
;
13203 gen_slt_imm(ctx
, OPC_SLTIU
, 24, rx
, imm
);
13210 funct
= (ctx
->opcode
>> 8) & 0x7;
13213 gen_compute_branch(ctx
, OPC_BEQ
, 2, 24, 0,
13214 ((int8_t)ctx
->opcode
) << 1, 0);
13217 gen_compute_branch(ctx
, OPC_BNE
, 2, 24, 0,
13218 ((int8_t)ctx
->opcode
) << 1, 0);
13221 gen_st(ctx
, OPC_SW
, 31, 29, (ctx
->opcode
& 0xff) << 2);
13224 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29,
13225 ((int8_t)ctx
->opcode
) << 3);
13228 check_insn(ctx
, ISA_MIPS_R1
);
13230 int do_ra
= ctx
->opcode
& (1 << 6);
13231 int do_s0
= ctx
->opcode
& (1 << 5);
13232 int do_s1
= ctx
->opcode
& (1 << 4);
13233 int framesize
= ctx
->opcode
& 0xf;
13235 if (framesize
== 0) {
13238 framesize
= framesize
<< 3;
13241 if (ctx
->opcode
& (1 << 7)) {
13242 gen_mips16_save(ctx
, 0, 0,
13243 do_ra
, do_s0
, do_s1
, framesize
);
13245 gen_mips16_restore(ctx
, 0, 0,
13246 do_ra
, do_s0
, do_s1
, framesize
);
13252 int rz
= xlat(ctx
->opcode
& 0x7);
13254 reg32
= (((ctx
->opcode
>> 3) & 0x3) << 3) |
13255 ((ctx
->opcode
>> 5) & 0x7);
13256 gen_arith(ctx
, OPC_ADDU
, reg32
, rz
, 0);
13260 reg32
= ctx
->opcode
& 0x1f;
13261 gen_arith(ctx
, OPC_ADDU
, ry
, reg32
, 0);
13264 gen_reserved_instruction(ctx
);
13271 int16_t imm
= (uint8_t) ctx
->opcode
;
13273 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 0, imm
);
13278 int16_t imm
= (uint8_t) ctx
->opcode
;
13279 gen_logic_imm(ctx
, OPC_XORI
, 24, rx
, imm
);
13282 #if defined(TARGET_MIPS64)
13284 check_insn(ctx
, ISA_MIPS3
);
13285 check_mips_64(ctx
);
13286 gen_st(ctx
, OPC_SD
, ry
, rx
, offset
<< 3);
13290 gen_ld(ctx
, OPC_LB
, ry
, rx
, offset
);
13293 gen_ld(ctx
, OPC_LH
, ry
, rx
, offset
<< 1);
13296 gen_ld(ctx
, OPC_LW
, rx
, 29, ((uint8_t)ctx
->opcode
) << 2);
13299 gen_ld(ctx
, OPC_LW
, ry
, rx
, offset
<< 2);
13302 gen_ld(ctx
, OPC_LBU
, ry
, rx
, offset
);
13305 gen_ld(ctx
, OPC_LHU
, ry
, rx
, offset
<< 1);
13308 gen_ld(ctx
, OPC_LWPC
, rx
, 0, ((uint8_t)ctx
->opcode
) << 2);
13310 #if defined(TARGET_MIPS64)
13312 check_insn(ctx
, ISA_MIPS3
);
13313 check_mips_64(ctx
);
13314 gen_ld(ctx
, OPC_LWU
, ry
, rx
, offset
<< 2);
13318 gen_st(ctx
, OPC_SB
, ry
, rx
, offset
);
13321 gen_st(ctx
, OPC_SH
, ry
, rx
, offset
<< 1);
13324 gen_st(ctx
, OPC_SW
, rx
, 29, ((uint8_t)ctx
->opcode
) << 2);
13327 gen_st(ctx
, OPC_SW
, ry
, rx
, offset
<< 2);
13331 int rz
= xlat((ctx
->opcode
>> 2) & 0x7);
13334 switch (ctx
->opcode
& 0x3) {
13336 mips32_op
= OPC_ADDU
;
13339 mips32_op
= OPC_SUBU
;
13341 #if defined(TARGET_MIPS64)
13343 mips32_op
= OPC_DADDU
;
13344 check_insn(ctx
, ISA_MIPS3
);
13345 check_mips_64(ctx
);
13348 mips32_op
= OPC_DSUBU
;
13349 check_insn(ctx
, ISA_MIPS3
);
13350 check_mips_64(ctx
);
13354 gen_reserved_instruction(ctx
);
13358 gen_arith(ctx
, mips32_op
, rz
, rx
, ry
);
13367 int nd
= (ctx
->opcode
>> 7) & 0x1;
13368 int link
= (ctx
->opcode
>> 6) & 0x1;
13369 int ra
= (ctx
->opcode
>> 5) & 0x1;
13372 check_insn(ctx
, ISA_MIPS_R1
);
13381 gen_compute_branch(ctx
, op
, 2, ra
? 31 : rx
, 31, 0,
13386 if (is_uhi(extract32(ctx
->opcode
, 5, 6))) {
13387 gen_helper_do_semihosting(cpu_env
);
13390 * XXX: not clear which exception should be raised
13391 * when in debug mode...
13393 check_insn(ctx
, ISA_MIPS_R1
);
13394 generate_exception_end(ctx
, EXCP_DBp
);
13398 gen_slt(ctx
, OPC_SLT
, 24, rx
, ry
);
13401 gen_slt(ctx
, OPC_SLTU
, 24, rx
, ry
);
13404 generate_exception_end(ctx
, EXCP_BREAK
);
13407 gen_shift(ctx
, OPC_SLLV
, ry
, rx
, ry
);
13410 gen_shift(ctx
, OPC_SRLV
, ry
, rx
, ry
);
13413 gen_shift(ctx
, OPC_SRAV
, ry
, rx
, ry
);
13415 #if defined(TARGET_MIPS64)
13417 check_insn(ctx
, ISA_MIPS3
);
13418 check_mips_64(ctx
);
13419 gen_shift_imm(ctx
, OPC_DSRL
, ry
, ry
, sa
);
13423 gen_logic(ctx
, OPC_XOR
, 24, rx
, ry
);
13426 gen_arith(ctx
, OPC_SUBU
, rx
, 0, ry
);
13429 gen_logic(ctx
, OPC_AND
, rx
, rx
, ry
);
13432 gen_logic(ctx
, OPC_OR
, rx
, rx
, ry
);
13435 gen_logic(ctx
, OPC_XOR
, rx
, rx
, ry
);
13438 gen_logic(ctx
, OPC_NOR
, rx
, ry
, 0);
13441 gen_HILO(ctx
, OPC_MFHI
, 0, rx
);
13444 check_insn(ctx
, ISA_MIPS_R1
);
13446 case RR_RY_CNVT_ZEB
:
13447 tcg_gen_ext8u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
13449 case RR_RY_CNVT_ZEH
:
13450 tcg_gen_ext16u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
13452 case RR_RY_CNVT_SEB
:
13453 tcg_gen_ext8s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
13455 case RR_RY_CNVT_SEH
:
13456 tcg_gen_ext16s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
13458 #if defined(TARGET_MIPS64)
13459 case RR_RY_CNVT_ZEW
:
13460 check_insn(ctx
, ISA_MIPS_R1
);
13461 check_mips_64(ctx
);
13462 tcg_gen_ext32u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
13464 case RR_RY_CNVT_SEW
:
13465 check_insn(ctx
, ISA_MIPS_R1
);
13466 check_mips_64(ctx
);
13467 tcg_gen_ext32s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
13471 gen_reserved_instruction(ctx
);
13476 gen_HILO(ctx
, OPC_MFLO
, 0, rx
);
13478 #if defined(TARGET_MIPS64)
13480 check_insn(ctx
, ISA_MIPS3
);
13481 check_mips_64(ctx
);
13482 gen_shift_imm(ctx
, OPC_DSRA
, ry
, ry
, sa
);
13485 check_insn(ctx
, ISA_MIPS3
);
13486 check_mips_64(ctx
);
13487 gen_shift(ctx
, OPC_DSLLV
, ry
, rx
, ry
);
13490 check_insn(ctx
, ISA_MIPS3
);
13491 check_mips_64(ctx
);
13492 gen_shift(ctx
, OPC_DSRLV
, ry
, rx
, ry
);
13495 check_insn(ctx
, ISA_MIPS3
);
13496 check_mips_64(ctx
);
13497 gen_shift(ctx
, OPC_DSRAV
, ry
, rx
, ry
);
13501 gen_muldiv(ctx
, OPC_MULT
, 0, rx
, ry
);
13504 gen_muldiv(ctx
, OPC_MULTU
, 0, rx
, ry
);
13507 gen_muldiv(ctx
, OPC_DIV
, 0, rx
, ry
);
13510 gen_muldiv(ctx
, OPC_DIVU
, 0, rx
, ry
);
13512 #if defined(TARGET_MIPS64)
13514 check_insn(ctx
, ISA_MIPS3
);
13515 check_mips_64(ctx
);
13516 gen_muldiv(ctx
, OPC_DMULT
, 0, rx
, ry
);
13519 check_insn(ctx
, ISA_MIPS3
);
13520 check_mips_64(ctx
);
13521 gen_muldiv(ctx
, OPC_DMULTU
, 0, rx
, ry
);
13524 check_insn(ctx
, ISA_MIPS3
);
13525 check_mips_64(ctx
);
13526 gen_muldiv(ctx
, OPC_DDIV
, 0, rx
, ry
);
13529 check_insn(ctx
, ISA_MIPS3
);
13530 check_mips_64(ctx
);
13531 gen_muldiv(ctx
, OPC_DDIVU
, 0, rx
, ry
);
13535 gen_reserved_instruction(ctx
);
13539 case M16_OPC_EXTEND
:
13540 decode_extended_mips16_opc(env
, ctx
);
13543 #if defined(TARGET_MIPS64)
13545 funct
= (ctx
->opcode
>> 8) & 0x7;
13546 decode_i64_mips16(ctx
, ry
, funct
, offset
, 0);
13550 gen_reserved_instruction(ctx
);
13557 /* microMIPS extension to MIPS32/MIPS64 */
13560 * microMIPS32/microMIPS64 major opcodes
13562 * 1. MIPS Architecture for Programmers Volume II-B:
13563 * The microMIPS32 Instruction Set (Revision 3.05)
13565 * Table 6.2 microMIPS32 Encoding of Major Opcode Field
13567 * 2. MIPS Architecture For Programmers Volume II-A:
13568 * The MIPS64 Instruction Set (Revision 3.51)
13598 POOL32S
= 0x16, /* MIPS64 */
13599 DADDIU32
= 0x17, /* MIPS64 */
13628 /* 0x29 is reserved */
13641 /* 0x31 is reserved */
13654 SD32
= 0x36, /* MIPS64 */
13655 LD32
= 0x37, /* MIPS64 */
13657 /* 0x39 is reserved */
13673 /* PCREL Instructions perform PC-Relative address calculation. bits 20..16 */
13695 /* POOL32A encoding of minor opcode field */
13699 * These opcodes are distinguished only by bits 9..6; those bits are
13700 * what are recorded below.
13738 /* The following can be distinguished by their lower 6 bits. */
13748 /* POOL32AXF encoding of minor opcode field extension */
13751 * 1. MIPS Architecture for Programmers Volume II-B:
13752 * The microMIPS32 Instruction Set (Revision 3.05)
13754 * Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
13756 * 2. MIPS Architecture for Programmers VolumeIV-e:
13757 * The MIPS DSP Application-Specific Extension
13758 * to the microMIPS32 Architecture (Revision 2.34)
13760 * Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
13775 /* begin of microMIPS32 DSP */
13777 /* bits 13..12 for 0x01 */
13783 /* bits 13..12 for 0x2a */
13789 /* bits 13..12 for 0x32 */
13793 /* end of microMIPS32 DSP */
13795 /* bits 15..12 for 0x2c */
13812 /* bits 15..12 for 0x34 */
13820 /* bits 15..12 for 0x3c */
13822 JR
= 0x0, /* alias */
13830 /* bits 15..12 for 0x05 */
13834 /* bits 15..12 for 0x0d */
13846 /* bits 15..12 for 0x15 */
13852 /* bits 15..12 for 0x1d */
13856 /* bits 15..12 for 0x2d */
13861 /* bits 15..12 for 0x35 */
13868 /* POOL32B encoding of minor opcode field (bits 15..12) */
13884 /* POOL32C encoding of minor opcode field (bits 15..12) */
13905 /* POOL32C LD-EVA encoding of minor opcode field (bits 11..9) */
13918 /* POOL32C ST-EVA encoding of minor opcode field (bits 11..9) */
13931 /* POOL32F encoding of minor opcode field (bits 5..0) */
13934 /* These are the bit 7..6 values */
13943 /* These are the bit 8..6 values */
13968 MOVZ_FMT_05
= 0x05,
14002 CABS_COND_FMT
= 0x1c, /* MIPS3D */
14009 /* POOL32Fxf encoding of minor opcode extension field */
14047 /* POOL32I encoding of minor opcode field (bits 25..21) */
14077 /* These overlap and are distinguished by bit16 of the instruction */
14086 /* POOL16A encoding of minor opcode field */
14093 /* POOL16B encoding of minor opcode field */
14100 /* POOL16C encoding of minor opcode field */
14120 /* R6 POOL16C encoding of minor opcode field (bits 0..5) */
14144 /* POOL16D encoding of minor opcode field */
14151 /* POOL16E encoding of minor opcode field */
14158 static int mmreg(int r
)
14160 static const int map
[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
14165 /* Used for 16-bit store instructions. */
14166 static int mmreg2(int r
)
14168 static const int map
[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
14173 #define uMIPS_RD(op) ((op >> 7) & 0x7)
14174 #define uMIPS_RS(op) ((op >> 4) & 0x7)
14175 #define uMIPS_RS2(op) uMIPS_RS(op)
14176 #define uMIPS_RS1(op) ((op >> 1) & 0x7)
14177 #define uMIPS_RD5(op) ((op >> 5) & 0x1f)
14178 #define uMIPS_RS5(op) (op & 0x1f)
14180 /* Signed immediate */
14181 #define SIMM(op, start, width) \
14182 ((int32_t)(((op >> start) & ((~0U) >> (32 - width))) \
14185 /* Zero-extended immediate */
14186 #define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32 - width)))
14188 static void gen_addiur1sp(DisasContext
*ctx
)
14190 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
14192 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, 29, ((ctx
->opcode
>> 1) & 0x3f) << 2);
14195 static void gen_addiur2(DisasContext
*ctx
)
14197 static const int decoded_imm
[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
14198 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
14199 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
14201 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, rs
, decoded_imm
[ZIMM(ctx
->opcode
, 1, 3)]);
14204 static void gen_addiusp(DisasContext
*ctx
)
14206 int encoded
= ZIMM(ctx
->opcode
, 1, 9);
14209 if (encoded
<= 1) {
14210 decoded
= 256 + encoded
;
14211 } else if (encoded
<= 255) {
14213 } else if (encoded
<= 509) {
14214 decoded
= encoded
- 512;
14216 decoded
= encoded
- 768;
14219 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, decoded
<< 2);
14222 static void gen_addius5(DisasContext
*ctx
)
14224 int imm
= SIMM(ctx
->opcode
, 1, 4);
14225 int rd
= (ctx
->opcode
>> 5) & 0x1f;
14227 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, rd
, imm
);
14230 static void gen_andi16(DisasContext
*ctx
)
14232 static const int decoded_imm
[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
14233 31, 32, 63, 64, 255, 32768, 65535 };
14234 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
14235 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
14236 int encoded
= ZIMM(ctx
->opcode
, 0, 4);
14238 gen_logic_imm(ctx
, OPC_ANDI
, rd
, rs
, decoded_imm
[encoded
]);
14241 static void gen_ldst_multiple(DisasContext
*ctx
, uint32_t opc
, int reglist
,
14242 int base
, int16_t offset
)
14247 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
14248 gen_reserved_instruction(ctx
);
14252 t0
= tcg_temp_new();
14254 gen_base_offset_addr(ctx
, t0
, base
, offset
);
14256 t1
= tcg_const_tl(reglist
);
14257 t2
= tcg_const_i32(ctx
->mem_idx
);
14259 save_cpu_state(ctx
, 1);
14262 gen_helper_lwm(cpu_env
, t0
, t1
, t2
);
14265 gen_helper_swm(cpu_env
, t0
, t1
, t2
);
14267 #ifdef TARGET_MIPS64
14269 gen_helper_ldm(cpu_env
, t0
, t1
, t2
);
14272 gen_helper_sdm(cpu_env
, t0
, t1
, t2
);
14278 tcg_temp_free_i32(t2
);
14282 static void gen_pool16c_insn(DisasContext
*ctx
)
14284 int rd
= mmreg((ctx
->opcode
>> 3) & 0x7);
14285 int rs
= mmreg(ctx
->opcode
& 0x7);
14287 switch (((ctx
->opcode
) >> 4) & 0x3f) {
14292 gen_logic(ctx
, OPC_NOR
, rd
, rs
, 0);
14298 gen_logic(ctx
, OPC_XOR
, rd
, rd
, rs
);
14304 gen_logic(ctx
, OPC_AND
, rd
, rd
, rs
);
14310 gen_logic(ctx
, OPC_OR
, rd
, rd
, rs
);
14317 static const int lwm_convert
[] = { 0x11, 0x12, 0x13, 0x14 };
14318 int offset
= ZIMM(ctx
->opcode
, 0, 4);
14320 gen_ldst_multiple(ctx
, LWM32
, lwm_convert
[(ctx
->opcode
>> 4) & 0x3],
14329 static const int swm_convert
[] = { 0x11, 0x12, 0x13, 0x14 };
14330 int offset
= ZIMM(ctx
->opcode
, 0, 4);
14332 gen_ldst_multiple(ctx
, SWM32
, swm_convert
[(ctx
->opcode
>> 4) & 0x3],
14339 int reg
= ctx
->opcode
& 0x1f;
14341 gen_compute_branch(ctx
, OPC_JR
, 2, reg
, 0, 0, 4);
14347 int reg
= ctx
->opcode
& 0x1f;
14348 gen_compute_branch(ctx
, OPC_JR
, 2, reg
, 0, 0, 0);
14350 * Let normal delay slot handling in our caller take us
14351 * to the branch target.
14357 gen_compute_branch(ctx
, OPC_JALR
, 2, ctx
->opcode
& 0x1f, 31, 0, 4);
14358 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
14362 gen_compute_branch(ctx
, OPC_JALR
, 2, ctx
->opcode
& 0x1f, 31, 0, 2);
14363 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
14367 gen_HILO(ctx
, OPC_MFHI
, 0, uMIPS_RS5(ctx
->opcode
));
14371 gen_HILO(ctx
, OPC_MFLO
, 0, uMIPS_RS5(ctx
->opcode
));
14374 generate_exception_end(ctx
, EXCP_BREAK
);
14377 if (is_uhi(extract32(ctx
->opcode
, 0, 4))) {
14378 gen_helper_do_semihosting(cpu_env
);
14381 * XXX: not clear which exception should be raised
14382 * when in debug mode...
14384 check_insn(ctx
, ISA_MIPS_R1
);
14385 generate_exception_end(ctx
, EXCP_DBp
);
14388 case JRADDIUSP
+ 0:
14389 case JRADDIUSP
+ 1:
14391 int imm
= ZIMM(ctx
->opcode
, 0, 5);
14392 gen_compute_branch(ctx
, OPC_JR
, 2, 31, 0, 0, 0);
14393 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, imm
<< 2);
14395 * Let normal delay slot handling in our caller take us
14396 * to the branch target.
14401 gen_reserved_instruction(ctx
);
14406 static inline void gen_movep(DisasContext
*ctx
, int enc_dest
, int enc_rt
,
14410 static const int rd_enc
[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
14411 static const int re_enc
[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
14412 static const int rs_rt_enc
[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
14414 rd
= rd_enc
[enc_dest
];
14415 re
= re_enc
[enc_dest
];
14416 gen_load_gpr(cpu_gpr
[rd
], rs_rt_enc
[enc_rs
]);
14417 gen_load_gpr(cpu_gpr
[re
], rs_rt_enc
[enc_rt
]);
14420 static void gen_pool16c_r6_insn(DisasContext
*ctx
)
14422 int rt
= mmreg((ctx
->opcode
>> 7) & 0x7);
14423 int rs
= mmreg((ctx
->opcode
>> 4) & 0x7);
14425 switch (ctx
->opcode
& 0xf) {
14427 gen_logic(ctx
, OPC_NOR
, rt
, rs
, 0);
14430 gen_logic(ctx
, OPC_AND
, rt
, rt
, rs
);
14434 int lwm_converted
= 0x11 + extract32(ctx
->opcode
, 8, 2);
14435 int offset
= extract32(ctx
->opcode
, 4, 4);
14436 gen_ldst_multiple(ctx
, LWM32
, lwm_converted
, 29, offset
<< 2);
14439 case R6_JRC16
: /* JRCADDIUSP */
14440 if ((ctx
->opcode
>> 4) & 1) {
14442 int imm
= extract32(ctx
->opcode
, 5, 5);
14443 gen_compute_branch(ctx
, OPC_JR
, 2, 31, 0, 0, 0);
14444 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, imm
<< 2);
14447 rs
= extract32(ctx
->opcode
, 5, 5);
14448 gen_compute_branch(ctx
, OPC_JR
, 2, rs
, 0, 0, 0);
14460 int enc_dest
= uMIPS_RD(ctx
->opcode
);
14461 int enc_rt
= uMIPS_RS2(ctx
->opcode
);
14462 int enc_rs
= (ctx
->opcode
& 3) | ((ctx
->opcode
>> 1) & 4);
14463 gen_movep(ctx
, enc_dest
, enc_rt
, enc_rs
);
14467 gen_logic(ctx
, OPC_XOR
, rt
, rt
, rs
);
14470 gen_logic(ctx
, OPC_OR
, rt
, rt
, rs
);
14474 int swm_converted
= 0x11 + extract32(ctx
->opcode
, 8, 2);
14475 int offset
= extract32(ctx
->opcode
, 4, 4);
14476 gen_ldst_multiple(ctx
, SWM32
, swm_converted
, 29, offset
<< 2);
14479 case JALRC16
: /* BREAK16, SDBBP16 */
14480 switch (ctx
->opcode
& 0x3f) {
14482 case JALRC16
+ 0x20:
14484 gen_compute_branch(ctx
, OPC_JALR
, 2, (ctx
->opcode
>> 5) & 0x1f,
14489 generate_exception(ctx
, EXCP_BREAK
);
14493 if (is_uhi(extract32(ctx
->opcode
, 6, 4))) {
14494 gen_helper_do_semihosting(cpu_env
);
14496 if (ctx
->hflags
& MIPS_HFLAG_SBRI
) {
14497 generate_exception(ctx
, EXCP_RI
);
14499 generate_exception(ctx
, EXCP_DBp
);
14506 generate_exception(ctx
, EXCP_RI
);
14511 static void gen_ldxs(DisasContext
*ctx
, int base
, int index
, int rd
)
14513 TCGv t0
= tcg_temp_new();
14514 TCGv t1
= tcg_temp_new();
14516 gen_load_gpr(t0
, base
);
14519 gen_load_gpr(t1
, index
);
14520 tcg_gen_shli_tl(t1
, t1
, 2);
14521 gen_op_addr_add(ctx
, t0
, t1
, t0
);
14524 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TESL
);
14525 gen_store_gpr(t1
, rd
);
14531 static void gen_ldst_pair(DisasContext
*ctx
, uint32_t opc
, int rd
,
14532 int base
, int16_t offset
)
14536 if (ctx
->hflags
& MIPS_HFLAG_BMASK
|| rd
== 31) {
14537 gen_reserved_instruction(ctx
);
14541 t0
= tcg_temp_new();
14542 t1
= tcg_temp_new();
14544 gen_base_offset_addr(ctx
, t0
, base
, offset
);
14549 gen_reserved_instruction(ctx
);
14552 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TESL
);
14553 gen_store_gpr(t1
, rd
);
14554 tcg_gen_movi_tl(t1
, 4);
14555 gen_op_addr_add(ctx
, t0
, t0
, t1
);
14556 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TESL
);
14557 gen_store_gpr(t1
, rd
+ 1);
14560 gen_load_gpr(t1
, rd
);
14561 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
14562 tcg_gen_movi_tl(t1
, 4);
14563 gen_op_addr_add(ctx
, t0
, t0
, t1
);
14564 gen_load_gpr(t1
, rd
+ 1);
14565 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
14567 #ifdef TARGET_MIPS64
14570 gen_reserved_instruction(ctx
);
14573 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
14574 gen_store_gpr(t1
, rd
);
14575 tcg_gen_movi_tl(t1
, 8);
14576 gen_op_addr_add(ctx
, t0
, t0
, t1
);
14577 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
14578 gen_store_gpr(t1
, rd
+ 1);
14581 gen_load_gpr(t1
, rd
);
14582 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
14583 tcg_gen_movi_tl(t1
, 8);
14584 gen_op_addr_add(ctx
, t0
, t0
, t1
);
14585 gen_load_gpr(t1
, rd
+ 1);
14586 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
14594 static void gen_sync(int stype
)
14596 TCGBar tcg_mo
= TCG_BAR_SC
;
14599 case 0x4: /* SYNC_WMB */
14600 tcg_mo
|= TCG_MO_ST_ST
;
14602 case 0x10: /* SYNC_MB */
14603 tcg_mo
|= TCG_MO_ALL
;
14605 case 0x11: /* SYNC_ACQUIRE */
14606 tcg_mo
|= TCG_MO_LD_LD
| TCG_MO_LD_ST
;
14608 case 0x12: /* SYNC_RELEASE */
14609 tcg_mo
|= TCG_MO_ST_ST
| TCG_MO_LD_ST
;
14611 case 0x13: /* SYNC_RMB */
14612 tcg_mo
|= TCG_MO_LD_LD
;
14615 tcg_mo
|= TCG_MO_ALL
;
14619 tcg_gen_mb(tcg_mo
);
14622 static void gen_pool32axf(CPUMIPSState
*env
, DisasContext
*ctx
, int rt
, int rs
)
14624 int extension
= (ctx
->opcode
>> 6) & 0x3f;
14625 int minor
= (ctx
->opcode
>> 12) & 0xf;
14626 uint32_t mips32_op
;
14628 switch (extension
) {
14630 mips32_op
= OPC_TEQ
;
14633 mips32_op
= OPC_TGE
;
14636 mips32_op
= OPC_TGEU
;
14639 mips32_op
= OPC_TLT
;
14642 mips32_op
= OPC_TLTU
;
14645 mips32_op
= OPC_TNE
;
14647 gen_trap(ctx
, mips32_op
, rs
, rt
, -1);
14649 #ifndef CONFIG_USER_ONLY
14652 check_cp0_enabled(ctx
);
14654 /* Treat as NOP. */
14657 gen_mfc0(ctx
, cpu_gpr
[rt
], rs
, (ctx
->opcode
>> 11) & 0x7);
14661 check_cp0_enabled(ctx
);
14663 TCGv t0
= tcg_temp_new();
14665 gen_load_gpr(t0
, rt
);
14666 gen_mtc0(ctx
, t0
, rs
, (ctx
->opcode
>> 11) & 0x7);
14672 switch (minor
& 3) {
14674 gen_muldiv(ctx
, OPC_MADD
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
14677 gen_muldiv(ctx
, OPC_MADDU
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
14680 gen_muldiv(ctx
, OPC_MSUB
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
14683 gen_muldiv(ctx
, OPC_MSUBU
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
14686 goto pool32axf_invalid
;
14690 switch (minor
& 3) {
14692 gen_muldiv(ctx
, OPC_MULT
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
14695 gen_muldiv(ctx
, OPC_MULTU
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
14698 goto pool32axf_invalid
;
14704 check_insn(ctx
, ISA_MIPS_R6
);
14705 gen_bitswap(ctx
, OPC_BITSWAP
, rs
, rt
);
14708 gen_bshfl(ctx
, OPC_SEB
, rs
, rt
);
14711 gen_bshfl(ctx
, OPC_SEH
, rs
, rt
);
14714 mips32_op
= OPC_CLO
;
14717 mips32_op
= OPC_CLZ
;
14719 check_insn(ctx
, ISA_MIPS_R1
);
14720 gen_cl(ctx
, mips32_op
, rt
, rs
);
14723 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
14724 gen_rdhwr(ctx
, rt
, rs
, 0);
14727 gen_bshfl(ctx
, OPC_WSBH
, rs
, rt
);
14730 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
14731 mips32_op
= OPC_MULT
;
14734 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
14735 mips32_op
= OPC_MULTU
;
14738 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
14739 mips32_op
= OPC_DIV
;
14742 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
14743 mips32_op
= OPC_DIVU
;
14746 check_insn(ctx
, ISA_MIPS_R1
);
14747 gen_muldiv(ctx
, mips32_op
, 0, rs
, rt
);
14750 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
14751 mips32_op
= OPC_MADD
;
14754 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
14755 mips32_op
= OPC_MADDU
;
14758 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
14759 mips32_op
= OPC_MSUB
;
14762 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
14763 mips32_op
= OPC_MSUBU
;
14765 check_insn(ctx
, ISA_MIPS_R1
);
14766 gen_muldiv(ctx
, mips32_op
, 0, rs
, rt
);
14769 goto pool32axf_invalid
;
14780 generate_exception_err(ctx
, EXCP_CpU
, 2);
14783 goto pool32axf_invalid
;
14788 case JALR
: /* JALRC */
14789 case JALR_HB
: /* JALRC_HB */
14790 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
14791 /* JALRC, JALRC_HB */
14792 gen_compute_branch(ctx
, OPC_JALR
, 4, rs
, rt
, 0, 0);
14794 /* JALR, JALR_HB */
14795 gen_compute_branch(ctx
, OPC_JALR
, 4, rs
, rt
, 0, 4);
14796 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
14801 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
14802 gen_compute_branch(ctx
, OPC_JALR
, 4, rs
, rt
, 0, 2);
14803 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
14806 goto pool32axf_invalid
;
14812 check_cp0_enabled(ctx
);
14813 check_insn(ctx
, ISA_MIPS_R2
);
14814 gen_load_srsgpr(rs
, rt
);
14817 check_cp0_enabled(ctx
);
14818 check_insn(ctx
, ISA_MIPS_R2
);
14819 gen_store_srsgpr(rs
, rt
);
14822 goto pool32axf_invalid
;
14825 #ifndef CONFIG_USER_ONLY
14829 mips32_op
= OPC_TLBP
;
14832 mips32_op
= OPC_TLBR
;
14835 mips32_op
= OPC_TLBWI
;
14838 mips32_op
= OPC_TLBWR
;
14841 mips32_op
= OPC_TLBINV
;
14844 mips32_op
= OPC_TLBINVF
;
14847 mips32_op
= OPC_WAIT
;
14850 mips32_op
= OPC_DERET
;
14853 mips32_op
= OPC_ERET
;
14855 gen_cp0(env
, ctx
, mips32_op
, rt
, rs
);
14858 goto pool32axf_invalid
;
14864 check_cp0_enabled(ctx
);
14866 TCGv t0
= tcg_temp_new();
14868 save_cpu_state(ctx
, 1);
14869 gen_helper_di(t0
, cpu_env
);
14870 gen_store_gpr(t0
, rs
);
14872 * Stop translation as we may have switched the execution
14875 ctx
->base
.is_jmp
= DISAS_STOP
;
14880 check_cp0_enabled(ctx
);
14882 TCGv t0
= tcg_temp_new();
14884 save_cpu_state(ctx
, 1);
14885 gen_helper_ei(t0
, cpu_env
);
14886 gen_store_gpr(t0
, rs
);
14888 * DISAS_STOP isn't sufficient, we need to ensure we break out
14889 * of translated code to check for pending interrupts.
14891 gen_save_pc(ctx
->base
.pc_next
+ 4);
14892 ctx
->base
.is_jmp
= DISAS_EXIT
;
14897 goto pool32axf_invalid
;
14904 gen_sync(extract32(ctx
->opcode
, 16, 5));
14907 generate_exception_end(ctx
, EXCP_SYSCALL
);
14910 if (is_uhi(extract32(ctx
->opcode
, 16, 10))) {
14911 gen_helper_do_semihosting(cpu_env
);
14913 check_insn(ctx
, ISA_MIPS_R1
);
14914 if (ctx
->hflags
& MIPS_HFLAG_SBRI
) {
14915 gen_reserved_instruction(ctx
);
14917 generate_exception_end(ctx
, EXCP_DBp
);
14922 goto pool32axf_invalid
;
14926 switch (minor
& 3) {
14928 gen_HILO(ctx
, OPC_MFHI
, minor
>> 2, rs
);
14931 gen_HILO(ctx
, OPC_MFLO
, minor
>> 2, rs
);
14934 gen_HILO(ctx
, OPC_MTHI
, minor
>> 2, rs
);
14937 gen_HILO(ctx
, OPC_MTLO
, minor
>> 2, rs
);
14940 goto pool32axf_invalid
;
14944 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
14947 gen_HILO(ctx
, OPC_MFHI
, 0, rs
);
14950 gen_HILO(ctx
, OPC_MFLO
, 0, rs
);
14953 gen_HILO(ctx
, OPC_MTHI
, 0, rs
);
14956 gen_HILO(ctx
, OPC_MTLO
, 0, rs
);
14959 goto pool32axf_invalid
;
14964 MIPS_INVAL("pool32axf");
14965 gen_reserved_instruction(ctx
);
14971 * Values for microMIPS fmt field. Variable-width, depending on which
14972 * formats the instruction supports.
14991 static void gen_pool32fxf(DisasContext
*ctx
, int rt
, int rs
)
14993 int extension
= (ctx
->opcode
>> 6) & 0x3ff;
14994 uint32_t mips32_op
;
14996 #define FLOAT_1BIT_FMT(opc, fmt) ((fmt << 8) | opc)
14997 #define FLOAT_2BIT_FMT(opc, fmt) ((fmt << 7) | opc)
14998 #define COND_FLOAT_MOV(opc, cond) ((cond << 7) | opc)
15000 switch (extension
) {
15001 case FLOAT_1BIT_FMT(CFC1
, 0):
15002 mips32_op
= OPC_CFC1
;
15004 case FLOAT_1BIT_FMT(CTC1
, 0):
15005 mips32_op
= OPC_CTC1
;
15007 case FLOAT_1BIT_FMT(MFC1
, 0):
15008 mips32_op
= OPC_MFC1
;
15010 case FLOAT_1BIT_FMT(MTC1
, 0):
15011 mips32_op
= OPC_MTC1
;
15013 case FLOAT_1BIT_FMT(MFHC1
, 0):
15014 mips32_op
= OPC_MFHC1
;
15016 case FLOAT_1BIT_FMT(MTHC1
, 0):
15017 mips32_op
= OPC_MTHC1
;
15019 gen_cp1(ctx
, mips32_op
, rt
, rs
);
15022 /* Reciprocal square root */
15023 case FLOAT_1BIT_FMT(RSQRT_FMT
, FMT_SD_S
):
15024 mips32_op
= OPC_RSQRT_S
;
15026 case FLOAT_1BIT_FMT(RSQRT_FMT
, FMT_SD_D
):
15027 mips32_op
= OPC_RSQRT_D
;
15031 case FLOAT_1BIT_FMT(SQRT_FMT
, FMT_SD_S
):
15032 mips32_op
= OPC_SQRT_S
;
15034 case FLOAT_1BIT_FMT(SQRT_FMT
, FMT_SD_D
):
15035 mips32_op
= OPC_SQRT_D
;
15039 case FLOAT_1BIT_FMT(RECIP_FMT
, FMT_SD_S
):
15040 mips32_op
= OPC_RECIP_S
;
15042 case FLOAT_1BIT_FMT(RECIP_FMT
, FMT_SD_D
):
15043 mips32_op
= OPC_RECIP_D
;
15047 case FLOAT_1BIT_FMT(FLOOR_L
, FMT_SD_S
):
15048 mips32_op
= OPC_FLOOR_L_S
;
15050 case FLOAT_1BIT_FMT(FLOOR_L
, FMT_SD_D
):
15051 mips32_op
= OPC_FLOOR_L_D
;
15053 case FLOAT_1BIT_FMT(FLOOR_W
, FMT_SD_S
):
15054 mips32_op
= OPC_FLOOR_W_S
;
15056 case FLOAT_1BIT_FMT(FLOOR_W
, FMT_SD_D
):
15057 mips32_op
= OPC_FLOOR_W_D
;
15061 case FLOAT_1BIT_FMT(CEIL_L
, FMT_SD_S
):
15062 mips32_op
= OPC_CEIL_L_S
;
15064 case FLOAT_1BIT_FMT(CEIL_L
, FMT_SD_D
):
15065 mips32_op
= OPC_CEIL_L_D
;
15067 case FLOAT_1BIT_FMT(CEIL_W
, FMT_SD_S
):
15068 mips32_op
= OPC_CEIL_W_S
;
15070 case FLOAT_1BIT_FMT(CEIL_W
, FMT_SD_D
):
15071 mips32_op
= OPC_CEIL_W_D
;
15075 case FLOAT_1BIT_FMT(TRUNC_L
, FMT_SD_S
):
15076 mips32_op
= OPC_TRUNC_L_S
;
15078 case FLOAT_1BIT_FMT(TRUNC_L
, FMT_SD_D
):
15079 mips32_op
= OPC_TRUNC_L_D
;
15081 case FLOAT_1BIT_FMT(TRUNC_W
, FMT_SD_S
):
15082 mips32_op
= OPC_TRUNC_W_S
;
15084 case FLOAT_1BIT_FMT(TRUNC_W
, FMT_SD_D
):
15085 mips32_op
= OPC_TRUNC_W_D
;
15089 case FLOAT_1BIT_FMT(ROUND_L
, FMT_SD_S
):
15090 mips32_op
= OPC_ROUND_L_S
;
15092 case FLOAT_1BIT_FMT(ROUND_L
, FMT_SD_D
):
15093 mips32_op
= OPC_ROUND_L_D
;
15095 case FLOAT_1BIT_FMT(ROUND_W
, FMT_SD_S
):
15096 mips32_op
= OPC_ROUND_W_S
;
15098 case FLOAT_1BIT_FMT(ROUND_W
, FMT_SD_D
):
15099 mips32_op
= OPC_ROUND_W_D
;
15102 /* Integer to floating-point conversion */
15103 case FLOAT_1BIT_FMT(CVT_L
, FMT_SD_S
):
15104 mips32_op
= OPC_CVT_L_S
;
15106 case FLOAT_1BIT_FMT(CVT_L
, FMT_SD_D
):
15107 mips32_op
= OPC_CVT_L_D
;
15109 case FLOAT_1BIT_FMT(CVT_W
, FMT_SD_S
):
15110 mips32_op
= OPC_CVT_W_S
;
15112 case FLOAT_1BIT_FMT(CVT_W
, FMT_SD_D
):
15113 mips32_op
= OPC_CVT_W_D
;
15116 /* Paired-foo conversions */
15117 case FLOAT_1BIT_FMT(CVT_S_PL
, 0):
15118 mips32_op
= OPC_CVT_S_PL
;
15120 case FLOAT_1BIT_FMT(CVT_S_PU
, 0):
15121 mips32_op
= OPC_CVT_S_PU
;
15123 case FLOAT_1BIT_FMT(CVT_PW_PS
, 0):
15124 mips32_op
= OPC_CVT_PW_PS
;
15126 case FLOAT_1BIT_FMT(CVT_PS_PW
, 0):
15127 mips32_op
= OPC_CVT_PS_PW
;
15130 /* Floating-point moves */
15131 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_S
):
15132 mips32_op
= OPC_MOV_S
;
15134 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_D
):
15135 mips32_op
= OPC_MOV_D
;
15137 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_PS
):
15138 mips32_op
= OPC_MOV_PS
;
15141 /* Absolute value */
15142 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_S
):
15143 mips32_op
= OPC_ABS_S
;
15145 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_D
):
15146 mips32_op
= OPC_ABS_D
;
15148 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_PS
):
15149 mips32_op
= OPC_ABS_PS
;
15153 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_S
):
15154 mips32_op
= OPC_NEG_S
;
15156 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_D
):
15157 mips32_op
= OPC_NEG_D
;
15159 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_PS
):
15160 mips32_op
= OPC_NEG_PS
;
15163 /* Reciprocal square root step */
15164 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_S
):
15165 mips32_op
= OPC_RSQRT1_S
;
15167 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_D
):
15168 mips32_op
= OPC_RSQRT1_D
;
15170 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_PS
):
15171 mips32_op
= OPC_RSQRT1_PS
;
15174 /* Reciprocal step */
15175 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_S
):
15176 mips32_op
= OPC_RECIP1_S
;
15178 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_D
):
15179 mips32_op
= OPC_RECIP1_S
;
15181 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_PS
):
15182 mips32_op
= OPC_RECIP1_PS
;
15185 /* Conversions from double */
15186 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_S
):
15187 mips32_op
= OPC_CVT_D_S
;
15189 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_W
):
15190 mips32_op
= OPC_CVT_D_W
;
15192 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_L
):
15193 mips32_op
= OPC_CVT_D_L
;
15196 /* Conversions from single */
15197 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_D
):
15198 mips32_op
= OPC_CVT_S_D
;
15200 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_W
):
15201 mips32_op
= OPC_CVT_S_W
;
15203 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_L
):
15204 mips32_op
= OPC_CVT_S_L
;
15206 gen_farith(ctx
, mips32_op
, -1, rs
, rt
, 0);
15209 /* Conditional moves on floating-point codes */
15210 case COND_FLOAT_MOV(MOVT
, 0):
15211 case COND_FLOAT_MOV(MOVT
, 1):
15212 case COND_FLOAT_MOV(MOVT
, 2):
15213 case COND_FLOAT_MOV(MOVT
, 3):
15214 case COND_FLOAT_MOV(MOVT
, 4):
15215 case COND_FLOAT_MOV(MOVT
, 5):
15216 case COND_FLOAT_MOV(MOVT
, 6):
15217 case COND_FLOAT_MOV(MOVT
, 7):
15218 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15219 gen_movci(ctx
, rt
, rs
, (ctx
->opcode
>> 13) & 0x7, 1);
15221 case COND_FLOAT_MOV(MOVF
, 0):
15222 case COND_FLOAT_MOV(MOVF
, 1):
15223 case COND_FLOAT_MOV(MOVF
, 2):
15224 case COND_FLOAT_MOV(MOVF
, 3):
15225 case COND_FLOAT_MOV(MOVF
, 4):
15226 case COND_FLOAT_MOV(MOVF
, 5):
15227 case COND_FLOAT_MOV(MOVF
, 6):
15228 case COND_FLOAT_MOV(MOVF
, 7):
15229 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15230 gen_movci(ctx
, rt
, rs
, (ctx
->opcode
>> 13) & 0x7, 0);
15233 MIPS_INVAL("pool32fxf");
15234 gen_reserved_instruction(ctx
);
15239 static void decode_micromips32_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
15243 int rt
, rs
, rd
, rr
;
15245 uint32_t op
, minor
, minor2
, mips32_op
;
15246 uint32_t cond
, fmt
, cc
;
15248 insn
= translator_lduw(env
, ctx
->base
.pc_next
+ 2);
15249 ctx
->opcode
= (ctx
->opcode
<< 16) | insn
;
15251 rt
= (ctx
->opcode
>> 21) & 0x1f;
15252 rs
= (ctx
->opcode
>> 16) & 0x1f;
15253 rd
= (ctx
->opcode
>> 11) & 0x1f;
15254 rr
= (ctx
->opcode
>> 6) & 0x1f;
15255 imm
= (int16_t) ctx
->opcode
;
15257 op
= (ctx
->opcode
>> 26) & 0x3f;
15260 minor
= ctx
->opcode
& 0x3f;
15263 minor
= (ctx
->opcode
>> 6) & 0xf;
15266 mips32_op
= OPC_SLL
;
15269 mips32_op
= OPC_SRA
;
15272 mips32_op
= OPC_SRL
;
15275 mips32_op
= OPC_ROTR
;
15277 gen_shift_imm(ctx
, mips32_op
, rt
, rs
, rd
);
15280 check_insn(ctx
, ISA_MIPS_R6
);
15281 gen_cond_move(ctx
, OPC_SELEQZ
, rd
, rs
, rt
);
15284 check_insn(ctx
, ISA_MIPS_R6
);
15285 gen_cond_move(ctx
, OPC_SELNEZ
, rd
, rs
, rt
);
15288 check_insn(ctx
, ISA_MIPS_R6
);
15289 gen_rdhwr(ctx
, rt
, rs
, extract32(ctx
->opcode
, 11, 3));
15292 goto pool32a_invalid
;
15296 minor
= (ctx
->opcode
>> 6) & 0xf;
15300 mips32_op
= OPC_ADD
;
15303 mips32_op
= OPC_ADDU
;
15306 mips32_op
= OPC_SUB
;
15309 mips32_op
= OPC_SUBU
;
15312 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15313 mips32_op
= OPC_MUL
;
15315 gen_arith(ctx
, mips32_op
, rd
, rs
, rt
);
15319 mips32_op
= OPC_SLLV
;
15322 mips32_op
= OPC_SRLV
;
15325 mips32_op
= OPC_SRAV
;
15328 mips32_op
= OPC_ROTRV
;
15330 gen_shift(ctx
, mips32_op
, rd
, rs
, rt
);
15332 /* Logical operations */
15334 mips32_op
= OPC_AND
;
15337 mips32_op
= OPC_OR
;
15340 mips32_op
= OPC_NOR
;
15343 mips32_op
= OPC_XOR
;
15345 gen_logic(ctx
, mips32_op
, rd
, rs
, rt
);
15347 /* Set less than */
15349 mips32_op
= OPC_SLT
;
15352 mips32_op
= OPC_SLTU
;
15354 gen_slt(ctx
, mips32_op
, rd
, rs
, rt
);
15357 goto pool32a_invalid
;
15361 minor
= (ctx
->opcode
>> 6) & 0xf;
15363 /* Conditional moves */
15364 case MOVN
: /* MUL */
15365 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
15367 gen_r6_muldiv(ctx
, R6_OPC_MUL
, rd
, rs
, rt
);
15370 gen_cond_move(ctx
, OPC_MOVN
, rd
, rs
, rt
);
15373 case MOVZ
: /* MUH */
15374 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
15376 gen_r6_muldiv(ctx
, R6_OPC_MUH
, rd
, rs
, rt
);
15379 gen_cond_move(ctx
, OPC_MOVZ
, rd
, rs
, rt
);
15383 check_insn(ctx
, ISA_MIPS_R6
);
15384 gen_r6_muldiv(ctx
, R6_OPC_MULU
, rd
, rs
, rt
);
15387 check_insn(ctx
, ISA_MIPS_R6
);
15388 gen_r6_muldiv(ctx
, R6_OPC_MUHU
, rd
, rs
, rt
);
15390 case LWXS
: /* DIV */
15391 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
15393 gen_r6_muldiv(ctx
, R6_OPC_DIV
, rd
, rs
, rt
);
15396 gen_ldxs(ctx
, rs
, rt
, rd
);
15400 check_insn(ctx
, ISA_MIPS_R6
);
15401 gen_r6_muldiv(ctx
, R6_OPC_MOD
, rd
, rs
, rt
);
15404 check_insn(ctx
, ISA_MIPS_R6
);
15405 gen_r6_muldiv(ctx
, R6_OPC_DIVU
, rd
, rs
, rt
);
15408 check_insn(ctx
, ISA_MIPS_R6
);
15409 gen_r6_muldiv(ctx
, R6_OPC_MODU
, rd
, rs
, rt
);
15412 goto pool32a_invalid
;
15416 gen_bitops(ctx
, OPC_INS
, rt
, rs
, rr
, rd
);
15419 check_insn(ctx
, ISA_MIPS_R6
);
15420 gen_lsa(ctx
, rd
, rt
, rs
, extract32(ctx
->opcode
, 9, 2));
15423 check_insn(ctx
, ISA_MIPS_R6
);
15424 gen_align(ctx
, 32, rd
, rs
, rt
, extract32(ctx
->opcode
, 9, 2));
15427 gen_bitops(ctx
, OPC_EXT
, rt
, rs
, rr
, rd
);
15430 gen_pool32axf(env
, ctx
, rt
, rs
);
15433 generate_exception_end(ctx
, EXCP_BREAK
);
15436 check_insn(ctx
, ISA_MIPS_R6
);
15437 gen_reserved_instruction(ctx
);
15441 MIPS_INVAL("pool32a");
15442 gen_reserved_instruction(ctx
);
15447 minor
= (ctx
->opcode
>> 12) & 0xf;
15450 check_cp0_enabled(ctx
);
15451 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
15452 gen_cache_operation(ctx
, rt
, rs
, imm
);
15457 /* COP2: Not implemented. */
15458 generate_exception_err(ctx
, EXCP_CpU
, 2);
15460 #ifdef TARGET_MIPS64
15463 check_insn(ctx
, ISA_MIPS3
);
15464 check_mips_64(ctx
);
15469 gen_ldst_pair(ctx
, minor
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
15471 #ifdef TARGET_MIPS64
15474 check_insn(ctx
, ISA_MIPS3
);
15475 check_mips_64(ctx
);
15480 gen_ldst_multiple(ctx
, minor
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
15483 MIPS_INVAL("pool32b");
15484 gen_reserved_instruction(ctx
);
15489 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
15490 minor
= ctx
->opcode
& 0x3f;
15491 check_cp1_enabled(ctx
);
15494 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15495 mips32_op
= OPC_ALNV_PS
;
15498 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15499 mips32_op
= OPC_MADD_S
;
15502 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15503 mips32_op
= OPC_MADD_D
;
15506 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15507 mips32_op
= OPC_MADD_PS
;
15510 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15511 mips32_op
= OPC_MSUB_S
;
15514 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15515 mips32_op
= OPC_MSUB_D
;
15518 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15519 mips32_op
= OPC_MSUB_PS
;
15522 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15523 mips32_op
= OPC_NMADD_S
;
15526 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15527 mips32_op
= OPC_NMADD_D
;
15530 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15531 mips32_op
= OPC_NMADD_PS
;
15534 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15535 mips32_op
= OPC_NMSUB_S
;
15538 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15539 mips32_op
= OPC_NMSUB_D
;
15542 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15543 mips32_op
= OPC_NMSUB_PS
;
15545 gen_flt3_arith(ctx
, mips32_op
, rd
, rr
, rs
, rt
);
15547 case CABS_COND_FMT
:
15548 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15549 cond
= (ctx
->opcode
>> 6) & 0xf;
15550 cc
= (ctx
->opcode
>> 13) & 0x7;
15551 fmt
= (ctx
->opcode
>> 10) & 0x3;
15554 gen_cmpabs_s(ctx
, cond
, rt
, rs
, cc
);
15557 gen_cmpabs_d(ctx
, cond
, rt
, rs
, cc
);
15560 gen_cmpabs_ps(ctx
, cond
, rt
, rs
, cc
);
15563 goto pool32f_invalid
;
15567 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15568 cond
= (ctx
->opcode
>> 6) & 0xf;
15569 cc
= (ctx
->opcode
>> 13) & 0x7;
15570 fmt
= (ctx
->opcode
>> 10) & 0x3;
15573 gen_cmp_s(ctx
, cond
, rt
, rs
, cc
);
15576 gen_cmp_d(ctx
, cond
, rt
, rs
, cc
);
15579 gen_cmp_ps(ctx
, cond
, rt
, rs
, cc
);
15582 goto pool32f_invalid
;
15586 check_insn(ctx
, ISA_MIPS_R6
);
15587 gen_r6_cmp_s(ctx
, (ctx
->opcode
>> 6) & 0x1f, rt
, rs
, rd
);
15590 check_insn(ctx
, ISA_MIPS_R6
);
15591 gen_r6_cmp_d(ctx
, (ctx
->opcode
>> 6) & 0x1f, rt
, rs
, rd
);
15594 gen_pool32fxf(ctx
, rt
, rs
);
15598 switch ((ctx
->opcode
>> 6) & 0x7) {
15600 mips32_op
= OPC_PLL_PS
;
15603 mips32_op
= OPC_PLU_PS
;
15606 mips32_op
= OPC_PUL_PS
;
15609 mips32_op
= OPC_PUU_PS
;
15612 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15613 mips32_op
= OPC_CVT_PS_S
;
15615 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
15618 goto pool32f_invalid
;
15622 check_insn(ctx
, ISA_MIPS_R6
);
15623 switch ((ctx
->opcode
>> 9) & 0x3) {
15625 gen_farith(ctx
, OPC_MIN_S
, rt
, rs
, rd
, 0);
15628 gen_farith(ctx
, OPC_MIN_D
, rt
, rs
, rd
, 0);
15631 goto pool32f_invalid
;
15636 switch ((ctx
->opcode
>> 6) & 0x7) {
15638 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15639 mips32_op
= OPC_LWXC1
;
15642 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15643 mips32_op
= OPC_SWXC1
;
15646 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15647 mips32_op
= OPC_LDXC1
;
15650 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15651 mips32_op
= OPC_SDXC1
;
15654 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15655 mips32_op
= OPC_LUXC1
;
15658 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15659 mips32_op
= OPC_SUXC1
;
15661 gen_flt3_ldst(ctx
, mips32_op
, rd
, rd
, rt
, rs
);
15664 goto pool32f_invalid
;
15668 check_insn(ctx
, ISA_MIPS_R6
);
15669 switch ((ctx
->opcode
>> 9) & 0x3) {
15671 gen_farith(ctx
, OPC_MAX_S
, rt
, rs
, rd
, 0);
15674 gen_farith(ctx
, OPC_MAX_D
, rt
, rs
, rd
, 0);
15677 goto pool32f_invalid
;
15682 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15683 fmt
= (ctx
->opcode
>> 9) & 0x3;
15684 switch ((ctx
->opcode
>> 6) & 0x7) {
15688 mips32_op
= OPC_RSQRT2_S
;
15691 mips32_op
= OPC_RSQRT2_D
;
15694 mips32_op
= OPC_RSQRT2_PS
;
15697 goto pool32f_invalid
;
15703 mips32_op
= OPC_RECIP2_S
;
15706 mips32_op
= OPC_RECIP2_D
;
15709 mips32_op
= OPC_RECIP2_PS
;
15712 goto pool32f_invalid
;
15716 mips32_op
= OPC_ADDR_PS
;
15719 mips32_op
= OPC_MULR_PS
;
15721 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
15724 goto pool32f_invalid
;
15728 /* MOV[FT].fmt, PREFX, RINT.fmt, CLASS.fmt*/
15729 cc
= (ctx
->opcode
>> 13) & 0x7;
15730 fmt
= (ctx
->opcode
>> 9) & 0x3;
15731 switch ((ctx
->opcode
>> 6) & 0x7) {
15732 case MOVF_FMT
: /* RINT_FMT */
15733 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
15737 gen_farith(ctx
, OPC_RINT_S
, 0, rt
, rs
, 0);
15740 gen_farith(ctx
, OPC_RINT_D
, 0, rt
, rs
, 0);
15743 goto pool32f_invalid
;
15749 gen_movcf_s(ctx
, rs
, rt
, cc
, 0);
15752 gen_movcf_d(ctx
, rs
, rt
, cc
, 0);
15756 gen_movcf_ps(ctx
, rs
, rt
, cc
, 0);
15759 goto pool32f_invalid
;
15763 case MOVT_FMT
: /* CLASS_FMT */
15764 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
15768 gen_farith(ctx
, OPC_CLASS_S
, 0, rt
, rs
, 0);
15771 gen_farith(ctx
, OPC_CLASS_D
, 0, rt
, rs
, 0);
15774 goto pool32f_invalid
;
15780 gen_movcf_s(ctx
, rs
, rt
, cc
, 1);
15783 gen_movcf_d(ctx
, rs
, rt
, cc
, 1);
15787 gen_movcf_ps(ctx
, rs
, rt
, cc
, 1);
15790 goto pool32f_invalid
;
15795 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15798 goto pool32f_invalid
;
15801 #define FINSN_3ARG_SDPS(prfx) \
15802 switch ((ctx->opcode >> 8) & 0x3) { \
15804 mips32_op = OPC_##prfx##_S; \
15807 mips32_op = OPC_##prfx##_D; \
15809 case FMT_SDPS_PS: \
15811 mips32_op = OPC_##prfx##_PS; \
15814 goto pool32f_invalid; \
15817 check_insn(ctx
, ISA_MIPS_R6
);
15818 switch ((ctx
->opcode
>> 9) & 0x3) {
15820 gen_farith(ctx
, OPC_MINA_S
, rt
, rs
, rd
, 0);
15823 gen_farith(ctx
, OPC_MINA_D
, rt
, rs
, rd
, 0);
15826 goto pool32f_invalid
;
15830 check_insn(ctx
, ISA_MIPS_R6
);
15831 switch ((ctx
->opcode
>> 9) & 0x3) {
15833 gen_farith(ctx
, OPC_MAXA_S
, rt
, rs
, rd
, 0);
15836 gen_farith(ctx
, OPC_MAXA_D
, rt
, rs
, rd
, 0);
15839 goto pool32f_invalid
;
15843 /* regular FP ops */
15844 switch ((ctx
->opcode
>> 6) & 0x3) {
15846 FINSN_3ARG_SDPS(ADD
);
15849 FINSN_3ARG_SDPS(SUB
);
15852 FINSN_3ARG_SDPS(MUL
);
15855 fmt
= (ctx
->opcode
>> 8) & 0x3;
15857 mips32_op
= OPC_DIV_D
;
15858 } else if (fmt
== 0) {
15859 mips32_op
= OPC_DIV_S
;
15861 goto pool32f_invalid
;
15865 goto pool32f_invalid
;
15870 switch ((ctx
->opcode
>> 6) & 0x7) {
15871 case MOVN_FMT
: /* SELEQZ_FMT */
15872 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
15874 switch ((ctx
->opcode
>> 9) & 0x3) {
15876 gen_sel_s(ctx
, OPC_SELEQZ_S
, rd
, rt
, rs
);
15879 gen_sel_d(ctx
, OPC_SELEQZ_D
, rd
, rt
, rs
);
15882 goto pool32f_invalid
;
15886 FINSN_3ARG_SDPS(MOVN
);
15890 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15891 FINSN_3ARG_SDPS(MOVN
);
15893 case MOVZ_FMT
: /* SELNEZ_FMT */
15894 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
15896 switch ((ctx
->opcode
>> 9) & 0x3) {
15898 gen_sel_s(ctx
, OPC_SELNEZ_S
, rd
, rt
, rs
);
15901 gen_sel_d(ctx
, OPC_SELNEZ_D
, rd
, rt
, rs
);
15904 goto pool32f_invalid
;
15908 FINSN_3ARG_SDPS(MOVZ
);
15912 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15913 FINSN_3ARG_SDPS(MOVZ
);
15916 check_insn(ctx
, ISA_MIPS_R6
);
15917 switch ((ctx
->opcode
>> 9) & 0x3) {
15919 gen_sel_s(ctx
, OPC_SEL_S
, rd
, rt
, rs
);
15922 gen_sel_d(ctx
, OPC_SEL_D
, rd
, rt
, rs
);
15925 goto pool32f_invalid
;
15929 check_insn(ctx
, ISA_MIPS_R6
);
15930 switch ((ctx
->opcode
>> 9) & 0x3) {
15932 mips32_op
= OPC_MADDF_S
;
15935 mips32_op
= OPC_MADDF_D
;
15938 goto pool32f_invalid
;
15942 check_insn(ctx
, ISA_MIPS_R6
);
15943 switch ((ctx
->opcode
>> 9) & 0x3) {
15945 mips32_op
= OPC_MSUBF_S
;
15948 mips32_op
= OPC_MSUBF_D
;
15951 goto pool32f_invalid
;
15955 goto pool32f_invalid
;
15959 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
15963 MIPS_INVAL("pool32f");
15964 gen_reserved_instruction(ctx
);
15968 generate_exception_err(ctx
, EXCP_CpU
, 1);
15972 minor
= (ctx
->opcode
>> 21) & 0x1f;
15975 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15976 gen_compute_branch(ctx
, OPC_BLTZ
, 4, rs
, -1, imm
<< 1, 4);
15979 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15980 gen_compute_branch(ctx
, OPC_BLTZAL
, 4, rs
, -1, imm
<< 1, 4);
15981 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
15984 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15985 gen_compute_branch(ctx
, OPC_BLTZAL
, 4, rs
, -1, imm
<< 1, 2);
15986 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
15989 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15990 gen_compute_branch(ctx
, OPC_BGEZ
, 4, rs
, -1, imm
<< 1, 4);
15993 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15994 gen_compute_branch(ctx
, OPC_BGEZAL
, 4, rs
, -1, imm
<< 1, 4);
15995 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
15998 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15999 gen_compute_branch(ctx
, OPC_BGEZAL
, 4, rs
, -1, imm
<< 1, 2);
16000 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
16003 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16004 gen_compute_branch(ctx
, OPC_BLEZ
, 4, rs
, -1, imm
<< 1, 4);
16007 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16008 gen_compute_branch(ctx
, OPC_BGTZ
, 4, rs
, -1, imm
<< 1, 4);
16012 case TLTI
: /* BC1EQZC */
16013 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16015 check_cp1_enabled(ctx
);
16016 gen_compute_branch1_r6(ctx
, OPC_BC1EQZ
, rs
, imm
<< 1, 0);
16019 mips32_op
= OPC_TLTI
;
16023 case TGEI
: /* BC1NEZC */
16024 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16026 check_cp1_enabled(ctx
);
16027 gen_compute_branch1_r6(ctx
, OPC_BC1NEZ
, rs
, imm
<< 1, 0);
16030 mips32_op
= OPC_TGEI
;
16035 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16036 mips32_op
= OPC_TLTIU
;
16039 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16040 mips32_op
= OPC_TGEIU
;
16042 case TNEI
: /* SYNCI */
16043 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16046 * Break the TB to be able to sync copied instructions
16049 ctx
->base
.is_jmp
= DISAS_STOP
;
16052 mips32_op
= OPC_TNEI
;
16057 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16058 mips32_op
= OPC_TEQI
;
16060 gen_trap(ctx
, mips32_op
, rs
, -1, imm
);
16065 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16066 gen_compute_branch(ctx
, minor
== BNEZC
? OPC_BNE
: OPC_BEQ
,
16067 4, rs
, 0, imm
<< 1, 0);
16069 * Compact branches don't have a delay slot, so just let
16070 * the normal delay slot handling take us to the branch
16075 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16076 gen_logic_imm(ctx
, OPC_LUI
, rs
, 0, imm
);
16079 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16081 * Break the TB to be able to sync copied instructions
16084 ctx
->base
.is_jmp
= DISAS_STOP
;
16088 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16089 /* COP2: Not implemented. */
16090 generate_exception_err(ctx
, EXCP_CpU
, 2);
16093 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16094 mips32_op
= (ctx
->opcode
& (1 << 16)) ? OPC_BC1FANY2
: OPC_BC1F
;
16097 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16098 mips32_op
= (ctx
->opcode
& (1 << 16)) ? OPC_BC1TANY2
: OPC_BC1T
;
16101 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16102 mips32_op
= OPC_BC1FANY4
;
16105 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16106 mips32_op
= OPC_BC1TANY4
;
16109 check_insn(ctx
, ASE_MIPS3D
);
16112 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
16113 check_cp1_enabled(ctx
);
16114 gen_compute_branch1(ctx
, mips32_op
,
16115 (ctx
->opcode
>> 18) & 0x7, imm
<< 1);
16117 generate_exception_err(ctx
, EXCP_CpU
, 1);
16122 /* MIPS DSP: not implemented */
16125 MIPS_INVAL("pool32i");
16126 gen_reserved_instruction(ctx
);
16131 minor
= (ctx
->opcode
>> 12) & 0xf;
16132 offset
= sextract32(ctx
->opcode
, 0,
16133 (ctx
->insn_flags
& ISA_MIPS_R6
) ? 9 : 12);
16136 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16137 mips32_op
= OPC_LWL
;
16140 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16141 mips32_op
= OPC_SWL
;
16144 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16145 mips32_op
= OPC_LWR
;
16148 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16149 mips32_op
= OPC_SWR
;
16151 #if defined(TARGET_MIPS64)
16153 check_insn(ctx
, ISA_MIPS3
);
16154 check_mips_64(ctx
);
16155 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16156 mips32_op
= OPC_LDL
;
16159 check_insn(ctx
, ISA_MIPS3
);
16160 check_mips_64(ctx
);
16161 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16162 mips32_op
= OPC_SDL
;
16165 check_insn(ctx
, ISA_MIPS3
);
16166 check_mips_64(ctx
);
16167 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16168 mips32_op
= OPC_LDR
;
16171 check_insn(ctx
, ISA_MIPS3
);
16172 check_mips_64(ctx
);
16173 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16174 mips32_op
= OPC_SDR
;
16177 check_insn(ctx
, ISA_MIPS3
);
16178 check_mips_64(ctx
);
16179 mips32_op
= OPC_LWU
;
16182 check_insn(ctx
, ISA_MIPS3
);
16183 check_mips_64(ctx
);
16184 mips32_op
= OPC_LLD
;
16188 mips32_op
= OPC_LL
;
16191 gen_ld(ctx
, mips32_op
, rt
, rs
, offset
);
16194 gen_st(ctx
, mips32_op
, rt
, rs
, offset
);
16197 gen_st_cond(ctx
, rt
, rs
, offset
, MO_TESL
, false);
16199 #if defined(TARGET_MIPS64)
16201 check_insn(ctx
, ISA_MIPS3
);
16202 check_mips_64(ctx
);
16203 gen_st_cond(ctx
, rt
, rs
, offset
, MO_TEQ
, false);
16208 MIPS_INVAL("pool32c ld-eva");
16209 gen_reserved_instruction(ctx
);
16212 check_cp0_enabled(ctx
);
16214 minor2
= (ctx
->opcode
>> 9) & 0x7;
16215 offset
= sextract32(ctx
->opcode
, 0, 9);
16218 mips32_op
= OPC_LBUE
;
16221 mips32_op
= OPC_LHUE
;
16224 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16225 mips32_op
= OPC_LWLE
;
16228 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16229 mips32_op
= OPC_LWRE
;
16232 mips32_op
= OPC_LBE
;
16235 mips32_op
= OPC_LHE
;
16238 mips32_op
= OPC_LLE
;
16241 mips32_op
= OPC_LWE
;
16247 MIPS_INVAL("pool32c st-eva");
16248 gen_reserved_instruction(ctx
);
16251 check_cp0_enabled(ctx
);
16253 minor2
= (ctx
->opcode
>> 9) & 0x7;
16254 offset
= sextract32(ctx
->opcode
, 0, 9);
16257 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16258 mips32_op
= OPC_SWLE
;
16261 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16262 mips32_op
= OPC_SWRE
;
16265 /* Treat as no-op */
16266 if ((ctx
->insn_flags
& ISA_MIPS_R6
) && (rt
>= 24)) {
16267 /* hint codes 24-31 are reserved and signal RI */
16268 generate_exception(ctx
, EXCP_RI
);
16272 /* Treat as no-op */
16273 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
16274 gen_cache_operation(ctx
, rt
, rs
, offset
);
16278 mips32_op
= OPC_SBE
;
16281 mips32_op
= OPC_SHE
;
16284 gen_st_cond(ctx
, rt
, rs
, offset
, MO_TESL
, true);
16287 mips32_op
= OPC_SWE
;
16292 /* Treat as no-op */
16293 if ((ctx
->insn_flags
& ISA_MIPS_R6
) && (rt
>= 24)) {
16294 /* hint codes 24-31 are reserved and signal RI */
16295 generate_exception(ctx
, EXCP_RI
);
16299 MIPS_INVAL("pool32c");
16300 gen_reserved_instruction(ctx
);
16304 case ADDI32
: /* AUI, LUI */
16305 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16307 gen_logic_imm(ctx
, OPC_LUI
, rt
, rs
, imm
);
16310 mips32_op
= OPC_ADDI
;
16315 mips32_op
= OPC_ADDIU
;
16317 gen_arith_imm(ctx
, mips32_op
, rt
, rs
, imm
);
16320 /* Logical operations */
16322 mips32_op
= OPC_ORI
;
16325 mips32_op
= OPC_XORI
;
16328 mips32_op
= OPC_ANDI
;
16330 gen_logic_imm(ctx
, mips32_op
, rt
, rs
, imm
);
16333 /* Set less than immediate */
16335 mips32_op
= OPC_SLTI
;
16338 mips32_op
= OPC_SLTIU
;
16340 gen_slt_imm(ctx
, mips32_op
, rt
, rs
, imm
);
16343 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16344 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
16345 gen_compute_branch(ctx
, OPC_JALX
, 4, rt
, rs
, offset
, 4);
16346 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
16348 case JALS32
: /* BOVC, BEQC, BEQZALC */
16349 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16352 mips32_op
= OPC_BOVC
;
16353 } else if (rs
< rt
&& rs
== 0) {
16355 mips32_op
= OPC_BEQZALC
;
16358 mips32_op
= OPC_BEQC
;
16360 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
16363 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1;
16364 gen_compute_branch(ctx
, OPC_JAL
, 4, rt
, rs
, offset
, 2);
16365 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
16368 case BEQ32
: /* BC */
16369 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16371 gen_compute_compact_branch(ctx
, OPC_BC
, 0, 0,
16372 sextract32(ctx
->opcode
<< 1, 0, 27));
16375 gen_compute_branch(ctx
, OPC_BEQ
, 4, rt
, rs
, imm
<< 1, 4);
16378 case BNE32
: /* BALC */
16379 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16381 gen_compute_compact_branch(ctx
, OPC_BALC
, 0, 0,
16382 sextract32(ctx
->opcode
<< 1, 0, 27));
16385 gen_compute_branch(ctx
, OPC_BNE
, 4, rt
, rs
, imm
<< 1, 4);
16388 case J32
: /* BGTZC, BLTZC, BLTC */
16389 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16390 if (rs
== 0 && rt
!= 0) {
16392 mips32_op
= OPC_BGTZC
;
16393 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
16395 mips32_op
= OPC_BLTZC
;
16398 mips32_op
= OPC_BLTC
;
16400 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
16403 gen_compute_branch(ctx
, OPC_J
, 4, rt
, rs
,
16404 (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1, 4);
16407 case JAL32
: /* BLEZC, BGEZC, BGEC */
16408 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16409 if (rs
== 0 && rt
!= 0) {
16411 mips32_op
= OPC_BLEZC
;
16412 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
16414 mips32_op
= OPC_BGEZC
;
16417 mips32_op
= OPC_BGEC
;
16419 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
16422 gen_compute_branch(ctx
, OPC_JAL
, 4, rt
, rs
,
16423 (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1, 4);
16424 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
16427 /* Floating point (COP1) */
16429 mips32_op
= OPC_LWC1
;
16432 mips32_op
= OPC_LDC1
;
16435 mips32_op
= OPC_SWC1
;
16438 mips32_op
= OPC_SDC1
;
16440 gen_cop1_ldst(ctx
, mips32_op
, rt
, rs
, imm
);
16442 case ADDIUPC
: /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
16443 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16444 /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
16445 switch ((ctx
->opcode
>> 16) & 0x1f) {
16454 gen_pcrel(ctx
, OPC_ADDIUPC
, ctx
->base
.pc_next
& ~0x3, rt
);
16457 gen_pcrel(ctx
, OPC_AUIPC
, ctx
->base
.pc_next
, rt
);
16460 gen_pcrel(ctx
, OPC_ALUIPC
, ctx
->base
.pc_next
, rt
);
16470 gen_pcrel(ctx
, R6_OPC_LWPC
, ctx
->base
.pc_next
& ~0x3, rt
);
16473 generate_exception(ctx
, EXCP_RI
);
16478 int reg
= mmreg(ZIMM(ctx
->opcode
, 23, 3));
16479 offset
= SIMM(ctx
->opcode
, 0, 23) << 2;
16481 gen_addiupc(ctx
, reg
, offset
, 0, 0);
16484 case BNVC
: /* BNEC, BNEZALC */
16485 check_insn(ctx
, ISA_MIPS_R6
);
16488 mips32_op
= OPC_BNVC
;
16489 } else if (rs
< rt
&& rs
== 0) {
16491 mips32_op
= OPC_BNEZALC
;
16494 mips32_op
= OPC_BNEC
;
16496 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
16498 case R6_BNEZC
: /* JIALC */
16499 check_insn(ctx
, ISA_MIPS_R6
);
16502 gen_compute_compact_branch(ctx
, OPC_BNEZC
, rt
, 0,
16503 sextract32(ctx
->opcode
<< 1, 0, 22));
16506 gen_compute_compact_branch(ctx
, OPC_JIALC
, 0, rs
, imm
);
16509 case R6_BEQZC
: /* JIC */
16510 check_insn(ctx
, ISA_MIPS_R6
);
16513 gen_compute_compact_branch(ctx
, OPC_BEQZC
, rt
, 0,
16514 sextract32(ctx
->opcode
<< 1, 0, 22));
16517 gen_compute_compact_branch(ctx
, OPC_JIC
, 0, rs
, imm
);
16520 case BLEZALC
: /* BGEZALC, BGEUC */
16521 check_insn(ctx
, ISA_MIPS_R6
);
16522 if (rs
== 0 && rt
!= 0) {
16524 mips32_op
= OPC_BLEZALC
;
16525 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
16527 mips32_op
= OPC_BGEZALC
;
16530 mips32_op
= OPC_BGEUC
;
16532 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
16534 case BGTZALC
: /* BLTZALC, BLTUC */
16535 check_insn(ctx
, ISA_MIPS_R6
);
16536 if (rs
== 0 && rt
!= 0) {
16538 mips32_op
= OPC_BGTZALC
;
16539 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
16541 mips32_op
= OPC_BLTZALC
;
16544 mips32_op
= OPC_BLTUC
;
16546 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
16548 /* Loads and stores */
16550 mips32_op
= OPC_LB
;
16553 mips32_op
= OPC_LBU
;
16556 mips32_op
= OPC_LH
;
16559 mips32_op
= OPC_LHU
;
16562 mips32_op
= OPC_LW
;
16564 #ifdef TARGET_MIPS64
16566 check_insn(ctx
, ISA_MIPS3
);
16567 check_mips_64(ctx
);
16568 mips32_op
= OPC_LD
;
16571 check_insn(ctx
, ISA_MIPS3
);
16572 check_mips_64(ctx
);
16573 mips32_op
= OPC_SD
;
16577 mips32_op
= OPC_SB
;
16580 mips32_op
= OPC_SH
;
16583 mips32_op
= OPC_SW
;
16586 gen_ld(ctx
, mips32_op
, rt
, rs
, imm
);
16589 gen_st(ctx
, mips32_op
, rt
, rs
, imm
);
16592 gen_reserved_instruction(ctx
);
16597 static int decode_micromips_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
16601 /* make sure instructions are on a halfword boundary */
16602 if (ctx
->base
.pc_next
& 0x1) {
16603 env
->CP0_BadVAddr
= ctx
->base
.pc_next
;
16604 generate_exception_end(ctx
, EXCP_AdEL
);
16608 op
= (ctx
->opcode
>> 10) & 0x3f;
16609 /* Enforce properly-sized instructions in a delay slot */
16610 if (ctx
->hflags
& MIPS_HFLAG_BDS_STRICT
) {
16611 switch (op
& 0x7) { /* MSB-3..MSB-5 */
16613 /* POOL32A, POOL32B, POOL32I, POOL32C */
16615 /* ADDI32, ADDIU32, ORI32, XORI32, SLTI32, SLTIU32, ANDI32, JALX32 */
16617 /* LBU32, LHU32, POOL32F, JALS32, BEQ32, BNE32, J32, JAL32 */
16619 /* SB32, SH32, ADDIUPC, SWC132, SDC132, SW32 */
16621 /* LB32, LH32, LWC132, LDC132, LW32 */
16622 if (ctx
->hflags
& MIPS_HFLAG_BDS16
) {
16623 gen_reserved_instruction(ctx
);
16628 /* POOL16A, POOL16B, POOL16C, LWGP16, POOL16F */
16630 /* LBU16, LHU16, LWSP16, LW16, SB16, SH16, SWSP16, SW16 */
16632 /* MOVE16, ANDI16, POOL16D, POOL16E, BEQZ16, BNEZ16, B16, LI16 */
16633 if (ctx
->hflags
& MIPS_HFLAG_BDS32
) {
16634 gen_reserved_instruction(ctx
);
16644 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
16645 int rs1
= mmreg(uMIPS_RS1(ctx
->opcode
));
16646 int rs2
= mmreg(uMIPS_RS2(ctx
->opcode
));
16649 switch (ctx
->opcode
& 0x1) {
16657 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16659 * In the Release 6, the register number location in
16660 * the instruction encoding has changed.
16662 gen_arith(ctx
, opc
, rs1
, rd
, rs2
);
16664 gen_arith(ctx
, opc
, rd
, rs1
, rs2
);
16670 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
16671 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
16672 int amount
= (ctx
->opcode
>> 1) & 0x7;
16674 amount
= amount
== 0 ? 8 : amount
;
16676 switch (ctx
->opcode
& 0x1) {
16685 gen_shift_imm(ctx
, opc
, rd
, rs
, amount
);
16689 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16690 gen_pool16c_r6_insn(ctx
);
16692 gen_pool16c_insn(ctx
);
16697 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
16698 int rb
= 28; /* GP */
16699 int16_t offset
= SIMM(ctx
->opcode
, 0, 7) << 2;
16701 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
16705 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16706 if (ctx
->opcode
& 1) {
16707 gen_reserved_instruction(ctx
);
16710 int enc_dest
= uMIPS_RD(ctx
->opcode
);
16711 int enc_rt
= uMIPS_RS2(ctx
->opcode
);
16712 int enc_rs
= uMIPS_RS1(ctx
->opcode
);
16713 gen_movep(ctx
, enc_dest
, enc_rt
, enc_rs
);
16718 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
16719 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
16720 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4);
16721 offset
= (offset
== 0xf ? -1 : offset
);
16723 gen_ld(ctx
, OPC_LBU
, rd
, rb
, offset
);
16728 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
16729 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
16730 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 1;
16732 gen_ld(ctx
, OPC_LHU
, rd
, rb
, offset
);
16737 int rd
= (ctx
->opcode
>> 5) & 0x1f;
16738 int rb
= 29; /* SP */
16739 int16_t offset
= ZIMM(ctx
->opcode
, 0, 5) << 2;
16741 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
16746 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
16747 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
16748 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 2;
16750 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
16755 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
16756 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
16757 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4);
16759 gen_st(ctx
, OPC_SB
, rd
, rb
, offset
);
16764 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
16765 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
16766 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 1;
16768 gen_st(ctx
, OPC_SH
, rd
, rb
, offset
);
16773 int rd
= (ctx
->opcode
>> 5) & 0x1f;
16774 int rb
= 29; /* SP */
16775 int16_t offset
= ZIMM(ctx
->opcode
, 0, 5) << 2;
16777 gen_st(ctx
, OPC_SW
, rd
, rb
, offset
);
16782 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
16783 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
16784 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 2;
16786 gen_st(ctx
, OPC_SW
, rd
, rb
, offset
);
16791 int rd
= uMIPS_RD5(ctx
->opcode
);
16792 int rs
= uMIPS_RS5(ctx
->opcode
);
16794 gen_arith(ctx
, OPC_ADDU
, rd
, rs
, 0);
16801 switch (ctx
->opcode
& 0x1) {
16811 switch (ctx
->opcode
& 0x1) {
16816 gen_addiur1sp(ctx
);
16820 case B16
: /* BC16 */
16821 gen_compute_branch(ctx
, OPC_BEQ
, 2, 0, 0,
16822 sextract32(ctx
->opcode
, 0, 10) << 1,
16823 (ctx
->insn_flags
& ISA_MIPS_R6
) ? 0 : 4);
16825 case BNEZ16
: /* BNEZC16 */
16826 case BEQZ16
: /* BEQZC16 */
16827 gen_compute_branch(ctx
, op
== BNEZ16
? OPC_BNE
: OPC_BEQ
, 2,
16828 mmreg(uMIPS_RD(ctx
->opcode
)),
16829 0, sextract32(ctx
->opcode
, 0, 7) << 1,
16830 (ctx
->insn_flags
& ISA_MIPS_R6
) ? 0 : 4);
16835 int reg
= mmreg(uMIPS_RD(ctx
->opcode
));
16836 int imm
= ZIMM(ctx
->opcode
, 0, 7);
16838 imm
= (imm
== 0x7f ? -1 : imm
);
16839 tcg_gen_movi_tl(cpu_gpr
[reg
], imm
);
16845 gen_reserved_instruction(ctx
);
16848 decode_micromips32_opc(env
, ctx
);
16861 /* MAJOR, P16, and P32 pools opcodes */
16865 NM_MOVE_BALC
= 0x02,
16873 NM_P16_SHIFT
= 0x0c,
16891 NM_P_LS_U12
= 0x21,
16901 NM_P16_ADDU
= 0x2c,
16915 NM_MOVEPREV
= 0x3f,
16918 /* POOL32A instruction pool */
16920 NM_POOL32A0
= 0x00,
16921 NM_SPECIAL2
= 0x01,
16924 NM_POOL32A5
= 0x05,
16925 NM_POOL32A7
= 0x07,
16928 /* P.GP.W instruction pool */
16930 NM_ADDIUGP_W
= 0x00,
16935 /* P48I instruction pool */
16939 NM_ADDIUGP48
= 0x02,
16940 NM_ADDIUPC48
= 0x03,
16945 /* P.U12 instruction pool */
16954 NM_ADDIUNEG
= 0x08,
16961 /* POOL32F instruction pool */
16963 NM_POOL32F_0
= 0x00,
16964 NM_POOL32F_3
= 0x03,
16965 NM_POOL32F_5
= 0x05,
16968 /* POOL32S instruction pool */
16970 NM_POOL32S_0
= 0x00,
16971 NM_POOL32S_4
= 0x04,
16974 /* P.LUI instruction pool */
16980 /* P.GP.BH instruction pool */
16985 NM_ADDIUGP_B
= 0x03,
16988 NM_P_GP_CP1
= 0x06,
16991 /* P.LS.U12 instruction pool */
16996 NM_P_PREFU12
= 0x03,
17009 /* P.LS.S9 instruction pool */
17015 NM_P_LS_UAWM
= 0x05,
17018 /* P.BAL instruction pool */
17024 /* P.J instruction pool */
17027 NM_JALRC_HB
= 0x01,
17028 NM_P_BALRSC
= 0x08,
17031 /* P.BR1 instruction pool */
17039 /* P.BR2 instruction pool */
17046 /* P.BRI instruction pool */
17058 /* P16.SHIFT instruction pool */
17064 /* POOL16C instruction pool */
17066 NM_POOL16C_0
= 0x00,
17070 /* P16.A1 instruction pool */
17072 NM_ADDIUR1SP
= 0x01,
17075 /* P16.A2 instruction pool */
17078 NM_P_ADDIURS5
= 0x01,
17081 /* P16.ADDU instruction pool */
17087 /* P16.SR instruction pool */
17090 NM_RESTORE_JRC16
= 0x01,
17093 /* P16.4X4 instruction pool */
17099 /* P16.LB instruction pool */
17106 /* P16.LH instruction pool */
17113 /* P.RI instruction pool */
17116 NM_P_SYSCALL
= 0x01,
17121 /* POOL32A0 instruction pool */
17156 NM_D_E_MT_VPE
= 0x56,
17164 /* CRC32 instruction pool */
17174 /* POOL32A5 instruction pool */
17176 NM_CMP_EQ_PH
= 0x00,
17177 NM_CMP_LT_PH
= 0x08,
17178 NM_CMP_LE_PH
= 0x10,
17179 NM_CMPGU_EQ_QB
= 0x18,
17180 NM_CMPGU_LT_QB
= 0x20,
17181 NM_CMPGU_LE_QB
= 0x28,
17182 NM_CMPGDU_EQ_QB
= 0x30,
17183 NM_CMPGDU_LT_QB
= 0x38,
17184 NM_CMPGDU_LE_QB
= 0x40,
17185 NM_CMPU_EQ_QB
= 0x48,
17186 NM_CMPU_LT_QB
= 0x50,
17187 NM_CMPU_LE_QB
= 0x58,
17188 NM_ADDQ_S_W
= 0x60,
17189 NM_SUBQ_S_W
= 0x68,
17193 NM_ADDQ_S_PH
= 0x01,
17194 NM_ADDQH_R_PH
= 0x09,
17195 NM_ADDQH_R_W
= 0x11,
17196 NM_ADDU_S_QB
= 0x19,
17197 NM_ADDU_S_PH
= 0x21,
17198 NM_ADDUH_R_QB
= 0x29,
17199 NM_SHRAV_R_PH
= 0x31,
17200 NM_SHRAV_R_QB
= 0x39,
17201 NM_SUBQ_S_PH
= 0x41,
17202 NM_SUBQH_R_PH
= 0x49,
17203 NM_SUBQH_R_W
= 0x51,
17204 NM_SUBU_S_QB
= 0x59,
17205 NM_SUBU_S_PH
= 0x61,
17206 NM_SUBUH_R_QB
= 0x69,
17207 NM_SHLLV_S_PH
= 0x71,
17208 NM_PRECR_SRA_R_PH_W
= 0x79,
17210 NM_MULEU_S_PH_QBL
= 0x12,
17211 NM_MULEU_S_PH_QBR
= 0x1a,
17212 NM_MULQ_RS_PH
= 0x22,
17213 NM_MULQ_S_PH
= 0x2a,
17214 NM_MULQ_RS_W
= 0x32,
17215 NM_MULQ_S_W
= 0x3a,
17218 NM_SHRAV_R_W
= 0x5a,
17219 NM_SHRLV_PH
= 0x62,
17220 NM_SHRLV_QB
= 0x6a,
17221 NM_SHLLV_QB
= 0x72,
17222 NM_SHLLV_S_W
= 0x7a,
17226 NM_MULEQ_S_W_PHL
= 0x04,
17227 NM_MULEQ_S_W_PHR
= 0x0c,
17229 NM_MUL_S_PH
= 0x05,
17230 NM_PRECR_QB_PH
= 0x0d,
17231 NM_PRECRQ_QB_PH
= 0x15,
17232 NM_PRECRQ_PH_W
= 0x1d,
17233 NM_PRECRQ_RS_PH_W
= 0x25,
17234 NM_PRECRQU_S_QB_PH
= 0x2d,
17235 NM_PACKRL_PH
= 0x35,
17239 NM_SHRA_R_W
= 0x5e,
17240 NM_SHRA_R_PH
= 0x66,
17241 NM_SHLL_S_PH
= 0x76,
17242 NM_SHLL_S_W
= 0x7e,
17247 /* POOL32A7 instruction pool */
17252 NM_POOL32AXF
= 0x07,
17255 /* P.SR instruction pool */
17261 /* P.SHIFT instruction pool */
17269 /* P.ROTX instruction pool */
17274 /* P.INS instruction pool */
17279 /* P.EXT instruction pool */
17284 /* POOL32F_0 (fmt) instruction pool */
17289 NM_SELEQZ_S
= 0x07,
17290 NM_SELEQZ_D
= 0x47,
17294 NM_SELNEZ_S
= 0x0f,
17295 NM_SELNEZ_D
= 0x4f,
17310 /* POOL32F_3 instruction pool */
17314 NM_MINA_FMT
= 0x04,
17315 NM_MAXA_FMT
= 0x05,
17316 NM_POOL32FXF
= 0x07,
17319 /* POOL32F_5 instruction pool */
17321 NM_CMP_CONDN_S
= 0x00,
17322 NM_CMP_CONDN_D
= 0x02,
17325 /* P.GP.LH instruction pool */
17331 /* P.GP.SH instruction pool */
17336 /* P.GP.CP1 instruction pool */
17344 /* P.LS.S0 instruction pool */
17361 NM_P_PREFS9
= 0x03,
17367 /* P.LS.S1 instruction pool */
17369 NM_ASET_ACLR
= 0x02,
17377 /* P.LS.E0 instruction pool */
17393 /* P.PREFE instruction pool */
17399 /* P.LLE instruction pool */
17405 /* P.SCE instruction pool */
17411 /* P.LS.WM instruction pool */
17417 /* P.LS.UAWM instruction pool */
17423 /* P.BR3A instruction pool */
17429 NM_BPOSGE32C
= 0x04,
17432 /* P16.RI instruction pool */
17434 NM_P16_SYSCALL
= 0x01,
17439 /* POOL16C_0 instruction pool */
17441 NM_POOL16C_00
= 0x00,
17444 /* P16.JRC instruction pool */
17450 /* P.SYSCALL instruction pool */
17456 /* P.TRAP instruction pool */
17462 /* P.CMOVE instruction pool */
17468 /* POOL32Axf instruction pool */
17470 NM_POOL32AXF_1
= 0x01,
17471 NM_POOL32AXF_2
= 0x02,
17472 NM_POOL32AXF_4
= 0x04,
17473 NM_POOL32AXF_5
= 0x05,
17474 NM_POOL32AXF_7
= 0x07,
17477 /* POOL32Axf_1 instruction pool */
17479 NM_POOL32AXF_1_0
= 0x00,
17480 NM_POOL32AXF_1_1
= 0x01,
17481 NM_POOL32AXF_1_3
= 0x03,
17482 NM_POOL32AXF_1_4
= 0x04,
17483 NM_POOL32AXF_1_5
= 0x05,
17484 NM_POOL32AXF_1_7
= 0x07,
17487 /* POOL32Axf_2 instruction pool */
17489 NM_POOL32AXF_2_0_7
= 0x00,
17490 NM_POOL32AXF_2_8_15
= 0x01,
17491 NM_POOL32AXF_2_16_23
= 0x02,
17492 NM_POOL32AXF_2_24_31
= 0x03,
17495 /* POOL32Axf_7 instruction pool */
17497 NM_SHRA_R_QB
= 0x0,
17502 /* POOL32Axf_1_0 instruction pool */
17510 /* POOL32Axf_1_1 instruction pool */
17516 /* POOL32Axf_1_3 instruction pool */
17524 /* POOL32Axf_1_4 instruction pool */
17530 /* POOL32Axf_1_5 instruction pool */
17532 NM_MAQ_S_W_PHR
= 0x0,
17533 NM_MAQ_S_W_PHL
= 0x1,
17534 NM_MAQ_SA_W_PHR
= 0x2,
17535 NM_MAQ_SA_W_PHL
= 0x3,
17538 /* POOL32Axf_1_7 instruction pool */
17542 NM_EXTR_RS_W
= 0x2,
17546 /* POOL32Axf_2_0_7 instruction pool */
17549 NM_DPAQ_S_W_PH
= 0x1,
17551 NM_DPSQ_S_W_PH
= 0x3,
17558 /* POOL32Axf_2_8_15 instruction pool */
17560 NM_DPAX_W_PH
= 0x0,
17561 NM_DPAQ_SA_L_W
= 0x1,
17562 NM_DPSX_W_PH
= 0x2,
17563 NM_DPSQ_SA_L_W
= 0x3,
17566 NM_EXTRV_R_W
= 0x7,
17569 /* POOL32Axf_2_16_23 instruction pool */
17571 NM_DPAU_H_QBL
= 0x0,
17572 NM_DPAQX_S_W_PH
= 0x1,
17573 NM_DPSU_H_QBL
= 0x2,
17574 NM_DPSQX_S_W_PH
= 0x3,
17577 NM_MULSA_W_PH
= 0x6,
17578 NM_EXTRV_RS_W
= 0x7,
17581 /* POOL32Axf_2_24_31 instruction pool */
17583 NM_DPAU_H_QBR
= 0x0,
17584 NM_DPAQX_SA_W_PH
= 0x1,
17585 NM_DPSU_H_QBR
= 0x2,
17586 NM_DPSQX_SA_W_PH
= 0x3,
17589 NM_MULSAQ_S_W_PH
= 0x6,
17590 NM_EXTRV_S_H
= 0x7,
17593 /* POOL32Axf_{4, 5} instruction pool */
17612 /* nanoMIPS DSP instructions */
17613 NM_ABSQ_S_QB
= 0x00,
17614 NM_ABSQ_S_PH
= 0x08,
17615 NM_ABSQ_S_W
= 0x10,
17616 NM_PRECEQ_W_PHL
= 0x28,
17617 NM_PRECEQ_W_PHR
= 0x30,
17618 NM_PRECEQU_PH_QBL
= 0x38,
17619 NM_PRECEQU_PH_QBR
= 0x48,
17620 NM_PRECEU_PH_QBL
= 0x58,
17621 NM_PRECEU_PH_QBR
= 0x68,
17622 NM_PRECEQU_PH_QBLA
= 0x39,
17623 NM_PRECEQU_PH_QBRA
= 0x49,
17624 NM_PRECEU_PH_QBLA
= 0x59,
17625 NM_PRECEU_PH_QBRA
= 0x69,
17626 NM_REPLV_PH
= 0x01,
17627 NM_REPLV_QB
= 0x09,
17630 NM_RADDU_W_QB
= 0x78,
17636 /* PP.SR instruction pool */
17640 NM_RESTORE_JRC
= 0x03,
17643 /* P.SR.F instruction pool */
17646 NM_RESTOREF
= 0x01,
17649 /* P16.SYSCALL instruction pool */
17651 NM_SYSCALL16
= 0x00,
17652 NM_HYPCALL16
= 0x01,
17655 /* POOL16C_00 instruction pool */
17663 /* PP.LSX and PP.LSXS instruction pool */
17701 /* ERETx instruction pool */
17707 /* POOL32FxF_{0, 1} insturction pool */
17716 NM_CVT_S_PL
= 0x84,
17717 NM_CVT_S_PU
= 0xa4,
17719 NM_CVT_L_S
= 0x004,
17720 NM_CVT_L_D
= 0x104,
17721 NM_CVT_W_S
= 0x024,
17722 NM_CVT_W_D
= 0x124,
17724 NM_RSQRT_S
= 0x008,
17725 NM_RSQRT_D
= 0x108,
17730 NM_RECIP_S
= 0x048,
17731 NM_RECIP_D
= 0x148,
17733 NM_FLOOR_L_S
= 0x00c,
17734 NM_FLOOR_L_D
= 0x10c,
17736 NM_FLOOR_W_S
= 0x02c,
17737 NM_FLOOR_W_D
= 0x12c,
17739 NM_CEIL_L_S
= 0x04c,
17740 NM_CEIL_L_D
= 0x14c,
17741 NM_CEIL_W_S
= 0x06c,
17742 NM_CEIL_W_D
= 0x16c,
17743 NM_TRUNC_L_S
= 0x08c,
17744 NM_TRUNC_L_D
= 0x18c,
17745 NM_TRUNC_W_S
= 0x0ac,
17746 NM_TRUNC_W_D
= 0x1ac,
17747 NM_ROUND_L_S
= 0x0cc,
17748 NM_ROUND_L_D
= 0x1cc,
17749 NM_ROUND_W_S
= 0x0ec,
17750 NM_ROUND_W_D
= 0x1ec,
17758 NM_CVT_D_S
= 0x04d,
17759 NM_CVT_D_W
= 0x0cd,
17760 NM_CVT_D_L
= 0x14d,
17761 NM_CVT_S_D
= 0x06d,
17762 NM_CVT_S_W
= 0x0ed,
17763 NM_CVT_S_L
= 0x16d,
17766 /* P.LL instruction pool */
17772 /* P.SC instruction pool */
17778 /* P.DVP instruction pool */
17787 * nanoMIPS decoding engine
17792 /* extraction utilities */
17794 #define NANOMIPS_EXTRACT_RT3(op) ((op >> 7) & 0x7)
17795 #define NANOMIPS_EXTRACT_RS3(op) ((op >> 4) & 0x7)
17796 #define NANOMIPS_EXTRACT_RD3(op) ((op >> 1) & 0x7)
17797 #define NANOMIPS_EXTRACT_RD5(op) ((op >> 5) & 0x1f)
17798 #define NANOMIPS_EXTRACT_RS5(op) (op & 0x1f)
17800 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3'). */
17801 static inline int decode_gpr_gpr3(int r
)
17803 static const int map
[] = { 16, 17, 18, 19, 4, 5, 6, 7 };
17805 return map
[r
& 0x7];
17808 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3.src.store'). */
17809 static inline int decode_gpr_gpr3_src_store(int r
)
17811 static const int map
[] = { 0, 17, 18, 19, 4, 5, 6, 7 };
17813 return map
[r
& 0x7];
17816 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4'). */
17817 static inline int decode_gpr_gpr4(int r
)
17819 static const int map
[] = { 8, 9, 10, 11, 4, 5, 6, 7,
17820 16, 17, 18, 19, 20, 21, 22, 23 };
17822 return map
[r
& 0xf];
17825 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4.zero'). */
17826 static inline int decode_gpr_gpr4_zero(int r
)
17828 static const int map
[] = { 8, 9, 10, 0, 4, 5, 6, 7,
17829 16, 17, 18, 19, 20, 21, 22, 23 };
17831 return map
[r
& 0xf];
17835 static void gen_adjust_sp(DisasContext
*ctx
, int u
)
17837 gen_op_addr_addi(ctx
, cpu_gpr
[29], cpu_gpr
[29], u
);
17840 static void gen_save(DisasContext
*ctx
, uint8_t rt
, uint8_t count
,
17841 uint8_t gp
, uint16_t u
)
17844 TCGv va
= tcg_temp_new();
17845 TCGv t0
= tcg_temp_new();
17847 while (counter
!= count
) {
17848 bool use_gp
= gp
&& (counter
== count
- 1);
17849 int this_rt
= use_gp
? 28 : (rt
& 0x10) | ((rt
+ counter
) & 0x1f);
17850 int this_offset
= -((counter
+ 1) << 2);
17851 gen_base_offset_addr(ctx
, va
, 29, this_offset
);
17852 gen_load_gpr(t0
, this_rt
);
17853 tcg_gen_qemu_st_tl(t0
, va
, ctx
->mem_idx
,
17854 (MO_TEUL
| ctx
->default_tcg_memop_mask
));
17858 /* adjust stack pointer */
17859 gen_adjust_sp(ctx
, -u
);
17865 static void gen_restore(DisasContext
*ctx
, uint8_t rt
, uint8_t count
,
17866 uint8_t gp
, uint16_t u
)
17869 TCGv va
= tcg_temp_new();
17870 TCGv t0
= tcg_temp_new();
17872 while (counter
!= count
) {
17873 bool use_gp
= gp
&& (counter
== count
- 1);
17874 int this_rt
= use_gp
? 28 : (rt
& 0x10) | ((rt
+ counter
) & 0x1f);
17875 int this_offset
= u
- ((counter
+ 1) << 2);
17876 gen_base_offset_addr(ctx
, va
, 29, this_offset
);
17877 tcg_gen_qemu_ld_tl(t0
, va
, ctx
->mem_idx
, MO_TESL
|
17878 ctx
->default_tcg_memop_mask
);
17879 tcg_gen_ext32s_tl(t0
, t0
);
17880 gen_store_gpr(t0
, this_rt
);
17884 /* adjust stack pointer */
17885 gen_adjust_sp(ctx
, u
);
17891 static void gen_pool16c_nanomips_insn(DisasContext
*ctx
)
17893 int rt
= decode_gpr_gpr3(NANOMIPS_EXTRACT_RT3(ctx
->opcode
));
17894 int rs
= decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx
->opcode
));
17896 switch (extract32(ctx
->opcode
, 2, 2)) {
17898 gen_logic(ctx
, OPC_NOR
, rt
, rs
, 0);
17901 gen_logic(ctx
, OPC_AND
, rt
, rt
, rs
);
17904 gen_logic(ctx
, OPC_XOR
, rt
, rt
, rs
);
17907 gen_logic(ctx
, OPC_OR
, rt
, rt
, rs
);
17912 static void gen_pool32a0_nanomips_insn(CPUMIPSState
*env
, DisasContext
*ctx
)
17914 int rt
= extract32(ctx
->opcode
, 21, 5);
17915 int rs
= extract32(ctx
->opcode
, 16, 5);
17916 int rd
= extract32(ctx
->opcode
, 11, 5);
17918 switch (extract32(ctx
->opcode
, 3, 7)) {
17920 switch (extract32(ctx
->opcode
, 10, 1)) {
17923 gen_trap(ctx
, OPC_TEQ
, rs
, rt
, -1);
17927 gen_trap(ctx
, OPC_TNE
, rs
, rt
, -1);
17933 gen_rdhwr(ctx
, rt
, rs
, extract32(ctx
->opcode
, 11, 3));
17937 gen_bshfl(ctx
, OPC_SEB
, rs
, rt
);
17940 gen_bshfl(ctx
, OPC_SEH
, rs
, rt
);
17943 gen_shift(ctx
, OPC_SLLV
, rd
, rt
, rs
);
17946 gen_shift(ctx
, OPC_SRLV
, rd
, rt
, rs
);
17949 gen_shift(ctx
, OPC_SRAV
, rd
, rt
, rs
);
17952 gen_shift(ctx
, OPC_ROTRV
, rd
, rt
, rs
);
17955 gen_arith(ctx
, OPC_ADD
, rd
, rs
, rt
);
17958 gen_arith(ctx
, OPC_ADDU
, rd
, rs
, rt
);
17962 gen_arith(ctx
, OPC_SUB
, rd
, rs
, rt
);
17965 gen_arith(ctx
, OPC_SUBU
, rd
, rs
, rt
);
17968 switch (extract32(ctx
->opcode
, 10, 1)) {
17970 gen_cond_move(ctx
, OPC_MOVZ
, rd
, rs
, rt
);
17973 gen_cond_move(ctx
, OPC_MOVN
, rd
, rs
, rt
);
17978 gen_logic(ctx
, OPC_AND
, rd
, rs
, rt
);
17981 gen_logic(ctx
, OPC_OR
, rd
, rs
, rt
);
17984 gen_logic(ctx
, OPC_NOR
, rd
, rs
, rt
);
17987 gen_logic(ctx
, OPC_XOR
, rd
, rs
, rt
);
17990 gen_slt(ctx
, OPC_SLT
, rd
, rs
, rt
);
17995 #ifndef CONFIG_USER_ONLY
17996 TCGv t0
= tcg_temp_new();
17997 switch (extract32(ctx
->opcode
, 10, 1)) {
18000 check_cp0_enabled(ctx
);
18001 gen_helper_dvp(t0
, cpu_env
);
18002 gen_store_gpr(t0
, rt
);
18007 check_cp0_enabled(ctx
);
18008 gen_helper_evp(t0
, cpu_env
);
18009 gen_store_gpr(t0
, rt
);
18016 gen_slt(ctx
, OPC_SLTU
, rd
, rs
, rt
);
18021 TCGv t0
= tcg_temp_new();
18022 TCGv t1
= tcg_temp_new();
18023 TCGv t2
= tcg_temp_new();
18025 gen_load_gpr(t1
, rs
);
18026 gen_load_gpr(t2
, rt
);
18027 tcg_gen_add_tl(t0
, t1
, t2
);
18028 tcg_gen_ext32s_tl(t0
, t0
);
18029 tcg_gen_xor_tl(t1
, t1
, t2
);
18030 tcg_gen_xor_tl(t2
, t0
, t2
);
18031 tcg_gen_andc_tl(t1
, t2
, t1
);
18033 /* operands of same sign, result different sign */
18034 tcg_gen_setcondi_tl(TCG_COND_LT
, t0
, t1
, 0);
18035 gen_store_gpr(t0
, rd
);
18043 gen_r6_muldiv(ctx
, R6_OPC_MUL
, rd
, rs
, rt
);
18046 gen_r6_muldiv(ctx
, R6_OPC_MUH
, rd
, rs
, rt
);
18049 gen_r6_muldiv(ctx
, R6_OPC_MULU
, rd
, rs
, rt
);
18052 gen_r6_muldiv(ctx
, R6_OPC_MUHU
, rd
, rs
, rt
);
18055 gen_r6_muldiv(ctx
, R6_OPC_DIV
, rd
, rs
, rt
);
18058 gen_r6_muldiv(ctx
, R6_OPC_MOD
, rd
, rs
, rt
);
18061 gen_r6_muldiv(ctx
, R6_OPC_DIVU
, rd
, rs
, rt
);
18064 gen_r6_muldiv(ctx
, R6_OPC_MODU
, rd
, rs
, rt
);
18066 #ifndef CONFIG_USER_ONLY
18068 check_cp0_enabled(ctx
);
18070 /* Treat as NOP. */
18073 gen_mfc0(ctx
, cpu_gpr
[rt
], rs
, extract32(ctx
->opcode
, 11, 3));
18076 check_cp0_enabled(ctx
);
18078 TCGv t0
= tcg_temp_new();
18080 gen_load_gpr(t0
, rt
);
18081 gen_mtc0(ctx
, t0
, rs
, extract32(ctx
->opcode
, 11, 3));
18085 case NM_D_E_MT_VPE
:
18087 uint8_t sc
= extract32(ctx
->opcode
, 10, 1);
18088 TCGv t0
= tcg_temp_new();
18095 gen_helper_dmt(t0
);
18096 gen_store_gpr(t0
, rt
);
18097 } else if (rs
== 0) {
18100 gen_helper_dvpe(t0
, cpu_env
);
18101 gen_store_gpr(t0
, rt
);
18103 gen_reserved_instruction(ctx
);
18110 gen_helper_emt(t0
);
18111 gen_store_gpr(t0
, rt
);
18112 } else if (rs
== 0) {
18115 gen_helper_evpe(t0
, cpu_env
);
18116 gen_store_gpr(t0
, rt
);
18118 gen_reserved_instruction(ctx
);
18129 TCGv t0
= tcg_temp_new();
18130 TCGv t1
= tcg_temp_new();
18132 gen_load_gpr(t0
, rt
);
18133 gen_load_gpr(t1
, rs
);
18134 gen_helper_fork(t0
, t1
);
18141 check_cp0_enabled(ctx
);
18143 /* Treat as NOP. */
18146 gen_mftr(env
, ctx
, rs
, rt
, extract32(ctx
->opcode
, 10, 1),
18147 extract32(ctx
->opcode
, 11, 5), extract32(ctx
->opcode
, 3, 1));
18151 check_cp0_enabled(ctx
);
18152 gen_mttr(env
, ctx
, rs
, rt
, extract32(ctx
->opcode
, 10, 1),
18153 extract32(ctx
->opcode
, 11, 5), extract32(ctx
->opcode
, 3, 1));
18158 TCGv t0
= tcg_temp_new();
18160 gen_load_gpr(t0
, rs
);
18161 gen_helper_yield(t0
, cpu_env
, t0
);
18162 gen_store_gpr(t0
, rt
);
18168 gen_reserved_instruction(ctx
);
18174 static void gen_pool32axf_1_5_nanomips_insn(DisasContext
*ctx
, uint32_t opc
,
18175 int ret
, int v1
, int v2
)
18181 t0
= tcg_temp_new_i32();
18183 v0_t
= tcg_temp_new();
18184 v1_t
= tcg_temp_new();
18186 tcg_gen_movi_i32(t0
, v2
>> 3);
18188 gen_load_gpr(v0_t
, ret
);
18189 gen_load_gpr(v1_t
, v1
);
18192 case NM_MAQ_S_W_PHR
:
18194 gen_helper_maq_s_w_phr(t0
, v1_t
, v0_t
, cpu_env
);
18196 case NM_MAQ_S_W_PHL
:
18198 gen_helper_maq_s_w_phl(t0
, v1_t
, v0_t
, cpu_env
);
18200 case NM_MAQ_SA_W_PHR
:
18202 gen_helper_maq_sa_w_phr(t0
, v1_t
, v0_t
, cpu_env
);
18204 case NM_MAQ_SA_W_PHL
:
18206 gen_helper_maq_sa_w_phl(t0
, v1_t
, v0_t
, cpu_env
);
18209 gen_reserved_instruction(ctx
);
18213 tcg_temp_free_i32(t0
);
18215 tcg_temp_free(v0_t
);
18216 tcg_temp_free(v1_t
);
18220 static void gen_pool32axf_1_nanomips_insn(DisasContext
*ctx
, uint32_t opc
,
18221 int ret
, int v1
, int v2
)
18224 TCGv t0
= tcg_temp_new();
18225 TCGv t1
= tcg_temp_new();
18226 TCGv v0_t
= tcg_temp_new();
18228 gen_load_gpr(v0_t
, v1
);
18231 case NM_POOL32AXF_1_0
:
18233 switch (extract32(ctx
->opcode
, 12, 2)) {
18235 gen_HILO(ctx
, OPC_MFHI
, v2
>> 3, ret
);
18238 gen_HILO(ctx
, OPC_MFLO
, v2
>> 3, ret
);
18241 gen_HILO(ctx
, OPC_MTHI
, v2
>> 3, v1
);
18244 gen_HILO(ctx
, OPC_MTLO
, v2
>> 3, v1
);
18248 case NM_POOL32AXF_1_1
:
18250 switch (extract32(ctx
->opcode
, 12, 2)) {
18252 tcg_gen_movi_tl(t0
, v2
);
18253 gen_helper_mthlip(t0
, v0_t
, cpu_env
);
18256 tcg_gen_movi_tl(t0
, v2
>> 3);
18257 gen_helper_shilo(t0
, v0_t
, cpu_env
);
18260 gen_reserved_instruction(ctx
);
18264 case NM_POOL32AXF_1_3
:
18266 imm
= extract32(ctx
->opcode
, 14, 7);
18267 switch (extract32(ctx
->opcode
, 12, 2)) {
18269 tcg_gen_movi_tl(t0
, imm
);
18270 gen_helper_rddsp(t0
, t0
, cpu_env
);
18271 gen_store_gpr(t0
, ret
);
18274 gen_load_gpr(t0
, ret
);
18275 tcg_gen_movi_tl(t1
, imm
);
18276 gen_helper_wrdsp(t0
, t1
, cpu_env
);
18279 tcg_gen_movi_tl(t0
, v2
>> 3);
18280 tcg_gen_movi_tl(t1
, v1
);
18281 gen_helper_extp(t0
, t0
, t1
, cpu_env
);
18282 gen_store_gpr(t0
, ret
);
18285 tcg_gen_movi_tl(t0
, v2
>> 3);
18286 tcg_gen_movi_tl(t1
, v1
);
18287 gen_helper_extpdp(t0
, t0
, t1
, cpu_env
);
18288 gen_store_gpr(t0
, ret
);
18292 case NM_POOL32AXF_1_4
:
18294 tcg_gen_movi_tl(t0
, v2
>> 2);
18295 switch (extract32(ctx
->opcode
, 12, 1)) {
18297 gen_helper_shll_qb(t0
, t0
, v0_t
, cpu_env
);
18298 gen_store_gpr(t0
, ret
);
18301 gen_helper_shrl_qb(t0
, t0
, v0_t
);
18302 gen_store_gpr(t0
, ret
);
18306 case NM_POOL32AXF_1_5
:
18307 opc
= extract32(ctx
->opcode
, 12, 2);
18308 gen_pool32axf_1_5_nanomips_insn(ctx
, opc
, ret
, v1
, v2
);
18310 case NM_POOL32AXF_1_7
:
18312 tcg_gen_movi_tl(t0
, v2
>> 3);
18313 tcg_gen_movi_tl(t1
, v1
);
18314 switch (extract32(ctx
->opcode
, 12, 2)) {
18316 gen_helper_extr_w(t0
, t0
, t1
, cpu_env
);
18317 gen_store_gpr(t0
, ret
);
18320 gen_helper_extr_r_w(t0
, t0
, t1
, cpu_env
);
18321 gen_store_gpr(t0
, ret
);
18324 gen_helper_extr_rs_w(t0
, t0
, t1
, cpu_env
);
18325 gen_store_gpr(t0
, ret
);
18328 gen_helper_extr_s_h(t0
, t0
, t1
, cpu_env
);
18329 gen_store_gpr(t0
, ret
);
18334 gen_reserved_instruction(ctx
);
18340 tcg_temp_free(v0_t
);
18343 static void gen_pool32axf_2_multiply(DisasContext
*ctx
, uint32_t opc
,
18344 TCGv v0
, TCGv v1
, int rd
)
18348 t0
= tcg_temp_new_i32();
18350 tcg_gen_movi_i32(t0
, rd
>> 3);
18353 case NM_POOL32AXF_2_0_7
:
18354 switch (extract32(ctx
->opcode
, 9, 3)) {
18357 gen_helper_dpa_w_ph(t0
, v1
, v0
, cpu_env
);
18359 case NM_DPAQ_S_W_PH
:
18361 gen_helper_dpaq_s_w_ph(t0
, v1
, v0
, cpu_env
);
18365 gen_helper_dps_w_ph(t0
, v1
, v0
, cpu_env
);
18367 case NM_DPSQ_S_W_PH
:
18369 gen_helper_dpsq_s_w_ph(t0
, v1
, v0
, cpu_env
);
18372 gen_reserved_instruction(ctx
);
18376 case NM_POOL32AXF_2_8_15
:
18377 switch (extract32(ctx
->opcode
, 9, 3)) {
18380 gen_helper_dpax_w_ph(t0
, v0
, v1
, cpu_env
);
18382 case NM_DPAQ_SA_L_W
:
18384 gen_helper_dpaq_sa_l_w(t0
, v0
, v1
, cpu_env
);
18388 gen_helper_dpsx_w_ph(t0
, v0
, v1
, cpu_env
);
18390 case NM_DPSQ_SA_L_W
:
18392 gen_helper_dpsq_sa_l_w(t0
, v0
, v1
, cpu_env
);
18395 gen_reserved_instruction(ctx
);
18399 case NM_POOL32AXF_2_16_23
:
18400 switch (extract32(ctx
->opcode
, 9, 3)) {
18401 case NM_DPAU_H_QBL
:
18403 gen_helper_dpau_h_qbl(t0
, v0
, v1
, cpu_env
);
18405 case NM_DPAQX_S_W_PH
:
18407 gen_helper_dpaqx_s_w_ph(t0
, v0
, v1
, cpu_env
);
18409 case NM_DPSU_H_QBL
:
18411 gen_helper_dpsu_h_qbl(t0
, v0
, v1
, cpu_env
);
18413 case NM_DPSQX_S_W_PH
:
18415 gen_helper_dpsqx_s_w_ph(t0
, v0
, v1
, cpu_env
);
18417 case NM_MULSA_W_PH
:
18419 gen_helper_mulsa_w_ph(t0
, v0
, v1
, cpu_env
);
18422 gen_reserved_instruction(ctx
);
18426 case NM_POOL32AXF_2_24_31
:
18427 switch (extract32(ctx
->opcode
, 9, 3)) {
18428 case NM_DPAU_H_QBR
:
18430 gen_helper_dpau_h_qbr(t0
, v1
, v0
, cpu_env
);
18432 case NM_DPAQX_SA_W_PH
:
18434 gen_helper_dpaqx_sa_w_ph(t0
, v1
, v0
, cpu_env
);
18436 case NM_DPSU_H_QBR
:
18438 gen_helper_dpsu_h_qbr(t0
, v1
, v0
, cpu_env
);
18440 case NM_DPSQX_SA_W_PH
:
18442 gen_helper_dpsqx_sa_w_ph(t0
, v1
, v0
, cpu_env
);
18444 case NM_MULSAQ_S_W_PH
:
18446 gen_helper_mulsaq_s_w_ph(t0
, v1
, v0
, cpu_env
);
18449 gen_reserved_instruction(ctx
);
18454 gen_reserved_instruction(ctx
);
18458 tcg_temp_free_i32(t0
);
18461 static void gen_pool32axf_2_nanomips_insn(DisasContext
*ctx
, uint32_t opc
,
18462 int rt
, int rs
, int rd
)
18465 TCGv t0
= tcg_temp_new();
18466 TCGv t1
= tcg_temp_new();
18467 TCGv v0_t
= tcg_temp_new();
18468 TCGv v1_t
= tcg_temp_new();
18470 gen_load_gpr(v0_t
, rt
);
18471 gen_load_gpr(v1_t
, rs
);
18474 case NM_POOL32AXF_2_0_7
:
18475 switch (extract32(ctx
->opcode
, 9, 3)) {
18477 case NM_DPAQ_S_W_PH
:
18479 case NM_DPSQ_S_W_PH
:
18480 gen_pool32axf_2_multiply(ctx
, opc
, v0_t
, v1_t
, rd
);
18485 gen_load_gpr(t0
, rs
);
18487 if (rd
!= 0 && rd
!= 2) {
18488 tcg_gen_shli_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], 8 * rd
);
18489 tcg_gen_ext32u_tl(t0
, t0
);
18490 tcg_gen_shri_tl(t0
, t0
, 8 * (4 - rd
));
18491 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
18493 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
18499 int acc
= extract32(ctx
->opcode
, 14, 2);
18500 TCGv_i64 t2
= tcg_temp_new_i64();
18501 TCGv_i64 t3
= tcg_temp_new_i64();
18503 gen_load_gpr(t0
, rt
);
18504 gen_load_gpr(t1
, rs
);
18505 tcg_gen_ext_tl_i64(t2
, t0
);
18506 tcg_gen_ext_tl_i64(t3
, t1
);
18507 tcg_gen_mul_i64(t2
, t2
, t3
);
18508 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
18509 tcg_gen_add_i64(t2
, t2
, t3
);
18510 tcg_temp_free_i64(t3
);
18511 gen_move_low32(cpu_LO
[acc
], t2
);
18512 gen_move_high32(cpu_HI
[acc
], t2
);
18513 tcg_temp_free_i64(t2
);
18519 int acc
= extract32(ctx
->opcode
, 14, 2);
18520 TCGv_i32 t2
= tcg_temp_new_i32();
18521 TCGv_i32 t3
= tcg_temp_new_i32();
18523 gen_load_gpr(t0
, rs
);
18524 gen_load_gpr(t1
, rt
);
18525 tcg_gen_trunc_tl_i32(t2
, t0
);
18526 tcg_gen_trunc_tl_i32(t3
, t1
);
18527 tcg_gen_muls2_i32(t2
, t3
, t2
, t3
);
18528 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
18529 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
18530 tcg_temp_free_i32(t2
);
18531 tcg_temp_free_i32(t3
);
18536 gen_load_gpr(v1_t
, rs
);
18537 tcg_gen_movi_tl(t0
, rd
>> 3);
18538 gen_helper_extr_w(t0
, t0
, v1_t
, cpu_env
);
18539 gen_store_gpr(t0
, ret
);
18543 case NM_POOL32AXF_2_8_15
:
18544 switch (extract32(ctx
->opcode
, 9, 3)) {
18546 case NM_DPAQ_SA_L_W
:
18548 case NM_DPSQ_SA_L_W
:
18549 gen_pool32axf_2_multiply(ctx
, opc
, v0_t
, v1_t
, rd
);
18554 int acc
= extract32(ctx
->opcode
, 14, 2);
18555 TCGv_i64 t2
= tcg_temp_new_i64();
18556 TCGv_i64 t3
= tcg_temp_new_i64();
18558 gen_load_gpr(t0
, rs
);
18559 gen_load_gpr(t1
, rt
);
18560 tcg_gen_ext32u_tl(t0
, t0
);
18561 tcg_gen_ext32u_tl(t1
, t1
);
18562 tcg_gen_extu_tl_i64(t2
, t0
);
18563 tcg_gen_extu_tl_i64(t3
, t1
);
18564 tcg_gen_mul_i64(t2
, t2
, t3
);
18565 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
18566 tcg_gen_add_i64(t2
, t2
, t3
);
18567 tcg_temp_free_i64(t3
);
18568 gen_move_low32(cpu_LO
[acc
], t2
);
18569 gen_move_high32(cpu_HI
[acc
], t2
);
18570 tcg_temp_free_i64(t2
);
18576 int acc
= extract32(ctx
->opcode
, 14, 2);
18577 TCGv_i32 t2
= tcg_temp_new_i32();
18578 TCGv_i32 t3
= tcg_temp_new_i32();
18580 gen_load_gpr(t0
, rs
);
18581 gen_load_gpr(t1
, rt
);
18582 tcg_gen_trunc_tl_i32(t2
, t0
);
18583 tcg_gen_trunc_tl_i32(t3
, t1
);
18584 tcg_gen_mulu2_i32(t2
, t3
, t2
, t3
);
18585 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
18586 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
18587 tcg_temp_free_i32(t2
);
18588 tcg_temp_free_i32(t3
);
18593 tcg_gen_movi_tl(t0
, rd
>> 3);
18594 gen_helper_extr_r_w(t0
, t0
, v1_t
, cpu_env
);
18595 gen_store_gpr(t0
, ret
);
18598 gen_reserved_instruction(ctx
);
18602 case NM_POOL32AXF_2_16_23
:
18603 switch (extract32(ctx
->opcode
, 9, 3)) {
18604 case NM_DPAU_H_QBL
:
18605 case NM_DPAQX_S_W_PH
:
18606 case NM_DPSU_H_QBL
:
18607 case NM_DPSQX_S_W_PH
:
18608 case NM_MULSA_W_PH
:
18609 gen_pool32axf_2_multiply(ctx
, opc
, v0_t
, v1_t
, rd
);
18613 tcg_gen_movi_tl(t0
, rd
>> 3);
18614 gen_helper_extp(t0
, t0
, v1_t
, cpu_env
);
18615 gen_store_gpr(t0
, ret
);
18620 int acc
= extract32(ctx
->opcode
, 14, 2);
18621 TCGv_i64 t2
= tcg_temp_new_i64();
18622 TCGv_i64 t3
= tcg_temp_new_i64();
18624 gen_load_gpr(t0
, rs
);
18625 gen_load_gpr(t1
, rt
);
18626 tcg_gen_ext_tl_i64(t2
, t0
);
18627 tcg_gen_ext_tl_i64(t3
, t1
);
18628 tcg_gen_mul_i64(t2
, t2
, t3
);
18629 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
18630 tcg_gen_sub_i64(t2
, t3
, t2
);
18631 tcg_temp_free_i64(t3
);
18632 gen_move_low32(cpu_LO
[acc
], t2
);
18633 gen_move_high32(cpu_HI
[acc
], t2
);
18634 tcg_temp_free_i64(t2
);
18637 case NM_EXTRV_RS_W
:
18639 tcg_gen_movi_tl(t0
, rd
>> 3);
18640 gen_helper_extr_rs_w(t0
, t0
, v1_t
, cpu_env
);
18641 gen_store_gpr(t0
, ret
);
18645 case NM_POOL32AXF_2_24_31
:
18646 switch (extract32(ctx
->opcode
, 9, 3)) {
18647 case NM_DPAU_H_QBR
:
18648 case NM_DPAQX_SA_W_PH
:
18649 case NM_DPSU_H_QBR
:
18650 case NM_DPSQX_SA_W_PH
:
18651 case NM_MULSAQ_S_W_PH
:
18652 gen_pool32axf_2_multiply(ctx
, opc
, v0_t
, v1_t
, rd
);
18656 tcg_gen_movi_tl(t0
, rd
>> 3);
18657 gen_helper_extpdp(t0
, t0
, v1_t
, cpu_env
);
18658 gen_store_gpr(t0
, ret
);
18663 int acc
= extract32(ctx
->opcode
, 14, 2);
18664 TCGv_i64 t2
= tcg_temp_new_i64();
18665 TCGv_i64 t3
= tcg_temp_new_i64();
18667 gen_load_gpr(t0
, rs
);
18668 gen_load_gpr(t1
, rt
);
18669 tcg_gen_ext32u_tl(t0
, t0
);
18670 tcg_gen_ext32u_tl(t1
, t1
);
18671 tcg_gen_extu_tl_i64(t2
, t0
);
18672 tcg_gen_extu_tl_i64(t3
, t1
);
18673 tcg_gen_mul_i64(t2
, t2
, t3
);
18674 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
18675 tcg_gen_sub_i64(t2
, t3
, t2
);
18676 tcg_temp_free_i64(t3
);
18677 gen_move_low32(cpu_LO
[acc
], t2
);
18678 gen_move_high32(cpu_HI
[acc
], t2
);
18679 tcg_temp_free_i64(t2
);
18684 tcg_gen_movi_tl(t0
, rd
>> 3);
18685 gen_helper_extr_s_h(t0
, t0
, v0_t
, cpu_env
);
18686 gen_store_gpr(t0
, ret
);
18691 gen_reserved_instruction(ctx
);
18698 tcg_temp_free(v0_t
);
18699 tcg_temp_free(v1_t
);
18702 static void gen_pool32axf_4_nanomips_insn(DisasContext
*ctx
, uint32_t opc
,
18706 TCGv t0
= tcg_temp_new();
18707 TCGv v0_t
= tcg_temp_new();
18709 gen_load_gpr(v0_t
, rs
);
18714 gen_helper_absq_s_qb(v0_t
, v0_t
, cpu_env
);
18715 gen_store_gpr(v0_t
, ret
);
18719 gen_helper_absq_s_ph(v0_t
, v0_t
, cpu_env
);
18720 gen_store_gpr(v0_t
, ret
);
18724 gen_helper_absq_s_w(v0_t
, v0_t
, cpu_env
);
18725 gen_store_gpr(v0_t
, ret
);
18727 case NM_PRECEQ_W_PHL
:
18729 tcg_gen_andi_tl(v0_t
, v0_t
, 0xFFFF0000);
18730 tcg_gen_ext32s_tl(v0_t
, v0_t
);
18731 gen_store_gpr(v0_t
, ret
);
18733 case NM_PRECEQ_W_PHR
:
18735 tcg_gen_andi_tl(v0_t
, v0_t
, 0x0000FFFF);
18736 tcg_gen_shli_tl(v0_t
, v0_t
, 16);
18737 tcg_gen_ext32s_tl(v0_t
, v0_t
);
18738 gen_store_gpr(v0_t
, ret
);
18740 case NM_PRECEQU_PH_QBL
:
18742 gen_helper_precequ_ph_qbl(v0_t
, v0_t
);
18743 gen_store_gpr(v0_t
, ret
);
18745 case NM_PRECEQU_PH_QBR
:
18747 gen_helper_precequ_ph_qbr(v0_t
, v0_t
);
18748 gen_store_gpr(v0_t
, ret
);
18750 case NM_PRECEQU_PH_QBLA
:
18752 gen_helper_precequ_ph_qbla(v0_t
, v0_t
);
18753 gen_store_gpr(v0_t
, ret
);
18755 case NM_PRECEQU_PH_QBRA
:
18757 gen_helper_precequ_ph_qbra(v0_t
, v0_t
);
18758 gen_store_gpr(v0_t
, ret
);
18760 case NM_PRECEU_PH_QBL
:
18762 gen_helper_preceu_ph_qbl(v0_t
, v0_t
);
18763 gen_store_gpr(v0_t
, ret
);
18765 case NM_PRECEU_PH_QBR
:
18767 gen_helper_preceu_ph_qbr(v0_t
, v0_t
);
18768 gen_store_gpr(v0_t
, ret
);
18770 case NM_PRECEU_PH_QBLA
:
18772 gen_helper_preceu_ph_qbla(v0_t
, v0_t
);
18773 gen_store_gpr(v0_t
, ret
);
18775 case NM_PRECEU_PH_QBRA
:
18777 gen_helper_preceu_ph_qbra(v0_t
, v0_t
);
18778 gen_store_gpr(v0_t
, ret
);
18782 tcg_gen_ext16u_tl(v0_t
, v0_t
);
18783 tcg_gen_shli_tl(t0
, v0_t
, 16);
18784 tcg_gen_or_tl(v0_t
, v0_t
, t0
);
18785 tcg_gen_ext32s_tl(v0_t
, v0_t
);
18786 gen_store_gpr(v0_t
, ret
);
18790 tcg_gen_ext8u_tl(v0_t
, v0_t
);
18791 tcg_gen_shli_tl(t0
, v0_t
, 8);
18792 tcg_gen_or_tl(v0_t
, v0_t
, t0
);
18793 tcg_gen_shli_tl(t0
, v0_t
, 16);
18794 tcg_gen_or_tl(v0_t
, v0_t
, t0
);
18795 tcg_gen_ext32s_tl(v0_t
, v0_t
);
18796 gen_store_gpr(v0_t
, ret
);
18800 gen_helper_bitrev(v0_t
, v0_t
);
18801 gen_store_gpr(v0_t
, ret
);
18806 TCGv tv0
= tcg_temp_new();
18808 gen_load_gpr(tv0
, rt
);
18809 gen_helper_insv(v0_t
, cpu_env
, v0_t
, tv0
);
18810 gen_store_gpr(v0_t
, ret
);
18811 tcg_temp_free(tv0
);
18814 case NM_RADDU_W_QB
:
18816 gen_helper_raddu_w_qb(v0_t
, v0_t
);
18817 gen_store_gpr(v0_t
, ret
);
18820 gen_bitswap(ctx
, OPC_BITSWAP
, ret
, rs
);
18824 gen_cl(ctx
, OPC_CLO
, ret
, rs
);
18828 gen_cl(ctx
, OPC_CLZ
, ret
, rs
);
18831 gen_bshfl(ctx
, OPC_WSBH
, ret
, rs
);
18834 gen_reserved_instruction(ctx
);
18838 tcg_temp_free(v0_t
);
18842 static void gen_pool32axf_7_nanomips_insn(DisasContext
*ctx
, uint32_t opc
,
18843 int rt
, int rs
, int rd
)
18845 TCGv t0
= tcg_temp_new();
18846 TCGv rs_t
= tcg_temp_new();
18848 gen_load_gpr(rs_t
, rs
);
18853 tcg_gen_movi_tl(t0
, rd
>> 2);
18854 switch (extract32(ctx
->opcode
, 12, 1)) {
18857 gen_helper_shra_qb(t0
, t0
, rs_t
);
18858 gen_store_gpr(t0
, rt
);
18862 gen_helper_shra_r_qb(t0
, t0
, rs_t
);
18863 gen_store_gpr(t0
, rt
);
18869 tcg_gen_movi_tl(t0
, rd
>> 1);
18870 gen_helper_shrl_ph(t0
, t0
, rs_t
);
18871 gen_store_gpr(t0
, rt
);
18877 target_long result
;
18878 imm
= extract32(ctx
->opcode
, 13, 8);
18879 result
= (uint32_t)imm
<< 24 |
18880 (uint32_t)imm
<< 16 |
18881 (uint32_t)imm
<< 8 |
18883 result
= (int32_t)result
;
18884 tcg_gen_movi_tl(t0
, result
);
18885 gen_store_gpr(t0
, rt
);
18889 gen_reserved_instruction(ctx
);
18893 tcg_temp_free(rs_t
);
18897 static void gen_pool32axf_nanomips_insn(CPUMIPSState
*env
, DisasContext
*ctx
)
18899 int rt
= extract32(ctx
->opcode
, 21, 5);
18900 int rs
= extract32(ctx
->opcode
, 16, 5);
18901 int rd
= extract32(ctx
->opcode
, 11, 5);
18903 switch (extract32(ctx
->opcode
, 6, 3)) {
18904 case NM_POOL32AXF_1
:
18906 int32_t op1
= extract32(ctx
->opcode
, 9, 3);
18907 gen_pool32axf_1_nanomips_insn(ctx
, op1
, rt
, rs
, rd
);
18910 case NM_POOL32AXF_2
:
18912 int32_t op1
= extract32(ctx
->opcode
, 12, 2);
18913 gen_pool32axf_2_nanomips_insn(ctx
, op1
, rt
, rs
, rd
);
18916 case NM_POOL32AXF_4
:
18918 int32_t op1
= extract32(ctx
->opcode
, 9, 7);
18919 gen_pool32axf_4_nanomips_insn(ctx
, op1
, rt
, rs
);
18922 case NM_POOL32AXF_5
:
18923 switch (extract32(ctx
->opcode
, 9, 7)) {
18924 #ifndef CONFIG_USER_ONLY
18926 gen_cp0(env
, ctx
, OPC_TLBP
, 0, 0);
18929 gen_cp0(env
, ctx
, OPC_TLBR
, 0, 0);
18932 gen_cp0(env
, ctx
, OPC_TLBWI
, 0, 0);
18935 gen_cp0(env
, ctx
, OPC_TLBWR
, 0, 0);
18938 gen_cp0(env
, ctx
, OPC_TLBINV
, 0, 0);
18941 gen_cp0(env
, ctx
, OPC_TLBINVF
, 0, 0);
18944 check_cp0_enabled(ctx
);
18946 TCGv t0
= tcg_temp_new();
18948 save_cpu_state(ctx
, 1);
18949 gen_helper_di(t0
, cpu_env
);
18950 gen_store_gpr(t0
, rt
);
18951 /* Stop translation as we may have switched the execution mode */
18952 ctx
->base
.is_jmp
= DISAS_STOP
;
18957 check_cp0_enabled(ctx
);
18959 TCGv t0
= tcg_temp_new();
18961 save_cpu_state(ctx
, 1);
18962 gen_helper_ei(t0
, cpu_env
);
18963 gen_store_gpr(t0
, rt
);
18964 /* Stop translation as we may have switched the execution mode */
18965 ctx
->base
.is_jmp
= DISAS_STOP
;
18970 gen_load_srsgpr(rs
, rt
);
18973 gen_store_srsgpr(rs
, rt
);
18976 gen_cp0(env
, ctx
, OPC_WAIT
, 0, 0);
18979 gen_cp0(env
, ctx
, OPC_DERET
, 0, 0);
18982 gen_cp0(env
, ctx
, OPC_ERET
, 0, 0);
18986 gen_reserved_instruction(ctx
);
18990 case NM_POOL32AXF_7
:
18992 int32_t op1
= extract32(ctx
->opcode
, 9, 3);
18993 gen_pool32axf_7_nanomips_insn(ctx
, op1
, rt
, rs
, rd
);
18997 gen_reserved_instruction(ctx
);
19002 /* Immediate Value Compact Branches */
19003 static void gen_compute_imm_branch(DisasContext
*ctx
, uint32_t opc
,
19004 int rt
, int32_t imm
, int32_t offset
)
19006 TCGCond cond
= TCG_COND_ALWAYS
;
19007 TCGv t0
= tcg_temp_new();
19008 TCGv t1
= tcg_temp_new();
19010 gen_load_gpr(t0
, rt
);
19011 tcg_gen_movi_tl(t1
, imm
);
19012 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
19014 /* Load needed operands and calculate btarget */
19017 if (rt
== 0 && imm
== 0) {
19018 /* Unconditional branch */
19019 } else if (rt
== 0 && imm
!= 0) {
19023 cond
= TCG_COND_EQ
;
19029 if (imm
>= 32 && !(ctx
->hflags
& MIPS_HFLAG_64
)) {
19030 gen_reserved_instruction(ctx
);
19032 } else if (rt
== 0 && opc
== NM_BBEQZC
) {
19033 /* Unconditional branch */
19034 } else if (rt
== 0 && opc
== NM_BBNEZC
) {
19038 tcg_gen_shri_tl(t0
, t0
, imm
);
19039 tcg_gen_andi_tl(t0
, t0
, 1);
19040 tcg_gen_movi_tl(t1
, 0);
19041 if (opc
== NM_BBEQZC
) {
19042 cond
= TCG_COND_EQ
;
19044 cond
= TCG_COND_NE
;
19049 if (rt
== 0 && imm
== 0) {
19052 } else if (rt
== 0 && imm
!= 0) {
19053 /* Unconditional branch */
19055 cond
= TCG_COND_NE
;
19059 if (rt
== 0 && imm
== 0) {
19060 /* Unconditional branch */
19062 cond
= TCG_COND_GE
;
19066 cond
= TCG_COND_LT
;
19069 if (rt
== 0 && imm
== 0) {
19070 /* Unconditional branch */
19072 cond
= TCG_COND_GEU
;
19076 cond
= TCG_COND_LTU
;
19079 MIPS_INVAL("Immediate Value Compact branch");
19080 gen_reserved_instruction(ctx
);
19084 /* branch completion */
19085 clear_branch_hflags(ctx
);
19086 ctx
->base
.is_jmp
= DISAS_NORETURN
;
19088 if (cond
== TCG_COND_ALWAYS
) {
19089 /* Uncoditional compact branch */
19090 gen_goto_tb(ctx
, 0, ctx
->btarget
);
19092 /* Conditional compact branch */
19093 TCGLabel
*fs
= gen_new_label();
19095 tcg_gen_brcond_tl(tcg_invert_cond(cond
), t0
, t1
, fs
);
19097 gen_goto_tb(ctx
, 1, ctx
->btarget
);
19100 gen_goto_tb(ctx
, 0, ctx
->base
.pc_next
+ 4);
19108 /* P.BALRSC type nanoMIPS R6 branches: BALRSC and BRSC */
19109 static void gen_compute_nanomips_pbalrsc_branch(DisasContext
*ctx
, int rs
,
19112 TCGv t0
= tcg_temp_new();
19113 TCGv t1
= tcg_temp_new();
19116 gen_load_gpr(t0
, rs
);
19120 tcg_gen_movi_tl(cpu_gpr
[rt
], ctx
->base
.pc_next
+ 4);
19123 /* calculate btarget */
19124 tcg_gen_shli_tl(t0
, t0
, 1);
19125 tcg_gen_movi_tl(t1
, ctx
->base
.pc_next
+ 4);
19126 gen_op_addr_add(ctx
, btarget
, t1
, t0
);
19128 /* branch completion */
19129 clear_branch_hflags(ctx
);
19130 ctx
->base
.is_jmp
= DISAS_NORETURN
;
19132 /* unconditional branch to register */
19133 tcg_gen_mov_tl(cpu_PC
, btarget
);
19134 tcg_gen_lookup_and_goto_ptr();
19140 /* nanoMIPS Branches */
19141 static void gen_compute_compact_branch_nm(DisasContext
*ctx
, uint32_t opc
,
19142 int rs
, int rt
, int32_t offset
)
19144 int bcond_compute
= 0;
19145 TCGv t0
= tcg_temp_new();
19146 TCGv t1
= tcg_temp_new();
19148 /* Load needed operands and calculate btarget */
19150 /* compact branch */
19153 gen_load_gpr(t0
, rs
);
19154 gen_load_gpr(t1
, rt
);
19156 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
19160 if (rs
== 0 || rs
== rt
) {
19161 /* OPC_BLEZALC, OPC_BGEZALC */
19162 /* OPC_BGTZALC, OPC_BLTZALC */
19163 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 4);
19165 gen_load_gpr(t0
, rs
);
19166 gen_load_gpr(t1
, rt
);
19168 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
19171 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
19175 /* OPC_BEQZC, OPC_BNEZC */
19176 gen_load_gpr(t0
, rs
);
19178 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
19180 /* OPC_JIC, OPC_JIALC */
19181 TCGv tbase
= tcg_temp_new();
19182 TCGv toffset
= tcg_temp_new();
19184 gen_load_gpr(tbase
, rt
);
19185 tcg_gen_movi_tl(toffset
, offset
);
19186 gen_op_addr_add(ctx
, btarget
, tbase
, toffset
);
19187 tcg_temp_free(tbase
);
19188 tcg_temp_free(toffset
);
19192 MIPS_INVAL("Compact branch/jump");
19193 gen_reserved_instruction(ctx
);
19197 if (bcond_compute
== 0) {
19198 /* Uncoditional compact branch */
19201 gen_goto_tb(ctx
, 0, ctx
->btarget
);
19204 MIPS_INVAL("Compact branch/jump");
19205 gen_reserved_instruction(ctx
);
19209 /* Conditional compact branch */
19210 TCGLabel
*fs
= gen_new_label();
19214 if (rs
== 0 && rt
!= 0) {
19216 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE
), t1
, 0, fs
);
19217 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
19219 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE
), t1
, 0, fs
);
19222 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU
), t0
, t1
, fs
);
19226 if (rs
== 0 && rt
!= 0) {
19228 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT
), t1
, 0, fs
);
19229 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
19231 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT
), t1
, 0, fs
);
19234 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU
), t0
, t1
, fs
);
19238 if (rs
== 0 && rt
!= 0) {
19240 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE
), t1
, 0, fs
);
19241 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
19243 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE
), t1
, 0, fs
);
19246 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE
), t0
, t1
, fs
);
19250 if (rs
== 0 && rt
!= 0) {
19252 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT
), t1
, 0, fs
);
19253 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
19255 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT
), t1
, 0, fs
);
19258 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT
), t0
, t1
, fs
);
19262 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ
), t0
, 0, fs
);
19265 MIPS_INVAL("Compact conditional branch/jump");
19266 gen_reserved_instruction(ctx
);
19270 /* branch completion */
19271 clear_branch_hflags(ctx
);
19272 ctx
->base
.is_jmp
= DISAS_NORETURN
;
19274 /* Generating branch here as compact branches don't have delay slot */
19275 gen_goto_tb(ctx
, 1, ctx
->btarget
);
19278 gen_goto_tb(ctx
, 0, ctx
->base
.pc_next
+ 4);
19287 /* nanoMIPS CP1 Branches */
19288 static void gen_compute_branch_cp1_nm(DisasContext
*ctx
, uint32_t op
,
19289 int32_t ft
, int32_t offset
)
19291 target_ulong btarget
;
19292 TCGv_i64 t0
= tcg_temp_new_i64();
19294 gen_load_fpr64(ctx
, t0
, ft
);
19295 tcg_gen_andi_i64(t0
, t0
, 1);
19297 btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
19301 tcg_gen_xori_i64(t0
, t0
, 1);
19302 ctx
->hflags
|= MIPS_HFLAG_BC
;
19305 /* t0 already set */
19306 ctx
->hflags
|= MIPS_HFLAG_BC
;
19309 MIPS_INVAL("cp1 cond branch");
19310 gen_reserved_instruction(ctx
);
19314 tcg_gen_trunc_i64_tl(bcond
, t0
);
19316 ctx
->btarget
= btarget
;
19319 tcg_temp_free_i64(t0
);
19323 static void gen_p_lsx(DisasContext
*ctx
, int rd
, int rs
, int rt
)
19326 t0
= tcg_temp_new();
19327 t1
= tcg_temp_new();
19329 gen_load_gpr(t0
, rs
);
19330 gen_load_gpr(t1
, rt
);
19332 if ((extract32(ctx
->opcode
, 6, 1)) == 1) {
19333 /* PP.LSXS instructions require shifting */
19334 switch (extract32(ctx
->opcode
, 7, 4)) {
19340 tcg_gen_shli_tl(t0
, t0
, 1);
19348 tcg_gen_shli_tl(t0
, t0
, 2);
19352 tcg_gen_shli_tl(t0
, t0
, 3);
19356 gen_op_addr_add(ctx
, t0
, t0
, t1
);
19358 switch (extract32(ctx
->opcode
, 7, 4)) {
19360 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
,
19362 gen_store_gpr(t0
, rd
);
19366 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
,
19368 gen_store_gpr(t0
, rd
);
19372 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
,
19374 gen_store_gpr(t0
, rd
);
19377 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
,
19379 gen_store_gpr(t0
, rd
);
19383 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
,
19385 gen_store_gpr(t0
, rd
);
19389 gen_load_gpr(t1
, rd
);
19390 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
,
19396 gen_load_gpr(t1
, rd
);
19397 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
,
19403 gen_load_gpr(t1
, rd
);
19404 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
,
19408 /*case NM_LWC1XS:*/
19410 /*case NM_LDC1XS:*/
19412 /*case NM_SWC1XS:*/
19414 /*case NM_SDC1XS:*/
19415 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
19416 check_cp1_enabled(ctx
);
19417 switch (extract32(ctx
->opcode
, 7, 4)) {
19419 /*case NM_LWC1XS:*/
19420 gen_flt_ldst(ctx
, OPC_LWC1
, rd
, t0
);
19423 /*case NM_LDC1XS:*/
19424 gen_flt_ldst(ctx
, OPC_LDC1
, rd
, t0
);
19427 /*case NM_SWC1XS:*/
19428 gen_flt_ldst(ctx
, OPC_SWC1
, rd
, t0
);
19431 /*case NM_SDC1XS:*/
19432 gen_flt_ldst(ctx
, OPC_SDC1
, rd
, t0
);
19436 generate_exception_err(ctx
, EXCP_CpU
, 1);
19440 gen_reserved_instruction(ctx
);
19448 static void gen_pool32f_nanomips_insn(DisasContext
*ctx
)
19452 rt
= extract32(ctx
->opcode
, 21, 5);
19453 rs
= extract32(ctx
->opcode
, 16, 5);
19454 rd
= extract32(ctx
->opcode
, 11, 5);
19456 if (!(ctx
->CP0_Config1
& (1 << CP0C1_FP
))) {
19457 gen_reserved_instruction(ctx
);
19460 check_cp1_enabled(ctx
);
19461 switch (extract32(ctx
->opcode
, 0, 3)) {
19463 switch (extract32(ctx
->opcode
, 3, 7)) {
19465 gen_farith(ctx
, OPC_RINT_S
, 0, rt
, rs
, 0);
19468 gen_farith(ctx
, OPC_RINT_D
, 0, rt
, rs
, 0);
19471 gen_farith(ctx
, OPC_CLASS_S
, 0, rt
, rs
, 0);
19474 gen_farith(ctx
, OPC_CLASS_D
, 0, rt
, rs
, 0);
19477 gen_farith(ctx
, OPC_ADD_S
, rt
, rs
, rd
, 0);
19480 gen_farith(ctx
, OPC_ADD_D
, rt
, rs
, rd
, 0);
19483 gen_farith(ctx
, OPC_SUB_S
, rt
, rs
, rd
, 0);
19486 gen_farith(ctx
, OPC_SUB_D
, rt
, rs
, rd
, 0);
19489 gen_farith(ctx
, OPC_MUL_S
, rt
, rs
, rd
, 0);
19492 gen_farith(ctx
, OPC_MUL_D
, rt
, rs
, rd
, 0);
19495 gen_farith(ctx
, OPC_DIV_S
, rt
, rs
, rd
, 0);
19498 gen_farith(ctx
, OPC_DIV_D
, rt
, rs
, rd
, 0);
19501 gen_sel_s(ctx
, OPC_SELEQZ_S
, rd
, rt
, rs
);
19504 gen_sel_d(ctx
, OPC_SELEQZ_D
, rd
, rt
, rs
);
19507 gen_sel_s(ctx
, OPC_SELNEZ_S
, rd
, rt
, rs
);
19510 gen_sel_d(ctx
, OPC_SELNEZ_D
, rd
, rt
, rs
);
19513 gen_sel_s(ctx
, OPC_SEL_S
, rd
, rt
, rs
);
19516 gen_sel_d(ctx
, OPC_SEL_D
, rd
, rt
, rs
);
19519 gen_farith(ctx
, OPC_MADDF_S
, rt
, rs
, rd
, 0);
19522 gen_farith(ctx
, OPC_MADDF_D
, rt
, rs
, rd
, 0);
19525 gen_farith(ctx
, OPC_MSUBF_S
, rt
, rs
, rd
, 0);
19528 gen_farith(ctx
, OPC_MSUBF_D
, rt
, rs
, rd
, 0);
19531 gen_reserved_instruction(ctx
);
19536 switch (extract32(ctx
->opcode
, 3, 3)) {
19538 switch (extract32(ctx
->opcode
, 9, 1)) {
19540 gen_farith(ctx
, OPC_MIN_S
, rt
, rs
, rd
, 0);
19543 gen_farith(ctx
, OPC_MIN_D
, rt
, rs
, rd
, 0);
19548 switch (extract32(ctx
->opcode
, 9, 1)) {
19550 gen_farith(ctx
, OPC_MAX_S
, rt
, rs
, rd
, 0);
19553 gen_farith(ctx
, OPC_MAX_D
, rt
, rs
, rd
, 0);
19558 switch (extract32(ctx
->opcode
, 9, 1)) {
19560 gen_farith(ctx
, OPC_MINA_S
, rt
, rs
, rd
, 0);
19563 gen_farith(ctx
, OPC_MINA_D
, rt
, rs
, rd
, 0);
19568 switch (extract32(ctx
->opcode
, 9, 1)) {
19570 gen_farith(ctx
, OPC_MAXA_S
, rt
, rs
, rd
, 0);
19573 gen_farith(ctx
, OPC_MAXA_D
, rt
, rs
, rd
, 0);
19578 switch (extract32(ctx
->opcode
, 6, 8)) {
19580 gen_cp1(ctx
, OPC_CFC1
, rt
, rs
);
19583 gen_cp1(ctx
, OPC_CTC1
, rt
, rs
);
19586 gen_cp1(ctx
, OPC_MFC1
, rt
, rs
);
19589 gen_cp1(ctx
, OPC_MTC1
, rt
, rs
);
19592 gen_cp1(ctx
, OPC_MFHC1
, rt
, rs
);
19595 gen_cp1(ctx
, OPC_MTHC1
, rt
, rs
);
19598 gen_farith(ctx
, OPC_CVT_S_PL
, -1, rs
, rt
, 0);
19601 gen_farith(ctx
, OPC_CVT_S_PU
, -1, rs
, rt
, 0);
19604 switch (extract32(ctx
->opcode
, 6, 9)) {
19606 gen_farith(ctx
, OPC_CVT_L_S
, -1, rs
, rt
, 0);
19609 gen_farith(ctx
, OPC_CVT_L_D
, -1, rs
, rt
, 0);
19612 gen_farith(ctx
, OPC_CVT_W_S
, -1, rs
, rt
, 0);
19615 gen_farith(ctx
, OPC_CVT_W_D
, -1, rs
, rt
, 0);
19618 gen_farith(ctx
, OPC_RSQRT_S
, -1, rs
, rt
, 0);
19621 gen_farith(ctx
, OPC_RSQRT_D
, -1, rs
, rt
, 0);
19624 gen_farith(ctx
, OPC_SQRT_S
, -1, rs
, rt
, 0);
19627 gen_farith(ctx
, OPC_SQRT_D
, -1, rs
, rt
, 0);
19630 gen_farith(ctx
, OPC_RECIP_S
, -1, rs
, rt
, 0);
19633 gen_farith(ctx
, OPC_RECIP_D
, -1, rs
, rt
, 0);
19636 gen_farith(ctx
, OPC_FLOOR_L_S
, -1, rs
, rt
, 0);
19639 gen_farith(ctx
, OPC_FLOOR_L_D
, -1, rs
, rt
, 0);
19642 gen_farith(ctx
, OPC_FLOOR_W_S
, -1, rs
, rt
, 0);
19645 gen_farith(ctx
, OPC_FLOOR_W_D
, -1, rs
, rt
, 0);
19648 gen_farith(ctx
, OPC_CEIL_L_S
, -1, rs
, rt
, 0);
19651 gen_farith(ctx
, OPC_CEIL_L_D
, -1, rs
, rt
, 0);
19654 gen_farith(ctx
, OPC_CEIL_W_S
, -1, rs
, rt
, 0);
19657 gen_farith(ctx
, OPC_CEIL_W_D
, -1, rs
, rt
, 0);
19660 gen_farith(ctx
, OPC_TRUNC_L_S
, -1, rs
, rt
, 0);
19663 gen_farith(ctx
, OPC_TRUNC_L_D
, -1, rs
, rt
, 0);
19666 gen_farith(ctx
, OPC_TRUNC_W_S
, -1, rs
, rt
, 0);
19669 gen_farith(ctx
, OPC_TRUNC_W_D
, -1, rs
, rt
, 0);
19672 gen_farith(ctx
, OPC_ROUND_L_S
, -1, rs
, rt
, 0);
19675 gen_farith(ctx
, OPC_ROUND_L_D
, -1, rs
, rt
, 0);
19678 gen_farith(ctx
, OPC_ROUND_W_S
, -1, rs
, rt
, 0);
19681 gen_farith(ctx
, OPC_ROUND_W_D
, -1, rs
, rt
, 0);
19684 gen_farith(ctx
, OPC_MOV_S
, -1, rs
, rt
, 0);
19687 gen_farith(ctx
, OPC_MOV_D
, -1, rs
, rt
, 0);
19690 gen_farith(ctx
, OPC_ABS_S
, -1, rs
, rt
, 0);
19693 gen_farith(ctx
, OPC_ABS_D
, -1, rs
, rt
, 0);
19696 gen_farith(ctx
, OPC_NEG_S
, -1, rs
, rt
, 0);
19699 gen_farith(ctx
, OPC_NEG_D
, -1, rs
, rt
, 0);
19702 gen_farith(ctx
, OPC_CVT_D_S
, -1, rs
, rt
, 0);
19705 gen_farith(ctx
, OPC_CVT_D_W
, -1, rs
, rt
, 0);
19708 gen_farith(ctx
, OPC_CVT_D_L
, -1, rs
, rt
, 0);
19711 gen_farith(ctx
, OPC_CVT_S_D
, -1, rs
, rt
, 0);
19714 gen_farith(ctx
, OPC_CVT_S_W
, -1, rs
, rt
, 0);
19717 gen_farith(ctx
, OPC_CVT_S_L
, -1, rs
, rt
, 0);
19720 gen_reserved_instruction(ctx
);
19729 switch (extract32(ctx
->opcode
, 3, 3)) {
19730 case NM_CMP_CONDN_S
:
19731 gen_r6_cmp_s(ctx
, extract32(ctx
->opcode
, 6, 5), rt
, rs
, rd
);
19733 case NM_CMP_CONDN_D
:
19734 gen_r6_cmp_d(ctx
, extract32(ctx
->opcode
, 6, 5), rt
, rs
, rd
);
19737 gen_reserved_instruction(ctx
);
19742 gen_reserved_instruction(ctx
);
19747 static void gen_pool32a5_nanomips_insn(DisasContext
*ctx
, int opc
,
19748 int rd
, int rs
, int rt
)
19751 TCGv t0
= tcg_temp_new();
19752 TCGv v1_t
= tcg_temp_new();
19753 TCGv v2_t
= tcg_temp_new();
19755 gen_load_gpr(v1_t
, rs
);
19756 gen_load_gpr(v2_t
, rt
);
19761 gen_helper_cmp_eq_ph(v1_t
, v2_t
, cpu_env
);
19765 gen_helper_cmp_lt_ph(v1_t
, v2_t
, cpu_env
);
19769 gen_helper_cmp_le_ph(v1_t
, v2_t
, cpu_env
);
19771 case NM_CMPU_EQ_QB
:
19773 gen_helper_cmpu_eq_qb(v1_t
, v2_t
, cpu_env
);
19775 case NM_CMPU_LT_QB
:
19777 gen_helper_cmpu_lt_qb(v1_t
, v2_t
, cpu_env
);
19779 case NM_CMPU_LE_QB
:
19781 gen_helper_cmpu_le_qb(v1_t
, v2_t
, cpu_env
);
19783 case NM_CMPGU_EQ_QB
:
19785 gen_helper_cmpgu_eq_qb(v1_t
, v1_t
, v2_t
);
19786 gen_store_gpr(v1_t
, ret
);
19788 case NM_CMPGU_LT_QB
:
19790 gen_helper_cmpgu_lt_qb(v1_t
, v1_t
, v2_t
);
19791 gen_store_gpr(v1_t
, ret
);
19793 case NM_CMPGU_LE_QB
:
19795 gen_helper_cmpgu_le_qb(v1_t
, v1_t
, v2_t
);
19796 gen_store_gpr(v1_t
, ret
);
19798 case NM_CMPGDU_EQ_QB
:
19800 gen_helper_cmpgu_eq_qb(v1_t
, v1_t
, v2_t
);
19801 tcg_gen_deposit_tl(cpu_dspctrl
, cpu_dspctrl
, v1_t
, 24, 4);
19802 gen_store_gpr(v1_t
, ret
);
19804 case NM_CMPGDU_LT_QB
:
19806 gen_helper_cmpgu_lt_qb(v1_t
, v1_t
, v2_t
);
19807 tcg_gen_deposit_tl(cpu_dspctrl
, cpu_dspctrl
, v1_t
, 24, 4);
19808 gen_store_gpr(v1_t
, ret
);
19810 case NM_CMPGDU_LE_QB
:
19812 gen_helper_cmpgu_le_qb(v1_t
, v1_t
, v2_t
);
19813 tcg_gen_deposit_tl(cpu_dspctrl
, cpu_dspctrl
, v1_t
, 24, 4);
19814 gen_store_gpr(v1_t
, ret
);
19818 gen_helper_packrl_ph(v1_t
, v1_t
, v2_t
);
19819 gen_store_gpr(v1_t
, ret
);
19823 gen_helper_pick_qb(v1_t
, v1_t
, v2_t
, cpu_env
);
19824 gen_store_gpr(v1_t
, ret
);
19828 gen_helper_pick_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
19829 gen_store_gpr(v1_t
, ret
);
19833 gen_helper_addq_s_w(v1_t
, v1_t
, v2_t
, cpu_env
);
19834 gen_store_gpr(v1_t
, ret
);
19838 gen_helper_subq_s_w(v1_t
, v1_t
, v2_t
, cpu_env
);
19839 gen_store_gpr(v1_t
, ret
);
19843 gen_helper_addsc(v1_t
, v1_t
, v2_t
, cpu_env
);
19844 gen_store_gpr(v1_t
, ret
);
19848 gen_helper_addwc(v1_t
, v1_t
, v2_t
, cpu_env
);
19849 gen_store_gpr(v1_t
, ret
);
19853 switch (extract32(ctx
->opcode
, 10, 1)) {
19856 gen_helper_addq_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
19857 gen_store_gpr(v1_t
, ret
);
19861 gen_helper_addq_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
19862 gen_store_gpr(v1_t
, ret
);
19866 case NM_ADDQH_R_PH
:
19868 switch (extract32(ctx
->opcode
, 10, 1)) {
19871 gen_helper_addqh_ph(v1_t
, v1_t
, v2_t
);
19872 gen_store_gpr(v1_t
, ret
);
19876 gen_helper_addqh_r_ph(v1_t
, v1_t
, v2_t
);
19877 gen_store_gpr(v1_t
, ret
);
19883 switch (extract32(ctx
->opcode
, 10, 1)) {
19886 gen_helper_addqh_w(v1_t
, v1_t
, v2_t
);
19887 gen_store_gpr(v1_t
, ret
);
19891 gen_helper_addqh_r_w(v1_t
, v1_t
, v2_t
);
19892 gen_store_gpr(v1_t
, ret
);
19898 switch (extract32(ctx
->opcode
, 10, 1)) {
19901 gen_helper_addu_qb(v1_t
, v1_t
, v2_t
, cpu_env
);
19902 gen_store_gpr(v1_t
, ret
);
19906 gen_helper_addu_s_qb(v1_t
, v1_t
, v2_t
, cpu_env
);
19907 gen_store_gpr(v1_t
, ret
);
19913 switch (extract32(ctx
->opcode
, 10, 1)) {
19916 gen_helper_addu_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
19917 gen_store_gpr(v1_t
, ret
);
19921 gen_helper_addu_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
19922 gen_store_gpr(v1_t
, ret
);
19926 case NM_ADDUH_R_QB
:
19928 switch (extract32(ctx
->opcode
, 10, 1)) {
19931 gen_helper_adduh_qb(v1_t
, v1_t
, v2_t
);
19932 gen_store_gpr(v1_t
, ret
);
19936 gen_helper_adduh_r_qb(v1_t
, v1_t
, v2_t
);
19937 gen_store_gpr(v1_t
, ret
);
19941 case NM_SHRAV_R_PH
:
19943 switch (extract32(ctx
->opcode
, 10, 1)) {
19946 gen_helper_shra_ph(v1_t
, v1_t
, v2_t
);
19947 gen_store_gpr(v1_t
, ret
);
19951 gen_helper_shra_r_ph(v1_t
, v1_t
, v2_t
);
19952 gen_store_gpr(v1_t
, ret
);
19956 case NM_SHRAV_R_QB
:
19958 switch (extract32(ctx
->opcode
, 10, 1)) {
19961 gen_helper_shra_qb(v1_t
, v1_t
, v2_t
);
19962 gen_store_gpr(v1_t
, ret
);
19966 gen_helper_shra_r_qb(v1_t
, v1_t
, v2_t
);
19967 gen_store_gpr(v1_t
, ret
);
19973 switch (extract32(ctx
->opcode
, 10, 1)) {
19976 gen_helper_subq_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
19977 gen_store_gpr(v1_t
, ret
);
19981 gen_helper_subq_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
19982 gen_store_gpr(v1_t
, ret
);
19986 case NM_SUBQH_R_PH
:
19988 switch (extract32(ctx
->opcode
, 10, 1)) {
19991 gen_helper_subqh_ph(v1_t
, v1_t
, v2_t
);
19992 gen_store_gpr(v1_t
, ret
);
19996 gen_helper_subqh_r_ph(v1_t
, v1_t
, v2_t
);
19997 gen_store_gpr(v1_t
, ret
);
20003 switch (extract32(ctx
->opcode
, 10, 1)) {
20006 gen_helper_subqh_w(v1_t
, v1_t
, v2_t
);
20007 gen_store_gpr(v1_t
, ret
);
20011 gen_helper_subqh_r_w(v1_t
, v1_t
, v2_t
);
20012 gen_store_gpr(v1_t
, ret
);
20018 switch (extract32(ctx
->opcode
, 10, 1)) {
20021 gen_helper_subu_qb(v1_t
, v1_t
, v2_t
, cpu_env
);
20022 gen_store_gpr(v1_t
, ret
);
20026 gen_helper_subu_s_qb(v1_t
, v1_t
, v2_t
, cpu_env
);
20027 gen_store_gpr(v1_t
, ret
);
20033 switch (extract32(ctx
->opcode
, 10, 1)) {
20036 gen_helper_subu_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20037 gen_store_gpr(v1_t
, ret
);
20041 gen_helper_subu_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20042 gen_store_gpr(v1_t
, ret
);
20046 case NM_SUBUH_R_QB
:
20048 switch (extract32(ctx
->opcode
, 10, 1)) {
20051 gen_helper_subuh_qb(v1_t
, v1_t
, v2_t
);
20052 gen_store_gpr(v1_t
, ret
);
20056 gen_helper_subuh_r_qb(v1_t
, v1_t
, v2_t
);
20057 gen_store_gpr(v1_t
, ret
);
20061 case NM_SHLLV_S_PH
:
20063 switch (extract32(ctx
->opcode
, 10, 1)) {
20066 gen_helper_shll_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20067 gen_store_gpr(v1_t
, ret
);
20071 gen_helper_shll_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20072 gen_store_gpr(v1_t
, ret
);
20076 case NM_PRECR_SRA_R_PH_W
:
20078 switch (extract32(ctx
->opcode
, 10, 1)) {
20080 /* PRECR_SRA_PH_W */
20082 TCGv_i32 sa_t
= tcg_const_i32(rd
);
20083 gen_helper_precr_sra_ph_w(v1_t
, sa_t
, v1_t
,
20085 gen_store_gpr(v1_t
, rt
);
20086 tcg_temp_free_i32(sa_t
);
20090 /* PRECR_SRA_R_PH_W */
20092 TCGv_i32 sa_t
= tcg_const_i32(rd
);
20093 gen_helper_precr_sra_r_ph_w(v1_t
, sa_t
, v1_t
,
20095 gen_store_gpr(v1_t
, rt
);
20096 tcg_temp_free_i32(sa_t
);
20101 case NM_MULEU_S_PH_QBL
:
20103 gen_helper_muleu_s_ph_qbl(v1_t
, v1_t
, v2_t
, cpu_env
);
20104 gen_store_gpr(v1_t
, ret
);
20106 case NM_MULEU_S_PH_QBR
:
20108 gen_helper_muleu_s_ph_qbr(v1_t
, v1_t
, v2_t
, cpu_env
);
20109 gen_store_gpr(v1_t
, ret
);
20111 case NM_MULQ_RS_PH
:
20113 gen_helper_mulq_rs_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20114 gen_store_gpr(v1_t
, ret
);
20118 gen_helper_mulq_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20119 gen_store_gpr(v1_t
, ret
);
20123 gen_helper_mulq_rs_w(v1_t
, v1_t
, v2_t
, cpu_env
);
20124 gen_store_gpr(v1_t
, ret
);
20128 gen_helper_mulq_s_w(v1_t
, v1_t
, v2_t
, cpu_env
);
20129 gen_store_gpr(v1_t
, ret
);
20133 gen_load_gpr(t0
, rs
);
20135 tcg_gen_deposit_tl(cpu_gpr
[rt
], t0
, cpu_gpr
[rt
], rd
, 32 - rd
);
20137 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
20141 gen_helper_modsub(v1_t
, v1_t
, v2_t
);
20142 gen_store_gpr(v1_t
, ret
);
20146 gen_helper_shra_r_w(v1_t
, v1_t
, v2_t
);
20147 gen_store_gpr(v1_t
, ret
);
20151 gen_helper_shrl_ph(v1_t
, v1_t
, v2_t
);
20152 gen_store_gpr(v1_t
, ret
);
20156 gen_helper_shrl_qb(v1_t
, v1_t
, v2_t
);
20157 gen_store_gpr(v1_t
, ret
);
20161 gen_helper_shll_qb(v1_t
, v1_t
, v2_t
, cpu_env
);
20162 gen_store_gpr(v1_t
, ret
);
20166 gen_helper_shll_s_w(v1_t
, v1_t
, v2_t
, cpu_env
);
20167 gen_store_gpr(v1_t
, ret
);
20172 TCGv tv0
= tcg_temp_new();
20173 TCGv tv1
= tcg_temp_new();
20174 int16_t imm
= extract32(ctx
->opcode
, 16, 7);
20176 tcg_gen_movi_tl(tv0
, rd
>> 3);
20177 tcg_gen_movi_tl(tv1
, imm
);
20178 gen_helper_shilo(tv0
, tv1
, cpu_env
);
20181 case NM_MULEQ_S_W_PHL
:
20183 gen_helper_muleq_s_w_phl(v1_t
, v1_t
, v2_t
, cpu_env
);
20184 gen_store_gpr(v1_t
, ret
);
20186 case NM_MULEQ_S_W_PHR
:
20188 gen_helper_muleq_s_w_phr(v1_t
, v1_t
, v2_t
, cpu_env
);
20189 gen_store_gpr(v1_t
, ret
);
20193 switch (extract32(ctx
->opcode
, 10, 1)) {
20196 gen_helper_mul_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20197 gen_store_gpr(v1_t
, ret
);
20201 gen_helper_mul_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20202 gen_store_gpr(v1_t
, ret
);
20206 case NM_PRECR_QB_PH
:
20208 gen_helper_precr_qb_ph(v1_t
, v1_t
, v2_t
);
20209 gen_store_gpr(v1_t
, ret
);
20211 case NM_PRECRQ_QB_PH
:
20213 gen_helper_precrq_qb_ph(v1_t
, v1_t
, v2_t
);
20214 gen_store_gpr(v1_t
, ret
);
20216 case NM_PRECRQ_PH_W
:
20218 gen_helper_precrq_ph_w(v1_t
, v1_t
, v2_t
);
20219 gen_store_gpr(v1_t
, ret
);
20221 case NM_PRECRQ_RS_PH_W
:
20223 gen_helper_precrq_rs_ph_w(v1_t
, v1_t
, v2_t
, cpu_env
);
20224 gen_store_gpr(v1_t
, ret
);
20226 case NM_PRECRQU_S_QB_PH
:
20228 gen_helper_precrqu_s_qb_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20229 gen_store_gpr(v1_t
, ret
);
20233 tcg_gen_movi_tl(t0
, rd
);
20234 gen_helper_shra_r_w(v1_t
, t0
, v1_t
);
20235 gen_store_gpr(v1_t
, rt
);
20239 tcg_gen_movi_tl(t0
, rd
>> 1);
20240 switch (extract32(ctx
->opcode
, 10, 1)) {
20243 gen_helper_shra_ph(v1_t
, t0
, v1_t
);
20244 gen_store_gpr(v1_t
, rt
);
20248 gen_helper_shra_r_ph(v1_t
, t0
, v1_t
);
20249 gen_store_gpr(v1_t
, rt
);
20255 tcg_gen_movi_tl(t0
, rd
>> 1);
20256 switch (extract32(ctx
->opcode
, 10, 2)) {
20259 gen_helper_shll_ph(v1_t
, t0
, v1_t
, cpu_env
);
20260 gen_store_gpr(v1_t
, rt
);
20264 gen_helper_shll_s_ph(v1_t
, t0
, v1_t
, cpu_env
);
20265 gen_store_gpr(v1_t
, rt
);
20268 gen_reserved_instruction(ctx
);
20274 tcg_gen_movi_tl(t0
, rd
);
20275 gen_helper_shll_s_w(v1_t
, t0
, v1_t
, cpu_env
);
20276 gen_store_gpr(v1_t
, rt
);
20282 imm
= sextract32(ctx
->opcode
, 11, 11);
20283 imm
= (int16_t)(imm
<< 6) >> 6;
20285 tcg_gen_movi_tl(cpu_gpr
[rt
], dup_const(MO_16
, imm
));
20290 gen_reserved_instruction(ctx
);
20295 static int decode_nanomips_32_48_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
20303 insn
= translator_lduw(env
, ctx
->base
.pc_next
+ 2);
20304 ctx
->opcode
= (ctx
->opcode
<< 16) | insn
;
20306 rt
= extract32(ctx
->opcode
, 21, 5);
20307 rs
= extract32(ctx
->opcode
, 16, 5);
20308 rd
= extract32(ctx
->opcode
, 11, 5);
20310 op
= extract32(ctx
->opcode
, 26, 6);
20315 switch (extract32(ctx
->opcode
, 19, 2)) {
20318 gen_reserved_instruction(ctx
);
20321 if ((extract32(ctx
->opcode
, 18, 1)) == NM_SYSCALL
) {
20322 generate_exception_end(ctx
, EXCP_SYSCALL
);
20324 gen_reserved_instruction(ctx
);
20328 generate_exception_end(ctx
, EXCP_BREAK
);
20331 if (is_uhi(extract32(ctx
->opcode
, 0, 19))) {
20332 gen_helper_do_semihosting(cpu_env
);
20334 if (ctx
->hflags
& MIPS_HFLAG_SBRI
) {
20335 gen_reserved_instruction(ctx
);
20337 generate_exception_end(ctx
, EXCP_DBp
);
20344 imm
= extract32(ctx
->opcode
, 0, 16);
20346 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], imm
);
20348 tcg_gen_movi_tl(cpu_gpr
[rt
], imm
);
20350 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
20355 offset
= sextract32(ctx
->opcode
, 0, 1) << 21 |
20356 extract32(ctx
->opcode
, 1, 20) << 1;
20357 target_long addr
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
20358 tcg_gen_movi_tl(cpu_gpr
[rt
], addr
);
20362 switch (ctx
->opcode
& 0x07) {
20364 gen_pool32a0_nanomips_insn(env
, ctx
);
20368 int32_t op1
= extract32(ctx
->opcode
, 3, 7);
20369 gen_pool32a5_nanomips_insn(ctx
, op1
, rd
, rs
, rt
);
20373 switch (extract32(ctx
->opcode
, 3, 3)) {
20375 gen_p_lsx(ctx
, rd
, rs
, rt
);
20379 * In nanoMIPS, the shift field directly encodes the shift
20380 * amount, meaning that the supported shift values are in
20381 * the range 0 to 3 (instead of 1 to 4 in MIPSR6).
20383 gen_lsa(ctx
, rd
, rt
, rs
, extract32(ctx
->opcode
, 9, 2) - 1);
20386 gen_ext(ctx
, 32, rd
, rs
, rt
, extract32(ctx
->opcode
, 6, 5));
20389 gen_pool32axf_nanomips_insn(env
, ctx
);
20392 gen_reserved_instruction(ctx
);
20397 gen_reserved_instruction(ctx
);
20402 switch (ctx
->opcode
& 0x03) {
20405 offset
= extract32(ctx
->opcode
, 0, 21);
20406 gen_op_addr_addi(ctx
, cpu_gpr
[rt
], cpu_gpr
[28], offset
);
20410 gen_ld(ctx
, OPC_LW
, rt
, 28, extract32(ctx
->opcode
, 2, 19) << 2);
20413 gen_st(ctx
, OPC_SW
, rt
, 28, extract32(ctx
->opcode
, 2, 19) << 2);
20416 gen_reserved_instruction(ctx
);
20422 insn
= translator_lduw(env
, ctx
->base
.pc_next
+ 4);
20423 target_long addr_off
= extract32(ctx
->opcode
, 0, 16) | insn
<< 16;
20424 switch (extract32(ctx
->opcode
, 16, 5)) {
20428 tcg_gen_movi_tl(cpu_gpr
[rt
], addr_off
);
20434 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], addr_off
);
20435 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
20441 gen_op_addr_addi(ctx
, cpu_gpr
[rt
], cpu_gpr
[28], addr_off
);
20447 target_long addr
= addr_add(ctx
, ctx
->base
.pc_next
+ 6,
20450 tcg_gen_movi_tl(cpu_gpr
[rt
], addr
);
20457 t0
= tcg_temp_new();
20459 target_long addr
= addr_add(ctx
, ctx
->base
.pc_next
+ 6,
20462 tcg_gen_movi_tl(t0
, addr
);
20463 tcg_gen_qemu_ld_tl(cpu_gpr
[rt
], t0
, ctx
->mem_idx
, MO_TESL
);
20471 t0
= tcg_temp_new();
20472 t1
= tcg_temp_new();
20474 target_long addr
= addr_add(ctx
, ctx
->base
.pc_next
+ 6,
20477 tcg_gen_movi_tl(t0
, addr
);
20478 gen_load_gpr(t1
, rt
);
20480 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
20487 gen_reserved_instruction(ctx
);
20493 switch (extract32(ctx
->opcode
, 12, 4)) {
20495 gen_logic_imm(ctx
, OPC_ORI
, rt
, rs
, extract32(ctx
->opcode
, 0, 12));
20498 gen_logic_imm(ctx
, OPC_XORI
, rt
, rs
, extract32(ctx
->opcode
, 0, 12));
20501 gen_logic_imm(ctx
, OPC_ANDI
, rt
, rs
, extract32(ctx
->opcode
, 0, 12));
20504 switch (extract32(ctx
->opcode
, 20, 1)) {
20506 switch (ctx
->opcode
& 3) {
20508 gen_save(ctx
, rt
, extract32(ctx
->opcode
, 16, 4),
20509 extract32(ctx
->opcode
, 2, 1),
20510 extract32(ctx
->opcode
, 3, 9) << 3);
20513 case NM_RESTORE_JRC
:
20514 gen_restore(ctx
, rt
, extract32(ctx
->opcode
, 16, 4),
20515 extract32(ctx
->opcode
, 2, 1),
20516 extract32(ctx
->opcode
, 3, 9) << 3);
20517 if ((ctx
->opcode
& 3) == NM_RESTORE_JRC
) {
20518 gen_compute_branch_nm(ctx
, OPC_JR
, 2, 31, 0, 0);
20522 gen_reserved_instruction(ctx
);
20527 gen_reserved_instruction(ctx
);
20532 gen_slt_imm(ctx
, OPC_SLTI
, rt
, rs
, extract32(ctx
->opcode
, 0, 12));
20535 gen_slt_imm(ctx
, OPC_SLTIU
, rt
, rs
, extract32(ctx
->opcode
, 0, 12));
20539 TCGv t0
= tcg_temp_new();
20541 imm
= extract32(ctx
->opcode
, 0, 12);
20542 gen_load_gpr(t0
, rs
);
20543 tcg_gen_setcondi_tl(TCG_COND_EQ
, t0
, t0
, imm
);
20544 gen_store_gpr(t0
, rt
);
20550 imm
= (int16_t) extract32(ctx
->opcode
, 0, 12);
20551 gen_arith_imm(ctx
, OPC_ADDIU
, rt
, rs
, -imm
);
20555 int shift
= extract32(ctx
->opcode
, 0, 5);
20556 switch (extract32(ctx
->opcode
, 5, 4)) {
20558 if (rt
== 0 && shift
== 0) {
20560 } else if (rt
== 0 && shift
== 3) {
20561 /* EHB - treat as NOP */
20562 } else if (rt
== 0 && shift
== 5) {
20563 /* PAUSE - treat as NOP */
20564 } else if (rt
== 0 && shift
== 6) {
20566 gen_sync(extract32(ctx
->opcode
, 16, 5));
20569 gen_shift_imm(ctx
, OPC_SLL
, rt
, rs
,
20570 extract32(ctx
->opcode
, 0, 5));
20574 gen_shift_imm(ctx
, OPC_SRL
, rt
, rs
,
20575 extract32(ctx
->opcode
, 0, 5));
20578 gen_shift_imm(ctx
, OPC_SRA
, rt
, rs
,
20579 extract32(ctx
->opcode
, 0, 5));
20582 gen_shift_imm(ctx
, OPC_ROTR
, rt
, rs
,
20583 extract32(ctx
->opcode
, 0, 5));
20591 TCGv t0
= tcg_temp_new();
20592 TCGv_i32 shift
= tcg_const_i32(extract32(ctx
->opcode
, 0, 5));
20593 TCGv_i32 shiftx
= tcg_const_i32(extract32(ctx
->opcode
, 7, 4)
20595 TCGv_i32 stripe
= tcg_const_i32(extract32(ctx
->opcode
, 6, 1));
20597 gen_load_gpr(t0
, rs
);
20598 gen_helper_rotx(cpu_gpr
[rt
], t0
, shift
, shiftx
, stripe
);
20601 tcg_temp_free_i32(shift
);
20602 tcg_temp_free_i32(shiftx
);
20603 tcg_temp_free_i32(stripe
);
20607 switch (((ctx
->opcode
>> 10) & 2) |
20608 (extract32(ctx
->opcode
, 5, 1))) {
20611 gen_bitops(ctx
, OPC_INS
, rt
, rs
, extract32(ctx
->opcode
, 0, 5),
20612 extract32(ctx
->opcode
, 6, 5));
20615 gen_reserved_instruction(ctx
);
20620 switch (((ctx
->opcode
>> 10) & 2) |
20621 (extract32(ctx
->opcode
, 5, 1))) {
20624 gen_bitops(ctx
, OPC_EXT
, rt
, rs
, extract32(ctx
->opcode
, 0, 5),
20625 extract32(ctx
->opcode
, 6, 5));
20628 gen_reserved_instruction(ctx
);
20633 gen_reserved_instruction(ctx
);
20638 gen_pool32f_nanomips_insn(ctx
);
20643 switch (extract32(ctx
->opcode
, 1, 1)) {
20646 tcg_gen_movi_tl(cpu_gpr
[rt
],
20647 sextract32(ctx
->opcode
, 0, 1) << 31 |
20648 extract32(ctx
->opcode
, 2, 10) << 21 |
20649 extract32(ctx
->opcode
, 12, 9) << 12);
20654 offset
= sextract32(ctx
->opcode
, 0, 1) << 31 |
20655 extract32(ctx
->opcode
, 2, 10) << 21 |
20656 extract32(ctx
->opcode
, 12, 9) << 12;
20658 addr
= ~0xFFF & addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
20659 tcg_gen_movi_tl(cpu_gpr
[rt
], addr
);
20666 uint32_t u
= extract32(ctx
->opcode
, 0, 18);
20668 switch (extract32(ctx
->opcode
, 18, 3)) {
20670 gen_ld(ctx
, OPC_LB
, rt
, 28, u
);
20673 gen_st(ctx
, OPC_SB
, rt
, 28, u
);
20676 gen_ld(ctx
, OPC_LBU
, rt
, 28, u
);
20680 gen_op_addr_addi(ctx
, cpu_gpr
[rt
], cpu_gpr
[28], u
);
20685 switch (ctx
->opcode
& 1) {
20687 gen_ld(ctx
, OPC_LH
, rt
, 28, u
);
20690 gen_ld(ctx
, OPC_LHU
, rt
, 28, u
);
20696 switch (ctx
->opcode
& 1) {
20698 gen_st(ctx
, OPC_SH
, rt
, 28, u
);
20701 gen_reserved_instruction(ctx
);
20707 switch (ctx
->opcode
& 0x3) {
20709 gen_cop1_ldst(ctx
, OPC_LWC1
, rt
, 28, u
);
20712 gen_cop1_ldst(ctx
, OPC_LDC1
, rt
, 28, u
);
20715 gen_cop1_ldst(ctx
, OPC_SWC1
, rt
, 28, u
);
20718 gen_cop1_ldst(ctx
, OPC_SDC1
, rt
, 28, u
);
20723 gen_reserved_instruction(ctx
);
20730 uint32_t u
= extract32(ctx
->opcode
, 0, 12);
20732 switch (extract32(ctx
->opcode
, 12, 4)) {
20737 * Break the TB to be able to sync copied instructions
20740 ctx
->base
.is_jmp
= DISAS_STOP
;
20743 /* Treat as NOP. */
20747 gen_ld(ctx
, OPC_LB
, rt
, rs
, u
);
20750 gen_ld(ctx
, OPC_LH
, rt
, rs
, u
);
20753 gen_ld(ctx
, OPC_LW
, rt
, rs
, u
);
20756 gen_ld(ctx
, OPC_LBU
, rt
, rs
, u
);
20759 gen_ld(ctx
, OPC_LHU
, rt
, rs
, u
);
20762 gen_st(ctx
, OPC_SB
, rt
, rs
, u
);
20765 gen_st(ctx
, OPC_SH
, rt
, rs
, u
);
20768 gen_st(ctx
, OPC_SW
, rt
, rs
, u
);
20771 gen_cop1_ldst(ctx
, OPC_LWC1
, rt
, rs
, u
);
20774 gen_cop1_ldst(ctx
, OPC_LDC1
, rt
, rs
, u
);
20777 gen_cop1_ldst(ctx
, OPC_SWC1
, rt
, rs
, u
);
20780 gen_cop1_ldst(ctx
, OPC_SDC1
, rt
, rs
, u
);
20783 gen_reserved_instruction(ctx
);
20790 int32_t s
= (sextract32(ctx
->opcode
, 15, 1) << 8) |
20791 extract32(ctx
->opcode
, 0, 8);
20793 switch (extract32(ctx
->opcode
, 8, 3)) {
20795 switch (extract32(ctx
->opcode
, 11, 4)) {
20797 gen_ld(ctx
, OPC_LB
, rt
, rs
, s
);
20800 gen_ld(ctx
, OPC_LH
, rt
, rs
, s
);
20803 gen_ld(ctx
, OPC_LW
, rt
, rs
, s
);
20806 gen_ld(ctx
, OPC_LBU
, rt
, rs
, s
);
20809 gen_ld(ctx
, OPC_LHU
, rt
, rs
, s
);
20812 gen_st(ctx
, OPC_SB
, rt
, rs
, s
);
20815 gen_st(ctx
, OPC_SH
, rt
, rs
, s
);
20818 gen_st(ctx
, OPC_SW
, rt
, rs
, s
);
20821 gen_cop1_ldst(ctx
, OPC_LWC1
, rt
, rs
, s
);
20824 gen_cop1_ldst(ctx
, OPC_LDC1
, rt
, rs
, s
);
20827 gen_cop1_ldst(ctx
, OPC_SWC1
, rt
, rs
, s
);
20830 gen_cop1_ldst(ctx
, OPC_SDC1
, rt
, rs
, s
);
20836 * Break the TB to be able to sync copied instructions
20839 ctx
->base
.is_jmp
= DISAS_STOP
;
20842 /* Treat as NOP. */
20846 gen_reserved_instruction(ctx
);
20851 switch (extract32(ctx
->opcode
, 11, 4)) {
20856 TCGv t0
= tcg_temp_new();
20857 TCGv t1
= tcg_temp_new();
20859 gen_base_offset_addr(ctx
, t0
, rs
, s
);
20861 switch (extract32(ctx
->opcode
, 11, 4)) {
20863 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESW
|
20865 gen_store_gpr(t0
, rt
);
20868 gen_load_gpr(t1
, rt
);
20869 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUW
|
20878 switch (ctx
->opcode
& 0x03) {
20880 gen_ld(ctx
, OPC_LL
, rt
, rs
, s
);
20884 gen_llwp(ctx
, rs
, 0, rt
, extract32(ctx
->opcode
, 3, 5));
20889 switch (ctx
->opcode
& 0x03) {
20891 gen_st_cond(ctx
, rt
, rs
, s
, MO_TESL
, false);
20895 gen_scwp(ctx
, rs
, 0, rt
, extract32(ctx
->opcode
, 3, 5),
20901 check_cp0_enabled(ctx
);
20902 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
20903 gen_cache_operation(ctx
, rt
, rs
, s
);
20909 switch (extract32(ctx
->opcode
, 11, 4)) {
20912 check_cp0_enabled(ctx
);
20913 gen_ld(ctx
, OPC_LBE
, rt
, rs
, s
);
20917 check_cp0_enabled(ctx
);
20918 gen_st(ctx
, OPC_SBE
, rt
, rs
, s
);
20922 check_cp0_enabled(ctx
);
20923 gen_ld(ctx
, OPC_LBUE
, rt
, rs
, s
);
20927 /* case NM_SYNCIE */
20929 check_cp0_enabled(ctx
);
20931 * Break the TB to be able to sync copied instructions
20934 ctx
->base
.is_jmp
= DISAS_STOP
;
20936 /* case NM_PREFE */
20938 check_cp0_enabled(ctx
);
20939 /* Treat as NOP. */
20944 check_cp0_enabled(ctx
);
20945 gen_ld(ctx
, OPC_LHE
, rt
, rs
, s
);
20949 check_cp0_enabled(ctx
);
20950 gen_st(ctx
, OPC_SHE
, rt
, rs
, s
);
20954 check_cp0_enabled(ctx
);
20955 gen_ld(ctx
, OPC_LHUE
, rt
, rs
, s
);
20958 check_nms_dl_il_sl_tl_l2c(ctx
);
20959 gen_cache_operation(ctx
, rt
, rs
, s
);
20963 check_cp0_enabled(ctx
);
20964 gen_ld(ctx
, OPC_LWE
, rt
, rs
, s
);
20968 check_cp0_enabled(ctx
);
20969 gen_st(ctx
, OPC_SWE
, rt
, rs
, s
);
20972 switch (extract32(ctx
->opcode
, 2, 2)) {
20976 check_cp0_enabled(ctx
);
20977 gen_ld(ctx
, OPC_LLE
, rt
, rs
, s
);
20982 check_cp0_enabled(ctx
);
20983 gen_llwp(ctx
, rs
, 0, rt
, extract32(ctx
->opcode
, 3, 5));
20986 gen_reserved_instruction(ctx
);
20991 switch (extract32(ctx
->opcode
, 2, 2)) {
20995 check_cp0_enabled(ctx
);
20996 gen_st_cond(ctx
, rt
, rs
, s
, MO_TESL
, true);
21001 check_cp0_enabled(ctx
);
21002 gen_scwp(ctx
, rs
, 0, rt
, extract32(ctx
->opcode
, 3, 5),
21006 gen_reserved_instruction(ctx
);
21016 int count
= extract32(ctx
->opcode
, 12, 3);
21019 offset
= sextract32(ctx
->opcode
, 15, 1) << 8 |
21020 extract32(ctx
->opcode
, 0, 8);
21021 TCGv va
= tcg_temp_new();
21022 TCGv t1
= tcg_temp_new();
21023 MemOp memop
= (extract32(ctx
->opcode
, 8, 3)) ==
21024 NM_P_LS_UAWM
? MO_UNALN
: 0;
21026 count
= (count
== 0) ? 8 : count
;
21027 while (counter
!= count
) {
21028 int this_rt
= ((rt
+ counter
) & 0x1f) | (rt
& 0x10);
21029 int this_offset
= offset
+ (counter
<< 2);
21031 gen_base_offset_addr(ctx
, va
, rs
, this_offset
);
21033 switch (extract32(ctx
->opcode
, 11, 1)) {
21035 tcg_gen_qemu_ld_tl(t1
, va
, ctx
->mem_idx
,
21037 gen_store_gpr(t1
, this_rt
);
21038 if ((this_rt
== rs
) &&
21039 (counter
!= (count
- 1))) {
21040 /* UNPREDICTABLE */
21044 this_rt
= (rt
== 0) ? 0 : this_rt
;
21045 gen_load_gpr(t1
, this_rt
);
21046 tcg_gen_qemu_st_tl(t1
, va
, ctx
->mem_idx
,
21057 gen_reserved_instruction(ctx
);
21065 TCGv t0
= tcg_temp_new();
21066 int32_t s
= sextract32(ctx
->opcode
, 0, 1) << 21 |
21067 extract32(ctx
->opcode
, 1, 20) << 1;
21068 rd
= (extract32(ctx
->opcode
, 24, 1)) == 0 ? 4 : 5;
21069 rt
= decode_gpr_gpr4_zero(extract32(ctx
->opcode
, 25, 1) << 3 |
21070 extract32(ctx
->opcode
, 21, 3));
21071 gen_load_gpr(t0
, rt
);
21072 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
21073 gen_compute_branch_nm(ctx
, OPC_BGEZAL
, 4, 0, 0, s
);
21079 int32_t s
= sextract32(ctx
->opcode
, 0, 1) << 25 |
21080 extract32(ctx
->opcode
, 1, 24) << 1;
21082 if ((extract32(ctx
->opcode
, 25, 1)) == 0) {
21084 gen_compute_branch_nm(ctx
, OPC_BEQ
, 4, 0, 0, s
);
21087 gen_compute_branch_nm(ctx
, OPC_BGEZAL
, 4, 0, 0, s
);
21092 switch (extract32(ctx
->opcode
, 12, 4)) {
21095 gen_compute_branch_nm(ctx
, OPC_JALR
, 4, rs
, rt
, 0);
21098 gen_compute_nanomips_pbalrsc_branch(ctx
, rs
, rt
);
21101 gen_reserved_instruction(ctx
);
21107 int32_t s
= sextract32(ctx
->opcode
, 0, 1) << 14 |
21108 extract32(ctx
->opcode
, 1, 13) << 1;
21109 switch (extract32(ctx
->opcode
, 14, 2)) {
21112 gen_compute_branch_nm(ctx
, OPC_BEQ
, 4, rs
, rt
, s
);
21115 s
= sextract32(ctx
->opcode
, 0, 1) << 14 |
21116 extract32(ctx
->opcode
, 1, 13) << 1;
21117 check_cp1_enabled(ctx
);
21118 switch (extract32(ctx
->opcode
, 16, 5)) {
21120 gen_compute_branch_cp1_nm(ctx
, OPC_BC1EQZ
, rt
, s
);
21123 gen_compute_branch_cp1_nm(ctx
, OPC_BC1NEZ
, rt
, s
);
21128 int32_t imm
= extract32(ctx
->opcode
, 1, 13) |
21129 extract32(ctx
->opcode
, 0, 1) << 13;
21131 gen_compute_branch_nm(ctx
, OPC_BPOSGE32
, 4, -1, -2,
21136 gen_reserved_instruction(ctx
);
21142 gen_compute_compact_branch_nm(ctx
, OPC_BC
, rs
, rt
, s
);
21144 gen_compute_compact_branch_nm(ctx
, OPC_BGEC
, rs
, rt
, s
);
21148 if (rs
== rt
|| rt
== 0) {
21149 gen_compute_compact_branch_nm(ctx
, OPC_BC
, 0, 0, s
);
21150 } else if (rs
== 0) {
21151 gen_compute_compact_branch_nm(ctx
, OPC_BEQZC
, rt
, 0, s
);
21153 gen_compute_compact_branch_nm(ctx
, OPC_BGEUC
, rs
, rt
, s
);
21161 int32_t s
= sextract32(ctx
->opcode
, 0, 1) << 14 |
21162 extract32(ctx
->opcode
, 1, 13) << 1;
21163 switch (extract32(ctx
->opcode
, 14, 2)) {
21166 gen_compute_branch_nm(ctx
, OPC_BNE
, 4, rs
, rt
, s
);
21169 if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
21171 ctx
->hflags
|= MIPS_HFLAG_FBNSLOT
;
21173 gen_compute_compact_branch_nm(ctx
, OPC_BLTC
, rs
, rt
, s
);
21177 if (rs
== 0 || rs
== rt
) {
21179 ctx
->hflags
|= MIPS_HFLAG_FBNSLOT
;
21181 gen_compute_compact_branch_nm(ctx
, OPC_BLTUC
, rs
, rt
, s
);
21185 gen_reserved_instruction(ctx
);
21192 int32_t s
= sextract32(ctx
->opcode
, 0, 1) << 11 |
21193 extract32(ctx
->opcode
, 1, 10) << 1;
21194 uint32_t u
= extract32(ctx
->opcode
, 11, 7);
21196 gen_compute_imm_branch(ctx
, extract32(ctx
->opcode
, 18, 3),
21201 gen_reserved_instruction(ctx
);
21207 static int decode_nanomips_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
21210 int rt
= decode_gpr_gpr3(NANOMIPS_EXTRACT_RT3(ctx
->opcode
));
21211 int rs
= decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx
->opcode
));
21212 int rd
= decode_gpr_gpr3(NANOMIPS_EXTRACT_RD3(ctx
->opcode
));
21216 /* make sure instructions are on a halfword boundary */
21217 if (ctx
->base
.pc_next
& 0x1) {
21218 TCGv tmp
= tcg_const_tl(ctx
->base
.pc_next
);
21219 tcg_gen_st_tl(tmp
, cpu_env
, offsetof(CPUMIPSState
, CP0_BadVAddr
));
21220 tcg_temp_free(tmp
);
21221 generate_exception_end(ctx
, EXCP_AdEL
);
21225 op
= extract32(ctx
->opcode
, 10, 6);
21228 rt
= NANOMIPS_EXTRACT_RD5(ctx
->opcode
);
21231 rs
= NANOMIPS_EXTRACT_RS5(ctx
->opcode
);
21232 gen_arith(ctx
, OPC_ADDU
, rt
, rs
, 0);
21235 switch (extract32(ctx
->opcode
, 3, 2)) {
21236 case NM_P16_SYSCALL
:
21237 if (extract32(ctx
->opcode
, 2, 1) == 0) {
21238 generate_exception_end(ctx
, EXCP_SYSCALL
);
21240 gen_reserved_instruction(ctx
);
21244 generate_exception_end(ctx
, EXCP_BREAK
);
21247 if (is_uhi(extract32(ctx
->opcode
, 0, 3))) {
21248 gen_helper_do_semihosting(cpu_env
);
21250 if (ctx
->hflags
& MIPS_HFLAG_SBRI
) {
21251 gen_reserved_instruction(ctx
);
21253 generate_exception_end(ctx
, EXCP_DBp
);
21258 gen_reserved_instruction(ctx
);
21265 int shift
= extract32(ctx
->opcode
, 0, 3);
21267 shift
= (shift
== 0) ? 8 : shift
;
21269 switch (extract32(ctx
->opcode
, 3, 1)) {
21277 gen_shift_imm(ctx
, opc
, rt
, rs
, shift
);
21281 switch (ctx
->opcode
& 1) {
21283 gen_pool16c_nanomips_insn(ctx
);
21286 gen_ldxs(ctx
, rt
, rs
, rd
);
21291 switch (extract32(ctx
->opcode
, 6, 1)) {
21293 imm
= extract32(ctx
->opcode
, 0, 6) << 2;
21294 gen_arith_imm(ctx
, OPC_ADDIU
, rt
, 29, imm
);
21297 gen_reserved_instruction(ctx
);
21302 switch (extract32(ctx
->opcode
, 3, 1)) {
21304 imm
= extract32(ctx
->opcode
, 0, 3) << 2;
21305 gen_arith_imm(ctx
, OPC_ADDIU
, rt
, rs
, imm
);
21307 case NM_P_ADDIURS5
:
21308 rt
= extract32(ctx
->opcode
, 5, 5);
21310 /* imm = sign_extend(s[3] . s[2:0] , from_nbits = 4) */
21311 imm
= (sextract32(ctx
->opcode
, 4, 1) << 3) |
21312 (extract32(ctx
->opcode
, 0, 3));
21313 gen_arith_imm(ctx
, OPC_ADDIU
, rt
, rt
, imm
);
21319 switch (ctx
->opcode
& 0x1) {
21321 gen_arith(ctx
, OPC_ADDU
, rd
, rs
, rt
);
21324 gen_arith(ctx
, OPC_SUBU
, rd
, rs
, rt
);
21329 rt
= (extract32(ctx
->opcode
, 9, 1) << 3) |
21330 extract32(ctx
->opcode
, 5, 3);
21331 rs
= (extract32(ctx
->opcode
, 4, 1) << 3) |
21332 extract32(ctx
->opcode
, 0, 3);
21333 rt
= decode_gpr_gpr4(rt
);
21334 rs
= decode_gpr_gpr4(rs
);
21335 switch ((extract32(ctx
->opcode
, 7, 2) & 0x2) |
21336 (extract32(ctx
->opcode
, 3, 1))) {
21339 gen_arith(ctx
, OPC_ADDU
, rt
, rs
, rt
);
21343 gen_r6_muldiv(ctx
, R6_OPC_MUL
, rt
, rs
, rt
);
21346 gen_reserved_instruction(ctx
);
21352 int imm
= extract32(ctx
->opcode
, 0, 7);
21353 imm
= (imm
== 0x7f ? -1 : imm
);
21355 tcg_gen_movi_tl(cpu_gpr
[rt
], imm
);
21361 uint32_t u
= extract32(ctx
->opcode
, 0, 4);
21362 u
= (u
== 12) ? 0xff :
21363 (u
== 13) ? 0xffff : u
;
21364 gen_logic_imm(ctx
, OPC_ANDI
, rt
, rs
, u
);
21368 offset
= extract32(ctx
->opcode
, 0, 2);
21369 switch (extract32(ctx
->opcode
, 2, 2)) {
21371 gen_ld(ctx
, OPC_LB
, rt
, rs
, offset
);
21374 rt
= decode_gpr_gpr3_src_store(
21375 NANOMIPS_EXTRACT_RT3(ctx
->opcode
));
21376 gen_st(ctx
, OPC_SB
, rt
, rs
, offset
);
21379 gen_ld(ctx
, OPC_LBU
, rt
, rs
, offset
);
21382 gen_reserved_instruction(ctx
);
21387 offset
= extract32(ctx
->opcode
, 1, 2) << 1;
21388 switch ((extract32(ctx
->opcode
, 3, 1) << 1) | (ctx
->opcode
& 1)) {
21390 gen_ld(ctx
, OPC_LH
, rt
, rs
, offset
);
21393 rt
= decode_gpr_gpr3_src_store(
21394 NANOMIPS_EXTRACT_RT3(ctx
->opcode
));
21395 gen_st(ctx
, OPC_SH
, rt
, rs
, offset
);
21398 gen_ld(ctx
, OPC_LHU
, rt
, rs
, offset
);
21401 gen_reserved_instruction(ctx
);
21406 offset
= extract32(ctx
->opcode
, 0, 4) << 2;
21407 gen_ld(ctx
, OPC_LW
, rt
, rs
, offset
);
21410 rt
= NANOMIPS_EXTRACT_RD5(ctx
->opcode
);
21411 offset
= extract32(ctx
->opcode
, 0, 5) << 2;
21412 gen_ld(ctx
, OPC_LW
, rt
, 29, offset
);
21416 rt
= (extract32(ctx
->opcode
, 9, 1) << 3) |
21417 extract32(ctx
->opcode
, 5, 3);
21418 rs
= (extract32(ctx
->opcode
, 4, 1) << 3) |
21419 extract32(ctx
->opcode
, 0, 3);
21420 offset
= (extract32(ctx
->opcode
, 3, 1) << 3) |
21421 (extract32(ctx
->opcode
, 8, 1) << 2);
21422 rt
= decode_gpr_gpr4(rt
);
21423 rs
= decode_gpr_gpr4(rs
);
21424 gen_ld(ctx
, OPC_LW
, rt
, rs
, offset
);
21428 rt
= (extract32(ctx
->opcode
, 9, 1) << 3) |
21429 extract32(ctx
->opcode
, 5, 3);
21430 rs
= (extract32(ctx
->opcode
, 4, 1) << 3) |
21431 extract32(ctx
->opcode
, 0, 3);
21432 offset
= (extract32(ctx
->opcode
, 3, 1) << 3) |
21433 (extract32(ctx
->opcode
, 8, 1) << 2);
21434 rt
= decode_gpr_gpr4_zero(rt
);
21435 rs
= decode_gpr_gpr4(rs
);
21436 gen_st(ctx
, OPC_SW
, rt
, rs
, offset
);
21439 offset
= extract32(ctx
->opcode
, 0, 7) << 2;
21440 gen_ld(ctx
, OPC_LW
, rt
, 28, offset
);
21443 rt
= NANOMIPS_EXTRACT_RD5(ctx
->opcode
);
21444 offset
= extract32(ctx
->opcode
, 0, 5) << 2;
21445 gen_st(ctx
, OPC_SW
, rt
, 29, offset
);
21448 rt
= decode_gpr_gpr3_src_store(
21449 NANOMIPS_EXTRACT_RT3(ctx
->opcode
));
21450 rs
= decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx
->opcode
));
21451 offset
= extract32(ctx
->opcode
, 0, 4) << 2;
21452 gen_st(ctx
, OPC_SW
, rt
, rs
, offset
);
21455 rt
= decode_gpr_gpr3_src_store(
21456 NANOMIPS_EXTRACT_RT3(ctx
->opcode
));
21457 offset
= extract32(ctx
->opcode
, 0, 7) << 2;
21458 gen_st(ctx
, OPC_SW
, rt
, 28, offset
);
21461 gen_compute_branch_nm(ctx
, OPC_BEQ
, 2, 0, 0,
21462 (sextract32(ctx
->opcode
, 0, 1) << 10) |
21463 (extract32(ctx
->opcode
, 1, 9) << 1));
21466 gen_compute_branch_nm(ctx
, OPC_BGEZAL
, 2, 0, 0,
21467 (sextract32(ctx
->opcode
, 0, 1) << 10) |
21468 (extract32(ctx
->opcode
, 1, 9) << 1));
21471 gen_compute_branch_nm(ctx
, OPC_BEQ
, 2, rt
, 0,
21472 (sextract32(ctx
->opcode
, 0, 1) << 7) |
21473 (extract32(ctx
->opcode
, 1, 6) << 1));
21476 gen_compute_branch_nm(ctx
, OPC_BNE
, 2, rt
, 0,
21477 (sextract32(ctx
->opcode
, 0, 1) << 7) |
21478 (extract32(ctx
->opcode
, 1, 6) << 1));
21481 switch (ctx
->opcode
& 0xf) {
21484 switch (extract32(ctx
->opcode
, 4, 1)) {
21486 gen_compute_branch_nm(ctx
, OPC_JR
, 2,
21487 extract32(ctx
->opcode
, 5, 5), 0, 0);
21490 gen_compute_branch_nm(ctx
, OPC_JALR
, 2,
21491 extract32(ctx
->opcode
, 5, 5), 31, 0);
21498 uint32_t opc
= extract32(ctx
->opcode
, 4, 3) <
21499 extract32(ctx
->opcode
, 7, 3) ? OPC_BEQ
: OPC_BNE
;
21500 gen_compute_branch_nm(ctx
, opc
, 2, rs
, rt
,
21501 extract32(ctx
->opcode
, 0, 4) << 1);
21508 int count
= extract32(ctx
->opcode
, 0, 4);
21509 int u
= extract32(ctx
->opcode
, 4, 4) << 4;
21511 rt
= 30 + extract32(ctx
->opcode
, 9, 1);
21512 switch (extract32(ctx
->opcode
, 8, 1)) {
21514 gen_save(ctx
, rt
, count
, 0, u
);
21516 case NM_RESTORE_JRC16
:
21517 gen_restore(ctx
, rt
, count
, 0, u
);
21518 gen_compute_branch_nm(ctx
, OPC_JR
, 2, 31, 0, 0);
21527 static const int gpr2reg1
[] = {4, 5, 6, 7};
21528 static const int gpr2reg2
[] = {5, 6, 7, 8};
21530 int rd2
= extract32(ctx
->opcode
, 3, 1) << 1 |
21531 extract32(ctx
->opcode
, 8, 1);
21532 int r1
= gpr2reg1
[rd2
];
21533 int r2
= gpr2reg2
[rd2
];
21534 int r3
= extract32(ctx
->opcode
, 4, 1) << 3 |
21535 extract32(ctx
->opcode
, 0, 3);
21536 int r4
= extract32(ctx
->opcode
, 9, 1) << 3 |
21537 extract32(ctx
->opcode
, 5, 3);
21538 TCGv t0
= tcg_temp_new();
21539 TCGv t1
= tcg_temp_new();
21540 if (op
== NM_MOVEP
) {
21543 rs
= decode_gpr_gpr4_zero(r3
);
21544 rt
= decode_gpr_gpr4_zero(r4
);
21546 rd
= decode_gpr_gpr4(r3
);
21547 re
= decode_gpr_gpr4(r4
);
21551 gen_load_gpr(t0
, rs
);
21552 gen_load_gpr(t1
, rt
);
21553 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
21554 tcg_gen_mov_tl(cpu_gpr
[re
], t1
);
21560 return decode_nanomips_32_48_opc(env
, ctx
);
21567 /* SmartMIPS extension to MIPS32 */
21569 #if defined(TARGET_MIPS64)
21571 /* MDMX extension to MIPS64 */
21575 /* MIPSDSP functions. */
21576 static void gen_mipsdsp_ld(DisasContext
*ctx
, uint32_t opc
,
21577 int rd
, int base
, int offset
)
21582 t0
= tcg_temp_new();
21585 gen_load_gpr(t0
, offset
);
21586 } else if (offset
== 0) {
21587 gen_load_gpr(t0
, base
);
21589 gen_op_addr_add(ctx
, t0
, cpu_gpr
[base
], cpu_gpr
[offset
]);
21594 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_UB
);
21595 gen_store_gpr(t0
, rd
);
21598 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESW
);
21599 gen_store_gpr(t0
, rd
);
21602 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESL
);
21603 gen_store_gpr(t0
, rd
);
21605 #if defined(TARGET_MIPS64)
21607 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
);
21608 gen_store_gpr(t0
, rd
);
21615 static void gen_mipsdsp_arith(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
21616 int ret
, int v1
, int v2
)
21622 /* Treat as NOP. */
21626 v1_t
= tcg_temp_new();
21627 v2_t
= tcg_temp_new();
21629 gen_load_gpr(v1_t
, v1
);
21630 gen_load_gpr(v2_t
, v2
);
21633 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
21634 case OPC_MULT_G_2E
:
21638 gen_helper_adduh_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
21640 case OPC_ADDUH_R_QB
:
21641 gen_helper_adduh_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
21644 gen_helper_addqh_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
21646 case OPC_ADDQH_R_PH
:
21647 gen_helper_addqh_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
21650 gen_helper_addqh_w(cpu_gpr
[ret
], v1_t
, v2_t
);
21652 case OPC_ADDQH_R_W
:
21653 gen_helper_addqh_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
21656 gen_helper_subuh_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
21658 case OPC_SUBUH_R_QB
:
21659 gen_helper_subuh_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
21662 gen_helper_subqh_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
21664 case OPC_SUBQH_R_PH
:
21665 gen_helper_subqh_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
21668 gen_helper_subqh_w(cpu_gpr
[ret
], v1_t
, v2_t
);
21670 case OPC_SUBQH_R_W
:
21671 gen_helper_subqh_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
21675 case OPC_ABSQ_S_PH_DSP
:
21677 case OPC_ABSQ_S_QB
:
21679 gen_helper_absq_s_qb(cpu_gpr
[ret
], v2_t
, cpu_env
);
21681 case OPC_ABSQ_S_PH
:
21683 gen_helper_absq_s_ph(cpu_gpr
[ret
], v2_t
, cpu_env
);
21687 gen_helper_absq_s_w(cpu_gpr
[ret
], v2_t
, cpu_env
);
21689 case OPC_PRECEQ_W_PHL
:
21691 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0xFFFF0000);
21692 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
21694 case OPC_PRECEQ_W_PHR
:
21696 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0x0000FFFF);
21697 tcg_gen_shli_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], 16);
21698 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
21700 case OPC_PRECEQU_PH_QBL
:
21702 gen_helper_precequ_ph_qbl(cpu_gpr
[ret
], v2_t
);
21704 case OPC_PRECEQU_PH_QBR
:
21706 gen_helper_precequ_ph_qbr(cpu_gpr
[ret
], v2_t
);
21708 case OPC_PRECEQU_PH_QBLA
:
21710 gen_helper_precequ_ph_qbla(cpu_gpr
[ret
], v2_t
);
21712 case OPC_PRECEQU_PH_QBRA
:
21714 gen_helper_precequ_ph_qbra(cpu_gpr
[ret
], v2_t
);
21716 case OPC_PRECEU_PH_QBL
:
21718 gen_helper_preceu_ph_qbl(cpu_gpr
[ret
], v2_t
);
21720 case OPC_PRECEU_PH_QBR
:
21722 gen_helper_preceu_ph_qbr(cpu_gpr
[ret
], v2_t
);
21724 case OPC_PRECEU_PH_QBLA
:
21726 gen_helper_preceu_ph_qbla(cpu_gpr
[ret
], v2_t
);
21728 case OPC_PRECEU_PH_QBRA
:
21730 gen_helper_preceu_ph_qbra(cpu_gpr
[ret
], v2_t
);
21734 case OPC_ADDU_QB_DSP
:
21738 gen_helper_addq_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21740 case OPC_ADDQ_S_PH
:
21742 gen_helper_addq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21746 gen_helper_addq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21750 gen_helper_addu_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21752 case OPC_ADDU_S_QB
:
21754 gen_helper_addu_s_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21758 gen_helper_addu_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21760 case OPC_ADDU_S_PH
:
21762 gen_helper_addu_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21766 gen_helper_subq_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21768 case OPC_SUBQ_S_PH
:
21770 gen_helper_subq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21774 gen_helper_subq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21778 gen_helper_subu_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21780 case OPC_SUBU_S_QB
:
21782 gen_helper_subu_s_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21786 gen_helper_subu_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21788 case OPC_SUBU_S_PH
:
21790 gen_helper_subu_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21794 gen_helper_addsc(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21798 gen_helper_addwc(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21802 gen_helper_modsub(cpu_gpr
[ret
], v1_t
, v2_t
);
21804 case OPC_RADDU_W_QB
:
21806 gen_helper_raddu_w_qb(cpu_gpr
[ret
], v1_t
);
21810 case OPC_CMPU_EQ_QB_DSP
:
21812 case OPC_PRECR_QB_PH
:
21814 gen_helper_precr_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
21816 case OPC_PRECRQ_QB_PH
:
21818 gen_helper_precrq_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
21820 case OPC_PRECR_SRA_PH_W
:
21823 TCGv_i32 sa_t
= tcg_const_i32(v2
);
21824 gen_helper_precr_sra_ph_w(cpu_gpr
[ret
], sa_t
, v1_t
,
21826 tcg_temp_free_i32(sa_t
);
21829 case OPC_PRECR_SRA_R_PH_W
:
21832 TCGv_i32 sa_t
= tcg_const_i32(v2
);
21833 gen_helper_precr_sra_r_ph_w(cpu_gpr
[ret
], sa_t
, v1_t
,
21835 tcg_temp_free_i32(sa_t
);
21838 case OPC_PRECRQ_PH_W
:
21840 gen_helper_precrq_ph_w(cpu_gpr
[ret
], v1_t
, v2_t
);
21842 case OPC_PRECRQ_RS_PH_W
:
21844 gen_helper_precrq_rs_ph_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21846 case OPC_PRECRQU_S_QB_PH
:
21848 gen_helper_precrqu_s_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21852 #ifdef TARGET_MIPS64
21853 case OPC_ABSQ_S_QH_DSP
:
21855 case OPC_PRECEQ_L_PWL
:
21857 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0xFFFFFFFF00000000ull
);
21859 case OPC_PRECEQ_L_PWR
:
21861 tcg_gen_shli_tl(cpu_gpr
[ret
], v2_t
, 32);
21863 case OPC_PRECEQ_PW_QHL
:
21865 gen_helper_preceq_pw_qhl(cpu_gpr
[ret
], v2_t
);
21867 case OPC_PRECEQ_PW_QHR
:
21869 gen_helper_preceq_pw_qhr(cpu_gpr
[ret
], v2_t
);
21871 case OPC_PRECEQ_PW_QHLA
:
21873 gen_helper_preceq_pw_qhla(cpu_gpr
[ret
], v2_t
);
21875 case OPC_PRECEQ_PW_QHRA
:
21877 gen_helper_preceq_pw_qhra(cpu_gpr
[ret
], v2_t
);
21879 case OPC_PRECEQU_QH_OBL
:
21881 gen_helper_precequ_qh_obl(cpu_gpr
[ret
], v2_t
);
21883 case OPC_PRECEQU_QH_OBR
:
21885 gen_helper_precequ_qh_obr(cpu_gpr
[ret
], v2_t
);
21887 case OPC_PRECEQU_QH_OBLA
:
21889 gen_helper_precequ_qh_obla(cpu_gpr
[ret
], v2_t
);
21891 case OPC_PRECEQU_QH_OBRA
:
21893 gen_helper_precequ_qh_obra(cpu_gpr
[ret
], v2_t
);
21895 case OPC_PRECEU_QH_OBL
:
21897 gen_helper_preceu_qh_obl(cpu_gpr
[ret
], v2_t
);
21899 case OPC_PRECEU_QH_OBR
:
21901 gen_helper_preceu_qh_obr(cpu_gpr
[ret
], v2_t
);
21903 case OPC_PRECEU_QH_OBLA
:
21905 gen_helper_preceu_qh_obla(cpu_gpr
[ret
], v2_t
);
21907 case OPC_PRECEU_QH_OBRA
:
21909 gen_helper_preceu_qh_obra(cpu_gpr
[ret
], v2_t
);
21911 case OPC_ABSQ_S_OB
:
21913 gen_helper_absq_s_ob(cpu_gpr
[ret
], v2_t
, cpu_env
);
21915 case OPC_ABSQ_S_PW
:
21917 gen_helper_absq_s_pw(cpu_gpr
[ret
], v2_t
, cpu_env
);
21919 case OPC_ABSQ_S_QH
:
21921 gen_helper_absq_s_qh(cpu_gpr
[ret
], v2_t
, cpu_env
);
21925 case OPC_ADDU_OB_DSP
:
21927 case OPC_RADDU_L_OB
:
21929 gen_helper_raddu_l_ob(cpu_gpr
[ret
], v1_t
);
21933 gen_helper_subq_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21935 case OPC_SUBQ_S_PW
:
21937 gen_helper_subq_s_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21941 gen_helper_subq_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21943 case OPC_SUBQ_S_QH
:
21945 gen_helper_subq_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21949 gen_helper_subu_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21951 case OPC_SUBU_S_OB
:
21953 gen_helper_subu_s_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21957 gen_helper_subu_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21959 case OPC_SUBU_S_QH
:
21961 gen_helper_subu_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21965 gen_helper_subuh_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
21967 case OPC_SUBUH_R_OB
:
21969 gen_helper_subuh_r_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
21973 gen_helper_addq_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21975 case OPC_ADDQ_S_PW
:
21977 gen_helper_addq_s_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21981 gen_helper_addq_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21983 case OPC_ADDQ_S_QH
:
21985 gen_helper_addq_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21989 gen_helper_addu_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21991 case OPC_ADDU_S_OB
:
21993 gen_helper_addu_s_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21997 gen_helper_addu_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21999 case OPC_ADDU_S_QH
:
22001 gen_helper_addu_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22005 gen_helper_adduh_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
22007 case OPC_ADDUH_R_OB
:
22009 gen_helper_adduh_r_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
22013 case OPC_CMPU_EQ_OB_DSP
:
22015 case OPC_PRECR_OB_QH
:
22017 gen_helper_precr_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
);
22019 case OPC_PRECR_SRA_QH_PW
:
22022 TCGv_i32 ret_t
= tcg_const_i32(ret
);
22023 gen_helper_precr_sra_qh_pw(v2_t
, v1_t
, v2_t
, ret_t
);
22024 tcg_temp_free_i32(ret_t
);
22027 case OPC_PRECR_SRA_R_QH_PW
:
22030 TCGv_i32 sa_v
= tcg_const_i32(ret
);
22031 gen_helper_precr_sra_r_qh_pw(v2_t
, v1_t
, v2_t
, sa_v
);
22032 tcg_temp_free_i32(sa_v
);
22035 case OPC_PRECRQ_OB_QH
:
22037 gen_helper_precrq_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
);
22039 case OPC_PRECRQ_PW_L
:
22041 gen_helper_precrq_pw_l(cpu_gpr
[ret
], v1_t
, v2_t
);
22043 case OPC_PRECRQ_QH_PW
:
22045 gen_helper_precrq_qh_pw(cpu_gpr
[ret
], v1_t
, v2_t
);
22047 case OPC_PRECRQ_RS_QH_PW
:
22049 gen_helper_precrq_rs_qh_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22051 case OPC_PRECRQU_S_OB_QH
:
22053 gen_helper_precrqu_s_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22060 tcg_temp_free(v1_t
);
22061 tcg_temp_free(v2_t
);
22064 static void gen_mipsdsp_shift(DisasContext
*ctx
, uint32_t opc
,
22065 int ret
, int v1
, int v2
)
22073 /* Treat as NOP. */
22077 t0
= tcg_temp_new();
22078 v1_t
= tcg_temp_new();
22079 v2_t
= tcg_temp_new();
22081 tcg_gen_movi_tl(t0
, v1
);
22082 gen_load_gpr(v1_t
, v1
);
22083 gen_load_gpr(v2_t
, v2
);
22086 case OPC_SHLL_QB_DSP
:
22088 op2
= MASK_SHLL_QB(ctx
->opcode
);
22092 gen_helper_shll_qb(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
22096 gen_helper_shll_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22100 gen_helper_shll_ph(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
22104 gen_helper_shll_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22106 case OPC_SHLL_S_PH
:
22108 gen_helper_shll_s_ph(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
22110 case OPC_SHLLV_S_PH
:
22112 gen_helper_shll_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22116 gen_helper_shll_s_w(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
22118 case OPC_SHLLV_S_W
:
22120 gen_helper_shll_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22124 gen_helper_shrl_qb(cpu_gpr
[ret
], t0
, v2_t
);
22128 gen_helper_shrl_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
22132 gen_helper_shrl_ph(cpu_gpr
[ret
], t0
, v2_t
);
22136 gen_helper_shrl_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
22140 gen_helper_shra_qb(cpu_gpr
[ret
], t0
, v2_t
);
22142 case OPC_SHRA_R_QB
:
22144 gen_helper_shra_r_qb(cpu_gpr
[ret
], t0
, v2_t
);
22148 gen_helper_shra_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
22150 case OPC_SHRAV_R_QB
:
22152 gen_helper_shra_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
22156 gen_helper_shra_ph(cpu_gpr
[ret
], t0
, v2_t
);
22158 case OPC_SHRA_R_PH
:
22160 gen_helper_shra_r_ph(cpu_gpr
[ret
], t0
, v2_t
);
22164 gen_helper_shra_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
22166 case OPC_SHRAV_R_PH
:
22168 gen_helper_shra_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
22172 gen_helper_shra_r_w(cpu_gpr
[ret
], t0
, v2_t
);
22174 case OPC_SHRAV_R_W
:
22176 gen_helper_shra_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
22178 default: /* Invalid */
22179 MIPS_INVAL("MASK SHLL.QB");
22180 gen_reserved_instruction(ctx
);
22185 #ifdef TARGET_MIPS64
22186 case OPC_SHLL_OB_DSP
:
22187 op2
= MASK_SHLL_OB(ctx
->opcode
);
22191 gen_helper_shll_pw(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
22195 gen_helper_shll_pw(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
22197 case OPC_SHLL_S_PW
:
22199 gen_helper_shll_s_pw(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
22201 case OPC_SHLLV_S_PW
:
22203 gen_helper_shll_s_pw(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
22207 gen_helper_shll_ob(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
22211 gen_helper_shll_ob(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
22215 gen_helper_shll_qh(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
22219 gen_helper_shll_qh(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
22221 case OPC_SHLL_S_QH
:
22223 gen_helper_shll_s_qh(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
22225 case OPC_SHLLV_S_QH
:
22227 gen_helper_shll_s_qh(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
22231 gen_helper_shra_ob(cpu_gpr
[ret
], v2_t
, t0
);
22235 gen_helper_shra_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
22237 case OPC_SHRA_R_OB
:
22239 gen_helper_shra_r_ob(cpu_gpr
[ret
], v2_t
, t0
);
22241 case OPC_SHRAV_R_OB
:
22243 gen_helper_shra_r_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
22247 gen_helper_shra_pw(cpu_gpr
[ret
], v2_t
, t0
);
22251 gen_helper_shra_pw(cpu_gpr
[ret
], v2_t
, v1_t
);
22253 case OPC_SHRA_R_PW
:
22255 gen_helper_shra_r_pw(cpu_gpr
[ret
], v2_t
, t0
);
22257 case OPC_SHRAV_R_PW
:
22259 gen_helper_shra_r_pw(cpu_gpr
[ret
], v2_t
, v1_t
);
22263 gen_helper_shra_qh(cpu_gpr
[ret
], v2_t
, t0
);
22267 gen_helper_shra_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
22269 case OPC_SHRA_R_QH
:
22271 gen_helper_shra_r_qh(cpu_gpr
[ret
], v2_t
, t0
);
22273 case OPC_SHRAV_R_QH
:
22275 gen_helper_shra_r_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
22279 gen_helper_shrl_ob(cpu_gpr
[ret
], v2_t
, t0
);
22283 gen_helper_shrl_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
22287 gen_helper_shrl_qh(cpu_gpr
[ret
], v2_t
, t0
);
22291 gen_helper_shrl_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
22293 default: /* Invalid */
22294 MIPS_INVAL("MASK SHLL.OB");
22295 gen_reserved_instruction(ctx
);
22303 tcg_temp_free(v1_t
);
22304 tcg_temp_free(v2_t
);
22307 static void gen_mipsdsp_multiply(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
22308 int ret
, int v1
, int v2
, int check_ret
)
22314 if ((ret
== 0) && (check_ret
== 1)) {
22315 /* Treat as NOP. */
22319 t0
= tcg_temp_new_i32();
22320 v1_t
= tcg_temp_new();
22321 v2_t
= tcg_temp_new();
22323 tcg_gen_movi_i32(t0
, ret
);
22324 gen_load_gpr(v1_t
, v1
);
22325 gen_load_gpr(v2_t
, v2
);
22329 * OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
22330 * the same mask and op1.
22332 case OPC_MULT_G_2E
:
22336 gen_helper_mul_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22339 gen_helper_mul_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22342 gen_helper_mulq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22344 case OPC_MULQ_RS_W
:
22345 gen_helper_mulq_rs_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22349 case OPC_DPA_W_PH_DSP
:
22351 case OPC_DPAU_H_QBL
:
22353 gen_helper_dpau_h_qbl(t0
, v1_t
, v2_t
, cpu_env
);
22355 case OPC_DPAU_H_QBR
:
22357 gen_helper_dpau_h_qbr(t0
, v1_t
, v2_t
, cpu_env
);
22359 case OPC_DPSU_H_QBL
:
22361 gen_helper_dpsu_h_qbl(t0
, v1_t
, v2_t
, cpu_env
);
22363 case OPC_DPSU_H_QBR
:
22365 gen_helper_dpsu_h_qbr(t0
, v1_t
, v2_t
, cpu_env
);
22369 gen_helper_dpa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
22371 case OPC_DPAX_W_PH
:
22373 gen_helper_dpax_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
22375 case OPC_DPAQ_S_W_PH
:
22377 gen_helper_dpaq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
22379 case OPC_DPAQX_S_W_PH
:
22381 gen_helper_dpaqx_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
22383 case OPC_DPAQX_SA_W_PH
:
22385 gen_helper_dpaqx_sa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
22389 gen_helper_dps_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
22391 case OPC_DPSX_W_PH
:
22393 gen_helper_dpsx_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
22395 case OPC_DPSQ_S_W_PH
:
22397 gen_helper_dpsq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
22399 case OPC_DPSQX_S_W_PH
:
22401 gen_helper_dpsqx_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
22403 case OPC_DPSQX_SA_W_PH
:
22405 gen_helper_dpsqx_sa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
22407 case OPC_MULSAQ_S_W_PH
:
22409 gen_helper_mulsaq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
22411 case OPC_DPAQ_SA_L_W
:
22413 gen_helper_dpaq_sa_l_w(t0
, v1_t
, v2_t
, cpu_env
);
22415 case OPC_DPSQ_SA_L_W
:
22417 gen_helper_dpsq_sa_l_w(t0
, v1_t
, v2_t
, cpu_env
);
22419 case OPC_MAQ_S_W_PHL
:
22421 gen_helper_maq_s_w_phl(t0
, v1_t
, v2_t
, cpu_env
);
22423 case OPC_MAQ_S_W_PHR
:
22425 gen_helper_maq_s_w_phr(t0
, v1_t
, v2_t
, cpu_env
);
22427 case OPC_MAQ_SA_W_PHL
:
22429 gen_helper_maq_sa_w_phl(t0
, v1_t
, v2_t
, cpu_env
);
22431 case OPC_MAQ_SA_W_PHR
:
22433 gen_helper_maq_sa_w_phr(t0
, v1_t
, v2_t
, cpu_env
);
22435 case OPC_MULSA_W_PH
:
22437 gen_helper_mulsa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
22441 #ifdef TARGET_MIPS64
22442 case OPC_DPAQ_W_QH_DSP
:
22444 int ac
= ret
& 0x03;
22445 tcg_gen_movi_i32(t0
, ac
);
22450 gen_helper_dmadd(v1_t
, v2_t
, t0
, cpu_env
);
22454 gen_helper_dmaddu(v1_t
, v2_t
, t0
, cpu_env
);
22458 gen_helper_dmsub(v1_t
, v2_t
, t0
, cpu_env
);
22462 gen_helper_dmsubu(v1_t
, v2_t
, t0
, cpu_env
);
22466 gen_helper_dpa_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
22468 case OPC_DPAQ_S_W_QH
:
22470 gen_helper_dpaq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
22472 case OPC_DPAQ_SA_L_PW
:
22474 gen_helper_dpaq_sa_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
22476 case OPC_DPAU_H_OBL
:
22478 gen_helper_dpau_h_obl(v1_t
, v2_t
, t0
, cpu_env
);
22480 case OPC_DPAU_H_OBR
:
22482 gen_helper_dpau_h_obr(v1_t
, v2_t
, t0
, cpu_env
);
22486 gen_helper_dps_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
22488 case OPC_DPSQ_S_W_QH
:
22490 gen_helper_dpsq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
22492 case OPC_DPSQ_SA_L_PW
:
22494 gen_helper_dpsq_sa_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
22496 case OPC_DPSU_H_OBL
:
22498 gen_helper_dpsu_h_obl(v1_t
, v2_t
, t0
, cpu_env
);
22500 case OPC_DPSU_H_OBR
:
22502 gen_helper_dpsu_h_obr(v1_t
, v2_t
, t0
, cpu_env
);
22504 case OPC_MAQ_S_L_PWL
:
22506 gen_helper_maq_s_l_pwl(v1_t
, v2_t
, t0
, cpu_env
);
22508 case OPC_MAQ_S_L_PWR
:
22510 gen_helper_maq_s_l_pwr(v1_t
, v2_t
, t0
, cpu_env
);
22512 case OPC_MAQ_S_W_QHLL
:
22514 gen_helper_maq_s_w_qhll(v1_t
, v2_t
, t0
, cpu_env
);
22516 case OPC_MAQ_SA_W_QHLL
:
22518 gen_helper_maq_sa_w_qhll(v1_t
, v2_t
, t0
, cpu_env
);
22520 case OPC_MAQ_S_W_QHLR
:
22522 gen_helper_maq_s_w_qhlr(v1_t
, v2_t
, t0
, cpu_env
);
22524 case OPC_MAQ_SA_W_QHLR
:
22526 gen_helper_maq_sa_w_qhlr(v1_t
, v2_t
, t0
, cpu_env
);
22528 case OPC_MAQ_S_W_QHRL
:
22530 gen_helper_maq_s_w_qhrl(v1_t
, v2_t
, t0
, cpu_env
);
22532 case OPC_MAQ_SA_W_QHRL
:
22534 gen_helper_maq_sa_w_qhrl(v1_t
, v2_t
, t0
, cpu_env
);
22536 case OPC_MAQ_S_W_QHRR
:
22538 gen_helper_maq_s_w_qhrr(v1_t
, v2_t
, t0
, cpu_env
);
22540 case OPC_MAQ_SA_W_QHRR
:
22542 gen_helper_maq_sa_w_qhrr(v1_t
, v2_t
, t0
, cpu_env
);
22544 case OPC_MULSAQ_S_L_PW
:
22546 gen_helper_mulsaq_s_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
22548 case OPC_MULSAQ_S_W_QH
:
22550 gen_helper_mulsaq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
22556 case OPC_ADDU_QB_DSP
:
22558 case OPC_MULEU_S_PH_QBL
:
22560 gen_helper_muleu_s_ph_qbl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22562 case OPC_MULEU_S_PH_QBR
:
22564 gen_helper_muleu_s_ph_qbr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22566 case OPC_MULQ_RS_PH
:
22568 gen_helper_mulq_rs_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22570 case OPC_MULEQ_S_W_PHL
:
22572 gen_helper_muleq_s_w_phl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22574 case OPC_MULEQ_S_W_PHR
:
22576 gen_helper_muleq_s_w_phr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22578 case OPC_MULQ_S_PH
:
22580 gen_helper_mulq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22584 #ifdef TARGET_MIPS64
22585 case OPC_ADDU_OB_DSP
:
22587 case OPC_MULEQ_S_PW_QHL
:
22589 gen_helper_muleq_s_pw_qhl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22591 case OPC_MULEQ_S_PW_QHR
:
22593 gen_helper_muleq_s_pw_qhr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22595 case OPC_MULEU_S_QH_OBL
:
22597 gen_helper_muleu_s_qh_obl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22599 case OPC_MULEU_S_QH_OBR
:
22601 gen_helper_muleu_s_qh_obr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22603 case OPC_MULQ_RS_QH
:
22605 gen_helper_mulq_rs_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22612 tcg_temp_free_i32(t0
);
22613 tcg_temp_free(v1_t
);
22614 tcg_temp_free(v2_t
);
22617 static void gen_mipsdsp_bitinsn(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
22625 /* Treat as NOP. */
22629 t0
= tcg_temp_new();
22630 val_t
= tcg_temp_new();
22631 gen_load_gpr(val_t
, val
);
22634 case OPC_ABSQ_S_PH_DSP
:
22638 gen_helper_bitrev(cpu_gpr
[ret
], val_t
);
22643 target_long result
;
22644 imm
= (ctx
->opcode
>> 16) & 0xFF;
22645 result
= (uint32_t)imm
<< 24 |
22646 (uint32_t)imm
<< 16 |
22647 (uint32_t)imm
<< 8 |
22649 result
= (int32_t)result
;
22650 tcg_gen_movi_tl(cpu_gpr
[ret
], result
);
22655 tcg_gen_ext8u_tl(cpu_gpr
[ret
], val_t
);
22656 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 8);
22657 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
22658 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
22659 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
22660 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
22665 imm
= (ctx
->opcode
>> 16) & 0x03FF;
22666 imm
= (int16_t)(imm
<< 6) >> 6;
22667 tcg_gen_movi_tl(cpu_gpr
[ret
], \
22668 (target_long
)((int32_t)imm
<< 16 | \
22674 tcg_gen_ext16u_tl(cpu_gpr
[ret
], val_t
);
22675 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
22676 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
22677 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
22681 #ifdef TARGET_MIPS64
22682 case OPC_ABSQ_S_QH_DSP
:
22689 imm
= (ctx
->opcode
>> 16) & 0xFF;
22690 temp
= ((uint64_t)imm
<< 8) | (uint64_t)imm
;
22691 temp
= (temp
<< 16) | temp
;
22692 temp
= (temp
<< 32) | temp
;
22693 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
22701 imm
= (ctx
->opcode
>> 16) & 0x03FF;
22702 imm
= (int16_t)(imm
<< 6) >> 6;
22703 temp
= ((target_long
)imm
<< 32) \
22704 | ((target_long
)imm
& 0xFFFFFFFF);
22705 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
22713 imm
= (ctx
->opcode
>> 16) & 0x03FF;
22714 imm
= (int16_t)(imm
<< 6) >> 6;
22716 temp
= ((uint64_t)(uint16_t)imm
<< 48) |
22717 ((uint64_t)(uint16_t)imm
<< 32) |
22718 ((uint64_t)(uint16_t)imm
<< 16) |
22719 (uint64_t)(uint16_t)imm
;
22720 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
22725 tcg_gen_ext8u_tl(cpu_gpr
[ret
], val_t
);
22726 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 8);
22727 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
22728 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
22729 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
22730 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
22731 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
22735 tcg_gen_ext32u_i64(cpu_gpr
[ret
], val_t
);
22736 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
22737 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
22741 tcg_gen_ext16u_tl(cpu_gpr
[ret
], val_t
);
22742 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
22743 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
22744 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
22745 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
22752 tcg_temp_free(val_t
);
22755 static void gen_mipsdsp_add_cmp_pick(DisasContext
*ctx
,
22756 uint32_t op1
, uint32_t op2
,
22757 int ret
, int v1
, int v2
, int check_ret
)
22763 if ((ret
== 0) && (check_ret
== 1)) {
22764 /* Treat as NOP. */
22768 t1
= tcg_temp_new();
22769 v1_t
= tcg_temp_new();
22770 v2_t
= tcg_temp_new();
22772 gen_load_gpr(v1_t
, v1
);
22773 gen_load_gpr(v2_t
, v2
);
22776 case OPC_CMPU_EQ_QB_DSP
:
22778 case OPC_CMPU_EQ_QB
:
22780 gen_helper_cmpu_eq_qb(v1_t
, v2_t
, cpu_env
);
22782 case OPC_CMPU_LT_QB
:
22784 gen_helper_cmpu_lt_qb(v1_t
, v2_t
, cpu_env
);
22786 case OPC_CMPU_LE_QB
:
22788 gen_helper_cmpu_le_qb(v1_t
, v2_t
, cpu_env
);
22790 case OPC_CMPGU_EQ_QB
:
22792 gen_helper_cmpgu_eq_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
22794 case OPC_CMPGU_LT_QB
:
22796 gen_helper_cmpgu_lt_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
22798 case OPC_CMPGU_LE_QB
:
22800 gen_helper_cmpgu_le_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
22802 case OPC_CMPGDU_EQ_QB
:
22804 gen_helper_cmpgu_eq_qb(t1
, v1_t
, v2_t
);
22805 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
22806 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
22807 tcg_gen_shli_tl(t1
, t1
, 24);
22808 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
22810 case OPC_CMPGDU_LT_QB
:
22812 gen_helper_cmpgu_lt_qb(t1
, v1_t
, v2_t
);
22813 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
22814 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
22815 tcg_gen_shli_tl(t1
, t1
, 24);
22816 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
22818 case OPC_CMPGDU_LE_QB
:
22820 gen_helper_cmpgu_le_qb(t1
, v1_t
, v2_t
);
22821 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
22822 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
22823 tcg_gen_shli_tl(t1
, t1
, 24);
22824 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
22826 case OPC_CMP_EQ_PH
:
22828 gen_helper_cmp_eq_ph(v1_t
, v2_t
, cpu_env
);
22830 case OPC_CMP_LT_PH
:
22832 gen_helper_cmp_lt_ph(v1_t
, v2_t
, cpu_env
);
22834 case OPC_CMP_LE_PH
:
22836 gen_helper_cmp_le_ph(v1_t
, v2_t
, cpu_env
);
22840 gen_helper_pick_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22844 gen_helper_pick_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22846 case OPC_PACKRL_PH
:
22848 gen_helper_packrl_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
22852 #ifdef TARGET_MIPS64
22853 case OPC_CMPU_EQ_OB_DSP
:
22855 case OPC_CMP_EQ_PW
:
22857 gen_helper_cmp_eq_pw(v1_t
, v2_t
, cpu_env
);
22859 case OPC_CMP_LT_PW
:
22861 gen_helper_cmp_lt_pw(v1_t
, v2_t
, cpu_env
);
22863 case OPC_CMP_LE_PW
:
22865 gen_helper_cmp_le_pw(v1_t
, v2_t
, cpu_env
);
22867 case OPC_CMP_EQ_QH
:
22869 gen_helper_cmp_eq_qh(v1_t
, v2_t
, cpu_env
);
22871 case OPC_CMP_LT_QH
:
22873 gen_helper_cmp_lt_qh(v1_t
, v2_t
, cpu_env
);
22875 case OPC_CMP_LE_QH
:
22877 gen_helper_cmp_le_qh(v1_t
, v2_t
, cpu_env
);
22879 case OPC_CMPGDU_EQ_OB
:
22881 gen_helper_cmpgdu_eq_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22883 case OPC_CMPGDU_LT_OB
:
22885 gen_helper_cmpgdu_lt_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22887 case OPC_CMPGDU_LE_OB
:
22889 gen_helper_cmpgdu_le_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22891 case OPC_CMPGU_EQ_OB
:
22893 gen_helper_cmpgu_eq_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
22895 case OPC_CMPGU_LT_OB
:
22897 gen_helper_cmpgu_lt_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
22899 case OPC_CMPGU_LE_OB
:
22901 gen_helper_cmpgu_le_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
22903 case OPC_CMPU_EQ_OB
:
22905 gen_helper_cmpu_eq_ob(v1_t
, v2_t
, cpu_env
);
22907 case OPC_CMPU_LT_OB
:
22909 gen_helper_cmpu_lt_ob(v1_t
, v2_t
, cpu_env
);
22911 case OPC_CMPU_LE_OB
:
22913 gen_helper_cmpu_le_ob(v1_t
, v2_t
, cpu_env
);
22915 case OPC_PACKRL_PW
:
22917 gen_helper_packrl_pw(cpu_gpr
[ret
], v1_t
, v2_t
);
22921 gen_helper_pick_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22925 gen_helper_pick_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22929 gen_helper_pick_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22937 tcg_temp_free(v1_t
);
22938 tcg_temp_free(v2_t
);
22941 static void gen_mipsdsp_append(CPUMIPSState
*env
, DisasContext
*ctx
,
22942 uint32_t op1
, int rt
, int rs
, int sa
)
22949 /* Treat as NOP. */
22953 t0
= tcg_temp_new();
22954 gen_load_gpr(t0
, rs
);
22957 case OPC_APPEND_DSP
:
22958 switch (MASK_APPEND(ctx
->opcode
)) {
22961 tcg_gen_deposit_tl(cpu_gpr
[rt
], t0
, cpu_gpr
[rt
], sa
, 32 - sa
);
22963 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
22967 tcg_gen_ext32u_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
22968 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], sa
);
22969 tcg_gen_shli_tl(t0
, t0
, 32 - sa
);
22970 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
22972 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
22976 if (sa
!= 0 && sa
!= 2) {
22977 tcg_gen_shli_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 8 * sa
);
22978 tcg_gen_ext32u_tl(t0
, t0
);
22979 tcg_gen_shri_tl(t0
, t0
, 8 * (4 - sa
));
22980 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
22982 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
22984 default: /* Invalid */
22985 MIPS_INVAL("MASK APPEND");
22986 gen_reserved_instruction(ctx
);
22990 #ifdef TARGET_MIPS64
22991 case OPC_DAPPEND_DSP
:
22992 switch (MASK_DAPPEND(ctx
->opcode
)) {
22995 tcg_gen_deposit_tl(cpu_gpr
[rt
], t0
, cpu_gpr
[rt
], sa
, 64 - sa
);
22999 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 0x20 | sa
);
23000 tcg_gen_shli_tl(t0
, t0
, 64 - (0x20 | sa
));
23001 tcg_gen_or_tl(cpu_gpr
[rt
], t0
, t0
);
23005 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], sa
);
23006 tcg_gen_shli_tl(t0
, t0
, 64 - sa
);
23007 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
23012 if (sa
!= 0 && sa
!= 2 && sa
!= 4) {
23013 tcg_gen_shli_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 8 * sa
);
23014 tcg_gen_shri_tl(t0
, t0
, 8 * (8 - sa
));
23015 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
23018 default: /* Invalid */
23019 MIPS_INVAL("MASK DAPPEND");
23020 gen_reserved_instruction(ctx
);
23029 static void gen_mipsdsp_accinsn(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
23030 int ret
, int v1
, int v2
, int check_ret
)
23039 if ((ret
== 0) && (check_ret
== 1)) {
23040 /* Treat as NOP. */
23044 t0
= tcg_temp_new();
23045 t1
= tcg_temp_new();
23046 v1_t
= tcg_temp_new();
23047 v2_t
= tcg_temp_new();
23049 gen_load_gpr(v1_t
, v1
);
23050 gen_load_gpr(v2_t
, v2
);
23053 case OPC_EXTR_W_DSP
:
23057 tcg_gen_movi_tl(t0
, v2
);
23058 tcg_gen_movi_tl(t1
, v1
);
23059 gen_helper_extr_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23062 tcg_gen_movi_tl(t0
, v2
);
23063 tcg_gen_movi_tl(t1
, v1
);
23064 gen_helper_extr_r_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23066 case OPC_EXTR_RS_W
:
23067 tcg_gen_movi_tl(t0
, v2
);
23068 tcg_gen_movi_tl(t1
, v1
);
23069 gen_helper_extr_rs_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23072 tcg_gen_movi_tl(t0
, v2
);
23073 tcg_gen_movi_tl(t1
, v1
);
23074 gen_helper_extr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23076 case OPC_EXTRV_S_H
:
23077 tcg_gen_movi_tl(t0
, v2
);
23078 gen_helper_extr_s_h(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
23081 tcg_gen_movi_tl(t0
, v2
);
23082 gen_helper_extr_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
23084 case OPC_EXTRV_R_W
:
23085 tcg_gen_movi_tl(t0
, v2
);
23086 gen_helper_extr_r_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
23088 case OPC_EXTRV_RS_W
:
23089 tcg_gen_movi_tl(t0
, v2
);
23090 gen_helper_extr_rs_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
23093 tcg_gen_movi_tl(t0
, v2
);
23094 tcg_gen_movi_tl(t1
, v1
);
23095 gen_helper_extp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23098 tcg_gen_movi_tl(t0
, v2
);
23099 gen_helper_extp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
23102 tcg_gen_movi_tl(t0
, v2
);
23103 tcg_gen_movi_tl(t1
, v1
);
23104 gen_helper_extpdp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23107 tcg_gen_movi_tl(t0
, v2
);
23108 gen_helper_extpdp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
23111 imm
= (ctx
->opcode
>> 20) & 0x3F;
23112 tcg_gen_movi_tl(t0
, ret
);
23113 tcg_gen_movi_tl(t1
, imm
);
23114 gen_helper_shilo(t0
, t1
, cpu_env
);
23117 tcg_gen_movi_tl(t0
, ret
);
23118 gen_helper_shilo(t0
, v1_t
, cpu_env
);
23121 tcg_gen_movi_tl(t0
, ret
);
23122 gen_helper_mthlip(t0
, v1_t
, cpu_env
);
23125 imm
= (ctx
->opcode
>> 11) & 0x3FF;
23126 tcg_gen_movi_tl(t0
, imm
);
23127 gen_helper_wrdsp(v1_t
, t0
, cpu_env
);
23130 imm
= (ctx
->opcode
>> 16) & 0x03FF;
23131 tcg_gen_movi_tl(t0
, imm
);
23132 gen_helper_rddsp(cpu_gpr
[ret
], t0
, cpu_env
);
23136 #ifdef TARGET_MIPS64
23137 case OPC_DEXTR_W_DSP
:
23141 tcg_gen_movi_tl(t0
, ret
);
23142 gen_helper_dmthlip(v1_t
, t0
, cpu_env
);
23146 int shift
= (ctx
->opcode
>> 19) & 0x7F;
23147 int ac
= (ctx
->opcode
>> 11) & 0x03;
23148 tcg_gen_movi_tl(t0
, shift
);
23149 tcg_gen_movi_tl(t1
, ac
);
23150 gen_helper_dshilo(t0
, t1
, cpu_env
);
23155 int ac
= (ctx
->opcode
>> 11) & 0x03;
23156 tcg_gen_movi_tl(t0
, ac
);
23157 gen_helper_dshilo(v1_t
, t0
, cpu_env
);
23161 tcg_gen_movi_tl(t0
, v2
);
23162 tcg_gen_movi_tl(t1
, v1
);
23164 gen_helper_dextp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23167 tcg_gen_movi_tl(t0
, v2
);
23168 gen_helper_dextp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
23171 tcg_gen_movi_tl(t0
, v2
);
23172 tcg_gen_movi_tl(t1
, v1
);
23173 gen_helper_dextpdp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23176 tcg_gen_movi_tl(t0
, v2
);
23177 gen_helper_dextpdp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
23180 tcg_gen_movi_tl(t0
, v2
);
23181 tcg_gen_movi_tl(t1
, v1
);
23182 gen_helper_dextr_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23184 case OPC_DEXTR_R_L
:
23185 tcg_gen_movi_tl(t0
, v2
);
23186 tcg_gen_movi_tl(t1
, v1
);
23187 gen_helper_dextr_r_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23189 case OPC_DEXTR_RS_L
:
23190 tcg_gen_movi_tl(t0
, v2
);
23191 tcg_gen_movi_tl(t1
, v1
);
23192 gen_helper_dextr_rs_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23195 tcg_gen_movi_tl(t0
, v2
);
23196 tcg_gen_movi_tl(t1
, v1
);
23197 gen_helper_dextr_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23199 case OPC_DEXTR_R_W
:
23200 tcg_gen_movi_tl(t0
, v2
);
23201 tcg_gen_movi_tl(t1
, v1
);
23202 gen_helper_dextr_r_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23204 case OPC_DEXTR_RS_W
:
23205 tcg_gen_movi_tl(t0
, v2
);
23206 tcg_gen_movi_tl(t1
, v1
);
23207 gen_helper_dextr_rs_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23209 case OPC_DEXTR_S_H
:
23210 tcg_gen_movi_tl(t0
, v2
);
23211 tcg_gen_movi_tl(t1
, v1
);
23212 gen_helper_dextr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23214 case OPC_DEXTRV_S_H
:
23215 tcg_gen_movi_tl(t0
, v2
);
23216 tcg_gen_movi_tl(t1
, v1
);
23217 gen_helper_dextr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23220 tcg_gen_movi_tl(t0
, v2
);
23221 gen_helper_dextr_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
23223 case OPC_DEXTRV_R_L
:
23224 tcg_gen_movi_tl(t0
, v2
);
23225 gen_helper_dextr_r_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
23227 case OPC_DEXTRV_RS_L
:
23228 tcg_gen_movi_tl(t0
, v2
);
23229 gen_helper_dextr_rs_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
23232 tcg_gen_movi_tl(t0
, v2
);
23233 gen_helper_dextr_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
23235 case OPC_DEXTRV_R_W
:
23236 tcg_gen_movi_tl(t0
, v2
);
23237 gen_helper_dextr_r_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
23239 case OPC_DEXTRV_RS_W
:
23240 tcg_gen_movi_tl(t0
, v2
);
23241 gen_helper_dextr_rs_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
23250 tcg_temp_free(v1_t
);
23251 tcg_temp_free(v2_t
);
23254 /* End MIPSDSP functions. */
23256 static void decode_opc_special_r6(CPUMIPSState
*env
, DisasContext
*ctx
)
23258 int rs
, rt
, rd
, sa
;
23261 rs
= (ctx
->opcode
>> 21) & 0x1f;
23262 rt
= (ctx
->opcode
>> 16) & 0x1f;
23263 rd
= (ctx
->opcode
>> 11) & 0x1f;
23264 sa
= (ctx
->opcode
>> 6) & 0x1f;
23266 op1
= MASK_SPECIAL(ctx
->opcode
);
23272 op2
= MASK_R6_MULDIV(ctx
->opcode
);
23282 gen_r6_muldiv(ctx
, op2
, rd
, rs
, rt
);
23285 MIPS_INVAL("special_r6 muldiv");
23286 gen_reserved_instruction(ctx
);
23292 gen_cond_move(ctx
, op1
, rd
, rs
, rt
);
23296 if (rt
== 0 && sa
== 1) {
23298 * Major opcode and function field is shared with preR6 MFHI/MTHI.
23299 * We need additionally to check other fields.
23301 gen_cl(ctx
, op1
, rd
, rs
);
23303 gen_reserved_instruction(ctx
);
23307 if (is_uhi(extract32(ctx
->opcode
, 6, 20))) {
23308 gen_helper_do_semihosting(cpu_env
);
23310 if (ctx
->hflags
& MIPS_HFLAG_SBRI
) {
23311 gen_reserved_instruction(ctx
);
23313 generate_exception_end(ctx
, EXCP_DBp
);
23317 #if defined(TARGET_MIPS64)
23320 if (rt
== 0 && sa
== 1) {
23322 * Major opcode and function field is shared with preR6 MFHI/MTHI.
23323 * We need additionally to check other fields.
23325 check_mips_64(ctx
);
23326 gen_cl(ctx
, op1
, rd
, rs
);
23328 gen_reserved_instruction(ctx
);
23336 op2
= MASK_R6_MULDIV(ctx
->opcode
);
23346 check_mips_64(ctx
);
23347 gen_r6_muldiv(ctx
, op2
, rd
, rs
, rt
);
23350 MIPS_INVAL("special_r6 muldiv");
23351 gen_reserved_instruction(ctx
);
23356 default: /* Invalid */
23357 MIPS_INVAL("special_r6");
23358 gen_reserved_instruction(ctx
);
23363 static void decode_opc_special_tx79(CPUMIPSState
*env
, DisasContext
*ctx
)
23365 int rs
= extract32(ctx
->opcode
, 21, 5);
23366 int rt
= extract32(ctx
->opcode
, 16, 5);
23367 int rd
= extract32(ctx
->opcode
, 11, 5);
23368 uint32_t op1
= MASK_SPECIAL(ctx
->opcode
);
23371 case OPC_MOVN
: /* Conditional move */
23373 gen_cond_move(ctx
, op1
, rd
, rs
, rt
);
23375 case OPC_MFHI
: /* Move from HI/LO */
23377 gen_HILO(ctx
, op1
, 0, rd
);
23380 case OPC_MTLO
: /* Move to HI/LO */
23381 gen_HILO(ctx
, op1
, 0, rs
);
23385 gen_mul_txx9(ctx
, op1
, rd
, rs
, rt
);
23389 gen_muldiv(ctx
, op1
, 0, rs
, rt
);
23391 #if defined(TARGET_MIPS64)
23396 check_insn_opc_user_only(ctx
, INSN_R5900
);
23397 gen_muldiv(ctx
, op1
, 0, rs
, rt
);
23401 gen_compute_branch(ctx
, op1
, 4, rs
, 0, 0, 4);
23403 default: /* Invalid */
23404 MIPS_INVAL("special_tx79");
23405 gen_reserved_instruction(ctx
);
23410 static void decode_opc_special_legacy(CPUMIPSState
*env
, DisasContext
*ctx
)
23412 int rs
, rt
, rd
, sa
;
23415 rs
= (ctx
->opcode
>> 21) & 0x1f;
23416 rt
= (ctx
->opcode
>> 16) & 0x1f;
23417 rd
= (ctx
->opcode
>> 11) & 0x1f;
23418 sa
= (ctx
->opcode
>> 6) & 0x1f;
23420 op1
= MASK_SPECIAL(ctx
->opcode
);
23422 case OPC_MOVN
: /* Conditional move */
23424 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS_R1
|
23425 INSN_LOONGSON2E
| INSN_LOONGSON2F
);
23426 gen_cond_move(ctx
, op1
, rd
, rs
, rt
);
23428 case OPC_MFHI
: /* Move from HI/LO */
23430 gen_HILO(ctx
, op1
, rs
& 3, rd
);
23433 case OPC_MTLO
: /* Move to HI/LO */
23434 gen_HILO(ctx
, op1
, rd
& 3, rs
);
23437 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS_R1
);
23438 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
23439 check_cp1_enabled(ctx
);
23440 gen_movci(ctx
, rd
, rs
, (ctx
->opcode
>> 18) & 0x7,
23441 (ctx
->opcode
>> 16) & 1);
23443 generate_exception_err(ctx
, EXCP_CpU
, 1);
23449 check_insn(ctx
, INSN_VR54XX
);
23450 op1
= MASK_MUL_VR54XX(ctx
->opcode
);
23451 gen_mul_vr54xx(ctx
, op1
, rd
, rs
, rt
);
23453 gen_muldiv(ctx
, op1
, rd
& 3, rs
, rt
);
23458 gen_muldiv(ctx
, op1
, 0, rs
, rt
);
23460 #if defined(TARGET_MIPS64)
23465 check_insn(ctx
, ISA_MIPS3
);
23466 check_mips_64(ctx
);
23467 gen_muldiv(ctx
, op1
, 0, rs
, rt
);
23471 gen_compute_branch(ctx
, op1
, 4, rs
, rd
, sa
, 4);
23474 #ifdef MIPS_STRICT_STANDARD
23475 MIPS_INVAL("SPIM");
23476 gen_reserved_instruction(ctx
);
23478 /* Implemented as RI exception for now. */
23479 MIPS_INVAL("spim (unofficial)");
23480 gen_reserved_instruction(ctx
);
23483 default: /* Invalid */
23484 MIPS_INVAL("special_legacy");
23485 gen_reserved_instruction(ctx
);
23490 static void decode_opc_special(CPUMIPSState
*env
, DisasContext
*ctx
)
23492 int rs
, rt
, rd
, sa
;
23495 rs
= (ctx
->opcode
>> 21) & 0x1f;
23496 rt
= (ctx
->opcode
>> 16) & 0x1f;
23497 rd
= (ctx
->opcode
>> 11) & 0x1f;
23498 sa
= (ctx
->opcode
>> 6) & 0x1f;
23500 op1
= MASK_SPECIAL(ctx
->opcode
);
23502 case OPC_SLL
: /* Shift with immediate */
23503 if (sa
== 5 && rd
== 0 &&
23504 rs
== 0 && rt
== 0) { /* PAUSE */
23505 if ((ctx
->insn_flags
& ISA_MIPS_R6
) &&
23506 (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
23507 gen_reserved_instruction(ctx
);
23513 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
23516 switch ((ctx
->opcode
>> 21) & 0x1f) {
23518 /* rotr is decoded as srl on non-R2 CPUs */
23519 if (ctx
->insn_flags
& ISA_MIPS_R2
) {
23524 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
23527 gen_reserved_instruction(ctx
);
23535 gen_arith(ctx
, op1
, rd
, rs
, rt
);
23537 case OPC_SLLV
: /* Shifts */
23539 gen_shift(ctx
, op1
, rd
, rs
, rt
);
23542 switch ((ctx
->opcode
>> 6) & 0x1f) {
23544 /* rotrv is decoded as srlv on non-R2 CPUs */
23545 if (ctx
->insn_flags
& ISA_MIPS_R2
) {
23550 gen_shift(ctx
, op1
, rd
, rs
, rt
);
23553 gen_reserved_instruction(ctx
);
23557 case OPC_SLT
: /* Set on less than */
23559 gen_slt(ctx
, op1
, rd
, rs
, rt
);
23561 case OPC_AND
: /* Logic*/
23565 gen_logic(ctx
, op1
, rd
, rs
, rt
);
23568 gen_compute_branch(ctx
, op1
, 4, rs
, rd
, sa
, 4);
23570 case OPC_TGE
: /* Traps */
23576 check_insn(ctx
, ISA_MIPS2
);
23577 gen_trap(ctx
, op1
, rs
, rt
, -1);
23580 /* Pmon entry point, also R4010 selsl */
23581 #ifdef MIPS_STRICT_STANDARD
23582 MIPS_INVAL("PMON / selsl");
23583 gen_reserved_instruction(ctx
);
23585 gen_helper_0e0i(pmon
, sa
);
23589 generate_exception_end(ctx
, EXCP_SYSCALL
);
23592 generate_exception_end(ctx
, EXCP_BREAK
);
23595 check_insn(ctx
, ISA_MIPS2
);
23596 gen_sync(extract32(ctx
->opcode
, 6, 5));
23599 #if defined(TARGET_MIPS64)
23600 /* MIPS64 specific opcodes */
23605 check_insn(ctx
, ISA_MIPS3
);
23606 check_mips_64(ctx
);
23607 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
23610 switch ((ctx
->opcode
>> 21) & 0x1f) {
23612 /* drotr is decoded as dsrl on non-R2 CPUs */
23613 if (ctx
->insn_flags
& ISA_MIPS_R2
) {
23618 check_insn(ctx
, ISA_MIPS3
);
23619 check_mips_64(ctx
);
23620 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
23623 gen_reserved_instruction(ctx
);
23628 switch ((ctx
->opcode
>> 21) & 0x1f) {
23630 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
23631 if (ctx
->insn_flags
& ISA_MIPS_R2
) {
23636 check_insn(ctx
, ISA_MIPS3
);
23637 check_mips_64(ctx
);
23638 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
23641 gen_reserved_instruction(ctx
);
23649 check_insn(ctx
, ISA_MIPS3
);
23650 check_mips_64(ctx
);
23651 gen_arith(ctx
, op1
, rd
, rs
, rt
);
23655 check_insn(ctx
, ISA_MIPS3
);
23656 check_mips_64(ctx
);
23657 gen_shift(ctx
, op1
, rd
, rs
, rt
);
23660 switch ((ctx
->opcode
>> 6) & 0x1f) {
23662 /* drotrv is decoded as dsrlv on non-R2 CPUs */
23663 if (ctx
->insn_flags
& ISA_MIPS_R2
) {
23668 check_insn(ctx
, ISA_MIPS3
);
23669 check_mips_64(ctx
);
23670 gen_shift(ctx
, op1
, rd
, rs
, rt
);
23673 gen_reserved_instruction(ctx
);
23679 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
23680 decode_opc_special_r6(env
, ctx
);
23681 } else if (ctx
->insn_flags
& INSN_R5900
) {
23682 decode_opc_special_tx79(env
, ctx
);
23684 decode_opc_special_legacy(env
, ctx
);
23690 static void decode_opc_special2_legacy(CPUMIPSState
*env
, DisasContext
*ctx
)
23695 rs
= (ctx
->opcode
>> 21) & 0x1f;
23696 rt
= (ctx
->opcode
>> 16) & 0x1f;
23697 rd
= (ctx
->opcode
>> 11) & 0x1f;
23699 op1
= MASK_SPECIAL2(ctx
->opcode
);
23701 case OPC_MADD
: /* Multiply and add/sub */
23705 check_insn(ctx
, ISA_MIPS_R1
);
23706 gen_muldiv(ctx
, op1
, rd
& 3, rs
, rt
);
23709 gen_arith(ctx
, op1
, rd
, rs
, rt
);
23712 case OPC_DIVU_G_2F
:
23713 case OPC_MULT_G_2F
:
23714 case OPC_MULTU_G_2F
:
23716 case OPC_MODU_G_2F
:
23717 check_insn(ctx
, INSN_LOONGSON2F
| ASE_LEXT
);
23718 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
23722 check_insn(ctx
, ISA_MIPS_R1
);
23723 gen_cl(ctx
, op1
, rd
, rs
);
23726 if (is_uhi(extract32(ctx
->opcode
, 6, 20))) {
23727 gen_helper_do_semihosting(cpu_env
);
23730 * XXX: not clear which exception should be raised
23731 * when in debug mode...
23733 check_insn(ctx
, ISA_MIPS_R1
);
23734 generate_exception_end(ctx
, EXCP_DBp
);
23737 #if defined(TARGET_MIPS64)
23740 check_insn(ctx
, ISA_MIPS_R1
);
23741 check_mips_64(ctx
);
23742 gen_cl(ctx
, op1
, rd
, rs
);
23744 case OPC_DMULT_G_2F
:
23745 case OPC_DMULTU_G_2F
:
23746 case OPC_DDIV_G_2F
:
23747 case OPC_DDIVU_G_2F
:
23748 case OPC_DMOD_G_2F
:
23749 case OPC_DMODU_G_2F
:
23750 check_insn(ctx
, INSN_LOONGSON2F
| ASE_LEXT
);
23751 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
23754 default: /* Invalid */
23755 MIPS_INVAL("special2_legacy");
23756 gen_reserved_instruction(ctx
);
23761 static void decode_opc_special3_r6(CPUMIPSState
*env
, DisasContext
*ctx
)
23763 int rs
, rt
, rd
, sa
;
23767 rs
= (ctx
->opcode
>> 21) & 0x1f;
23768 rt
= (ctx
->opcode
>> 16) & 0x1f;
23769 rd
= (ctx
->opcode
>> 11) & 0x1f;
23770 sa
= (ctx
->opcode
>> 6) & 0x1f;
23771 imm
= (int16_t)ctx
->opcode
>> 7;
23773 op1
= MASK_SPECIAL3(ctx
->opcode
);
23777 /* hint codes 24-31 are reserved and signal RI */
23778 gen_reserved_instruction(ctx
);
23780 /* Treat as NOP. */
23783 check_cp0_enabled(ctx
);
23784 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
23785 gen_cache_operation(ctx
, rt
, rs
, imm
);
23789 gen_st_cond(ctx
, rt
, rs
, imm
, MO_TESL
, false);
23792 gen_ld(ctx
, op1
, rt
, rs
, imm
);
23797 /* Treat as NOP. */
23800 op2
= MASK_BSHFL(ctx
->opcode
);
23806 gen_align(ctx
, 32, rd
, rs
, rt
, sa
& 3);
23809 gen_bitswap(ctx
, op2
, rd
, rt
);
23814 #ifndef CONFIG_USER_ONLY
23816 if (unlikely(ctx
->gi
<= 1)) {
23817 gen_reserved_instruction(ctx
);
23819 check_cp0_enabled(ctx
);
23820 switch ((ctx
->opcode
>> 6) & 3) {
23821 case 0: /* GINVI */
23822 /* Treat as NOP. */
23824 case 2: /* GINVT */
23825 gen_helper_0e1i(ginvt
, cpu_gpr
[rs
], extract32(ctx
->opcode
, 8, 2));
23828 gen_reserved_instruction(ctx
);
23833 #if defined(TARGET_MIPS64)
23835 gen_st_cond(ctx
, rt
, rs
, imm
, MO_TEQ
, false);
23838 gen_ld(ctx
, op1
, rt
, rs
, imm
);
23841 check_mips_64(ctx
);
23844 /* Treat as NOP. */
23847 op2
= MASK_DBSHFL(ctx
->opcode
);
23857 gen_align(ctx
, 64, rd
, rs
, rt
, sa
& 7);
23860 gen_bitswap(ctx
, op2
, rd
, rt
);
23867 default: /* Invalid */
23868 MIPS_INVAL("special3_r6");
23869 gen_reserved_instruction(ctx
);
23874 static void decode_opc_special3_legacy(CPUMIPSState
*env
, DisasContext
*ctx
)
23879 rs
= (ctx
->opcode
>> 21) & 0x1f;
23880 rt
= (ctx
->opcode
>> 16) & 0x1f;
23881 rd
= (ctx
->opcode
>> 11) & 0x1f;
23883 op1
= MASK_SPECIAL3(ctx
->opcode
);
23886 case OPC_DIVU_G_2E
:
23888 case OPC_MODU_G_2E
:
23889 case OPC_MULT_G_2E
:
23890 case OPC_MULTU_G_2E
:
23892 * OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
23893 * the same mask and op1.
23895 if ((ctx
->insn_flags
& ASE_DSP_R2
) && (op1
== OPC_MULT_G_2E
)) {
23896 op2
= MASK_ADDUH_QB(ctx
->opcode
);
23899 case OPC_ADDUH_R_QB
:
23901 case OPC_ADDQH_R_PH
:
23903 case OPC_ADDQH_R_W
:
23905 case OPC_SUBUH_R_QB
:
23907 case OPC_SUBQH_R_PH
:
23909 case OPC_SUBQH_R_W
:
23910 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
23915 case OPC_MULQ_RS_W
:
23916 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
23919 MIPS_INVAL("MASK ADDUH.QB");
23920 gen_reserved_instruction(ctx
);
23923 } else if (ctx
->insn_flags
& INSN_LOONGSON2E
) {
23924 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
23926 gen_reserved_instruction(ctx
);
23930 op2
= MASK_LX(ctx
->opcode
);
23932 #if defined(TARGET_MIPS64)
23938 gen_mipsdsp_ld(ctx
, op2
, rd
, rs
, rt
);
23940 default: /* Invalid */
23941 MIPS_INVAL("MASK LX");
23942 gen_reserved_instruction(ctx
);
23946 case OPC_ABSQ_S_PH_DSP
:
23947 op2
= MASK_ABSQ_S_PH(ctx
->opcode
);
23949 case OPC_ABSQ_S_QB
:
23950 case OPC_ABSQ_S_PH
:
23952 case OPC_PRECEQ_W_PHL
:
23953 case OPC_PRECEQ_W_PHR
:
23954 case OPC_PRECEQU_PH_QBL
:
23955 case OPC_PRECEQU_PH_QBR
:
23956 case OPC_PRECEQU_PH_QBLA
:
23957 case OPC_PRECEQU_PH_QBRA
:
23958 case OPC_PRECEU_PH_QBL
:
23959 case OPC_PRECEU_PH_QBR
:
23960 case OPC_PRECEU_PH_QBLA
:
23961 case OPC_PRECEU_PH_QBRA
:
23962 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
23969 gen_mipsdsp_bitinsn(ctx
, op1
, op2
, rd
, rt
);
23972 MIPS_INVAL("MASK ABSQ_S.PH");
23973 gen_reserved_instruction(ctx
);
23977 case OPC_ADDU_QB_DSP
:
23978 op2
= MASK_ADDU_QB(ctx
->opcode
);
23981 case OPC_ADDQ_S_PH
:
23984 case OPC_ADDU_S_QB
:
23986 case OPC_ADDU_S_PH
:
23988 case OPC_SUBQ_S_PH
:
23991 case OPC_SUBU_S_QB
:
23993 case OPC_SUBU_S_PH
:
23997 case OPC_RADDU_W_QB
:
23998 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
24000 case OPC_MULEU_S_PH_QBL
:
24001 case OPC_MULEU_S_PH_QBR
:
24002 case OPC_MULQ_RS_PH
:
24003 case OPC_MULEQ_S_W_PHL
:
24004 case OPC_MULEQ_S_W_PHR
:
24005 case OPC_MULQ_S_PH
:
24006 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
24008 default: /* Invalid */
24009 MIPS_INVAL("MASK ADDU.QB");
24010 gen_reserved_instruction(ctx
);
24015 case OPC_CMPU_EQ_QB_DSP
:
24016 op2
= MASK_CMPU_EQ_QB(ctx
->opcode
);
24018 case OPC_PRECR_SRA_PH_W
:
24019 case OPC_PRECR_SRA_R_PH_W
:
24020 gen_mipsdsp_arith(ctx
, op1
, op2
, rt
, rs
, rd
);
24022 case OPC_PRECR_QB_PH
:
24023 case OPC_PRECRQ_QB_PH
:
24024 case OPC_PRECRQ_PH_W
:
24025 case OPC_PRECRQ_RS_PH_W
:
24026 case OPC_PRECRQU_S_QB_PH
:
24027 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
24029 case OPC_CMPU_EQ_QB
:
24030 case OPC_CMPU_LT_QB
:
24031 case OPC_CMPU_LE_QB
:
24032 case OPC_CMP_EQ_PH
:
24033 case OPC_CMP_LT_PH
:
24034 case OPC_CMP_LE_PH
:
24035 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
24037 case OPC_CMPGU_EQ_QB
:
24038 case OPC_CMPGU_LT_QB
:
24039 case OPC_CMPGU_LE_QB
:
24040 case OPC_CMPGDU_EQ_QB
:
24041 case OPC_CMPGDU_LT_QB
:
24042 case OPC_CMPGDU_LE_QB
:
24045 case OPC_PACKRL_PH
:
24046 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
24048 default: /* Invalid */
24049 MIPS_INVAL("MASK CMPU.EQ.QB");
24050 gen_reserved_instruction(ctx
);
24054 case OPC_SHLL_QB_DSP
:
24055 gen_mipsdsp_shift(ctx
, op1
, rd
, rs
, rt
);
24057 case OPC_DPA_W_PH_DSP
:
24058 op2
= MASK_DPA_W_PH(ctx
->opcode
);
24060 case OPC_DPAU_H_QBL
:
24061 case OPC_DPAU_H_QBR
:
24062 case OPC_DPSU_H_QBL
:
24063 case OPC_DPSU_H_QBR
:
24065 case OPC_DPAX_W_PH
:
24066 case OPC_DPAQ_S_W_PH
:
24067 case OPC_DPAQX_S_W_PH
:
24068 case OPC_DPAQX_SA_W_PH
:
24070 case OPC_DPSX_W_PH
:
24071 case OPC_DPSQ_S_W_PH
:
24072 case OPC_DPSQX_S_W_PH
:
24073 case OPC_DPSQX_SA_W_PH
:
24074 case OPC_MULSAQ_S_W_PH
:
24075 case OPC_DPAQ_SA_L_W
:
24076 case OPC_DPSQ_SA_L_W
:
24077 case OPC_MAQ_S_W_PHL
:
24078 case OPC_MAQ_S_W_PHR
:
24079 case OPC_MAQ_SA_W_PHL
:
24080 case OPC_MAQ_SA_W_PHR
:
24081 case OPC_MULSA_W_PH
:
24082 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
24084 default: /* Invalid */
24085 MIPS_INVAL("MASK DPAW.PH");
24086 gen_reserved_instruction(ctx
);
24091 op2
= MASK_INSV(ctx
->opcode
);
24102 t0
= tcg_temp_new();
24103 t1
= tcg_temp_new();
24105 gen_load_gpr(t0
, rt
);
24106 gen_load_gpr(t1
, rs
);
24108 gen_helper_insv(cpu_gpr
[rt
], cpu_env
, t1
, t0
);
24114 default: /* Invalid */
24115 MIPS_INVAL("MASK INSV");
24116 gen_reserved_instruction(ctx
);
24120 case OPC_APPEND_DSP
:
24121 gen_mipsdsp_append(env
, ctx
, op1
, rt
, rs
, rd
);
24123 case OPC_EXTR_W_DSP
:
24124 op2
= MASK_EXTR_W(ctx
->opcode
);
24128 case OPC_EXTR_RS_W
:
24130 case OPC_EXTRV_S_H
:
24132 case OPC_EXTRV_R_W
:
24133 case OPC_EXTRV_RS_W
:
24138 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rt
, rs
, rd
, 1);
24141 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
24147 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
24149 default: /* Invalid */
24150 MIPS_INVAL("MASK EXTR.W");
24151 gen_reserved_instruction(ctx
);
24155 #if defined(TARGET_MIPS64)
24156 case OPC_DDIV_G_2E
:
24157 case OPC_DDIVU_G_2E
:
24158 case OPC_DMULT_G_2E
:
24159 case OPC_DMULTU_G_2E
:
24160 case OPC_DMOD_G_2E
:
24161 case OPC_DMODU_G_2E
:
24162 check_insn(ctx
, INSN_LOONGSON2E
);
24163 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
24165 case OPC_ABSQ_S_QH_DSP
:
24166 op2
= MASK_ABSQ_S_QH(ctx
->opcode
);
24168 case OPC_PRECEQ_L_PWL
:
24169 case OPC_PRECEQ_L_PWR
:
24170 case OPC_PRECEQ_PW_QHL
:
24171 case OPC_PRECEQ_PW_QHR
:
24172 case OPC_PRECEQ_PW_QHLA
:
24173 case OPC_PRECEQ_PW_QHRA
:
24174 case OPC_PRECEQU_QH_OBL
:
24175 case OPC_PRECEQU_QH_OBR
:
24176 case OPC_PRECEQU_QH_OBLA
:
24177 case OPC_PRECEQU_QH_OBRA
:
24178 case OPC_PRECEU_QH_OBL
:
24179 case OPC_PRECEU_QH_OBR
:
24180 case OPC_PRECEU_QH_OBLA
:
24181 case OPC_PRECEU_QH_OBRA
:
24182 case OPC_ABSQ_S_OB
:
24183 case OPC_ABSQ_S_PW
:
24184 case OPC_ABSQ_S_QH
:
24185 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
24193 gen_mipsdsp_bitinsn(ctx
, op1
, op2
, rd
, rt
);
24195 default: /* Invalid */
24196 MIPS_INVAL("MASK ABSQ_S.QH");
24197 gen_reserved_instruction(ctx
);
24201 case OPC_ADDU_OB_DSP
:
24202 op2
= MASK_ADDU_OB(ctx
->opcode
);
24204 case OPC_RADDU_L_OB
:
24206 case OPC_SUBQ_S_PW
:
24208 case OPC_SUBQ_S_QH
:
24210 case OPC_SUBU_S_OB
:
24212 case OPC_SUBU_S_QH
:
24214 case OPC_SUBUH_R_OB
:
24216 case OPC_ADDQ_S_PW
:
24218 case OPC_ADDQ_S_QH
:
24220 case OPC_ADDU_S_OB
:
24222 case OPC_ADDU_S_QH
:
24224 case OPC_ADDUH_R_OB
:
24225 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
24227 case OPC_MULEQ_S_PW_QHL
:
24228 case OPC_MULEQ_S_PW_QHR
:
24229 case OPC_MULEU_S_QH_OBL
:
24230 case OPC_MULEU_S_QH_OBR
:
24231 case OPC_MULQ_RS_QH
:
24232 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
24234 default: /* Invalid */
24235 MIPS_INVAL("MASK ADDU.OB");
24236 gen_reserved_instruction(ctx
);
24240 case OPC_CMPU_EQ_OB_DSP
:
24241 op2
= MASK_CMPU_EQ_OB(ctx
->opcode
);
24243 case OPC_PRECR_SRA_QH_PW
:
24244 case OPC_PRECR_SRA_R_QH_PW
:
24245 /* Return value is rt. */
24246 gen_mipsdsp_arith(ctx
, op1
, op2
, rt
, rs
, rd
);
24248 case OPC_PRECR_OB_QH
:
24249 case OPC_PRECRQ_OB_QH
:
24250 case OPC_PRECRQ_PW_L
:
24251 case OPC_PRECRQ_QH_PW
:
24252 case OPC_PRECRQ_RS_QH_PW
:
24253 case OPC_PRECRQU_S_OB_QH
:
24254 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
24256 case OPC_CMPU_EQ_OB
:
24257 case OPC_CMPU_LT_OB
:
24258 case OPC_CMPU_LE_OB
:
24259 case OPC_CMP_EQ_QH
:
24260 case OPC_CMP_LT_QH
:
24261 case OPC_CMP_LE_QH
:
24262 case OPC_CMP_EQ_PW
:
24263 case OPC_CMP_LT_PW
:
24264 case OPC_CMP_LE_PW
:
24265 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
24267 case OPC_CMPGDU_EQ_OB
:
24268 case OPC_CMPGDU_LT_OB
:
24269 case OPC_CMPGDU_LE_OB
:
24270 case OPC_CMPGU_EQ_OB
:
24271 case OPC_CMPGU_LT_OB
:
24272 case OPC_CMPGU_LE_OB
:
24273 case OPC_PACKRL_PW
:
24277 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
24279 default: /* Invalid */
24280 MIPS_INVAL("MASK CMPU_EQ.OB");
24281 gen_reserved_instruction(ctx
);
24285 case OPC_DAPPEND_DSP
:
24286 gen_mipsdsp_append(env
, ctx
, op1
, rt
, rs
, rd
);
24288 case OPC_DEXTR_W_DSP
:
24289 op2
= MASK_DEXTR_W(ctx
->opcode
);
24296 case OPC_DEXTR_R_L
:
24297 case OPC_DEXTR_RS_L
:
24299 case OPC_DEXTR_R_W
:
24300 case OPC_DEXTR_RS_W
:
24301 case OPC_DEXTR_S_H
:
24303 case OPC_DEXTRV_R_L
:
24304 case OPC_DEXTRV_RS_L
:
24305 case OPC_DEXTRV_S_H
:
24307 case OPC_DEXTRV_R_W
:
24308 case OPC_DEXTRV_RS_W
:
24309 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rt
, rs
, rd
, 1);
24314 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
24316 default: /* Invalid */
24317 MIPS_INVAL("MASK EXTR.W");
24318 gen_reserved_instruction(ctx
);
24322 case OPC_DPAQ_W_QH_DSP
:
24323 op2
= MASK_DPAQ_W_QH(ctx
->opcode
);
24325 case OPC_DPAU_H_OBL
:
24326 case OPC_DPAU_H_OBR
:
24327 case OPC_DPSU_H_OBL
:
24328 case OPC_DPSU_H_OBR
:
24330 case OPC_DPAQ_S_W_QH
:
24332 case OPC_DPSQ_S_W_QH
:
24333 case OPC_MULSAQ_S_W_QH
:
24334 case OPC_DPAQ_SA_L_PW
:
24335 case OPC_DPSQ_SA_L_PW
:
24336 case OPC_MULSAQ_S_L_PW
:
24337 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
24339 case OPC_MAQ_S_W_QHLL
:
24340 case OPC_MAQ_S_W_QHLR
:
24341 case OPC_MAQ_S_W_QHRL
:
24342 case OPC_MAQ_S_W_QHRR
:
24343 case OPC_MAQ_SA_W_QHLL
:
24344 case OPC_MAQ_SA_W_QHLR
:
24345 case OPC_MAQ_SA_W_QHRL
:
24346 case OPC_MAQ_SA_W_QHRR
:
24347 case OPC_MAQ_S_L_PWL
:
24348 case OPC_MAQ_S_L_PWR
:
24353 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
24355 default: /* Invalid */
24356 MIPS_INVAL("MASK DPAQ.W.QH");
24357 gen_reserved_instruction(ctx
);
24361 case OPC_DINSV_DSP
:
24362 op2
= MASK_INSV(ctx
->opcode
);
24373 t0
= tcg_temp_new();
24374 t1
= tcg_temp_new();
24376 gen_load_gpr(t0
, rt
);
24377 gen_load_gpr(t1
, rs
);
24379 gen_helper_dinsv(cpu_gpr
[rt
], cpu_env
, t1
, t0
);
24385 default: /* Invalid */
24386 MIPS_INVAL("MASK DINSV");
24387 gen_reserved_instruction(ctx
);
24391 case OPC_SHLL_OB_DSP
:
24392 gen_mipsdsp_shift(ctx
, op1
, rd
, rs
, rt
);
24395 default: /* Invalid */
24396 MIPS_INVAL("special3_legacy");
24397 gen_reserved_instruction(ctx
);
24403 #if defined(TARGET_MIPS64)
24405 static void decode_mmi(CPUMIPSState
*env
, DisasContext
*ctx
)
24407 uint32_t opc
= MASK_MMI(ctx
->opcode
);
24408 int rs
= extract32(ctx
->opcode
, 21, 5);
24409 int rt
= extract32(ctx
->opcode
, 16, 5);
24410 int rd
= extract32(ctx
->opcode
, 11, 5);
24413 case MMI_OPC_MULT1
:
24414 case MMI_OPC_MULTU1
:
24416 case MMI_OPC_MADDU
:
24417 case MMI_OPC_MADD1
:
24418 case MMI_OPC_MADDU1
:
24419 gen_mul_txx9(ctx
, opc
, rd
, rs
, rt
);
24422 case MMI_OPC_DIVU1
:
24423 gen_div1_tx79(ctx
, opc
, rs
, rt
);
24426 MIPS_INVAL("TX79 MMI class");
24427 gen_reserved_instruction(ctx
);
24432 static void gen_mmi_lq(CPUMIPSState
*env
, DisasContext
*ctx
)
24434 gen_reserved_instruction(ctx
); /* TODO: MMI_OPC_LQ */
24437 static void gen_mmi_sq(DisasContext
*ctx
, int base
, int rt
, int offset
)
24439 gen_reserved_instruction(ctx
); /* TODO: MMI_OPC_SQ */
24443 * The TX79-specific instruction Store Quadword
24445 * +--------+-------+-------+------------------------+
24446 * | 011111 | base | rt | offset | SQ
24447 * +--------+-------+-------+------------------------+
24450 * has the same opcode as the Read Hardware Register instruction
24452 * +--------+-------+-------+-------+-------+--------+
24453 * | 011111 | 00000 | rt | rd | 00000 | 111011 | RDHWR
24454 * +--------+-------+-------+-------+-------+--------+
24457 * that is required, trapped and emulated by the Linux kernel. However, all
24458 * RDHWR encodings yield address error exceptions on the TX79 since the SQ
24459 * offset is odd. Therefore all valid SQ instructions can execute normally.
24460 * In user mode, QEMU must verify the upper and lower 11 bits to distinguish
24461 * between SQ and RDHWR, as the Linux kernel does.
24463 static void decode_mmi_sq(CPUMIPSState
*env
, DisasContext
*ctx
)
24465 int base
= extract32(ctx
->opcode
, 21, 5);
24466 int rt
= extract32(ctx
->opcode
, 16, 5);
24467 int offset
= extract32(ctx
->opcode
, 0, 16);
24469 #ifdef CONFIG_USER_ONLY
24470 uint32_t op1
= MASK_SPECIAL3(ctx
->opcode
);
24471 uint32_t op2
= extract32(ctx
->opcode
, 6, 5);
24473 if (base
== 0 && op2
== 0 && op1
== OPC_RDHWR
) {
24474 int rd
= extract32(ctx
->opcode
, 11, 5);
24476 gen_rdhwr(ctx
, rt
, rd
, 0);
24481 gen_mmi_sq(ctx
, base
, rt
, offset
);
24486 static void decode_opc_special3(CPUMIPSState
*env
, DisasContext
*ctx
)
24488 int rs
, rt
, rd
, sa
;
24492 rs
= (ctx
->opcode
>> 21) & 0x1f;
24493 rt
= (ctx
->opcode
>> 16) & 0x1f;
24494 rd
= (ctx
->opcode
>> 11) & 0x1f;
24495 sa
= (ctx
->opcode
>> 6) & 0x1f;
24496 imm
= sextract32(ctx
->opcode
, 7, 9);
24498 op1
= MASK_SPECIAL3(ctx
->opcode
);
24501 * EVA loads and stores overlap Loongson 2E instructions decoded by
24502 * decode_opc_special3_legacy(), so be careful to allow their decoding when
24515 check_cp0_enabled(ctx
);
24516 gen_ld(ctx
, op1
, rt
, rs
, imm
);
24523 check_cp0_enabled(ctx
);
24524 gen_st(ctx
, op1
, rt
, rs
, imm
);
24527 check_cp0_enabled(ctx
);
24528 gen_st_cond(ctx
, rt
, rs
, imm
, MO_TESL
, true);
24531 check_cp0_enabled(ctx
);
24532 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
24533 gen_cache_operation(ctx
, rt
, rs
, imm
);
24535 /* Treat as NOP. */
24538 check_cp0_enabled(ctx
);
24539 /* Treat as NOP. */
24547 check_insn(ctx
, ISA_MIPS_R2
);
24548 gen_bitops(ctx
, op1
, rt
, rs
, sa
, rd
);
24551 op2
= MASK_BSHFL(ctx
->opcode
);
24558 check_insn(ctx
, ISA_MIPS_R6
);
24559 decode_opc_special3_r6(env
, ctx
);
24562 check_insn(ctx
, ISA_MIPS_R2
);
24563 gen_bshfl(ctx
, op2
, rt
, rd
);
24567 #if defined(TARGET_MIPS64)
24574 check_insn(ctx
, ISA_MIPS_R2
);
24575 check_mips_64(ctx
);
24576 gen_bitops(ctx
, op1
, rt
, rs
, sa
, rd
);
24579 op2
= MASK_DBSHFL(ctx
->opcode
);
24590 check_insn(ctx
, ISA_MIPS_R6
);
24591 decode_opc_special3_r6(env
, ctx
);
24594 check_insn(ctx
, ISA_MIPS_R2
);
24595 check_mips_64(ctx
);
24596 op2
= MASK_DBSHFL(ctx
->opcode
);
24597 gen_bshfl(ctx
, op2
, rt
, rd
);
24603 gen_rdhwr(ctx
, rt
, rd
, extract32(ctx
->opcode
, 6, 3));
24608 TCGv t0
= tcg_temp_new();
24609 TCGv t1
= tcg_temp_new();
24611 gen_load_gpr(t0
, rt
);
24612 gen_load_gpr(t1
, rs
);
24613 gen_helper_fork(t0
, t1
);
24621 TCGv t0
= tcg_temp_new();
24623 gen_load_gpr(t0
, rs
);
24624 gen_helper_yield(t0
, cpu_env
, t0
);
24625 gen_store_gpr(t0
, rd
);
24630 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
24631 decode_opc_special3_r6(env
, ctx
);
24633 decode_opc_special3_legacy(env
, ctx
);
24638 static bool decode_opc_legacy(CPUMIPSState
*env
, DisasContext
*ctx
)
24641 int rs
, rt
, rd
, sa
;
24645 op
= MASK_OP_MAJOR(ctx
->opcode
);
24646 rs
= (ctx
->opcode
>> 21) & 0x1f;
24647 rt
= (ctx
->opcode
>> 16) & 0x1f;
24648 rd
= (ctx
->opcode
>> 11) & 0x1f;
24649 sa
= (ctx
->opcode
>> 6) & 0x1f;
24650 imm
= (int16_t)ctx
->opcode
;
24653 decode_opc_special(env
, ctx
);
24656 #if defined(TARGET_MIPS64)
24657 if ((ctx
->insn_flags
& INSN_R5900
) && (ctx
->insn_flags
& ASE_MMI
)) {
24658 decode_mmi(env
, ctx
);
24662 if (TARGET_LONG_BITS
== 32 && (ctx
->insn_flags
& ASE_MXU
)) {
24663 if (MASK_SPECIAL2(ctx
->opcode
) == OPC_MUL
) {
24664 gen_arith(ctx
, OPC_MUL
, rd
, rs
, rt
);
24666 decode_ase_mxu(ctx
, ctx
->opcode
);
24670 decode_opc_special2_legacy(env
, ctx
);
24673 #if defined(TARGET_MIPS64)
24674 if (ctx
->insn_flags
& INSN_R5900
) {
24675 decode_mmi_sq(env
, ctx
); /* MMI_OPC_SQ */
24677 decode_opc_special3(env
, ctx
);
24680 decode_opc_special3(env
, ctx
);
24684 op1
= MASK_REGIMM(ctx
->opcode
);
24686 case OPC_BLTZL
: /* REGIMM branches */
24690 check_insn(ctx
, ISA_MIPS2
);
24691 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
24695 gen_compute_branch(ctx
, op1
, 4, rs
, -1, imm
<< 2, 4);
24699 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
24701 /* OPC_NAL, OPC_BAL */
24702 gen_compute_branch(ctx
, op1
, 4, 0, -1, imm
<< 2, 4);
24704 gen_reserved_instruction(ctx
);
24707 gen_compute_branch(ctx
, op1
, 4, rs
, -1, imm
<< 2, 4);
24710 case OPC_TGEI
: /* REGIMM traps */
24717 check_insn(ctx
, ISA_MIPS2
);
24718 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
24719 gen_trap(ctx
, op1
, rs
, -1, imm
);
24722 check_insn(ctx
, ISA_MIPS_R6
);
24723 gen_reserved_instruction(ctx
);
24726 check_insn(ctx
, ISA_MIPS_R2
);
24728 * Break the TB to be able to sync copied instructions
24731 ctx
->base
.is_jmp
= DISAS_STOP
;
24733 case OPC_BPOSGE32
: /* MIPS DSP branch */
24734 #if defined(TARGET_MIPS64)
24738 gen_compute_branch(ctx
, op1
, 4, -1, -2, (int32_t)imm
<< 2, 4);
24740 #if defined(TARGET_MIPS64)
24742 check_insn(ctx
, ISA_MIPS_R6
);
24743 check_mips_64(ctx
);
24745 tcg_gen_addi_tl(cpu_gpr
[rs
], cpu_gpr
[rs
], (int64_t)imm
<< 32);
24749 check_insn(ctx
, ISA_MIPS_R6
);
24750 check_mips_64(ctx
);
24752 tcg_gen_addi_tl(cpu_gpr
[rs
], cpu_gpr
[rs
], (int64_t)imm
<< 48);
24756 default: /* Invalid */
24757 MIPS_INVAL("regimm");
24758 gen_reserved_instruction(ctx
);
24763 check_cp0_enabled(ctx
);
24764 op1
= MASK_CP0(ctx
->opcode
);
24772 #if defined(TARGET_MIPS64)
24776 #ifndef CONFIG_USER_ONLY
24777 gen_cp0(env
, ctx
, op1
, rt
, rd
);
24778 #endif /* !CONFIG_USER_ONLY */
24796 #ifndef CONFIG_USER_ONLY
24797 gen_cp0(env
, ctx
, MASK_C0(ctx
->opcode
), rt
, rd
);
24798 #endif /* !CONFIG_USER_ONLY */
24801 #ifndef CONFIG_USER_ONLY
24804 TCGv t0
= tcg_temp_new();
24806 op2
= MASK_MFMC0(ctx
->opcode
);
24810 gen_helper_dmt(t0
);
24811 gen_store_gpr(t0
, rt
);
24815 gen_helper_emt(t0
);
24816 gen_store_gpr(t0
, rt
);
24820 gen_helper_dvpe(t0
, cpu_env
);
24821 gen_store_gpr(t0
, rt
);
24825 gen_helper_evpe(t0
, cpu_env
);
24826 gen_store_gpr(t0
, rt
);
24829 check_insn(ctx
, ISA_MIPS_R6
);
24831 gen_helper_dvp(t0
, cpu_env
);
24832 gen_store_gpr(t0
, rt
);
24836 check_insn(ctx
, ISA_MIPS_R6
);
24838 gen_helper_evp(t0
, cpu_env
);
24839 gen_store_gpr(t0
, rt
);
24843 check_insn(ctx
, ISA_MIPS_R2
);
24844 save_cpu_state(ctx
, 1);
24845 gen_helper_di(t0
, cpu_env
);
24846 gen_store_gpr(t0
, rt
);
24848 * Stop translation as we may have switched
24849 * the execution mode.
24851 ctx
->base
.is_jmp
= DISAS_STOP
;
24854 check_insn(ctx
, ISA_MIPS_R2
);
24855 save_cpu_state(ctx
, 1);
24856 gen_helper_ei(t0
, cpu_env
);
24857 gen_store_gpr(t0
, rt
);
24859 * DISAS_STOP isn't sufficient, we need to ensure we break
24860 * out of translated code to check for pending interrupts.
24862 gen_save_pc(ctx
->base
.pc_next
+ 4);
24863 ctx
->base
.is_jmp
= DISAS_EXIT
;
24865 default: /* Invalid */
24866 MIPS_INVAL("mfmc0");
24867 gen_reserved_instruction(ctx
);
24872 #endif /* !CONFIG_USER_ONLY */
24875 check_insn(ctx
, ISA_MIPS_R2
);
24876 gen_load_srsgpr(rt
, rd
);
24879 check_insn(ctx
, ISA_MIPS_R2
);
24880 gen_store_srsgpr(rt
, rd
);
24884 gen_reserved_instruction(ctx
);
24888 case OPC_BOVC
: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */
24889 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
24890 /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */
24891 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
24894 /* Arithmetic with immediate opcode */
24895 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
24899 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
24901 case OPC_SLTI
: /* Set on less than with immediate opcode */
24903 gen_slt_imm(ctx
, op
, rt
, rs
, imm
);
24905 case OPC_ANDI
: /* Arithmetic with immediate opcode */
24906 case OPC_LUI
: /* OPC_AUI */
24909 gen_logic_imm(ctx
, op
, rt
, rs
, imm
);
24911 case OPC_J
: /* Jump */
24913 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
24914 gen_compute_branch(ctx
, op
, 4, rs
, rt
, offset
, 4);
24917 case OPC_BLEZC
: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */
24918 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
24920 gen_reserved_instruction(ctx
);
24923 /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */
24924 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
24927 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
24930 case OPC_BGTZC
: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */
24931 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
24933 gen_reserved_instruction(ctx
);
24936 /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */
24937 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
24940 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
24943 case OPC_BLEZALC
: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */
24946 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
24948 check_insn(ctx
, ISA_MIPS_R6
);
24949 /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */
24950 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
24953 case OPC_BGTZALC
: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */
24956 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
24958 check_insn(ctx
, ISA_MIPS_R6
);
24959 /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */
24960 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
24965 check_insn(ctx
, ISA_MIPS2
);
24966 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
24970 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
24972 case OPC_LL
: /* Load and stores */
24973 check_insn(ctx
, ISA_MIPS2
);
24974 if (ctx
->insn_flags
& INSN_R5900
) {
24975 check_insn_opc_user_only(ctx
, INSN_R5900
);
24986 gen_ld(ctx
, op
, rt
, rs
, imm
);
24993 gen_st(ctx
, op
, rt
, rs
, imm
);
24996 check_insn(ctx
, ISA_MIPS2
);
24997 if (ctx
->insn_flags
& INSN_R5900
) {
24998 check_insn_opc_user_only(ctx
, INSN_R5900
);
25000 gen_st_cond(ctx
, rt
, rs
, imm
, MO_TESL
, false);
25003 check_cp0_enabled(ctx
);
25004 check_insn(ctx
, ISA_MIPS3
| ISA_MIPS_R1
);
25005 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
25006 gen_cache_operation(ctx
, rt
, rs
, imm
);
25008 /* Treat as NOP. */
25011 if (ctx
->insn_flags
& INSN_R5900
) {
25012 /* Treat as NOP. */
25014 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS_R1
);
25015 /* Treat as NOP. */
25019 /* Floating point (COP1). */
25024 gen_cop1_ldst(ctx
, op
, rt
, rs
, imm
);
25028 op1
= MASK_CP1(ctx
->opcode
);
25033 check_cp1_enabled(ctx
);
25034 check_insn(ctx
, ISA_MIPS_R2
);
25040 check_cp1_enabled(ctx
);
25041 gen_cp1(ctx
, op1
, rt
, rd
);
25043 #if defined(TARGET_MIPS64)
25046 check_cp1_enabled(ctx
);
25047 check_insn(ctx
, ISA_MIPS3
);
25048 check_mips_64(ctx
);
25049 gen_cp1(ctx
, op1
, rt
, rd
);
25052 case OPC_BC1EQZ
: /* OPC_BC1ANY2 */
25053 check_cp1_enabled(ctx
);
25054 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
25056 gen_compute_branch1_r6(ctx
, MASK_CP1(ctx
->opcode
),
25061 check_insn(ctx
, ASE_MIPS3D
);
25062 gen_compute_branch1(ctx
, MASK_BC1(ctx
->opcode
),
25063 (rt
>> 2) & 0x7, imm
<< 2);
25067 check_cp1_enabled(ctx
);
25068 check_insn(ctx
, ISA_MIPS_R6
);
25069 gen_compute_branch1_r6(ctx
, MASK_CP1(ctx
->opcode
),
25073 check_cp1_enabled(ctx
);
25074 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
25076 check_insn(ctx
, ASE_MIPS3D
);
25079 check_cp1_enabled(ctx
);
25080 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
25081 gen_compute_branch1(ctx
, MASK_BC1(ctx
->opcode
),
25082 (rt
>> 2) & 0x7, imm
<< 2);
25089 check_cp1_enabled(ctx
);
25090 gen_farith(ctx
, ctx
->opcode
& FOP(0x3f, 0x1f), rt
, rd
, sa
,
25096 int r6_op
= ctx
->opcode
& FOP(0x3f, 0x1f);
25097 check_cp1_enabled(ctx
);
25098 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
25100 case R6_OPC_CMP_AF_S
:
25101 case R6_OPC_CMP_UN_S
:
25102 case R6_OPC_CMP_EQ_S
:
25103 case R6_OPC_CMP_UEQ_S
:
25104 case R6_OPC_CMP_LT_S
:
25105 case R6_OPC_CMP_ULT_S
:
25106 case R6_OPC_CMP_LE_S
:
25107 case R6_OPC_CMP_ULE_S
:
25108 case R6_OPC_CMP_SAF_S
:
25109 case R6_OPC_CMP_SUN_S
:
25110 case R6_OPC_CMP_SEQ_S
:
25111 case R6_OPC_CMP_SEUQ_S
:
25112 case R6_OPC_CMP_SLT_S
:
25113 case R6_OPC_CMP_SULT_S
:
25114 case R6_OPC_CMP_SLE_S
:
25115 case R6_OPC_CMP_SULE_S
:
25116 case R6_OPC_CMP_OR_S
:
25117 case R6_OPC_CMP_UNE_S
:
25118 case R6_OPC_CMP_NE_S
:
25119 case R6_OPC_CMP_SOR_S
:
25120 case R6_OPC_CMP_SUNE_S
:
25121 case R6_OPC_CMP_SNE_S
:
25122 gen_r6_cmp_s(ctx
, ctx
->opcode
& 0x1f, rt
, rd
, sa
);
25124 case R6_OPC_CMP_AF_D
:
25125 case R6_OPC_CMP_UN_D
:
25126 case R6_OPC_CMP_EQ_D
:
25127 case R6_OPC_CMP_UEQ_D
:
25128 case R6_OPC_CMP_LT_D
:
25129 case R6_OPC_CMP_ULT_D
:
25130 case R6_OPC_CMP_LE_D
:
25131 case R6_OPC_CMP_ULE_D
:
25132 case R6_OPC_CMP_SAF_D
:
25133 case R6_OPC_CMP_SUN_D
:
25134 case R6_OPC_CMP_SEQ_D
:
25135 case R6_OPC_CMP_SEUQ_D
:
25136 case R6_OPC_CMP_SLT_D
:
25137 case R6_OPC_CMP_SULT_D
:
25138 case R6_OPC_CMP_SLE_D
:
25139 case R6_OPC_CMP_SULE_D
:
25140 case R6_OPC_CMP_OR_D
:
25141 case R6_OPC_CMP_UNE_D
:
25142 case R6_OPC_CMP_NE_D
:
25143 case R6_OPC_CMP_SOR_D
:
25144 case R6_OPC_CMP_SUNE_D
:
25145 case R6_OPC_CMP_SNE_D
:
25146 gen_r6_cmp_d(ctx
, ctx
->opcode
& 0x1f, rt
, rd
, sa
);
25149 gen_farith(ctx
, ctx
->opcode
& FOP(0x3f, 0x1f),
25150 rt
, rd
, sa
, (imm
>> 8) & 0x7);
25155 gen_farith(ctx
, ctx
->opcode
& FOP(0x3f, 0x1f), rt
, rd
, sa
,
25162 gen_reserved_instruction(ctx
);
25167 /* Compact branches [R6] and COP2 [non-R6] */
25168 case OPC_BC
: /* OPC_LWC2 */
25169 case OPC_BALC
: /* OPC_SWC2 */
25170 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
25171 /* OPC_BC, OPC_BALC */
25172 gen_compute_compact_branch(ctx
, op
, 0, 0,
25173 sextract32(ctx
->opcode
<< 2, 0, 28));
25174 } else if (ctx
->insn_flags
& ASE_LEXT
) {
25175 gen_loongson_lswc2(ctx
, rt
, rs
, rd
);
25177 /* OPC_LWC2, OPC_SWC2 */
25178 /* COP2: Not implemented. */
25179 generate_exception_err(ctx
, EXCP_CpU
, 2);
25182 case OPC_BEQZC
: /* OPC_JIC, OPC_LDC2 */
25183 case OPC_BNEZC
: /* OPC_JIALC, OPC_SDC2 */
25184 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
25186 /* OPC_BEQZC, OPC_BNEZC */
25187 gen_compute_compact_branch(ctx
, op
, rs
, 0,
25188 sextract32(ctx
->opcode
<< 2, 0, 23));
25190 /* OPC_JIC, OPC_JIALC */
25191 gen_compute_compact_branch(ctx
, op
, 0, rt
, imm
);
25193 } else if (ctx
->insn_flags
& ASE_LEXT
) {
25194 gen_loongson_lsdc2(ctx
, rt
, rs
, rd
);
25196 /* OPC_LWC2, OPC_SWC2 */
25197 /* COP2: Not implemented. */
25198 generate_exception_err(ctx
, EXCP_CpU
, 2);
25202 check_insn(ctx
, ASE_LMMI
);
25203 /* Note that these instructions use different fields. */
25204 gen_loongson_multimedia(ctx
, sa
, rd
, rt
);
25208 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
25209 check_cp1_enabled(ctx
);
25210 op1
= MASK_CP3(ctx
->opcode
);
25214 check_insn(ctx
, ISA_MIPS5
| ISA_MIPS_R2
);
25220 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS_R2
);
25221 gen_flt3_ldst(ctx
, op1
, sa
, rd
, rs
, rt
);
25224 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS_R2
);
25225 /* Treat as NOP. */
25228 check_insn(ctx
, ISA_MIPS5
| ISA_MIPS_R2
);
25242 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS_R2
);
25243 gen_flt3_arith(ctx
, op1
, sa
, rs
, rd
, rt
);
25247 gen_reserved_instruction(ctx
);
25251 generate_exception_err(ctx
, EXCP_CpU
, 1);
25255 #if defined(TARGET_MIPS64)
25256 /* MIPS64 opcodes */
25258 if (ctx
->insn_flags
& INSN_R5900
) {
25259 check_insn_opc_user_only(ctx
, INSN_R5900
);
25266 check_insn(ctx
, ISA_MIPS3
);
25267 check_mips_64(ctx
);
25268 gen_ld(ctx
, op
, rt
, rs
, imm
);
25273 check_insn(ctx
, ISA_MIPS3
);
25274 check_mips_64(ctx
);
25275 gen_st(ctx
, op
, rt
, rs
, imm
);
25278 check_insn(ctx
, ISA_MIPS3
);
25279 if (ctx
->insn_flags
& INSN_R5900
) {
25280 check_insn_opc_user_only(ctx
, INSN_R5900
);
25282 check_mips_64(ctx
);
25283 gen_st_cond(ctx
, rt
, rs
, imm
, MO_TEQ
, false);
25285 case OPC_BNVC
: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */
25286 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
25287 /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */
25288 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
25291 check_insn(ctx
, ISA_MIPS3
);
25292 check_mips_64(ctx
);
25293 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
25297 check_insn(ctx
, ISA_MIPS3
);
25298 check_mips_64(ctx
);
25299 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
25302 case OPC_BNVC
: /* OPC_BNEZALC, OPC_BNEC */
25303 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
25304 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
25306 MIPS_INVAL("major opcode");
25307 gen_reserved_instruction(ctx
);
25311 case OPC_DAUI
: /* OPC_JALX */
25312 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
25313 #if defined(TARGET_MIPS64)
25315 check_mips_64(ctx
);
25317 generate_exception(ctx
, EXCP_RI
);
25318 } else if (rt
!= 0) {
25319 TCGv t0
= tcg_temp_new();
25320 gen_load_gpr(t0
, rs
);
25321 tcg_gen_addi_tl(cpu_gpr
[rt
], t0
, imm
<< 16);
25325 gen_reserved_instruction(ctx
);
25326 MIPS_INVAL("major opcode");
25330 check_insn(ctx
, ASE_MIPS16
| ASE_MICROMIPS
);
25331 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
25332 gen_compute_branch(ctx
, op
, 4, rs
, rt
, offset
, 4);
25335 case OPC_MDMX
: /* MMI_OPC_LQ */
25336 if (ctx
->insn_flags
& INSN_R5900
) {
25337 #if defined(TARGET_MIPS64)
25338 gen_mmi_lq(env
, ctx
);
25341 /* MDMX: Not implemented. */
25345 check_insn(ctx
, ISA_MIPS_R6
);
25346 gen_pcrel(ctx
, ctx
->opcode
, ctx
->base
.pc_next
, rs
);
25348 default: /* Invalid */
25349 MIPS_INVAL("major opcode");
25355 static void decode_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
25357 /* make sure instructions are on a word boundary */
25358 if (ctx
->base
.pc_next
& 0x3) {
25359 env
->CP0_BadVAddr
= ctx
->base
.pc_next
;
25360 generate_exception_err(ctx
, EXCP_AdEL
, EXCP_INST_NOTAVAIL
);
25364 /* Handle blikely not taken case */
25365 if ((ctx
->hflags
& MIPS_HFLAG_BMASK_BASE
) == MIPS_HFLAG_BL
) {
25366 TCGLabel
*l1
= gen_new_label();
25368 tcg_gen_brcondi_tl(TCG_COND_NE
, bcond
, 0, l1
);
25369 tcg_gen_movi_i32(hflags
, ctx
->hflags
& ~MIPS_HFLAG_BMASK
);
25370 gen_goto_tb(ctx
, 1, ctx
->base
.pc_next
+ 4);
25374 /* Transition to the auto-generated decoder. */
25376 /* ISA extensions */
25377 if (ase_msa_available(env
) && decode_ase_msa(ctx
, ctx
->opcode
)) {
25381 /* ISA (from latest to oldest) */
25382 if (cpu_supports_isa(env
, ISA_MIPS_R6
) && decode_isa_rel6(ctx
, ctx
->opcode
)) {
25385 if (cpu_supports_isa(env
, INSN_R5900
) && decode_ext_txx9(ctx
, ctx
->opcode
)) {
25389 if (decode_opc_legacy(env
, ctx
)) {
25393 gen_reserved_instruction(ctx
);
25396 static void mips_tr_init_disas_context(DisasContextBase
*dcbase
, CPUState
*cs
)
25398 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
25399 CPUMIPSState
*env
= cs
->env_ptr
;
25401 ctx
->page_start
= ctx
->base
.pc_first
& TARGET_PAGE_MASK
;
25402 ctx
->saved_pc
= -1;
25403 ctx
->insn_flags
= env
->insn_flags
;
25404 ctx
->CP0_Config1
= env
->CP0_Config1
;
25405 ctx
->CP0_Config2
= env
->CP0_Config2
;
25406 ctx
->CP0_Config3
= env
->CP0_Config3
;
25407 ctx
->CP0_Config5
= env
->CP0_Config5
;
25409 ctx
->kscrexist
= (env
->CP0_Config4
>> CP0C4_KScrExist
) & 0xff;
25410 ctx
->rxi
= (env
->CP0_Config3
>> CP0C3_RXI
) & 1;
25411 ctx
->ie
= (env
->CP0_Config4
>> CP0C4_IE
) & 3;
25412 ctx
->bi
= (env
->CP0_Config3
>> CP0C3_BI
) & 1;
25413 ctx
->bp
= (env
->CP0_Config3
>> CP0C3_BP
) & 1;
25414 ctx
->PAMask
= env
->PAMask
;
25415 ctx
->mvh
= (env
->CP0_Config5
>> CP0C5_MVH
) & 1;
25416 ctx
->eva
= (env
->CP0_Config5
>> CP0C5_EVA
) & 1;
25417 ctx
->sc
= (env
->CP0_Config3
>> CP0C3_SC
) & 1;
25418 ctx
->CP0_LLAddr_shift
= env
->CP0_LLAddr_shift
;
25419 ctx
->cmgcr
= (env
->CP0_Config3
>> CP0C3_CMGCR
) & 1;
25420 /* Restore delay slot state from the tb context. */
25421 ctx
->hflags
= (uint32_t)ctx
->base
.tb
->flags
; /* FIXME: maybe use 64 bits? */
25422 ctx
->ulri
= (env
->CP0_Config3
>> CP0C3_ULRI
) & 1;
25423 ctx
->ps
= ((env
->active_fpu
.fcr0
>> FCR0_PS
) & 1) ||
25424 (env
->insn_flags
& (INSN_LOONGSON2E
| INSN_LOONGSON2F
));
25425 ctx
->vp
= (env
->CP0_Config5
>> CP0C5_VP
) & 1;
25426 ctx
->mrp
= (env
->CP0_Config5
>> CP0C5_MRP
) & 1;
25427 ctx
->nan2008
= (env
->active_fpu
.fcr31
>> FCR31_NAN2008
) & 1;
25428 ctx
->abs2008
= (env
->active_fpu
.fcr31
>> FCR31_ABS2008
) & 1;
25429 ctx
->mi
= (env
->CP0_Config5
>> CP0C5_MI
) & 1;
25430 ctx
->gi
= (env
->CP0_Config5
>> CP0C5_GI
) & 3;
25431 restore_cpu_state(env
, ctx
);
25432 #ifdef CONFIG_USER_ONLY
25433 ctx
->mem_idx
= MIPS_HFLAG_UM
;
25435 ctx
->mem_idx
= hflags_mmu_index(ctx
->hflags
);
25437 ctx
->default_tcg_memop_mask
= (ctx
->insn_flags
& (ISA_MIPS_R6
|
25438 INSN_LOONGSON3A
)) ? MO_UNALN
: MO_ALIGN
;
25440 LOG_DISAS("\ntb %p idx %d hflags %04x\n", ctx
->base
.tb
, ctx
->mem_idx
,
25444 static void mips_tr_tb_start(DisasContextBase
*dcbase
, CPUState
*cs
)
25448 static void mips_tr_insn_start(DisasContextBase
*dcbase
, CPUState
*cs
)
25450 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
25452 tcg_gen_insn_start(ctx
->base
.pc_next
, ctx
->hflags
& MIPS_HFLAG_BMASK
,
25456 static bool mips_tr_breakpoint_check(DisasContextBase
*dcbase
, CPUState
*cs
,
25457 const CPUBreakpoint
*bp
)
25459 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
25461 save_cpu_state(ctx
, 1);
25462 ctx
->base
.is_jmp
= DISAS_NORETURN
;
25463 gen_helper_raise_exception_debug(cpu_env
);
25465 * The address covered by the breakpoint must be included in
25466 * [tb->pc, tb->pc + tb->size) in order to for it to be
25467 * properly cleared -- thus we increment the PC here so that
25468 * the logic setting tb->size below does the right thing.
25470 ctx
->base
.pc_next
+= 4;
25474 static void mips_tr_translate_insn(DisasContextBase
*dcbase
, CPUState
*cs
)
25476 CPUMIPSState
*env
= cs
->env_ptr
;
25477 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
25481 is_slot
= ctx
->hflags
& MIPS_HFLAG_BMASK
;
25482 if (ctx
->insn_flags
& ISA_NANOMIPS32
) {
25483 ctx
->opcode
= translator_lduw(env
, ctx
->base
.pc_next
);
25484 insn_bytes
= decode_nanomips_opc(env
, ctx
);
25485 } else if (!(ctx
->hflags
& MIPS_HFLAG_M16
)) {
25486 ctx
->opcode
= translator_ldl(env
, ctx
->base
.pc_next
);
25488 decode_opc(env
, ctx
);
25489 } else if (ctx
->insn_flags
& ASE_MICROMIPS
) {
25490 ctx
->opcode
= translator_lduw(env
, ctx
->base
.pc_next
);
25491 insn_bytes
= decode_micromips_opc(env
, ctx
);
25492 } else if (ctx
->insn_flags
& ASE_MIPS16
) {
25493 ctx
->opcode
= translator_lduw(env
, ctx
->base
.pc_next
);
25494 insn_bytes
= decode_mips16_opc(env
, ctx
);
25496 gen_reserved_instruction(ctx
);
25497 g_assert(ctx
->base
.is_jmp
== DISAS_NORETURN
);
25501 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
25502 if (!(ctx
->hflags
& (MIPS_HFLAG_BDS16
| MIPS_HFLAG_BDS32
|
25503 MIPS_HFLAG_FBNSLOT
))) {
25505 * Force to generate branch as there is neither delay nor
25510 if ((ctx
->hflags
& MIPS_HFLAG_M16
) &&
25511 (ctx
->hflags
& MIPS_HFLAG_FBNSLOT
)) {
25513 * Force to generate branch as microMIPS R6 doesn't restrict
25514 * branches in the forbidden slot.
25520 gen_branch(ctx
, insn_bytes
);
25522 ctx
->base
.pc_next
+= insn_bytes
;
25524 if (ctx
->base
.is_jmp
!= DISAS_NEXT
) {
25528 * Execute a branch and its delay slot as a single instruction.
25529 * This is what GDB expects and is consistent with what the
25530 * hardware does (e.g. if a delay slot instruction faults, the
25531 * reported PC is the PC of the branch).
25533 if (ctx
->base
.singlestep_enabled
&&
25534 (ctx
->hflags
& MIPS_HFLAG_BMASK
) == 0) {
25535 ctx
->base
.is_jmp
= DISAS_TOO_MANY
;
25537 if (ctx
->base
.pc_next
- ctx
->page_start
>= TARGET_PAGE_SIZE
) {
25538 ctx
->base
.is_jmp
= DISAS_TOO_MANY
;
25542 static void mips_tr_tb_stop(DisasContextBase
*dcbase
, CPUState
*cs
)
25544 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
25546 if (ctx
->base
.singlestep_enabled
&& ctx
->base
.is_jmp
!= DISAS_NORETURN
) {
25547 save_cpu_state(ctx
, ctx
->base
.is_jmp
!= DISAS_EXIT
);
25548 gen_helper_raise_exception_debug(cpu_env
);
25550 switch (ctx
->base
.is_jmp
) {
25552 gen_save_pc(ctx
->base
.pc_next
);
25553 tcg_gen_lookup_and_goto_ptr();
25556 case DISAS_TOO_MANY
:
25557 save_cpu_state(ctx
, 0);
25558 gen_goto_tb(ctx
, 0, ctx
->base
.pc_next
);
25561 tcg_gen_exit_tb(NULL
, 0);
25563 case DISAS_NORETURN
:
25566 g_assert_not_reached();
25571 static void mips_tr_disas_log(const DisasContextBase
*dcbase
, CPUState
*cs
)
25573 qemu_log("IN: %s\n", lookup_symbol(dcbase
->pc_first
));
25574 log_target_disas(cs
, dcbase
->pc_first
, dcbase
->tb
->size
);
25577 static const TranslatorOps mips_tr_ops
= {
25578 .init_disas_context
= mips_tr_init_disas_context
,
25579 .tb_start
= mips_tr_tb_start
,
25580 .insn_start
= mips_tr_insn_start
,
25581 .breakpoint_check
= mips_tr_breakpoint_check
,
25582 .translate_insn
= mips_tr_translate_insn
,
25583 .tb_stop
= mips_tr_tb_stop
,
25584 .disas_log
= mips_tr_disas_log
,
25587 void gen_intermediate_code(CPUState
*cs
, TranslationBlock
*tb
, int max_insns
)
25591 translator_loop(&mips_tr_ops
, &ctx
.base
, cs
, tb
, max_insns
);
25594 static void fpu_dump_state(CPUMIPSState
*env
, FILE * f
, int flags
)
25597 int is_fpu64
= !!(env
->hflags
& MIPS_HFLAG_F64
);
25599 #define printfpr(fp) \
25602 qemu_fprintf(f, "w:%08x d:%016" PRIx64 \
25603 " fd:%13g fs:%13g psu: %13g\n", \
25604 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
25605 (double)(fp)->fd, \
25606 (double)(fp)->fs[FP_ENDIAN_IDX], \
25607 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
25610 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
25611 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
25612 qemu_fprintf(f, "w:%08x d:%016" PRIx64 \
25613 " fd:%13g fs:%13g psu:%13g\n", \
25614 tmp.w[FP_ENDIAN_IDX], tmp.d, \
25616 (double)tmp.fs[FP_ENDIAN_IDX], \
25617 (double)tmp.fs[!FP_ENDIAN_IDX]); \
25623 "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
25624 env
->active_fpu
.fcr0
, env
->active_fpu
.fcr31
, is_fpu64
,
25625 get_float_exception_flags(&env
->active_fpu
.fp_status
));
25626 for (i
= 0; i
< 32; (is_fpu64
) ? i
++ : (i
+= 2)) {
25627 qemu_fprintf(f
, "%3s: ", fregnames
[i
]);
25628 printfpr(&env
->active_fpu
.fpr
[i
]);
25634 void mips_cpu_dump_state(CPUState
*cs
, FILE *f
, int flags
)
25636 MIPSCPU
*cpu
= MIPS_CPU(cs
);
25637 CPUMIPSState
*env
= &cpu
->env
;
25640 qemu_fprintf(f
, "pc=0x" TARGET_FMT_lx
" HI=0x" TARGET_FMT_lx
25641 " LO=0x" TARGET_FMT_lx
" ds %04x "
25642 TARGET_FMT_lx
" " TARGET_FMT_ld
"\n",
25643 env
->active_tc
.PC
, env
->active_tc
.HI
[0], env
->active_tc
.LO
[0],
25644 env
->hflags
, env
->btarget
, env
->bcond
);
25645 for (i
= 0; i
< 32; i
++) {
25646 if ((i
& 3) == 0) {
25647 qemu_fprintf(f
, "GPR%02d:", i
);
25649 qemu_fprintf(f
, " %s " TARGET_FMT_lx
,
25650 regnames
[i
], env
->active_tc
.gpr
[i
]);
25651 if ((i
& 3) == 3) {
25652 qemu_fprintf(f
, "\n");
25656 qemu_fprintf(f
, "CP0 Status 0x%08x Cause 0x%08x EPC 0x"
25657 TARGET_FMT_lx
"\n",
25658 env
->CP0_Status
, env
->CP0_Cause
, env
->CP0_EPC
);
25659 qemu_fprintf(f
, " Config0 0x%08x Config1 0x%08x LLAddr 0x%016"
25661 env
->CP0_Config0
, env
->CP0_Config1
, env
->CP0_LLAddr
);
25662 qemu_fprintf(f
, " Config2 0x%08x Config3 0x%08x\n",
25663 env
->CP0_Config2
, env
->CP0_Config3
);
25664 qemu_fprintf(f
, " Config4 0x%08x Config5 0x%08x\n",
25665 env
->CP0_Config4
, env
->CP0_Config5
);
25666 if ((flags
& CPU_DUMP_FPU
) && (env
->hflags
& MIPS_HFLAG_FPU
)) {
25667 fpu_dump_state(env
, f
, flags
);
25671 void mips_tcg_init(void)
25676 for (i
= 1; i
< 32; i
++)
25677 cpu_gpr
[i
] = tcg_global_mem_new(cpu_env
,
25678 offsetof(CPUMIPSState
,
25681 #if defined(TARGET_MIPS64)
25682 cpu_gpr_hi
[0] = NULL
;
25684 for (unsigned i
= 1; i
< 32; i
++) {
25685 g_autofree
char *rname
= g_strdup_printf("%s[hi]", regnames
[i
]);
25687 cpu_gpr_hi
[i
] = tcg_global_mem_new_i64(cpu_env
,
25688 offsetof(CPUMIPSState
,
25689 active_tc
.gpr_hi
[i
]),
25692 #endif /* !TARGET_MIPS64 */
25693 for (i
= 0; i
< 32; i
++) {
25694 int off
= offsetof(CPUMIPSState
, active_fpu
.fpr
[i
].wr
.d
[0]);
25696 fpu_f64
[i
] = tcg_global_mem_new_i64(cpu_env
, off
, fregnames
[i
]);
25698 msa_translate_init();
25699 cpu_PC
= tcg_global_mem_new(cpu_env
,
25700 offsetof(CPUMIPSState
, active_tc
.PC
), "PC");
25701 for (i
= 0; i
< MIPS_DSP_ACC
; i
++) {
25702 cpu_HI
[i
] = tcg_global_mem_new(cpu_env
,
25703 offsetof(CPUMIPSState
, active_tc
.HI
[i
]),
25705 cpu_LO
[i
] = tcg_global_mem_new(cpu_env
,
25706 offsetof(CPUMIPSState
, active_tc
.LO
[i
]),
25709 cpu_dspctrl
= tcg_global_mem_new(cpu_env
,
25710 offsetof(CPUMIPSState
,
25711 active_tc
.DSPControl
),
25713 bcond
= tcg_global_mem_new(cpu_env
,
25714 offsetof(CPUMIPSState
, bcond
), "bcond");
25715 btarget
= tcg_global_mem_new(cpu_env
,
25716 offsetof(CPUMIPSState
, btarget
), "btarget");
25717 hflags
= tcg_global_mem_new_i32(cpu_env
,
25718 offsetof(CPUMIPSState
, hflags
), "hflags");
25720 fpu_fcr0
= tcg_global_mem_new_i32(cpu_env
,
25721 offsetof(CPUMIPSState
, active_fpu
.fcr0
),
25723 fpu_fcr31
= tcg_global_mem_new_i32(cpu_env
,
25724 offsetof(CPUMIPSState
, active_fpu
.fcr31
),
25726 cpu_lladdr
= tcg_global_mem_new(cpu_env
, offsetof(CPUMIPSState
, lladdr
),
25728 cpu_llval
= tcg_global_mem_new(cpu_env
, offsetof(CPUMIPSState
, llval
),
25731 if (TARGET_LONG_BITS
== 32) {
25732 mxu_translate_init();
25736 void restore_state_to_opc(CPUMIPSState
*env
, TranslationBlock
*tb
,
25737 target_ulong
*data
)
25739 env
->active_tc
.PC
= data
[0];
25740 env
->hflags
&= ~MIPS_HFLAG_BMASK
;
25741 env
->hflags
|= data
[1];
25742 switch (env
->hflags
& MIPS_HFLAG_BMASK_BASE
) {
25743 case MIPS_HFLAG_BR
:
25745 case MIPS_HFLAG_BC
:
25746 case MIPS_HFLAG_BL
:
25748 env
->btarget
= data
[2];