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_HI
[] = {
1271 "HI0", "HI1", "HI2", "HI3",
1274 static const char * const regnames_LO
[] = {
1275 "LO0", "LO1", "LO2", "LO3",
1278 /* General purpose registers moves. */
1279 void gen_load_gpr(TCGv t
, int reg
)
1282 tcg_gen_movi_tl(t
, 0);
1284 tcg_gen_mov_tl(t
, cpu_gpr
[reg
]);
1288 void gen_store_gpr(TCGv t
, int reg
)
1291 tcg_gen_mov_tl(cpu_gpr
[reg
], t
);
1295 #if defined(TARGET_MIPS64)
1296 void gen_load_gpr_hi(TCGv_i64 t
, int reg
)
1299 tcg_gen_movi_i64(t
, 0);
1301 tcg_gen_mov_i64(t
, cpu_gpr_hi
[reg
]);
1305 void gen_store_gpr_hi(TCGv_i64 t
, int reg
)
1308 tcg_gen_mov_i64(cpu_gpr_hi
[reg
], t
);
1311 #endif /* TARGET_MIPS64 */
1313 /* Moves to/from shadow registers. */
1314 static inline void gen_load_srsgpr(int from
, int to
)
1316 TCGv t0
= tcg_temp_new();
1319 tcg_gen_movi_tl(t0
, 0);
1321 TCGv_i32 t2
= tcg_temp_new_i32();
1322 TCGv_ptr addr
= tcg_temp_new_ptr();
1324 tcg_gen_ld_i32(t2
, cpu_env
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
1325 tcg_gen_shri_i32(t2
, t2
, CP0SRSCtl_PSS
);
1326 tcg_gen_andi_i32(t2
, t2
, 0xf);
1327 tcg_gen_muli_i32(t2
, t2
, sizeof(target_ulong
) * 32);
1328 tcg_gen_ext_i32_ptr(addr
, t2
);
1329 tcg_gen_add_ptr(addr
, cpu_env
, addr
);
1331 tcg_gen_ld_tl(t0
, addr
, sizeof(target_ulong
) * from
);
1332 tcg_temp_free_ptr(addr
);
1333 tcg_temp_free_i32(t2
);
1335 gen_store_gpr(t0
, to
);
1339 static inline void gen_store_srsgpr(int from
, int to
)
1342 TCGv t0
= tcg_temp_new();
1343 TCGv_i32 t2
= tcg_temp_new_i32();
1344 TCGv_ptr addr
= tcg_temp_new_ptr();
1346 gen_load_gpr(t0
, from
);
1347 tcg_gen_ld_i32(t2
, cpu_env
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
1348 tcg_gen_shri_i32(t2
, t2
, CP0SRSCtl_PSS
);
1349 tcg_gen_andi_i32(t2
, t2
, 0xf);
1350 tcg_gen_muli_i32(t2
, t2
, sizeof(target_ulong
) * 32);
1351 tcg_gen_ext_i32_ptr(addr
, t2
);
1352 tcg_gen_add_ptr(addr
, cpu_env
, addr
);
1354 tcg_gen_st_tl(t0
, addr
, sizeof(target_ulong
) * to
);
1355 tcg_temp_free_ptr(addr
);
1356 tcg_temp_free_i32(t2
);
1362 static inline void gen_save_pc(target_ulong pc
)
1364 tcg_gen_movi_tl(cpu_PC
, pc
);
1367 static inline void save_cpu_state(DisasContext
*ctx
, int do_save_pc
)
1369 LOG_DISAS("hflags %08x saved %08x\n", ctx
->hflags
, ctx
->saved_hflags
);
1370 if (do_save_pc
&& ctx
->base
.pc_next
!= ctx
->saved_pc
) {
1371 gen_save_pc(ctx
->base
.pc_next
);
1372 ctx
->saved_pc
= ctx
->base
.pc_next
;
1374 if (ctx
->hflags
!= ctx
->saved_hflags
) {
1375 tcg_gen_movi_i32(hflags
, ctx
->hflags
);
1376 ctx
->saved_hflags
= ctx
->hflags
;
1377 switch (ctx
->hflags
& MIPS_HFLAG_BMASK_BASE
) {
1383 tcg_gen_movi_tl(btarget
, ctx
->btarget
);
1389 static inline void restore_cpu_state(CPUMIPSState
*env
, DisasContext
*ctx
)
1391 ctx
->saved_hflags
= ctx
->hflags
;
1392 switch (ctx
->hflags
& MIPS_HFLAG_BMASK_BASE
) {
1398 ctx
->btarget
= env
->btarget
;
1403 void generate_exception_err(DisasContext
*ctx
, int excp
, int err
)
1405 TCGv_i32 texcp
= tcg_const_i32(excp
);
1406 TCGv_i32 terr
= tcg_const_i32(err
);
1407 save_cpu_state(ctx
, 1);
1408 gen_helper_raise_exception_err(cpu_env
, texcp
, terr
);
1409 tcg_temp_free_i32(terr
);
1410 tcg_temp_free_i32(texcp
);
1411 ctx
->base
.is_jmp
= DISAS_NORETURN
;
1414 void generate_exception(DisasContext
*ctx
, int excp
)
1416 gen_helper_0e0i(raise_exception
, excp
);
1419 void generate_exception_end(DisasContext
*ctx
, int excp
)
1421 generate_exception_err(ctx
, excp
, 0);
1424 void gen_reserved_instruction(DisasContext
*ctx
)
1426 generate_exception_end(ctx
, EXCP_RI
);
1429 /* Floating point register moves. */
1430 void gen_load_fpr32(DisasContext
*ctx
, TCGv_i32 t
, int reg
)
1432 if (ctx
->hflags
& MIPS_HFLAG_FRE
) {
1433 generate_exception(ctx
, EXCP_RI
);
1435 tcg_gen_extrl_i64_i32(t
, fpu_f64
[reg
]);
1438 void gen_store_fpr32(DisasContext
*ctx
, TCGv_i32 t
, int reg
)
1441 if (ctx
->hflags
& MIPS_HFLAG_FRE
) {
1442 generate_exception(ctx
, EXCP_RI
);
1444 t64
= tcg_temp_new_i64();
1445 tcg_gen_extu_i32_i64(t64
, t
);
1446 tcg_gen_deposit_i64(fpu_f64
[reg
], fpu_f64
[reg
], t64
, 0, 32);
1447 tcg_temp_free_i64(t64
);
1450 static void gen_load_fpr32h(DisasContext
*ctx
, TCGv_i32 t
, int reg
)
1452 if (ctx
->hflags
& MIPS_HFLAG_F64
) {
1453 tcg_gen_extrh_i64_i32(t
, fpu_f64
[reg
]);
1455 gen_load_fpr32(ctx
, t
, reg
| 1);
1459 static void gen_store_fpr32h(DisasContext
*ctx
, TCGv_i32 t
, int reg
)
1461 if (ctx
->hflags
& MIPS_HFLAG_F64
) {
1462 TCGv_i64 t64
= tcg_temp_new_i64();
1463 tcg_gen_extu_i32_i64(t64
, t
);
1464 tcg_gen_deposit_i64(fpu_f64
[reg
], fpu_f64
[reg
], t64
, 32, 32);
1465 tcg_temp_free_i64(t64
);
1467 gen_store_fpr32(ctx
, t
, reg
| 1);
1471 void gen_load_fpr64(DisasContext
*ctx
, TCGv_i64 t
, int reg
)
1473 if (ctx
->hflags
& MIPS_HFLAG_F64
) {
1474 tcg_gen_mov_i64(t
, fpu_f64
[reg
]);
1476 tcg_gen_concat32_i64(t
, fpu_f64
[reg
& ~1], fpu_f64
[reg
| 1]);
1480 void gen_store_fpr64(DisasContext
*ctx
, TCGv_i64 t
, int reg
)
1482 if (ctx
->hflags
& MIPS_HFLAG_F64
) {
1483 tcg_gen_mov_i64(fpu_f64
[reg
], t
);
1486 tcg_gen_deposit_i64(fpu_f64
[reg
& ~1], fpu_f64
[reg
& ~1], t
, 0, 32);
1487 t0
= tcg_temp_new_i64();
1488 tcg_gen_shri_i64(t0
, t
, 32);
1489 tcg_gen_deposit_i64(fpu_f64
[reg
| 1], fpu_f64
[reg
| 1], t0
, 0, 32);
1490 tcg_temp_free_i64(t0
);
1494 int get_fp_bit(int cc
)
1503 /* Addresses computation */
1504 void gen_op_addr_add(DisasContext
*ctx
, TCGv ret
, TCGv arg0
, TCGv arg1
)
1506 tcg_gen_add_tl(ret
, arg0
, arg1
);
1508 #if defined(TARGET_MIPS64)
1509 if (ctx
->hflags
& MIPS_HFLAG_AWRAP
) {
1510 tcg_gen_ext32s_i64(ret
, ret
);
1515 static inline void gen_op_addr_addi(DisasContext
*ctx
, TCGv ret
, TCGv base
,
1518 tcg_gen_addi_tl(ret
, base
, ofs
);
1520 #if defined(TARGET_MIPS64)
1521 if (ctx
->hflags
& MIPS_HFLAG_AWRAP
) {
1522 tcg_gen_ext32s_i64(ret
, ret
);
1527 /* Addresses computation (translation time) */
1528 static target_long
addr_add(DisasContext
*ctx
, target_long base
,
1531 target_long sum
= base
+ offset
;
1533 #if defined(TARGET_MIPS64)
1534 if (ctx
->hflags
& MIPS_HFLAG_AWRAP
) {
1541 /* Sign-extract the low 32-bits to a target_long. */
1542 void gen_move_low32(TCGv ret
, TCGv_i64 arg
)
1544 #if defined(TARGET_MIPS64)
1545 tcg_gen_ext32s_i64(ret
, arg
);
1547 tcg_gen_extrl_i64_i32(ret
, arg
);
1551 /* Sign-extract the high 32-bits to a target_long. */
1552 void gen_move_high32(TCGv ret
, TCGv_i64 arg
)
1554 #if defined(TARGET_MIPS64)
1555 tcg_gen_sari_i64(ret
, arg
, 32);
1557 tcg_gen_extrh_i64_i32(ret
, arg
);
1561 bool check_cp0_enabled(DisasContext
*ctx
)
1563 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_CP0
))) {
1564 generate_exception_end(ctx
, EXCP_CpU
);
1570 void check_cp1_enabled(DisasContext
*ctx
)
1572 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_FPU
))) {
1573 generate_exception_err(ctx
, EXCP_CpU
, 1);
1578 * Verify that the processor is running with COP1X instructions enabled.
1579 * This is associated with the nabla symbol in the MIPS32 and MIPS64
1582 void check_cop1x(DisasContext
*ctx
)
1584 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_COP1X
))) {
1585 gen_reserved_instruction(ctx
);
1590 * Verify that the processor is running with 64-bit floating-point
1591 * operations enabled.
1593 void check_cp1_64bitmode(DisasContext
*ctx
)
1595 if (unlikely(~ctx
->hflags
& (MIPS_HFLAG_F64
| MIPS_HFLAG_COP1X
))) {
1596 gen_reserved_instruction(ctx
);
1601 * Verify if floating point register is valid; an operation is not defined
1602 * if bit 0 of any register specification is set and the FR bit in the
1603 * Status register equals zero, since the register numbers specify an
1604 * even-odd pair of adjacent coprocessor general registers. When the FR bit
1605 * in the Status register equals one, both even and odd register numbers
1606 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
1608 * Multiple 64 bit wide registers can be checked by calling
1609 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
1611 void check_cp1_registers(DisasContext
*ctx
, int regs
)
1613 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_F64
) && (regs
& 1))) {
1614 gen_reserved_instruction(ctx
);
1619 * Verify that the processor is running with DSP instructions enabled.
1620 * This is enabled by CP0 Status register MX(24) bit.
1622 static inline void check_dsp(DisasContext
*ctx
)
1624 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_DSP
))) {
1625 if (ctx
->insn_flags
& ASE_DSP
) {
1626 generate_exception_end(ctx
, EXCP_DSPDIS
);
1628 gen_reserved_instruction(ctx
);
1633 static inline void check_dsp_r2(DisasContext
*ctx
)
1635 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_DSP_R2
))) {
1636 if (ctx
->insn_flags
& ASE_DSP
) {
1637 generate_exception_end(ctx
, EXCP_DSPDIS
);
1639 gen_reserved_instruction(ctx
);
1644 static inline void check_dsp_r3(DisasContext
*ctx
)
1646 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_DSP_R3
))) {
1647 if (ctx
->insn_flags
& ASE_DSP
) {
1648 generate_exception_end(ctx
, EXCP_DSPDIS
);
1650 gen_reserved_instruction(ctx
);
1656 * This code generates a "reserved instruction" exception if the
1657 * CPU does not support the instruction set corresponding to flags.
1659 void check_insn(DisasContext
*ctx
, uint64_t flags
)
1661 if (unlikely(!(ctx
->insn_flags
& flags
))) {
1662 gen_reserved_instruction(ctx
);
1667 * This code generates a "reserved instruction" exception if the
1668 * CPU has corresponding flag set which indicates that the instruction
1671 static inline void check_insn_opc_removed(DisasContext
*ctx
, uint64_t flags
)
1673 if (unlikely(ctx
->insn_flags
& flags
)) {
1674 gen_reserved_instruction(ctx
);
1679 * The Linux kernel traps certain reserved instruction exceptions to
1680 * emulate the corresponding instructions. QEMU is the kernel in user
1681 * mode, so those traps are emulated by accepting the instructions.
1683 * A reserved instruction exception is generated for flagged CPUs if
1684 * QEMU runs in system mode.
1686 static inline void check_insn_opc_user_only(DisasContext
*ctx
, uint64_t flags
)
1688 #ifndef CONFIG_USER_ONLY
1689 check_insn_opc_removed(ctx
, flags
);
1694 * This code generates a "reserved instruction" exception if the
1695 * CPU does not support 64-bit paired-single (PS) floating point data type.
1697 static inline void check_ps(DisasContext
*ctx
)
1699 if (unlikely(!ctx
->ps
)) {
1700 generate_exception(ctx
, EXCP_RI
);
1702 check_cp1_64bitmode(ctx
);
1706 * This code generates a "reserved instruction" exception if cpu is not
1707 * 64-bit or 64-bit instructions are not enabled.
1709 void check_mips_64(DisasContext
*ctx
)
1711 if (unlikely((TARGET_LONG_BITS
!= 64) || !(ctx
->hflags
& MIPS_HFLAG_64
))) {
1712 gen_reserved_instruction(ctx
);
1716 #ifndef CONFIG_USER_ONLY
1717 static inline void check_mvh(DisasContext
*ctx
)
1719 if (unlikely(!ctx
->mvh
)) {
1720 generate_exception(ctx
, EXCP_RI
);
1726 * This code generates a "reserved instruction" exception if the
1727 * Config5 XNP bit is set.
1729 static inline void check_xnp(DisasContext
*ctx
)
1731 if (unlikely(ctx
->CP0_Config5
& (1 << CP0C5_XNP
))) {
1732 gen_reserved_instruction(ctx
);
1736 #ifndef CONFIG_USER_ONLY
1738 * This code generates a "reserved instruction" exception if the
1739 * Config3 PW bit is NOT set.
1741 static inline void check_pw(DisasContext
*ctx
)
1743 if (unlikely(!(ctx
->CP0_Config3
& (1 << CP0C3_PW
)))) {
1744 gen_reserved_instruction(ctx
);
1750 * This code generates a "reserved instruction" exception if the
1751 * Config3 MT bit is NOT set.
1753 static inline void check_mt(DisasContext
*ctx
)
1755 if (unlikely(!(ctx
->CP0_Config3
& (1 << CP0C3_MT
)))) {
1756 gen_reserved_instruction(ctx
);
1760 #ifndef CONFIG_USER_ONLY
1762 * This code generates a "coprocessor unusable" exception if CP0 is not
1763 * available, and, if that is not the case, generates a "reserved instruction"
1764 * exception if the Config5 MT bit is NOT set. This is needed for availability
1765 * control of some of MT ASE instructions.
1767 static inline void check_cp0_mt(DisasContext
*ctx
)
1769 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_CP0
))) {
1770 generate_exception_end(ctx
, EXCP_CpU
);
1772 if (unlikely(!(ctx
->CP0_Config3
& (1 << CP0C3_MT
)))) {
1773 gen_reserved_instruction(ctx
);
1780 * This code generates a "reserved instruction" exception if the
1781 * Config5 NMS bit is set.
1783 static inline void check_nms(DisasContext
*ctx
)
1785 if (unlikely(ctx
->CP0_Config5
& (1 << CP0C5_NMS
))) {
1786 gen_reserved_instruction(ctx
);
1791 * This code generates a "reserved instruction" exception if the
1792 * Config5 NMS bit is set, and Config1 DL, Config1 IL, Config2 SL,
1793 * Config2 TL, and Config5 L2C are unset.
1795 static inline void check_nms_dl_il_sl_tl_l2c(DisasContext
*ctx
)
1797 if (unlikely((ctx
->CP0_Config5
& (1 << CP0C5_NMS
)) &&
1798 !(ctx
->CP0_Config1
& (1 << CP0C1_DL
)) &&
1799 !(ctx
->CP0_Config1
& (1 << CP0C1_IL
)) &&
1800 !(ctx
->CP0_Config2
& (1 << CP0C2_SL
)) &&
1801 !(ctx
->CP0_Config2
& (1 << CP0C2_TL
)) &&
1802 !(ctx
->CP0_Config5
& (1 << CP0C5_L2C
)))) {
1803 gen_reserved_instruction(ctx
);
1808 * This code generates a "reserved instruction" exception if the
1809 * Config5 EVA bit is NOT set.
1811 static inline void check_eva(DisasContext
*ctx
)
1813 if (unlikely(!(ctx
->CP0_Config5
& (1 << CP0C5_EVA
)))) {
1814 gen_reserved_instruction(ctx
);
1820 * Define small wrappers for gen_load_fpr* so that we have a uniform
1821 * calling interface for 32 and 64-bit FPRs. No sense in changing
1822 * all callers for gen_load_fpr32 when we need the CTX parameter for
1825 #define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(ctx, x, y)
1826 #define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
1827 #define FOP_CONDS(type, abs, fmt, ifmt, bits) \
1828 static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
1829 int ft, int fs, int cc) \
1831 TCGv_i##bits fp0 = tcg_temp_new_i##bits(); \
1832 TCGv_i##bits fp1 = tcg_temp_new_i##bits(); \
1841 check_cp1_registers(ctx, fs | ft); \
1849 gen_ldcmp_fpr##bits(ctx, fp0, fs); \
1850 gen_ldcmp_fpr##bits(ctx, fp1, ft); \
1853 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); \
1856 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); \
1859 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); \
1862 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); \
1865 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); \
1868 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); \
1871 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); \
1874 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); \
1877 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); \
1880 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); \
1883 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); \
1886 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); \
1889 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); \
1892 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); \
1895 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); \
1898 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); \
1903 tcg_temp_free_i##bits(fp0); \
1904 tcg_temp_free_i##bits(fp1); \
1907 FOP_CONDS(, 0, d
, FMT_D
, 64)
1908 FOP_CONDS(abs
, 1, d
, FMT_D
, 64)
1909 FOP_CONDS(, 0, s
, FMT_S
, 32)
1910 FOP_CONDS(abs
, 1, s
, FMT_S
, 32)
1911 FOP_CONDS(, 0, ps
, FMT_PS
, 64)
1912 FOP_CONDS(abs
, 1, ps
, FMT_PS
, 64)
1915 #define FOP_CONDNS(fmt, ifmt, bits, STORE) \
1916 static inline void gen_r6_cmp_ ## fmt(DisasContext *ctx, int n, \
1917 int ft, int fs, int fd) \
1919 TCGv_i ## bits fp0 = tcg_temp_new_i ## bits(); \
1920 TCGv_i ## bits fp1 = tcg_temp_new_i ## bits(); \
1921 if (ifmt == FMT_D) { \
1922 check_cp1_registers(ctx, fs | ft | fd); \
1924 gen_ldcmp_fpr ## bits(ctx, fp0, fs); \
1925 gen_ldcmp_fpr ## bits(ctx, fp1, ft); \
1928 gen_helper_r6_cmp_ ## fmt ## _af(fp0, cpu_env, fp0, fp1); \
1931 gen_helper_r6_cmp_ ## fmt ## _un(fp0, cpu_env, fp0, fp1); \
1934 gen_helper_r6_cmp_ ## fmt ## _eq(fp0, cpu_env, fp0, fp1); \
1937 gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, cpu_env, fp0, fp1); \
1940 gen_helper_r6_cmp_ ## fmt ## _lt(fp0, cpu_env, fp0, fp1); \
1943 gen_helper_r6_cmp_ ## fmt ## _ult(fp0, cpu_env, fp0, fp1); \
1946 gen_helper_r6_cmp_ ## fmt ## _le(fp0, cpu_env, fp0, fp1); \
1949 gen_helper_r6_cmp_ ## fmt ## _ule(fp0, cpu_env, fp0, fp1); \
1952 gen_helper_r6_cmp_ ## fmt ## _saf(fp0, cpu_env, fp0, fp1); \
1955 gen_helper_r6_cmp_ ## fmt ## _sun(fp0, cpu_env, fp0, fp1); \
1958 gen_helper_r6_cmp_ ## fmt ## _seq(fp0, cpu_env, fp0, fp1); \
1961 gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, cpu_env, fp0, fp1); \
1964 gen_helper_r6_cmp_ ## fmt ## _slt(fp0, cpu_env, fp0, fp1); \
1967 gen_helper_r6_cmp_ ## fmt ## _sult(fp0, cpu_env, fp0, fp1); \
1970 gen_helper_r6_cmp_ ## fmt ## _sle(fp0, cpu_env, fp0, fp1); \
1973 gen_helper_r6_cmp_ ## fmt ## _sule(fp0, cpu_env, fp0, fp1); \
1976 gen_helper_r6_cmp_ ## fmt ## _or(fp0, cpu_env, fp0, fp1); \
1979 gen_helper_r6_cmp_ ## fmt ## _une(fp0, cpu_env, fp0, fp1); \
1982 gen_helper_r6_cmp_ ## fmt ## _ne(fp0, cpu_env, fp0, fp1); \
1985 gen_helper_r6_cmp_ ## fmt ## _sor(fp0, cpu_env, fp0, fp1); \
1988 gen_helper_r6_cmp_ ## fmt ## _sune(fp0, cpu_env, fp0, fp1); \
1991 gen_helper_r6_cmp_ ## fmt ## _sne(fp0, cpu_env, fp0, fp1); \
1997 tcg_temp_free_i ## bits(fp0); \
1998 tcg_temp_free_i ## bits(fp1); \
2001 FOP_CONDNS(d
, FMT_D
, 64, gen_store_fpr64(ctx
, fp0
, fd
))
2002 FOP_CONDNS(s
, FMT_S
, 32, gen_store_fpr32(ctx
, fp0
, fd
))
2004 #undef gen_ldcmp_fpr32
2005 #undef gen_ldcmp_fpr64
2007 /* load/store instructions. */
2008 #ifdef CONFIG_USER_ONLY
2009 #define OP_LD_ATOMIC(insn, fname) \
2010 static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \
2011 DisasContext *ctx) \
2013 TCGv t0 = tcg_temp_new(); \
2014 tcg_gen_mov_tl(t0, arg1); \
2015 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
2016 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
2017 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
2018 tcg_temp_free(t0); \
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 gen_helper_1e1i(insn, ret, arg1, mem_idx); \
2028 OP_LD_ATOMIC(ll
, ld32s
);
2029 #if defined(TARGET_MIPS64)
2030 OP_LD_ATOMIC(lld
, ld64
);
2034 void gen_base_offset_addr(DisasContext
*ctx
, TCGv addr
, int base
, int offset
)
2037 tcg_gen_movi_tl(addr
, offset
);
2038 } else if (offset
== 0) {
2039 gen_load_gpr(addr
, base
);
2041 tcg_gen_movi_tl(addr
, offset
);
2042 gen_op_addr_add(ctx
, addr
, cpu_gpr
[base
], addr
);
2046 static target_ulong
pc_relative_pc(DisasContext
*ctx
)
2048 target_ulong pc
= ctx
->base
.pc_next
;
2050 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
2051 int branch_bytes
= ctx
->hflags
& MIPS_HFLAG_BDS16
? 2 : 4;
2056 pc
&= ~(target_ulong
)3;
2061 static void gen_ld(DisasContext
*ctx
, uint32_t opc
,
2062 int rt
, int base
, int offset
)
2065 int mem_idx
= ctx
->mem_idx
;
2067 if (rt
== 0 && ctx
->insn_flags
& (INSN_LOONGSON2E
| INSN_LOONGSON2F
|
2070 * Loongson CPU uses a load to zero register for prefetch.
2071 * We emulate it as a NOP. On other CPU we must perform the
2072 * actual memory access.
2077 t0
= tcg_temp_new();
2078 gen_base_offset_addr(ctx
, t0
, base
, offset
);
2081 #if defined(TARGET_MIPS64)
2083 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEUL
|
2084 ctx
->default_tcg_memop_mask
);
2085 gen_store_gpr(t0
, rt
);
2088 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEQ
|
2089 ctx
->default_tcg_memop_mask
);
2090 gen_store_gpr(t0
, rt
);
2094 op_ld_lld(t0
, t0
, mem_idx
, ctx
);
2095 gen_store_gpr(t0
, rt
);
2098 t1
= tcg_temp_new();
2100 * Do a byte access to possibly trigger a page
2101 * fault with the unaligned address.
2103 tcg_gen_qemu_ld_tl(t1
, t0
, mem_idx
, MO_UB
);
2104 tcg_gen_andi_tl(t1
, t0
, 7);
2105 #ifndef TARGET_WORDS_BIGENDIAN
2106 tcg_gen_xori_tl(t1
, t1
, 7);
2108 tcg_gen_shli_tl(t1
, t1
, 3);
2109 tcg_gen_andi_tl(t0
, t0
, ~7);
2110 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEQ
);
2111 tcg_gen_shl_tl(t0
, t0
, t1
);
2112 t2
= tcg_const_tl(-1);
2113 tcg_gen_shl_tl(t2
, t2
, t1
);
2114 gen_load_gpr(t1
, rt
);
2115 tcg_gen_andc_tl(t1
, t1
, t2
);
2117 tcg_gen_or_tl(t0
, t0
, t1
);
2119 gen_store_gpr(t0
, rt
);
2122 t1
= tcg_temp_new();
2124 * Do a byte access to possibly trigger a page
2125 * fault with the unaligned address.
2127 tcg_gen_qemu_ld_tl(t1
, t0
, mem_idx
, MO_UB
);
2128 tcg_gen_andi_tl(t1
, t0
, 7);
2129 #ifdef TARGET_WORDS_BIGENDIAN
2130 tcg_gen_xori_tl(t1
, t1
, 7);
2132 tcg_gen_shli_tl(t1
, t1
, 3);
2133 tcg_gen_andi_tl(t0
, t0
, ~7);
2134 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEQ
);
2135 tcg_gen_shr_tl(t0
, t0
, t1
);
2136 tcg_gen_xori_tl(t1
, t1
, 63);
2137 t2
= tcg_const_tl(0xfffffffffffffffeull
);
2138 tcg_gen_shl_tl(t2
, t2
, t1
);
2139 gen_load_gpr(t1
, rt
);
2140 tcg_gen_and_tl(t1
, t1
, t2
);
2142 tcg_gen_or_tl(t0
, t0
, t1
);
2144 gen_store_gpr(t0
, rt
);
2147 t1
= tcg_const_tl(pc_relative_pc(ctx
));
2148 gen_op_addr_add(ctx
, t0
, t0
, t1
);
2150 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEQ
);
2151 gen_store_gpr(t0
, rt
);
2155 t1
= tcg_const_tl(pc_relative_pc(ctx
));
2156 gen_op_addr_add(ctx
, t0
, t0
, t1
);
2158 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TESL
);
2159 gen_store_gpr(t0
, rt
);
2162 mem_idx
= MIPS_HFLAG_UM
;
2165 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TESL
|
2166 ctx
->default_tcg_memop_mask
);
2167 gen_store_gpr(t0
, rt
);
2170 mem_idx
= MIPS_HFLAG_UM
;
2173 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TESW
|
2174 ctx
->default_tcg_memop_mask
);
2175 gen_store_gpr(t0
, rt
);
2178 mem_idx
= MIPS_HFLAG_UM
;
2181 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEUW
|
2182 ctx
->default_tcg_memop_mask
);
2183 gen_store_gpr(t0
, rt
);
2186 mem_idx
= MIPS_HFLAG_UM
;
2189 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_SB
);
2190 gen_store_gpr(t0
, rt
);
2193 mem_idx
= MIPS_HFLAG_UM
;
2196 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_UB
);
2197 gen_store_gpr(t0
, rt
);
2200 mem_idx
= MIPS_HFLAG_UM
;
2203 t1
= tcg_temp_new();
2205 * Do a byte access to possibly trigger a page
2206 * fault with the unaligned address.
2208 tcg_gen_qemu_ld_tl(t1
, t0
, mem_idx
, MO_UB
);
2209 tcg_gen_andi_tl(t1
, t0
, 3);
2210 #ifndef TARGET_WORDS_BIGENDIAN
2211 tcg_gen_xori_tl(t1
, t1
, 3);
2213 tcg_gen_shli_tl(t1
, t1
, 3);
2214 tcg_gen_andi_tl(t0
, t0
, ~3);
2215 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEUL
);
2216 tcg_gen_shl_tl(t0
, t0
, t1
);
2217 t2
= tcg_const_tl(-1);
2218 tcg_gen_shl_tl(t2
, t2
, t1
);
2219 gen_load_gpr(t1
, rt
);
2220 tcg_gen_andc_tl(t1
, t1
, t2
);
2222 tcg_gen_or_tl(t0
, t0
, t1
);
2224 tcg_gen_ext32s_tl(t0
, t0
);
2225 gen_store_gpr(t0
, rt
);
2228 mem_idx
= MIPS_HFLAG_UM
;
2231 t1
= tcg_temp_new();
2233 * Do a byte access to possibly trigger a page
2234 * fault with the unaligned address.
2236 tcg_gen_qemu_ld_tl(t1
, t0
, mem_idx
, MO_UB
);
2237 tcg_gen_andi_tl(t1
, t0
, 3);
2238 #ifdef TARGET_WORDS_BIGENDIAN
2239 tcg_gen_xori_tl(t1
, t1
, 3);
2241 tcg_gen_shli_tl(t1
, t1
, 3);
2242 tcg_gen_andi_tl(t0
, t0
, ~3);
2243 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEUL
);
2244 tcg_gen_shr_tl(t0
, t0
, t1
);
2245 tcg_gen_xori_tl(t1
, t1
, 31);
2246 t2
= tcg_const_tl(0xfffffffeull
);
2247 tcg_gen_shl_tl(t2
, t2
, t1
);
2248 gen_load_gpr(t1
, rt
);
2249 tcg_gen_and_tl(t1
, t1
, t2
);
2251 tcg_gen_or_tl(t0
, t0
, t1
);
2253 tcg_gen_ext32s_tl(t0
, t0
);
2254 gen_store_gpr(t0
, rt
);
2257 mem_idx
= MIPS_HFLAG_UM
;
2261 op_ld_ll(t0
, t0
, mem_idx
, ctx
);
2262 gen_store_gpr(t0
, rt
);
2268 static void gen_llwp(DisasContext
*ctx
, uint32_t base
, int16_t offset
,
2269 uint32_t reg1
, uint32_t reg2
)
2271 TCGv taddr
= tcg_temp_new();
2272 TCGv_i64 tval
= tcg_temp_new_i64();
2273 TCGv tmp1
= tcg_temp_new();
2274 TCGv tmp2
= tcg_temp_new();
2276 gen_base_offset_addr(ctx
, taddr
, base
, offset
);
2277 tcg_gen_qemu_ld64(tval
, taddr
, ctx
->mem_idx
);
2278 #ifdef TARGET_WORDS_BIGENDIAN
2279 tcg_gen_extr_i64_tl(tmp2
, tmp1
, tval
);
2281 tcg_gen_extr_i64_tl(tmp1
, tmp2
, tval
);
2283 gen_store_gpr(tmp1
, reg1
);
2284 tcg_temp_free(tmp1
);
2285 gen_store_gpr(tmp2
, reg2
);
2286 tcg_temp_free(tmp2
);
2287 tcg_gen_st_i64(tval
, cpu_env
, offsetof(CPUMIPSState
, llval_wp
));
2288 tcg_temp_free_i64(tval
);
2289 tcg_gen_st_tl(taddr
, cpu_env
, offsetof(CPUMIPSState
, lladdr
));
2290 tcg_temp_free(taddr
);
2294 static void gen_st(DisasContext
*ctx
, uint32_t opc
, int rt
,
2295 int base
, int offset
)
2297 TCGv t0
= tcg_temp_new();
2298 TCGv t1
= tcg_temp_new();
2299 int mem_idx
= ctx
->mem_idx
;
2301 gen_base_offset_addr(ctx
, t0
, base
, offset
);
2302 gen_load_gpr(t1
, rt
);
2304 #if defined(TARGET_MIPS64)
2306 tcg_gen_qemu_st_tl(t1
, t0
, mem_idx
, MO_TEQ
|
2307 ctx
->default_tcg_memop_mask
);
2310 gen_helper_0e2i(sdl
, t1
, t0
, mem_idx
);
2313 gen_helper_0e2i(sdr
, t1
, t0
, mem_idx
);
2317 mem_idx
= MIPS_HFLAG_UM
;
2320 tcg_gen_qemu_st_tl(t1
, t0
, mem_idx
, MO_TEUL
|
2321 ctx
->default_tcg_memop_mask
);
2324 mem_idx
= MIPS_HFLAG_UM
;
2327 tcg_gen_qemu_st_tl(t1
, t0
, mem_idx
, MO_TEUW
|
2328 ctx
->default_tcg_memop_mask
);
2331 mem_idx
= MIPS_HFLAG_UM
;
2334 tcg_gen_qemu_st_tl(t1
, t0
, mem_idx
, MO_8
);
2337 mem_idx
= MIPS_HFLAG_UM
;
2340 gen_helper_0e2i(swl
, t1
, t0
, mem_idx
);
2343 mem_idx
= MIPS_HFLAG_UM
;
2346 gen_helper_0e2i(swr
, t1
, t0
, mem_idx
);
2354 /* Store conditional */
2355 static void gen_st_cond(DisasContext
*ctx
, int rt
, int base
, int offset
,
2356 MemOp tcg_mo
, bool eva
)
2359 TCGLabel
*l1
= gen_new_label();
2360 TCGLabel
*done
= gen_new_label();
2362 t0
= tcg_temp_new();
2363 addr
= tcg_temp_new();
2364 /* compare the address against that of the preceding LL */
2365 gen_base_offset_addr(ctx
, addr
, base
, offset
);
2366 tcg_gen_brcond_tl(TCG_COND_EQ
, addr
, cpu_lladdr
, l1
);
2367 tcg_temp_free(addr
);
2368 tcg_gen_movi_tl(t0
, 0);
2369 gen_store_gpr(t0
, rt
);
2373 /* generate cmpxchg */
2374 val
= tcg_temp_new();
2375 gen_load_gpr(val
, rt
);
2376 tcg_gen_atomic_cmpxchg_tl(t0
, cpu_lladdr
, cpu_llval
, val
,
2377 eva
? MIPS_HFLAG_UM
: ctx
->mem_idx
, tcg_mo
);
2378 tcg_gen_setcond_tl(TCG_COND_EQ
, t0
, t0
, cpu_llval
);
2379 gen_store_gpr(t0
, rt
);
2382 gen_set_label(done
);
2387 static void gen_scwp(DisasContext
*ctx
, uint32_t base
, int16_t offset
,
2388 uint32_t reg1
, uint32_t reg2
, bool eva
)
2390 TCGv taddr
= tcg_temp_local_new();
2391 TCGv lladdr
= tcg_temp_local_new();
2392 TCGv_i64 tval
= tcg_temp_new_i64();
2393 TCGv_i64 llval
= tcg_temp_new_i64();
2394 TCGv_i64 val
= tcg_temp_new_i64();
2395 TCGv tmp1
= tcg_temp_new();
2396 TCGv tmp2
= tcg_temp_new();
2397 TCGLabel
*lab_fail
= gen_new_label();
2398 TCGLabel
*lab_done
= gen_new_label();
2400 gen_base_offset_addr(ctx
, taddr
, base
, offset
);
2402 tcg_gen_ld_tl(lladdr
, cpu_env
, offsetof(CPUMIPSState
, lladdr
));
2403 tcg_gen_brcond_tl(TCG_COND_NE
, taddr
, lladdr
, lab_fail
);
2405 gen_load_gpr(tmp1
, reg1
);
2406 gen_load_gpr(tmp2
, reg2
);
2408 #ifdef TARGET_WORDS_BIGENDIAN
2409 tcg_gen_concat_tl_i64(tval
, tmp2
, tmp1
);
2411 tcg_gen_concat_tl_i64(tval
, tmp1
, tmp2
);
2414 tcg_gen_ld_i64(llval
, cpu_env
, offsetof(CPUMIPSState
, llval_wp
));
2415 tcg_gen_atomic_cmpxchg_i64(val
, taddr
, llval
, tval
,
2416 eva
? MIPS_HFLAG_UM
: ctx
->mem_idx
, MO_64
);
2418 tcg_gen_movi_tl(cpu_gpr
[reg1
], 1);
2420 tcg_gen_brcond_i64(TCG_COND_EQ
, val
, llval
, lab_done
);
2422 gen_set_label(lab_fail
);
2425 tcg_gen_movi_tl(cpu_gpr
[reg1
], 0);
2427 gen_set_label(lab_done
);
2428 tcg_gen_movi_tl(lladdr
, -1);
2429 tcg_gen_st_tl(lladdr
, cpu_env
, offsetof(CPUMIPSState
, lladdr
));
2432 /* Load and store */
2433 static void gen_flt_ldst(DisasContext
*ctx
, uint32_t opc
, int ft
,
2437 * Don't do NOP if destination is zero: we must perform the actual
2443 TCGv_i32 fp0
= tcg_temp_new_i32();
2444 tcg_gen_qemu_ld_i32(fp0
, t0
, ctx
->mem_idx
, MO_TESL
|
2445 ctx
->default_tcg_memop_mask
);
2446 gen_store_fpr32(ctx
, fp0
, ft
);
2447 tcg_temp_free_i32(fp0
);
2452 TCGv_i32 fp0
= tcg_temp_new_i32();
2453 gen_load_fpr32(ctx
, fp0
, ft
);
2454 tcg_gen_qemu_st_i32(fp0
, t0
, ctx
->mem_idx
, MO_TEUL
|
2455 ctx
->default_tcg_memop_mask
);
2456 tcg_temp_free_i32(fp0
);
2461 TCGv_i64 fp0
= tcg_temp_new_i64();
2462 tcg_gen_qemu_ld_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
|
2463 ctx
->default_tcg_memop_mask
);
2464 gen_store_fpr64(ctx
, fp0
, ft
);
2465 tcg_temp_free_i64(fp0
);
2470 TCGv_i64 fp0
= tcg_temp_new_i64();
2471 gen_load_fpr64(ctx
, fp0
, ft
);
2472 tcg_gen_qemu_st_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
|
2473 ctx
->default_tcg_memop_mask
);
2474 tcg_temp_free_i64(fp0
);
2478 MIPS_INVAL("flt_ldst");
2479 gen_reserved_instruction(ctx
);
2484 static void gen_cop1_ldst(DisasContext
*ctx
, uint32_t op
, int rt
,
2485 int rs
, int16_t imm
)
2487 TCGv t0
= tcg_temp_new();
2489 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
2490 check_cp1_enabled(ctx
);
2494 check_insn(ctx
, ISA_MIPS2
);
2497 gen_base_offset_addr(ctx
, t0
, rs
, imm
);
2498 gen_flt_ldst(ctx
, op
, rt
, t0
);
2501 generate_exception_err(ctx
, EXCP_CpU
, 1);
2506 /* Arithmetic with immediate operand */
2507 static void gen_arith_imm(DisasContext
*ctx
, uint32_t opc
,
2508 int rt
, int rs
, int imm
)
2510 target_ulong uimm
= (target_long
)imm
; /* Sign extend to 32/64 bits */
2512 if (rt
== 0 && opc
!= OPC_ADDI
&& opc
!= OPC_DADDI
) {
2514 * If no destination, treat it as a NOP.
2515 * For addi, we must generate the overflow exception when needed.
2522 TCGv t0
= tcg_temp_local_new();
2523 TCGv t1
= tcg_temp_new();
2524 TCGv t2
= tcg_temp_new();
2525 TCGLabel
*l1
= gen_new_label();
2527 gen_load_gpr(t1
, rs
);
2528 tcg_gen_addi_tl(t0
, t1
, uimm
);
2529 tcg_gen_ext32s_tl(t0
, t0
);
2531 tcg_gen_xori_tl(t1
, t1
, ~uimm
);
2532 tcg_gen_xori_tl(t2
, t0
, uimm
);
2533 tcg_gen_and_tl(t1
, t1
, t2
);
2535 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2537 /* operands of same sign, result different sign */
2538 generate_exception(ctx
, EXCP_OVERFLOW
);
2540 tcg_gen_ext32s_tl(t0
, t0
);
2541 gen_store_gpr(t0
, rt
);
2547 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
2548 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
2550 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
2553 #if defined(TARGET_MIPS64)
2556 TCGv t0
= tcg_temp_local_new();
2557 TCGv t1
= tcg_temp_new();
2558 TCGv t2
= tcg_temp_new();
2559 TCGLabel
*l1
= gen_new_label();
2561 gen_load_gpr(t1
, rs
);
2562 tcg_gen_addi_tl(t0
, t1
, uimm
);
2564 tcg_gen_xori_tl(t1
, t1
, ~uimm
);
2565 tcg_gen_xori_tl(t2
, t0
, uimm
);
2566 tcg_gen_and_tl(t1
, t1
, t2
);
2568 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2570 /* operands of same sign, result different sign */
2571 generate_exception(ctx
, EXCP_OVERFLOW
);
2573 gen_store_gpr(t0
, rt
);
2579 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
2581 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
2588 /* Logic with immediate operand */
2589 static void gen_logic_imm(DisasContext
*ctx
, uint32_t opc
,
2590 int rt
, int rs
, int16_t imm
)
2595 /* If no destination, treat it as a NOP. */
2598 uimm
= (uint16_t)imm
;
2601 if (likely(rs
!= 0)) {
2602 tcg_gen_andi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
2604 tcg_gen_movi_tl(cpu_gpr
[rt
], 0);
2609 tcg_gen_ori_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
2611 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
2615 if (likely(rs
!= 0)) {
2616 tcg_gen_xori_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
2618 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
2622 if (rs
!= 0 && (ctx
->insn_flags
& ISA_MIPS_R6
)) {
2624 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], imm
<< 16);
2625 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
2627 tcg_gen_movi_tl(cpu_gpr
[rt
], imm
<< 16);
2636 /* Set on less than with immediate operand */
2637 static void gen_slt_imm(DisasContext
*ctx
, uint32_t opc
,
2638 int rt
, int rs
, int16_t imm
)
2640 target_ulong uimm
= (target_long
)imm
; /* Sign extend to 32/64 bits */
2644 /* If no destination, treat it as a NOP. */
2647 t0
= tcg_temp_new();
2648 gen_load_gpr(t0
, rs
);
2651 tcg_gen_setcondi_tl(TCG_COND_LT
, cpu_gpr
[rt
], t0
, uimm
);
2654 tcg_gen_setcondi_tl(TCG_COND_LTU
, cpu_gpr
[rt
], t0
, uimm
);
2660 /* Shifts with immediate operand */
2661 static void gen_shift_imm(DisasContext
*ctx
, uint32_t opc
,
2662 int rt
, int rs
, int16_t imm
)
2664 target_ulong uimm
= ((uint16_t)imm
) & 0x1f;
2668 /* If no destination, treat it as a NOP. */
2672 t0
= tcg_temp_new();
2673 gen_load_gpr(t0
, rs
);
2676 tcg_gen_shli_tl(t0
, t0
, uimm
);
2677 tcg_gen_ext32s_tl(cpu_gpr
[rt
], t0
);
2680 tcg_gen_sari_tl(cpu_gpr
[rt
], t0
, uimm
);
2684 tcg_gen_ext32u_tl(t0
, t0
);
2685 tcg_gen_shri_tl(cpu_gpr
[rt
], t0
, uimm
);
2687 tcg_gen_ext32s_tl(cpu_gpr
[rt
], t0
);
2692 TCGv_i32 t1
= tcg_temp_new_i32();
2694 tcg_gen_trunc_tl_i32(t1
, t0
);
2695 tcg_gen_rotri_i32(t1
, t1
, uimm
);
2696 tcg_gen_ext_i32_tl(cpu_gpr
[rt
], t1
);
2697 tcg_temp_free_i32(t1
);
2699 tcg_gen_ext32s_tl(cpu_gpr
[rt
], t0
);
2702 #if defined(TARGET_MIPS64)
2704 tcg_gen_shli_tl(cpu_gpr
[rt
], t0
, uimm
);
2707 tcg_gen_sari_tl(cpu_gpr
[rt
], t0
, uimm
);
2710 tcg_gen_shri_tl(cpu_gpr
[rt
], t0
, uimm
);
2714 tcg_gen_rotri_tl(cpu_gpr
[rt
], t0
, uimm
);
2716 tcg_gen_mov_tl(cpu_gpr
[rt
], t0
);
2720 tcg_gen_shli_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
2723 tcg_gen_sari_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
2726 tcg_gen_shri_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
2729 tcg_gen_rotri_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
2737 static void gen_arith(DisasContext
*ctx
, uint32_t opc
,
2738 int rd
, int rs
, int rt
)
2740 if (rd
== 0 && opc
!= OPC_ADD
&& opc
!= OPC_SUB
2741 && opc
!= OPC_DADD
&& opc
!= OPC_DSUB
) {
2743 * If no destination, treat it as a NOP.
2744 * For add & sub, we must generate the overflow exception when needed.
2752 TCGv t0
= tcg_temp_local_new();
2753 TCGv t1
= tcg_temp_new();
2754 TCGv t2
= tcg_temp_new();
2755 TCGLabel
*l1
= gen_new_label();
2757 gen_load_gpr(t1
, rs
);
2758 gen_load_gpr(t2
, rt
);
2759 tcg_gen_add_tl(t0
, t1
, t2
);
2760 tcg_gen_ext32s_tl(t0
, t0
);
2761 tcg_gen_xor_tl(t1
, t1
, t2
);
2762 tcg_gen_xor_tl(t2
, t0
, t2
);
2763 tcg_gen_andc_tl(t1
, t2
, t1
);
2765 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2767 /* operands of same sign, result different sign */
2768 generate_exception(ctx
, EXCP_OVERFLOW
);
2770 gen_store_gpr(t0
, rd
);
2775 if (rs
!= 0 && rt
!= 0) {
2776 tcg_gen_add_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2777 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
2778 } else if (rs
== 0 && rt
!= 0) {
2779 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2780 } else if (rs
!= 0 && rt
== 0) {
2781 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2783 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2788 TCGv t0
= tcg_temp_local_new();
2789 TCGv t1
= tcg_temp_new();
2790 TCGv t2
= tcg_temp_new();
2791 TCGLabel
*l1
= gen_new_label();
2793 gen_load_gpr(t1
, rs
);
2794 gen_load_gpr(t2
, rt
);
2795 tcg_gen_sub_tl(t0
, t1
, t2
);
2796 tcg_gen_ext32s_tl(t0
, t0
);
2797 tcg_gen_xor_tl(t2
, t1
, t2
);
2798 tcg_gen_xor_tl(t1
, t0
, t1
);
2799 tcg_gen_and_tl(t1
, t1
, t2
);
2801 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2804 * operands of different sign, first operand and the result
2807 generate_exception(ctx
, EXCP_OVERFLOW
);
2809 gen_store_gpr(t0
, rd
);
2814 if (rs
!= 0 && rt
!= 0) {
2815 tcg_gen_sub_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2816 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
2817 } else if (rs
== 0 && rt
!= 0) {
2818 tcg_gen_neg_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2819 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
2820 } else if (rs
!= 0 && rt
== 0) {
2821 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2823 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2826 #if defined(TARGET_MIPS64)
2829 TCGv t0
= tcg_temp_local_new();
2830 TCGv t1
= tcg_temp_new();
2831 TCGv t2
= tcg_temp_new();
2832 TCGLabel
*l1
= gen_new_label();
2834 gen_load_gpr(t1
, rs
);
2835 gen_load_gpr(t2
, rt
);
2836 tcg_gen_add_tl(t0
, t1
, t2
);
2837 tcg_gen_xor_tl(t1
, t1
, t2
);
2838 tcg_gen_xor_tl(t2
, t0
, t2
);
2839 tcg_gen_andc_tl(t1
, t2
, t1
);
2841 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2843 /* operands of same sign, result different sign */
2844 generate_exception(ctx
, EXCP_OVERFLOW
);
2846 gen_store_gpr(t0
, rd
);
2851 if (rs
!= 0 && rt
!= 0) {
2852 tcg_gen_add_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2853 } else if (rs
== 0 && rt
!= 0) {
2854 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2855 } else if (rs
!= 0 && rt
== 0) {
2856 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2858 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2863 TCGv t0
= tcg_temp_local_new();
2864 TCGv t1
= tcg_temp_new();
2865 TCGv t2
= tcg_temp_new();
2866 TCGLabel
*l1
= gen_new_label();
2868 gen_load_gpr(t1
, rs
);
2869 gen_load_gpr(t2
, rt
);
2870 tcg_gen_sub_tl(t0
, t1
, t2
);
2871 tcg_gen_xor_tl(t2
, t1
, t2
);
2872 tcg_gen_xor_tl(t1
, t0
, t1
);
2873 tcg_gen_and_tl(t1
, t1
, t2
);
2875 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2878 * Operands of different sign, first operand and result different
2881 generate_exception(ctx
, EXCP_OVERFLOW
);
2883 gen_store_gpr(t0
, rd
);
2888 if (rs
!= 0 && rt
!= 0) {
2889 tcg_gen_sub_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2890 } else if (rs
== 0 && rt
!= 0) {
2891 tcg_gen_neg_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2892 } else if (rs
!= 0 && rt
== 0) {
2893 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2895 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2900 if (likely(rs
!= 0 && rt
!= 0)) {
2901 tcg_gen_mul_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2902 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
2904 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2910 /* Conditional move */
2911 static void gen_cond_move(DisasContext
*ctx
, uint32_t opc
,
2912 int rd
, int rs
, int rt
)
2917 /* If no destination, treat it as a NOP. */
2921 t0
= tcg_temp_new();
2922 gen_load_gpr(t0
, rt
);
2923 t1
= tcg_const_tl(0);
2924 t2
= tcg_temp_new();
2925 gen_load_gpr(t2
, rs
);
2928 tcg_gen_movcond_tl(TCG_COND_NE
, cpu_gpr
[rd
], t0
, t1
, t2
, cpu_gpr
[rd
]);
2931 tcg_gen_movcond_tl(TCG_COND_EQ
, cpu_gpr
[rd
], t0
, t1
, t2
, cpu_gpr
[rd
]);
2934 tcg_gen_movcond_tl(TCG_COND_NE
, cpu_gpr
[rd
], t0
, t1
, t2
, t1
);
2937 tcg_gen_movcond_tl(TCG_COND_EQ
, cpu_gpr
[rd
], t0
, t1
, t2
, t1
);
2946 static void gen_logic(DisasContext
*ctx
, uint32_t opc
,
2947 int rd
, int rs
, int rt
)
2950 /* If no destination, treat it as a NOP. */
2956 if (likely(rs
!= 0 && rt
!= 0)) {
2957 tcg_gen_and_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2959 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2963 if (rs
!= 0 && rt
!= 0) {
2964 tcg_gen_nor_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2965 } else if (rs
== 0 && rt
!= 0) {
2966 tcg_gen_not_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2967 } else if (rs
!= 0 && rt
== 0) {
2968 tcg_gen_not_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2970 tcg_gen_movi_tl(cpu_gpr
[rd
], ~((target_ulong
)0));
2974 if (likely(rs
!= 0 && rt
!= 0)) {
2975 tcg_gen_or_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2976 } else if (rs
== 0 && rt
!= 0) {
2977 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2978 } else if (rs
!= 0 && rt
== 0) {
2979 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2981 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2985 if (likely(rs
!= 0 && rt
!= 0)) {
2986 tcg_gen_xor_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2987 } else if (rs
== 0 && rt
!= 0) {
2988 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2989 } else if (rs
!= 0 && rt
== 0) {
2990 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2992 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2998 /* Set on lower than */
2999 static void gen_slt(DisasContext
*ctx
, uint32_t opc
,
3000 int rd
, int rs
, int rt
)
3005 /* If no destination, treat it as a NOP. */
3009 t0
= tcg_temp_new();
3010 t1
= tcg_temp_new();
3011 gen_load_gpr(t0
, rs
);
3012 gen_load_gpr(t1
, rt
);
3015 tcg_gen_setcond_tl(TCG_COND_LT
, cpu_gpr
[rd
], t0
, t1
);
3018 tcg_gen_setcond_tl(TCG_COND_LTU
, cpu_gpr
[rd
], t0
, t1
);
3026 static void gen_shift(DisasContext
*ctx
, uint32_t opc
,
3027 int rd
, int rs
, int rt
)
3033 * If no destination, treat it as a NOP.
3034 * For add & sub, we must generate the overflow exception when needed.
3039 t0
= tcg_temp_new();
3040 t1
= tcg_temp_new();
3041 gen_load_gpr(t0
, rs
);
3042 gen_load_gpr(t1
, rt
);
3045 tcg_gen_andi_tl(t0
, t0
, 0x1f);
3046 tcg_gen_shl_tl(t0
, t1
, t0
);
3047 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
3050 tcg_gen_andi_tl(t0
, t0
, 0x1f);
3051 tcg_gen_sar_tl(cpu_gpr
[rd
], t1
, t0
);
3054 tcg_gen_ext32u_tl(t1
, t1
);
3055 tcg_gen_andi_tl(t0
, t0
, 0x1f);
3056 tcg_gen_shr_tl(t0
, t1
, t0
);
3057 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
3061 TCGv_i32 t2
= tcg_temp_new_i32();
3062 TCGv_i32 t3
= tcg_temp_new_i32();
3064 tcg_gen_trunc_tl_i32(t2
, t0
);
3065 tcg_gen_trunc_tl_i32(t3
, t1
);
3066 tcg_gen_andi_i32(t2
, t2
, 0x1f);
3067 tcg_gen_rotr_i32(t2
, t3
, t2
);
3068 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
3069 tcg_temp_free_i32(t2
);
3070 tcg_temp_free_i32(t3
);
3073 #if defined(TARGET_MIPS64)
3075 tcg_gen_andi_tl(t0
, t0
, 0x3f);
3076 tcg_gen_shl_tl(cpu_gpr
[rd
], t1
, t0
);
3079 tcg_gen_andi_tl(t0
, t0
, 0x3f);
3080 tcg_gen_sar_tl(cpu_gpr
[rd
], t1
, t0
);
3083 tcg_gen_andi_tl(t0
, t0
, 0x3f);
3084 tcg_gen_shr_tl(cpu_gpr
[rd
], t1
, t0
);
3087 tcg_gen_andi_tl(t0
, t0
, 0x3f);
3088 tcg_gen_rotr_tl(cpu_gpr
[rd
], t1
, t0
);
3096 /* Arithmetic on HI/LO registers */
3097 static void gen_HILO(DisasContext
*ctx
, uint32_t opc
, int acc
, int reg
)
3099 if (reg
== 0 && (opc
== OPC_MFHI
|| opc
== OPC_MFLO
)) {
3110 #if defined(TARGET_MIPS64)
3112 tcg_gen_ext32s_tl(cpu_gpr
[reg
], cpu_HI
[acc
]);
3116 tcg_gen_mov_tl(cpu_gpr
[reg
], cpu_HI
[acc
]);
3120 #if defined(TARGET_MIPS64)
3122 tcg_gen_ext32s_tl(cpu_gpr
[reg
], cpu_LO
[acc
]);
3126 tcg_gen_mov_tl(cpu_gpr
[reg
], cpu_LO
[acc
]);
3131 #if defined(TARGET_MIPS64)
3133 tcg_gen_ext32s_tl(cpu_HI
[acc
], cpu_gpr
[reg
]);
3137 tcg_gen_mov_tl(cpu_HI
[acc
], cpu_gpr
[reg
]);
3140 tcg_gen_movi_tl(cpu_HI
[acc
], 0);
3145 #if defined(TARGET_MIPS64)
3147 tcg_gen_ext32s_tl(cpu_LO
[acc
], cpu_gpr
[reg
]);
3151 tcg_gen_mov_tl(cpu_LO
[acc
], cpu_gpr
[reg
]);
3154 tcg_gen_movi_tl(cpu_LO
[acc
], 0);
3160 static inline void gen_r6_ld(target_long addr
, int reg
, int memidx
,
3163 TCGv t0
= tcg_const_tl(addr
);
3164 tcg_gen_qemu_ld_tl(t0
, t0
, memidx
, memop
);
3165 gen_store_gpr(t0
, reg
);
3169 static inline void gen_pcrel(DisasContext
*ctx
, int opc
, target_ulong pc
,
3175 switch (MASK_OPC_PCREL_TOP2BITS(opc
)) {
3178 offset
= sextract32(ctx
->opcode
<< 2, 0, 21);
3179 addr
= addr_add(ctx
, pc
, offset
);
3180 tcg_gen_movi_tl(cpu_gpr
[rs
], addr
);
3184 offset
= sextract32(ctx
->opcode
<< 2, 0, 21);
3185 addr
= addr_add(ctx
, pc
, offset
);
3186 gen_r6_ld(addr
, rs
, ctx
->mem_idx
, MO_TESL
);
3188 #if defined(TARGET_MIPS64)
3191 offset
= sextract32(ctx
->opcode
<< 2, 0, 21);
3192 addr
= addr_add(ctx
, pc
, offset
);
3193 gen_r6_ld(addr
, rs
, ctx
->mem_idx
, MO_TEUL
);
3197 switch (MASK_OPC_PCREL_TOP5BITS(opc
)) {
3200 offset
= sextract32(ctx
->opcode
, 0, 16) << 16;
3201 addr
= addr_add(ctx
, pc
, offset
);
3202 tcg_gen_movi_tl(cpu_gpr
[rs
], addr
);
3207 offset
= sextract32(ctx
->opcode
, 0, 16) << 16;
3208 addr
= ~0xFFFF & addr_add(ctx
, pc
, offset
);
3209 tcg_gen_movi_tl(cpu_gpr
[rs
], addr
);
3212 #if defined(TARGET_MIPS64)
3213 case R6_OPC_LDPC
: /* bits 16 and 17 are part of immediate */
3214 case R6_OPC_LDPC
+ (1 << 16):
3215 case R6_OPC_LDPC
+ (2 << 16):
3216 case R6_OPC_LDPC
+ (3 << 16):
3218 offset
= sextract32(ctx
->opcode
<< 3, 0, 21);
3219 addr
= addr_add(ctx
, (pc
& ~0x7), offset
);
3220 gen_r6_ld(addr
, rs
, ctx
->mem_idx
, MO_TEQ
);
3224 MIPS_INVAL("OPC_PCREL");
3225 gen_reserved_instruction(ctx
);
3232 static void gen_r6_muldiv(DisasContext
*ctx
, int opc
, int rd
, int rs
, int rt
)
3241 t0
= tcg_temp_new();
3242 t1
= tcg_temp_new();
3244 gen_load_gpr(t0
, rs
);
3245 gen_load_gpr(t1
, rt
);
3250 TCGv t2
= tcg_temp_new();
3251 TCGv t3
= tcg_temp_new();
3252 tcg_gen_ext32s_tl(t0
, t0
);
3253 tcg_gen_ext32s_tl(t1
, t1
);
3254 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, INT_MIN
);
3255 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1);
3256 tcg_gen_and_tl(t2
, t2
, t3
);
3257 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
3258 tcg_gen_or_tl(t2
, t2
, t3
);
3259 tcg_gen_movi_tl(t3
, 0);
3260 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
3261 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
3262 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3269 TCGv t2
= tcg_temp_new();
3270 TCGv t3
= tcg_temp_new();
3271 tcg_gen_ext32s_tl(t0
, t0
);
3272 tcg_gen_ext32s_tl(t1
, t1
);
3273 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, INT_MIN
);
3274 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1);
3275 tcg_gen_and_tl(t2
, t2
, t3
);
3276 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
3277 tcg_gen_or_tl(t2
, t2
, t3
);
3278 tcg_gen_movi_tl(t3
, 0);
3279 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
3280 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
3281 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3288 TCGv t2
= tcg_const_tl(0);
3289 TCGv t3
= tcg_const_tl(1);
3290 tcg_gen_ext32u_tl(t0
, t0
);
3291 tcg_gen_ext32u_tl(t1
, t1
);
3292 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
3293 tcg_gen_divu_tl(cpu_gpr
[rd
], t0
, t1
);
3294 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3301 TCGv t2
= tcg_const_tl(0);
3302 TCGv t3
= tcg_const_tl(1);
3303 tcg_gen_ext32u_tl(t0
, t0
);
3304 tcg_gen_ext32u_tl(t1
, t1
);
3305 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
3306 tcg_gen_remu_tl(cpu_gpr
[rd
], t0
, t1
);
3307 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3314 TCGv_i32 t2
= tcg_temp_new_i32();
3315 TCGv_i32 t3
= tcg_temp_new_i32();
3316 tcg_gen_trunc_tl_i32(t2
, t0
);
3317 tcg_gen_trunc_tl_i32(t3
, t1
);
3318 tcg_gen_mul_i32(t2
, t2
, t3
);
3319 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
3320 tcg_temp_free_i32(t2
);
3321 tcg_temp_free_i32(t3
);
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_muls2_i32(t2
, t3
, t2
, t3
);
3331 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t3
);
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_mul_i32(t2
, t2
, t3
);
3343 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
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_mulu2_i32(t2
, t3
, t2
, t3
);
3355 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t3
);
3356 tcg_temp_free_i32(t2
);
3357 tcg_temp_free_i32(t3
);
3360 #if defined(TARGET_MIPS64)
3363 TCGv t2
= tcg_temp_new();
3364 TCGv t3
= tcg_temp_new();
3365 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, -1LL << 63);
3366 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1LL);
3367 tcg_gen_and_tl(t2
, t2
, t3
);
3368 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
3369 tcg_gen_or_tl(t2
, t2
, t3
);
3370 tcg_gen_movi_tl(t3
, 0);
3371 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
3372 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
3379 TCGv t2
= tcg_temp_new();
3380 TCGv t3
= tcg_temp_new();
3381 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, -1LL << 63);
3382 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1LL);
3383 tcg_gen_and_tl(t2
, t2
, t3
);
3384 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
3385 tcg_gen_or_tl(t2
, t2
, t3
);
3386 tcg_gen_movi_tl(t3
, 0);
3387 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
3388 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
3395 TCGv t2
= tcg_const_tl(0);
3396 TCGv t3
= tcg_const_tl(1);
3397 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
3398 tcg_gen_divu_i64(cpu_gpr
[rd
], t0
, t1
);
3405 TCGv t2
= tcg_const_tl(0);
3406 TCGv t3
= tcg_const_tl(1);
3407 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
3408 tcg_gen_remu_i64(cpu_gpr
[rd
], t0
, t1
);
3414 tcg_gen_mul_i64(cpu_gpr
[rd
], t0
, t1
);
3418 TCGv t2
= tcg_temp_new();
3419 tcg_gen_muls2_i64(t2
, cpu_gpr
[rd
], t0
, t1
);
3424 tcg_gen_mul_i64(cpu_gpr
[rd
], t0
, t1
);
3428 TCGv t2
= tcg_temp_new();
3429 tcg_gen_mulu2_i64(t2
, cpu_gpr
[rd
], t0
, t1
);
3435 MIPS_INVAL("r6 mul/div");
3436 gen_reserved_instruction(ctx
);
3444 #if defined(TARGET_MIPS64)
3445 static void gen_div1_tx79(DisasContext
*ctx
, uint32_t opc
, int rs
, int rt
)
3449 t0
= tcg_temp_new();
3450 t1
= tcg_temp_new();
3452 gen_load_gpr(t0
, rs
);
3453 gen_load_gpr(t1
, rt
);
3458 TCGv t2
= tcg_temp_new();
3459 TCGv t3
= tcg_temp_new();
3460 tcg_gen_ext32s_tl(t0
, t0
);
3461 tcg_gen_ext32s_tl(t1
, t1
);
3462 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, INT_MIN
);
3463 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1);
3464 tcg_gen_and_tl(t2
, t2
, t3
);
3465 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
3466 tcg_gen_or_tl(t2
, t2
, t3
);
3467 tcg_gen_movi_tl(t3
, 0);
3468 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
3469 tcg_gen_div_tl(cpu_LO
[1], t0
, t1
);
3470 tcg_gen_rem_tl(cpu_HI
[1], t0
, t1
);
3471 tcg_gen_ext32s_tl(cpu_LO
[1], cpu_LO
[1]);
3472 tcg_gen_ext32s_tl(cpu_HI
[1], cpu_HI
[1]);
3479 TCGv t2
= tcg_const_tl(0);
3480 TCGv t3
= tcg_const_tl(1);
3481 tcg_gen_ext32u_tl(t0
, t0
);
3482 tcg_gen_ext32u_tl(t1
, t1
);
3483 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
3484 tcg_gen_divu_tl(cpu_LO
[1], t0
, t1
);
3485 tcg_gen_remu_tl(cpu_HI
[1], t0
, t1
);
3486 tcg_gen_ext32s_tl(cpu_LO
[1], cpu_LO
[1]);
3487 tcg_gen_ext32s_tl(cpu_HI
[1], cpu_HI
[1]);
3493 MIPS_INVAL("div1 TX79");
3494 gen_reserved_instruction(ctx
);
3503 static void gen_muldiv(DisasContext
*ctx
, uint32_t opc
,
3504 int acc
, int rs
, int rt
)
3508 t0
= tcg_temp_new();
3509 t1
= tcg_temp_new();
3511 gen_load_gpr(t0
, rs
);
3512 gen_load_gpr(t1
, rt
);
3521 TCGv t2
= tcg_temp_new();
3522 TCGv t3
= tcg_temp_new();
3523 tcg_gen_ext32s_tl(t0
, t0
);
3524 tcg_gen_ext32s_tl(t1
, t1
);
3525 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, INT_MIN
);
3526 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1);
3527 tcg_gen_and_tl(t2
, t2
, t3
);
3528 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
3529 tcg_gen_or_tl(t2
, t2
, t3
);
3530 tcg_gen_movi_tl(t3
, 0);
3531 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
3532 tcg_gen_div_tl(cpu_LO
[acc
], t0
, t1
);
3533 tcg_gen_rem_tl(cpu_HI
[acc
], t0
, t1
);
3534 tcg_gen_ext32s_tl(cpu_LO
[acc
], cpu_LO
[acc
]);
3535 tcg_gen_ext32s_tl(cpu_HI
[acc
], cpu_HI
[acc
]);
3542 TCGv t2
= tcg_const_tl(0);
3543 TCGv t3
= tcg_const_tl(1);
3544 tcg_gen_ext32u_tl(t0
, t0
);
3545 tcg_gen_ext32u_tl(t1
, t1
);
3546 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
3547 tcg_gen_divu_tl(cpu_LO
[acc
], t0
, t1
);
3548 tcg_gen_remu_tl(cpu_HI
[acc
], t0
, t1
);
3549 tcg_gen_ext32s_tl(cpu_LO
[acc
], cpu_LO
[acc
]);
3550 tcg_gen_ext32s_tl(cpu_HI
[acc
], cpu_HI
[acc
]);
3557 TCGv_i32 t2
= tcg_temp_new_i32();
3558 TCGv_i32 t3
= tcg_temp_new_i32();
3559 tcg_gen_trunc_tl_i32(t2
, t0
);
3560 tcg_gen_trunc_tl_i32(t3
, t1
);
3561 tcg_gen_muls2_i32(t2
, t3
, t2
, t3
);
3562 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
3563 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
3564 tcg_temp_free_i32(t2
);
3565 tcg_temp_free_i32(t3
);
3570 TCGv_i32 t2
= tcg_temp_new_i32();
3571 TCGv_i32 t3
= tcg_temp_new_i32();
3572 tcg_gen_trunc_tl_i32(t2
, t0
);
3573 tcg_gen_trunc_tl_i32(t3
, t1
);
3574 tcg_gen_mulu2_i32(t2
, t3
, t2
, t3
);
3575 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
3576 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
3577 tcg_temp_free_i32(t2
);
3578 tcg_temp_free_i32(t3
);
3581 #if defined(TARGET_MIPS64)
3584 TCGv t2
= tcg_temp_new();
3585 TCGv t3
= tcg_temp_new();
3586 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, -1LL << 63);
3587 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1LL);
3588 tcg_gen_and_tl(t2
, t2
, t3
);
3589 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
3590 tcg_gen_or_tl(t2
, t2
, t3
);
3591 tcg_gen_movi_tl(t3
, 0);
3592 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
3593 tcg_gen_div_tl(cpu_LO
[acc
], t0
, t1
);
3594 tcg_gen_rem_tl(cpu_HI
[acc
], t0
, t1
);
3601 TCGv t2
= tcg_const_tl(0);
3602 TCGv t3
= tcg_const_tl(1);
3603 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
3604 tcg_gen_divu_i64(cpu_LO
[acc
], t0
, t1
);
3605 tcg_gen_remu_i64(cpu_HI
[acc
], t0
, t1
);
3611 tcg_gen_muls2_i64(cpu_LO
[acc
], cpu_HI
[acc
], t0
, t1
);
3614 tcg_gen_mulu2_i64(cpu_LO
[acc
], cpu_HI
[acc
], t0
, t1
);
3619 TCGv_i64 t2
= tcg_temp_new_i64();
3620 TCGv_i64 t3
= tcg_temp_new_i64();
3622 tcg_gen_ext_tl_i64(t2
, t0
);
3623 tcg_gen_ext_tl_i64(t3
, t1
);
3624 tcg_gen_mul_i64(t2
, t2
, t3
);
3625 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
3626 tcg_gen_add_i64(t2
, t2
, t3
);
3627 tcg_temp_free_i64(t3
);
3628 gen_move_low32(cpu_LO
[acc
], t2
);
3629 gen_move_high32(cpu_HI
[acc
], t2
);
3630 tcg_temp_free_i64(t2
);
3635 TCGv_i64 t2
= tcg_temp_new_i64();
3636 TCGv_i64 t3
= tcg_temp_new_i64();
3638 tcg_gen_ext32u_tl(t0
, t0
);
3639 tcg_gen_ext32u_tl(t1
, t1
);
3640 tcg_gen_extu_tl_i64(t2
, t0
);
3641 tcg_gen_extu_tl_i64(t3
, t1
);
3642 tcg_gen_mul_i64(t2
, t2
, t3
);
3643 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
3644 tcg_gen_add_i64(t2
, t2
, t3
);
3645 tcg_temp_free_i64(t3
);
3646 gen_move_low32(cpu_LO
[acc
], t2
);
3647 gen_move_high32(cpu_HI
[acc
], t2
);
3648 tcg_temp_free_i64(t2
);
3653 TCGv_i64 t2
= tcg_temp_new_i64();
3654 TCGv_i64 t3
= tcg_temp_new_i64();
3656 tcg_gen_ext_tl_i64(t2
, t0
);
3657 tcg_gen_ext_tl_i64(t3
, t1
);
3658 tcg_gen_mul_i64(t2
, t2
, t3
);
3659 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
3660 tcg_gen_sub_i64(t2
, t3
, t2
);
3661 tcg_temp_free_i64(t3
);
3662 gen_move_low32(cpu_LO
[acc
], t2
);
3663 gen_move_high32(cpu_HI
[acc
], t2
);
3664 tcg_temp_free_i64(t2
);
3669 TCGv_i64 t2
= tcg_temp_new_i64();
3670 TCGv_i64 t3
= tcg_temp_new_i64();
3672 tcg_gen_ext32u_tl(t0
, t0
);
3673 tcg_gen_ext32u_tl(t1
, t1
);
3674 tcg_gen_extu_tl_i64(t2
, t0
);
3675 tcg_gen_extu_tl_i64(t3
, t1
);
3676 tcg_gen_mul_i64(t2
, t2
, t3
);
3677 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
3678 tcg_gen_sub_i64(t2
, t3
, t2
);
3679 tcg_temp_free_i64(t3
);
3680 gen_move_low32(cpu_LO
[acc
], t2
);
3681 gen_move_high32(cpu_HI
[acc
], t2
);
3682 tcg_temp_free_i64(t2
);
3686 MIPS_INVAL("mul/div");
3687 gen_reserved_instruction(ctx
);
3696 * These MULT[U] and MADD[U] instructions implemented in for example
3697 * the Toshiba/Sony R5900 and the Toshiba TX19, TX39 and TX79 core
3698 * architectures are special three-operand variants with the syntax
3700 * MULT[U][1] rd, rs, rt
3704 * (rd, LO, HI) <- rs * rt
3708 * MADD[U][1] rd, rs, rt
3712 * (rd, LO, HI) <- (LO, HI) + rs * rt
3714 * where the low-order 32-bits of the result is placed into both the
3715 * GPR rd and the special register LO. The high-order 32-bits of the
3716 * result is placed into the special register HI.
3718 * If the GPR rd is omitted in assembly language, it is taken to be 0,
3719 * which is the zero register that always reads as 0.
3721 static void gen_mul_txx9(DisasContext
*ctx
, uint32_t opc
,
3722 int rd
, int rs
, int rt
)
3724 TCGv t0
= tcg_temp_new();
3725 TCGv t1
= tcg_temp_new();
3728 gen_load_gpr(t0
, rs
);
3729 gen_load_gpr(t1
, rt
);
3737 TCGv_i32 t2
= tcg_temp_new_i32();
3738 TCGv_i32 t3
= tcg_temp_new_i32();
3739 tcg_gen_trunc_tl_i32(t2
, t0
);
3740 tcg_gen_trunc_tl_i32(t3
, t1
);
3741 tcg_gen_muls2_i32(t2
, t3
, t2
, t3
);
3743 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
3745 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
3746 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
3747 tcg_temp_free_i32(t2
);
3748 tcg_temp_free_i32(t3
);
3751 case MMI_OPC_MULTU1
:
3756 TCGv_i32 t2
= tcg_temp_new_i32();
3757 TCGv_i32 t3
= tcg_temp_new_i32();
3758 tcg_gen_trunc_tl_i32(t2
, t0
);
3759 tcg_gen_trunc_tl_i32(t3
, t1
);
3760 tcg_gen_mulu2_i32(t2
, t3
, t2
, t3
);
3762 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
3764 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
3765 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
3766 tcg_temp_free_i32(t2
);
3767 tcg_temp_free_i32(t3
);
3775 TCGv_i64 t2
= tcg_temp_new_i64();
3776 TCGv_i64 t3
= tcg_temp_new_i64();
3778 tcg_gen_ext_tl_i64(t2
, t0
);
3779 tcg_gen_ext_tl_i64(t3
, t1
);
3780 tcg_gen_mul_i64(t2
, t2
, t3
);
3781 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
3782 tcg_gen_add_i64(t2
, t2
, t3
);
3783 tcg_temp_free_i64(t3
);
3784 gen_move_low32(cpu_LO
[acc
], t2
);
3785 gen_move_high32(cpu_HI
[acc
], t2
);
3787 gen_move_low32(cpu_gpr
[rd
], t2
);
3789 tcg_temp_free_i64(t2
);
3792 case MMI_OPC_MADDU1
:
3797 TCGv_i64 t2
= tcg_temp_new_i64();
3798 TCGv_i64 t3
= tcg_temp_new_i64();
3800 tcg_gen_ext32u_tl(t0
, t0
);
3801 tcg_gen_ext32u_tl(t1
, t1
);
3802 tcg_gen_extu_tl_i64(t2
, t0
);
3803 tcg_gen_extu_tl_i64(t3
, t1
);
3804 tcg_gen_mul_i64(t2
, t2
, t3
);
3805 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
3806 tcg_gen_add_i64(t2
, t2
, t3
);
3807 tcg_temp_free_i64(t3
);
3808 gen_move_low32(cpu_LO
[acc
], t2
);
3809 gen_move_high32(cpu_HI
[acc
], t2
);
3811 gen_move_low32(cpu_gpr
[rd
], t2
);
3813 tcg_temp_free_i64(t2
);
3817 MIPS_INVAL("mul/madd TXx9");
3818 gen_reserved_instruction(ctx
);
3827 static void gen_mul_vr54xx(DisasContext
*ctx
, uint32_t opc
,
3828 int rd
, int rs
, int rt
)
3830 TCGv t0
= tcg_temp_new();
3831 TCGv t1
= tcg_temp_new();
3833 gen_load_gpr(t0
, rs
);
3834 gen_load_gpr(t1
, rt
);
3837 case OPC_VR54XX_MULS
:
3838 gen_helper_muls(t0
, cpu_env
, t0
, t1
);
3840 case OPC_VR54XX_MULSU
:
3841 gen_helper_mulsu(t0
, cpu_env
, t0
, t1
);
3843 case OPC_VR54XX_MACC
:
3844 gen_helper_macc(t0
, cpu_env
, t0
, t1
);
3846 case OPC_VR54XX_MACCU
:
3847 gen_helper_maccu(t0
, cpu_env
, t0
, t1
);
3849 case OPC_VR54XX_MSAC
:
3850 gen_helper_msac(t0
, cpu_env
, t0
, t1
);
3852 case OPC_VR54XX_MSACU
:
3853 gen_helper_msacu(t0
, cpu_env
, t0
, t1
);
3855 case OPC_VR54XX_MULHI
:
3856 gen_helper_mulhi(t0
, cpu_env
, t0
, t1
);
3858 case OPC_VR54XX_MULHIU
:
3859 gen_helper_mulhiu(t0
, cpu_env
, t0
, t1
);
3861 case OPC_VR54XX_MULSHI
:
3862 gen_helper_mulshi(t0
, cpu_env
, t0
, t1
);
3864 case OPC_VR54XX_MULSHIU
:
3865 gen_helper_mulshiu(t0
, cpu_env
, t0
, t1
);
3867 case OPC_VR54XX_MACCHI
:
3868 gen_helper_macchi(t0
, cpu_env
, t0
, t1
);
3870 case OPC_VR54XX_MACCHIU
:
3871 gen_helper_macchiu(t0
, cpu_env
, t0
, t1
);
3873 case OPC_VR54XX_MSACHI
:
3874 gen_helper_msachi(t0
, cpu_env
, t0
, t1
);
3876 case OPC_VR54XX_MSACHIU
:
3877 gen_helper_msachiu(t0
, cpu_env
, t0
, t1
);
3880 MIPS_INVAL("mul vr54xx");
3881 gen_reserved_instruction(ctx
);
3884 gen_store_gpr(t0
, rd
);
3891 static void gen_cl(DisasContext
*ctx
, uint32_t opc
,
3901 gen_load_gpr(t0
, rs
);
3906 #if defined(TARGET_MIPS64)
3910 tcg_gen_not_tl(t0
, t0
);
3919 tcg_gen_ext32u_tl(t0
, t0
);
3920 tcg_gen_clzi_tl(t0
, t0
, TARGET_LONG_BITS
);
3921 tcg_gen_subi_tl(t0
, t0
, TARGET_LONG_BITS
- 32);
3923 #if defined(TARGET_MIPS64)
3928 tcg_gen_clzi_i64(t0
, t0
, 64);
3934 /* Godson integer instructions */
3935 static void gen_loongson_integer(DisasContext
*ctx
, uint32_t opc
,
3936 int rd
, int rs
, int rt
)
3948 case OPC_MULTU_G_2E
:
3949 case OPC_MULTU_G_2F
:
3950 #if defined(TARGET_MIPS64)
3951 case OPC_DMULT_G_2E
:
3952 case OPC_DMULT_G_2F
:
3953 case OPC_DMULTU_G_2E
:
3954 case OPC_DMULTU_G_2F
:
3956 t0
= tcg_temp_new();
3957 t1
= tcg_temp_new();
3960 t0
= tcg_temp_local_new();
3961 t1
= tcg_temp_local_new();
3965 gen_load_gpr(t0
, rs
);
3966 gen_load_gpr(t1
, rt
);
3971 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
3972 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3974 case OPC_MULTU_G_2E
:
3975 case OPC_MULTU_G_2F
:
3976 tcg_gen_ext32u_tl(t0
, t0
);
3977 tcg_gen_ext32u_tl(t1
, t1
);
3978 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
3979 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3984 TCGLabel
*l1
= gen_new_label();
3985 TCGLabel
*l2
= gen_new_label();
3986 TCGLabel
*l3
= gen_new_label();
3987 tcg_gen_ext32s_tl(t0
, t0
);
3988 tcg_gen_ext32s_tl(t1
, t1
);
3989 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3990 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3993 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, INT_MIN
, l2
);
3994 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1, l2
);
3995 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
3998 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
3999 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
4006 TCGLabel
*l1
= gen_new_label();
4007 TCGLabel
*l2
= gen_new_label();
4008 tcg_gen_ext32u_tl(t0
, t0
);
4009 tcg_gen_ext32u_tl(t1
, t1
);
4010 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
4011 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4014 tcg_gen_divu_tl(cpu_gpr
[rd
], t0
, t1
);
4015 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
4022 TCGLabel
*l1
= gen_new_label();
4023 TCGLabel
*l2
= gen_new_label();
4024 TCGLabel
*l3
= gen_new_label();
4025 tcg_gen_ext32u_tl(t0
, t0
);
4026 tcg_gen_ext32u_tl(t1
, t1
);
4027 tcg_gen_brcondi_tl(TCG_COND_EQ
, t1
, 0, l1
);
4028 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, INT_MIN
, l2
);
4029 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1, l2
);
4031 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4034 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
4035 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
4042 TCGLabel
*l1
= gen_new_label();
4043 TCGLabel
*l2
= gen_new_label();
4044 tcg_gen_ext32u_tl(t0
, t0
);
4045 tcg_gen_ext32u_tl(t1
, t1
);
4046 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
4047 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4050 tcg_gen_remu_tl(cpu_gpr
[rd
], t0
, t1
);
4051 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
4055 #if defined(TARGET_MIPS64)
4056 case OPC_DMULT_G_2E
:
4057 case OPC_DMULT_G_2F
:
4058 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
4060 case OPC_DMULTU_G_2E
:
4061 case OPC_DMULTU_G_2F
:
4062 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
4067 TCGLabel
*l1
= gen_new_label();
4068 TCGLabel
*l2
= gen_new_label();
4069 TCGLabel
*l3
= gen_new_label();
4070 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
4071 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4074 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, -1LL << 63, l2
);
4075 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1LL, l2
);
4076 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
4079 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
4083 case OPC_DDIVU_G_2E
:
4084 case OPC_DDIVU_G_2F
:
4086 TCGLabel
*l1
= gen_new_label();
4087 TCGLabel
*l2
= gen_new_label();
4088 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
4089 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4092 tcg_gen_divu_tl(cpu_gpr
[rd
], t0
, t1
);
4099 TCGLabel
*l1
= gen_new_label();
4100 TCGLabel
*l2
= gen_new_label();
4101 TCGLabel
*l3
= gen_new_label();
4102 tcg_gen_brcondi_tl(TCG_COND_EQ
, t1
, 0, l1
);
4103 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, -1LL << 63, l2
);
4104 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1LL, l2
);
4106 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4109 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
4113 case OPC_DMODU_G_2E
:
4114 case OPC_DMODU_G_2F
:
4116 TCGLabel
*l1
= gen_new_label();
4117 TCGLabel
*l2
= gen_new_label();
4118 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
4119 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4122 tcg_gen_remu_tl(cpu_gpr
[rd
], t0
, t1
);
4133 /* Loongson multimedia instructions */
4134 static void gen_loongson_multimedia(DisasContext
*ctx
, int rd
, int rs
, int rt
)
4136 uint32_t opc
, shift_max
;
4140 opc
= MASK_LMMI(ctx
->opcode
);
4146 t0
= tcg_temp_local_new_i64();
4147 t1
= tcg_temp_local_new_i64();
4150 t0
= tcg_temp_new_i64();
4151 t1
= tcg_temp_new_i64();
4155 check_cp1_enabled(ctx
);
4156 gen_load_fpr64(ctx
, t0
, rs
);
4157 gen_load_fpr64(ctx
, t1
, rt
);
4161 gen_helper_paddsh(t0
, t0
, t1
);
4164 gen_helper_paddush(t0
, t0
, t1
);
4167 gen_helper_paddh(t0
, t0
, t1
);
4170 gen_helper_paddw(t0
, t0
, t1
);
4173 gen_helper_paddsb(t0
, t0
, t1
);
4176 gen_helper_paddusb(t0
, t0
, t1
);
4179 gen_helper_paddb(t0
, t0
, t1
);
4183 gen_helper_psubsh(t0
, t0
, t1
);
4186 gen_helper_psubush(t0
, t0
, t1
);
4189 gen_helper_psubh(t0
, t0
, t1
);
4192 gen_helper_psubw(t0
, t0
, t1
);
4195 gen_helper_psubsb(t0
, t0
, t1
);
4198 gen_helper_psubusb(t0
, t0
, t1
);
4201 gen_helper_psubb(t0
, t0
, t1
);
4205 gen_helper_pshufh(t0
, t0
, t1
);
4208 gen_helper_packsswh(t0
, t0
, t1
);
4211 gen_helper_packsshb(t0
, t0
, t1
);
4214 gen_helper_packushb(t0
, t0
, t1
);
4218 gen_helper_punpcklhw(t0
, t0
, t1
);
4221 gen_helper_punpckhhw(t0
, t0
, t1
);
4224 gen_helper_punpcklbh(t0
, t0
, t1
);
4227 gen_helper_punpckhbh(t0
, t0
, t1
);
4230 gen_helper_punpcklwd(t0
, t0
, t1
);
4233 gen_helper_punpckhwd(t0
, t0
, t1
);
4237 gen_helper_pavgh(t0
, t0
, t1
);
4240 gen_helper_pavgb(t0
, t0
, t1
);
4243 gen_helper_pmaxsh(t0
, t0
, t1
);
4246 gen_helper_pminsh(t0
, t0
, t1
);
4249 gen_helper_pmaxub(t0
, t0
, t1
);
4252 gen_helper_pminub(t0
, t0
, t1
);
4256 gen_helper_pcmpeqw(t0
, t0
, t1
);
4259 gen_helper_pcmpgtw(t0
, t0
, t1
);
4262 gen_helper_pcmpeqh(t0
, t0
, t1
);
4265 gen_helper_pcmpgth(t0
, t0
, t1
);
4268 gen_helper_pcmpeqb(t0
, t0
, t1
);
4271 gen_helper_pcmpgtb(t0
, t0
, t1
);
4275 gen_helper_psllw(t0
, t0
, t1
);
4278 gen_helper_psllh(t0
, t0
, t1
);
4281 gen_helper_psrlw(t0
, t0
, t1
);
4284 gen_helper_psrlh(t0
, t0
, t1
);
4287 gen_helper_psraw(t0
, t0
, t1
);
4290 gen_helper_psrah(t0
, t0
, t1
);
4294 gen_helper_pmullh(t0
, t0
, t1
);
4297 gen_helper_pmulhh(t0
, t0
, t1
);
4300 gen_helper_pmulhuh(t0
, t0
, t1
);
4303 gen_helper_pmaddhw(t0
, t0
, t1
);
4307 gen_helper_pasubub(t0
, t0
, t1
);
4310 gen_helper_biadd(t0
, t0
);
4313 gen_helper_pmovmskb(t0
, t0
);
4317 tcg_gen_add_i64(t0
, t0
, t1
);
4320 tcg_gen_sub_i64(t0
, t0
, t1
);
4323 tcg_gen_xor_i64(t0
, t0
, t1
);
4326 tcg_gen_nor_i64(t0
, t0
, t1
);
4329 tcg_gen_and_i64(t0
, t0
, t1
);
4332 tcg_gen_or_i64(t0
, t0
, t1
);
4336 tcg_gen_andc_i64(t0
, t1
, t0
);
4340 tcg_gen_deposit_i64(t0
, t0
, t1
, 0, 16);
4343 tcg_gen_deposit_i64(t0
, t0
, t1
, 16, 16);
4346 tcg_gen_deposit_i64(t0
, t0
, t1
, 32, 16);
4349 tcg_gen_deposit_i64(t0
, t0
, t1
, 48, 16);
4353 tcg_gen_andi_i64(t1
, t1
, 3);
4354 tcg_gen_shli_i64(t1
, t1
, 4);
4355 tcg_gen_shr_i64(t0
, t0
, t1
);
4356 tcg_gen_ext16u_i64(t0
, t0
);
4360 tcg_gen_add_i64(t0
, t0
, t1
);
4361 tcg_gen_ext32s_i64(t0
, t0
);
4364 tcg_gen_sub_i64(t0
, t0
, t1
);
4365 tcg_gen_ext32s_i64(t0
, t0
);
4387 /* Make sure shift count isn't TCG undefined behaviour. */
4388 tcg_gen_andi_i64(t1
, t1
, shift_max
- 1);
4393 tcg_gen_shl_i64(t0
, t0
, t1
);
4398 * Since SRA is UndefinedResult without sign-extended inputs,
4399 * we can treat SRA and DSRA the same.
4401 tcg_gen_sar_i64(t0
, t0
, t1
);
4404 /* We want to shift in zeros for SRL; zero-extend first. */
4405 tcg_gen_ext32u_i64(t0
, t0
);
4408 tcg_gen_shr_i64(t0
, t0
, t1
);
4412 if (shift_max
== 32) {
4413 tcg_gen_ext32s_i64(t0
, t0
);
4416 /* Shifts larger than MAX produce zero. */
4417 tcg_gen_setcondi_i64(TCG_COND_LTU
, t1
, t1
, shift_max
);
4418 tcg_gen_neg_i64(t1
, t1
);
4419 tcg_gen_and_i64(t0
, t0
, t1
);
4425 TCGv_i64 t2
= tcg_temp_new_i64();
4426 TCGLabel
*lab
= gen_new_label();
4428 tcg_gen_mov_i64(t2
, t0
);
4429 tcg_gen_add_i64(t0
, t1
, t2
);
4430 if (opc
== OPC_ADD_CP2
) {
4431 tcg_gen_ext32s_i64(t0
, t0
);
4433 tcg_gen_xor_i64(t1
, t1
, t2
);
4434 tcg_gen_xor_i64(t2
, t2
, t0
);
4435 tcg_gen_andc_i64(t1
, t2
, t1
);
4436 tcg_temp_free_i64(t2
);
4437 tcg_gen_brcondi_i64(TCG_COND_GE
, t1
, 0, lab
);
4438 generate_exception(ctx
, EXCP_OVERFLOW
);
4446 TCGv_i64 t2
= tcg_temp_new_i64();
4447 TCGLabel
*lab
= gen_new_label();
4449 tcg_gen_mov_i64(t2
, t0
);
4450 tcg_gen_sub_i64(t0
, t1
, t2
);
4451 if (opc
== OPC_SUB_CP2
) {
4452 tcg_gen_ext32s_i64(t0
, t0
);
4454 tcg_gen_xor_i64(t1
, t1
, t2
);
4455 tcg_gen_xor_i64(t2
, t2
, t0
);
4456 tcg_gen_and_i64(t1
, t1
, t2
);
4457 tcg_temp_free_i64(t2
);
4458 tcg_gen_brcondi_i64(TCG_COND_GE
, t1
, 0, lab
);
4459 generate_exception(ctx
, EXCP_OVERFLOW
);
4465 tcg_gen_ext32u_i64(t0
, t0
);
4466 tcg_gen_ext32u_i64(t1
, t1
);
4467 tcg_gen_mul_i64(t0
, t0
, t1
);
4476 cond
= TCG_COND_LTU
;
4484 cond
= TCG_COND_LEU
;
4491 int cc
= (ctx
->opcode
>> 8) & 0x7;
4492 TCGv_i64 t64
= tcg_temp_new_i64();
4493 TCGv_i32 t32
= tcg_temp_new_i32();
4495 tcg_gen_setcond_i64(cond
, t64
, t0
, t1
);
4496 tcg_gen_extrl_i64_i32(t32
, t64
);
4497 tcg_gen_deposit_i32(fpu_fcr31
, fpu_fcr31
, t32
,
4500 tcg_temp_free_i32(t32
);
4501 tcg_temp_free_i64(t64
);
4506 MIPS_INVAL("loongson_cp2");
4507 gen_reserved_instruction(ctx
);
4511 gen_store_fpr64(ctx
, t0
, rd
);
4514 tcg_temp_free_i64(t0
);
4515 tcg_temp_free_i64(t1
);
4518 static void gen_loongson_lswc2(DisasContext
*ctx
, int rt
,
4523 #if defined(TARGET_MIPS64)
4524 int lsq_rt1
= ctx
->opcode
& 0x1f;
4525 int lsq_offset
= sextract32(ctx
->opcode
, 6, 9) << 4;
4527 int shf_offset
= sextract32(ctx
->opcode
, 6, 8);
4529 t0
= tcg_temp_new();
4531 switch (MASK_LOONGSON_GSLSQ(ctx
->opcode
)) {
4532 #if defined(TARGET_MIPS64)
4534 t1
= tcg_temp_new();
4535 gen_base_offset_addr(ctx
, t0
, rs
, lsq_offset
);
4536 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
|
4537 ctx
->default_tcg_memop_mask
);
4538 gen_base_offset_addr(ctx
, t0
, rs
, lsq_offset
+ 8);
4539 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
|
4540 ctx
->default_tcg_memop_mask
);
4541 gen_store_gpr(t1
, rt
);
4542 gen_store_gpr(t0
, lsq_rt1
);
4546 check_cp1_enabled(ctx
);
4547 t1
= tcg_temp_new();
4548 gen_base_offset_addr(ctx
, t0
, rs
, lsq_offset
);
4549 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
|
4550 ctx
->default_tcg_memop_mask
);
4551 gen_base_offset_addr(ctx
, t0
, rs
, lsq_offset
+ 8);
4552 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
|
4553 ctx
->default_tcg_memop_mask
);
4554 gen_store_fpr64(ctx
, t1
, rt
);
4555 gen_store_fpr64(ctx
, t0
, lsq_rt1
);
4559 t1
= tcg_temp_new();
4560 gen_base_offset_addr(ctx
, t0
, rs
, lsq_offset
);
4561 gen_load_gpr(t1
, rt
);
4562 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
|
4563 ctx
->default_tcg_memop_mask
);
4564 gen_base_offset_addr(ctx
, t0
, rs
, lsq_offset
+ 8);
4565 gen_load_gpr(t1
, lsq_rt1
);
4566 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
|
4567 ctx
->default_tcg_memop_mask
);
4571 check_cp1_enabled(ctx
);
4572 t1
= tcg_temp_new();
4573 gen_base_offset_addr(ctx
, t0
, rs
, lsq_offset
);
4574 gen_load_fpr64(ctx
, t1
, rt
);
4575 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
|
4576 ctx
->default_tcg_memop_mask
);
4577 gen_base_offset_addr(ctx
, t0
, rs
, lsq_offset
+ 8);
4578 gen_load_fpr64(ctx
, t1
, lsq_rt1
);
4579 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
|
4580 ctx
->default_tcg_memop_mask
);
4585 switch (MASK_LOONGSON_GSSHFLS(ctx
->opcode
)) {
4587 check_cp1_enabled(ctx
);
4588 gen_base_offset_addr(ctx
, t0
, rs
, shf_offset
);
4589 t1
= tcg_temp_new();
4590 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
4591 tcg_gen_andi_tl(t1
, t0
, 3);
4592 #ifndef TARGET_WORDS_BIGENDIAN
4593 tcg_gen_xori_tl(t1
, t1
, 3);
4595 tcg_gen_shli_tl(t1
, t1
, 3);
4596 tcg_gen_andi_tl(t0
, t0
, ~3);
4597 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEUL
);
4598 tcg_gen_shl_tl(t0
, t0
, t1
);
4599 t2
= tcg_const_tl(-1);
4600 tcg_gen_shl_tl(t2
, t2
, t1
);
4601 fp0
= tcg_temp_new_i32();
4602 gen_load_fpr32(ctx
, fp0
, rt
);
4603 tcg_gen_ext_i32_tl(t1
, fp0
);
4604 tcg_gen_andc_tl(t1
, t1
, t2
);
4606 tcg_gen_or_tl(t0
, t0
, t1
);
4608 #if defined(TARGET_MIPS64)
4609 tcg_gen_extrl_i64_i32(fp0
, t0
);
4611 tcg_gen_ext32s_tl(fp0
, t0
);
4613 gen_store_fpr32(ctx
, fp0
, rt
);
4614 tcg_temp_free_i32(fp0
);
4617 check_cp1_enabled(ctx
);
4618 gen_base_offset_addr(ctx
, t0
, rs
, shf_offset
);
4619 t1
= tcg_temp_new();
4620 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
4621 tcg_gen_andi_tl(t1
, t0
, 3);
4622 #ifdef TARGET_WORDS_BIGENDIAN
4623 tcg_gen_xori_tl(t1
, t1
, 3);
4625 tcg_gen_shli_tl(t1
, t1
, 3);
4626 tcg_gen_andi_tl(t0
, t0
, ~3);
4627 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEUL
);
4628 tcg_gen_shr_tl(t0
, t0
, t1
);
4629 tcg_gen_xori_tl(t1
, t1
, 31);
4630 t2
= tcg_const_tl(0xfffffffeull
);
4631 tcg_gen_shl_tl(t2
, t2
, t1
);
4632 fp0
= tcg_temp_new_i32();
4633 gen_load_fpr32(ctx
, fp0
, rt
);
4634 tcg_gen_ext_i32_tl(t1
, fp0
);
4635 tcg_gen_and_tl(t1
, t1
, t2
);
4637 tcg_gen_or_tl(t0
, t0
, t1
);
4639 #if defined(TARGET_MIPS64)
4640 tcg_gen_extrl_i64_i32(fp0
, t0
);
4642 tcg_gen_ext32s_tl(fp0
, t0
);
4644 gen_store_fpr32(ctx
, fp0
, rt
);
4645 tcg_temp_free_i32(fp0
);
4647 #if defined(TARGET_MIPS64)
4649 check_cp1_enabled(ctx
);
4650 gen_base_offset_addr(ctx
, t0
, rs
, shf_offset
);
4651 t1
= tcg_temp_new();
4652 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
4653 tcg_gen_andi_tl(t1
, t0
, 7);
4654 #ifndef TARGET_WORDS_BIGENDIAN
4655 tcg_gen_xori_tl(t1
, t1
, 7);
4657 tcg_gen_shli_tl(t1
, t1
, 3);
4658 tcg_gen_andi_tl(t0
, t0
, ~7);
4659 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
);
4660 tcg_gen_shl_tl(t0
, t0
, t1
);
4661 t2
= tcg_const_tl(-1);
4662 tcg_gen_shl_tl(t2
, t2
, t1
);
4663 gen_load_fpr64(ctx
, t1
, rt
);
4664 tcg_gen_andc_tl(t1
, t1
, t2
);
4666 tcg_gen_or_tl(t0
, t0
, t1
);
4668 gen_store_fpr64(ctx
, t0
, rt
);
4671 check_cp1_enabled(ctx
);
4672 gen_base_offset_addr(ctx
, t0
, rs
, shf_offset
);
4673 t1
= tcg_temp_new();
4674 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
4675 tcg_gen_andi_tl(t1
, t0
, 7);
4676 #ifdef TARGET_WORDS_BIGENDIAN
4677 tcg_gen_xori_tl(t1
, t1
, 7);
4679 tcg_gen_shli_tl(t1
, t1
, 3);
4680 tcg_gen_andi_tl(t0
, t0
, ~7);
4681 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
);
4682 tcg_gen_shr_tl(t0
, t0
, t1
);
4683 tcg_gen_xori_tl(t1
, t1
, 63);
4684 t2
= tcg_const_tl(0xfffffffffffffffeull
);
4685 tcg_gen_shl_tl(t2
, t2
, t1
);
4686 gen_load_fpr64(ctx
, t1
, rt
);
4687 tcg_gen_and_tl(t1
, t1
, t2
);
4689 tcg_gen_or_tl(t0
, t0
, t1
);
4691 gen_store_fpr64(ctx
, t0
, rt
);
4695 MIPS_INVAL("loongson_gsshfl");
4696 gen_reserved_instruction(ctx
);
4701 switch (MASK_LOONGSON_GSSHFLS(ctx
->opcode
)) {
4703 check_cp1_enabled(ctx
);
4704 t1
= tcg_temp_new();
4705 gen_base_offset_addr(ctx
, t0
, rs
, shf_offset
);
4706 fp0
= tcg_temp_new_i32();
4707 gen_load_fpr32(ctx
, fp0
, rt
);
4708 tcg_gen_ext_i32_tl(t1
, fp0
);
4709 gen_helper_0e2i(swl
, t1
, t0
, ctx
->mem_idx
);
4710 tcg_temp_free_i32(fp0
);
4714 check_cp1_enabled(ctx
);
4715 t1
= tcg_temp_new();
4716 gen_base_offset_addr(ctx
, t0
, rs
, shf_offset
);
4717 fp0
= tcg_temp_new_i32();
4718 gen_load_fpr32(ctx
, fp0
, rt
);
4719 tcg_gen_ext_i32_tl(t1
, fp0
);
4720 gen_helper_0e2i(swr
, t1
, t0
, ctx
->mem_idx
);
4721 tcg_temp_free_i32(fp0
);
4724 #if defined(TARGET_MIPS64)
4726 check_cp1_enabled(ctx
);
4727 t1
= tcg_temp_new();
4728 gen_base_offset_addr(ctx
, t0
, rs
, shf_offset
);
4729 gen_load_fpr64(ctx
, t1
, rt
);
4730 gen_helper_0e2i(sdl
, t1
, t0
, ctx
->mem_idx
);
4734 check_cp1_enabled(ctx
);
4735 t1
= tcg_temp_new();
4736 gen_base_offset_addr(ctx
, t0
, rs
, shf_offset
);
4737 gen_load_fpr64(ctx
, t1
, rt
);
4738 gen_helper_0e2i(sdr
, t1
, t0
, ctx
->mem_idx
);
4743 MIPS_INVAL("loongson_gsshfs");
4744 gen_reserved_instruction(ctx
);
4749 MIPS_INVAL("loongson_gslsq");
4750 gen_reserved_instruction(ctx
);
4756 /* Loongson EXT LDC2/SDC2 */
4757 static void gen_loongson_lsdc2(DisasContext
*ctx
, int rt
,
4760 int offset
= sextract32(ctx
->opcode
, 3, 8);
4761 uint32_t opc
= MASK_LOONGSON_LSDC2(ctx
->opcode
);
4765 /* Pre-conditions */
4771 /* prefetch, implement as NOP */
4782 #if defined(TARGET_MIPS64)
4785 check_cp1_enabled(ctx
);
4786 /* prefetch, implement as NOP */
4792 #if defined(TARGET_MIPS64)
4795 check_cp1_enabled(ctx
);
4798 MIPS_INVAL("loongson_lsdc2");
4799 gen_reserved_instruction(ctx
);
4804 t0
= tcg_temp_new();
4806 gen_base_offset_addr(ctx
, t0
, rs
, offset
);
4807 gen_op_addr_add(ctx
, t0
, cpu_gpr
[rd
], t0
);
4811 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_SB
);
4812 gen_store_gpr(t0
, rt
);
4815 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESW
|
4816 ctx
->default_tcg_memop_mask
);
4817 gen_store_gpr(t0
, rt
);
4820 gen_base_offset_addr(ctx
, t0
, rs
, offset
);
4822 gen_op_addr_add(ctx
, t0
, cpu_gpr
[rd
], t0
);
4824 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESL
|
4825 ctx
->default_tcg_memop_mask
);
4826 gen_store_gpr(t0
, rt
);
4828 #if defined(TARGET_MIPS64)
4830 gen_base_offset_addr(ctx
, t0
, rs
, offset
);
4832 gen_op_addr_add(ctx
, t0
, cpu_gpr
[rd
], t0
);
4834 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
|
4835 ctx
->default_tcg_memop_mask
);
4836 gen_store_gpr(t0
, rt
);
4840 check_cp1_enabled(ctx
);
4841 gen_base_offset_addr(ctx
, t0
, rs
, offset
);
4843 gen_op_addr_add(ctx
, t0
, cpu_gpr
[rd
], t0
);
4845 fp0
= tcg_temp_new_i32();
4846 tcg_gen_qemu_ld_i32(fp0
, t0
, ctx
->mem_idx
, MO_TESL
|
4847 ctx
->default_tcg_memop_mask
);
4848 gen_store_fpr32(ctx
, fp0
, rt
);
4849 tcg_temp_free_i32(fp0
);
4851 #if defined(TARGET_MIPS64)
4853 check_cp1_enabled(ctx
);
4854 gen_base_offset_addr(ctx
, t0
, rs
, offset
);
4856 gen_op_addr_add(ctx
, t0
, cpu_gpr
[rd
], t0
);
4858 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
|
4859 ctx
->default_tcg_memop_mask
);
4860 gen_store_fpr64(ctx
, t0
, rt
);
4864 t1
= tcg_temp_new();
4865 gen_load_gpr(t1
, rt
);
4866 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_SB
);
4870 t1
= tcg_temp_new();
4871 gen_load_gpr(t1
, rt
);
4872 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUW
|
4873 ctx
->default_tcg_memop_mask
);
4877 t1
= tcg_temp_new();
4878 gen_load_gpr(t1
, rt
);
4879 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
|
4880 ctx
->default_tcg_memop_mask
);
4883 #if defined(TARGET_MIPS64)
4885 t1
= tcg_temp_new();
4886 gen_load_gpr(t1
, rt
);
4887 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
|
4888 ctx
->default_tcg_memop_mask
);
4893 fp0
= tcg_temp_new_i32();
4894 gen_load_fpr32(ctx
, fp0
, rt
);
4895 tcg_gen_qemu_st_i32(fp0
, t0
, ctx
->mem_idx
, MO_TEUL
|
4896 ctx
->default_tcg_memop_mask
);
4897 tcg_temp_free_i32(fp0
);
4899 #if defined(TARGET_MIPS64)
4901 t1
= tcg_temp_new();
4902 gen_load_fpr64(ctx
, t1
, rt
);
4903 tcg_gen_qemu_st_i64(t1
, t0
, ctx
->mem_idx
, MO_TEQ
|
4904 ctx
->default_tcg_memop_mask
);
4916 static void gen_trap(DisasContext
*ctx
, uint32_t opc
,
4917 int rs
, int rt
, int16_t imm
)
4920 TCGv t0
= tcg_temp_new();
4921 TCGv t1
= tcg_temp_new();
4924 /* Load needed operands */
4932 /* Compare two registers */
4934 gen_load_gpr(t0
, rs
);
4935 gen_load_gpr(t1
, rt
);
4945 /* Compare register to immediate */
4946 if (rs
!= 0 || imm
!= 0) {
4947 gen_load_gpr(t0
, rs
);
4948 tcg_gen_movi_tl(t1
, (int32_t)imm
);
4955 case OPC_TEQ
: /* rs == rs */
4956 case OPC_TEQI
: /* r0 == 0 */
4957 case OPC_TGE
: /* rs >= rs */
4958 case OPC_TGEI
: /* r0 >= 0 */
4959 case OPC_TGEU
: /* rs >= rs unsigned */
4960 case OPC_TGEIU
: /* r0 >= 0 unsigned */
4962 generate_exception_end(ctx
, EXCP_TRAP
);
4964 case OPC_TLT
: /* rs < rs */
4965 case OPC_TLTI
: /* r0 < 0 */
4966 case OPC_TLTU
: /* rs < rs unsigned */
4967 case OPC_TLTIU
: /* r0 < 0 unsigned */
4968 case OPC_TNE
: /* rs != rs */
4969 case OPC_TNEI
: /* r0 != 0 */
4970 /* Never trap: treat as NOP. */
4974 TCGLabel
*l1
= gen_new_label();
4979 tcg_gen_brcond_tl(TCG_COND_NE
, t0
, t1
, l1
);
4983 tcg_gen_brcond_tl(TCG_COND_LT
, t0
, t1
, l1
);
4987 tcg_gen_brcond_tl(TCG_COND_LTU
, t0
, t1
, l1
);
4991 tcg_gen_brcond_tl(TCG_COND_GE
, t0
, t1
, l1
);
4995 tcg_gen_brcond_tl(TCG_COND_GEU
, t0
, t1
, l1
);
4999 tcg_gen_brcond_tl(TCG_COND_EQ
, t0
, t1
, l1
);
5002 generate_exception(ctx
, EXCP_TRAP
);
5009 static inline bool use_goto_tb(DisasContext
*ctx
, target_ulong dest
)
5011 if (unlikely(ctx
->base
.singlestep_enabled
)) {
5015 #ifndef CONFIG_USER_ONLY
5016 return (ctx
->base
.tb
->pc
& TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
);
5022 static inline void gen_goto_tb(DisasContext
*ctx
, int n
, target_ulong dest
)
5024 if (use_goto_tb(ctx
, dest
)) {
5027 tcg_gen_exit_tb(ctx
->base
.tb
, n
);
5030 if (ctx
->base
.singlestep_enabled
) {
5031 save_cpu_state(ctx
, 0);
5032 gen_helper_raise_exception_debug(cpu_env
);
5034 tcg_gen_lookup_and_goto_ptr();
5038 /* Branches (before delay slot) */
5039 static void gen_compute_branch(DisasContext
*ctx
, uint32_t opc
,
5041 int rs
, int rt
, int32_t offset
,
5044 target_ulong btgt
= -1;
5046 int bcond_compute
= 0;
5047 TCGv t0
= tcg_temp_new();
5048 TCGv t1
= tcg_temp_new();
5050 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
5051 #ifdef MIPS_DEBUG_DISAS
5052 LOG_DISAS("Branch in delay / forbidden slot at PC 0x"
5053 TARGET_FMT_lx
"\n", ctx
->base
.pc_next
);
5055 gen_reserved_instruction(ctx
);
5059 /* Load needed operands */
5065 /* Compare two registers */
5067 gen_load_gpr(t0
, rs
);
5068 gen_load_gpr(t1
, rt
);
5071 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ offset
;
5085 /* Compare to zero */
5087 gen_load_gpr(t0
, rs
);
5090 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ offset
;
5093 #if defined(TARGET_MIPS64)
5095 tcg_gen_andi_tl(t0
, cpu_dspctrl
, 0x7F);
5097 tcg_gen_andi_tl(t0
, cpu_dspctrl
, 0x3F);
5100 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ offset
;
5105 /* Jump to immediate */
5106 btgt
= ((ctx
->base
.pc_next
+ insn_bytes
) & (int32_t)0xF0000000) |
5111 /* Jump to register */
5112 if (offset
!= 0 && offset
!= 16) {
5114 * Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
5115 * others are reserved.
5117 MIPS_INVAL("jump hint");
5118 gen_reserved_instruction(ctx
);
5121 gen_load_gpr(btarget
, rs
);
5124 MIPS_INVAL("branch/jump");
5125 gen_reserved_instruction(ctx
);
5128 if (bcond_compute
== 0) {
5129 /* No condition to be computed */
5131 case OPC_BEQ
: /* rx == rx */
5132 case OPC_BEQL
: /* rx == rx likely */
5133 case OPC_BGEZ
: /* 0 >= 0 */
5134 case OPC_BGEZL
: /* 0 >= 0 likely */
5135 case OPC_BLEZ
: /* 0 <= 0 */
5136 case OPC_BLEZL
: /* 0 <= 0 likely */
5138 ctx
->hflags
|= MIPS_HFLAG_B
;
5140 case OPC_BGEZAL
: /* 0 >= 0 */
5141 case OPC_BGEZALL
: /* 0 >= 0 likely */
5142 /* Always take and link */
5144 ctx
->hflags
|= MIPS_HFLAG_B
;
5146 case OPC_BNE
: /* rx != rx */
5147 case OPC_BGTZ
: /* 0 > 0 */
5148 case OPC_BLTZ
: /* 0 < 0 */
5151 case OPC_BLTZAL
: /* 0 < 0 */
5153 * Handle as an unconditional branch to get correct delay
5157 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ delayslot_size
;
5158 ctx
->hflags
|= MIPS_HFLAG_B
;
5160 case OPC_BLTZALL
: /* 0 < 0 likely */
5161 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 8);
5162 /* Skip the instruction in the delay slot */
5163 ctx
->base
.pc_next
+= 4;
5165 case OPC_BNEL
: /* rx != rx likely */
5166 case OPC_BGTZL
: /* 0 > 0 likely */
5167 case OPC_BLTZL
: /* 0 < 0 likely */
5168 /* Skip the instruction in the delay slot */
5169 ctx
->base
.pc_next
+= 4;
5172 ctx
->hflags
|= MIPS_HFLAG_B
;
5175 ctx
->hflags
|= MIPS_HFLAG_BX
;
5179 ctx
->hflags
|= MIPS_HFLAG_B
;
5182 ctx
->hflags
|= MIPS_HFLAG_BR
;
5186 ctx
->hflags
|= MIPS_HFLAG_BR
;
5189 MIPS_INVAL("branch/jump");
5190 gen_reserved_instruction(ctx
);
5196 tcg_gen_setcond_tl(TCG_COND_EQ
, bcond
, t0
, t1
);
5199 tcg_gen_setcond_tl(TCG_COND_EQ
, bcond
, t0
, t1
);
5202 tcg_gen_setcond_tl(TCG_COND_NE
, bcond
, t0
, t1
);
5205 tcg_gen_setcond_tl(TCG_COND_NE
, bcond
, t0
, t1
);
5208 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
5211 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
5214 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
5218 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
5222 tcg_gen_setcondi_tl(TCG_COND_GT
, bcond
, t0
, 0);
5225 tcg_gen_setcondi_tl(TCG_COND_GT
, bcond
, t0
, 0);
5228 tcg_gen_setcondi_tl(TCG_COND_LE
, bcond
, t0
, 0);
5231 tcg_gen_setcondi_tl(TCG_COND_LE
, bcond
, t0
, 0);
5234 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
5237 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
5240 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 32);
5242 #if defined(TARGET_MIPS64)
5244 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 64);
5248 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
5251 ctx
->hflags
|= MIPS_HFLAG_BC
;
5254 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
5257 ctx
->hflags
|= MIPS_HFLAG_BL
;
5260 MIPS_INVAL("conditional branch/jump");
5261 gen_reserved_instruction(ctx
);
5266 ctx
->btarget
= btgt
;
5268 switch (delayslot_size
) {
5270 ctx
->hflags
|= MIPS_HFLAG_BDS16
;
5273 ctx
->hflags
|= MIPS_HFLAG_BDS32
;
5278 int post_delay
= insn_bytes
+ delayslot_size
;
5279 int lowbit
= !!(ctx
->hflags
& MIPS_HFLAG_M16
);
5281 tcg_gen_movi_tl(cpu_gpr
[blink
],
5282 ctx
->base
.pc_next
+ post_delay
+ lowbit
);
5286 if (insn_bytes
== 2) {
5287 ctx
->hflags
|= MIPS_HFLAG_B16
;
5294 /* nanoMIPS Branches */
5295 static void gen_compute_branch_nm(DisasContext
*ctx
, uint32_t opc
,
5297 int rs
, int rt
, int32_t offset
)
5299 target_ulong btgt
= -1;
5300 int bcond_compute
= 0;
5301 TCGv t0
= tcg_temp_new();
5302 TCGv t1
= tcg_temp_new();
5304 /* Load needed operands */
5308 /* Compare two registers */
5310 gen_load_gpr(t0
, rs
);
5311 gen_load_gpr(t1
, rt
);
5314 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ offset
;
5317 /* Compare to zero */
5319 gen_load_gpr(t0
, rs
);
5322 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ offset
;
5325 tcg_gen_andi_tl(t0
, cpu_dspctrl
, 0x3F);
5327 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ offset
;
5331 /* Jump to register */
5332 if (offset
!= 0 && offset
!= 16) {
5334 * Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
5335 * others are reserved.
5337 MIPS_INVAL("jump hint");
5338 gen_reserved_instruction(ctx
);
5341 gen_load_gpr(btarget
, rs
);
5344 MIPS_INVAL("branch/jump");
5345 gen_reserved_instruction(ctx
);
5348 if (bcond_compute
== 0) {
5349 /* No condition to be computed */
5351 case OPC_BEQ
: /* rx == rx */
5353 ctx
->hflags
|= MIPS_HFLAG_B
;
5355 case OPC_BGEZAL
: /* 0 >= 0 */
5356 /* Always take and link */
5357 tcg_gen_movi_tl(cpu_gpr
[31],
5358 ctx
->base
.pc_next
+ insn_bytes
);
5359 ctx
->hflags
|= MIPS_HFLAG_B
;
5361 case OPC_BNE
: /* rx != rx */
5362 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 8);
5363 /* Skip the instruction in the delay slot */
5364 ctx
->base
.pc_next
+= 4;
5367 ctx
->hflags
|= MIPS_HFLAG_BR
;
5371 tcg_gen_movi_tl(cpu_gpr
[rt
],
5372 ctx
->base
.pc_next
+ insn_bytes
);
5374 ctx
->hflags
|= MIPS_HFLAG_BR
;
5377 MIPS_INVAL("branch/jump");
5378 gen_reserved_instruction(ctx
);
5384 tcg_gen_setcond_tl(TCG_COND_EQ
, bcond
, t0
, t1
);
5387 tcg_gen_setcond_tl(TCG_COND_NE
, bcond
, t0
, t1
);
5390 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
5391 tcg_gen_movi_tl(cpu_gpr
[31],
5392 ctx
->base
.pc_next
+ insn_bytes
);
5395 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 32);
5397 ctx
->hflags
|= MIPS_HFLAG_BC
;
5400 MIPS_INVAL("conditional branch/jump");
5401 gen_reserved_instruction(ctx
);
5406 ctx
->btarget
= btgt
;
5409 if (insn_bytes
== 2) {
5410 ctx
->hflags
|= MIPS_HFLAG_B16
;
5417 /* special3 bitfield operations */
5418 static void gen_bitops(DisasContext
*ctx
, uint32_t opc
, int rt
,
5419 int rs
, int lsb
, int msb
)
5421 TCGv t0
= tcg_temp_new();
5422 TCGv t1
= tcg_temp_new();
5424 gen_load_gpr(t1
, rs
);
5427 if (lsb
+ msb
> 31) {
5431 tcg_gen_extract_tl(t0
, t1
, lsb
, msb
+ 1);
5434 * The two checks together imply that lsb == 0,
5435 * so this is a simple sign-extension.
5437 tcg_gen_ext32s_tl(t0
, t1
);
5440 #if defined(TARGET_MIPS64)
5449 if (lsb
+ msb
> 63) {
5452 tcg_gen_extract_tl(t0
, t1
, lsb
, msb
+ 1);
5459 gen_load_gpr(t0
, rt
);
5460 tcg_gen_deposit_tl(t0
, t0
, t1
, lsb
, msb
- lsb
+ 1);
5461 tcg_gen_ext32s_tl(t0
, t0
);
5463 #if defined(TARGET_MIPS64)
5474 gen_load_gpr(t0
, rt
);
5475 tcg_gen_deposit_tl(t0
, t0
, t1
, lsb
, msb
- lsb
+ 1);
5480 MIPS_INVAL("bitops");
5481 gen_reserved_instruction(ctx
);
5486 gen_store_gpr(t0
, rt
);
5491 static void gen_bshfl(DisasContext
*ctx
, uint32_t op2
, int rt
, int rd
)
5496 /* If no destination, treat it as a NOP. */
5500 t0
= tcg_temp_new();
5501 gen_load_gpr(t0
, rt
);
5505 TCGv t1
= tcg_temp_new();
5506 TCGv t2
= tcg_const_tl(0x00FF00FF);
5508 tcg_gen_shri_tl(t1
, t0
, 8);
5509 tcg_gen_and_tl(t1
, t1
, t2
);
5510 tcg_gen_and_tl(t0
, t0
, t2
);
5511 tcg_gen_shli_tl(t0
, t0
, 8);
5512 tcg_gen_or_tl(t0
, t0
, t1
);
5515 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
5519 tcg_gen_ext8s_tl(cpu_gpr
[rd
], t0
);
5522 tcg_gen_ext16s_tl(cpu_gpr
[rd
], t0
);
5524 #if defined(TARGET_MIPS64)
5527 TCGv t1
= tcg_temp_new();
5528 TCGv t2
= tcg_const_tl(0x00FF00FF00FF00FFULL
);
5530 tcg_gen_shri_tl(t1
, t0
, 8);
5531 tcg_gen_and_tl(t1
, t1
, t2
);
5532 tcg_gen_and_tl(t0
, t0
, t2
);
5533 tcg_gen_shli_tl(t0
, t0
, 8);
5534 tcg_gen_or_tl(cpu_gpr
[rd
], t0
, t1
);
5541 TCGv t1
= tcg_temp_new();
5542 TCGv t2
= tcg_const_tl(0x0000FFFF0000FFFFULL
);
5544 tcg_gen_shri_tl(t1
, t0
, 16);
5545 tcg_gen_and_tl(t1
, t1
, t2
);
5546 tcg_gen_and_tl(t0
, t0
, t2
);
5547 tcg_gen_shli_tl(t0
, t0
, 16);
5548 tcg_gen_or_tl(t0
, t0
, t1
);
5549 tcg_gen_shri_tl(t1
, t0
, 32);
5550 tcg_gen_shli_tl(t0
, t0
, 32);
5551 tcg_gen_or_tl(cpu_gpr
[rd
], t0
, t1
);
5558 MIPS_INVAL("bsfhl");
5559 gen_reserved_instruction(ctx
);
5566 static void gen_align_bits(DisasContext
*ctx
, int wordsz
, int rd
, int rs
,
5574 t0
= tcg_temp_new();
5575 if (bits
== 0 || bits
== wordsz
) {
5577 gen_load_gpr(t0
, rt
);
5579 gen_load_gpr(t0
, rs
);
5583 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
5585 #if defined(TARGET_MIPS64)
5587 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
5592 TCGv t1
= tcg_temp_new();
5593 gen_load_gpr(t0
, rt
);
5594 gen_load_gpr(t1
, rs
);
5598 TCGv_i64 t2
= tcg_temp_new_i64();
5599 tcg_gen_concat_tl_i64(t2
, t1
, t0
);
5600 tcg_gen_shri_i64(t2
, t2
, 32 - bits
);
5601 gen_move_low32(cpu_gpr
[rd
], t2
);
5602 tcg_temp_free_i64(t2
);
5605 #if defined(TARGET_MIPS64)
5607 tcg_gen_shli_tl(t0
, t0
, bits
);
5608 tcg_gen_shri_tl(t1
, t1
, 64 - bits
);
5609 tcg_gen_or_tl(cpu_gpr
[rd
], t1
, t0
);
5619 static void gen_align(DisasContext
*ctx
, int wordsz
, int rd
, int rs
, int rt
,
5622 gen_align_bits(ctx
, wordsz
, rd
, rs
, rt
, bp
* 8);
5625 static void gen_ext(DisasContext
*ctx
, int wordsz
, int rd
, int rs
, int rt
,
5628 gen_align_bits(ctx
, wordsz
, rd
, rs
, rt
, wordsz
- shift
);
5631 static void gen_bitswap(DisasContext
*ctx
, int opc
, int rd
, int rt
)
5638 t0
= tcg_temp_new();
5639 gen_load_gpr(t0
, rt
);
5642 gen_helper_bitswap(cpu_gpr
[rd
], t0
);
5644 #if defined(TARGET_MIPS64)
5646 gen_helper_dbitswap(cpu_gpr
[rd
], t0
);
5653 #ifndef CONFIG_USER_ONLY
5654 /* CP0 (MMU and control) */
5655 static inline void gen_mthc0_entrylo(TCGv arg
, target_ulong off
)
5657 TCGv_i64 t0
= tcg_temp_new_i64();
5658 TCGv_i64 t1
= tcg_temp_new_i64();
5660 tcg_gen_ext_tl_i64(t0
, arg
);
5661 tcg_gen_ld_i64(t1
, cpu_env
, off
);
5662 #if defined(TARGET_MIPS64)
5663 tcg_gen_deposit_i64(t1
, t1
, t0
, 30, 32);
5665 tcg_gen_concat32_i64(t1
, t1
, t0
);
5667 tcg_gen_st_i64(t1
, cpu_env
, off
);
5668 tcg_temp_free_i64(t1
);
5669 tcg_temp_free_i64(t0
);
5672 static inline void gen_mthc0_store64(TCGv arg
, target_ulong off
)
5674 TCGv_i64 t0
= tcg_temp_new_i64();
5675 TCGv_i64 t1
= tcg_temp_new_i64();
5677 tcg_gen_ext_tl_i64(t0
, arg
);
5678 tcg_gen_ld_i64(t1
, cpu_env
, off
);
5679 tcg_gen_concat32_i64(t1
, t1
, t0
);
5680 tcg_gen_st_i64(t1
, cpu_env
, off
);
5681 tcg_temp_free_i64(t1
);
5682 tcg_temp_free_i64(t0
);
5685 static inline void gen_mfhc0_entrylo(TCGv arg
, target_ulong off
)
5687 TCGv_i64 t0
= tcg_temp_new_i64();
5689 tcg_gen_ld_i64(t0
, cpu_env
, off
);
5690 #if defined(TARGET_MIPS64)
5691 tcg_gen_shri_i64(t0
, t0
, 30);
5693 tcg_gen_shri_i64(t0
, t0
, 32);
5695 gen_move_low32(arg
, t0
);
5696 tcg_temp_free_i64(t0
);
5699 static inline void gen_mfhc0_load64(TCGv arg
, target_ulong off
, int shift
)
5701 TCGv_i64 t0
= tcg_temp_new_i64();
5703 tcg_gen_ld_i64(t0
, cpu_env
, off
);
5704 tcg_gen_shri_i64(t0
, t0
, 32 + shift
);
5705 gen_move_low32(arg
, t0
);
5706 tcg_temp_free_i64(t0
);
5709 static inline void gen_mfc0_load32(TCGv arg
, target_ulong off
)
5711 TCGv_i32 t0
= tcg_temp_new_i32();
5713 tcg_gen_ld_i32(t0
, cpu_env
, off
);
5714 tcg_gen_ext_i32_tl(arg
, t0
);
5715 tcg_temp_free_i32(t0
);
5718 static inline void gen_mfc0_load64(TCGv arg
, target_ulong off
)
5720 tcg_gen_ld_tl(arg
, cpu_env
, off
);
5721 tcg_gen_ext32s_tl(arg
, arg
);
5724 static inline void gen_mtc0_store32(TCGv arg
, target_ulong off
)
5726 TCGv_i32 t0
= tcg_temp_new_i32();
5728 tcg_gen_trunc_tl_i32(t0
, arg
);
5729 tcg_gen_st_i32(t0
, cpu_env
, off
);
5730 tcg_temp_free_i32(t0
);
5733 #define CP0_CHECK(c) \
5736 goto cp0_unimplemented; \
5740 static void gen_mfhc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
5742 const char *register_name
= "invalid";
5745 case CP0_REGISTER_02
:
5748 CP0_CHECK(ctx
->hflags
& MIPS_HFLAG_ELPA
);
5749 gen_mfhc0_entrylo(arg
, offsetof(CPUMIPSState
, CP0_EntryLo0
));
5750 register_name
= "EntryLo0";
5753 goto cp0_unimplemented
;
5756 case CP0_REGISTER_03
:
5758 case CP0_REG03__ENTRYLO1
:
5759 CP0_CHECK(ctx
->hflags
& MIPS_HFLAG_ELPA
);
5760 gen_mfhc0_entrylo(arg
, offsetof(CPUMIPSState
, CP0_EntryLo1
));
5761 register_name
= "EntryLo1";
5764 goto cp0_unimplemented
;
5767 case CP0_REGISTER_09
:
5769 case CP0_REG09__SAAR
:
5770 CP0_CHECK(ctx
->saar
);
5771 gen_helper_mfhc0_saar(arg
, cpu_env
);
5772 register_name
= "SAAR";
5775 goto cp0_unimplemented
;
5778 case CP0_REGISTER_17
:
5780 case CP0_REG17__LLADDR
:
5781 gen_mfhc0_load64(arg
, offsetof(CPUMIPSState
, CP0_LLAddr
),
5782 ctx
->CP0_LLAddr_shift
);
5783 register_name
= "LLAddr";
5785 case CP0_REG17__MAAR
:
5786 CP0_CHECK(ctx
->mrp
);
5787 gen_helper_mfhc0_maar(arg
, cpu_env
);
5788 register_name
= "MAAR";
5791 goto cp0_unimplemented
;
5794 case CP0_REGISTER_19
:
5796 case CP0_REG19__WATCHHI0
:
5797 case CP0_REG19__WATCHHI1
:
5798 case CP0_REG19__WATCHHI2
:
5799 case CP0_REG19__WATCHHI3
:
5800 case CP0_REG19__WATCHHI4
:
5801 case CP0_REG19__WATCHHI5
:
5802 case CP0_REG19__WATCHHI6
:
5803 case CP0_REG19__WATCHHI7
:
5804 /* upper 32 bits are only available when Config5MI != 0 */
5806 gen_mfhc0_load64(arg
, offsetof(CPUMIPSState
, CP0_WatchHi
[sel
]), 0);
5807 register_name
= "WatchHi";
5810 goto cp0_unimplemented
;
5813 case CP0_REGISTER_28
:
5819 gen_mfhc0_load64(arg
, offsetof(CPUMIPSState
, CP0_TagLo
), 0);
5820 register_name
= "TagLo";
5823 goto cp0_unimplemented
;
5827 goto cp0_unimplemented
;
5829 trace_mips_translate_c0("mfhc0", register_name
, reg
, sel
);
5833 qemu_log_mask(LOG_UNIMP
, "mfhc0 %s (reg %d sel %d)\n",
5834 register_name
, reg
, sel
);
5835 tcg_gen_movi_tl(arg
, 0);
5838 static void gen_mthc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
5840 const char *register_name
= "invalid";
5841 uint64_t mask
= ctx
->PAMask
>> 36;
5844 case CP0_REGISTER_02
:
5847 CP0_CHECK(ctx
->hflags
& MIPS_HFLAG_ELPA
);
5848 tcg_gen_andi_tl(arg
, arg
, mask
);
5849 gen_mthc0_entrylo(arg
, offsetof(CPUMIPSState
, CP0_EntryLo0
));
5850 register_name
= "EntryLo0";
5853 goto cp0_unimplemented
;
5856 case CP0_REGISTER_03
:
5858 case CP0_REG03__ENTRYLO1
:
5859 CP0_CHECK(ctx
->hflags
& MIPS_HFLAG_ELPA
);
5860 tcg_gen_andi_tl(arg
, arg
, mask
);
5861 gen_mthc0_entrylo(arg
, offsetof(CPUMIPSState
, CP0_EntryLo1
));
5862 register_name
= "EntryLo1";
5865 goto cp0_unimplemented
;
5868 case CP0_REGISTER_09
:
5870 case CP0_REG09__SAAR
:
5871 CP0_CHECK(ctx
->saar
);
5872 gen_helper_mthc0_saar(cpu_env
, arg
);
5873 register_name
= "SAAR";
5876 goto cp0_unimplemented
;
5879 case CP0_REGISTER_17
:
5881 case CP0_REG17__LLADDR
:
5883 * LLAddr is read-only (the only exception is bit 0 if LLB is
5884 * supported); the CP0_LLAddr_rw_bitmask does not seem to be
5885 * relevant for modern MIPS cores supporting MTHC0, therefore
5886 * treating MTHC0 to LLAddr as NOP.
5888 register_name
= "LLAddr";
5890 case CP0_REG17__MAAR
:
5891 CP0_CHECK(ctx
->mrp
);
5892 gen_helper_mthc0_maar(cpu_env
, arg
);
5893 register_name
= "MAAR";
5896 goto cp0_unimplemented
;
5899 case CP0_REGISTER_19
:
5901 case CP0_REG19__WATCHHI0
:
5902 case CP0_REG19__WATCHHI1
:
5903 case CP0_REG19__WATCHHI2
:
5904 case CP0_REG19__WATCHHI3
:
5905 case CP0_REG19__WATCHHI4
:
5906 case CP0_REG19__WATCHHI5
:
5907 case CP0_REG19__WATCHHI6
:
5908 case CP0_REG19__WATCHHI7
:
5909 /* upper 32 bits are only available when Config5MI != 0 */
5911 gen_helper_0e1i(mthc0_watchhi
, arg
, sel
);
5912 register_name
= "WatchHi";
5915 goto cp0_unimplemented
;
5918 case CP0_REGISTER_28
:
5924 tcg_gen_andi_tl(arg
, arg
, mask
);
5925 gen_mthc0_store64(arg
, offsetof(CPUMIPSState
, CP0_TagLo
));
5926 register_name
= "TagLo";
5929 goto cp0_unimplemented
;
5933 goto cp0_unimplemented
;
5935 trace_mips_translate_c0("mthc0", register_name
, reg
, sel
);
5939 qemu_log_mask(LOG_UNIMP
, "mthc0 %s (reg %d sel %d)\n",
5940 register_name
, reg
, sel
);
5943 static inline void gen_mfc0_unimplemented(DisasContext
*ctx
, TCGv arg
)
5945 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
5946 tcg_gen_movi_tl(arg
, 0);
5948 tcg_gen_movi_tl(arg
, ~0);
5952 static void gen_mfc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
5954 const char *register_name
= "invalid";
5957 check_insn(ctx
, ISA_MIPS_R1
);
5961 case CP0_REGISTER_00
:
5963 case CP0_REG00__INDEX
:
5964 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Index
));
5965 register_name
= "Index";
5967 case CP0_REG00__MVPCONTROL
:
5968 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5969 gen_helper_mfc0_mvpcontrol(arg
, cpu_env
);
5970 register_name
= "MVPControl";
5972 case CP0_REG00__MVPCONF0
:
5973 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5974 gen_helper_mfc0_mvpconf0(arg
, cpu_env
);
5975 register_name
= "MVPConf0";
5977 case CP0_REG00__MVPCONF1
:
5978 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5979 gen_helper_mfc0_mvpconf1(arg
, cpu_env
);
5980 register_name
= "MVPConf1";
5982 case CP0_REG00__VPCONTROL
:
5984 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPControl
));
5985 register_name
= "VPControl";
5988 goto cp0_unimplemented
;
5991 case CP0_REGISTER_01
:
5993 case CP0_REG01__RANDOM
:
5994 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS_R6
));
5995 gen_helper_mfc0_random(arg
, cpu_env
);
5996 register_name
= "Random";
5998 case CP0_REG01__VPECONTROL
:
5999 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6000 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEControl
));
6001 register_name
= "VPEControl";
6003 case CP0_REG01__VPECONF0
:
6004 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6005 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf0
));
6006 register_name
= "VPEConf0";
6008 case CP0_REG01__VPECONF1
:
6009 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6010 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf1
));
6011 register_name
= "VPEConf1";
6013 case CP0_REG01__YQMASK
:
6014 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6015 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_YQMask
));
6016 register_name
= "YQMask";
6018 case CP0_REG01__VPESCHEDULE
:
6019 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6020 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_VPESchedule
));
6021 register_name
= "VPESchedule";
6023 case CP0_REG01__VPESCHEFBACK
:
6024 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6025 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
6026 register_name
= "VPEScheFBack";
6028 case CP0_REG01__VPEOPT
:
6029 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6030 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEOpt
));
6031 register_name
= "VPEOpt";
6034 goto cp0_unimplemented
;
6037 case CP0_REGISTER_02
:
6039 case CP0_REG02__ENTRYLO0
:
6041 TCGv_i64 tmp
= tcg_temp_new_i64();
6042 tcg_gen_ld_i64(tmp
, cpu_env
,
6043 offsetof(CPUMIPSState
, CP0_EntryLo0
));
6044 #if defined(TARGET_MIPS64)
6046 /* Move RI/XI fields to bits 31:30 */
6047 tcg_gen_shri_tl(arg
, tmp
, CP0EnLo_XI
);
6048 tcg_gen_deposit_tl(tmp
, tmp
, arg
, 30, 2);
6051 gen_move_low32(arg
, tmp
);
6052 tcg_temp_free_i64(tmp
);
6054 register_name
= "EntryLo0";
6056 case CP0_REG02__TCSTATUS
:
6057 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6058 gen_helper_mfc0_tcstatus(arg
, cpu_env
);
6059 register_name
= "TCStatus";
6061 case CP0_REG02__TCBIND
:
6062 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6063 gen_helper_mfc0_tcbind(arg
, cpu_env
);
6064 register_name
= "TCBind";
6066 case CP0_REG02__TCRESTART
:
6067 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6068 gen_helper_mfc0_tcrestart(arg
, cpu_env
);
6069 register_name
= "TCRestart";
6071 case CP0_REG02__TCHALT
:
6072 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6073 gen_helper_mfc0_tchalt(arg
, cpu_env
);
6074 register_name
= "TCHalt";
6076 case CP0_REG02__TCCONTEXT
:
6077 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6078 gen_helper_mfc0_tccontext(arg
, cpu_env
);
6079 register_name
= "TCContext";
6081 case CP0_REG02__TCSCHEDULE
:
6082 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6083 gen_helper_mfc0_tcschedule(arg
, cpu_env
);
6084 register_name
= "TCSchedule";
6086 case CP0_REG02__TCSCHEFBACK
:
6087 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6088 gen_helper_mfc0_tcschefback(arg
, cpu_env
);
6089 register_name
= "TCScheFBack";
6092 goto cp0_unimplemented
;
6095 case CP0_REGISTER_03
:
6097 case CP0_REG03__ENTRYLO1
:
6099 TCGv_i64 tmp
= tcg_temp_new_i64();
6100 tcg_gen_ld_i64(tmp
, cpu_env
,
6101 offsetof(CPUMIPSState
, CP0_EntryLo1
));
6102 #if defined(TARGET_MIPS64)
6104 /* Move RI/XI fields to bits 31:30 */
6105 tcg_gen_shri_tl(arg
, tmp
, CP0EnLo_XI
);
6106 tcg_gen_deposit_tl(tmp
, tmp
, arg
, 30, 2);
6109 gen_move_low32(arg
, tmp
);
6110 tcg_temp_free_i64(tmp
);
6112 register_name
= "EntryLo1";
6114 case CP0_REG03__GLOBALNUM
:
6116 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_GlobalNumber
));
6117 register_name
= "GlobalNumber";
6120 goto cp0_unimplemented
;
6123 case CP0_REGISTER_04
:
6125 case CP0_REG04__CONTEXT
:
6126 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_Context
));
6127 tcg_gen_ext32s_tl(arg
, arg
);
6128 register_name
= "Context";
6130 case CP0_REG04__CONTEXTCONFIG
:
6132 /* gen_helper_mfc0_contextconfig(arg); */
6133 register_name
= "ContextConfig";
6134 goto cp0_unimplemented
;
6135 case CP0_REG04__USERLOCAL
:
6136 CP0_CHECK(ctx
->ulri
);
6137 tcg_gen_ld_tl(arg
, cpu_env
,
6138 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
6139 tcg_gen_ext32s_tl(arg
, arg
);
6140 register_name
= "UserLocal";
6142 case CP0_REG04__MMID
:
6144 gen_helper_mtc0_memorymapid(cpu_env
, arg
);
6145 register_name
= "MMID";
6148 goto cp0_unimplemented
;
6151 case CP0_REGISTER_05
:
6153 case CP0_REG05__PAGEMASK
:
6154 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageMask
));
6155 register_name
= "PageMask";
6157 case CP0_REG05__PAGEGRAIN
:
6158 check_insn(ctx
, ISA_MIPS_R2
);
6159 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageGrain
));
6160 register_name
= "PageGrain";
6162 case CP0_REG05__SEGCTL0
:
6164 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_SegCtl0
));
6165 tcg_gen_ext32s_tl(arg
, arg
);
6166 register_name
= "SegCtl0";
6168 case CP0_REG05__SEGCTL1
:
6170 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_SegCtl1
));
6171 tcg_gen_ext32s_tl(arg
, arg
);
6172 register_name
= "SegCtl1";
6174 case CP0_REG05__SEGCTL2
:
6176 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_SegCtl2
));
6177 tcg_gen_ext32s_tl(arg
, arg
);
6178 register_name
= "SegCtl2";
6180 case CP0_REG05__PWBASE
:
6182 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PWBase
));
6183 register_name
= "PWBase";
6185 case CP0_REG05__PWFIELD
:
6187 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PWField
));
6188 register_name
= "PWField";
6190 case CP0_REG05__PWSIZE
:
6192 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PWSize
));
6193 register_name
= "PWSize";
6196 goto cp0_unimplemented
;
6199 case CP0_REGISTER_06
:
6201 case CP0_REG06__WIRED
:
6202 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Wired
));
6203 register_name
= "Wired";
6205 case CP0_REG06__SRSCONF0
:
6206 check_insn(ctx
, ISA_MIPS_R2
);
6207 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf0
));
6208 register_name
= "SRSConf0";
6210 case CP0_REG06__SRSCONF1
:
6211 check_insn(ctx
, ISA_MIPS_R2
);
6212 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf1
));
6213 register_name
= "SRSConf1";
6215 case CP0_REG06__SRSCONF2
:
6216 check_insn(ctx
, ISA_MIPS_R2
);
6217 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf2
));
6218 register_name
= "SRSConf2";
6220 case CP0_REG06__SRSCONF3
:
6221 check_insn(ctx
, ISA_MIPS_R2
);
6222 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf3
));
6223 register_name
= "SRSConf3";
6225 case CP0_REG06__SRSCONF4
:
6226 check_insn(ctx
, ISA_MIPS_R2
);
6227 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf4
));
6228 register_name
= "SRSConf4";
6230 case CP0_REG06__PWCTL
:
6232 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PWCtl
));
6233 register_name
= "PWCtl";
6236 goto cp0_unimplemented
;
6239 case CP0_REGISTER_07
:
6241 case CP0_REG07__HWRENA
:
6242 check_insn(ctx
, ISA_MIPS_R2
);
6243 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_HWREna
));
6244 register_name
= "HWREna";
6247 goto cp0_unimplemented
;
6250 case CP0_REGISTER_08
:
6252 case CP0_REG08__BADVADDR
:
6253 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_BadVAddr
));
6254 tcg_gen_ext32s_tl(arg
, arg
);
6255 register_name
= "BadVAddr";
6257 case CP0_REG08__BADINSTR
:
6259 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstr
));
6260 register_name
= "BadInstr";
6262 case CP0_REG08__BADINSTRP
:
6264 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstrP
));
6265 register_name
= "BadInstrP";
6267 case CP0_REG08__BADINSTRX
:
6269 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstrX
));
6270 tcg_gen_andi_tl(arg
, arg
, ~0xffff);
6271 register_name
= "BadInstrX";
6274 goto cp0_unimplemented
;
6277 case CP0_REGISTER_09
:
6279 case CP0_REG09__COUNT
:
6280 /* Mark as an IO operation because we read the time. */
6281 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
6284 gen_helper_mfc0_count(arg
, cpu_env
);
6286 * Break the TB to be able to take timer interrupts immediately
6287 * after reading count. DISAS_STOP isn't sufficient, we need to
6288 * ensure we break completely out of translated code.
6290 gen_save_pc(ctx
->base
.pc_next
+ 4);
6291 ctx
->base
.is_jmp
= DISAS_EXIT
;
6292 register_name
= "Count";
6294 case CP0_REG09__SAARI
:
6295 CP0_CHECK(ctx
->saar
);
6296 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SAARI
));
6297 register_name
= "SAARI";
6299 case CP0_REG09__SAAR
:
6300 CP0_CHECK(ctx
->saar
);
6301 gen_helper_mfc0_saar(arg
, cpu_env
);
6302 register_name
= "SAAR";
6305 goto cp0_unimplemented
;
6308 case CP0_REGISTER_10
:
6310 case CP0_REG10__ENTRYHI
:
6311 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryHi
));
6312 tcg_gen_ext32s_tl(arg
, arg
);
6313 register_name
= "EntryHi";
6316 goto cp0_unimplemented
;
6319 case CP0_REGISTER_11
:
6321 case CP0_REG11__COMPARE
:
6322 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Compare
));
6323 register_name
= "Compare";
6325 /* 6,7 are implementation dependent */
6327 goto cp0_unimplemented
;
6330 case CP0_REGISTER_12
:
6332 case CP0_REG12__STATUS
:
6333 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Status
));
6334 register_name
= "Status";
6336 case CP0_REG12__INTCTL
:
6337 check_insn(ctx
, ISA_MIPS_R2
);
6338 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_IntCtl
));
6339 register_name
= "IntCtl";
6341 case CP0_REG12__SRSCTL
:
6342 check_insn(ctx
, ISA_MIPS_R2
);
6343 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
6344 register_name
= "SRSCtl";
6346 case CP0_REG12__SRSMAP
:
6347 check_insn(ctx
, ISA_MIPS_R2
);
6348 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
6349 register_name
= "SRSMap";
6352 goto cp0_unimplemented
;
6355 case CP0_REGISTER_13
:
6357 case CP0_REG13__CAUSE
:
6358 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Cause
));
6359 register_name
= "Cause";
6362 goto cp0_unimplemented
;
6365 case CP0_REGISTER_14
:
6367 case CP0_REG14__EPC
:
6368 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
6369 tcg_gen_ext32s_tl(arg
, arg
);
6370 register_name
= "EPC";
6373 goto cp0_unimplemented
;
6376 case CP0_REGISTER_15
:
6378 case CP0_REG15__PRID
:
6379 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PRid
));
6380 register_name
= "PRid";
6382 case CP0_REG15__EBASE
:
6383 check_insn(ctx
, ISA_MIPS_R2
);
6384 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EBase
));
6385 tcg_gen_ext32s_tl(arg
, arg
);
6386 register_name
= "EBase";
6388 case CP0_REG15__CMGCRBASE
:
6389 check_insn(ctx
, ISA_MIPS_R2
);
6390 CP0_CHECK(ctx
->cmgcr
);
6391 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_CMGCRBase
));
6392 tcg_gen_ext32s_tl(arg
, arg
);
6393 register_name
= "CMGCRBase";
6396 goto cp0_unimplemented
;
6399 case CP0_REGISTER_16
:
6401 case CP0_REG16__CONFIG
:
6402 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config0
));
6403 register_name
= "Config";
6405 case CP0_REG16__CONFIG1
:
6406 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config1
));
6407 register_name
= "Config1";
6409 case CP0_REG16__CONFIG2
:
6410 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config2
));
6411 register_name
= "Config2";
6413 case CP0_REG16__CONFIG3
:
6414 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config3
));
6415 register_name
= "Config3";
6417 case CP0_REG16__CONFIG4
:
6418 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config4
));
6419 register_name
= "Config4";
6421 case CP0_REG16__CONFIG5
:
6422 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config5
));
6423 register_name
= "Config5";
6425 /* 6,7 are implementation dependent */
6426 case CP0_REG16__CONFIG6
:
6427 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config6
));
6428 register_name
= "Config6";
6430 case CP0_REG16__CONFIG7
:
6431 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config7
));
6432 register_name
= "Config7";
6435 goto cp0_unimplemented
;
6438 case CP0_REGISTER_17
:
6440 case CP0_REG17__LLADDR
:
6441 gen_helper_mfc0_lladdr(arg
, cpu_env
);
6442 register_name
= "LLAddr";
6444 case CP0_REG17__MAAR
:
6445 CP0_CHECK(ctx
->mrp
);
6446 gen_helper_mfc0_maar(arg
, cpu_env
);
6447 register_name
= "MAAR";
6449 case CP0_REG17__MAARI
:
6450 CP0_CHECK(ctx
->mrp
);
6451 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_MAARI
));
6452 register_name
= "MAARI";
6455 goto cp0_unimplemented
;
6458 case CP0_REGISTER_18
:
6460 case CP0_REG18__WATCHLO0
:
6461 case CP0_REG18__WATCHLO1
:
6462 case CP0_REG18__WATCHLO2
:
6463 case CP0_REG18__WATCHLO3
:
6464 case CP0_REG18__WATCHLO4
:
6465 case CP0_REG18__WATCHLO5
:
6466 case CP0_REG18__WATCHLO6
:
6467 case CP0_REG18__WATCHLO7
:
6468 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
6469 gen_helper_1e0i(mfc0_watchlo
, arg
, sel
);
6470 register_name
= "WatchLo";
6473 goto cp0_unimplemented
;
6476 case CP0_REGISTER_19
:
6478 case CP0_REG19__WATCHHI0
:
6479 case CP0_REG19__WATCHHI1
:
6480 case CP0_REG19__WATCHHI2
:
6481 case CP0_REG19__WATCHHI3
:
6482 case CP0_REG19__WATCHHI4
:
6483 case CP0_REG19__WATCHHI5
:
6484 case CP0_REG19__WATCHHI6
:
6485 case CP0_REG19__WATCHHI7
:
6486 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
6487 gen_helper_1e0i(mfc0_watchhi
, arg
, sel
);
6488 register_name
= "WatchHi";
6491 goto cp0_unimplemented
;
6494 case CP0_REGISTER_20
:
6496 case CP0_REG20__XCONTEXT
:
6497 #if defined(TARGET_MIPS64)
6498 check_insn(ctx
, ISA_MIPS3
);
6499 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_XContext
));
6500 tcg_gen_ext32s_tl(arg
, arg
);
6501 register_name
= "XContext";
6505 goto cp0_unimplemented
;
6508 case CP0_REGISTER_21
:
6509 /* Officially reserved, but sel 0 is used for R1x000 framemask */
6510 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS_R6
));
6513 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Framemask
));
6514 register_name
= "Framemask";
6517 goto cp0_unimplemented
;
6520 case CP0_REGISTER_22
:
6521 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
6522 register_name
= "'Diagnostic"; /* implementation dependent */
6524 case CP0_REGISTER_23
:
6526 case CP0_REG23__DEBUG
:
6527 gen_helper_mfc0_debug(arg
, cpu_env
); /* EJTAG support */
6528 register_name
= "Debug";
6530 case CP0_REG23__TRACECONTROL
:
6531 /* PDtrace support */
6532 /* gen_helper_mfc0_tracecontrol(arg); */
6533 register_name
= "TraceControl";
6534 goto cp0_unimplemented
;
6535 case CP0_REG23__TRACECONTROL2
:
6536 /* PDtrace support */
6537 /* gen_helper_mfc0_tracecontrol2(arg); */
6538 register_name
= "TraceControl2";
6539 goto cp0_unimplemented
;
6540 case CP0_REG23__USERTRACEDATA1
:
6541 /* PDtrace support */
6542 /* gen_helper_mfc0_usertracedata1(arg);*/
6543 register_name
= "UserTraceData1";
6544 goto cp0_unimplemented
;
6545 case CP0_REG23__TRACEIBPC
:
6546 /* PDtrace support */
6547 /* gen_helper_mfc0_traceibpc(arg); */
6548 register_name
= "TraceIBPC";
6549 goto cp0_unimplemented
;
6550 case CP0_REG23__TRACEDBPC
:
6551 /* PDtrace support */
6552 /* gen_helper_mfc0_tracedbpc(arg); */
6553 register_name
= "TraceDBPC";
6554 goto cp0_unimplemented
;
6556 goto cp0_unimplemented
;
6559 case CP0_REGISTER_24
:
6561 case CP0_REG24__DEPC
:
6563 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
6564 tcg_gen_ext32s_tl(arg
, arg
);
6565 register_name
= "DEPC";
6568 goto cp0_unimplemented
;
6571 case CP0_REGISTER_25
:
6573 case CP0_REG25__PERFCTL0
:
6574 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Performance0
));
6575 register_name
= "Performance0";
6577 case CP0_REG25__PERFCNT0
:
6578 /* gen_helper_mfc0_performance1(arg); */
6579 register_name
= "Performance1";
6580 goto cp0_unimplemented
;
6581 case CP0_REG25__PERFCTL1
:
6582 /* gen_helper_mfc0_performance2(arg); */
6583 register_name
= "Performance2";
6584 goto cp0_unimplemented
;
6585 case CP0_REG25__PERFCNT1
:
6586 /* gen_helper_mfc0_performance3(arg); */
6587 register_name
= "Performance3";
6588 goto cp0_unimplemented
;
6589 case CP0_REG25__PERFCTL2
:
6590 /* gen_helper_mfc0_performance4(arg); */
6591 register_name
= "Performance4";
6592 goto cp0_unimplemented
;
6593 case CP0_REG25__PERFCNT2
:
6594 /* gen_helper_mfc0_performance5(arg); */
6595 register_name
= "Performance5";
6596 goto cp0_unimplemented
;
6597 case CP0_REG25__PERFCTL3
:
6598 /* gen_helper_mfc0_performance6(arg); */
6599 register_name
= "Performance6";
6600 goto cp0_unimplemented
;
6601 case CP0_REG25__PERFCNT3
:
6602 /* gen_helper_mfc0_performance7(arg); */
6603 register_name
= "Performance7";
6604 goto cp0_unimplemented
;
6606 goto cp0_unimplemented
;
6609 case CP0_REGISTER_26
:
6611 case CP0_REG26__ERRCTL
:
6612 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_ErrCtl
));
6613 register_name
= "ErrCtl";
6616 goto cp0_unimplemented
;
6619 case CP0_REGISTER_27
:
6621 case CP0_REG27__CACHERR
:
6622 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
6623 register_name
= "CacheErr";
6626 goto cp0_unimplemented
;
6629 case CP0_REGISTER_28
:
6631 case CP0_REG28__TAGLO
:
6632 case CP0_REG28__TAGLO1
:
6633 case CP0_REG28__TAGLO2
:
6634 case CP0_REG28__TAGLO3
:
6636 TCGv_i64 tmp
= tcg_temp_new_i64();
6637 tcg_gen_ld_i64(tmp
, cpu_env
, offsetof(CPUMIPSState
, CP0_TagLo
));
6638 gen_move_low32(arg
, tmp
);
6639 tcg_temp_free_i64(tmp
);
6641 register_name
= "TagLo";
6643 case CP0_REG28__DATALO
:
6644 case CP0_REG28__DATALO1
:
6645 case CP0_REG28__DATALO2
:
6646 case CP0_REG28__DATALO3
:
6647 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataLo
));
6648 register_name
= "DataLo";
6651 goto cp0_unimplemented
;
6654 case CP0_REGISTER_29
:
6656 case CP0_REG29__TAGHI
:
6657 case CP0_REG29__TAGHI1
:
6658 case CP0_REG29__TAGHI2
:
6659 case CP0_REG29__TAGHI3
:
6660 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagHi
));
6661 register_name
= "TagHi";
6663 case CP0_REG29__DATAHI
:
6664 case CP0_REG29__DATAHI1
:
6665 case CP0_REG29__DATAHI2
:
6666 case CP0_REG29__DATAHI3
:
6667 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataHi
));
6668 register_name
= "DataHi";
6671 goto cp0_unimplemented
;
6674 case CP0_REGISTER_30
:
6676 case CP0_REG30__ERROREPC
:
6677 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
6678 tcg_gen_ext32s_tl(arg
, arg
);
6679 register_name
= "ErrorEPC";
6682 goto cp0_unimplemented
;
6685 case CP0_REGISTER_31
:
6687 case CP0_REG31__DESAVE
:
6689 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
6690 register_name
= "DESAVE";
6692 case CP0_REG31__KSCRATCH1
:
6693 case CP0_REG31__KSCRATCH2
:
6694 case CP0_REG31__KSCRATCH3
:
6695 case CP0_REG31__KSCRATCH4
:
6696 case CP0_REG31__KSCRATCH5
:
6697 case CP0_REG31__KSCRATCH6
:
6698 CP0_CHECK(ctx
->kscrexist
& (1 << sel
));
6699 tcg_gen_ld_tl(arg
, cpu_env
,
6700 offsetof(CPUMIPSState
, CP0_KScratch
[sel
- 2]));
6701 tcg_gen_ext32s_tl(arg
, arg
);
6702 register_name
= "KScratch";
6705 goto cp0_unimplemented
;
6709 goto cp0_unimplemented
;
6711 trace_mips_translate_c0("mfc0", register_name
, reg
, sel
);
6715 qemu_log_mask(LOG_UNIMP
, "mfc0 %s (reg %d sel %d)\n",
6716 register_name
, reg
, sel
);
6717 gen_mfc0_unimplemented(ctx
, arg
);
6720 static void gen_mtc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
6722 const char *register_name
= "invalid";
6725 check_insn(ctx
, ISA_MIPS_R1
);
6728 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
6733 case CP0_REGISTER_00
:
6735 case CP0_REG00__INDEX
:
6736 gen_helper_mtc0_index(cpu_env
, arg
);
6737 register_name
= "Index";
6739 case CP0_REG00__MVPCONTROL
:
6740 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6741 gen_helper_mtc0_mvpcontrol(cpu_env
, arg
);
6742 register_name
= "MVPControl";
6744 case CP0_REG00__MVPCONF0
:
6745 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6747 register_name
= "MVPConf0";
6749 case CP0_REG00__MVPCONF1
:
6750 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6752 register_name
= "MVPConf1";
6754 case CP0_REG00__VPCONTROL
:
6757 register_name
= "VPControl";
6760 goto cp0_unimplemented
;
6763 case CP0_REGISTER_01
:
6765 case CP0_REG01__RANDOM
:
6767 register_name
= "Random";
6769 case CP0_REG01__VPECONTROL
:
6770 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6771 gen_helper_mtc0_vpecontrol(cpu_env
, arg
);
6772 register_name
= "VPEControl";
6774 case CP0_REG01__VPECONF0
:
6775 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6776 gen_helper_mtc0_vpeconf0(cpu_env
, arg
);
6777 register_name
= "VPEConf0";
6779 case CP0_REG01__VPECONF1
:
6780 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6781 gen_helper_mtc0_vpeconf1(cpu_env
, arg
);
6782 register_name
= "VPEConf1";
6784 case CP0_REG01__YQMASK
:
6785 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6786 gen_helper_mtc0_yqmask(cpu_env
, arg
);
6787 register_name
= "YQMask";
6789 case CP0_REG01__VPESCHEDULE
:
6790 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6791 tcg_gen_st_tl(arg
, cpu_env
,
6792 offsetof(CPUMIPSState
, CP0_VPESchedule
));
6793 register_name
= "VPESchedule";
6795 case CP0_REG01__VPESCHEFBACK
:
6796 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6797 tcg_gen_st_tl(arg
, cpu_env
,
6798 offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
6799 register_name
= "VPEScheFBack";
6801 case CP0_REG01__VPEOPT
:
6802 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6803 gen_helper_mtc0_vpeopt(cpu_env
, arg
);
6804 register_name
= "VPEOpt";
6807 goto cp0_unimplemented
;
6810 case CP0_REGISTER_02
:
6812 case CP0_REG02__ENTRYLO0
:
6813 gen_helper_mtc0_entrylo0(cpu_env
, arg
);
6814 register_name
= "EntryLo0";
6816 case CP0_REG02__TCSTATUS
:
6817 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6818 gen_helper_mtc0_tcstatus(cpu_env
, arg
);
6819 register_name
= "TCStatus";
6821 case CP0_REG02__TCBIND
:
6822 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6823 gen_helper_mtc0_tcbind(cpu_env
, arg
);
6824 register_name
= "TCBind";
6826 case CP0_REG02__TCRESTART
:
6827 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6828 gen_helper_mtc0_tcrestart(cpu_env
, arg
);
6829 register_name
= "TCRestart";
6831 case CP0_REG02__TCHALT
:
6832 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6833 gen_helper_mtc0_tchalt(cpu_env
, arg
);
6834 register_name
= "TCHalt";
6836 case CP0_REG02__TCCONTEXT
:
6837 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6838 gen_helper_mtc0_tccontext(cpu_env
, arg
);
6839 register_name
= "TCContext";
6841 case CP0_REG02__TCSCHEDULE
:
6842 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6843 gen_helper_mtc0_tcschedule(cpu_env
, arg
);
6844 register_name
= "TCSchedule";
6846 case CP0_REG02__TCSCHEFBACK
:
6847 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6848 gen_helper_mtc0_tcschefback(cpu_env
, arg
);
6849 register_name
= "TCScheFBack";
6852 goto cp0_unimplemented
;
6855 case CP0_REGISTER_03
:
6857 case CP0_REG03__ENTRYLO1
:
6858 gen_helper_mtc0_entrylo1(cpu_env
, arg
);
6859 register_name
= "EntryLo1";
6861 case CP0_REG03__GLOBALNUM
:
6864 register_name
= "GlobalNumber";
6867 goto cp0_unimplemented
;
6870 case CP0_REGISTER_04
:
6872 case CP0_REG04__CONTEXT
:
6873 gen_helper_mtc0_context(cpu_env
, arg
);
6874 register_name
= "Context";
6876 case CP0_REG04__CONTEXTCONFIG
:
6878 /* gen_helper_mtc0_contextconfig(arg); */
6879 register_name
= "ContextConfig";
6880 goto cp0_unimplemented
;
6881 case CP0_REG04__USERLOCAL
:
6882 CP0_CHECK(ctx
->ulri
);
6883 tcg_gen_st_tl(arg
, cpu_env
,
6884 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
6885 register_name
= "UserLocal";
6887 case CP0_REG04__MMID
:
6889 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_MemoryMapID
));
6890 register_name
= "MMID";
6893 goto cp0_unimplemented
;
6896 case CP0_REGISTER_05
:
6898 case CP0_REG05__PAGEMASK
:
6899 gen_helper_mtc0_pagemask(cpu_env
, arg
);
6900 register_name
= "PageMask";
6902 case CP0_REG05__PAGEGRAIN
:
6903 check_insn(ctx
, ISA_MIPS_R2
);
6904 gen_helper_mtc0_pagegrain(cpu_env
, arg
);
6905 register_name
= "PageGrain";
6906 ctx
->base
.is_jmp
= DISAS_STOP
;
6908 case CP0_REG05__SEGCTL0
:
6910 gen_helper_mtc0_segctl0(cpu_env
, arg
);
6911 register_name
= "SegCtl0";
6913 case CP0_REG05__SEGCTL1
:
6915 gen_helper_mtc0_segctl1(cpu_env
, arg
);
6916 register_name
= "SegCtl1";
6918 case CP0_REG05__SEGCTL2
:
6920 gen_helper_mtc0_segctl2(cpu_env
, arg
);
6921 register_name
= "SegCtl2";
6923 case CP0_REG05__PWBASE
:
6925 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_PWBase
));
6926 register_name
= "PWBase";
6928 case CP0_REG05__PWFIELD
:
6930 gen_helper_mtc0_pwfield(cpu_env
, arg
);
6931 register_name
= "PWField";
6933 case CP0_REG05__PWSIZE
:
6935 gen_helper_mtc0_pwsize(cpu_env
, arg
);
6936 register_name
= "PWSize";
6939 goto cp0_unimplemented
;
6942 case CP0_REGISTER_06
:
6944 case CP0_REG06__WIRED
:
6945 gen_helper_mtc0_wired(cpu_env
, arg
);
6946 register_name
= "Wired";
6948 case CP0_REG06__SRSCONF0
:
6949 check_insn(ctx
, ISA_MIPS_R2
);
6950 gen_helper_mtc0_srsconf0(cpu_env
, arg
);
6951 register_name
= "SRSConf0";
6953 case CP0_REG06__SRSCONF1
:
6954 check_insn(ctx
, ISA_MIPS_R2
);
6955 gen_helper_mtc0_srsconf1(cpu_env
, arg
);
6956 register_name
= "SRSConf1";
6958 case CP0_REG06__SRSCONF2
:
6959 check_insn(ctx
, ISA_MIPS_R2
);
6960 gen_helper_mtc0_srsconf2(cpu_env
, arg
);
6961 register_name
= "SRSConf2";
6963 case CP0_REG06__SRSCONF3
:
6964 check_insn(ctx
, ISA_MIPS_R2
);
6965 gen_helper_mtc0_srsconf3(cpu_env
, arg
);
6966 register_name
= "SRSConf3";
6968 case CP0_REG06__SRSCONF4
:
6969 check_insn(ctx
, ISA_MIPS_R2
);
6970 gen_helper_mtc0_srsconf4(cpu_env
, arg
);
6971 register_name
= "SRSConf4";
6973 case CP0_REG06__PWCTL
:
6975 gen_helper_mtc0_pwctl(cpu_env
, arg
);
6976 register_name
= "PWCtl";
6979 goto cp0_unimplemented
;
6982 case CP0_REGISTER_07
:
6984 case CP0_REG07__HWRENA
:
6985 check_insn(ctx
, ISA_MIPS_R2
);
6986 gen_helper_mtc0_hwrena(cpu_env
, arg
);
6987 ctx
->base
.is_jmp
= DISAS_STOP
;
6988 register_name
= "HWREna";
6991 goto cp0_unimplemented
;
6994 case CP0_REGISTER_08
:
6996 case CP0_REG08__BADVADDR
:
6998 register_name
= "BadVAddr";
7000 case CP0_REG08__BADINSTR
:
7002 register_name
= "BadInstr";
7004 case CP0_REG08__BADINSTRP
:
7006 register_name
= "BadInstrP";
7008 case CP0_REG08__BADINSTRX
:
7010 register_name
= "BadInstrX";
7013 goto cp0_unimplemented
;
7016 case CP0_REGISTER_09
:
7018 case CP0_REG09__COUNT
:
7019 gen_helper_mtc0_count(cpu_env
, arg
);
7020 register_name
= "Count";
7022 case CP0_REG09__SAARI
:
7023 CP0_CHECK(ctx
->saar
);
7024 gen_helper_mtc0_saari(cpu_env
, arg
);
7025 register_name
= "SAARI";
7027 case CP0_REG09__SAAR
:
7028 CP0_CHECK(ctx
->saar
);
7029 gen_helper_mtc0_saar(cpu_env
, arg
);
7030 register_name
= "SAAR";
7033 goto cp0_unimplemented
;
7036 case CP0_REGISTER_10
:
7038 case CP0_REG10__ENTRYHI
:
7039 gen_helper_mtc0_entryhi(cpu_env
, arg
);
7040 register_name
= "EntryHi";
7043 goto cp0_unimplemented
;
7046 case CP0_REGISTER_11
:
7048 case CP0_REG11__COMPARE
:
7049 gen_helper_mtc0_compare(cpu_env
, arg
);
7050 register_name
= "Compare";
7052 /* 6,7 are implementation dependent */
7054 goto cp0_unimplemented
;
7057 case CP0_REGISTER_12
:
7059 case CP0_REG12__STATUS
:
7060 save_cpu_state(ctx
, 1);
7061 gen_helper_mtc0_status(cpu_env
, arg
);
7062 /* DISAS_STOP isn't good enough here, hflags may have changed. */
7063 gen_save_pc(ctx
->base
.pc_next
+ 4);
7064 ctx
->base
.is_jmp
= DISAS_EXIT
;
7065 register_name
= "Status";
7067 case CP0_REG12__INTCTL
:
7068 check_insn(ctx
, ISA_MIPS_R2
);
7069 gen_helper_mtc0_intctl(cpu_env
, arg
);
7070 /* Stop translation as we may have switched the execution mode */
7071 ctx
->base
.is_jmp
= DISAS_STOP
;
7072 register_name
= "IntCtl";
7074 case CP0_REG12__SRSCTL
:
7075 check_insn(ctx
, ISA_MIPS_R2
);
7076 gen_helper_mtc0_srsctl(cpu_env
, arg
);
7077 /* Stop translation as we may have switched the execution mode */
7078 ctx
->base
.is_jmp
= DISAS_STOP
;
7079 register_name
= "SRSCtl";
7081 case CP0_REG12__SRSMAP
:
7082 check_insn(ctx
, ISA_MIPS_R2
);
7083 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
7084 /* Stop translation as we may have switched the execution mode */
7085 ctx
->base
.is_jmp
= DISAS_STOP
;
7086 register_name
= "SRSMap";
7089 goto cp0_unimplemented
;
7092 case CP0_REGISTER_13
:
7094 case CP0_REG13__CAUSE
:
7095 save_cpu_state(ctx
, 1);
7096 gen_helper_mtc0_cause(cpu_env
, arg
);
7098 * Stop translation as we may have triggered an interrupt.
7099 * DISAS_STOP isn't sufficient, we need to ensure we break out of
7100 * translated code to check for pending interrupts.
7102 gen_save_pc(ctx
->base
.pc_next
+ 4);
7103 ctx
->base
.is_jmp
= DISAS_EXIT
;
7104 register_name
= "Cause";
7107 goto cp0_unimplemented
;
7110 case CP0_REGISTER_14
:
7112 case CP0_REG14__EPC
:
7113 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
7114 register_name
= "EPC";
7117 goto cp0_unimplemented
;
7120 case CP0_REGISTER_15
:
7122 case CP0_REG15__PRID
:
7124 register_name
= "PRid";
7126 case CP0_REG15__EBASE
:
7127 check_insn(ctx
, ISA_MIPS_R2
);
7128 gen_helper_mtc0_ebase(cpu_env
, arg
);
7129 register_name
= "EBase";
7132 goto cp0_unimplemented
;
7135 case CP0_REGISTER_16
:
7137 case CP0_REG16__CONFIG
:
7138 gen_helper_mtc0_config0(cpu_env
, arg
);
7139 register_name
= "Config";
7140 /* Stop translation as we may have switched the execution mode */
7141 ctx
->base
.is_jmp
= DISAS_STOP
;
7143 case CP0_REG16__CONFIG1
:
7144 /* ignored, read only */
7145 register_name
= "Config1";
7147 case CP0_REG16__CONFIG2
:
7148 gen_helper_mtc0_config2(cpu_env
, arg
);
7149 register_name
= "Config2";
7150 /* Stop translation as we may have switched the execution mode */
7151 ctx
->base
.is_jmp
= DISAS_STOP
;
7153 case CP0_REG16__CONFIG3
:
7154 gen_helper_mtc0_config3(cpu_env
, arg
);
7155 register_name
= "Config3";
7156 /* Stop translation as we may have switched the execution mode */
7157 ctx
->base
.is_jmp
= DISAS_STOP
;
7159 case CP0_REG16__CONFIG4
:
7160 gen_helper_mtc0_config4(cpu_env
, arg
);
7161 register_name
= "Config4";
7162 ctx
->base
.is_jmp
= DISAS_STOP
;
7164 case CP0_REG16__CONFIG5
:
7165 gen_helper_mtc0_config5(cpu_env
, arg
);
7166 register_name
= "Config5";
7167 /* Stop translation as we may have switched the execution mode */
7168 ctx
->base
.is_jmp
= DISAS_STOP
;
7170 /* 6,7 are implementation dependent */
7171 case CP0_REG16__CONFIG6
:
7173 register_name
= "Config6";
7175 case CP0_REG16__CONFIG7
:
7177 register_name
= "Config7";
7180 register_name
= "Invalid config selector";
7181 goto cp0_unimplemented
;
7184 case CP0_REGISTER_17
:
7186 case CP0_REG17__LLADDR
:
7187 gen_helper_mtc0_lladdr(cpu_env
, arg
);
7188 register_name
= "LLAddr";
7190 case CP0_REG17__MAAR
:
7191 CP0_CHECK(ctx
->mrp
);
7192 gen_helper_mtc0_maar(cpu_env
, arg
);
7193 register_name
= "MAAR";
7195 case CP0_REG17__MAARI
:
7196 CP0_CHECK(ctx
->mrp
);
7197 gen_helper_mtc0_maari(cpu_env
, arg
);
7198 register_name
= "MAARI";
7201 goto cp0_unimplemented
;
7204 case CP0_REGISTER_18
:
7206 case CP0_REG18__WATCHLO0
:
7207 case CP0_REG18__WATCHLO1
:
7208 case CP0_REG18__WATCHLO2
:
7209 case CP0_REG18__WATCHLO3
:
7210 case CP0_REG18__WATCHLO4
:
7211 case CP0_REG18__WATCHLO5
:
7212 case CP0_REG18__WATCHLO6
:
7213 case CP0_REG18__WATCHLO7
:
7214 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
7215 gen_helper_0e1i(mtc0_watchlo
, arg
, sel
);
7216 register_name
= "WatchLo";
7219 goto cp0_unimplemented
;
7222 case CP0_REGISTER_19
:
7224 case CP0_REG19__WATCHHI0
:
7225 case CP0_REG19__WATCHHI1
:
7226 case CP0_REG19__WATCHHI2
:
7227 case CP0_REG19__WATCHHI3
:
7228 case CP0_REG19__WATCHHI4
:
7229 case CP0_REG19__WATCHHI5
:
7230 case CP0_REG19__WATCHHI6
:
7231 case CP0_REG19__WATCHHI7
:
7232 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
7233 gen_helper_0e1i(mtc0_watchhi
, arg
, sel
);
7234 register_name
= "WatchHi";
7237 goto cp0_unimplemented
;
7240 case CP0_REGISTER_20
:
7242 case CP0_REG20__XCONTEXT
:
7243 #if defined(TARGET_MIPS64)
7244 check_insn(ctx
, ISA_MIPS3
);
7245 gen_helper_mtc0_xcontext(cpu_env
, arg
);
7246 register_name
= "XContext";
7250 goto cp0_unimplemented
;
7253 case CP0_REGISTER_21
:
7254 /* Officially reserved, but sel 0 is used for R1x000 framemask */
7255 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS_R6
));
7258 gen_helper_mtc0_framemask(cpu_env
, arg
);
7259 register_name
= "Framemask";
7262 goto cp0_unimplemented
;
7265 case CP0_REGISTER_22
:
7267 register_name
= "Diagnostic"; /* implementation dependent */
7269 case CP0_REGISTER_23
:
7271 case CP0_REG23__DEBUG
:
7272 gen_helper_mtc0_debug(cpu_env
, arg
); /* EJTAG support */
7273 /* DISAS_STOP isn't good enough here, hflags may have changed. */
7274 gen_save_pc(ctx
->base
.pc_next
+ 4);
7275 ctx
->base
.is_jmp
= DISAS_EXIT
;
7276 register_name
= "Debug";
7278 case CP0_REG23__TRACECONTROL
:
7279 /* PDtrace support */
7280 /* gen_helper_mtc0_tracecontrol(cpu_env, arg); */
7281 register_name
= "TraceControl";
7282 /* Stop translation as we may have switched the execution mode */
7283 ctx
->base
.is_jmp
= DISAS_STOP
;
7284 goto cp0_unimplemented
;
7285 case CP0_REG23__TRACECONTROL2
:
7286 /* PDtrace support */
7287 /* gen_helper_mtc0_tracecontrol2(cpu_env, arg); */
7288 register_name
= "TraceControl2";
7289 /* Stop translation as we may have switched the execution mode */
7290 ctx
->base
.is_jmp
= DISAS_STOP
;
7291 goto cp0_unimplemented
;
7292 case CP0_REG23__USERTRACEDATA1
:
7293 /* Stop translation as we may have switched the execution mode */
7294 ctx
->base
.is_jmp
= DISAS_STOP
;
7295 /* PDtrace support */
7296 /* gen_helper_mtc0_usertracedata1(cpu_env, arg);*/
7297 register_name
= "UserTraceData";
7298 /* Stop translation as we may have switched the execution mode */
7299 ctx
->base
.is_jmp
= DISAS_STOP
;
7300 goto cp0_unimplemented
;
7301 case CP0_REG23__TRACEIBPC
:
7302 /* PDtrace support */
7303 /* gen_helper_mtc0_traceibpc(cpu_env, arg); */
7304 /* Stop translation as we may have switched the execution mode */
7305 ctx
->base
.is_jmp
= DISAS_STOP
;
7306 register_name
= "TraceIBPC";
7307 goto cp0_unimplemented
;
7308 case CP0_REG23__TRACEDBPC
:
7309 /* PDtrace support */
7310 /* gen_helper_mtc0_tracedbpc(cpu_env, arg); */
7311 /* Stop translation as we may have switched the execution mode */
7312 ctx
->base
.is_jmp
= DISAS_STOP
;
7313 register_name
= "TraceDBPC";
7314 goto cp0_unimplemented
;
7316 goto cp0_unimplemented
;
7319 case CP0_REGISTER_24
:
7321 case CP0_REG24__DEPC
:
7323 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
7324 register_name
= "DEPC";
7327 goto cp0_unimplemented
;
7330 case CP0_REGISTER_25
:
7332 case CP0_REG25__PERFCTL0
:
7333 gen_helper_mtc0_performance0(cpu_env
, arg
);
7334 register_name
= "Performance0";
7336 case CP0_REG25__PERFCNT0
:
7337 /* gen_helper_mtc0_performance1(arg); */
7338 register_name
= "Performance1";
7339 goto cp0_unimplemented
;
7340 case CP0_REG25__PERFCTL1
:
7341 /* gen_helper_mtc0_performance2(arg); */
7342 register_name
= "Performance2";
7343 goto cp0_unimplemented
;
7344 case CP0_REG25__PERFCNT1
:
7345 /* gen_helper_mtc0_performance3(arg); */
7346 register_name
= "Performance3";
7347 goto cp0_unimplemented
;
7348 case CP0_REG25__PERFCTL2
:
7349 /* gen_helper_mtc0_performance4(arg); */
7350 register_name
= "Performance4";
7351 goto cp0_unimplemented
;
7352 case CP0_REG25__PERFCNT2
:
7353 /* gen_helper_mtc0_performance5(arg); */
7354 register_name
= "Performance5";
7355 goto cp0_unimplemented
;
7356 case CP0_REG25__PERFCTL3
:
7357 /* gen_helper_mtc0_performance6(arg); */
7358 register_name
= "Performance6";
7359 goto cp0_unimplemented
;
7360 case CP0_REG25__PERFCNT3
:
7361 /* gen_helper_mtc0_performance7(arg); */
7362 register_name
= "Performance7";
7363 goto cp0_unimplemented
;
7365 goto cp0_unimplemented
;
7368 case CP0_REGISTER_26
:
7370 case CP0_REG26__ERRCTL
:
7371 gen_helper_mtc0_errctl(cpu_env
, arg
);
7372 ctx
->base
.is_jmp
= DISAS_STOP
;
7373 register_name
= "ErrCtl";
7376 goto cp0_unimplemented
;
7379 case CP0_REGISTER_27
:
7381 case CP0_REG27__CACHERR
:
7383 register_name
= "CacheErr";
7386 goto cp0_unimplemented
;
7389 case CP0_REGISTER_28
:
7391 case CP0_REG28__TAGLO
:
7392 case CP0_REG28__TAGLO1
:
7393 case CP0_REG28__TAGLO2
:
7394 case CP0_REG28__TAGLO3
:
7395 gen_helper_mtc0_taglo(cpu_env
, arg
);
7396 register_name
= "TagLo";
7398 case CP0_REG28__DATALO
:
7399 case CP0_REG28__DATALO1
:
7400 case CP0_REG28__DATALO2
:
7401 case CP0_REG28__DATALO3
:
7402 gen_helper_mtc0_datalo(cpu_env
, arg
);
7403 register_name
= "DataLo";
7406 goto cp0_unimplemented
;
7409 case CP0_REGISTER_29
:
7411 case CP0_REG29__TAGHI
:
7412 case CP0_REG29__TAGHI1
:
7413 case CP0_REG29__TAGHI2
:
7414 case CP0_REG29__TAGHI3
:
7415 gen_helper_mtc0_taghi(cpu_env
, arg
);
7416 register_name
= "TagHi";
7418 case CP0_REG29__DATAHI
:
7419 case CP0_REG29__DATAHI1
:
7420 case CP0_REG29__DATAHI2
:
7421 case CP0_REG29__DATAHI3
:
7422 gen_helper_mtc0_datahi(cpu_env
, arg
);
7423 register_name
= "DataHi";
7426 register_name
= "invalid sel";
7427 goto cp0_unimplemented
;
7430 case CP0_REGISTER_30
:
7432 case CP0_REG30__ERROREPC
:
7433 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
7434 register_name
= "ErrorEPC";
7437 goto cp0_unimplemented
;
7440 case CP0_REGISTER_31
:
7442 case CP0_REG31__DESAVE
:
7444 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
7445 register_name
= "DESAVE";
7447 case CP0_REG31__KSCRATCH1
:
7448 case CP0_REG31__KSCRATCH2
:
7449 case CP0_REG31__KSCRATCH3
:
7450 case CP0_REG31__KSCRATCH4
:
7451 case CP0_REG31__KSCRATCH5
:
7452 case CP0_REG31__KSCRATCH6
:
7453 CP0_CHECK(ctx
->kscrexist
& (1 << sel
));
7454 tcg_gen_st_tl(arg
, cpu_env
,
7455 offsetof(CPUMIPSState
, CP0_KScratch
[sel
- 2]));
7456 register_name
= "KScratch";
7459 goto cp0_unimplemented
;
7463 goto cp0_unimplemented
;
7465 trace_mips_translate_c0("mtc0", register_name
, reg
, sel
);
7467 /* For simplicity assume that all writes can cause interrupts. */
7468 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
7470 * DISAS_STOP isn't sufficient, we need to ensure we break out of
7471 * translated code to check for pending interrupts.
7473 gen_save_pc(ctx
->base
.pc_next
+ 4);
7474 ctx
->base
.is_jmp
= DISAS_EXIT
;
7479 qemu_log_mask(LOG_UNIMP
, "mtc0 %s (reg %d sel %d)\n",
7480 register_name
, reg
, sel
);
7483 #if defined(TARGET_MIPS64)
7484 static void gen_dmfc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
7486 const char *register_name
= "invalid";
7489 check_insn(ctx
, ISA_MIPS_R1
);
7493 case CP0_REGISTER_00
:
7495 case CP0_REG00__INDEX
:
7496 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Index
));
7497 register_name
= "Index";
7499 case CP0_REG00__MVPCONTROL
:
7500 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7501 gen_helper_mfc0_mvpcontrol(arg
, cpu_env
);
7502 register_name
= "MVPControl";
7504 case CP0_REG00__MVPCONF0
:
7505 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7506 gen_helper_mfc0_mvpconf0(arg
, cpu_env
);
7507 register_name
= "MVPConf0";
7509 case CP0_REG00__MVPCONF1
:
7510 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7511 gen_helper_mfc0_mvpconf1(arg
, cpu_env
);
7512 register_name
= "MVPConf1";
7514 case CP0_REG00__VPCONTROL
:
7516 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPControl
));
7517 register_name
= "VPControl";
7520 goto cp0_unimplemented
;
7523 case CP0_REGISTER_01
:
7525 case CP0_REG01__RANDOM
:
7526 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS_R6
));
7527 gen_helper_mfc0_random(arg
, cpu_env
);
7528 register_name
= "Random";
7530 case CP0_REG01__VPECONTROL
:
7531 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7532 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEControl
));
7533 register_name
= "VPEControl";
7535 case CP0_REG01__VPECONF0
:
7536 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7537 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf0
));
7538 register_name
= "VPEConf0";
7540 case CP0_REG01__VPECONF1
:
7541 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7542 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf1
));
7543 register_name
= "VPEConf1";
7545 case CP0_REG01__YQMASK
:
7546 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7547 tcg_gen_ld_tl(arg
, cpu_env
,
7548 offsetof(CPUMIPSState
, CP0_YQMask
));
7549 register_name
= "YQMask";
7551 case CP0_REG01__VPESCHEDULE
:
7552 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7553 tcg_gen_ld_tl(arg
, cpu_env
,
7554 offsetof(CPUMIPSState
, CP0_VPESchedule
));
7555 register_name
= "VPESchedule";
7557 case CP0_REG01__VPESCHEFBACK
:
7558 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7559 tcg_gen_ld_tl(arg
, cpu_env
,
7560 offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
7561 register_name
= "VPEScheFBack";
7563 case CP0_REG01__VPEOPT
:
7564 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7565 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEOpt
));
7566 register_name
= "VPEOpt";
7569 goto cp0_unimplemented
;
7572 case CP0_REGISTER_02
:
7574 case CP0_REG02__ENTRYLO0
:
7575 tcg_gen_ld_tl(arg
, cpu_env
,
7576 offsetof(CPUMIPSState
, CP0_EntryLo0
));
7577 register_name
= "EntryLo0";
7579 case CP0_REG02__TCSTATUS
:
7580 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7581 gen_helper_mfc0_tcstatus(arg
, cpu_env
);
7582 register_name
= "TCStatus";
7584 case CP0_REG02__TCBIND
:
7585 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7586 gen_helper_mfc0_tcbind(arg
, cpu_env
);
7587 register_name
= "TCBind";
7589 case CP0_REG02__TCRESTART
:
7590 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7591 gen_helper_dmfc0_tcrestart(arg
, cpu_env
);
7592 register_name
= "TCRestart";
7594 case CP0_REG02__TCHALT
:
7595 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7596 gen_helper_dmfc0_tchalt(arg
, cpu_env
);
7597 register_name
= "TCHalt";
7599 case CP0_REG02__TCCONTEXT
:
7600 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7601 gen_helper_dmfc0_tccontext(arg
, cpu_env
);
7602 register_name
= "TCContext";
7604 case CP0_REG02__TCSCHEDULE
:
7605 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7606 gen_helper_dmfc0_tcschedule(arg
, cpu_env
);
7607 register_name
= "TCSchedule";
7609 case CP0_REG02__TCSCHEFBACK
:
7610 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7611 gen_helper_dmfc0_tcschefback(arg
, cpu_env
);
7612 register_name
= "TCScheFBack";
7615 goto cp0_unimplemented
;
7618 case CP0_REGISTER_03
:
7620 case CP0_REG03__ENTRYLO1
:
7621 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryLo1
));
7622 register_name
= "EntryLo1";
7624 case CP0_REG03__GLOBALNUM
:
7626 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_GlobalNumber
));
7627 register_name
= "GlobalNumber";
7630 goto cp0_unimplemented
;
7633 case CP0_REGISTER_04
:
7635 case CP0_REG04__CONTEXT
:
7636 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_Context
));
7637 register_name
= "Context";
7639 case CP0_REG04__CONTEXTCONFIG
:
7641 /* gen_helper_dmfc0_contextconfig(arg); */
7642 register_name
= "ContextConfig";
7643 goto cp0_unimplemented
;
7644 case CP0_REG04__USERLOCAL
:
7645 CP0_CHECK(ctx
->ulri
);
7646 tcg_gen_ld_tl(arg
, cpu_env
,
7647 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
7648 register_name
= "UserLocal";
7650 case CP0_REG04__MMID
:
7652 gen_helper_mtc0_memorymapid(cpu_env
, arg
);
7653 register_name
= "MMID";
7656 goto cp0_unimplemented
;
7659 case CP0_REGISTER_05
:
7661 case CP0_REG05__PAGEMASK
:
7662 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageMask
));
7663 register_name
= "PageMask";
7665 case CP0_REG05__PAGEGRAIN
:
7666 check_insn(ctx
, ISA_MIPS_R2
);
7667 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageGrain
));
7668 register_name
= "PageGrain";
7670 case CP0_REG05__SEGCTL0
:
7672 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_SegCtl0
));
7673 register_name
= "SegCtl0";
7675 case CP0_REG05__SEGCTL1
:
7677 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_SegCtl1
));
7678 register_name
= "SegCtl1";
7680 case CP0_REG05__SEGCTL2
:
7682 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_SegCtl2
));
7683 register_name
= "SegCtl2";
7685 case CP0_REG05__PWBASE
:
7687 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_PWBase
));
7688 register_name
= "PWBase";
7690 case CP0_REG05__PWFIELD
:
7692 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_PWField
));
7693 register_name
= "PWField";
7695 case CP0_REG05__PWSIZE
:
7697 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_PWSize
));
7698 register_name
= "PWSize";
7701 goto cp0_unimplemented
;
7704 case CP0_REGISTER_06
:
7706 case CP0_REG06__WIRED
:
7707 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Wired
));
7708 register_name
= "Wired";
7710 case CP0_REG06__SRSCONF0
:
7711 check_insn(ctx
, ISA_MIPS_R2
);
7712 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf0
));
7713 register_name
= "SRSConf0";
7715 case CP0_REG06__SRSCONF1
:
7716 check_insn(ctx
, ISA_MIPS_R2
);
7717 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf1
));
7718 register_name
= "SRSConf1";
7720 case CP0_REG06__SRSCONF2
:
7721 check_insn(ctx
, ISA_MIPS_R2
);
7722 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf2
));
7723 register_name
= "SRSConf2";
7725 case CP0_REG06__SRSCONF3
:
7726 check_insn(ctx
, ISA_MIPS_R2
);
7727 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf3
));
7728 register_name
= "SRSConf3";
7730 case CP0_REG06__SRSCONF4
:
7731 check_insn(ctx
, ISA_MIPS_R2
);
7732 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf4
));
7733 register_name
= "SRSConf4";
7735 case CP0_REG06__PWCTL
:
7737 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PWCtl
));
7738 register_name
= "PWCtl";
7741 goto cp0_unimplemented
;
7744 case CP0_REGISTER_07
:
7746 case CP0_REG07__HWRENA
:
7747 check_insn(ctx
, ISA_MIPS_R2
);
7748 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_HWREna
));
7749 register_name
= "HWREna";
7752 goto cp0_unimplemented
;
7755 case CP0_REGISTER_08
:
7757 case CP0_REG08__BADVADDR
:
7758 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_BadVAddr
));
7759 register_name
= "BadVAddr";
7761 case CP0_REG08__BADINSTR
:
7763 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstr
));
7764 register_name
= "BadInstr";
7766 case CP0_REG08__BADINSTRP
:
7768 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstrP
));
7769 register_name
= "BadInstrP";
7771 case CP0_REG08__BADINSTRX
:
7773 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstrX
));
7774 tcg_gen_andi_tl(arg
, arg
, ~0xffff);
7775 register_name
= "BadInstrX";
7778 goto cp0_unimplemented
;
7781 case CP0_REGISTER_09
:
7783 case CP0_REG09__COUNT
:
7784 /* Mark as an IO operation because we read the time. */
7785 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
7788 gen_helper_mfc0_count(arg
, cpu_env
);
7790 * Break the TB to be able to take timer interrupts immediately
7791 * after reading count. DISAS_STOP isn't sufficient, we need to
7792 * ensure we break completely out of translated code.
7794 gen_save_pc(ctx
->base
.pc_next
+ 4);
7795 ctx
->base
.is_jmp
= DISAS_EXIT
;
7796 register_name
= "Count";
7798 case CP0_REG09__SAARI
:
7799 CP0_CHECK(ctx
->saar
);
7800 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SAARI
));
7801 register_name
= "SAARI";
7803 case CP0_REG09__SAAR
:
7804 CP0_CHECK(ctx
->saar
);
7805 gen_helper_dmfc0_saar(arg
, cpu_env
);
7806 register_name
= "SAAR";
7809 goto cp0_unimplemented
;
7812 case CP0_REGISTER_10
:
7814 case CP0_REG10__ENTRYHI
:
7815 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryHi
));
7816 register_name
= "EntryHi";
7819 goto cp0_unimplemented
;
7822 case CP0_REGISTER_11
:
7824 case CP0_REG11__COMPARE
:
7825 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Compare
));
7826 register_name
= "Compare";
7828 /* 6,7 are implementation dependent */
7830 goto cp0_unimplemented
;
7833 case CP0_REGISTER_12
:
7835 case CP0_REG12__STATUS
:
7836 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Status
));
7837 register_name
= "Status";
7839 case CP0_REG12__INTCTL
:
7840 check_insn(ctx
, ISA_MIPS_R2
);
7841 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_IntCtl
));
7842 register_name
= "IntCtl";
7844 case CP0_REG12__SRSCTL
:
7845 check_insn(ctx
, ISA_MIPS_R2
);
7846 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
7847 register_name
= "SRSCtl";
7849 case CP0_REG12__SRSMAP
:
7850 check_insn(ctx
, ISA_MIPS_R2
);
7851 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
7852 register_name
= "SRSMap";
7855 goto cp0_unimplemented
;
7858 case CP0_REGISTER_13
:
7860 case CP0_REG13__CAUSE
:
7861 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Cause
));
7862 register_name
= "Cause";
7865 goto cp0_unimplemented
;
7868 case CP0_REGISTER_14
:
7870 case CP0_REG14__EPC
:
7871 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
7872 register_name
= "EPC";
7875 goto cp0_unimplemented
;
7878 case CP0_REGISTER_15
:
7880 case CP0_REG15__PRID
:
7881 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PRid
));
7882 register_name
= "PRid";
7884 case CP0_REG15__EBASE
:
7885 check_insn(ctx
, ISA_MIPS_R2
);
7886 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EBase
));
7887 register_name
= "EBase";
7889 case CP0_REG15__CMGCRBASE
:
7890 check_insn(ctx
, ISA_MIPS_R2
);
7891 CP0_CHECK(ctx
->cmgcr
);
7892 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_CMGCRBase
));
7893 register_name
= "CMGCRBase";
7896 goto cp0_unimplemented
;
7899 case CP0_REGISTER_16
:
7901 case CP0_REG16__CONFIG
:
7902 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config0
));
7903 register_name
= "Config";
7905 case CP0_REG16__CONFIG1
:
7906 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config1
));
7907 register_name
= "Config1";
7909 case CP0_REG16__CONFIG2
:
7910 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config2
));
7911 register_name
= "Config2";
7913 case CP0_REG16__CONFIG3
:
7914 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config3
));
7915 register_name
= "Config3";
7917 case CP0_REG16__CONFIG4
:
7918 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config4
));
7919 register_name
= "Config4";
7921 case CP0_REG16__CONFIG5
:
7922 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config5
));
7923 register_name
= "Config5";
7925 /* 6,7 are implementation dependent */
7926 case CP0_REG16__CONFIG6
:
7927 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config6
));
7928 register_name
= "Config6";
7930 case CP0_REG16__CONFIG7
:
7931 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config7
));
7932 register_name
= "Config7";
7935 goto cp0_unimplemented
;
7938 case CP0_REGISTER_17
:
7940 case CP0_REG17__LLADDR
:
7941 gen_helper_dmfc0_lladdr(arg
, cpu_env
);
7942 register_name
= "LLAddr";
7944 case CP0_REG17__MAAR
:
7945 CP0_CHECK(ctx
->mrp
);
7946 gen_helper_dmfc0_maar(arg
, cpu_env
);
7947 register_name
= "MAAR";
7949 case CP0_REG17__MAARI
:
7950 CP0_CHECK(ctx
->mrp
);
7951 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_MAARI
));
7952 register_name
= "MAARI";
7955 goto cp0_unimplemented
;
7958 case CP0_REGISTER_18
:
7960 case CP0_REG18__WATCHLO0
:
7961 case CP0_REG18__WATCHLO1
:
7962 case CP0_REG18__WATCHLO2
:
7963 case CP0_REG18__WATCHLO3
:
7964 case CP0_REG18__WATCHLO4
:
7965 case CP0_REG18__WATCHLO5
:
7966 case CP0_REG18__WATCHLO6
:
7967 case CP0_REG18__WATCHLO7
:
7968 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
7969 gen_helper_1e0i(dmfc0_watchlo
, arg
, sel
);
7970 register_name
= "WatchLo";
7973 goto cp0_unimplemented
;
7976 case CP0_REGISTER_19
:
7978 case CP0_REG19__WATCHHI0
:
7979 case CP0_REG19__WATCHHI1
:
7980 case CP0_REG19__WATCHHI2
:
7981 case CP0_REG19__WATCHHI3
:
7982 case CP0_REG19__WATCHHI4
:
7983 case CP0_REG19__WATCHHI5
:
7984 case CP0_REG19__WATCHHI6
:
7985 case CP0_REG19__WATCHHI7
:
7986 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
7987 gen_helper_1e0i(dmfc0_watchhi
, arg
, sel
);
7988 register_name
= "WatchHi";
7991 goto cp0_unimplemented
;
7994 case CP0_REGISTER_20
:
7996 case CP0_REG20__XCONTEXT
:
7997 check_insn(ctx
, ISA_MIPS3
);
7998 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_XContext
));
7999 register_name
= "XContext";
8002 goto cp0_unimplemented
;
8005 case CP0_REGISTER_21
:
8006 /* Officially reserved, but sel 0 is used for R1x000 framemask */
8007 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS_R6
));
8010 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Framemask
));
8011 register_name
= "Framemask";
8014 goto cp0_unimplemented
;
8017 case CP0_REGISTER_22
:
8018 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
8019 register_name
= "'Diagnostic"; /* implementation dependent */
8021 case CP0_REGISTER_23
:
8023 case CP0_REG23__DEBUG
:
8024 gen_helper_mfc0_debug(arg
, cpu_env
); /* EJTAG support */
8025 register_name
= "Debug";
8027 case CP0_REG23__TRACECONTROL
:
8028 /* PDtrace support */
8029 /* gen_helper_dmfc0_tracecontrol(arg, cpu_env); */
8030 register_name
= "TraceControl";
8031 goto cp0_unimplemented
;
8032 case CP0_REG23__TRACECONTROL2
:
8033 /* PDtrace support */
8034 /* gen_helper_dmfc0_tracecontrol2(arg, cpu_env); */
8035 register_name
= "TraceControl2";
8036 goto cp0_unimplemented
;
8037 case CP0_REG23__USERTRACEDATA1
:
8038 /* PDtrace support */
8039 /* gen_helper_dmfc0_usertracedata1(arg, cpu_env);*/
8040 register_name
= "UserTraceData1";
8041 goto cp0_unimplemented
;
8042 case CP0_REG23__TRACEIBPC
:
8043 /* PDtrace support */
8044 /* gen_helper_dmfc0_traceibpc(arg, cpu_env); */
8045 register_name
= "TraceIBPC";
8046 goto cp0_unimplemented
;
8047 case CP0_REG23__TRACEDBPC
:
8048 /* PDtrace support */
8049 /* gen_helper_dmfc0_tracedbpc(arg, cpu_env); */
8050 register_name
= "TraceDBPC";
8051 goto cp0_unimplemented
;
8053 goto cp0_unimplemented
;
8056 case CP0_REGISTER_24
:
8058 case CP0_REG24__DEPC
:
8060 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
8061 register_name
= "DEPC";
8064 goto cp0_unimplemented
;
8067 case CP0_REGISTER_25
:
8069 case CP0_REG25__PERFCTL0
:
8070 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Performance0
));
8071 register_name
= "Performance0";
8073 case CP0_REG25__PERFCNT0
:
8074 /* gen_helper_dmfc0_performance1(arg); */
8075 register_name
= "Performance1";
8076 goto cp0_unimplemented
;
8077 case CP0_REG25__PERFCTL1
:
8078 /* gen_helper_dmfc0_performance2(arg); */
8079 register_name
= "Performance2";
8080 goto cp0_unimplemented
;
8081 case CP0_REG25__PERFCNT1
:
8082 /* gen_helper_dmfc0_performance3(arg); */
8083 register_name
= "Performance3";
8084 goto cp0_unimplemented
;
8085 case CP0_REG25__PERFCTL2
:
8086 /* gen_helper_dmfc0_performance4(arg); */
8087 register_name
= "Performance4";
8088 goto cp0_unimplemented
;
8089 case CP0_REG25__PERFCNT2
:
8090 /* gen_helper_dmfc0_performance5(arg); */
8091 register_name
= "Performance5";
8092 goto cp0_unimplemented
;
8093 case CP0_REG25__PERFCTL3
:
8094 /* gen_helper_dmfc0_performance6(arg); */
8095 register_name
= "Performance6";
8096 goto cp0_unimplemented
;
8097 case CP0_REG25__PERFCNT3
:
8098 /* gen_helper_dmfc0_performance7(arg); */
8099 register_name
= "Performance7";
8100 goto cp0_unimplemented
;
8102 goto cp0_unimplemented
;
8105 case CP0_REGISTER_26
:
8107 case CP0_REG26__ERRCTL
:
8108 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_ErrCtl
));
8109 register_name
= "ErrCtl";
8112 goto cp0_unimplemented
;
8115 case CP0_REGISTER_27
:
8118 case CP0_REG27__CACHERR
:
8119 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
8120 register_name
= "CacheErr";
8123 goto cp0_unimplemented
;
8126 case CP0_REGISTER_28
:
8128 case CP0_REG28__TAGLO
:
8129 case CP0_REG28__TAGLO1
:
8130 case CP0_REG28__TAGLO2
:
8131 case CP0_REG28__TAGLO3
:
8132 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagLo
));
8133 register_name
= "TagLo";
8135 case CP0_REG28__DATALO
:
8136 case CP0_REG28__DATALO1
:
8137 case CP0_REG28__DATALO2
:
8138 case CP0_REG28__DATALO3
:
8139 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataLo
));
8140 register_name
= "DataLo";
8143 goto cp0_unimplemented
;
8146 case CP0_REGISTER_29
:
8148 case CP0_REG29__TAGHI
:
8149 case CP0_REG29__TAGHI1
:
8150 case CP0_REG29__TAGHI2
:
8151 case CP0_REG29__TAGHI3
:
8152 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagHi
));
8153 register_name
= "TagHi";
8155 case CP0_REG29__DATAHI
:
8156 case CP0_REG29__DATAHI1
:
8157 case CP0_REG29__DATAHI2
:
8158 case CP0_REG29__DATAHI3
:
8159 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataHi
));
8160 register_name
= "DataHi";
8163 goto cp0_unimplemented
;
8166 case CP0_REGISTER_30
:
8168 case CP0_REG30__ERROREPC
:
8169 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
8170 register_name
= "ErrorEPC";
8173 goto cp0_unimplemented
;
8176 case CP0_REGISTER_31
:
8178 case CP0_REG31__DESAVE
:
8180 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
8181 register_name
= "DESAVE";
8183 case CP0_REG31__KSCRATCH1
:
8184 case CP0_REG31__KSCRATCH2
:
8185 case CP0_REG31__KSCRATCH3
:
8186 case CP0_REG31__KSCRATCH4
:
8187 case CP0_REG31__KSCRATCH5
:
8188 case CP0_REG31__KSCRATCH6
:
8189 CP0_CHECK(ctx
->kscrexist
& (1 << sel
));
8190 tcg_gen_ld_tl(arg
, cpu_env
,
8191 offsetof(CPUMIPSState
, CP0_KScratch
[sel
- 2]));
8192 register_name
= "KScratch";
8195 goto cp0_unimplemented
;
8199 goto cp0_unimplemented
;
8201 trace_mips_translate_c0("dmfc0", register_name
, reg
, sel
);
8205 qemu_log_mask(LOG_UNIMP
, "dmfc0 %s (reg %d sel %d)\n",
8206 register_name
, reg
, sel
);
8207 gen_mfc0_unimplemented(ctx
, arg
);
8210 static void gen_dmtc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
8212 const char *register_name
= "invalid";
8215 check_insn(ctx
, ISA_MIPS_R1
);
8218 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
8223 case CP0_REGISTER_00
:
8225 case CP0_REG00__INDEX
:
8226 gen_helper_mtc0_index(cpu_env
, arg
);
8227 register_name
= "Index";
8229 case CP0_REG00__MVPCONTROL
:
8230 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8231 gen_helper_mtc0_mvpcontrol(cpu_env
, arg
);
8232 register_name
= "MVPControl";
8234 case CP0_REG00__MVPCONF0
:
8235 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8237 register_name
= "MVPConf0";
8239 case CP0_REG00__MVPCONF1
:
8240 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8242 register_name
= "MVPConf1";
8244 case CP0_REG00__VPCONTROL
:
8247 register_name
= "VPControl";
8250 goto cp0_unimplemented
;
8253 case CP0_REGISTER_01
:
8255 case CP0_REG01__RANDOM
:
8257 register_name
= "Random";
8259 case CP0_REG01__VPECONTROL
:
8260 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8261 gen_helper_mtc0_vpecontrol(cpu_env
, arg
);
8262 register_name
= "VPEControl";
8264 case CP0_REG01__VPECONF0
:
8265 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8266 gen_helper_mtc0_vpeconf0(cpu_env
, arg
);
8267 register_name
= "VPEConf0";
8269 case CP0_REG01__VPECONF1
:
8270 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8271 gen_helper_mtc0_vpeconf1(cpu_env
, arg
);
8272 register_name
= "VPEConf1";
8274 case CP0_REG01__YQMASK
:
8275 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8276 gen_helper_mtc0_yqmask(cpu_env
, arg
);
8277 register_name
= "YQMask";
8279 case CP0_REG01__VPESCHEDULE
:
8280 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8281 tcg_gen_st_tl(arg
, cpu_env
,
8282 offsetof(CPUMIPSState
, CP0_VPESchedule
));
8283 register_name
= "VPESchedule";
8285 case CP0_REG01__VPESCHEFBACK
:
8286 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8287 tcg_gen_st_tl(arg
, cpu_env
,
8288 offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
8289 register_name
= "VPEScheFBack";
8291 case CP0_REG01__VPEOPT
:
8292 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8293 gen_helper_mtc0_vpeopt(cpu_env
, arg
);
8294 register_name
= "VPEOpt";
8297 goto cp0_unimplemented
;
8300 case CP0_REGISTER_02
:
8302 case CP0_REG02__ENTRYLO0
:
8303 gen_helper_dmtc0_entrylo0(cpu_env
, arg
);
8304 register_name
= "EntryLo0";
8306 case CP0_REG02__TCSTATUS
:
8307 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8308 gen_helper_mtc0_tcstatus(cpu_env
, arg
);
8309 register_name
= "TCStatus";
8311 case CP0_REG02__TCBIND
:
8312 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8313 gen_helper_mtc0_tcbind(cpu_env
, arg
);
8314 register_name
= "TCBind";
8316 case CP0_REG02__TCRESTART
:
8317 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8318 gen_helper_mtc0_tcrestart(cpu_env
, arg
);
8319 register_name
= "TCRestart";
8321 case CP0_REG02__TCHALT
:
8322 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8323 gen_helper_mtc0_tchalt(cpu_env
, arg
);
8324 register_name
= "TCHalt";
8326 case CP0_REG02__TCCONTEXT
:
8327 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8328 gen_helper_mtc0_tccontext(cpu_env
, arg
);
8329 register_name
= "TCContext";
8331 case CP0_REG02__TCSCHEDULE
:
8332 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8333 gen_helper_mtc0_tcschedule(cpu_env
, arg
);
8334 register_name
= "TCSchedule";
8336 case CP0_REG02__TCSCHEFBACK
:
8337 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8338 gen_helper_mtc0_tcschefback(cpu_env
, arg
);
8339 register_name
= "TCScheFBack";
8342 goto cp0_unimplemented
;
8345 case CP0_REGISTER_03
:
8347 case CP0_REG03__ENTRYLO1
:
8348 gen_helper_dmtc0_entrylo1(cpu_env
, arg
);
8349 register_name
= "EntryLo1";
8351 case CP0_REG03__GLOBALNUM
:
8354 register_name
= "GlobalNumber";
8357 goto cp0_unimplemented
;
8360 case CP0_REGISTER_04
:
8362 case CP0_REG04__CONTEXT
:
8363 gen_helper_mtc0_context(cpu_env
, arg
);
8364 register_name
= "Context";
8366 case CP0_REG04__CONTEXTCONFIG
:
8368 /* gen_helper_dmtc0_contextconfig(arg); */
8369 register_name
= "ContextConfig";
8370 goto cp0_unimplemented
;
8371 case CP0_REG04__USERLOCAL
:
8372 CP0_CHECK(ctx
->ulri
);
8373 tcg_gen_st_tl(arg
, cpu_env
,
8374 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
8375 register_name
= "UserLocal";
8377 case CP0_REG04__MMID
:
8379 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_MemoryMapID
));
8380 register_name
= "MMID";
8383 goto cp0_unimplemented
;
8386 case CP0_REGISTER_05
:
8388 case CP0_REG05__PAGEMASK
:
8389 gen_helper_mtc0_pagemask(cpu_env
, arg
);
8390 register_name
= "PageMask";
8392 case CP0_REG05__PAGEGRAIN
:
8393 check_insn(ctx
, ISA_MIPS_R2
);
8394 gen_helper_mtc0_pagegrain(cpu_env
, arg
);
8395 register_name
= "PageGrain";
8397 case CP0_REG05__SEGCTL0
:
8399 gen_helper_mtc0_segctl0(cpu_env
, arg
);
8400 register_name
= "SegCtl0";
8402 case CP0_REG05__SEGCTL1
:
8404 gen_helper_mtc0_segctl1(cpu_env
, arg
);
8405 register_name
= "SegCtl1";
8407 case CP0_REG05__SEGCTL2
:
8409 gen_helper_mtc0_segctl2(cpu_env
, arg
);
8410 register_name
= "SegCtl2";
8412 case CP0_REG05__PWBASE
:
8414 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_PWBase
));
8415 register_name
= "PWBase";
8417 case CP0_REG05__PWFIELD
:
8419 gen_helper_mtc0_pwfield(cpu_env
, arg
);
8420 register_name
= "PWField";
8422 case CP0_REG05__PWSIZE
:
8424 gen_helper_mtc0_pwsize(cpu_env
, arg
);
8425 register_name
= "PWSize";
8428 goto cp0_unimplemented
;
8431 case CP0_REGISTER_06
:
8433 case CP0_REG06__WIRED
:
8434 gen_helper_mtc0_wired(cpu_env
, arg
);
8435 register_name
= "Wired";
8437 case CP0_REG06__SRSCONF0
:
8438 check_insn(ctx
, ISA_MIPS_R2
);
8439 gen_helper_mtc0_srsconf0(cpu_env
, arg
);
8440 register_name
= "SRSConf0";
8442 case CP0_REG06__SRSCONF1
:
8443 check_insn(ctx
, ISA_MIPS_R2
);
8444 gen_helper_mtc0_srsconf1(cpu_env
, arg
);
8445 register_name
= "SRSConf1";
8447 case CP0_REG06__SRSCONF2
:
8448 check_insn(ctx
, ISA_MIPS_R2
);
8449 gen_helper_mtc0_srsconf2(cpu_env
, arg
);
8450 register_name
= "SRSConf2";
8452 case CP0_REG06__SRSCONF3
:
8453 check_insn(ctx
, ISA_MIPS_R2
);
8454 gen_helper_mtc0_srsconf3(cpu_env
, arg
);
8455 register_name
= "SRSConf3";
8457 case CP0_REG06__SRSCONF4
:
8458 check_insn(ctx
, ISA_MIPS_R2
);
8459 gen_helper_mtc0_srsconf4(cpu_env
, arg
);
8460 register_name
= "SRSConf4";
8462 case CP0_REG06__PWCTL
:
8464 gen_helper_mtc0_pwctl(cpu_env
, arg
);
8465 register_name
= "PWCtl";
8468 goto cp0_unimplemented
;
8471 case CP0_REGISTER_07
:
8473 case CP0_REG07__HWRENA
:
8474 check_insn(ctx
, ISA_MIPS_R2
);
8475 gen_helper_mtc0_hwrena(cpu_env
, arg
);
8476 ctx
->base
.is_jmp
= DISAS_STOP
;
8477 register_name
= "HWREna";
8480 goto cp0_unimplemented
;
8483 case CP0_REGISTER_08
:
8485 case CP0_REG08__BADVADDR
:
8487 register_name
= "BadVAddr";
8489 case CP0_REG08__BADINSTR
:
8491 register_name
= "BadInstr";
8493 case CP0_REG08__BADINSTRP
:
8495 register_name
= "BadInstrP";
8497 case CP0_REG08__BADINSTRX
:
8499 register_name
= "BadInstrX";
8502 goto cp0_unimplemented
;
8505 case CP0_REGISTER_09
:
8507 case CP0_REG09__COUNT
:
8508 gen_helper_mtc0_count(cpu_env
, arg
);
8509 register_name
= "Count";
8511 case CP0_REG09__SAARI
:
8512 CP0_CHECK(ctx
->saar
);
8513 gen_helper_mtc0_saari(cpu_env
, arg
);
8514 register_name
= "SAARI";
8516 case CP0_REG09__SAAR
:
8517 CP0_CHECK(ctx
->saar
);
8518 gen_helper_mtc0_saar(cpu_env
, arg
);
8519 register_name
= "SAAR";
8522 goto cp0_unimplemented
;
8524 /* Stop translation as we may have switched the execution mode */
8525 ctx
->base
.is_jmp
= DISAS_STOP
;
8527 case CP0_REGISTER_10
:
8529 case CP0_REG10__ENTRYHI
:
8530 gen_helper_mtc0_entryhi(cpu_env
, arg
);
8531 register_name
= "EntryHi";
8534 goto cp0_unimplemented
;
8537 case CP0_REGISTER_11
:
8539 case CP0_REG11__COMPARE
:
8540 gen_helper_mtc0_compare(cpu_env
, arg
);
8541 register_name
= "Compare";
8543 /* 6,7 are implementation dependent */
8545 goto cp0_unimplemented
;
8547 /* Stop translation as we may have switched the execution mode */
8548 ctx
->base
.is_jmp
= DISAS_STOP
;
8550 case CP0_REGISTER_12
:
8552 case CP0_REG12__STATUS
:
8553 save_cpu_state(ctx
, 1);
8554 gen_helper_mtc0_status(cpu_env
, arg
);
8555 /* DISAS_STOP isn't good enough here, hflags may have changed. */
8556 gen_save_pc(ctx
->base
.pc_next
+ 4);
8557 ctx
->base
.is_jmp
= DISAS_EXIT
;
8558 register_name
= "Status";
8560 case CP0_REG12__INTCTL
:
8561 check_insn(ctx
, ISA_MIPS_R2
);
8562 gen_helper_mtc0_intctl(cpu_env
, arg
);
8563 /* Stop translation as we may have switched the execution mode */
8564 ctx
->base
.is_jmp
= DISAS_STOP
;
8565 register_name
= "IntCtl";
8567 case CP0_REG12__SRSCTL
:
8568 check_insn(ctx
, ISA_MIPS_R2
);
8569 gen_helper_mtc0_srsctl(cpu_env
, arg
);
8570 /* Stop translation as we may have switched the execution mode */
8571 ctx
->base
.is_jmp
= DISAS_STOP
;
8572 register_name
= "SRSCtl";
8574 case CP0_REG12__SRSMAP
:
8575 check_insn(ctx
, ISA_MIPS_R2
);
8576 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
8577 /* Stop translation as we may have switched the execution mode */
8578 ctx
->base
.is_jmp
= DISAS_STOP
;
8579 register_name
= "SRSMap";
8582 goto cp0_unimplemented
;
8585 case CP0_REGISTER_13
:
8587 case CP0_REG13__CAUSE
:
8588 save_cpu_state(ctx
, 1);
8589 gen_helper_mtc0_cause(cpu_env
, arg
);
8591 * Stop translation as we may have triggered an interrupt.
8592 * DISAS_STOP isn't sufficient, we need to ensure we break out of
8593 * translated code to check for pending interrupts.
8595 gen_save_pc(ctx
->base
.pc_next
+ 4);
8596 ctx
->base
.is_jmp
= DISAS_EXIT
;
8597 register_name
= "Cause";
8600 goto cp0_unimplemented
;
8603 case CP0_REGISTER_14
:
8605 case CP0_REG14__EPC
:
8606 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
8607 register_name
= "EPC";
8610 goto cp0_unimplemented
;
8613 case CP0_REGISTER_15
:
8615 case CP0_REG15__PRID
:
8617 register_name
= "PRid";
8619 case CP0_REG15__EBASE
:
8620 check_insn(ctx
, ISA_MIPS_R2
);
8621 gen_helper_mtc0_ebase(cpu_env
, arg
);
8622 register_name
= "EBase";
8625 goto cp0_unimplemented
;
8628 case CP0_REGISTER_16
:
8630 case CP0_REG16__CONFIG
:
8631 gen_helper_mtc0_config0(cpu_env
, arg
);
8632 register_name
= "Config";
8633 /* Stop translation as we may have switched the execution mode */
8634 ctx
->base
.is_jmp
= DISAS_STOP
;
8636 case CP0_REG16__CONFIG1
:
8637 /* ignored, read only */
8638 register_name
= "Config1";
8640 case CP0_REG16__CONFIG2
:
8641 gen_helper_mtc0_config2(cpu_env
, arg
);
8642 register_name
= "Config2";
8643 /* Stop translation as we may have switched the execution mode */
8644 ctx
->base
.is_jmp
= DISAS_STOP
;
8646 case CP0_REG16__CONFIG3
:
8647 gen_helper_mtc0_config3(cpu_env
, arg
);
8648 register_name
= "Config3";
8649 /* Stop translation as we may have switched the execution mode */
8650 ctx
->base
.is_jmp
= DISAS_STOP
;
8652 case CP0_REG16__CONFIG4
:
8653 /* currently ignored */
8654 register_name
= "Config4";
8656 case CP0_REG16__CONFIG5
:
8657 gen_helper_mtc0_config5(cpu_env
, arg
);
8658 register_name
= "Config5";
8659 /* Stop translation as we may have switched the execution mode */
8660 ctx
->base
.is_jmp
= DISAS_STOP
;
8662 /* 6,7 are implementation dependent */
8664 register_name
= "Invalid config selector";
8665 goto cp0_unimplemented
;
8668 case CP0_REGISTER_17
:
8670 case CP0_REG17__LLADDR
:
8671 gen_helper_mtc0_lladdr(cpu_env
, arg
);
8672 register_name
= "LLAddr";
8674 case CP0_REG17__MAAR
:
8675 CP0_CHECK(ctx
->mrp
);
8676 gen_helper_mtc0_maar(cpu_env
, arg
);
8677 register_name
= "MAAR";
8679 case CP0_REG17__MAARI
:
8680 CP0_CHECK(ctx
->mrp
);
8681 gen_helper_mtc0_maari(cpu_env
, arg
);
8682 register_name
= "MAARI";
8685 goto cp0_unimplemented
;
8688 case CP0_REGISTER_18
:
8690 case CP0_REG18__WATCHLO0
:
8691 case CP0_REG18__WATCHLO1
:
8692 case CP0_REG18__WATCHLO2
:
8693 case CP0_REG18__WATCHLO3
:
8694 case CP0_REG18__WATCHLO4
:
8695 case CP0_REG18__WATCHLO5
:
8696 case CP0_REG18__WATCHLO6
:
8697 case CP0_REG18__WATCHLO7
:
8698 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
8699 gen_helper_0e1i(mtc0_watchlo
, arg
, sel
);
8700 register_name
= "WatchLo";
8703 goto cp0_unimplemented
;
8706 case CP0_REGISTER_19
:
8708 case CP0_REG19__WATCHHI0
:
8709 case CP0_REG19__WATCHHI1
:
8710 case CP0_REG19__WATCHHI2
:
8711 case CP0_REG19__WATCHHI3
:
8712 case CP0_REG19__WATCHHI4
:
8713 case CP0_REG19__WATCHHI5
:
8714 case CP0_REG19__WATCHHI6
:
8715 case CP0_REG19__WATCHHI7
:
8716 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
8717 gen_helper_0e1i(mtc0_watchhi
, arg
, sel
);
8718 register_name
= "WatchHi";
8721 goto cp0_unimplemented
;
8724 case CP0_REGISTER_20
:
8726 case CP0_REG20__XCONTEXT
:
8727 check_insn(ctx
, ISA_MIPS3
);
8728 gen_helper_mtc0_xcontext(cpu_env
, arg
);
8729 register_name
= "XContext";
8732 goto cp0_unimplemented
;
8735 case CP0_REGISTER_21
:
8736 /* Officially reserved, but sel 0 is used for R1x000 framemask */
8737 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS_R6
));
8740 gen_helper_mtc0_framemask(cpu_env
, arg
);
8741 register_name
= "Framemask";
8744 goto cp0_unimplemented
;
8747 case CP0_REGISTER_22
:
8749 register_name
= "Diagnostic"; /* implementation dependent */
8751 case CP0_REGISTER_23
:
8753 case CP0_REG23__DEBUG
:
8754 gen_helper_mtc0_debug(cpu_env
, arg
); /* EJTAG support */
8755 /* DISAS_STOP isn't good enough here, hflags may have changed. */
8756 gen_save_pc(ctx
->base
.pc_next
+ 4);
8757 ctx
->base
.is_jmp
= DISAS_EXIT
;
8758 register_name
= "Debug";
8760 case CP0_REG23__TRACECONTROL
:
8761 /* PDtrace support */
8762 /* gen_helper_mtc0_tracecontrol(cpu_env, arg); */
8763 /* Stop translation as we may have switched the execution mode */
8764 ctx
->base
.is_jmp
= DISAS_STOP
;
8765 register_name
= "TraceControl";
8766 goto cp0_unimplemented
;
8767 case CP0_REG23__TRACECONTROL2
:
8768 /* PDtrace support */
8769 /* gen_helper_mtc0_tracecontrol2(cpu_env, arg); */
8770 /* Stop translation as we may have switched the execution mode */
8771 ctx
->base
.is_jmp
= DISAS_STOP
;
8772 register_name
= "TraceControl2";
8773 goto cp0_unimplemented
;
8774 case CP0_REG23__USERTRACEDATA1
:
8775 /* PDtrace support */
8776 /* gen_helper_mtc0_usertracedata1(cpu_env, arg);*/
8777 /* Stop translation as we may have switched the execution mode */
8778 ctx
->base
.is_jmp
= DISAS_STOP
;
8779 register_name
= "UserTraceData1";
8780 goto cp0_unimplemented
;
8781 case CP0_REG23__TRACEIBPC
:
8782 /* PDtrace support */
8783 /* gen_helper_mtc0_traceibpc(cpu_env, arg); */
8784 /* Stop translation as we may have switched the execution mode */
8785 ctx
->base
.is_jmp
= DISAS_STOP
;
8786 register_name
= "TraceIBPC";
8787 goto cp0_unimplemented
;
8788 case CP0_REG23__TRACEDBPC
:
8789 /* PDtrace support */
8790 /* gen_helper_mtc0_tracedbpc(cpu_env, arg); */
8791 /* Stop translation as we may have switched the execution mode */
8792 ctx
->base
.is_jmp
= DISAS_STOP
;
8793 register_name
= "TraceDBPC";
8794 goto cp0_unimplemented
;
8796 goto cp0_unimplemented
;
8799 case CP0_REGISTER_24
:
8801 case CP0_REG24__DEPC
:
8803 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
8804 register_name
= "DEPC";
8807 goto cp0_unimplemented
;
8810 case CP0_REGISTER_25
:
8812 case CP0_REG25__PERFCTL0
:
8813 gen_helper_mtc0_performance0(cpu_env
, arg
);
8814 register_name
= "Performance0";
8816 case CP0_REG25__PERFCNT0
:
8817 /* gen_helper_mtc0_performance1(cpu_env, arg); */
8818 register_name
= "Performance1";
8819 goto cp0_unimplemented
;
8820 case CP0_REG25__PERFCTL1
:
8821 /* gen_helper_mtc0_performance2(cpu_env, arg); */
8822 register_name
= "Performance2";
8823 goto cp0_unimplemented
;
8824 case CP0_REG25__PERFCNT1
:
8825 /* gen_helper_mtc0_performance3(cpu_env, arg); */
8826 register_name
= "Performance3";
8827 goto cp0_unimplemented
;
8828 case CP0_REG25__PERFCTL2
:
8829 /* gen_helper_mtc0_performance4(cpu_env, arg); */
8830 register_name
= "Performance4";
8831 goto cp0_unimplemented
;
8832 case CP0_REG25__PERFCNT2
:
8833 /* gen_helper_mtc0_performance5(cpu_env, arg); */
8834 register_name
= "Performance5";
8835 goto cp0_unimplemented
;
8836 case CP0_REG25__PERFCTL3
:
8837 /* gen_helper_mtc0_performance6(cpu_env, arg); */
8838 register_name
= "Performance6";
8839 goto cp0_unimplemented
;
8840 case CP0_REG25__PERFCNT3
:
8841 /* gen_helper_mtc0_performance7(cpu_env, arg); */
8842 register_name
= "Performance7";
8843 goto cp0_unimplemented
;
8845 goto cp0_unimplemented
;
8848 case CP0_REGISTER_26
:
8850 case CP0_REG26__ERRCTL
:
8851 gen_helper_mtc0_errctl(cpu_env
, arg
);
8852 ctx
->base
.is_jmp
= DISAS_STOP
;
8853 register_name
= "ErrCtl";
8856 goto cp0_unimplemented
;
8859 case CP0_REGISTER_27
:
8861 case CP0_REG27__CACHERR
:
8863 register_name
= "CacheErr";
8866 goto cp0_unimplemented
;
8869 case CP0_REGISTER_28
:
8871 case CP0_REG28__TAGLO
:
8872 case CP0_REG28__TAGLO1
:
8873 case CP0_REG28__TAGLO2
:
8874 case CP0_REG28__TAGLO3
:
8875 gen_helper_mtc0_taglo(cpu_env
, arg
);
8876 register_name
= "TagLo";
8878 case CP0_REG28__DATALO
:
8879 case CP0_REG28__DATALO1
:
8880 case CP0_REG28__DATALO2
:
8881 case CP0_REG28__DATALO3
:
8882 gen_helper_mtc0_datalo(cpu_env
, arg
);
8883 register_name
= "DataLo";
8886 goto cp0_unimplemented
;
8889 case CP0_REGISTER_29
:
8891 case CP0_REG29__TAGHI
:
8892 case CP0_REG29__TAGHI1
:
8893 case CP0_REG29__TAGHI2
:
8894 case CP0_REG29__TAGHI3
:
8895 gen_helper_mtc0_taghi(cpu_env
, arg
);
8896 register_name
= "TagHi";
8898 case CP0_REG29__DATAHI
:
8899 case CP0_REG29__DATAHI1
:
8900 case CP0_REG29__DATAHI2
:
8901 case CP0_REG29__DATAHI3
:
8902 gen_helper_mtc0_datahi(cpu_env
, arg
);
8903 register_name
= "DataHi";
8906 register_name
= "invalid sel";
8907 goto cp0_unimplemented
;
8910 case CP0_REGISTER_30
:
8912 case CP0_REG30__ERROREPC
:
8913 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
8914 register_name
= "ErrorEPC";
8917 goto cp0_unimplemented
;
8920 case CP0_REGISTER_31
:
8922 case CP0_REG31__DESAVE
:
8924 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
8925 register_name
= "DESAVE";
8927 case CP0_REG31__KSCRATCH1
:
8928 case CP0_REG31__KSCRATCH2
:
8929 case CP0_REG31__KSCRATCH3
:
8930 case CP0_REG31__KSCRATCH4
:
8931 case CP0_REG31__KSCRATCH5
:
8932 case CP0_REG31__KSCRATCH6
:
8933 CP0_CHECK(ctx
->kscrexist
& (1 << sel
));
8934 tcg_gen_st_tl(arg
, cpu_env
,
8935 offsetof(CPUMIPSState
, CP0_KScratch
[sel
- 2]));
8936 register_name
= "KScratch";
8939 goto cp0_unimplemented
;
8943 goto cp0_unimplemented
;
8945 trace_mips_translate_c0("dmtc0", register_name
, reg
, sel
);
8947 /* For simplicity assume that all writes can cause interrupts. */
8948 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
8950 * DISAS_STOP isn't sufficient, we need to ensure we break out of
8951 * translated code to check for pending interrupts.
8953 gen_save_pc(ctx
->base
.pc_next
+ 4);
8954 ctx
->base
.is_jmp
= DISAS_EXIT
;
8959 qemu_log_mask(LOG_UNIMP
, "dmtc0 %s (reg %d sel %d)\n",
8960 register_name
, reg
, sel
);
8962 #endif /* TARGET_MIPS64 */
8964 static void gen_mftr(CPUMIPSState
*env
, DisasContext
*ctx
, int rt
, int rd
,
8965 int u
, int sel
, int h
)
8967 int other_tc
= env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
);
8968 TCGv t0
= tcg_temp_local_new();
8970 if ((env
->CP0_VPEConf0
& (1 << CP0VPEC0_MVP
)) == 0 &&
8971 ((env
->tcs
[other_tc
].CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)) !=
8972 (env
->active_tc
.CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)))) {
8973 tcg_gen_movi_tl(t0
, -1);
8974 } else if ((env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
)) >
8975 (env
->mvp
->CP0_MVPConf0
& (0xff << CP0MVPC0_PTC
))) {
8976 tcg_gen_movi_tl(t0
, -1);
8977 } else if (u
== 0) {
8982 gen_helper_mftc0_vpecontrol(t0
, cpu_env
);
8985 gen_helper_mftc0_vpeconf0(t0
, cpu_env
);
8995 gen_helper_mftc0_tcstatus(t0
, cpu_env
);
8998 gen_helper_mftc0_tcbind(t0
, cpu_env
);
9001 gen_helper_mftc0_tcrestart(t0
, cpu_env
);
9004 gen_helper_mftc0_tchalt(t0
, cpu_env
);
9007 gen_helper_mftc0_tccontext(t0
, cpu_env
);
9010 gen_helper_mftc0_tcschedule(t0
, cpu_env
);
9013 gen_helper_mftc0_tcschefback(t0
, cpu_env
);
9016 gen_mfc0(ctx
, t0
, rt
, sel
);
9023 gen_helper_mftc0_entryhi(t0
, cpu_env
);
9026 gen_mfc0(ctx
, t0
, rt
, sel
);
9033 gen_helper_mftc0_status(t0
, cpu_env
);
9036 gen_mfc0(ctx
, t0
, rt
, sel
);
9043 gen_helper_mftc0_cause(t0
, cpu_env
);
9053 gen_helper_mftc0_epc(t0
, cpu_env
);
9063 gen_helper_mftc0_ebase(t0
, cpu_env
);
9080 gen_helper_mftc0_configx(t0
, cpu_env
, tcg_const_tl(sel
));
9090 gen_helper_mftc0_debug(t0
, cpu_env
);
9093 gen_mfc0(ctx
, t0
, rt
, sel
);
9098 gen_mfc0(ctx
, t0
, rt
, sel
);
9102 /* GPR registers. */
9104 gen_helper_1e0i(mftgpr
, t0
, rt
);
9106 /* Auxiliary CPU registers */
9110 gen_helper_1e0i(mftlo
, t0
, 0);
9113 gen_helper_1e0i(mfthi
, t0
, 0);
9116 gen_helper_1e0i(mftacx
, t0
, 0);
9119 gen_helper_1e0i(mftlo
, t0
, 1);
9122 gen_helper_1e0i(mfthi
, t0
, 1);
9125 gen_helper_1e0i(mftacx
, t0
, 1);
9128 gen_helper_1e0i(mftlo
, t0
, 2);
9131 gen_helper_1e0i(mfthi
, t0
, 2);
9134 gen_helper_1e0i(mftacx
, t0
, 2);
9137 gen_helper_1e0i(mftlo
, t0
, 3);
9140 gen_helper_1e0i(mfthi
, t0
, 3);
9143 gen_helper_1e0i(mftacx
, t0
, 3);
9146 gen_helper_mftdsp(t0
, cpu_env
);
9152 /* Floating point (COP1). */
9154 /* XXX: For now we support only a single FPU context. */
9156 TCGv_i32 fp0
= tcg_temp_new_i32();
9158 gen_load_fpr32(ctx
, fp0
, rt
);
9159 tcg_gen_ext_i32_tl(t0
, fp0
);
9160 tcg_temp_free_i32(fp0
);
9162 TCGv_i32 fp0
= tcg_temp_new_i32();
9164 gen_load_fpr32h(ctx
, fp0
, rt
);
9165 tcg_gen_ext_i32_tl(t0
, fp0
);
9166 tcg_temp_free_i32(fp0
);
9170 /* XXX: For now we support only a single FPU context. */
9171 gen_helper_1e0i(cfc1
, t0
, rt
);
9173 /* COP2: Not implemented. */
9181 trace_mips_translate_tr("mftr", rt
, u
, sel
, h
);
9182 gen_store_gpr(t0
, rd
);
9188 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt
, u
, sel
, h
);
9189 gen_reserved_instruction(ctx
);
9192 static void gen_mttr(CPUMIPSState
*env
, DisasContext
*ctx
, int rd
, int rt
,
9193 int u
, int sel
, int h
)
9195 int other_tc
= env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
);
9196 TCGv t0
= tcg_temp_local_new();
9198 gen_load_gpr(t0
, rt
);
9199 if ((env
->CP0_VPEConf0
& (1 << CP0VPEC0_MVP
)) == 0 &&
9200 ((env
->tcs
[other_tc
].CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)) !=
9201 (env
->active_tc
.CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)))) {
9204 } else if ((env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
)) >
9205 (env
->mvp
->CP0_MVPConf0
& (0xff << CP0MVPC0_PTC
))) {
9208 } else if (u
== 0) {
9213 gen_helper_mttc0_vpecontrol(cpu_env
, t0
);
9216 gen_helper_mttc0_vpeconf0(cpu_env
, t0
);
9226 gen_helper_mttc0_tcstatus(cpu_env
, t0
);
9229 gen_helper_mttc0_tcbind(cpu_env
, t0
);
9232 gen_helper_mttc0_tcrestart(cpu_env
, t0
);
9235 gen_helper_mttc0_tchalt(cpu_env
, t0
);
9238 gen_helper_mttc0_tccontext(cpu_env
, t0
);
9241 gen_helper_mttc0_tcschedule(cpu_env
, t0
);
9244 gen_helper_mttc0_tcschefback(cpu_env
, t0
);
9247 gen_mtc0(ctx
, t0
, rd
, sel
);
9254 gen_helper_mttc0_entryhi(cpu_env
, t0
);
9257 gen_mtc0(ctx
, t0
, rd
, sel
);
9264 gen_helper_mttc0_status(cpu_env
, t0
);
9267 gen_mtc0(ctx
, t0
, rd
, sel
);
9274 gen_helper_mttc0_cause(cpu_env
, t0
);
9284 gen_helper_mttc0_ebase(cpu_env
, t0
);
9294 gen_helper_mttc0_debug(cpu_env
, t0
);
9297 gen_mtc0(ctx
, t0
, rd
, sel
);
9302 gen_mtc0(ctx
, t0
, rd
, sel
);
9306 /* GPR registers. */
9308 gen_helper_0e1i(mttgpr
, t0
, rd
);
9310 /* Auxiliary CPU registers */
9314 gen_helper_0e1i(mttlo
, t0
, 0);
9317 gen_helper_0e1i(mtthi
, t0
, 0);
9320 gen_helper_0e1i(mttacx
, t0
, 0);
9323 gen_helper_0e1i(mttlo
, t0
, 1);
9326 gen_helper_0e1i(mtthi
, t0
, 1);
9329 gen_helper_0e1i(mttacx
, t0
, 1);
9332 gen_helper_0e1i(mttlo
, t0
, 2);
9335 gen_helper_0e1i(mtthi
, t0
, 2);
9338 gen_helper_0e1i(mttacx
, t0
, 2);
9341 gen_helper_0e1i(mttlo
, t0
, 3);
9344 gen_helper_0e1i(mtthi
, t0
, 3);
9347 gen_helper_0e1i(mttacx
, t0
, 3);
9350 gen_helper_mttdsp(cpu_env
, t0
);
9356 /* Floating point (COP1). */
9358 /* XXX: For now we support only a single FPU context. */
9360 TCGv_i32 fp0
= tcg_temp_new_i32();
9362 tcg_gen_trunc_tl_i32(fp0
, t0
);
9363 gen_store_fpr32(ctx
, fp0
, rd
);
9364 tcg_temp_free_i32(fp0
);
9366 TCGv_i32 fp0
= tcg_temp_new_i32();
9368 tcg_gen_trunc_tl_i32(fp0
, t0
);
9369 gen_store_fpr32h(ctx
, fp0
, rd
);
9370 tcg_temp_free_i32(fp0
);
9374 /* XXX: For now we support only a single FPU context. */
9376 TCGv_i32 fs_tmp
= tcg_const_i32(rd
);
9378 gen_helper_0e2i(ctc1
, t0
, fs_tmp
, rt
);
9379 tcg_temp_free_i32(fs_tmp
);
9381 /* Stop translation as we may have changed hflags */
9382 ctx
->base
.is_jmp
= DISAS_STOP
;
9384 /* COP2: Not implemented. */
9392 trace_mips_translate_tr("mttr", rd
, u
, sel
, h
);
9398 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd
, u
, sel
, h
);
9399 gen_reserved_instruction(ctx
);
9402 static void gen_cp0(CPUMIPSState
*env
, DisasContext
*ctx
, uint32_t opc
,
9405 const char *opn
= "ldst";
9407 check_cp0_enabled(ctx
);
9414 gen_mfc0(ctx
, cpu_gpr
[rt
], rd
, ctx
->opcode
& 0x7);
9419 TCGv t0
= tcg_temp_new();
9421 gen_load_gpr(t0
, rt
);
9422 gen_mtc0(ctx
, t0
, rd
, ctx
->opcode
& 0x7);
9427 #if defined(TARGET_MIPS64)
9429 check_insn(ctx
, ISA_MIPS3
);
9434 gen_dmfc0(ctx
, cpu_gpr
[rt
], rd
, ctx
->opcode
& 0x7);
9438 check_insn(ctx
, ISA_MIPS3
);
9440 TCGv t0
= tcg_temp_new();
9442 gen_load_gpr(t0
, rt
);
9443 gen_dmtc0(ctx
, t0
, rd
, ctx
->opcode
& 0x7);
9455 gen_mfhc0(ctx
, cpu_gpr
[rt
], rd
, ctx
->opcode
& 0x7);
9461 TCGv t0
= tcg_temp_new();
9462 gen_load_gpr(t0
, rt
);
9463 gen_mthc0(ctx
, t0
, rd
, ctx
->opcode
& 0x7);
9469 check_cp0_enabled(ctx
);
9474 gen_mftr(env
, ctx
, rt
, rd
, (ctx
->opcode
>> 5) & 1,
9475 ctx
->opcode
& 0x7, (ctx
->opcode
>> 4) & 1);
9479 check_cp0_enabled(ctx
);
9480 gen_mttr(env
, ctx
, rd
, rt
, (ctx
->opcode
>> 5) & 1,
9481 ctx
->opcode
& 0x7, (ctx
->opcode
>> 4) & 1);
9486 if (!env
->tlb
->helper_tlbwi
) {
9489 gen_helper_tlbwi(cpu_env
);
9494 if (!env
->tlb
->helper_tlbinv
) {
9497 gen_helper_tlbinv(cpu_env
);
9498 } /* treat as nop if TLBINV not supported */
9503 if (!env
->tlb
->helper_tlbinvf
) {
9506 gen_helper_tlbinvf(cpu_env
);
9507 } /* treat as nop if TLBINV not supported */
9511 if (!env
->tlb
->helper_tlbwr
) {
9514 gen_helper_tlbwr(cpu_env
);
9518 if (!env
->tlb
->helper_tlbp
) {
9521 gen_helper_tlbp(cpu_env
);
9525 if (!env
->tlb
->helper_tlbr
) {
9528 gen_helper_tlbr(cpu_env
);
9530 case OPC_ERET
: /* OPC_ERETNC */
9531 if ((ctx
->insn_flags
& ISA_MIPS_R6
) &&
9532 (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
9535 int bit_shift
= (ctx
->hflags
& MIPS_HFLAG_M16
) ? 16 : 6;
9536 if (ctx
->opcode
& (1 << bit_shift
)) {
9539 check_insn(ctx
, ISA_MIPS_R5
);
9540 gen_helper_eretnc(cpu_env
);
9544 check_insn(ctx
, ISA_MIPS2
);
9545 gen_helper_eret(cpu_env
);
9547 ctx
->base
.is_jmp
= DISAS_EXIT
;
9552 check_insn(ctx
, ISA_MIPS_R1
);
9553 if ((ctx
->insn_flags
& ISA_MIPS_R6
) &&
9554 (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
9557 if (!(ctx
->hflags
& MIPS_HFLAG_DM
)) {
9559 gen_reserved_instruction(ctx
);
9561 gen_helper_deret(cpu_env
);
9562 ctx
->base
.is_jmp
= DISAS_EXIT
;
9567 check_insn(ctx
, ISA_MIPS3
| ISA_MIPS_R1
);
9568 if ((ctx
->insn_flags
& ISA_MIPS_R6
) &&
9569 (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
9572 /* If we get an exception, we want to restart at next instruction */
9573 ctx
->base
.pc_next
+= 4;
9574 save_cpu_state(ctx
, 1);
9575 ctx
->base
.pc_next
-= 4;
9576 gen_helper_wait(cpu_env
);
9577 ctx
->base
.is_jmp
= DISAS_NORETURN
;
9582 gen_reserved_instruction(ctx
);
9585 (void)opn
; /* avoid a compiler warning */
9587 #endif /* !CONFIG_USER_ONLY */
9589 /* CP1 Branches (before delay slot) */
9590 static void gen_compute_branch1(DisasContext
*ctx
, uint32_t op
,
9591 int32_t cc
, int32_t offset
)
9593 target_ulong btarget
;
9594 TCGv_i32 t0
= tcg_temp_new_i32();
9596 if ((ctx
->insn_flags
& ISA_MIPS_R6
) && (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
9597 gen_reserved_instruction(ctx
);
9602 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS_R1
);
9605 btarget
= ctx
->base
.pc_next
+ 4 + offset
;
9609 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
9610 tcg_gen_not_i32(t0
, t0
);
9611 tcg_gen_andi_i32(t0
, t0
, 1);
9612 tcg_gen_extu_i32_tl(bcond
, t0
);
9615 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
9616 tcg_gen_not_i32(t0
, t0
);
9617 tcg_gen_andi_i32(t0
, t0
, 1);
9618 tcg_gen_extu_i32_tl(bcond
, t0
);
9621 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
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_andi_i32(t0
, t0
, 1);
9628 tcg_gen_extu_i32_tl(bcond
, t0
);
9630 ctx
->hflags
|= MIPS_HFLAG_BL
;
9634 TCGv_i32 t1
= tcg_temp_new_i32();
9635 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
9636 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 1));
9637 tcg_gen_nand_i32(t0
, t0
, t1
);
9638 tcg_temp_free_i32(t1
);
9639 tcg_gen_andi_i32(t0
, t0
, 1);
9640 tcg_gen_extu_i32_tl(bcond
, t0
);
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_or_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_and_i32(t0
, t0
, t1
);
9660 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 2));
9661 tcg_gen_and_i32(t0
, t0
, t1
);
9662 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 3));
9663 tcg_gen_nand_i32(t0
, t0
, t1
);
9664 tcg_temp_free_i32(t1
);
9665 tcg_gen_andi_i32(t0
, t0
, 1);
9666 tcg_gen_extu_i32_tl(bcond
, t0
);
9671 TCGv_i32 t1
= tcg_temp_new_i32();
9672 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
9673 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 1));
9674 tcg_gen_or_i32(t0
, t0
, t1
);
9675 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 2));
9676 tcg_gen_or_i32(t0
, t0
, t1
);
9677 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 3));
9678 tcg_gen_or_i32(t0
, t0
, t1
);
9679 tcg_temp_free_i32(t1
);
9680 tcg_gen_andi_i32(t0
, t0
, 1);
9681 tcg_gen_extu_i32_tl(bcond
, t0
);
9684 ctx
->hflags
|= MIPS_HFLAG_BC
;
9687 MIPS_INVAL("cp1 cond branch");
9688 gen_reserved_instruction(ctx
);
9691 ctx
->btarget
= btarget
;
9692 ctx
->hflags
|= MIPS_HFLAG_BDS32
;
9694 tcg_temp_free_i32(t0
);
9697 /* R6 CP1 Branches */
9698 static void gen_compute_branch1_r6(DisasContext
*ctx
, uint32_t op
,
9699 int32_t ft
, int32_t offset
,
9702 target_ulong btarget
;
9703 TCGv_i64 t0
= tcg_temp_new_i64();
9705 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
9706 #ifdef MIPS_DEBUG_DISAS
9707 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
9708 "\n", ctx
->base
.pc_next
);
9710 gen_reserved_instruction(ctx
);
9714 gen_load_fpr64(ctx
, t0
, ft
);
9715 tcg_gen_andi_i64(t0
, t0
, 1);
9717 btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
9721 tcg_gen_xori_i64(t0
, t0
, 1);
9722 ctx
->hflags
|= MIPS_HFLAG_BC
;
9725 /* t0 already set */
9726 ctx
->hflags
|= MIPS_HFLAG_BC
;
9729 MIPS_INVAL("cp1 cond branch");
9730 gen_reserved_instruction(ctx
);
9734 tcg_gen_trunc_i64_tl(bcond
, t0
);
9736 ctx
->btarget
= btarget
;
9738 switch (delayslot_size
) {
9740 ctx
->hflags
|= MIPS_HFLAG_BDS16
;
9743 ctx
->hflags
|= MIPS_HFLAG_BDS32
;
9748 tcg_temp_free_i64(t0
);
9751 /* Coprocessor 1 (FPU) */
9753 #define FOP(func, fmt) (((fmt) << 21) | (func))
9756 OPC_ADD_S
= FOP(0, FMT_S
),
9757 OPC_SUB_S
= FOP(1, FMT_S
),
9758 OPC_MUL_S
= FOP(2, FMT_S
),
9759 OPC_DIV_S
= FOP(3, FMT_S
),
9760 OPC_SQRT_S
= FOP(4, FMT_S
),
9761 OPC_ABS_S
= FOP(5, FMT_S
),
9762 OPC_MOV_S
= FOP(6, FMT_S
),
9763 OPC_NEG_S
= FOP(7, FMT_S
),
9764 OPC_ROUND_L_S
= FOP(8, FMT_S
),
9765 OPC_TRUNC_L_S
= FOP(9, FMT_S
),
9766 OPC_CEIL_L_S
= FOP(10, FMT_S
),
9767 OPC_FLOOR_L_S
= FOP(11, FMT_S
),
9768 OPC_ROUND_W_S
= FOP(12, FMT_S
),
9769 OPC_TRUNC_W_S
= FOP(13, FMT_S
),
9770 OPC_CEIL_W_S
= FOP(14, FMT_S
),
9771 OPC_FLOOR_W_S
= FOP(15, FMT_S
),
9772 OPC_SEL_S
= FOP(16, FMT_S
),
9773 OPC_MOVCF_S
= FOP(17, FMT_S
),
9774 OPC_MOVZ_S
= FOP(18, FMT_S
),
9775 OPC_MOVN_S
= FOP(19, FMT_S
),
9776 OPC_SELEQZ_S
= FOP(20, FMT_S
),
9777 OPC_RECIP_S
= FOP(21, FMT_S
),
9778 OPC_RSQRT_S
= FOP(22, FMT_S
),
9779 OPC_SELNEZ_S
= FOP(23, FMT_S
),
9780 OPC_MADDF_S
= FOP(24, FMT_S
),
9781 OPC_MSUBF_S
= FOP(25, FMT_S
),
9782 OPC_RINT_S
= FOP(26, FMT_S
),
9783 OPC_CLASS_S
= FOP(27, FMT_S
),
9784 OPC_MIN_S
= FOP(28, FMT_S
),
9785 OPC_RECIP2_S
= FOP(28, FMT_S
),
9786 OPC_MINA_S
= FOP(29, FMT_S
),
9787 OPC_RECIP1_S
= FOP(29, FMT_S
),
9788 OPC_MAX_S
= FOP(30, FMT_S
),
9789 OPC_RSQRT1_S
= FOP(30, FMT_S
),
9790 OPC_MAXA_S
= FOP(31, FMT_S
),
9791 OPC_RSQRT2_S
= FOP(31, FMT_S
),
9792 OPC_CVT_D_S
= FOP(33, FMT_S
),
9793 OPC_CVT_W_S
= FOP(36, FMT_S
),
9794 OPC_CVT_L_S
= FOP(37, FMT_S
),
9795 OPC_CVT_PS_S
= FOP(38, FMT_S
),
9796 OPC_CMP_F_S
= FOP(48, FMT_S
),
9797 OPC_CMP_UN_S
= FOP(49, FMT_S
),
9798 OPC_CMP_EQ_S
= FOP(50, FMT_S
),
9799 OPC_CMP_UEQ_S
= FOP(51, FMT_S
),
9800 OPC_CMP_OLT_S
= FOP(52, FMT_S
),
9801 OPC_CMP_ULT_S
= FOP(53, FMT_S
),
9802 OPC_CMP_OLE_S
= FOP(54, FMT_S
),
9803 OPC_CMP_ULE_S
= FOP(55, FMT_S
),
9804 OPC_CMP_SF_S
= FOP(56, FMT_S
),
9805 OPC_CMP_NGLE_S
= FOP(57, FMT_S
),
9806 OPC_CMP_SEQ_S
= FOP(58, FMT_S
),
9807 OPC_CMP_NGL_S
= FOP(59, FMT_S
),
9808 OPC_CMP_LT_S
= FOP(60, FMT_S
),
9809 OPC_CMP_NGE_S
= FOP(61, FMT_S
),
9810 OPC_CMP_LE_S
= FOP(62, FMT_S
),
9811 OPC_CMP_NGT_S
= FOP(63, FMT_S
),
9813 OPC_ADD_D
= FOP(0, FMT_D
),
9814 OPC_SUB_D
= FOP(1, FMT_D
),
9815 OPC_MUL_D
= FOP(2, FMT_D
),
9816 OPC_DIV_D
= FOP(3, FMT_D
),
9817 OPC_SQRT_D
= FOP(4, FMT_D
),
9818 OPC_ABS_D
= FOP(5, FMT_D
),
9819 OPC_MOV_D
= FOP(6, FMT_D
),
9820 OPC_NEG_D
= FOP(7, FMT_D
),
9821 OPC_ROUND_L_D
= FOP(8, FMT_D
),
9822 OPC_TRUNC_L_D
= FOP(9, FMT_D
),
9823 OPC_CEIL_L_D
= FOP(10, FMT_D
),
9824 OPC_FLOOR_L_D
= FOP(11, FMT_D
),
9825 OPC_ROUND_W_D
= FOP(12, FMT_D
),
9826 OPC_TRUNC_W_D
= FOP(13, FMT_D
),
9827 OPC_CEIL_W_D
= FOP(14, FMT_D
),
9828 OPC_FLOOR_W_D
= FOP(15, FMT_D
),
9829 OPC_SEL_D
= FOP(16, FMT_D
),
9830 OPC_MOVCF_D
= FOP(17, FMT_D
),
9831 OPC_MOVZ_D
= FOP(18, FMT_D
),
9832 OPC_MOVN_D
= FOP(19, FMT_D
),
9833 OPC_SELEQZ_D
= FOP(20, FMT_D
),
9834 OPC_RECIP_D
= FOP(21, FMT_D
),
9835 OPC_RSQRT_D
= FOP(22, FMT_D
),
9836 OPC_SELNEZ_D
= FOP(23, FMT_D
),
9837 OPC_MADDF_D
= FOP(24, FMT_D
),
9838 OPC_MSUBF_D
= FOP(25, FMT_D
),
9839 OPC_RINT_D
= FOP(26, FMT_D
),
9840 OPC_CLASS_D
= FOP(27, FMT_D
),
9841 OPC_MIN_D
= FOP(28, FMT_D
),
9842 OPC_RECIP2_D
= FOP(28, FMT_D
),
9843 OPC_MINA_D
= FOP(29, FMT_D
),
9844 OPC_RECIP1_D
= FOP(29, FMT_D
),
9845 OPC_MAX_D
= FOP(30, FMT_D
),
9846 OPC_RSQRT1_D
= FOP(30, FMT_D
),
9847 OPC_MAXA_D
= FOP(31, FMT_D
),
9848 OPC_RSQRT2_D
= FOP(31, FMT_D
),
9849 OPC_CVT_S_D
= FOP(32, FMT_D
),
9850 OPC_CVT_W_D
= FOP(36, FMT_D
),
9851 OPC_CVT_L_D
= FOP(37, FMT_D
),
9852 OPC_CMP_F_D
= FOP(48, FMT_D
),
9853 OPC_CMP_UN_D
= FOP(49, FMT_D
),
9854 OPC_CMP_EQ_D
= FOP(50, FMT_D
),
9855 OPC_CMP_UEQ_D
= FOP(51, FMT_D
),
9856 OPC_CMP_OLT_D
= FOP(52, FMT_D
),
9857 OPC_CMP_ULT_D
= FOP(53, FMT_D
),
9858 OPC_CMP_OLE_D
= FOP(54, FMT_D
),
9859 OPC_CMP_ULE_D
= FOP(55, FMT_D
),
9860 OPC_CMP_SF_D
= FOP(56, FMT_D
),
9861 OPC_CMP_NGLE_D
= FOP(57, FMT_D
),
9862 OPC_CMP_SEQ_D
= FOP(58, FMT_D
),
9863 OPC_CMP_NGL_D
= FOP(59, FMT_D
),
9864 OPC_CMP_LT_D
= FOP(60, FMT_D
),
9865 OPC_CMP_NGE_D
= FOP(61, FMT_D
),
9866 OPC_CMP_LE_D
= FOP(62, FMT_D
),
9867 OPC_CMP_NGT_D
= FOP(63, FMT_D
),
9869 OPC_CVT_S_W
= FOP(32, FMT_W
),
9870 OPC_CVT_D_W
= FOP(33, FMT_W
),
9871 OPC_CVT_S_L
= FOP(32, FMT_L
),
9872 OPC_CVT_D_L
= FOP(33, FMT_L
),
9873 OPC_CVT_PS_PW
= FOP(38, FMT_W
),
9875 OPC_ADD_PS
= FOP(0, FMT_PS
),
9876 OPC_SUB_PS
= FOP(1, FMT_PS
),
9877 OPC_MUL_PS
= FOP(2, FMT_PS
),
9878 OPC_DIV_PS
= FOP(3, FMT_PS
),
9879 OPC_ABS_PS
= FOP(5, FMT_PS
),
9880 OPC_MOV_PS
= FOP(6, FMT_PS
),
9881 OPC_NEG_PS
= FOP(7, FMT_PS
),
9882 OPC_MOVCF_PS
= FOP(17, FMT_PS
),
9883 OPC_MOVZ_PS
= FOP(18, FMT_PS
),
9884 OPC_MOVN_PS
= FOP(19, FMT_PS
),
9885 OPC_ADDR_PS
= FOP(24, FMT_PS
),
9886 OPC_MULR_PS
= FOP(26, FMT_PS
),
9887 OPC_RECIP2_PS
= FOP(28, FMT_PS
),
9888 OPC_RECIP1_PS
= FOP(29, FMT_PS
),
9889 OPC_RSQRT1_PS
= FOP(30, FMT_PS
),
9890 OPC_RSQRT2_PS
= FOP(31, FMT_PS
),
9892 OPC_CVT_S_PU
= FOP(32, FMT_PS
),
9893 OPC_CVT_PW_PS
= FOP(36, FMT_PS
),
9894 OPC_CVT_S_PL
= FOP(40, FMT_PS
),
9895 OPC_PLL_PS
= FOP(44, FMT_PS
),
9896 OPC_PLU_PS
= FOP(45, FMT_PS
),
9897 OPC_PUL_PS
= FOP(46, FMT_PS
),
9898 OPC_PUU_PS
= FOP(47, FMT_PS
),
9899 OPC_CMP_F_PS
= FOP(48, FMT_PS
),
9900 OPC_CMP_UN_PS
= FOP(49, FMT_PS
),
9901 OPC_CMP_EQ_PS
= FOP(50, FMT_PS
),
9902 OPC_CMP_UEQ_PS
= FOP(51, FMT_PS
),
9903 OPC_CMP_OLT_PS
= FOP(52, FMT_PS
),
9904 OPC_CMP_ULT_PS
= FOP(53, FMT_PS
),
9905 OPC_CMP_OLE_PS
= FOP(54, FMT_PS
),
9906 OPC_CMP_ULE_PS
= FOP(55, FMT_PS
),
9907 OPC_CMP_SF_PS
= FOP(56, FMT_PS
),
9908 OPC_CMP_NGLE_PS
= FOP(57, FMT_PS
),
9909 OPC_CMP_SEQ_PS
= FOP(58, FMT_PS
),
9910 OPC_CMP_NGL_PS
= FOP(59, FMT_PS
),
9911 OPC_CMP_LT_PS
= FOP(60, FMT_PS
),
9912 OPC_CMP_NGE_PS
= FOP(61, FMT_PS
),
9913 OPC_CMP_LE_PS
= FOP(62, FMT_PS
),
9914 OPC_CMP_NGT_PS
= FOP(63, FMT_PS
),
9918 R6_OPC_CMP_AF_S
= FOP(0, FMT_W
),
9919 R6_OPC_CMP_UN_S
= FOP(1, FMT_W
),
9920 R6_OPC_CMP_EQ_S
= FOP(2, FMT_W
),
9921 R6_OPC_CMP_UEQ_S
= FOP(3, FMT_W
),
9922 R6_OPC_CMP_LT_S
= FOP(4, FMT_W
),
9923 R6_OPC_CMP_ULT_S
= FOP(5, FMT_W
),
9924 R6_OPC_CMP_LE_S
= FOP(6, FMT_W
),
9925 R6_OPC_CMP_ULE_S
= FOP(7, FMT_W
),
9926 R6_OPC_CMP_SAF_S
= FOP(8, FMT_W
),
9927 R6_OPC_CMP_SUN_S
= FOP(9, FMT_W
),
9928 R6_OPC_CMP_SEQ_S
= FOP(10, FMT_W
),
9929 R6_OPC_CMP_SEUQ_S
= FOP(11, FMT_W
),
9930 R6_OPC_CMP_SLT_S
= FOP(12, FMT_W
),
9931 R6_OPC_CMP_SULT_S
= FOP(13, FMT_W
),
9932 R6_OPC_CMP_SLE_S
= FOP(14, FMT_W
),
9933 R6_OPC_CMP_SULE_S
= FOP(15, FMT_W
),
9934 R6_OPC_CMP_OR_S
= FOP(17, FMT_W
),
9935 R6_OPC_CMP_UNE_S
= FOP(18, FMT_W
),
9936 R6_OPC_CMP_NE_S
= FOP(19, FMT_W
),
9937 R6_OPC_CMP_SOR_S
= FOP(25, FMT_W
),
9938 R6_OPC_CMP_SUNE_S
= FOP(26, FMT_W
),
9939 R6_OPC_CMP_SNE_S
= FOP(27, FMT_W
),
9941 R6_OPC_CMP_AF_D
= FOP(0, FMT_L
),
9942 R6_OPC_CMP_UN_D
= FOP(1, FMT_L
),
9943 R6_OPC_CMP_EQ_D
= FOP(2, FMT_L
),
9944 R6_OPC_CMP_UEQ_D
= FOP(3, FMT_L
),
9945 R6_OPC_CMP_LT_D
= FOP(4, FMT_L
),
9946 R6_OPC_CMP_ULT_D
= FOP(5, FMT_L
),
9947 R6_OPC_CMP_LE_D
= FOP(6, FMT_L
),
9948 R6_OPC_CMP_ULE_D
= FOP(7, FMT_L
),
9949 R6_OPC_CMP_SAF_D
= FOP(8, FMT_L
),
9950 R6_OPC_CMP_SUN_D
= FOP(9, FMT_L
),
9951 R6_OPC_CMP_SEQ_D
= FOP(10, FMT_L
),
9952 R6_OPC_CMP_SEUQ_D
= FOP(11, FMT_L
),
9953 R6_OPC_CMP_SLT_D
= FOP(12, FMT_L
),
9954 R6_OPC_CMP_SULT_D
= FOP(13, FMT_L
),
9955 R6_OPC_CMP_SLE_D
= FOP(14, FMT_L
),
9956 R6_OPC_CMP_SULE_D
= FOP(15, FMT_L
),
9957 R6_OPC_CMP_OR_D
= FOP(17, FMT_L
),
9958 R6_OPC_CMP_UNE_D
= FOP(18, FMT_L
),
9959 R6_OPC_CMP_NE_D
= FOP(19, FMT_L
),
9960 R6_OPC_CMP_SOR_D
= FOP(25, FMT_L
),
9961 R6_OPC_CMP_SUNE_D
= FOP(26, FMT_L
),
9962 R6_OPC_CMP_SNE_D
= FOP(27, FMT_L
),
9965 static void gen_cp1(DisasContext
*ctx
, uint32_t opc
, int rt
, int fs
)
9967 TCGv t0
= tcg_temp_new();
9972 TCGv_i32 fp0
= tcg_temp_new_i32();
9974 gen_load_fpr32(ctx
, fp0
, fs
);
9975 tcg_gen_ext_i32_tl(t0
, fp0
);
9976 tcg_temp_free_i32(fp0
);
9978 gen_store_gpr(t0
, rt
);
9981 gen_load_gpr(t0
, rt
);
9983 TCGv_i32 fp0
= tcg_temp_new_i32();
9985 tcg_gen_trunc_tl_i32(fp0
, t0
);
9986 gen_store_fpr32(ctx
, fp0
, fs
);
9987 tcg_temp_free_i32(fp0
);
9991 gen_helper_1e0i(cfc1
, t0
, fs
);
9992 gen_store_gpr(t0
, rt
);
9995 gen_load_gpr(t0
, rt
);
9996 save_cpu_state(ctx
, 0);
9998 TCGv_i32 fs_tmp
= tcg_const_i32(fs
);
10000 gen_helper_0e2i(ctc1
, t0
, fs_tmp
, rt
);
10001 tcg_temp_free_i32(fs_tmp
);
10003 /* Stop translation as we may have changed hflags */
10004 ctx
->base
.is_jmp
= DISAS_STOP
;
10006 #if defined(TARGET_MIPS64)
10008 gen_load_fpr64(ctx
, t0
, fs
);
10009 gen_store_gpr(t0
, rt
);
10012 gen_load_gpr(t0
, rt
);
10013 gen_store_fpr64(ctx
, t0
, fs
);
10018 TCGv_i32 fp0
= tcg_temp_new_i32();
10020 gen_load_fpr32h(ctx
, fp0
, fs
);
10021 tcg_gen_ext_i32_tl(t0
, fp0
);
10022 tcg_temp_free_i32(fp0
);
10024 gen_store_gpr(t0
, rt
);
10027 gen_load_gpr(t0
, rt
);
10029 TCGv_i32 fp0
= tcg_temp_new_i32();
10031 tcg_gen_trunc_tl_i32(fp0
, t0
);
10032 gen_store_fpr32h(ctx
, fp0
, fs
);
10033 tcg_temp_free_i32(fp0
);
10037 MIPS_INVAL("cp1 move");
10038 gen_reserved_instruction(ctx
);
10046 static void gen_movci(DisasContext
*ctx
, int rd
, int rs
, int cc
, int tf
)
10053 /* Treat as NOP. */
10058 cond
= TCG_COND_EQ
;
10060 cond
= TCG_COND_NE
;
10063 l1
= gen_new_label();
10064 t0
= tcg_temp_new_i32();
10065 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
10066 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
10067 tcg_temp_free_i32(t0
);
10068 gen_load_gpr(cpu_gpr
[rd
], rs
);
10072 static inline void gen_movcf_s(DisasContext
*ctx
, int fs
, int fd
, int cc
,
10076 TCGv_i32 t0
= tcg_temp_new_i32();
10077 TCGLabel
*l1
= gen_new_label();
10080 cond
= TCG_COND_EQ
;
10082 cond
= TCG_COND_NE
;
10085 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
10086 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
10087 gen_load_fpr32(ctx
, t0
, fs
);
10088 gen_store_fpr32(ctx
, t0
, fd
);
10090 tcg_temp_free_i32(t0
);
10093 static inline void gen_movcf_d(DisasContext
*ctx
, int fs
, int fd
, int cc
,
10097 TCGv_i32 t0
= tcg_temp_new_i32();
10099 TCGLabel
*l1
= gen_new_label();
10102 cond
= TCG_COND_EQ
;
10104 cond
= TCG_COND_NE
;
10107 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
10108 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
10109 tcg_temp_free_i32(t0
);
10110 fp0
= tcg_temp_new_i64();
10111 gen_load_fpr64(ctx
, fp0
, fs
);
10112 gen_store_fpr64(ctx
, fp0
, fd
);
10113 tcg_temp_free_i64(fp0
);
10117 static inline void gen_movcf_ps(DisasContext
*ctx
, int fs
, int fd
,
10121 TCGv_i32 t0
= tcg_temp_new_i32();
10122 TCGLabel
*l1
= gen_new_label();
10123 TCGLabel
*l2
= gen_new_label();
10126 cond
= TCG_COND_EQ
;
10128 cond
= TCG_COND_NE
;
10131 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
10132 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
10133 gen_load_fpr32(ctx
, t0
, fs
);
10134 gen_store_fpr32(ctx
, t0
, fd
);
10137 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
+ 1));
10138 tcg_gen_brcondi_i32(cond
, t0
, 0, l2
);
10139 gen_load_fpr32h(ctx
, t0
, fs
);
10140 gen_store_fpr32h(ctx
, t0
, fd
);
10141 tcg_temp_free_i32(t0
);
10145 static void gen_sel_s(DisasContext
*ctx
, enum fopcode op1
, int fd
, int ft
,
10148 TCGv_i32 t1
= tcg_const_i32(0);
10149 TCGv_i32 fp0
= tcg_temp_new_i32();
10150 TCGv_i32 fp1
= tcg_temp_new_i32();
10151 TCGv_i32 fp2
= tcg_temp_new_i32();
10152 gen_load_fpr32(ctx
, fp0
, fd
);
10153 gen_load_fpr32(ctx
, fp1
, ft
);
10154 gen_load_fpr32(ctx
, fp2
, fs
);
10158 tcg_gen_andi_i32(fp0
, fp0
, 1);
10159 tcg_gen_movcond_i32(TCG_COND_NE
, fp0
, fp0
, t1
, fp1
, fp2
);
10162 tcg_gen_andi_i32(fp1
, fp1
, 1);
10163 tcg_gen_movcond_i32(TCG_COND_EQ
, fp0
, fp1
, t1
, fp2
, t1
);
10166 tcg_gen_andi_i32(fp1
, fp1
, 1);
10167 tcg_gen_movcond_i32(TCG_COND_NE
, fp0
, fp1
, t1
, fp2
, t1
);
10170 MIPS_INVAL("gen_sel_s");
10171 gen_reserved_instruction(ctx
);
10175 gen_store_fpr32(ctx
, fp0
, fd
);
10176 tcg_temp_free_i32(fp2
);
10177 tcg_temp_free_i32(fp1
);
10178 tcg_temp_free_i32(fp0
);
10179 tcg_temp_free_i32(t1
);
10182 static void gen_sel_d(DisasContext
*ctx
, enum fopcode op1
, int fd
, int ft
,
10185 TCGv_i64 t1
= tcg_const_i64(0);
10186 TCGv_i64 fp0
= tcg_temp_new_i64();
10187 TCGv_i64 fp1
= tcg_temp_new_i64();
10188 TCGv_i64 fp2
= tcg_temp_new_i64();
10189 gen_load_fpr64(ctx
, fp0
, fd
);
10190 gen_load_fpr64(ctx
, fp1
, ft
);
10191 gen_load_fpr64(ctx
, fp2
, fs
);
10195 tcg_gen_andi_i64(fp0
, fp0
, 1);
10196 tcg_gen_movcond_i64(TCG_COND_NE
, fp0
, fp0
, t1
, fp1
, fp2
);
10199 tcg_gen_andi_i64(fp1
, fp1
, 1);
10200 tcg_gen_movcond_i64(TCG_COND_EQ
, fp0
, fp1
, t1
, fp2
, t1
);
10203 tcg_gen_andi_i64(fp1
, fp1
, 1);
10204 tcg_gen_movcond_i64(TCG_COND_NE
, fp0
, fp1
, t1
, fp2
, t1
);
10207 MIPS_INVAL("gen_sel_d");
10208 gen_reserved_instruction(ctx
);
10212 gen_store_fpr64(ctx
, fp0
, fd
);
10213 tcg_temp_free_i64(fp2
);
10214 tcg_temp_free_i64(fp1
);
10215 tcg_temp_free_i64(fp0
);
10216 tcg_temp_free_i64(t1
);
10219 static void gen_farith(DisasContext
*ctx
, enum fopcode op1
,
10220 int ft
, int fs
, int fd
, int cc
)
10222 uint32_t func
= ctx
->opcode
& 0x3f;
10226 TCGv_i32 fp0
= tcg_temp_new_i32();
10227 TCGv_i32 fp1
= tcg_temp_new_i32();
10229 gen_load_fpr32(ctx
, fp0
, fs
);
10230 gen_load_fpr32(ctx
, fp1
, ft
);
10231 gen_helper_float_add_s(fp0
, cpu_env
, fp0
, fp1
);
10232 tcg_temp_free_i32(fp1
);
10233 gen_store_fpr32(ctx
, fp0
, fd
);
10234 tcg_temp_free_i32(fp0
);
10239 TCGv_i32 fp0
= tcg_temp_new_i32();
10240 TCGv_i32 fp1
= tcg_temp_new_i32();
10242 gen_load_fpr32(ctx
, fp0
, fs
);
10243 gen_load_fpr32(ctx
, fp1
, ft
);
10244 gen_helper_float_sub_s(fp0
, cpu_env
, fp0
, fp1
);
10245 tcg_temp_free_i32(fp1
);
10246 gen_store_fpr32(ctx
, fp0
, fd
);
10247 tcg_temp_free_i32(fp0
);
10252 TCGv_i32 fp0
= tcg_temp_new_i32();
10253 TCGv_i32 fp1
= tcg_temp_new_i32();
10255 gen_load_fpr32(ctx
, fp0
, fs
);
10256 gen_load_fpr32(ctx
, fp1
, ft
);
10257 gen_helper_float_mul_s(fp0
, cpu_env
, fp0
, fp1
);
10258 tcg_temp_free_i32(fp1
);
10259 gen_store_fpr32(ctx
, fp0
, fd
);
10260 tcg_temp_free_i32(fp0
);
10265 TCGv_i32 fp0
= tcg_temp_new_i32();
10266 TCGv_i32 fp1
= tcg_temp_new_i32();
10268 gen_load_fpr32(ctx
, fp0
, fs
);
10269 gen_load_fpr32(ctx
, fp1
, ft
);
10270 gen_helper_float_div_s(fp0
, cpu_env
, fp0
, fp1
);
10271 tcg_temp_free_i32(fp1
);
10272 gen_store_fpr32(ctx
, fp0
, fd
);
10273 tcg_temp_free_i32(fp0
);
10278 TCGv_i32 fp0
= tcg_temp_new_i32();
10280 gen_load_fpr32(ctx
, fp0
, fs
);
10281 gen_helper_float_sqrt_s(fp0
, cpu_env
, fp0
);
10282 gen_store_fpr32(ctx
, fp0
, fd
);
10283 tcg_temp_free_i32(fp0
);
10288 TCGv_i32 fp0
= tcg_temp_new_i32();
10290 gen_load_fpr32(ctx
, fp0
, fs
);
10291 if (ctx
->abs2008
) {
10292 tcg_gen_andi_i32(fp0
, fp0
, 0x7fffffffUL
);
10294 gen_helper_float_abs_s(fp0
, fp0
);
10296 gen_store_fpr32(ctx
, fp0
, fd
);
10297 tcg_temp_free_i32(fp0
);
10302 TCGv_i32 fp0
= tcg_temp_new_i32();
10304 gen_load_fpr32(ctx
, fp0
, fs
);
10305 gen_store_fpr32(ctx
, fp0
, fd
);
10306 tcg_temp_free_i32(fp0
);
10311 TCGv_i32 fp0
= tcg_temp_new_i32();
10313 gen_load_fpr32(ctx
, fp0
, fs
);
10314 if (ctx
->abs2008
) {
10315 tcg_gen_xori_i32(fp0
, fp0
, 1UL << 31);
10317 gen_helper_float_chs_s(fp0
, fp0
);
10319 gen_store_fpr32(ctx
, fp0
, fd
);
10320 tcg_temp_free_i32(fp0
);
10323 case OPC_ROUND_L_S
:
10324 check_cp1_64bitmode(ctx
);
10326 TCGv_i32 fp32
= tcg_temp_new_i32();
10327 TCGv_i64 fp64
= tcg_temp_new_i64();
10329 gen_load_fpr32(ctx
, fp32
, fs
);
10330 if (ctx
->nan2008
) {
10331 gen_helper_float_round_2008_l_s(fp64
, cpu_env
, fp32
);
10333 gen_helper_float_round_l_s(fp64
, cpu_env
, fp32
);
10335 tcg_temp_free_i32(fp32
);
10336 gen_store_fpr64(ctx
, fp64
, fd
);
10337 tcg_temp_free_i64(fp64
);
10340 case OPC_TRUNC_L_S
:
10341 check_cp1_64bitmode(ctx
);
10343 TCGv_i32 fp32
= tcg_temp_new_i32();
10344 TCGv_i64 fp64
= tcg_temp_new_i64();
10346 gen_load_fpr32(ctx
, fp32
, fs
);
10347 if (ctx
->nan2008
) {
10348 gen_helper_float_trunc_2008_l_s(fp64
, cpu_env
, fp32
);
10350 gen_helper_float_trunc_l_s(fp64
, cpu_env
, fp32
);
10352 tcg_temp_free_i32(fp32
);
10353 gen_store_fpr64(ctx
, fp64
, fd
);
10354 tcg_temp_free_i64(fp64
);
10358 check_cp1_64bitmode(ctx
);
10360 TCGv_i32 fp32
= tcg_temp_new_i32();
10361 TCGv_i64 fp64
= tcg_temp_new_i64();
10363 gen_load_fpr32(ctx
, fp32
, fs
);
10364 if (ctx
->nan2008
) {
10365 gen_helper_float_ceil_2008_l_s(fp64
, cpu_env
, fp32
);
10367 gen_helper_float_ceil_l_s(fp64
, cpu_env
, fp32
);
10369 tcg_temp_free_i32(fp32
);
10370 gen_store_fpr64(ctx
, fp64
, fd
);
10371 tcg_temp_free_i64(fp64
);
10374 case OPC_FLOOR_L_S
:
10375 check_cp1_64bitmode(ctx
);
10377 TCGv_i32 fp32
= tcg_temp_new_i32();
10378 TCGv_i64 fp64
= tcg_temp_new_i64();
10380 gen_load_fpr32(ctx
, fp32
, fs
);
10381 if (ctx
->nan2008
) {
10382 gen_helper_float_floor_2008_l_s(fp64
, cpu_env
, fp32
);
10384 gen_helper_float_floor_l_s(fp64
, cpu_env
, fp32
);
10386 tcg_temp_free_i32(fp32
);
10387 gen_store_fpr64(ctx
, fp64
, fd
);
10388 tcg_temp_free_i64(fp64
);
10391 case OPC_ROUND_W_S
:
10393 TCGv_i32 fp0
= tcg_temp_new_i32();
10395 gen_load_fpr32(ctx
, fp0
, fs
);
10396 if (ctx
->nan2008
) {
10397 gen_helper_float_round_2008_w_s(fp0
, cpu_env
, fp0
);
10399 gen_helper_float_round_w_s(fp0
, cpu_env
, fp0
);
10401 gen_store_fpr32(ctx
, fp0
, fd
);
10402 tcg_temp_free_i32(fp0
);
10405 case OPC_TRUNC_W_S
:
10407 TCGv_i32 fp0
= tcg_temp_new_i32();
10409 gen_load_fpr32(ctx
, fp0
, fs
);
10410 if (ctx
->nan2008
) {
10411 gen_helper_float_trunc_2008_w_s(fp0
, cpu_env
, fp0
);
10413 gen_helper_float_trunc_w_s(fp0
, cpu_env
, fp0
);
10415 gen_store_fpr32(ctx
, fp0
, fd
);
10416 tcg_temp_free_i32(fp0
);
10421 TCGv_i32 fp0
= tcg_temp_new_i32();
10423 gen_load_fpr32(ctx
, fp0
, fs
);
10424 if (ctx
->nan2008
) {
10425 gen_helper_float_ceil_2008_w_s(fp0
, cpu_env
, fp0
);
10427 gen_helper_float_ceil_w_s(fp0
, cpu_env
, fp0
);
10429 gen_store_fpr32(ctx
, fp0
, fd
);
10430 tcg_temp_free_i32(fp0
);
10433 case OPC_FLOOR_W_S
:
10435 TCGv_i32 fp0
= tcg_temp_new_i32();
10437 gen_load_fpr32(ctx
, fp0
, fs
);
10438 if (ctx
->nan2008
) {
10439 gen_helper_float_floor_2008_w_s(fp0
, cpu_env
, fp0
);
10441 gen_helper_float_floor_w_s(fp0
, cpu_env
, fp0
);
10443 gen_store_fpr32(ctx
, fp0
, fd
);
10444 tcg_temp_free_i32(fp0
);
10448 check_insn(ctx
, ISA_MIPS_R6
);
10449 gen_sel_s(ctx
, op1
, fd
, ft
, fs
);
10452 check_insn(ctx
, ISA_MIPS_R6
);
10453 gen_sel_s(ctx
, op1
, fd
, ft
, fs
);
10456 check_insn(ctx
, ISA_MIPS_R6
);
10457 gen_sel_s(ctx
, op1
, fd
, ft
, fs
);
10460 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
10461 gen_movcf_s(ctx
, fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
10464 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
10466 TCGLabel
*l1
= gen_new_label();
10470 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
10472 fp0
= tcg_temp_new_i32();
10473 gen_load_fpr32(ctx
, fp0
, fs
);
10474 gen_store_fpr32(ctx
, fp0
, fd
);
10475 tcg_temp_free_i32(fp0
);
10480 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
10482 TCGLabel
*l1
= gen_new_label();
10486 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
10487 fp0
= tcg_temp_new_i32();
10488 gen_load_fpr32(ctx
, fp0
, fs
);
10489 gen_store_fpr32(ctx
, fp0
, fd
);
10490 tcg_temp_free_i32(fp0
);
10497 TCGv_i32 fp0
= tcg_temp_new_i32();
10499 gen_load_fpr32(ctx
, fp0
, fs
);
10500 gen_helper_float_recip_s(fp0
, cpu_env
, fp0
);
10501 gen_store_fpr32(ctx
, fp0
, fd
);
10502 tcg_temp_free_i32(fp0
);
10507 TCGv_i32 fp0
= tcg_temp_new_i32();
10509 gen_load_fpr32(ctx
, fp0
, fs
);
10510 gen_helper_float_rsqrt_s(fp0
, cpu_env
, fp0
);
10511 gen_store_fpr32(ctx
, fp0
, fd
);
10512 tcg_temp_free_i32(fp0
);
10516 check_insn(ctx
, ISA_MIPS_R6
);
10518 TCGv_i32 fp0
= tcg_temp_new_i32();
10519 TCGv_i32 fp1
= tcg_temp_new_i32();
10520 TCGv_i32 fp2
= tcg_temp_new_i32();
10521 gen_load_fpr32(ctx
, fp0
, fs
);
10522 gen_load_fpr32(ctx
, fp1
, ft
);
10523 gen_load_fpr32(ctx
, fp2
, fd
);
10524 gen_helper_float_maddf_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
10525 gen_store_fpr32(ctx
, fp2
, fd
);
10526 tcg_temp_free_i32(fp2
);
10527 tcg_temp_free_i32(fp1
);
10528 tcg_temp_free_i32(fp0
);
10532 check_insn(ctx
, ISA_MIPS_R6
);
10534 TCGv_i32 fp0
= tcg_temp_new_i32();
10535 TCGv_i32 fp1
= tcg_temp_new_i32();
10536 TCGv_i32 fp2
= tcg_temp_new_i32();
10537 gen_load_fpr32(ctx
, fp0
, fs
);
10538 gen_load_fpr32(ctx
, fp1
, ft
);
10539 gen_load_fpr32(ctx
, fp2
, fd
);
10540 gen_helper_float_msubf_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
10541 gen_store_fpr32(ctx
, fp2
, fd
);
10542 tcg_temp_free_i32(fp2
);
10543 tcg_temp_free_i32(fp1
);
10544 tcg_temp_free_i32(fp0
);
10548 check_insn(ctx
, ISA_MIPS_R6
);
10550 TCGv_i32 fp0
= tcg_temp_new_i32();
10551 gen_load_fpr32(ctx
, fp0
, fs
);
10552 gen_helper_float_rint_s(fp0
, cpu_env
, fp0
);
10553 gen_store_fpr32(ctx
, fp0
, fd
);
10554 tcg_temp_free_i32(fp0
);
10558 check_insn(ctx
, ISA_MIPS_R6
);
10560 TCGv_i32 fp0
= tcg_temp_new_i32();
10561 gen_load_fpr32(ctx
, fp0
, fs
);
10562 gen_helper_float_class_s(fp0
, cpu_env
, fp0
);
10563 gen_store_fpr32(ctx
, fp0
, fd
);
10564 tcg_temp_free_i32(fp0
);
10567 case OPC_MIN_S
: /* OPC_RECIP2_S */
10568 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
10570 TCGv_i32 fp0
= tcg_temp_new_i32();
10571 TCGv_i32 fp1
= tcg_temp_new_i32();
10572 TCGv_i32 fp2
= tcg_temp_new_i32();
10573 gen_load_fpr32(ctx
, fp0
, fs
);
10574 gen_load_fpr32(ctx
, fp1
, ft
);
10575 gen_helper_float_min_s(fp2
, cpu_env
, fp0
, fp1
);
10576 gen_store_fpr32(ctx
, fp2
, fd
);
10577 tcg_temp_free_i32(fp2
);
10578 tcg_temp_free_i32(fp1
);
10579 tcg_temp_free_i32(fp0
);
10582 check_cp1_64bitmode(ctx
);
10584 TCGv_i32 fp0
= tcg_temp_new_i32();
10585 TCGv_i32 fp1
= tcg_temp_new_i32();
10587 gen_load_fpr32(ctx
, fp0
, fs
);
10588 gen_load_fpr32(ctx
, fp1
, ft
);
10589 gen_helper_float_recip2_s(fp0
, cpu_env
, fp0
, fp1
);
10590 tcg_temp_free_i32(fp1
);
10591 gen_store_fpr32(ctx
, fp0
, fd
);
10592 tcg_temp_free_i32(fp0
);
10596 case OPC_MINA_S
: /* OPC_RECIP1_S */
10597 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
10599 TCGv_i32 fp0
= tcg_temp_new_i32();
10600 TCGv_i32 fp1
= tcg_temp_new_i32();
10601 TCGv_i32 fp2
= tcg_temp_new_i32();
10602 gen_load_fpr32(ctx
, fp0
, fs
);
10603 gen_load_fpr32(ctx
, fp1
, ft
);
10604 gen_helper_float_mina_s(fp2
, cpu_env
, fp0
, fp1
);
10605 gen_store_fpr32(ctx
, fp2
, fd
);
10606 tcg_temp_free_i32(fp2
);
10607 tcg_temp_free_i32(fp1
);
10608 tcg_temp_free_i32(fp0
);
10611 check_cp1_64bitmode(ctx
);
10613 TCGv_i32 fp0
= tcg_temp_new_i32();
10615 gen_load_fpr32(ctx
, fp0
, fs
);
10616 gen_helper_float_recip1_s(fp0
, cpu_env
, fp0
);
10617 gen_store_fpr32(ctx
, fp0
, fd
);
10618 tcg_temp_free_i32(fp0
);
10622 case OPC_MAX_S
: /* OPC_RSQRT1_S */
10623 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
10625 TCGv_i32 fp0
= tcg_temp_new_i32();
10626 TCGv_i32 fp1
= tcg_temp_new_i32();
10627 gen_load_fpr32(ctx
, fp0
, fs
);
10628 gen_load_fpr32(ctx
, fp1
, ft
);
10629 gen_helper_float_max_s(fp1
, cpu_env
, fp0
, fp1
);
10630 gen_store_fpr32(ctx
, fp1
, fd
);
10631 tcg_temp_free_i32(fp1
);
10632 tcg_temp_free_i32(fp0
);
10635 check_cp1_64bitmode(ctx
);
10637 TCGv_i32 fp0
= tcg_temp_new_i32();
10639 gen_load_fpr32(ctx
, fp0
, fs
);
10640 gen_helper_float_rsqrt1_s(fp0
, cpu_env
, fp0
);
10641 gen_store_fpr32(ctx
, fp0
, fd
);
10642 tcg_temp_free_i32(fp0
);
10646 case OPC_MAXA_S
: /* OPC_RSQRT2_S */
10647 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
10649 TCGv_i32 fp0
= tcg_temp_new_i32();
10650 TCGv_i32 fp1
= tcg_temp_new_i32();
10651 gen_load_fpr32(ctx
, fp0
, fs
);
10652 gen_load_fpr32(ctx
, fp1
, ft
);
10653 gen_helper_float_maxa_s(fp1
, cpu_env
, fp0
, fp1
);
10654 gen_store_fpr32(ctx
, fp1
, fd
);
10655 tcg_temp_free_i32(fp1
);
10656 tcg_temp_free_i32(fp0
);
10659 check_cp1_64bitmode(ctx
);
10661 TCGv_i32 fp0
= tcg_temp_new_i32();
10662 TCGv_i32 fp1
= tcg_temp_new_i32();
10664 gen_load_fpr32(ctx
, fp0
, fs
);
10665 gen_load_fpr32(ctx
, fp1
, ft
);
10666 gen_helper_float_rsqrt2_s(fp0
, cpu_env
, fp0
, fp1
);
10667 tcg_temp_free_i32(fp1
);
10668 gen_store_fpr32(ctx
, fp0
, fd
);
10669 tcg_temp_free_i32(fp0
);
10674 check_cp1_registers(ctx
, fd
);
10676 TCGv_i32 fp32
= tcg_temp_new_i32();
10677 TCGv_i64 fp64
= tcg_temp_new_i64();
10679 gen_load_fpr32(ctx
, fp32
, fs
);
10680 gen_helper_float_cvtd_s(fp64
, cpu_env
, fp32
);
10681 tcg_temp_free_i32(fp32
);
10682 gen_store_fpr64(ctx
, fp64
, fd
);
10683 tcg_temp_free_i64(fp64
);
10688 TCGv_i32 fp0
= tcg_temp_new_i32();
10690 gen_load_fpr32(ctx
, fp0
, fs
);
10691 if (ctx
->nan2008
) {
10692 gen_helper_float_cvt_2008_w_s(fp0
, cpu_env
, fp0
);
10694 gen_helper_float_cvt_w_s(fp0
, cpu_env
, fp0
);
10696 gen_store_fpr32(ctx
, fp0
, fd
);
10697 tcg_temp_free_i32(fp0
);
10701 check_cp1_64bitmode(ctx
);
10703 TCGv_i32 fp32
= tcg_temp_new_i32();
10704 TCGv_i64 fp64
= tcg_temp_new_i64();
10706 gen_load_fpr32(ctx
, fp32
, fs
);
10707 if (ctx
->nan2008
) {
10708 gen_helper_float_cvt_2008_l_s(fp64
, cpu_env
, fp32
);
10710 gen_helper_float_cvt_l_s(fp64
, cpu_env
, fp32
);
10712 tcg_temp_free_i32(fp32
);
10713 gen_store_fpr64(ctx
, fp64
, fd
);
10714 tcg_temp_free_i64(fp64
);
10720 TCGv_i64 fp64
= tcg_temp_new_i64();
10721 TCGv_i32 fp32_0
= tcg_temp_new_i32();
10722 TCGv_i32 fp32_1
= tcg_temp_new_i32();
10724 gen_load_fpr32(ctx
, fp32_0
, fs
);
10725 gen_load_fpr32(ctx
, fp32_1
, ft
);
10726 tcg_gen_concat_i32_i64(fp64
, fp32_1
, fp32_0
);
10727 tcg_temp_free_i32(fp32_1
);
10728 tcg_temp_free_i32(fp32_0
);
10729 gen_store_fpr64(ctx
, fp64
, fd
);
10730 tcg_temp_free_i64(fp64
);
10736 case OPC_CMP_UEQ_S
:
10737 case OPC_CMP_OLT_S
:
10738 case OPC_CMP_ULT_S
:
10739 case OPC_CMP_OLE_S
:
10740 case OPC_CMP_ULE_S
:
10742 case OPC_CMP_NGLE_S
:
10743 case OPC_CMP_SEQ_S
:
10744 case OPC_CMP_NGL_S
:
10746 case OPC_CMP_NGE_S
:
10748 case OPC_CMP_NGT_S
:
10749 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
10750 if (ctx
->opcode
& (1 << 6)) {
10751 gen_cmpabs_s(ctx
, func
- 48, ft
, fs
, cc
);
10753 gen_cmp_s(ctx
, func
- 48, ft
, fs
, cc
);
10757 check_cp1_registers(ctx
, fs
| ft
| fd
);
10759 TCGv_i64 fp0
= tcg_temp_new_i64();
10760 TCGv_i64 fp1
= tcg_temp_new_i64();
10762 gen_load_fpr64(ctx
, fp0
, fs
);
10763 gen_load_fpr64(ctx
, fp1
, ft
);
10764 gen_helper_float_add_d(fp0
, cpu_env
, fp0
, fp1
);
10765 tcg_temp_free_i64(fp1
);
10766 gen_store_fpr64(ctx
, fp0
, fd
);
10767 tcg_temp_free_i64(fp0
);
10771 check_cp1_registers(ctx
, fs
| ft
| fd
);
10773 TCGv_i64 fp0
= tcg_temp_new_i64();
10774 TCGv_i64 fp1
= tcg_temp_new_i64();
10776 gen_load_fpr64(ctx
, fp0
, fs
);
10777 gen_load_fpr64(ctx
, fp1
, ft
);
10778 gen_helper_float_sub_d(fp0
, cpu_env
, fp0
, fp1
);
10779 tcg_temp_free_i64(fp1
);
10780 gen_store_fpr64(ctx
, fp0
, fd
);
10781 tcg_temp_free_i64(fp0
);
10785 check_cp1_registers(ctx
, fs
| ft
| fd
);
10787 TCGv_i64 fp0
= tcg_temp_new_i64();
10788 TCGv_i64 fp1
= tcg_temp_new_i64();
10790 gen_load_fpr64(ctx
, fp0
, fs
);
10791 gen_load_fpr64(ctx
, fp1
, ft
);
10792 gen_helper_float_mul_d(fp0
, cpu_env
, fp0
, fp1
);
10793 tcg_temp_free_i64(fp1
);
10794 gen_store_fpr64(ctx
, fp0
, fd
);
10795 tcg_temp_free_i64(fp0
);
10799 check_cp1_registers(ctx
, fs
| ft
| fd
);
10801 TCGv_i64 fp0
= tcg_temp_new_i64();
10802 TCGv_i64 fp1
= tcg_temp_new_i64();
10804 gen_load_fpr64(ctx
, fp0
, fs
);
10805 gen_load_fpr64(ctx
, fp1
, ft
);
10806 gen_helper_float_div_d(fp0
, cpu_env
, fp0
, fp1
);
10807 tcg_temp_free_i64(fp1
);
10808 gen_store_fpr64(ctx
, fp0
, fd
);
10809 tcg_temp_free_i64(fp0
);
10813 check_cp1_registers(ctx
, fs
| fd
);
10815 TCGv_i64 fp0
= tcg_temp_new_i64();
10817 gen_load_fpr64(ctx
, fp0
, fs
);
10818 gen_helper_float_sqrt_d(fp0
, cpu_env
, fp0
);
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 if (ctx
->abs2008
) {
10830 tcg_gen_andi_i64(fp0
, fp0
, 0x7fffffffffffffffULL
);
10832 gen_helper_float_abs_d(fp0
, fp0
);
10834 gen_store_fpr64(ctx
, fp0
, fd
);
10835 tcg_temp_free_i64(fp0
);
10839 check_cp1_registers(ctx
, fs
| fd
);
10841 TCGv_i64 fp0
= tcg_temp_new_i64();
10843 gen_load_fpr64(ctx
, fp0
, fs
);
10844 gen_store_fpr64(ctx
, fp0
, fd
);
10845 tcg_temp_free_i64(fp0
);
10849 check_cp1_registers(ctx
, fs
| fd
);
10851 TCGv_i64 fp0
= tcg_temp_new_i64();
10853 gen_load_fpr64(ctx
, fp0
, fs
);
10854 if (ctx
->abs2008
) {
10855 tcg_gen_xori_i64(fp0
, fp0
, 1ULL << 63);
10857 gen_helper_float_chs_d(fp0
, fp0
);
10859 gen_store_fpr64(ctx
, fp0
, fd
);
10860 tcg_temp_free_i64(fp0
);
10863 case OPC_ROUND_L_D
:
10864 check_cp1_64bitmode(ctx
);
10866 TCGv_i64 fp0
= tcg_temp_new_i64();
10868 gen_load_fpr64(ctx
, fp0
, fs
);
10869 if (ctx
->nan2008
) {
10870 gen_helper_float_round_2008_l_d(fp0
, cpu_env
, fp0
);
10872 gen_helper_float_round_l_d(fp0
, cpu_env
, fp0
);
10874 gen_store_fpr64(ctx
, fp0
, fd
);
10875 tcg_temp_free_i64(fp0
);
10878 case OPC_TRUNC_L_D
:
10879 check_cp1_64bitmode(ctx
);
10881 TCGv_i64 fp0
= tcg_temp_new_i64();
10883 gen_load_fpr64(ctx
, fp0
, fs
);
10884 if (ctx
->nan2008
) {
10885 gen_helper_float_trunc_2008_l_d(fp0
, cpu_env
, fp0
);
10887 gen_helper_float_trunc_l_d(fp0
, cpu_env
, fp0
);
10889 gen_store_fpr64(ctx
, fp0
, fd
);
10890 tcg_temp_free_i64(fp0
);
10894 check_cp1_64bitmode(ctx
);
10896 TCGv_i64 fp0
= tcg_temp_new_i64();
10898 gen_load_fpr64(ctx
, fp0
, fs
);
10899 if (ctx
->nan2008
) {
10900 gen_helper_float_ceil_2008_l_d(fp0
, cpu_env
, fp0
);
10902 gen_helper_float_ceil_l_d(fp0
, cpu_env
, fp0
);
10904 gen_store_fpr64(ctx
, fp0
, fd
);
10905 tcg_temp_free_i64(fp0
);
10908 case OPC_FLOOR_L_D
:
10909 check_cp1_64bitmode(ctx
);
10911 TCGv_i64 fp0
= tcg_temp_new_i64();
10913 gen_load_fpr64(ctx
, fp0
, fs
);
10914 if (ctx
->nan2008
) {
10915 gen_helper_float_floor_2008_l_d(fp0
, cpu_env
, fp0
);
10917 gen_helper_float_floor_l_d(fp0
, cpu_env
, fp0
);
10919 gen_store_fpr64(ctx
, fp0
, fd
);
10920 tcg_temp_free_i64(fp0
);
10923 case OPC_ROUND_W_D
:
10924 check_cp1_registers(ctx
, fs
);
10926 TCGv_i32 fp32
= tcg_temp_new_i32();
10927 TCGv_i64 fp64
= tcg_temp_new_i64();
10929 gen_load_fpr64(ctx
, fp64
, fs
);
10930 if (ctx
->nan2008
) {
10931 gen_helper_float_round_2008_w_d(fp32
, cpu_env
, fp64
);
10933 gen_helper_float_round_w_d(fp32
, cpu_env
, fp64
);
10935 tcg_temp_free_i64(fp64
);
10936 gen_store_fpr32(ctx
, fp32
, fd
);
10937 tcg_temp_free_i32(fp32
);
10940 case OPC_TRUNC_W_D
:
10941 check_cp1_registers(ctx
, fs
);
10943 TCGv_i32 fp32
= tcg_temp_new_i32();
10944 TCGv_i64 fp64
= tcg_temp_new_i64();
10946 gen_load_fpr64(ctx
, fp64
, fs
);
10947 if (ctx
->nan2008
) {
10948 gen_helper_float_trunc_2008_w_d(fp32
, cpu_env
, fp64
);
10950 gen_helper_float_trunc_w_d(fp32
, cpu_env
, fp64
);
10952 tcg_temp_free_i64(fp64
);
10953 gen_store_fpr32(ctx
, fp32
, fd
);
10954 tcg_temp_free_i32(fp32
);
10958 check_cp1_registers(ctx
, fs
);
10960 TCGv_i32 fp32
= tcg_temp_new_i32();
10961 TCGv_i64 fp64
= tcg_temp_new_i64();
10963 gen_load_fpr64(ctx
, fp64
, fs
);
10964 if (ctx
->nan2008
) {
10965 gen_helper_float_ceil_2008_w_d(fp32
, cpu_env
, fp64
);
10967 gen_helper_float_ceil_w_d(fp32
, cpu_env
, fp64
);
10969 tcg_temp_free_i64(fp64
);
10970 gen_store_fpr32(ctx
, fp32
, fd
);
10971 tcg_temp_free_i32(fp32
);
10974 case OPC_FLOOR_W_D
:
10975 check_cp1_registers(ctx
, fs
);
10977 TCGv_i32 fp32
= tcg_temp_new_i32();
10978 TCGv_i64 fp64
= tcg_temp_new_i64();
10980 gen_load_fpr64(ctx
, fp64
, fs
);
10981 if (ctx
->nan2008
) {
10982 gen_helper_float_floor_2008_w_d(fp32
, cpu_env
, fp64
);
10984 gen_helper_float_floor_w_d(fp32
, cpu_env
, fp64
);
10986 tcg_temp_free_i64(fp64
);
10987 gen_store_fpr32(ctx
, fp32
, fd
);
10988 tcg_temp_free_i32(fp32
);
10992 check_insn(ctx
, ISA_MIPS_R6
);
10993 gen_sel_d(ctx
, op1
, fd
, ft
, fs
);
10996 check_insn(ctx
, ISA_MIPS_R6
);
10997 gen_sel_d(ctx
, op1
, fd
, ft
, fs
);
11000 check_insn(ctx
, ISA_MIPS_R6
);
11001 gen_sel_d(ctx
, op1
, fd
, ft
, fs
);
11004 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
11005 gen_movcf_d(ctx
, fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
11008 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
11010 TCGLabel
*l1
= gen_new_label();
11014 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
11016 fp0
= tcg_temp_new_i64();
11017 gen_load_fpr64(ctx
, fp0
, fs
);
11018 gen_store_fpr64(ctx
, fp0
, fd
);
11019 tcg_temp_free_i64(fp0
);
11024 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
11026 TCGLabel
*l1
= gen_new_label();
11030 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
11031 fp0
= tcg_temp_new_i64();
11032 gen_load_fpr64(ctx
, fp0
, fs
);
11033 gen_store_fpr64(ctx
, fp0
, fd
);
11034 tcg_temp_free_i64(fp0
);
11040 check_cp1_registers(ctx
, fs
| fd
);
11042 TCGv_i64 fp0
= tcg_temp_new_i64();
11044 gen_load_fpr64(ctx
, fp0
, fs
);
11045 gen_helper_float_recip_d(fp0
, cpu_env
, fp0
);
11046 gen_store_fpr64(ctx
, fp0
, fd
);
11047 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_rsqrt_d(fp0
, cpu_env
, fp0
);
11057 gen_store_fpr64(ctx
, fp0
, fd
);
11058 tcg_temp_free_i64(fp0
);
11062 check_insn(ctx
, ISA_MIPS_R6
);
11064 TCGv_i64 fp0
= tcg_temp_new_i64();
11065 TCGv_i64 fp1
= tcg_temp_new_i64();
11066 TCGv_i64 fp2
= tcg_temp_new_i64();
11067 gen_load_fpr64(ctx
, fp0
, fs
);
11068 gen_load_fpr64(ctx
, fp1
, ft
);
11069 gen_load_fpr64(ctx
, fp2
, fd
);
11070 gen_helper_float_maddf_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
11071 gen_store_fpr64(ctx
, fp2
, fd
);
11072 tcg_temp_free_i64(fp2
);
11073 tcg_temp_free_i64(fp1
);
11074 tcg_temp_free_i64(fp0
);
11078 check_insn(ctx
, ISA_MIPS_R6
);
11080 TCGv_i64 fp0
= tcg_temp_new_i64();
11081 TCGv_i64 fp1
= tcg_temp_new_i64();
11082 TCGv_i64 fp2
= tcg_temp_new_i64();
11083 gen_load_fpr64(ctx
, fp0
, fs
);
11084 gen_load_fpr64(ctx
, fp1
, ft
);
11085 gen_load_fpr64(ctx
, fp2
, fd
);
11086 gen_helper_float_msubf_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
11087 gen_store_fpr64(ctx
, fp2
, fd
);
11088 tcg_temp_free_i64(fp2
);
11089 tcg_temp_free_i64(fp1
);
11090 tcg_temp_free_i64(fp0
);
11094 check_insn(ctx
, ISA_MIPS_R6
);
11096 TCGv_i64 fp0
= tcg_temp_new_i64();
11097 gen_load_fpr64(ctx
, fp0
, fs
);
11098 gen_helper_float_rint_d(fp0
, cpu_env
, fp0
);
11099 gen_store_fpr64(ctx
, fp0
, fd
);
11100 tcg_temp_free_i64(fp0
);
11104 check_insn(ctx
, ISA_MIPS_R6
);
11106 TCGv_i64 fp0
= tcg_temp_new_i64();
11107 gen_load_fpr64(ctx
, fp0
, fs
);
11108 gen_helper_float_class_d(fp0
, cpu_env
, fp0
);
11109 gen_store_fpr64(ctx
, fp0
, fd
);
11110 tcg_temp_free_i64(fp0
);
11113 case OPC_MIN_D
: /* OPC_RECIP2_D */
11114 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
11116 TCGv_i64 fp0
= tcg_temp_new_i64();
11117 TCGv_i64 fp1
= tcg_temp_new_i64();
11118 gen_load_fpr64(ctx
, fp0
, fs
);
11119 gen_load_fpr64(ctx
, fp1
, ft
);
11120 gen_helper_float_min_d(fp1
, cpu_env
, fp0
, fp1
);
11121 gen_store_fpr64(ctx
, fp1
, fd
);
11122 tcg_temp_free_i64(fp1
);
11123 tcg_temp_free_i64(fp0
);
11126 check_cp1_64bitmode(ctx
);
11128 TCGv_i64 fp0
= tcg_temp_new_i64();
11129 TCGv_i64 fp1
= tcg_temp_new_i64();
11131 gen_load_fpr64(ctx
, fp0
, fs
);
11132 gen_load_fpr64(ctx
, fp1
, ft
);
11133 gen_helper_float_recip2_d(fp0
, cpu_env
, fp0
, fp1
);
11134 tcg_temp_free_i64(fp1
);
11135 gen_store_fpr64(ctx
, fp0
, fd
);
11136 tcg_temp_free_i64(fp0
);
11140 case OPC_MINA_D
: /* OPC_RECIP1_D */
11141 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
11143 TCGv_i64 fp0
= tcg_temp_new_i64();
11144 TCGv_i64 fp1
= tcg_temp_new_i64();
11145 gen_load_fpr64(ctx
, fp0
, fs
);
11146 gen_load_fpr64(ctx
, fp1
, ft
);
11147 gen_helper_float_mina_d(fp1
, cpu_env
, fp0
, fp1
);
11148 gen_store_fpr64(ctx
, fp1
, fd
);
11149 tcg_temp_free_i64(fp1
);
11150 tcg_temp_free_i64(fp0
);
11153 check_cp1_64bitmode(ctx
);
11155 TCGv_i64 fp0
= tcg_temp_new_i64();
11157 gen_load_fpr64(ctx
, fp0
, fs
);
11158 gen_helper_float_recip1_d(fp0
, cpu_env
, fp0
);
11159 gen_store_fpr64(ctx
, fp0
, fd
);
11160 tcg_temp_free_i64(fp0
);
11164 case OPC_MAX_D
: /* OPC_RSQRT1_D */
11165 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
11167 TCGv_i64 fp0
= tcg_temp_new_i64();
11168 TCGv_i64 fp1
= tcg_temp_new_i64();
11169 gen_load_fpr64(ctx
, fp0
, fs
);
11170 gen_load_fpr64(ctx
, fp1
, ft
);
11171 gen_helper_float_max_d(fp1
, cpu_env
, fp0
, fp1
);
11172 gen_store_fpr64(ctx
, fp1
, fd
);
11173 tcg_temp_free_i64(fp1
);
11174 tcg_temp_free_i64(fp0
);
11177 check_cp1_64bitmode(ctx
);
11179 TCGv_i64 fp0
= tcg_temp_new_i64();
11181 gen_load_fpr64(ctx
, fp0
, fs
);
11182 gen_helper_float_rsqrt1_d(fp0
, cpu_env
, fp0
);
11183 gen_store_fpr64(ctx
, fp0
, fd
);
11184 tcg_temp_free_i64(fp0
);
11188 case OPC_MAXA_D
: /* OPC_RSQRT2_D */
11189 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
11191 TCGv_i64 fp0
= tcg_temp_new_i64();
11192 TCGv_i64 fp1
= tcg_temp_new_i64();
11193 gen_load_fpr64(ctx
, fp0
, fs
);
11194 gen_load_fpr64(ctx
, fp1
, ft
);
11195 gen_helper_float_maxa_d(fp1
, cpu_env
, fp0
, fp1
);
11196 gen_store_fpr64(ctx
, fp1
, fd
);
11197 tcg_temp_free_i64(fp1
);
11198 tcg_temp_free_i64(fp0
);
11201 check_cp1_64bitmode(ctx
);
11203 TCGv_i64 fp0
= tcg_temp_new_i64();
11204 TCGv_i64 fp1
= tcg_temp_new_i64();
11206 gen_load_fpr64(ctx
, fp0
, fs
);
11207 gen_load_fpr64(ctx
, fp1
, ft
);
11208 gen_helper_float_rsqrt2_d(fp0
, cpu_env
, fp0
, fp1
);
11209 tcg_temp_free_i64(fp1
);
11210 gen_store_fpr64(ctx
, fp0
, fd
);
11211 tcg_temp_free_i64(fp0
);
11218 case OPC_CMP_UEQ_D
:
11219 case OPC_CMP_OLT_D
:
11220 case OPC_CMP_ULT_D
:
11221 case OPC_CMP_OLE_D
:
11222 case OPC_CMP_ULE_D
:
11224 case OPC_CMP_NGLE_D
:
11225 case OPC_CMP_SEQ_D
:
11226 case OPC_CMP_NGL_D
:
11228 case OPC_CMP_NGE_D
:
11230 case OPC_CMP_NGT_D
:
11231 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
11232 if (ctx
->opcode
& (1 << 6)) {
11233 gen_cmpabs_d(ctx
, func
- 48, ft
, fs
, cc
);
11235 gen_cmp_d(ctx
, func
- 48, ft
, fs
, cc
);
11239 check_cp1_registers(ctx
, fs
);
11241 TCGv_i32 fp32
= tcg_temp_new_i32();
11242 TCGv_i64 fp64
= tcg_temp_new_i64();
11244 gen_load_fpr64(ctx
, fp64
, fs
);
11245 gen_helper_float_cvts_d(fp32
, cpu_env
, fp64
);
11246 tcg_temp_free_i64(fp64
);
11247 gen_store_fpr32(ctx
, fp32
, fd
);
11248 tcg_temp_free_i32(fp32
);
11252 check_cp1_registers(ctx
, fs
);
11254 TCGv_i32 fp32
= tcg_temp_new_i32();
11255 TCGv_i64 fp64
= tcg_temp_new_i64();
11257 gen_load_fpr64(ctx
, fp64
, fs
);
11258 if (ctx
->nan2008
) {
11259 gen_helper_float_cvt_2008_w_d(fp32
, cpu_env
, fp64
);
11261 gen_helper_float_cvt_w_d(fp32
, cpu_env
, fp64
);
11263 tcg_temp_free_i64(fp64
);
11264 gen_store_fpr32(ctx
, fp32
, fd
);
11265 tcg_temp_free_i32(fp32
);
11269 check_cp1_64bitmode(ctx
);
11271 TCGv_i64 fp0
= tcg_temp_new_i64();
11273 gen_load_fpr64(ctx
, fp0
, fs
);
11274 if (ctx
->nan2008
) {
11275 gen_helper_float_cvt_2008_l_d(fp0
, cpu_env
, fp0
);
11277 gen_helper_float_cvt_l_d(fp0
, cpu_env
, fp0
);
11279 gen_store_fpr64(ctx
, fp0
, fd
);
11280 tcg_temp_free_i64(fp0
);
11285 TCGv_i32 fp0
= tcg_temp_new_i32();
11287 gen_load_fpr32(ctx
, fp0
, fs
);
11288 gen_helper_float_cvts_w(fp0
, cpu_env
, fp0
);
11289 gen_store_fpr32(ctx
, fp0
, fd
);
11290 tcg_temp_free_i32(fp0
);
11294 check_cp1_registers(ctx
, fd
);
11296 TCGv_i32 fp32
= tcg_temp_new_i32();
11297 TCGv_i64 fp64
= tcg_temp_new_i64();
11299 gen_load_fpr32(ctx
, fp32
, fs
);
11300 gen_helper_float_cvtd_w(fp64
, cpu_env
, fp32
);
11301 tcg_temp_free_i32(fp32
);
11302 gen_store_fpr64(ctx
, fp64
, fd
);
11303 tcg_temp_free_i64(fp64
);
11307 check_cp1_64bitmode(ctx
);
11309 TCGv_i32 fp32
= tcg_temp_new_i32();
11310 TCGv_i64 fp64
= tcg_temp_new_i64();
11312 gen_load_fpr64(ctx
, fp64
, fs
);
11313 gen_helper_float_cvts_l(fp32
, cpu_env
, fp64
);
11314 tcg_temp_free_i64(fp64
);
11315 gen_store_fpr32(ctx
, fp32
, fd
);
11316 tcg_temp_free_i32(fp32
);
11320 check_cp1_64bitmode(ctx
);
11322 TCGv_i64 fp0
= tcg_temp_new_i64();
11324 gen_load_fpr64(ctx
, fp0
, fs
);
11325 gen_helper_float_cvtd_l(fp0
, cpu_env
, fp0
);
11326 gen_store_fpr64(ctx
, fp0
, fd
);
11327 tcg_temp_free_i64(fp0
);
11330 case OPC_CVT_PS_PW
:
11333 TCGv_i64 fp0
= tcg_temp_new_i64();
11335 gen_load_fpr64(ctx
, fp0
, fs
);
11336 gen_helper_float_cvtps_pw(fp0
, cpu_env
, fp0
);
11337 gen_store_fpr64(ctx
, fp0
, fd
);
11338 tcg_temp_free_i64(fp0
);
11344 TCGv_i64 fp0
= tcg_temp_new_i64();
11345 TCGv_i64 fp1
= tcg_temp_new_i64();
11347 gen_load_fpr64(ctx
, fp0
, fs
);
11348 gen_load_fpr64(ctx
, fp1
, ft
);
11349 gen_helper_float_add_ps(fp0
, cpu_env
, fp0
, fp1
);
11350 tcg_temp_free_i64(fp1
);
11351 gen_store_fpr64(ctx
, fp0
, fd
);
11352 tcg_temp_free_i64(fp0
);
11358 TCGv_i64 fp0
= tcg_temp_new_i64();
11359 TCGv_i64 fp1
= tcg_temp_new_i64();
11361 gen_load_fpr64(ctx
, fp0
, fs
);
11362 gen_load_fpr64(ctx
, fp1
, ft
);
11363 gen_helper_float_sub_ps(fp0
, cpu_env
, fp0
, fp1
);
11364 tcg_temp_free_i64(fp1
);
11365 gen_store_fpr64(ctx
, fp0
, fd
);
11366 tcg_temp_free_i64(fp0
);
11372 TCGv_i64 fp0
= tcg_temp_new_i64();
11373 TCGv_i64 fp1
= tcg_temp_new_i64();
11375 gen_load_fpr64(ctx
, fp0
, fs
);
11376 gen_load_fpr64(ctx
, fp1
, ft
);
11377 gen_helper_float_mul_ps(fp0
, cpu_env
, fp0
, fp1
);
11378 tcg_temp_free_i64(fp1
);
11379 gen_store_fpr64(ctx
, fp0
, fd
);
11380 tcg_temp_free_i64(fp0
);
11386 TCGv_i64 fp0
= tcg_temp_new_i64();
11388 gen_load_fpr64(ctx
, fp0
, fs
);
11389 gen_helper_float_abs_ps(fp0
, fp0
);
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_store_fpr64(ctx
, fp0
, fd
);
11401 tcg_temp_free_i64(fp0
);
11407 TCGv_i64 fp0
= tcg_temp_new_i64();
11409 gen_load_fpr64(ctx
, fp0
, fs
);
11410 gen_helper_float_chs_ps(fp0
, fp0
);
11411 gen_store_fpr64(ctx
, fp0
, fd
);
11412 tcg_temp_free_i64(fp0
);
11417 gen_movcf_ps(ctx
, fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
11422 TCGLabel
*l1
= gen_new_label();
11426 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
11428 fp0
= tcg_temp_new_i64();
11429 gen_load_fpr64(ctx
, fp0
, fs
);
11430 gen_store_fpr64(ctx
, fp0
, fd
);
11431 tcg_temp_free_i64(fp0
);
11438 TCGLabel
*l1
= gen_new_label();
11442 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
11443 fp0
= tcg_temp_new_i64();
11444 gen_load_fpr64(ctx
, fp0
, fs
);
11445 gen_store_fpr64(ctx
, fp0
, fd
);
11446 tcg_temp_free_i64(fp0
);
11454 TCGv_i64 fp0
= tcg_temp_new_i64();
11455 TCGv_i64 fp1
= tcg_temp_new_i64();
11457 gen_load_fpr64(ctx
, fp0
, ft
);
11458 gen_load_fpr64(ctx
, fp1
, fs
);
11459 gen_helper_float_addr_ps(fp0
, cpu_env
, fp0
, fp1
);
11460 tcg_temp_free_i64(fp1
);
11461 gen_store_fpr64(ctx
, fp0
, fd
);
11462 tcg_temp_free_i64(fp0
);
11468 TCGv_i64 fp0
= tcg_temp_new_i64();
11469 TCGv_i64 fp1
= tcg_temp_new_i64();
11471 gen_load_fpr64(ctx
, fp0
, ft
);
11472 gen_load_fpr64(ctx
, fp1
, fs
);
11473 gen_helper_float_mulr_ps(fp0
, cpu_env
, fp0
, fp1
);
11474 tcg_temp_free_i64(fp1
);
11475 gen_store_fpr64(ctx
, fp0
, fd
);
11476 tcg_temp_free_i64(fp0
);
11479 case OPC_RECIP2_PS
:
11482 TCGv_i64 fp0
= tcg_temp_new_i64();
11483 TCGv_i64 fp1
= tcg_temp_new_i64();
11485 gen_load_fpr64(ctx
, fp0
, fs
);
11486 gen_load_fpr64(ctx
, fp1
, ft
);
11487 gen_helper_float_recip2_ps(fp0
, cpu_env
, fp0
, fp1
);
11488 tcg_temp_free_i64(fp1
);
11489 gen_store_fpr64(ctx
, fp0
, fd
);
11490 tcg_temp_free_i64(fp0
);
11493 case OPC_RECIP1_PS
:
11496 TCGv_i64 fp0
= tcg_temp_new_i64();
11498 gen_load_fpr64(ctx
, fp0
, fs
);
11499 gen_helper_float_recip1_ps(fp0
, cpu_env
, fp0
);
11500 gen_store_fpr64(ctx
, fp0
, fd
);
11501 tcg_temp_free_i64(fp0
);
11504 case OPC_RSQRT1_PS
:
11507 TCGv_i64 fp0
= tcg_temp_new_i64();
11509 gen_load_fpr64(ctx
, fp0
, fs
);
11510 gen_helper_float_rsqrt1_ps(fp0
, cpu_env
, fp0
);
11511 gen_store_fpr64(ctx
, fp0
, fd
);
11512 tcg_temp_free_i64(fp0
);
11515 case OPC_RSQRT2_PS
:
11518 TCGv_i64 fp0
= tcg_temp_new_i64();
11519 TCGv_i64 fp1
= tcg_temp_new_i64();
11521 gen_load_fpr64(ctx
, fp0
, fs
);
11522 gen_load_fpr64(ctx
, fp1
, ft
);
11523 gen_helper_float_rsqrt2_ps(fp0
, cpu_env
, fp0
, fp1
);
11524 tcg_temp_free_i64(fp1
);
11525 gen_store_fpr64(ctx
, fp0
, fd
);
11526 tcg_temp_free_i64(fp0
);
11530 check_cp1_64bitmode(ctx
);
11532 TCGv_i32 fp0
= tcg_temp_new_i32();
11534 gen_load_fpr32h(ctx
, fp0
, fs
);
11535 gen_helper_float_cvts_pu(fp0
, cpu_env
, fp0
);
11536 gen_store_fpr32(ctx
, fp0
, fd
);
11537 tcg_temp_free_i32(fp0
);
11540 case OPC_CVT_PW_PS
:
11543 TCGv_i64 fp0
= tcg_temp_new_i64();
11545 gen_load_fpr64(ctx
, fp0
, fs
);
11546 gen_helper_float_cvtpw_ps(fp0
, cpu_env
, fp0
);
11547 gen_store_fpr64(ctx
, fp0
, fd
);
11548 tcg_temp_free_i64(fp0
);
11552 check_cp1_64bitmode(ctx
);
11554 TCGv_i32 fp0
= tcg_temp_new_i32();
11556 gen_load_fpr32(ctx
, fp0
, fs
);
11557 gen_helper_float_cvts_pl(fp0
, cpu_env
, fp0
);
11558 gen_store_fpr32(ctx
, fp0
, fd
);
11559 tcg_temp_free_i32(fp0
);
11565 TCGv_i32 fp0
= tcg_temp_new_i32();
11566 TCGv_i32 fp1
= tcg_temp_new_i32();
11568 gen_load_fpr32(ctx
, fp0
, fs
);
11569 gen_load_fpr32(ctx
, fp1
, ft
);
11570 gen_store_fpr32h(ctx
, fp0
, fd
);
11571 gen_store_fpr32(ctx
, fp1
, fd
);
11572 tcg_temp_free_i32(fp0
);
11573 tcg_temp_free_i32(fp1
);
11579 TCGv_i32 fp0
= tcg_temp_new_i32();
11580 TCGv_i32 fp1
= tcg_temp_new_i32();
11582 gen_load_fpr32(ctx
, fp0
, fs
);
11583 gen_load_fpr32h(ctx
, fp1
, ft
);
11584 gen_store_fpr32(ctx
, fp1
, fd
);
11585 gen_store_fpr32h(ctx
, fp0
, fd
);
11586 tcg_temp_free_i32(fp0
);
11587 tcg_temp_free_i32(fp1
);
11593 TCGv_i32 fp0
= tcg_temp_new_i32();
11594 TCGv_i32 fp1
= tcg_temp_new_i32();
11596 gen_load_fpr32h(ctx
, fp0
, fs
);
11597 gen_load_fpr32(ctx
, fp1
, ft
);
11598 gen_store_fpr32(ctx
, fp1
, fd
);
11599 gen_store_fpr32h(ctx
, fp0
, fd
);
11600 tcg_temp_free_i32(fp0
);
11601 tcg_temp_free_i32(fp1
);
11607 TCGv_i32 fp0
= tcg_temp_new_i32();
11608 TCGv_i32 fp1
= tcg_temp_new_i32();
11610 gen_load_fpr32h(ctx
, fp0
, fs
);
11611 gen_load_fpr32h(ctx
, fp1
, ft
);
11612 gen_store_fpr32(ctx
, fp1
, fd
);
11613 gen_store_fpr32h(ctx
, fp0
, fd
);
11614 tcg_temp_free_i32(fp0
);
11615 tcg_temp_free_i32(fp1
);
11619 case OPC_CMP_UN_PS
:
11620 case OPC_CMP_EQ_PS
:
11621 case OPC_CMP_UEQ_PS
:
11622 case OPC_CMP_OLT_PS
:
11623 case OPC_CMP_ULT_PS
:
11624 case OPC_CMP_OLE_PS
:
11625 case OPC_CMP_ULE_PS
:
11626 case OPC_CMP_SF_PS
:
11627 case OPC_CMP_NGLE_PS
:
11628 case OPC_CMP_SEQ_PS
:
11629 case OPC_CMP_NGL_PS
:
11630 case OPC_CMP_LT_PS
:
11631 case OPC_CMP_NGE_PS
:
11632 case OPC_CMP_LE_PS
:
11633 case OPC_CMP_NGT_PS
:
11634 if (ctx
->opcode
& (1 << 6)) {
11635 gen_cmpabs_ps(ctx
, func
- 48, ft
, fs
, cc
);
11637 gen_cmp_ps(ctx
, func
- 48, ft
, fs
, cc
);
11641 MIPS_INVAL("farith");
11642 gen_reserved_instruction(ctx
);
11647 /* Coprocessor 3 (FPU) */
11648 static void gen_flt3_ldst(DisasContext
*ctx
, uint32_t opc
,
11649 int fd
, int fs
, int base
, int index
)
11651 TCGv t0
= tcg_temp_new();
11654 gen_load_gpr(t0
, index
);
11655 } else if (index
== 0) {
11656 gen_load_gpr(t0
, base
);
11658 gen_op_addr_add(ctx
, t0
, cpu_gpr
[base
], cpu_gpr
[index
]);
11661 * Don't do NOP if destination is zero: we must perform the actual
11668 TCGv_i32 fp0
= tcg_temp_new_i32();
11670 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESL
);
11671 tcg_gen_trunc_tl_i32(fp0
, t0
);
11672 gen_store_fpr32(ctx
, fp0
, fd
);
11673 tcg_temp_free_i32(fp0
);
11678 check_cp1_registers(ctx
, fd
);
11680 TCGv_i64 fp0
= tcg_temp_new_i64();
11681 tcg_gen_qemu_ld_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
11682 gen_store_fpr64(ctx
, fp0
, fd
);
11683 tcg_temp_free_i64(fp0
);
11687 check_cp1_64bitmode(ctx
);
11688 tcg_gen_andi_tl(t0
, t0
, ~0x7);
11690 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
);
11700 TCGv_i32 fp0
= tcg_temp_new_i32();
11701 gen_load_fpr32(ctx
, fp0
, fs
);
11702 tcg_gen_qemu_st_i32(fp0
, t0
, ctx
->mem_idx
, MO_TEUL
);
11703 tcg_temp_free_i32(fp0
);
11708 check_cp1_registers(ctx
, fs
);
11710 TCGv_i64 fp0
= tcg_temp_new_i64();
11711 gen_load_fpr64(ctx
, fp0
, fs
);
11712 tcg_gen_qemu_st_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
11713 tcg_temp_free_i64(fp0
);
11717 check_cp1_64bitmode(ctx
);
11718 tcg_gen_andi_tl(t0
, t0
, ~0x7);
11720 TCGv_i64 fp0
= tcg_temp_new_i64();
11721 gen_load_fpr64(ctx
, fp0
, fs
);
11722 tcg_gen_qemu_st_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
11723 tcg_temp_free_i64(fp0
);
11730 static void gen_flt3_arith(DisasContext
*ctx
, uint32_t opc
,
11731 int fd
, int fr
, int fs
, int ft
)
11737 TCGv t0
= tcg_temp_local_new();
11738 TCGv_i32 fp
= tcg_temp_new_i32();
11739 TCGv_i32 fph
= tcg_temp_new_i32();
11740 TCGLabel
*l1
= gen_new_label();
11741 TCGLabel
*l2
= gen_new_label();
11743 gen_load_gpr(t0
, fr
);
11744 tcg_gen_andi_tl(t0
, t0
, 0x7);
11746 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, 0, l1
);
11747 gen_load_fpr32(ctx
, fp
, fs
);
11748 gen_load_fpr32h(ctx
, fph
, fs
);
11749 gen_store_fpr32(ctx
, fp
, fd
);
11750 gen_store_fpr32h(ctx
, fph
, fd
);
11753 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, 4, l2
);
11755 #ifdef TARGET_WORDS_BIGENDIAN
11756 gen_load_fpr32(ctx
, fp
, fs
);
11757 gen_load_fpr32h(ctx
, fph
, ft
);
11758 gen_store_fpr32h(ctx
, fp
, fd
);
11759 gen_store_fpr32(ctx
, fph
, fd
);
11761 gen_load_fpr32h(ctx
, fph
, fs
);
11762 gen_load_fpr32(ctx
, fp
, ft
);
11763 gen_store_fpr32(ctx
, fph
, fd
);
11764 gen_store_fpr32h(ctx
, fp
, fd
);
11767 tcg_temp_free_i32(fp
);
11768 tcg_temp_free_i32(fph
);
11774 TCGv_i32 fp0
= tcg_temp_new_i32();
11775 TCGv_i32 fp1
= tcg_temp_new_i32();
11776 TCGv_i32 fp2
= tcg_temp_new_i32();
11778 gen_load_fpr32(ctx
, fp0
, fs
);
11779 gen_load_fpr32(ctx
, fp1
, ft
);
11780 gen_load_fpr32(ctx
, fp2
, fr
);
11781 gen_helper_float_madd_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
11782 tcg_temp_free_i32(fp0
);
11783 tcg_temp_free_i32(fp1
);
11784 gen_store_fpr32(ctx
, fp2
, fd
);
11785 tcg_temp_free_i32(fp2
);
11790 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
11792 TCGv_i64 fp0
= tcg_temp_new_i64();
11793 TCGv_i64 fp1
= tcg_temp_new_i64();
11794 TCGv_i64 fp2
= tcg_temp_new_i64();
11796 gen_load_fpr64(ctx
, fp0
, fs
);
11797 gen_load_fpr64(ctx
, fp1
, ft
);
11798 gen_load_fpr64(ctx
, fp2
, fr
);
11799 gen_helper_float_madd_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
11800 tcg_temp_free_i64(fp0
);
11801 tcg_temp_free_i64(fp1
);
11802 gen_store_fpr64(ctx
, fp2
, fd
);
11803 tcg_temp_free_i64(fp2
);
11809 TCGv_i64 fp0
= tcg_temp_new_i64();
11810 TCGv_i64 fp1
= tcg_temp_new_i64();
11811 TCGv_i64 fp2
= tcg_temp_new_i64();
11813 gen_load_fpr64(ctx
, fp0
, fs
);
11814 gen_load_fpr64(ctx
, fp1
, ft
);
11815 gen_load_fpr64(ctx
, fp2
, fr
);
11816 gen_helper_float_madd_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
11817 tcg_temp_free_i64(fp0
);
11818 tcg_temp_free_i64(fp1
);
11819 gen_store_fpr64(ctx
, fp2
, fd
);
11820 tcg_temp_free_i64(fp2
);
11826 TCGv_i32 fp0
= tcg_temp_new_i32();
11827 TCGv_i32 fp1
= tcg_temp_new_i32();
11828 TCGv_i32 fp2
= tcg_temp_new_i32();
11830 gen_load_fpr32(ctx
, fp0
, fs
);
11831 gen_load_fpr32(ctx
, fp1
, ft
);
11832 gen_load_fpr32(ctx
, fp2
, fr
);
11833 gen_helper_float_msub_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
11834 tcg_temp_free_i32(fp0
);
11835 tcg_temp_free_i32(fp1
);
11836 gen_store_fpr32(ctx
, fp2
, fd
);
11837 tcg_temp_free_i32(fp2
);
11842 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
11844 TCGv_i64 fp0
= tcg_temp_new_i64();
11845 TCGv_i64 fp1
= tcg_temp_new_i64();
11846 TCGv_i64 fp2
= tcg_temp_new_i64();
11848 gen_load_fpr64(ctx
, fp0
, fs
);
11849 gen_load_fpr64(ctx
, fp1
, ft
);
11850 gen_load_fpr64(ctx
, fp2
, fr
);
11851 gen_helper_float_msub_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
11852 tcg_temp_free_i64(fp0
);
11853 tcg_temp_free_i64(fp1
);
11854 gen_store_fpr64(ctx
, fp2
, fd
);
11855 tcg_temp_free_i64(fp2
);
11861 TCGv_i64 fp0
= tcg_temp_new_i64();
11862 TCGv_i64 fp1
= tcg_temp_new_i64();
11863 TCGv_i64 fp2
= tcg_temp_new_i64();
11865 gen_load_fpr64(ctx
, fp0
, fs
);
11866 gen_load_fpr64(ctx
, fp1
, ft
);
11867 gen_load_fpr64(ctx
, fp2
, fr
);
11868 gen_helper_float_msub_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
11869 tcg_temp_free_i64(fp0
);
11870 tcg_temp_free_i64(fp1
);
11871 gen_store_fpr64(ctx
, fp2
, fd
);
11872 tcg_temp_free_i64(fp2
);
11878 TCGv_i32 fp0
= tcg_temp_new_i32();
11879 TCGv_i32 fp1
= tcg_temp_new_i32();
11880 TCGv_i32 fp2
= tcg_temp_new_i32();
11882 gen_load_fpr32(ctx
, fp0
, fs
);
11883 gen_load_fpr32(ctx
, fp1
, ft
);
11884 gen_load_fpr32(ctx
, fp2
, fr
);
11885 gen_helper_float_nmadd_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
11886 tcg_temp_free_i32(fp0
);
11887 tcg_temp_free_i32(fp1
);
11888 gen_store_fpr32(ctx
, fp2
, fd
);
11889 tcg_temp_free_i32(fp2
);
11894 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
11896 TCGv_i64 fp0
= tcg_temp_new_i64();
11897 TCGv_i64 fp1
= tcg_temp_new_i64();
11898 TCGv_i64 fp2
= tcg_temp_new_i64();
11900 gen_load_fpr64(ctx
, fp0
, fs
);
11901 gen_load_fpr64(ctx
, fp1
, ft
);
11902 gen_load_fpr64(ctx
, fp2
, fr
);
11903 gen_helper_float_nmadd_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
11904 tcg_temp_free_i64(fp0
);
11905 tcg_temp_free_i64(fp1
);
11906 gen_store_fpr64(ctx
, fp2
, fd
);
11907 tcg_temp_free_i64(fp2
);
11913 TCGv_i64 fp0
= tcg_temp_new_i64();
11914 TCGv_i64 fp1
= tcg_temp_new_i64();
11915 TCGv_i64 fp2
= tcg_temp_new_i64();
11917 gen_load_fpr64(ctx
, fp0
, fs
);
11918 gen_load_fpr64(ctx
, fp1
, ft
);
11919 gen_load_fpr64(ctx
, fp2
, fr
);
11920 gen_helper_float_nmadd_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
11921 tcg_temp_free_i64(fp0
);
11922 tcg_temp_free_i64(fp1
);
11923 gen_store_fpr64(ctx
, fp2
, fd
);
11924 tcg_temp_free_i64(fp2
);
11930 TCGv_i32 fp0
= tcg_temp_new_i32();
11931 TCGv_i32 fp1
= tcg_temp_new_i32();
11932 TCGv_i32 fp2
= tcg_temp_new_i32();
11934 gen_load_fpr32(ctx
, fp0
, fs
);
11935 gen_load_fpr32(ctx
, fp1
, ft
);
11936 gen_load_fpr32(ctx
, fp2
, fr
);
11937 gen_helper_float_nmsub_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
11938 tcg_temp_free_i32(fp0
);
11939 tcg_temp_free_i32(fp1
);
11940 gen_store_fpr32(ctx
, fp2
, fd
);
11941 tcg_temp_free_i32(fp2
);
11946 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
11948 TCGv_i64 fp0
= tcg_temp_new_i64();
11949 TCGv_i64 fp1
= tcg_temp_new_i64();
11950 TCGv_i64 fp2
= tcg_temp_new_i64();
11952 gen_load_fpr64(ctx
, fp0
, fs
);
11953 gen_load_fpr64(ctx
, fp1
, ft
);
11954 gen_load_fpr64(ctx
, fp2
, fr
);
11955 gen_helper_float_nmsub_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
11956 tcg_temp_free_i64(fp0
);
11957 tcg_temp_free_i64(fp1
);
11958 gen_store_fpr64(ctx
, fp2
, fd
);
11959 tcg_temp_free_i64(fp2
);
11965 TCGv_i64 fp0
= tcg_temp_new_i64();
11966 TCGv_i64 fp1
= tcg_temp_new_i64();
11967 TCGv_i64 fp2
= tcg_temp_new_i64();
11969 gen_load_fpr64(ctx
, fp0
, fs
);
11970 gen_load_fpr64(ctx
, fp1
, ft
);
11971 gen_load_fpr64(ctx
, fp2
, fr
);
11972 gen_helper_float_nmsub_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
11973 tcg_temp_free_i64(fp0
);
11974 tcg_temp_free_i64(fp1
);
11975 gen_store_fpr64(ctx
, fp2
, fd
);
11976 tcg_temp_free_i64(fp2
);
11980 MIPS_INVAL("flt3_arith");
11981 gen_reserved_instruction(ctx
);
11986 void gen_rdhwr(DisasContext
*ctx
, int rt
, int rd
, int sel
)
11990 #if !defined(CONFIG_USER_ONLY)
11992 * The Linux kernel will emulate rdhwr if it's not supported natively.
11993 * Therefore only check the ISA in system mode.
11995 check_insn(ctx
, ISA_MIPS_R2
);
11997 t0
= tcg_temp_new();
12001 gen_helper_rdhwr_cpunum(t0
, cpu_env
);
12002 gen_store_gpr(t0
, rt
);
12005 gen_helper_rdhwr_synci_step(t0
, cpu_env
);
12006 gen_store_gpr(t0
, rt
);
12009 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
12012 gen_helper_rdhwr_cc(t0
, cpu_env
);
12013 gen_store_gpr(t0
, rt
);
12015 * Break the TB to be able to take timer interrupts immediately
12016 * after reading count. DISAS_STOP isn't sufficient, we need to ensure
12017 * we break completely out of translated code.
12019 gen_save_pc(ctx
->base
.pc_next
+ 4);
12020 ctx
->base
.is_jmp
= DISAS_EXIT
;
12023 gen_helper_rdhwr_ccres(t0
, cpu_env
);
12024 gen_store_gpr(t0
, rt
);
12027 check_insn(ctx
, ISA_MIPS_R6
);
12030 * Performance counter registers are not implemented other than
12031 * control register 0.
12033 generate_exception(ctx
, EXCP_RI
);
12035 gen_helper_rdhwr_performance(t0
, cpu_env
);
12036 gen_store_gpr(t0
, rt
);
12039 check_insn(ctx
, ISA_MIPS_R6
);
12040 gen_helper_rdhwr_xnp(t0
, cpu_env
);
12041 gen_store_gpr(t0
, rt
);
12044 #if defined(CONFIG_USER_ONLY)
12045 tcg_gen_ld_tl(t0
, cpu_env
,
12046 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
12047 gen_store_gpr(t0
, rt
);
12050 if ((ctx
->hflags
& MIPS_HFLAG_CP0
) ||
12051 (ctx
->hflags
& MIPS_HFLAG_HWRENA_ULR
)) {
12052 tcg_gen_ld_tl(t0
, cpu_env
,
12053 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
12054 gen_store_gpr(t0
, rt
);
12056 gen_reserved_instruction(ctx
);
12060 default: /* Invalid */
12061 MIPS_INVAL("rdhwr");
12062 gen_reserved_instruction(ctx
);
12068 static inline void clear_branch_hflags(DisasContext
*ctx
)
12070 ctx
->hflags
&= ~MIPS_HFLAG_BMASK
;
12071 if (ctx
->base
.is_jmp
== DISAS_NEXT
) {
12072 save_cpu_state(ctx
, 0);
12075 * It is not safe to save ctx->hflags as hflags may be changed
12076 * in execution time by the instruction in delay / forbidden slot.
12078 tcg_gen_andi_i32(hflags
, hflags
, ~MIPS_HFLAG_BMASK
);
12082 static void gen_branch(DisasContext
*ctx
, int insn_bytes
)
12084 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
12085 int proc_hflags
= ctx
->hflags
& MIPS_HFLAG_BMASK
;
12086 /* Branches completion */
12087 clear_branch_hflags(ctx
);
12088 ctx
->base
.is_jmp
= DISAS_NORETURN
;
12089 /* FIXME: Need to clear can_do_io. */
12090 switch (proc_hflags
& MIPS_HFLAG_BMASK_BASE
) {
12091 case MIPS_HFLAG_FBNSLOT
:
12092 gen_goto_tb(ctx
, 0, ctx
->base
.pc_next
+ insn_bytes
);
12095 /* unconditional branch */
12096 if (proc_hflags
& MIPS_HFLAG_BX
) {
12097 tcg_gen_xori_i32(hflags
, hflags
, MIPS_HFLAG_M16
);
12099 gen_goto_tb(ctx
, 0, ctx
->btarget
);
12101 case MIPS_HFLAG_BL
:
12102 /* blikely taken case */
12103 gen_goto_tb(ctx
, 0, ctx
->btarget
);
12105 case MIPS_HFLAG_BC
:
12106 /* Conditional branch */
12108 TCGLabel
*l1
= gen_new_label();
12110 tcg_gen_brcondi_tl(TCG_COND_NE
, bcond
, 0, l1
);
12111 gen_goto_tb(ctx
, 1, ctx
->base
.pc_next
+ insn_bytes
);
12113 gen_goto_tb(ctx
, 0, ctx
->btarget
);
12116 case MIPS_HFLAG_BR
:
12117 /* unconditional branch to register */
12118 if (ctx
->insn_flags
& (ASE_MIPS16
| ASE_MICROMIPS
)) {
12119 TCGv t0
= tcg_temp_new();
12120 TCGv_i32 t1
= tcg_temp_new_i32();
12122 tcg_gen_andi_tl(t0
, btarget
, 0x1);
12123 tcg_gen_trunc_tl_i32(t1
, t0
);
12125 tcg_gen_andi_i32(hflags
, hflags
, ~(uint32_t)MIPS_HFLAG_M16
);
12126 tcg_gen_shli_i32(t1
, t1
, MIPS_HFLAG_M16_SHIFT
);
12127 tcg_gen_or_i32(hflags
, hflags
, t1
);
12128 tcg_temp_free_i32(t1
);
12130 tcg_gen_andi_tl(cpu_PC
, btarget
, ~(target_ulong
)0x1);
12132 tcg_gen_mov_tl(cpu_PC
, btarget
);
12134 if (ctx
->base
.singlestep_enabled
) {
12135 save_cpu_state(ctx
, 0);
12136 gen_helper_raise_exception_debug(cpu_env
);
12138 tcg_gen_lookup_and_goto_ptr();
12141 fprintf(stderr
, "unknown branch 0x%x\n", proc_hflags
);
12147 /* Compact Branches */
12148 static void gen_compute_compact_branch(DisasContext
*ctx
, uint32_t opc
,
12149 int rs
, int rt
, int32_t offset
)
12151 int bcond_compute
= 0;
12152 TCGv t0
= tcg_temp_new();
12153 TCGv t1
= tcg_temp_new();
12154 int m16_lowbit
= (ctx
->hflags
& MIPS_HFLAG_M16
) != 0;
12156 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
12157 #ifdef MIPS_DEBUG_DISAS
12158 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
12159 "\n", ctx
->base
.pc_next
);
12161 gen_reserved_instruction(ctx
);
12165 /* Load needed operands and calculate btarget */
12167 /* compact branch */
12168 case OPC_BOVC
: /* OPC_BEQZALC, OPC_BEQC */
12169 case OPC_BNVC
: /* OPC_BNEZALC, OPC_BNEC */
12170 gen_load_gpr(t0
, rs
);
12171 gen_load_gpr(t1
, rt
);
12173 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
12174 if (rs
<= rt
&& rs
== 0) {
12175 /* OPC_BEQZALC, OPC_BNEZALC */
12176 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 4 + m16_lowbit
);
12179 case OPC_BLEZC
: /* OPC_BGEZC, OPC_BGEC */
12180 case OPC_BGTZC
: /* OPC_BLTZC, OPC_BLTC */
12181 gen_load_gpr(t0
, rs
);
12182 gen_load_gpr(t1
, rt
);
12184 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
12186 case OPC_BLEZALC
: /* OPC_BGEZALC, OPC_BGEUC */
12187 case OPC_BGTZALC
: /* OPC_BLTZALC, OPC_BLTUC */
12188 if (rs
== 0 || rs
== rt
) {
12189 /* OPC_BLEZALC, OPC_BGEZALC */
12190 /* OPC_BGTZALC, OPC_BLTZALC */
12191 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 4 + m16_lowbit
);
12193 gen_load_gpr(t0
, rs
);
12194 gen_load_gpr(t1
, rt
);
12196 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
12200 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
12205 /* OPC_BEQZC, OPC_BNEZC */
12206 gen_load_gpr(t0
, rs
);
12208 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
12210 /* OPC_JIC, OPC_JIALC */
12211 TCGv tbase
= tcg_temp_new();
12212 TCGv toffset
= tcg_temp_new();
12214 gen_load_gpr(tbase
, rt
);
12215 tcg_gen_movi_tl(toffset
, offset
);
12216 gen_op_addr_add(ctx
, btarget
, tbase
, toffset
);
12217 tcg_temp_free(tbase
);
12218 tcg_temp_free(toffset
);
12222 MIPS_INVAL("Compact branch/jump");
12223 gen_reserved_instruction(ctx
);
12227 if (bcond_compute
== 0) {
12228 /* Uncoditional compact branch */
12231 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 4 + m16_lowbit
);
12234 ctx
->hflags
|= MIPS_HFLAG_BR
;
12237 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 4 + m16_lowbit
);
12240 ctx
->hflags
|= MIPS_HFLAG_B
;
12243 MIPS_INVAL("Compact branch/jump");
12244 gen_reserved_instruction(ctx
);
12248 /* Generating branch here as compact branches don't have delay slot */
12249 gen_branch(ctx
, 4);
12251 /* Conditional compact branch */
12252 TCGLabel
*fs
= gen_new_label();
12253 save_cpu_state(ctx
, 0);
12256 case OPC_BLEZALC
: /* OPC_BGEZALC, OPC_BGEUC */
12257 if (rs
== 0 && rt
!= 0) {
12259 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE
), t1
, 0, fs
);
12260 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
12262 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE
), t1
, 0, fs
);
12265 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU
), t0
, t1
, fs
);
12268 case OPC_BGTZALC
: /* OPC_BLTZALC, OPC_BLTUC */
12269 if (rs
== 0 && rt
!= 0) {
12271 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT
), t1
, 0, fs
);
12272 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
12274 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT
), t1
, 0, fs
);
12277 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU
), t0
, t1
, fs
);
12280 case OPC_BLEZC
: /* OPC_BGEZC, OPC_BGEC */
12281 if (rs
== 0 && rt
!= 0) {
12283 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE
), t1
, 0, fs
);
12284 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
12286 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE
), t1
, 0, fs
);
12289 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE
), t0
, t1
, fs
);
12292 case OPC_BGTZC
: /* OPC_BLTZC, OPC_BLTC */
12293 if (rs
== 0 && rt
!= 0) {
12295 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT
), t1
, 0, fs
);
12296 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
12298 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT
), t1
, 0, fs
);
12301 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT
), t0
, t1
, fs
);
12304 case OPC_BOVC
: /* OPC_BEQZALC, OPC_BEQC */
12305 case OPC_BNVC
: /* OPC_BNEZALC, OPC_BNEC */
12307 /* OPC_BOVC, OPC_BNVC */
12308 TCGv t2
= tcg_temp_new();
12309 TCGv t3
= tcg_temp_new();
12310 TCGv t4
= tcg_temp_new();
12311 TCGv input_overflow
= tcg_temp_new();
12313 gen_load_gpr(t0
, rs
);
12314 gen_load_gpr(t1
, rt
);
12315 tcg_gen_ext32s_tl(t2
, t0
);
12316 tcg_gen_setcond_tl(TCG_COND_NE
, input_overflow
, t2
, t0
);
12317 tcg_gen_ext32s_tl(t3
, t1
);
12318 tcg_gen_setcond_tl(TCG_COND_NE
, t4
, t3
, t1
);
12319 tcg_gen_or_tl(input_overflow
, input_overflow
, t4
);
12321 tcg_gen_add_tl(t4
, t2
, t3
);
12322 tcg_gen_ext32s_tl(t4
, t4
);
12323 tcg_gen_xor_tl(t2
, t2
, t3
);
12324 tcg_gen_xor_tl(t3
, t4
, t3
);
12325 tcg_gen_andc_tl(t2
, t3
, t2
);
12326 tcg_gen_setcondi_tl(TCG_COND_LT
, t4
, t2
, 0);
12327 tcg_gen_or_tl(t4
, t4
, input_overflow
);
12328 if (opc
== OPC_BOVC
) {
12330 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE
), t4
, 0, fs
);
12333 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ
), t4
, 0, fs
);
12335 tcg_temp_free(input_overflow
);
12339 } else if (rs
< rt
&& rs
== 0) {
12340 /* OPC_BEQZALC, OPC_BNEZALC */
12341 if (opc
== OPC_BEQZALC
) {
12343 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ
), t1
, 0, fs
);
12346 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE
), t1
, 0, fs
);
12349 /* OPC_BEQC, OPC_BNEC */
12350 if (opc
== OPC_BEQC
) {
12352 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ
), t0
, t1
, fs
);
12355 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE
), t0
, t1
, fs
);
12360 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ
), t0
, 0, fs
);
12363 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE
), t0
, 0, fs
);
12366 MIPS_INVAL("Compact conditional branch/jump");
12367 gen_reserved_instruction(ctx
);
12371 /* Generating branch here as compact branches don't have delay slot */
12372 gen_goto_tb(ctx
, 1, ctx
->btarget
);
12375 ctx
->hflags
|= MIPS_HFLAG_FBNSLOT
;
12383 /* ISA extensions (ASEs) */
12384 /* MIPS16 extension to MIPS32 */
12386 /* MIPS16 major opcodes */
12388 M16_OPC_ADDIUSP
= 0x00,
12389 M16_OPC_ADDIUPC
= 0x01,
12391 M16_OPC_JAL
= 0x03,
12392 M16_OPC_BEQZ
= 0x04,
12393 M16_OPC_BNEQZ
= 0x05,
12394 M16_OPC_SHIFT
= 0x06,
12396 M16_OPC_RRIA
= 0x08,
12397 M16_OPC_ADDIU8
= 0x09,
12398 M16_OPC_SLTI
= 0x0a,
12399 M16_OPC_SLTIU
= 0x0b,
12402 M16_OPC_CMPI
= 0x0e,
12406 M16_OPC_LWSP
= 0x12,
12408 M16_OPC_LBU
= 0x14,
12409 M16_OPC_LHU
= 0x15,
12410 M16_OPC_LWPC
= 0x16,
12411 M16_OPC_LWU
= 0x17,
12414 M16_OPC_SWSP
= 0x1a,
12416 M16_OPC_RRR
= 0x1c,
12418 M16_OPC_EXTEND
= 0x1e,
12422 /* I8 funct field */
12441 /* RR funct field */
12475 /* I64 funct field */
12483 I64_DADDIUPC
= 0x6,
12487 /* RR ry field for CNVT */
12489 RR_RY_CNVT_ZEB
= 0x0,
12490 RR_RY_CNVT_ZEH
= 0x1,
12491 RR_RY_CNVT_ZEW
= 0x2,
12492 RR_RY_CNVT_SEB
= 0x4,
12493 RR_RY_CNVT_SEH
= 0x5,
12494 RR_RY_CNVT_SEW
= 0x6,
12497 static int xlat(int r
)
12499 static int map
[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
12504 static void gen_mips16_save(DisasContext
*ctx
,
12505 int xsregs
, int aregs
,
12506 int do_ra
, int do_s0
, int do_s1
,
12509 TCGv t0
= tcg_temp_new();
12510 TCGv t1
= tcg_temp_new();
12511 TCGv t2
= tcg_temp_new();
12541 gen_reserved_instruction(ctx
);
12547 gen_base_offset_addr(ctx
, t0
, 29, 12);
12548 gen_load_gpr(t1
, 7);
12549 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
12552 gen_base_offset_addr(ctx
, t0
, 29, 8);
12553 gen_load_gpr(t1
, 6);
12554 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
12557 gen_base_offset_addr(ctx
, t0
, 29, 4);
12558 gen_load_gpr(t1
, 5);
12559 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
12562 gen_base_offset_addr(ctx
, t0
, 29, 0);
12563 gen_load_gpr(t1
, 4);
12564 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
12567 gen_load_gpr(t0
, 29);
12569 #define DECR_AND_STORE(reg) do { \
12570 tcg_gen_movi_tl(t2, -4); \
12571 gen_op_addr_add(ctx, t0, t0, t2); \
12572 gen_load_gpr(t1, reg); \
12573 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \
12577 DECR_AND_STORE(31);
12582 DECR_AND_STORE(30);
12585 DECR_AND_STORE(23);
12588 DECR_AND_STORE(22);
12591 DECR_AND_STORE(21);
12594 DECR_AND_STORE(20);
12597 DECR_AND_STORE(19);
12600 DECR_AND_STORE(18);
12604 DECR_AND_STORE(17);
12607 DECR_AND_STORE(16);
12637 gen_reserved_instruction(ctx
);
12653 #undef DECR_AND_STORE
12655 tcg_gen_movi_tl(t2
, -framesize
);
12656 gen_op_addr_add(ctx
, cpu_gpr
[29], cpu_gpr
[29], t2
);
12662 static void gen_mips16_restore(DisasContext
*ctx
,
12663 int xsregs
, int aregs
,
12664 int do_ra
, int do_s0
, int do_s1
,
12668 TCGv t0
= tcg_temp_new();
12669 TCGv t1
= tcg_temp_new();
12670 TCGv t2
= tcg_temp_new();
12672 tcg_gen_movi_tl(t2
, framesize
);
12673 gen_op_addr_add(ctx
, t0
, cpu_gpr
[29], t2
);
12675 #define DECR_AND_LOAD(reg) do { \
12676 tcg_gen_movi_tl(t2, -4); \
12677 gen_op_addr_add(ctx, t0, t0, t2); \
12678 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \
12679 gen_store_gpr(t1, reg); \
12743 gen_reserved_instruction(ctx
);
12759 #undef DECR_AND_LOAD
12761 tcg_gen_movi_tl(t2
, framesize
);
12762 gen_op_addr_add(ctx
, cpu_gpr
[29], cpu_gpr
[29], t2
);
12768 static void gen_addiupc(DisasContext
*ctx
, int rx
, int imm
,
12769 int is_64_bit
, int extended
)
12773 if (extended
&& (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
12774 gen_reserved_instruction(ctx
);
12778 t0
= tcg_temp_new();
12780 tcg_gen_movi_tl(t0
, pc_relative_pc(ctx
));
12781 tcg_gen_addi_tl(cpu_gpr
[rx
], t0
, imm
);
12783 tcg_gen_ext32s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
12789 static void gen_cache_operation(DisasContext
*ctx
, uint32_t op
, int base
,
12792 TCGv_i32 t0
= tcg_const_i32(op
);
12793 TCGv t1
= tcg_temp_new();
12794 gen_base_offset_addr(ctx
, t1
, base
, offset
);
12795 gen_helper_cache(cpu_env
, t1
, t0
);
12797 tcg_temp_free_i32(t0
);
12800 #if defined(TARGET_MIPS64)
12801 static void decode_i64_mips16(DisasContext
*ctx
,
12802 int ry
, int funct
, int16_t offset
,
12807 check_insn(ctx
, ISA_MIPS3
);
12808 check_mips_64(ctx
);
12809 offset
= extended
? offset
: offset
<< 3;
12810 gen_ld(ctx
, OPC_LD
, ry
, 29, offset
);
12813 check_insn(ctx
, ISA_MIPS3
);
12814 check_mips_64(ctx
);
12815 offset
= extended
? offset
: offset
<< 3;
12816 gen_st(ctx
, OPC_SD
, ry
, 29, offset
);
12819 check_insn(ctx
, ISA_MIPS3
);
12820 check_mips_64(ctx
);
12821 offset
= extended
? offset
: (ctx
->opcode
& 0xff) << 3;
12822 gen_st(ctx
, OPC_SD
, 31, 29, offset
);
12825 check_insn(ctx
, ISA_MIPS3
);
12826 check_mips_64(ctx
);
12827 offset
= extended
? offset
: ((int8_t)ctx
->opcode
) << 3;
12828 gen_arith_imm(ctx
, OPC_DADDIU
, 29, 29, offset
);
12831 check_insn(ctx
, ISA_MIPS3
);
12832 check_mips_64(ctx
);
12833 if (extended
&& (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
12834 gen_reserved_instruction(ctx
);
12836 offset
= extended
? offset
: offset
<< 3;
12837 gen_ld(ctx
, OPC_LDPC
, ry
, 0, offset
);
12841 check_insn(ctx
, ISA_MIPS3
);
12842 check_mips_64(ctx
);
12843 offset
= extended
? offset
: ((int8_t)(offset
<< 3)) >> 3;
12844 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, ry
, offset
);
12847 check_insn(ctx
, ISA_MIPS3
);
12848 check_mips_64(ctx
);
12849 offset
= extended
? offset
: offset
<< 2;
12850 gen_addiupc(ctx
, ry
, offset
, 1, extended
);
12853 check_insn(ctx
, ISA_MIPS3
);
12854 check_mips_64(ctx
);
12855 offset
= extended
? offset
: offset
<< 2;
12856 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, 29, offset
);
12862 static int decode_extended_mips16_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
12864 int extend
= translator_lduw(env
, ctx
->base
.pc_next
+ 2);
12865 int op
, rx
, ry
, funct
, sa
;
12866 int16_t imm
, offset
;
12868 ctx
->opcode
= (ctx
->opcode
<< 16) | extend
;
12869 op
= (ctx
->opcode
>> 11) & 0x1f;
12870 sa
= (ctx
->opcode
>> 22) & 0x1f;
12871 funct
= (ctx
->opcode
>> 8) & 0x7;
12872 rx
= xlat((ctx
->opcode
>> 8) & 0x7);
12873 ry
= xlat((ctx
->opcode
>> 5) & 0x7);
12874 offset
= imm
= (int16_t) (((ctx
->opcode
>> 16) & 0x1f) << 11
12875 | ((ctx
->opcode
>> 21) & 0x3f) << 5
12876 | (ctx
->opcode
& 0x1f));
12879 * The extended opcodes cleverly reuse the opcodes from their 16-bit
12883 case M16_OPC_ADDIUSP
:
12884 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 29, imm
);
12886 case M16_OPC_ADDIUPC
:
12887 gen_addiupc(ctx
, rx
, imm
, 0, 1);
12890 gen_compute_branch(ctx
, OPC_BEQ
, 4, 0, 0, offset
<< 1, 0);
12891 /* No delay slot, so just process as a normal instruction */
12894 gen_compute_branch(ctx
, OPC_BEQ
, 4, rx
, 0, offset
<< 1, 0);
12895 /* No delay slot, so just process as a normal instruction */
12897 case M16_OPC_BNEQZ
:
12898 gen_compute_branch(ctx
, OPC_BNE
, 4, rx
, 0, offset
<< 1, 0);
12899 /* No delay slot, so just process as a normal instruction */
12901 case M16_OPC_SHIFT
:
12902 switch (ctx
->opcode
& 0x3) {
12904 gen_shift_imm(ctx
, OPC_SLL
, rx
, ry
, sa
);
12907 #if defined(TARGET_MIPS64)
12908 check_mips_64(ctx
);
12909 gen_shift_imm(ctx
, OPC_DSLL
, rx
, ry
, sa
);
12911 gen_reserved_instruction(ctx
);
12915 gen_shift_imm(ctx
, OPC_SRL
, rx
, ry
, sa
);
12918 gen_shift_imm(ctx
, OPC_SRA
, rx
, ry
, sa
);
12922 #if defined(TARGET_MIPS64)
12924 check_insn(ctx
, ISA_MIPS3
);
12925 check_mips_64(ctx
);
12926 gen_ld(ctx
, OPC_LD
, ry
, rx
, offset
);
12930 imm
= ctx
->opcode
& 0xf;
12931 imm
= imm
| ((ctx
->opcode
>> 20) & 0x7f) << 4;
12932 imm
= imm
| ((ctx
->opcode
>> 16) & 0xf) << 11;
12933 imm
= (int16_t) (imm
<< 1) >> 1;
12934 if ((ctx
->opcode
>> 4) & 0x1) {
12935 #if defined(TARGET_MIPS64)
12936 check_mips_64(ctx
);
12937 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, rx
, imm
);
12939 gen_reserved_instruction(ctx
);
12942 gen_arith_imm(ctx
, OPC_ADDIU
, ry
, rx
, imm
);
12945 case M16_OPC_ADDIU8
:
12946 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, rx
, imm
);
12949 gen_slt_imm(ctx
, OPC_SLTI
, 24, rx
, imm
);
12951 case M16_OPC_SLTIU
:
12952 gen_slt_imm(ctx
, OPC_SLTIU
, 24, rx
, imm
);
12957 gen_compute_branch(ctx
, OPC_BEQ
, 4, 24, 0, offset
<< 1, 0);
12960 gen_compute_branch(ctx
, OPC_BNE
, 4, 24, 0, offset
<< 1, 0);
12963 gen_st(ctx
, OPC_SW
, 31, 29, imm
);
12966 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, imm
);
12969 check_insn(ctx
, ISA_MIPS_R1
);
12971 int xsregs
= (ctx
->opcode
>> 24) & 0x7;
12972 int aregs
= (ctx
->opcode
>> 16) & 0xf;
12973 int do_ra
= (ctx
->opcode
>> 6) & 0x1;
12974 int do_s0
= (ctx
->opcode
>> 5) & 0x1;
12975 int do_s1
= (ctx
->opcode
>> 4) & 0x1;
12976 int framesize
= (((ctx
->opcode
>> 20) & 0xf) << 4
12977 | (ctx
->opcode
& 0xf)) << 3;
12979 if (ctx
->opcode
& (1 << 7)) {
12980 gen_mips16_save(ctx
, xsregs
, aregs
,
12981 do_ra
, do_s0
, do_s1
,
12984 gen_mips16_restore(ctx
, xsregs
, aregs
,
12985 do_ra
, do_s0
, do_s1
,
12991 gen_reserved_instruction(ctx
);
12996 tcg_gen_movi_tl(cpu_gpr
[rx
], (uint16_t) imm
);
12999 tcg_gen_xori_tl(cpu_gpr
[24], cpu_gpr
[rx
], (uint16_t) imm
);
13001 #if defined(TARGET_MIPS64)
13003 check_insn(ctx
, ISA_MIPS3
);
13004 check_mips_64(ctx
);
13005 gen_st(ctx
, OPC_SD
, ry
, rx
, offset
);
13009 gen_ld(ctx
, OPC_LB
, ry
, rx
, offset
);
13012 gen_ld(ctx
, OPC_LH
, ry
, rx
, offset
);
13015 gen_ld(ctx
, OPC_LW
, rx
, 29, offset
);
13018 gen_ld(ctx
, OPC_LW
, ry
, rx
, offset
);
13021 gen_ld(ctx
, OPC_LBU
, ry
, rx
, offset
);
13024 gen_ld(ctx
, OPC_LHU
, ry
, rx
, offset
);
13027 gen_ld(ctx
, OPC_LWPC
, rx
, 0, offset
);
13029 #if defined(TARGET_MIPS64)
13031 check_insn(ctx
, ISA_MIPS3
);
13032 check_mips_64(ctx
);
13033 gen_ld(ctx
, OPC_LWU
, ry
, rx
, offset
);
13037 gen_st(ctx
, OPC_SB
, ry
, rx
, offset
);
13040 gen_st(ctx
, OPC_SH
, ry
, rx
, offset
);
13043 gen_st(ctx
, OPC_SW
, rx
, 29, offset
);
13046 gen_st(ctx
, OPC_SW
, ry
, rx
, offset
);
13048 #if defined(TARGET_MIPS64)
13050 decode_i64_mips16(ctx
, ry
, funct
, offset
, 1);
13054 gen_reserved_instruction(ctx
);
13061 static inline bool is_uhi(int sdbbp_code
)
13063 #ifdef CONFIG_USER_ONLY
13066 return semihosting_enabled() && sdbbp_code
== 1;
13070 #ifdef CONFIG_USER_ONLY
13071 /* The above should dead-code away any calls to this..*/
13072 static inline void gen_helper_do_semihosting(void *env
)
13074 g_assert_not_reached();
13078 static int decode_mips16_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
13082 int op
, cnvt_op
, op1
, offset
;
13086 op
= (ctx
->opcode
>> 11) & 0x1f;
13087 sa
= (ctx
->opcode
>> 2) & 0x7;
13088 sa
= sa
== 0 ? 8 : sa
;
13089 rx
= xlat((ctx
->opcode
>> 8) & 0x7);
13090 cnvt_op
= (ctx
->opcode
>> 5) & 0x7;
13091 ry
= xlat((ctx
->opcode
>> 5) & 0x7);
13092 op1
= offset
= ctx
->opcode
& 0x1f;
13097 case M16_OPC_ADDIUSP
:
13099 int16_t imm
= ((uint8_t) ctx
->opcode
) << 2;
13101 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 29, imm
);
13104 case M16_OPC_ADDIUPC
:
13105 gen_addiupc(ctx
, rx
, ((uint8_t) ctx
->opcode
) << 2, 0, 0);
13108 offset
= (ctx
->opcode
& 0x7ff) << 1;
13109 offset
= (int16_t)(offset
<< 4) >> 4;
13110 gen_compute_branch(ctx
, OPC_BEQ
, 2, 0, 0, offset
, 0);
13111 /* No delay slot, so just process as a normal instruction */
13114 offset
= translator_lduw(env
, ctx
->base
.pc_next
+ 2);
13115 offset
= (((ctx
->opcode
& 0x1f) << 21)
13116 | ((ctx
->opcode
>> 5) & 0x1f) << 16
13118 op
= ((ctx
->opcode
>> 10) & 0x1) ? OPC_JALX
: OPC_JAL
;
13119 gen_compute_branch(ctx
, op
, 4, rx
, ry
, offset
, 2);
13123 gen_compute_branch(ctx
, OPC_BEQ
, 2, rx
, 0,
13124 ((int8_t)ctx
->opcode
) << 1, 0);
13125 /* No delay slot, so just process as a normal instruction */
13127 case M16_OPC_BNEQZ
:
13128 gen_compute_branch(ctx
, OPC_BNE
, 2, rx
, 0,
13129 ((int8_t)ctx
->opcode
) << 1, 0);
13130 /* No delay slot, so just process as a normal instruction */
13132 case M16_OPC_SHIFT
:
13133 switch (ctx
->opcode
& 0x3) {
13135 gen_shift_imm(ctx
, OPC_SLL
, rx
, ry
, sa
);
13138 #if defined(TARGET_MIPS64)
13139 check_insn(ctx
, ISA_MIPS3
);
13140 check_mips_64(ctx
);
13141 gen_shift_imm(ctx
, OPC_DSLL
, rx
, ry
, sa
);
13143 gen_reserved_instruction(ctx
);
13147 gen_shift_imm(ctx
, OPC_SRL
, rx
, ry
, sa
);
13150 gen_shift_imm(ctx
, OPC_SRA
, rx
, ry
, sa
);
13154 #if defined(TARGET_MIPS64)
13156 check_insn(ctx
, ISA_MIPS3
);
13157 check_mips_64(ctx
);
13158 gen_ld(ctx
, OPC_LD
, ry
, rx
, offset
<< 3);
13163 int16_t imm
= (int8_t)((ctx
->opcode
& 0xf) << 4) >> 4;
13165 if ((ctx
->opcode
>> 4) & 1) {
13166 #if defined(TARGET_MIPS64)
13167 check_insn(ctx
, ISA_MIPS3
);
13168 check_mips_64(ctx
);
13169 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, rx
, imm
);
13171 gen_reserved_instruction(ctx
);
13174 gen_arith_imm(ctx
, OPC_ADDIU
, ry
, rx
, imm
);
13178 case M16_OPC_ADDIU8
:
13180 int16_t imm
= (int8_t) ctx
->opcode
;
13182 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, rx
, imm
);
13187 int16_t imm
= (uint8_t) ctx
->opcode
;
13188 gen_slt_imm(ctx
, OPC_SLTI
, 24, rx
, imm
);
13191 case M16_OPC_SLTIU
:
13193 int16_t imm
= (uint8_t) ctx
->opcode
;
13194 gen_slt_imm(ctx
, OPC_SLTIU
, 24, rx
, imm
);
13201 funct
= (ctx
->opcode
>> 8) & 0x7;
13204 gen_compute_branch(ctx
, OPC_BEQ
, 2, 24, 0,
13205 ((int8_t)ctx
->opcode
) << 1, 0);
13208 gen_compute_branch(ctx
, OPC_BNE
, 2, 24, 0,
13209 ((int8_t)ctx
->opcode
) << 1, 0);
13212 gen_st(ctx
, OPC_SW
, 31, 29, (ctx
->opcode
& 0xff) << 2);
13215 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29,
13216 ((int8_t)ctx
->opcode
) << 3);
13219 check_insn(ctx
, ISA_MIPS_R1
);
13221 int do_ra
= ctx
->opcode
& (1 << 6);
13222 int do_s0
= ctx
->opcode
& (1 << 5);
13223 int do_s1
= ctx
->opcode
& (1 << 4);
13224 int framesize
= ctx
->opcode
& 0xf;
13226 if (framesize
== 0) {
13229 framesize
= framesize
<< 3;
13232 if (ctx
->opcode
& (1 << 7)) {
13233 gen_mips16_save(ctx
, 0, 0,
13234 do_ra
, do_s0
, do_s1
, framesize
);
13236 gen_mips16_restore(ctx
, 0, 0,
13237 do_ra
, do_s0
, do_s1
, framesize
);
13243 int rz
= xlat(ctx
->opcode
& 0x7);
13245 reg32
= (((ctx
->opcode
>> 3) & 0x3) << 3) |
13246 ((ctx
->opcode
>> 5) & 0x7);
13247 gen_arith(ctx
, OPC_ADDU
, reg32
, rz
, 0);
13251 reg32
= ctx
->opcode
& 0x1f;
13252 gen_arith(ctx
, OPC_ADDU
, ry
, reg32
, 0);
13255 gen_reserved_instruction(ctx
);
13262 int16_t imm
= (uint8_t) ctx
->opcode
;
13264 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 0, imm
);
13269 int16_t imm
= (uint8_t) ctx
->opcode
;
13270 gen_logic_imm(ctx
, OPC_XORI
, 24, rx
, imm
);
13273 #if defined(TARGET_MIPS64)
13275 check_insn(ctx
, ISA_MIPS3
);
13276 check_mips_64(ctx
);
13277 gen_st(ctx
, OPC_SD
, ry
, rx
, offset
<< 3);
13281 gen_ld(ctx
, OPC_LB
, ry
, rx
, offset
);
13284 gen_ld(ctx
, OPC_LH
, ry
, rx
, offset
<< 1);
13287 gen_ld(ctx
, OPC_LW
, rx
, 29, ((uint8_t)ctx
->opcode
) << 2);
13290 gen_ld(ctx
, OPC_LW
, ry
, rx
, offset
<< 2);
13293 gen_ld(ctx
, OPC_LBU
, ry
, rx
, offset
);
13296 gen_ld(ctx
, OPC_LHU
, ry
, rx
, offset
<< 1);
13299 gen_ld(ctx
, OPC_LWPC
, rx
, 0, ((uint8_t)ctx
->opcode
) << 2);
13301 #if defined(TARGET_MIPS64)
13303 check_insn(ctx
, ISA_MIPS3
);
13304 check_mips_64(ctx
);
13305 gen_ld(ctx
, OPC_LWU
, ry
, rx
, offset
<< 2);
13309 gen_st(ctx
, OPC_SB
, ry
, rx
, offset
);
13312 gen_st(ctx
, OPC_SH
, ry
, rx
, offset
<< 1);
13315 gen_st(ctx
, OPC_SW
, rx
, 29, ((uint8_t)ctx
->opcode
) << 2);
13318 gen_st(ctx
, OPC_SW
, ry
, rx
, offset
<< 2);
13322 int rz
= xlat((ctx
->opcode
>> 2) & 0x7);
13325 switch (ctx
->opcode
& 0x3) {
13327 mips32_op
= OPC_ADDU
;
13330 mips32_op
= OPC_SUBU
;
13332 #if defined(TARGET_MIPS64)
13334 mips32_op
= OPC_DADDU
;
13335 check_insn(ctx
, ISA_MIPS3
);
13336 check_mips_64(ctx
);
13339 mips32_op
= OPC_DSUBU
;
13340 check_insn(ctx
, ISA_MIPS3
);
13341 check_mips_64(ctx
);
13345 gen_reserved_instruction(ctx
);
13349 gen_arith(ctx
, mips32_op
, rz
, rx
, ry
);
13358 int nd
= (ctx
->opcode
>> 7) & 0x1;
13359 int link
= (ctx
->opcode
>> 6) & 0x1;
13360 int ra
= (ctx
->opcode
>> 5) & 0x1;
13363 check_insn(ctx
, ISA_MIPS_R1
);
13372 gen_compute_branch(ctx
, op
, 2, ra
? 31 : rx
, 31, 0,
13377 if (is_uhi(extract32(ctx
->opcode
, 5, 6))) {
13378 gen_helper_do_semihosting(cpu_env
);
13381 * XXX: not clear which exception should be raised
13382 * when in debug mode...
13384 check_insn(ctx
, ISA_MIPS_R1
);
13385 generate_exception_end(ctx
, EXCP_DBp
);
13389 gen_slt(ctx
, OPC_SLT
, 24, rx
, ry
);
13392 gen_slt(ctx
, OPC_SLTU
, 24, rx
, ry
);
13395 generate_exception_end(ctx
, EXCP_BREAK
);
13398 gen_shift(ctx
, OPC_SLLV
, ry
, rx
, ry
);
13401 gen_shift(ctx
, OPC_SRLV
, ry
, rx
, ry
);
13404 gen_shift(ctx
, OPC_SRAV
, ry
, rx
, ry
);
13406 #if defined(TARGET_MIPS64)
13408 check_insn(ctx
, ISA_MIPS3
);
13409 check_mips_64(ctx
);
13410 gen_shift_imm(ctx
, OPC_DSRL
, ry
, ry
, sa
);
13414 gen_logic(ctx
, OPC_XOR
, 24, rx
, ry
);
13417 gen_arith(ctx
, OPC_SUBU
, rx
, 0, ry
);
13420 gen_logic(ctx
, OPC_AND
, rx
, rx
, ry
);
13423 gen_logic(ctx
, OPC_OR
, rx
, rx
, ry
);
13426 gen_logic(ctx
, OPC_XOR
, rx
, rx
, ry
);
13429 gen_logic(ctx
, OPC_NOR
, rx
, ry
, 0);
13432 gen_HILO(ctx
, OPC_MFHI
, 0, rx
);
13435 check_insn(ctx
, ISA_MIPS_R1
);
13437 case RR_RY_CNVT_ZEB
:
13438 tcg_gen_ext8u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
13440 case RR_RY_CNVT_ZEH
:
13441 tcg_gen_ext16u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
13443 case RR_RY_CNVT_SEB
:
13444 tcg_gen_ext8s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
13446 case RR_RY_CNVT_SEH
:
13447 tcg_gen_ext16s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
13449 #if defined(TARGET_MIPS64)
13450 case RR_RY_CNVT_ZEW
:
13451 check_insn(ctx
, ISA_MIPS_R1
);
13452 check_mips_64(ctx
);
13453 tcg_gen_ext32u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
13455 case RR_RY_CNVT_SEW
:
13456 check_insn(ctx
, ISA_MIPS_R1
);
13457 check_mips_64(ctx
);
13458 tcg_gen_ext32s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
13462 gen_reserved_instruction(ctx
);
13467 gen_HILO(ctx
, OPC_MFLO
, 0, rx
);
13469 #if defined(TARGET_MIPS64)
13471 check_insn(ctx
, ISA_MIPS3
);
13472 check_mips_64(ctx
);
13473 gen_shift_imm(ctx
, OPC_DSRA
, ry
, ry
, sa
);
13476 check_insn(ctx
, ISA_MIPS3
);
13477 check_mips_64(ctx
);
13478 gen_shift(ctx
, OPC_DSLLV
, ry
, rx
, ry
);
13481 check_insn(ctx
, ISA_MIPS3
);
13482 check_mips_64(ctx
);
13483 gen_shift(ctx
, OPC_DSRLV
, ry
, rx
, ry
);
13486 check_insn(ctx
, ISA_MIPS3
);
13487 check_mips_64(ctx
);
13488 gen_shift(ctx
, OPC_DSRAV
, ry
, rx
, ry
);
13492 gen_muldiv(ctx
, OPC_MULT
, 0, rx
, ry
);
13495 gen_muldiv(ctx
, OPC_MULTU
, 0, rx
, ry
);
13498 gen_muldiv(ctx
, OPC_DIV
, 0, rx
, ry
);
13501 gen_muldiv(ctx
, OPC_DIVU
, 0, rx
, ry
);
13503 #if defined(TARGET_MIPS64)
13505 check_insn(ctx
, ISA_MIPS3
);
13506 check_mips_64(ctx
);
13507 gen_muldiv(ctx
, OPC_DMULT
, 0, rx
, ry
);
13510 check_insn(ctx
, ISA_MIPS3
);
13511 check_mips_64(ctx
);
13512 gen_muldiv(ctx
, OPC_DMULTU
, 0, rx
, ry
);
13515 check_insn(ctx
, ISA_MIPS3
);
13516 check_mips_64(ctx
);
13517 gen_muldiv(ctx
, OPC_DDIV
, 0, rx
, ry
);
13520 check_insn(ctx
, ISA_MIPS3
);
13521 check_mips_64(ctx
);
13522 gen_muldiv(ctx
, OPC_DDIVU
, 0, rx
, ry
);
13526 gen_reserved_instruction(ctx
);
13530 case M16_OPC_EXTEND
:
13531 decode_extended_mips16_opc(env
, ctx
);
13534 #if defined(TARGET_MIPS64)
13536 funct
= (ctx
->opcode
>> 8) & 0x7;
13537 decode_i64_mips16(ctx
, ry
, funct
, offset
, 0);
13541 gen_reserved_instruction(ctx
);
13548 /* microMIPS extension to MIPS32/MIPS64 */
13551 * microMIPS32/microMIPS64 major opcodes
13553 * 1. MIPS Architecture for Programmers Volume II-B:
13554 * The microMIPS32 Instruction Set (Revision 3.05)
13556 * Table 6.2 microMIPS32 Encoding of Major Opcode Field
13558 * 2. MIPS Architecture For Programmers Volume II-A:
13559 * The MIPS64 Instruction Set (Revision 3.51)
13589 POOL32S
= 0x16, /* MIPS64 */
13590 DADDIU32
= 0x17, /* MIPS64 */
13619 /* 0x29 is reserved */
13632 /* 0x31 is reserved */
13645 SD32
= 0x36, /* MIPS64 */
13646 LD32
= 0x37, /* MIPS64 */
13648 /* 0x39 is reserved */
13664 /* PCREL Instructions perform PC-Relative address calculation. bits 20..16 */
13686 /* POOL32A encoding of minor opcode field */
13690 * These opcodes are distinguished only by bits 9..6; those bits are
13691 * what are recorded below.
13729 /* The following can be distinguished by their lower 6 bits. */
13739 /* POOL32AXF encoding of minor opcode field extension */
13742 * 1. MIPS Architecture for Programmers Volume II-B:
13743 * The microMIPS32 Instruction Set (Revision 3.05)
13745 * Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
13747 * 2. MIPS Architecture for Programmers VolumeIV-e:
13748 * The MIPS DSP Application-Specific Extension
13749 * to the microMIPS32 Architecture (Revision 2.34)
13751 * Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
13766 /* begin of microMIPS32 DSP */
13768 /* bits 13..12 for 0x01 */
13774 /* bits 13..12 for 0x2a */
13780 /* bits 13..12 for 0x32 */
13784 /* end of microMIPS32 DSP */
13786 /* bits 15..12 for 0x2c */
13803 /* bits 15..12 for 0x34 */
13811 /* bits 15..12 for 0x3c */
13813 JR
= 0x0, /* alias */
13821 /* bits 15..12 for 0x05 */
13825 /* bits 15..12 for 0x0d */
13837 /* bits 15..12 for 0x15 */
13843 /* bits 15..12 for 0x1d */
13847 /* bits 15..12 for 0x2d */
13852 /* bits 15..12 for 0x35 */
13859 /* POOL32B encoding of minor opcode field (bits 15..12) */
13875 /* POOL32C encoding of minor opcode field (bits 15..12) */
13896 /* POOL32C LD-EVA encoding of minor opcode field (bits 11..9) */
13909 /* POOL32C ST-EVA encoding of minor opcode field (bits 11..9) */
13922 /* POOL32F encoding of minor opcode field (bits 5..0) */
13925 /* These are the bit 7..6 values */
13934 /* These are the bit 8..6 values */
13959 MOVZ_FMT_05
= 0x05,
13993 CABS_COND_FMT
= 0x1c, /* MIPS3D */
14000 /* POOL32Fxf encoding of minor opcode extension field */
14038 /* POOL32I encoding of minor opcode field (bits 25..21) */
14068 /* These overlap and are distinguished by bit16 of the instruction */
14077 /* POOL16A encoding of minor opcode field */
14084 /* POOL16B encoding of minor opcode field */
14091 /* POOL16C encoding of minor opcode field */
14111 /* R6 POOL16C encoding of minor opcode field (bits 0..5) */
14135 /* POOL16D encoding of minor opcode field */
14142 /* POOL16E encoding of minor opcode field */
14149 static int mmreg(int r
)
14151 static const int map
[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
14156 /* Used for 16-bit store instructions. */
14157 static int mmreg2(int r
)
14159 static const int map
[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
14164 #define uMIPS_RD(op) ((op >> 7) & 0x7)
14165 #define uMIPS_RS(op) ((op >> 4) & 0x7)
14166 #define uMIPS_RS2(op) uMIPS_RS(op)
14167 #define uMIPS_RS1(op) ((op >> 1) & 0x7)
14168 #define uMIPS_RD5(op) ((op >> 5) & 0x1f)
14169 #define uMIPS_RS5(op) (op & 0x1f)
14171 /* Signed immediate */
14172 #define SIMM(op, start, width) \
14173 ((int32_t)(((op >> start) & ((~0U) >> (32 - width))) \
14176 /* Zero-extended immediate */
14177 #define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32 - width)))
14179 static void gen_addiur1sp(DisasContext
*ctx
)
14181 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
14183 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, 29, ((ctx
->opcode
>> 1) & 0x3f) << 2);
14186 static void gen_addiur2(DisasContext
*ctx
)
14188 static const int decoded_imm
[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
14189 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
14190 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
14192 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, rs
, decoded_imm
[ZIMM(ctx
->opcode
, 1, 3)]);
14195 static void gen_addiusp(DisasContext
*ctx
)
14197 int encoded
= ZIMM(ctx
->opcode
, 1, 9);
14200 if (encoded
<= 1) {
14201 decoded
= 256 + encoded
;
14202 } else if (encoded
<= 255) {
14204 } else if (encoded
<= 509) {
14205 decoded
= encoded
- 512;
14207 decoded
= encoded
- 768;
14210 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, decoded
<< 2);
14213 static void gen_addius5(DisasContext
*ctx
)
14215 int imm
= SIMM(ctx
->opcode
, 1, 4);
14216 int rd
= (ctx
->opcode
>> 5) & 0x1f;
14218 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, rd
, imm
);
14221 static void gen_andi16(DisasContext
*ctx
)
14223 static const int decoded_imm
[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
14224 31, 32, 63, 64, 255, 32768, 65535 };
14225 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
14226 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
14227 int encoded
= ZIMM(ctx
->opcode
, 0, 4);
14229 gen_logic_imm(ctx
, OPC_ANDI
, rd
, rs
, decoded_imm
[encoded
]);
14232 static void gen_ldst_multiple(DisasContext
*ctx
, uint32_t opc
, int reglist
,
14233 int base
, int16_t offset
)
14238 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
14239 gen_reserved_instruction(ctx
);
14243 t0
= tcg_temp_new();
14245 gen_base_offset_addr(ctx
, t0
, base
, offset
);
14247 t1
= tcg_const_tl(reglist
);
14248 t2
= tcg_const_i32(ctx
->mem_idx
);
14250 save_cpu_state(ctx
, 1);
14253 gen_helper_lwm(cpu_env
, t0
, t1
, t2
);
14256 gen_helper_swm(cpu_env
, t0
, t1
, t2
);
14258 #ifdef TARGET_MIPS64
14260 gen_helper_ldm(cpu_env
, t0
, t1
, t2
);
14263 gen_helper_sdm(cpu_env
, t0
, t1
, t2
);
14269 tcg_temp_free_i32(t2
);
14273 static void gen_pool16c_insn(DisasContext
*ctx
)
14275 int rd
= mmreg((ctx
->opcode
>> 3) & 0x7);
14276 int rs
= mmreg(ctx
->opcode
& 0x7);
14278 switch (((ctx
->opcode
) >> 4) & 0x3f) {
14283 gen_logic(ctx
, OPC_NOR
, rd
, rs
, 0);
14289 gen_logic(ctx
, OPC_XOR
, rd
, rd
, rs
);
14295 gen_logic(ctx
, OPC_AND
, rd
, rd
, rs
);
14301 gen_logic(ctx
, OPC_OR
, rd
, rd
, rs
);
14308 static const int lwm_convert
[] = { 0x11, 0x12, 0x13, 0x14 };
14309 int offset
= ZIMM(ctx
->opcode
, 0, 4);
14311 gen_ldst_multiple(ctx
, LWM32
, lwm_convert
[(ctx
->opcode
>> 4) & 0x3],
14320 static const int swm_convert
[] = { 0x11, 0x12, 0x13, 0x14 };
14321 int offset
= ZIMM(ctx
->opcode
, 0, 4);
14323 gen_ldst_multiple(ctx
, SWM32
, swm_convert
[(ctx
->opcode
>> 4) & 0x3],
14330 int reg
= ctx
->opcode
& 0x1f;
14332 gen_compute_branch(ctx
, OPC_JR
, 2, reg
, 0, 0, 4);
14338 int reg
= ctx
->opcode
& 0x1f;
14339 gen_compute_branch(ctx
, OPC_JR
, 2, reg
, 0, 0, 0);
14341 * Let normal delay slot handling in our caller take us
14342 * to the branch target.
14348 gen_compute_branch(ctx
, OPC_JALR
, 2, ctx
->opcode
& 0x1f, 31, 0, 4);
14349 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
14353 gen_compute_branch(ctx
, OPC_JALR
, 2, ctx
->opcode
& 0x1f, 31, 0, 2);
14354 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
14358 gen_HILO(ctx
, OPC_MFHI
, 0, uMIPS_RS5(ctx
->opcode
));
14362 gen_HILO(ctx
, OPC_MFLO
, 0, uMIPS_RS5(ctx
->opcode
));
14365 generate_exception_end(ctx
, EXCP_BREAK
);
14368 if (is_uhi(extract32(ctx
->opcode
, 0, 4))) {
14369 gen_helper_do_semihosting(cpu_env
);
14372 * XXX: not clear which exception should be raised
14373 * when in debug mode...
14375 check_insn(ctx
, ISA_MIPS_R1
);
14376 generate_exception_end(ctx
, EXCP_DBp
);
14379 case JRADDIUSP
+ 0:
14380 case JRADDIUSP
+ 1:
14382 int imm
= ZIMM(ctx
->opcode
, 0, 5);
14383 gen_compute_branch(ctx
, OPC_JR
, 2, 31, 0, 0, 0);
14384 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, imm
<< 2);
14386 * Let normal delay slot handling in our caller take us
14387 * to the branch target.
14392 gen_reserved_instruction(ctx
);
14397 static inline void gen_movep(DisasContext
*ctx
, int enc_dest
, int enc_rt
,
14401 static const int rd_enc
[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
14402 static const int re_enc
[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
14403 static const int rs_rt_enc
[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
14405 rd
= rd_enc
[enc_dest
];
14406 re
= re_enc
[enc_dest
];
14407 gen_load_gpr(cpu_gpr
[rd
], rs_rt_enc
[enc_rs
]);
14408 gen_load_gpr(cpu_gpr
[re
], rs_rt_enc
[enc_rt
]);
14411 static void gen_pool16c_r6_insn(DisasContext
*ctx
)
14413 int rt
= mmreg((ctx
->opcode
>> 7) & 0x7);
14414 int rs
= mmreg((ctx
->opcode
>> 4) & 0x7);
14416 switch (ctx
->opcode
& 0xf) {
14418 gen_logic(ctx
, OPC_NOR
, rt
, rs
, 0);
14421 gen_logic(ctx
, OPC_AND
, rt
, rt
, rs
);
14425 int lwm_converted
= 0x11 + extract32(ctx
->opcode
, 8, 2);
14426 int offset
= extract32(ctx
->opcode
, 4, 4);
14427 gen_ldst_multiple(ctx
, LWM32
, lwm_converted
, 29, offset
<< 2);
14430 case R6_JRC16
: /* JRCADDIUSP */
14431 if ((ctx
->opcode
>> 4) & 1) {
14433 int imm
= extract32(ctx
->opcode
, 5, 5);
14434 gen_compute_branch(ctx
, OPC_JR
, 2, 31, 0, 0, 0);
14435 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, imm
<< 2);
14438 rs
= extract32(ctx
->opcode
, 5, 5);
14439 gen_compute_branch(ctx
, OPC_JR
, 2, rs
, 0, 0, 0);
14451 int enc_dest
= uMIPS_RD(ctx
->opcode
);
14452 int enc_rt
= uMIPS_RS2(ctx
->opcode
);
14453 int enc_rs
= (ctx
->opcode
& 3) | ((ctx
->opcode
>> 1) & 4);
14454 gen_movep(ctx
, enc_dest
, enc_rt
, enc_rs
);
14458 gen_logic(ctx
, OPC_XOR
, rt
, rt
, rs
);
14461 gen_logic(ctx
, OPC_OR
, rt
, rt
, rs
);
14465 int swm_converted
= 0x11 + extract32(ctx
->opcode
, 8, 2);
14466 int offset
= extract32(ctx
->opcode
, 4, 4);
14467 gen_ldst_multiple(ctx
, SWM32
, swm_converted
, 29, offset
<< 2);
14470 case JALRC16
: /* BREAK16, SDBBP16 */
14471 switch (ctx
->opcode
& 0x3f) {
14473 case JALRC16
+ 0x20:
14475 gen_compute_branch(ctx
, OPC_JALR
, 2, (ctx
->opcode
>> 5) & 0x1f,
14480 generate_exception(ctx
, EXCP_BREAK
);
14484 if (is_uhi(extract32(ctx
->opcode
, 6, 4))) {
14485 gen_helper_do_semihosting(cpu_env
);
14487 if (ctx
->hflags
& MIPS_HFLAG_SBRI
) {
14488 generate_exception(ctx
, EXCP_RI
);
14490 generate_exception(ctx
, EXCP_DBp
);
14497 generate_exception(ctx
, EXCP_RI
);
14502 static void gen_ldxs(DisasContext
*ctx
, int base
, int index
, int rd
)
14504 TCGv t0
= tcg_temp_new();
14505 TCGv t1
= tcg_temp_new();
14507 gen_load_gpr(t0
, base
);
14510 gen_load_gpr(t1
, index
);
14511 tcg_gen_shli_tl(t1
, t1
, 2);
14512 gen_op_addr_add(ctx
, t0
, t1
, t0
);
14515 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TESL
);
14516 gen_store_gpr(t1
, rd
);
14522 static void gen_ldst_pair(DisasContext
*ctx
, uint32_t opc
, int rd
,
14523 int base
, int16_t offset
)
14527 if (ctx
->hflags
& MIPS_HFLAG_BMASK
|| rd
== 31) {
14528 gen_reserved_instruction(ctx
);
14532 t0
= tcg_temp_new();
14533 t1
= tcg_temp_new();
14535 gen_base_offset_addr(ctx
, t0
, base
, offset
);
14540 gen_reserved_instruction(ctx
);
14543 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TESL
);
14544 gen_store_gpr(t1
, rd
);
14545 tcg_gen_movi_tl(t1
, 4);
14546 gen_op_addr_add(ctx
, t0
, t0
, t1
);
14547 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TESL
);
14548 gen_store_gpr(t1
, rd
+ 1);
14551 gen_load_gpr(t1
, rd
);
14552 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
14553 tcg_gen_movi_tl(t1
, 4);
14554 gen_op_addr_add(ctx
, t0
, t0
, t1
);
14555 gen_load_gpr(t1
, rd
+ 1);
14556 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
14558 #ifdef TARGET_MIPS64
14561 gen_reserved_instruction(ctx
);
14564 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
14565 gen_store_gpr(t1
, rd
);
14566 tcg_gen_movi_tl(t1
, 8);
14567 gen_op_addr_add(ctx
, t0
, t0
, t1
);
14568 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
14569 gen_store_gpr(t1
, rd
+ 1);
14572 gen_load_gpr(t1
, rd
);
14573 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
14574 tcg_gen_movi_tl(t1
, 8);
14575 gen_op_addr_add(ctx
, t0
, t0
, t1
);
14576 gen_load_gpr(t1
, rd
+ 1);
14577 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
14585 static void gen_sync(int stype
)
14587 TCGBar tcg_mo
= TCG_BAR_SC
;
14590 case 0x4: /* SYNC_WMB */
14591 tcg_mo
|= TCG_MO_ST_ST
;
14593 case 0x10: /* SYNC_MB */
14594 tcg_mo
|= TCG_MO_ALL
;
14596 case 0x11: /* SYNC_ACQUIRE */
14597 tcg_mo
|= TCG_MO_LD_LD
| TCG_MO_LD_ST
;
14599 case 0x12: /* SYNC_RELEASE */
14600 tcg_mo
|= TCG_MO_ST_ST
| TCG_MO_LD_ST
;
14602 case 0x13: /* SYNC_RMB */
14603 tcg_mo
|= TCG_MO_LD_LD
;
14606 tcg_mo
|= TCG_MO_ALL
;
14610 tcg_gen_mb(tcg_mo
);
14613 static void gen_pool32axf(CPUMIPSState
*env
, DisasContext
*ctx
, int rt
, int rs
)
14615 int extension
= (ctx
->opcode
>> 6) & 0x3f;
14616 int minor
= (ctx
->opcode
>> 12) & 0xf;
14617 uint32_t mips32_op
;
14619 switch (extension
) {
14621 mips32_op
= OPC_TEQ
;
14624 mips32_op
= OPC_TGE
;
14627 mips32_op
= OPC_TGEU
;
14630 mips32_op
= OPC_TLT
;
14633 mips32_op
= OPC_TLTU
;
14636 mips32_op
= OPC_TNE
;
14638 gen_trap(ctx
, mips32_op
, rs
, rt
, -1);
14640 #ifndef CONFIG_USER_ONLY
14643 check_cp0_enabled(ctx
);
14645 /* Treat as NOP. */
14648 gen_mfc0(ctx
, cpu_gpr
[rt
], rs
, (ctx
->opcode
>> 11) & 0x7);
14652 check_cp0_enabled(ctx
);
14654 TCGv t0
= tcg_temp_new();
14656 gen_load_gpr(t0
, rt
);
14657 gen_mtc0(ctx
, t0
, rs
, (ctx
->opcode
>> 11) & 0x7);
14663 switch (minor
& 3) {
14665 gen_muldiv(ctx
, OPC_MADD
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
14668 gen_muldiv(ctx
, OPC_MADDU
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
14671 gen_muldiv(ctx
, OPC_MSUB
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
14674 gen_muldiv(ctx
, OPC_MSUBU
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
14677 goto pool32axf_invalid
;
14681 switch (minor
& 3) {
14683 gen_muldiv(ctx
, OPC_MULT
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
14686 gen_muldiv(ctx
, OPC_MULTU
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
14689 goto pool32axf_invalid
;
14695 check_insn(ctx
, ISA_MIPS_R6
);
14696 gen_bitswap(ctx
, OPC_BITSWAP
, rs
, rt
);
14699 gen_bshfl(ctx
, OPC_SEB
, rs
, rt
);
14702 gen_bshfl(ctx
, OPC_SEH
, rs
, rt
);
14705 mips32_op
= OPC_CLO
;
14708 mips32_op
= OPC_CLZ
;
14710 check_insn(ctx
, ISA_MIPS_R1
);
14711 gen_cl(ctx
, mips32_op
, rt
, rs
);
14714 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
14715 gen_rdhwr(ctx
, rt
, rs
, 0);
14718 gen_bshfl(ctx
, OPC_WSBH
, rs
, rt
);
14721 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
14722 mips32_op
= OPC_MULT
;
14725 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
14726 mips32_op
= OPC_MULTU
;
14729 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
14730 mips32_op
= OPC_DIV
;
14733 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
14734 mips32_op
= OPC_DIVU
;
14737 check_insn(ctx
, ISA_MIPS_R1
);
14738 gen_muldiv(ctx
, mips32_op
, 0, rs
, rt
);
14741 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
14742 mips32_op
= OPC_MADD
;
14745 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
14746 mips32_op
= OPC_MADDU
;
14749 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
14750 mips32_op
= OPC_MSUB
;
14753 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
14754 mips32_op
= OPC_MSUBU
;
14756 check_insn(ctx
, ISA_MIPS_R1
);
14757 gen_muldiv(ctx
, mips32_op
, 0, rs
, rt
);
14760 goto pool32axf_invalid
;
14771 generate_exception_err(ctx
, EXCP_CpU
, 2);
14774 goto pool32axf_invalid
;
14779 case JALR
: /* JALRC */
14780 case JALR_HB
: /* JALRC_HB */
14781 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
14782 /* JALRC, JALRC_HB */
14783 gen_compute_branch(ctx
, OPC_JALR
, 4, rs
, rt
, 0, 0);
14785 /* JALR, JALR_HB */
14786 gen_compute_branch(ctx
, OPC_JALR
, 4, rs
, rt
, 0, 4);
14787 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
14792 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
14793 gen_compute_branch(ctx
, OPC_JALR
, 4, rs
, rt
, 0, 2);
14794 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
14797 goto pool32axf_invalid
;
14803 check_cp0_enabled(ctx
);
14804 check_insn(ctx
, ISA_MIPS_R2
);
14805 gen_load_srsgpr(rs
, rt
);
14808 check_cp0_enabled(ctx
);
14809 check_insn(ctx
, ISA_MIPS_R2
);
14810 gen_store_srsgpr(rs
, rt
);
14813 goto pool32axf_invalid
;
14816 #ifndef CONFIG_USER_ONLY
14820 mips32_op
= OPC_TLBP
;
14823 mips32_op
= OPC_TLBR
;
14826 mips32_op
= OPC_TLBWI
;
14829 mips32_op
= OPC_TLBWR
;
14832 mips32_op
= OPC_TLBINV
;
14835 mips32_op
= OPC_TLBINVF
;
14838 mips32_op
= OPC_WAIT
;
14841 mips32_op
= OPC_DERET
;
14844 mips32_op
= OPC_ERET
;
14846 gen_cp0(env
, ctx
, mips32_op
, rt
, rs
);
14849 goto pool32axf_invalid
;
14855 check_cp0_enabled(ctx
);
14857 TCGv t0
= tcg_temp_new();
14859 save_cpu_state(ctx
, 1);
14860 gen_helper_di(t0
, cpu_env
);
14861 gen_store_gpr(t0
, rs
);
14863 * Stop translation as we may have switched the execution
14866 ctx
->base
.is_jmp
= DISAS_STOP
;
14871 check_cp0_enabled(ctx
);
14873 TCGv t0
= tcg_temp_new();
14875 save_cpu_state(ctx
, 1);
14876 gen_helper_ei(t0
, cpu_env
);
14877 gen_store_gpr(t0
, rs
);
14879 * DISAS_STOP isn't sufficient, we need to ensure we break out
14880 * of translated code to check for pending interrupts.
14882 gen_save_pc(ctx
->base
.pc_next
+ 4);
14883 ctx
->base
.is_jmp
= DISAS_EXIT
;
14888 goto pool32axf_invalid
;
14895 gen_sync(extract32(ctx
->opcode
, 16, 5));
14898 generate_exception_end(ctx
, EXCP_SYSCALL
);
14901 if (is_uhi(extract32(ctx
->opcode
, 16, 10))) {
14902 gen_helper_do_semihosting(cpu_env
);
14904 check_insn(ctx
, ISA_MIPS_R1
);
14905 if (ctx
->hflags
& MIPS_HFLAG_SBRI
) {
14906 gen_reserved_instruction(ctx
);
14908 generate_exception_end(ctx
, EXCP_DBp
);
14913 goto pool32axf_invalid
;
14917 switch (minor
& 3) {
14919 gen_HILO(ctx
, OPC_MFHI
, minor
>> 2, rs
);
14922 gen_HILO(ctx
, OPC_MFLO
, minor
>> 2, rs
);
14925 gen_HILO(ctx
, OPC_MTHI
, minor
>> 2, rs
);
14928 gen_HILO(ctx
, OPC_MTLO
, minor
>> 2, rs
);
14931 goto pool32axf_invalid
;
14935 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
14938 gen_HILO(ctx
, OPC_MFHI
, 0, rs
);
14941 gen_HILO(ctx
, OPC_MFLO
, 0, rs
);
14944 gen_HILO(ctx
, OPC_MTHI
, 0, rs
);
14947 gen_HILO(ctx
, OPC_MTLO
, 0, rs
);
14950 goto pool32axf_invalid
;
14955 MIPS_INVAL("pool32axf");
14956 gen_reserved_instruction(ctx
);
14962 * Values for microMIPS fmt field. Variable-width, depending on which
14963 * formats the instruction supports.
14982 static void gen_pool32fxf(DisasContext
*ctx
, int rt
, int rs
)
14984 int extension
= (ctx
->opcode
>> 6) & 0x3ff;
14985 uint32_t mips32_op
;
14987 #define FLOAT_1BIT_FMT(opc, fmt) ((fmt << 8) | opc)
14988 #define FLOAT_2BIT_FMT(opc, fmt) ((fmt << 7) | opc)
14989 #define COND_FLOAT_MOV(opc, cond) ((cond << 7) | opc)
14991 switch (extension
) {
14992 case FLOAT_1BIT_FMT(CFC1
, 0):
14993 mips32_op
= OPC_CFC1
;
14995 case FLOAT_1BIT_FMT(CTC1
, 0):
14996 mips32_op
= OPC_CTC1
;
14998 case FLOAT_1BIT_FMT(MFC1
, 0):
14999 mips32_op
= OPC_MFC1
;
15001 case FLOAT_1BIT_FMT(MTC1
, 0):
15002 mips32_op
= OPC_MTC1
;
15004 case FLOAT_1BIT_FMT(MFHC1
, 0):
15005 mips32_op
= OPC_MFHC1
;
15007 case FLOAT_1BIT_FMT(MTHC1
, 0):
15008 mips32_op
= OPC_MTHC1
;
15010 gen_cp1(ctx
, mips32_op
, rt
, rs
);
15013 /* Reciprocal square root */
15014 case FLOAT_1BIT_FMT(RSQRT_FMT
, FMT_SD_S
):
15015 mips32_op
= OPC_RSQRT_S
;
15017 case FLOAT_1BIT_FMT(RSQRT_FMT
, FMT_SD_D
):
15018 mips32_op
= OPC_RSQRT_D
;
15022 case FLOAT_1BIT_FMT(SQRT_FMT
, FMT_SD_S
):
15023 mips32_op
= OPC_SQRT_S
;
15025 case FLOAT_1BIT_FMT(SQRT_FMT
, FMT_SD_D
):
15026 mips32_op
= OPC_SQRT_D
;
15030 case FLOAT_1BIT_FMT(RECIP_FMT
, FMT_SD_S
):
15031 mips32_op
= OPC_RECIP_S
;
15033 case FLOAT_1BIT_FMT(RECIP_FMT
, FMT_SD_D
):
15034 mips32_op
= OPC_RECIP_D
;
15038 case FLOAT_1BIT_FMT(FLOOR_L
, FMT_SD_S
):
15039 mips32_op
= OPC_FLOOR_L_S
;
15041 case FLOAT_1BIT_FMT(FLOOR_L
, FMT_SD_D
):
15042 mips32_op
= OPC_FLOOR_L_D
;
15044 case FLOAT_1BIT_FMT(FLOOR_W
, FMT_SD_S
):
15045 mips32_op
= OPC_FLOOR_W_S
;
15047 case FLOAT_1BIT_FMT(FLOOR_W
, FMT_SD_D
):
15048 mips32_op
= OPC_FLOOR_W_D
;
15052 case FLOAT_1BIT_FMT(CEIL_L
, FMT_SD_S
):
15053 mips32_op
= OPC_CEIL_L_S
;
15055 case FLOAT_1BIT_FMT(CEIL_L
, FMT_SD_D
):
15056 mips32_op
= OPC_CEIL_L_D
;
15058 case FLOAT_1BIT_FMT(CEIL_W
, FMT_SD_S
):
15059 mips32_op
= OPC_CEIL_W_S
;
15061 case FLOAT_1BIT_FMT(CEIL_W
, FMT_SD_D
):
15062 mips32_op
= OPC_CEIL_W_D
;
15066 case FLOAT_1BIT_FMT(TRUNC_L
, FMT_SD_S
):
15067 mips32_op
= OPC_TRUNC_L_S
;
15069 case FLOAT_1BIT_FMT(TRUNC_L
, FMT_SD_D
):
15070 mips32_op
= OPC_TRUNC_L_D
;
15072 case FLOAT_1BIT_FMT(TRUNC_W
, FMT_SD_S
):
15073 mips32_op
= OPC_TRUNC_W_S
;
15075 case FLOAT_1BIT_FMT(TRUNC_W
, FMT_SD_D
):
15076 mips32_op
= OPC_TRUNC_W_D
;
15080 case FLOAT_1BIT_FMT(ROUND_L
, FMT_SD_S
):
15081 mips32_op
= OPC_ROUND_L_S
;
15083 case FLOAT_1BIT_FMT(ROUND_L
, FMT_SD_D
):
15084 mips32_op
= OPC_ROUND_L_D
;
15086 case FLOAT_1BIT_FMT(ROUND_W
, FMT_SD_S
):
15087 mips32_op
= OPC_ROUND_W_S
;
15089 case FLOAT_1BIT_FMT(ROUND_W
, FMT_SD_D
):
15090 mips32_op
= OPC_ROUND_W_D
;
15093 /* Integer to floating-point conversion */
15094 case FLOAT_1BIT_FMT(CVT_L
, FMT_SD_S
):
15095 mips32_op
= OPC_CVT_L_S
;
15097 case FLOAT_1BIT_FMT(CVT_L
, FMT_SD_D
):
15098 mips32_op
= OPC_CVT_L_D
;
15100 case FLOAT_1BIT_FMT(CVT_W
, FMT_SD_S
):
15101 mips32_op
= OPC_CVT_W_S
;
15103 case FLOAT_1BIT_FMT(CVT_W
, FMT_SD_D
):
15104 mips32_op
= OPC_CVT_W_D
;
15107 /* Paired-foo conversions */
15108 case FLOAT_1BIT_FMT(CVT_S_PL
, 0):
15109 mips32_op
= OPC_CVT_S_PL
;
15111 case FLOAT_1BIT_FMT(CVT_S_PU
, 0):
15112 mips32_op
= OPC_CVT_S_PU
;
15114 case FLOAT_1BIT_FMT(CVT_PW_PS
, 0):
15115 mips32_op
= OPC_CVT_PW_PS
;
15117 case FLOAT_1BIT_FMT(CVT_PS_PW
, 0):
15118 mips32_op
= OPC_CVT_PS_PW
;
15121 /* Floating-point moves */
15122 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_S
):
15123 mips32_op
= OPC_MOV_S
;
15125 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_D
):
15126 mips32_op
= OPC_MOV_D
;
15128 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_PS
):
15129 mips32_op
= OPC_MOV_PS
;
15132 /* Absolute value */
15133 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_S
):
15134 mips32_op
= OPC_ABS_S
;
15136 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_D
):
15137 mips32_op
= OPC_ABS_D
;
15139 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_PS
):
15140 mips32_op
= OPC_ABS_PS
;
15144 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_S
):
15145 mips32_op
= OPC_NEG_S
;
15147 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_D
):
15148 mips32_op
= OPC_NEG_D
;
15150 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_PS
):
15151 mips32_op
= OPC_NEG_PS
;
15154 /* Reciprocal square root step */
15155 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_S
):
15156 mips32_op
= OPC_RSQRT1_S
;
15158 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_D
):
15159 mips32_op
= OPC_RSQRT1_D
;
15161 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_PS
):
15162 mips32_op
= OPC_RSQRT1_PS
;
15165 /* Reciprocal step */
15166 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_S
):
15167 mips32_op
= OPC_RECIP1_S
;
15169 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_D
):
15170 mips32_op
= OPC_RECIP1_S
;
15172 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_PS
):
15173 mips32_op
= OPC_RECIP1_PS
;
15176 /* Conversions from double */
15177 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_S
):
15178 mips32_op
= OPC_CVT_D_S
;
15180 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_W
):
15181 mips32_op
= OPC_CVT_D_W
;
15183 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_L
):
15184 mips32_op
= OPC_CVT_D_L
;
15187 /* Conversions from single */
15188 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_D
):
15189 mips32_op
= OPC_CVT_S_D
;
15191 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_W
):
15192 mips32_op
= OPC_CVT_S_W
;
15194 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_L
):
15195 mips32_op
= OPC_CVT_S_L
;
15197 gen_farith(ctx
, mips32_op
, -1, rs
, rt
, 0);
15200 /* Conditional moves on floating-point codes */
15201 case COND_FLOAT_MOV(MOVT
, 0):
15202 case COND_FLOAT_MOV(MOVT
, 1):
15203 case COND_FLOAT_MOV(MOVT
, 2):
15204 case COND_FLOAT_MOV(MOVT
, 3):
15205 case COND_FLOAT_MOV(MOVT
, 4):
15206 case COND_FLOAT_MOV(MOVT
, 5):
15207 case COND_FLOAT_MOV(MOVT
, 6):
15208 case COND_FLOAT_MOV(MOVT
, 7):
15209 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15210 gen_movci(ctx
, rt
, rs
, (ctx
->opcode
>> 13) & 0x7, 1);
15212 case COND_FLOAT_MOV(MOVF
, 0):
15213 case COND_FLOAT_MOV(MOVF
, 1):
15214 case COND_FLOAT_MOV(MOVF
, 2):
15215 case COND_FLOAT_MOV(MOVF
, 3):
15216 case COND_FLOAT_MOV(MOVF
, 4):
15217 case COND_FLOAT_MOV(MOVF
, 5):
15218 case COND_FLOAT_MOV(MOVF
, 6):
15219 case COND_FLOAT_MOV(MOVF
, 7):
15220 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15221 gen_movci(ctx
, rt
, rs
, (ctx
->opcode
>> 13) & 0x7, 0);
15224 MIPS_INVAL("pool32fxf");
15225 gen_reserved_instruction(ctx
);
15230 static void decode_micromips32_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
15234 int rt
, rs
, rd
, rr
;
15236 uint32_t op
, minor
, minor2
, mips32_op
;
15237 uint32_t cond
, fmt
, cc
;
15239 insn
= translator_lduw(env
, ctx
->base
.pc_next
+ 2);
15240 ctx
->opcode
= (ctx
->opcode
<< 16) | insn
;
15242 rt
= (ctx
->opcode
>> 21) & 0x1f;
15243 rs
= (ctx
->opcode
>> 16) & 0x1f;
15244 rd
= (ctx
->opcode
>> 11) & 0x1f;
15245 rr
= (ctx
->opcode
>> 6) & 0x1f;
15246 imm
= (int16_t) ctx
->opcode
;
15248 op
= (ctx
->opcode
>> 26) & 0x3f;
15251 minor
= ctx
->opcode
& 0x3f;
15254 minor
= (ctx
->opcode
>> 6) & 0xf;
15257 mips32_op
= OPC_SLL
;
15260 mips32_op
= OPC_SRA
;
15263 mips32_op
= OPC_SRL
;
15266 mips32_op
= OPC_ROTR
;
15268 gen_shift_imm(ctx
, mips32_op
, rt
, rs
, rd
);
15271 check_insn(ctx
, ISA_MIPS_R6
);
15272 gen_cond_move(ctx
, OPC_SELEQZ
, rd
, rs
, rt
);
15275 check_insn(ctx
, ISA_MIPS_R6
);
15276 gen_cond_move(ctx
, OPC_SELNEZ
, rd
, rs
, rt
);
15279 check_insn(ctx
, ISA_MIPS_R6
);
15280 gen_rdhwr(ctx
, rt
, rs
, extract32(ctx
->opcode
, 11, 3));
15283 goto pool32a_invalid
;
15287 minor
= (ctx
->opcode
>> 6) & 0xf;
15291 mips32_op
= OPC_ADD
;
15294 mips32_op
= OPC_ADDU
;
15297 mips32_op
= OPC_SUB
;
15300 mips32_op
= OPC_SUBU
;
15303 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15304 mips32_op
= OPC_MUL
;
15306 gen_arith(ctx
, mips32_op
, rd
, rs
, rt
);
15310 mips32_op
= OPC_SLLV
;
15313 mips32_op
= OPC_SRLV
;
15316 mips32_op
= OPC_SRAV
;
15319 mips32_op
= OPC_ROTRV
;
15321 gen_shift(ctx
, mips32_op
, rd
, rs
, rt
);
15323 /* Logical operations */
15325 mips32_op
= OPC_AND
;
15328 mips32_op
= OPC_OR
;
15331 mips32_op
= OPC_NOR
;
15334 mips32_op
= OPC_XOR
;
15336 gen_logic(ctx
, mips32_op
, rd
, rs
, rt
);
15338 /* Set less than */
15340 mips32_op
= OPC_SLT
;
15343 mips32_op
= OPC_SLTU
;
15345 gen_slt(ctx
, mips32_op
, rd
, rs
, rt
);
15348 goto pool32a_invalid
;
15352 minor
= (ctx
->opcode
>> 6) & 0xf;
15354 /* Conditional moves */
15355 case MOVN
: /* MUL */
15356 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
15358 gen_r6_muldiv(ctx
, R6_OPC_MUL
, rd
, rs
, rt
);
15361 gen_cond_move(ctx
, OPC_MOVN
, rd
, rs
, rt
);
15364 case MOVZ
: /* MUH */
15365 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
15367 gen_r6_muldiv(ctx
, R6_OPC_MUH
, rd
, rs
, rt
);
15370 gen_cond_move(ctx
, OPC_MOVZ
, rd
, rs
, rt
);
15374 check_insn(ctx
, ISA_MIPS_R6
);
15375 gen_r6_muldiv(ctx
, R6_OPC_MULU
, rd
, rs
, rt
);
15378 check_insn(ctx
, ISA_MIPS_R6
);
15379 gen_r6_muldiv(ctx
, R6_OPC_MUHU
, rd
, rs
, rt
);
15381 case LWXS
: /* DIV */
15382 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
15384 gen_r6_muldiv(ctx
, R6_OPC_DIV
, rd
, rs
, rt
);
15387 gen_ldxs(ctx
, rs
, rt
, rd
);
15391 check_insn(ctx
, ISA_MIPS_R6
);
15392 gen_r6_muldiv(ctx
, R6_OPC_MOD
, rd
, rs
, rt
);
15395 check_insn(ctx
, ISA_MIPS_R6
);
15396 gen_r6_muldiv(ctx
, R6_OPC_DIVU
, rd
, rs
, rt
);
15399 check_insn(ctx
, ISA_MIPS_R6
);
15400 gen_r6_muldiv(ctx
, R6_OPC_MODU
, rd
, rs
, rt
);
15403 goto pool32a_invalid
;
15407 gen_bitops(ctx
, OPC_INS
, rt
, rs
, rr
, rd
);
15410 check_insn(ctx
, ISA_MIPS_R6
);
15411 gen_lsa(ctx
, rd
, rt
, rs
, extract32(ctx
->opcode
, 9, 2));
15414 check_insn(ctx
, ISA_MIPS_R6
);
15415 gen_align(ctx
, 32, rd
, rs
, rt
, extract32(ctx
->opcode
, 9, 2));
15418 gen_bitops(ctx
, OPC_EXT
, rt
, rs
, rr
, rd
);
15421 gen_pool32axf(env
, ctx
, rt
, rs
);
15424 generate_exception_end(ctx
, EXCP_BREAK
);
15427 check_insn(ctx
, ISA_MIPS_R6
);
15428 gen_reserved_instruction(ctx
);
15432 MIPS_INVAL("pool32a");
15433 gen_reserved_instruction(ctx
);
15438 minor
= (ctx
->opcode
>> 12) & 0xf;
15441 check_cp0_enabled(ctx
);
15442 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
15443 gen_cache_operation(ctx
, rt
, rs
, imm
);
15448 /* COP2: Not implemented. */
15449 generate_exception_err(ctx
, EXCP_CpU
, 2);
15451 #ifdef TARGET_MIPS64
15454 check_insn(ctx
, ISA_MIPS3
);
15455 check_mips_64(ctx
);
15460 gen_ldst_pair(ctx
, minor
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
15462 #ifdef TARGET_MIPS64
15465 check_insn(ctx
, ISA_MIPS3
);
15466 check_mips_64(ctx
);
15471 gen_ldst_multiple(ctx
, minor
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
15474 MIPS_INVAL("pool32b");
15475 gen_reserved_instruction(ctx
);
15480 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
15481 minor
= ctx
->opcode
& 0x3f;
15482 check_cp1_enabled(ctx
);
15485 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15486 mips32_op
= OPC_ALNV_PS
;
15489 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15490 mips32_op
= OPC_MADD_S
;
15493 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15494 mips32_op
= OPC_MADD_D
;
15497 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15498 mips32_op
= OPC_MADD_PS
;
15501 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15502 mips32_op
= OPC_MSUB_S
;
15505 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15506 mips32_op
= OPC_MSUB_D
;
15509 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15510 mips32_op
= OPC_MSUB_PS
;
15513 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15514 mips32_op
= OPC_NMADD_S
;
15517 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15518 mips32_op
= OPC_NMADD_D
;
15521 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15522 mips32_op
= OPC_NMADD_PS
;
15525 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15526 mips32_op
= OPC_NMSUB_S
;
15529 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15530 mips32_op
= OPC_NMSUB_D
;
15533 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15534 mips32_op
= OPC_NMSUB_PS
;
15536 gen_flt3_arith(ctx
, mips32_op
, rd
, rr
, rs
, rt
);
15538 case CABS_COND_FMT
:
15539 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15540 cond
= (ctx
->opcode
>> 6) & 0xf;
15541 cc
= (ctx
->opcode
>> 13) & 0x7;
15542 fmt
= (ctx
->opcode
>> 10) & 0x3;
15545 gen_cmpabs_s(ctx
, cond
, rt
, rs
, cc
);
15548 gen_cmpabs_d(ctx
, cond
, rt
, rs
, cc
);
15551 gen_cmpabs_ps(ctx
, cond
, rt
, rs
, cc
);
15554 goto pool32f_invalid
;
15558 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15559 cond
= (ctx
->opcode
>> 6) & 0xf;
15560 cc
= (ctx
->opcode
>> 13) & 0x7;
15561 fmt
= (ctx
->opcode
>> 10) & 0x3;
15564 gen_cmp_s(ctx
, cond
, rt
, rs
, cc
);
15567 gen_cmp_d(ctx
, cond
, rt
, rs
, cc
);
15570 gen_cmp_ps(ctx
, cond
, rt
, rs
, cc
);
15573 goto pool32f_invalid
;
15577 check_insn(ctx
, ISA_MIPS_R6
);
15578 gen_r6_cmp_s(ctx
, (ctx
->opcode
>> 6) & 0x1f, rt
, rs
, rd
);
15581 check_insn(ctx
, ISA_MIPS_R6
);
15582 gen_r6_cmp_d(ctx
, (ctx
->opcode
>> 6) & 0x1f, rt
, rs
, rd
);
15585 gen_pool32fxf(ctx
, rt
, rs
);
15589 switch ((ctx
->opcode
>> 6) & 0x7) {
15591 mips32_op
= OPC_PLL_PS
;
15594 mips32_op
= OPC_PLU_PS
;
15597 mips32_op
= OPC_PUL_PS
;
15600 mips32_op
= OPC_PUU_PS
;
15603 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15604 mips32_op
= OPC_CVT_PS_S
;
15606 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
15609 goto pool32f_invalid
;
15613 check_insn(ctx
, ISA_MIPS_R6
);
15614 switch ((ctx
->opcode
>> 9) & 0x3) {
15616 gen_farith(ctx
, OPC_MIN_S
, rt
, rs
, rd
, 0);
15619 gen_farith(ctx
, OPC_MIN_D
, rt
, rs
, rd
, 0);
15622 goto pool32f_invalid
;
15627 switch ((ctx
->opcode
>> 6) & 0x7) {
15629 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15630 mips32_op
= OPC_LWXC1
;
15633 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15634 mips32_op
= OPC_SWXC1
;
15637 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15638 mips32_op
= OPC_LDXC1
;
15641 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15642 mips32_op
= OPC_SDXC1
;
15645 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15646 mips32_op
= OPC_LUXC1
;
15649 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15650 mips32_op
= OPC_SUXC1
;
15652 gen_flt3_ldst(ctx
, mips32_op
, rd
, rd
, rt
, rs
);
15655 goto pool32f_invalid
;
15659 check_insn(ctx
, ISA_MIPS_R6
);
15660 switch ((ctx
->opcode
>> 9) & 0x3) {
15662 gen_farith(ctx
, OPC_MAX_S
, rt
, rs
, rd
, 0);
15665 gen_farith(ctx
, OPC_MAX_D
, rt
, rs
, rd
, 0);
15668 goto pool32f_invalid
;
15673 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15674 fmt
= (ctx
->opcode
>> 9) & 0x3;
15675 switch ((ctx
->opcode
>> 6) & 0x7) {
15679 mips32_op
= OPC_RSQRT2_S
;
15682 mips32_op
= OPC_RSQRT2_D
;
15685 mips32_op
= OPC_RSQRT2_PS
;
15688 goto pool32f_invalid
;
15694 mips32_op
= OPC_RECIP2_S
;
15697 mips32_op
= OPC_RECIP2_D
;
15700 mips32_op
= OPC_RECIP2_PS
;
15703 goto pool32f_invalid
;
15707 mips32_op
= OPC_ADDR_PS
;
15710 mips32_op
= OPC_MULR_PS
;
15712 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
15715 goto pool32f_invalid
;
15719 /* MOV[FT].fmt, PREFX, RINT.fmt, CLASS.fmt*/
15720 cc
= (ctx
->opcode
>> 13) & 0x7;
15721 fmt
= (ctx
->opcode
>> 9) & 0x3;
15722 switch ((ctx
->opcode
>> 6) & 0x7) {
15723 case MOVF_FMT
: /* RINT_FMT */
15724 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
15728 gen_farith(ctx
, OPC_RINT_S
, 0, rt
, rs
, 0);
15731 gen_farith(ctx
, OPC_RINT_D
, 0, rt
, rs
, 0);
15734 goto pool32f_invalid
;
15740 gen_movcf_s(ctx
, rs
, rt
, cc
, 0);
15743 gen_movcf_d(ctx
, rs
, rt
, cc
, 0);
15747 gen_movcf_ps(ctx
, rs
, rt
, cc
, 0);
15750 goto pool32f_invalid
;
15754 case MOVT_FMT
: /* CLASS_FMT */
15755 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
15759 gen_farith(ctx
, OPC_CLASS_S
, 0, rt
, rs
, 0);
15762 gen_farith(ctx
, OPC_CLASS_D
, 0, rt
, rs
, 0);
15765 goto pool32f_invalid
;
15771 gen_movcf_s(ctx
, rs
, rt
, cc
, 1);
15774 gen_movcf_d(ctx
, rs
, rt
, cc
, 1);
15778 gen_movcf_ps(ctx
, rs
, rt
, cc
, 1);
15781 goto pool32f_invalid
;
15786 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15789 goto pool32f_invalid
;
15792 #define FINSN_3ARG_SDPS(prfx) \
15793 switch ((ctx->opcode >> 8) & 0x3) { \
15795 mips32_op = OPC_##prfx##_S; \
15798 mips32_op = OPC_##prfx##_D; \
15800 case FMT_SDPS_PS: \
15802 mips32_op = OPC_##prfx##_PS; \
15805 goto pool32f_invalid; \
15808 check_insn(ctx
, ISA_MIPS_R6
);
15809 switch ((ctx
->opcode
>> 9) & 0x3) {
15811 gen_farith(ctx
, OPC_MINA_S
, rt
, rs
, rd
, 0);
15814 gen_farith(ctx
, OPC_MINA_D
, rt
, rs
, rd
, 0);
15817 goto pool32f_invalid
;
15821 check_insn(ctx
, ISA_MIPS_R6
);
15822 switch ((ctx
->opcode
>> 9) & 0x3) {
15824 gen_farith(ctx
, OPC_MAXA_S
, rt
, rs
, rd
, 0);
15827 gen_farith(ctx
, OPC_MAXA_D
, rt
, rs
, rd
, 0);
15830 goto pool32f_invalid
;
15834 /* regular FP ops */
15835 switch ((ctx
->opcode
>> 6) & 0x3) {
15837 FINSN_3ARG_SDPS(ADD
);
15840 FINSN_3ARG_SDPS(SUB
);
15843 FINSN_3ARG_SDPS(MUL
);
15846 fmt
= (ctx
->opcode
>> 8) & 0x3;
15848 mips32_op
= OPC_DIV_D
;
15849 } else if (fmt
== 0) {
15850 mips32_op
= OPC_DIV_S
;
15852 goto pool32f_invalid
;
15856 goto pool32f_invalid
;
15861 switch ((ctx
->opcode
>> 6) & 0x7) {
15862 case MOVN_FMT
: /* SELEQZ_FMT */
15863 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
15865 switch ((ctx
->opcode
>> 9) & 0x3) {
15867 gen_sel_s(ctx
, OPC_SELEQZ_S
, rd
, rt
, rs
);
15870 gen_sel_d(ctx
, OPC_SELEQZ_D
, rd
, rt
, rs
);
15873 goto pool32f_invalid
;
15877 FINSN_3ARG_SDPS(MOVN
);
15881 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15882 FINSN_3ARG_SDPS(MOVN
);
15884 case MOVZ_FMT
: /* SELNEZ_FMT */
15885 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
15887 switch ((ctx
->opcode
>> 9) & 0x3) {
15889 gen_sel_s(ctx
, OPC_SELNEZ_S
, rd
, rt
, rs
);
15892 gen_sel_d(ctx
, OPC_SELNEZ_D
, rd
, rt
, rs
);
15895 goto pool32f_invalid
;
15899 FINSN_3ARG_SDPS(MOVZ
);
15903 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15904 FINSN_3ARG_SDPS(MOVZ
);
15907 check_insn(ctx
, ISA_MIPS_R6
);
15908 switch ((ctx
->opcode
>> 9) & 0x3) {
15910 gen_sel_s(ctx
, OPC_SEL_S
, rd
, rt
, rs
);
15913 gen_sel_d(ctx
, OPC_SEL_D
, rd
, rt
, rs
);
15916 goto pool32f_invalid
;
15920 check_insn(ctx
, ISA_MIPS_R6
);
15921 switch ((ctx
->opcode
>> 9) & 0x3) {
15923 mips32_op
= OPC_MADDF_S
;
15926 mips32_op
= OPC_MADDF_D
;
15929 goto pool32f_invalid
;
15933 check_insn(ctx
, ISA_MIPS_R6
);
15934 switch ((ctx
->opcode
>> 9) & 0x3) {
15936 mips32_op
= OPC_MSUBF_S
;
15939 mips32_op
= OPC_MSUBF_D
;
15942 goto pool32f_invalid
;
15946 goto pool32f_invalid
;
15950 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
15954 MIPS_INVAL("pool32f");
15955 gen_reserved_instruction(ctx
);
15959 generate_exception_err(ctx
, EXCP_CpU
, 1);
15963 minor
= (ctx
->opcode
>> 21) & 0x1f;
15966 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15967 gen_compute_branch(ctx
, OPC_BLTZ
, 4, rs
, -1, imm
<< 1, 4);
15970 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15971 gen_compute_branch(ctx
, OPC_BLTZAL
, 4, rs
, -1, imm
<< 1, 4);
15972 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
15975 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15976 gen_compute_branch(ctx
, OPC_BLTZAL
, 4, rs
, -1, imm
<< 1, 2);
15977 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
15980 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15981 gen_compute_branch(ctx
, OPC_BGEZ
, 4, rs
, -1, imm
<< 1, 4);
15984 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15985 gen_compute_branch(ctx
, OPC_BGEZAL
, 4, rs
, -1, imm
<< 1, 4);
15986 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
15989 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15990 gen_compute_branch(ctx
, OPC_BGEZAL
, 4, rs
, -1, imm
<< 1, 2);
15991 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
15994 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15995 gen_compute_branch(ctx
, OPC_BLEZ
, 4, rs
, -1, imm
<< 1, 4);
15998 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15999 gen_compute_branch(ctx
, OPC_BGTZ
, 4, rs
, -1, imm
<< 1, 4);
16003 case TLTI
: /* BC1EQZC */
16004 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16006 check_cp1_enabled(ctx
);
16007 gen_compute_branch1_r6(ctx
, OPC_BC1EQZ
, rs
, imm
<< 1, 0);
16010 mips32_op
= OPC_TLTI
;
16014 case TGEI
: /* BC1NEZC */
16015 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16017 check_cp1_enabled(ctx
);
16018 gen_compute_branch1_r6(ctx
, OPC_BC1NEZ
, rs
, imm
<< 1, 0);
16021 mips32_op
= OPC_TGEI
;
16026 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16027 mips32_op
= OPC_TLTIU
;
16030 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16031 mips32_op
= OPC_TGEIU
;
16033 case TNEI
: /* SYNCI */
16034 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16037 * Break the TB to be able to sync copied instructions
16040 ctx
->base
.is_jmp
= DISAS_STOP
;
16043 mips32_op
= OPC_TNEI
;
16048 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16049 mips32_op
= OPC_TEQI
;
16051 gen_trap(ctx
, mips32_op
, rs
, -1, imm
);
16056 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16057 gen_compute_branch(ctx
, minor
== BNEZC
? OPC_BNE
: OPC_BEQ
,
16058 4, rs
, 0, imm
<< 1, 0);
16060 * Compact branches don't have a delay slot, so just let
16061 * the normal delay slot handling take us to the branch
16066 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16067 gen_logic_imm(ctx
, OPC_LUI
, rs
, 0, imm
);
16070 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16072 * Break the TB to be able to sync copied instructions
16075 ctx
->base
.is_jmp
= DISAS_STOP
;
16079 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16080 /* COP2: Not implemented. */
16081 generate_exception_err(ctx
, EXCP_CpU
, 2);
16084 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16085 mips32_op
= (ctx
->opcode
& (1 << 16)) ? OPC_BC1FANY2
: OPC_BC1F
;
16088 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16089 mips32_op
= (ctx
->opcode
& (1 << 16)) ? OPC_BC1TANY2
: OPC_BC1T
;
16092 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16093 mips32_op
= OPC_BC1FANY4
;
16096 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16097 mips32_op
= OPC_BC1TANY4
;
16100 check_insn(ctx
, ASE_MIPS3D
);
16103 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
16104 check_cp1_enabled(ctx
);
16105 gen_compute_branch1(ctx
, mips32_op
,
16106 (ctx
->opcode
>> 18) & 0x7, imm
<< 1);
16108 generate_exception_err(ctx
, EXCP_CpU
, 1);
16113 /* MIPS DSP: not implemented */
16116 MIPS_INVAL("pool32i");
16117 gen_reserved_instruction(ctx
);
16122 minor
= (ctx
->opcode
>> 12) & 0xf;
16123 offset
= sextract32(ctx
->opcode
, 0,
16124 (ctx
->insn_flags
& ISA_MIPS_R6
) ? 9 : 12);
16127 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16128 mips32_op
= OPC_LWL
;
16131 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16132 mips32_op
= OPC_SWL
;
16135 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16136 mips32_op
= OPC_LWR
;
16139 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16140 mips32_op
= OPC_SWR
;
16142 #if defined(TARGET_MIPS64)
16144 check_insn(ctx
, ISA_MIPS3
);
16145 check_mips_64(ctx
);
16146 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16147 mips32_op
= OPC_LDL
;
16150 check_insn(ctx
, ISA_MIPS3
);
16151 check_mips_64(ctx
);
16152 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16153 mips32_op
= OPC_SDL
;
16156 check_insn(ctx
, ISA_MIPS3
);
16157 check_mips_64(ctx
);
16158 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16159 mips32_op
= OPC_LDR
;
16162 check_insn(ctx
, ISA_MIPS3
);
16163 check_mips_64(ctx
);
16164 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16165 mips32_op
= OPC_SDR
;
16168 check_insn(ctx
, ISA_MIPS3
);
16169 check_mips_64(ctx
);
16170 mips32_op
= OPC_LWU
;
16173 check_insn(ctx
, ISA_MIPS3
);
16174 check_mips_64(ctx
);
16175 mips32_op
= OPC_LLD
;
16179 mips32_op
= OPC_LL
;
16182 gen_ld(ctx
, mips32_op
, rt
, rs
, offset
);
16185 gen_st(ctx
, mips32_op
, rt
, rs
, offset
);
16188 gen_st_cond(ctx
, rt
, rs
, offset
, MO_TESL
, false);
16190 #if defined(TARGET_MIPS64)
16192 check_insn(ctx
, ISA_MIPS3
);
16193 check_mips_64(ctx
);
16194 gen_st_cond(ctx
, rt
, rs
, offset
, MO_TEQ
, false);
16199 MIPS_INVAL("pool32c ld-eva");
16200 gen_reserved_instruction(ctx
);
16203 check_cp0_enabled(ctx
);
16205 minor2
= (ctx
->opcode
>> 9) & 0x7;
16206 offset
= sextract32(ctx
->opcode
, 0, 9);
16209 mips32_op
= OPC_LBUE
;
16212 mips32_op
= OPC_LHUE
;
16215 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16216 mips32_op
= OPC_LWLE
;
16219 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16220 mips32_op
= OPC_LWRE
;
16223 mips32_op
= OPC_LBE
;
16226 mips32_op
= OPC_LHE
;
16229 mips32_op
= OPC_LLE
;
16232 mips32_op
= OPC_LWE
;
16238 MIPS_INVAL("pool32c st-eva");
16239 gen_reserved_instruction(ctx
);
16242 check_cp0_enabled(ctx
);
16244 minor2
= (ctx
->opcode
>> 9) & 0x7;
16245 offset
= sextract32(ctx
->opcode
, 0, 9);
16248 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16249 mips32_op
= OPC_SWLE
;
16252 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16253 mips32_op
= OPC_SWRE
;
16256 /* Treat as no-op */
16257 if ((ctx
->insn_flags
& ISA_MIPS_R6
) && (rt
>= 24)) {
16258 /* hint codes 24-31 are reserved and signal RI */
16259 generate_exception(ctx
, EXCP_RI
);
16263 /* Treat as no-op */
16264 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
16265 gen_cache_operation(ctx
, rt
, rs
, offset
);
16269 mips32_op
= OPC_SBE
;
16272 mips32_op
= OPC_SHE
;
16275 gen_st_cond(ctx
, rt
, rs
, offset
, MO_TESL
, true);
16278 mips32_op
= OPC_SWE
;
16283 /* Treat as no-op */
16284 if ((ctx
->insn_flags
& ISA_MIPS_R6
) && (rt
>= 24)) {
16285 /* hint codes 24-31 are reserved and signal RI */
16286 generate_exception(ctx
, EXCP_RI
);
16290 MIPS_INVAL("pool32c");
16291 gen_reserved_instruction(ctx
);
16295 case ADDI32
: /* AUI, LUI */
16296 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16298 gen_logic_imm(ctx
, OPC_LUI
, rt
, rs
, imm
);
16301 mips32_op
= OPC_ADDI
;
16306 mips32_op
= OPC_ADDIU
;
16308 gen_arith_imm(ctx
, mips32_op
, rt
, rs
, imm
);
16311 /* Logical operations */
16313 mips32_op
= OPC_ORI
;
16316 mips32_op
= OPC_XORI
;
16319 mips32_op
= OPC_ANDI
;
16321 gen_logic_imm(ctx
, mips32_op
, rt
, rs
, imm
);
16324 /* Set less than immediate */
16326 mips32_op
= OPC_SLTI
;
16329 mips32_op
= OPC_SLTIU
;
16331 gen_slt_imm(ctx
, mips32_op
, rt
, rs
, imm
);
16334 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16335 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
16336 gen_compute_branch(ctx
, OPC_JALX
, 4, rt
, rs
, offset
, 4);
16337 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
16339 case JALS32
: /* BOVC, BEQC, BEQZALC */
16340 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16343 mips32_op
= OPC_BOVC
;
16344 } else if (rs
< rt
&& rs
== 0) {
16346 mips32_op
= OPC_BEQZALC
;
16349 mips32_op
= OPC_BEQC
;
16351 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
16354 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1;
16355 gen_compute_branch(ctx
, OPC_JAL
, 4, rt
, rs
, offset
, 2);
16356 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
16359 case BEQ32
: /* BC */
16360 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16362 gen_compute_compact_branch(ctx
, OPC_BC
, 0, 0,
16363 sextract32(ctx
->opcode
<< 1, 0, 27));
16366 gen_compute_branch(ctx
, OPC_BEQ
, 4, rt
, rs
, imm
<< 1, 4);
16369 case BNE32
: /* BALC */
16370 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16372 gen_compute_compact_branch(ctx
, OPC_BALC
, 0, 0,
16373 sextract32(ctx
->opcode
<< 1, 0, 27));
16376 gen_compute_branch(ctx
, OPC_BNE
, 4, rt
, rs
, imm
<< 1, 4);
16379 case J32
: /* BGTZC, BLTZC, BLTC */
16380 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16381 if (rs
== 0 && rt
!= 0) {
16383 mips32_op
= OPC_BGTZC
;
16384 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
16386 mips32_op
= OPC_BLTZC
;
16389 mips32_op
= OPC_BLTC
;
16391 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
16394 gen_compute_branch(ctx
, OPC_J
, 4, rt
, rs
,
16395 (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1, 4);
16398 case JAL32
: /* BLEZC, BGEZC, BGEC */
16399 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16400 if (rs
== 0 && rt
!= 0) {
16402 mips32_op
= OPC_BLEZC
;
16403 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
16405 mips32_op
= OPC_BGEZC
;
16408 mips32_op
= OPC_BGEC
;
16410 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
16413 gen_compute_branch(ctx
, OPC_JAL
, 4, rt
, rs
,
16414 (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1, 4);
16415 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
16418 /* Floating point (COP1) */
16420 mips32_op
= OPC_LWC1
;
16423 mips32_op
= OPC_LDC1
;
16426 mips32_op
= OPC_SWC1
;
16429 mips32_op
= OPC_SDC1
;
16431 gen_cop1_ldst(ctx
, mips32_op
, rt
, rs
, imm
);
16433 case ADDIUPC
: /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
16434 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16435 /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
16436 switch ((ctx
->opcode
>> 16) & 0x1f) {
16445 gen_pcrel(ctx
, OPC_ADDIUPC
, ctx
->base
.pc_next
& ~0x3, rt
);
16448 gen_pcrel(ctx
, OPC_AUIPC
, ctx
->base
.pc_next
, rt
);
16451 gen_pcrel(ctx
, OPC_ALUIPC
, ctx
->base
.pc_next
, rt
);
16461 gen_pcrel(ctx
, R6_OPC_LWPC
, ctx
->base
.pc_next
& ~0x3, rt
);
16464 generate_exception(ctx
, EXCP_RI
);
16469 int reg
= mmreg(ZIMM(ctx
->opcode
, 23, 3));
16470 offset
= SIMM(ctx
->opcode
, 0, 23) << 2;
16472 gen_addiupc(ctx
, reg
, offset
, 0, 0);
16475 case BNVC
: /* BNEC, BNEZALC */
16476 check_insn(ctx
, ISA_MIPS_R6
);
16479 mips32_op
= OPC_BNVC
;
16480 } else if (rs
< rt
&& rs
== 0) {
16482 mips32_op
= OPC_BNEZALC
;
16485 mips32_op
= OPC_BNEC
;
16487 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
16489 case R6_BNEZC
: /* JIALC */
16490 check_insn(ctx
, ISA_MIPS_R6
);
16493 gen_compute_compact_branch(ctx
, OPC_BNEZC
, rt
, 0,
16494 sextract32(ctx
->opcode
<< 1, 0, 22));
16497 gen_compute_compact_branch(ctx
, OPC_JIALC
, 0, rs
, imm
);
16500 case R6_BEQZC
: /* JIC */
16501 check_insn(ctx
, ISA_MIPS_R6
);
16504 gen_compute_compact_branch(ctx
, OPC_BEQZC
, rt
, 0,
16505 sextract32(ctx
->opcode
<< 1, 0, 22));
16508 gen_compute_compact_branch(ctx
, OPC_JIC
, 0, rs
, imm
);
16511 case BLEZALC
: /* BGEZALC, BGEUC */
16512 check_insn(ctx
, ISA_MIPS_R6
);
16513 if (rs
== 0 && rt
!= 0) {
16515 mips32_op
= OPC_BLEZALC
;
16516 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
16518 mips32_op
= OPC_BGEZALC
;
16521 mips32_op
= OPC_BGEUC
;
16523 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
16525 case BGTZALC
: /* BLTZALC, BLTUC */
16526 check_insn(ctx
, ISA_MIPS_R6
);
16527 if (rs
== 0 && rt
!= 0) {
16529 mips32_op
= OPC_BGTZALC
;
16530 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
16532 mips32_op
= OPC_BLTZALC
;
16535 mips32_op
= OPC_BLTUC
;
16537 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
16539 /* Loads and stores */
16541 mips32_op
= OPC_LB
;
16544 mips32_op
= OPC_LBU
;
16547 mips32_op
= OPC_LH
;
16550 mips32_op
= OPC_LHU
;
16553 mips32_op
= OPC_LW
;
16555 #ifdef TARGET_MIPS64
16557 check_insn(ctx
, ISA_MIPS3
);
16558 check_mips_64(ctx
);
16559 mips32_op
= OPC_LD
;
16562 check_insn(ctx
, ISA_MIPS3
);
16563 check_mips_64(ctx
);
16564 mips32_op
= OPC_SD
;
16568 mips32_op
= OPC_SB
;
16571 mips32_op
= OPC_SH
;
16574 mips32_op
= OPC_SW
;
16577 gen_ld(ctx
, mips32_op
, rt
, rs
, imm
);
16580 gen_st(ctx
, mips32_op
, rt
, rs
, imm
);
16583 gen_reserved_instruction(ctx
);
16588 static int decode_micromips_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
16592 /* make sure instructions are on a halfword boundary */
16593 if (ctx
->base
.pc_next
& 0x1) {
16594 env
->CP0_BadVAddr
= ctx
->base
.pc_next
;
16595 generate_exception_end(ctx
, EXCP_AdEL
);
16599 op
= (ctx
->opcode
>> 10) & 0x3f;
16600 /* Enforce properly-sized instructions in a delay slot */
16601 if (ctx
->hflags
& MIPS_HFLAG_BDS_STRICT
) {
16602 switch (op
& 0x7) { /* MSB-3..MSB-5 */
16604 /* POOL32A, POOL32B, POOL32I, POOL32C */
16606 /* ADDI32, ADDIU32, ORI32, XORI32, SLTI32, SLTIU32, ANDI32, JALX32 */
16608 /* LBU32, LHU32, POOL32F, JALS32, BEQ32, BNE32, J32, JAL32 */
16610 /* SB32, SH32, ADDIUPC, SWC132, SDC132, SW32 */
16612 /* LB32, LH32, LWC132, LDC132, LW32 */
16613 if (ctx
->hflags
& MIPS_HFLAG_BDS16
) {
16614 gen_reserved_instruction(ctx
);
16619 /* POOL16A, POOL16B, POOL16C, LWGP16, POOL16F */
16621 /* LBU16, LHU16, LWSP16, LW16, SB16, SH16, SWSP16, SW16 */
16623 /* MOVE16, ANDI16, POOL16D, POOL16E, BEQZ16, BNEZ16, B16, LI16 */
16624 if (ctx
->hflags
& MIPS_HFLAG_BDS32
) {
16625 gen_reserved_instruction(ctx
);
16635 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
16636 int rs1
= mmreg(uMIPS_RS1(ctx
->opcode
));
16637 int rs2
= mmreg(uMIPS_RS2(ctx
->opcode
));
16640 switch (ctx
->opcode
& 0x1) {
16648 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16650 * In the Release 6, the register number location in
16651 * the instruction encoding has changed.
16653 gen_arith(ctx
, opc
, rs1
, rd
, rs2
);
16655 gen_arith(ctx
, opc
, rd
, rs1
, rs2
);
16661 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
16662 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
16663 int amount
= (ctx
->opcode
>> 1) & 0x7;
16665 amount
= amount
== 0 ? 8 : amount
;
16667 switch (ctx
->opcode
& 0x1) {
16676 gen_shift_imm(ctx
, opc
, rd
, rs
, amount
);
16680 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16681 gen_pool16c_r6_insn(ctx
);
16683 gen_pool16c_insn(ctx
);
16688 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
16689 int rb
= 28; /* GP */
16690 int16_t offset
= SIMM(ctx
->opcode
, 0, 7) << 2;
16692 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
16696 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16697 if (ctx
->opcode
& 1) {
16698 gen_reserved_instruction(ctx
);
16701 int enc_dest
= uMIPS_RD(ctx
->opcode
);
16702 int enc_rt
= uMIPS_RS2(ctx
->opcode
);
16703 int enc_rs
= uMIPS_RS1(ctx
->opcode
);
16704 gen_movep(ctx
, enc_dest
, enc_rt
, enc_rs
);
16709 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
16710 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
16711 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4);
16712 offset
= (offset
== 0xf ? -1 : offset
);
16714 gen_ld(ctx
, OPC_LBU
, rd
, rb
, offset
);
16719 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
16720 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
16721 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 1;
16723 gen_ld(ctx
, OPC_LHU
, rd
, rb
, offset
);
16728 int rd
= (ctx
->opcode
>> 5) & 0x1f;
16729 int rb
= 29; /* SP */
16730 int16_t offset
= ZIMM(ctx
->opcode
, 0, 5) << 2;
16732 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
16737 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
16738 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
16739 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 2;
16741 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
16746 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
16747 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
16748 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4);
16750 gen_st(ctx
, OPC_SB
, 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) << 1;
16759 gen_st(ctx
, OPC_SH
, rd
, rb
, offset
);
16764 int rd
= (ctx
->opcode
>> 5) & 0x1f;
16765 int rb
= 29; /* SP */
16766 int16_t offset
= ZIMM(ctx
->opcode
, 0, 5) << 2;
16768 gen_st(ctx
, OPC_SW
, rd
, rb
, offset
);
16773 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
16774 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
16775 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 2;
16777 gen_st(ctx
, OPC_SW
, rd
, rb
, offset
);
16782 int rd
= uMIPS_RD5(ctx
->opcode
);
16783 int rs
= uMIPS_RS5(ctx
->opcode
);
16785 gen_arith(ctx
, OPC_ADDU
, rd
, rs
, 0);
16792 switch (ctx
->opcode
& 0x1) {
16802 switch (ctx
->opcode
& 0x1) {
16807 gen_addiur1sp(ctx
);
16811 case B16
: /* BC16 */
16812 gen_compute_branch(ctx
, OPC_BEQ
, 2, 0, 0,
16813 sextract32(ctx
->opcode
, 0, 10) << 1,
16814 (ctx
->insn_flags
& ISA_MIPS_R6
) ? 0 : 4);
16816 case BNEZ16
: /* BNEZC16 */
16817 case BEQZ16
: /* BEQZC16 */
16818 gen_compute_branch(ctx
, op
== BNEZ16
? OPC_BNE
: OPC_BEQ
, 2,
16819 mmreg(uMIPS_RD(ctx
->opcode
)),
16820 0, sextract32(ctx
->opcode
, 0, 7) << 1,
16821 (ctx
->insn_flags
& ISA_MIPS_R6
) ? 0 : 4);
16826 int reg
= mmreg(uMIPS_RD(ctx
->opcode
));
16827 int imm
= ZIMM(ctx
->opcode
, 0, 7);
16829 imm
= (imm
== 0x7f ? -1 : imm
);
16830 tcg_gen_movi_tl(cpu_gpr
[reg
], imm
);
16836 gen_reserved_instruction(ctx
);
16839 decode_micromips32_opc(env
, ctx
);
16852 /* MAJOR, P16, and P32 pools opcodes */
16856 NM_MOVE_BALC
= 0x02,
16864 NM_P16_SHIFT
= 0x0c,
16882 NM_P_LS_U12
= 0x21,
16892 NM_P16_ADDU
= 0x2c,
16906 NM_MOVEPREV
= 0x3f,
16909 /* POOL32A instruction pool */
16911 NM_POOL32A0
= 0x00,
16912 NM_SPECIAL2
= 0x01,
16915 NM_POOL32A5
= 0x05,
16916 NM_POOL32A7
= 0x07,
16919 /* P.GP.W instruction pool */
16921 NM_ADDIUGP_W
= 0x00,
16926 /* P48I instruction pool */
16930 NM_ADDIUGP48
= 0x02,
16931 NM_ADDIUPC48
= 0x03,
16936 /* P.U12 instruction pool */
16945 NM_ADDIUNEG
= 0x08,
16952 /* POOL32F instruction pool */
16954 NM_POOL32F_0
= 0x00,
16955 NM_POOL32F_3
= 0x03,
16956 NM_POOL32F_5
= 0x05,
16959 /* POOL32S instruction pool */
16961 NM_POOL32S_0
= 0x00,
16962 NM_POOL32S_4
= 0x04,
16965 /* P.LUI instruction pool */
16971 /* P.GP.BH instruction pool */
16976 NM_ADDIUGP_B
= 0x03,
16979 NM_P_GP_CP1
= 0x06,
16982 /* P.LS.U12 instruction pool */
16987 NM_P_PREFU12
= 0x03,
17000 /* P.LS.S9 instruction pool */
17006 NM_P_LS_UAWM
= 0x05,
17009 /* P.BAL instruction pool */
17015 /* P.J instruction pool */
17018 NM_JALRC_HB
= 0x01,
17019 NM_P_BALRSC
= 0x08,
17022 /* P.BR1 instruction pool */
17030 /* P.BR2 instruction pool */
17037 /* P.BRI instruction pool */
17049 /* P16.SHIFT instruction pool */
17055 /* POOL16C instruction pool */
17057 NM_POOL16C_0
= 0x00,
17061 /* P16.A1 instruction pool */
17063 NM_ADDIUR1SP
= 0x01,
17066 /* P16.A2 instruction pool */
17069 NM_P_ADDIURS5
= 0x01,
17072 /* P16.ADDU instruction pool */
17078 /* P16.SR instruction pool */
17081 NM_RESTORE_JRC16
= 0x01,
17084 /* P16.4X4 instruction pool */
17090 /* P16.LB instruction pool */
17097 /* P16.LH instruction pool */
17104 /* P.RI instruction pool */
17107 NM_P_SYSCALL
= 0x01,
17112 /* POOL32A0 instruction pool */
17147 NM_D_E_MT_VPE
= 0x56,
17155 /* CRC32 instruction pool */
17165 /* POOL32A5 instruction pool */
17167 NM_CMP_EQ_PH
= 0x00,
17168 NM_CMP_LT_PH
= 0x08,
17169 NM_CMP_LE_PH
= 0x10,
17170 NM_CMPGU_EQ_QB
= 0x18,
17171 NM_CMPGU_LT_QB
= 0x20,
17172 NM_CMPGU_LE_QB
= 0x28,
17173 NM_CMPGDU_EQ_QB
= 0x30,
17174 NM_CMPGDU_LT_QB
= 0x38,
17175 NM_CMPGDU_LE_QB
= 0x40,
17176 NM_CMPU_EQ_QB
= 0x48,
17177 NM_CMPU_LT_QB
= 0x50,
17178 NM_CMPU_LE_QB
= 0x58,
17179 NM_ADDQ_S_W
= 0x60,
17180 NM_SUBQ_S_W
= 0x68,
17184 NM_ADDQ_S_PH
= 0x01,
17185 NM_ADDQH_R_PH
= 0x09,
17186 NM_ADDQH_R_W
= 0x11,
17187 NM_ADDU_S_QB
= 0x19,
17188 NM_ADDU_S_PH
= 0x21,
17189 NM_ADDUH_R_QB
= 0x29,
17190 NM_SHRAV_R_PH
= 0x31,
17191 NM_SHRAV_R_QB
= 0x39,
17192 NM_SUBQ_S_PH
= 0x41,
17193 NM_SUBQH_R_PH
= 0x49,
17194 NM_SUBQH_R_W
= 0x51,
17195 NM_SUBU_S_QB
= 0x59,
17196 NM_SUBU_S_PH
= 0x61,
17197 NM_SUBUH_R_QB
= 0x69,
17198 NM_SHLLV_S_PH
= 0x71,
17199 NM_PRECR_SRA_R_PH_W
= 0x79,
17201 NM_MULEU_S_PH_QBL
= 0x12,
17202 NM_MULEU_S_PH_QBR
= 0x1a,
17203 NM_MULQ_RS_PH
= 0x22,
17204 NM_MULQ_S_PH
= 0x2a,
17205 NM_MULQ_RS_W
= 0x32,
17206 NM_MULQ_S_W
= 0x3a,
17209 NM_SHRAV_R_W
= 0x5a,
17210 NM_SHRLV_PH
= 0x62,
17211 NM_SHRLV_QB
= 0x6a,
17212 NM_SHLLV_QB
= 0x72,
17213 NM_SHLLV_S_W
= 0x7a,
17217 NM_MULEQ_S_W_PHL
= 0x04,
17218 NM_MULEQ_S_W_PHR
= 0x0c,
17220 NM_MUL_S_PH
= 0x05,
17221 NM_PRECR_QB_PH
= 0x0d,
17222 NM_PRECRQ_QB_PH
= 0x15,
17223 NM_PRECRQ_PH_W
= 0x1d,
17224 NM_PRECRQ_RS_PH_W
= 0x25,
17225 NM_PRECRQU_S_QB_PH
= 0x2d,
17226 NM_PACKRL_PH
= 0x35,
17230 NM_SHRA_R_W
= 0x5e,
17231 NM_SHRA_R_PH
= 0x66,
17232 NM_SHLL_S_PH
= 0x76,
17233 NM_SHLL_S_W
= 0x7e,
17238 /* POOL32A7 instruction pool */
17243 NM_POOL32AXF
= 0x07,
17246 /* P.SR instruction pool */
17252 /* P.SHIFT instruction pool */
17260 /* P.ROTX instruction pool */
17265 /* P.INS instruction pool */
17270 /* P.EXT instruction pool */
17275 /* POOL32F_0 (fmt) instruction pool */
17280 NM_SELEQZ_S
= 0x07,
17281 NM_SELEQZ_D
= 0x47,
17285 NM_SELNEZ_S
= 0x0f,
17286 NM_SELNEZ_D
= 0x4f,
17301 /* POOL32F_3 instruction pool */
17305 NM_MINA_FMT
= 0x04,
17306 NM_MAXA_FMT
= 0x05,
17307 NM_POOL32FXF
= 0x07,
17310 /* POOL32F_5 instruction pool */
17312 NM_CMP_CONDN_S
= 0x00,
17313 NM_CMP_CONDN_D
= 0x02,
17316 /* P.GP.LH instruction pool */
17322 /* P.GP.SH instruction pool */
17327 /* P.GP.CP1 instruction pool */
17335 /* P.LS.S0 instruction pool */
17352 NM_P_PREFS9
= 0x03,
17358 /* P.LS.S1 instruction pool */
17360 NM_ASET_ACLR
= 0x02,
17368 /* P.LS.E0 instruction pool */
17384 /* P.PREFE instruction pool */
17390 /* P.LLE instruction pool */
17396 /* P.SCE instruction pool */
17402 /* P.LS.WM instruction pool */
17408 /* P.LS.UAWM instruction pool */
17414 /* P.BR3A instruction pool */
17420 NM_BPOSGE32C
= 0x04,
17423 /* P16.RI instruction pool */
17425 NM_P16_SYSCALL
= 0x01,
17430 /* POOL16C_0 instruction pool */
17432 NM_POOL16C_00
= 0x00,
17435 /* P16.JRC instruction pool */
17441 /* P.SYSCALL instruction pool */
17447 /* P.TRAP instruction pool */
17453 /* P.CMOVE instruction pool */
17459 /* POOL32Axf instruction pool */
17461 NM_POOL32AXF_1
= 0x01,
17462 NM_POOL32AXF_2
= 0x02,
17463 NM_POOL32AXF_4
= 0x04,
17464 NM_POOL32AXF_5
= 0x05,
17465 NM_POOL32AXF_7
= 0x07,
17468 /* POOL32Axf_1 instruction pool */
17470 NM_POOL32AXF_1_0
= 0x00,
17471 NM_POOL32AXF_1_1
= 0x01,
17472 NM_POOL32AXF_1_3
= 0x03,
17473 NM_POOL32AXF_1_4
= 0x04,
17474 NM_POOL32AXF_1_5
= 0x05,
17475 NM_POOL32AXF_1_7
= 0x07,
17478 /* POOL32Axf_2 instruction pool */
17480 NM_POOL32AXF_2_0_7
= 0x00,
17481 NM_POOL32AXF_2_8_15
= 0x01,
17482 NM_POOL32AXF_2_16_23
= 0x02,
17483 NM_POOL32AXF_2_24_31
= 0x03,
17486 /* POOL32Axf_7 instruction pool */
17488 NM_SHRA_R_QB
= 0x0,
17493 /* POOL32Axf_1_0 instruction pool */
17501 /* POOL32Axf_1_1 instruction pool */
17507 /* POOL32Axf_1_3 instruction pool */
17515 /* POOL32Axf_1_4 instruction pool */
17521 /* POOL32Axf_1_5 instruction pool */
17523 NM_MAQ_S_W_PHR
= 0x0,
17524 NM_MAQ_S_W_PHL
= 0x1,
17525 NM_MAQ_SA_W_PHR
= 0x2,
17526 NM_MAQ_SA_W_PHL
= 0x3,
17529 /* POOL32Axf_1_7 instruction pool */
17533 NM_EXTR_RS_W
= 0x2,
17537 /* POOL32Axf_2_0_7 instruction pool */
17540 NM_DPAQ_S_W_PH
= 0x1,
17542 NM_DPSQ_S_W_PH
= 0x3,
17549 /* POOL32Axf_2_8_15 instruction pool */
17551 NM_DPAX_W_PH
= 0x0,
17552 NM_DPAQ_SA_L_W
= 0x1,
17553 NM_DPSX_W_PH
= 0x2,
17554 NM_DPSQ_SA_L_W
= 0x3,
17557 NM_EXTRV_R_W
= 0x7,
17560 /* POOL32Axf_2_16_23 instruction pool */
17562 NM_DPAU_H_QBL
= 0x0,
17563 NM_DPAQX_S_W_PH
= 0x1,
17564 NM_DPSU_H_QBL
= 0x2,
17565 NM_DPSQX_S_W_PH
= 0x3,
17568 NM_MULSA_W_PH
= 0x6,
17569 NM_EXTRV_RS_W
= 0x7,
17572 /* POOL32Axf_2_24_31 instruction pool */
17574 NM_DPAU_H_QBR
= 0x0,
17575 NM_DPAQX_SA_W_PH
= 0x1,
17576 NM_DPSU_H_QBR
= 0x2,
17577 NM_DPSQX_SA_W_PH
= 0x3,
17580 NM_MULSAQ_S_W_PH
= 0x6,
17581 NM_EXTRV_S_H
= 0x7,
17584 /* POOL32Axf_{4, 5} instruction pool */
17603 /* nanoMIPS DSP instructions */
17604 NM_ABSQ_S_QB
= 0x00,
17605 NM_ABSQ_S_PH
= 0x08,
17606 NM_ABSQ_S_W
= 0x10,
17607 NM_PRECEQ_W_PHL
= 0x28,
17608 NM_PRECEQ_W_PHR
= 0x30,
17609 NM_PRECEQU_PH_QBL
= 0x38,
17610 NM_PRECEQU_PH_QBR
= 0x48,
17611 NM_PRECEU_PH_QBL
= 0x58,
17612 NM_PRECEU_PH_QBR
= 0x68,
17613 NM_PRECEQU_PH_QBLA
= 0x39,
17614 NM_PRECEQU_PH_QBRA
= 0x49,
17615 NM_PRECEU_PH_QBLA
= 0x59,
17616 NM_PRECEU_PH_QBRA
= 0x69,
17617 NM_REPLV_PH
= 0x01,
17618 NM_REPLV_QB
= 0x09,
17621 NM_RADDU_W_QB
= 0x78,
17627 /* PP.SR instruction pool */
17631 NM_RESTORE_JRC
= 0x03,
17634 /* P.SR.F instruction pool */
17637 NM_RESTOREF
= 0x01,
17640 /* P16.SYSCALL instruction pool */
17642 NM_SYSCALL16
= 0x00,
17643 NM_HYPCALL16
= 0x01,
17646 /* POOL16C_00 instruction pool */
17654 /* PP.LSX and PP.LSXS instruction pool */
17692 /* ERETx instruction pool */
17698 /* POOL32FxF_{0, 1} insturction pool */
17707 NM_CVT_S_PL
= 0x84,
17708 NM_CVT_S_PU
= 0xa4,
17710 NM_CVT_L_S
= 0x004,
17711 NM_CVT_L_D
= 0x104,
17712 NM_CVT_W_S
= 0x024,
17713 NM_CVT_W_D
= 0x124,
17715 NM_RSQRT_S
= 0x008,
17716 NM_RSQRT_D
= 0x108,
17721 NM_RECIP_S
= 0x048,
17722 NM_RECIP_D
= 0x148,
17724 NM_FLOOR_L_S
= 0x00c,
17725 NM_FLOOR_L_D
= 0x10c,
17727 NM_FLOOR_W_S
= 0x02c,
17728 NM_FLOOR_W_D
= 0x12c,
17730 NM_CEIL_L_S
= 0x04c,
17731 NM_CEIL_L_D
= 0x14c,
17732 NM_CEIL_W_S
= 0x06c,
17733 NM_CEIL_W_D
= 0x16c,
17734 NM_TRUNC_L_S
= 0x08c,
17735 NM_TRUNC_L_D
= 0x18c,
17736 NM_TRUNC_W_S
= 0x0ac,
17737 NM_TRUNC_W_D
= 0x1ac,
17738 NM_ROUND_L_S
= 0x0cc,
17739 NM_ROUND_L_D
= 0x1cc,
17740 NM_ROUND_W_S
= 0x0ec,
17741 NM_ROUND_W_D
= 0x1ec,
17749 NM_CVT_D_S
= 0x04d,
17750 NM_CVT_D_W
= 0x0cd,
17751 NM_CVT_D_L
= 0x14d,
17752 NM_CVT_S_D
= 0x06d,
17753 NM_CVT_S_W
= 0x0ed,
17754 NM_CVT_S_L
= 0x16d,
17757 /* P.LL instruction pool */
17763 /* P.SC instruction pool */
17769 /* P.DVP instruction pool */
17778 * nanoMIPS decoding engine
17783 /* extraction utilities */
17785 #define NANOMIPS_EXTRACT_RT3(op) ((op >> 7) & 0x7)
17786 #define NANOMIPS_EXTRACT_RS3(op) ((op >> 4) & 0x7)
17787 #define NANOMIPS_EXTRACT_RD3(op) ((op >> 1) & 0x7)
17788 #define NANOMIPS_EXTRACT_RD5(op) ((op >> 5) & 0x1f)
17789 #define NANOMIPS_EXTRACT_RS5(op) (op & 0x1f)
17791 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3'). */
17792 static inline int decode_gpr_gpr3(int r
)
17794 static const int map
[] = { 16, 17, 18, 19, 4, 5, 6, 7 };
17796 return map
[r
& 0x7];
17799 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3.src.store'). */
17800 static inline int decode_gpr_gpr3_src_store(int r
)
17802 static const int map
[] = { 0, 17, 18, 19, 4, 5, 6, 7 };
17804 return map
[r
& 0x7];
17807 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4'). */
17808 static inline int decode_gpr_gpr4(int r
)
17810 static const int map
[] = { 8, 9, 10, 11, 4, 5, 6, 7,
17811 16, 17, 18, 19, 20, 21, 22, 23 };
17813 return map
[r
& 0xf];
17816 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4.zero'). */
17817 static inline int decode_gpr_gpr4_zero(int r
)
17819 static const int map
[] = { 8, 9, 10, 0, 4, 5, 6, 7,
17820 16, 17, 18, 19, 20, 21, 22, 23 };
17822 return map
[r
& 0xf];
17826 static void gen_adjust_sp(DisasContext
*ctx
, int u
)
17828 gen_op_addr_addi(ctx
, cpu_gpr
[29], cpu_gpr
[29], u
);
17831 static void gen_save(DisasContext
*ctx
, uint8_t rt
, uint8_t count
,
17832 uint8_t gp
, uint16_t u
)
17835 TCGv va
= tcg_temp_new();
17836 TCGv t0
= tcg_temp_new();
17838 while (counter
!= count
) {
17839 bool use_gp
= gp
&& (counter
== count
- 1);
17840 int this_rt
= use_gp
? 28 : (rt
& 0x10) | ((rt
+ counter
) & 0x1f);
17841 int this_offset
= -((counter
+ 1) << 2);
17842 gen_base_offset_addr(ctx
, va
, 29, this_offset
);
17843 gen_load_gpr(t0
, this_rt
);
17844 tcg_gen_qemu_st_tl(t0
, va
, ctx
->mem_idx
,
17845 (MO_TEUL
| ctx
->default_tcg_memop_mask
));
17849 /* adjust stack pointer */
17850 gen_adjust_sp(ctx
, -u
);
17856 static void gen_restore(DisasContext
*ctx
, uint8_t rt
, uint8_t count
,
17857 uint8_t gp
, uint16_t u
)
17860 TCGv va
= tcg_temp_new();
17861 TCGv t0
= tcg_temp_new();
17863 while (counter
!= count
) {
17864 bool use_gp
= gp
&& (counter
== count
- 1);
17865 int this_rt
= use_gp
? 28 : (rt
& 0x10) | ((rt
+ counter
) & 0x1f);
17866 int this_offset
= u
- ((counter
+ 1) << 2);
17867 gen_base_offset_addr(ctx
, va
, 29, this_offset
);
17868 tcg_gen_qemu_ld_tl(t0
, va
, ctx
->mem_idx
, MO_TESL
|
17869 ctx
->default_tcg_memop_mask
);
17870 tcg_gen_ext32s_tl(t0
, t0
);
17871 gen_store_gpr(t0
, this_rt
);
17875 /* adjust stack pointer */
17876 gen_adjust_sp(ctx
, u
);
17882 static void gen_pool16c_nanomips_insn(DisasContext
*ctx
)
17884 int rt
= decode_gpr_gpr3(NANOMIPS_EXTRACT_RT3(ctx
->opcode
));
17885 int rs
= decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx
->opcode
));
17887 switch (extract32(ctx
->opcode
, 2, 2)) {
17889 gen_logic(ctx
, OPC_NOR
, rt
, rs
, 0);
17892 gen_logic(ctx
, OPC_AND
, rt
, rt
, rs
);
17895 gen_logic(ctx
, OPC_XOR
, rt
, rt
, rs
);
17898 gen_logic(ctx
, OPC_OR
, rt
, rt
, rs
);
17903 static void gen_pool32a0_nanomips_insn(CPUMIPSState
*env
, DisasContext
*ctx
)
17905 int rt
= extract32(ctx
->opcode
, 21, 5);
17906 int rs
= extract32(ctx
->opcode
, 16, 5);
17907 int rd
= extract32(ctx
->opcode
, 11, 5);
17909 switch (extract32(ctx
->opcode
, 3, 7)) {
17911 switch (extract32(ctx
->opcode
, 10, 1)) {
17914 gen_trap(ctx
, OPC_TEQ
, rs
, rt
, -1);
17918 gen_trap(ctx
, OPC_TNE
, rs
, rt
, -1);
17924 gen_rdhwr(ctx
, rt
, rs
, extract32(ctx
->opcode
, 11, 3));
17928 gen_bshfl(ctx
, OPC_SEB
, rs
, rt
);
17931 gen_bshfl(ctx
, OPC_SEH
, rs
, rt
);
17934 gen_shift(ctx
, OPC_SLLV
, rd
, rt
, rs
);
17937 gen_shift(ctx
, OPC_SRLV
, rd
, rt
, rs
);
17940 gen_shift(ctx
, OPC_SRAV
, rd
, rt
, rs
);
17943 gen_shift(ctx
, OPC_ROTRV
, rd
, rt
, rs
);
17946 gen_arith(ctx
, OPC_ADD
, rd
, rs
, rt
);
17949 gen_arith(ctx
, OPC_ADDU
, rd
, rs
, rt
);
17953 gen_arith(ctx
, OPC_SUB
, rd
, rs
, rt
);
17956 gen_arith(ctx
, OPC_SUBU
, rd
, rs
, rt
);
17959 switch (extract32(ctx
->opcode
, 10, 1)) {
17961 gen_cond_move(ctx
, OPC_MOVZ
, rd
, rs
, rt
);
17964 gen_cond_move(ctx
, OPC_MOVN
, rd
, rs
, rt
);
17969 gen_logic(ctx
, OPC_AND
, rd
, rs
, rt
);
17972 gen_logic(ctx
, OPC_OR
, rd
, rs
, rt
);
17975 gen_logic(ctx
, OPC_NOR
, rd
, rs
, rt
);
17978 gen_logic(ctx
, OPC_XOR
, rd
, rs
, rt
);
17981 gen_slt(ctx
, OPC_SLT
, rd
, rs
, rt
);
17986 #ifndef CONFIG_USER_ONLY
17987 TCGv t0
= tcg_temp_new();
17988 switch (extract32(ctx
->opcode
, 10, 1)) {
17991 check_cp0_enabled(ctx
);
17992 gen_helper_dvp(t0
, cpu_env
);
17993 gen_store_gpr(t0
, rt
);
17998 check_cp0_enabled(ctx
);
17999 gen_helper_evp(t0
, cpu_env
);
18000 gen_store_gpr(t0
, rt
);
18007 gen_slt(ctx
, OPC_SLTU
, rd
, rs
, rt
);
18012 TCGv t0
= tcg_temp_new();
18013 TCGv t1
= tcg_temp_new();
18014 TCGv t2
= tcg_temp_new();
18016 gen_load_gpr(t1
, rs
);
18017 gen_load_gpr(t2
, rt
);
18018 tcg_gen_add_tl(t0
, t1
, t2
);
18019 tcg_gen_ext32s_tl(t0
, t0
);
18020 tcg_gen_xor_tl(t1
, t1
, t2
);
18021 tcg_gen_xor_tl(t2
, t0
, t2
);
18022 tcg_gen_andc_tl(t1
, t2
, t1
);
18024 /* operands of same sign, result different sign */
18025 tcg_gen_setcondi_tl(TCG_COND_LT
, t0
, t1
, 0);
18026 gen_store_gpr(t0
, rd
);
18034 gen_r6_muldiv(ctx
, R6_OPC_MUL
, rd
, rs
, rt
);
18037 gen_r6_muldiv(ctx
, R6_OPC_MUH
, rd
, rs
, rt
);
18040 gen_r6_muldiv(ctx
, R6_OPC_MULU
, rd
, rs
, rt
);
18043 gen_r6_muldiv(ctx
, R6_OPC_MUHU
, rd
, rs
, rt
);
18046 gen_r6_muldiv(ctx
, R6_OPC_DIV
, rd
, rs
, rt
);
18049 gen_r6_muldiv(ctx
, R6_OPC_MOD
, rd
, rs
, rt
);
18052 gen_r6_muldiv(ctx
, R6_OPC_DIVU
, rd
, rs
, rt
);
18055 gen_r6_muldiv(ctx
, R6_OPC_MODU
, rd
, rs
, rt
);
18057 #ifndef CONFIG_USER_ONLY
18059 check_cp0_enabled(ctx
);
18061 /* Treat as NOP. */
18064 gen_mfc0(ctx
, cpu_gpr
[rt
], rs
, extract32(ctx
->opcode
, 11, 3));
18067 check_cp0_enabled(ctx
);
18069 TCGv t0
= tcg_temp_new();
18071 gen_load_gpr(t0
, rt
);
18072 gen_mtc0(ctx
, t0
, rs
, extract32(ctx
->opcode
, 11, 3));
18076 case NM_D_E_MT_VPE
:
18078 uint8_t sc
= extract32(ctx
->opcode
, 10, 1);
18079 TCGv t0
= tcg_temp_new();
18086 gen_helper_dmt(t0
);
18087 gen_store_gpr(t0
, rt
);
18088 } else if (rs
== 0) {
18091 gen_helper_dvpe(t0
, cpu_env
);
18092 gen_store_gpr(t0
, rt
);
18094 gen_reserved_instruction(ctx
);
18101 gen_helper_emt(t0
);
18102 gen_store_gpr(t0
, rt
);
18103 } else if (rs
== 0) {
18106 gen_helper_evpe(t0
, cpu_env
);
18107 gen_store_gpr(t0
, rt
);
18109 gen_reserved_instruction(ctx
);
18120 TCGv t0
= tcg_temp_new();
18121 TCGv t1
= tcg_temp_new();
18123 gen_load_gpr(t0
, rt
);
18124 gen_load_gpr(t1
, rs
);
18125 gen_helper_fork(t0
, t1
);
18132 check_cp0_enabled(ctx
);
18134 /* Treat as NOP. */
18137 gen_mftr(env
, ctx
, rs
, rt
, extract32(ctx
->opcode
, 10, 1),
18138 extract32(ctx
->opcode
, 11, 5), extract32(ctx
->opcode
, 3, 1));
18142 check_cp0_enabled(ctx
);
18143 gen_mttr(env
, ctx
, rs
, rt
, extract32(ctx
->opcode
, 10, 1),
18144 extract32(ctx
->opcode
, 11, 5), extract32(ctx
->opcode
, 3, 1));
18149 TCGv t0
= tcg_temp_new();
18151 gen_load_gpr(t0
, rs
);
18152 gen_helper_yield(t0
, cpu_env
, t0
);
18153 gen_store_gpr(t0
, rt
);
18159 gen_reserved_instruction(ctx
);
18165 static void gen_pool32axf_1_5_nanomips_insn(DisasContext
*ctx
, uint32_t opc
,
18166 int ret
, int v1
, int v2
)
18172 t0
= tcg_temp_new_i32();
18174 v0_t
= tcg_temp_new();
18175 v1_t
= tcg_temp_new();
18177 tcg_gen_movi_i32(t0
, v2
>> 3);
18179 gen_load_gpr(v0_t
, ret
);
18180 gen_load_gpr(v1_t
, v1
);
18183 case NM_MAQ_S_W_PHR
:
18185 gen_helper_maq_s_w_phr(t0
, v1_t
, v0_t
, cpu_env
);
18187 case NM_MAQ_S_W_PHL
:
18189 gen_helper_maq_s_w_phl(t0
, v1_t
, v0_t
, cpu_env
);
18191 case NM_MAQ_SA_W_PHR
:
18193 gen_helper_maq_sa_w_phr(t0
, v1_t
, v0_t
, cpu_env
);
18195 case NM_MAQ_SA_W_PHL
:
18197 gen_helper_maq_sa_w_phl(t0
, v1_t
, v0_t
, cpu_env
);
18200 gen_reserved_instruction(ctx
);
18204 tcg_temp_free_i32(t0
);
18206 tcg_temp_free(v0_t
);
18207 tcg_temp_free(v1_t
);
18211 static void gen_pool32axf_1_nanomips_insn(DisasContext
*ctx
, uint32_t opc
,
18212 int ret
, int v1
, int v2
)
18215 TCGv t0
= tcg_temp_new();
18216 TCGv t1
= tcg_temp_new();
18217 TCGv v0_t
= tcg_temp_new();
18219 gen_load_gpr(v0_t
, v1
);
18222 case NM_POOL32AXF_1_0
:
18224 switch (extract32(ctx
->opcode
, 12, 2)) {
18226 gen_HILO(ctx
, OPC_MFHI
, v2
>> 3, ret
);
18229 gen_HILO(ctx
, OPC_MFLO
, v2
>> 3, ret
);
18232 gen_HILO(ctx
, OPC_MTHI
, v2
>> 3, v1
);
18235 gen_HILO(ctx
, OPC_MTLO
, v2
>> 3, v1
);
18239 case NM_POOL32AXF_1_1
:
18241 switch (extract32(ctx
->opcode
, 12, 2)) {
18243 tcg_gen_movi_tl(t0
, v2
);
18244 gen_helper_mthlip(t0
, v0_t
, cpu_env
);
18247 tcg_gen_movi_tl(t0
, v2
>> 3);
18248 gen_helper_shilo(t0
, v0_t
, cpu_env
);
18251 gen_reserved_instruction(ctx
);
18255 case NM_POOL32AXF_1_3
:
18257 imm
= extract32(ctx
->opcode
, 14, 7);
18258 switch (extract32(ctx
->opcode
, 12, 2)) {
18260 tcg_gen_movi_tl(t0
, imm
);
18261 gen_helper_rddsp(t0
, t0
, cpu_env
);
18262 gen_store_gpr(t0
, ret
);
18265 gen_load_gpr(t0
, ret
);
18266 tcg_gen_movi_tl(t1
, imm
);
18267 gen_helper_wrdsp(t0
, t1
, cpu_env
);
18270 tcg_gen_movi_tl(t0
, v2
>> 3);
18271 tcg_gen_movi_tl(t1
, v1
);
18272 gen_helper_extp(t0
, t0
, t1
, cpu_env
);
18273 gen_store_gpr(t0
, ret
);
18276 tcg_gen_movi_tl(t0
, v2
>> 3);
18277 tcg_gen_movi_tl(t1
, v1
);
18278 gen_helper_extpdp(t0
, t0
, t1
, cpu_env
);
18279 gen_store_gpr(t0
, ret
);
18283 case NM_POOL32AXF_1_4
:
18285 tcg_gen_movi_tl(t0
, v2
>> 2);
18286 switch (extract32(ctx
->opcode
, 12, 1)) {
18288 gen_helper_shll_qb(t0
, t0
, v0_t
, cpu_env
);
18289 gen_store_gpr(t0
, ret
);
18292 gen_helper_shrl_qb(t0
, t0
, v0_t
);
18293 gen_store_gpr(t0
, ret
);
18297 case NM_POOL32AXF_1_5
:
18298 opc
= extract32(ctx
->opcode
, 12, 2);
18299 gen_pool32axf_1_5_nanomips_insn(ctx
, opc
, ret
, v1
, v2
);
18301 case NM_POOL32AXF_1_7
:
18303 tcg_gen_movi_tl(t0
, v2
>> 3);
18304 tcg_gen_movi_tl(t1
, v1
);
18305 switch (extract32(ctx
->opcode
, 12, 2)) {
18307 gen_helper_extr_w(t0
, t0
, t1
, cpu_env
);
18308 gen_store_gpr(t0
, ret
);
18311 gen_helper_extr_r_w(t0
, t0
, t1
, cpu_env
);
18312 gen_store_gpr(t0
, ret
);
18315 gen_helper_extr_rs_w(t0
, t0
, t1
, cpu_env
);
18316 gen_store_gpr(t0
, ret
);
18319 gen_helper_extr_s_h(t0
, t0
, t1
, cpu_env
);
18320 gen_store_gpr(t0
, ret
);
18325 gen_reserved_instruction(ctx
);
18331 tcg_temp_free(v0_t
);
18334 static void gen_pool32axf_2_multiply(DisasContext
*ctx
, uint32_t opc
,
18335 TCGv v0
, TCGv v1
, int rd
)
18339 t0
= tcg_temp_new_i32();
18341 tcg_gen_movi_i32(t0
, rd
>> 3);
18344 case NM_POOL32AXF_2_0_7
:
18345 switch (extract32(ctx
->opcode
, 9, 3)) {
18348 gen_helper_dpa_w_ph(t0
, v1
, v0
, cpu_env
);
18350 case NM_DPAQ_S_W_PH
:
18352 gen_helper_dpaq_s_w_ph(t0
, v1
, v0
, cpu_env
);
18356 gen_helper_dps_w_ph(t0
, v1
, v0
, cpu_env
);
18358 case NM_DPSQ_S_W_PH
:
18360 gen_helper_dpsq_s_w_ph(t0
, v1
, v0
, cpu_env
);
18363 gen_reserved_instruction(ctx
);
18367 case NM_POOL32AXF_2_8_15
:
18368 switch (extract32(ctx
->opcode
, 9, 3)) {
18371 gen_helper_dpax_w_ph(t0
, v0
, v1
, cpu_env
);
18373 case NM_DPAQ_SA_L_W
:
18375 gen_helper_dpaq_sa_l_w(t0
, v0
, v1
, cpu_env
);
18379 gen_helper_dpsx_w_ph(t0
, v0
, v1
, cpu_env
);
18381 case NM_DPSQ_SA_L_W
:
18383 gen_helper_dpsq_sa_l_w(t0
, v0
, v1
, cpu_env
);
18386 gen_reserved_instruction(ctx
);
18390 case NM_POOL32AXF_2_16_23
:
18391 switch (extract32(ctx
->opcode
, 9, 3)) {
18392 case NM_DPAU_H_QBL
:
18394 gen_helper_dpau_h_qbl(t0
, v0
, v1
, cpu_env
);
18396 case NM_DPAQX_S_W_PH
:
18398 gen_helper_dpaqx_s_w_ph(t0
, v0
, v1
, cpu_env
);
18400 case NM_DPSU_H_QBL
:
18402 gen_helper_dpsu_h_qbl(t0
, v0
, v1
, cpu_env
);
18404 case NM_DPSQX_S_W_PH
:
18406 gen_helper_dpsqx_s_w_ph(t0
, v0
, v1
, cpu_env
);
18408 case NM_MULSA_W_PH
:
18410 gen_helper_mulsa_w_ph(t0
, v0
, v1
, cpu_env
);
18413 gen_reserved_instruction(ctx
);
18417 case NM_POOL32AXF_2_24_31
:
18418 switch (extract32(ctx
->opcode
, 9, 3)) {
18419 case NM_DPAU_H_QBR
:
18421 gen_helper_dpau_h_qbr(t0
, v1
, v0
, cpu_env
);
18423 case NM_DPAQX_SA_W_PH
:
18425 gen_helper_dpaqx_sa_w_ph(t0
, v1
, v0
, cpu_env
);
18427 case NM_DPSU_H_QBR
:
18429 gen_helper_dpsu_h_qbr(t0
, v1
, v0
, cpu_env
);
18431 case NM_DPSQX_SA_W_PH
:
18433 gen_helper_dpsqx_sa_w_ph(t0
, v1
, v0
, cpu_env
);
18435 case NM_MULSAQ_S_W_PH
:
18437 gen_helper_mulsaq_s_w_ph(t0
, v1
, v0
, cpu_env
);
18440 gen_reserved_instruction(ctx
);
18445 gen_reserved_instruction(ctx
);
18449 tcg_temp_free_i32(t0
);
18452 static void gen_pool32axf_2_nanomips_insn(DisasContext
*ctx
, uint32_t opc
,
18453 int rt
, int rs
, int rd
)
18456 TCGv t0
= tcg_temp_new();
18457 TCGv t1
= tcg_temp_new();
18458 TCGv v0_t
= tcg_temp_new();
18459 TCGv v1_t
= tcg_temp_new();
18461 gen_load_gpr(v0_t
, rt
);
18462 gen_load_gpr(v1_t
, rs
);
18465 case NM_POOL32AXF_2_0_7
:
18466 switch (extract32(ctx
->opcode
, 9, 3)) {
18468 case NM_DPAQ_S_W_PH
:
18470 case NM_DPSQ_S_W_PH
:
18471 gen_pool32axf_2_multiply(ctx
, opc
, v0_t
, v1_t
, rd
);
18476 gen_load_gpr(t0
, rs
);
18478 if (rd
!= 0 && rd
!= 2) {
18479 tcg_gen_shli_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], 8 * rd
);
18480 tcg_gen_ext32u_tl(t0
, t0
);
18481 tcg_gen_shri_tl(t0
, t0
, 8 * (4 - rd
));
18482 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
18484 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
18490 int acc
= extract32(ctx
->opcode
, 14, 2);
18491 TCGv_i64 t2
= tcg_temp_new_i64();
18492 TCGv_i64 t3
= tcg_temp_new_i64();
18494 gen_load_gpr(t0
, rt
);
18495 gen_load_gpr(t1
, rs
);
18496 tcg_gen_ext_tl_i64(t2
, t0
);
18497 tcg_gen_ext_tl_i64(t3
, t1
);
18498 tcg_gen_mul_i64(t2
, t2
, t3
);
18499 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
18500 tcg_gen_add_i64(t2
, t2
, t3
);
18501 tcg_temp_free_i64(t3
);
18502 gen_move_low32(cpu_LO
[acc
], t2
);
18503 gen_move_high32(cpu_HI
[acc
], t2
);
18504 tcg_temp_free_i64(t2
);
18510 int acc
= extract32(ctx
->opcode
, 14, 2);
18511 TCGv_i32 t2
= tcg_temp_new_i32();
18512 TCGv_i32 t3
= tcg_temp_new_i32();
18514 gen_load_gpr(t0
, rs
);
18515 gen_load_gpr(t1
, rt
);
18516 tcg_gen_trunc_tl_i32(t2
, t0
);
18517 tcg_gen_trunc_tl_i32(t3
, t1
);
18518 tcg_gen_muls2_i32(t2
, t3
, t2
, t3
);
18519 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
18520 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
18521 tcg_temp_free_i32(t2
);
18522 tcg_temp_free_i32(t3
);
18527 gen_load_gpr(v1_t
, rs
);
18528 tcg_gen_movi_tl(t0
, rd
>> 3);
18529 gen_helper_extr_w(t0
, t0
, v1_t
, cpu_env
);
18530 gen_store_gpr(t0
, ret
);
18534 case NM_POOL32AXF_2_8_15
:
18535 switch (extract32(ctx
->opcode
, 9, 3)) {
18537 case NM_DPAQ_SA_L_W
:
18539 case NM_DPSQ_SA_L_W
:
18540 gen_pool32axf_2_multiply(ctx
, opc
, v0_t
, v1_t
, rd
);
18545 int acc
= extract32(ctx
->opcode
, 14, 2);
18546 TCGv_i64 t2
= tcg_temp_new_i64();
18547 TCGv_i64 t3
= tcg_temp_new_i64();
18549 gen_load_gpr(t0
, rs
);
18550 gen_load_gpr(t1
, rt
);
18551 tcg_gen_ext32u_tl(t0
, t0
);
18552 tcg_gen_ext32u_tl(t1
, t1
);
18553 tcg_gen_extu_tl_i64(t2
, t0
);
18554 tcg_gen_extu_tl_i64(t3
, t1
);
18555 tcg_gen_mul_i64(t2
, t2
, t3
);
18556 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
18557 tcg_gen_add_i64(t2
, t2
, t3
);
18558 tcg_temp_free_i64(t3
);
18559 gen_move_low32(cpu_LO
[acc
], t2
);
18560 gen_move_high32(cpu_HI
[acc
], t2
);
18561 tcg_temp_free_i64(t2
);
18567 int acc
= extract32(ctx
->opcode
, 14, 2);
18568 TCGv_i32 t2
= tcg_temp_new_i32();
18569 TCGv_i32 t3
= tcg_temp_new_i32();
18571 gen_load_gpr(t0
, rs
);
18572 gen_load_gpr(t1
, rt
);
18573 tcg_gen_trunc_tl_i32(t2
, t0
);
18574 tcg_gen_trunc_tl_i32(t3
, t1
);
18575 tcg_gen_mulu2_i32(t2
, t3
, t2
, t3
);
18576 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
18577 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
18578 tcg_temp_free_i32(t2
);
18579 tcg_temp_free_i32(t3
);
18584 tcg_gen_movi_tl(t0
, rd
>> 3);
18585 gen_helper_extr_r_w(t0
, t0
, v1_t
, cpu_env
);
18586 gen_store_gpr(t0
, ret
);
18589 gen_reserved_instruction(ctx
);
18593 case NM_POOL32AXF_2_16_23
:
18594 switch (extract32(ctx
->opcode
, 9, 3)) {
18595 case NM_DPAU_H_QBL
:
18596 case NM_DPAQX_S_W_PH
:
18597 case NM_DPSU_H_QBL
:
18598 case NM_DPSQX_S_W_PH
:
18599 case NM_MULSA_W_PH
:
18600 gen_pool32axf_2_multiply(ctx
, opc
, v0_t
, v1_t
, rd
);
18604 tcg_gen_movi_tl(t0
, rd
>> 3);
18605 gen_helper_extp(t0
, t0
, v1_t
, cpu_env
);
18606 gen_store_gpr(t0
, ret
);
18611 int acc
= extract32(ctx
->opcode
, 14, 2);
18612 TCGv_i64 t2
= tcg_temp_new_i64();
18613 TCGv_i64 t3
= tcg_temp_new_i64();
18615 gen_load_gpr(t0
, rs
);
18616 gen_load_gpr(t1
, rt
);
18617 tcg_gen_ext_tl_i64(t2
, t0
);
18618 tcg_gen_ext_tl_i64(t3
, t1
);
18619 tcg_gen_mul_i64(t2
, t2
, t3
);
18620 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
18621 tcg_gen_sub_i64(t2
, t3
, t2
);
18622 tcg_temp_free_i64(t3
);
18623 gen_move_low32(cpu_LO
[acc
], t2
);
18624 gen_move_high32(cpu_HI
[acc
], t2
);
18625 tcg_temp_free_i64(t2
);
18628 case NM_EXTRV_RS_W
:
18630 tcg_gen_movi_tl(t0
, rd
>> 3);
18631 gen_helper_extr_rs_w(t0
, t0
, v1_t
, cpu_env
);
18632 gen_store_gpr(t0
, ret
);
18636 case NM_POOL32AXF_2_24_31
:
18637 switch (extract32(ctx
->opcode
, 9, 3)) {
18638 case NM_DPAU_H_QBR
:
18639 case NM_DPAQX_SA_W_PH
:
18640 case NM_DPSU_H_QBR
:
18641 case NM_DPSQX_SA_W_PH
:
18642 case NM_MULSAQ_S_W_PH
:
18643 gen_pool32axf_2_multiply(ctx
, opc
, v0_t
, v1_t
, rd
);
18647 tcg_gen_movi_tl(t0
, rd
>> 3);
18648 gen_helper_extpdp(t0
, t0
, v1_t
, cpu_env
);
18649 gen_store_gpr(t0
, ret
);
18654 int acc
= extract32(ctx
->opcode
, 14, 2);
18655 TCGv_i64 t2
= tcg_temp_new_i64();
18656 TCGv_i64 t3
= tcg_temp_new_i64();
18658 gen_load_gpr(t0
, rs
);
18659 gen_load_gpr(t1
, rt
);
18660 tcg_gen_ext32u_tl(t0
, t0
);
18661 tcg_gen_ext32u_tl(t1
, t1
);
18662 tcg_gen_extu_tl_i64(t2
, t0
);
18663 tcg_gen_extu_tl_i64(t3
, t1
);
18664 tcg_gen_mul_i64(t2
, t2
, t3
);
18665 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
18666 tcg_gen_sub_i64(t2
, t3
, t2
);
18667 tcg_temp_free_i64(t3
);
18668 gen_move_low32(cpu_LO
[acc
], t2
);
18669 gen_move_high32(cpu_HI
[acc
], t2
);
18670 tcg_temp_free_i64(t2
);
18675 tcg_gen_movi_tl(t0
, rd
>> 3);
18676 gen_helper_extr_s_h(t0
, t0
, v0_t
, cpu_env
);
18677 gen_store_gpr(t0
, ret
);
18682 gen_reserved_instruction(ctx
);
18689 tcg_temp_free(v0_t
);
18690 tcg_temp_free(v1_t
);
18693 static void gen_pool32axf_4_nanomips_insn(DisasContext
*ctx
, uint32_t opc
,
18697 TCGv t0
= tcg_temp_new();
18698 TCGv v0_t
= tcg_temp_new();
18700 gen_load_gpr(v0_t
, rs
);
18705 gen_helper_absq_s_qb(v0_t
, v0_t
, cpu_env
);
18706 gen_store_gpr(v0_t
, ret
);
18710 gen_helper_absq_s_ph(v0_t
, v0_t
, cpu_env
);
18711 gen_store_gpr(v0_t
, ret
);
18715 gen_helper_absq_s_w(v0_t
, v0_t
, cpu_env
);
18716 gen_store_gpr(v0_t
, ret
);
18718 case NM_PRECEQ_W_PHL
:
18720 tcg_gen_andi_tl(v0_t
, v0_t
, 0xFFFF0000);
18721 tcg_gen_ext32s_tl(v0_t
, v0_t
);
18722 gen_store_gpr(v0_t
, ret
);
18724 case NM_PRECEQ_W_PHR
:
18726 tcg_gen_andi_tl(v0_t
, v0_t
, 0x0000FFFF);
18727 tcg_gen_shli_tl(v0_t
, v0_t
, 16);
18728 tcg_gen_ext32s_tl(v0_t
, v0_t
);
18729 gen_store_gpr(v0_t
, ret
);
18731 case NM_PRECEQU_PH_QBL
:
18733 gen_helper_precequ_ph_qbl(v0_t
, v0_t
);
18734 gen_store_gpr(v0_t
, ret
);
18736 case NM_PRECEQU_PH_QBR
:
18738 gen_helper_precequ_ph_qbr(v0_t
, v0_t
);
18739 gen_store_gpr(v0_t
, ret
);
18741 case NM_PRECEQU_PH_QBLA
:
18743 gen_helper_precequ_ph_qbla(v0_t
, v0_t
);
18744 gen_store_gpr(v0_t
, ret
);
18746 case NM_PRECEQU_PH_QBRA
:
18748 gen_helper_precequ_ph_qbra(v0_t
, v0_t
);
18749 gen_store_gpr(v0_t
, ret
);
18751 case NM_PRECEU_PH_QBL
:
18753 gen_helper_preceu_ph_qbl(v0_t
, v0_t
);
18754 gen_store_gpr(v0_t
, ret
);
18756 case NM_PRECEU_PH_QBR
:
18758 gen_helper_preceu_ph_qbr(v0_t
, v0_t
);
18759 gen_store_gpr(v0_t
, ret
);
18761 case NM_PRECEU_PH_QBLA
:
18763 gen_helper_preceu_ph_qbla(v0_t
, v0_t
);
18764 gen_store_gpr(v0_t
, ret
);
18766 case NM_PRECEU_PH_QBRA
:
18768 gen_helper_preceu_ph_qbra(v0_t
, v0_t
);
18769 gen_store_gpr(v0_t
, ret
);
18773 tcg_gen_ext16u_tl(v0_t
, v0_t
);
18774 tcg_gen_shli_tl(t0
, v0_t
, 16);
18775 tcg_gen_or_tl(v0_t
, v0_t
, t0
);
18776 tcg_gen_ext32s_tl(v0_t
, v0_t
);
18777 gen_store_gpr(v0_t
, ret
);
18781 tcg_gen_ext8u_tl(v0_t
, v0_t
);
18782 tcg_gen_shli_tl(t0
, v0_t
, 8);
18783 tcg_gen_or_tl(v0_t
, v0_t
, t0
);
18784 tcg_gen_shli_tl(t0
, v0_t
, 16);
18785 tcg_gen_or_tl(v0_t
, v0_t
, t0
);
18786 tcg_gen_ext32s_tl(v0_t
, v0_t
);
18787 gen_store_gpr(v0_t
, ret
);
18791 gen_helper_bitrev(v0_t
, v0_t
);
18792 gen_store_gpr(v0_t
, ret
);
18797 TCGv tv0
= tcg_temp_new();
18799 gen_load_gpr(tv0
, rt
);
18800 gen_helper_insv(v0_t
, cpu_env
, v0_t
, tv0
);
18801 gen_store_gpr(v0_t
, ret
);
18802 tcg_temp_free(tv0
);
18805 case NM_RADDU_W_QB
:
18807 gen_helper_raddu_w_qb(v0_t
, v0_t
);
18808 gen_store_gpr(v0_t
, ret
);
18811 gen_bitswap(ctx
, OPC_BITSWAP
, ret
, rs
);
18815 gen_cl(ctx
, OPC_CLO
, ret
, rs
);
18819 gen_cl(ctx
, OPC_CLZ
, ret
, rs
);
18822 gen_bshfl(ctx
, OPC_WSBH
, ret
, rs
);
18825 gen_reserved_instruction(ctx
);
18829 tcg_temp_free(v0_t
);
18833 static void gen_pool32axf_7_nanomips_insn(DisasContext
*ctx
, uint32_t opc
,
18834 int rt
, int rs
, int rd
)
18836 TCGv t0
= tcg_temp_new();
18837 TCGv rs_t
= tcg_temp_new();
18839 gen_load_gpr(rs_t
, rs
);
18844 tcg_gen_movi_tl(t0
, rd
>> 2);
18845 switch (extract32(ctx
->opcode
, 12, 1)) {
18848 gen_helper_shra_qb(t0
, t0
, rs_t
);
18849 gen_store_gpr(t0
, rt
);
18853 gen_helper_shra_r_qb(t0
, t0
, rs_t
);
18854 gen_store_gpr(t0
, rt
);
18860 tcg_gen_movi_tl(t0
, rd
>> 1);
18861 gen_helper_shrl_ph(t0
, t0
, rs_t
);
18862 gen_store_gpr(t0
, rt
);
18868 target_long result
;
18869 imm
= extract32(ctx
->opcode
, 13, 8);
18870 result
= (uint32_t)imm
<< 24 |
18871 (uint32_t)imm
<< 16 |
18872 (uint32_t)imm
<< 8 |
18874 result
= (int32_t)result
;
18875 tcg_gen_movi_tl(t0
, result
);
18876 gen_store_gpr(t0
, rt
);
18880 gen_reserved_instruction(ctx
);
18884 tcg_temp_free(rs_t
);
18888 static void gen_pool32axf_nanomips_insn(CPUMIPSState
*env
, DisasContext
*ctx
)
18890 int rt
= extract32(ctx
->opcode
, 21, 5);
18891 int rs
= extract32(ctx
->opcode
, 16, 5);
18892 int rd
= extract32(ctx
->opcode
, 11, 5);
18894 switch (extract32(ctx
->opcode
, 6, 3)) {
18895 case NM_POOL32AXF_1
:
18897 int32_t op1
= extract32(ctx
->opcode
, 9, 3);
18898 gen_pool32axf_1_nanomips_insn(ctx
, op1
, rt
, rs
, rd
);
18901 case NM_POOL32AXF_2
:
18903 int32_t op1
= extract32(ctx
->opcode
, 12, 2);
18904 gen_pool32axf_2_nanomips_insn(ctx
, op1
, rt
, rs
, rd
);
18907 case NM_POOL32AXF_4
:
18909 int32_t op1
= extract32(ctx
->opcode
, 9, 7);
18910 gen_pool32axf_4_nanomips_insn(ctx
, op1
, rt
, rs
);
18913 case NM_POOL32AXF_5
:
18914 switch (extract32(ctx
->opcode
, 9, 7)) {
18915 #ifndef CONFIG_USER_ONLY
18917 gen_cp0(env
, ctx
, OPC_TLBP
, 0, 0);
18920 gen_cp0(env
, ctx
, OPC_TLBR
, 0, 0);
18923 gen_cp0(env
, ctx
, OPC_TLBWI
, 0, 0);
18926 gen_cp0(env
, ctx
, OPC_TLBWR
, 0, 0);
18929 gen_cp0(env
, ctx
, OPC_TLBINV
, 0, 0);
18932 gen_cp0(env
, ctx
, OPC_TLBINVF
, 0, 0);
18935 check_cp0_enabled(ctx
);
18937 TCGv t0
= tcg_temp_new();
18939 save_cpu_state(ctx
, 1);
18940 gen_helper_di(t0
, cpu_env
);
18941 gen_store_gpr(t0
, rt
);
18942 /* Stop translation as we may have switched the execution mode */
18943 ctx
->base
.is_jmp
= DISAS_STOP
;
18948 check_cp0_enabled(ctx
);
18950 TCGv t0
= tcg_temp_new();
18952 save_cpu_state(ctx
, 1);
18953 gen_helper_ei(t0
, cpu_env
);
18954 gen_store_gpr(t0
, rt
);
18955 /* Stop translation as we may have switched the execution mode */
18956 ctx
->base
.is_jmp
= DISAS_STOP
;
18961 check_cp0_enabled(ctx
);
18962 gen_load_srsgpr(rs
, rt
);
18965 check_cp0_enabled(ctx
);
18966 gen_store_srsgpr(rs
, rt
);
18969 gen_cp0(env
, ctx
, OPC_WAIT
, 0, 0);
18972 gen_cp0(env
, ctx
, OPC_DERET
, 0, 0);
18975 gen_cp0(env
, ctx
, OPC_ERET
, 0, 0);
18979 gen_reserved_instruction(ctx
);
18983 case NM_POOL32AXF_7
:
18985 int32_t op1
= extract32(ctx
->opcode
, 9, 3);
18986 gen_pool32axf_7_nanomips_insn(ctx
, op1
, rt
, rs
, rd
);
18990 gen_reserved_instruction(ctx
);
18995 /* Immediate Value Compact Branches */
18996 static void gen_compute_imm_branch(DisasContext
*ctx
, uint32_t opc
,
18997 int rt
, int32_t imm
, int32_t offset
)
18999 TCGCond cond
= TCG_COND_ALWAYS
;
19000 TCGv t0
= tcg_temp_new();
19001 TCGv t1
= tcg_temp_new();
19003 gen_load_gpr(t0
, rt
);
19004 tcg_gen_movi_tl(t1
, imm
);
19005 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
19007 /* Load needed operands and calculate btarget */
19010 if (rt
== 0 && imm
== 0) {
19011 /* Unconditional branch */
19012 } else if (rt
== 0 && imm
!= 0) {
19016 cond
= TCG_COND_EQ
;
19022 if (imm
>= 32 && !(ctx
->hflags
& MIPS_HFLAG_64
)) {
19023 gen_reserved_instruction(ctx
);
19025 } else if (rt
== 0 && opc
== NM_BBEQZC
) {
19026 /* Unconditional branch */
19027 } else if (rt
== 0 && opc
== NM_BBNEZC
) {
19031 tcg_gen_shri_tl(t0
, t0
, imm
);
19032 tcg_gen_andi_tl(t0
, t0
, 1);
19033 tcg_gen_movi_tl(t1
, 0);
19034 if (opc
== NM_BBEQZC
) {
19035 cond
= TCG_COND_EQ
;
19037 cond
= TCG_COND_NE
;
19042 if (rt
== 0 && imm
== 0) {
19045 } else if (rt
== 0 && imm
!= 0) {
19046 /* Unconditional branch */
19048 cond
= TCG_COND_NE
;
19052 if (rt
== 0 && imm
== 0) {
19053 /* Unconditional branch */
19055 cond
= TCG_COND_GE
;
19059 cond
= TCG_COND_LT
;
19062 if (rt
== 0 && imm
== 0) {
19063 /* Unconditional branch */
19065 cond
= TCG_COND_GEU
;
19069 cond
= TCG_COND_LTU
;
19072 MIPS_INVAL("Immediate Value Compact branch");
19073 gen_reserved_instruction(ctx
);
19077 /* branch completion */
19078 clear_branch_hflags(ctx
);
19079 ctx
->base
.is_jmp
= DISAS_NORETURN
;
19081 if (cond
== TCG_COND_ALWAYS
) {
19082 /* Uncoditional compact branch */
19083 gen_goto_tb(ctx
, 0, ctx
->btarget
);
19085 /* Conditional compact branch */
19086 TCGLabel
*fs
= gen_new_label();
19088 tcg_gen_brcond_tl(tcg_invert_cond(cond
), t0
, t1
, fs
);
19090 gen_goto_tb(ctx
, 1, ctx
->btarget
);
19093 gen_goto_tb(ctx
, 0, ctx
->base
.pc_next
+ 4);
19101 /* P.BALRSC type nanoMIPS R6 branches: BALRSC and BRSC */
19102 static void gen_compute_nanomips_pbalrsc_branch(DisasContext
*ctx
, int rs
,
19105 TCGv t0
= tcg_temp_new();
19106 TCGv t1
= tcg_temp_new();
19109 gen_load_gpr(t0
, rs
);
19113 tcg_gen_movi_tl(cpu_gpr
[rt
], ctx
->base
.pc_next
+ 4);
19116 /* calculate btarget */
19117 tcg_gen_shli_tl(t0
, t0
, 1);
19118 tcg_gen_movi_tl(t1
, ctx
->base
.pc_next
+ 4);
19119 gen_op_addr_add(ctx
, btarget
, t1
, t0
);
19121 /* branch completion */
19122 clear_branch_hflags(ctx
);
19123 ctx
->base
.is_jmp
= DISAS_NORETURN
;
19125 /* unconditional branch to register */
19126 tcg_gen_mov_tl(cpu_PC
, btarget
);
19127 tcg_gen_lookup_and_goto_ptr();
19133 /* nanoMIPS Branches */
19134 static void gen_compute_compact_branch_nm(DisasContext
*ctx
, uint32_t opc
,
19135 int rs
, int rt
, int32_t offset
)
19137 int bcond_compute
= 0;
19138 TCGv t0
= tcg_temp_new();
19139 TCGv t1
= tcg_temp_new();
19141 /* Load needed operands and calculate btarget */
19143 /* compact branch */
19146 gen_load_gpr(t0
, rs
);
19147 gen_load_gpr(t1
, rt
);
19149 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
19153 if (rs
== 0 || rs
== rt
) {
19154 /* OPC_BLEZALC, OPC_BGEZALC */
19155 /* OPC_BGTZALC, OPC_BLTZALC */
19156 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 4);
19158 gen_load_gpr(t0
, rs
);
19159 gen_load_gpr(t1
, rt
);
19161 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
19164 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
19168 /* OPC_BEQZC, OPC_BNEZC */
19169 gen_load_gpr(t0
, rs
);
19171 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
19173 /* OPC_JIC, OPC_JIALC */
19174 TCGv tbase
= tcg_temp_new();
19175 TCGv toffset
= tcg_temp_new();
19177 gen_load_gpr(tbase
, rt
);
19178 tcg_gen_movi_tl(toffset
, offset
);
19179 gen_op_addr_add(ctx
, btarget
, tbase
, toffset
);
19180 tcg_temp_free(tbase
);
19181 tcg_temp_free(toffset
);
19185 MIPS_INVAL("Compact branch/jump");
19186 gen_reserved_instruction(ctx
);
19190 if (bcond_compute
== 0) {
19191 /* Uncoditional compact branch */
19194 gen_goto_tb(ctx
, 0, ctx
->btarget
);
19197 MIPS_INVAL("Compact branch/jump");
19198 gen_reserved_instruction(ctx
);
19202 /* Conditional compact branch */
19203 TCGLabel
*fs
= gen_new_label();
19207 if (rs
== 0 && rt
!= 0) {
19209 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE
), t1
, 0, fs
);
19210 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
19212 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE
), t1
, 0, fs
);
19215 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU
), t0
, t1
, fs
);
19219 if (rs
== 0 && rt
!= 0) {
19221 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT
), t1
, 0, fs
);
19222 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
19224 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT
), t1
, 0, fs
);
19227 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU
), t0
, t1
, fs
);
19231 if (rs
== 0 && rt
!= 0) {
19233 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE
), t1
, 0, fs
);
19234 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
19236 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE
), t1
, 0, fs
);
19239 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE
), t0
, t1
, fs
);
19243 if (rs
== 0 && rt
!= 0) {
19245 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT
), t1
, 0, fs
);
19246 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
19248 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT
), t1
, 0, fs
);
19251 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT
), t0
, t1
, fs
);
19255 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ
), t0
, 0, fs
);
19258 MIPS_INVAL("Compact conditional branch/jump");
19259 gen_reserved_instruction(ctx
);
19263 /* branch completion */
19264 clear_branch_hflags(ctx
);
19265 ctx
->base
.is_jmp
= DISAS_NORETURN
;
19267 /* Generating branch here as compact branches don't have delay slot */
19268 gen_goto_tb(ctx
, 1, ctx
->btarget
);
19271 gen_goto_tb(ctx
, 0, ctx
->base
.pc_next
+ 4);
19280 /* nanoMIPS CP1 Branches */
19281 static void gen_compute_branch_cp1_nm(DisasContext
*ctx
, uint32_t op
,
19282 int32_t ft
, int32_t offset
)
19284 target_ulong btarget
;
19285 TCGv_i64 t0
= tcg_temp_new_i64();
19287 gen_load_fpr64(ctx
, t0
, ft
);
19288 tcg_gen_andi_i64(t0
, t0
, 1);
19290 btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
19294 tcg_gen_xori_i64(t0
, t0
, 1);
19295 ctx
->hflags
|= MIPS_HFLAG_BC
;
19298 /* t0 already set */
19299 ctx
->hflags
|= MIPS_HFLAG_BC
;
19302 MIPS_INVAL("cp1 cond branch");
19303 gen_reserved_instruction(ctx
);
19307 tcg_gen_trunc_i64_tl(bcond
, t0
);
19309 ctx
->btarget
= btarget
;
19312 tcg_temp_free_i64(t0
);
19316 static void gen_p_lsx(DisasContext
*ctx
, int rd
, int rs
, int rt
)
19319 t0
= tcg_temp_new();
19320 t1
= tcg_temp_new();
19322 gen_load_gpr(t0
, rs
);
19323 gen_load_gpr(t1
, rt
);
19325 if ((extract32(ctx
->opcode
, 6, 1)) == 1) {
19326 /* PP.LSXS instructions require shifting */
19327 switch (extract32(ctx
->opcode
, 7, 4)) {
19333 tcg_gen_shli_tl(t0
, t0
, 1);
19341 tcg_gen_shli_tl(t0
, t0
, 2);
19345 tcg_gen_shli_tl(t0
, t0
, 3);
19349 gen_op_addr_add(ctx
, t0
, t0
, t1
);
19351 switch (extract32(ctx
->opcode
, 7, 4)) {
19353 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
,
19355 gen_store_gpr(t0
, rd
);
19359 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
,
19361 gen_store_gpr(t0
, rd
);
19365 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
,
19367 gen_store_gpr(t0
, rd
);
19370 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
,
19372 gen_store_gpr(t0
, rd
);
19376 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
,
19378 gen_store_gpr(t0
, rd
);
19382 gen_load_gpr(t1
, rd
);
19383 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
,
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
,
19401 /*case NM_LWC1XS:*/
19403 /*case NM_LDC1XS:*/
19405 /*case NM_SWC1XS:*/
19407 /*case NM_SDC1XS:*/
19408 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
19409 check_cp1_enabled(ctx
);
19410 switch (extract32(ctx
->opcode
, 7, 4)) {
19412 /*case NM_LWC1XS:*/
19413 gen_flt_ldst(ctx
, OPC_LWC1
, rd
, t0
);
19416 /*case NM_LDC1XS:*/
19417 gen_flt_ldst(ctx
, OPC_LDC1
, rd
, t0
);
19420 /*case NM_SWC1XS:*/
19421 gen_flt_ldst(ctx
, OPC_SWC1
, rd
, t0
);
19424 /*case NM_SDC1XS:*/
19425 gen_flt_ldst(ctx
, OPC_SDC1
, rd
, t0
);
19429 generate_exception_err(ctx
, EXCP_CpU
, 1);
19433 gen_reserved_instruction(ctx
);
19441 static void gen_pool32f_nanomips_insn(DisasContext
*ctx
)
19445 rt
= extract32(ctx
->opcode
, 21, 5);
19446 rs
= extract32(ctx
->opcode
, 16, 5);
19447 rd
= extract32(ctx
->opcode
, 11, 5);
19449 if (!(ctx
->CP0_Config1
& (1 << CP0C1_FP
))) {
19450 gen_reserved_instruction(ctx
);
19453 check_cp1_enabled(ctx
);
19454 switch (extract32(ctx
->opcode
, 0, 3)) {
19456 switch (extract32(ctx
->opcode
, 3, 7)) {
19458 gen_farith(ctx
, OPC_RINT_S
, 0, rt
, rs
, 0);
19461 gen_farith(ctx
, OPC_RINT_D
, 0, rt
, rs
, 0);
19464 gen_farith(ctx
, OPC_CLASS_S
, 0, rt
, rs
, 0);
19467 gen_farith(ctx
, OPC_CLASS_D
, 0, rt
, rs
, 0);
19470 gen_farith(ctx
, OPC_ADD_S
, rt
, rs
, rd
, 0);
19473 gen_farith(ctx
, OPC_ADD_D
, rt
, rs
, rd
, 0);
19476 gen_farith(ctx
, OPC_SUB_S
, rt
, rs
, rd
, 0);
19479 gen_farith(ctx
, OPC_SUB_D
, rt
, rs
, rd
, 0);
19482 gen_farith(ctx
, OPC_MUL_S
, rt
, rs
, rd
, 0);
19485 gen_farith(ctx
, OPC_MUL_D
, rt
, rs
, rd
, 0);
19488 gen_farith(ctx
, OPC_DIV_S
, rt
, rs
, rd
, 0);
19491 gen_farith(ctx
, OPC_DIV_D
, rt
, rs
, rd
, 0);
19494 gen_sel_s(ctx
, OPC_SELEQZ_S
, rd
, rt
, rs
);
19497 gen_sel_d(ctx
, OPC_SELEQZ_D
, rd
, rt
, rs
);
19500 gen_sel_s(ctx
, OPC_SELNEZ_S
, rd
, rt
, rs
);
19503 gen_sel_d(ctx
, OPC_SELNEZ_D
, rd
, rt
, rs
);
19506 gen_sel_s(ctx
, OPC_SEL_S
, rd
, rt
, rs
);
19509 gen_sel_d(ctx
, OPC_SEL_D
, rd
, rt
, rs
);
19512 gen_farith(ctx
, OPC_MADDF_S
, rt
, rs
, rd
, 0);
19515 gen_farith(ctx
, OPC_MADDF_D
, rt
, rs
, rd
, 0);
19518 gen_farith(ctx
, OPC_MSUBF_S
, rt
, rs
, rd
, 0);
19521 gen_farith(ctx
, OPC_MSUBF_D
, rt
, rs
, rd
, 0);
19524 gen_reserved_instruction(ctx
);
19529 switch (extract32(ctx
->opcode
, 3, 3)) {
19531 switch (extract32(ctx
->opcode
, 9, 1)) {
19533 gen_farith(ctx
, OPC_MIN_S
, rt
, rs
, rd
, 0);
19536 gen_farith(ctx
, OPC_MIN_D
, rt
, rs
, rd
, 0);
19541 switch (extract32(ctx
->opcode
, 9, 1)) {
19543 gen_farith(ctx
, OPC_MAX_S
, rt
, rs
, rd
, 0);
19546 gen_farith(ctx
, OPC_MAX_D
, rt
, rs
, rd
, 0);
19551 switch (extract32(ctx
->opcode
, 9, 1)) {
19553 gen_farith(ctx
, OPC_MINA_S
, rt
, rs
, rd
, 0);
19556 gen_farith(ctx
, OPC_MINA_D
, rt
, rs
, rd
, 0);
19561 switch (extract32(ctx
->opcode
, 9, 1)) {
19563 gen_farith(ctx
, OPC_MAXA_S
, rt
, rs
, rd
, 0);
19566 gen_farith(ctx
, OPC_MAXA_D
, rt
, rs
, rd
, 0);
19571 switch (extract32(ctx
->opcode
, 6, 8)) {
19573 gen_cp1(ctx
, OPC_CFC1
, rt
, rs
);
19576 gen_cp1(ctx
, OPC_CTC1
, rt
, rs
);
19579 gen_cp1(ctx
, OPC_MFC1
, rt
, rs
);
19582 gen_cp1(ctx
, OPC_MTC1
, rt
, rs
);
19585 gen_cp1(ctx
, OPC_MFHC1
, rt
, rs
);
19588 gen_cp1(ctx
, OPC_MTHC1
, rt
, rs
);
19591 gen_farith(ctx
, OPC_CVT_S_PL
, -1, rs
, rt
, 0);
19594 gen_farith(ctx
, OPC_CVT_S_PU
, -1, rs
, rt
, 0);
19597 switch (extract32(ctx
->opcode
, 6, 9)) {
19599 gen_farith(ctx
, OPC_CVT_L_S
, -1, rs
, rt
, 0);
19602 gen_farith(ctx
, OPC_CVT_L_D
, -1, rs
, rt
, 0);
19605 gen_farith(ctx
, OPC_CVT_W_S
, -1, rs
, rt
, 0);
19608 gen_farith(ctx
, OPC_CVT_W_D
, -1, rs
, rt
, 0);
19611 gen_farith(ctx
, OPC_RSQRT_S
, -1, rs
, rt
, 0);
19614 gen_farith(ctx
, OPC_RSQRT_D
, -1, rs
, rt
, 0);
19617 gen_farith(ctx
, OPC_SQRT_S
, -1, rs
, rt
, 0);
19620 gen_farith(ctx
, OPC_SQRT_D
, -1, rs
, rt
, 0);
19623 gen_farith(ctx
, OPC_RECIP_S
, -1, rs
, rt
, 0);
19626 gen_farith(ctx
, OPC_RECIP_D
, -1, rs
, rt
, 0);
19629 gen_farith(ctx
, OPC_FLOOR_L_S
, -1, rs
, rt
, 0);
19632 gen_farith(ctx
, OPC_FLOOR_L_D
, -1, rs
, rt
, 0);
19635 gen_farith(ctx
, OPC_FLOOR_W_S
, -1, rs
, rt
, 0);
19638 gen_farith(ctx
, OPC_FLOOR_W_D
, -1, rs
, rt
, 0);
19641 gen_farith(ctx
, OPC_CEIL_L_S
, -1, rs
, rt
, 0);
19644 gen_farith(ctx
, OPC_CEIL_L_D
, -1, rs
, rt
, 0);
19647 gen_farith(ctx
, OPC_CEIL_W_S
, -1, rs
, rt
, 0);
19650 gen_farith(ctx
, OPC_CEIL_W_D
, -1, rs
, rt
, 0);
19653 gen_farith(ctx
, OPC_TRUNC_L_S
, -1, rs
, rt
, 0);
19656 gen_farith(ctx
, OPC_TRUNC_L_D
, -1, rs
, rt
, 0);
19659 gen_farith(ctx
, OPC_TRUNC_W_S
, -1, rs
, rt
, 0);
19662 gen_farith(ctx
, OPC_TRUNC_W_D
, -1, rs
, rt
, 0);
19665 gen_farith(ctx
, OPC_ROUND_L_S
, -1, rs
, rt
, 0);
19668 gen_farith(ctx
, OPC_ROUND_L_D
, -1, rs
, rt
, 0);
19671 gen_farith(ctx
, OPC_ROUND_W_S
, -1, rs
, rt
, 0);
19674 gen_farith(ctx
, OPC_ROUND_W_D
, -1, rs
, rt
, 0);
19677 gen_farith(ctx
, OPC_MOV_S
, -1, rs
, rt
, 0);
19680 gen_farith(ctx
, OPC_MOV_D
, -1, rs
, rt
, 0);
19683 gen_farith(ctx
, OPC_ABS_S
, -1, rs
, rt
, 0);
19686 gen_farith(ctx
, OPC_ABS_D
, -1, rs
, rt
, 0);
19689 gen_farith(ctx
, OPC_NEG_S
, -1, rs
, rt
, 0);
19692 gen_farith(ctx
, OPC_NEG_D
, -1, rs
, rt
, 0);
19695 gen_farith(ctx
, OPC_CVT_D_S
, -1, rs
, rt
, 0);
19698 gen_farith(ctx
, OPC_CVT_D_W
, -1, rs
, rt
, 0);
19701 gen_farith(ctx
, OPC_CVT_D_L
, -1, rs
, rt
, 0);
19704 gen_farith(ctx
, OPC_CVT_S_D
, -1, rs
, rt
, 0);
19707 gen_farith(ctx
, OPC_CVT_S_W
, -1, rs
, rt
, 0);
19710 gen_farith(ctx
, OPC_CVT_S_L
, -1, rs
, rt
, 0);
19713 gen_reserved_instruction(ctx
);
19722 switch (extract32(ctx
->opcode
, 3, 3)) {
19723 case NM_CMP_CONDN_S
:
19724 gen_r6_cmp_s(ctx
, extract32(ctx
->opcode
, 6, 5), rt
, rs
, rd
);
19726 case NM_CMP_CONDN_D
:
19727 gen_r6_cmp_d(ctx
, extract32(ctx
->opcode
, 6, 5), rt
, rs
, rd
);
19730 gen_reserved_instruction(ctx
);
19735 gen_reserved_instruction(ctx
);
19740 static void gen_pool32a5_nanomips_insn(DisasContext
*ctx
, int opc
,
19741 int rd
, int rs
, int rt
)
19744 TCGv t0
= tcg_temp_new();
19745 TCGv v1_t
= tcg_temp_new();
19746 TCGv v2_t
= tcg_temp_new();
19748 gen_load_gpr(v1_t
, rs
);
19749 gen_load_gpr(v2_t
, rt
);
19754 gen_helper_cmp_eq_ph(v1_t
, v2_t
, cpu_env
);
19758 gen_helper_cmp_lt_ph(v1_t
, v2_t
, cpu_env
);
19762 gen_helper_cmp_le_ph(v1_t
, v2_t
, cpu_env
);
19764 case NM_CMPU_EQ_QB
:
19766 gen_helper_cmpu_eq_qb(v1_t
, v2_t
, cpu_env
);
19768 case NM_CMPU_LT_QB
:
19770 gen_helper_cmpu_lt_qb(v1_t
, v2_t
, cpu_env
);
19772 case NM_CMPU_LE_QB
:
19774 gen_helper_cmpu_le_qb(v1_t
, v2_t
, cpu_env
);
19776 case NM_CMPGU_EQ_QB
:
19778 gen_helper_cmpgu_eq_qb(v1_t
, v1_t
, v2_t
);
19779 gen_store_gpr(v1_t
, ret
);
19781 case NM_CMPGU_LT_QB
:
19783 gen_helper_cmpgu_lt_qb(v1_t
, v1_t
, v2_t
);
19784 gen_store_gpr(v1_t
, ret
);
19786 case NM_CMPGU_LE_QB
:
19788 gen_helper_cmpgu_le_qb(v1_t
, v1_t
, v2_t
);
19789 gen_store_gpr(v1_t
, ret
);
19791 case NM_CMPGDU_EQ_QB
:
19793 gen_helper_cmpgu_eq_qb(v1_t
, v1_t
, v2_t
);
19794 tcg_gen_deposit_tl(cpu_dspctrl
, cpu_dspctrl
, v1_t
, 24, 4);
19795 gen_store_gpr(v1_t
, ret
);
19797 case NM_CMPGDU_LT_QB
:
19799 gen_helper_cmpgu_lt_qb(v1_t
, v1_t
, v2_t
);
19800 tcg_gen_deposit_tl(cpu_dspctrl
, cpu_dspctrl
, v1_t
, 24, 4);
19801 gen_store_gpr(v1_t
, ret
);
19803 case NM_CMPGDU_LE_QB
:
19805 gen_helper_cmpgu_le_qb(v1_t
, v1_t
, v2_t
);
19806 tcg_gen_deposit_tl(cpu_dspctrl
, cpu_dspctrl
, v1_t
, 24, 4);
19807 gen_store_gpr(v1_t
, ret
);
19811 gen_helper_packrl_ph(v1_t
, v1_t
, v2_t
);
19812 gen_store_gpr(v1_t
, ret
);
19816 gen_helper_pick_qb(v1_t
, v1_t
, v2_t
, cpu_env
);
19817 gen_store_gpr(v1_t
, ret
);
19821 gen_helper_pick_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
19822 gen_store_gpr(v1_t
, ret
);
19826 gen_helper_addq_s_w(v1_t
, v1_t
, v2_t
, cpu_env
);
19827 gen_store_gpr(v1_t
, ret
);
19831 gen_helper_subq_s_w(v1_t
, v1_t
, v2_t
, cpu_env
);
19832 gen_store_gpr(v1_t
, ret
);
19836 gen_helper_addsc(v1_t
, v1_t
, v2_t
, cpu_env
);
19837 gen_store_gpr(v1_t
, ret
);
19841 gen_helper_addwc(v1_t
, v1_t
, v2_t
, cpu_env
);
19842 gen_store_gpr(v1_t
, ret
);
19846 switch (extract32(ctx
->opcode
, 10, 1)) {
19849 gen_helper_addq_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
19850 gen_store_gpr(v1_t
, ret
);
19854 gen_helper_addq_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
19855 gen_store_gpr(v1_t
, ret
);
19859 case NM_ADDQH_R_PH
:
19861 switch (extract32(ctx
->opcode
, 10, 1)) {
19864 gen_helper_addqh_ph(v1_t
, v1_t
, v2_t
);
19865 gen_store_gpr(v1_t
, ret
);
19869 gen_helper_addqh_r_ph(v1_t
, v1_t
, v2_t
);
19870 gen_store_gpr(v1_t
, ret
);
19876 switch (extract32(ctx
->opcode
, 10, 1)) {
19879 gen_helper_addqh_w(v1_t
, v1_t
, v2_t
);
19880 gen_store_gpr(v1_t
, ret
);
19884 gen_helper_addqh_r_w(v1_t
, v1_t
, v2_t
);
19885 gen_store_gpr(v1_t
, ret
);
19891 switch (extract32(ctx
->opcode
, 10, 1)) {
19894 gen_helper_addu_qb(v1_t
, v1_t
, v2_t
, cpu_env
);
19895 gen_store_gpr(v1_t
, ret
);
19899 gen_helper_addu_s_qb(v1_t
, v1_t
, v2_t
, cpu_env
);
19900 gen_store_gpr(v1_t
, ret
);
19906 switch (extract32(ctx
->opcode
, 10, 1)) {
19909 gen_helper_addu_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
19910 gen_store_gpr(v1_t
, ret
);
19914 gen_helper_addu_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
19915 gen_store_gpr(v1_t
, ret
);
19919 case NM_ADDUH_R_QB
:
19921 switch (extract32(ctx
->opcode
, 10, 1)) {
19924 gen_helper_adduh_qb(v1_t
, v1_t
, v2_t
);
19925 gen_store_gpr(v1_t
, ret
);
19929 gen_helper_adduh_r_qb(v1_t
, v1_t
, v2_t
);
19930 gen_store_gpr(v1_t
, ret
);
19934 case NM_SHRAV_R_PH
:
19936 switch (extract32(ctx
->opcode
, 10, 1)) {
19939 gen_helper_shra_ph(v1_t
, v1_t
, v2_t
);
19940 gen_store_gpr(v1_t
, ret
);
19944 gen_helper_shra_r_ph(v1_t
, v1_t
, v2_t
);
19945 gen_store_gpr(v1_t
, ret
);
19949 case NM_SHRAV_R_QB
:
19951 switch (extract32(ctx
->opcode
, 10, 1)) {
19954 gen_helper_shra_qb(v1_t
, v1_t
, v2_t
);
19955 gen_store_gpr(v1_t
, ret
);
19959 gen_helper_shra_r_qb(v1_t
, v1_t
, v2_t
);
19960 gen_store_gpr(v1_t
, ret
);
19966 switch (extract32(ctx
->opcode
, 10, 1)) {
19969 gen_helper_subq_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
19970 gen_store_gpr(v1_t
, ret
);
19974 gen_helper_subq_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
19975 gen_store_gpr(v1_t
, ret
);
19979 case NM_SUBQH_R_PH
:
19981 switch (extract32(ctx
->opcode
, 10, 1)) {
19984 gen_helper_subqh_ph(v1_t
, v1_t
, v2_t
);
19985 gen_store_gpr(v1_t
, ret
);
19989 gen_helper_subqh_r_ph(v1_t
, v1_t
, v2_t
);
19990 gen_store_gpr(v1_t
, ret
);
19996 switch (extract32(ctx
->opcode
, 10, 1)) {
19999 gen_helper_subqh_w(v1_t
, v1_t
, v2_t
);
20000 gen_store_gpr(v1_t
, ret
);
20004 gen_helper_subqh_r_w(v1_t
, v1_t
, v2_t
);
20005 gen_store_gpr(v1_t
, ret
);
20011 switch (extract32(ctx
->opcode
, 10, 1)) {
20014 gen_helper_subu_qb(v1_t
, v1_t
, v2_t
, cpu_env
);
20015 gen_store_gpr(v1_t
, ret
);
20019 gen_helper_subu_s_qb(v1_t
, v1_t
, v2_t
, cpu_env
);
20020 gen_store_gpr(v1_t
, ret
);
20026 switch (extract32(ctx
->opcode
, 10, 1)) {
20029 gen_helper_subu_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20030 gen_store_gpr(v1_t
, ret
);
20034 gen_helper_subu_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20035 gen_store_gpr(v1_t
, ret
);
20039 case NM_SUBUH_R_QB
:
20041 switch (extract32(ctx
->opcode
, 10, 1)) {
20044 gen_helper_subuh_qb(v1_t
, v1_t
, v2_t
);
20045 gen_store_gpr(v1_t
, ret
);
20049 gen_helper_subuh_r_qb(v1_t
, v1_t
, v2_t
);
20050 gen_store_gpr(v1_t
, ret
);
20054 case NM_SHLLV_S_PH
:
20056 switch (extract32(ctx
->opcode
, 10, 1)) {
20059 gen_helper_shll_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20060 gen_store_gpr(v1_t
, ret
);
20064 gen_helper_shll_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20065 gen_store_gpr(v1_t
, ret
);
20069 case NM_PRECR_SRA_R_PH_W
:
20071 switch (extract32(ctx
->opcode
, 10, 1)) {
20073 /* PRECR_SRA_PH_W */
20075 TCGv_i32 sa_t
= tcg_const_i32(rd
);
20076 gen_helper_precr_sra_ph_w(v1_t
, sa_t
, v1_t
,
20078 gen_store_gpr(v1_t
, rt
);
20079 tcg_temp_free_i32(sa_t
);
20083 /* PRECR_SRA_R_PH_W */
20085 TCGv_i32 sa_t
= tcg_const_i32(rd
);
20086 gen_helper_precr_sra_r_ph_w(v1_t
, sa_t
, v1_t
,
20088 gen_store_gpr(v1_t
, rt
);
20089 tcg_temp_free_i32(sa_t
);
20094 case NM_MULEU_S_PH_QBL
:
20096 gen_helper_muleu_s_ph_qbl(v1_t
, v1_t
, v2_t
, cpu_env
);
20097 gen_store_gpr(v1_t
, ret
);
20099 case NM_MULEU_S_PH_QBR
:
20101 gen_helper_muleu_s_ph_qbr(v1_t
, v1_t
, v2_t
, cpu_env
);
20102 gen_store_gpr(v1_t
, ret
);
20104 case NM_MULQ_RS_PH
:
20106 gen_helper_mulq_rs_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20107 gen_store_gpr(v1_t
, ret
);
20111 gen_helper_mulq_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20112 gen_store_gpr(v1_t
, ret
);
20116 gen_helper_mulq_rs_w(v1_t
, v1_t
, v2_t
, cpu_env
);
20117 gen_store_gpr(v1_t
, ret
);
20121 gen_helper_mulq_s_w(v1_t
, v1_t
, v2_t
, cpu_env
);
20122 gen_store_gpr(v1_t
, ret
);
20126 gen_load_gpr(t0
, rs
);
20128 tcg_gen_deposit_tl(cpu_gpr
[rt
], t0
, cpu_gpr
[rt
], rd
, 32 - rd
);
20130 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
20134 gen_helper_modsub(v1_t
, v1_t
, v2_t
);
20135 gen_store_gpr(v1_t
, ret
);
20139 gen_helper_shra_r_w(v1_t
, v1_t
, v2_t
);
20140 gen_store_gpr(v1_t
, ret
);
20144 gen_helper_shrl_ph(v1_t
, v1_t
, v2_t
);
20145 gen_store_gpr(v1_t
, ret
);
20149 gen_helper_shrl_qb(v1_t
, v1_t
, v2_t
);
20150 gen_store_gpr(v1_t
, ret
);
20154 gen_helper_shll_qb(v1_t
, v1_t
, v2_t
, cpu_env
);
20155 gen_store_gpr(v1_t
, ret
);
20159 gen_helper_shll_s_w(v1_t
, v1_t
, v2_t
, cpu_env
);
20160 gen_store_gpr(v1_t
, ret
);
20165 TCGv tv0
= tcg_temp_new();
20166 TCGv tv1
= tcg_temp_new();
20167 int16_t imm
= extract32(ctx
->opcode
, 16, 7);
20169 tcg_gen_movi_tl(tv0
, rd
>> 3);
20170 tcg_gen_movi_tl(tv1
, imm
);
20171 gen_helper_shilo(tv0
, tv1
, cpu_env
);
20174 case NM_MULEQ_S_W_PHL
:
20176 gen_helper_muleq_s_w_phl(v1_t
, v1_t
, v2_t
, cpu_env
);
20177 gen_store_gpr(v1_t
, ret
);
20179 case NM_MULEQ_S_W_PHR
:
20181 gen_helper_muleq_s_w_phr(v1_t
, v1_t
, v2_t
, cpu_env
);
20182 gen_store_gpr(v1_t
, ret
);
20186 switch (extract32(ctx
->opcode
, 10, 1)) {
20189 gen_helper_mul_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20190 gen_store_gpr(v1_t
, ret
);
20194 gen_helper_mul_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20195 gen_store_gpr(v1_t
, ret
);
20199 case NM_PRECR_QB_PH
:
20201 gen_helper_precr_qb_ph(v1_t
, v1_t
, v2_t
);
20202 gen_store_gpr(v1_t
, ret
);
20204 case NM_PRECRQ_QB_PH
:
20206 gen_helper_precrq_qb_ph(v1_t
, v1_t
, v2_t
);
20207 gen_store_gpr(v1_t
, ret
);
20209 case NM_PRECRQ_PH_W
:
20211 gen_helper_precrq_ph_w(v1_t
, v1_t
, v2_t
);
20212 gen_store_gpr(v1_t
, ret
);
20214 case NM_PRECRQ_RS_PH_W
:
20216 gen_helper_precrq_rs_ph_w(v1_t
, v1_t
, v2_t
, cpu_env
);
20217 gen_store_gpr(v1_t
, ret
);
20219 case NM_PRECRQU_S_QB_PH
:
20221 gen_helper_precrqu_s_qb_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20222 gen_store_gpr(v1_t
, ret
);
20226 tcg_gen_movi_tl(t0
, rd
);
20227 gen_helper_shra_r_w(v1_t
, t0
, v1_t
);
20228 gen_store_gpr(v1_t
, rt
);
20232 tcg_gen_movi_tl(t0
, rd
>> 1);
20233 switch (extract32(ctx
->opcode
, 10, 1)) {
20236 gen_helper_shra_ph(v1_t
, t0
, v1_t
);
20237 gen_store_gpr(v1_t
, rt
);
20241 gen_helper_shra_r_ph(v1_t
, t0
, v1_t
);
20242 gen_store_gpr(v1_t
, rt
);
20248 tcg_gen_movi_tl(t0
, rd
>> 1);
20249 switch (extract32(ctx
->opcode
, 10, 2)) {
20252 gen_helper_shll_ph(v1_t
, t0
, v1_t
, cpu_env
);
20253 gen_store_gpr(v1_t
, rt
);
20257 gen_helper_shll_s_ph(v1_t
, t0
, v1_t
, cpu_env
);
20258 gen_store_gpr(v1_t
, rt
);
20261 gen_reserved_instruction(ctx
);
20267 tcg_gen_movi_tl(t0
, rd
);
20268 gen_helper_shll_s_w(v1_t
, t0
, v1_t
, cpu_env
);
20269 gen_store_gpr(v1_t
, rt
);
20275 imm
= sextract32(ctx
->opcode
, 11, 11);
20276 imm
= (int16_t)(imm
<< 6) >> 6;
20278 tcg_gen_movi_tl(cpu_gpr
[rt
], dup_const(MO_16
, imm
));
20283 gen_reserved_instruction(ctx
);
20288 static int decode_nanomips_32_48_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
20296 insn
= translator_lduw(env
, ctx
->base
.pc_next
+ 2);
20297 ctx
->opcode
= (ctx
->opcode
<< 16) | insn
;
20299 rt
= extract32(ctx
->opcode
, 21, 5);
20300 rs
= extract32(ctx
->opcode
, 16, 5);
20301 rd
= extract32(ctx
->opcode
, 11, 5);
20303 op
= extract32(ctx
->opcode
, 26, 6);
20308 switch (extract32(ctx
->opcode
, 19, 2)) {
20311 gen_reserved_instruction(ctx
);
20314 if ((extract32(ctx
->opcode
, 18, 1)) == NM_SYSCALL
) {
20315 generate_exception_end(ctx
, EXCP_SYSCALL
);
20317 gen_reserved_instruction(ctx
);
20321 generate_exception_end(ctx
, EXCP_BREAK
);
20324 if (is_uhi(extract32(ctx
->opcode
, 0, 19))) {
20325 gen_helper_do_semihosting(cpu_env
);
20327 if (ctx
->hflags
& MIPS_HFLAG_SBRI
) {
20328 gen_reserved_instruction(ctx
);
20330 generate_exception_end(ctx
, EXCP_DBp
);
20337 imm
= extract32(ctx
->opcode
, 0, 16);
20339 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], imm
);
20341 tcg_gen_movi_tl(cpu_gpr
[rt
], imm
);
20343 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
20348 offset
= sextract32(ctx
->opcode
, 0, 1) << 21 |
20349 extract32(ctx
->opcode
, 1, 20) << 1;
20350 target_long addr
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
20351 tcg_gen_movi_tl(cpu_gpr
[rt
], addr
);
20355 switch (ctx
->opcode
& 0x07) {
20357 gen_pool32a0_nanomips_insn(env
, ctx
);
20361 int32_t op1
= extract32(ctx
->opcode
, 3, 7);
20362 gen_pool32a5_nanomips_insn(ctx
, op1
, rd
, rs
, rt
);
20366 switch (extract32(ctx
->opcode
, 3, 3)) {
20368 gen_p_lsx(ctx
, rd
, rs
, rt
);
20372 * In nanoMIPS, the shift field directly encodes the shift
20373 * amount, meaning that the supported shift values are in
20374 * the range 0 to 3 (instead of 1 to 4 in MIPSR6).
20376 gen_lsa(ctx
, rd
, rt
, rs
, extract32(ctx
->opcode
, 9, 2) - 1);
20379 gen_ext(ctx
, 32, rd
, rs
, rt
, extract32(ctx
->opcode
, 6, 5));
20382 gen_pool32axf_nanomips_insn(env
, ctx
);
20385 gen_reserved_instruction(ctx
);
20390 gen_reserved_instruction(ctx
);
20395 switch (ctx
->opcode
& 0x03) {
20398 offset
= extract32(ctx
->opcode
, 0, 21);
20399 gen_op_addr_addi(ctx
, cpu_gpr
[rt
], cpu_gpr
[28], offset
);
20403 gen_ld(ctx
, OPC_LW
, rt
, 28, extract32(ctx
->opcode
, 2, 19) << 2);
20406 gen_st(ctx
, OPC_SW
, rt
, 28, extract32(ctx
->opcode
, 2, 19) << 2);
20409 gen_reserved_instruction(ctx
);
20415 insn
= translator_lduw(env
, ctx
->base
.pc_next
+ 4);
20416 target_long addr_off
= extract32(ctx
->opcode
, 0, 16) | insn
<< 16;
20417 switch (extract32(ctx
->opcode
, 16, 5)) {
20421 tcg_gen_movi_tl(cpu_gpr
[rt
], addr_off
);
20427 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], addr_off
);
20428 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
20434 gen_op_addr_addi(ctx
, cpu_gpr
[rt
], cpu_gpr
[28], addr_off
);
20440 target_long addr
= addr_add(ctx
, ctx
->base
.pc_next
+ 6,
20443 tcg_gen_movi_tl(cpu_gpr
[rt
], addr
);
20450 t0
= tcg_temp_new();
20452 target_long addr
= addr_add(ctx
, ctx
->base
.pc_next
+ 6,
20455 tcg_gen_movi_tl(t0
, addr
);
20456 tcg_gen_qemu_ld_tl(cpu_gpr
[rt
], t0
, ctx
->mem_idx
, MO_TESL
);
20464 t0
= tcg_temp_new();
20465 t1
= tcg_temp_new();
20467 target_long addr
= addr_add(ctx
, ctx
->base
.pc_next
+ 6,
20470 tcg_gen_movi_tl(t0
, addr
);
20471 gen_load_gpr(t1
, rt
);
20473 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
20480 gen_reserved_instruction(ctx
);
20486 switch (extract32(ctx
->opcode
, 12, 4)) {
20488 gen_logic_imm(ctx
, OPC_ORI
, rt
, rs
, extract32(ctx
->opcode
, 0, 12));
20491 gen_logic_imm(ctx
, OPC_XORI
, rt
, rs
, extract32(ctx
->opcode
, 0, 12));
20494 gen_logic_imm(ctx
, OPC_ANDI
, rt
, rs
, extract32(ctx
->opcode
, 0, 12));
20497 switch (extract32(ctx
->opcode
, 20, 1)) {
20499 switch (ctx
->opcode
& 3) {
20501 gen_save(ctx
, rt
, extract32(ctx
->opcode
, 16, 4),
20502 extract32(ctx
->opcode
, 2, 1),
20503 extract32(ctx
->opcode
, 3, 9) << 3);
20506 case NM_RESTORE_JRC
:
20507 gen_restore(ctx
, rt
, extract32(ctx
->opcode
, 16, 4),
20508 extract32(ctx
->opcode
, 2, 1),
20509 extract32(ctx
->opcode
, 3, 9) << 3);
20510 if ((ctx
->opcode
& 3) == NM_RESTORE_JRC
) {
20511 gen_compute_branch_nm(ctx
, OPC_JR
, 2, 31, 0, 0);
20515 gen_reserved_instruction(ctx
);
20520 gen_reserved_instruction(ctx
);
20525 gen_slt_imm(ctx
, OPC_SLTI
, rt
, rs
, extract32(ctx
->opcode
, 0, 12));
20528 gen_slt_imm(ctx
, OPC_SLTIU
, rt
, rs
, extract32(ctx
->opcode
, 0, 12));
20532 TCGv t0
= tcg_temp_new();
20534 imm
= extract32(ctx
->opcode
, 0, 12);
20535 gen_load_gpr(t0
, rs
);
20536 tcg_gen_setcondi_tl(TCG_COND_EQ
, t0
, t0
, imm
);
20537 gen_store_gpr(t0
, rt
);
20543 imm
= (int16_t) extract32(ctx
->opcode
, 0, 12);
20544 gen_arith_imm(ctx
, OPC_ADDIU
, rt
, rs
, -imm
);
20548 int shift
= extract32(ctx
->opcode
, 0, 5);
20549 switch (extract32(ctx
->opcode
, 5, 4)) {
20551 if (rt
== 0 && shift
== 0) {
20553 } else if (rt
== 0 && shift
== 3) {
20554 /* EHB - treat as NOP */
20555 } else if (rt
== 0 && shift
== 5) {
20556 /* PAUSE - treat as NOP */
20557 } else if (rt
== 0 && shift
== 6) {
20559 gen_sync(extract32(ctx
->opcode
, 16, 5));
20562 gen_shift_imm(ctx
, OPC_SLL
, rt
, rs
,
20563 extract32(ctx
->opcode
, 0, 5));
20567 gen_shift_imm(ctx
, OPC_SRL
, rt
, rs
,
20568 extract32(ctx
->opcode
, 0, 5));
20571 gen_shift_imm(ctx
, OPC_SRA
, rt
, rs
,
20572 extract32(ctx
->opcode
, 0, 5));
20575 gen_shift_imm(ctx
, OPC_ROTR
, rt
, rs
,
20576 extract32(ctx
->opcode
, 0, 5));
20584 TCGv t0
= tcg_temp_new();
20585 TCGv_i32 shift
= tcg_const_i32(extract32(ctx
->opcode
, 0, 5));
20586 TCGv_i32 shiftx
= tcg_const_i32(extract32(ctx
->opcode
, 7, 4)
20588 TCGv_i32 stripe
= tcg_const_i32(extract32(ctx
->opcode
, 6, 1));
20590 gen_load_gpr(t0
, rs
);
20591 gen_helper_rotx(cpu_gpr
[rt
], t0
, shift
, shiftx
, stripe
);
20594 tcg_temp_free_i32(shift
);
20595 tcg_temp_free_i32(shiftx
);
20596 tcg_temp_free_i32(stripe
);
20600 switch (((ctx
->opcode
>> 10) & 2) |
20601 (extract32(ctx
->opcode
, 5, 1))) {
20604 gen_bitops(ctx
, OPC_INS
, rt
, rs
, extract32(ctx
->opcode
, 0, 5),
20605 extract32(ctx
->opcode
, 6, 5));
20608 gen_reserved_instruction(ctx
);
20613 switch (((ctx
->opcode
>> 10) & 2) |
20614 (extract32(ctx
->opcode
, 5, 1))) {
20617 gen_bitops(ctx
, OPC_EXT
, rt
, rs
, extract32(ctx
->opcode
, 0, 5),
20618 extract32(ctx
->opcode
, 6, 5));
20621 gen_reserved_instruction(ctx
);
20626 gen_reserved_instruction(ctx
);
20631 gen_pool32f_nanomips_insn(ctx
);
20636 switch (extract32(ctx
->opcode
, 1, 1)) {
20639 tcg_gen_movi_tl(cpu_gpr
[rt
],
20640 sextract32(ctx
->opcode
, 0, 1) << 31 |
20641 extract32(ctx
->opcode
, 2, 10) << 21 |
20642 extract32(ctx
->opcode
, 12, 9) << 12);
20647 offset
= sextract32(ctx
->opcode
, 0, 1) << 31 |
20648 extract32(ctx
->opcode
, 2, 10) << 21 |
20649 extract32(ctx
->opcode
, 12, 9) << 12;
20651 addr
= ~0xFFF & addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
20652 tcg_gen_movi_tl(cpu_gpr
[rt
], addr
);
20659 uint32_t u
= extract32(ctx
->opcode
, 0, 18);
20661 switch (extract32(ctx
->opcode
, 18, 3)) {
20663 gen_ld(ctx
, OPC_LB
, rt
, 28, u
);
20666 gen_st(ctx
, OPC_SB
, rt
, 28, u
);
20669 gen_ld(ctx
, OPC_LBU
, rt
, 28, u
);
20673 gen_op_addr_addi(ctx
, cpu_gpr
[rt
], cpu_gpr
[28], u
);
20678 switch (ctx
->opcode
& 1) {
20680 gen_ld(ctx
, OPC_LH
, rt
, 28, u
);
20683 gen_ld(ctx
, OPC_LHU
, rt
, 28, u
);
20689 switch (ctx
->opcode
& 1) {
20691 gen_st(ctx
, OPC_SH
, rt
, 28, u
);
20694 gen_reserved_instruction(ctx
);
20700 switch (ctx
->opcode
& 0x3) {
20702 gen_cop1_ldst(ctx
, OPC_LWC1
, rt
, 28, u
);
20705 gen_cop1_ldst(ctx
, OPC_LDC1
, rt
, 28, u
);
20708 gen_cop1_ldst(ctx
, OPC_SWC1
, rt
, 28, u
);
20711 gen_cop1_ldst(ctx
, OPC_SDC1
, rt
, 28, u
);
20716 gen_reserved_instruction(ctx
);
20723 uint32_t u
= extract32(ctx
->opcode
, 0, 12);
20725 switch (extract32(ctx
->opcode
, 12, 4)) {
20730 * Break the TB to be able to sync copied instructions
20733 ctx
->base
.is_jmp
= DISAS_STOP
;
20736 /* Treat as NOP. */
20740 gen_ld(ctx
, OPC_LB
, rt
, rs
, u
);
20743 gen_ld(ctx
, OPC_LH
, rt
, rs
, u
);
20746 gen_ld(ctx
, OPC_LW
, rt
, rs
, u
);
20749 gen_ld(ctx
, OPC_LBU
, rt
, rs
, u
);
20752 gen_ld(ctx
, OPC_LHU
, rt
, rs
, u
);
20755 gen_st(ctx
, OPC_SB
, rt
, rs
, u
);
20758 gen_st(ctx
, OPC_SH
, rt
, rs
, u
);
20761 gen_st(ctx
, OPC_SW
, rt
, rs
, u
);
20764 gen_cop1_ldst(ctx
, OPC_LWC1
, rt
, rs
, u
);
20767 gen_cop1_ldst(ctx
, OPC_LDC1
, rt
, rs
, u
);
20770 gen_cop1_ldst(ctx
, OPC_SWC1
, rt
, rs
, u
);
20773 gen_cop1_ldst(ctx
, OPC_SDC1
, rt
, rs
, u
);
20776 gen_reserved_instruction(ctx
);
20783 int32_t s
= (sextract32(ctx
->opcode
, 15, 1) << 8) |
20784 extract32(ctx
->opcode
, 0, 8);
20786 switch (extract32(ctx
->opcode
, 8, 3)) {
20788 switch (extract32(ctx
->opcode
, 11, 4)) {
20790 gen_ld(ctx
, OPC_LB
, rt
, rs
, s
);
20793 gen_ld(ctx
, OPC_LH
, rt
, rs
, s
);
20796 gen_ld(ctx
, OPC_LW
, rt
, rs
, s
);
20799 gen_ld(ctx
, OPC_LBU
, rt
, rs
, s
);
20802 gen_ld(ctx
, OPC_LHU
, rt
, rs
, s
);
20805 gen_st(ctx
, OPC_SB
, rt
, rs
, s
);
20808 gen_st(ctx
, OPC_SH
, rt
, rs
, s
);
20811 gen_st(ctx
, OPC_SW
, rt
, rs
, s
);
20814 gen_cop1_ldst(ctx
, OPC_LWC1
, rt
, rs
, s
);
20817 gen_cop1_ldst(ctx
, OPC_LDC1
, rt
, rs
, s
);
20820 gen_cop1_ldst(ctx
, OPC_SWC1
, rt
, rs
, s
);
20823 gen_cop1_ldst(ctx
, OPC_SDC1
, rt
, rs
, s
);
20829 * Break the TB to be able to sync copied instructions
20832 ctx
->base
.is_jmp
= DISAS_STOP
;
20835 /* Treat as NOP. */
20839 gen_reserved_instruction(ctx
);
20844 switch (extract32(ctx
->opcode
, 11, 4)) {
20849 TCGv t0
= tcg_temp_new();
20850 TCGv t1
= tcg_temp_new();
20852 gen_base_offset_addr(ctx
, t0
, rs
, s
);
20854 switch (extract32(ctx
->opcode
, 11, 4)) {
20856 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESW
|
20858 gen_store_gpr(t0
, rt
);
20861 gen_load_gpr(t1
, rt
);
20862 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUW
|
20871 switch (ctx
->opcode
& 0x03) {
20873 gen_ld(ctx
, OPC_LL
, rt
, rs
, s
);
20877 gen_llwp(ctx
, rs
, 0, rt
, extract32(ctx
->opcode
, 3, 5));
20882 switch (ctx
->opcode
& 0x03) {
20884 gen_st_cond(ctx
, rt
, rs
, s
, MO_TESL
, false);
20888 gen_scwp(ctx
, rs
, 0, rt
, extract32(ctx
->opcode
, 3, 5),
20894 check_cp0_enabled(ctx
);
20895 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
20896 gen_cache_operation(ctx
, rt
, rs
, s
);
20902 switch (extract32(ctx
->opcode
, 11, 4)) {
20905 check_cp0_enabled(ctx
);
20906 gen_ld(ctx
, OPC_LBE
, rt
, rs
, s
);
20910 check_cp0_enabled(ctx
);
20911 gen_st(ctx
, OPC_SBE
, rt
, rs
, s
);
20915 check_cp0_enabled(ctx
);
20916 gen_ld(ctx
, OPC_LBUE
, rt
, rs
, s
);
20920 /* case NM_SYNCIE */
20922 check_cp0_enabled(ctx
);
20924 * Break the TB to be able to sync copied instructions
20927 ctx
->base
.is_jmp
= DISAS_STOP
;
20929 /* case NM_PREFE */
20931 check_cp0_enabled(ctx
);
20932 /* Treat as NOP. */
20937 check_cp0_enabled(ctx
);
20938 gen_ld(ctx
, OPC_LHE
, rt
, rs
, s
);
20942 check_cp0_enabled(ctx
);
20943 gen_st(ctx
, OPC_SHE
, rt
, rs
, s
);
20947 check_cp0_enabled(ctx
);
20948 gen_ld(ctx
, OPC_LHUE
, rt
, rs
, s
);
20952 check_cp0_enabled(ctx
);
20953 check_nms_dl_il_sl_tl_l2c(ctx
);
20954 gen_cache_operation(ctx
, rt
, rs
, s
);
20958 check_cp0_enabled(ctx
);
20959 gen_ld(ctx
, OPC_LWE
, rt
, rs
, s
);
20963 check_cp0_enabled(ctx
);
20964 gen_st(ctx
, OPC_SWE
, rt
, rs
, s
);
20967 switch (extract32(ctx
->opcode
, 2, 2)) {
20971 check_cp0_enabled(ctx
);
20972 gen_ld(ctx
, OPC_LLE
, rt
, rs
, s
);
20977 check_cp0_enabled(ctx
);
20978 gen_llwp(ctx
, rs
, 0, rt
, extract32(ctx
->opcode
, 3, 5));
20981 gen_reserved_instruction(ctx
);
20986 switch (extract32(ctx
->opcode
, 2, 2)) {
20990 check_cp0_enabled(ctx
);
20991 gen_st_cond(ctx
, rt
, rs
, s
, MO_TESL
, true);
20996 check_cp0_enabled(ctx
);
20997 gen_scwp(ctx
, rs
, 0, rt
, extract32(ctx
->opcode
, 3, 5),
21001 gen_reserved_instruction(ctx
);
21011 int count
= extract32(ctx
->opcode
, 12, 3);
21014 offset
= sextract32(ctx
->opcode
, 15, 1) << 8 |
21015 extract32(ctx
->opcode
, 0, 8);
21016 TCGv va
= tcg_temp_new();
21017 TCGv t1
= tcg_temp_new();
21018 MemOp memop
= (extract32(ctx
->opcode
, 8, 3)) ==
21019 NM_P_LS_UAWM
? MO_UNALN
: 0;
21021 count
= (count
== 0) ? 8 : count
;
21022 while (counter
!= count
) {
21023 int this_rt
= ((rt
+ counter
) & 0x1f) | (rt
& 0x10);
21024 int this_offset
= offset
+ (counter
<< 2);
21026 gen_base_offset_addr(ctx
, va
, rs
, this_offset
);
21028 switch (extract32(ctx
->opcode
, 11, 1)) {
21030 tcg_gen_qemu_ld_tl(t1
, va
, ctx
->mem_idx
,
21032 gen_store_gpr(t1
, this_rt
);
21033 if ((this_rt
== rs
) &&
21034 (counter
!= (count
- 1))) {
21035 /* UNPREDICTABLE */
21039 this_rt
= (rt
== 0) ? 0 : this_rt
;
21040 gen_load_gpr(t1
, this_rt
);
21041 tcg_gen_qemu_st_tl(t1
, va
, ctx
->mem_idx
,
21052 gen_reserved_instruction(ctx
);
21060 TCGv t0
= tcg_temp_new();
21061 int32_t s
= sextract32(ctx
->opcode
, 0, 1) << 21 |
21062 extract32(ctx
->opcode
, 1, 20) << 1;
21063 rd
= (extract32(ctx
->opcode
, 24, 1)) == 0 ? 4 : 5;
21064 rt
= decode_gpr_gpr4_zero(extract32(ctx
->opcode
, 25, 1) << 3 |
21065 extract32(ctx
->opcode
, 21, 3));
21066 gen_load_gpr(t0
, rt
);
21067 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
21068 gen_compute_branch_nm(ctx
, OPC_BGEZAL
, 4, 0, 0, s
);
21074 int32_t s
= sextract32(ctx
->opcode
, 0, 1) << 25 |
21075 extract32(ctx
->opcode
, 1, 24) << 1;
21077 if ((extract32(ctx
->opcode
, 25, 1)) == 0) {
21079 gen_compute_branch_nm(ctx
, OPC_BEQ
, 4, 0, 0, s
);
21082 gen_compute_branch_nm(ctx
, OPC_BGEZAL
, 4, 0, 0, s
);
21087 switch (extract32(ctx
->opcode
, 12, 4)) {
21090 gen_compute_branch_nm(ctx
, OPC_JALR
, 4, rs
, rt
, 0);
21093 gen_compute_nanomips_pbalrsc_branch(ctx
, rs
, rt
);
21096 gen_reserved_instruction(ctx
);
21102 int32_t s
= sextract32(ctx
->opcode
, 0, 1) << 14 |
21103 extract32(ctx
->opcode
, 1, 13) << 1;
21104 switch (extract32(ctx
->opcode
, 14, 2)) {
21107 gen_compute_branch_nm(ctx
, OPC_BEQ
, 4, rs
, rt
, s
);
21110 s
= sextract32(ctx
->opcode
, 0, 1) << 14 |
21111 extract32(ctx
->opcode
, 1, 13) << 1;
21112 check_cp1_enabled(ctx
);
21113 switch (extract32(ctx
->opcode
, 16, 5)) {
21115 gen_compute_branch_cp1_nm(ctx
, OPC_BC1EQZ
, rt
, s
);
21118 gen_compute_branch_cp1_nm(ctx
, OPC_BC1NEZ
, rt
, s
);
21123 int32_t imm
= extract32(ctx
->opcode
, 1, 13) |
21124 extract32(ctx
->opcode
, 0, 1) << 13;
21126 gen_compute_branch_nm(ctx
, OPC_BPOSGE32
, 4, -1, -2,
21131 gen_reserved_instruction(ctx
);
21137 gen_compute_compact_branch_nm(ctx
, OPC_BC
, rs
, rt
, s
);
21139 gen_compute_compact_branch_nm(ctx
, OPC_BGEC
, rs
, rt
, s
);
21143 if (rs
== rt
|| rt
== 0) {
21144 gen_compute_compact_branch_nm(ctx
, OPC_BC
, 0, 0, s
);
21145 } else if (rs
== 0) {
21146 gen_compute_compact_branch_nm(ctx
, OPC_BEQZC
, rt
, 0, s
);
21148 gen_compute_compact_branch_nm(ctx
, OPC_BGEUC
, rs
, rt
, s
);
21156 int32_t s
= sextract32(ctx
->opcode
, 0, 1) << 14 |
21157 extract32(ctx
->opcode
, 1, 13) << 1;
21158 switch (extract32(ctx
->opcode
, 14, 2)) {
21161 gen_compute_branch_nm(ctx
, OPC_BNE
, 4, rs
, rt
, s
);
21164 if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
21166 ctx
->hflags
|= MIPS_HFLAG_FBNSLOT
;
21168 gen_compute_compact_branch_nm(ctx
, OPC_BLTC
, rs
, rt
, s
);
21172 if (rs
== 0 || rs
== rt
) {
21174 ctx
->hflags
|= MIPS_HFLAG_FBNSLOT
;
21176 gen_compute_compact_branch_nm(ctx
, OPC_BLTUC
, rs
, rt
, s
);
21180 gen_reserved_instruction(ctx
);
21187 int32_t s
= sextract32(ctx
->opcode
, 0, 1) << 11 |
21188 extract32(ctx
->opcode
, 1, 10) << 1;
21189 uint32_t u
= extract32(ctx
->opcode
, 11, 7);
21191 gen_compute_imm_branch(ctx
, extract32(ctx
->opcode
, 18, 3),
21196 gen_reserved_instruction(ctx
);
21202 static int decode_nanomips_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
21205 int rt
= decode_gpr_gpr3(NANOMIPS_EXTRACT_RT3(ctx
->opcode
));
21206 int rs
= decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx
->opcode
));
21207 int rd
= decode_gpr_gpr3(NANOMIPS_EXTRACT_RD3(ctx
->opcode
));
21211 /* make sure instructions are on a halfword boundary */
21212 if (ctx
->base
.pc_next
& 0x1) {
21213 TCGv tmp
= tcg_const_tl(ctx
->base
.pc_next
);
21214 tcg_gen_st_tl(tmp
, cpu_env
, offsetof(CPUMIPSState
, CP0_BadVAddr
));
21215 tcg_temp_free(tmp
);
21216 generate_exception_end(ctx
, EXCP_AdEL
);
21220 op
= extract32(ctx
->opcode
, 10, 6);
21223 rt
= NANOMIPS_EXTRACT_RD5(ctx
->opcode
);
21226 rs
= NANOMIPS_EXTRACT_RS5(ctx
->opcode
);
21227 gen_arith(ctx
, OPC_ADDU
, rt
, rs
, 0);
21230 switch (extract32(ctx
->opcode
, 3, 2)) {
21231 case NM_P16_SYSCALL
:
21232 if (extract32(ctx
->opcode
, 2, 1) == 0) {
21233 generate_exception_end(ctx
, EXCP_SYSCALL
);
21235 gen_reserved_instruction(ctx
);
21239 generate_exception_end(ctx
, EXCP_BREAK
);
21242 if (is_uhi(extract32(ctx
->opcode
, 0, 3))) {
21243 gen_helper_do_semihosting(cpu_env
);
21245 if (ctx
->hflags
& MIPS_HFLAG_SBRI
) {
21246 gen_reserved_instruction(ctx
);
21248 generate_exception_end(ctx
, EXCP_DBp
);
21253 gen_reserved_instruction(ctx
);
21260 int shift
= extract32(ctx
->opcode
, 0, 3);
21262 shift
= (shift
== 0) ? 8 : shift
;
21264 switch (extract32(ctx
->opcode
, 3, 1)) {
21272 gen_shift_imm(ctx
, opc
, rt
, rs
, shift
);
21276 switch (ctx
->opcode
& 1) {
21278 gen_pool16c_nanomips_insn(ctx
);
21281 gen_ldxs(ctx
, rt
, rs
, rd
);
21286 switch (extract32(ctx
->opcode
, 6, 1)) {
21288 imm
= extract32(ctx
->opcode
, 0, 6) << 2;
21289 gen_arith_imm(ctx
, OPC_ADDIU
, rt
, 29, imm
);
21292 gen_reserved_instruction(ctx
);
21297 switch (extract32(ctx
->opcode
, 3, 1)) {
21299 imm
= extract32(ctx
->opcode
, 0, 3) << 2;
21300 gen_arith_imm(ctx
, OPC_ADDIU
, rt
, rs
, imm
);
21302 case NM_P_ADDIURS5
:
21303 rt
= extract32(ctx
->opcode
, 5, 5);
21305 /* imm = sign_extend(s[3] . s[2:0] , from_nbits = 4) */
21306 imm
= (sextract32(ctx
->opcode
, 4, 1) << 3) |
21307 (extract32(ctx
->opcode
, 0, 3));
21308 gen_arith_imm(ctx
, OPC_ADDIU
, rt
, rt
, imm
);
21314 switch (ctx
->opcode
& 0x1) {
21316 gen_arith(ctx
, OPC_ADDU
, rd
, rs
, rt
);
21319 gen_arith(ctx
, OPC_SUBU
, rd
, rs
, rt
);
21324 rt
= (extract32(ctx
->opcode
, 9, 1) << 3) |
21325 extract32(ctx
->opcode
, 5, 3);
21326 rs
= (extract32(ctx
->opcode
, 4, 1) << 3) |
21327 extract32(ctx
->opcode
, 0, 3);
21328 rt
= decode_gpr_gpr4(rt
);
21329 rs
= decode_gpr_gpr4(rs
);
21330 switch ((extract32(ctx
->opcode
, 7, 2) & 0x2) |
21331 (extract32(ctx
->opcode
, 3, 1))) {
21334 gen_arith(ctx
, OPC_ADDU
, rt
, rs
, rt
);
21338 gen_r6_muldiv(ctx
, R6_OPC_MUL
, rt
, rs
, rt
);
21341 gen_reserved_instruction(ctx
);
21347 int imm
= extract32(ctx
->opcode
, 0, 7);
21348 imm
= (imm
== 0x7f ? -1 : imm
);
21350 tcg_gen_movi_tl(cpu_gpr
[rt
], imm
);
21356 uint32_t u
= extract32(ctx
->opcode
, 0, 4);
21357 u
= (u
== 12) ? 0xff :
21358 (u
== 13) ? 0xffff : u
;
21359 gen_logic_imm(ctx
, OPC_ANDI
, rt
, rs
, u
);
21363 offset
= extract32(ctx
->opcode
, 0, 2);
21364 switch (extract32(ctx
->opcode
, 2, 2)) {
21366 gen_ld(ctx
, OPC_LB
, rt
, rs
, offset
);
21369 rt
= decode_gpr_gpr3_src_store(
21370 NANOMIPS_EXTRACT_RT3(ctx
->opcode
));
21371 gen_st(ctx
, OPC_SB
, rt
, rs
, offset
);
21374 gen_ld(ctx
, OPC_LBU
, rt
, rs
, offset
);
21377 gen_reserved_instruction(ctx
);
21382 offset
= extract32(ctx
->opcode
, 1, 2) << 1;
21383 switch ((extract32(ctx
->opcode
, 3, 1) << 1) | (ctx
->opcode
& 1)) {
21385 gen_ld(ctx
, OPC_LH
, rt
, rs
, offset
);
21388 rt
= decode_gpr_gpr3_src_store(
21389 NANOMIPS_EXTRACT_RT3(ctx
->opcode
));
21390 gen_st(ctx
, OPC_SH
, rt
, rs
, offset
);
21393 gen_ld(ctx
, OPC_LHU
, rt
, rs
, offset
);
21396 gen_reserved_instruction(ctx
);
21401 offset
= extract32(ctx
->opcode
, 0, 4) << 2;
21402 gen_ld(ctx
, OPC_LW
, rt
, rs
, offset
);
21405 rt
= NANOMIPS_EXTRACT_RD5(ctx
->opcode
);
21406 offset
= extract32(ctx
->opcode
, 0, 5) << 2;
21407 gen_ld(ctx
, OPC_LW
, rt
, 29, offset
);
21411 rt
= (extract32(ctx
->opcode
, 9, 1) << 3) |
21412 extract32(ctx
->opcode
, 5, 3);
21413 rs
= (extract32(ctx
->opcode
, 4, 1) << 3) |
21414 extract32(ctx
->opcode
, 0, 3);
21415 offset
= (extract32(ctx
->opcode
, 3, 1) << 3) |
21416 (extract32(ctx
->opcode
, 8, 1) << 2);
21417 rt
= decode_gpr_gpr4(rt
);
21418 rs
= decode_gpr_gpr4(rs
);
21419 gen_ld(ctx
, OPC_LW
, rt
, rs
, offset
);
21423 rt
= (extract32(ctx
->opcode
, 9, 1) << 3) |
21424 extract32(ctx
->opcode
, 5, 3);
21425 rs
= (extract32(ctx
->opcode
, 4, 1) << 3) |
21426 extract32(ctx
->opcode
, 0, 3);
21427 offset
= (extract32(ctx
->opcode
, 3, 1) << 3) |
21428 (extract32(ctx
->opcode
, 8, 1) << 2);
21429 rt
= decode_gpr_gpr4_zero(rt
);
21430 rs
= decode_gpr_gpr4(rs
);
21431 gen_st(ctx
, OPC_SW
, rt
, rs
, offset
);
21434 offset
= extract32(ctx
->opcode
, 0, 7) << 2;
21435 gen_ld(ctx
, OPC_LW
, rt
, 28, offset
);
21438 rt
= NANOMIPS_EXTRACT_RD5(ctx
->opcode
);
21439 offset
= extract32(ctx
->opcode
, 0, 5) << 2;
21440 gen_st(ctx
, OPC_SW
, rt
, 29, offset
);
21443 rt
= decode_gpr_gpr3_src_store(
21444 NANOMIPS_EXTRACT_RT3(ctx
->opcode
));
21445 rs
= decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx
->opcode
));
21446 offset
= extract32(ctx
->opcode
, 0, 4) << 2;
21447 gen_st(ctx
, OPC_SW
, rt
, rs
, offset
);
21450 rt
= decode_gpr_gpr3_src_store(
21451 NANOMIPS_EXTRACT_RT3(ctx
->opcode
));
21452 offset
= extract32(ctx
->opcode
, 0, 7) << 2;
21453 gen_st(ctx
, OPC_SW
, rt
, 28, offset
);
21456 gen_compute_branch_nm(ctx
, OPC_BEQ
, 2, 0, 0,
21457 (sextract32(ctx
->opcode
, 0, 1) << 10) |
21458 (extract32(ctx
->opcode
, 1, 9) << 1));
21461 gen_compute_branch_nm(ctx
, OPC_BGEZAL
, 2, 0, 0,
21462 (sextract32(ctx
->opcode
, 0, 1) << 10) |
21463 (extract32(ctx
->opcode
, 1, 9) << 1));
21466 gen_compute_branch_nm(ctx
, OPC_BEQ
, 2, rt
, 0,
21467 (sextract32(ctx
->opcode
, 0, 1) << 7) |
21468 (extract32(ctx
->opcode
, 1, 6) << 1));
21471 gen_compute_branch_nm(ctx
, OPC_BNE
, 2, rt
, 0,
21472 (sextract32(ctx
->opcode
, 0, 1) << 7) |
21473 (extract32(ctx
->opcode
, 1, 6) << 1));
21476 switch (ctx
->opcode
& 0xf) {
21479 switch (extract32(ctx
->opcode
, 4, 1)) {
21481 gen_compute_branch_nm(ctx
, OPC_JR
, 2,
21482 extract32(ctx
->opcode
, 5, 5), 0, 0);
21485 gen_compute_branch_nm(ctx
, OPC_JALR
, 2,
21486 extract32(ctx
->opcode
, 5, 5), 31, 0);
21493 uint32_t opc
= extract32(ctx
->opcode
, 4, 3) <
21494 extract32(ctx
->opcode
, 7, 3) ? OPC_BEQ
: OPC_BNE
;
21495 gen_compute_branch_nm(ctx
, opc
, 2, rs
, rt
,
21496 extract32(ctx
->opcode
, 0, 4) << 1);
21503 int count
= extract32(ctx
->opcode
, 0, 4);
21504 int u
= extract32(ctx
->opcode
, 4, 4) << 4;
21506 rt
= 30 + extract32(ctx
->opcode
, 9, 1);
21507 switch (extract32(ctx
->opcode
, 8, 1)) {
21509 gen_save(ctx
, rt
, count
, 0, u
);
21511 case NM_RESTORE_JRC16
:
21512 gen_restore(ctx
, rt
, count
, 0, u
);
21513 gen_compute_branch_nm(ctx
, OPC_JR
, 2, 31, 0, 0);
21522 static const int gpr2reg1
[] = {4, 5, 6, 7};
21523 static const int gpr2reg2
[] = {5, 6, 7, 8};
21525 int rd2
= extract32(ctx
->opcode
, 3, 1) << 1 |
21526 extract32(ctx
->opcode
, 8, 1);
21527 int r1
= gpr2reg1
[rd2
];
21528 int r2
= gpr2reg2
[rd2
];
21529 int r3
= extract32(ctx
->opcode
, 4, 1) << 3 |
21530 extract32(ctx
->opcode
, 0, 3);
21531 int r4
= extract32(ctx
->opcode
, 9, 1) << 3 |
21532 extract32(ctx
->opcode
, 5, 3);
21533 TCGv t0
= tcg_temp_new();
21534 TCGv t1
= tcg_temp_new();
21535 if (op
== NM_MOVEP
) {
21538 rs
= decode_gpr_gpr4_zero(r3
);
21539 rt
= decode_gpr_gpr4_zero(r4
);
21541 rd
= decode_gpr_gpr4(r3
);
21542 re
= decode_gpr_gpr4(r4
);
21546 gen_load_gpr(t0
, rs
);
21547 gen_load_gpr(t1
, rt
);
21548 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
21549 tcg_gen_mov_tl(cpu_gpr
[re
], t1
);
21555 return decode_nanomips_32_48_opc(env
, ctx
);
21562 /* SmartMIPS extension to MIPS32 */
21564 #if defined(TARGET_MIPS64)
21566 /* MDMX extension to MIPS64 */
21570 /* MIPSDSP functions. */
21571 static void gen_mipsdsp_ld(DisasContext
*ctx
, uint32_t opc
,
21572 int rd
, int base
, int offset
)
21577 t0
= tcg_temp_new();
21580 gen_load_gpr(t0
, offset
);
21581 } else if (offset
== 0) {
21582 gen_load_gpr(t0
, base
);
21584 gen_op_addr_add(ctx
, t0
, cpu_gpr
[base
], cpu_gpr
[offset
]);
21589 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_UB
);
21590 gen_store_gpr(t0
, rd
);
21593 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESW
);
21594 gen_store_gpr(t0
, rd
);
21597 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESL
);
21598 gen_store_gpr(t0
, rd
);
21600 #if defined(TARGET_MIPS64)
21602 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
);
21603 gen_store_gpr(t0
, rd
);
21610 static void gen_mipsdsp_arith(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
21611 int ret
, int v1
, int v2
)
21617 /* Treat as NOP. */
21621 v1_t
= tcg_temp_new();
21622 v2_t
= tcg_temp_new();
21624 gen_load_gpr(v1_t
, v1
);
21625 gen_load_gpr(v2_t
, v2
);
21628 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
21629 case OPC_MULT_G_2E
:
21633 gen_helper_adduh_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
21635 case OPC_ADDUH_R_QB
:
21636 gen_helper_adduh_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
21639 gen_helper_addqh_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
21641 case OPC_ADDQH_R_PH
:
21642 gen_helper_addqh_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
21645 gen_helper_addqh_w(cpu_gpr
[ret
], v1_t
, v2_t
);
21647 case OPC_ADDQH_R_W
:
21648 gen_helper_addqh_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
21651 gen_helper_subuh_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
21653 case OPC_SUBUH_R_QB
:
21654 gen_helper_subuh_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
21657 gen_helper_subqh_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
21659 case OPC_SUBQH_R_PH
:
21660 gen_helper_subqh_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
21663 gen_helper_subqh_w(cpu_gpr
[ret
], v1_t
, v2_t
);
21665 case OPC_SUBQH_R_W
:
21666 gen_helper_subqh_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
21670 case OPC_ABSQ_S_PH_DSP
:
21672 case OPC_ABSQ_S_QB
:
21674 gen_helper_absq_s_qb(cpu_gpr
[ret
], v2_t
, cpu_env
);
21676 case OPC_ABSQ_S_PH
:
21678 gen_helper_absq_s_ph(cpu_gpr
[ret
], v2_t
, cpu_env
);
21682 gen_helper_absq_s_w(cpu_gpr
[ret
], v2_t
, cpu_env
);
21684 case OPC_PRECEQ_W_PHL
:
21686 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0xFFFF0000);
21687 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
21689 case OPC_PRECEQ_W_PHR
:
21691 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0x0000FFFF);
21692 tcg_gen_shli_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], 16);
21693 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
21695 case OPC_PRECEQU_PH_QBL
:
21697 gen_helper_precequ_ph_qbl(cpu_gpr
[ret
], v2_t
);
21699 case OPC_PRECEQU_PH_QBR
:
21701 gen_helper_precequ_ph_qbr(cpu_gpr
[ret
], v2_t
);
21703 case OPC_PRECEQU_PH_QBLA
:
21705 gen_helper_precequ_ph_qbla(cpu_gpr
[ret
], v2_t
);
21707 case OPC_PRECEQU_PH_QBRA
:
21709 gen_helper_precequ_ph_qbra(cpu_gpr
[ret
], v2_t
);
21711 case OPC_PRECEU_PH_QBL
:
21713 gen_helper_preceu_ph_qbl(cpu_gpr
[ret
], v2_t
);
21715 case OPC_PRECEU_PH_QBR
:
21717 gen_helper_preceu_ph_qbr(cpu_gpr
[ret
], v2_t
);
21719 case OPC_PRECEU_PH_QBLA
:
21721 gen_helper_preceu_ph_qbla(cpu_gpr
[ret
], v2_t
);
21723 case OPC_PRECEU_PH_QBRA
:
21725 gen_helper_preceu_ph_qbra(cpu_gpr
[ret
], v2_t
);
21729 case OPC_ADDU_QB_DSP
:
21733 gen_helper_addq_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21735 case OPC_ADDQ_S_PH
:
21737 gen_helper_addq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21741 gen_helper_addq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21745 gen_helper_addu_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21747 case OPC_ADDU_S_QB
:
21749 gen_helper_addu_s_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21753 gen_helper_addu_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21755 case OPC_ADDU_S_PH
:
21757 gen_helper_addu_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21761 gen_helper_subq_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21763 case OPC_SUBQ_S_PH
:
21765 gen_helper_subq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21769 gen_helper_subq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21773 gen_helper_subu_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21775 case OPC_SUBU_S_QB
:
21777 gen_helper_subu_s_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21781 gen_helper_subu_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21783 case OPC_SUBU_S_PH
:
21785 gen_helper_subu_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21789 gen_helper_addsc(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21793 gen_helper_addwc(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21797 gen_helper_modsub(cpu_gpr
[ret
], v1_t
, v2_t
);
21799 case OPC_RADDU_W_QB
:
21801 gen_helper_raddu_w_qb(cpu_gpr
[ret
], v1_t
);
21805 case OPC_CMPU_EQ_QB_DSP
:
21807 case OPC_PRECR_QB_PH
:
21809 gen_helper_precr_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
21811 case OPC_PRECRQ_QB_PH
:
21813 gen_helper_precrq_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
21815 case OPC_PRECR_SRA_PH_W
:
21818 TCGv_i32 sa_t
= tcg_const_i32(v2
);
21819 gen_helper_precr_sra_ph_w(cpu_gpr
[ret
], sa_t
, v1_t
,
21821 tcg_temp_free_i32(sa_t
);
21824 case OPC_PRECR_SRA_R_PH_W
:
21827 TCGv_i32 sa_t
= tcg_const_i32(v2
);
21828 gen_helper_precr_sra_r_ph_w(cpu_gpr
[ret
], sa_t
, v1_t
,
21830 tcg_temp_free_i32(sa_t
);
21833 case OPC_PRECRQ_PH_W
:
21835 gen_helper_precrq_ph_w(cpu_gpr
[ret
], v1_t
, v2_t
);
21837 case OPC_PRECRQ_RS_PH_W
:
21839 gen_helper_precrq_rs_ph_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21841 case OPC_PRECRQU_S_QB_PH
:
21843 gen_helper_precrqu_s_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21847 #ifdef TARGET_MIPS64
21848 case OPC_ABSQ_S_QH_DSP
:
21850 case OPC_PRECEQ_L_PWL
:
21852 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0xFFFFFFFF00000000ull
);
21854 case OPC_PRECEQ_L_PWR
:
21856 tcg_gen_shli_tl(cpu_gpr
[ret
], v2_t
, 32);
21858 case OPC_PRECEQ_PW_QHL
:
21860 gen_helper_preceq_pw_qhl(cpu_gpr
[ret
], v2_t
);
21862 case OPC_PRECEQ_PW_QHR
:
21864 gen_helper_preceq_pw_qhr(cpu_gpr
[ret
], v2_t
);
21866 case OPC_PRECEQ_PW_QHLA
:
21868 gen_helper_preceq_pw_qhla(cpu_gpr
[ret
], v2_t
);
21870 case OPC_PRECEQ_PW_QHRA
:
21872 gen_helper_preceq_pw_qhra(cpu_gpr
[ret
], v2_t
);
21874 case OPC_PRECEQU_QH_OBL
:
21876 gen_helper_precequ_qh_obl(cpu_gpr
[ret
], v2_t
);
21878 case OPC_PRECEQU_QH_OBR
:
21880 gen_helper_precequ_qh_obr(cpu_gpr
[ret
], v2_t
);
21882 case OPC_PRECEQU_QH_OBLA
:
21884 gen_helper_precequ_qh_obla(cpu_gpr
[ret
], v2_t
);
21886 case OPC_PRECEQU_QH_OBRA
:
21888 gen_helper_precequ_qh_obra(cpu_gpr
[ret
], v2_t
);
21890 case OPC_PRECEU_QH_OBL
:
21892 gen_helper_preceu_qh_obl(cpu_gpr
[ret
], v2_t
);
21894 case OPC_PRECEU_QH_OBR
:
21896 gen_helper_preceu_qh_obr(cpu_gpr
[ret
], v2_t
);
21898 case OPC_PRECEU_QH_OBLA
:
21900 gen_helper_preceu_qh_obla(cpu_gpr
[ret
], v2_t
);
21902 case OPC_PRECEU_QH_OBRA
:
21904 gen_helper_preceu_qh_obra(cpu_gpr
[ret
], v2_t
);
21906 case OPC_ABSQ_S_OB
:
21908 gen_helper_absq_s_ob(cpu_gpr
[ret
], v2_t
, cpu_env
);
21910 case OPC_ABSQ_S_PW
:
21912 gen_helper_absq_s_pw(cpu_gpr
[ret
], v2_t
, cpu_env
);
21914 case OPC_ABSQ_S_QH
:
21916 gen_helper_absq_s_qh(cpu_gpr
[ret
], v2_t
, cpu_env
);
21920 case OPC_ADDU_OB_DSP
:
21922 case OPC_RADDU_L_OB
:
21924 gen_helper_raddu_l_ob(cpu_gpr
[ret
], v1_t
);
21928 gen_helper_subq_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21930 case OPC_SUBQ_S_PW
:
21932 gen_helper_subq_s_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21936 gen_helper_subq_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21938 case OPC_SUBQ_S_QH
:
21940 gen_helper_subq_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21944 gen_helper_subu_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21946 case OPC_SUBU_S_OB
:
21948 gen_helper_subu_s_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21952 gen_helper_subu_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21954 case OPC_SUBU_S_QH
:
21956 gen_helper_subu_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21960 gen_helper_subuh_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
21962 case OPC_SUBUH_R_OB
:
21964 gen_helper_subuh_r_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
21968 gen_helper_addq_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21970 case OPC_ADDQ_S_PW
:
21972 gen_helper_addq_s_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21976 gen_helper_addq_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21978 case OPC_ADDQ_S_QH
:
21980 gen_helper_addq_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21984 gen_helper_addu_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21986 case OPC_ADDU_S_OB
:
21988 gen_helper_addu_s_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21992 gen_helper_addu_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
21994 case OPC_ADDU_S_QH
:
21996 gen_helper_addu_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22000 gen_helper_adduh_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
22002 case OPC_ADDUH_R_OB
:
22004 gen_helper_adduh_r_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
22008 case OPC_CMPU_EQ_OB_DSP
:
22010 case OPC_PRECR_OB_QH
:
22012 gen_helper_precr_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
);
22014 case OPC_PRECR_SRA_QH_PW
:
22017 TCGv_i32 ret_t
= tcg_const_i32(ret
);
22018 gen_helper_precr_sra_qh_pw(v2_t
, v1_t
, v2_t
, ret_t
);
22019 tcg_temp_free_i32(ret_t
);
22022 case OPC_PRECR_SRA_R_QH_PW
:
22025 TCGv_i32 sa_v
= tcg_const_i32(ret
);
22026 gen_helper_precr_sra_r_qh_pw(v2_t
, v1_t
, v2_t
, sa_v
);
22027 tcg_temp_free_i32(sa_v
);
22030 case OPC_PRECRQ_OB_QH
:
22032 gen_helper_precrq_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
);
22034 case OPC_PRECRQ_PW_L
:
22036 gen_helper_precrq_pw_l(cpu_gpr
[ret
], v1_t
, v2_t
);
22038 case OPC_PRECRQ_QH_PW
:
22040 gen_helper_precrq_qh_pw(cpu_gpr
[ret
], v1_t
, v2_t
);
22042 case OPC_PRECRQ_RS_QH_PW
:
22044 gen_helper_precrq_rs_qh_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22046 case OPC_PRECRQU_S_OB_QH
:
22048 gen_helper_precrqu_s_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22055 tcg_temp_free(v1_t
);
22056 tcg_temp_free(v2_t
);
22059 static void gen_mipsdsp_shift(DisasContext
*ctx
, uint32_t opc
,
22060 int ret
, int v1
, int v2
)
22068 /* Treat as NOP. */
22072 t0
= tcg_temp_new();
22073 v1_t
= tcg_temp_new();
22074 v2_t
= tcg_temp_new();
22076 tcg_gen_movi_tl(t0
, v1
);
22077 gen_load_gpr(v1_t
, v1
);
22078 gen_load_gpr(v2_t
, v2
);
22081 case OPC_SHLL_QB_DSP
:
22083 op2
= MASK_SHLL_QB(ctx
->opcode
);
22087 gen_helper_shll_qb(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
22091 gen_helper_shll_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22095 gen_helper_shll_ph(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
22099 gen_helper_shll_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22101 case OPC_SHLL_S_PH
:
22103 gen_helper_shll_s_ph(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
22105 case OPC_SHLLV_S_PH
:
22107 gen_helper_shll_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22111 gen_helper_shll_s_w(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
22113 case OPC_SHLLV_S_W
:
22115 gen_helper_shll_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22119 gen_helper_shrl_qb(cpu_gpr
[ret
], t0
, v2_t
);
22123 gen_helper_shrl_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
22127 gen_helper_shrl_ph(cpu_gpr
[ret
], t0
, v2_t
);
22131 gen_helper_shrl_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
22135 gen_helper_shra_qb(cpu_gpr
[ret
], t0
, v2_t
);
22137 case OPC_SHRA_R_QB
:
22139 gen_helper_shra_r_qb(cpu_gpr
[ret
], t0
, v2_t
);
22143 gen_helper_shra_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
22145 case OPC_SHRAV_R_QB
:
22147 gen_helper_shra_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
22151 gen_helper_shra_ph(cpu_gpr
[ret
], t0
, v2_t
);
22153 case OPC_SHRA_R_PH
:
22155 gen_helper_shra_r_ph(cpu_gpr
[ret
], t0
, v2_t
);
22159 gen_helper_shra_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
22161 case OPC_SHRAV_R_PH
:
22163 gen_helper_shra_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
22167 gen_helper_shra_r_w(cpu_gpr
[ret
], t0
, v2_t
);
22169 case OPC_SHRAV_R_W
:
22171 gen_helper_shra_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
22173 default: /* Invalid */
22174 MIPS_INVAL("MASK SHLL.QB");
22175 gen_reserved_instruction(ctx
);
22180 #ifdef TARGET_MIPS64
22181 case OPC_SHLL_OB_DSP
:
22182 op2
= MASK_SHLL_OB(ctx
->opcode
);
22186 gen_helper_shll_pw(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
22190 gen_helper_shll_pw(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
22192 case OPC_SHLL_S_PW
:
22194 gen_helper_shll_s_pw(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
22196 case OPC_SHLLV_S_PW
:
22198 gen_helper_shll_s_pw(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
22202 gen_helper_shll_ob(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
22206 gen_helper_shll_ob(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
22210 gen_helper_shll_qh(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
22214 gen_helper_shll_qh(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
22216 case OPC_SHLL_S_QH
:
22218 gen_helper_shll_s_qh(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
22220 case OPC_SHLLV_S_QH
:
22222 gen_helper_shll_s_qh(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
22226 gen_helper_shra_ob(cpu_gpr
[ret
], v2_t
, t0
);
22230 gen_helper_shra_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
22232 case OPC_SHRA_R_OB
:
22234 gen_helper_shra_r_ob(cpu_gpr
[ret
], v2_t
, t0
);
22236 case OPC_SHRAV_R_OB
:
22238 gen_helper_shra_r_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
22242 gen_helper_shra_pw(cpu_gpr
[ret
], v2_t
, t0
);
22246 gen_helper_shra_pw(cpu_gpr
[ret
], v2_t
, v1_t
);
22248 case OPC_SHRA_R_PW
:
22250 gen_helper_shra_r_pw(cpu_gpr
[ret
], v2_t
, t0
);
22252 case OPC_SHRAV_R_PW
:
22254 gen_helper_shra_r_pw(cpu_gpr
[ret
], v2_t
, v1_t
);
22258 gen_helper_shra_qh(cpu_gpr
[ret
], v2_t
, t0
);
22262 gen_helper_shra_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
22264 case OPC_SHRA_R_QH
:
22266 gen_helper_shra_r_qh(cpu_gpr
[ret
], v2_t
, t0
);
22268 case OPC_SHRAV_R_QH
:
22270 gen_helper_shra_r_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
22274 gen_helper_shrl_ob(cpu_gpr
[ret
], v2_t
, t0
);
22278 gen_helper_shrl_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
22282 gen_helper_shrl_qh(cpu_gpr
[ret
], v2_t
, t0
);
22286 gen_helper_shrl_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
22288 default: /* Invalid */
22289 MIPS_INVAL("MASK SHLL.OB");
22290 gen_reserved_instruction(ctx
);
22298 tcg_temp_free(v1_t
);
22299 tcg_temp_free(v2_t
);
22302 static void gen_mipsdsp_multiply(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
22303 int ret
, int v1
, int v2
, int check_ret
)
22309 if ((ret
== 0) && (check_ret
== 1)) {
22310 /* Treat as NOP. */
22314 t0
= tcg_temp_new_i32();
22315 v1_t
= tcg_temp_new();
22316 v2_t
= tcg_temp_new();
22318 tcg_gen_movi_i32(t0
, ret
);
22319 gen_load_gpr(v1_t
, v1
);
22320 gen_load_gpr(v2_t
, v2
);
22324 * OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
22325 * the same mask and op1.
22327 case OPC_MULT_G_2E
:
22331 gen_helper_mul_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22334 gen_helper_mul_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22337 gen_helper_mulq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22339 case OPC_MULQ_RS_W
:
22340 gen_helper_mulq_rs_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22344 case OPC_DPA_W_PH_DSP
:
22346 case OPC_DPAU_H_QBL
:
22348 gen_helper_dpau_h_qbl(t0
, v1_t
, v2_t
, cpu_env
);
22350 case OPC_DPAU_H_QBR
:
22352 gen_helper_dpau_h_qbr(t0
, v1_t
, v2_t
, cpu_env
);
22354 case OPC_DPSU_H_QBL
:
22356 gen_helper_dpsu_h_qbl(t0
, v1_t
, v2_t
, cpu_env
);
22358 case OPC_DPSU_H_QBR
:
22360 gen_helper_dpsu_h_qbr(t0
, v1_t
, v2_t
, cpu_env
);
22364 gen_helper_dpa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
22366 case OPC_DPAX_W_PH
:
22368 gen_helper_dpax_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
22370 case OPC_DPAQ_S_W_PH
:
22372 gen_helper_dpaq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
22374 case OPC_DPAQX_S_W_PH
:
22376 gen_helper_dpaqx_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
22378 case OPC_DPAQX_SA_W_PH
:
22380 gen_helper_dpaqx_sa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
22384 gen_helper_dps_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
22386 case OPC_DPSX_W_PH
:
22388 gen_helper_dpsx_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
22390 case OPC_DPSQ_S_W_PH
:
22392 gen_helper_dpsq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
22394 case OPC_DPSQX_S_W_PH
:
22396 gen_helper_dpsqx_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
22398 case OPC_DPSQX_SA_W_PH
:
22400 gen_helper_dpsqx_sa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
22402 case OPC_MULSAQ_S_W_PH
:
22404 gen_helper_mulsaq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
22406 case OPC_DPAQ_SA_L_W
:
22408 gen_helper_dpaq_sa_l_w(t0
, v1_t
, v2_t
, cpu_env
);
22410 case OPC_DPSQ_SA_L_W
:
22412 gen_helper_dpsq_sa_l_w(t0
, v1_t
, v2_t
, cpu_env
);
22414 case OPC_MAQ_S_W_PHL
:
22416 gen_helper_maq_s_w_phl(t0
, v1_t
, v2_t
, cpu_env
);
22418 case OPC_MAQ_S_W_PHR
:
22420 gen_helper_maq_s_w_phr(t0
, v1_t
, v2_t
, cpu_env
);
22422 case OPC_MAQ_SA_W_PHL
:
22424 gen_helper_maq_sa_w_phl(t0
, v1_t
, v2_t
, cpu_env
);
22426 case OPC_MAQ_SA_W_PHR
:
22428 gen_helper_maq_sa_w_phr(t0
, v1_t
, v2_t
, cpu_env
);
22430 case OPC_MULSA_W_PH
:
22432 gen_helper_mulsa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
22436 #ifdef TARGET_MIPS64
22437 case OPC_DPAQ_W_QH_DSP
:
22439 int ac
= ret
& 0x03;
22440 tcg_gen_movi_i32(t0
, ac
);
22445 gen_helper_dmadd(v1_t
, v2_t
, t0
, cpu_env
);
22449 gen_helper_dmaddu(v1_t
, v2_t
, t0
, cpu_env
);
22453 gen_helper_dmsub(v1_t
, v2_t
, t0
, cpu_env
);
22457 gen_helper_dmsubu(v1_t
, v2_t
, t0
, cpu_env
);
22461 gen_helper_dpa_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
22463 case OPC_DPAQ_S_W_QH
:
22465 gen_helper_dpaq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
22467 case OPC_DPAQ_SA_L_PW
:
22469 gen_helper_dpaq_sa_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
22471 case OPC_DPAU_H_OBL
:
22473 gen_helper_dpau_h_obl(v1_t
, v2_t
, t0
, cpu_env
);
22475 case OPC_DPAU_H_OBR
:
22477 gen_helper_dpau_h_obr(v1_t
, v2_t
, t0
, cpu_env
);
22481 gen_helper_dps_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
22483 case OPC_DPSQ_S_W_QH
:
22485 gen_helper_dpsq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
22487 case OPC_DPSQ_SA_L_PW
:
22489 gen_helper_dpsq_sa_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
22491 case OPC_DPSU_H_OBL
:
22493 gen_helper_dpsu_h_obl(v1_t
, v2_t
, t0
, cpu_env
);
22495 case OPC_DPSU_H_OBR
:
22497 gen_helper_dpsu_h_obr(v1_t
, v2_t
, t0
, cpu_env
);
22499 case OPC_MAQ_S_L_PWL
:
22501 gen_helper_maq_s_l_pwl(v1_t
, v2_t
, t0
, cpu_env
);
22503 case OPC_MAQ_S_L_PWR
:
22505 gen_helper_maq_s_l_pwr(v1_t
, v2_t
, t0
, cpu_env
);
22507 case OPC_MAQ_S_W_QHLL
:
22509 gen_helper_maq_s_w_qhll(v1_t
, v2_t
, t0
, cpu_env
);
22511 case OPC_MAQ_SA_W_QHLL
:
22513 gen_helper_maq_sa_w_qhll(v1_t
, v2_t
, t0
, cpu_env
);
22515 case OPC_MAQ_S_W_QHLR
:
22517 gen_helper_maq_s_w_qhlr(v1_t
, v2_t
, t0
, cpu_env
);
22519 case OPC_MAQ_SA_W_QHLR
:
22521 gen_helper_maq_sa_w_qhlr(v1_t
, v2_t
, t0
, cpu_env
);
22523 case OPC_MAQ_S_W_QHRL
:
22525 gen_helper_maq_s_w_qhrl(v1_t
, v2_t
, t0
, cpu_env
);
22527 case OPC_MAQ_SA_W_QHRL
:
22529 gen_helper_maq_sa_w_qhrl(v1_t
, v2_t
, t0
, cpu_env
);
22531 case OPC_MAQ_S_W_QHRR
:
22533 gen_helper_maq_s_w_qhrr(v1_t
, v2_t
, t0
, cpu_env
);
22535 case OPC_MAQ_SA_W_QHRR
:
22537 gen_helper_maq_sa_w_qhrr(v1_t
, v2_t
, t0
, cpu_env
);
22539 case OPC_MULSAQ_S_L_PW
:
22541 gen_helper_mulsaq_s_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
22543 case OPC_MULSAQ_S_W_QH
:
22545 gen_helper_mulsaq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
22551 case OPC_ADDU_QB_DSP
:
22553 case OPC_MULEU_S_PH_QBL
:
22555 gen_helper_muleu_s_ph_qbl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22557 case OPC_MULEU_S_PH_QBR
:
22559 gen_helper_muleu_s_ph_qbr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22561 case OPC_MULQ_RS_PH
:
22563 gen_helper_mulq_rs_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22565 case OPC_MULEQ_S_W_PHL
:
22567 gen_helper_muleq_s_w_phl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22569 case OPC_MULEQ_S_W_PHR
:
22571 gen_helper_muleq_s_w_phr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22573 case OPC_MULQ_S_PH
:
22575 gen_helper_mulq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22579 #ifdef TARGET_MIPS64
22580 case OPC_ADDU_OB_DSP
:
22582 case OPC_MULEQ_S_PW_QHL
:
22584 gen_helper_muleq_s_pw_qhl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22586 case OPC_MULEQ_S_PW_QHR
:
22588 gen_helper_muleq_s_pw_qhr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22590 case OPC_MULEU_S_QH_OBL
:
22592 gen_helper_muleu_s_qh_obl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22594 case OPC_MULEU_S_QH_OBR
:
22596 gen_helper_muleu_s_qh_obr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22598 case OPC_MULQ_RS_QH
:
22600 gen_helper_mulq_rs_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22607 tcg_temp_free_i32(t0
);
22608 tcg_temp_free(v1_t
);
22609 tcg_temp_free(v2_t
);
22612 static void gen_mipsdsp_bitinsn(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
22620 /* Treat as NOP. */
22624 t0
= tcg_temp_new();
22625 val_t
= tcg_temp_new();
22626 gen_load_gpr(val_t
, val
);
22629 case OPC_ABSQ_S_PH_DSP
:
22633 gen_helper_bitrev(cpu_gpr
[ret
], val_t
);
22638 target_long result
;
22639 imm
= (ctx
->opcode
>> 16) & 0xFF;
22640 result
= (uint32_t)imm
<< 24 |
22641 (uint32_t)imm
<< 16 |
22642 (uint32_t)imm
<< 8 |
22644 result
= (int32_t)result
;
22645 tcg_gen_movi_tl(cpu_gpr
[ret
], result
);
22650 tcg_gen_ext8u_tl(cpu_gpr
[ret
], val_t
);
22651 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 8);
22652 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
22653 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
22654 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
22655 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
22660 imm
= (ctx
->opcode
>> 16) & 0x03FF;
22661 imm
= (int16_t)(imm
<< 6) >> 6;
22662 tcg_gen_movi_tl(cpu_gpr
[ret
], \
22663 (target_long
)((int32_t)imm
<< 16 | \
22669 tcg_gen_ext16u_tl(cpu_gpr
[ret
], val_t
);
22670 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
22671 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
22672 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
22676 #ifdef TARGET_MIPS64
22677 case OPC_ABSQ_S_QH_DSP
:
22684 imm
= (ctx
->opcode
>> 16) & 0xFF;
22685 temp
= ((uint64_t)imm
<< 8) | (uint64_t)imm
;
22686 temp
= (temp
<< 16) | temp
;
22687 temp
= (temp
<< 32) | temp
;
22688 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
22696 imm
= (ctx
->opcode
>> 16) & 0x03FF;
22697 imm
= (int16_t)(imm
<< 6) >> 6;
22698 temp
= ((target_long
)imm
<< 32) \
22699 | ((target_long
)imm
& 0xFFFFFFFF);
22700 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
22708 imm
= (ctx
->opcode
>> 16) & 0x03FF;
22709 imm
= (int16_t)(imm
<< 6) >> 6;
22711 temp
= ((uint64_t)(uint16_t)imm
<< 48) |
22712 ((uint64_t)(uint16_t)imm
<< 32) |
22713 ((uint64_t)(uint16_t)imm
<< 16) |
22714 (uint64_t)(uint16_t)imm
;
22715 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
22720 tcg_gen_ext8u_tl(cpu_gpr
[ret
], val_t
);
22721 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 8);
22722 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
22723 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
22724 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
22725 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
22726 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
22730 tcg_gen_ext32u_i64(cpu_gpr
[ret
], val_t
);
22731 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
22732 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
22736 tcg_gen_ext16u_tl(cpu_gpr
[ret
], val_t
);
22737 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
22738 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
22739 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
22740 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
22747 tcg_temp_free(val_t
);
22750 static void gen_mipsdsp_add_cmp_pick(DisasContext
*ctx
,
22751 uint32_t op1
, uint32_t op2
,
22752 int ret
, int v1
, int v2
, int check_ret
)
22758 if ((ret
== 0) && (check_ret
== 1)) {
22759 /* Treat as NOP. */
22763 t1
= tcg_temp_new();
22764 v1_t
= tcg_temp_new();
22765 v2_t
= tcg_temp_new();
22767 gen_load_gpr(v1_t
, v1
);
22768 gen_load_gpr(v2_t
, v2
);
22771 case OPC_CMPU_EQ_QB_DSP
:
22773 case OPC_CMPU_EQ_QB
:
22775 gen_helper_cmpu_eq_qb(v1_t
, v2_t
, cpu_env
);
22777 case OPC_CMPU_LT_QB
:
22779 gen_helper_cmpu_lt_qb(v1_t
, v2_t
, cpu_env
);
22781 case OPC_CMPU_LE_QB
:
22783 gen_helper_cmpu_le_qb(v1_t
, v2_t
, cpu_env
);
22785 case OPC_CMPGU_EQ_QB
:
22787 gen_helper_cmpgu_eq_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
22789 case OPC_CMPGU_LT_QB
:
22791 gen_helper_cmpgu_lt_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
22793 case OPC_CMPGU_LE_QB
:
22795 gen_helper_cmpgu_le_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
22797 case OPC_CMPGDU_EQ_QB
:
22799 gen_helper_cmpgu_eq_qb(t1
, v1_t
, v2_t
);
22800 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
22801 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
22802 tcg_gen_shli_tl(t1
, t1
, 24);
22803 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
22805 case OPC_CMPGDU_LT_QB
:
22807 gen_helper_cmpgu_lt_qb(t1
, v1_t
, v2_t
);
22808 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
22809 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
22810 tcg_gen_shli_tl(t1
, t1
, 24);
22811 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
22813 case OPC_CMPGDU_LE_QB
:
22815 gen_helper_cmpgu_le_qb(t1
, v1_t
, v2_t
);
22816 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
22817 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
22818 tcg_gen_shli_tl(t1
, t1
, 24);
22819 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
22821 case OPC_CMP_EQ_PH
:
22823 gen_helper_cmp_eq_ph(v1_t
, v2_t
, cpu_env
);
22825 case OPC_CMP_LT_PH
:
22827 gen_helper_cmp_lt_ph(v1_t
, v2_t
, cpu_env
);
22829 case OPC_CMP_LE_PH
:
22831 gen_helper_cmp_le_ph(v1_t
, v2_t
, cpu_env
);
22835 gen_helper_pick_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22839 gen_helper_pick_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22841 case OPC_PACKRL_PH
:
22843 gen_helper_packrl_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
22847 #ifdef TARGET_MIPS64
22848 case OPC_CMPU_EQ_OB_DSP
:
22850 case OPC_CMP_EQ_PW
:
22852 gen_helper_cmp_eq_pw(v1_t
, v2_t
, cpu_env
);
22854 case OPC_CMP_LT_PW
:
22856 gen_helper_cmp_lt_pw(v1_t
, v2_t
, cpu_env
);
22858 case OPC_CMP_LE_PW
:
22860 gen_helper_cmp_le_pw(v1_t
, v2_t
, cpu_env
);
22862 case OPC_CMP_EQ_QH
:
22864 gen_helper_cmp_eq_qh(v1_t
, v2_t
, cpu_env
);
22866 case OPC_CMP_LT_QH
:
22868 gen_helper_cmp_lt_qh(v1_t
, v2_t
, cpu_env
);
22870 case OPC_CMP_LE_QH
:
22872 gen_helper_cmp_le_qh(v1_t
, v2_t
, cpu_env
);
22874 case OPC_CMPGDU_EQ_OB
:
22876 gen_helper_cmpgdu_eq_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22878 case OPC_CMPGDU_LT_OB
:
22880 gen_helper_cmpgdu_lt_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22882 case OPC_CMPGDU_LE_OB
:
22884 gen_helper_cmpgdu_le_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22886 case OPC_CMPGU_EQ_OB
:
22888 gen_helper_cmpgu_eq_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
22890 case OPC_CMPGU_LT_OB
:
22892 gen_helper_cmpgu_lt_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
22894 case OPC_CMPGU_LE_OB
:
22896 gen_helper_cmpgu_le_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
22898 case OPC_CMPU_EQ_OB
:
22900 gen_helper_cmpu_eq_ob(v1_t
, v2_t
, cpu_env
);
22902 case OPC_CMPU_LT_OB
:
22904 gen_helper_cmpu_lt_ob(v1_t
, v2_t
, cpu_env
);
22906 case OPC_CMPU_LE_OB
:
22908 gen_helper_cmpu_le_ob(v1_t
, v2_t
, cpu_env
);
22910 case OPC_PACKRL_PW
:
22912 gen_helper_packrl_pw(cpu_gpr
[ret
], v1_t
, v2_t
);
22916 gen_helper_pick_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22920 gen_helper_pick_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22924 gen_helper_pick_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22932 tcg_temp_free(v1_t
);
22933 tcg_temp_free(v2_t
);
22936 static void gen_mipsdsp_append(CPUMIPSState
*env
, DisasContext
*ctx
,
22937 uint32_t op1
, int rt
, int rs
, int sa
)
22944 /* Treat as NOP. */
22948 t0
= tcg_temp_new();
22949 gen_load_gpr(t0
, rs
);
22952 case OPC_APPEND_DSP
:
22953 switch (MASK_APPEND(ctx
->opcode
)) {
22956 tcg_gen_deposit_tl(cpu_gpr
[rt
], t0
, cpu_gpr
[rt
], sa
, 32 - sa
);
22958 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
22962 tcg_gen_ext32u_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
22963 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], sa
);
22964 tcg_gen_shli_tl(t0
, t0
, 32 - sa
);
22965 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
22967 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
22971 if (sa
!= 0 && sa
!= 2) {
22972 tcg_gen_shli_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 8 * sa
);
22973 tcg_gen_ext32u_tl(t0
, t0
);
22974 tcg_gen_shri_tl(t0
, t0
, 8 * (4 - sa
));
22975 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
22977 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
22979 default: /* Invalid */
22980 MIPS_INVAL("MASK APPEND");
22981 gen_reserved_instruction(ctx
);
22985 #ifdef TARGET_MIPS64
22986 case OPC_DAPPEND_DSP
:
22987 switch (MASK_DAPPEND(ctx
->opcode
)) {
22990 tcg_gen_deposit_tl(cpu_gpr
[rt
], t0
, cpu_gpr
[rt
], sa
, 64 - sa
);
22994 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 0x20 | sa
);
22995 tcg_gen_shli_tl(t0
, t0
, 64 - (0x20 | sa
));
22996 tcg_gen_or_tl(cpu_gpr
[rt
], t0
, t0
);
23000 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], sa
);
23001 tcg_gen_shli_tl(t0
, t0
, 64 - sa
);
23002 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
23007 if (sa
!= 0 && sa
!= 2 && sa
!= 4) {
23008 tcg_gen_shli_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 8 * sa
);
23009 tcg_gen_shri_tl(t0
, t0
, 8 * (8 - sa
));
23010 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
23013 default: /* Invalid */
23014 MIPS_INVAL("MASK DAPPEND");
23015 gen_reserved_instruction(ctx
);
23024 static void gen_mipsdsp_accinsn(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
23025 int ret
, int v1
, int v2
, int check_ret
)
23034 if ((ret
== 0) && (check_ret
== 1)) {
23035 /* Treat as NOP. */
23039 t0
= tcg_temp_new();
23040 t1
= tcg_temp_new();
23041 v1_t
= tcg_temp_new();
23042 v2_t
= tcg_temp_new();
23044 gen_load_gpr(v1_t
, v1
);
23045 gen_load_gpr(v2_t
, v2
);
23048 case OPC_EXTR_W_DSP
:
23052 tcg_gen_movi_tl(t0
, v2
);
23053 tcg_gen_movi_tl(t1
, v1
);
23054 gen_helper_extr_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23057 tcg_gen_movi_tl(t0
, v2
);
23058 tcg_gen_movi_tl(t1
, v1
);
23059 gen_helper_extr_r_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23061 case OPC_EXTR_RS_W
:
23062 tcg_gen_movi_tl(t0
, v2
);
23063 tcg_gen_movi_tl(t1
, v1
);
23064 gen_helper_extr_rs_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23067 tcg_gen_movi_tl(t0
, v2
);
23068 tcg_gen_movi_tl(t1
, v1
);
23069 gen_helper_extr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23071 case OPC_EXTRV_S_H
:
23072 tcg_gen_movi_tl(t0
, v2
);
23073 gen_helper_extr_s_h(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
23076 tcg_gen_movi_tl(t0
, v2
);
23077 gen_helper_extr_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
23079 case OPC_EXTRV_R_W
:
23080 tcg_gen_movi_tl(t0
, v2
);
23081 gen_helper_extr_r_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
23083 case OPC_EXTRV_RS_W
:
23084 tcg_gen_movi_tl(t0
, v2
);
23085 gen_helper_extr_rs_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
23088 tcg_gen_movi_tl(t0
, v2
);
23089 tcg_gen_movi_tl(t1
, v1
);
23090 gen_helper_extp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23093 tcg_gen_movi_tl(t0
, v2
);
23094 gen_helper_extp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
23097 tcg_gen_movi_tl(t0
, v2
);
23098 tcg_gen_movi_tl(t1
, v1
);
23099 gen_helper_extpdp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23102 tcg_gen_movi_tl(t0
, v2
);
23103 gen_helper_extpdp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
23106 imm
= (ctx
->opcode
>> 20) & 0x3F;
23107 tcg_gen_movi_tl(t0
, ret
);
23108 tcg_gen_movi_tl(t1
, imm
);
23109 gen_helper_shilo(t0
, t1
, cpu_env
);
23112 tcg_gen_movi_tl(t0
, ret
);
23113 gen_helper_shilo(t0
, v1_t
, cpu_env
);
23116 tcg_gen_movi_tl(t0
, ret
);
23117 gen_helper_mthlip(t0
, v1_t
, cpu_env
);
23120 imm
= (ctx
->opcode
>> 11) & 0x3FF;
23121 tcg_gen_movi_tl(t0
, imm
);
23122 gen_helper_wrdsp(v1_t
, t0
, cpu_env
);
23125 imm
= (ctx
->opcode
>> 16) & 0x03FF;
23126 tcg_gen_movi_tl(t0
, imm
);
23127 gen_helper_rddsp(cpu_gpr
[ret
], t0
, cpu_env
);
23131 #ifdef TARGET_MIPS64
23132 case OPC_DEXTR_W_DSP
:
23136 tcg_gen_movi_tl(t0
, ret
);
23137 gen_helper_dmthlip(v1_t
, t0
, cpu_env
);
23141 int shift
= (ctx
->opcode
>> 19) & 0x7F;
23142 int ac
= (ctx
->opcode
>> 11) & 0x03;
23143 tcg_gen_movi_tl(t0
, shift
);
23144 tcg_gen_movi_tl(t1
, ac
);
23145 gen_helper_dshilo(t0
, t1
, cpu_env
);
23150 int ac
= (ctx
->opcode
>> 11) & 0x03;
23151 tcg_gen_movi_tl(t0
, ac
);
23152 gen_helper_dshilo(v1_t
, t0
, cpu_env
);
23156 tcg_gen_movi_tl(t0
, v2
);
23157 tcg_gen_movi_tl(t1
, v1
);
23159 gen_helper_dextp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23162 tcg_gen_movi_tl(t0
, v2
);
23163 gen_helper_dextp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
23166 tcg_gen_movi_tl(t0
, v2
);
23167 tcg_gen_movi_tl(t1
, v1
);
23168 gen_helper_dextpdp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23171 tcg_gen_movi_tl(t0
, v2
);
23172 gen_helper_dextpdp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
23175 tcg_gen_movi_tl(t0
, v2
);
23176 tcg_gen_movi_tl(t1
, v1
);
23177 gen_helper_dextr_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23179 case OPC_DEXTR_R_L
:
23180 tcg_gen_movi_tl(t0
, v2
);
23181 tcg_gen_movi_tl(t1
, v1
);
23182 gen_helper_dextr_r_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23184 case OPC_DEXTR_RS_L
:
23185 tcg_gen_movi_tl(t0
, v2
);
23186 tcg_gen_movi_tl(t1
, v1
);
23187 gen_helper_dextr_rs_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23190 tcg_gen_movi_tl(t0
, v2
);
23191 tcg_gen_movi_tl(t1
, v1
);
23192 gen_helper_dextr_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23194 case OPC_DEXTR_R_W
:
23195 tcg_gen_movi_tl(t0
, v2
);
23196 tcg_gen_movi_tl(t1
, v1
);
23197 gen_helper_dextr_r_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23199 case OPC_DEXTR_RS_W
:
23200 tcg_gen_movi_tl(t0
, v2
);
23201 tcg_gen_movi_tl(t1
, v1
);
23202 gen_helper_dextr_rs_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23204 case OPC_DEXTR_S_H
:
23205 tcg_gen_movi_tl(t0
, v2
);
23206 tcg_gen_movi_tl(t1
, v1
);
23207 gen_helper_dextr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23209 case OPC_DEXTRV_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
);
23215 tcg_gen_movi_tl(t0
, v2
);
23216 gen_helper_dextr_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
23218 case OPC_DEXTRV_R_L
:
23219 tcg_gen_movi_tl(t0
, v2
);
23220 gen_helper_dextr_r_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
23222 case OPC_DEXTRV_RS_L
:
23223 tcg_gen_movi_tl(t0
, v2
);
23224 gen_helper_dextr_rs_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
23227 tcg_gen_movi_tl(t0
, v2
);
23228 gen_helper_dextr_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
23230 case OPC_DEXTRV_R_W
:
23231 tcg_gen_movi_tl(t0
, v2
);
23232 gen_helper_dextr_r_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
23234 case OPC_DEXTRV_RS_W
:
23235 tcg_gen_movi_tl(t0
, v2
);
23236 gen_helper_dextr_rs_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
23245 tcg_temp_free(v1_t
);
23246 tcg_temp_free(v2_t
);
23249 /* End MIPSDSP functions. */
23251 static void decode_opc_special_r6(CPUMIPSState
*env
, DisasContext
*ctx
)
23253 int rs
, rt
, rd
, sa
;
23256 rs
= (ctx
->opcode
>> 21) & 0x1f;
23257 rt
= (ctx
->opcode
>> 16) & 0x1f;
23258 rd
= (ctx
->opcode
>> 11) & 0x1f;
23259 sa
= (ctx
->opcode
>> 6) & 0x1f;
23261 op1
= MASK_SPECIAL(ctx
->opcode
);
23267 op2
= MASK_R6_MULDIV(ctx
->opcode
);
23277 gen_r6_muldiv(ctx
, op2
, rd
, rs
, rt
);
23280 MIPS_INVAL("special_r6 muldiv");
23281 gen_reserved_instruction(ctx
);
23287 gen_cond_move(ctx
, op1
, rd
, rs
, rt
);
23291 if (rt
== 0 && sa
== 1) {
23293 * Major opcode and function field is shared with preR6 MFHI/MTHI.
23294 * We need additionally to check other fields.
23296 gen_cl(ctx
, op1
, rd
, rs
);
23298 gen_reserved_instruction(ctx
);
23302 if (is_uhi(extract32(ctx
->opcode
, 6, 20))) {
23303 gen_helper_do_semihosting(cpu_env
);
23305 if (ctx
->hflags
& MIPS_HFLAG_SBRI
) {
23306 gen_reserved_instruction(ctx
);
23308 generate_exception_end(ctx
, EXCP_DBp
);
23312 #if defined(TARGET_MIPS64)
23315 if (rt
== 0 && sa
== 1) {
23317 * Major opcode and function field is shared with preR6 MFHI/MTHI.
23318 * We need additionally to check other fields.
23320 check_mips_64(ctx
);
23321 gen_cl(ctx
, op1
, rd
, rs
);
23323 gen_reserved_instruction(ctx
);
23331 op2
= MASK_R6_MULDIV(ctx
->opcode
);
23341 check_mips_64(ctx
);
23342 gen_r6_muldiv(ctx
, op2
, rd
, rs
, rt
);
23345 MIPS_INVAL("special_r6 muldiv");
23346 gen_reserved_instruction(ctx
);
23351 default: /* Invalid */
23352 MIPS_INVAL("special_r6");
23353 gen_reserved_instruction(ctx
);
23358 static void decode_opc_special_tx79(CPUMIPSState
*env
, DisasContext
*ctx
)
23360 int rs
= extract32(ctx
->opcode
, 21, 5);
23361 int rt
= extract32(ctx
->opcode
, 16, 5);
23362 int rd
= extract32(ctx
->opcode
, 11, 5);
23363 uint32_t op1
= MASK_SPECIAL(ctx
->opcode
);
23366 case OPC_MOVN
: /* Conditional move */
23368 gen_cond_move(ctx
, op1
, rd
, rs
, rt
);
23370 case OPC_MFHI
: /* Move from HI/LO */
23372 gen_HILO(ctx
, op1
, 0, rd
);
23375 case OPC_MTLO
: /* Move to HI/LO */
23376 gen_HILO(ctx
, op1
, 0, rs
);
23380 gen_mul_txx9(ctx
, op1
, rd
, rs
, rt
);
23384 gen_muldiv(ctx
, op1
, 0, rs
, rt
);
23386 #if defined(TARGET_MIPS64)
23391 check_insn_opc_user_only(ctx
, INSN_R5900
);
23392 gen_muldiv(ctx
, op1
, 0, rs
, rt
);
23396 gen_compute_branch(ctx
, op1
, 4, rs
, 0, 0, 4);
23398 default: /* Invalid */
23399 MIPS_INVAL("special_tx79");
23400 gen_reserved_instruction(ctx
);
23405 static void decode_opc_special_legacy(CPUMIPSState
*env
, DisasContext
*ctx
)
23407 int rs
, rt
, rd
, sa
;
23410 rs
= (ctx
->opcode
>> 21) & 0x1f;
23411 rt
= (ctx
->opcode
>> 16) & 0x1f;
23412 rd
= (ctx
->opcode
>> 11) & 0x1f;
23413 sa
= (ctx
->opcode
>> 6) & 0x1f;
23415 op1
= MASK_SPECIAL(ctx
->opcode
);
23417 case OPC_MOVN
: /* Conditional move */
23419 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS_R1
|
23420 INSN_LOONGSON2E
| INSN_LOONGSON2F
);
23421 gen_cond_move(ctx
, op1
, rd
, rs
, rt
);
23423 case OPC_MFHI
: /* Move from HI/LO */
23425 gen_HILO(ctx
, op1
, rs
& 3, rd
);
23428 case OPC_MTLO
: /* Move to HI/LO */
23429 gen_HILO(ctx
, op1
, rd
& 3, rs
);
23432 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS_R1
);
23433 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
23434 check_cp1_enabled(ctx
);
23435 gen_movci(ctx
, rd
, rs
, (ctx
->opcode
>> 18) & 0x7,
23436 (ctx
->opcode
>> 16) & 1);
23438 generate_exception_err(ctx
, EXCP_CpU
, 1);
23444 check_insn(ctx
, INSN_VR54XX
);
23445 op1
= MASK_MUL_VR54XX(ctx
->opcode
);
23446 gen_mul_vr54xx(ctx
, op1
, rd
, rs
, rt
);
23448 gen_muldiv(ctx
, op1
, rd
& 3, rs
, rt
);
23453 gen_muldiv(ctx
, op1
, 0, rs
, rt
);
23455 #if defined(TARGET_MIPS64)
23460 check_insn(ctx
, ISA_MIPS3
);
23461 check_mips_64(ctx
);
23462 gen_muldiv(ctx
, op1
, 0, rs
, rt
);
23466 gen_compute_branch(ctx
, op1
, 4, rs
, rd
, sa
, 4);
23469 #ifdef MIPS_STRICT_STANDARD
23470 MIPS_INVAL("SPIM");
23471 gen_reserved_instruction(ctx
);
23473 /* Implemented as RI exception for now. */
23474 MIPS_INVAL("spim (unofficial)");
23475 gen_reserved_instruction(ctx
);
23478 default: /* Invalid */
23479 MIPS_INVAL("special_legacy");
23480 gen_reserved_instruction(ctx
);
23485 static void decode_opc_special(CPUMIPSState
*env
, DisasContext
*ctx
)
23487 int rs
, rt
, rd
, sa
;
23490 rs
= (ctx
->opcode
>> 21) & 0x1f;
23491 rt
= (ctx
->opcode
>> 16) & 0x1f;
23492 rd
= (ctx
->opcode
>> 11) & 0x1f;
23493 sa
= (ctx
->opcode
>> 6) & 0x1f;
23495 op1
= MASK_SPECIAL(ctx
->opcode
);
23497 case OPC_SLL
: /* Shift with immediate */
23498 if (sa
== 5 && rd
== 0 &&
23499 rs
== 0 && rt
== 0) { /* PAUSE */
23500 if ((ctx
->insn_flags
& ISA_MIPS_R6
) &&
23501 (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
23502 gen_reserved_instruction(ctx
);
23508 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
23511 switch ((ctx
->opcode
>> 21) & 0x1f) {
23513 /* rotr is decoded as srl on non-R2 CPUs */
23514 if (ctx
->insn_flags
& ISA_MIPS_R2
) {
23519 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
23522 gen_reserved_instruction(ctx
);
23530 gen_arith(ctx
, op1
, rd
, rs
, rt
);
23532 case OPC_SLLV
: /* Shifts */
23534 gen_shift(ctx
, op1
, rd
, rs
, rt
);
23537 switch ((ctx
->opcode
>> 6) & 0x1f) {
23539 /* rotrv is decoded as srlv on non-R2 CPUs */
23540 if (ctx
->insn_flags
& ISA_MIPS_R2
) {
23545 gen_shift(ctx
, op1
, rd
, rs
, rt
);
23548 gen_reserved_instruction(ctx
);
23552 case OPC_SLT
: /* Set on less than */
23554 gen_slt(ctx
, op1
, rd
, rs
, rt
);
23556 case OPC_AND
: /* Logic*/
23560 gen_logic(ctx
, op1
, rd
, rs
, rt
);
23563 gen_compute_branch(ctx
, op1
, 4, rs
, rd
, sa
, 4);
23565 case OPC_TGE
: /* Traps */
23571 check_insn(ctx
, ISA_MIPS2
);
23572 gen_trap(ctx
, op1
, rs
, rt
, -1);
23575 /* Pmon entry point, also R4010 selsl */
23576 #ifdef MIPS_STRICT_STANDARD
23577 MIPS_INVAL("PMON / selsl");
23578 gen_reserved_instruction(ctx
);
23580 gen_helper_0e0i(pmon
, sa
);
23584 generate_exception_end(ctx
, EXCP_SYSCALL
);
23587 generate_exception_end(ctx
, EXCP_BREAK
);
23590 check_insn(ctx
, ISA_MIPS2
);
23591 gen_sync(extract32(ctx
->opcode
, 6, 5));
23594 #if defined(TARGET_MIPS64)
23595 /* MIPS64 specific opcodes */
23600 check_insn(ctx
, ISA_MIPS3
);
23601 check_mips_64(ctx
);
23602 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
23605 switch ((ctx
->opcode
>> 21) & 0x1f) {
23607 /* drotr is decoded as dsrl on non-R2 CPUs */
23608 if (ctx
->insn_flags
& ISA_MIPS_R2
) {
23613 check_insn(ctx
, ISA_MIPS3
);
23614 check_mips_64(ctx
);
23615 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
23618 gen_reserved_instruction(ctx
);
23623 switch ((ctx
->opcode
>> 21) & 0x1f) {
23625 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
23626 if (ctx
->insn_flags
& ISA_MIPS_R2
) {
23631 check_insn(ctx
, ISA_MIPS3
);
23632 check_mips_64(ctx
);
23633 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
23636 gen_reserved_instruction(ctx
);
23644 check_insn(ctx
, ISA_MIPS3
);
23645 check_mips_64(ctx
);
23646 gen_arith(ctx
, op1
, rd
, rs
, rt
);
23650 check_insn(ctx
, ISA_MIPS3
);
23651 check_mips_64(ctx
);
23652 gen_shift(ctx
, op1
, rd
, rs
, rt
);
23655 switch ((ctx
->opcode
>> 6) & 0x1f) {
23657 /* drotrv is decoded as dsrlv on non-R2 CPUs */
23658 if (ctx
->insn_flags
& ISA_MIPS_R2
) {
23663 check_insn(ctx
, ISA_MIPS3
);
23664 check_mips_64(ctx
);
23665 gen_shift(ctx
, op1
, rd
, rs
, rt
);
23668 gen_reserved_instruction(ctx
);
23674 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
23675 decode_opc_special_r6(env
, ctx
);
23676 } else if (ctx
->insn_flags
& INSN_R5900
) {
23677 decode_opc_special_tx79(env
, ctx
);
23679 decode_opc_special_legacy(env
, ctx
);
23685 static void decode_opc_special2_legacy(CPUMIPSState
*env
, DisasContext
*ctx
)
23690 rs
= (ctx
->opcode
>> 21) & 0x1f;
23691 rt
= (ctx
->opcode
>> 16) & 0x1f;
23692 rd
= (ctx
->opcode
>> 11) & 0x1f;
23694 op1
= MASK_SPECIAL2(ctx
->opcode
);
23696 case OPC_MADD
: /* Multiply and add/sub */
23700 check_insn(ctx
, ISA_MIPS_R1
);
23701 gen_muldiv(ctx
, op1
, rd
& 3, rs
, rt
);
23704 gen_arith(ctx
, op1
, rd
, rs
, rt
);
23707 case OPC_DIVU_G_2F
:
23708 case OPC_MULT_G_2F
:
23709 case OPC_MULTU_G_2F
:
23711 case OPC_MODU_G_2F
:
23712 check_insn(ctx
, INSN_LOONGSON2F
| ASE_LEXT
);
23713 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
23717 check_insn(ctx
, ISA_MIPS_R1
);
23718 gen_cl(ctx
, op1
, rd
, rs
);
23721 if (is_uhi(extract32(ctx
->opcode
, 6, 20))) {
23722 gen_helper_do_semihosting(cpu_env
);
23725 * XXX: not clear which exception should be raised
23726 * when in debug mode...
23728 check_insn(ctx
, ISA_MIPS_R1
);
23729 generate_exception_end(ctx
, EXCP_DBp
);
23732 #if defined(TARGET_MIPS64)
23735 check_insn(ctx
, ISA_MIPS_R1
);
23736 check_mips_64(ctx
);
23737 gen_cl(ctx
, op1
, rd
, rs
);
23739 case OPC_DMULT_G_2F
:
23740 case OPC_DMULTU_G_2F
:
23741 case OPC_DDIV_G_2F
:
23742 case OPC_DDIVU_G_2F
:
23743 case OPC_DMOD_G_2F
:
23744 case OPC_DMODU_G_2F
:
23745 check_insn(ctx
, INSN_LOONGSON2F
| ASE_LEXT
);
23746 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
23749 default: /* Invalid */
23750 MIPS_INVAL("special2_legacy");
23751 gen_reserved_instruction(ctx
);
23756 static void decode_opc_special3_r6(CPUMIPSState
*env
, DisasContext
*ctx
)
23758 int rs
, rt
, rd
, sa
;
23762 rs
= (ctx
->opcode
>> 21) & 0x1f;
23763 rt
= (ctx
->opcode
>> 16) & 0x1f;
23764 rd
= (ctx
->opcode
>> 11) & 0x1f;
23765 sa
= (ctx
->opcode
>> 6) & 0x1f;
23766 imm
= (int16_t)ctx
->opcode
>> 7;
23768 op1
= MASK_SPECIAL3(ctx
->opcode
);
23772 /* hint codes 24-31 are reserved and signal RI */
23773 gen_reserved_instruction(ctx
);
23775 /* Treat as NOP. */
23778 check_cp0_enabled(ctx
);
23779 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
23780 gen_cache_operation(ctx
, rt
, rs
, imm
);
23784 gen_st_cond(ctx
, rt
, rs
, imm
, MO_TESL
, false);
23787 gen_ld(ctx
, op1
, rt
, rs
, imm
);
23792 /* Treat as NOP. */
23795 op2
= MASK_BSHFL(ctx
->opcode
);
23801 gen_align(ctx
, 32, rd
, rs
, rt
, sa
& 3);
23804 gen_bitswap(ctx
, op2
, rd
, rt
);
23809 #ifndef CONFIG_USER_ONLY
23811 if (unlikely(ctx
->gi
<= 1)) {
23812 gen_reserved_instruction(ctx
);
23814 check_cp0_enabled(ctx
);
23815 switch ((ctx
->opcode
>> 6) & 3) {
23816 case 0: /* GINVI */
23817 /* Treat as NOP. */
23819 case 2: /* GINVT */
23820 gen_helper_0e1i(ginvt
, cpu_gpr
[rs
], extract32(ctx
->opcode
, 8, 2));
23823 gen_reserved_instruction(ctx
);
23828 #if defined(TARGET_MIPS64)
23830 gen_st_cond(ctx
, rt
, rs
, imm
, MO_TEQ
, false);
23833 gen_ld(ctx
, op1
, rt
, rs
, imm
);
23836 check_mips_64(ctx
);
23839 /* Treat as NOP. */
23842 op2
= MASK_DBSHFL(ctx
->opcode
);
23852 gen_align(ctx
, 64, rd
, rs
, rt
, sa
& 7);
23855 gen_bitswap(ctx
, op2
, rd
, rt
);
23862 default: /* Invalid */
23863 MIPS_INVAL("special3_r6");
23864 gen_reserved_instruction(ctx
);
23869 static void decode_opc_special3_legacy(CPUMIPSState
*env
, DisasContext
*ctx
)
23874 rs
= (ctx
->opcode
>> 21) & 0x1f;
23875 rt
= (ctx
->opcode
>> 16) & 0x1f;
23876 rd
= (ctx
->opcode
>> 11) & 0x1f;
23878 op1
= MASK_SPECIAL3(ctx
->opcode
);
23881 case OPC_DIVU_G_2E
:
23883 case OPC_MODU_G_2E
:
23884 case OPC_MULT_G_2E
:
23885 case OPC_MULTU_G_2E
:
23887 * OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
23888 * the same mask and op1.
23890 if ((ctx
->insn_flags
& ASE_DSP_R2
) && (op1
== OPC_MULT_G_2E
)) {
23891 op2
= MASK_ADDUH_QB(ctx
->opcode
);
23894 case OPC_ADDUH_R_QB
:
23896 case OPC_ADDQH_R_PH
:
23898 case OPC_ADDQH_R_W
:
23900 case OPC_SUBUH_R_QB
:
23902 case OPC_SUBQH_R_PH
:
23904 case OPC_SUBQH_R_W
:
23905 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
23910 case OPC_MULQ_RS_W
:
23911 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
23914 MIPS_INVAL("MASK ADDUH.QB");
23915 gen_reserved_instruction(ctx
);
23918 } else if (ctx
->insn_flags
& INSN_LOONGSON2E
) {
23919 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
23921 gen_reserved_instruction(ctx
);
23925 op2
= MASK_LX(ctx
->opcode
);
23927 #if defined(TARGET_MIPS64)
23933 gen_mipsdsp_ld(ctx
, op2
, rd
, rs
, rt
);
23935 default: /* Invalid */
23936 MIPS_INVAL("MASK LX");
23937 gen_reserved_instruction(ctx
);
23941 case OPC_ABSQ_S_PH_DSP
:
23942 op2
= MASK_ABSQ_S_PH(ctx
->opcode
);
23944 case OPC_ABSQ_S_QB
:
23945 case OPC_ABSQ_S_PH
:
23947 case OPC_PRECEQ_W_PHL
:
23948 case OPC_PRECEQ_W_PHR
:
23949 case OPC_PRECEQU_PH_QBL
:
23950 case OPC_PRECEQU_PH_QBR
:
23951 case OPC_PRECEQU_PH_QBLA
:
23952 case OPC_PRECEQU_PH_QBRA
:
23953 case OPC_PRECEU_PH_QBL
:
23954 case OPC_PRECEU_PH_QBR
:
23955 case OPC_PRECEU_PH_QBLA
:
23956 case OPC_PRECEU_PH_QBRA
:
23957 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
23964 gen_mipsdsp_bitinsn(ctx
, op1
, op2
, rd
, rt
);
23967 MIPS_INVAL("MASK ABSQ_S.PH");
23968 gen_reserved_instruction(ctx
);
23972 case OPC_ADDU_QB_DSP
:
23973 op2
= MASK_ADDU_QB(ctx
->opcode
);
23976 case OPC_ADDQ_S_PH
:
23979 case OPC_ADDU_S_QB
:
23981 case OPC_ADDU_S_PH
:
23983 case OPC_SUBQ_S_PH
:
23986 case OPC_SUBU_S_QB
:
23988 case OPC_SUBU_S_PH
:
23992 case OPC_RADDU_W_QB
:
23993 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
23995 case OPC_MULEU_S_PH_QBL
:
23996 case OPC_MULEU_S_PH_QBR
:
23997 case OPC_MULQ_RS_PH
:
23998 case OPC_MULEQ_S_W_PHL
:
23999 case OPC_MULEQ_S_W_PHR
:
24000 case OPC_MULQ_S_PH
:
24001 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
24003 default: /* Invalid */
24004 MIPS_INVAL("MASK ADDU.QB");
24005 gen_reserved_instruction(ctx
);
24010 case OPC_CMPU_EQ_QB_DSP
:
24011 op2
= MASK_CMPU_EQ_QB(ctx
->opcode
);
24013 case OPC_PRECR_SRA_PH_W
:
24014 case OPC_PRECR_SRA_R_PH_W
:
24015 gen_mipsdsp_arith(ctx
, op1
, op2
, rt
, rs
, rd
);
24017 case OPC_PRECR_QB_PH
:
24018 case OPC_PRECRQ_QB_PH
:
24019 case OPC_PRECRQ_PH_W
:
24020 case OPC_PRECRQ_RS_PH_W
:
24021 case OPC_PRECRQU_S_QB_PH
:
24022 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
24024 case OPC_CMPU_EQ_QB
:
24025 case OPC_CMPU_LT_QB
:
24026 case OPC_CMPU_LE_QB
:
24027 case OPC_CMP_EQ_PH
:
24028 case OPC_CMP_LT_PH
:
24029 case OPC_CMP_LE_PH
:
24030 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
24032 case OPC_CMPGU_EQ_QB
:
24033 case OPC_CMPGU_LT_QB
:
24034 case OPC_CMPGU_LE_QB
:
24035 case OPC_CMPGDU_EQ_QB
:
24036 case OPC_CMPGDU_LT_QB
:
24037 case OPC_CMPGDU_LE_QB
:
24040 case OPC_PACKRL_PH
:
24041 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
24043 default: /* Invalid */
24044 MIPS_INVAL("MASK CMPU.EQ.QB");
24045 gen_reserved_instruction(ctx
);
24049 case OPC_SHLL_QB_DSP
:
24050 gen_mipsdsp_shift(ctx
, op1
, rd
, rs
, rt
);
24052 case OPC_DPA_W_PH_DSP
:
24053 op2
= MASK_DPA_W_PH(ctx
->opcode
);
24055 case OPC_DPAU_H_QBL
:
24056 case OPC_DPAU_H_QBR
:
24057 case OPC_DPSU_H_QBL
:
24058 case OPC_DPSU_H_QBR
:
24060 case OPC_DPAX_W_PH
:
24061 case OPC_DPAQ_S_W_PH
:
24062 case OPC_DPAQX_S_W_PH
:
24063 case OPC_DPAQX_SA_W_PH
:
24065 case OPC_DPSX_W_PH
:
24066 case OPC_DPSQ_S_W_PH
:
24067 case OPC_DPSQX_S_W_PH
:
24068 case OPC_DPSQX_SA_W_PH
:
24069 case OPC_MULSAQ_S_W_PH
:
24070 case OPC_DPAQ_SA_L_W
:
24071 case OPC_DPSQ_SA_L_W
:
24072 case OPC_MAQ_S_W_PHL
:
24073 case OPC_MAQ_S_W_PHR
:
24074 case OPC_MAQ_SA_W_PHL
:
24075 case OPC_MAQ_SA_W_PHR
:
24076 case OPC_MULSA_W_PH
:
24077 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
24079 default: /* Invalid */
24080 MIPS_INVAL("MASK DPAW.PH");
24081 gen_reserved_instruction(ctx
);
24086 op2
= MASK_INSV(ctx
->opcode
);
24097 t0
= tcg_temp_new();
24098 t1
= tcg_temp_new();
24100 gen_load_gpr(t0
, rt
);
24101 gen_load_gpr(t1
, rs
);
24103 gen_helper_insv(cpu_gpr
[rt
], cpu_env
, t1
, t0
);
24109 default: /* Invalid */
24110 MIPS_INVAL("MASK INSV");
24111 gen_reserved_instruction(ctx
);
24115 case OPC_APPEND_DSP
:
24116 gen_mipsdsp_append(env
, ctx
, op1
, rt
, rs
, rd
);
24118 case OPC_EXTR_W_DSP
:
24119 op2
= MASK_EXTR_W(ctx
->opcode
);
24123 case OPC_EXTR_RS_W
:
24125 case OPC_EXTRV_S_H
:
24127 case OPC_EXTRV_R_W
:
24128 case OPC_EXTRV_RS_W
:
24133 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rt
, rs
, rd
, 1);
24136 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
24142 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
24144 default: /* Invalid */
24145 MIPS_INVAL("MASK EXTR.W");
24146 gen_reserved_instruction(ctx
);
24150 #if defined(TARGET_MIPS64)
24151 case OPC_DDIV_G_2E
:
24152 case OPC_DDIVU_G_2E
:
24153 case OPC_DMULT_G_2E
:
24154 case OPC_DMULTU_G_2E
:
24155 case OPC_DMOD_G_2E
:
24156 case OPC_DMODU_G_2E
:
24157 check_insn(ctx
, INSN_LOONGSON2E
);
24158 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
24160 case OPC_ABSQ_S_QH_DSP
:
24161 op2
= MASK_ABSQ_S_QH(ctx
->opcode
);
24163 case OPC_PRECEQ_L_PWL
:
24164 case OPC_PRECEQ_L_PWR
:
24165 case OPC_PRECEQ_PW_QHL
:
24166 case OPC_PRECEQ_PW_QHR
:
24167 case OPC_PRECEQ_PW_QHLA
:
24168 case OPC_PRECEQ_PW_QHRA
:
24169 case OPC_PRECEQU_QH_OBL
:
24170 case OPC_PRECEQU_QH_OBR
:
24171 case OPC_PRECEQU_QH_OBLA
:
24172 case OPC_PRECEQU_QH_OBRA
:
24173 case OPC_PRECEU_QH_OBL
:
24174 case OPC_PRECEU_QH_OBR
:
24175 case OPC_PRECEU_QH_OBLA
:
24176 case OPC_PRECEU_QH_OBRA
:
24177 case OPC_ABSQ_S_OB
:
24178 case OPC_ABSQ_S_PW
:
24179 case OPC_ABSQ_S_QH
:
24180 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
24188 gen_mipsdsp_bitinsn(ctx
, op1
, op2
, rd
, rt
);
24190 default: /* Invalid */
24191 MIPS_INVAL("MASK ABSQ_S.QH");
24192 gen_reserved_instruction(ctx
);
24196 case OPC_ADDU_OB_DSP
:
24197 op2
= MASK_ADDU_OB(ctx
->opcode
);
24199 case OPC_RADDU_L_OB
:
24201 case OPC_SUBQ_S_PW
:
24203 case OPC_SUBQ_S_QH
:
24205 case OPC_SUBU_S_OB
:
24207 case OPC_SUBU_S_QH
:
24209 case OPC_SUBUH_R_OB
:
24211 case OPC_ADDQ_S_PW
:
24213 case OPC_ADDQ_S_QH
:
24215 case OPC_ADDU_S_OB
:
24217 case OPC_ADDU_S_QH
:
24219 case OPC_ADDUH_R_OB
:
24220 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
24222 case OPC_MULEQ_S_PW_QHL
:
24223 case OPC_MULEQ_S_PW_QHR
:
24224 case OPC_MULEU_S_QH_OBL
:
24225 case OPC_MULEU_S_QH_OBR
:
24226 case OPC_MULQ_RS_QH
:
24227 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
24229 default: /* Invalid */
24230 MIPS_INVAL("MASK ADDU.OB");
24231 gen_reserved_instruction(ctx
);
24235 case OPC_CMPU_EQ_OB_DSP
:
24236 op2
= MASK_CMPU_EQ_OB(ctx
->opcode
);
24238 case OPC_PRECR_SRA_QH_PW
:
24239 case OPC_PRECR_SRA_R_QH_PW
:
24240 /* Return value is rt. */
24241 gen_mipsdsp_arith(ctx
, op1
, op2
, rt
, rs
, rd
);
24243 case OPC_PRECR_OB_QH
:
24244 case OPC_PRECRQ_OB_QH
:
24245 case OPC_PRECRQ_PW_L
:
24246 case OPC_PRECRQ_QH_PW
:
24247 case OPC_PRECRQ_RS_QH_PW
:
24248 case OPC_PRECRQU_S_OB_QH
:
24249 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
24251 case OPC_CMPU_EQ_OB
:
24252 case OPC_CMPU_LT_OB
:
24253 case OPC_CMPU_LE_OB
:
24254 case OPC_CMP_EQ_QH
:
24255 case OPC_CMP_LT_QH
:
24256 case OPC_CMP_LE_QH
:
24257 case OPC_CMP_EQ_PW
:
24258 case OPC_CMP_LT_PW
:
24259 case OPC_CMP_LE_PW
:
24260 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
24262 case OPC_CMPGDU_EQ_OB
:
24263 case OPC_CMPGDU_LT_OB
:
24264 case OPC_CMPGDU_LE_OB
:
24265 case OPC_CMPGU_EQ_OB
:
24266 case OPC_CMPGU_LT_OB
:
24267 case OPC_CMPGU_LE_OB
:
24268 case OPC_PACKRL_PW
:
24272 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
24274 default: /* Invalid */
24275 MIPS_INVAL("MASK CMPU_EQ.OB");
24276 gen_reserved_instruction(ctx
);
24280 case OPC_DAPPEND_DSP
:
24281 gen_mipsdsp_append(env
, ctx
, op1
, rt
, rs
, rd
);
24283 case OPC_DEXTR_W_DSP
:
24284 op2
= MASK_DEXTR_W(ctx
->opcode
);
24291 case OPC_DEXTR_R_L
:
24292 case OPC_DEXTR_RS_L
:
24294 case OPC_DEXTR_R_W
:
24295 case OPC_DEXTR_RS_W
:
24296 case OPC_DEXTR_S_H
:
24298 case OPC_DEXTRV_R_L
:
24299 case OPC_DEXTRV_RS_L
:
24300 case OPC_DEXTRV_S_H
:
24302 case OPC_DEXTRV_R_W
:
24303 case OPC_DEXTRV_RS_W
:
24304 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rt
, rs
, rd
, 1);
24309 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
24311 default: /* Invalid */
24312 MIPS_INVAL("MASK EXTR.W");
24313 gen_reserved_instruction(ctx
);
24317 case OPC_DPAQ_W_QH_DSP
:
24318 op2
= MASK_DPAQ_W_QH(ctx
->opcode
);
24320 case OPC_DPAU_H_OBL
:
24321 case OPC_DPAU_H_OBR
:
24322 case OPC_DPSU_H_OBL
:
24323 case OPC_DPSU_H_OBR
:
24325 case OPC_DPAQ_S_W_QH
:
24327 case OPC_DPSQ_S_W_QH
:
24328 case OPC_MULSAQ_S_W_QH
:
24329 case OPC_DPAQ_SA_L_PW
:
24330 case OPC_DPSQ_SA_L_PW
:
24331 case OPC_MULSAQ_S_L_PW
:
24332 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
24334 case OPC_MAQ_S_W_QHLL
:
24335 case OPC_MAQ_S_W_QHLR
:
24336 case OPC_MAQ_S_W_QHRL
:
24337 case OPC_MAQ_S_W_QHRR
:
24338 case OPC_MAQ_SA_W_QHLL
:
24339 case OPC_MAQ_SA_W_QHLR
:
24340 case OPC_MAQ_SA_W_QHRL
:
24341 case OPC_MAQ_SA_W_QHRR
:
24342 case OPC_MAQ_S_L_PWL
:
24343 case OPC_MAQ_S_L_PWR
:
24348 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
24350 default: /* Invalid */
24351 MIPS_INVAL("MASK DPAQ.W.QH");
24352 gen_reserved_instruction(ctx
);
24356 case OPC_DINSV_DSP
:
24357 op2
= MASK_INSV(ctx
->opcode
);
24368 t0
= tcg_temp_new();
24369 t1
= tcg_temp_new();
24371 gen_load_gpr(t0
, rt
);
24372 gen_load_gpr(t1
, rs
);
24374 gen_helper_dinsv(cpu_gpr
[rt
], cpu_env
, t1
, t0
);
24380 default: /* Invalid */
24381 MIPS_INVAL("MASK DINSV");
24382 gen_reserved_instruction(ctx
);
24386 case OPC_SHLL_OB_DSP
:
24387 gen_mipsdsp_shift(ctx
, op1
, rd
, rs
, rt
);
24390 default: /* Invalid */
24391 MIPS_INVAL("special3_legacy");
24392 gen_reserved_instruction(ctx
);
24398 #if defined(TARGET_MIPS64)
24400 static void decode_mmi(CPUMIPSState
*env
, DisasContext
*ctx
)
24402 uint32_t opc
= MASK_MMI(ctx
->opcode
);
24403 int rs
= extract32(ctx
->opcode
, 21, 5);
24404 int rt
= extract32(ctx
->opcode
, 16, 5);
24405 int rd
= extract32(ctx
->opcode
, 11, 5);
24408 case MMI_OPC_MULT1
:
24409 case MMI_OPC_MULTU1
:
24411 case MMI_OPC_MADDU
:
24412 case MMI_OPC_MADD1
:
24413 case MMI_OPC_MADDU1
:
24414 gen_mul_txx9(ctx
, opc
, rd
, rs
, rt
);
24417 case MMI_OPC_DIVU1
:
24418 gen_div1_tx79(ctx
, opc
, rs
, rt
);
24421 MIPS_INVAL("TX79 MMI class");
24422 gen_reserved_instruction(ctx
);
24427 static void gen_mmi_lq(CPUMIPSState
*env
, DisasContext
*ctx
)
24429 gen_reserved_instruction(ctx
); /* TODO: MMI_OPC_LQ */
24432 static void gen_mmi_sq(DisasContext
*ctx
, int base
, int rt
, int offset
)
24434 gen_reserved_instruction(ctx
); /* TODO: MMI_OPC_SQ */
24438 * The TX79-specific instruction Store Quadword
24440 * +--------+-------+-------+------------------------+
24441 * | 011111 | base | rt | offset | SQ
24442 * +--------+-------+-------+------------------------+
24445 * has the same opcode as the Read Hardware Register instruction
24447 * +--------+-------+-------+-------+-------+--------+
24448 * | 011111 | 00000 | rt | rd | 00000 | 111011 | RDHWR
24449 * +--------+-------+-------+-------+-------+--------+
24452 * that is required, trapped and emulated by the Linux kernel. However, all
24453 * RDHWR encodings yield address error exceptions on the TX79 since the SQ
24454 * offset is odd. Therefore all valid SQ instructions can execute normally.
24455 * In user mode, QEMU must verify the upper and lower 11 bits to distinguish
24456 * between SQ and RDHWR, as the Linux kernel does.
24458 static void decode_mmi_sq(CPUMIPSState
*env
, DisasContext
*ctx
)
24460 int base
= extract32(ctx
->opcode
, 21, 5);
24461 int rt
= extract32(ctx
->opcode
, 16, 5);
24462 int offset
= extract32(ctx
->opcode
, 0, 16);
24464 #ifdef CONFIG_USER_ONLY
24465 uint32_t op1
= MASK_SPECIAL3(ctx
->opcode
);
24466 uint32_t op2
= extract32(ctx
->opcode
, 6, 5);
24468 if (base
== 0 && op2
== 0 && op1
== OPC_RDHWR
) {
24469 int rd
= extract32(ctx
->opcode
, 11, 5);
24471 gen_rdhwr(ctx
, rt
, rd
, 0);
24476 gen_mmi_sq(ctx
, base
, rt
, offset
);
24481 static void decode_opc_special3(CPUMIPSState
*env
, DisasContext
*ctx
)
24483 int rs
, rt
, rd
, sa
;
24487 rs
= (ctx
->opcode
>> 21) & 0x1f;
24488 rt
= (ctx
->opcode
>> 16) & 0x1f;
24489 rd
= (ctx
->opcode
>> 11) & 0x1f;
24490 sa
= (ctx
->opcode
>> 6) & 0x1f;
24491 imm
= sextract32(ctx
->opcode
, 7, 9);
24493 op1
= MASK_SPECIAL3(ctx
->opcode
);
24496 * EVA loads and stores overlap Loongson 2E instructions decoded by
24497 * decode_opc_special3_legacy(), so be careful to allow their decoding when
24510 check_cp0_enabled(ctx
);
24511 gen_ld(ctx
, op1
, rt
, rs
, imm
);
24518 check_cp0_enabled(ctx
);
24519 gen_st(ctx
, op1
, rt
, rs
, imm
);
24522 check_cp0_enabled(ctx
);
24523 gen_st_cond(ctx
, rt
, rs
, imm
, MO_TESL
, true);
24527 check_cp0_enabled(ctx
);
24528 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
24529 gen_cache_operation(ctx
, rt
, rs
, imm
);
24533 check_cp0_enabled(ctx
);
24534 /* Treat as NOP. */
24542 check_insn(ctx
, ISA_MIPS_R2
);
24543 gen_bitops(ctx
, op1
, rt
, rs
, sa
, rd
);
24546 op2
= MASK_BSHFL(ctx
->opcode
);
24553 check_insn(ctx
, ISA_MIPS_R6
);
24554 decode_opc_special3_r6(env
, ctx
);
24557 check_insn(ctx
, ISA_MIPS_R2
);
24558 gen_bshfl(ctx
, op2
, rt
, rd
);
24562 #if defined(TARGET_MIPS64)
24569 check_insn(ctx
, ISA_MIPS_R2
);
24570 check_mips_64(ctx
);
24571 gen_bitops(ctx
, op1
, rt
, rs
, sa
, rd
);
24574 op2
= MASK_DBSHFL(ctx
->opcode
);
24585 check_insn(ctx
, ISA_MIPS_R6
);
24586 decode_opc_special3_r6(env
, ctx
);
24589 check_insn(ctx
, ISA_MIPS_R2
);
24590 check_mips_64(ctx
);
24591 op2
= MASK_DBSHFL(ctx
->opcode
);
24592 gen_bshfl(ctx
, op2
, rt
, rd
);
24598 gen_rdhwr(ctx
, rt
, rd
, extract32(ctx
->opcode
, 6, 3));
24603 TCGv t0
= tcg_temp_new();
24604 TCGv t1
= tcg_temp_new();
24606 gen_load_gpr(t0
, rt
);
24607 gen_load_gpr(t1
, rs
);
24608 gen_helper_fork(t0
, t1
);
24616 TCGv t0
= tcg_temp_new();
24618 gen_load_gpr(t0
, rs
);
24619 gen_helper_yield(t0
, cpu_env
, t0
);
24620 gen_store_gpr(t0
, rd
);
24625 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
24626 decode_opc_special3_r6(env
, ctx
);
24628 decode_opc_special3_legacy(env
, ctx
);
24633 static bool decode_opc_legacy(CPUMIPSState
*env
, DisasContext
*ctx
)
24636 int rs
, rt
, rd
, sa
;
24640 op
= MASK_OP_MAJOR(ctx
->opcode
);
24641 rs
= (ctx
->opcode
>> 21) & 0x1f;
24642 rt
= (ctx
->opcode
>> 16) & 0x1f;
24643 rd
= (ctx
->opcode
>> 11) & 0x1f;
24644 sa
= (ctx
->opcode
>> 6) & 0x1f;
24645 imm
= (int16_t)ctx
->opcode
;
24648 decode_opc_special(env
, ctx
);
24651 #if defined(TARGET_MIPS64)
24652 if ((ctx
->insn_flags
& INSN_R5900
) && (ctx
->insn_flags
& ASE_MMI
)) {
24653 decode_mmi(env
, ctx
);
24657 if (TARGET_LONG_BITS
== 32 && (ctx
->insn_flags
& ASE_MXU
)) {
24658 if (MASK_SPECIAL2(ctx
->opcode
) == OPC_MUL
) {
24659 gen_arith(ctx
, OPC_MUL
, rd
, rs
, rt
);
24661 decode_ase_mxu(ctx
, ctx
->opcode
);
24665 decode_opc_special2_legacy(env
, ctx
);
24668 #if defined(TARGET_MIPS64)
24669 if (ctx
->insn_flags
& INSN_R5900
) {
24670 decode_mmi_sq(env
, ctx
); /* MMI_OPC_SQ */
24672 decode_opc_special3(env
, ctx
);
24675 decode_opc_special3(env
, ctx
);
24679 op1
= MASK_REGIMM(ctx
->opcode
);
24681 case OPC_BLTZL
: /* REGIMM branches */
24685 check_insn(ctx
, ISA_MIPS2
);
24686 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
24690 gen_compute_branch(ctx
, op1
, 4, rs
, -1, imm
<< 2, 4);
24694 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
24696 /* OPC_NAL, OPC_BAL */
24697 gen_compute_branch(ctx
, op1
, 4, 0, -1, imm
<< 2, 4);
24699 gen_reserved_instruction(ctx
);
24702 gen_compute_branch(ctx
, op1
, 4, rs
, -1, imm
<< 2, 4);
24705 case OPC_TGEI
: /* REGIMM traps */
24712 check_insn(ctx
, ISA_MIPS2
);
24713 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
24714 gen_trap(ctx
, op1
, rs
, -1, imm
);
24717 check_insn(ctx
, ISA_MIPS_R6
);
24718 gen_reserved_instruction(ctx
);
24721 check_insn(ctx
, ISA_MIPS_R2
);
24723 * Break the TB to be able to sync copied instructions
24726 ctx
->base
.is_jmp
= DISAS_STOP
;
24728 case OPC_BPOSGE32
: /* MIPS DSP branch */
24729 #if defined(TARGET_MIPS64)
24733 gen_compute_branch(ctx
, op1
, 4, -1, -2, (int32_t)imm
<< 2, 4);
24735 #if defined(TARGET_MIPS64)
24737 check_insn(ctx
, ISA_MIPS_R6
);
24738 check_mips_64(ctx
);
24740 tcg_gen_addi_tl(cpu_gpr
[rs
], cpu_gpr
[rs
], (int64_t)imm
<< 32);
24744 check_insn(ctx
, ISA_MIPS_R6
);
24745 check_mips_64(ctx
);
24747 tcg_gen_addi_tl(cpu_gpr
[rs
], cpu_gpr
[rs
], (int64_t)imm
<< 48);
24751 default: /* Invalid */
24752 MIPS_INVAL("regimm");
24753 gen_reserved_instruction(ctx
);
24758 check_cp0_enabled(ctx
);
24759 op1
= MASK_CP0(ctx
->opcode
);
24767 #if defined(TARGET_MIPS64)
24771 #ifndef CONFIG_USER_ONLY
24772 gen_cp0(env
, ctx
, op1
, rt
, rd
);
24773 #endif /* !CONFIG_USER_ONLY */
24791 #ifndef CONFIG_USER_ONLY
24792 gen_cp0(env
, ctx
, MASK_C0(ctx
->opcode
), rt
, rd
);
24793 #endif /* !CONFIG_USER_ONLY */
24796 #ifndef CONFIG_USER_ONLY
24799 TCGv t0
= tcg_temp_new();
24801 op2
= MASK_MFMC0(ctx
->opcode
);
24805 gen_helper_dmt(t0
);
24806 gen_store_gpr(t0
, rt
);
24810 gen_helper_emt(t0
);
24811 gen_store_gpr(t0
, rt
);
24815 gen_helper_dvpe(t0
, cpu_env
);
24816 gen_store_gpr(t0
, rt
);
24820 gen_helper_evpe(t0
, cpu_env
);
24821 gen_store_gpr(t0
, rt
);
24824 check_insn(ctx
, ISA_MIPS_R6
);
24826 gen_helper_dvp(t0
, cpu_env
);
24827 gen_store_gpr(t0
, rt
);
24831 check_insn(ctx
, ISA_MIPS_R6
);
24833 gen_helper_evp(t0
, cpu_env
);
24834 gen_store_gpr(t0
, rt
);
24838 check_insn(ctx
, ISA_MIPS_R2
);
24839 save_cpu_state(ctx
, 1);
24840 gen_helper_di(t0
, cpu_env
);
24841 gen_store_gpr(t0
, rt
);
24843 * Stop translation as we may have switched
24844 * the execution mode.
24846 ctx
->base
.is_jmp
= DISAS_STOP
;
24849 check_insn(ctx
, ISA_MIPS_R2
);
24850 save_cpu_state(ctx
, 1);
24851 gen_helper_ei(t0
, cpu_env
);
24852 gen_store_gpr(t0
, rt
);
24854 * DISAS_STOP isn't sufficient, we need to ensure we break
24855 * out of translated code to check for pending interrupts.
24857 gen_save_pc(ctx
->base
.pc_next
+ 4);
24858 ctx
->base
.is_jmp
= DISAS_EXIT
;
24860 default: /* Invalid */
24861 MIPS_INVAL("mfmc0");
24862 gen_reserved_instruction(ctx
);
24867 #endif /* !CONFIG_USER_ONLY */
24870 check_insn(ctx
, ISA_MIPS_R2
);
24871 gen_load_srsgpr(rt
, rd
);
24874 check_insn(ctx
, ISA_MIPS_R2
);
24875 gen_store_srsgpr(rt
, rd
);
24879 gen_reserved_instruction(ctx
);
24883 case OPC_BOVC
: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */
24884 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
24885 /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */
24886 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
24889 /* Arithmetic with immediate opcode */
24890 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
24894 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
24896 case OPC_SLTI
: /* Set on less than with immediate opcode */
24898 gen_slt_imm(ctx
, op
, rt
, rs
, imm
);
24900 case OPC_ANDI
: /* Arithmetic with immediate opcode */
24901 case OPC_LUI
: /* OPC_AUI */
24904 gen_logic_imm(ctx
, op
, rt
, rs
, imm
);
24906 case OPC_J
: /* Jump */
24908 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
24909 gen_compute_branch(ctx
, op
, 4, rs
, rt
, offset
, 4);
24912 case OPC_BLEZC
: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */
24913 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
24915 gen_reserved_instruction(ctx
);
24918 /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */
24919 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
24922 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
24925 case OPC_BGTZC
: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */
24926 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
24928 gen_reserved_instruction(ctx
);
24931 /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */
24932 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
24935 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
24938 case OPC_BLEZALC
: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */
24941 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
24943 check_insn(ctx
, ISA_MIPS_R6
);
24944 /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */
24945 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
24948 case OPC_BGTZALC
: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */
24951 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
24953 check_insn(ctx
, ISA_MIPS_R6
);
24954 /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */
24955 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
24960 check_insn(ctx
, ISA_MIPS2
);
24961 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
24965 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
24967 case OPC_LL
: /* Load and stores */
24968 check_insn(ctx
, ISA_MIPS2
);
24969 if (ctx
->insn_flags
& INSN_R5900
) {
24970 check_insn_opc_user_only(ctx
, INSN_R5900
);
24981 gen_ld(ctx
, op
, rt
, rs
, imm
);
24988 gen_st(ctx
, op
, rt
, rs
, imm
);
24991 check_insn(ctx
, ISA_MIPS2
);
24992 if (ctx
->insn_flags
& INSN_R5900
) {
24993 check_insn_opc_user_only(ctx
, INSN_R5900
);
24995 gen_st_cond(ctx
, rt
, rs
, imm
, MO_TESL
, false);
24998 check_cp0_enabled(ctx
);
24999 check_insn(ctx
, ISA_MIPS3
| ISA_MIPS_R1
);
25000 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
25001 gen_cache_operation(ctx
, rt
, rs
, imm
);
25003 /* Treat as NOP. */
25006 if (ctx
->insn_flags
& INSN_R5900
) {
25007 /* Treat as NOP. */
25009 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS_R1
);
25010 /* Treat as NOP. */
25014 /* Floating point (COP1). */
25019 gen_cop1_ldst(ctx
, op
, rt
, rs
, imm
);
25023 op1
= MASK_CP1(ctx
->opcode
);
25028 check_cp1_enabled(ctx
);
25029 check_insn(ctx
, ISA_MIPS_R2
);
25035 check_cp1_enabled(ctx
);
25036 gen_cp1(ctx
, op1
, rt
, rd
);
25038 #if defined(TARGET_MIPS64)
25041 check_cp1_enabled(ctx
);
25042 check_insn(ctx
, ISA_MIPS3
);
25043 check_mips_64(ctx
);
25044 gen_cp1(ctx
, op1
, rt
, rd
);
25047 case OPC_BC1EQZ
: /* OPC_BC1ANY2 */
25048 check_cp1_enabled(ctx
);
25049 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
25051 gen_compute_branch1_r6(ctx
, MASK_CP1(ctx
->opcode
),
25056 check_insn(ctx
, ASE_MIPS3D
);
25057 gen_compute_branch1(ctx
, MASK_BC1(ctx
->opcode
),
25058 (rt
>> 2) & 0x7, imm
<< 2);
25062 check_cp1_enabled(ctx
);
25063 check_insn(ctx
, ISA_MIPS_R6
);
25064 gen_compute_branch1_r6(ctx
, MASK_CP1(ctx
->opcode
),
25068 check_cp1_enabled(ctx
);
25069 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
25071 check_insn(ctx
, ASE_MIPS3D
);
25074 check_cp1_enabled(ctx
);
25075 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
25076 gen_compute_branch1(ctx
, MASK_BC1(ctx
->opcode
),
25077 (rt
>> 2) & 0x7, imm
<< 2);
25084 check_cp1_enabled(ctx
);
25085 gen_farith(ctx
, ctx
->opcode
& FOP(0x3f, 0x1f), rt
, rd
, sa
,
25091 int r6_op
= ctx
->opcode
& FOP(0x3f, 0x1f);
25092 check_cp1_enabled(ctx
);
25093 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
25095 case R6_OPC_CMP_AF_S
:
25096 case R6_OPC_CMP_UN_S
:
25097 case R6_OPC_CMP_EQ_S
:
25098 case R6_OPC_CMP_UEQ_S
:
25099 case R6_OPC_CMP_LT_S
:
25100 case R6_OPC_CMP_ULT_S
:
25101 case R6_OPC_CMP_LE_S
:
25102 case R6_OPC_CMP_ULE_S
:
25103 case R6_OPC_CMP_SAF_S
:
25104 case R6_OPC_CMP_SUN_S
:
25105 case R6_OPC_CMP_SEQ_S
:
25106 case R6_OPC_CMP_SEUQ_S
:
25107 case R6_OPC_CMP_SLT_S
:
25108 case R6_OPC_CMP_SULT_S
:
25109 case R6_OPC_CMP_SLE_S
:
25110 case R6_OPC_CMP_SULE_S
:
25111 case R6_OPC_CMP_OR_S
:
25112 case R6_OPC_CMP_UNE_S
:
25113 case R6_OPC_CMP_NE_S
:
25114 case R6_OPC_CMP_SOR_S
:
25115 case R6_OPC_CMP_SUNE_S
:
25116 case R6_OPC_CMP_SNE_S
:
25117 gen_r6_cmp_s(ctx
, ctx
->opcode
& 0x1f, rt
, rd
, sa
);
25119 case R6_OPC_CMP_AF_D
:
25120 case R6_OPC_CMP_UN_D
:
25121 case R6_OPC_CMP_EQ_D
:
25122 case R6_OPC_CMP_UEQ_D
:
25123 case R6_OPC_CMP_LT_D
:
25124 case R6_OPC_CMP_ULT_D
:
25125 case R6_OPC_CMP_LE_D
:
25126 case R6_OPC_CMP_ULE_D
:
25127 case R6_OPC_CMP_SAF_D
:
25128 case R6_OPC_CMP_SUN_D
:
25129 case R6_OPC_CMP_SEQ_D
:
25130 case R6_OPC_CMP_SEUQ_D
:
25131 case R6_OPC_CMP_SLT_D
:
25132 case R6_OPC_CMP_SULT_D
:
25133 case R6_OPC_CMP_SLE_D
:
25134 case R6_OPC_CMP_SULE_D
:
25135 case R6_OPC_CMP_OR_D
:
25136 case R6_OPC_CMP_UNE_D
:
25137 case R6_OPC_CMP_NE_D
:
25138 case R6_OPC_CMP_SOR_D
:
25139 case R6_OPC_CMP_SUNE_D
:
25140 case R6_OPC_CMP_SNE_D
:
25141 gen_r6_cmp_d(ctx
, ctx
->opcode
& 0x1f, rt
, rd
, sa
);
25144 gen_farith(ctx
, ctx
->opcode
& FOP(0x3f, 0x1f),
25145 rt
, rd
, sa
, (imm
>> 8) & 0x7);
25150 gen_farith(ctx
, ctx
->opcode
& FOP(0x3f, 0x1f), rt
, rd
, sa
,
25157 gen_reserved_instruction(ctx
);
25162 /* Compact branches [R6] and COP2 [non-R6] */
25163 case OPC_BC
: /* OPC_LWC2 */
25164 case OPC_BALC
: /* OPC_SWC2 */
25165 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
25166 /* OPC_BC, OPC_BALC */
25167 gen_compute_compact_branch(ctx
, op
, 0, 0,
25168 sextract32(ctx
->opcode
<< 2, 0, 28));
25169 } else if (ctx
->insn_flags
& ASE_LEXT
) {
25170 gen_loongson_lswc2(ctx
, rt
, rs
, rd
);
25172 /* OPC_LWC2, OPC_SWC2 */
25173 /* COP2: Not implemented. */
25174 generate_exception_err(ctx
, EXCP_CpU
, 2);
25177 case OPC_BEQZC
: /* OPC_JIC, OPC_LDC2 */
25178 case OPC_BNEZC
: /* OPC_JIALC, OPC_SDC2 */
25179 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
25181 /* OPC_BEQZC, OPC_BNEZC */
25182 gen_compute_compact_branch(ctx
, op
, rs
, 0,
25183 sextract32(ctx
->opcode
<< 2, 0, 23));
25185 /* OPC_JIC, OPC_JIALC */
25186 gen_compute_compact_branch(ctx
, op
, 0, rt
, imm
);
25188 } else if (ctx
->insn_flags
& ASE_LEXT
) {
25189 gen_loongson_lsdc2(ctx
, rt
, rs
, rd
);
25191 /* OPC_LWC2, OPC_SWC2 */
25192 /* COP2: Not implemented. */
25193 generate_exception_err(ctx
, EXCP_CpU
, 2);
25197 check_insn(ctx
, ASE_LMMI
);
25198 /* Note that these instructions use different fields. */
25199 gen_loongson_multimedia(ctx
, sa
, rd
, rt
);
25203 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
25204 check_cp1_enabled(ctx
);
25205 op1
= MASK_CP3(ctx
->opcode
);
25209 check_insn(ctx
, ISA_MIPS5
| ISA_MIPS_R2
);
25215 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS_R2
);
25216 gen_flt3_ldst(ctx
, op1
, sa
, rd
, rs
, rt
);
25219 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS_R2
);
25220 /* Treat as NOP. */
25223 check_insn(ctx
, ISA_MIPS5
| ISA_MIPS_R2
);
25237 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS_R2
);
25238 gen_flt3_arith(ctx
, op1
, sa
, rs
, rd
, rt
);
25242 gen_reserved_instruction(ctx
);
25246 generate_exception_err(ctx
, EXCP_CpU
, 1);
25250 #if defined(TARGET_MIPS64)
25251 /* MIPS64 opcodes */
25253 if (ctx
->insn_flags
& INSN_R5900
) {
25254 check_insn_opc_user_only(ctx
, INSN_R5900
);
25261 check_insn(ctx
, ISA_MIPS3
);
25262 check_mips_64(ctx
);
25263 gen_ld(ctx
, op
, rt
, rs
, imm
);
25268 check_insn(ctx
, ISA_MIPS3
);
25269 check_mips_64(ctx
);
25270 gen_st(ctx
, op
, rt
, rs
, imm
);
25273 check_insn(ctx
, ISA_MIPS3
);
25274 if (ctx
->insn_flags
& INSN_R5900
) {
25275 check_insn_opc_user_only(ctx
, INSN_R5900
);
25277 check_mips_64(ctx
);
25278 gen_st_cond(ctx
, rt
, rs
, imm
, MO_TEQ
, false);
25280 case OPC_BNVC
: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */
25281 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
25282 /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */
25283 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
25286 check_insn(ctx
, ISA_MIPS3
);
25287 check_mips_64(ctx
);
25288 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
25292 check_insn(ctx
, ISA_MIPS3
);
25293 check_mips_64(ctx
);
25294 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
25297 case OPC_BNVC
: /* OPC_BNEZALC, OPC_BNEC */
25298 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
25299 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
25301 MIPS_INVAL("major opcode");
25302 gen_reserved_instruction(ctx
);
25306 case OPC_DAUI
: /* OPC_JALX */
25307 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
25308 #if defined(TARGET_MIPS64)
25310 check_mips_64(ctx
);
25312 generate_exception(ctx
, EXCP_RI
);
25313 } else if (rt
!= 0) {
25314 TCGv t0
= tcg_temp_new();
25315 gen_load_gpr(t0
, rs
);
25316 tcg_gen_addi_tl(cpu_gpr
[rt
], t0
, imm
<< 16);
25320 gen_reserved_instruction(ctx
);
25321 MIPS_INVAL("major opcode");
25325 check_insn(ctx
, ASE_MIPS16
| ASE_MICROMIPS
);
25326 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
25327 gen_compute_branch(ctx
, op
, 4, rs
, rt
, offset
, 4);
25330 case OPC_MDMX
: /* MMI_OPC_LQ */
25331 if (ctx
->insn_flags
& INSN_R5900
) {
25332 #if defined(TARGET_MIPS64)
25333 gen_mmi_lq(env
, ctx
);
25336 /* MDMX: Not implemented. */
25340 check_insn(ctx
, ISA_MIPS_R6
);
25341 gen_pcrel(ctx
, ctx
->opcode
, ctx
->base
.pc_next
, rs
);
25343 default: /* Invalid */
25344 MIPS_INVAL("major opcode");
25350 static void decode_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
25352 /* make sure instructions are on a word boundary */
25353 if (ctx
->base
.pc_next
& 0x3) {
25354 env
->CP0_BadVAddr
= ctx
->base
.pc_next
;
25355 generate_exception_err(ctx
, EXCP_AdEL
, EXCP_INST_NOTAVAIL
);
25359 /* Handle blikely not taken case */
25360 if ((ctx
->hflags
& MIPS_HFLAG_BMASK_BASE
) == MIPS_HFLAG_BL
) {
25361 TCGLabel
*l1
= gen_new_label();
25363 tcg_gen_brcondi_tl(TCG_COND_NE
, bcond
, 0, l1
);
25364 tcg_gen_movi_i32(hflags
, ctx
->hflags
& ~MIPS_HFLAG_BMASK
);
25365 gen_goto_tb(ctx
, 1, ctx
->base
.pc_next
+ 4);
25369 /* Transition to the auto-generated decoder. */
25371 /* ISA extensions */
25372 if (ase_msa_available(env
) && decode_ase_msa(ctx
, ctx
->opcode
)) {
25376 /* ISA (from latest to oldest) */
25377 if (cpu_supports_isa(env
, ISA_MIPS_R6
) && decode_isa_rel6(ctx
, ctx
->opcode
)) {
25380 if (cpu_supports_isa(env
, INSN_R5900
) && decode_ext_txx9(ctx
, ctx
->opcode
)) {
25384 if (decode_opc_legacy(env
, ctx
)) {
25388 gen_reserved_instruction(ctx
);
25391 static void mips_tr_init_disas_context(DisasContextBase
*dcbase
, CPUState
*cs
)
25393 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
25394 CPUMIPSState
*env
= cs
->env_ptr
;
25396 ctx
->page_start
= ctx
->base
.pc_first
& TARGET_PAGE_MASK
;
25397 ctx
->saved_pc
= -1;
25398 ctx
->insn_flags
= env
->insn_flags
;
25399 ctx
->CP0_Config1
= env
->CP0_Config1
;
25400 ctx
->CP0_Config2
= env
->CP0_Config2
;
25401 ctx
->CP0_Config3
= env
->CP0_Config3
;
25402 ctx
->CP0_Config5
= env
->CP0_Config5
;
25404 ctx
->kscrexist
= (env
->CP0_Config4
>> CP0C4_KScrExist
) & 0xff;
25405 ctx
->rxi
= (env
->CP0_Config3
>> CP0C3_RXI
) & 1;
25406 ctx
->ie
= (env
->CP0_Config4
>> CP0C4_IE
) & 3;
25407 ctx
->bi
= (env
->CP0_Config3
>> CP0C3_BI
) & 1;
25408 ctx
->bp
= (env
->CP0_Config3
>> CP0C3_BP
) & 1;
25409 ctx
->PAMask
= env
->PAMask
;
25410 ctx
->mvh
= (env
->CP0_Config5
>> CP0C5_MVH
) & 1;
25411 ctx
->eva
= (env
->CP0_Config5
>> CP0C5_EVA
) & 1;
25412 ctx
->sc
= (env
->CP0_Config3
>> CP0C3_SC
) & 1;
25413 ctx
->CP0_LLAddr_shift
= env
->CP0_LLAddr_shift
;
25414 ctx
->cmgcr
= (env
->CP0_Config3
>> CP0C3_CMGCR
) & 1;
25415 /* Restore delay slot state from the tb context. */
25416 ctx
->hflags
= (uint32_t)ctx
->base
.tb
->flags
; /* FIXME: maybe use 64 bits? */
25417 ctx
->ulri
= (env
->CP0_Config3
>> CP0C3_ULRI
) & 1;
25418 ctx
->ps
= ((env
->active_fpu
.fcr0
>> FCR0_PS
) & 1) ||
25419 (env
->insn_flags
& (INSN_LOONGSON2E
| INSN_LOONGSON2F
));
25420 ctx
->vp
= (env
->CP0_Config5
>> CP0C5_VP
) & 1;
25421 ctx
->mrp
= (env
->CP0_Config5
>> CP0C5_MRP
) & 1;
25422 ctx
->nan2008
= (env
->active_fpu
.fcr31
>> FCR31_NAN2008
) & 1;
25423 ctx
->abs2008
= (env
->active_fpu
.fcr31
>> FCR31_ABS2008
) & 1;
25424 ctx
->mi
= (env
->CP0_Config5
>> CP0C5_MI
) & 1;
25425 ctx
->gi
= (env
->CP0_Config5
>> CP0C5_GI
) & 3;
25426 restore_cpu_state(env
, ctx
);
25427 #ifdef CONFIG_USER_ONLY
25428 ctx
->mem_idx
= MIPS_HFLAG_UM
;
25430 ctx
->mem_idx
= hflags_mmu_index(ctx
->hflags
);
25432 ctx
->default_tcg_memop_mask
= (ctx
->insn_flags
& (ISA_MIPS_R6
|
25433 INSN_LOONGSON3A
)) ? MO_UNALN
: MO_ALIGN
;
25435 LOG_DISAS("\ntb %p idx %d hflags %04x\n", ctx
->base
.tb
, ctx
->mem_idx
,
25439 static void mips_tr_tb_start(DisasContextBase
*dcbase
, CPUState
*cs
)
25443 static void mips_tr_insn_start(DisasContextBase
*dcbase
, CPUState
*cs
)
25445 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
25447 tcg_gen_insn_start(ctx
->base
.pc_next
, ctx
->hflags
& MIPS_HFLAG_BMASK
,
25451 static bool mips_tr_breakpoint_check(DisasContextBase
*dcbase
, CPUState
*cs
,
25452 const CPUBreakpoint
*bp
)
25454 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
25456 save_cpu_state(ctx
, 1);
25457 ctx
->base
.is_jmp
= DISAS_NORETURN
;
25458 gen_helper_raise_exception_debug(cpu_env
);
25460 * The address covered by the breakpoint must be included in
25461 * [tb->pc, tb->pc + tb->size) in order to for it to be
25462 * properly cleared -- thus we increment the PC here so that
25463 * the logic setting tb->size below does the right thing.
25465 ctx
->base
.pc_next
+= 4;
25469 static void mips_tr_translate_insn(DisasContextBase
*dcbase
, CPUState
*cs
)
25471 CPUMIPSState
*env
= cs
->env_ptr
;
25472 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
25476 is_slot
= ctx
->hflags
& MIPS_HFLAG_BMASK
;
25477 if (ctx
->insn_flags
& ISA_NANOMIPS32
) {
25478 ctx
->opcode
= translator_lduw(env
, ctx
->base
.pc_next
);
25479 insn_bytes
= decode_nanomips_opc(env
, ctx
);
25480 } else if (!(ctx
->hflags
& MIPS_HFLAG_M16
)) {
25481 ctx
->opcode
= translator_ldl(env
, ctx
->base
.pc_next
);
25483 decode_opc(env
, ctx
);
25484 } else if (ctx
->insn_flags
& ASE_MICROMIPS
) {
25485 ctx
->opcode
= translator_lduw(env
, ctx
->base
.pc_next
);
25486 insn_bytes
= decode_micromips_opc(env
, ctx
);
25487 } else if (ctx
->insn_flags
& ASE_MIPS16
) {
25488 ctx
->opcode
= translator_lduw(env
, ctx
->base
.pc_next
);
25489 insn_bytes
= decode_mips16_opc(env
, ctx
);
25491 gen_reserved_instruction(ctx
);
25492 g_assert(ctx
->base
.is_jmp
== DISAS_NORETURN
);
25496 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
25497 if (!(ctx
->hflags
& (MIPS_HFLAG_BDS16
| MIPS_HFLAG_BDS32
|
25498 MIPS_HFLAG_FBNSLOT
))) {
25500 * Force to generate branch as there is neither delay nor
25505 if ((ctx
->hflags
& MIPS_HFLAG_M16
) &&
25506 (ctx
->hflags
& MIPS_HFLAG_FBNSLOT
)) {
25508 * Force to generate branch as microMIPS R6 doesn't restrict
25509 * branches in the forbidden slot.
25515 gen_branch(ctx
, insn_bytes
);
25517 ctx
->base
.pc_next
+= insn_bytes
;
25519 if (ctx
->base
.is_jmp
!= DISAS_NEXT
) {
25523 * Execute a branch and its delay slot as a single instruction.
25524 * This is what GDB expects and is consistent with what the
25525 * hardware does (e.g. if a delay slot instruction faults, the
25526 * reported PC is the PC of the branch).
25528 if (ctx
->base
.singlestep_enabled
&&
25529 (ctx
->hflags
& MIPS_HFLAG_BMASK
) == 0) {
25530 ctx
->base
.is_jmp
= DISAS_TOO_MANY
;
25532 if (ctx
->base
.pc_next
- ctx
->page_start
>= TARGET_PAGE_SIZE
) {
25533 ctx
->base
.is_jmp
= DISAS_TOO_MANY
;
25537 static void mips_tr_tb_stop(DisasContextBase
*dcbase
, CPUState
*cs
)
25539 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
25541 if (ctx
->base
.singlestep_enabled
&& ctx
->base
.is_jmp
!= DISAS_NORETURN
) {
25542 save_cpu_state(ctx
, ctx
->base
.is_jmp
!= DISAS_EXIT
);
25543 gen_helper_raise_exception_debug(cpu_env
);
25545 switch (ctx
->base
.is_jmp
) {
25547 gen_save_pc(ctx
->base
.pc_next
);
25548 tcg_gen_lookup_and_goto_ptr();
25551 case DISAS_TOO_MANY
:
25552 save_cpu_state(ctx
, 0);
25553 gen_goto_tb(ctx
, 0, ctx
->base
.pc_next
);
25556 tcg_gen_exit_tb(NULL
, 0);
25558 case DISAS_NORETURN
:
25561 g_assert_not_reached();
25566 static void mips_tr_disas_log(const DisasContextBase
*dcbase
, CPUState
*cs
)
25568 qemu_log("IN: %s\n", lookup_symbol(dcbase
->pc_first
));
25569 log_target_disas(cs
, dcbase
->pc_first
, dcbase
->tb
->size
);
25572 static const TranslatorOps mips_tr_ops
= {
25573 .init_disas_context
= mips_tr_init_disas_context
,
25574 .tb_start
= mips_tr_tb_start
,
25575 .insn_start
= mips_tr_insn_start
,
25576 .breakpoint_check
= mips_tr_breakpoint_check
,
25577 .translate_insn
= mips_tr_translate_insn
,
25578 .tb_stop
= mips_tr_tb_stop
,
25579 .disas_log
= mips_tr_disas_log
,
25582 void gen_intermediate_code(CPUState
*cs
, TranslationBlock
*tb
, int max_insns
)
25586 translator_loop(&mips_tr_ops
, &ctx
.base
, cs
, tb
, max_insns
);
25589 void mips_tcg_init(void)
25594 for (i
= 1; i
< 32; i
++)
25595 cpu_gpr
[i
] = tcg_global_mem_new(cpu_env
,
25596 offsetof(CPUMIPSState
,
25599 #if defined(TARGET_MIPS64)
25600 cpu_gpr_hi
[0] = NULL
;
25602 for (unsigned i
= 1; i
< 32; i
++) {
25603 g_autofree
char *rname
= g_strdup_printf("%s[hi]", regnames
[i
]);
25605 cpu_gpr_hi
[i
] = tcg_global_mem_new_i64(cpu_env
,
25606 offsetof(CPUMIPSState
,
25607 active_tc
.gpr_hi
[i
]),
25610 #endif /* !TARGET_MIPS64 */
25611 for (i
= 0; i
< 32; i
++) {
25612 int off
= offsetof(CPUMIPSState
, active_fpu
.fpr
[i
].wr
.d
[0]);
25614 fpu_f64
[i
] = tcg_global_mem_new_i64(cpu_env
, off
, fregnames
[i
]);
25616 msa_translate_init();
25617 cpu_PC
= tcg_global_mem_new(cpu_env
,
25618 offsetof(CPUMIPSState
, active_tc
.PC
), "PC");
25619 for (i
= 0; i
< MIPS_DSP_ACC
; i
++) {
25620 cpu_HI
[i
] = tcg_global_mem_new(cpu_env
,
25621 offsetof(CPUMIPSState
, active_tc
.HI
[i
]),
25623 cpu_LO
[i
] = tcg_global_mem_new(cpu_env
,
25624 offsetof(CPUMIPSState
, active_tc
.LO
[i
]),
25627 cpu_dspctrl
= tcg_global_mem_new(cpu_env
,
25628 offsetof(CPUMIPSState
,
25629 active_tc
.DSPControl
),
25631 bcond
= tcg_global_mem_new(cpu_env
,
25632 offsetof(CPUMIPSState
, bcond
), "bcond");
25633 btarget
= tcg_global_mem_new(cpu_env
,
25634 offsetof(CPUMIPSState
, btarget
), "btarget");
25635 hflags
= tcg_global_mem_new_i32(cpu_env
,
25636 offsetof(CPUMIPSState
, hflags
), "hflags");
25638 fpu_fcr0
= tcg_global_mem_new_i32(cpu_env
,
25639 offsetof(CPUMIPSState
, active_fpu
.fcr0
),
25641 fpu_fcr31
= tcg_global_mem_new_i32(cpu_env
,
25642 offsetof(CPUMIPSState
, active_fpu
.fcr31
),
25644 cpu_lladdr
= tcg_global_mem_new(cpu_env
, offsetof(CPUMIPSState
, lladdr
),
25646 cpu_llval
= tcg_global_mem_new(cpu_env
, offsetof(CPUMIPSState
, llval
),
25649 if (TARGET_LONG_BITS
== 32) {
25650 mxu_translate_init();
25654 void restore_state_to_opc(CPUMIPSState
*env
, TranslationBlock
*tb
,
25655 target_ulong
*data
)
25657 env
->active_tc
.PC
= data
[0];
25658 env
->hflags
&= ~MIPS_HFLAG_BMASK
;
25659 env
->hflags
|= data
[1];
25660 switch (env
->hflags
& MIPS_HFLAG_BMASK_BASE
) {
25661 case MIPS_HFLAG_BR
:
25663 case MIPS_HFLAG_BC
:
25664 case MIPS_HFLAG_BL
:
25666 env
->btarget
= data
[2];