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
,
1134 * AN OVERVIEW OF MXU EXTENSION INSTRUCTION SET
1135 * ============================================
1138 * MXU (full name: MIPS eXtension/enhanced Unit) is a SIMD extension of MIPS32
1139 * instructions set. It is designed to fit the needs of signal, graphical and
1140 * video processing applications. MXU instruction set is used in Xburst family
1141 * of microprocessors by Ingenic.
1143 * MXU unit contains 17 registers called X0-X16. X0 is always zero, and X16 is
1144 * the control register.
1147 * The notation used in MXU assembler mnemonics
1148 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1150 * Register operands:
1152 * XRa, XRb, XRc, XRd - MXU registers
1153 * Rb, Rc, Rd, Rs, Rt - general purpose MIPS registers
1155 * Non-register operands:
1157 * aptn1 - 1-bit accumulate add/subtract pattern
1158 * aptn2 - 2-bit accumulate add/subtract pattern
1159 * eptn2 - 2-bit execute add/subtract pattern
1160 * optn2 - 2-bit operand pattern
1161 * optn3 - 3-bit operand pattern
1162 * sft4 - 4-bit shift amount
1163 * strd2 - 2-bit stride amount
1167 * Level of parallelism: Operand size:
1168 * S - single operation at a time 32 - word
1169 * D - two operations in parallel 16 - half word
1170 * Q - four operations in parallel 8 - byte
1174 * ADD - Add or subtract
1175 * ADDC - Add with carry-in
1177 * ASUM - Sum together then accumulate (add or subtract)
1178 * ASUMC - Sum together then accumulate (add or subtract) with carry-in
1179 * AVG - Average between 2 operands
1180 * ABD - Absolute difference
1182 * AND - Logical bitwise 'and' operation
1184 * EXTR - Extract bits
1185 * I2M - Move from GPR register to MXU register
1186 * LDD - Load data from memory to XRF
1187 * LDI - Load data from memory to XRF (and increase the address base)
1188 * LUI - Load unsigned immediate
1190 * MULU - Unsigned multiply
1191 * MADD - 64-bit operand add 32x32 product
1192 * MSUB - 64-bit operand subtract 32x32 product
1193 * MAC - Multiply and accumulate (add or subtract)
1194 * MAD - Multiply and add or subtract
1195 * MAX - Maximum between 2 operands
1196 * MIN - Minimum between 2 operands
1197 * M2I - Move from MXU register to GPR register
1198 * MOVZ - Move if zero
1199 * MOVN - Move if non-zero
1200 * NOR - Logical bitwise 'nor' operation
1201 * OR - Logical bitwise 'or' operation
1202 * STD - Store data from XRF to memory
1203 * SDI - Store data from XRF to memory (and increase the address base)
1204 * SLT - Set of less than comparison
1205 * SAD - Sum of absolute differences
1206 * SLL - Logical shift left
1207 * SLR - Logical shift right
1208 * SAR - Arithmetic shift right
1211 * SCOP - Calculate x’s scope (-1, means x<0; 0, means x==0; 1, means x>0)
1212 * XOR - Logical bitwise 'exclusive or' operation
1216 * E - Expand results
1217 * F - Fixed point multiplication
1218 * L - Low part result
1219 * R - Doing rounding
1220 * V - Variable instead of immediate
1221 * W - Combine above L and V
1224 * The list of MXU instructions grouped by functionality
1225 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1227 * Load/Store instructions Multiplication instructions
1228 * ----------------------- ---------------------------
1230 * S32LDD XRa, Rb, s12 S32MADD XRa, XRd, Rs, Rt
1231 * S32STD XRa, Rb, s12 S32MADDU XRa, XRd, Rs, Rt
1232 * S32LDDV XRa, Rb, rc, strd2 S32MSUB XRa, XRd, Rs, Rt
1233 * S32STDV XRa, Rb, rc, strd2 S32MSUBU XRa, XRd, Rs, Rt
1234 * S32LDI XRa, Rb, s12 S32MUL XRa, XRd, Rs, Rt
1235 * S32SDI XRa, Rb, s12 S32MULU XRa, XRd, Rs, Rt
1236 * S32LDIV XRa, Rb, rc, strd2 D16MUL XRa, XRb, XRc, XRd, optn2
1237 * S32SDIV XRa, Rb, rc, strd2 D16MULE XRa, XRb, XRc, optn2
1238 * S32LDDR XRa, Rb, s12 D16MULF XRa, XRb, XRc, optn2
1239 * S32STDR XRa, Rb, s12 D16MAC XRa, XRb, XRc, XRd, aptn2, optn2
1240 * S32LDDVR XRa, Rb, rc, strd2 D16MACE XRa, XRb, XRc, XRd, aptn2, optn2
1241 * S32STDVR XRa, Rb, rc, strd2 D16MACF XRa, XRb, XRc, XRd, aptn2, optn2
1242 * S32LDIR XRa, Rb, s12 D16MADL XRa, XRb, XRc, XRd, aptn2, optn2
1243 * S32SDIR XRa, Rb, s12 S16MAD XRa, XRb, XRc, XRd, aptn1, optn2
1244 * S32LDIVR XRa, Rb, rc, strd2 Q8MUL XRa, XRb, XRc, XRd
1245 * S32SDIVR XRa, Rb, rc, strd2 Q8MULSU XRa, XRb, XRc, XRd
1246 * S16LDD XRa, Rb, s10, eptn2 Q8MAC XRa, XRb, XRc, XRd, aptn2
1247 * S16STD XRa, Rb, s10, eptn2 Q8MACSU XRa, XRb, XRc, XRd, aptn2
1248 * S16LDI XRa, Rb, s10, eptn2 Q8MADL XRa, XRb, XRc, XRd, aptn2
1249 * S16SDI XRa, Rb, s10, eptn2
1250 * S8LDD XRa, Rb, s8, eptn3
1251 * S8STD XRa, Rb, s8, eptn3 Addition and subtraction instructions
1252 * S8LDI XRa, Rb, s8, eptn3 -------------------------------------
1253 * S8SDI XRa, Rb, s8, eptn3
1254 * LXW Rd, Rs, Rt, strd2 D32ADD XRa, XRb, XRc, XRd, eptn2
1255 * LXH Rd, Rs, Rt, strd2 D32ADDC XRa, XRb, XRc, XRd
1256 * LXHU Rd, Rs, Rt, strd2 D32ACC XRa, XRb, XRc, XRd, eptn2
1257 * LXB Rd, Rs, Rt, strd2 D32ACCM XRa, XRb, XRc, XRd, eptn2
1258 * LXBU Rd, Rs, Rt, strd2 D32ASUM XRa, XRb, XRc, XRd, eptn2
1259 * S32CPS XRa, XRb, XRc
1260 * Q16ADD XRa, XRb, XRc, XRd, eptn2, optn2
1261 * Comparison instructions Q16ACC XRa, XRb, XRc, XRd, eptn2
1262 * ----------------------- Q16ACCM XRa, XRb, XRc, XRd, eptn2
1263 * D16ASUM XRa, XRb, XRc, XRd, eptn2
1264 * S32MAX XRa, XRb, XRc D16CPS XRa, XRb,
1265 * S32MIN XRa, XRb, XRc D16AVG XRa, XRb, XRc
1266 * S32SLT XRa, XRb, XRc D16AVGR XRa, XRb, XRc
1267 * S32MOVZ XRa, XRb, XRc Q8ADD XRa, XRb, XRc, eptn2
1268 * S32MOVN XRa, XRb, XRc Q8ADDE XRa, XRb, XRc, XRd, eptn2
1269 * D16MAX XRa, XRb, XRc Q8ACCE XRa, XRb, XRc, XRd, eptn2
1270 * D16MIN XRa, XRb, XRc Q8ABD XRa, XRb, XRc
1271 * D16SLT XRa, XRb, XRc Q8SAD XRa, XRb, XRc, XRd
1272 * D16MOVZ XRa, XRb, XRc Q8AVG XRa, XRb, XRc
1273 * D16MOVN XRa, XRb, XRc Q8AVGR XRa, XRb, XRc
1274 * Q8MAX XRa, XRb, XRc D8SUM XRa, XRb, XRc, XRd
1275 * Q8MIN XRa, XRb, XRc D8SUMC XRa, XRb, XRc, XRd
1276 * Q8SLT XRa, XRb, XRc
1277 * Q8SLTU XRa, XRb, XRc
1278 * Q8MOVZ XRa, XRb, XRc Shift instructions
1279 * Q8MOVN XRa, XRb, XRc ------------------
1281 * D32SLL XRa, XRb, XRc, XRd, sft4
1282 * Bitwise instructions D32SLR XRa, XRb, XRc, XRd, sft4
1283 * -------------------- D32SAR XRa, XRb, XRc, XRd, sft4
1284 * D32SARL XRa, XRb, XRc, sft4
1285 * S32NOR XRa, XRb, XRc D32SLLV XRa, XRb, Rb
1286 * S32AND XRa, XRb, XRc D32SLRV XRa, XRb, Rb
1287 * S32XOR XRa, XRb, XRc D32SARV XRa, XRb, Rb
1288 * S32OR XRa, XRb, XRc D32SARW XRa, XRb, XRc, Rb
1289 * Q16SLL XRa, XRb, XRc, XRd, sft4
1290 * Q16SLR XRa, XRb, XRc, XRd, sft4
1291 * Miscellaneous instructions Q16SAR XRa, XRb, XRc, XRd, sft4
1292 * ------------------------- Q16SLLV XRa, XRb, Rb
1293 * Q16SLRV XRa, XRb, Rb
1294 * S32SFL XRa, XRb, XRc, XRd, optn2 Q16SARV XRa, XRb, Rb
1295 * S32ALN XRa, XRb, XRc, Rb
1296 * S32ALNI XRa, XRb, XRc, s3
1297 * S32LUI XRa, s8, optn3 Move instructions
1298 * S32EXTR XRa, XRb, Rb, bits5 -----------------
1299 * S32EXTRV XRa, XRb, Rs, Rt
1300 * Q16SCOP XRa, XRb, XRc, XRd S32M2I XRa, Rb
1301 * Q16SAT XRa, XRb, XRc S32I2M XRa, Rb
1304 * The opcode organization of MXU instructions
1305 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1307 * The bits 31..26 of all MXU instructions are equal to 0x1C (also referred
1308 * as opcode SPECIAL2 in the base MIPS ISA). The organization and meaning of
1309 * other bits up to the instruction level is as follows:
1314 * ┌─ 000000 ─ OPC_MXU_S32MADD
1315 * ├─ 000001 ─ OPC_MXU_S32MADDU
1316 * ├─ 000010 ─ <not assigned> (non-MXU OPC_MUL)
1319 * ├─ 000011 ─ OPC_MXU__POOL00 ─┬─ 000 ─ OPC_MXU_S32MAX
1320 * │ ├─ 001 ─ OPC_MXU_S32MIN
1321 * │ ├─ 010 ─ OPC_MXU_D16MAX
1322 * │ ├─ 011 ─ OPC_MXU_D16MIN
1323 * │ ├─ 100 ─ OPC_MXU_Q8MAX
1324 * │ ├─ 101 ─ OPC_MXU_Q8MIN
1325 * │ ├─ 110 ─ OPC_MXU_Q8SLT
1326 * │ └─ 111 ─ OPC_MXU_Q8SLTU
1327 * ├─ 000100 ─ OPC_MXU_S32MSUB
1328 * ├─ 000101 ─ OPC_MXU_S32MSUBU 20..18
1329 * ├─ 000110 ─ OPC_MXU__POOL01 ─┬─ 000 ─ OPC_MXU_S32SLT
1330 * │ ├─ 001 ─ OPC_MXU_D16SLT
1331 * │ ├─ 010 ─ OPC_MXU_D16AVG
1332 * │ ├─ 011 ─ OPC_MXU_D16AVGR
1333 * │ ├─ 100 ─ OPC_MXU_Q8AVG
1334 * │ ├─ 101 ─ OPC_MXU_Q8AVGR
1335 * │ └─ 111 ─ OPC_MXU_Q8ADD
1338 * ├─ 000111 ─ OPC_MXU__POOL02 ─┬─ 000 ─ OPC_MXU_S32CPS
1339 * │ ├─ 010 ─ OPC_MXU_D16CPS
1340 * │ ├─ 100 ─ OPC_MXU_Q8ABD
1341 * │ └─ 110 ─ OPC_MXU_Q16SAT
1342 * ├─ 001000 ─ OPC_MXU_D16MUL
1344 * ├─ 001001 ─ OPC_MXU__POOL03 ─┬─ 00 ─ OPC_MXU_D16MULF
1345 * │ └─ 01 ─ OPC_MXU_D16MULE
1346 * ├─ 001010 ─ OPC_MXU_D16MAC
1347 * ├─ 001011 ─ OPC_MXU_D16MACF
1348 * ├─ 001100 ─ OPC_MXU_D16MADL
1349 * ├─ 001101 ─ OPC_MXU_S16MAD
1350 * ├─ 001110 ─ OPC_MXU_Q16ADD
1351 * ├─ 001111 ─ OPC_MXU_D16MACE 23
1352 * │ ┌─ 0 ─ OPC_MXU_S32LDD
1353 * ├─ 010000 ─ OPC_MXU__POOL04 ─┴─ 1 ─ OPC_MXU_S32LDDR
1356 * ├─ 010001 ─ OPC_MXU__POOL05 ─┬─ 0 ─ OPC_MXU_S32STD
1357 * │ └─ 1 ─ OPC_MXU_S32STDR
1360 * ├─ 010010 ─ OPC_MXU__POOL06 ─┬─ 0000 ─ OPC_MXU_S32LDDV
1361 * │ └─ 0001 ─ OPC_MXU_S32LDDVR
1364 * ├─ 010011 ─ OPC_MXU__POOL07 ─┬─ 0000 ─ OPC_MXU_S32STDV
1365 * │ └─ 0001 ─ OPC_MXU_S32STDVR
1368 * ├─ 010100 ─ OPC_MXU__POOL08 ─┬─ 0 ─ OPC_MXU_S32LDI
1369 * │ └─ 1 ─ OPC_MXU_S32LDIR
1372 * ├─ 010101 ─ OPC_MXU__POOL09 ─┬─ 0 ─ OPC_MXU_S32SDI
1373 * │ └─ 1 ─ OPC_MXU_S32SDIR
1376 * ├─ 010110 ─ OPC_MXU__POOL10 ─┬─ 0000 ─ OPC_MXU_S32LDIV
1377 * │ └─ 0001 ─ OPC_MXU_S32LDIVR
1380 * ├─ 010111 ─ OPC_MXU__POOL11 ─┬─ 0000 ─ OPC_MXU_S32SDIV
1381 * │ └─ 0001 ─ OPC_MXU_S32SDIVR
1382 * ├─ 011000 ─ OPC_MXU_D32ADD
1384 * MXU ├─ 011001 ─ OPC_MXU__POOL12 ─┬─ 00 ─ OPC_MXU_D32ACC
1385 * opcodes ─┤ ├─ 01 ─ OPC_MXU_D32ACCM
1386 * │ └─ 10 ─ OPC_MXU_D32ASUM
1387 * ├─ 011010 ─ <not assigned>
1389 * ├─ 011011 ─ OPC_MXU__POOL13 ─┬─ 00 ─ OPC_MXU_Q16ACC
1390 * │ ├─ 01 ─ OPC_MXU_Q16ACCM
1391 * │ └─ 10 ─ OPC_MXU_Q16ASUM
1394 * ├─ 011100 ─ OPC_MXU__POOL14 ─┬─ 00 ─ OPC_MXU_Q8ADDE
1395 * │ ├─ 01 ─ OPC_MXU_D8SUM
1396 * ├─ 011101 ─ OPC_MXU_Q8ACCE └─ 10 ─ OPC_MXU_D8SUMC
1397 * ├─ 011110 ─ <not assigned>
1398 * ├─ 011111 ─ <not assigned>
1399 * ├─ 100000 ─ <not assigned> (overlaps with CLZ)
1400 * ├─ 100001 ─ <not assigned> (overlaps with CLO)
1401 * ├─ 100010 ─ OPC_MXU_S8LDD
1402 * ├─ 100011 ─ OPC_MXU_S8STD 15..14
1403 * ├─ 100100 ─ OPC_MXU_S8LDI ┌─ 00 ─ OPC_MXU_S32MUL
1404 * ├─ 100101 ─ OPC_MXU_S8SDI ├─ 00 ─ OPC_MXU_S32MULU
1405 * │ ├─ 00 ─ OPC_MXU_S32EXTR
1406 * ├─ 100110 ─ OPC_MXU__POOL15 ─┴─ 00 ─ OPC_MXU_S32EXTRV
1409 * ├─ 100111 ─ OPC_MXU__POOL16 ─┬─ 000 ─ OPC_MXU_D32SARW
1410 * │ ├─ 001 ─ OPC_MXU_S32ALN
1411 * │ ├─ 010 ─ OPC_MXU_S32ALNI
1412 * │ ├─ 011 ─ OPC_MXU_S32LUI
1413 * │ ├─ 100 ─ OPC_MXU_S32NOR
1414 * │ ├─ 101 ─ OPC_MXU_S32AND
1415 * │ ├─ 110 ─ OPC_MXU_S32OR
1416 * │ └─ 111 ─ OPC_MXU_S32XOR
1419 * ├─ 101000 ─ OPC_MXU__POOL17 ─┬─ 000 ─ OPC_MXU_LXB
1420 * │ ├─ 001 ─ OPC_MXU_LXH
1421 * ├─ 101001 ─ <not assigned> ├─ 011 ─ OPC_MXU_LXW
1422 * ├─ 101010 ─ OPC_MXU_S16LDD ├─ 100 ─ OPC_MXU_LXBU
1423 * ├─ 101011 ─ OPC_MXU_S16STD └─ 101 ─ OPC_MXU_LXHU
1424 * ├─ 101100 ─ OPC_MXU_S16LDI
1425 * ├─ 101101 ─ OPC_MXU_S16SDI
1426 * ├─ 101110 ─ OPC_MXU_S32M2I
1427 * ├─ 101111 ─ OPC_MXU_S32I2M
1428 * ├─ 110000 ─ OPC_MXU_D32SLL
1429 * ├─ 110001 ─ OPC_MXU_D32SLR 20..18
1430 * ├─ 110010 ─ OPC_MXU_D32SARL ┌─ 000 ─ OPC_MXU_D32SLLV
1431 * ├─ 110011 ─ OPC_MXU_D32SAR ├─ 001 ─ OPC_MXU_D32SLRV
1432 * ├─ 110100 ─ OPC_MXU_Q16SLL ├─ 010 ─ OPC_MXU_D32SARV
1433 * ├─ 110101 ─ OPC_MXU_Q16SLR ├─ 011 ─ OPC_MXU_Q16SLLV
1434 * │ ├─ 100 ─ OPC_MXU_Q16SLRV
1435 * ├─ 110110 ─ OPC_MXU__POOL18 ─┴─ 101 ─ OPC_MXU_Q16SARV
1437 * ├─ 110111 ─ OPC_MXU_Q16SAR
1439 * ├─ 111000 ─ OPC_MXU__POOL19 ─┬─ 00 ─ OPC_MXU_Q8MUL
1440 * │ └─ 01 ─ OPC_MXU_Q8MULSU
1443 * ├─ 111001 ─ OPC_MXU__POOL20 ─┬─ 000 ─ OPC_MXU_Q8MOVZ
1444 * │ ├─ 001 ─ OPC_MXU_Q8MOVN
1445 * │ ├─ 010 ─ OPC_MXU_D16MOVZ
1446 * │ ├─ 011 ─ OPC_MXU_D16MOVN
1447 * │ ├─ 100 ─ OPC_MXU_S32MOVZ
1448 * │ └─ 101 ─ OPC_MXU_S32MOVN
1451 * ├─ 111010 ─ OPC_MXU__POOL21 ─┬─ 00 ─ OPC_MXU_Q8MAC
1452 * │ └─ 10 ─ OPC_MXU_Q8MACSU
1453 * ├─ 111011 ─ OPC_MXU_Q16SCOP
1454 * ├─ 111100 ─ OPC_MXU_Q8MADL
1455 * ├─ 111101 ─ OPC_MXU_S32SFL
1456 * ├─ 111110 ─ OPC_MXU_Q8SAD
1457 * └─ 111111 ─ <not assigned> (overlaps with SDBBP)
1462 * "XBurst® Instruction Set Architecture MIPS eXtension/enhanced Unit
1463 * Programming Manual", Ingenic Semiconductor Co, Ltd., revision June 2, 2017
1467 OPC_MXU__POOL00
= 0x03,
1468 OPC_MXU_D16MUL
= 0x08,
1469 OPC_MXU_D16MAC
= 0x0A,
1470 OPC_MXU__POOL04
= 0x10,
1471 OPC_MXU_S8LDD
= 0x22,
1472 OPC_MXU__POOL16
= 0x27,
1473 OPC_MXU_S32M2I
= 0x2E,
1474 OPC_MXU_S32I2M
= 0x2F,
1475 OPC_MXU__POOL19
= 0x38,
1483 OPC_MXU_S32MAX
= 0x00,
1484 OPC_MXU_S32MIN
= 0x01,
1485 OPC_MXU_D16MAX
= 0x02,
1486 OPC_MXU_D16MIN
= 0x03,
1487 OPC_MXU_Q8MAX
= 0x04,
1488 OPC_MXU_Q8MIN
= 0x05,
1495 OPC_MXU_S32LDD
= 0x00,
1496 OPC_MXU_S32LDDR
= 0x01,
1503 OPC_MXU_S32ALNI
= 0x02,
1504 OPC_MXU_S32NOR
= 0x04,
1505 OPC_MXU_S32AND
= 0x05,
1506 OPC_MXU_S32OR
= 0x06,
1507 OPC_MXU_S32XOR
= 0x07,
1514 OPC_MXU_Q8MUL
= 0x00,
1515 OPC_MXU_Q8MULSU
= 0x01,
1519 * Overview of the TX79-specific instruction set
1520 * =============================================
1522 * The R5900 and the C790 have 128-bit wide GPRs, where the upper 64 bits
1523 * are only used by the specific quadword (128-bit) LQ/SQ load/store
1524 * instructions and certain multimedia instructions (MMIs). These MMIs
1525 * configure the 128-bit data path as two 64-bit, four 32-bit, eight 16-bit
1526 * or sixteen 8-bit paths.
1530 * The Toshiba TX System RISC TX79 Core Architecture manual,
1531 * https://wiki.qemu.org/File:C790.pdf
1533 * Three-Operand Multiply and Multiply-Add (4 instructions)
1534 * --------------------------------------------------------
1535 * MADD [rd,] rs, rt Multiply/Add
1536 * MADDU [rd,] rs, rt Multiply/Add Unsigned
1537 * MULT [rd,] rs, rt Multiply (3-operand)
1538 * MULTU [rd,] rs, rt Multiply Unsigned (3-operand)
1540 * Multiply Instructions for Pipeline 1 (10 instructions)
1541 * ------------------------------------------------------
1542 * MULT1 [rd,] rs, rt Multiply Pipeline 1
1543 * MULTU1 [rd,] rs, rt Multiply Unsigned Pipeline 1
1544 * DIV1 rs, rt Divide Pipeline 1
1545 * DIVU1 rs, rt Divide Unsigned Pipeline 1
1546 * MADD1 [rd,] rs, rt Multiply-Add Pipeline 1
1547 * MADDU1 [rd,] rs, rt Multiply-Add Unsigned Pipeline 1
1548 * MFHI1 rd Move From HI1 Register
1549 * MFLO1 rd Move From LO1 Register
1550 * MTHI1 rs Move To HI1 Register
1551 * MTLO1 rs Move To LO1 Register
1553 * Arithmetic (19 instructions)
1554 * ----------------------------
1555 * PADDB rd, rs, rt Parallel Add Byte
1556 * PSUBB rd, rs, rt Parallel Subtract Byte
1557 * PADDH rd, rs, rt Parallel Add Halfword
1558 * PSUBH rd, rs, rt Parallel Subtract Halfword
1559 * PADDW rd, rs, rt Parallel Add Word
1560 * PSUBW rd, rs, rt Parallel Subtract Word
1561 * PADSBH rd, rs, rt Parallel Add/Subtract Halfword
1562 * PADDSB rd, rs, rt Parallel Add with Signed Saturation Byte
1563 * PSUBSB rd, rs, rt Parallel Subtract with Signed Saturation Byte
1564 * PADDSH rd, rs, rt Parallel Add with Signed Saturation Halfword
1565 * PSUBSH rd, rs, rt Parallel Subtract with Signed Saturation Halfword
1566 * PADDSW rd, rs, rt Parallel Add with Signed Saturation Word
1567 * PSUBSW rd, rs, rt Parallel Subtract with Signed Saturation Word
1568 * PADDUB rd, rs, rt Parallel Add with Unsigned saturation Byte
1569 * PSUBUB rd, rs, rt Parallel Subtract with Unsigned saturation Byte
1570 * PADDUH rd, rs, rt Parallel Add with Unsigned saturation Halfword
1571 * PSUBUH rd, rs, rt Parallel Subtract with Unsigned saturation Halfword
1572 * PADDUW rd, rs, rt Parallel Add with Unsigned saturation Word
1573 * PSUBUW rd, rs, rt Parallel Subtract with Unsigned saturation Word
1575 * Min/Max (4 instructions)
1576 * ------------------------
1577 * PMAXH rd, rs, rt Parallel Maximum Halfword
1578 * PMINH rd, rs, rt Parallel Minimum Halfword
1579 * PMAXW rd, rs, rt Parallel Maximum Word
1580 * PMINW rd, rs, rt Parallel Minimum Word
1582 * Absolute (2 instructions)
1583 * -------------------------
1584 * PABSH rd, rt Parallel Absolute Halfword
1585 * PABSW rd, rt Parallel Absolute Word
1587 * Logical (4 instructions)
1588 * ------------------------
1589 * PAND rd, rs, rt Parallel AND
1590 * POR rd, rs, rt Parallel OR
1591 * PXOR rd, rs, rt Parallel XOR
1592 * PNOR rd, rs, rt Parallel NOR
1594 * Shift (9 instructions)
1595 * ----------------------
1596 * PSLLH rd, rt, sa Parallel Shift Left Logical Halfword
1597 * PSRLH rd, rt, sa Parallel Shift Right Logical Halfword
1598 * PSRAH rd, rt, sa Parallel Shift Right Arithmetic Halfword
1599 * PSLLW rd, rt, sa Parallel Shift Left Logical Word
1600 * PSRLW rd, rt, sa Parallel Shift Right Logical Word
1601 * PSRAW rd, rt, sa Parallel Shift Right Arithmetic Word
1602 * PSLLVW rd, rt, rs Parallel Shift Left Logical Variable Word
1603 * PSRLVW rd, rt, rs Parallel Shift Right Logical Variable Word
1604 * PSRAVW rd, rt, rs Parallel Shift Right Arithmetic Variable Word
1606 * Compare (6 instructions)
1607 * ------------------------
1608 * PCGTB rd, rs, rt Parallel Compare for Greater Than Byte
1609 * PCEQB rd, rs, rt Parallel Compare for Equal Byte
1610 * PCGTH rd, rs, rt Parallel Compare for Greater Than Halfword
1611 * PCEQH rd, rs, rt Parallel Compare for Equal Halfword
1612 * PCGTW rd, rs, rt Parallel Compare for Greater Than Word
1613 * PCEQW rd, rs, rt Parallel Compare for Equal Word
1615 * LZC (1 instruction)
1616 * -------------------
1617 * PLZCW rd, rs Parallel Leading Zero or One Count Word
1619 * Quadword Load and Store (2 instructions)
1620 * ----------------------------------------
1621 * LQ rt, offset(base) Load Quadword
1622 * SQ rt, offset(base) Store Quadword
1624 * Multiply and Divide (19 instructions)
1625 * -------------------------------------
1626 * PMULTW rd, rs, rt Parallel Multiply Word
1627 * PMULTUW rd, rs, rt Parallel Multiply Unsigned Word
1628 * PDIVW rs, rt Parallel Divide Word
1629 * PDIVUW rs, rt Parallel Divide Unsigned Word
1630 * PMADDW rd, rs, rt Parallel Multiply-Add Word
1631 * PMADDUW rd, rs, rt Parallel Multiply-Add Unsigned Word
1632 * PMSUBW rd, rs, rt Parallel Multiply-Subtract Word
1633 * PMULTH rd, rs, rt Parallel Multiply Halfword
1634 * PMADDH rd, rs, rt Parallel Multiply-Add Halfword
1635 * PMSUBH rd, rs, rt Parallel Multiply-Subtract Halfword
1636 * PHMADH rd, rs, rt Parallel Horizontal Multiply-Add Halfword
1637 * PHMSBH rd, rs, rt Parallel Horizontal Multiply-Subtract Halfword
1638 * PDIVBW rs, rt Parallel Divide Broadcast Word
1639 * PMFHI rd Parallel Move From HI Register
1640 * PMFLO rd Parallel Move From LO Register
1641 * PMTHI rs Parallel Move To HI Register
1642 * PMTLO rs Parallel Move To LO Register
1643 * PMFHL rd Parallel Move From HI/LO Register
1644 * PMTHL rs Parallel Move To HI/LO Register
1646 * Pack/Extend (11 instructions)
1647 * -----------------------------
1648 * PPAC5 rd, rt Parallel Pack to 5 bits
1649 * PPACB rd, rs, rt Parallel Pack to Byte
1650 * PPACH rd, rs, rt Parallel Pack to Halfword
1651 * PPACW rd, rs, rt Parallel Pack to Word
1652 * PEXT5 rd, rt Parallel Extend Upper from 5 bits
1653 * PEXTUB rd, rs, rt Parallel Extend Upper from Byte
1654 * PEXTLB rd, rs, rt Parallel Extend Lower from Byte
1655 * PEXTUH rd, rs, rt Parallel Extend Upper from Halfword
1656 * PEXTLH rd, rs, rt Parallel Extend Lower from Halfword
1657 * PEXTUW rd, rs, rt Parallel Extend Upper from Word
1658 * PEXTLW rd, rs, rt Parallel Extend Lower from Word
1660 * Others (16 instructions)
1661 * ------------------------
1662 * PCPYH rd, rt Parallel Copy Halfword
1663 * PCPYLD rd, rs, rt Parallel Copy Lower Doubleword
1664 * PCPYUD rd, rs, rt Parallel Copy Upper Doubleword
1665 * PREVH rd, rt Parallel Reverse Halfword
1666 * PINTH rd, rs, rt Parallel Interleave Halfword
1667 * PINTEH rd, rs, rt Parallel Interleave Even Halfword
1668 * PEXEH rd, rt Parallel Exchange Even Halfword
1669 * PEXCH rd, rt Parallel Exchange Center Halfword
1670 * PEXEW rd, rt Parallel Exchange Even Word
1671 * PEXCW rd, rt Parallel Exchange Center Word
1672 * QFSRV rd, rs, rt Quadword Funnel Shift Right Variable
1673 * MFSA rd Move from Shift Amount Register
1674 * MTSA rs Move to Shift Amount Register
1675 * MTSAB rs, immediate Move Byte Count to Shift Amount Register
1676 * MTSAH rs, immediate Move Halfword Count to Shift Amount Register
1677 * PROT3W rd, rt Parallel Rotate 3 Words
1679 * MMI (MultiMedia Instruction) encodings
1680 * ======================================
1682 * MMI instructions encoding table keys:
1684 * * This code is reserved for future use. An attempt to execute it
1685 * causes a Reserved Instruction exception.
1686 * % This code indicates an instruction class. The instruction word
1687 * must be further decoded by examining additional tables that show
1688 * the values for other instruction fields.
1689 * # This code is reserved for the unsupported instructions DMULT,
1690 * DMULTU, DDIV, DDIVU, LL, LLD, SC, SCD, LWC2 and SWC2. An attempt
1691 * to execute it causes a Reserved Instruction exception.
1693 * MMI instructions encoded by opcode field (MMI, LQ, SQ):
1696 * +--------+----------------------------------------+
1698 * +--------+----------------------------------------+
1700 * opcode bits 28..26
1701 * bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
1702 * 31..29 | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111
1703 * -------+-------+-------+-------+-------+-------+-------+-------+-------
1704 * 0 000 |SPECIAL| REGIMM| J | JAL | BEQ | BNE | BLEZ | BGTZ
1705 * 1 001 | ADDI | ADDIU | SLTI | SLTIU | ANDI | ORI | XORI | LUI
1706 * 2 010 | COP0 | COP1 | * | * | BEQL | BNEL | BLEZL | BGTZL
1707 * 3 011 | DADDI | DADDIU| LDL | LDR | MMI% | * | LQ | SQ
1708 * 4 100 | LB | LH | LWL | LW | LBU | LHU | LWR | LWU
1709 * 5 101 | SB | SH | SWL | SW | SDL | SDR | SWR | CACHE
1710 * 6 110 | # | LWC1 | # | PREF | # | LDC1 | # | LD
1711 * 7 111 | # | SWC1 | # | * | # | SDC1 | # | SD
1715 MMI_OPC_CLASS_MMI
= 0x1C << 26, /* Same as OPC_SPECIAL2 */
1716 MMI_OPC_LQ
= 0x1E << 26, /* Same as OPC_MSA */
1717 MMI_OPC_SQ
= 0x1F << 26, /* Same as OPC_SPECIAL3 */
1721 * MMI instructions with opcode field = MMI:
1724 * +--------+-------------------------------+--------+
1725 * | MMI | |function|
1726 * +--------+-------------------------------+--------+
1728 * function bits 2..0
1729 * bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
1730 * 5..3 | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111
1731 * -------+-------+-------+-------+-------+-------+-------+-------+-------
1732 * 0 000 | MADD | MADDU | * | * | PLZCW | * | * | *
1733 * 1 001 | MMI0% | MMI2% | * | * | * | * | * | *
1734 * 2 010 | MFHI1 | MTHI1 | MFLO1 | MTLO1 | * | * | * | *
1735 * 3 011 | MULT1 | MULTU1| DIV1 | DIVU1 | * | * | * | *
1736 * 4 100 | MADD1 | MADDU1| * | * | * | * | * | *
1737 * 5 101 | MMI1% | MMI3% | * | * | * | * | * | *
1738 * 6 110 | PMFHL | PMTHL | * | * | PSLLH | * | PSRLH | PSRAH
1739 * 7 111 | * | * | * | * | PSLLW | * | PSRLW | PSRAW
1742 #define MASK_MMI(op) (MASK_OP_MAJOR(op) | ((op) & 0x3F))
1744 MMI_OPC_MADD
= 0x00 | MMI_OPC_CLASS_MMI
, /* Same as OPC_MADD */
1745 MMI_OPC_MADDU
= 0x01 | MMI_OPC_CLASS_MMI
, /* Same as OPC_MADDU */
1746 MMI_OPC_PLZCW
= 0x04 | MMI_OPC_CLASS_MMI
,
1747 MMI_OPC_CLASS_MMI0
= 0x08 | MMI_OPC_CLASS_MMI
,
1748 MMI_OPC_CLASS_MMI2
= 0x09 | MMI_OPC_CLASS_MMI
,
1749 MMI_OPC_MFHI1
= 0x10 | MMI_OPC_CLASS_MMI
, /* Same minor as OPC_MFHI */
1750 MMI_OPC_MTHI1
= 0x11 | MMI_OPC_CLASS_MMI
, /* Same minor as OPC_MTHI */
1751 MMI_OPC_MFLO1
= 0x12 | MMI_OPC_CLASS_MMI
, /* Same minor as OPC_MFLO */
1752 MMI_OPC_MTLO1
= 0x13 | MMI_OPC_CLASS_MMI
, /* Same minor as OPC_MTLO */
1753 MMI_OPC_MULT1
= 0x18 | MMI_OPC_CLASS_MMI
, /* Same minor as OPC_MULT */
1754 MMI_OPC_MULTU1
= 0x19 | MMI_OPC_CLASS_MMI
, /* Same min. as OPC_MULTU */
1755 MMI_OPC_DIV1
= 0x1A | MMI_OPC_CLASS_MMI
, /* Same minor as OPC_DIV */
1756 MMI_OPC_DIVU1
= 0x1B | MMI_OPC_CLASS_MMI
, /* Same minor as OPC_DIVU */
1757 MMI_OPC_MADD1
= 0x20 | MMI_OPC_CLASS_MMI
,
1758 MMI_OPC_MADDU1
= 0x21 | MMI_OPC_CLASS_MMI
,
1759 MMI_OPC_CLASS_MMI1
= 0x28 | MMI_OPC_CLASS_MMI
,
1760 MMI_OPC_CLASS_MMI3
= 0x29 | MMI_OPC_CLASS_MMI
,
1761 MMI_OPC_PMFHL
= 0x30 | MMI_OPC_CLASS_MMI
,
1762 MMI_OPC_PMTHL
= 0x31 | MMI_OPC_CLASS_MMI
,
1763 MMI_OPC_PSLLH
= 0x34 | MMI_OPC_CLASS_MMI
,
1764 MMI_OPC_PSRLH
= 0x36 | MMI_OPC_CLASS_MMI
,
1765 MMI_OPC_PSRAH
= 0x37 | MMI_OPC_CLASS_MMI
,
1766 MMI_OPC_PSLLW
= 0x3C | MMI_OPC_CLASS_MMI
,
1767 MMI_OPC_PSRLW
= 0x3E | MMI_OPC_CLASS_MMI
,
1768 MMI_OPC_PSRAW
= 0x3F | MMI_OPC_CLASS_MMI
,
1772 * MMI instructions with opcode field = MMI and bits 5..0 = MMI0:
1775 * +--------+----------------------+--------+--------+
1776 * | MMI | |function| MMI0 |
1777 * +--------+----------------------+--------+--------+
1779 * function bits 7..6
1780 * bits | 0 | 1 | 2 | 3
1781 * 10..8 | 00 | 01 | 10 | 11
1782 * -------+-------+-------+-------+-------
1783 * 0 000 | PADDW | PSUBW | PCGTW | PMAXW
1784 * 1 001 | PADDH | PSUBH | PCGTH | PMAXH
1785 * 2 010 | PADDB | PSUBB | PCGTB | *
1786 * 3 011 | * | * | * | *
1787 * 4 100 | PADDSW| PSUBSW| PEXTLW| PPACW
1788 * 5 101 | PADDSH| PSUBSH| PEXTLH| PPACH
1789 * 6 110 | PADDSB| PSUBSB| PEXTLB| PPACB
1790 * 7 111 | * | * | PEXT5 | PPAC5
1793 #define MASK_MMI0(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
1795 MMI_OPC_0_PADDW
= (0x00 << 6) | MMI_OPC_CLASS_MMI0
,
1796 MMI_OPC_0_PSUBW
= (0x01 << 6) | MMI_OPC_CLASS_MMI0
,
1797 MMI_OPC_0_PCGTW
= (0x02 << 6) | MMI_OPC_CLASS_MMI0
,
1798 MMI_OPC_0_PMAXW
= (0x03 << 6) | MMI_OPC_CLASS_MMI0
,
1799 MMI_OPC_0_PADDH
= (0x04 << 6) | MMI_OPC_CLASS_MMI0
,
1800 MMI_OPC_0_PSUBH
= (0x05 << 6) | MMI_OPC_CLASS_MMI0
,
1801 MMI_OPC_0_PCGTH
= (0x06 << 6) | MMI_OPC_CLASS_MMI0
,
1802 MMI_OPC_0_PMAXH
= (0x07 << 6) | MMI_OPC_CLASS_MMI0
,
1803 MMI_OPC_0_PADDB
= (0x08 << 6) | MMI_OPC_CLASS_MMI0
,
1804 MMI_OPC_0_PSUBB
= (0x09 << 6) | MMI_OPC_CLASS_MMI0
,
1805 MMI_OPC_0_PCGTB
= (0x0A << 6) | MMI_OPC_CLASS_MMI0
,
1806 MMI_OPC_0_PADDSW
= (0x10 << 6) | MMI_OPC_CLASS_MMI0
,
1807 MMI_OPC_0_PSUBSW
= (0x11 << 6) | MMI_OPC_CLASS_MMI0
,
1808 MMI_OPC_0_PEXTLW
= (0x12 << 6) | MMI_OPC_CLASS_MMI0
,
1809 MMI_OPC_0_PPACW
= (0x13 << 6) | MMI_OPC_CLASS_MMI0
,
1810 MMI_OPC_0_PADDSH
= (0x14 << 6) | MMI_OPC_CLASS_MMI0
,
1811 MMI_OPC_0_PSUBSH
= (0x15 << 6) | MMI_OPC_CLASS_MMI0
,
1812 MMI_OPC_0_PEXTLH
= (0x16 << 6) | MMI_OPC_CLASS_MMI0
,
1813 MMI_OPC_0_PPACH
= (0x17 << 6) | MMI_OPC_CLASS_MMI0
,
1814 MMI_OPC_0_PADDSB
= (0x18 << 6) | MMI_OPC_CLASS_MMI0
,
1815 MMI_OPC_0_PSUBSB
= (0x19 << 6) | MMI_OPC_CLASS_MMI0
,
1816 MMI_OPC_0_PEXTLB
= (0x1A << 6) | MMI_OPC_CLASS_MMI0
,
1817 MMI_OPC_0_PPACB
= (0x1B << 6) | MMI_OPC_CLASS_MMI0
,
1818 MMI_OPC_0_PEXT5
= (0x1E << 6) | MMI_OPC_CLASS_MMI0
,
1819 MMI_OPC_0_PPAC5
= (0x1F << 6) | MMI_OPC_CLASS_MMI0
,
1823 * MMI instructions with opcode field = MMI and bits 5..0 = MMI1:
1826 * +--------+----------------------+--------+--------+
1827 * | MMI | |function| MMI1 |
1828 * +--------+----------------------+--------+--------+
1830 * function bits 7..6
1831 * bits | 0 | 1 | 2 | 3
1832 * 10..8 | 00 | 01 | 10 | 11
1833 * -------+-------+-------+-------+-------
1834 * 0 000 | * | PABSW | PCEQW | PMINW
1835 * 1 001 | PADSBH| PABSH | PCEQH | PMINH
1836 * 2 010 | * | * | PCEQB | *
1837 * 3 011 | * | * | * | *
1838 * 4 100 | PADDUW| PSUBUW| PEXTUW| *
1839 * 5 101 | PADDUH| PSUBUH| PEXTUH| *
1840 * 6 110 | PADDUB| PSUBUB| PEXTUB| QFSRV
1841 * 7 111 | * | * | * | *
1844 #define MASK_MMI1(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
1846 MMI_OPC_1_PABSW
= (0x01 << 6) | MMI_OPC_CLASS_MMI1
,
1847 MMI_OPC_1_PCEQW
= (0x02 << 6) | MMI_OPC_CLASS_MMI1
,
1848 MMI_OPC_1_PMINW
= (0x03 << 6) | MMI_OPC_CLASS_MMI1
,
1849 MMI_OPC_1_PADSBH
= (0x04 << 6) | MMI_OPC_CLASS_MMI1
,
1850 MMI_OPC_1_PABSH
= (0x05 << 6) | MMI_OPC_CLASS_MMI1
,
1851 MMI_OPC_1_PCEQH
= (0x06 << 6) | MMI_OPC_CLASS_MMI1
,
1852 MMI_OPC_1_PMINH
= (0x07 << 6) | MMI_OPC_CLASS_MMI1
,
1853 MMI_OPC_1_PCEQB
= (0x0A << 6) | MMI_OPC_CLASS_MMI1
,
1854 MMI_OPC_1_PADDUW
= (0x10 << 6) | MMI_OPC_CLASS_MMI1
,
1855 MMI_OPC_1_PSUBUW
= (0x11 << 6) | MMI_OPC_CLASS_MMI1
,
1856 MMI_OPC_1_PEXTUW
= (0x12 << 6) | MMI_OPC_CLASS_MMI1
,
1857 MMI_OPC_1_PADDUH
= (0x14 << 6) | MMI_OPC_CLASS_MMI1
,
1858 MMI_OPC_1_PSUBUH
= (0x15 << 6) | MMI_OPC_CLASS_MMI1
,
1859 MMI_OPC_1_PEXTUH
= (0x16 << 6) | MMI_OPC_CLASS_MMI1
,
1860 MMI_OPC_1_PADDUB
= (0x18 << 6) | MMI_OPC_CLASS_MMI1
,
1861 MMI_OPC_1_PSUBUB
= (0x19 << 6) | MMI_OPC_CLASS_MMI1
,
1862 MMI_OPC_1_PEXTUB
= (0x1A << 6) | MMI_OPC_CLASS_MMI1
,
1863 MMI_OPC_1_QFSRV
= (0x1B << 6) | MMI_OPC_CLASS_MMI1
,
1867 * MMI instructions with opcode field = MMI and bits 5..0 = MMI2:
1870 * +--------+----------------------+--------+--------+
1871 * | MMI | |function| MMI2 |
1872 * +--------+----------------------+--------+--------+
1874 * function bits 7..6
1875 * bits | 0 | 1 | 2 | 3
1876 * 10..8 | 00 | 01 | 10 | 11
1877 * -------+-------+-------+-------+-------
1878 * 0 000 | PMADDW| * | PSLLVW| PSRLVW
1879 * 1 001 | PMSUBW| * | * | *
1880 * 2 010 | PMFHI | PMFLO | PINTH | *
1881 * 3 011 | PMULTW| PDIVW | PCPYLD| *
1882 * 4 100 | PMADDH| PHMADH| PAND | PXOR
1883 * 5 101 | PMSUBH| PHMSBH| * | *
1884 * 6 110 | * | * | PEXEH | PREVH
1885 * 7 111 | PMULTH| PDIVBW| PEXEW | PROT3W
1888 #define MASK_MMI2(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
1890 MMI_OPC_2_PMADDW
= (0x00 << 6) | MMI_OPC_CLASS_MMI2
,
1891 MMI_OPC_2_PSLLVW
= (0x02 << 6) | MMI_OPC_CLASS_MMI2
,
1892 MMI_OPC_2_PSRLVW
= (0x03 << 6) | MMI_OPC_CLASS_MMI2
,
1893 MMI_OPC_2_PMSUBW
= (0x04 << 6) | MMI_OPC_CLASS_MMI2
,
1894 MMI_OPC_2_PMFHI
= (0x08 << 6) | MMI_OPC_CLASS_MMI2
,
1895 MMI_OPC_2_PMFLO
= (0x09 << 6) | MMI_OPC_CLASS_MMI2
,
1896 MMI_OPC_2_PINTH
= (0x0A << 6) | MMI_OPC_CLASS_MMI2
,
1897 MMI_OPC_2_PMULTW
= (0x0C << 6) | MMI_OPC_CLASS_MMI2
,
1898 MMI_OPC_2_PDIVW
= (0x0D << 6) | MMI_OPC_CLASS_MMI2
,
1899 MMI_OPC_2_PCPYLD
= (0x0E << 6) | MMI_OPC_CLASS_MMI2
,
1900 MMI_OPC_2_PMADDH
= (0x10 << 6) | MMI_OPC_CLASS_MMI2
,
1901 MMI_OPC_2_PHMADH
= (0x11 << 6) | MMI_OPC_CLASS_MMI2
,
1902 MMI_OPC_2_PAND
= (0x12 << 6) | MMI_OPC_CLASS_MMI2
,
1903 MMI_OPC_2_PXOR
= (0x13 << 6) | MMI_OPC_CLASS_MMI2
,
1904 MMI_OPC_2_PMSUBH
= (0x14 << 6) | MMI_OPC_CLASS_MMI2
,
1905 MMI_OPC_2_PHMSBH
= (0x15 << 6) | MMI_OPC_CLASS_MMI2
,
1906 MMI_OPC_2_PEXEH
= (0x1A << 6) | MMI_OPC_CLASS_MMI2
,
1907 MMI_OPC_2_PREVH
= (0x1B << 6) | MMI_OPC_CLASS_MMI2
,
1908 MMI_OPC_2_PMULTH
= (0x1C << 6) | MMI_OPC_CLASS_MMI2
,
1909 MMI_OPC_2_PDIVBW
= (0x1D << 6) | MMI_OPC_CLASS_MMI2
,
1910 MMI_OPC_2_PEXEW
= (0x1E << 6) | MMI_OPC_CLASS_MMI2
,
1911 MMI_OPC_2_PROT3W
= (0x1F << 6) | MMI_OPC_CLASS_MMI2
,
1915 * MMI instructions with opcode field = MMI and bits 5..0 = MMI3:
1918 * +--------+----------------------+--------+--------+
1919 * | MMI | |function| MMI3 |
1920 * +--------+----------------------+--------+--------+
1922 * function bits 7..6
1923 * bits | 0 | 1 | 2 | 3
1924 * 10..8 | 00 | 01 | 10 | 11
1925 * -------+-------+-------+-------+-------
1926 * 0 000 |PMADDUW| * | * | PSRAVW
1927 * 1 001 | * | * | * | *
1928 * 2 010 | PMTHI | PMTLO | PINTEH| *
1929 * 3 011 |PMULTUW| PDIVUW| PCPYUD| *
1930 * 4 100 | * | * | POR | PNOR
1931 * 5 101 | * | * | * | *
1932 * 6 110 | * | * | PEXCH | PCPYH
1933 * 7 111 | * | * | PEXCW | *
1936 #define MASK_MMI3(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
1938 MMI_OPC_3_PMADDUW
= (0x00 << 6) | MMI_OPC_CLASS_MMI3
,
1939 MMI_OPC_3_PSRAVW
= (0x03 << 6) | MMI_OPC_CLASS_MMI3
,
1940 MMI_OPC_3_PMTHI
= (0x08 << 6) | MMI_OPC_CLASS_MMI3
,
1941 MMI_OPC_3_PMTLO
= (0x09 << 6) | MMI_OPC_CLASS_MMI3
,
1942 MMI_OPC_3_PINTEH
= (0x0A << 6) | MMI_OPC_CLASS_MMI3
,
1943 MMI_OPC_3_PMULTUW
= (0x0C << 6) | MMI_OPC_CLASS_MMI3
,
1944 MMI_OPC_3_PDIVUW
= (0x0D << 6) | MMI_OPC_CLASS_MMI3
,
1945 MMI_OPC_3_PCPYUD
= (0x0E << 6) | MMI_OPC_CLASS_MMI3
,
1946 MMI_OPC_3_POR
= (0x12 << 6) | MMI_OPC_CLASS_MMI3
,
1947 MMI_OPC_3_PNOR
= (0x13 << 6) | MMI_OPC_CLASS_MMI3
,
1948 MMI_OPC_3_PEXCH
= (0x1A << 6) | MMI_OPC_CLASS_MMI3
,
1949 MMI_OPC_3_PCPYH
= (0x1B << 6) | MMI_OPC_CLASS_MMI3
,
1950 MMI_OPC_3_PEXCW
= (0x1E << 6) | MMI_OPC_CLASS_MMI3
,
1953 /* global register indices */
1954 TCGv cpu_gpr
[32], cpu_PC
;
1956 * For CPUs using 128-bit GPR registers, we put the lower halves in cpu_gpr[])
1957 * and the upper halves in cpu_gpr_hi[].
1959 TCGv_i64 cpu_gpr_hi
[32];
1960 TCGv cpu_HI
[MIPS_DSP_ACC
], cpu_LO
[MIPS_DSP_ACC
];
1961 static TCGv cpu_dspctrl
, btarget
;
1963 static TCGv cpu_lladdr
, cpu_llval
;
1964 static TCGv_i32 hflags
;
1965 TCGv_i32 fpu_fcr0
, fpu_fcr31
;
1966 TCGv_i64 fpu_f64
[32];
1968 #if !defined(TARGET_MIPS64)
1970 static TCGv mxu_gpr
[NUMBER_OF_MXU_REGISTERS
- 1];
1974 #include "exec/gen-icount.h"
1976 #define gen_helper_0e0i(name, arg) do { \
1977 TCGv_i32 helper_tmp = tcg_const_i32(arg); \
1978 gen_helper_##name(cpu_env, helper_tmp); \
1979 tcg_temp_free_i32(helper_tmp); \
1982 #define gen_helper_0e1i(name, arg1, arg2) do { \
1983 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1984 gen_helper_##name(cpu_env, arg1, helper_tmp); \
1985 tcg_temp_free_i32(helper_tmp); \
1988 #define gen_helper_1e0i(name, ret, arg1) do { \
1989 TCGv_i32 helper_tmp = tcg_const_i32(arg1); \
1990 gen_helper_##name(ret, cpu_env, helper_tmp); \
1991 tcg_temp_free_i32(helper_tmp); \
1994 #define gen_helper_1e1i(name, ret, arg1, arg2) do { \
1995 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1996 gen_helper_##name(ret, cpu_env, arg1, helper_tmp); \
1997 tcg_temp_free_i32(helper_tmp); \
2000 #define gen_helper_0e2i(name, arg1, arg2, arg3) do { \
2001 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
2002 gen_helper_##name(cpu_env, arg1, arg2, helper_tmp); \
2003 tcg_temp_free_i32(helper_tmp); \
2006 #define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do { \
2007 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
2008 gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp); \
2009 tcg_temp_free_i32(helper_tmp); \
2012 #define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do { \
2013 TCGv_i32 helper_tmp = tcg_const_i32(arg4); \
2014 gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp); \
2015 tcg_temp_free_i32(helper_tmp); \
2018 #define DISAS_STOP DISAS_TARGET_0
2019 #define DISAS_EXIT DISAS_TARGET_1
2021 static const char * const regnames
[] = {
2022 "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
2023 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
2024 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
2025 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
2028 static const char * const regnames_HI
[] = {
2029 "HI0", "HI1", "HI2", "HI3",
2032 static const char * const regnames_LO
[] = {
2033 "LO0", "LO1", "LO2", "LO3",
2036 static const char * const fregnames
[] = {
2037 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
2038 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
2039 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
2040 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
2043 #if !defined(TARGET_MIPS64)
2044 static const char * const mxuregnames
[] = {
2045 "XR1", "XR2", "XR3", "XR4", "XR5", "XR6", "XR7", "XR8",
2046 "XR9", "XR10", "XR11", "XR12", "XR13", "XR14", "XR15", "MXU_CR",
2049 void mxu_translate_init(void)
2051 for (unsigned i
= 0; i
< NUMBER_OF_MXU_REGISTERS
- 1; i
++) {
2052 mxu_gpr
[i
] = tcg_global_mem_new(cpu_env
,
2053 offsetof(CPUMIPSState
, active_tc
.mxu_gpr
[i
]),
2057 mxu_CR
= tcg_global_mem_new(cpu_env
,
2058 offsetof(CPUMIPSState
, active_tc
.mxu_cr
),
2059 mxuregnames
[NUMBER_OF_MXU_REGISTERS
- 1]);
2061 #endif /* !TARGET_MIPS64 */
2063 /* General purpose registers moves. */
2064 void gen_load_gpr(TCGv t
, int reg
)
2067 tcg_gen_movi_tl(t
, 0);
2069 tcg_gen_mov_tl(t
, cpu_gpr
[reg
]);
2073 void gen_store_gpr(TCGv t
, int reg
)
2076 tcg_gen_mov_tl(cpu_gpr
[reg
], t
);
2080 #if defined(TARGET_MIPS64)
2081 void gen_load_gpr_hi(TCGv_i64 t
, int reg
)
2084 tcg_gen_movi_i64(t
, 0);
2086 tcg_gen_mov_i64(t
, cpu_gpr_hi
[reg
]);
2090 void gen_store_gpr_hi(TCGv_i64 t
, int reg
)
2093 tcg_gen_mov_i64(cpu_gpr_hi
[reg
], t
);
2096 #endif /* TARGET_MIPS64 */
2098 /* Moves to/from shadow registers. */
2099 static inline void gen_load_srsgpr(int from
, int to
)
2101 TCGv t0
= tcg_temp_new();
2104 tcg_gen_movi_tl(t0
, 0);
2106 TCGv_i32 t2
= tcg_temp_new_i32();
2107 TCGv_ptr addr
= tcg_temp_new_ptr();
2109 tcg_gen_ld_i32(t2
, cpu_env
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
2110 tcg_gen_shri_i32(t2
, t2
, CP0SRSCtl_PSS
);
2111 tcg_gen_andi_i32(t2
, t2
, 0xf);
2112 tcg_gen_muli_i32(t2
, t2
, sizeof(target_ulong
) * 32);
2113 tcg_gen_ext_i32_ptr(addr
, t2
);
2114 tcg_gen_add_ptr(addr
, cpu_env
, addr
);
2116 tcg_gen_ld_tl(t0
, addr
, sizeof(target_ulong
) * from
);
2117 tcg_temp_free_ptr(addr
);
2118 tcg_temp_free_i32(t2
);
2120 gen_store_gpr(t0
, to
);
2124 static inline void gen_store_srsgpr(int from
, int to
)
2127 TCGv t0
= tcg_temp_new();
2128 TCGv_i32 t2
= tcg_temp_new_i32();
2129 TCGv_ptr addr
= tcg_temp_new_ptr();
2131 gen_load_gpr(t0
, from
);
2132 tcg_gen_ld_i32(t2
, cpu_env
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
2133 tcg_gen_shri_i32(t2
, t2
, CP0SRSCtl_PSS
);
2134 tcg_gen_andi_i32(t2
, t2
, 0xf);
2135 tcg_gen_muli_i32(t2
, t2
, sizeof(target_ulong
) * 32);
2136 tcg_gen_ext_i32_ptr(addr
, t2
);
2137 tcg_gen_add_ptr(addr
, cpu_env
, addr
);
2139 tcg_gen_st_tl(t0
, addr
, sizeof(target_ulong
) * to
);
2140 tcg_temp_free_ptr(addr
);
2141 tcg_temp_free_i32(t2
);
2146 #if !defined(TARGET_MIPS64)
2147 /* MXU General purpose registers moves. */
2148 static inline void gen_load_mxu_gpr(TCGv t
, unsigned int reg
)
2151 tcg_gen_movi_tl(t
, 0);
2152 } else if (reg
<= 15) {
2153 tcg_gen_mov_tl(t
, mxu_gpr
[reg
- 1]);
2157 static inline void gen_store_mxu_gpr(TCGv t
, unsigned int reg
)
2159 if (reg
> 0 && reg
<= 15) {
2160 tcg_gen_mov_tl(mxu_gpr
[reg
- 1], t
);
2164 /* MXU control register moves. */
2165 static inline void gen_load_mxu_cr(TCGv t
)
2167 tcg_gen_mov_tl(t
, mxu_CR
);
2170 static inline void gen_store_mxu_cr(TCGv t
)
2172 /* TODO: Add handling of RW rules for MXU_CR. */
2173 tcg_gen_mov_tl(mxu_CR
, t
);
2179 static inline void gen_save_pc(target_ulong pc
)
2181 tcg_gen_movi_tl(cpu_PC
, pc
);
2184 static inline void save_cpu_state(DisasContext
*ctx
, int do_save_pc
)
2186 LOG_DISAS("hflags %08x saved %08x\n", ctx
->hflags
, ctx
->saved_hflags
);
2187 if (do_save_pc
&& ctx
->base
.pc_next
!= ctx
->saved_pc
) {
2188 gen_save_pc(ctx
->base
.pc_next
);
2189 ctx
->saved_pc
= ctx
->base
.pc_next
;
2191 if (ctx
->hflags
!= ctx
->saved_hflags
) {
2192 tcg_gen_movi_i32(hflags
, ctx
->hflags
);
2193 ctx
->saved_hflags
= ctx
->hflags
;
2194 switch (ctx
->hflags
& MIPS_HFLAG_BMASK_BASE
) {
2200 tcg_gen_movi_tl(btarget
, ctx
->btarget
);
2206 static inline void restore_cpu_state(CPUMIPSState
*env
, DisasContext
*ctx
)
2208 ctx
->saved_hflags
= ctx
->hflags
;
2209 switch (ctx
->hflags
& MIPS_HFLAG_BMASK_BASE
) {
2215 ctx
->btarget
= env
->btarget
;
2220 void generate_exception_err(DisasContext
*ctx
, int excp
, int err
)
2222 TCGv_i32 texcp
= tcg_const_i32(excp
);
2223 TCGv_i32 terr
= tcg_const_i32(err
);
2224 save_cpu_state(ctx
, 1);
2225 gen_helper_raise_exception_err(cpu_env
, texcp
, terr
);
2226 tcg_temp_free_i32(terr
);
2227 tcg_temp_free_i32(texcp
);
2228 ctx
->base
.is_jmp
= DISAS_NORETURN
;
2231 void generate_exception(DisasContext
*ctx
, int excp
)
2233 gen_helper_0e0i(raise_exception
, excp
);
2236 void generate_exception_end(DisasContext
*ctx
, int excp
)
2238 generate_exception_err(ctx
, excp
, 0);
2241 void gen_reserved_instruction(DisasContext
*ctx
)
2243 generate_exception_end(ctx
, EXCP_RI
);
2246 /* Floating point register moves. */
2247 void gen_load_fpr32(DisasContext
*ctx
, TCGv_i32 t
, int reg
)
2249 if (ctx
->hflags
& MIPS_HFLAG_FRE
) {
2250 generate_exception(ctx
, EXCP_RI
);
2252 tcg_gen_extrl_i64_i32(t
, fpu_f64
[reg
]);
2255 void gen_store_fpr32(DisasContext
*ctx
, TCGv_i32 t
, int reg
)
2258 if (ctx
->hflags
& MIPS_HFLAG_FRE
) {
2259 generate_exception(ctx
, EXCP_RI
);
2261 t64
= tcg_temp_new_i64();
2262 tcg_gen_extu_i32_i64(t64
, t
);
2263 tcg_gen_deposit_i64(fpu_f64
[reg
], fpu_f64
[reg
], t64
, 0, 32);
2264 tcg_temp_free_i64(t64
);
2267 static void gen_load_fpr32h(DisasContext
*ctx
, TCGv_i32 t
, int reg
)
2269 if (ctx
->hflags
& MIPS_HFLAG_F64
) {
2270 tcg_gen_extrh_i64_i32(t
, fpu_f64
[reg
]);
2272 gen_load_fpr32(ctx
, t
, reg
| 1);
2276 static void gen_store_fpr32h(DisasContext
*ctx
, TCGv_i32 t
, int reg
)
2278 if (ctx
->hflags
& MIPS_HFLAG_F64
) {
2279 TCGv_i64 t64
= tcg_temp_new_i64();
2280 tcg_gen_extu_i32_i64(t64
, t
);
2281 tcg_gen_deposit_i64(fpu_f64
[reg
], fpu_f64
[reg
], t64
, 32, 32);
2282 tcg_temp_free_i64(t64
);
2284 gen_store_fpr32(ctx
, t
, reg
| 1);
2288 void gen_load_fpr64(DisasContext
*ctx
, TCGv_i64 t
, int reg
)
2290 if (ctx
->hflags
& MIPS_HFLAG_F64
) {
2291 tcg_gen_mov_i64(t
, fpu_f64
[reg
]);
2293 tcg_gen_concat32_i64(t
, fpu_f64
[reg
& ~1], fpu_f64
[reg
| 1]);
2297 void gen_store_fpr64(DisasContext
*ctx
, TCGv_i64 t
, int reg
)
2299 if (ctx
->hflags
& MIPS_HFLAG_F64
) {
2300 tcg_gen_mov_i64(fpu_f64
[reg
], t
);
2303 tcg_gen_deposit_i64(fpu_f64
[reg
& ~1], fpu_f64
[reg
& ~1], t
, 0, 32);
2304 t0
= tcg_temp_new_i64();
2305 tcg_gen_shri_i64(t0
, t
, 32);
2306 tcg_gen_deposit_i64(fpu_f64
[reg
| 1], fpu_f64
[reg
| 1], t0
, 0, 32);
2307 tcg_temp_free_i64(t0
);
2311 int get_fp_bit(int cc
)
2320 /* Addresses computation */
2321 void gen_op_addr_add(DisasContext
*ctx
, TCGv ret
, TCGv arg0
, TCGv arg1
)
2323 tcg_gen_add_tl(ret
, arg0
, arg1
);
2325 #if defined(TARGET_MIPS64)
2326 if (ctx
->hflags
& MIPS_HFLAG_AWRAP
) {
2327 tcg_gen_ext32s_i64(ret
, ret
);
2332 static inline void gen_op_addr_addi(DisasContext
*ctx
, TCGv ret
, TCGv base
,
2335 tcg_gen_addi_tl(ret
, base
, ofs
);
2337 #if defined(TARGET_MIPS64)
2338 if (ctx
->hflags
& MIPS_HFLAG_AWRAP
) {
2339 tcg_gen_ext32s_i64(ret
, ret
);
2344 /* Addresses computation (translation time) */
2345 static target_long
addr_add(DisasContext
*ctx
, target_long base
,
2348 target_long sum
= base
+ offset
;
2350 #if defined(TARGET_MIPS64)
2351 if (ctx
->hflags
& MIPS_HFLAG_AWRAP
) {
2358 /* Sign-extract the low 32-bits to a target_long. */
2359 void gen_move_low32(TCGv ret
, TCGv_i64 arg
)
2361 #if defined(TARGET_MIPS64)
2362 tcg_gen_ext32s_i64(ret
, arg
);
2364 tcg_gen_extrl_i64_i32(ret
, arg
);
2368 /* Sign-extract the high 32-bits to a target_long. */
2369 void gen_move_high32(TCGv ret
, TCGv_i64 arg
)
2371 #if defined(TARGET_MIPS64)
2372 tcg_gen_sari_i64(ret
, arg
, 32);
2374 tcg_gen_extrh_i64_i32(ret
, arg
);
2378 void check_cp0_enabled(DisasContext
*ctx
)
2380 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_CP0
))) {
2381 generate_exception_end(ctx
, EXCP_CpU
);
2385 void check_cp1_enabled(DisasContext
*ctx
)
2387 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_FPU
))) {
2388 generate_exception_err(ctx
, EXCP_CpU
, 1);
2393 * Verify that the processor is running with COP1X instructions enabled.
2394 * This is associated with the nabla symbol in the MIPS32 and MIPS64
2397 void check_cop1x(DisasContext
*ctx
)
2399 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_COP1X
))) {
2400 gen_reserved_instruction(ctx
);
2405 * Verify that the processor is running with 64-bit floating-point
2406 * operations enabled.
2408 void check_cp1_64bitmode(DisasContext
*ctx
)
2410 if (unlikely(~ctx
->hflags
& (MIPS_HFLAG_F64
| MIPS_HFLAG_COP1X
))) {
2411 gen_reserved_instruction(ctx
);
2416 * Verify if floating point register is valid; an operation is not defined
2417 * if bit 0 of any register specification is set and the FR bit in the
2418 * Status register equals zero, since the register numbers specify an
2419 * even-odd pair of adjacent coprocessor general registers. When the FR bit
2420 * in the Status register equals one, both even and odd register numbers
2421 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
2423 * Multiple 64 bit wide registers can be checked by calling
2424 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
2426 void check_cp1_registers(DisasContext
*ctx
, int regs
)
2428 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_F64
) && (regs
& 1))) {
2429 gen_reserved_instruction(ctx
);
2434 * Verify that the processor is running with DSP instructions enabled.
2435 * This is enabled by CP0 Status register MX(24) bit.
2437 static inline void check_dsp(DisasContext
*ctx
)
2439 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_DSP
))) {
2440 if (ctx
->insn_flags
& ASE_DSP
) {
2441 generate_exception_end(ctx
, EXCP_DSPDIS
);
2443 gen_reserved_instruction(ctx
);
2448 static inline void check_dsp_r2(DisasContext
*ctx
)
2450 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_DSP_R2
))) {
2451 if (ctx
->insn_flags
& ASE_DSP
) {
2452 generate_exception_end(ctx
, EXCP_DSPDIS
);
2454 gen_reserved_instruction(ctx
);
2459 static inline void check_dsp_r3(DisasContext
*ctx
)
2461 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_DSP_R3
))) {
2462 if (ctx
->insn_flags
& ASE_DSP
) {
2463 generate_exception_end(ctx
, EXCP_DSPDIS
);
2465 gen_reserved_instruction(ctx
);
2471 * This code generates a "reserved instruction" exception if the
2472 * CPU does not support the instruction set corresponding to flags.
2474 void check_insn(DisasContext
*ctx
, uint64_t flags
)
2476 if (unlikely(!(ctx
->insn_flags
& flags
))) {
2477 gen_reserved_instruction(ctx
);
2482 * This code generates a "reserved instruction" exception if the
2483 * CPU has corresponding flag set which indicates that the instruction
2486 static inline void check_insn_opc_removed(DisasContext
*ctx
, uint64_t flags
)
2488 if (unlikely(ctx
->insn_flags
& flags
)) {
2489 gen_reserved_instruction(ctx
);
2494 * The Linux kernel traps certain reserved instruction exceptions to
2495 * emulate the corresponding instructions. QEMU is the kernel in user
2496 * mode, so those traps are emulated by accepting the instructions.
2498 * A reserved instruction exception is generated for flagged CPUs if
2499 * QEMU runs in system mode.
2501 static inline void check_insn_opc_user_only(DisasContext
*ctx
, uint64_t flags
)
2503 #ifndef CONFIG_USER_ONLY
2504 check_insn_opc_removed(ctx
, flags
);
2509 * This code generates a "reserved instruction" exception if the
2510 * CPU does not support 64-bit paired-single (PS) floating point data type.
2512 static inline void check_ps(DisasContext
*ctx
)
2514 if (unlikely(!ctx
->ps
)) {
2515 generate_exception(ctx
, EXCP_RI
);
2517 check_cp1_64bitmode(ctx
);
2521 * This code generates a "reserved instruction" exception if cpu is not
2522 * 64-bit or 64-bit instructions are not enabled.
2524 void check_mips_64(DisasContext
*ctx
)
2526 if (unlikely((TARGET_LONG_BITS
!= 64) || !(ctx
->hflags
& MIPS_HFLAG_64
))) {
2527 gen_reserved_instruction(ctx
);
2531 #ifndef CONFIG_USER_ONLY
2532 static inline void check_mvh(DisasContext
*ctx
)
2534 if (unlikely(!ctx
->mvh
)) {
2535 generate_exception(ctx
, EXCP_RI
);
2541 * This code generates a "reserved instruction" exception if the
2542 * Config5 XNP bit is set.
2544 static inline void check_xnp(DisasContext
*ctx
)
2546 if (unlikely(ctx
->CP0_Config5
& (1 << CP0C5_XNP
))) {
2547 gen_reserved_instruction(ctx
);
2551 #ifndef CONFIG_USER_ONLY
2553 * This code generates a "reserved instruction" exception if the
2554 * Config3 PW bit is NOT set.
2556 static inline void check_pw(DisasContext
*ctx
)
2558 if (unlikely(!(ctx
->CP0_Config3
& (1 << CP0C3_PW
)))) {
2559 gen_reserved_instruction(ctx
);
2565 * This code generates a "reserved instruction" exception if the
2566 * Config3 MT bit is NOT set.
2568 static inline void check_mt(DisasContext
*ctx
)
2570 if (unlikely(!(ctx
->CP0_Config3
& (1 << CP0C3_MT
)))) {
2571 gen_reserved_instruction(ctx
);
2575 #ifndef CONFIG_USER_ONLY
2577 * This code generates a "coprocessor unusable" exception if CP0 is not
2578 * available, and, if that is not the case, generates a "reserved instruction"
2579 * exception if the Config5 MT bit is NOT set. This is needed for availability
2580 * control of some of MT ASE instructions.
2582 static inline void check_cp0_mt(DisasContext
*ctx
)
2584 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_CP0
))) {
2585 generate_exception_end(ctx
, EXCP_CpU
);
2587 if (unlikely(!(ctx
->CP0_Config3
& (1 << CP0C3_MT
)))) {
2588 gen_reserved_instruction(ctx
);
2595 * This code generates a "reserved instruction" exception if the
2596 * Config5 NMS bit is set.
2598 static inline void check_nms(DisasContext
*ctx
)
2600 if (unlikely(ctx
->CP0_Config5
& (1 << CP0C5_NMS
))) {
2601 gen_reserved_instruction(ctx
);
2606 * This code generates a "reserved instruction" exception if the
2607 * Config5 NMS bit is set, and Config1 DL, Config1 IL, Config2 SL,
2608 * Config2 TL, and Config5 L2C are unset.
2610 static inline void check_nms_dl_il_sl_tl_l2c(DisasContext
*ctx
)
2612 if (unlikely((ctx
->CP0_Config5
& (1 << CP0C5_NMS
)) &&
2613 !(ctx
->CP0_Config1
& (1 << CP0C1_DL
)) &&
2614 !(ctx
->CP0_Config1
& (1 << CP0C1_IL
)) &&
2615 !(ctx
->CP0_Config2
& (1 << CP0C2_SL
)) &&
2616 !(ctx
->CP0_Config2
& (1 << CP0C2_TL
)) &&
2617 !(ctx
->CP0_Config5
& (1 << CP0C5_L2C
)))) {
2618 gen_reserved_instruction(ctx
);
2623 * This code generates a "reserved instruction" exception if the
2624 * Config5 EVA bit is NOT set.
2626 static inline void check_eva(DisasContext
*ctx
)
2628 if (unlikely(!(ctx
->CP0_Config5
& (1 << CP0C5_EVA
)))) {
2629 gen_reserved_instruction(ctx
);
2635 * Define small wrappers for gen_load_fpr* so that we have a uniform
2636 * calling interface for 32 and 64-bit FPRs. No sense in changing
2637 * all callers for gen_load_fpr32 when we need the CTX parameter for
2640 #define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(ctx, x, y)
2641 #define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
2642 #define FOP_CONDS(type, abs, fmt, ifmt, bits) \
2643 static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
2644 int ft, int fs, int cc) \
2646 TCGv_i##bits fp0 = tcg_temp_new_i##bits(); \
2647 TCGv_i##bits fp1 = tcg_temp_new_i##bits(); \
2656 check_cp1_registers(ctx, fs | ft); \
2664 gen_ldcmp_fpr##bits(ctx, fp0, fs); \
2665 gen_ldcmp_fpr##bits(ctx, fp1, ft); \
2668 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); \
2671 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); \
2674 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); \
2677 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); \
2680 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); \
2683 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); \
2686 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); \
2689 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); \
2692 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); \
2695 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); \
2698 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); \
2701 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); \
2704 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); \
2707 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); \
2710 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); \
2713 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); \
2718 tcg_temp_free_i##bits(fp0); \
2719 tcg_temp_free_i##bits(fp1); \
2722 FOP_CONDS(, 0, d
, FMT_D
, 64)
2723 FOP_CONDS(abs
, 1, d
, FMT_D
, 64)
2724 FOP_CONDS(, 0, s
, FMT_S
, 32)
2725 FOP_CONDS(abs
, 1, s
, FMT_S
, 32)
2726 FOP_CONDS(, 0, ps
, FMT_PS
, 64)
2727 FOP_CONDS(abs
, 1, ps
, FMT_PS
, 64)
2730 #define FOP_CONDNS(fmt, ifmt, bits, STORE) \
2731 static inline void gen_r6_cmp_ ## fmt(DisasContext *ctx, int n, \
2732 int ft, int fs, int fd) \
2734 TCGv_i ## bits fp0 = tcg_temp_new_i ## bits(); \
2735 TCGv_i ## bits fp1 = tcg_temp_new_i ## bits(); \
2736 if (ifmt == FMT_D) { \
2737 check_cp1_registers(ctx, fs | ft | fd); \
2739 gen_ldcmp_fpr ## bits(ctx, fp0, fs); \
2740 gen_ldcmp_fpr ## bits(ctx, fp1, ft); \
2743 gen_helper_r6_cmp_ ## fmt ## _af(fp0, cpu_env, fp0, fp1); \
2746 gen_helper_r6_cmp_ ## fmt ## _un(fp0, cpu_env, fp0, fp1); \
2749 gen_helper_r6_cmp_ ## fmt ## _eq(fp0, cpu_env, fp0, fp1); \
2752 gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, cpu_env, fp0, fp1); \
2755 gen_helper_r6_cmp_ ## fmt ## _lt(fp0, cpu_env, fp0, fp1); \
2758 gen_helper_r6_cmp_ ## fmt ## _ult(fp0, cpu_env, fp0, fp1); \
2761 gen_helper_r6_cmp_ ## fmt ## _le(fp0, cpu_env, fp0, fp1); \
2764 gen_helper_r6_cmp_ ## fmt ## _ule(fp0, cpu_env, fp0, fp1); \
2767 gen_helper_r6_cmp_ ## fmt ## _saf(fp0, cpu_env, fp0, fp1); \
2770 gen_helper_r6_cmp_ ## fmt ## _sun(fp0, cpu_env, fp0, fp1); \
2773 gen_helper_r6_cmp_ ## fmt ## _seq(fp0, cpu_env, fp0, fp1); \
2776 gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, cpu_env, fp0, fp1); \
2779 gen_helper_r6_cmp_ ## fmt ## _slt(fp0, cpu_env, fp0, fp1); \
2782 gen_helper_r6_cmp_ ## fmt ## _sult(fp0, cpu_env, fp0, fp1); \
2785 gen_helper_r6_cmp_ ## fmt ## _sle(fp0, cpu_env, fp0, fp1); \
2788 gen_helper_r6_cmp_ ## fmt ## _sule(fp0, cpu_env, fp0, fp1); \
2791 gen_helper_r6_cmp_ ## fmt ## _or(fp0, cpu_env, fp0, fp1); \
2794 gen_helper_r6_cmp_ ## fmt ## _une(fp0, cpu_env, fp0, fp1); \
2797 gen_helper_r6_cmp_ ## fmt ## _ne(fp0, cpu_env, fp0, fp1); \
2800 gen_helper_r6_cmp_ ## fmt ## _sor(fp0, cpu_env, fp0, fp1); \
2803 gen_helper_r6_cmp_ ## fmt ## _sune(fp0, cpu_env, fp0, fp1); \
2806 gen_helper_r6_cmp_ ## fmt ## _sne(fp0, cpu_env, fp0, fp1); \
2812 tcg_temp_free_i ## bits(fp0); \
2813 tcg_temp_free_i ## bits(fp1); \
2816 FOP_CONDNS(d
, FMT_D
, 64, gen_store_fpr64(ctx
, fp0
, fd
))
2817 FOP_CONDNS(s
, FMT_S
, 32, gen_store_fpr32(ctx
, fp0
, fd
))
2819 #undef gen_ldcmp_fpr32
2820 #undef gen_ldcmp_fpr64
2822 /* load/store instructions. */
2823 #ifdef CONFIG_USER_ONLY
2824 #define OP_LD_ATOMIC(insn, fname) \
2825 static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \
2826 DisasContext *ctx) \
2828 TCGv t0 = tcg_temp_new(); \
2829 tcg_gen_mov_tl(t0, arg1); \
2830 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
2831 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
2832 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
2833 tcg_temp_free(t0); \
2836 #define OP_LD_ATOMIC(insn, fname) \
2837 static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \
2838 DisasContext *ctx) \
2840 gen_helper_1e1i(insn, ret, arg1, mem_idx); \
2843 OP_LD_ATOMIC(ll
, ld32s
);
2844 #if defined(TARGET_MIPS64)
2845 OP_LD_ATOMIC(lld
, ld64
);
2849 void gen_base_offset_addr(DisasContext
*ctx
, TCGv addr
, int base
, int offset
)
2852 tcg_gen_movi_tl(addr
, offset
);
2853 } else if (offset
== 0) {
2854 gen_load_gpr(addr
, base
);
2856 tcg_gen_movi_tl(addr
, offset
);
2857 gen_op_addr_add(ctx
, addr
, cpu_gpr
[base
], addr
);
2861 static target_ulong
pc_relative_pc(DisasContext
*ctx
)
2863 target_ulong pc
= ctx
->base
.pc_next
;
2865 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
2866 int branch_bytes
= ctx
->hflags
& MIPS_HFLAG_BDS16
? 2 : 4;
2871 pc
&= ~(target_ulong
)3;
2876 static void gen_ld(DisasContext
*ctx
, uint32_t opc
,
2877 int rt
, int base
, int offset
)
2880 int mem_idx
= ctx
->mem_idx
;
2882 if (rt
== 0 && ctx
->insn_flags
& (INSN_LOONGSON2E
| INSN_LOONGSON2F
|
2885 * Loongson CPU uses a load to zero register for prefetch.
2886 * We emulate it as a NOP. On other CPU we must perform the
2887 * actual memory access.
2892 t0
= tcg_temp_new();
2893 gen_base_offset_addr(ctx
, t0
, base
, offset
);
2896 #if defined(TARGET_MIPS64)
2898 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEUL
|
2899 ctx
->default_tcg_memop_mask
);
2900 gen_store_gpr(t0
, rt
);
2903 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEQ
|
2904 ctx
->default_tcg_memop_mask
);
2905 gen_store_gpr(t0
, rt
);
2909 op_ld_lld(t0
, t0
, mem_idx
, ctx
);
2910 gen_store_gpr(t0
, rt
);
2913 t1
= tcg_temp_new();
2915 * Do a byte access to possibly trigger a page
2916 * fault with the unaligned address.
2918 tcg_gen_qemu_ld_tl(t1
, t0
, mem_idx
, MO_UB
);
2919 tcg_gen_andi_tl(t1
, t0
, 7);
2920 #ifndef TARGET_WORDS_BIGENDIAN
2921 tcg_gen_xori_tl(t1
, t1
, 7);
2923 tcg_gen_shli_tl(t1
, t1
, 3);
2924 tcg_gen_andi_tl(t0
, t0
, ~7);
2925 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEQ
);
2926 tcg_gen_shl_tl(t0
, t0
, t1
);
2927 t2
= tcg_const_tl(-1);
2928 tcg_gen_shl_tl(t2
, t2
, t1
);
2929 gen_load_gpr(t1
, rt
);
2930 tcg_gen_andc_tl(t1
, t1
, t2
);
2932 tcg_gen_or_tl(t0
, t0
, t1
);
2934 gen_store_gpr(t0
, rt
);
2937 t1
= tcg_temp_new();
2939 * Do a byte access to possibly trigger a page
2940 * fault with the unaligned address.
2942 tcg_gen_qemu_ld_tl(t1
, t0
, mem_idx
, MO_UB
);
2943 tcg_gen_andi_tl(t1
, t0
, 7);
2944 #ifdef TARGET_WORDS_BIGENDIAN
2945 tcg_gen_xori_tl(t1
, t1
, 7);
2947 tcg_gen_shli_tl(t1
, t1
, 3);
2948 tcg_gen_andi_tl(t0
, t0
, ~7);
2949 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEQ
);
2950 tcg_gen_shr_tl(t0
, t0
, t1
);
2951 tcg_gen_xori_tl(t1
, t1
, 63);
2952 t2
= tcg_const_tl(0xfffffffffffffffeull
);
2953 tcg_gen_shl_tl(t2
, t2
, t1
);
2954 gen_load_gpr(t1
, rt
);
2955 tcg_gen_and_tl(t1
, t1
, t2
);
2957 tcg_gen_or_tl(t0
, t0
, t1
);
2959 gen_store_gpr(t0
, rt
);
2962 t1
= tcg_const_tl(pc_relative_pc(ctx
));
2963 gen_op_addr_add(ctx
, t0
, t0
, t1
);
2965 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEQ
);
2966 gen_store_gpr(t0
, rt
);
2970 t1
= tcg_const_tl(pc_relative_pc(ctx
));
2971 gen_op_addr_add(ctx
, t0
, t0
, t1
);
2973 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TESL
);
2974 gen_store_gpr(t0
, rt
);
2977 mem_idx
= MIPS_HFLAG_UM
;
2980 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TESL
|
2981 ctx
->default_tcg_memop_mask
);
2982 gen_store_gpr(t0
, rt
);
2985 mem_idx
= MIPS_HFLAG_UM
;
2988 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TESW
|
2989 ctx
->default_tcg_memop_mask
);
2990 gen_store_gpr(t0
, rt
);
2993 mem_idx
= MIPS_HFLAG_UM
;
2996 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEUW
|
2997 ctx
->default_tcg_memop_mask
);
2998 gen_store_gpr(t0
, rt
);
3001 mem_idx
= MIPS_HFLAG_UM
;
3004 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_SB
);
3005 gen_store_gpr(t0
, rt
);
3008 mem_idx
= MIPS_HFLAG_UM
;
3011 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_UB
);
3012 gen_store_gpr(t0
, rt
);
3015 mem_idx
= MIPS_HFLAG_UM
;
3018 t1
= tcg_temp_new();
3020 * Do a byte access to possibly trigger a page
3021 * fault with the unaligned address.
3023 tcg_gen_qemu_ld_tl(t1
, t0
, mem_idx
, MO_UB
);
3024 tcg_gen_andi_tl(t1
, t0
, 3);
3025 #ifndef TARGET_WORDS_BIGENDIAN
3026 tcg_gen_xori_tl(t1
, t1
, 3);
3028 tcg_gen_shli_tl(t1
, t1
, 3);
3029 tcg_gen_andi_tl(t0
, t0
, ~3);
3030 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEUL
);
3031 tcg_gen_shl_tl(t0
, t0
, t1
);
3032 t2
= tcg_const_tl(-1);
3033 tcg_gen_shl_tl(t2
, t2
, t1
);
3034 gen_load_gpr(t1
, rt
);
3035 tcg_gen_andc_tl(t1
, t1
, t2
);
3037 tcg_gen_or_tl(t0
, t0
, t1
);
3039 tcg_gen_ext32s_tl(t0
, t0
);
3040 gen_store_gpr(t0
, rt
);
3043 mem_idx
= MIPS_HFLAG_UM
;
3046 t1
= tcg_temp_new();
3048 * Do a byte access to possibly trigger a page
3049 * fault with the unaligned address.
3051 tcg_gen_qemu_ld_tl(t1
, t0
, mem_idx
, MO_UB
);
3052 tcg_gen_andi_tl(t1
, t0
, 3);
3053 #ifdef TARGET_WORDS_BIGENDIAN
3054 tcg_gen_xori_tl(t1
, t1
, 3);
3056 tcg_gen_shli_tl(t1
, t1
, 3);
3057 tcg_gen_andi_tl(t0
, t0
, ~3);
3058 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEUL
);
3059 tcg_gen_shr_tl(t0
, t0
, t1
);
3060 tcg_gen_xori_tl(t1
, t1
, 31);
3061 t2
= tcg_const_tl(0xfffffffeull
);
3062 tcg_gen_shl_tl(t2
, t2
, t1
);
3063 gen_load_gpr(t1
, rt
);
3064 tcg_gen_and_tl(t1
, t1
, t2
);
3066 tcg_gen_or_tl(t0
, t0
, t1
);
3068 tcg_gen_ext32s_tl(t0
, t0
);
3069 gen_store_gpr(t0
, rt
);
3072 mem_idx
= MIPS_HFLAG_UM
;
3076 op_ld_ll(t0
, t0
, mem_idx
, ctx
);
3077 gen_store_gpr(t0
, rt
);
3083 static void gen_llwp(DisasContext
*ctx
, uint32_t base
, int16_t offset
,
3084 uint32_t reg1
, uint32_t reg2
)
3086 TCGv taddr
= tcg_temp_new();
3087 TCGv_i64 tval
= tcg_temp_new_i64();
3088 TCGv tmp1
= tcg_temp_new();
3089 TCGv tmp2
= tcg_temp_new();
3091 gen_base_offset_addr(ctx
, taddr
, base
, offset
);
3092 tcg_gen_qemu_ld64(tval
, taddr
, ctx
->mem_idx
);
3093 #ifdef TARGET_WORDS_BIGENDIAN
3094 tcg_gen_extr_i64_tl(tmp2
, tmp1
, tval
);
3096 tcg_gen_extr_i64_tl(tmp1
, tmp2
, tval
);
3098 gen_store_gpr(tmp1
, reg1
);
3099 tcg_temp_free(tmp1
);
3100 gen_store_gpr(tmp2
, reg2
);
3101 tcg_temp_free(tmp2
);
3102 tcg_gen_st_i64(tval
, cpu_env
, offsetof(CPUMIPSState
, llval_wp
));
3103 tcg_temp_free_i64(tval
);
3104 tcg_gen_st_tl(taddr
, cpu_env
, offsetof(CPUMIPSState
, lladdr
));
3105 tcg_temp_free(taddr
);
3109 static void gen_st(DisasContext
*ctx
, uint32_t opc
, int rt
,
3110 int base
, int offset
)
3112 TCGv t0
= tcg_temp_new();
3113 TCGv t1
= tcg_temp_new();
3114 int mem_idx
= ctx
->mem_idx
;
3116 gen_base_offset_addr(ctx
, t0
, base
, offset
);
3117 gen_load_gpr(t1
, rt
);
3119 #if defined(TARGET_MIPS64)
3121 tcg_gen_qemu_st_tl(t1
, t0
, mem_idx
, MO_TEQ
|
3122 ctx
->default_tcg_memop_mask
);
3125 gen_helper_0e2i(sdl
, t1
, t0
, mem_idx
);
3128 gen_helper_0e2i(sdr
, t1
, t0
, mem_idx
);
3132 mem_idx
= MIPS_HFLAG_UM
;
3135 tcg_gen_qemu_st_tl(t1
, t0
, mem_idx
, MO_TEUL
|
3136 ctx
->default_tcg_memop_mask
);
3139 mem_idx
= MIPS_HFLAG_UM
;
3142 tcg_gen_qemu_st_tl(t1
, t0
, mem_idx
, MO_TEUW
|
3143 ctx
->default_tcg_memop_mask
);
3146 mem_idx
= MIPS_HFLAG_UM
;
3149 tcg_gen_qemu_st_tl(t1
, t0
, mem_idx
, MO_8
);
3152 mem_idx
= MIPS_HFLAG_UM
;
3155 gen_helper_0e2i(swl
, t1
, t0
, mem_idx
);
3158 mem_idx
= MIPS_HFLAG_UM
;
3161 gen_helper_0e2i(swr
, t1
, t0
, mem_idx
);
3169 /* Store conditional */
3170 static void gen_st_cond(DisasContext
*ctx
, int rt
, int base
, int offset
,
3171 MemOp tcg_mo
, bool eva
)
3174 TCGLabel
*l1
= gen_new_label();
3175 TCGLabel
*done
= gen_new_label();
3177 t0
= tcg_temp_new();
3178 addr
= tcg_temp_new();
3179 /* compare the address against that of the preceding LL */
3180 gen_base_offset_addr(ctx
, addr
, base
, offset
);
3181 tcg_gen_brcond_tl(TCG_COND_EQ
, addr
, cpu_lladdr
, l1
);
3182 tcg_temp_free(addr
);
3183 tcg_gen_movi_tl(t0
, 0);
3184 gen_store_gpr(t0
, rt
);
3188 /* generate cmpxchg */
3189 val
= tcg_temp_new();
3190 gen_load_gpr(val
, rt
);
3191 tcg_gen_atomic_cmpxchg_tl(t0
, cpu_lladdr
, cpu_llval
, val
,
3192 eva
? MIPS_HFLAG_UM
: ctx
->mem_idx
, tcg_mo
);
3193 tcg_gen_setcond_tl(TCG_COND_EQ
, t0
, t0
, cpu_llval
);
3194 gen_store_gpr(t0
, rt
);
3197 gen_set_label(done
);
3202 static void gen_scwp(DisasContext
*ctx
, uint32_t base
, int16_t offset
,
3203 uint32_t reg1
, uint32_t reg2
, bool eva
)
3205 TCGv taddr
= tcg_temp_local_new();
3206 TCGv lladdr
= tcg_temp_local_new();
3207 TCGv_i64 tval
= tcg_temp_new_i64();
3208 TCGv_i64 llval
= tcg_temp_new_i64();
3209 TCGv_i64 val
= tcg_temp_new_i64();
3210 TCGv tmp1
= tcg_temp_new();
3211 TCGv tmp2
= tcg_temp_new();
3212 TCGLabel
*lab_fail
= gen_new_label();
3213 TCGLabel
*lab_done
= gen_new_label();
3215 gen_base_offset_addr(ctx
, taddr
, base
, offset
);
3217 tcg_gen_ld_tl(lladdr
, cpu_env
, offsetof(CPUMIPSState
, lladdr
));
3218 tcg_gen_brcond_tl(TCG_COND_NE
, taddr
, lladdr
, lab_fail
);
3220 gen_load_gpr(tmp1
, reg1
);
3221 gen_load_gpr(tmp2
, reg2
);
3223 #ifdef TARGET_WORDS_BIGENDIAN
3224 tcg_gen_concat_tl_i64(tval
, tmp2
, tmp1
);
3226 tcg_gen_concat_tl_i64(tval
, tmp1
, tmp2
);
3229 tcg_gen_ld_i64(llval
, cpu_env
, offsetof(CPUMIPSState
, llval_wp
));
3230 tcg_gen_atomic_cmpxchg_i64(val
, taddr
, llval
, tval
,
3231 eva
? MIPS_HFLAG_UM
: ctx
->mem_idx
, MO_64
);
3233 tcg_gen_movi_tl(cpu_gpr
[reg1
], 1);
3235 tcg_gen_brcond_i64(TCG_COND_EQ
, val
, llval
, lab_done
);
3237 gen_set_label(lab_fail
);
3240 tcg_gen_movi_tl(cpu_gpr
[reg1
], 0);
3242 gen_set_label(lab_done
);
3243 tcg_gen_movi_tl(lladdr
, -1);
3244 tcg_gen_st_tl(lladdr
, cpu_env
, offsetof(CPUMIPSState
, lladdr
));
3247 /* Load and store */
3248 static void gen_flt_ldst(DisasContext
*ctx
, uint32_t opc
, int ft
,
3252 * Don't do NOP if destination is zero: we must perform the actual
3258 TCGv_i32 fp0
= tcg_temp_new_i32();
3259 tcg_gen_qemu_ld_i32(fp0
, t0
, ctx
->mem_idx
, MO_TESL
|
3260 ctx
->default_tcg_memop_mask
);
3261 gen_store_fpr32(ctx
, fp0
, ft
);
3262 tcg_temp_free_i32(fp0
);
3267 TCGv_i32 fp0
= tcg_temp_new_i32();
3268 gen_load_fpr32(ctx
, fp0
, ft
);
3269 tcg_gen_qemu_st_i32(fp0
, t0
, ctx
->mem_idx
, MO_TEUL
|
3270 ctx
->default_tcg_memop_mask
);
3271 tcg_temp_free_i32(fp0
);
3276 TCGv_i64 fp0
= tcg_temp_new_i64();
3277 tcg_gen_qemu_ld_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
|
3278 ctx
->default_tcg_memop_mask
);
3279 gen_store_fpr64(ctx
, fp0
, ft
);
3280 tcg_temp_free_i64(fp0
);
3285 TCGv_i64 fp0
= tcg_temp_new_i64();
3286 gen_load_fpr64(ctx
, fp0
, ft
);
3287 tcg_gen_qemu_st_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
|
3288 ctx
->default_tcg_memop_mask
);
3289 tcg_temp_free_i64(fp0
);
3293 MIPS_INVAL("flt_ldst");
3294 gen_reserved_instruction(ctx
);
3299 static void gen_cop1_ldst(DisasContext
*ctx
, uint32_t op
, int rt
,
3300 int rs
, int16_t imm
)
3302 TCGv t0
= tcg_temp_new();
3304 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
3305 check_cp1_enabled(ctx
);
3309 check_insn(ctx
, ISA_MIPS2
);
3312 gen_base_offset_addr(ctx
, t0
, rs
, imm
);
3313 gen_flt_ldst(ctx
, op
, rt
, t0
);
3316 generate_exception_err(ctx
, EXCP_CpU
, 1);
3321 /* Arithmetic with immediate operand */
3322 static void gen_arith_imm(DisasContext
*ctx
, uint32_t opc
,
3323 int rt
, int rs
, int imm
)
3325 target_ulong uimm
= (target_long
)imm
; /* Sign extend to 32/64 bits */
3327 if (rt
== 0 && opc
!= OPC_ADDI
&& opc
!= OPC_DADDI
) {
3329 * If no destination, treat it as a NOP.
3330 * For addi, we must generate the overflow exception when needed.
3337 TCGv t0
= tcg_temp_local_new();
3338 TCGv t1
= tcg_temp_new();
3339 TCGv t2
= tcg_temp_new();
3340 TCGLabel
*l1
= gen_new_label();
3342 gen_load_gpr(t1
, rs
);
3343 tcg_gen_addi_tl(t0
, t1
, uimm
);
3344 tcg_gen_ext32s_tl(t0
, t0
);
3346 tcg_gen_xori_tl(t1
, t1
, ~uimm
);
3347 tcg_gen_xori_tl(t2
, t0
, uimm
);
3348 tcg_gen_and_tl(t1
, t1
, t2
);
3350 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
3352 /* operands of same sign, result different sign */
3353 generate_exception(ctx
, EXCP_OVERFLOW
);
3355 tcg_gen_ext32s_tl(t0
, t0
);
3356 gen_store_gpr(t0
, rt
);
3362 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
3363 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
3365 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
3368 #if defined(TARGET_MIPS64)
3371 TCGv t0
= tcg_temp_local_new();
3372 TCGv t1
= tcg_temp_new();
3373 TCGv t2
= tcg_temp_new();
3374 TCGLabel
*l1
= gen_new_label();
3376 gen_load_gpr(t1
, rs
);
3377 tcg_gen_addi_tl(t0
, t1
, uimm
);
3379 tcg_gen_xori_tl(t1
, t1
, ~uimm
);
3380 tcg_gen_xori_tl(t2
, t0
, uimm
);
3381 tcg_gen_and_tl(t1
, t1
, t2
);
3383 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
3385 /* operands of same sign, result different sign */
3386 generate_exception(ctx
, EXCP_OVERFLOW
);
3388 gen_store_gpr(t0
, rt
);
3394 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
3396 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
3403 /* Logic with immediate operand */
3404 static void gen_logic_imm(DisasContext
*ctx
, uint32_t opc
,
3405 int rt
, int rs
, int16_t imm
)
3410 /* If no destination, treat it as a NOP. */
3413 uimm
= (uint16_t)imm
;
3416 if (likely(rs
!= 0)) {
3417 tcg_gen_andi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
3419 tcg_gen_movi_tl(cpu_gpr
[rt
], 0);
3424 tcg_gen_ori_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
3426 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
3430 if (likely(rs
!= 0)) {
3431 tcg_gen_xori_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
3433 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
3437 if (rs
!= 0 && (ctx
->insn_flags
& ISA_MIPS_R6
)) {
3439 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], imm
<< 16);
3440 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
3442 tcg_gen_movi_tl(cpu_gpr
[rt
], imm
<< 16);
3451 /* Set on less than with immediate operand */
3452 static void gen_slt_imm(DisasContext
*ctx
, uint32_t opc
,
3453 int rt
, int rs
, int16_t imm
)
3455 target_ulong uimm
= (target_long
)imm
; /* Sign extend to 32/64 bits */
3459 /* If no destination, treat it as a NOP. */
3462 t0
= tcg_temp_new();
3463 gen_load_gpr(t0
, rs
);
3466 tcg_gen_setcondi_tl(TCG_COND_LT
, cpu_gpr
[rt
], t0
, uimm
);
3469 tcg_gen_setcondi_tl(TCG_COND_LTU
, cpu_gpr
[rt
], t0
, uimm
);
3475 /* Shifts with immediate operand */
3476 static void gen_shift_imm(DisasContext
*ctx
, uint32_t opc
,
3477 int rt
, int rs
, int16_t imm
)
3479 target_ulong uimm
= ((uint16_t)imm
) & 0x1f;
3483 /* If no destination, treat it as a NOP. */
3487 t0
= tcg_temp_new();
3488 gen_load_gpr(t0
, rs
);
3491 tcg_gen_shli_tl(t0
, t0
, uimm
);
3492 tcg_gen_ext32s_tl(cpu_gpr
[rt
], t0
);
3495 tcg_gen_sari_tl(cpu_gpr
[rt
], t0
, uimm
);
3499 tcg_gen_ext32u_tl(t0
, t0
);
3500 tcg_gen_shri_tl(cpu_gpr
[rt
], t0
, uimm
);
3502 tcg_gen_ext32s_tl(cpu_gpr
[rt
], t0
);
3507 TCGv_i32 t1
= tcg_temp_new_i32();
3509 tcg_gen_trunc_tl_i32(t1
, t0
);
3510 tcg_gen_rotri_i32(t1
, t1
, uimm
);
3511 tcg_gen_ext_i32_tl(cpu_gpr
[rt
], t1
);
3512 tcg_temp_free_i32(t1
);
3514 tcg_gen_ext32s_tl(cpu_gpr
[rt
], t0
);
3517 #if defined(TARGET_MIPS64)
3519 tcg_gen_shli_tl(cpu_gpr
[rt
], t0
, uimm
);
3522 tcg_gen_sari_tl(cpu_gpr
[rt
], t0
, uimm
);
3525 tcg_gen_shri_tl(cpu_gpr
[rt
], t0
, uimm
);
3529 tcg_gen_rotri_tl(cpu_gpr
[rt
], t0
, uimm
);
3531 tcg_gen_mov_tl(cpu_gpr
[rt
], t0
);
3535 tcg_gen_shli_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
3538 tcg_gen_sari_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
3541 tcg_gen_shri_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
3544 tcg_gen_rotri_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
3552 static void gen_arith(DisasContext
*ctx
, uint32_t opc
,
3553 int rd
, int rs
, int rt
)
3555 if (rd
== 0 && opc
!= OPC_ADD
&& opc
!= OPC_SUB
3556 && opc
!= OPC_DADD
&& opc
!= OPC_DSUB
) {
3558 * If no destination, treat it as a NOP.
3559 * For add & sub, we must generate the overflow exception when needed.
3567 TCGv t0
= tcg_temp_local_new();
3568 TCGv t1
= tcg_temp_new();
3569 TCGv t2
= tcg_temp_new();
3570 TCGLabel
*l1
= gen_new_label();
3572 gen_load_gpr(t1
, rs
);
3573 gen_load_gpr(t2
, rt
);
3574 tcg_gen_add_tl(t0
, t1
, t2
);
3575 tcg_gen_ext32s_tl(t0
, t0
);
3576 tcg_gen_xor_tl(t1
, t1
, t2
);
3577 tcg_gen_xor_tl(t2
, t0
, t2
);
3578 tcg_gen_andc_tl(t1
, t2
, t1
);
3580 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
3582 /* operands of same sign, result different sign */
3583 generate_exception(ctx
, EXCP_OVERFLOW
);
3585 gen_store_gpr(t0
, rd
);
3590 if (rs
!= 0 && rt
!= 0) {
3591 tcg_gen_add_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
3592 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3593 } else if (rs
== 0 && rt
!= 0) {
3594 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
3595 } else if (rs
!= 0 && rt
== 0) {
3596 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
3598 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3603 TCGv t0
= tcg_temp_local_new();
3604 TCGv t1
= tcg_temp_new();
3605 TCGv t2
= tcg_temp_new();
3606 TCGLabel
*l1
= gen_new_label();
3608 gen_load_gpr(t1
, rs
);
3609 gen_load_gpr(t2
, rt
);
3610 tcg_gen_sub_tl(t0
, t1
, t2
);
3611 tcg_gen_ext32s_tl(t0
, t0
);
3612 tcg_gen_xor_tl(t2
, t1
, t2
);
3613 tcg_gen_xor_tl(t1
, t0
, t1
);
3614 tcg_gen_and_tl(t1
, t1
, t2
);
3616 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
3619 * operands of different sign, first operand and the result
3622 generate_exception(ctx
, EXCP_OVERFLOW
);
3624 gen_store_gpr(t0
, rd
);
3629 if (rs
!= 0 && rt
!= 0) {
3630 tcg_gen_sub_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
3631 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3632 } else if (rs
== 0 && rt
!= 0) {
3633 tcg_gen_neg_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
3634 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3635 } else if (rs
!= 0 && rt
== 0) {
3636 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
3638 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3641 #if defined(TARGET_MIPS64)
3644 TCGv t0
= tcg_temp_local_new();
3645 TCGv t1
= tcg_temp_new();
3646 TCGv t2
= tcg_temp_new();
3647 TCGLabel
*l1
= gen_new_label();
3649 gen_load_gpr(t1
, rs
);
3650 gen_load_gpr(t2
, rt
);
3651 tcg_gen_add_tl(t0
, t1
, t2
);
3652 tcg_gen_xor_tl(t1
, t1
, t2
);
3653 tcg_gen_xor_tl(t2
, t0
, t2
);
3654 tcg_gen_andc_tl(t1
, t2
, t1
);
3656 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
3658 /* operands of same sign, result different sign */
3659 generate_exception(ctx
, EXCP_OVERFLOW
);
3661 gen_store_gpr(t0
, rd
);
3666 if (rs
!= 0 && rt
!= 0) {
3667 tcg_gen_add_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
3668 } else if (rs
== 0 && rt
!= 0) {
3669 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
3670 } else if (rs
!= 0 && rt
== 0) {
3671 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
3673 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3678 TCGv t0
= tcg_temp_local_new();
3679 TCGv t1
= tcg_temp_new();
3680 TCGv t2
= tcg_temp_new();
3681 TCGLabel
*l1
= gen_new_label();
3683 gen_load_gpr(t1
, rs
);
3684 gen_load_gpr(t2
, rt
);
3685 tcg_gen_sub_tl(t0
, t1
, t2
);
3686 tcg_gen_xor_tl(t2
, t1
, t2
);
3687 tcg_gen_xor_tl(t1
, t0
, t1
);
3688 tcg_gen_and_tl(t1
, t1
, t2
);
3690 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
3693 * Operands of different sign, first operand and result different
3696 generate_exception(ctx
, EXCP_OVERFLOW
);
3698 gen_store_gpr(t0
, rd
);
3703 if (rs
!= 0 && rt
!= 0) {
3704 tcg_gen_sub_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
3705 } else if (rs
== 0 && rt
!= 0) {
3706 tcg_gen_neg_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
3707 } else if (rs
!= 0 && rt
== 0) {
3708 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
3710 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3715 if (likely(rs
!= 0 && rt
!= 0)) {
3716 tcg_gen_mul_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
3717 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3719 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3725 /* Conditional move */
3726 static void gen_cond_move(DisasContext
*ctx
, uint32_t opc
,
3727 int rd
, int rs
, int rt
)
3732 /* If no destination, treat it as a NOP. */
3736 t0
= tcg_temp_new();
3737 gen_load_gpr(t0
, rt
);
3738 t1
= tcg_const_tl(0);
3739 t2
= tcg_temp_new();
3740 gen_load_gpr(t2
, rs
);
3743 tcg_gen_movcond_tl(TCG_COND_NE
, cpu_gpr
[rd
], t0
, t1
, t2
, cpu_gpr
[rd
]);
3746 tcg_gen_movcond_tl(TCG_COND_EQ
, cpu_gpr
[rd
], t0
, t1
, t2
, cpu_gpr
[rd
]);
3749 tcg_gen_movcond_tl(TCG_COND_NE
, cpu_gpr
[rd
], t0
, t1
, t2
, t1
);
3752 tcg_gen_movcond_tl(TCG_COND_EQ
, cpu_gpr
[rd
], t0
, t1
, t2
, t1
);
3761 static void gen_logic(DisasContext
*ctx
, uint32_t opc
,
3762 int rd
, int rs
, int rt
)
3765 /* If no destination, treat it as a NOP. */
3771 if (likely(rs
!= 0 && rt
!= 0)) {
3772 tcg_gen_and_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
3774 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3778 if (rs
!= 0 && rt
!= 0) {
3779 tcg_gen_nor_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
3780 } else if (rs
== 0 && rt
!= 0) {
3781 tcg_gen_not_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
3782 } else if (rs
!= 0 && rt
== 0) {
3783 tcg_gen_not_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
3785 tcg_gen_movi_tl(cpu_gpr
[rd
], ~((target_ulong
)0));
3789 if (likely(rs
!= 0 && rt
!= 0)) {
3790 tcg_gen_or_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
3791 } else if (rs
== 0 && rt
!= 0) {
3792 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
3793 } else if (rs
!= 0 && rt
== 0) {
3794 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
3796 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3800 if (likely(rs
!= 0 && rt
!= 0)) {
3801 tcg_gen_xor_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
3802 } else if (rs
== 0 && rt
!= 0) {
3803 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
3804 } else if (rs
!= 0 && rt
== 0) {
3805 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
3807 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3813 /* Set on lower than */
3814 static void gen_slt(DisasContext
*ctx
, uint32_t opc
,
3815 int rd
, int rs
, int rt
)
3820 /* If no destination, treat it as a NOP. */
3824 t0
= tcg_temp_new();
3825 t1
= tcg_temp_new();
3826 gen_load_gpr(t0
, rs
);
3827 gen_load_gpr(t1
, rt
);
3830 tcg_gen_setcond_tl(TCG_COND_LT
, cpu_gpr
[rd
], t0
, t1
);
3833 tcg_gen_setcond_tl(TCG_COND_LTU
, cpu_gpr
[rd
], t0
, t1
);
3841 static void gen_shift(DisasContext
*ctx
, uint32_t opc
,
3842 int rd
, int rs
, int rt
)
3848 * If no destination, treat it as a NOP.
3849 * For add & sub, we must generate the overflow exception when needed.
3854 t0
= tcg_temp_new();
3855 t1
= tcg_temp_new();
3856 gen_load_gpr(t0
, rs
);
3857 gen_load_gpr(t1
, rt
);
3860 tcg_gen_andi_tl(t0
, t0
, 0x1f);
3861 tcg_gen_shl_tl(t0
, t1
, t0
);
3862 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
3865 tcg_gen_andi_tl(t0
, t0
, 0x1f);
3866 tcg_gen_sar_tl(cpu_gpr
[rd
], t1
, t0
);
3869 tcg_gen_ext32u_tl(t1
, t1
);
3870 tcg_gen_andi_tl(t0
, t0
, 0x1f);
3871 tcg_gen_shr_tl(t0
, t1
, t0
);
3872 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
3876 TCGv_i32 t2
= tcg_temp_new_i32();
3877 TCGv_i32 t3
= tcg_temp_new_i32();
3879 tcg_gen_trunc_tl_i32(t2
, t0
);
3880 tcg_gen_trunc_tl_i32(t3
, t1
);
3881 tcg_gen_andi_i32(t2
, t2
, 0x1f);
3882 tcg_gen_rotr_i32(t2
, t3
, t2
);
3883 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
3884 tcg_temp_free_i32(t2
);
3885 tcg_temp_free_i32(t3
);
3888 #if defined(TARGET_MIPS64)
3890 tcg_gen_andi_tl(t0
, t0
, 0x3f);
3891 tcg_gen_shl_tl(cpu_gpr
[rd
], t1
, t0
);
3894 tcg_gen_andi_tl(t0
, t0
, 0x3f);
3895 tcg_gen_sar_tl(cpu_gpr
[rd
], t1
, t0
);
3898 tcg_gen_andi_tl(t0
, t0
, 0x3f);
3899 tcg_gen_shr_tl(cpu_gpr
[rd
], t1
, t0
);
3902 tcg_gen_andi_tl(t0
, t0
, 0x3f);
3903 tcg_gen_rotr_tl(cpu_gpr
[rd
], t1
, t0
);
3911 #if defined(TARGET_MIPS64)
3912 /* Copy GPR to and from TX79 HI1/LO1 register. */
3913 static void gen_HILO1_tx79(DisasContext
*ctx
, uint32_t opc
, int reg
)
3917 gen_store_gpr(cpu_HI
[1], reg
);
3920 gen_store_gpr(cpu_LO
[1], reg
);
3923 gen_load_gpr(cpu_HI
[1], reg
);
3926 gen_load_gpr(cpu_LO
[1], reg
);
3929 MIPS_INVAL("mfthilo1 TX79");
3930 gen_reserved_instruction(ctx
);
3936 /* Arithmetic on HI/LO registers */
3937 static void gen_HILO(DisasContext
*ctx
, uint32_t opc
, int acc
, int reg
)
3939 if (reg
== 0 && (opc
== OPC_MFHI
|| opc
== OPC_MFLO
)) {
3950 #if defined(TARGET_MIPS64)
3952 tcg_gen_ext32s_tl(cpu_gpr
[reg
], cpu_HI
[acc
]);
3956 tcg_gen_mov_tl(cpu_gpr
[reg
], cpu_HI
[acc
]);
3960 #if defined(TARGET_MIPS64)
3962 tcg_gen_ext32s_tl(cpu_gpr
[reg
], cpu_LO
[acc
]);
3966 tcg_gen_mov_tl(cpu_gpr
[reg
], cpu_LO
[acc
]);
3971 #if defined(TARGET_MIPS64)
3973 tcg_gen_ext32s_tl(cpu_HI
[acc
], cpu_gpr
[reg
]);
3977 tcg_gen_mov_tl(cpu_HI
[acc
], cpu_gpr
[reg
]);
3980 tcg_gen_movi_tl(cpu_HI
[acc
], 0);
3985 #if defined(TARGET_MIPS64)
3987 tcg_gen_ext32s_tl(cpu_LO
[acc
], cpu_gpr
[reg
]);
3991 tcg_gen_mov_tl(cpu_LO
[acc
], cpu_gpr
[reg
]);
3994 tcg_gen_movi_tl(cpu_LO
[acc
], 0);
4000 static inline void gen_r6_ld(target_long addr
, int reg
, int memidx
,
4003 TCGv t0
= tcg_const_tl(addr
);
4004 tcg_gen_qemu_ld_tl(t0
, t0
, memidx
, memop
);
4005 gen_store_gpr(t0
, reg
);
4009 static inline void gen_pcrel(DisasContext
*ctx
, int opc
, target_ulong pc
,
4015 switch (MASK_OPC_PCREL_TOP2BITS(opc
)) {
4018 offset
= sextract32(ctx
->opcode
<< 2, 0, 21);
4019 addr
= addr_add(ctx
, pc
, offset
);
4020 tcg_gen_movi_tl(cpu_gpr
[rs
], addr
);
4024 offset
= sextract32(ctx
->opcode
<< 2, 0, 21);
4025 addr
= addr_add(ctx
, pc
, offset
);
4026 gen_r6_ld(addr
, rs
, ctx
->mem_idx
, MO_TESL
);
4028 #if defined(TARGET_MIPS64)
4031 offset
= sextract32(ctx
->opcode
<< 2, 0, 21);
4032 addr
= addr_add(ctx
, pc
, offset
);
4033 gen_r6_ld(addr
, rs
, ctx
->mem_idx
, MO_TEUL
);
4037 switch (MASK_OPC_PCREL_TOP5BITS(opc
)) {
4040 offset
= sextract32(ctx
->opcode
, 0, 16) << 16;
4041 addr
= addr_add(ctx
, pc
, offset
);
4042 tcg_gen_movi_tl(cpu_gpr
[rs
], addr
);
4047 offset
= sextract32(ctx
->opcode
, 0, 16) << 16;
4048 addr
= ~0xFFFF & addr_add(ctx
, pc
, offset
);
4049 tcg_gen_movi_tl(cpu_gpr
[rs
], addr
);
4052 #if defined(TARGET_MIPS64)
4053 case R6_OPC_LDPC
: /* bits 16 and 17 are part of immediate */
4054 case R6_OPC_LDPC
+ (1 << 16):
4055 case R6_OPC_LDPC
+ (2 << 16):
4056 case R6_OPC_LDPC
+ (3 << 16):
4058 offset
= sextract32(ctx
->opcode
<< 3, 0, 21);
4059 addr
= addr_add(ctx
, (pc
& ~0x7), offset
);
4060 gen_r6_ld(addr
, rs
, ctx
->mem_idx
, MO_TEQ
);
4064 MIPS_INVAL("OPC_PCREL");
4065 gen_reserved_instruction(ctx
);
4072 static void gen_r6_muldiv(DisasContext
*ctx
, int opc
, int rd
, int rs
, int rt
)
4081 t0
= tcg_temp_new();
4082 t1
= tcg_temp_new();
4084 gen_load_gpr(t0
, rs
);
4085 gen_load_gpr(t1
, rt
);
4090 TCGv t2
= tcg_temp_new();
4091 TCGv t3
= tcg_temp_new();
4092 tcg_gen_ext32s_tl(t0
, t0
);
4093 tcg_gen_ext32s_tl(t1
, t1
);
4094 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, INT_MIN
);
4095 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1);
4096 tcg_gen_and_tl(t2
, t2
, t3
);
4097 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
4098 tcg_gen_or_tl(t2
, t2
, t3
);
4099 tcg_gen_movi_tl(t3
, 0);
4100 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
4101 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
4102 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
4109 TCGv t2
= tcg_temp_new();
4110 TCGv t3
= tcg_temp_new();
4111 tcg_gen_ext32s_tl(t0
, t0
);
4112 tcg_gen_ext32s_tl(t1
, t1
);
4113 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, INT_MIN
);
4114 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1);
4115 tcg_gen_and_tl(t2
, t2
, t3
);
4116 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
4117 tcg_gen_or_tl(t2
, t2
, t3
);
4118 tcg_gen_movi_tl(t3
, 0);
4119 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
4120 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
4121 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
4128 TCGv t2
= tcg_const_tl(0);
4129 TCGv t3
= tcg_const_tl(1);
4130 tcg_gen_ext32u_tl(t0
, t0
);
4131 tcg_gen_ext32u_tl(t1
, t1
);
4132 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
4133 tcg_gen_divu_tl(cpu_gpr
[rd
], t0
, t1
);
4134 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
4141 TCGv t2
= tcg_const_tl(0);
4142 TCGv t3
= tcg_const_tl(1);
4143 tcg_gen_ext32u_tl(t0
, t0
);
4144 tcg_gen_ext32u_tl(t1
, t1
);
4145 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
4146 tcg_gen_remu_tl(cpu_gpr
[rd
], t0
, t1
);
4147 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
4154 TCGv_i32 t2
= tcg_temp_new_i32();
4155 TCGv_i32 t3
= tcg_temp_new_i32();
4156 tcg_gen_trunc_tl_i32(t2
, t0
);
4157 tcg_gen_trunc_tl_i32(t3
, t1
);
4158 tcg_gen_mul_i32(t2
, t2
, t3
);
4159 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
4160 tcg_temp_free_i32(t2
);
4161 tcg_temp_free_i32(t3
);
4166 TCGv_i32 t2
= tcg_temp_new_i32();
4167 TCGv_i32 t3
= tcg_temp_new_i32();
4168 tcg_gen_trunc_tl_i32(t2
, t0
);
4169 tcg_gen_trunc_tl_i32(t3
, t1
);
4170 tcg_gen_muls2_i32(t2
, t3
, t2
, t3
);
4171 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t3
);
4172 tcg_temp_free_i32(t2
);
4173 tcg_temp_free_i32(t3
);
4178 TCGv_i32 t2
= tcg_temp_new_i32();
4179 TCGv_i32 t3
= tcg_temp_new_i32();
4180 tcg_gen_trunc_tl_i32(t2
, t0
);
4181 tcg_gen_trunc_tl_i32(t3
, t1
);
4182 tcg_gen_mul_i32(t2
, t2
, t3
);
4183 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
4184 tcg_temp_free_i32(t2
);
4185 tcg_temp_free_i32(t3
);
4190 TCGv_i32 t2
= tcg_temp_new_i32();
4191 TCGv_i32 t3
= tcg_temp_new_i32();
4192 tcg_gen_trunc_tl_i32(t2
, t0
);
4193 tcg_gen_trunc_tl_i32(t3
, t1
);
4194 tcg_gen_mulu2_i32(t2
, t3
, t2
, t3
);
4195 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t3
);
4196 tcg_temp_free_i32(t2
);
4197 tcg_temp_free_i32(t3
);
4200 #if defined(TARGET_MIPS64)
4203 TCGv t2
= tcg_temp_new();
4204 TCGv t3
= tcg_temp_new();
4205 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, -1LL << 63);
4206 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1LL);
4207 tcg_gen_and_tl(t2
, t2
, t3
);
4208 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
4209 tcg_gen_or_tl(t2
, t2
, t3
);
4210 tcg_gen_movi_tl(t3
, 0);
4211 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
4212 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
4219 TCGv t2
= tcg_temp_new();
4220 TCGv t3
= tcg_temp_new();
4221 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, -1LL << 63);
4222 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1LL);
4223 tcg_gen_and_tl(t2
, t2
, t3
);
4224 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
4225 tcg_gen_or_tl(t2
, t2
, t3
);
4226 tcg_gen_movi_tl(t3
, 0);
4227 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
4228 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
4235 TCGv t2
= tcg_const_tl(0);
4236 TCGv t3
= tcg_const_tl(1);
4237 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
4238 tcg_gen_divu_i64(cpu_gpr
[rd
], t0
, t1
);
4245 TCGv t2
= tcg_const_tl(0);
4246 TCGv t3
= tcg_const_tl(1);
4247 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
4248 tcg_gen_remu_i64(cpu_gpr
[rd
], t0
, t1
);
4254 tcg_gen_mul_i64(cpu_gpr
[rd
], t0
, t1
);
4258 TCGv t2
= tcg_temp_new();
4259 tcg_gen_muls2_i64(t2
, cpu_gpr
[rd
], t0
, t1
);
4264 tcg_gen_mul_i64(cpu_gpr
[rd
], t0
, t1
);
4268 TCGv t2
= tcg_temp_new();
4269 tcg_gen_mulu2_i64(t2
, cpu_gpr
[rd
], t0
, t1
);
4275 MIPS_INVAL("r6 mul/div");
4276 gen_reserved_instruction(ctx
);
4284 #if defined(TARGET_MIPS64)
4285 static void gen_div1_tx79(DisasContext
*ctx
, uint32_t opc
, int rs
, int rt
)
4289 t0
= tcg_temp_new();
4290 t1
= tcg_temp_new();
4292 gen_load_gpr(t0
, rs
);
4293 gen_load_gpr(t1
, rt
);
4298 TCGv t2
= tcg_temp_new();
4299 TCGv t3
= tcg_temp_new();
4300 tcg_gen_ext32s_tl(t0
, t0
);
4301 tcg_gen_ext32s_tl(t1
, t1
);
4302 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, INT_MIN
);
4303 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1);
4304 tcg_gen_and_tl(t2
, t2
, t3
);
4305 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
4306 tcg_gen_or_tl(t2
, t2
, t3
);
4307 tcg_gen_movi_tl(t3
, 0);
4308 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
4309 tcg_gen_div_tl(cpu_LO
[1], t0
, t1
);
4310 tcg_gen_rem_tl(cpu_HI
[1], t0
, t1
);
4311 tcg_gen_ext32s_tl(cpu_LO
[1], cpu_LO
[1]);
4312 tcg_gen_ext32s_tl(cpu_HI
[1], cpu_HI
[1]);
4319 TCGv t2
= tcg_const_tl(0);
4320 TCGv t3
= tcg_const_tl(1);
4321 tcg_gen_ext32u_tl(t0
, t0
);
4322 tcg_gen_ext32u_tl(t1
, t1
);
4323 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
4324 tcg_gen_divu_tl(cpu_LO
[1], t0
, t1
);
4325 tcg_gen_remu_tl(cpu_HI
[1], t0
, t1
);
4326 tcg_gen_ext32s_tl(cpu_LO
[1], cpu_LO
[1]);
4327 tcg_gen_ext32s_tl(cpu_HI
[1], cpu_HI
[1]);
4333 MIPS_INVAL("div1 TX79");
4334 gen_reserved_instruction(ctx
);
4343 static void gen_muldiv(DisasContext
*ctx
, uint32_t opc
,
4344 int acc
, int rs
, int rt
)
4348 t0
= tcg_temp_new();
4349 t1
= tcg_temp_new();
4351 gen_load_gpr(t0
, rs
);
4352 gen_load_gpr(t1
, rt
);
4361 TCGv t2
= tcg_temp_new();
4362 TCGv t3
= tcg_temp_new();
4363 tcg_gen_ext32s_tl(t0
, t0
);
4364 tcg_gen_ext32s_tl(t1
, t1
);
4365 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, INT_MIN
);
4366 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1);
4367 tcg_gen_and_tl(t2
, t2
, t3
);
4368 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
4369 tcg_gen_or_tl(t2
, t2
, t3
);
4370 tcg_gen_movi_tl(t3
, 0);
4371 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
4372 tcg_gen_div_tl(cpu_LO
[acc
], t0
, t1
);
4373 tcg_gen_rem_tl(cpu_HI
[acc
], t0
, t1
);
4374 tcg_gen_ext32s_tl(cpu_LO
[acc
], cpu_LO
[acc
]);
4375 tcg_gen_ext32s_tl(cpu_HI
[acc
], cpu_HI
[acc
]);
4382 TCGv t2
= tcg_const_tl(0);
4383 TCGv t3
= tcg_const_tl(1);
4384 tcg_gen_ext32u_tl(t0
, t0
);
4385 tcg_gen_ext32u_tl(t1
, t1
);
4386 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
4387 tcg_gen_divu_tl(cpu_LO
[acc
], t0
, t1
);
4388 tcg_gen_remu_tl(cpu_HI
[acc
], t0
, t1
);
4389 tcg_gen_ext32s_tl(cpu_LO
[acc
], cpu_LO
[acc
]);
4390 tcg_gen_ext32s_tl(cpu_HI
[acc
], cpu_HI
[acc
]);
4397 TCGv_i32 t2
= tcg_temp_new_i32();
4398 TCGv_i32 t3
= tcg_temp_new_i32();
4399 tcg_gen_trunc_tl_i32(t2
, t0
);
4400 tcg_gen_trunc_tl_i32(t3
, t1
);
4401 tcg_gen_muls2_i32(t2
, t3
, t2
, t3
);
4402 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
4403 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
4404 tcg_temp_free_i32(t2
);
4405 tcg_temp_free_i32(t3
);
4410 TCGv_i32 t2
= tcg_temp_new_i32();
4411 TCGv_i32 t3
= tcg_temp_new_i32();
4412 tcg_gen_trunc_tl_i32(t2
, t0
);
4413 tcg_gen_trunc_tl_i32(t3
, t1
);
4414 tcg_gen_mulu2_i32(t2
, t3
, t2
, t3
);
4415 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
4416 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
4417 tcg_temp_free_i32(t2
);
4418 tcg_temp_free_i32(t3
);
4421 #if defined(TARGET_MIPS64)
4424 TCGv t2
= tcg_temp_new();
4425 TCGv t3
= tcg_temp_new();
4426 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, -1LL << 63);
4427 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1LL);
4428 tcg_gen_and_tl(t2
, t2
, t3
);
4429 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
4430 tcg_gen_or_tl(t2
, t2
, t3
);
4431 tcg_gen_movi_tl(t3
, 0);
4432 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
4433 tcg_gen_div_tl(cpu_LO
[acc
], t0
, t1
);
4434 tcg_gen_rem_tl(cpu_HI
[acc
], t0
, t1
);
4441 TCGv t2
= tcg_const_tl(0);
4442 TCGv t3
= tcg_const_tl(1);
4443 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
4444 tcg_gen_divu_i64(cpu_LO
[acc
], t0
, t1
);
4445 tcg_gen_remu_i64(cpu_HI
[acc
], t0
, t1
);
4451 tcg_gen_muls2_i64(cpu_LO
[acc
], cpu_HI
[acc
], t0
, t1
);
4454 tcg_gen_mulu2_i64(cpu_LO
[acc
], cpu_HI
[acc
], t0
, t1
);
4459 TCGv_i64 t2
= tcg_temp_new_i64();
4460 TCGv_i64 t3
= tcg_temp_new_i64();
4462 tcg_gen_ext_tl_i64(t2
, t0
);
4463 tcg_gen_ext_tl_i64(t3
, t1
);
4464 tcg_gen_mul_i64(t2
, t2
, t3
);
4465 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
4466 tcg_gen_add_i64(t2
, t2
, t3
);
4467 tcg_temp_free_i64(t3
);
4468 gen_move_low32(cpu_LO
[acc
], t2
);
4469 gen_move_high32(cpu_HI
[acc
], t2
);
4470 tcg_temp_free_i64(t2
);
4475 TCGv_i64 t2
= tcg_temp_new_i64();
4476 TCGv_i64 t3
= tcg_temp_new_i64();
4478 tcg_gen_ext32u_tl(t0
, t0
);
4479 tcg_gen_ext32u_tl(t1
, t1
);
4480 tcg_gen_extu_tl_i64(t2
, t0
);
4481 tcg_gen_extu_tl_i64(t3
, t1
);
4482 tcg_gen_mul_i64(t2
, t2
, t3
);
4483 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
4484 tcg_gen_add_i64(t2
, t2
, t3
);
4485 tcg_temp_free_i64(t3
);
4486 gen_move_low32(cpu_LO
[acc
], t2
);
4487 gen_move_high32(cpu_HI
[acc
], t2
);
4488 tcg_temp_free_i64(t2
);
4493 TCGv_i64 t2
= tcg_temp_new_i64();
4494 TCGv_i64 t3
= tcg_temp_new_i64();
4496 tcg_gen_ext_tl_i64(t2
, t0
);
4497 tcg_gen_ext_tl_i64(t3
, t1
);
4498 tcg_gen_mul_i64(t2
, t2
, t3
);
4499 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
4500 tcg_gen_sub_i64(t2
, t3
, t2
);
4501 tcg_temp_free_i64(t3
);
4502 gen_move_low32(cpu_LO
[acc
], t2
);
4503 gen_move_high32(cpu_HI
[acc
], t2
);
4504 tcg_temp_free_i64(t2
);
4509 TCGv_i64 t2
= tcg_temp_new_i64();
4510 TCGv_i64 t3
= tcg_temp_new_i64();
4512 tcg_gen_ext32u_tl(t0
, t0
);
4513 tcg_gen_ext32u_tl(t1
, t1
);
4514 tcg_gen_extu_tl_i64(t2
, t0
);
4515 tcg_gen_extu_tl_i64(t3
, t1
);
4516 tcg_gen_mul_i64(t2
, t2
, t3
);
4517 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
4518 tcg_gen_sub_i64(t2
, t3
, t2
);
4519 tcg_temp_free_i64(t3
);
4520 gen_move_low32(cpu_LO
[acc
], t2
);
4521 gen_move_high32(cpu_HI
[acc
], t2
);
4522 tcg_temp_free_i64(t2
);
4526 MIPS_INVAL("mul/div");
4527 gen_reserved_instruction(ctx
);
4536 * These MULT[U] and MADD[U] instructions implemented in for example
4537 * the Toshiba/Sony R5900 and the Toshiba TX19, TX39 and TX79 core
4538 * architectures are special three-operand variants with the syntax
4540 * MULT[U][1] rd, rs, rt
4544 * (rd, LO, HI) <- rs * rt
4548 * MADD[U][1] rd, rs, rt
4552 * (rd, LO, HI) <- (LO, HI) + rs * rt
4554 * where the low-order 32-bits of the result is placed into both the
4555 * GPR rd and the special register LO. The high-order 32-bits of the
4556 * result is placed into the special register HI.
4558 * If the GPR rd is omitted in assembly language, it is taken to be 0,
4559 * which is the zero register that always reads as 0.
4561 static void gen_mul_txx9(DisasContext
*ctx
, uint32_t opc
,
4562 int rd
, int rs
, int rt
)
4564 TCGv t0
= tcg_temp_new();
4565 TCGv t1
= tcg_temp_new();
4568 gen_load_gpr(t0
, rs
);
4569 gen_load_gpr(t1
, rt
);
4577 TCGv_i32 t2
= tcg_temp_new_i32();
4578 TCGv_i32 t3
= tcg_temp_new_i32();
4579 tcg_gen_trunc_tl_i32(t2
, t0
);
4580 tcg_gen_trunc_tl_i32(t3
, t1
);
4581 tcg_gen_muls2_i32(t2
, t3
, t2
, t3
);
4583 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
4585 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
4586 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
4587 tcg_temp_free_i32(t2
);
4588 tcg_temp_free_i32(t3
);
4591 case MMI_OPC_MULTU1
:
4596 TCGv_i32 t2
= tcg_temp_new_i32();
4597 TCGv_i32 t3
= tcg_temp_new_i32();
4598 tcg_gen_trunc_tl_i32(t2
, t0
);
4599 tcg_gen_trunc_tl_i32(t3
, t1
);
4600 tcg_gen_mulu2_i32(t2
, t3
, t2
, t3
);
4602 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
4604 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
4605 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
4606 tcg_temp_free_i32(t2
);
4607 tcg_temp_free_i32(t3
);
4615 TCGv_i64 t2
= tcg_temp_new_i64();
4616 TCGv_i64 t3
= tcg_temp_new_i64();
4618 tcg_gen_ext_tl_i64(t2
, t0
);
4619 tcg_gen_ext_tl_i64(t3
, t1
);
4620 tcg_gen_mul_i64(t2
, t2
, t3
);
4621 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
4622 tcg_gen_add_i64(t2
, t2
, t3
);
4623 tcg_temp_free_i64(t3
);
4624 gen_move_low32(cpu_LO
[acc
], t2
);
4625 gen_move_high32(cpu_HI
[acc
], t2
);
4627 gen_move_low32(cpu_gpr
[rd
], t2
);
4629 tcg_temp_free_i64(t2
);
4632 case MMI_OPC_MADDU1
:
4637 TCGv_i64 t2
= tcg_temp_new_i64();
4638 TCGv_i64 t3
= tcg_temp_new_i64();
4640 tcg_gen_ext32u_tl(t0
, t0
);
4641 tcg_gen_ext32u_tl(t1
, t1
);
4642 tcg_gen_extu_tl_i64(t2
, t0
);
4643 tcg_gen_extu_tl_i64(t3
, t1
);
4644 tcg_gen_mul_i64(t2
, t2
, t3
);
4645 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
4646 tcg_gen_add_i64(t2
, t2
, t3
);
4647 tcg_temp_free_i64(t3
);
4648 gen_move_low32(cpu_LO
[acc
], t2
);
4649 gen_move_high32(cpu_HI
[acc
], t2
);
4651 gen_move_low32(cpu_gpr
[rd
], t2
);
4653 tcg_temp_free_i64(t2
);
4657 MIPS_INVAL("mul/madd TXx9");
4658 gen_reserved_instruction(ctx
);
4667 static void gen_mul_vr54xx(DisasContext
*ctx
, uint32_t opc
,
4668 int rd
, int rs
, int rt
)
4670 TCGv t0
= tcg_temp_new();
4671 TCGv t1
= tcg_temp_new();
4673 gen_load_gpr(t0
, rs
);
4674 gen_load_gpr(t1
, rt
);
4677 case OPC_VR54XX_MULS
:
4678 gen_helper_muls(t0
, cpu_env
, t0
, t1
);
4680 case OPC_VR54XX_MULSU
:
4681 gen_helper_mulsu(t0
, cpu_env
, t0
, t1
);
4683 case OPC_VR54XX_MACC
:
4684 gen_helper_macc(t0
, cpu_env
, t0
, t1
);
4686 case OPC_VR54XX_MACCU
:
4687 gen_helper_maccu(t0
, cpu_env
, t0
, t1
);
4689 case OPC_VR54XX_MSAC
:
4690 gen_helper_msac(t0
, cpu_env
, t0
, t1
);
4692 case OPC_VR54XX_MSACU
:
4693 gen_helper_msacu(t0
, cpu_env
, t0
, t1
);
4695 case OPC_VR54XX_MULHI
:
4696 gen_helper_mulhi(t0
, cpu_env
, t0
, t1
);
4698 case OPC_VR54XX_MULHIU
:
4699 gen_helper_mulhiu(t0
, cpu_env
, t0
, t1
);
4701 case OPC_VR54XX_MULSHI
:
4702 gen_helper_mulshi(t0
, cpu_env
, t0
, t1
);
4704 case OPC_VR54XX_MULSHIU
:
4705 gen_helper_mulshiu(t0
, cpu_env
, t0
, t1
);
4707 case OPC_VR54XX_MACCHI
:
4708 gen_helper_macchi(t0
, cpu_env
, t0
, t1
);
4710 case OPC_VR54XX_MACCHIU
:
4711 gen_helper_macchiu(t0
, cpu_env
, t0
, t1
);
4713 case OPC_VR54XX_MSACHI
:
4714 gen_helper_msachi(t0
, cpu_env
, t0
, t1
);
4716 case OPC_VR54XX_MSACHIU
:
4717 gen_helper_msachiu(t0
, cpu_env
, t0
, t1
);
4720 MIPS_INVAL("mul vr54xx");
4721 gen_reserved_instruction(ctx
);
4724 gen_store_gpr(t0
, rd
);
4731 static void gen_cl(DisasContext
*ctx
, uint32_t opc
,
4741 gen_load_gpr(t0
, rs
);
4746 #if defined(TARGET_MIPS64)
4750 tcg_gen_not_tl(t0
, t0
);
4759 tcg_gen_ext32u_tl(t0
, t0
);
4760 tcg_gen_clzi_tl(t0
, t0
, TARGET_LONG_BITS
);
4761 tcg_gen_subi_tl(t0
, t0
, TARGET_LONG_BITS
- 32);
4763 #if defined(TARGET_MIPS64)
4768 tcg_gen_clzi_i64(t0
, t0
, 64);
4774 /* Godson integer instructions */
4775 static void gen_loongson_integer(DisasContext
*ctx
, uint32_t opc
,
4776 int rd
, int rs
, int rt
)
4788 case OPC_MULTU_G_2E
:
4789 case OPC_MULTU_G_2F
:
4790 #if defined(TARGET_MIPS64)
4791 case OPC_DMULT_G_2E
:
4792 case OPC_DMULT_G_2F
:
4793 case OPC_DMULTU_G_2E
:
4794 case OPC_DMULTU_G_2F
:
4796 t0
= tcg_temp_new();
4797 t1
= tcg_temp_new();
4800 t0
= tcg_temp_local_new();
4801 t1
= tcg_temp_local_new();
4805 gen_load_gpr(t0
, rs
);
4806 gen_load_gpr(t1
, rt
);
4811 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
4812 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
4814 case OPC_MULTU_G_2E
:
4815 case OPC_MULTU_G_2F
:
4816 tcg_gen_ext32u_tl(t0
, t0
);
4817 tcg_gen_ext32u_tl(t1
, t1
);
4818 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
4819 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
4824 TCGLabel
*l1
= gen_new_label();
4825 TCGLabel
*l2
= gen_new_label();
4826 TCGLabel
*l3
= gen_new_label();
4827 tcg_gen_ext32s_tl(t0
, t0
);
4828 tcg_gen_ext32s_tl(t1
, t1
);
4829 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
4830 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4833 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, INT_MIN
, l2
);
4834 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1, l2
);
4835 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
4838 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
4839 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
4846 TCGLabel
*l1
= gen_new_label();
4847 TCGLabel
*l2
= gen_new_label();
4848 tcg_gen_ext32u_tl(t0
, t0
);
4849 tcg_gen_ext32u_tl(t1
, t1
);
4850 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
4851 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4854 tcg_gen_divu_tl(cpu_gpr
[rd
], t0
, t1
);
4855 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
4862 TCGLabel
*l1
= gen_new_label();
4863 TCGLabel
*l2
= gen_new_label();
4864 TCGLabel
*l3
= gen_new_label();
4865 tcg_gen_ext32u_tl(t0
, t0
);
4866 tcg_gen_ext32u_tl(t1
, t1
);
4867 tcg_gen_brcondi_tl(TCG_COND_EQ
, t1
, 0, l1
);
4868 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, INT_MIN
, l2
);
4869 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1, l2
);
4871 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4874 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
4875 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
4882 TCGLabel
*l1
= gen_new_label();
4883 TCGLabel
*l2
= gen_new_label();
4884 tcg_gen_ext32u_tl(t0
, t0
);
4885 tcg_gen_ext32u_tl(t1
, t1
);
4886 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
4887 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4890 tcg_gen_remu_tl(cpu_gpr
[rd
], t0
, t1
);
4891 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
4895 #if defined(TARGET_MIPS64)
4896 case OPC_DMULT_G_2E
:
4897 case OPC_DMULT_G_2F
:
4898 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
4900 case OPC_DMULTU_G_2E
:
4901 case OPC_DMULTU_G_2F
:
4902 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
4907 TCGLabel
*l1
= gen_new_label();
4908 TCGLabel
*l2
= gen_new_label();
4909 TCGLabel
*l3
= gen_new_label();
4910 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
4911 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4914 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, -1LL << 63, l2
);
4915 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1LL, l2
);
4916 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
4919 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
4923 case OPC_DDIVU_G_2E
:
4924 case OPC_DDIVU_G_2F
:
4926 TCGLabel
*l1
= gen_new_label();
4927 TCGLabel
*l2
= gen_new_label();
4928 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
4929 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4932 tcg_gen_divu_tl(cpu_gpr
[rd
], t0
, t1
);
4939 TCGLabel
*l1
= gen_new_label();
4940 TCGLabel
*l2
= gen_new_label();
4941 TCGLabel
*l3
= gen_new_label();
4942 tcg_gen_brcondi_tl(TCG_COND_EQ
, t1
, 0, l1
);
4943 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, -1LL << 63, l2
);
4944 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1LL, l2
);
4946 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4949 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
4953 case OPC_DMODU_G_2E
:
4954 case OPC_DMODU_G_2F
:
4956 TCGLabel
*l1
= gen_new_label();
4957 TCGLabel
*l2
= gen_new_label();
4958 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
4959 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4962 tcg_gen_remu_tl(cpu_gpr
[rd
], t0
, t1
);
4973 /* Loongson multimedia instructions */
4974 static void gen_loongson_multimedia(DisasContext
*ctx
, int rd
, int rs
, int rt
)
4976 uint32_t opc
, shift_max
;
4980 opc
= MASK_LMMI(ctx
->opcode
);
4986 t0
= tcg_temp_local_new_i64();
4987 t1
= tcg_temp_local_new_i64();
4990 t0
= tcg_temp_new_i64();
4991 t1
= tcg_temp_new_i64();
4995 check_cp1_enabled(ctx
);
4996 gen_load_fpr64(ctx
, t0
, rs
);
4997 gen_load_fpr64(ctx
, t1
, rt
);
5001 gen_helper_paddsh(t0
, t0
, t1
);
5004 gen_helper_paddush(t0
, t0
, t1
);
5007 gen_helper_paddh(t0
, t0
, t1
);
5010 gen_helper_paddw(t0
, t0
, t1
);
5013 gen_helper_paddsb(t0
, t0
, t1
);
5016 gen_helper_paddusb(t0
, t0
, t1
);
5019 gen_helper_paddb(t0
, t0
, t1
);
5023 gen_helper_psubsh(t0
, t0
, t1
);
5026 gen_helper_psubush(t0
, t0
, t1
);
5029 gen_helper_psubh(t0
, t0
, t1
);
5032 gen_helper_psubw(t0
, t0
, t1
);
5035 gen_helper_psubsb(t0
, t0
, t1
);
5038 gen_helper_psubusb(t0
, t0
, t1
);
5041 gen_helper_psubb(t0
, t0
, t1
);
5045 gen_helper_pshufh(t0
, t0
, t1
);
5048 gen_helper_packsswh(t0
, t0
, t1
);
5051 gen_helper_packsshb(t0
, t0
, t1
);
5054 gen_helper_packushb(t0
, t0
, t1
);
5058 gen_helper_punpcklhw(t0
, t0
, t1
);
5061 gen_helper_punpckhhw(t0
, t0
, t1
);
5064 gen_helper_punpcklbh(t0
, t0
, t1
);
5067 gen_helper_punpckhbh(t0
, t0
, t1
);
5070 gen_helper_punpcklwd(t0
, t0
, t1
);
5073 gen_helper_punpckhwd(t0
, t0
, t1
);
5077 gen_helper_pavgh(t0
, t0
, t1
);
5080 gen_helper_pavgb(t0
, t0
, t1
);
5083 gen_helper_pmaxsh(t0
, t0
, t1
);
5086 gen_helper_pminsh(t0
, t0
, t1
);
5089 gen_helper_pmaxub(t0
, t0
, t1
);
5092 gen_helper_pminub(t0
, t0
, t1
);
5096 gen_helper_pcmpeqw(t0
, t0
, t1
);
5099 gen_helper_pcmpgtw(t0
, t0
, t1
);
5102 gen_helper_pcmpeqh(t0
, t0
, t1
);
5105 gen_helper_pcmpgth(t0
, t0
, t1
);
5108 gen_helper_pcmpeqb(t0
, t0
, t1
);
5111 gen_helper_pcmpgtb(t0
, t0
, t1
);
5115 gen_helper_psllw(t0
, t0
, t1
);
5118 gen_helper_psllh(t0
, t0
, t1
);
5121 gen_helper_psrlw(t0
, t0
, t1
);
5124 gen_helper_psrlh(t0
, t0
, t1
);
5127 gen_helper_psraw(t0
, t0
, t1
);
5130 gen_helper_psrah(t0
, t0
, t1
);
5134 gen_helper_pmullh(t0
, t0
, t1
);
5137 gen_helper_pmulhh(t0
, t0
, t1
);
5140 gen_helper_pmulhuh(t0
, t0
, t1
);
5143 gen_helper_pmaddhw(t0
, t0
, t1
);
5147 gen_helper_pasubub(t0
, t0
, t1
);
5150 gen_helper_biadd(t0
, t0
);
5153 gen_helper_pmovmskb(t0
, t0
);
5157 tcg_gen_add_i64(t0
, t0
, t1
);
5160 tcg_gen_sub_i64(t0
, t0
, t1
);
5163 tcg_gen_xor_i64(t0
, t0
, t1
);
5166 tcg_gen_nor_i64(t0
, t0
, t1
);
5169 tcg_gen_and_i64(t0
, t0
, t1
);
5172 tcg_gen_or_i64(t0
, t0
, t1
);
5176 tcg_gen_andc_i64(t0
, t1
, t0
);
5180 tcg_gen_deposit_i64(t0
, t0
, t1
, 0, 16);
5183 tcg_gen_deposit_i64(t0
, t0
, t1
, 16, 16);
5186 tcg_gen_deposit_i64(t0
, t0
, t1
, 32, 16);
5189 tcg_gen_deposit_i64(t0
, t0
, t1
, 48, 16);
5193 tcg_gen_andi_i64(t1
, t1
, 3);
5194 tcg_gen_shli_i64(t1
, t1
, 4);
5195 tcg_gen_shr_i64(t0
, t0
, t1
);
5196 tcg_gen_ext16u_i64(t0
, t0
);
5200 tcg_gen_add_i64(t0
, t0
, t1
);
5201 tcg_gen_ext32s_i64(t0
, t0
);
5204 tcg_gen_sub_i64(t0
, t0
, t1
);
5205 tcg_gen_ext32s_i64(t0
, t0
);
5227 /* Make sure shift count isn't TCG undefined behaviour. */
5228 tcg_gen_andi_i64(t1
, t1
, shift_max
- 1);
5233 tcg_gen_shl_i64(t0
, t0
, t1
);
5238 * Since SRA is UndefinedResult without sign-extended inputs,
5239 * we can treat SRA and DSRA the same.
5241 tcg_gen_sar_i64(t0
, t0
, t1
);
5244 /* We want to shift in zeros for SRL; zero-extend first. */
5245 tcg_gen_ext32u_i64(t0
, t0
);
5248 tcg_gen_shr_i64(t0
, t0
, t1
);
5252 if (shift_max
== 32) {
5253 tcg_gen_ext32s_i64(t0
, t0
);
5256 /* Shifts larger than MAX produce zero. */
5257 tcg_gen_setcondi_i64(TCG_COND_LTU
, t1
, t1
, shift_max
);
5258 tcg_gen_neg_i64(t1
, t1
);
5259 tcg_gen_and_i64(t0
, t0
, t1
);
5265 TCGv_i64 t2
= tcg_temp_new_i64();
5266 TCGLabel
*lab
= gen_new_label();
5268 tcg_gen_mov_i64(t2
, t0
);
5269 tcg_gen_add_i64(t0
, t1
, t2
);
5270 if (opc
== OPC_ADD_CP2
) {
5271 tcg_gen_ext32s_i64(t0
, t0
);
5273 tcg_gen_xor_i64(t1
, t1
, t2
);
5274 tcg_gen_xor_i64(t2
, t2
, t0
);
5275 tcg_gen_andc_i64(t1
, t2
, t1
);
5276 tcg_temp_free_i64(t2
);
5277 tcg_gen_brcondi_i64(TCG_COND_GE
, t1
, 0, lab
);
5278 generate_exception(ctx
, EXCP_OVERFLOW
);
5286 TCGv_i64 t2
= tcg_temp_new_i64();
5287 TCGLabel
*lab
= gen_new_label();
5289 tcg_gen_mov_i64(t2
, t0
);
5290 tcg_gen_sub_i64(t0
, t1
, t2
);
5291 if (opc
== OPC_SUB_CP2
) {
5292 tcg_gen_ext32s_i64(t0
, t0
);
5294 tcg_gen_xor_i64(t1
, t1
, t2
);
5295 tcg_gen_xor_i64(t2
, t2
, t0
);
5296 tcg_gen_and_i64(t1
, t1
, t2
);
5297 tcg_temp_free_i64(t2
);
5298 tcg_gen_brcondi_i64(TCG_COND_GE
, t1
, 0, lab
);
5299 generate_exception(ctx
, EXCP_OVERFLOW
);
5305 tcg_gen_ext32u_i64(t0
, t0
);
5306 tcg_gen_ext32u_i64(t1
, t1
);
5307 tcg_gen_mul_i64(t0
, t0
, t1
);
5316 cond
= TCG_COND_LTU
;
5324 cond
= TCG_COND_LEU
;
5331 int cc
= (ctx
->opcode
>> 8) & 0x7;
5332 TCGv_i64 t64
= tcg_temp_new_i64();
5333 TCGv_i32 t32
= tcg_temp_new_i32();
5335 tcg_gen_setcond_i64(cond
, t64
, t0
, t1
);
5336 tcg_gen_extrl_i64_i32(t32
, t64
);
5337 tcg_gen_deposit_i32(fpu_fcr31
, fpu_fcr31
, t32
,
5340 tcg_temp_free_i32(t32
);
5341 tcg_temp_free_i64(t64
);
5346 MIPS_INVAL("loongson_cp2");
5347 gen_reserved_instruction(ctx
);
5351 gen_store_fpr64(ctx
, t0
, rd
);
5354 tcg_temp_free_i64(t0
);
5355 tcg_temp_free_i64(t1
);
5358 static void gen_loongson_lswc2(DisasContext
*ctx
, int rt
,
5363 #if defined(TARGET_MIPS64)
5364 int lsq_rt1
= ctx
->opcode
& 0x1f;
5365 int lsq_offset
= sextract32(ctx
->opcode
, 6, 9) << 4;
5367 int shf_offset
= sextract32(ctx
->opcode
, 6, 8);
5369 t0
= tcg_temp_new();
5371 switch (MASK_LOONGSON_GSLSQ(ctx
->opcode
)) {
5372 #if defined(TARGET_MIPS64)
5374 t1
= tcg_temp_new();
5375 gen_base_offset_addr(ctx
, t0
, rs
, lsq_offset
);
5376 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
|
5377 ctx
->default_tcg_memop_mask
);
5378 gen_base_offset_addr(ctx
, t0
, rs
, lsq_offset
+ 8);
5379 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
|
5380 ctx
->default_tcg_memop_mask
);
5381 gen_store_gpr(t1
, rt
);
5382 gen_store_gpr(t0
, lsq_rt1
);
5386 check_cp1_enabled(ctx
);
5387 t1
= tcg_temp_new();
5388 gen_base_offset_addr(ctx
, t0
, rs
, lsq_offset
);
5389 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
|
5390 ctx
->default_tcg_memop_mask
);
5391 gen_base_offset_addr(ctx
, t0
, rs
, lsq_offset
+ 8);
5392 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
|
5393 ctx
->default_tcg_memop_mask
);
5394 gen_store_fpr64(ctx
, t1
, rt
);
5395 gen_store_fpr64(ctx
, t0
, lsq_rt1
);
5399 t1
= tcg_temp_new();
5400 gen_base_offset_addr(ctx
, t0
, rs
, lsq_offset
);
5401 gen_load_gpr(t1
, rt
);
5402 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
|
5403 ctx
->default_tcg_memop_mask
);
5404 gen_base_offset_addr(ctx
, t0
, rs
, lsq_offset
+ 8);
5405 gen_load_gpr(t1
, lsq_rt1
);
5406 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
|
5407 ctx
->default_tcg_memop_mask
);
5411 check_cp1_enabled(ctx
);
5412 t1
= tcg_temp_new();
5413 gen_base_offset_addr(ctx
, t0
, rs
, lsq_offset
);
5414 gen_load_fpr64(ctx
, t1
, rt
);
5415 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
|
5416 ctx
->default_tcg_memop_mask
);
5417 gen_base_offset_addr(ctx
, t0
, rs
, lsq_offset
+ 8);
5418 gen_load_fpr64(ctx
, t1
, lsq_rt1
);
5419 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
|
5420 ctx
->default_tcg_memop_mask
);
5425 switch (MASK_LOONGSON_GSSHFLS(ctx
->opcode
)) {
5427 check_cp1_enabled(ctx
);
5428 gen_base_offset_addr(ctx
, t0
, rs
, shf_offset
);
5429 t1
= tcg_temp_new();
5430 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
5431 tcg_gen_andi_tl(t1
, t0
, 3);
5432 #ifndef TARGET_WORDS_BIGENDIAN
5433 tcg_gen_xori_tl(t1
, t1
, 3);
5435 tcg_gen_shli_tl(t1
, t1
, 3);
5436 tcg_gen_andi_tl(t0
, t0
, ~3);
5437 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEUL
);
5438 tcg_gen_shl_tl(t0
, t0
, t1
);
5439 t2
= tcg_const_tl(-1);
5440 tcg_gen_shl_tl(t2
, t2
, t1
);
5441 fp0
= tcg_temp_new_i32();
5442 gen_load_fpr32(ctx
, fp0
, rt
);
5443 tcg_gen_ext_i32_tl(t1
, fp0
);
5444 tcg_gen_andc_tl(t1
, t1
, t2
);
5446 tcg_gen_or_tl(t0
, t0
, t1
);
5448 #if defined(TARGET_MIPS64)
5449 tcg_gen_extrl_i64_i32(fp0
, t0
);
5451 tcg_gen_ext32s_tl(fp0
, t0
);
5453 gen_store_fpr32(ctx
, fp0
, rt
);
5454 tcg_temp_free_i32(fp0
);
5457 check_cp1_enabled(ctx
);
5458 gen_base_offset_addr(ctx
, t0
, rs
, shf_offset
);
5459 t1
= tcg_temp_new();
5460 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
5461 tcg_gen_andi_tl(t1
, t0
, 3);
5462 #ifdef TARGET_WORDS_BIGENDIAN
5463 tcg_gen_xori_tl(t1
, t1
, 3);
5465 tcg_gen_shli_tl(t1
, t1
, 3);
5466 tcg_gen_andi_tl(t0
, t0
, ~3);
5467 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEUL
);
5468 tcg_gen_shr_tl(t0
, t0
, t1
);
5469 tcg_gen_xori_tl(t1
, t1
, 31);
5470 t2
= tcg_const_tl(0xfffffffeull
);
5471 tcg_gen_shl_tl(t2
, t2
, t1
);
5472 fp0
= tcg_temp_new_i32();
5473 gen_load_fpr32(ctx
, fp0
, rt
);
5474 tcg_gen_ext_i32_tl(t1
, fp0
);
5475 tcg_gen_and_tl(t1
, t1
, t2
);
5477 tcg_gen_or_tl(t0
, t0
, t1
);
5479 #if defined(TARGET_MIPS64)
5480 tcg_gen_extrl_i64_i32(fp0
, t0
);
5482 tcg_gen_ext32s_tl(fp0
, t0
);
5484 gen_store_fpr32(ctx
, fp0
, rt
);
5485 tcg_temp_free_i32(fp0
);
5487 #if defined(TARGET_MIPS64)
5489 check_cp1_enabled(ctx
);
5490 gen_base_offset_addr(ctx
, t0
, rs
, shf_offset
);
5491 t1
= tcg_temp_new();
5492 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
5493 tcg_gen_andi_tl(t1
, t0
, 7);
5494 #ifndef TARGET_WORDS_BIGENDIAN
5495 tcg_gen_xori_tl(t1
, t1
, 7);
5497 tcg_gen_shli_tl(t1
, t1
, 3);
5498 tcg_gen_andi_tl(t0
, t0
, ~7);
5499 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
);
5500 tcg_gen_shl_tl(t0
, t0
, t1
);
5501 t2
= tcg_const_tl(-1);
5502 tcg_gen_shl_tl(t2
, t2
, t1
);
5503 gen_load_fpr64(ctx
, t1
, rt
);
5504 tcg_gen_andc_tl(t1
, t1
, t2
);
5506 tcg_gen_or_tl(t0
, t0
, t1
);
5508 gen_store_fpr64(ctx
, t0
, rt
);
5511 check_cp1_enabled(ctx
);
5512 gen_base_offset_addr(ctx
, t0
, rs
, shf_offset
);
5513 t1
= tcg_temp_new();
5514 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
5515 tcg_gen_andi_tl(t1
, t0
, 7);
5516 #ifdef TARGET_WORDS_BIGENDIAN
5517 tcg_gen_xori_tl(t1
, t1
, 7);
5519 tcg_gen_shli_tl(t1
, t1
, 3);
5520 tcg_gen_andi_tl(t0
, t0
, ~7);
5521 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
);
5522 tcg_gen_shr_tl(t0
, t0
, t1
);
5523 tcg_gen_xori_tl(t1
, t1
, 63);
5524 t2
= tcg_const_tl(0xfffffffffffffffeull
);
5525 tcg_gen_shl_tl(t2
, t2
, t1
);
5526 gen_load_fpr64(ctx
, t1
, rt
);
5527 tcg_gen_and_tl(t1
, t1
, t2
);
5529 tcg_gen_or_tl(t0
, t0
, t1
);
5531 gen_store_fpr64(ctx
, t0
, rt
);
5535 MIPS_INVAL("loongson_gsshfl");
5536 gen_reserved_instruction(ctx
);
5541 switch (MASK_LOONGSON_GSSHFLS(ctx
->opcode
)) {
5543 check_cp1_enabled(ctx
);
5544 t1
= tcg_temp_new();
5545 gen_base_offset_addr(ctx
, t0
, rs
, shf_offset
);
5546 fp0
= tcg_temp_new_i32();
5547 gen_load_fpr32(ctx
, fp0
, rt
);
5548 tcg_gen_ext_i32_tl(t1
, fp0
);
5549 gen_helper_0e2i(swl
, t1
, t0
, ctx
->mem_idx
);
5550 tcg_temp_free_i32(fp0
);
5554 check_cp1_enabled(ctx
);
5555 t1
= tcg_temp_new();
5556 gen_base_offset_addr(ctx
, t0
, rs
, shf_offset
);
5557 fp0
= tcg_temp_new_i32();
5558 gen_load_fpr32(ctx
, fp0
, rt
);
5559 tcg_gen_ext_i32_tl(t1
, fp0
);
5560 gen_helper_0e2i(swr
, t1
, t0
, ctx
->mem_idx
);
5561 tcg_temp_free_i32(fp0
);
5564 #if defined(TARGET_MIPS64)
5566 check_cp1_enabled(ctx
);
5567 t1
= tcg_temp_new();
5568 gen_base_offset_addr(ctx
, t0
, rs
, shf_offset
);
5569 gen_load_fpr64(ctx
, t1
, rt
);
5570 gen_helper_0e2i(sdl
, t1
, t0
, ctx
->mem_idx
);
5574 check_cp1_enabled(ctx
);
5575 t1
= tcg_temp_new();
5576 gen_base_offset_addr(ctx
, t0
, rs
, shf_offset
);
5577 gen_load_fpr64(ctx
, t1
, rt
);
5578 gen_helper_0e2i(sdr
, t1
, t0
, ctx
->mem_idx
);
5583 MIPS_INVAL("loongson_gsshfs");
5584 gen_reserved_instruction(ctx
);
5589 MIPS_INVAL("loongson_gslsq");
5590 gen_reserved_instruction(ctx
);
5596 /* Loongson EXT LDC2/SDC2 */
5597 static void gen_loongson_lsdc2(DisasContext
*ctx
, int rt
,
5600 int offset
= sextract32(ctx
->opcode
, 3, 8);
5601 uint32_t opc
= MASK_LOONGSON_LSDC2(ctx
->opcode
);
5605 /* Pre-conditions */
5611 /* prefetch, implement as NOP */
5622 #if defined(TARGET_MIPS64)
5625 check_cp1_enabled(ctx
);
5626 /* prefetch, implement as NOP */
5632 #if defined(TARGET_MIPS64)
5635 check_cp1_enabled(ctx
);
5638 MIPS_INVAL("loongson_lsdc2");
5639 gen_reserved_instruction(ctx
);
5644 t0
= tcg_temp_new();
5646 gen_base_offset_addr(ctx
, t0
, rs
, offset
);
5647 gen_op_addr_add(ctx
, t0
, cpu_gpr
[rd
], t0
);
5651 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_SB
);
5652 gen_store_gpr(t0
, rt
);
5655 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESW
|
5656 ctx
->default_tcg_memop_mask
);
5657 gen_store_gpr(t0
, rt
);
5660 gen_base_offset_addr(ctx
, t0
, rs
, offset
);
5662 gen_op_addr_add(ctx
, t0
, cpu_gpr
[rd
], t0
);
5664 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESL
|
5665 ctx
->default_tcg_memop_mask
);
5666 gen_store_gpr(t0
, rt
);
5668 #if defined(TARGET_MIPS64)
5670 gen_base_offset_addr(ctx
, t0
, rs
, offset
);
5672 gen_op_addr_add(ctx
, t0
, cpu_gpr
[rd
], t0
);
5674 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
|
5675 ctx
->default_tcg_memop_mask
);
5676 gen_store_gpr(t0
, rt
);
5680 check_cp1_enabled(ctx
);
5681 gen_base_offset_addr(ctx
, t0
, rs
, offset
);
5683 gen_op_addr_add(ctx
, t0
, cpu_gpr
[rd
], t0
);
5685 fp0
= tcg_temp_new_i32();
5686 tcg_gen_qemu_ld_i32(fp0
, t0
, ctx
->mem_idx
, MO_TESL
|
5687 ctx
->default_tcg_memop_mask
);
5688 gen_store_fpr32(ctx
, fp0
, rt
);
5689 tcg_temp_free_i32(fp0
);
5691 #if defined(TARGET_MIPS64)
5693 check_cp1_enabled(ctx
);
5694 gen_base_offset_addr(ctx
, t0
, rs
, offset
);
5696 gen_op_addr_add(ctx
, t0
, cpu_gpr
[rd
], t0
);
5698 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
|
5699 ctx
->default_tcg_memop_mask
);
5700 gen_store_fpr64(ctx
, t0
, rt
);
5704 t1
= tcg_temp_new();
5705 gen_load_gpr(t1
, rt
);
5706 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_SB
);
5710 t1
= tcg_temp_new();
5711 gen_load_gpr(t1
, rt
);
5712 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUW
|
5713 ctx
->default_tcg_memop_mask
);
5717 t1
= tcg_temp_new();
5718 gen_load_gpr(t1
, rt
);
5719 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
|
5720 ctx
->default_tcg_memop_mask
);
5723 #if defined(TARGET_MIPS64)
5725 t1
= tcg_temp_new();
5726 gen_load_gpr(t1
, rt
);
5727 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
|
5728 ctx
->default_tcg_memop_mask
);
5733 fp0
= tcg_temp_new_i32();
5734 gen_load_fpr32(ctx
, fp0
, rt
);
5735 tcg_gen_qemu_st_i32(fp0
, t0
, ctx
->mem_idx
, MO_TEUL
|
5736 ctx
->default_tcg_memop_mask
);
5737 tcg_temp_free_i32(fp0
);
5739 #if defined(TARGET_MIPS64)
5741 t1
= tcg_temp_new();
5742 gen_load_fpr64(ctx
, t1
, rt
);
5743 tcg_gen_qemu_st_i64(t1
, t0
, ctx
->mem_idx
, MO_TEQ
|
5744 ctx
->default_tcg_memop_mask
);
5756 static void gen_trap(DisasContext
*ctx
, uint32_t opc
,
5757 int rs
, int rt
, int16_t imm
)
5760 TCGv t0
= tcg_temp_new();
5761 TCGv t1
= tcg_temp_new();
5764 /* Load needed operands */
5772 /* Compare two registers */
5774 gen_load_gpr(t0
, rs
);
5775 gen_load_gpr(t1
, rt
);
5785 /* Compare register to immediate */
5786 if (rs
!= 0 || imm
!= 0) {
5787 gen_load_gpr(t0
, rs
);
5788 tcg_gen_movi_tl(t1
, (int32_t)imm
);
5795 case OPC_TEQ
: /* rs == rs */
5796 case OPC_TEQI
: /* r0 == 0 */
5797 case OPC_TGE
: /* rs >= rs */
5798 case OPC_TGEI
: /* r0 >= 0 */
5799 case OPC_TGEU
: /* rs >= rs unsigned */
5800 case OPC_TGEIU
: /* r0 >= 0 unsigned */
5802 generate_exception_end(ctx
, EXCP_TRAP
);
5804 case OPC_TLT
: /* rs < rs */
5805 case OPC_TLTI
: /* r0 < 0 */
5806 case OPC_TLTU
: /* rs < rs unsigned */
5807 case OPC_TLTIU
: /* r0 < 0 unsigned */
5808 case OPC_TNE
: /* rs != rs */
5809 case OPC_TNEI
: /* r0 != 0 */
5810 /* Never trap: treat as NOP. */
5814 TCGLabel
*l1
= gen_new_label();
5819 tcg_gen_brcond_tl(TCG_COND_NE
, t0
, t1
, l1
);
5823 tcg_gen_brcond_tl(TCG_COND_LT
, t0
, t1
, l1
);
5827 tcg_gen_brcond_tl(TCG_COND_LTU
, t0
, t1
, l1
);
5831 tcg_gen_brcond_tl(TCG_COND_GE
, t0
, t1
, l1
);
5835 tcg_gen_brcond_tl(TCG_COND_GEU
, t0
, t1
, l1
);
5839 tcg_gen_brcond_tl(TCG_COND_EQ
, t0
, t1
, l1
);
5842 generate_exception(ctx
, EXCP_TRAP
);
5849 static inline bool use_goto_tb(DisasContext
*ctx
, target_ulong dest
)
5851 if (unlikely(ctx
->base
.singlestep_enabled
)) {
5855 #ifndef CONFIG_USER_ONLY
5856 return (ctx
->base
.tb
->pc
& TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
);
5862 static inline void gen_goto_tb(DisasContext
*ctx
, int n
, target_ulong dest
)
5864 if (use_goto_tb(ctx
, dest
)) {
5867 tcg_gen_exit_tb(ctx
->base
.tb
, n
);
5870 if (ctx
->base
.singlestep_enabled
) {
5871 save_cpu_state(ctx
, 0);
5872 gen_helper_raise_exception_debug(cpu_env
);
5874 tcg_gen_lookup_and_goto_ptr();
5878 /* Branches (before delay slot) */
5879 static void gen_compute_branch(DisasContext
*ctx
, uint32_t opc
,
5881 int rs
, int rt
, int32_t offset
,
5884 target_ulong btgt
= -1;
5886 int bcond_compute
= 0;
5887 TCGv t0
= tcg_temp_new();
5888 TCGv t1
= tcg_temp_new();
5890 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
5891 #ifdef MIPS_DEBUG_DISAS
5892 LOG_DISAS("Branch in delay / forbidden slot at PC 0x"
5893 TARGET_FMT_lx
"\n", ctx
->base
.pc_next
);
5895 gen_reserved_instruction(ctx
);
5899 /* Load needed operands */
5905 /* Compare two registers */
5907 gen_load_gpr(t0
, rs
);
5908 gen_load_gpr(t1
, rt
);
5911 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ offset
;
5925 /* Compare to zero */
5927 gen_load_gpr(t0
, rs
);
5930 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ offset
;
5933 #if defined(TARGET_MIPS64)
5935 tcg_gen_andi_tl(t0
, cpu_dspctrl
, 0x7F);
5937 tcg_gen_andi_tl(t0
, cpu_dspctrl
, 0x3F);
5940 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ offset
;
5945 /* Jump to immediate */
5946 btgt
= ((ctx
->base
.pc_next
+ insn_bytes
) & (int32_t)0xF0000000) |
5951 /* Jump to register */
5952 if (offset
!= 0 && offset
!= 16) {
5954 * Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
5955 * others are reserved.
5957 MIPS_INVAL("jump hint");
5958 gen_reserved_instruction(ctx
);
5961 gen_load_gpr(btarget
, rs
);
5964 MIPS_INVAL("branch/jump");
5965 gen_reserved_instruction(ctx
);
5968 if (bcond_compute
== 0) {
5969 /* No condition to be computed */
5971 case OPC_BEQ
: /* rx == rx */
5972 case OPC_BEQL
: /* rx == rx likely */
5973 case OPC_BGEZ
: /* 0 >= 0 */
5974 case OPC_BGEZL
: /* 0 >= 0 likely */
5975 case OPC_BLEZ
: /* 0 <= 0 */
5976 case OPC_BLEZL
: /* 0 <= 0 likely */
5978 ctx
->hflags
|= MIPS_HFLAG_B
;
5980 case OPC_BGEZAL
: /* 0 >= 0 */
5981 case OPC_BGEZALL
: /* 0 >= 0 likely */
5982 /* Always take and link */
5984 ctx
->hflags
|= MIPS_HFLAG_B
;
5986 case OPC_BNE
: /* rx != rx */
5987 case OPC_BGTZ
: /* 0 > 0 */
5988 case OPC_BLTZ
: /* 0 < 0 */
5991 case OPC_BLTZAL
: /* 0 < 0 */
5993 * Handle as an unconditional branch to get correct delay
5997 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ delayslot_size
;
5998 ctx
->hflags
|= MIPS_HFLAG_B
;
6000 case OPC_BLTZALL
: /* 0 < 0 likely */
6001 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 8);
6002 /* Skip the instruction in the delay slot */
6003 ctx
->base
.pc_next
+= 4;
6005 case OPC_BNEL
: /* rx != rx likely */
6006 case OPC_BGTZL
: /* 0 > 0 likely */
6007 case OPC_BLTZL
: /* 0 < 0 likely */
6008 /* Skip the instruction in the delay slot */
6009 ctx
->base
.pc_next
+= 4;
6012 ctx
->hflags
|= MIPS_HFLAG_B
;
6015 ctx
->hflags
|= MIPS_HFLAG_BX
;
6019 ctx
->hflags
|= MIPS_HFLAG_B
;
6022 ctx
->hflags
|= MIPS_HFLAG_BR
;
6026 ctx
->hflags
|= MIPS_HFLAG_BR
;
6029 MIPS_INVAL("branch/jump");
6030 gen_reserved_instruction(ctx
);
6036 tcg_gen_setcond_tl(TCG_COND_EQ
, bcond
, t0
, t1
);
6039 tcg_gen_setcond_tl(TCG_COND_EQ
, bcond
, t0
, t1
);
6042 tcg_gen_setcond_tl(TCG_COND_NE
, bcond
, t0
, t1
);
6045 tcg_gen_setcond_tl(TCG_COND_NE
, bcond
, t0
, t1
);
6048 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
6051 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
6054 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
6058 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
6062 tcg_gen_setcondi_tl(TCG_COND_GT
, bcond
, t0
, 0);
6065 tcg_gen_setcondi_tl(TCG_COND_GT
, bcond
, t0
, 0);
6068 tcg_gen_setcondi_tl(TCG_COND_LE
, bcond
, t0
, 0);
6071 tcg_gen_setcondi_tl(TCG_COND_LE
, bcond
, t0
, 0);
6074 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
6077 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
6080 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 32);
6082 #if defined(TARGET_MIPS64)
6084 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 64);
6088 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
6091 ctx
->hflags
|= MIPS_HFLAG_BC
;
6094 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
6097 ctx
->hflags
|= MIPS_HFLAG_BL
;
6100 MIPS_INVAL("conditional branch/jump");
6101 gen_reserved_instruction(ctx
);
6106 ctx
->btarget
= btgt
;
6108 switch (delayslot_size
) {
6110 ctx
->hflags
|= MIPS_HFLAG_BDS16
;
6113 ctx
->hflags
|= MIPS_HFLAG_BDS32
;
6118 int post_delay
= insn_bytes
+ delayslot_size
;
6119 int lowbit
= !!(ctx
->hflags
& MIPS_HFLAG_M16
);
6121 tcg_gen_movi_tl(cpu_gpr
[blink
],
6122 ctx
->base
.pc_next
+ post_delay
+ lowbit
);
6126 if (insn_bytes
== 2) {
6127 ctx
->hflags
|= MIPS_HFLAG_B16
;
6134 /* nanoMIPS Branches */
6135 static void gen_compute_branch_nm(DisasContext
*ctx
, uint32_t opc
,
6137 int rs
, int rt
, int32_t offset
)
6139 target_ulong btgt
= -1;
6140 int bcond_compute
= 0;
6141 TCGv t0
= tcg_temp_new();
6142 TCGv t1
= tcg_temp_new();
6144 /* Load needed operands */
6148 /* Compare two registers */
6150 gen_load_gpr(t0
, rs
);
6151 gen_load_gpr(t1
, rt
);
6154 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ offset
;
6157 /* Compare to zero */
6159 gen_load_gpr(t0
, rs
);
6162 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ offset
;
6165 tcg_gen_andi_tl(t0
, cpu_dspctrl
, 0x3F);
6167 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ offset
;
6171 /* Jump to register */
6172 if (offset
!= 0 && offset
!= 16) {
6174 * Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
6175 * others are reserved.
6177 MIPS_INVAL("jump hint");
6178 gen_reserved_instruction(ctx
);
6181 gen_load_gpr(btarget
, rs
);
6184 MIPS_INVAL("branch/jump");
6185 gen_reserved_instruction(ctx
);
6188 if (bcond_compute
== 0) {
6189 /* No condition to be computed */
6191 case OPC_BEQ
: /* rx == rx */
6193 ctx
->hflags
|= MIPS_HFLAG_B
;
6195 case OPC_BGEZAL
: /* 0 >= 0 */
6196 /* Always take and link */
6197 tcg_gen_movi_tl(cpu_gpr
[31],
6198 ctx
->base
.pc_next
+ insn_bytes
);
6199 ctx
->hflags
|= MIPS_HFLAG_B
;
6201 case OPC_BNE
: /* rx != rx */
6202 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 8);
6203 /* Skip the instruction in the delay slot */
6204 ctx
->base
.pc_next
+= 4;
6207 ctx
->hflags
|= MIPS_HFLAG_BR
;
6211 tcg_gen_movi_tl(cpu_gpr
[rt
],
6212 ctx
->base
.pc_next
+ insn_bytes
);
6214 ctx
->hflags
|= MIPS_HFLAG_BR
;
6217 MIPS_INVAL("branch/jump");
6218 gen_reserved_instruction(ctx
);
6224 tcg_gen_setcond_tl(TCG_COND_EQ
, bcond
, t0
, t1
);
6227 tcg_gen_setcond_tl(TCG_COND_NE
, bcond
, t0
, t1
);
6230 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
6231 tcg_gen_movi_tl(cpu_gpr
[31],
6232 ctx
->base
.pc_next
+ insn_bytes
);
6235 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 32);
6237 ctx
->hflags
|= MIPS_HFLAG_BC
;
6240 MIPS_INVAL("conditional branch/jump");
6241 gen_reserved_instruction(ctx
);
6246 ctx
->btarget
= btgt
;
6249 if (insn_bytes
== 2) {
6250 ctx
->hflags
|= MIPS_HFLAG_B16
;
6257 /* special3 bitfield operations */
6258 static void gen_bitops(DisasContext
*ctx
, uint32_t opc
, int rt
,
6259 int rs
, int lsb
, int msb
)
6261 TCGv t0
= tcg_temp_new();
6262 TCGv t1
= tcg_temp_new();
6264 gen_load_gpr(t1
, rs
);
6267 if (lsb
+ msb
> 31) {
6271 tcg_gen_extract_tl(t0
, t1
, lsb
, msb
+ 1);
6274 * The two checks together imply that lsb == 0,
6275 * so this is a simple sign-extension.
6277 tcg_gen_ext32s_tl(t0
, t1
);
6280 #if defined(TARGET_MIPS64)
6289 if (lsb
+ msb
> 63) {
6292 tcg_gen_extract_tl(t0
, t1
, lsb
, msb
+ 1);
6299 gen_load_gpr(t0
, rt
);
6300 tcg_gen_deposit_tl(t0
, t0
, t1
, lsb
, msb
- lsb
+ 1);
6301 tcg_gen_ext32s_tl(t0
, t0
);
6303 #if defined(TARGET_MIPS64)
6314 gen_load_gpr(t0
, rt
);
6315 tcg_gen_deposit_tl(t0
, t0
, t1
, lsb
, msb
- lsb
+ 1);
6320 MIPS_INVAL("bitops");
6321 gen_reserved_instruction(ctx
);
6326 gen_store_gpr(t0
, rt
);
6331 static void gen_bshfl(DisasContext
*ctx
, uint32_t op2
, int rt
, int rd
)
6336 /* If no destination, treat it as a NOP. */
6340 t0
= tcg_temp_new();
6341 gen_load_gpr(t0
, rt
);
6345 TCGv t1
= tcg_temp_new();
6346 TCGv t2
= tcg_const_tl(0x00FF00FF);
6348 tcg_gen_shri_tl(t1
, t0
, 8);
6349 tcg_gen_and_tl(t1
, t1
, t2
);
6350 tcg_gen_and_tl(t0
, t0
, t2
);
6351 tcg_gen_shli_tl(t0
, t0
, 8);
6352 tcg_gen_or_tl(t0
, t0
, t1
);
6355 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
6359 tcg_gen_ext8s_tl(cpu_gpr
[rd
], t0
);
6362 tcg_gen_ext16s_tl(cpu_gpr
[rd
], t0
);
6364 #if defined(TARGET_MIPS64)
6367 TCGv t1
= tcg_temp_new();
6368 TCGv t2
= tcg_const_tl(0x00FF00FF00FF00FFULL
);
6370 tcg_gen_shri_tl(t1
, t0
, 8);
6371 tcg_gen_and_tl(t1
, t1
, t2
);
6372 tcg_gen_and_tl(t0
, t0
, t2
);
6373 tcg_gen_shli_tl(t0
, t0
, 8);
6374 tcg_gen_or_tl(cpu_gpr
[rd
], t0
, t1
);
6381 TCGv t1
= tcg_temp_new();
6382 TCGv t2
= tcg_const_tl(0x0000FFFF0000FFFFULL
);
6384 tcg_gen_shri_tl(t1
, t0
, 16);
6385 tcg_gen_and_tl(t1
, t1
, t2
);
6386 tcg_gen_and_tl(t0
, t0
, t2
);
6387 tcg_gen_shli_tl(t0
, t0
, 16);
6388 tcg_gen_or_tl(t0
, t0
, t1
);
6389 tcg_gen_shri_tl(t1
, t0
, 32);
6390 tcg_gen_shli_tl(t0
, t0
, 32);
6391 tcg_gen_or_tl(cpu_gpr
[rd
], t0
, t1
);
6398 MIPS_INVAL("bsfhl");
6399 gen_reserved_instruction(ctx
);
6406 static void gen_align_bits(DisasContext
*ctx
, int wordsz
, int rd
, int rs
,
6414 t0
= tcg_temp_new();
6415 if (bits
== 0 || bits
== wordsz
) {
6417 gen_load_gpr(t0
, rt
);
6419 gen_load_gpr(t0
, rs
);
6423 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
6425 #if defined(TARGET_MIPS64)
6427 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
6432 TCGv t1
= tcg_temp_new();
6433 gen_load_gpr(t0
, rt
);
6434 gen_load_gpr(t1
, rs
);
6438 TCGv_i64 t2
= tcg_temp_new_i64();
6439 tcg_gen_concat_tl_i64(t2
, t1
, t0
);
6440 tcg_gen_shri_i64(t2
, t2
, 32 - bits
);
6441 gen_move_low32(cpu_gpr
[rd
], t2
);
6442 tcg_temp_free_i64(t2
);
6445 #if defined(TARGET_MIPS64)
6447 tcg_gen_shli_tl(t0
, t0
, bits
);
6448 tcg_gen_shri_tl(t1
, t1
, 64 - bits
);
6449 tcg_gen_or_tl(cpu_gpr
[rd
], t1
, t0
);
6459 static void gen_align(DisasContext
*ctx
, int wordsz
, int rd
, int rs
, int rt
,
6462 gen_align_bits(ctx
, wordsz
, rd
, rs
, rt
, bp
* 8);
6465 static void gen_ext(DisasContext
*ctx
, int wordsz
, int rd
, int rs
, int rt
,
6468 gen_align_bits(ctx
, wordsz
, rd
, rs
, rt
, wordsz
- shift
);
6471 static void gen_bitswap(DisasContext
*ctx
, int opc
, int rd
, int rt
)
6478 t0
= tcg_temp_new();
6479 gen_load_gpr(t0
, rt
);
6482 gen_helper_bitswap(cpu_gpr
[rd
], t0
);
6484 #if defined(TARGET_MIPS64)
6486 gen_helper_dbitswap(cpu_gpr
[rd
], t0
);
6493 #ifndef CONFIG_USER_ONLY
6494 /* CP0 (MMU and control) */
6495 static inline void gen_mthc0_entrylo(TCGv arg
, target_ulong off
)
6497 TCGv_i64 t0
= tcg_temp_new_i64();
6498 TCGv_i64 t1
= tcg_temp_new_i64();
6500 tcg_gen_ext_tl_i64(t0
, arg
);
6501 tcg_gen_ld_i64(t1
, cpu_env
, off
);
6502 #if defined(TARGET_MIPS64)
6503 tcg_gen_deposit_i64(t1
, t1
, t0
, 30, 32);
6505 tcg_gen_concat32_i64(t1
, t1
, t0
);
6507 tcg_gen_st_i64(t1
, cpu_env
, off
);
6508 tcg_temp_free_i64(t1
);
6509 tcg_temp_free_i64(t0
);
6512 static inline void gen_mthc0_store64(TCGv arg
, target_ulong off
)
6514 TCGv_i64 t0
= tcg_temp_new_i64();
6515 TCGv_i64 t1
= tcg_temp_new_i64();
6517 tcg_gen_ext_tl_i64(t0
, arg
);
6518 tcg_gen_ld_i64(t1
, cpu_env
, off
);
6519 tcg_gen_concat32_i64(t1
, t1
, t0
);
6520 tcg_gen_st_i64(t1
, cpu_env
, off
);
6521 tcg_temp_free_i64(t1
);
6522 tcg_temp_free_i64(t0
);
6525 static inline void gen_mfhc0_entrylo(TCGv arg
, target_ulong off
)
6527 TCGv_i64 t0
= tcg_temp_new_i64();
6529 tcg_gen_ld_i64(t0
, cpu_env
, off
);
6530 #if defined(TARGET_MIPS64)
6531 tcg_gen_shri_i64(t0
, t0
, 30);
6533 tcg_gen_shri_i64(t0
, t0
, 32);
6535 gen_move_low32(arg
, t0
);
6536 tcg_temp_free_i64(t0
);
6539 static inline void gen_mfhc0_load64(TCGv arg
, target_ulong off
, int shift
)
6541 TCGv_i64 t0
= tcg_temp_new_i64();
6543 tcg_gen_ld_i64(t0
, cpu_env
, off
);
6544 tcg_gen_shri_i64(t0
, t0
, 32 + shift
);
6545 gen_move_low32(arg
, t0
);
6546 tcg_temp_free_i64(t0
);
6549 static inline void gen_mfc0_load32(TCGv arg
, target_ulong off
)
6551 TCGv_i32 t0
= tcg_temp_new_i32();
6553 tcg_gen_ld_i32(t0
, cpu_env
, off
);
6554 tcg_gen_ext_i32_tl(arg
, t0
);
6555 tcg_temp_free_i32(t0
);
6558 static inline void gen_mfc0_load64(TCGv arg
, target_ulong off
)
6560 tcg_gen_ld_tl(arg
, cpu_env
, off
);
6561 tcg_gen_ext32s_tl(arg
, arg
);
6564 static inline void gen_mtc0_store32(TCGv arg
, target_ulong off
)
6566 TCGv_i32 t0
= tcg_temp_new_i32();
6568 tcg_gen_trunc_tl_i32(t0
, arg
);
6569 tcg_gen_st_i32(t0
, cpu_env
, off
);
6570 tcg_temp_free_i32(t0
);
6573 #define CP0_CHECK(c) \
6576 goto cp0_unimplemented; \
6580 static void gen_mfhc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
6582 const char *register_name
= "invalid";
6585 case CP0_REGISTER_02
:
6588 CP0_CHECK(ctx
->hflags
& MIPS_HFLAG_ELPA
);
6589 gen_mfhc0_entrylo(arg
, offsetof(CPUMIPSState
, CP0_EntryLo0
));
6590 register_name
= "EntryLo0";
6593 goto cp0_unimplemented
;
6596 case CP0_REGISTER_03
:
6598 case CP0_REG03__ENTRYLO1
:
6599 CP0_CHECK(ctx
->hflags
& MIPS_HFLAG_ELPA
);
6600 gen_mfhc0_entrylo(arg
, offsetof(CPUMIPSState
, CP0_EntryLo1
));
6601 register_name
= "EntryLo1";
6604 goto cp0_unimplemented
;
6607 case CP0_REGISTER_09
:
6609 case CP0_REG09__SAAR
:
6610 CP0_CHECK(ctx
->saar
);
6611 gen_helper_mfhc0_saar(arg
, cpu_env
);
6612 register_name
= "SAAR";
6615 goto cp0_unimplemented
;
6618 case CP0_REGISTER_17
:
6620 case CP0_REG17__LLADDR
:
6621 gen_mfhc0_load64(arg
, offsetof(CPUMIPSState
, CP0_LLAddr
),
6622 ctx
->CP0_LLAddr_shift
);
6623 register_name
= "LLAddr";
6625 case CP0_REG17__MAAR
:
6626 CP0_CHECK(ctx
->mrp
);
6627 gen_helper_mfhc0_maar(arg
, cpu_env
);
6628 register_name
= "MAAR";
6631 goto cp0_unimplemented
;
6634 case CP0_REGISTER_19
:
6636 case CP0_REG19__WATCHHI0
:
6637 case CP0_REG19__WATCHHI1
:
6638 case CP0_REG19__WATCHHI2
:
6639 case CP0_REG19__WATCHHI3
:
6640 case CP0_REG19__WATCHHI4
:
6641 case CP0_REG19__WATCHHI5
:
6642 case CP0_REG19__WATCHHI6
:
6643 case CP0_REG19__WATCHHI7
:
6644 /* upper 32 bits are only available when Config5MI != 0 */
6646 gen_mfhc0_load64(arg
, offsetof(CPUMIPSState
, CP0_WatchHi
[sel
]), 0);
6647 register_name
= "WatchHi";
6650 goto cp0_unimplemented
;
6653 case CP0_REGISTER_28
:
6659 gen_mfhc0_load64(arg
, offsetof(CPUMIPSState
, CP0_TagLo
), 0);
6660 register_name
= "TagLo";
6663 goto cp0_unimplemented
;
6667 goto cp0_unimplemented
;
6669 trace_mips_translate_c0("mfhc0", register_name
, reg
, sel
);
6673 qemu_log_mask(LOG_UNIMP
, "mfhc0 %s (reg %d sel %d)\n",
6674 register_name
, reg
, sel
);
6675 tcg_gen_movi_tl(arg
, 0);
6678 static void gen_mthc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
6680 const char *register_name
= "invalid";
6681 uint64_t mask
= ctx
->PAMask
>> 36;
6684 case CP0_REGISTER_02
:
6687 CP0_CHECK(ctx
->hflags
& MIPS_HFLAG_ELPA
);
6688 tcg_gen_andi_tl(arg
, arg
, mask
);
6689 gen_mthc0_entrylo(arg
, offsetof(CPUMIPSState
, CP0_EntryLo0
));
6690 register_name
= "EntryLo0";
6693 goto cp0_unimplemented
;
6696 case CP0_REGISTER_03
:
6698 case CP0_REG03__ENTRYLO1
:
6699 CP0_CHECK(ctx
->hflags
& MIPS_HFLAG_ELPA
);
6700 tcg_gen_andi_tl(arg
, arg
, mask
);
6701 gen_mthc0_entrylo(arg
, offsetof(CPUMIPSState
, CP0_EntryLo1
));
6702 register_name
= "EntryLo1";
6705 goto cp0_unimplemented
;
6708 case CP0_REGISTER_09
:
6710 case CP0_REG09__SAAR
:
6711 CP0_CHECK(ctx
->saar
);
6712 gen_helper_mthc0_saar(cpu_env
, arg
);
6713 register_name
= "SAAR";
6716 goto cp0_unimplemented
;
6719 case CP0_REGISTER_17
:
6721 case CP0_REG17__LLADDR
:
6723 * LLAddr is read-only (the only exception is bit 0 if LLB is
6724 * supported); the CP0_LLAddr_rw_bitmask does not seem to be
6725 * relevant for modern MIPS cores supporting MTHC0, therefore
6726 * treating MTHC0 to LLAddr as NOP.
6728 register_name
= "LLAddr";
6730 case CP0_REG17__MAAR
:
6731 CP0_CHECK(ctx
->mrp
);
6732 gen_helper_mthc0_maar(cpu_env
, arg
);
6733 register_name
= "MAAR";
6736 goto cp0_unimplemented
;
6739 case CP0_REGISTER_19
:
6741 case CP0_REG19__WATCHHI0
:
6742 case CP0_REG19__WATCHHI1
:
6743 case CP0_REG19__WATCHHI2
:
6744 case CP0_REG19__WATCHHI3
:
6745 case CP0_REG19__WATCHHI4
:
6746 case CP0_REG19__WATCHHI5
:
6747 case CP0_REG19__WATCHHI6
:
6748 case CP0_REG19__WATCHHI7
:
6749 /* upper 32 bits are only available when Config5MI != 0 */
6751 gen_helper_0e1i(mthc0_watchhi
, arg
, sel
);
6752 register_name
= "WatchHi";
6755 goto cp0_unimplemented
;
6758 case CP0_REGISTER_28
:
6764 tcg_gen_andi_tl(arg
, arg
, mask
);
6765 gen_mthc0_store64(arg
, offsetof(CPUMIPSState
, CP0_TagLo
));
6766 register_name
= "TagLo";
6769 goto cp0_unimplemented
;
6773 goto cp0_unimplemented
;
6775 trace_mips_translate_c0("mthc0", register_name
, reg
, sel
);
6778 qemu_log_mask(LOG_UNIMP
, "mthc0 %s (reg %d sel %d)\n",
6779 register_name
, reg
, sel
);
6782 static inline void gen_mfc0_unimplemented(DisasContext
*ctx
, TCGv arg
)
6784 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
6785 tcg_gen_movi_tl(arg
, 0);
6787 tcg_gen_movi_tl(arg
, ~0);
6791 static void gen_mfc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
6793 const char *register_name
= "invalid";
6796 check_insn(ctx
, ISA_MIPS_R1
);
6800 case CP0_REGISTER_00
:
6802 case CP0_REG00__INDEX
:
6803 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Index
));
6804 register_name
= "Index";
6806 case CP0_REG00__MVPCONTROL
:
6807 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6808 gen_helper_mfc0_mvpcontrol(arg
, cpu_env
);
6809 register_name
= "MVPControl";
6811 case CP0_REG00__MVPCONF0
:
6812 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6813 gen_helper_mfc0_mvpconf0(arg
, cpu_env
);
6814 register_name
= "MVPConf0";
6816 case CP0_REG00__MVPCONF1
:
6817 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6818 gen_helper_mfc0_mvpconf1(arg
, cpu_env
);
6819 register_name
= "MVPConf1";
6821 case CP0_REG00__VPCONTROL
:
6823 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPControl
));
6824 register_name
= "VPControl";
6827 goto cp0_unimplemented
;
6830 case CP0_REGISTER_01
:
6832 case CP0_REG01__RANDOM
:
6833 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS_R6
));
6834 gen_helper_mfc0_random(arg
, cpu_env
);
6835 register_name
= "Random";
6837 case CP0_REG01__VPECONTROL
:
6838 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6839 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEControl
));
6840 register_name
= "VPEControl";
6842 case CP0_REG01__VPECONF0
:
6843 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6844 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf0
));
6845 register_name
= "VPEConf0";
6847 case CP0_REG01__VPECONF1
:
6848 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6849 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf1
));
6850 register_name
= "VPEConf1";
6852 case CP0_REG01__YQMASK
:
6853 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6854 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_YQMask
));
6855 register_name
= "YQMask";
6857 case CP0_REG01__VPESCHEDULE
:
6858 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6859 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_VPESchedule
));
6860 register_name
= "VPESchedule";
6862 case CP0_REG01__VPESCHEFBACK
:
6863 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6864 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
6865 register_name
= "VPEScheFBack";
6867 case CP0_REG01__VPEOPT
:
6868 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6869 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEOpt
));
6870 register_name
= "VPEOpt";
6873 goto cp0_unimplemented
;
6876 case CP0_REGISTER_02
:
6878 case CP0_REG02__ENTRYLO0
:
6880 TCGv_i64 tmp
= tcg_temp_new_i64();
6881 tcg_gen_ld_i64(tmp
, cpu_env
,
6882 offsetof(CPUMIPSState
, CP0_EntryLo0
));
6883 #if defined(TARGET_MIPS64)
6885 /* Move RI/XI fields to bits 31:30 */
6886 tcg_gen_shri_tl(arg
, tmp
, CP0EnLo_XI
);
6887 tcg_gen_deposit_tl(tmp
, tmp
, arg
, 30, 2);
6890 gen_move_low32(arg
, tmp
);
6891 tcg_temp_free_i64(tmp
);
6893 register_name
= "EntryLo0";
6895 case CP0_REG02__TCSTATUS
:
6896 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6897 gen_helper_mfc0_tcstatus(arg
, cpu_env
);
6898 register_name
= "TCStatus";
6900 case CP0_REG02__TCBIND
:
6901 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6902 gen_helper_mfc0_tcbind(arg
, cpu_env
);
6903 register_name
= "TCBind";
6905 case CP0_REG02__TCRESTART
:
6906 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6907 gen_helper_mfc0_tcrestart(arg
, cpu_env
);
6908 register_name
= "TCRestart";
6910 case CP0_REG02__TCHALT
:
6911 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6912 gen_helper_mfc0_tchalt(arg
, cpu_env
);
6913 register_name
= "TCHalt";
6915 case CP0_REG02__TCCONTEXT
:
6916 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6917 gen_helper_mfc0_tccontext(arg
, cpu_env
);
6918 register_name
= "TCContext";
6920 case CP0_REG02__TCSCHEDULE
:
6921 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6922 gen_helper_mfc0_tcschedule(arg
, cpu_env
);
6923 register_name
= "TCSchedule";
6925 case CP0_REG02__TCSCHEFBACK
:
6926 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6927 gen_helper_mfc0_tcschefback(arg
, cpu_env
);
6928 register_name
= "TCScheFBack";
6931 goto cp0_unimplemented
;
6934 case CP0_REGISTER_03
:
6936 case CP0_REG03__ENTRYLO1
:
6938 TCGv_i64 tmp
= tcg_temp_new_i64();
6939 tcg_gen_ld_i64(tmp
, cpu_env
,
6940 offsetof(CPUMIPSState
, CP0_EntryLo1
));
6941 #if defined(TARGET_MIPS64)
6943 /* Move RI/XI fields to bits 31:30 */
6944 tcg_gen_shri_tl(arg
, tmp
, CP0EnLo_XI
);
6945 tcg_gen_deposit_tl(tmp
, tmp
, arg
, 30, 2);
6948 gen_move_low32(arg
, tmp
);
6949 tcg_temp_free_i64(tmp
);
6951 register_name
= "EntryLo1";
6953 case CP0_REG03__GLOBALNUM
:
6955 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_GlobalNumber
));
6956 register_name
= "GlobalNumber";
6959 goto cp0_unimplemented
;
6962 case CP0_REGISTER_04
:
6964 case CP0_REG04__CONTEXT
:
6965 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_Context
));
6966 tcg_gen_ext32s_tl(arg
, arg
);
6967 register_name
= "Context";
6969 case CP0_REG04__CONTEXTCONFIG
:
6971 /* gen_helper_mfc0_contextconfig(arg); */
6972 register_name
= "ContextConfig";
6973 goto cp0_unimplemented
;
6974 case CP0_REG04__USERLOCAL
:
6975 CP0_CHECK(ctx
->ulri
);
6976 tcg_gen_ld_tl(arg
, cpu_env
,
6977 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
6978 tcg_gen_ext32s_tl(arg
, arg
);
6979 register_name
= "UserLocal";
6981 case CP0_REG04__MMID
:
6983 gen_helper_mtc0_memorymapid(cpu_env
, arg
);
6984 register_name
= "MMID";
6987 goto cp0_unimplemented
;
6990 case CP0_REGISTER_05
:
6992 case CP0_REG05__PAGEMASK
:
6993 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageMask
));
6994 register_name
= "PageMask";
6996 case CP0_REG05__PAGEGRAIN
:
6997 check_insn(ctx
, ISA_MIPS_R2
);
6998 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageGrain
));
6999 register_name
= "PageGrain";
7001 case CP0_REG05__SEGCTL0
:
7003 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_SegCtl0
));
7004 tcg_gen_ext32s_tl(arg
, arg
);
7005 register_name
= "SegCtl0";
7007 case CP0_REG05__SEGCTL1
:
7009 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_SegCtl1
));
7010 tcg_gen_ext32s_tl(arg
, arg
);
7011 register_name
= "SegCtl1";
7013 case CP0_REG05__SEGCTL2
:
7015 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_SegCtl2
));
7016 tcg_gen_ext32s_tl(arg
, arg
);
7017 register_name
= "SegCtl2";
7019 case CP0_REG05__PWBASE
:
7021 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PWBase
));
7022 register_name
= "PWBase";
7024 case CP0_REG05__PWFIELD
:
7026 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PWField
));
7027 register_name
= "PWField";
7029 case CP0_REG05__PWSIZE
:
7031 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PWSize
));
7032 register_name
= "PWSize";
7035 goto cp0_unimplemented
;
7038 case CP0_REGISTER_06
:
7040 case CP0_REG06__WIRED
:
7041 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Wired
));
7042 register_name
= "Wired";
7044 case CP0_REG06__SRSCONF0
:
7045 check_insn(ctx
, ISA_MIPS_R2
);
7046 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf0
));
7047 register_name
= "SRSConf0";
7049 case CP0_REG06__SRSCONF1
:
7050 check_insn(ctx
, ISA_MIPS_R2
);
7051 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf1
));
7052 register_name
= "SRSConf1";
7054 case CP0_REG06__SRSCONF2
:
7055 check_insn(ctx
, ISA_MIPS_R2
);
7056 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf2
));
7057 register_name
= "SRSConf2";
7059 case CP0_REG06__SRSCONF3
:
7060 check_insn(ctx
, ISA_MIPS_R2
);
7061 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf3
));
7062 register_name
= "SRSConf3";
7064 case CP0_REG06__SRSCONF4
:
7065 check_insn(ctx
, ISA_MIPS_R2
);
7066 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf4
));
7067 register_name
= "SRSConf4";
7069 case CP0_REG06__PWCTL
:
7071 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PWCtl
));
7072 register_name
= "PWCtl";
7075 goto cp0_unimplemented
;
7078 case CP0_REGISTER_07
:
7080 case CP0_REG07__HWRENA
:
7081 check_insn(ctx
, ISA_MIPS_R2
);
7082 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_HWREna
));
7083 register_name
= "HWREna";
7086 goto cp0_unimplemented
;
7089 case CP0_REGISTER_08
:
7091 case CP0_REG08__BADVADDR
:
7092 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_BadVAddr
));
7093 tcg_gen_ext32s_tl(arg
, arg
);
7094 register_name
= "BadVAddr";
7096 case CP0_REG08__BADINSTR
:
7098 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstr
));
7099 register_name
= "BadInstr";
7101 case CP0_REG08__BADINSTRP
:
7103 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstrP
));
7104 register_name
= "BadInstrP";
7106 case CP0_REG08__BADINSTRX
:
7108 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstrX
));
7109 tcg_gen_andi_tl(arg
, arg
, ~0xffff);
7110 register_name
= "BadInstrX";
7113 goto cp0_unimplemented
;
7116 case CP0_REGISTER_09
:
7118 case CP0_REG09__COUNT
:
7119 /* Mark as an IO operation because we read the time. */
7120 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
7123 gen_helper_mfc0_count(arg
, cpu_env
);
7125 * Break the TB to be able to take timer interrupts immediately
7126 * after reading count. DISAS_STOP isn't sufficient, we need to
7127 * ensure we break completely out of translated code.
7129 gen_save_pc(ctx
->base
.pc_next
+ 4);
7130 ctx
->base
.is_jmp
= DISAS_EXIT
;
7131 register_name
= "Count";
7133 case CP0_REG09__SAARI
:
7134 CP0_CHECK(ctx
->saar
);
7135 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SAARI
));
7136 register_name
= "SAARI";
7138 case CP0_REG09__SAAR
:
7139 CP0_CHECK(ctx
->saar
);
7140 gen_helper_mfc0_saar(arg
, cpu_env
);
7141 register_name
= "SAAR";
7144 goto cp0_unimplemented
;
7147 case CP0_REGISTER_10
:
7149 case CP0_REG10__ENTRYHI
:
7150 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryHi
));
7151 tcg_gen_ext32s_tl(arg
, arg
);
7152 register_name
= "EntryHi";
7155 goto cp0_unimplemented
;
7158 case CP0_REGISTER_11
:
7160 case CP0_REG11__COMPARE
:
7161 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Compare
));
7162 register_name
= "Compare";
7164 /* 6,7 are implementation dependent */
7166 goto cp0_unimplemented
;
7169 case CP0_REGISTER_12
:
7171 case CP0_REG12__STATUS
:
7172 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Status
));
7173 register_name
= "Status";
7175 case CP0_REG12__INTCTL
:
7176 check_insn(ctx
, ISA_MIPS_R2
);
7177 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_IntCtl
));
7178 register_name
= "IntCtl";
7180 case CP0_REG12__SRSCTL
:
7181 check_insn(ctx
, ISA_MIPS_R2
);
7182 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
7183 register_name
= "SRSCtl";
7185 case CP0_REG12__SRSMAP
:
7186 check_insn(ctx
, ISA_MIPS_R2
);
7187 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
7188 register_name
= "SRSMap";
7191 goto cp0_unimplemented
;
7194 case CP0_REGISTER_13
:
7196 case CP0_REG13__CAUSE
:
7197 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Cause
));
7198 register_name
= "Cause";
7201 goto cp0_unimplemented
;
7204 case CP0_REGISTER_14
:
7206 case CP0_REG14__EPC
:
7207 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
7208 tcg_gen_ext32s_tl(arg
, arg
);
7209 register_name
= "EPC";
7212 goto cp0_unimplemented
;
7215 case CP0_REGISTER_15
:
7217 case CP0_REG15__PRID
:
7218 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PRid
));
7219 register_name
= "PRid";
7221 case CP0_REG15__EBASE
:
7222 check_insn(ctx
, ISA_MIPS_R2
);
7223 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EBase
));
7224 tcg_gen_ext32s_tl(arg
, arg
);
7225 register_name
= "EBase";
7227 case CP0_REG15__CMGCRBASE
:
7228 check_insn(ctx
, ISA_MIPS_R2
);
7229 CP0_CHECK(ctx
->cmgcr
);
7230 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_CMGCRBase
));
7231 tcg_gen_ext32s_tl(arg
, arg
);
7232 register_name
= "CMGCRBase";
7235 goto cp0_unimplemented
;
7238 case CP0_REGISTER_16
:
7240 case CP0_REG16__CONFIG
:
7241 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config0
));
7242 register_name
= "Config";
7244 case CP0_REG16__CONFIG1
:
7245 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config1
));
7246 register_name
= "Config1";
7248 case CP0_REG16__CONFIG2
:
7249 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config2
));
7250 register_name
= "Config2";
7252 case CP0_REG16__CONFIG3
:
7253 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config3
));
7254 register_name
= "Config3";
7256 case CP0_REG16__CONFIG4
:
7257 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config4
));
7258 register_name
= "Config4";
7260 case CP0_REG16__CONFIG5
:
7261 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config5
));
7262 register_name
= "Config5";
7264 /* 6,7 are implementation dependent */
7265 case CP0_REG16__CONFIG6
:
7266 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config6
));
7267 register_name
= "Config6";
7269 case CP0_REG16__CONFIG7
:
7270 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config7
));
7271 register_name
= "Config7";
7274 goto cp0_unimplemented
;
7277 case CP0_REGISTER_17
:
7279 case CP0_REG17__LLADDR
:
7280 gen_helper_mfc0_lladdr(arg
, cpu_env
);
7281 register_name
= "LLAddr";
7283 case CP0_REG17__MAAR
:
7284 CP0_CHECK(ctx
->mrp
);
7285 gen_helper_mfc0_maar(arg
, cpu_env
);
7286 register_name
= "MAAR";
7288 case CP0_REG17__MAARI
:
7289 CP0_CHECK(ctx
->mrp
);
7290 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_MAARI
));
7291 register_name
= "MAARI";
7294 goto cp0_unimplemented
;
7297 case CP0_REGISTER_18
:
7299 case CP0_REG18__WATCHLO0
:
7300 case CP0_REG18__WATCHLO1
:
7301 case CP0_REG18__WATCHLO2
:
7302 case CP0_REG18__WATCHLO3
:
7303 case CP0_REG18__WATCHLO4
:
7304 case CP0_REG18__WATCHLO5
:
7305 case CP0_REG18__WATCHLO6
:
7306 case CP0_REG18__WATCHLO7
:
7307 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
7308 gen_helper_1e0i(mfc0_watchlo
, arg
, sel
);
7309 register_name
= "WatchLo";
7312 goto cp0_unimplemented
;
7315 case CP0_REGISTER_19
:
7317 case CP0_REG19__WATCHHI0
:
7318 case CP0_REG19__WATCHHI1
:
7319 case CP0_REG19__WATCHHI2
:
7320 case CP0_REG19__WATCHHI3
:
7321 case CP0_REG19__WATCHHI4
:
7322 case CP0_REG19__WATCHHI5
:
7323 case CP0_REG19__WATCHHI6
:
7324 case CP0_REG19__WATCHHI7
:
7325 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
7326 gen_helper_1e0i(mfc0_watchhi
, arg
, sel
);
7327 register_name
= "WatchHi";
7330 goto cp0_unimplemented
;
7333 case CP0_REGISTER_20
:
7335 case CP0_REG20__XCONTEXT
:
7336 #if defined(TARGET_MIPS64)
7337 check_insn(ctx
, ISA_MIPS3
);
7338 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_XContext
));
7339 tcg_gen_ext32s_tl(arg
, arg
);
7340 register_name
= "XContext";
7344 goto cp0_unimplemented
;
7347 case CP0_REGISTER_21
:
7348 /* Officially reserved, but sel 0 is used for R1x000 framemask */
7349 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS_R6
));
7352 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Framemask
));
7353 register_name
= "Framemask";
7356 goto cp0_unimplemented
;
7359 case CP0_REGISTER_22
:
7360 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
7361 register_name
= "'Diagnostic"; /* implementation dependent */
7363 case CP0_REGISTER_23
:
7365 case CP0_REG23__DEBUG
:
7366 gen_helper_mfc0_debug(arg
, cpu_env
); /* EJTAG support */
7367 register_name
= "Debug";
7369 case CP0_REG23__TRACECONTROL
:
7370 /* PDtrace support */
7371 /* gen_helper_mfc0_tracecontrol(arg); */
7372 register_name
= "TraceControl";
7373 goto cp0_unimplemented
;
7374 case CP0_REG23__TRACECONTROL2
:
7375 /* PDtrace support */
7376 /* gen_helper_mfc0_tracecontrol2(arg); */
7377 register_name
= "TraceControl2";
7378 goto cp0_unimplemented
;
7379 case CP0_REG23__USERTRACEDATA1
:
7380 /* PDtrace support */
7381 /* gen_helper_mfc0_usertracedata1(arg);*/
7382 register_name
= "UserTraceData1";
7383 goto cp0_unimplemented
;
7384 case CP0_REG23__TRACEIBPC
:
7385 /* PDtrace support */
7386 /* gen_helper_mfc0_traceibpc(arg); */
7387 register_name
= "TraceIBPC";
7388 goto cp0_unimplemented
;
7389 case CP0_REG23__TRACEDBPC
:
7390 /* PDtrace support */
7391 /* gen_helper_mfc0_tracedbpc(arg); */
7392 register_name
= "TraceDBPC";
7393 goto cp0_unimplemented
;
7395 goto cp0_unimplemented
;
7398 case CP0_REGISTER_24
:
7400 case CP0_REG24__DEPC
:
7402 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
7403 tcg_gen_ext32s_tl(arg
, arg
);
7404 register_name
= "DEPC";
7407 goto cp0_unimplemented
;
7410 case CP0_REGISTER_25
:
7412 case CP0_REG25__PERFCTL0
:
7413 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Performance0
));
7414 register_name
= "Performance0";
7416 case CP0_REG25__PERFCNT0
:
7417 /* gen_helper_mfc0_performance1(arg); */
7418 register_name
= "Performance1";
7419 goto cp0_unimplemented
;
7420 case CP0_REG25__PERFCTL1
:
7421 /* gen_helper_mfc0_performance2(arg); */
7422 register_name
= "Performance2";
7423 goto cp0_unimplemented
;
7424 case CP0_REG25__PERFCNT1
:
7425 /* gen_helper_mfc0_performance3(arg); */
7426 register_name
= "Performance3";
7427 goto cp0_unimplemented
;
7428 case CP0_REG25__PERFCTL2
:
7429 /* gen_helper_mfc0_performance4(arg); */
7430 register_name
= "Performance4";
7431 goto cp0_unimplemented
;
7432 case CP0_REG25__PERFCNT2
:
7433 /* gen_helper_mfc0_performance5(arg); */
7434 register_name
= "Performance5";
7435 goto cp0_unimplemented
;
7436 case CP0_REG25__PERFCTL3
:
7437 /* gen_helper_mfc0_performance6(arg); */
7438 register_name
= "Performance6";
7439 goto cp0_unimplemented
;
7440 case CP0_REG25__PERFCNT3
:
7441 /* gen_helper_mfc0_performance7(arg); */
7442 register_name
= "Performance7";
7443 goto cp0_unimplemented
;
7445 goto cp0_unimplemented
;
7448 case CP0_REGISTER_26
:
7450 case CP0_REG26__ERRCTL
:
7451 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_ErrCtl
));
7452 register_name
= "ErrCtl";
7455 goto cp0_unimplemented
;
7458 case CP0_REGISTER_27
:
7460 case CP0_REG27__CACHERR
:
7461 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
7462 register_name
= "CacheErr";
7465 goto cp0_unimplemented
;
7468 case CP0_REGISTER_28
:
7470 case CP0_REG28__TAGLO
:
7471 case CP0_REG28__TAGLO1
:
7472 case CP0_REG28__TAGLO2
:
7473 case CP0_REG28__TAGLO3
:
7475 TCGv_i64 tmp
= tcg_temp_new_i64();
7476 tcg_gen_ld_i64(tmp
, cpu_env
, offsetof(CPUMIPSState
, CP0_TagLo
));
7477 gen_move_low32(arg
, tmp
);
7478 tcg_temp_free_i64(tmp
);
7480 register_name
= "TagLo";
7482 case CP0_REG28__DATALO
:
7483 case CP0_REG28__DATALO1
:
7484 case CP0_REG28__DATALO2
:
7485 case CP0_REG28__DATALO3
:
7486 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataLo
));
7487 register_name
= "DataLo";
7490 goto cp0_unimplemented
;
7493 case CP0_REGISTER_29
:
7495 case CP0_REG29__TAGHI
:
7496 case CP0_REG29__TAGHI1
:
7497 case CP0_REG29__TAGHI2
:
7498 case CP0_REG29__TAGHI3
:
7499 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagHi
));
7500 register_name
= "TagHi";
7502 case CP0_REG29__DATAHI
:
7503 case CP0_REG29__DATAHI1
:
7504 case CP0_REG29__DATAHI2
:
7505 case CP0_REG29__DATAHI3
:
7506 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataHi
));
7507 register_name
= "DataHi";
7510 goto cp0_unimplemented
;
7513 case CP0_REGISTER_30
:
7515 case CP0_REG30__ERROREPC
:
7516 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
7517 tcg_gen_ext32s_tl(arg
, arg
);
7518 register_name
= "ErrorEPC";
7521 goto cp0_unimplemented
;
7524 case CP0_REGISTER_31
:
7526 case CP0_REG31__DESAVE
:
7528 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
7529 register_name
= "DESAVE";
7531 case CP0_REG31__KSCRATCH1
:
7532 case CP0_REG31__KSCRATCH2
:
7533 case CP0_REG31__KSCRATCH3
:
7534 case CP0_REG31__KSCRATCH4
:
7535 case CP0_REG31__KSCRATCH5
:
7536 case CP0_REG31__KSCRATCH6
:
7537 CP0_CHECK(ctx
->kscrexist
& (1 << sel
));
7538 tcg_gen_ld_tl(arg
, cpu_env
,
7539 offsetof(CPUMIPSState
, CP0_KScratch
[sel
- 2]));
7540 tcg_gen_ext32s_tl(arg
, arg
);
7541 register_name
= "KScratch";
7544 goto cp0_unimplemented
;
7548 goto cp0_unimplemented
;
7550 trace_mips_translate_c0("mfc0", register_name
, reg
, sel
);
7554 qemu_log_mask(LOG_UNIMP
, "mfc0 %s (reg %d sel %d)\n",
7555 register_name
, reg
, sel
);
7556 gen_mfc0_unimplemented(ctx
, arg
);
7559 static void gen_mtc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
7561 const char *register_name
= "invalid";
7564 check_insn(ctx
, ISA_MIPS_R1
);
7567 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
7572 case CP0_REGISTER_00
:
7574 case CP0_REG00__INDEX
:
7575 gen_helper_mtc0_index(cpu_env
, arg
);
7576 register_name
= "Index";
7578 case CP0_REG00__MVPCONTROL
:
7579 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7580 gen_helper_mtc0_mvpcontrol(cpu_env
, arg
);
7581 register_name
= "MVPControl";
7583 case CP0_REG00__MVPCONF0
:
7584 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7586 register_name
= "MVPConf0";
7588 case CP0_REG00__MVPCONF1
:
7589 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7591 register_name
= "MVPConf1";
7593 case CP0_REG00__VPCONTROL
:
7596 register_name
= "VPControl";
7599 goto cp0_unimplemented
;
7602 case CP0_REGISTER_01
:
7604 case CP0_REG01__RANDOM
:
7606 register_name
= "Random";
7608 case CP0_REG01__VPECONTROL
:
7609 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7610 gen_helper_mtc0_vpecontrol(cpu_env
, arg
);
7611 register_name
= "VPEControl";
7613 case CP0_REG01__VPECONF0
:
7614 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7615 gen_helper_mtc0_vpeconf0(cpu_env
, arg
);
7616 register_name
= "VPEConf0";
7618 case CP0_REG01__VPECONF1
:
7619 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7620 gen_helper_mtc0_vpeconf1(cpu_env
, arg
);
7621 register_name
= "VPEConf1";
7623 case CP0_REG01__YQMASK
:
7624 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7625 gen_helper_mtc0_yqmask(cpu_env
, arg
);
7626 register_name
= "YQMask";
7628 case CP0_REG01__VPESCHEDULE
:
7629 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7630 tcg_gen_st_tl(arg
, cpu_env
,
7631 offsetof(CPUMIPSState
, CP0_VPESchedule
));
7632 register_name
= "VPESchedule";
7634 case CP0_REG01__VPESCHEFBACK
:
7635 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7636 tcg_gen_st_tl(arg
, cpu_env
,
7637 offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
7638 register_name
= "VPEScheFBack";
7640 case CP0_REG01__VPEOPT
:
7641 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7642 gen_helper_mtc0_vpeopt(cpu_env
, arg
);
7643 register_name
= "VPEOpt";
7646 goto cp0_unimplemented
;
7649 case CP0_REGISTER_02
:
7651 case CP0_REG02__ENTRYLO0
:
7652 gen_helper_mtc0_entrylo0(cpu_env
, arg
);
7653 register_name
= "EntryLo0";
7655 case CP0_REG02__TCSTATUS
:
7656 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7657 gen_helper_mtc0_tcstatus(cpu_env
, arg
);
7658 register_name
= "TCStatus";
7660 case CP0_REG02__TCBIND
:
7661 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7662 gen_helper_mtc0_tcbind(cpu_env
, arg
);
7663 register_name
= "TCBind";
7665 case CP0_REG02__TCRESTART
:
7666 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7667 gen_helper_mtc0_tcrestart(cpu_env
, arg
);
7668 register_name
= "TCRestart";
7670 case CP0_REG02__TCHALT
:
7671 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7672 gen_helper_mtc0_tchalt(cpu_env
, arg
);
7673 register_name
= "TCHalt";
7675 case CP0_REG02__TCCONTEXT
:
7676 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7677 gen_helper_mtc0_tccontext(cpu_env
, arg
);
7678 register_name
= "TCContext";
7680 case CP0_REG02__TCSCHEDULE
:
7681 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7682 gen_helper_mtc0_tcschedule(cpu_env
, arg
);
7683 register_name
= "TCSchedule";
7685 case CP0_REG02__TCSCHEFBACK
:
7686 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7687 gen_helper_mtc0_tcschefback(cpu_env
, arg
);
7688 register_name
= "TCScheFBack";
7691 goto cp0_unimplemented
;
7694 case CP0_REGISTER_03
:
7696 case CP0_REG03__ENTRYLO1
:
7697 gen_helper_mtc0_entrylo1(cpu_env
, arg
);
7698 register_name
= "EntryLo1";
7700 case CP0_REG03__GLOBALNUM
:
7703 register_name
= "GlobalNumber";
7706 goto cp0_unimplemented
;
7709 case CP0_REGISTER_04
:
7711 case CP0_REG04__CONTEXT
:
7712 gen_helper_mtc0_context(cpu_env
, arg
);
7713 register_name
= "Context";
7715 case CP0_REG04__CONTEXTCONFIG
:
7717 /* gen_helper_mtc0_contextconfig(arg); */
7718 register_name
= "ContextConfig";
7719 goto cp0_unimplemented
;
7720 case CP0_REG04__USERLOCAL
:
7721 CP0_CHECK(ctx
->ulri
);
7722 tcg_gen_st_tl(arg
, cpu_env
,
7723 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
7724 register_name
= "UserLocal";
7726 case CP0_REG04__MMID
:
7728 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_MemoryMapID
));
7729 register_name
= "MMID";
7732 goto cp0_unimplemented
;
7735 case CP0_REGISTER_05
:
7737 case CP0_REG05__PAGEMASK
:
7738 gen_helper_mtc0_pagemask(cpu_env
, arg
);
7739 register_name
= "PageMask";
7741 case CP0_REG05__PAGEGRAIN
:
7742 check_insn(ctx
, ISA_MIPS_R2
);
7743 gen_helper_mtc0_pagegrain(cpu_env
, arg
);
7744 register_name
= "PageGrain";
7745 ctx
->base
.is_jmp
= DISAS_STOP
;
7747 case CP0_REG05__SEGCTL0
:
7749 gen_helper_mtc0_segctl0(cpu_env
, arg
);
7750 register_name
= "SegCtl0";
7752 case CP0_REG05__SEGCTL1
:
7754 gen_helper_mtc0_segctl1(cpu_env
, arg
);
7755 register_name
= "SegCtl1";
7757 case CP0_REG05__SEGCTL2
:
7759 gen_helper_mtc0_segctl2(cpu_env
, arg
);
7760 register_name
= "SegCtl2";
7762 case CP0_REG05__PWBASE
:
7764 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_PWBase
));
7765 register_name
= "PWBase";
7767 case CP0_REG05__PWFIELD
:
7769 gen_helper_mtc0_pwfield(cpu_env
, arg
);
7770 register_name
= "PWField";
7772 case CP0_REG05__PWSIZE
:
7774 gen_helper_mtc0_pwsize(cpu_env
, arg
);
7775 register_name
= "PWSize";
7778 goto cp0_unimplemented
;
7781 case CP0_REGISTER_06
:
7783 case CP0_REG06__WIRED
:
7784 gen_helper_mtc0_wired(cpu_env
, arg
);
7785 register_name
= "Wired";
7787 case CP0_REG06__SRSCONF0
:
7788 check_insn(ctx
, ISA_MIPS_R2
);
7789 gen_helper_mtc0_srsconf0(cpu_env
, arg
);
7790 register_name
= "SRSConf0";
7792 case CP0_REG06__SRSCONF1
:
7793 check_insn(ctx
, ISA_MIPS_R2
);
7794 gen_helper_mtc0_srsconf1(cpu_env
, arg
);
7795 register_name
= "SRSConf1";
7797 case CP0_REG06__SRSCONF2
:
7798 check_insn(ctx
, ISA_MIPS_R2
);
7799 gen_helper_mtc0_srsconf2(cpu_env
, arg
);
7800 register_name
= "SRSConf2";
7802 case CP0_REG06__SRSCONF3
:
7803 check_insn(ctx
, ISA_MIPS_R2
);
7804 gen_helper_mtc0_srsconf3(cpu_env
, arg
);
7805 register_name
= "SRSConf3";
7807 case CP0_REG06__SRSCONF4
:
7808 check_insn(ctx
, ISA_MIPS_R2
);
7809 gen_helper_mtc0_srsconf4(cpu_env
, arg
);
7810 register_name
= "SRSConf4";
7812 case CP0_REG06__PWCTL
:
7814 gen_helper_mtc0_pwctl(cpu_env
, arg
);
7815 register_name
= "PWCtl";
7818 goto cp0_unimplemented
;
7821 case CP0_REGISTER_07
:
7823 case CP0_REG07__HWRENA
:
7824 check_insn(ctx
, ISA_MIPS_R2
);
7825 gen_helper_mtc0_hwrena(cpu_env
, arg
);
7826 ctx
->base
.is_jmp
= DISAS_STOP
;
7827 register_name
= "HWREna";
7830 goto cp0_unimplemented
;
7833 case CP0_REGISTER_08
:
7835 case CP0_REG08__BADVADDR
:
7837 register_name
= "BadVAddr";
7839 case CP0_REG08__BADINSTR
:
7841 register_name
= "BadInstr";
7843 case CP0_REG08__BADINSTRP
:
7845 register_name
= "BadInstrP";
7847 case CP0_REG08__BADINSTRX
:
7849 register_name
= "BadInstrX";
7852 goto cp0_unimplemented
;
7855 case CP0_REGISTER_09
:
7857 case CP0_REG09__COUNT
:
7858 gen_helper_mtc0_count(cpu_env
, arg
);
7859 register_name
= "Count";
7861 case CP0_REG09__SAARI
:
7862 CP0_CHECK(ctx
->saar
);
7863 gen_helper_mtc0_saari(cpu_env
, arg
);
7864 register_name
= "SAARI";
7866 case CP0_REG09__SAAR
:
7867 CP0_CHECK(ctx
->saar
);
7868 gen_helper_mtc0_saar(cpu_env
, arg
);
7869 register_name
= "SAAR";
7872 goto cp0_unimplemented
;
7875 case CP0_REGISTER_10
:
7877 case CP0_REG10__ENTRYHI
:
7878 gen_helper_mtc0_entryhi(cpu_env
, arg
);
7879 register_name
= "EntryHi";
7882 goto cp0_unimplemented
;
7885 case CP0_REGISTER_11
:
7887 case CP0_REG11__COMPARE
:
7888 gen_helper_mtc0_compare(cpu_env
, arg
);
7889 register_name
= "Compare";
7891 /* 6,7 are implementation dependent */
7893 goto cp0_unimplemented
;
7896 case CP0_REGISTER_12
:
7898 case CP0_REG12__STATUS
:
7899 save_cpu_state(ctx
, 1);
7900 gen_helper_mtc0_status(cpu_env
, arg
);
7901 /* DISAS_STOP isn't good enough here, hflags may have changed. */
7902 gen_save_pc(ctx
->base
.pc_next
+ 4);
7903 ctx
->base
.is_jmp
= DISAS_EXIT
;
7904 register_name
= "Status";
7906 case CP0_REG12__INTCTL
:
7907 check_insn(ctx
, ISA_MIPS_R2
);
7908 gen_helper_mtc0_intctl(cpu_env
, arg
);
7909 /* Stop translation as we may have switched the execution mode */
7910 ctx
->base
.is_jmp
= DISAS_STOP
;
7911 register_name
= "IntCtl";
7913 case CP0_REG12__SRSCTL
:
7914 check_insn(ctx
, ISA_MIPS_R2
);
7915 gen_helper_mtc0_srsctl(cpu_env
, arg
);
7916 /* Stop translation as we may have switched the execution mode */
7917 ctx
->base
.is_jmp
= DISAS_STOP
;
7918 register_name
= "SRSCtl";
7920 case CP0_REG12__SRSMAP
:
7921 check_insn(ctx
, ISA_MIPS_R2
);
7922 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
7923 /* Stop translation as we may have switched the execution mode */
7924 ctx
->base
.is_jmp
= DISAS_STOP
;
7925 register_name
= "SRSMap";
7928 goto cp0_unimplemented
;
7931 case CP0_REGISTER_13
:
7933 case CP0_REG13__CAUSE
:
7934 save_cpu_state(ctx
, 1);
7935 gen_helper_mtc0_cause(cpu_env
, arg
);
7937 * Stop translation as we may have triggered an interrupt.
7938 * DISAS_STOP isn't sufficient, we need to ensure we break out of
7939 * translated code to check for pending interrupts.
7941 gen_save_pc(ctx
->base
.pc_next
+ 4);
7942 ctx
->base
.is_jmp
= DISAS_EXIT
;
7943 register_name
= "Cause";
7946 goto cp0_unimplemented
;
7949 case CP0_REGISTER_14
:
7951 case CP0_REG14__EPC
:
7952 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
7953 register_name
= "EPC";
7956 goto cp0_unimplemented
;
7959 case CP0_REGISTER_15
:
7961 case CP0_REG15__PRID
:
7963 register_name
= "PRid";
7965 case CP0_REG15__EBASE
:
7966 check_insn(ctx
, ISA_MIPS_R2
);
7967 gen_helper_mtc0_ebase(cpu_env
, arg
);
7968 register_name
= "EBase";
7971 goto cp0_unimplemented
;
7974 case CP0_REGISTER_16
:
7976 case CP0_REG16__CONFIG
:
7977 gen_helper_mtc0_config0(cpu_env
, arg
);
7978 register_name
= "Config";
7979 /* Stop translation as we may have switched the execution mode */
7980 ctx
->base
.is_jmp
= DISAS_STOP
;
7982 case CP0_REG16__CONFIG1
:
7983 /* ignored, read only */
7984 register_name
= "Config1";
7986 case CP0_REG16__CONFIG2
:
7987 gen_helper_mtc0_config2(cpu_env
, arg
);
7988 register_name
= "Config2";
7989 /* Stop translation as we may have switched the execution mode */
7990 ctx
->base
.is_jmp
= DISAS_STOP
;
7992 case CP0_REG16__CONFIG3
:
7993 gen_helper_mtc0_config3(cpu_env
, arg
);
7994 register_name
= "Config3";
7995 /* Stop translation as we may have switched the execution mode */
7996 ctx
->base
.is_jmp
= DISAS_STOP
;
7998 case CP0_REG16__CONFIG4
:
7999 gen_helper_mtc0_config4(cpu_env
, arg
);
8000 register_name
= "Config4";
8001 ctx
->base
.is_jmp
= DISAS_STOP
;
8003 case CP0_REG16__CONFIG5
:
8004 gen_helper_mtc0_config5(cpu_env
, arg
);
8005 register_name
= "Config5";
8006 /* Stop translation as we may have switched the execution mode */
8007 ctx
->base
.is_jmp
= DISAS_STOP
;
8009 /* 6,7 are implementation dependent */
8010 case CP0_REG16__CONFIG6
:
8012 register_name
= "Config6";
8014 case CP0_REG16__CONFIG7
:
8016 register_name
= "Config7";
8019 register_name
= "Invalid config selector";
8020 goto cp0_unimplemented
;
8023 case CP0_REGISTER_17
:
8025 case CP0_REG17__LLADDR
:
8026 gen_helper_mtc0_lladdr(cpu_env
, arg
);
8027 register_name
= "LLAddr";
8029 case CP0_REG17__MAAR
:
8030 CP0_CHECK(ctx
->mrp
);
8031 gen_helper_mtc0_maar(cpu_env
, arg
);
8032 register_name
= "MAAR";
8034 case CP0_REG17__MAARI
:
8035 CP0_CHECK(ctx
->mrp
);
8036 gen_helper_mtc0_maari(cpu_env
, arg
);
8037 register_name
= "MAARI";
8040 goto cp0_unimplemented
;
8043 case CP0_REGISTER_18
:
8045 case CP0_REG18__WATCHLO0
:
8046 case CP0_REG18__WATCHLO1
:
8047 case CP0_REG18__WATCHLO2
:
8048 case CP0_REG18__WATCHLO3
:
8049 case CP0_REG18__WATCHLO4
:
8050 case CP0_REG18__WATCHLO5
:
8051 case CP0_REG18__WATCHLO6
:
8052 case CP0_REG18__WATCHLO7
:
8053 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
8054 gen_helper_0e1i(mtc0_watchlo
, arg
, sel
);
8055 register_name
= "WatchLo";
8058 goto cp0_unimplemented
;
8061 case CP0_REGISTER_19
:
8063 case CP0_REG19__WATCHHI0
:
8064 case CP0_REG19__WATCHHI1
:
8065 case CP0_REG19__WATCHHI2
:
8066 case CP0_REG19__WATCHHI3
:
8067 case CP0_REG19__WATCHHI4
:
8068 case CP0_REG19__WATCHHI5
:
8069 case CP0_REG19__WATCHHI6
:
8070 case CP0_REG19__WATCHHI7
:
8071 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
8072 gen_helper_0e1i(mtc0_watchhi
, arg
, sel
);
8073 register_name
= "WatchHi";
8076 goto cp0_unimplemented
;
8079 case CP0_REGISTER_20
:
8081 case CP0_REG20__XCONTEXT
:
8082 #if defined(TARGET_MIPS64)
8083 check_insn(ctx
, ISA_MIPS3
);
8084 gen_helper_mtc0_xcontext(cpu_env
, arg
);
8085 register_name
= "XContext";
8089 goto cp0_unimplemented
;
8092 case CP0_REGISTER_21
:
8093 /* Officially reserved, but sel 0 is used for R1x000 framemask */
8094 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS_R6
));
8097 gen_helper_mtc0_framemask(cpu_env
, arg
);
8098 register_name
= "Framemask";
8101 goto cp0_unimplemented
;
8104 case CP0_REGISTER_22
:
8106 register_name
= "Diagnostic"; /* implementation dependent */
8108 case CP0_REGISTER_23
:
8110 case CP0_REG23__DEBUG
:
8111 gen_helper_mtc0_debug(cpu_env
, arg
); /* EJTAG support */
8112 /* DISAS_STOP isn't good enough here, hflags may have changed. */
8113 gen_save_pc(ctx
->base
.pc_next
+ 4);
8114 ctx
->base
.is_jmp
= DISAS_EXIT
;
8115 register_name
= "Debug";
8117 case CP0_REG23__TRACECONTROL
:
8118 /* PDtrace support */
8119 /* gen_helper_mtc0_tracecontrol(cpu_env, arg); */
8120 register_name
= "TraceControl";
8121 /* Stop translation as we may have switched the execution mode */
8122 ctx
->base
.is_jmp
= DISAS_STOP
;
8123 goto cp0_unimplemented
;
8124 case CP0_REG23__TRACECONTROL2
:
8125 /* PDtrace support */
8126 /* gen_helper_mtc0_tracecontrol2(cpu_env, arg); */
8127 register_name
= "TraceControl2";
8128 /* Stop translation as we may have switched the execution mode */
8129 ctx
->base
.is_jmp
= DISAS_STOP
;
8130 goto cp0_unimplemented
;
8131 case CP0_REG23__USERTRACEDATA1
:
8132 /* Stop translation as we may have switched the execution mode */
8133 ctx
->base
.is_jmp
= DISAS_STOP
;
8134 /* PDtrace support */
8135 /* gen_helper_mtc0_usertracedata1(cpu_env, arg);*/
8136 register_name
= "UserTraceData";
8137 /* Stop translation as we may have switched the execution mode */
8138 ctx
->base
.is_jmp
= DISAS_STOP
;
8139 goto cp0_unimplemented
;
8140 case CP0_REG23__TRACEIBPC
:
8141 /* PDtrace support */
8142 /* gen_helper_mtc0_traceibpc(cpu_env, arg); */
8143 /* Stop translation as we may have switched the execution mode */
8144 ctx
->base
.is_jmp
= DISAS_STOP
;
8145 register_name
= "TraceIBPC";
8146 goto cp0_unimplemented
;
8147 case CP0_REG23__TRACEDBPC
:
8148 /* PDtrace support */
8149 /* gen_helper_mtc0_tracedbpc(cpu_env, arg); */
8150 /* Stop translation as we may have switched the execution mode */
8151 ctx
->base
.is_jmp
= DISAS_STOP
;
8152 register_name
= "TraceDBPC";
8153 goto cp0_unimplemented
;
8155 goto cp0_unimplemented
;
8158 case CP0_REGISTER_24
:
8160 case CP0_REG24__DEPC
:
8162 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
8163 register_name
= "DEPC";
8166 goto cp0_unimplemented
;
8169 case CP0_REGISTER_25
:
8171 case CP0_REG25__PERFCTL0
:
8172 gen_helper_mtc0_performance0(cpu_env
, arg
);
8173 register_name
= "Performance0";
8175 case CP0_REG25__PERFCNT0
:
8176 /* gen_helper_mtc0_performance1(arg); */
8177 register_name
= "Performance1";
8178 goto cp0_unimplemented
;
8179 case CP0_REG25__PERFCTL1
:
8180 /* gen_helper_mtc0_performance2(arg); */
8181 register_name
= "Performance2";
8182 goto cp0_unimplemented
;
8183 case CP0_REG25__PERFCNT1
:
8184 /* gen_helper_mtc0_performance3(arg); */
8185 register_name
= "Performance3";
8186 goto cp0_unimplemented
;
8187 case CP0_REG25__PERFCTL2
:
8188 /* gen_helper_mtc0_performance4(arg); */
8189 register_name
= "Performance4";
8190 goto cp0_unimplemented
;
8191 case CP0_REG25__PERFCNT2
:
8192 /* gen_helper_mtc0_performance5(arg); */
8193 register_name
= "Performance5";
8194 goto cp0_unimplemented
;
8195 case CP0_REG25__PERFCTL3
:
8196 /* gen_helper_mtc0_performance6(arg); */
8197 register_name
= "Performance6";
8198 goto cp0_unimplemented
;
8199 case CP0_REG25__PERFCNT3
:
8200 /* gen_helper_mtc0_performance7(arg); */
8201 register_name
= "Performance7";
8202 goto cp0_unimplemented
;
8204 goto cp0_unimplemented
;
8207 case CP0_REGISTER_26
:
8209 case CP0_REG26__ERRCTL
:
8210 gen_helper_mtc0_errctl(cpu_env
, arg
);
8211 ctx
->base
.is_jmp
= DISAS_STOP
;
8212 register_name
= "ErrCtl";
8215 goto cp0_unimplemented
;
8218 case CP0_REGISTER_27
:
8220 case CP0_REG27__CACHERR
:
8222 register_name
= "CacheErr";
8225 goto cp0_unimplemented
;
8228 case CP0_REGISTER_28
:
8230 case CP0_REG28__TAGLO
:
8231 case CP0_REG28__TAGLO1
:
8232 case CP0_REG28__TAGLO2
:
8233 case CP0_REG28__TAGLO3
:
8234 gen_helper_mtc0_taglo(cpu_env
, arg
);
8235 register_name
= "TagLo";
8237 case CP0_REG28__DATALO
:
8238 case CP0_REG28__DATALO1
:
8239 case CP0_REG28__DATALO2
:
8240 case CP0_REG28__DATALO3
:
8241 gen_helper_mtc0_datalo(cpu_env
, arg
);
8242 register_name
= "DataLo";
8245 goto cp0_unimplemented
;
8248 case CP0_REGISTER_29
:
8250 case CP0_REG29__TAGHI
:
8251 case CP0_REG29__TAGHI1
:
8252 case CP0_REG29__TAGHI2
:
8253 case CP0_REG29__TAGHI3
:
8254 gen_helper_mtc0_taghi(cpu_env
, arg
);
8255 register_name
= "TagHi";
8257 case CP0_REG29__DATAHI
:
8258 case CP0_REG29__DATAHI1
:
8259 case CP0_REG29__DATAHI2
:
8260 case CP0_REG29__DATAHI3
:
8261 gen_helper_mtc0_datahi(cpu_env
, arg
);
8262 register_name
= "DataHi";
8265 register_name
= "invalid sel";
8266 goto cp0_unimplemented
;
8269 case CP0_REGISTER_30
:
8271 case CP0_REG30__ERROREPC
:
8272 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
8273 register_name
= "ErrorEPC";
8276 goto cp0_unimplemented
;
8279 case CP0_REGISTER_31
:
8281 case CP0_REG31__DESAVE
:
8283 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
8284 register_name
= "DESAVE";
8286 case CP0_REG31__KSCRATCH1
:
8287 case CP0_REG31__KSCRATCH2
:
8288 case CP0_REG31__KSCRATCH3
:
8289 case CP0_REG31__KSCRATCH4
:
8290 case CP0_REG31__KSCRATCH5
:
8291 case CP0_REG31__KSCRATCH6
:
8292 CP0_CHECK(ctx
->kscrexist
& (1 << sel
));
8293 tcg_gen_st_tl(arg
, cpu_env
,
8294 offsetof(CPUMIPSState
, CP0_KScratch
[sel
- 2]));
8295 register_name
= "KScratch";
8298 goto cp0_unimplemented
;
8302 goto cp0_unimplemented
;
8304 trace_mips_translate_c0("mtc0", register_name
, reg
, sel
);
8306 /* For simplicity assume that all writes can cause interrupts. */
8307 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
8309 * DISAS_STOP isn't sufficient, we need to ensure we break out of
8310 * translated code to check for pending interrupts.
8312 gen_save_pc(ctx
->base
.pc_next
+ 4);
8313 ctx
->base
.is_jmp
= DISAS_EXIT
;
8318 qemu_log_mask(LOG_UNIMP
, "mtc0 %s (reg %d sel %d)\n",
8319 register_name
, reg
, sel
);
8322 #if defined(TARGET_MIPS64)
8323 static void gen_dmfc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
8325 const char *register_name
= "invalid";
8328 check_insn(ctx
, ISA_MIPS_R1
);
8332 case CP0_REGISTER_00
:
8334 case CP0_REG00__INDEX
:
8335 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Index
));
8336 register_name
= "Index";
8338 case CP0_REG00__MVPCONTROL
:
8339 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8340 gen_helper_mfc0_mvpcontrol(arg
, cpu_env
);
8341 register_name
= "MVPControl";
8343 case CP0_REG00__MVPCONF0
:
8344 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8345 gen_helper_mfc0_mvpconf0(arg
, cpu_env
);
8346 register_name
= "MVPConf0";
8348 case CP0_REG00__MVPCONF1
:
8349 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8350 gen_helper_mfc0_mvpconf1(arg
, cpu_env
);
8351 register_name
= "MVPConf1";
8353 case CP0_REG00__VPCONTROL
:
8355 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPControl
));
8356 register_name
= "VPControl";
8359 goto cp0_unimplemented
;
8362 case CP0_REGISTER_01
:
8364 case CP0_REG01__RANDOM
:
8365 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS_R6
));
8366 gen_helper_mfc0_random(arg
, cpu_env
);
8367 register_name
= "Random";
8369 case CP0_REG01__VPECONTROL
:
8370 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8371 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEControl
));
8372 register_name
= "VPEControl";
8374 case CP0_REG01__VPECONF0
:
8375 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8376 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf0
));
8377 register_name
= "VPEConf0";
8379 case CP0_REG01__VPECONF1
:
8380 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8381 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf1
));
8382 register_name
= "VPEConf1";
8384 case CP0_REG01__YQMASK
:
8385 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8386 tcg_gen_ld_tl(arg
, cpu_env
,
8387 offsetof(CPUMIPSState
, CP0_YQMask
));
8388 register_name
= "YQMask";
8390 case CP0_REG01__VPESCHEDULE
:
8391 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8392 tcg_gen_ld_tl(arg
, cpu_env
,
8393 offsetof(CPUMIPSState
, CP0_VPESchedule
));
8394 register_name
= "VPESchedule";
8396 case CP0_REG01__VPESCHEFBACK
:
8397 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8398 tcg_gen_ld_tl(arg
, cpu_env
,
8399 offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
8400 register_name
= "VPEScheFBack";
8402 case CP0_REG01__VPEOPT
:
8403 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8404 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEOpt
));
8405 register_name
= "VPEOpt";
8408 goto cp0_unimplemented
;
8411 case CP0_REGISTER_02
:
8413 case CP0_REG02__ENTRYLO0
:
8414 tcg_gen_ld_tl(arg
, cpu_env
,
8415 offsetof(CPUMIPSState
, CP0_EntryLo0
));
8416 register_name
= "EntryLo0";
8418 case CP0_REG02__TCSTATUS
:
8419 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8420 gen_helper_mfc0_tcstatus(arg
, cpu_env
);
8421 register_name
= "TCStatus";
8423 case CP0_REG02__TCBIND
:
8424 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8425 gen_helper_mfc0_tcbind(arg
, cpu_env
);
8426 register_name
= "TCBind";
8428 case CP0_REG02__TCRESTART
:
8429 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8430 gen_helper_dmfc0_tcrestart(arg
, cpu_env
);
8431 register_name
= "TCRestart";
8433 case CP0_REG02__TCHALT
:
8434 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8435 gen_helper_dmfc0_tchalt(arg
, cpu_env
);
8436 register_name
= "TCHalt";
8438 case CP0_REG02__TCCONTEXT
:
8439 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8440 gen_helper_dmfc0_tccontext(arg
, cpu_env
);
8441 register_name
= "TCContext";
8443 case CP0_REG02__TCSCHEDULE
:
8444 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8445 gen_helper_dmfc0_tcschedule(arg
, cpu_env
);
8446 register_name
= "TCSchedule";
8448 case CP0_REG02__TCSCHEFBACK
:
8449 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8450 gen_helper_dmfc0_tcschefback(arg
, cpu_env
);
8451 register_name
= "TCScheFBack";
8454 goto cp0_unimplemented
;
8457 case CP0_REGISTER_03
:
8459 case CP0_REG03__ENTRYLO1
:
8460 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryLo1
));
8461 register_name
= "EntryLo1";
8463 case CP0_REG03__GLOBALNUM
:
8465 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_GlobalNumber
));
8466 register_name
= "GlobalNumber";
8469 goto cp0_unimplemented
;
8472 case CP0_REGISTER_04
:
8474 case CP0_REG04__CONTEXT
:
8475 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_Context
));
8476 register_name
= "Context";
8478 case CP0_REG04__CONTEXTCONFIG
:
8480 /* gen_helper_dmfc0_contextconfig(arg); */
8481 register_name
= "ContextConfig";
8482 goto cp0_unimplemented
;
8483 case CP0_REG04__USERLOCAL
:
8484 CP0_CHECK(ctx
->ulri
);
8485 tcg_gen_ld_tl(arg
, cpu_env
,
8486 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
8487 register_name
= "UserLocal";
8489 case CP0_REG04__MMID
:
8491 gen_helper_mtc0_memorymapid(cpu_env
, arg
);
8492 register_name
= "MMID";
8495 goto cp0_unimplemented
;
8498 case CP0_REGISTER_05
:
8500 case CP0_REG05__PAGEMASK
:
8501 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageMask
));
8502 register_name
= "PageMask";
8504 case CP0_REG05__PAGEGRAIN
:
8505 check_insn(ctx
, ISA_MIPS_R2
);
8506 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageGrain
));
8507 register_name
= "PageGrain";
8509 case CP0_REG05__SEGCTL0
:
8511 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_SegCtl0
));
8512 register_name
= "SegCtl0";
8514 case CP0_REG05__SEGCTL1
:
8516 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_SegCtl1
));
8517 register_name
= "SegCtl1";
8519 case CP0_REG05__SEGCTL2
:
8521 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_SegCtl2
));
8522 register_name
= "SegCtl2";
8524 case CP0_REG05__PWBASE
:
8526 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_PWBase
));
8527 register_name
= "PWBase";
8529 case CP0_REG05__PWFIELD
:
8531 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_PWField
));
8532 register_name
= "PWField";
8534 case CP0_REG05__PWSIZE
:
8536 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_PWSize
));
8537 register_name
= "PWSize";
8540 goto cp0_unimplemented
;
8543 case CP0_REGISTER_06
:
8545 case CP0_REG06__WIRED
:
8546 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Wired
));
8547 register_name
= "Wired";
8549 case CP0_REG06__SRSCONF0
:
8550 check_insn(ctx
, ISA_MIPS_R2
);
8551 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf0
));
8552 register_name
= "SRSConf0";
8554 case CP0_REG06__SRSCONF1
:
8555 check_insn(ctx
, ISA_MIPS_R2
);
8556 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf1
));
8557 register_name
= "SRSConf1";
8559 case CP0_REG06__SRSCONF2
:
8560 check_insn(ctx
, ISA_MIPS_R2
);
8561 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf2
));
8562 register_name
= "SRSConf2";
8564 case CP0_REG06__SRSCONF3
:
8565 check_insn(ctx
, ISA_MIPS_R2
);
8566 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf3
));
8567 register_name
= "SRSConf3";
8569 case CP0_REG06__SRSCONF4
:
8570 check_insn(ctx
, ISA_MIPS_R2
);
8571 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf4
));
8572 register_name
= "SRSConf4";
8574 case CP0_REG06__PWCTL
:
8576 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PWCtl
));
8577 register_name
= "PWCtl";
8580 goto cp0_unimplemented
;
8583 case CP0_REGISTER_07
:
8585 case CP0_REG07__HWRENA
:
8586 check_insn(ctx
, ISA_MIPS_R2
);
8587 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_HWREna
));
8588 register_name
= "HWREna";
8591 goto cp0_unimplemented
;
8594 case CP0_REGISTER_08
:
8596 case CP0_REG08__BADVADDR
:
8597 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_BadVAddr
));
8598 register_name
= "BadVAddr";
8600 case CP0_REG08__BADINSTR
:
8602 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstr
));
8603 register_name
= "BadInstr";
8605 case CP0_REG08__BADINSTRP
:
8607 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstrP
));
8608 register_name
= "BadInstrP";
8610 case CP0_REG08__BADINSTRX
:
8612 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstrX
));
8613 tcg_gen_andi_tl(arg
, arg
, ~0xffff);
8614 register_name
= "BadInstrX";
8617 goto cp0_unimplemented
;
8620 case CP0_REGISTER_09
:
8622 case CP0_REG09__COUNT
:
8623 /* Mark as an IO operation because we read the time. */
8624 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
8627 gen_helper_mfc0_count(arg
, cpu_env
);
8629 * Break the TB to be able to take timer interrupts immediately
8630 * after reading count. DISAS_STOP isn't sufficient, we need to
8631 * ensure we break completely out of translated code.
8633 gen_save_pc(ctx
->base
.pc_next
+ 4);
8634 ctx
->base
.is_jmp
= DISAS_EXIT
;
8635 register_name
= "Count";
8637 case CP0_REG09__SAARI
:
8638 CP0_CHECK(ctx
->saar
);
8639 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SAARI
));
8640 register_name
= "SAARI";
8642 case CP0_REG09__SAAR
:
8643 CP0_CHECK(ctx
->saar
);
8644 gen_helper_dmfc0_saar(arg
, cpu_env
);
8645 register_name
= "SAAR";
8648 goto cp0_unimplemented
;
8651 case CP0_REGISTER_10
:
8653 case CP0_REG10__ENTRYHI
:
8654 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryHi
));
8655 register_name
= "EntryHi";
8658 goto cp0_unimplemented
;
8661 case CP0_REGISTER_11
:
8663 case CP0_REG11__COMPARE
:
8664 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Compare
));
8665 register_name
= "Compare";
8667 /* 6,7 are implementation dependent */
8669 goto cp0_unimplemented
;
8672 case CP0_REGISTER_12
:
8674 case CP0_REG12__STATUS
:
8675 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Status
));
8676 register_name
= "Status";
8678 case CP0_REG12__INTCTL
:
8679 check_insn(ctx
, ISA_MIPS_R2
);
8680 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_IntCtl
));
8681 register_name
= "IntCtl";
8683 case CP0_REG12__SRSCTL
:
8684 check_insn(ctx
, ISA_MIPS_R2
);
8685 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
8686 register_name
= "SRSCtl";
8688 case CP0_REG12__SRSMAP
:
8689 check_insn(ctx
, ISA_MIPS_R2
);
8690 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
8691 register_name
= "SRSMap";
8694 goto cp0_unimplemented
;
8697 case CP0_REGISTER_13
:
8699 case CP0_REG13__CAUSE
:
8700 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Cause
));
8701 register_name
= "Cause";
8704 goto cp0_unimplemented
;
8707 case CP0_REGISTER_14
:
8709 case CP0_REG14__EPC
:
8710 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
8711 register_name
= "EPC";
8714 goto cp0_unimplemented
;
8717 case CP0_REGISTER_15
:
8719 case CP0_REG15__PRID
:
8720 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PRid
));
8721 register_name
= "PRid";
8723 case CP0_REG15__EBASE
:
8724 check_insn(ctx
, ISA_MIPS_R2
);
8725 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EBase
));
8726 register_name
= "EBase";
8728 case CP0_REG15__CMGCRBASE
:
8729 check_insn(ctx
, ISA_MIPS_R2
);
8730 CP0_CHECK(ctx
->cmgcr
);
8731 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_CMGCRBase
));
8732 register_name
= "CMGCRBase";
8735 goto cp0_unimplemented
;
8738 case CP0_REGISTER_16
:
8740 case CP0_REG16__CONFIG
:
8741 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config0
));
8742 register_name
= "Config";
8744 case CP0_REG16__CONFIG1
:
8745 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config1
));
8746 register_name
= "Config1";
8748 case CP0_REG16__CONFIG2
:
8749 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config2
));
8750 register_name
= "Config2";
8752 case CP0_REG16__CONFIG3
:
8753 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config3
));
8754 register_name
= "Config3";
8756 case CP0_REG16__CONFIG4
:
8757 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config4
));
8758 register_name
= "Config4";
8760 case CP0_REG16__CONFIG5
:
8761 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config5
));
8762 register_name
= "Config5";
8764 /* 6,7 are implementation dependent */
8765 case CP0_REG16__CONFIG6
:
8766 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config6
));
8767 register_name
= "Config6";
8769 case CP0_REG16__CONFIG7
:
8770 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config7
));
8771 register_name
= "Config7";
8774 goto cp0_unimplemented
;
8777 case CP0_REGISTER_17
:
8779 case CP0_REG17__LLADDR
:
8780 gen_helper_dmfc0_lladdr(arg
, cpu_env
);
8781 register_name
= "LLAddr";
8783 case CP0_REG17__MAAR
:
8784 CP0_CHECK(ctx
->mrp
);
8785 gen_helper_dmfc0_maar(arg
, cpu_env
);
8786 register_name
= "MAAR";
8788 case CP0_REG17__MAARI
:
8789 CP0_CHECK(ctx
->mrp
);
8790 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_MAARI
));
8791 register_name
= "MAARI";
8794 goto cp0_unimplemented
;
8797 case CP0_REGISTER_18
:
8799 case CP0_REG18__WATCHLO0
:
8800 case CP0_REG18__WATCHLO1
:
8801 case CP0_REG18__WATCHLO2
:
8802 case CP0_REG18__WATCHLO3
:
8803 case CP0_REG18__WATCHLO4
:
8804 case CP0_REG18__WATCHLO5
:
8805 case CP0_REG18__WATCHLO6
:
8806 case CP0_REG18__WATCHLO7
:
8807 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
8808 gen_helper_1e0i(dmfc0_watchlo
, arg
, sel
);
8809 register_name
= "WatchLo";
8812 goto cp0_unimplemented
;
8815 case CP0_REGISTER_19
:
8817 case CP0_REG19__WATCHHI0
:
8818 case CP0_REG19__WATCHHI1
:
8819 case CP0_REG19__WATCHHI2
:
8820 case CP0_REG19__WATCHHI3
:
8821 case CP0_REG19__WATCHHI4
:
8822 case CP0_REG19__WATCHHI5
:
8823 case CP0_REG19__WATCHHI6
:
8824 case CP0_REG19__WATCHHI7
:
8825 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
8826 gen_helper_1e0i(dmfc0_watchhi
, arg
, sel
);
8827 register_name
= "WatchHi";
8830 goto cp0_unimplemented
;
8833 case CP0_REGISTER_20
:
8835 case CP0_REG20__XCONTEXT
:
8836 check_insn(ctx
, ISA_MIPS3
);
8837 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_XContext
));
8838 register_name
= "XContext";
8841 goto cp0_unimplemented
;
8844 case CP0_REGISTER_21
:
8845 /* Officially reserved, but sel 0 is used for R1x000 framemask */
8846 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS_R6
));
8849 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Framemask
));
8850 register_name
= "Framemask";
8853 goto cp0_unimplemented
;
8856 case CP0_REGISTER_22
:
8857 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
8858 register_name
= "'Diagnostic"; /* implementation dependent */
8860 case CP0_REGISTER_23
:
8862 case CP0_REG23__DEBUG
:
8863 gen_helper_mfc0_debug(arg
, cpu_env
); /* EJTAG support */
8864 register_name
= "Debug";
8866 case CP0_REG23__TRACECONTROL
:
8867 /* PDtrace support */
8868 /* gen_helper_dmfc0_tracecontrol(arg, cpu_env); */
8869 register_name
= "TraceControl";
8870 goto cp0_unimplemented
;
8871 case CP0_REG23__TRACECONTROL2
:
8872 /* PDtrace support */
8873 /* gen_helper_dmfc0_tracecontrol2(arg, cpu_env); */
8874 register_name
= "TraceControl2";
8875 goto cp0_unimplemented
;
8876 case CP0_REG23__USERTRACEDATA1
:
8877 /* PDtrace support */
8878 /* gen_helper_dmfc0_usertracedata1(arg, cpu_env);*/
8879 register_name
= "UserTraceData1";
8880 goto cp0_unimplemented
;
8881 case CP0_REG23__TRACEIBPC
:
8882 /* PDtrace support */
8883 /* gen_helper_dmfc0_traceibpc(arg, cpu_env); */
8884 register_name
= "TraceIBPC";
8885 goto cp0_unimplemented
;
8886 case CP0_REG23__TRACEDBPC
:
8887 /* PDtrace support */
8888 /* gen_helper_dmfc0_tracedbpc(arg, cpu_env); */
8889 register_name
= "TraceDBPC";
8890 goto cp0_unimplemented
;
8892 goto cp0_unimplemented
;
8895 case CP0_REGISTER_24
:
8897 case CP0_REG24__DEPC
:
8899 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
8900 register_name
= "DEPC";
8903 goto cp0_unimplemented
;
8906 case CP0_REGISTER_25
:
8908 case CP0_REG25__PERFCTL0
:
8909 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Performance0
));
8910 register_name
= "Performance0";
8912 case CP0_REG25__PERFCNT0
:
8913 /* gen_helper_dmfc0_performance1(arg); */
8914 register_name
= "Performance1";
8915 goto cp0_unimplemented
;
8916 case CP0_REG25__PERFCTL1
:
8917 /* gen_helper_dmfc0_performance2(arg); */
8918 register_name
= "Performance2";
8919 goto cp0_unimplemented
;
8920 case CP0_REG25__PERFCNT1
:
8921 /* gen_helper_dmfc0_performance3(arg); */
8922 register_name
= "Performance3";
8923 goto cp0_unimplemented
;
8924 case CP0_REG25__PERFCTL2
:
8925 /* gen_helper_dmfc0_performance4(arg); */
8926 register_name
= "Performance4";
8927 goto cp0_unimplemented
;
8928 case CP0_REG25__PERFCNT2
:
8929 /* gen_helper_dmfc0_performance5(arg); */
8930 register_name
= "Performance5";
8931 goto cp0_unimplemented
;
8932 case CP0_REG25__PERFCTL3
:
8933 /* gen_helper_dmfc0_performance6(arg); */
8934 register_name
= "Performance6";
8935 goto cp0_unimplemented
;
8936 case CP0_REG25__PERFCNT3
:
8937 /* gen_helper_dmfc0_performance7(arg); */
8938 register_name
= "Performance7";
8939 goto cp0_unimplemented
;
8941 goto cp0_unimplemented
;
8944 case CP0_REGISTER_26
:
8946 case CP0_REG26__ERRCTL
:
8947 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_ErrCtl
));
8948 register_name
= "ErrCtl";
8951 goto cp0_unimplemented
;
8954 case CP0_REGISTER_27
:
8957 case CP0_REG27__CACHERR
:
8958 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
8959 register_name
= "CacheErr";
8962 goto cp0_unimplemented
;
8965 case CP0_REGISTER_28
:
8967 case CP0_REG28__TAGLO
:
8968 case CP0_REG28__TAGLO1
:
8969 case CP0_REG28__TAGLO2
:
8970 case CP0_REG28__TAGLO3
:
8971 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagLo
));
8972 register_name
= "TagLo";
8974 case CP0_REG28__DATALO
:
8975 case CP0_REG28__DATALO1
:
8976 case CP0_REG28__DATALO2
:
8977 case CP0_REG28__DATALO3
:
8978 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataLo
));
8979 register_name
= "DataLo";
8982 goto cp0_unimplemented
;
8985 case CP0_REGISTER_29
:
8987 case CP0_REG29__TAGHI
:
8988 case CP0_REG29__TAGHI1
:
8989 case CP0_REG29__TAGHI2
:
8990 case CP0_REG29__TAGHI3
:
8991 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagHi
));
8992 register_name
= "TagHi";
8994 case CP0_REG29__DATAHI
:
8995 case CP0_REG29__DATAHI1
:
8996 case CP0_REG29__DATAHI2
:
8997 case CP0_REG29__DATAHI3
:
8998 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataHi
));
8999 register_name
= "DataHi";
9002 goto cp0_unimplemented
;
9005 case CP0_REGISTER_30
:
9007 case CP0_REG30__ERROREPC
:
9008 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
9009 register_name
= "ErrorEPC";
9012 goto cp0_unimplemented
;
9015 case CP0_REGISTER_31
:
9017 case CP0_REG31__DESAVE
:
9019 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
9020 register_name
= "DESAVE";
9022 case CP0_REG31__KSCRATCH1
:
9023 case CP0_REG31__KSCRATCH2
:
9024 case CP0_REG31__KSCRATCH3
:
9025 case CP0_REG31__KSCRATCH4
:
9026 case CP0_REG31__KSCRATCH5
:
9027 case CP0_REG31__KSCRATCH6
:
9028 CP0_CHECK(ctx
->kscrexist
& (1 << sel
));
9029 tcg_gen_ld_tl(arg
, cpu_env
,
9030 offsetof(CPUMIPSState
, CP0_KScratch
[sel
- 2]));
9031 register_name
= "KScratch";
9034 goto cp0_unimplemented
;
9038 goto cp0_unimplemented
;
9040 trace_mips_translate_c0("dmfc0", register_name
, reg
, sel
);
9044 qemu_log_mask(LOG_UNIMP
, "dmfc0 %s (reg %d sel %d)\n",
9045 register_name
, reg
, sel
);
9046 gen_mfc0_unimplemented(ctx
, arg
);
9049 static void gen_dmtc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
9051 const char *register_name
= "invalid";
9054 check_insn(ctx
, ISA_MIPS_R1
);
9057 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
9062 case CP0_REGISTER_00
:
9064 case CP0_REG00__INDEX
:
9065 gen_helper_mtc0_index(cpu_env
, arg
);
9066 register_name
= "Index";
9068 case CP0_REG00__MVPCONTROL
:
9069 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9070 gen_helper_mtc0_mvpcontrol(cpu_env
, arg
);
9071 register_name
= "MVPControl";
9073 case CP0_REG00__MVPCONF0
:
9074 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9076 register_name
= "MVPConf0";
9078 case CP0_REG00__MVPCONF1
:
9079 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9081 register_name
= "MVPConf1";
9083 case CP0_REG00__VPCONTROL
:
9086 register_name
= "VPControl";
9089 goto cp0_unimplemented
;
9092 case CP0_REGISTER_01
:
9094 case CP0_REG01__RANDOM
:
9096 register_name
= "Random";
9098 case CP0_REG01__VPECONTROL
:
9099 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9100 gen_helper_mtc0_vpecontrol(cpu_env
, arg
);
9101 register_name
= "VPEControl";
9103 case CP0_REG01__VPECONF0
:
9104 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9105 gen_helper_mtc0_vpeconf0(cpu_env
, arg
);
9106 register_name
= "VPEConf0";
9108 case CP0_REG01__VPECONF1
:
9109 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9110 gen_helper_mtc0_vpeconf1(cpu_env
, arg
);
9111 register_name
= "VPEConf1";
9113 case CP0_REG01__YQMASK
:
9114 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9115 gen_helper_mtc0_yqmask(cpu_env
, arg
);
9116 register_name
= "YQMask";
9118 case CP0_REG01__VPESCHEDULE
:
9119 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9120 tcg_gen_st_tl(arg
, cpu_env
,
9121 offsetof(CPUMIPSState
, CP0_VPESchedule
));
9122 register_name
= "VPESchedule";
9124 case CP0_REG01__VPESCHEFBACK
:
9125 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9126 tcg_gen_st_tl(arg
, cpu_env
,
9127 offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
9128 register_name
= "VPEScheFBack";
9130 case CP0_REG01__VPEOPT
:
9131 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9132 gen_helper_mtc0_vpeopt(cpu_env
, arg
);
9133 register_name
= "VPEOpt";
9136 goto cp0_unimplemented
;
9139 case CP0_REGISTER_02
:
9141 case CP0_REG02__ENTRYLO0
:
9142 gen_helper_dmtc0_entrylo0(cpu_env
, arg
);
9143 register_name
= "EntryLo0";
9145 case CP0_REG02__TCSTATUS
:
9146 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9147 gen_helper_mtc0_tcstatus(cpu_env
, arg
);
9148 register_name
= "TCStatus";
9150 case CP0_REG02__TCBIND
:
9151 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9152 gen_helper_mtc0_tcbind(cpu_env
, arg
);
9153 register_name
= "TCBind";
9155 case CP0_REG02__TCRESTART
:
9156 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9157 gen_helper_mtc0_tcrestart(cpu_env
, arg
);
9158 register_name
= "TCRestart";
9160 case CP0_REG02__TCHALT
:
9161 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9162 gen_helper_mtc0_tchalt(cpu_env
, arg
);
9163 register_name
= "TCHalt";
9165 case CP0_REG02__TCCONTEXT
:
9166 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9167 gen_helper_mtc0_tccontext(cpu_env
, arg
);
9168 register_name
= "TCContext";
9170 case CP0_REG02__TCSCHEDULE
:
9171 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9172 gen_helper_mtc0_tcschedule(cpu_env
, arg
);
9173 register_name
= "TCSchedule";
9175 case CP0_REG02__TCSCHEFBACK
:
9176 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9177 gen_helper_mtc0_tcschefback(cpu_env
, arg
);
9178 register_name
= "TCScheFBack";
9181 goto cp0_unimplemented
;
9184 case CP0_REGISTER_03
:
9186 case CP0_REG03__ENTRYLO1
:
9187 gen_helper_dmtc0_entrylo1(cpu_env
, arg
);
9188 register_name
= "EntryLo1";
9190 case CP0_REG03__GLOBALNUM
:
9193 register_name
= "GlobalNumber";
9196 goto cp0_unimplemented
;
9199 case CP0_REGISTER_04
:
9201 case CP0_REG04__CONTEXT
:
9202 gen_helper_mtc0_context(cpu_env
, arg
);
9203 register_name
= "Context";
9205 case CP0_REG04__CONTEXTCONFIG
:
9207 /* gen_helper_dmtc0_contextconfig(arg); */
9208 register_name
= "ContextConfig";
9209 goto cp0_unimplemented
;
9210 case CP0_REG04__USERLOCAL
:
9211 CP0_CHECK(ctx
->ulri
);
9212 tcg_gen_st_tl(arg
, cpu_env
,
9213 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
9214 register_name
= "UserLocal";
9216 case CP0_REG04__MMID
:
9218 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_MemoryMapID
));
9219 register_name
= "MMID";
9222 goto cp0_unimplemented
;
9225 case CP0_REGISTER_05
:
9227 case CP0_REG05__PAGEMASK
:
9228 gen_helper_mtc0_pagemask(cpu_env
, arg
);
9229 register_name
= "PageMask";
9231 case CP0_REG05__PAGEGRAIN
:
9232 check_insn(ctx
, ISA_MIPS_R2
);
9233 gen_helper_mtc0_pagegrain(cpu_env
, arg
);
9234 register_name
= "PageGrain";
9236 case CP0_REG05__SEGCTL0
:
9238 gen_helper_mtc0_segctl0(cpu_env
, arg
);
9239 register_name
= "SegCtl0";
9241 case CP0_REG05__SEGCTL1
:
9243 gen_helper_mtc0_segctl1(cpu_env
, arg
);
9244 register_name
= "SegCtl1";
9246 case CP0_REG05__SEGCTL2
:
9248 gen_helper_mtc0_segctl2(cpu_env
, arg
);
9249 register_name
= "SegCtl2";
9251 case CP0_REG05__PWBASE
:
9253 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_PWBase
));
9254 register_name
= "PWBase";
9256 case CP0_REG05__PWFIELD
:
9258 gen_helper_mtc0_pwfield(cpu_env
, arg
);
9259 register_name
= "PWField";
9261 case CP0_REG05__PWSIZE
:
9263 gen_helper_mtc0_pwsize(cpu_env
, arg
);
9264 register_name
= "PWSize";
9267 goto cp0_unimplemented
;
9270 case CP0_REGISTER_06
:
9272 case CP0_REG06__WIRED
:
9273 gen_helper_mtc0_wired(cpu_env
, arg
);
9274 register_name
= "Wired";
9276 case CP0_REG06__SRSCONF0
:
9277 check_insn(ctx
, ISA_MIPS_R2
);
9278 gen_helper_mtc0_srsconf0(cpu_env
, arg
);
9279 register_name
= "SRSConf0";
9281 case CP0_REG06__SRSCONF1
:
9282 check_insn(ctx
, ISA_MIPS_R2
);
9283 gen_helper_mtc0_srsconf1(cpu_env
, arg
);
9284 register_name
= "SRSConf1";
9286 case CP0_REG06__SRSCONF2
:
9287 check_insn(ctx
, ISA_MIPS_R2
);
9288 gen_helper_mtc0_srsconf2(cpu_env
, arg
);
9289 register_name
= "SRSConf2";
9291 case CP0_REG06__SRSCONF3
:
9292 check_insn(ctx
, ISA_MIPS_R2
);
9293 gen_helper_mtc0_srsconf3(cpu_env
, arg
);
9294 register_name
= "SRSConf3";
9296 case CP0_REG06__SRSCONF4
:
9297 check_insn(ctx
, ISA_MIPS_R2
);
9298 gen_helper_mtc0_srsconf4(cpu_env
, arg
);
9299 register_name
= "SRSConf4";
9301 case CP0_REG06__PWCTL
:
9303 gen_helper_mtc0_pwctl(cpu_env
, arg
);
9304 register_name
= "PWCtl";
9307 goto cp0_unimplemented
;
9310 case CP0_REGISTER_07
:
9312 case CP0_REG07__HWRENA
:
9313 check_insn(ctx
, ISA_MIPS_R2
);
9314 gen_helper_mtc0_hwrena(cpu_env
, arg
);
9315 ctx
->base
.is_jmp
= DISAS_STOP
;
9316 register_name
= "HWREna";
9319 goto cp0_unimplemented
;
9322 case CP0_REGISTER_08
:
9324 case CP0_REG08__BADVADDR
:
9326 register_name
= "BadVAddr";
9328 case CP0_REG08__BADINSTR
:
9330 register_name
= "BadInstr";
9332 case CP0_REG08__BADINSTRP
:
9334 register_name
= "BadInstrP";
9336 case CP0_REG08__BADINSTRX
:
9338 register_name
= "BadInstrX";
9341 goto cp0_unimplemented
;
9344 case CP0_REGISTER_09
:
9346 case CP0_REG09__COUNT
:
9347 gen_helper_mtc0_count(cpu_env
, arg
);
9348 register_name
= "Count";
9350 case CP0_REG09__SAARI
:
9351 CP0_CHECK(ctx
->saar
);
9352 gen_helper_mtc0_saari(cpu_env
, arg
);
9353 register_name
= "SAARI";
9355 case CP0_REG09__SAAR
:
9356 CP0_CHECK(ctx
->saar
);
9357 gen_helper_mtc0_saar(cpu_env
, arg
);
9358 register_name
= "SAAR";
9361 goto cp0_unimplemented
;
9363 /* Stop translation as we may have switched the execution mode */
9364 ctx
->base
.is_jmp
= DISAS_STOP
;
9366 case CP0_REGISTER_10
:
9368 case CP0_REG10__ENTRYHI
:
9369 gen_helper_mtc0_entryhi(cpu_env
, arg
);
9370 register_name
= "EntryHi";
9373 goto cp0_unimplemented
;
9376 case CP0_REGISTER_11
:
9378 case CP0_REG11__COMPARE
:
9379 gen_helper_mtc0_compare(cpu_env
, arg
);
9380 register_name
= "Compare";
9382 /* 6,7 are implementation dependent */
9384 goto cp0_unimplemented
;
9386 /* Stop translation as we may have switched the execution mode */
9387 ctx
->base
.is_jmp
= DISAS_STOP
;
9389 case CP0_REGISTER_12
:
9391 case CP0_REG12__STATUS
:
9392 save_cpu_state(ctx
, 1);
9393 gen_helper_mtc0_status(cpu_env
, arg
);
9394 /* DISAS_STOP isn't good enough here, hflags may have changed. */
9395 gen_save_pc(ctx
->base
.pc_next
+ 4);
9396 ctx
->base
.is_jmp
= DISAS_EXIT
;
9397 register_name
= "Status";
9399 case CP0_REG12__INTCTL
:
9400 check_insn(ctx
, ISA_MIPS_R2
);
9401 gen_helper_mtc0_intctl(cpu_env
, arg
);
9402 /* Stop translation as we may have switched the execution mode */
9403 ctx
->base
.is_jmp
= DISAS_STOP
;
9404 register_name
= "IntCtl";
9406 case CP0_REG12__SRSCTL
:
9407 check_insn(ctx
, ISA_MIPS_R2
);
9408 gen_helper_mtc0_srsctl(cpu_env
, arg
);
9409 /* Stop translation as we may have switched the execution mode */
9410 ctx
->base
.is_jmp
= DISAS_STOP
;
9411 register_name
= "SRSCtl";
9413 case CP0_REG12__SRSMAP
:
9414 check_insn(ctx
, ISA_MIPS_R2
);
9415 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
9416 /* Stop translation as we may have switched the execution mode */
9417 ctx
->base
.is_jmp
= DISAS_STOP
;
9418 register_name
= "SRSMap";
9421 goto cp0_unimplemented
;
9424 case CP0_REGISTER_13
:
9426 case CP0_REG13__CAUSE
:
9427 save_cpu_state(ctx
, 1);
9428 gen_helper_mtc0_cause(cpu_env
, arg
);
9430 * Stop translation as we may have triggered an interrupt.
9431 * DISAS_STOP isn't sufficient, we need to ensure we break out of
9432 * translated code to check for pending interrupts.
9434 gen_save_pc(ctx
->base
.pc_next
+ 4);
9435 ctx
->base
.is_jmp
= DISAS_EXIT
;
9436 register_name
= "Cause";
9439 goto cp0_unimplemented
;
9442 case CP0_REGISTER_14
:
9444 case CP0_REG14__EPC
:
9445 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
9446 register_name
= "EPC";
9449 goto cp0_unimplemented
;
9452 case CP0_REGISTER_15
:
9454 case CP0_REG15__PRID
:
9456 register_name
= "PRid";
9458 case CP0_REG15__EBASE
:
9459 check_insn(ctx
, ISA_MIPS_R2
);
9460 gen_helper_mtc0_ebase(cpu_env
, arg
);
9461 register_name
= "EBase";
9464 goto cp0_unimplemented
;
9467 case CP0_REGISTER_16
:
9469 case CP0_REG16__CONFIG
:
9470 gen_helper_mtc0_config0(cpu_env
, arg
);
9471 register_name
= "Config";
9472 /* Stop translation as we may have switched the execution mode */
9473 ctx
->base
.is_jmp
= DISAS_STOP
;
9475 case CP0_REG16__CONFIG1
:
9476 /* ignored, read only */
9477 register_name
= "Config1";
9479 case CP0_REG16__CONFIG2
:
9480 gen_helper_mtc0_config2(cpu_env
, arg
);
9481 register_name
= "Config2";
9482 /* Stop translation as we may have switched the execution mode */
9483 ctx
->base
.is_jmp
= DISAS_STOP
;
9485 case CP0_REG16__CONFIG3
:
9486 gen_helper_mtc0_config3(cpu_env
, arg
);
9487 register_name
= "Config3";
9488 /* Stop translation as we may have switched the execution mode */
9489 ctx
->base
.is_jmp
= DISAS_STOP
;
9491 case CP0_REG16__CONFIG4
:
9492 /* currently ignored */
9493 register_name
= "Config4";
9495 case CP0_REG16__CONFIG5
:
9496 gen_helper_mtc0_config5(cpu_env
, arg
);
9497 register_name
= "Config5";
9498 /* Stop translation as we may have switched the execution mode */
9499 ctx
->base
.is_jmp
= DISAS_STOP
;
9501 /* 6,7 are implementation dependent */
9503 register_name
= "Invalid config selector";
9504 goto cp0_unimplemented
;
9507 case CP0_REGISTER_17
:
9509 case CP0_REG17__LLADDR
:
9510 gen_helper_mtc0_lladdr(cpu_env
, arg
);
9511 register_name
= "LLAddr";
9513 case CP0_REG17__MAAR
:
9514 CP0_CHECK(ctx
->mrp
);
9515 gen_helper_mtc0_maar(cpu_env
, arg
);
9516 register_name
= "MAAR";
9518 case CP0_REG17__MAARI
:
9519 CP0_CHECK(ctx
->mrp
);
9520 gen_helper_mtc0_maari(cpu_env
, arg
);
9521 register_name
= "MAARI";
9524 goto cp0_unimplemented
;
9527 case CP0_REGISTER_18
:
9529 case CP0_REG18__WATCHLO0
:
9530 case CP0_REG18__WATCHLO1
:
9531 case CP0_REG18__WATCHLO2
:
9532 case CP0_REG18__WATCHLO3
:
9533 case CP0_REG18__WATCHLO4
:
9534 case CP0_REG18__WATCHLO5
:
9535 case CP0_REG18__WATCHLO6
:
9536 case CP0_REG18__WATCHLO7
:
9537 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
9538 gen_helper_0e1i(mtc0_watchlo
, arg
, sel
);
9539 register_name
= "WatchLo";
9542 goto cp0_unimplemented
;
9545 case CP0_REGISTER_19
:
9547 case CP0_REG19__WATCHHI0
:
9548 case CP0_REG19__WATCHHI1
:
9549 case CP0_REG19__WATCHHI2
:
9550 case CP0_REG19__WATCHHI3
:
9551 case CP0_REG19__WATCHHI4
:
9552 case CP0_REG19__WATCHHI5
:
9553 case CP0_REG19__WATCHHI6
:
9554 case CP0_REG19__WATCHHI7
:
9555 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
9556 gen_helper_0e1i(mtc0_watchhi
, arg
, sel
);
9557 register_name
= "WatchHi";
9560 goto cp0_unimplemented
;
9563 case CP0_REGISTER_20
:
9565 case CP0_REG20__XCONTEXT
:
9566 check_insn(ctx
, ISA_MIPS3
);
9567 gen_helper_mtc0_xcontext(cpu_env
, arg
);
9568 register_name
= "XContext";
9571 goto cp0_unimplemented
;
9574 case CP0_REGISTER_21
:
9575 /* Officially reserved, but sel 0 is used for R1x000 framemask */
9576 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS_R6
));
9579 gen_helper_mtc0_framemask(cpu_env
, arg
);
9580 register_name
= "Framemask";
9583 goto cp0_unimplemented
;
9586 case CP0_REGISTER_22
:
9588 register_name
= "Diagnostic"; /* implementation dependent */
9590 case CP0_REGISTER_23
:
9592 case CP0_REG23__DEBUG
:
9593 gen_helper_mtc0_debug(cpu_env
, arg
); /* EJTAG support */
9594 /* DISAS_STOP isn't good enough here, hflags may have changed. */
9595 gen_save_pc(ctx
->base
.pc_next
+ 4);
9596 ctx
->base
.is_jmp
= DISAS_EXIT
;
9597 register_name
= "Debug";
9599 case CP0_REG23__TRACECONTROL
:
9600 /* PDtrace support */
9601 /* gen_helper_mtc0_tracecontrol(cpu_env, arg); */
9602 /* Stop translation as we may have switched the execution mode */
9603 ctx
->base
.is_jmp
= DISAS_STOP
;
9604 register_name
= "TraceControl";
9605 goto cp0_unimplemented
;
9606 case CP0_REG23__TRACECONTROL2
:
9607 /* PDtrace support */
9608 /* gen_helper_mtc0_tracecontrol2(cpu_env, arg); */
9609 /* Stop translation as we may have switched the execution mode */
9610 ctx
->base
.is_jmp
= DISAS_STOP
;
9611 register_name
= "TraceControl2";
9612 goto cp0_unimplemented
;
9613 case CP0_REG23__USERTRACEDATA1
:
9614 /* PDtrace support */
9615 /* gen_helper_mtc0_usertracedata1(cpu_env, arg);*/
9616 /* Stop translation as we may have switched the execution mode */
9617 ctx
->base
.is_jmp
= DISAS_STOP
;
9618 register_name
= "UserTraceData1";
9619 goto cp0_unimplemented
;
9620 case CP0_REG23__TRACEIBPC
:
9621 /* PDtrace support */
9622 /* gen_helper_mtc0_traceibpc(cpu_env, arg); */
9623 /* Stop translation as we may have switched the execution mode */
9624 ctx
->base
.is_jmp
= DISAS_STOP
;
9625 register_name
= "TraceIBPC";
9626 goto cp0_unimplemented
;
9627 case CP0_REG23__TRACEDBPC
:
9628 /* PDtrace support */
9629 /* gen_helper_mtc0_tracedbpc(cpu_env, arg); */
9630 /* Stop translation as we may have switched the execution mode */
9631 ctx
->base
.is_jmp
= DISAS_STOP
;
9632 register_name
= "TraceDBPC";
9633 goto cp0_unimplemented
;
9635 goto cp0_unimplemented
;
9638 case CP0_REGISTER_24
:
9640 case CP0_REG24__DEPC
:
9642 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
9643 register_name
= "DEPC";
9646 goto cp0_unimplemented
;
9649 case CP0_REGISTER_25
:
9651 case CP0_REG25__PERFCTL0
:
9652 gen_helper_mtc0_performance0(cpu_env
, arg
);
9653 register_name
= "Performance0";
9655 case CP0_REG25__PERFCNT0
:
9656 /* gen_helper_mtc0_performance1(cpu_env, arg); */
9657 register_name
= "Performance1";
9658 goto cp0_unimplemented
;
9659 case CP0_REG25__PERFCTL1
:
9660 /* gen_helper_mtc0_performance2(cpu_env, arg); */
9661 register_name
= "Performance2";
9662 goto cp0_unimplemented
;
9663 case CP0_REG25__PERFCNT1
:
9664 /* gen_helper_mtc0_performance3(cpu_env, arg); */
9665 register_name
= "Performance3";
9666 goto cp0_unimplemented
;
9667 case CP0_REG25__PERFCTL2
:
9668 /* gen_helper_mtc0_performance4(cpu_env, arg); */
9669 register_name
= "Performance4";
9670 goto cp0_unimplemented
;
9671 case CP0_REG25__PERFCNT2
:
9672 /* gen_helper_mtc0_performance5(cpu_env, arg); */
9673 register_name
= "Performance5";
9674 goto cp0_unimplemented
;
9675 case CP0_REG25__PERFCTL3
:
9676 /* gen_helper_mtc0_performance6(cpu_env, arg); */
9677 register_name
= "Performance6";
9678 goto cp0_unimplemented
;
9679 case CP0_REG25__PERFCNT3
:
9680 /* gen_helper_mtc0_performance7(cpu_env, arg); */
9681 register_name
= "Performance7";
9682 goto cp0_unimplemented
;
9684 goto cp0_unimplemented
;
9687 case CP0_REGISTER_26
:
9689 case CP0_REG26__ERRCTL
:
9690 gen_helper_mtc0_errctl(cpu_env
, arg
);
9691 ctx
->base
.is_jmp
= DISAS_STOP
;
9692 register_name
= "ErrCtl";
9695 goto cp0_unimplemented
;
9698 case CP0_REGISTER_27
:
9700 case CP0_REG27__CACHERR
:
9702 register_name
= "CacheErr";
9705 goto cp0_unimplemented
;
9708 case CP0_REGISTER_28
:
9710 case CP0_REG28__TAGLO
:
9711 case CP0_REG28__TAGLO1
:
9712 case CP0_REG28__TAGLO2
:
9713 case CP0_REG28__TAGLO3
:
9714 gen_helper_mtc0_taglo(cpu_env
, arg
);
9715 register_name
= "TagLo";
9717 case CP0_REG28__DATALO
:
9718 case CP0_REG28__DATALO1
:
9719 case CP0_REG28__DATALO2
:
9720 case CP0_REG28__DATALO3
:
9721 gen_helper_mtc0_datalo(cpu_env
, arg
);
9722 register_name
= "DataLo";
9725 goto cp0_unimplemented
;
9728 case CP0_REGISTER_29
:
9730 case CP0_REG29__TAGHI
:
9731 case CP0_REG29__TAGHI1
:
9732 case CP0_REG29__TAGHI2
:
9733 case CP0_REG29__TAGHI3
:
9734 gen_helper_mtc0_taghi(cpu_env
, arg
);
9735 register_name
= "TagHi";
9737 case CP0_REG29__DATAHI
:
9738 case CP0_REG29__DATAHI1
:
9739 case CP0_REG29__DATAHI2
:
9740 case CP0_REG29__DATAHI3
:
9741 gen_helper_mtc0_datahi(cpu_env
, arg
);
9742 register_name
= "DataHi";
9745 register_name
= "invalid sel";
9746 goto cp0_unimplemented
;
9749 case CP0_REGISTER_30
:
9751 case CP0_REG30__ERROREPC
:
9752 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
9753 register_name
= "ErrorEPC";
9756 goto cp0_unimplemented
;
9759 case CP0_REGISTER_31
:
9761 case CP0_REG31__DESAVE
:
9763 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
9764 register_name
= "DESAVE";
9766 case CP0_REG31__KSCRATCH1
:
9767 case CP0_REG31__KSCRATCH2
:
9768 case CP0_REG31__KSCRATCH3
:
9769 case CP0_REG31__KSCRATCH4
:
9770 case CP0_REG31__KSCRATCH5
:
9771 case CP0_REG31__KSCRATCH6
:
9772 CP0_CHECK(ctx
->kscrexist
& (1 << sel
));
9773 tcg_gen_st_tl(arg
, cpu_env
,
9774 offsetof(CPUMIPSState
, CP0_KScratch
[sel
- 2]));
9775 register_name
= "KScratch";
9778 goto cp0_unimplemented
;
9782 goto cp0_unimplemented
;
9784 trace_mips_translate_c0("dmtc0", register_name
, reg
, sel
);
9786 /* For simplicity assume that all writes can cause interrupts. */
9787 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
9789 * DISAS_STOP isn't sufficient, we need to ensure we break out of
9790 * translated code to check for pending interrupts.
9792 gen_save_pc(ctx
->base
.pc_next
+ 4);
9793 ctx
->base
.is_jmp
= DISAS_EXIT
;
9798 qemu_log_mask(LOG_UNIMP
, "dmtc0 %s (reg %d sel %d)\n",
9799 register_name
, reg
, sel
);
9801 #endif /* TARGET_MIPS64 */
9803 static void gen_mftr(CPUMIPSState
*env
, DisasContext
*ctx
, int rt
, int rd
,
9804 int u
, int sel
, int h
)
9806 int other_tc
= env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
);
9807 TCGv t0
= tcg_temp_local_new();
9809 if ((env
->CP0_VPEConf0
& (1 << CP0VPEC0_MVP
)) == 0 &&
9810 ((env
->tcs
[other_tc
].CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)) !=
9811 (env
->active_tc
.CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)))) {
9812 tcg_gen_movi_tl(t0
, -1);
9813 } else if ((env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
)) >
9814 (env
->mvp
->CP0_MVPConf0
& (0xff << CP0MVPC0_PTC
))) {
9815 tcg_gen_movi_tl(t0
, -1);
9816 } else if (u
== 0) {
9821 gen_helper_mftc0_vpecontrol(t0
, cpu_env
);
9824 gen_helper_mftc0_vpeconf0(t0
, cpu_env
);
9834 gen_helper_mftc0_tcstatus(t0
, cpu_env
);
9837 gen_helper_mftc0_tcbind(t0
, cpu_env
);
9840 gen_helper_mftc0_tcrestart(t0
, cpu_env
);
9843 gen_helper_mftc0_tchalt(t0
, cpu_env
);
9846 gen_helper_mftc0_tccontext(t0
, cpu_env
);
9849 gen_helper_mftc0_tcschedule(t0
, cpu_env
);
9852 gen_helper_mftc0_tcschefback(t0
, cpu_env
);
9855 gen_mfc0(ctx
, t0
, rt
, sel
);
9862 gen_helper_mftc0_entryhi(t0
, cpu_env
);
9865 gen_mfc0(ctx
, t0
, rt
, sel
);
9872 gen_helper_mftc0_status(t0
, cpu_env
);
9875 gen_mfc0(ctx
, t0
, rt
, sel
);
9882 gen_helper_mftc0_cause(t0
, cpu_env
);
9892 gen_helper_mftc0_epc(t0
, cpu_env
);
9902 gen_helper_mftc0_ebase(t0
, cpu_env
);
9919 gen_helper_mftc0_configx(t0
, cpu_env
, tcg_const_tl(sel
));
9929 gen_helper_mftc0_debug(t0
, cpu_env
);
9932 gen_mfc0(ctx
, t0
, rt
, sel
);
9937 gen_mfc0(ctx
, t0
, rt
, sel
);
9941 /* GPR registers. */
9943 gen_helper_1e0i(mftgpr
, t0
, rt
);
9945 /* Auxiliary CPU registers */
9949 gen_helper_1e0i(mftlo
, t0
, 0);
9952 gen_helper_1e0i(mfthi
, t0
, 0);
9955 gen_helper_1e0i(mftacx
, t0
, 0);
9958 gen_helper_1e0i(mftlo
, t0
, 1);
9961 gen_helper_1e0i(mfthi
, t0
, 1);
9964 gen_helper_1e0i(mftacx
, t0
, 1);
9967 gen_helper_1e0i(mftlo
, t0
, 2);
9970 gen_helper_1e0i(mfthi
, t0
, 2);
9973 gen_helper_1e0i(mftacx
, t0
, 2);
9976 gen_helper_1e0i(mftlo
, t0
, 3);
9979 gen_helper_1e0i(mfthi
, t0
, 3);
9982 gen_helper_1e0i(mftacx
, t0
, 3);
9985 gen_helper_mftdsp(t0
, cpu_env
);
9991 /* Floating point (COP1). */
9993 /* XXX: For now we support only a single FPU context. */
9995 TCGv_i32 fp0
= tcg_temp_new_i32();
9997 gen_load_fpr32(ctx
, fp0
, rt
);
9998 tcg_gen_ext_i32_tl(t0
, fp0
);
9999 tcg_temp_free_i32(fp0
);
10001 TCGv_i32 fp0
= tcg_temp_new_i32();
10003 gen_load_fpr32h(ctx
, fp0
, rt
);
10004 tcg_gen_ext_i32_tl(t0
, fp0
);
10005 tcg_temp_free_i32(fp0
);
10009 /* XXX: For now we support only a single FPU context. */
10010 gen_helper_1e0i(cfc1
, t0
, rt
);
10012 /* COP2: Not implemented. */
10020 trace_mips_translate_tr("mftr", rt
, u
, sel
, h
);
10021 gen_store_gpr(t0
, rd
);
10027 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt
, u
, sel
, h
);
10028 gen_reserved_instruction(ctx
);
10031 static void gen_mttr(CPUMIPSState
*env
, DisasContext
*ctx
, int rd
, int rt
,
10032 int u
, int sel
, int h
)
10034 int other_tc
= env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
);
10035 TCGv t0
= tcg_temp_local_new();
10037 gen_load_gpr(t0
, rt
);
10038 if ((env
->CP0_VPEConf0
& (1 << CP0VPEC0_MVP
)) == 0 &&
10039 ((env
->tcs
[other_tc
].CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)) !=
10040 (env
->active_tc
.CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)))) {
10043 } else if ((env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
)) >
10044 (env
->mvp
->CP0_MVPConf0
& (0xff << CP0MVPC0_PTC
))) {
10047 } else if (u
== 0) {
10052 gen_helper_mttc0_vpecontrol(cpu_env
, t0
);
10055 gen_helper_mttc0_vpeconf0(cpu_env
, t0
);
10065 gen_helper_mttc0_tcstatus(cpu_env
, t0
);
10068 gen_helper_mttc0_tcbind(cpu_env
, t0
);
10071 gen_helper_mttc0_tcrestart(cpu_env
, t0
);
10074 gen_helper_mttc0_tchalt(cpu_env
, t0
);
10077 gen_helper_mttc0_tccontext(cpu_env
, t0
);
10080 gen_helper_mttc0_tcschedule(cpu_env
, t0
);
10083 gen_helper_mttc0_tcschefback(cpu_env
, t0
);
10086 gen_mtc0(ctx
, t0
, rd
, sel
);
10093 gen_helper_mttc0_entryhi(cpu_env
, t0
);
10096 gen_mtc0(ctx
, t0
, rd
, sel
);
10103 gen_helper_mttc0_status(cpu_env
, t0
);
10106 gen_mtc0(ctx
, t0
, rd
, sel
);
10113 gen_helper_mttc0_cause(cpu_env
, t0
);
10123 gen_helper_mttc0_ebase(cpu_env
, t0
);
10133 gen_helper_mttc0_debug(cpu_env
, t0
);
10136 gen_mtc0(ctx
, t0
, rd
, sel
);
10141 gen_mtc0(ctx
, t0
, rd
, sel
);
10145 /* GPR registers. */
10147 gen_helper_0e1i(mttgpr
, t0
, rd
);
10149 /* Auxiliary CPU registers */
10153 gen_helper_0e1i(mttlo
, t0
, 0);
10156 gen_helper_0e1i(mtthi
, t0
, 0);
10159 gen_helper_0e1i(mttacx
, t0
, 0);
10162 gen_helper_0e1i(mttlo
, t0
, 1);
10165 gen_helper_0e1i(mtthi
, t0
, 1);
10168 gen_helper_0e1i(mttacx
, t0
, 1);
10171 gen_helper_0e1i(mttlo
, t0
, 2);
10174 gen_helper_0e1i(mtthi
, t0
, 2);
10177 gen_helper_0e1i(mttacx
, t0
, 2);
10180 gen_helper_0e1i(mttlo
, t0
, 3);
10183 gen_helper_0e1i(mtthi
, t0
, 3);
10186 gen_helper_0e1i(mttacx
, t0
, 3);
10189 gen_helper_mttdsp(cpu_env
, t0
);
10195 /* Floating point (COP1). */
10197 /* XXX: For now we support only a single FPU context. */
10199 TCGv_i32 fp0
= tcg_temp_new_i32();
10201 tcg_gen_trunc_tl_i32(fp0
, t0
);
10202 gen_store_fpr32(ctx
, fp0
, rd
);
10203 tcg_temp_free_i32(fp0
);
10205 TCGv_i32 fp0
= tcg_temp_new_i32();
10207 tcg_gen_trunc_tl_i32(fp0
, t0
);
10208 gen_store_fpr32h(ctx
, fp0
, rd
);
10209 tcg_temp_free_i32(fp0
);
10213 /* XXX: For now we support only a single FPU context. */
10215 TCGv_i32 fs_tmp
= tcg_const_i32(rd
);
10217 gen_helper_0e2i(ctc1
, t0
, fs_tmp
, rt
);
10218 tcg_temp_free_i32(fs_tmp
);
10220 /* Stop translation as we may have changed hflags */
10221 ctx
->base
.is_jmp
= DISAS_STOP
;
10223 /* COP2: Not implemented. */
10231 trace_mips_translate_tr("mttr", rd
, u
, sel
, h
);
10237 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd
, u
, sel
, h
);
10238 gen_reserved_instruction(ctx
);
10241 static void gen_cp0(CPUMIPSState
*env
, DisasContext
*ctx
, uint32_t opc
,
10244 const char *opn
= "ldst";
10246 check_cp0_enabled(ctx
);
10250 /* Treat as NOP. */
10253 gen_mfc0(ctx
, cpu_gpr
[rt
], rd
, ctx
->opcode
& 0x7);
10258 TCGv t0
= tcg_temp_new();
10260 gen_load_gpr(t0
, rt
);
10261 gen_mtc0(ctx
, t0
, rd
, ctx
->opcode
& 0x7);
10266 #if defined(TARGET_MIPS64)
10268 check_insn(ctx
, ISA_MIPS3
);
10270 /* Treat as NOP. */
10273 gen_dmfc0(ctx
, cpu_gpr
[rt
], rd
, ctx
->opcode
& 0x7);
10277 check_insn(ctx
, ISA_MIPS3
);
10279 TCGv t0
= tcg_temp_new();
10281 gen_load_gpr(t0
, rt
);
10282 gen_dmtc0(ctx
, t0
, rd
, ctx
->opcode
& 0x7);
10291 /* Treat as NOP. */
10294 gen_mfhc0(ctx
, cpu_gpr
[rt
], rd
, ctx
->opcode
& 0x7);
10300 TCGv t0
= tcg_temp_new();
10301 gen_load_gpr(t0
, rt
);
10302 gen_mthc0(ctx
, t0
, rd
, ctx
->opcode
& 0x7);
10308 check_cp0_enabled(ctx
);
10310 /* Treat as NOP. */
10313 gen_mftr(env
, ctx
, rt
, rd
, (ctx
->opcode
>> 5) & 1,
10314 ctx
->opcode
& 0x7, (ctx
->opcode
>> 4) & 1);
10318 check_cp0_enabled(ctx
);
10319 gen_mttr(env
, ctx
, rd
, rt
, (ctx
->opcode
>> 5) & 1,
10320 ctx
->opcode
& 0x7, (ctx
->opcode
>> 4) & 1);
10325 if (!env
->tlb
->helper_tlbwi
) {
10328 gen_helper_tlbwi(cpu_env
);
10332 if (ctx
->ie
>= 2) {
10333 if (!env
->tlb
->helper_tlbinv
) {
10336 gen_helper_tlbinv(cpu_env
);
10337 } /* treat as nop if TLBINV not supported */
10341 if (ctx
->ie
>= 2) {
10342 if (!env
->tlb
->helper_tlbinvf
) {
10345 gen_helper_tlbinvf(cpu_env
);
10346 } /* treat as nop if TLBINV not supported */
10350 if (!env
->tlb
->helper_tlbwr
) {
10353 gen_helper_tlbwr(cpu_env
);
10357 if (!env
->tlb
->helper_tlbp
) {
10360 gen_helper_tlbp(cpu_env
);
10364 if (!env
->tlb
->helper_tlbr
) {
10367 gen_helper_tlbr(cpu_env
);
10369 case OPC_ERET
: /* OPC_ERETNC */
10370 if ((ctx
->insn_flags
& ISA_MIPS_R6
) &&
10371 (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
10374 int bit_shift
= (ctx
->hflags
& MIPS_HFLAG_M16
) ? 16 : 6;
10375 if (ctx
->opcode
& (1 << bit_shift
)) {
10378 check_insn(ctx
, ISA_MIPS_R5
);
10379 gen_helper_eretnc(cpu_env
);
10383 check_insn(ctx
, ISA_MIPS2
);
10384 gen_helper_eret(cpu_env
);
10386 ctx
->base
.is_jmp
= DISAS_EXIT
;
10391 check_insn(ctx
, ISA_MIPS_R1
);
10392 if ((ctx
->insn_flags
& ISA_MIPS_R6
) &&
10393 (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
10396 if (!(ctx
->hflags
& MIPS_HFLAG_DM
)) {
10398 gen_reserved_instruction(ctx
);
10400 gen_helper_deret(cpu_env
);
10401 ctx
->base
.is_jmp
= DISAS_EXIT
;
10406 check_insn(ctx
, ISA_MIPS3
| ISA_MIPS_R1
);
10407 if ((ctx
->insn_flags
& ISA_MIPS_R6
) &&
10408 (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
10411 /* If we get an exception, we want to restart at next instruction */
10412 ctx
->base
.pc_next
+= 4;
10413 save_cpu_state(ctx
, 1);
10414 ctx
->base
.pc_next
-= 4;
10415 gen_helper_wait(cpu_env
);
10416 ctx
->base
.is_jmp
= DISAS_NORETURN
;
10421 gen_reserved_instruction(ctx
);
10424 (void)opn
; /* avoid a compiler warning */
10426 #endif /* !CONFIG_USER_ONLY */
10428 /* CP1 Branches (before delay slot) */
10429 static void gen_compute_branch1(DisasContext
*ctx
, uint32_t op
,
10430 int32_t cc
, int32_t offset
)
10432 target_ulong btarget
;
10433 TCGv_i32 t0
= tcg_temp_new_i32();
10435 if ((ctx
->insn_flags
& ISA_MIPS_R6
) && (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
10436 gen_reserved_instruction(ctx
);
10441 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS_R1
);
10444 btarget
= ctx
->base
.pc_next
+ 4 + offset
;
10448 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
10449 tcg_gen_not_i32(t0
, t0
);
10450 tcg_gen_andi_i32(t0
, t0
, 1);
10451 tcg_gen_extu_i32_tl(bcond
, t0
);
10454 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
10455 tcg_gen_not_i32(t0
, t0
);
10456 tcg_gen_andi_i32(t0
, t0
, 1);
10457 tcg_gen_extu_i32_tl(bcond
, t0
);
10460 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
10461 tcg_gen_andi_i32(t0
, t0
, 1);
10462 tcg_gen_extu_i32_tl(bcond
, t0
);
10465 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
10466 tcg_gen_andi_i32(t0
, t0
, 1);
10467 tcg_gen_extu_i32_tl(bcond
, t0
);
10469 ctx
->hflags
|= MIPS_HFLAG_BL
;
10473 TCGv_i32 t1
= tcg_temp_new_i32();
10474 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
10475 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 1));
10476 tcg_gen_nand_i32(t0
, t0
, t1
);
10477 tcg_temp_free_i32(t1
);
10478 tcg_gen_andi_i32(t0
, t0
, 1);
10479 tcg_gen_extu_i32_tl(bcond
, t0
);
10484 TCGv_i32 t1
= tcg_temp_new_i32();
10485 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
10486 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 1));
10487 tcg_gen_or_i32(t0
, t0
, t1
);
10488 tcg_temp_free_i32(t1
);
10489 tcg_gen_andi_i32(t0
, t0
, 1);
10490 tcg_gen_extu_i32_tl(bcond
, t0
);
10495 TCGv_i32 t1
= tcg_temp_new_i32();
10496 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
10497 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 1));
10498 tcg_gen_and_i32(t0
, t0
, t1
);
10499 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 2));
10500 tcg_gen_and_i32(t0
, t0
, t1
);
10501 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 3));
10502 tcg_gen_nand_i32(t0
, t0
, t1
);
10503 tcg_temp_free_i32(t1
);
10504 tcg_gen_andi_i32(t0
, t0
, 1);
10505 tcg_gen_extu_i32_tl(bcond
, t0
);
10510 TCGv_i32 t1
= tcg_temp_new_i32();
10511 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
10512 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 1));
10513 tcg_gen_or_i32(t0
, t0
, t1
);
10514 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 2));
10515 tcg_gen_or_i32(t0
, t0
, t1
);
10516 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 3));
10517 tcg_gen_or_i32(t0
, t0
, t1
);
10518 tcg_temp_free_i32(t1
);
10519 tcg_gen_andi_i32(t0
, t0
, 1);
10520 tcg_gen_extu_i32_tl(bcond
, t0
);
10523 ctx
->hflags
|= MIPS_HFLAG_BC
;
10526 MIPS_INVAL("cp1 cond branch");
10527 gen_reserved_instruction(ctx
);
10530 ctx
->btarget
= btarget
;
10531 ctx
->hflags
|= MIPS_HFLAG_BDS32
;
10533 tcg_temp_free_i32(t0
);
10536 /* R6 CP1 Branches */
10537 static void gen_compute_branch1_r6(DisasContext
*ctx
, uint32_t op
,
10538 int32_t ft
, int32_t offset
,
10539 int delayslot_size
)
10541 target_ulong btarget
;
10542 TCGv_i64 t0
= tcg_temp_new_i64();
10544 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
10545 #ifdef MIPS_DEBUG_DISAS
10546 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
10547 "\n", ctx
->base
.pc_next
);
10549 gen_reserved_instruction(ctx
);
10553 gen_load_fpr64(ctx
, t0
, ft
);
10554 tcg_gen_andi_i64(t0
, t0
, 1);
10556 btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
10560 tcg_gen_xori_i64(t0
, t0
, 1);
10561 ctx
->hflags
|= MIPS_HFLAG_BC
;
10564 /* t0 already set */
10565 ctx
->hflags
|= MIPS_HFLAG_BC
;
10568 MIPS_INVAL("cp1 cond branch");
10569 gen_reserved_instruction(ctx
);
10573 tcg_gen_trunc_i64_tl(bcond
, t0
);
10575 ctx
->btarget
= btarget
;
10577 switch (delayslot_size
) {
10579 ctx
->hflags
|= MIPS_HFLAG_BDS16
;
10582 ctx
->hflags
|= MIPS_HFLAG_BDS32
;
10587 tcg_temp_free_i64(t0
);
10590 /* Coprocessor 1 (FPU) */
10592 #define FOP(func, fmt) (((fmt) << 21) | (func))
10595 OPC_ADD_S
= FOP(0, FMT_S
),
10596 OPC_SUB_S
= FOP(1, FMT_S
),
10597 OPC_MUL_S
= FOP(2, FMT_S
),
10598 OPC_DIV_S
= FOP(3, FMT_S
),
10599 OPC_SQRT_S
= FOP(4, FMT_S
),
10600 OPC_ABS_S
= FOP(5, FMT_S
),
10601 OPC_MOV_S
= FOP(6, FMT_S
),
10602 OPC_NEG_S
= FOP(7, FMT_S
),
10603 OPC_ROUND_L_S
= FOP(8, FMT_S
),
10604 OPC_TRUNC_L_S
= FOP(9, FMT_S
),
10605 OPC_CEIL_L_S
= FOP(10, FMT_S
),
10606 OPC_FLOOR_L_S
= FOP(11, FMT_S
),
10607 OPC_ROUND_W_S
= FOP(12, FMT_S
),
10608 OPC_TRUNC_W_S
= FOP(13, FMT_S
),
10609 OPC_CEIL_W_S
= FOP(14, FMT_S
),
10610 OPC_FLOOR_W_S
= FOP(15, FMT_S
),
10611 OPC_SEL_S
= FOP(16, FMT_S
),
10612 OPC_MOVCF_S
= FOP(17, FMT_S
),
10613 OPC_MOVZ_S
= FOP(18, FMT_S
),
10614 OPC_MOVN_S
= FOP(19, FMT_S
),
10615 OPC_SELEQZ_S
= FOP(20, FMT_S
),
10616 OPC_RECIP_S
= FOP(21, FMT_S
),
10617 OPC_RSQRT_S
= FOP(22, FMT_S
),
10618 OPC_SELNEZ_S
= FOP(23, FMT_S
),
10619 OPC_MADDF_S
= FOP(24, FMT_S
),
10620 OPC_MSUBF_S
= FOP(25, FMT_S
),
10621 OPC_RINT_S
= FOP(26, FMT_S
),
10622 OPC_CLASS_S
= FOP(27, FMT_S
),
10623 OPC_MIN_S
= FOP(28, FMT_S
),
10624 OPC_RECIP2_S
= FOP(28, FMT_S
),
10625 OPC_MINA_S
= FOP(29, FMT_S
),
10626 OPC_RECIP1_S
= FOP(29, FMT_S
),
10627 OPC_MAX_S
= FOP(30, FMT_S
),
10628 OPC_RSQRT1_S
= FOP(30, FMT_S
),
10629 OPC_MAXA_S
= FOP(31, FMT_S
),
10630 OPC_RSQRT2_S
= FOP(31, FMT_S
),
10631 OPC_CVT_D_S
= FOP(33, FMT_S
),
10632 OPC_CVT_W_S
= FOP(36, FMT_S
),
10633 OPC_CVT_L_S
= FOP(37, FMT_S
),
10634 OPC_CVT_PS_S
= FOP(38, FMT_S
),
10635 OPC_CMP_F_S
= FOP(48, FMT_S
),
10636 OPC_CMP_UN_S
= FOP(49, FMT_S
),
10637 OPC_CMP_EQ_S
= FOP(50, FMT_S
),
10638 OPC_CMP_UEQ_S
= FOP(51, FMT_S
),
10639 OPC_CMP_OLT_S
= FOP(52, FMT_S
),
10640 OPC_CMP_ULT_S
= FOP(53, FMT_S
),
10641 OPC_CMP_OLE_S
= FOP(54, FMT_S
),
10642 OPC_CMP_ULE_S
= FOP(55, FMT_S
),
10643 OPC_CMP_SF_S
= FOP(56, FMT_S
),
10644 OPC_CMP_NGLE_S
= FOP(57, FMT_S
),
10645 OPC_CMP_SEQ_S
= FOP(58, FMT_S
),
10646 OPC_CMP_NGL_S
= FOP(59, FMT_S
),
10647 OPC_CMP_LT_S
= FOP(60, FMT_S
),
10648 OPC_CMP_NGE_S
= FOP(61, FMT_S
),
10649 OPC_CMP_LE_S
= FOP(62, FMT_S
),
10650 OPC_CMP_NGT_S
= FOP(63, FMT_S
),
10652 OPC_ADD_D
= FOP(0, FMT_D
),
10653 OPC_SUB_D
= FOP(1, FMT_D
),
10654 OPC_MUL_D
= FOP(2, FMT_D
),
10655 OPC_DIV_D
= FOP(3, FMT_D
),
10656 OPC_SQRT_D
= FOP(4, FMT_D
),
10657 OPC_ABS_D
= FOP(5, FMT_D
),
10658 OPC_MOV_D
= FOP(6, FMT_D
),
10659 OPC_NEG_D
= FOP(7, FMT_D
),
10660 OPC_ROUND_L_D
= FOP(8, FMT_D
),
10661 OPC_TRUNC_L_D
= FOP(9, FMT_D
),
10662 OPC_CEIL_L_D
= FOP(10, FMT_D
),
10663 OPC_FLOOR_L_D
= FOP(11, FMT_D
),
10664 OPC_ROUND_W_D
= FOP(12, FMT_D
),
10665 OPC_TRUNC_W_D
= FOP(13, FMT_D
),
10666 OPC_CEIL_W_D
= FOP(14, FMT_D
),
10667 OPC_FLOOR_W_D
= FOP(15, FMT_D
),
10668 OPC_SEL_D
= FOP(16, FMT_D
),
10669 OPC_MOVCF_D
= FOP(17, FMT_D
),
10670 OPC_MOVZ_D
= FOP(18, FMT_D
),
10671 OPC_MOVN_D
= FOP(19, FMT_D
),
10672 OPC_SELEQZ_D
= FOP(20, FMT_D
),
10673 OPC_RECIP_D
= FOP(21, FMT_D
),
10674 OPC_RSQRT_D
= FOP(22, FMT_D
),
10675 OPC_SELNEZ_D
= FOP(23, FMT_D
),
10676 OPC_MADDF_D
= FOP(24, FMT_D
),
10677 OPC_MSUBF_D
= FOP(25, FMT_D
),
10678 OPC_RINT_D
= FOP(26, FMT_D
),
10679 OPC_CLASS_D
= FOP(27, FMT_D
),
10680 OPC_MIN_D
= FOP(28, FMT_D
),
10681 OPC_RECIP2_D
= FOP(28, FMT_D
),
10682 OPC_MINA_D
= FOP(29, FMT_D
),
10683 OPC_RECIP1_D
= FOP(29, FMT_D
),
10684 OPC_MAX_D
= FOP(30, FMT_D
),
10685 OPC_RSQRT1_D
= FOP(30, FMT_D
),
10686 OPC_MAXA_D
= FOP(31, FMT_D
),
10687 OPC_RSQRT2_D
= FOP(31, FMT_D
),
10688 OPC_CVT_S_D
= FOP(32, FMT_D
),
10689 OPC_CVT_W_D
= FOP(36, FMT_D
),
10690 OPC_CVT_L_D
= FOP(37, FMT_D
),
10691 OPC_CMP_F_D
= FOP(48, FMT_D
),
10692 OPC_CMP_UN_D
= FOP(49, FMT_D
),
10693 OPC_CMP_EQ_D
= FOP(50, FMT_D
),
10694 OPC_CMP_UEQ_D
= FOP(51, FMT_D
),
10695 OPC_CMP_OLT_D
= FOP(52, FMT_D
),
10696 OPC_CMP_ULT_D
= FOP(53, FMT_D
),
10697 OPC_CMP_OLE_D
= FOP(54, FMT_D
),
10698 OPC_CMP_ULE_D
= FOP(55, FMT_D
),
10699 OPC_CMP_SF_D
= FOP(56, FMT_D
),
10700 OPC_CMP_NGLE_D
= FOP(57, FMT_D
),
10701 OPC_CMP_SEQ_D
= FOP(58, FMT_D
),
10702 OPC_CMP_NGL_D
= FOP(59, FMT_D
),
10703 OPC_CMP_LT_D
= FOP(60, FMT_D
),
10704 OPC_CMP_NGE_D
= FOP(61, FMT_D
),
10705 OPC_CMP_LE_D
= FOP(62, FMT_D
),
10706 OPC_CMP_NGT_D
= FOP(63, FMT_D
),
10708 OPC_CVT_S_W
= FOP(32, FMT_W
),
10709 OPC_CVT_D_W
= FOP(33, FMT_W
),
10710 OPC_CVT_S_L
= FOP(32, FMT_L
),
10711 OPC_CVT_D_L
= FOP(33, FMT_L
),
10712 OPC_CVT_PS_PW
= FOP(38, FMT_W
),
10714 OPC_ADD_PS
= FOP(0, FMT_PS
),
10715 OPC_SUB_PS
= FOP(1, FMT_PS
),
10716 OPC_MUL_PS
= FOP(2, FMT_PS
),
10717 OPC_DIV_PS
= FOP(3, FMT_PS
),
10718 OPC_ABS_PS
= FOP(5, FMT_PS
),
10719 OPC_MOV_PS
= FOP(6, FMT_PS
),
10720 OPC_NEG_PS
= FOP(7, FMT_PS
),
10721 OPC_MOVCF_PS
= FOP(17, FMT_PS
),
10722 OPC_MOVZ_PS
= FOP(18, FMT_PS
),
10723 OPC_MOVN_PS
= FOP(19, FMT_PS
),
10724 OPC_ADDR_PS
= FOP(24, FMT_PS
),
10725 OPC_MULR_PS
= FOP(26, FMT_PS
),
10726 OPC_RECIP2_PS
= FOP(28, FMT_PS
),
10727 OPC_RECIP1_PS
= FOP(29, FMT_PS
),
10728 OPC_RSQRT1_PS
= FOP(30, FMT_PS
),
10729 OPC_RSQRT2_PS
= FOP(31, FMT_PS
),
10731 OPC_CVT_S_PU
= FOP(32, FMT_PS
),
10732 OPC_CVT_PW_PS
= FOP(36, FMT_PS
),
10733 OPC_CVT_S_PL
= FOP(40, FMT_PS
),
10734 OPC_PLL_PS
= FOP(44, FMT_PS
),
10735 OPC_PLU_PS
= FOP(45, FMT_PS
),
10736 OPC_PUL_PS
= FOP(46, FMT_PS
),
10737 OPC_PUU_PS
= FOP(47, FMT_PS
),
10738 OPC_CMP_F_PS
= FOP(48, FMT_PS
),
10739 OPC_CMP_UN_PS
= FOP(49, FMT_PS
),
10740 OPC_CMP_EQ_PS
= FOP(50, FMT_PS
),
10741 OPC_CMP_UEQ_PS
= FOP(51, FMT_PS
),
10742 OPC_CMP_OLT_PS
= FOP(52, FMT_PS
),
10743 OPC_CMP_ULT_PS
= FOP(53, FMT_PS
),
10744 OPC_CMP_OLE_PS
= FOP(54, FMT_PS
),
10745 OPC_CMP_ULE_PS
= FOP(55, FMT_PS
),
10746 OPC_CMP_SF_PS
= FOP(56, FMT_PS
),
10747 OPC_CMP_NGLE_PS
= FOP(57, FMT_PS
),
10748 OPC_CMP_SEQ_PS
= FOP(58, FMT_PS
),
10749 OPC_CMP_NGL_PS
= FOP(59, FMT_PS
),
10750 OPC_CMP_LT_PS
= FOP(60, FMT_PS
),
10751 OPC_CMP_NGE_PS
= FOP(61, FMT_PS
),
10752 OPC_CMP_LE_PS
= FOP(62, FMT_PS
),
10753 OPC_CMP_NGT_PS
= FOP(63, FMT_PS
),
10757 R6_OPC_CMP_AF_S
= FOP(0, FMT_W
),
10758 R6_OPC_CMP_UN_S
= FOP(1, FMT_W
),
10759 R6_OPC_CMP_EQ_S
= FOP(2, FMT_W
),
10760 R6_OPC_CMP_UEQ_S
= FOP(3, FMT_W
),
10761 R6_OPC_CMP_LT_S
= FOP(4, FMT_W
),
10762 R6_OPC_CMP_ULT_S
= FOP(5, FMT_W
),
10763 R6_OPC_CMP_LE_S
= FOP(6, FMT_W
),
10764 R6_OPC_CMP_ULE_S
= FOP(7, FMT_W
),
10765 R6_OPC_CMP_SAF_S
= FOP(8, FMT_W
),
10766 R6_OPC_CMP_SUN_S
= FOP(9, FMT_W
),
10767 R6_OPC_CMP_SEQ_S
= FOP(10, FMT_W
),
10768 R6_OPC_CMP_SEUQ_S
= FOP(11, FMT_W
),
10769 R6_OPC_CMP_SLT_S
= FOP(12, FMT_W
),
10770 R6_OPC_CMP_SULT_S
= FOP(13, FMT_W
),
10771 R6_OPC_CMP_SLE_S
= FOP(14, FMT_W
),
10772 R6_OPC_CMP_SULE_S
= FOP(15, FMT_W
),
10773 R6_OPC_CMP_OR_S
= FOP(17, FMT_W
),
10774 R6_OPC_CMP_UNE_S
= FOP(18, FMT_W
),
10775 R6_OPC_CMP_NE_S
= FOP(19, FMT_W
),
10776 R6_OPC_CMP_SOR_S
= FOP(25, FMT_W
),
10777 R6_OPC_CMP_SUNE_S
= FOP(26, FMT_W
),
10778 R6_OPC_CMP_SNE_S
= FOP(27, FMT_W
),
10780 R6_OPC_CMP_AF_D
= FOP(0, FMT_L
),
10781 R6_OPC_CMP_UN_D
= FOP(1, FMT_L
),
10782 R6_OPC_CMP_EQ_D
= FOP(2, FMT_L
),
10783 R6_OPC_CMP_UEQ_D
= FOP(3, FMT_L
),
10784 R6_OPC_CMP_LT_D
= FOP(4, FMT_L
),
10785 R6_OPC_CMP_ULT_D
= FOP(5, FMT_L
),
10786 R6_OPC_CMP_LE_D
= FOP(6, FMT_L
),
10787 R6_OPC_CMP_ULE_D
= FOP(7, FMT_L
),
10788 R6_OPC_CMP_SAF_D
= FOP(8, FMT_L
),
10789 R6_OPC_CMP_SUN_D
= FOP(9, FMT_L
),
10790 R6_OPC_CMP_SEQ_D
= FOP(10, FMT_L
),
10791 R6_OPC_CMP_SEUQ_D
= FOP(11, FMT_L
),
10792 R6_OPC_CMP_SLT_D
= FOP(12, FMT_L
),
10793 R6_OPC_CMP_SULT_D
= FOP(13, FMT_L
),
10794 R6_OPC_CMP_SLE_D
= FOP(14, FMT_L
),
10795 R6_OPC_CMP_SULE_D
= FOP(15, FMT_L
),
10796 R6_OPC_CMP_OR_D
= FOP(17, FMT_L
),
10797 R6_OPC_CMP_UNE_D
= FOP(18, FMT_L
),
10798 R6_OPC_CMP_NE_D
= FOP(19, FMT_L
),
10799 R6_OPC_CMP_SOR_D
= FOP(25, FMT_L
),
10800 R6_OPC_CMP_SUNE_D
= FOP(26, FMT_L
),
10801 R6_OPC_CMP_SNE_D
= FOP(27, FMT_L
),
10804 static void gen_cp1(DisasContext
*ctx
, uint32_t opc
, int rt
, int fs
)
10806 TCGv t0
= tcg_temp_new();
10811 TCGv_i32 fp0
= tcg_temp_new_i32();
10813 gen_load_fpr32(ctx
, fp0
, fs
);
10814 tcg_gen_ext_i32_tl(t0
, fp0
);
10815 tcg_temp_free_i32(fp0
);
10817 gen_store_gpr(t0
, rt
);
10820 gen_load_gpr(t0
, rt
);
10822 TCGv_i32 fp0
= tcg_temp_new_i32();
10824 tcg_gen_trunc_tl_i32(fp0
, t0
);
10825 gen_store_fpr32(ctx
, fp0
, fs
);
10826 tcg_temp_free_i32(fp0
);
10830 gen_helper_1e0i(cfc1
, t0
, fs
);
10831 gen_store_gpr(t0
, rt
);
10834 gen_load_gpr(t0
, rt
);
10835 save_cpu_state(ctx
, 0);
10837 TCGv_i32 fs_tmp
= tcg_const_i32(fs
);
10839 gen_helper_0e2i(ctc1
, t0
, fs_tmp
, rt
);
10840 tcg_temp_free_i32(fs_tmp
);
10842 /* Stop translation as we may have changed hflags */
10843 ctx
->base
.is_jmp
= DISAS_STOP
;
10845 #if defined(TARGET_MIPS64)
10847 gen_load_fpr64(ctx
, t0
, fs
);
10848 gen_store_gpr(t0
, rt
);
10851 gen_load_gpr(t0
, rt
);
10852 gen_store_fpr64(ctx
, t0
, fs
);
10857 TCGv_i32 fp0
= tcg_temp_new_i32();
10859 gen_load_fpr32h(ctx
, fp0
, fs
);
10860 tcg_gen_ext_i32_tl(t0
, fp0
);
10861 tcg_temp_free_i32(fp0
);
10863 gen_store_gpr(t0
, rt
);
10866 gen_load_gpr(t0
, rt
);
10868 TCGv_i32 fp0
= tcg_temp_new_i32();
10870 tcg_gen_trunc_tl_i32(fp0
, t0
);
10871 gen_store_fpr32h(ctx
, fp0
, fs
);
10872 tcg_temp_free_i32(fp0
);
10876 MIPS_INVAL("cp1 move");
10877 gen_reserved_instruction(ctx
);
10885 static void gen_movci(DisasContext
*ctx
, int rd
, int rs
, int cc
, int tf
)
10892 /* Treat as NOP. */
10897 cond
= TCG_COND_EQ
;
10899 cond
= TCG_COND_NE
;
10902 l1
= gen_new_label();
10903 t0
= tcg_temp_new_i32();
10904 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
10905 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
10906 tcg_temp_free_i32(t0
);
10908 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
10910 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
10915 static inline void gen_movcf_s(DisasContext
*ctx
, int fs
, int fd
, int cc
,
10919 TCGv_i32 t0
= tcg_temp_new_i32();
10920 TCGLabel
*l1
= gen_new_label();
10923 cond
= TCG_COND_EQ
;
10925 cond
= TCG_COND_NE
;
10928 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
10929 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
10930 gen_load_fpr32(ctx
, t0
, fs
);
10931 gen_store_fpr32(ctx
, t0
, fd
);
10933 tcg_temp_free_i32(t0
);
10936 static inline void gen_movcf_d(DisasContext
*ctx
, int fs
, int fd
, int cc
,
10940 TCGv_i32 t0
= tcg_temp_new_i32();
10942 TCGLabel
*l1
= gen_new_label();
10945 cond
= TCG_COND_EQ
;
10947 cond
= TCG_COND_NE
;
10950 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
10951 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
10952 tcg_temp_free_i32(t0
);
10953 fp0
= tcg_temp_new_i64();
10954 gen_load_fpr64(ctx
, fp0
, fs
);
10955 gen_store_fpr64(ctx
, fp0
, fd
);
10956 tcg_temp_free_i64(fp0
);
10960 static inline void gen_movcf_ps(DisasContext
*ctx
, int fs
, int fd
,
10964 TCGv_i32 t0
= tcg_temp_new_i32();
10965 TCGLabel
*l1
= gen_new_label();
10966 TCGLabel
*l2
= gen_new_label();
10969 cond
= TCG_COND_EQ
;
10971 cond
= TCG_COND_NE
;
10974 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
10975 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
10976 gen_load_fpr32(ctx
, t0
, fs
);
10977 gen_store_fpr32(ctx
, t0
, fd
);
10980 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
+ 1));
10981 tcg_gen_brcondi_i32(cond
, t0
, 0, l2
);
10982 gen_load_fpr32h(ctx
, t0
, fs
);
10983 gen_store_fpr32h(ctx
, t0
, fd
);
10984 tcg_temp_free_i32(t0
);
10988 static void gen_sel_s(DisasContext
*ctx
, enum fopcode op1
, int fd
, int ft
,
10991 TCGv_i32 t1
= tcg_const_i32(0);
10992 TCGv_i32 fp0
= tcg_temp_new_i32();
10993 TCGv_i32 fp1
= tcg_temp_new_i32();
10994 TCGv_i32 fp2
= tcg_temp_new_i32();
10995 gen_load_fpr32(ctx
, fp0
, fd
);
10996 gen_load_fpr32(ctx
, fp1
, ft
);
10997 gen_load_fpr32(ctx
, fp2
, fs
);
11001 tcg_gen_andi_i32(fp0
, fp0
, 1);
11002 tcg_gen_movcond_i32(TCG_COND_NE
, fp0
, fp0
, t1
, fp1
, fp2
);
11005 tcg_gen_andi_i32(fp1
, fp1
, 1);
11006 tcg_gen_movcond_i32(TCG_COND_EQ
, fp0
, fp1
, t1
, fp2
, t1
);
11009 tcg_gen_andi_i32(fp1
, fp1
, 1);
11010 tcg_gen_movcond_i32(TCG_COND_NE
, fp0
, fp1
, t1
, fp2
, t1
);
11013 MIPS_INVAL("gen_sel_s");
11014 gen_reserved_instruction(ctx
);
11018 gen_store_fpr32(ctx
, fp0
, fd
);
11019 tcg_temp_free_i32(fp2
);
11020 tcg_temp_free_i32(fp1
);
11021 tcg_temp_free_i32(fp0
);
11022 tcg_temp_free_i32(t1
);
11025 static void gen_sel_d(DisasContext
*ctx
, enum fopcode op1
, int fd
, int ft
,
11028 TCGv_i64 t1
= tcg_const_i64(0);
11029 TCGv_i64 fp0
= tcg_temp_new_i64();
11030 TCGv_i64 fp1
= tcg_temp_new_i64();
11031 TCGv_i64 fp2
= tcg_temp_new_i64();
11032 gen_load_fpr64(ctx
, fp0
, fd
);
11033 gen_load_fpr64(ctx
, fp1
, ft
);
11034 gen_load_fpr64(ctx
, fp2
, fs
);
11038 tcg_gen_andi_i64(fp0
, fp0
, 1);
11039 tcg_gen_movcond_i64(TCG_COND_NE
, fp0
, fp0
, t1
, fp1
, fp2
);
11042 tcg_gen_andi_i64(fp1
, fp1
, 1);
11043 tcg_gen_movcond_i64(TCG_COND_EQ
, fp0
, fp1
, t1
, fp2
, t1
);
11046 tcg_gen_andi_i64(fp1
, fp1
, 1);
11047 tcg_gen_movcond_i64(TCG_COND_NE
, fp0
, fp1
, t1
, fp2
, t1
);
11050 MIPS_INVAL("gen_sel_d");
11051 gen_reserved_instruction(ctx
);
11055 gen_store_fpr64(ctx
, fp0
, fd
);
11056 tcg_temp_free_i64(fp2
);
11057 tcg_temp_free_i64(fp1
);
11058 tcg_temp_free_i64(fp0
);
11059 tcg_temp_free_i64(t1
);
11062 static void gen_farith(DisasContext
*ctx
, enum fopcode op1
,
11063 int ft
, int fs
, int fd
, int cc
)
11065 uint32_t func
= ctx
->opcode
& 0x3f;
11069 TCGv_i32 fp0
= tcg_temp_new_i32();
11070 TCGv_i32 fp1
= tcg_temp_new_i32();
11072 gen_load_fpr32(ctx
, fp0
, fs
);
11073 gen_load_fpr32(ctx
, fp1
, ft
);
11074 gen_helper_float_add_s(fp0
, cpu_env
, fp0
, fp1
);
11075 tcg_temp_free_i32(fp1
);
11076 gen_store_fpr32(ctx
, fp0
, fd
);
11077 tcg_temp_free_i32(fp0
);
11082 TCGv_i32 fp0
= tcg_temp_new_i32();
11083 TCGv_i32 fp1
= tcg_temp_new_i32();
11085 gen_load_fpr32(ctx
, fp0
, fs
);
11086 gen_load_fpr32(ctx
, fp1
, ft
);
11087 gen_helper_float_sub_s(fp0
, cpu_env
, fp0
, fp1
);
11088 tcg_temp_free_i32(fp1
);
11089 gen_store_fpr32(ctx
, fp0
, fd
);
11090 tcg_temp_free_i32(fp0
);
11095 TCGv_i32 fp0
= tcg_temp_new_i32();
11096 TCGv_i32 fp1
= tcg_temp_new_i32();
11098 gen_load_fpr32(ctx
, fp0
, fs
);
11099 gen_load_fpr32(ctx
, fp1
, ft
);
11100 gen_helper_float_mul_s(fp0
, cpu_env
, fp0
, fp1
);
11101 tcg_temp_free_i32(fp1
);
11102 gen_store_fpr32(ctx
, fp0
, fd
);
11103 tcg_temp_free_i32(fp0
);
11108 TCGv_i32 fp0
= tcg_temp_new_i32();
11109 TCGv_i32 fp1
= tcg_temp_new_i32();
11111 gen_load_fpr32(ctx
, fp0
, fs
);
11112 gen_load_fpr32(ctx
, fp1
, ft
);
11113 gen_helper_float_div_s(fp0
, cpu_env
, fp0
, fp1
);
11114 tcg_temp_free_i32(fp1
);
11115 gen_store_fpr32(ctx
, fp0
, fd
);
11116 tcg_temp_free_i32(fp0
);
11121 TCGv_i32 fp0
= tcg_temp_new_i32();
11123 gen_load_fpr32(ctx
, fp0
, fs
);
11124 gen_helper_float_sqrt_s(fp0
, cpu_env
, fp0
);
11125 gen_store_fpr32(ctx
, fp0
, fd
);
11126 tcg_temp_free_i32(fp0
);
11131 TCGv_i32 fp0
= tcg_temp_new_i32();
11133 gen_load_fpr32(ctx
, fp0
, fs
);
11134 if (ctx
->abs2008
) {
11135 tcg_gen_andi_i32(fp0
, fp0
, 0x7fffffffUL
);
11137 gen_helper_float_abs_s(fp0
, fp0
);
11139 gen_store_fpr32(ctx
, fp0
, fd
);
11140 tcg_temp_free_i32(fp0
);
11145 TCGv_i32 fp0
= tcg_temp_new_i32();
11147 gen_load_fpr32(ctx
, fp0
, fs
);
11148 gen_store_fpr32(ctx
, fp0
, fd
);
11149 tcg_temp_free_i32(fp0
);
11154 TCGv_i32 fp0
= tcg_temp_new_i32();
11156 gen_load_fpr32(ctx
, fp0
, fs
);
11157 if (ctx
->abs2008
) {
11158 tcg_gen_xori_i32(fp0
, fp0
, 1UL << 31);
11160 gen_helper_float_chs_s(fp0
, fp0
);
11162 gen_store_fpr32(ctx
, fp0
, fd
);
11163 tcg_temp_free_i32(fp0
);
11166 case OPC_ROUND_L_S
:
11167 check_cp1_64bitmode(ctx
);
11169 TCGv_i32 fp32
= tcg_temp_new_i32();
11170 TCGv_i64 fp64
= tcg_temp_new_i64();
11172 gen_load_fpr32(ctx
, fp32
, fs
);
11173 if (ctx
->nan2008
) {
11174 gen_helper_float_round_2008_l_s(fp64
, cpu_env
, fp32
);
11176 gen_helper_float_round_l_s(fp64
, cpu_env
, fp32
);
11178 tcg_temp_free_i32(fp32
);
11179 gen_store_fpr64(ctx
, fp64
, fd
);
11180 tcg_temp_free_i64(fp64
);
11183 case OPC_TRUNC_L_S
:
11184 check_cp1_64bitmode(ctx
);
11186 TCGv_i32 fp32
= tcg_temp_new_i32();
11187 TCGv_i64 fp64
= tcg_temp_new_i64();
11189 gen_load_fpr32(ctx
, fp32
, fs
);
11190 if (ctx
->nan2008
) {
11191 gen_helper_float_trunc_2008_l_s(fp64
, cpu_env
, fp32
);
11193 gen_helper_float_trunc_l_s(fp64
, cpu_env
, fp32
);
11195 tcg_temp_free_i32(fp32
);
11196 gen_store_fpr64(ctx
, fp64
, fd
);
11197 tcg_temp_free_i64(fp64
);
11201 check_cp1_64bitmode(ctx
);
11203 TCGv_i32 fp32
= tcg_temp_new_i32();
11204 TCGv_i64 fp64
= tcg_temp_new_i64();
11206 gen_load_fpr32(ctx
, fp32
, fs
);
11207 if (ctx
->nan2008
) {
11208 gen_helper_float_ceil_2008_l_s(fp64
, cpu_env
, fp32
);
11210 gen_helper_float_ceil_l_s(fp64
, cpu_env
, fp32
);
11212 tcg_temp_free_i32(fp32
);
11213 gen_store_fpr64(ctx
, fp64
, fd
);
11214 tcg_temp_free_i64(fp64
);
11217 case OPC_FLOOR_L_S
:
11218 check_cp1_64bitmode(ctx
);
11220 TCGv_i32 fp32
= tcg_temp_new_i32();
11221 TCGv_i64 fp64
= tcg_temp_new_i64();
11223 gen_load_fpr32(ctx
, fp32
, fs
);
11224 if (ctx
->nan2008
) {
11225 gen_helper_float_floor_2008_l_s(fp64
, cpu_env
, fp32
);
11227 gen_helper_float_floor_l_s(fp64
, cpu_env
, fp32
);
11229 tcg_temp_free_i32(fp32
);
11230 gen_store_fpr64(ctx
, fp64
, fd
);
11231 tcg_temp_free_i64(fp64
);
11234 case OPC_ROUND_W_S
:
11236 TCGv_i32 fp0
= tcg_temp_new_i32();
11238 gen_load_fpr32(ctx
, fp0
, fs
);
11239 if (ctx
->nan2008
) {
11240 gen_helper_float_round_2008_w_s(fp0
, cpu_env
, fp0
);
11242 gen_helper_float_round_w_s(fp0
, cpu_env
, fp0
);
11244 gen_store_fpr32(ctx
, fp0
, fd
);
11245 tcg_temp_free_i32(fp0
);
11248 case OPC_TRUNC_W_S
:
11250 TCGv_i32 fp0
= tcg_temp_new_i32();
11252 gen_load_fpr32(ctx
, fp0
, fs
);
11253 if (ctx
->nan2008
) {
11254 gen_helper_float_trunc_2008_w_s(fp0
, cpu_env
, fp0
);
11256 gen_helper_float_trunc_w_s(fp0
, cpu_env
, fp0
);
11258 gen_store_fpr32(ctx
, fp0
, fd
);
11259 tcg_temp_free_i32(fp0
);
11264 TCGv_i32 fp0
= tcg_temp_new_i32();
11266 gen_load_fpr32(ctx
, fp0
, fs
);
11267 if (ctx
->nan2008
) {
11268 gen_helper_float_ceil_2008_w_s(fp0
, cpu_env
, fp0
);
11270 gen_helper_float_ceil_w_s(fp0
, cpu_env
, fp0
);
11272 gen_store_fpr32(ctx
, fp0
, fd
);
11273 tcg_temp_free_i32(fp0
);
11276 case OPC_FLOOR_W_S
:
11278 TCGv_i32 fp0
= tcg_temp_new_i32();
11280 gen_load_fpr32(ctx
, fp0
, fs
);
11281 if (ctx
->nan2008
) {
11282 gen_helper_float_floor_2008_w_s(fp0
, cpu_env
, fp0
);
11284 gen_helper_float_floor_w_s(fp0
, cpu_env
, fp0
);
11286 gen_store_fpr32(ctx
, fp0
, fd
);
11287 tcg_temp_free_i32(fp0
);
11291 check_insn(ctx
, ISA_MIPS_R6
);
11292 gen_sel_s(ctx
, op1
, fd
, ft
, fs
);
11295 check_insn(ctx
, ISA_MIPS_R6
);
11296 gen_sel_s(ctx
, op1
, fd
, ft
, fs
);
11299 check_insn(ctx
, ISA_MIPS_R6
);
11300 gen_sel_s(ctx
, op1
, fd
, ft
, fs
);
11303 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
11304 gen_movcf_s(ctx
, fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
11307 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
11309 TCGLabel
*l1
= gen_new_label();
11313 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
11315 fp0
= tcg_temp_new_i32();
11316 gen_load_fpr32(ctx
, fp0
, fs
);
11317 gen_store_fpr32(ctx
, fp0
, fd
);
11318 tcg_temp_free_i32(fp0
);
11323 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
11325 TCGLabel
*l1
= gen_new_label();
11329 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
11330 fp0
= tcg_temp_new_i32();
11331 gen_load_fpr32(ctx
, fp0
, fs
);
11332 gen_store_fpr32(ctx
, fp0
, fd
);
11333 tcg_temp_free_i32(fp0
);
11340 TCGv_i32 fp0
= tcg_temp_new_i32();
11342 gen_load_fpr32(ctx
, fp0
, fs
);
11343 gen_helper_float_recip_s(fp0
, cpu_env
, fp0
);
11344 gen_store_fpr32(ctx
, fp0
, fd
);
11345 tcg_temp_free_i32(fp0
);
11350 TCGv_i32 fp0
= tcg_temp_new_i32();
11352 gen_load_fpr32(ctx
, fp0
, fs
);
11353 gen_helper_float_rsqrt_s(fp0
, cpu_env
, fp0
);
11354 gen_store_fpr32(ctx
, fp0
, fd
);
11355 tcg_temp_free_i32(fp0
);
11359 check_insn(ctx
, ISA_MIPS_R6
);
11361 TCGv_i32 fp0
= tcg_temp_new_i32();
11362 TCGv_i32 fp1
= tcg_temp_new_i32();
11363 TCGv_i32 fp2
= tcg_temp_new_i32();
11364 gen_load_fpr32(ctx
, fp0
, fs
);
11365 gen_load_fpr32(ctx
, fp1
, ft
);
11366 gen_load_fpr32(ctx
, fp2
, fd
);
11367 gen_helper_float_maddf_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
11368 gen_store_fpr32(ctx
, fp2
, fd
);
11369 tcg_temp_free_i32(fp2
);
11370 tcg_temp_free_i32(fp1
);
11371 tcg_temp_free_i32(fp0
);
11375 check_insn(ctx
, ISA_MIPS_R6
);
11377 TCGv_i32 fp0
= tcg_temp_new_i32();
11378 TCGv_i32 fp1
= tcg_temp_new_i32();
11379 TCGv_i32 fp2
= tcg_temp_new_i32();
11380 gen_load_fpr32(ctx
, fp0
, fs
);
11381 gen_load_fpr32(ctx
, fp1
, ft
);
11382 gen_load_fpr32(ctx
, fp2
, fd
);
11383 gen_helper_float_msubf_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
11384 gen_store_fpr32(ctx
, fp2
, fd
);
11385 tcg_temp_free_i32(fp2
);
11386 tcg_temp_free_i32(fp1
);
11387 tcg_temp_free_i32(fp0
);
11391 check_insn(ctx
, ISA_MIPS_R6
);
11393 TCGv_i32 fp0
= tcg_temp_new_i32();
11394 gen_load_fpr32(ctx
, fp0
, fs
);
11395 gen_helper_float_rint_s(fp0
, cpu_env
, fp0
);
11396 gen_store_fpr32(ctx
, fp0
, fd
);
11397 tcg_temp_free_i32(fp0
);
11401 check_insn(ctx
, ISA_MIPS_R6
);
11403 TCGv_i32 fp0
= tcg_temp_new_i32();
11404 gen_load_fpr32(ctx
, fp0
, fs
);
11405 gen_helper_float_class_s(fp0
, cpu_env
, fp0
);
11406 gen_store_fpr32(ctx
, fp0
, fd
);
11407 tcg_temp_free_i32(fp0
);
11410 case OPC_MIN_S
: /* OPC_RECIP2_S */
11411 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
11413 TCGv_i32 fp0
= tcg_temp_new_i32();
11414 TCGv_i32 fp1
= tcg_temp_new_i32();
11415 TCGv_i32 fp2
= tcg_temp_new_i32();
11416 gen_load_fpr32(ctx
, fp0
, fs
);
11417 gen_load_fpr32(ctx
, fp1
, ft
);
11418 gen_helper_float_min_s(fp2
, cpu_env
, fp0
, fp1
);
11419 gen_store_fpr32(ctx
, fp2
, fd
);
11420 tcg_temp_free_i32(fp2
);
11421 tcg_temp_free_i32(fp1
);
11422 tcg_temp_free_i32(fp0
);
11425 check_cp1_64bitmode(ctx
);
11427 TCGv_i32 fp0
= tcg_temp_new_i32();
11428 TCGv_i32 fp1
= tcg_temp_new_i32();
11430 gen_load_fpr32(ctx
, fp0
, fs
);
11431 gen_load_fpr32(ctx
, fp1
, ft
);
11432 gen_helper_float_recip2_s(fp0
, cpu_env
, fp0
, fp1
);
11433 tcg_temp_free_i32(fp1
);
11434 gen_store_fpr32(ctx
, fp0
, fd
);
11435 tcg_temp_free_i32(fp0
);
11439 case OPC_MINA_S
: /* OPC_RECIP1_S */
11440 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
11442 TCGv_i32 fp0
= tcg_temp_new_i32();
11443 TCGv_i32 fp1
= tcg_temp_new_i32();
11444 TCGv_i32 fp2
= tcg_temp_new_i32();
11445 gen_load_fpr32(ctx
, fp0
, fs
);
11446 gen_load_fpr32(ctx
, fp1
, ft
);
11447 gen_helper_float_mina_s(fp2
, cpu_env
, fp0
, fp1
);
11448 gen_store_fpr32(ctx
, fp2
, fd
);
11449 tcg_temp_free_i32(fp2
);
11450 tcg_temp_free_i32(fp1
);
11451 tcg_temp_free_i32(fp0
);
11454 check_cp1_64bitmode(ctx
);
11456 TCGv_i32 fp0
= tcg_temp_new_i32();
11458 gen_load_fpr32(ctx
, fp0
, fs
);
11459 gen_helper_float_recip1_s(fp0
, cpu_env
, fp0
);
11460 gen_store_fpr32(ctx
, fp0
, fd
);
11461 tcg_temp_free_i32(fp0
);
11465 case OPC_MAX_S
: /* OPC_RSQRT1_S */
11466 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
11468 TCGv_i32 fp0
= tcg_temp_new_i32();
11469 TCGv_i32 fp1
= tcg_temp_new_i32();
11470 gen_load_fpr32(ctx
, fp0
, fs
);
11471 gen_load_fpr32(ctx
, fp1
, ft
);
11472 gen_helper_float_max_s(fp1
, cpu_env
, fp0
, fp1
);
11473 gen_store_fpr32(ctx
, fp1
, fd
);
11474 tcg_temp_free_i32(fp1
);
11475 tcg_temp_free_i32(fp0
);
11478 check_cp1_64bitmode(ctx
);
11480 TCGv_i32 fp0
= tcg_temp_new_i32();
11482 gen_load_fpr32(ctx
, fp0
, fs
);
11483 gen_helper_float_rsqrt1_s(fp0
, cpu_env
, fp0
);
11484 gen_store_fpr32(ctx
, fp0
, fd
);
11485 tcg_temp_free_i32(fp0
);
11489 case OPC_MAXA_S
: /* OPC_RSQRT2_S */
11490 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
11492 TCGv_i32 fp0
= tcg_temp_new_i32();
11493 TCGv_i32 fp1
= tcg_temp_new_i32();
11494 gen_load_fpr32(ctx
, fp0
, fs
);
11495 gen_load_fpr32(ctx
, fp1
, ft
);
11496 gen_helper_float_maxa_s(fp1
, cpu_env
, fp0
, fp1
);
11497 gen_store_fpr32(ctx
, fp1
, fd
);
11498 tcg_temp_free_i32(fp1
);
11499 tcg_temp_free_i32(fp0
);
11502 check_cp1_64bitmode(ctx
);
11504 TCGv_i32 fp0
= tcg_temp_new_i32();
11505 TCGv_i32 fp1
= tcg_temp_new_i32();
11507 gen_load_fpr32(ctx
, fp0
, fs
);
11508 gen_load_fpr32(ctx
, fp1
, ft
);
11509 gen_helper_float_rsqrt2_s(fp0
, cpu_env
, fp0
, fp1
);
11510 tcg_temp_free_i32(fp1
);
11511 gen_store_fpr32(ctx
, fp0
, fd
);
11512 tcg_temp_free_i32(fp0
);
11517 check_cp1_registers(ctx
, fd
);
11519 TCGv_i32 fp32
= tcg_temp_new_i32();
11520 TCGv_i64 fp64
= tcg_temp_new_i64();
11522 gen_load_fpr32(ctx
, fp32
, fs
);
11523 gen_helper_float_cvtd_s(fp64
, cpu_env
, fp32
);
11524 tcg_temp_free_i32(fp32
);
11525 gen_store_fpr64(ctx
, fp64
, fd
);
11526 tcg_temp_free_i64(fp64
);
11531 TCGv_i32 fp0
= tcg_temp_new_i32();
11533 gen_load_fpr32(ctx
, fp0
, fs
);
11534 if (ctx
->nan2008
) {
11535 gen_helper_float_cvt_2008_w_s(fp0
, cpu_env
, fp0
);
11537 gen_helper_float_cvt_w_s(fp0
, cpu_env
, fp0
);
11539 gen_store_fpr32(ctx
, fp0
, fd
);
11540 tcg_temp_free_i32(fp0
);
11544 check_cp1_64bitmode(ctx
);
11546 TCGv_i32 fp32
= tcg_temp_new_i32();
11547 TCGv_i64 fp64
= tcg_temp_new_i64();
11549 gen_load_fpr32(ctx
, fp32
, fs
);
11550 if (ctx
->nan2008
) {
11551 gen_helper_float_cvt_2008_l_s(fp64
, cpu_env
, fp32
);
11553 gen_helper_float_cvt_l_s(fp64
, cpu_env
, fp32
);
11555 tcg_temp_free_i32(fp32
);
11556 gen_store_fpr64(ctx
, fp64
, fd
);
11557 tcg_temp_free_i64(fp64
);
11563 TCGv_i64 fp64
= tcg_temp_new_i64();
11564 TCGv_i32 fp32_0
= tcg_temp_new_i32();
11565 TCGv_i32 fp32_1
= tcg_temp_new_i32();
11567 gen_load_fpr32(ctx
, fp32_0
, fs
);
11568 gen_load_fpr32(ctx
, fp32_1
, ft
);
11569 tcg_gen_concat_i32_i64(fp64
, fp32_1
, fp32_0
);
11570 tcg_temp_free_i32(fp32_1
);
11571 tcg_temp_free_i32(fp32_0
);
11572 gen_store_fpr64(ctx
, fp64
, fd
);
11573 tcg_temp_free_i64(fp64
);
11579 case OPC_CMP_UEQ_S
:
11580 case OPC_CMP_OLT_S
:
11581 case OPC_CMP_ULT_S
:
11582 case OPC_CMP_OLE_S
:
11583 case OPC_CMP_ULE_S
:
11585 case OPC_CMP_NGLE_S
:
11586 case OPC_CMP_SEQ_S
:
11587 case OPC_CMP_NGL_S
:
11589 case OPC_CMP_NGE_S
:
11591 case OPC_CMP_NGT_S
:
11592 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
11593 if (ctx
->opcode
& (1 << 6)) {
11594 gen_cmpabs_s(ctx
, func
- 48, ft
, fs
, cc
);
11596 gen_cmp_s(ctx
, func
- 48, ft
, fs
, cc
);
11600 check_cp1_registers(ctx
, fs
| ft
| fd
);
11602 TCGv_i64 fp0
= tcg_temp_new_i64();
11603 TCGv_i64 fp1
= tcg_temp_new_i64();
11605 gen_load_fpr64(ctx
, fp0
, fs
);
11606 gen_load_fpr64(ctx
, fp1
, ft
);
11607 gen_helper_float_add_d(fp0
, cpu_env
, fp0
, fp1
);
11608 tcg_temp_free_i64(fp1
);
11609 gen_store_fpr64(ctx
, fp0
, fd
);
11610 tcg_temp_free_i64(fp0
);
11614 check_cp1_registers(ctx
, fs
| ft
| fd
);
11616 TCGv_i64 fp0
= tcg_temp_new_i64();
11617 TCGv_i64 fp1
= tcg_temp_new_i64();
11619 gen_load_fpr64(ctx
, fp0
, fs
);
11620 gen_load_fpr64(ctx
, fp1
, ft
);
11621 gen_helper_float_sub_d(fp0
, cpu_env
, fp0
, fp1
);
11622 tcg_temp_free_i64(fp1
);
11623 gen_store_fpr64(ctx
, fp0
, fd
);
11624 tcg_temp_free_i64(fp0
);
11628 check_cp1_registers(ctx
, fs
| ft
| fd
);
11630 TCGv_i64 fp0
= tcg_temp_new_i64();
11631 TCGv_i64 fp1
= tcg_temp_new_i64();
11633 gen_load_fpr64(ctx
, fp0
, fs
);
11634 gen_load_fpr64(ctx
, fp1
, ft
);
11635 gen_helper_float_mul_d(fp0
, cpu_env
, fp0
, fp1
);
11636 tcg_temp_free_i64(fp1
);
11637 gen_store_fpr64(ctx
, fp0
, fd
);
11638 tcg_temp_free_i64(fp0
);
11642 check_cp1_registers(ctx
, fs
| ft
| fd
);
11644 TCGv_i64 fp0
= tcg_temp_new_i64();
11645 TCGv_i64 fp1
= tcg_temp_new_i64();
11647 gen_load_fpr64(ctx
, fp0
, fs
);
11648 gen_load_fpr64(ctx
, fp1
, ft
);
11649 gen_helper_float_div_d(fp0
, cpu_env
, fp0
, fp1
);
11650 tcg_temp_free_i64(fp1
);
11651 gen_store_fpr64(ctx
, fp0
, fd
);
11652 tcg_temp_free_i64(fp0
);
11656 check_cp1_registers(ctx
, fs
| fd
);
11658 TCGv_i64 fp0
= tcg_temp_new_i64();
11660 gen_load_fpr64(ctx
, fp0
, fs
);
11661 gen_helper_float_sqrt_d(fp0
, cpu_env
, fp0
);
11662 gen_store_fpr64(ctx
, fp0
, fd
);
11663 tcg_temp_free_i64(fp0
);
11667 check_cp1_registers(ctx
, fs
| fd
);
11669 TCGv_i64 fp0
= tcg_temp_new_i64();
11671 gen_load_fpr64(ctx
, fp0
, fs
);
11672 if (ctx
->abs2008
) {
11673 tcg_gen_andi_i64(fp0
, fp0
, 0x7fffffffffffffffULL
);
11675 gen_helper_float_abs_d(fp0
, fp0
);
11677 gen_store_fpr64(ctx
, fp0
, fd
);
11678 tcg_temp_free_i64(fp0
);
11682 check_cp1_registers(ctx
, fs
| fd
);
11684 TCGv_i64 fp0
= tcg_temp_new_i64();
11686 gen_load_fpr64(ctx
, fp0
, fs
);
11687 gen_store_fpr64(ctx
, fp0
, fd
);
11688 tcg_temp_free_i64(fp0
);
11692 check_cp1_registers(ctx
, fs
| fd
);
11694 TCGv_i64 fp0
= tcg_temp_new_i64();
11696 gen_load_fpr64(ctx
, fp0
, fs
);
11697 if (ctx
->abs2008
) {
11698 tcg_gen_xori_i64(fp0
, fp0
, 1ULL << 63);
11700 gen_helper_float_chs_d(fp0
, fp0
);
11702 gen_store_fpr64(ctx
, fp0
, fd
);
11703 tcg_temp_free_i64(fp0
);
11706 case OPC_ROUND_L_D
:
11707 check_cp1_64bitmode(ctx
);
11709 TCGv_i64 fp0
= tcg_temp_new_i64();
11711 gen_load_fpr64(ctx
, fp0
, fs
);
11712 if (ctx
->nan2008
) {
11713 gen_helper_float_round_2008_l_d(fp0
, cpu_env
, fp0
);
11715 gen_helper_float_round_l_d(fp0
, cpu_env
, fp0
);
11717 gen_store_fpr64(ctx
, fp0
, fd
);
11718 tcg_temp_free_i64(fp0
);
11721 case OPC_TRUNC_L_D
:
11722 check_cp1_64bitmode(ctx
);
11724 TCGv_i64 fp0
= tcg_temp_new_i64();
11726 gen_load_fpr64(ctx
, fp0
, fs
);
11727 if (ctx
->nan2008
) {
11728 gen_helper_float_trunc_2008_l_d(fp0
, cpu_env
, fp0
);
11730 gen_helper_float_trunc_l_d(fp0
, cpu_env
, fp0
);
11732 gen_store_fpr64(ctx
, fp0
, fd
);
11733 tcg_temp_free_i64(fp0
);
11737 check_cp1_64bitmode(ctx
);
11739 TCGv_i64 fp0
= tcg_temp_new_i64();
11741 gen_load_fpr64(ctx
, fp0
, fs
);
11742 if (ctx
->nan2008
) {
11743 gen_helper_float_ceil_2008_l_d(fp0
, cpu_env
, fp0
);
11745 gen_helper_float_ceil_l_d(fp0
, cpu_env
, fp0
);
11747 gen_store_fpr64(ctx
, fp0
, fd
);
11748 tcg_temp_free_i64(fp0
);
11751 case OPC_FLOOR_L_D
:
11752 check_cp1_64bitmode(ctx
);
11754 TCGv_i64 fp0
= tcg_temp_new_i64();
11756 gen_load_fpr64(ctx
, fp0
, fs
);
11757 if (ctx
->nan2008
) {
11758 gen_helper_float_floor_2008_l_d(fp0
, cpu_env
, fp0
);
11760 gen_helper_float_floor_l_d(fp0
, cpu_env
, fp0
);
11762 gen_store_fpr64(ctx
, fp0
, fd
);
11763 tcg_temp_free_i64(fp0
);
11766 case OPC_ROUND_W_D
:
11767 check_cp1_registers(ctx
, fs
);
11769 TCGv_i32 fp32
= tcg_temp_new_i32();
11770 TCGv_i64 fp64
= tcg_temp_new_i64();
11772 gen_load_fpr64(ctx
, fp64
, fs
);
11773 if (ctx
->nan2008
) {
11774 gen_helper_float_round_2008_w_d(fp32
, cpu_env
, fp64
);
11776 gen_helper_float_round_w_d(fp32
, cpu_env
, fp64
);
11778 tcg_temp_free_i64(fp64
);
11779 gen_store_fpr32(ctx
, fp32
, fd
);
11780 tcg_temp_free_i32(fp32
);
11783 case OPC_TRUNC_W_D
:
11784 check_cp1_registers(ctx
, fs
);
11786 TCGv_i32 fp32
= tcg_temp_new_i32();
11787 TCGv_i64 fp64
= tcg_temp_new_i64();
11789 gen_load_fpr64(ctx
, fp64
, fs
);
11790 if (ctx
->nan2008
) {
11791 gen_helper_float_trunc_2008_w_d(fp32
, cpu_env
, fp64
);
11793 gen_helper_float_trunc_w_d(fp32
, cpu_env
, fp64
);
11795 tcg_temp_free_i64(fp64
);
11796 gen_store_fpr32(ctx
, fp32
, fd
);
11797 tcg_temp_free_i32(fp32
);
11801 check_cp1_registers(ctx
, fs
);
11803 TCGv_i32 fp32
= tcg_temp_new_i32();
11804 TCGv_i64 fp64
= tcg_temp_new_i64();
11806 gen_load_fpr64(ctx
, fp64
, fs
);
11807 if (ctx
->nan2008
) {
11808 gen_helper_float_ceil_2008_w_d(fp32
, cpu_env
, fp64
);
11810 gen_helper_float_ceil_w_d(fp32
, cpu_env
, fp64
);
11812 tcg_temp_free_i64(fp64
);
11813 gen_store_fpr32(ctx
, fp32
, fd
);
11814 tcg_temp_free_i32(fp32
);
11817 case OPC_FLOOR_W_D
:
11818 check_cp1_registers(ctx
, fs
);
11820 TCGv_i32 fp32
= tcg_temp_new_i32();
11821 TCGv_i64 fp64
= tcg_temp_new_i64();
11823 gen_load_fpr64(ctx
, fp64
, fs
);
11824 if (ctx
->nan2008
) {
11825 gen_helper_float_floor_2008_w_d(fp32
, cpu_env
, fp64
);
11827 gen_helper_float_floor_w_d(fp32
, cpu_env
, fp64
);
11829 tcg_temp_free_i64(fp64
);
11830 gen_store_fpr32(ctx
, fp32
, fd
);
11831 tcg_temp_free_i32(fp32
);
11835 check_insn(ctx
, ISA_MIPS_R6
);
11836 gen_sel_d(ctx
, op1
, fd
, ft
, fs
);
11839 check_insn(ctx
, ISA_MIPS_R6
);
11840 gen_sel_d(ctx
, op1
, fd
, ft
, fs
);
11843 check_insn(ctx
, ISA_MIPS_R6
);
11844 gen_sel_d(ctx
, op1
, fd
, ft
, fs
);
11847 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
11848 gen_movcf_d(ctx
, fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
11851 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
11853 TCGLabel
*l1
= gen_new_label();
11857 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
11859 fp0
= tcg_temp_new_i64();
11860 gen_load_fpr64(ctx
, fp0
, fs
);
11861 gen_store_fpr64(ctx
, fp0
, fd
);
11862 tcg_temp_free_i64(fp0
);
11867 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
11869 TCGLabel
*l1
= gen_new_label();
11873 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
11874 fp0
= tcg_temp_new_i64();
11875 gen_load_fpr64(ctx
, fp0
, fs
);
11876 gen_store_fpr64(ctx
, fp0
, fd
);
11877 tcg_temp_free_i64(fp0
);
11883 check_cp1_registers(ctx
, fs
| fd
);
11885 TCGv_i64 fp0
= tcg_temp_new_i64();
11887 gen_load_fpr64(ctx
, fp0
, fs
);
11888 gen_helper_float_recip_d(fp0
, cpu_env
, fp0
);
11889 gen_store_fpr64(ctx
, fp0
, fd
);
11890 tcg_temp_free_i64(fp0
);
11894 check_cp1_registers(ctx
, fs
| fd
);
11896 TCGv_i64 fp0
= tcg_temp_new_i64();
11898 gen_load_fpr64(ctx
, fp0
, fs
);
11899 gen_helper_float_rsqrt_d(fp0
, cpu_env
, fp0
);
11900 gen_store_fpr64(ctx
, fp0
, fd
);
11901 tcg_temp_free_i64(fp0
);
11905 check_insn(ctx
, ISA_MIPS_R6
);
11907 TCGv_i64 fp0
= tcg_temp_new_i64();
11908 TCGv_i64 fp1
= tcg_temp_new_i64();
11909 TCGv_i64 fp2
= tcg_temp_new_i64();
11910 gen_load_fpr64(ctx
, fp0
, fs
);
11911 gen_load_fpr64(ctx
, fp1
, ft
);
11912 gen_load_fpr64(ctx
, fp2
, fd
);
11913 gen_helper_float_maddf_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
11914 gen_store_fpr64(ctx
, fp2
, fd
);
11915 tcg_temp_free_i64(fp2
);
11916 tcg_temp_free_i64(fp1
);
11917 tcg_temp_free_i64(fp0
);
11921 check_insn(ctx
, ISA_MIPS_R6
);
11923 TCGv_i64 fp0
= tcg_temp_new_i64();
11924 TCGv_i64 fp1
= tcg_temp_new_i64();
11925 TCGv_i64 fp2
= tcg_temp_new_i64();
11926 gen_load_fpr64(ctx
, fp0
, fs
);
11927 gen_load_fpr64(ctx
, fp1
, ft
);
11928 gen_load_fpr64(ctx
, fp2
, fd
);
11929 gen_helper_float_msubf_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
11930 gen_store_fpr64(ctx
, fp2
, fd
);
11931 tcg_temp_free_i64(fp2
);
11932 tcg_temp_free_i64(fp1
);
11933 tcg_temp_free_i64(fp0
);
11937 check_insn(ctx
, ISA_MIPS_R6
);
11939 TCGv_i64 fp0
= tcg_temp_new_i64();
11940 gen_load_fpr64(ctx
, fp0
, fs
);
11941 gen_helper_float_rint_d(fp0
, cpu_env
, fp0
);
11942 gen_store_fpr64(ctx
, fp0
, fd
);
11943 tcg_temp_free_i64(fp0
);
11947 check_insn(ctx
, ISA_MIPS_R6
);
11949 TCGv_i64 fp0
= tcg_temp_new_i64();
11950 gen_load_fpr64(ctx
, fp0
, fs
);
11951 gen_helper_float_class_d(fp0
, cpu_env
, fp0
);
11952 gen_store_fpr64(ctx
, fp0
, fd
);
11953 tcg_temp_free_i64(fp0
);
11956 case OPC_MIN_D
: /* OPC_RECIP2_D */
11957 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
11959 TCGv_i64 fp0
= tcg_temp_new_i64();
11960 TCGv_i64 fp1
= tcg_temp_new_i64();
11961 gen_load_fpr64(ctx
, fp0
, fs
);
11962 gen_load_fpr64(ctx
, fp1
, ft
);
11963 gen_helper_float_min_d(fp1
, cpu_env
, fp0
, fp1
);
11964 gen_store_fpr64(ctx
, fp1
, fd
);
11965 tcg_temp_free_i64(fp1
);
11966 tcg_temp_free_i64(fp0
);
11969 check_cp1_64bitmode(ctx
);
11971 TCGv_i64 fp0
= tcg_temp_new_i64();
11972 TCGv_i64 fp1
= tcg_temp_new_i64();
11974 gen_load_fpr64(ctx
, fp0
, fs
);
11975 gen_load_fpr64(ctx
, fp1
, ft
);
11976 gen_helper_float_recip2_d(fp0
, cpu_env
, fp0
, fp1
);
11977 tcg_temp_free_i64(fp1
);
11978 gen_store_fpr64(ctx
, fp0
, fd
);
11979 tcg_temp_free_i64(fp0
);
11983 case OPC_MINA_D
: /* OPC_RECIP1_D */
11984 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
11986 TCGv_i64 fp0
= tcg_temp_new_i64();
11987 TCGv_i64 fp1
= tcg_temp_new_i64();
11988 gen_load_fpr64(ctx
, fp0
, fs
);
11989 gen_load_fpr64(ctx
, fp1
, ft
);
11990 gen_helper_float_mina_d(fp1
, cpu_env
, fp0
, fp1
);
11991 gen_store_fpr64(ctx
, fp1
, fd
);
11992 tcg_temp_free_i64(fp1
);
11993 tcg_temp_free_i64(fp0
);
11996 check_cp1_64bitmode(ctx
);
11998 TCGv_i64 fp0
= tcg_temp_new_i64();
12000 gen_load_fpr64(ctx
, fp0
, fs
);
12001 gen_helper_float_recip1_d(fp0
, cpu_env
, fp0
);
12002 gen_store_fpr64(ctx
, fp0
, fd
);
12003 tcg_temp_free_i64(fp0
);
12007 case OPC_MAX_D
: /* OPC_RSQRT1_D */
12008 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
12010 TCGv_i64 fp0
= tcg_temp_new_i64();
12011 TCGv_i64 fp1
= tcg_temp_new_i64();
12012 gen_load_fpr64(ctx
, fp0
, fs
);
12013 gen_load_fpr64(ctx
, fp1
, ft
);
12014 gen_helper_float_max_d(fp1
, cpu_env
, fp0
, fp1
);
12015 gen_store_fpr64(ctx
, fp1
, fd
);
12016 tcg_temp_free_i64(fp1
);
12017 tcg_temp_free_i64(fp0
);
12020 check_cp1_64bitmode(ctx
);
12022 TCGv_i64 fp0
= tcg_temp_new_i64();
12024 gen_load_fpr64(ctx
, fp0
, fs
);
12025 gen_helper_float_rsqrt1_d(fp0
, cpu_env
, fp0
);
12026 gen_store_fpr64(ctx
, fp0
, fd
);
12027 tcg_temp_free_i64(fp0
);
12031 case OPC_MAXA_D
: /* OPC_RSQRT2_D */
12032 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
12034 TCGv_i64 fp0
= tcg_temp_new_i64();
12035 TCGv_i64 fp1
= tcg_temp_new_i64();
12036 gen_load_fpr64(ctx
, fp0
, fs
);
12037 gen_load_fpr64(ctx
, fp1
, ft
);
12038 gen_helper_float_maxa_d(fp1
, cpu_env
, fp0
, fp1
);
12039 gen_store_fpr64(ctx
, fp1
, fd
);
12040 tcg_temp_free_i64(fp1
);
12041 tcg_temp_free_i64(fp0
);
12044 check_cp1_64bitmode(ctx
);
12046 TCGv_i64 fp0
= tcg_temp_new_i64();
12047 TCGv_i64 fp1
= tcg_temp_new_i64();
12049 gen_load_fpr64(ctx
, fp0
, fs
);
12050 gen_load_fpr64(ctx
, fp1
, ft
);
12051 gen_helper_float_rsqrt2_d(fp0
, cpu_env
, fp0
, fp1
);
12052 tcg_temp_free_i64(fp1
);
12053 gen_store_fpr64(ctx
, fp0
, fd
);
12054 tcg_temp_free_i64(fp0
);
12061 case OPC_CMP_UEQ_D
:
12062 case OPC_CMP_OLT_D
:
12063 case OPC_CMP_ULT_D
:
12064 case OPC_CMP_OLE_D
:
12065 case OPC_CMP_ULE_D
:
12067 case OPC_CMP_NGLE_D
:
12068 case OPC_CMP_SEQ_D
:
12069 case OPC_CMP_NGL_D
:
12071 case OPC_CMP_NGE_D
:
12073 case OPC_CMP_NGT_D
:
12074 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
12075 if (ctx
->opcode
& (1 << 6)) {
12076 gen_cmpabs_d(ctx
, func
- 48, ft
, fs
, cc
);
12078 gen_cmp_d(ctx
, func
- 48, ft
, fs
, cc
);
12082 check_cp1_registers(ctx
, fs
);
12084 TCGv_i32 fp32
= tcg_temp_new_i32();
12085 TCGv_i64 fp64
= tcg_temp_new_i64();
12087 gen_load_fpr64(ctx
, fp64
, fs
);
12088 gen_helper_float_cvts_d(fp32
, cpu_env
, fp64
);
12089 tcg_temp_free_i64(fp64
);
12090 gen_store_fpr32(ctx
, fp32
, fd
);
12091 tcg_temp_free_i32(fp32
);
12095 check_cp1_registers(ctx
, fs
);
12097 TCGv_i32 fp32
= tcg_temp_new_i32();
12098 TCGv_i64 fp64
= tcg_temp_new_i64();
12100 gen_load_fpr64(ctx
, fp64
, fs
);
12101 if (ctx
->nan2008
) {
12102 gen_helper_float_cvt_2008_w_d(fp32
, cpu_env
, fp64
);
12104 gen_helper_float_cvt_w_d(fp32
, cpu_env
, fp64
);
12106 tcg_temp_free_i64(fp64
);
12107 gen_store_fpr32(ctx
, fp32
, fd
);
12108 tcg_temp_free_i32(fp32
);
12112 check_cp1_64bitmode(ctx
);
12114 TCGv_i64 fp0
= tcg_temp_new_i64();
12116 gen_load_fpr64(ctx
, fp0
, fs
);
12117 if (ctx
->nan2008
) {
12118 gen_helper_float_cvt_2008_l_d(fp0
, cpu_env
, fp0
);
12120 gen_helper_float_cvt_l_d(fp0
, cpu_env
, fp0
);
12122 gen_store_fpr64(ctx
, fp0
, fd
);
12123 tcg_temp_free_i64(fp0
);
12128 TCGv_i32 fp0
= tcg_temp_new_i32();
12130 gen_load_fpr32(ctx
, fp0
, fs
);
12131 gen_helper_float_cvts_w(fp0
, cpu_env
, fp0
);
12132 gen_store_fpr32(ctx
, fp0
, fd
);
12133 tcg_temp_free_i32(fp0
);
12137 check_cp1_registers(ctx
, fd
);
12139 TCGv_i32 fp32
= tcg_temp_new_i32();
12140 TCGv_i64 fp64
= tcg_temp_new_i64();
12142 gen_load_fpr32(ctx
, fp32
, fs
);
12143 gen_helper_float_cvtd_w(fp64
, cpu_env
, fp32
);
12144 tcg_temp_free_i32(fp32
);
12145 gen_store_fpr64(ctx
, fp64
, fd
);
12146 tcg_temp_free_i64(fp64
);
12150 check_cp1_64bitmode(ctx
);
12152 TCGv_i32 fp32
= tcg_temp_new_i32();
12153 TCGv_i64 fp64
= tcg_temp_new_i64();
12155 gen_load_fpr64(ctx
, fp64
, fs
);
12156 gen_helper_float_cvts_l(fp32
, cpu_env
, fp64
);
12157 tcg_temp_free_i64(fp64
);
12158 gen_store_fpr32(ctx
, fp32
, fd
);
12159 tcg_temp_free_i32(fp32
);
12163 check_cp1_64bitmode(ctx
);
12165 TCGv_i64 fp0
= tcg_temp_new_i64();
12167 gen_load_fpr64(ctx
, fp0
, fs
);
12168 gen_helper_float_cvtd_l(fp0
, cpu_env
, fp0
);
12169 gen_store_fpr64(ctx
, fp0
, fd
);
12170 tcg_temp_free_i64(fp0
);
12173 case OPC_CVT_PS_PW
:
12176 TCGv_i64 fp0
= tcg_temp_new_i64();
12178 gen_load_fpr64(ctx
, fp0
, fs
);
12179 gen_helper_float_cvtps_pw(fp0
, cpu_env
, fp0
);
12180 gen_store_fpr64(ctx
, fp0
, fd
);
12181 tcg_temp_free_i64(fp0
);
12187 TCGv_i64 fp0
= tcg_temp_new_i64();
12188 TCGv_i64 fp1
= tcg_temp_new_i64();
12190 gen_load_fpr64(ctx
, fp0
, fs
);
12191 gen_load_fpr64(ctx
, fp1
, ft
);
12192 gen_helper_float_add_ps(fp0
, cpu_env
, fp0
, fp1
);
12193 tcg_temp_free_i64(fp1
);
12194 gen_store_fpr64(ctx
, fp0
, fd
);
12195 tcg_temp_free_i64(fp0
);
12201 TCGv_i64 fp0
= tcg_temp_new_i64();
12202 TCGv_i64 fp1
= tcg_temp_new_i64();
12204 gen_load_fpr64(ctx
, fp0
, fs
);
12205 gen_load_fpr64(ctx
, fp1
, ft
);
12206 gen_helper_float_sub_ps(fp0
, cpu_env
, fp0
, fp1
);
12207 tcg_temp_free_i64(fp1
);
12208 gen_store_fpr64(ctx
, fp0
, fd
);
12209 tcg_temp_free_i64(fp0
);
12215 TCGv_i64 fp0
= tcg_temp_new_i64();
12216 TCGv_i64 fp1
= tcg_temp_new_i64();
12218 gen_load_fpr64(ctx
, fp0
, fs
);
12219 gen_load_fpr64(ctx
, fp1
, ft
);
12220 gen_helper_float_mul_ps(fp0
, cpu_env
, fp0
, fp1
);
12221 tcg_temp_free_i64(fp1
);
12222 gen_store_fpr64(ctx
, fp0
, fd
);
12223 tcg_temp_free_i64(fp0
);
12229 TCGv_i64 fp0
= tcg_temp_new_i64();
12231 gen_load_fpr64(ctx
, fp0
, fs
);
12232 gen_helper_float_abs_ps(fp0
, fp0
);
12233 gen_store_fpr64(ctx
, fp0
, fd
);
12234 tcg_temp_free_i64(fp0
);
12240 TCGv_i64 fp0
= tcg_temp_new_i64();
12242 gen_load_fpr64(ctx
, fp0
, fs
);
12243 gen_store_fpr64(ctx
, fp0
, fd
);
12244 tcg_temp_free_i64(fp0
);
12250 TCGv_i64 fp0
= tcg_temp_new_i64();
12252 gen_load_fpr64(ctx
, fp0
, fs
);
12253 gen_helper_float_chs_ps(fp0
, fp0
);
12254 gen_store_fpr64(ctx
, fp0
, fd
);
12255 tcg_temp_free_i64(fp0
);
12260 gen_movcf_ps(ctx
, fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
12265 TCGLabel
*l1
= gen_new_label();
12269 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
12271 fp0
= tcg_temp_new_i64();
12272 gen_load_fpr64(ctx
, fp0
, fs
);
12273 gen_store_fpr64(ctx
, fp0
, fd
);
12274 tcg_temp_free_i64(fp0
);
12281 TCGLabel
*l1
= gen_new_label();
12285 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
12286 fp0
= tcg_temp_new_i64();
12287 gen_load_fpr64(ctx
, fp0
, fs
);
12288 gen_store_fpr64(ctx
, fp0
, fd
);
12289 tcg_temp_free_i64(fp0
);
12297 TCGv_i64 fp0
= tcg_temp_new_i64();
12298 TCGv_i64 fp1
= tcg_temp_new_i64();
12300 gen_load_fpr64(ctx
, fp0
, ft
);
12301 gen_load_fpr64(ctx
, fp1
, fs
);
12302 gen_helper_float_addr_ps(fp0
, cpu_env
, fp0
, fp1
);
12303 tcg_temp_free_i64(fp1
);
12304 gen_store_fpr64(ctx
, fp0
, fd
);
12305 tcg_temp_free_i64(fp0
);
12311 TCGv_i64 fp0
= tcg_temp_new_i64();
12312 TCGv_i64 fp1
= tcg_temp_new_i64();
12314 gen_load_fpr64(ctx
, fp0
, ft
);
12315 gen_load_fpr64(ctx
, fp1
, fs
);
12316 gen_helper_float_mulr_ps(fp0
, cpu_env
, fp0
, fp1
);
12317 tcg_temp_free_i64(fp1
);
12318 gen_store_fpr64(ctx
, fp0
, fd
);
12319 tcg_temp_free_i64(fp0
);
12322 case OPC_RECIP2_PS
:
12325 TCGv_i64 fp0
= tcg_temp_new_i64();
12326 TCGv_i64 fp1
= tcg_temp_new_i64();
12328 gen_load_fpr64(ctx
, fp0
, fs
);
12329 gen_load_fpr64(ctx
, fp1
, ft
);
12330 gen_helper_float_recip2_ps(fp0
, cpu_env
, fp0
, fp1
);
12331 tcg_temp_free_i64(fp1
);
12332 gen_store_fpr64(ctx
, fp0
, fd
);
12333 tcg_temp_free_i64(fp0
);
12336 case OPC_RECIP1_PS
:
12339 TCGv_i64 fp0
= tcg_temp_new_i64();
12341 gen_load_fpr64(ctx
, fp0
, fs
);
12342 gen_helper_float_recip1_ps(fp0
, cpu_env
, fp0
);
12343 gen_store_fpr64(ctx
, fp0
, fd
);
12344 tcg_temp_free_i64(fp0
);
12347 case OPC_RSQRT1_PS
:
12350 TCGv_i64 fp0
= tcg_temp_new_i64();
12352 gen_load_fpr64(ctx
, fp0
, fs
);
12353 gen_helper_float_rsqrt1_ps(fp0
, cpu_env
, fp0
);
12354 gen_store_fpr64(ctx
, fp0
, fd
);
12355 tcg_temp_free_i64(fp0
);
12358 case OPC_RSQRT2_PS
:
12361 TCGv_i64 fp0
= tcg_temp_new_i64();
12362 TCGv_i64 fp1
= tcg_temp_new_i64();
12364 gen_load_fpr64(ctx
, fp0
, fs
);
12365 gen_load_fpr64(ctx
, fp1
, ft
);
12366 gen_helper_float_rsqrt2_ps(fp0
, cpu_env
, fp0
, fp1
);
12367 tcg_temp_free_i64(fp1
);
12368 gen_store_fpr64(ctx
, fp0
, fd
);
12369 tcg_temp_free_i64(fp0
);
12373 check_cp1_64bitmode(ctx
);
12375 TCGv_i32 fp0
= tcg_temp_new_i32();
12377 gen_load_fpr32h(ctx
, fp0
, fs
);
12378 gen_helper_float_cvts_pu(fp0
, cpu_env
, fp0
);
12379 gen_store_fpr32(ctx
, fp0
, fd
);
12380 tcg_temp_free_i32(fp0
);
12383 case OPC_CVT_PW_PS
:
12386 TCGv_i64 fp0
= tcg_temp_new_i64();
12388 gen_load_fpr64(ctx
, fp0
, fs
);
12389 gen_helper_float_cvtpw_ps(fp0
, cpu_env
, fp0
);
12390 gen_store_fpr64(ctx
, fp0
, fd
);
12391 tcg_temp_free_i64(fp0
);
12395 check_cp1_64bitmode(ctx
);
12397 TCGv_i32 fp0
= tcg_temp_new_i32();
12399 gen_load_fpr32(ctx
, fp0
, fs
);
12400 gen_helper_float_cvts_pl(fp0
, cpu_env
, fp0
);
12401 gen_store_fpr32(ctx
, fp0
, fd
);
12402 tcg_temp_free_i32(fp0
);
12408 TCGv_i32 fp0
= tcg_temp_new_i32();
12409 TCGv_i32 fp1
= tcg_temp_new_i32();
12411 gen_load_fpr32(ctx
, fp0
, fs
);
12412 gen_load_fpr32(ctx
, fp1
, ft
);
12413 gen_store_fpr32h(ctx
, fp0
, fd
);
12414 gen_store_fpr32(ctx
, fp1
, fd
);
12415 tcg_temp_free_i32(fp0
);
12416 tcg_temp_free_i32(fp1
);
12422 TCGv_i32 fp0
= tcg_temp_new_i32();
12423 TCGv_i32 fp1
= tcg_temp_new_i32();
12425 gen_load_fpr32(ctx
, fp0
, fs
);
12426 gen_load_fpr32h(ctx
, fp1
, ft
);
12427 gen_store_fpr32(ctx
, fp1
, fd
);
12428 gen_store_fpr32h(ctx
, fp0
, fd
);
12429 tcg_temp_free_i32(fp0
);
12430 tcg_temp_free_i32(fp1
);
12436 TCGv_i32 fp0
= tcg_temp_new_i32();
12437 TCGv_i32 fp1
= tcg_temp_new_i32();
12439 gen_load_fpr32h(ctx
, fp0
, fs
);
12440 gen_load_fpr32(ctx
, fp1
, ft
);
12441 gen_store_fpr32(ctx
, fp1
, fd
);
12442 gen_store_fpr32h(ctx
, fp0
, fd
);
12443 tcg_temp_free_i32(fp0
);
12444 tcg_temp_free_i32(fp1
);
12450 TCGv_i32 fp0
= tcg_temp_new_i32();
12451 TCGv_i32 fp1
= tcg_temp_new_i32();
12453 gen_load_fpr32h(ctx
, fp0
, fs
);
12454 gen_load_fpr32h(ctx
, fp1
, ft
);
12455 gen_store_fpr32(ctx
, fp1
, fd
);
12456 gen_store_fpr32h(ctx
, fp0
, fd
);
12457 tcg_temp_free_i32(fp0
);
12458 tcg_temp_free_i32(fp1
);
12462 case OPC_CMP_UN_PS
:
12463 case OPC_CMP_EQ_PS
:
12464 case OPC_CMP_UEQ_PS
:
12465 case OPC_CMP_OLT_PS
:
12466 case OPC_CMP_ULT_PS
:
12467 case OPC_CMP_OLE_PS
:
12468 case OPC_CMP_ULE_PS
:
12469 case OPC_CMP_SF_PS
:
12470 case OPC_CMP_NGLE_PS
:
12471 case OPC_CMP_SEQ_PS
:
12472 case OPC_CMP_NGL_PS
:
12473 case OPC_CMP_LT_PS
:
12474 case OPC_CMP_NGE_PS
:
12475 case OPC_CMP_LE_PS
:
12476 case OPC_CMP_NGT_PS
:
12477 if (ctx
->opcode
& (1 << 6)) {
12478 gen_cmpabs_ps(ctx
, func
- 48, ft
, fs
, cc
);
12480 gen_cmp_ps(ctx
, func
- 48, ft
, fs
, cc
);
12484 MIPS_INVAL("farith");
12485 gen_reserved_instruction(ctx
);
12490 /* Coprocessor 3 (FPU) */
12491 static void gen_flt3_ldst(DisasContext
*ctx
, uint32_t opc
,
12492 int fd
, int fs
, int base
, int index
)
12494 TCGv t0
= tcg_temp_new();
12497 gen_load_gpr(t0
, index
);
12498 } else if (index
== 0) {
12499 gen_load_gpr(t0
, base
);
12501 gen_op_addr_add(ctx
, t0
, cpu_gpr
[base
], cpu_gpr
[index
]);
12504 * Don't do NOP if destination is zero: we must perform the actual
12511 TCGv_i32 fp0
= tcg_temp_new_i32();
12513 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESL
);
12514 tcg_gen_trunc_tl_i32(fp0
, t0
);
12515 gen_store_fpr32(ctx
, fp0
, fd
);
12516 tcg_temp_free_i32(fp0
);
12521 check_cp1_registers(ctx
, fd
);
12523 TCGv_i64 fp0
= tcg_temp_new_i64();
12524 tcg_gen_qemu_ld_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
12525 gen_store_fpr64(ctx
, fp0
, fd
);
12526 tcg_temp_free_i64(fp0
);
12530 check_cp1_64bitmode(ctx
);
12531 tcg_gen_andi_tl(t0
, t0
, ~0x7);
12533 TCGv_i64 fp0
= tcg_temp_new_i64();
12535 tcg_gen_qemu_ld_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
12536 gen_store_fpr64(ctx
, fp0
, fd
);
12537 tcg_temp_free_i64(fp0
);
12543 TCGv_i32 fp0
= tcg_temp_new_i32();
12544 gen_load_fpr32(ctx
, fp0
, fs
);
12545 tcg_gen_qemu_st_i32(fp0
, t0
, ctx
->mem_idx
, MO_TEUL
);
12546 tcg_temp_free_i32(fp0
);
12551 check_cp1_registers(ctx
, fs
);
12553 TCGv_i64 fp0
= tcg_temp_new_i64();
12554 gen_load_fpr64(ctx
, fp0
, fs
);
12555 tcg_gen_qemu_st_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
12556 tcg_temp_free_i64(fp0
);
12560 check_cp1_64bitmode(ctx
);
12561 tcg_gen_andi_tl(t0
, t0
, ~0x7);
12563 TCGv_i64 fp0
= tcg_temp_new_i64();
12564 gen_load_fpr64(ctx
, fp0
, fs
);
12565 tcg_gen_qemu_st_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
12566 tcg_temp_free_i64(fp0
);
12573 static void gen_flt3_arith(DisasContext
*ctx
, uint32_t opc
,
12574 int fd
, int fr
, int fs
, int ft
)
12580 TCGv t0
= tcg_temp_local_new();
12581 TCGv_i32 fp
= tcg_temp_new_i32();
12582 TCGv_i32 fph
= tcg_temp_new_i32();
12583 TCGLabel
*l1
= gen_new_label();
12584 TCGLabel
*l2
= gen_new_label();
12586 gen_load_gpr(t0
, fr
);
12587 tcg_gen_andi_tl(t0
, t0
, 0x7);
12589 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, 0, l1
);
12590 gen_load_fpr32(ctx
, fp
, fs
);
12591 gen_load_fpr32h(ctx
, fph
, fs
);
12592 gen_store_fpr32(ctx
, fp
, fd
);
12593 gen_store_fpr32h(ctx
, fph
, fd
);
12596 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, 4, l2
);
12598 #ifdef TARGET_WORDS_BIGENDIAN
12599 gen_load_fpr32(ctx
, fp
, fs
);
12600 gen_load_fpr32h(ctx
, fph
, ft
);
12601 gen_store_fpr32h(ctx
, fp
, fd
);
12602 gen_store_fpr32(ctx
, fph
, fd
);
12604 gen_load_fpr32h(ctx
, fph
, fs
);
12605 gen_load_fpr32(ctx
, fp
, ft
);
12606 gen_store_fpr32(ctx
, fph
, fd
);
12607 gen_store_fpr32h(ctx
, fp
, fd
);
12610 tcg_temp_free_i32(fp
);
12611 tcg_temp_free_i32(fph
);
12617 TCGv_i32 fp0
= tcg_temp_new_i32();
12618 TCGv_i32 fp1
= tcg_temp_new_i32();
12619 TCGv_i32 fp2
= tcg_temp_new_i32();
12621 gen_load_fpr32(ctx
, fp0
, fs
);
12622 gen_load_fpr32(ctx
, fp1
, ft
);
12623 gen_load_fpr32(ctx
, fp2
, fr
);
12624 gen_helper_float_madd_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12625 tcg_temp_free_i32(fp0
);
12626 tcg_temp_free_i32(fp1
);
12627 gen_store_fpr32(ctx
, fp2
, fd
);
12628 tcg_temp_free_i32(fp2
);
12633 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
12635 TCGv_i64 fp0
= tcg_temp_new_i64();
12636 TCGv_i64 fp1
= tcg_temp_new_i64();
12637 TCGv_i64 fp2
= tcg_temp_new_i64();
12639 gen_load_fpr64(ctx
, fp0
, fs
);
12640 gen_load_fpr64(ctx
, fp1
, ft
);
12641 gen_load_fpr64(ctx
, fp2
, fr
);
12642 gen_helper_float_madd_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12643 tcg_temp_free_i64(fp0
);
12644 tcg_temp_free_i64(fp1
);
12645 gen_store_fpr64(ctx
, fp2
, fd
);
12646 tcg_temp_free_i64(fp2
);
12652 TCGv_i64 fp0
= tcg_temp_new_i64();
12653 TCGv_i64 fp1
= tcg_temp_new_i64();
12654 TCGv_i64 fp2
= tcg_temp_new_i64();
12656 gen_load_fpr64(ctx
, fp0
, fs
);
12657 gen_load_fpr64(ctx
, fp1
, ft
);
12658 gen_load_fpr64(ctx
, fp2
, fr
);
12659 gen_helper_float_madd_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12660 tcg_temp_free_i64(fp0
);
12661 tcg_temp_free_i64(fp1
);
12662 gen_store_fpr64(ctx
, fp2
, fd
);
12663 tcg_temp_free_i64(fp2
);
12669 TCGv_i32 fp0
= tcg_temp_new_i32();
12670 TCGv_i32 fp1
= tcg_temp_new_i32();
12671 TCGv_i32 fp2
= tcg_temp_new_i32();
12673 gen_load_fpr32(ctx
, fp0
, fs
);
12674 gen_load_fpr32(ctx
, fp1
, ft
);
12675 gen_load_fpr32(ctx
, fp2
, fr
);
12676 gen_helper_float_msub_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12677 tcg_temp_free_i32(fp0
);
12678 tcg_temp_free_i32(fp1
);
12679 gen_store_fpr32(ctx
, fp2
, fd
);
12680 tcg_temp_free_i32(fp2
);
12685 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
12687 TCGv_i64 fp0
= tcg_temp_new_i64();
12688 TCGv_i64 fp1
= tcg_temp_new_i64();
12689 TCGv_i64 fp2
= tcg_temp_new_i64();
12691 gen_load_fpr64(ctx
, fp0
, fs
);
12692 gen_load_fpr64(ctx
, fp1
, ft
);
12693 gen_load_fpr64(ctx
, fp2
, fr
);
12694 gen_helper_float_msub_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12695 tcg_temp_free_i64(fp0
);
12696 tcg_temp_free_i64(fp1
);
12697 gen_store_fpr64(ctx
, fp2
, fd
);
12698 tcg_temp_free_i64(fp2
);
12704 TCGv_i64 fp0
= tcg_temp_new_i64();
12705 TCGv_i64 fp1
= tcg_temp_new_i64();
12706 TCGv_i64 fp2
= tcg_temp_new_i64();
12708 gen_load_fpr64(ctx
, fp0
, fs
);
12709 gen_load_fpr64(ctx
, fp1
, ft
);
12710 gen_load_fpr64(ctx
, fp2
, fr
);
12711 gen_helper_float_msub_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12712 tcg_temp_free_i64(fp0
);
12713 tcg_temp_free_i64(fp1
);
12714 gen_store_fpr64(ctx
, fp2
, fd
);
12715 tcg_temp_free_i64(fp2
);
12721 TCGv_i32 fp0
= tcg_temp_new_i32();
12722 TCGv_i32 fp1
= tcg_temp_new_i32();
12723 TCGv_i32 fp2
= tcg_temp_new_i32();
12725 gen_load_fpr32(ctx
, fp0
, fs
);
12726 gen_load_fpr32(ctx
, fp1
, ft
);
12727 gen_load_fpr32(ctx
, fp2
, fr
);
12728 gen_helper_float_nmadd_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12729 tcg_temp_free_i32(fp0
);
12730 tcg_temp_free_i32(fp1
);
12731 gen_store_fpr32(ctx
, fp2
, fd
);
12732 tcg_temp_free_i32(fp2
);
12737 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
12739 TCGv_i64 fp0
= tcg_temp_new_i64();
12740 TCGv_i64 fp1
= tcg_temp_new_i64();
12741 TCGv_i64 fp2
= tcg_temp_new_i64();
12743 gen_load_fpr64(ctx
, fp0
, fs
);
12744 gen_load_fpr64(ctx
, fp1
, ft
);
12745 gen_load_fpr64(ctx
, fp2
, fr
);
12746 gen_helper_float_nmadd_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12747 tcg_temp_free_i64(fp0
);
12748 tcg_temp_free_i64(fp1
);
12749 gen_store_fpr64(ctx
, fp2
, fd
);
12750 tcg_temp_free_i64(fp2
);
12756 TCGv_i64 fp0
= tcg_temp_new_i64();
12757 TCGv_i64 fp1
= tcg_temp_new_i64();
12758 TCGv_i64 fp2
= tcg_temp_new_i64();
12760 gen_load_fpr64(ctx
, fp0
, fs
);
12761 gen_load_fpr64(ctx
, fp1
, ft
);
12762 gen_load_fpr64(ctx
, fp2
, fr
);
12763 gen_helper_float_nmadd_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12764 tcg_temp_free_i64(fp0
);
12765 tcg_temp_free_i64(fp1
);
12766 gen_store_fpr64(ctx
, fp2
, fd
);
12767 tcg_temp_free_i64(fp2
);
12773 TCGv_i32 fp0
= tcg_temp_new_i32();
12774 TCGv_i32 fp1
= tcg_temp_new_i32();
12775 TCGv_i32 fp2
= tcg_temp_new_i32();
12777 gen_load_fpr32(ctx
, fp0
, fs
);
12778 gen_load_fpr32(ctx
, fp1
, ft
);
12779 gen_load_fpr32(ctx
, fp2
, fr
);
12780 gen_helper_float_nmsub_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12781 tcg_temp_free_i32(fp0
);
12782 tcg_temp_free_i32(fp1
);
12783 gen_store_fpr32(ctx
, fp2
, fd
);
12784 tcg_temp_free_i32(fp2
);
12789 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
12791 TCGv_i64 fp0
= tcg_temp_new_i64();
12792 TCGv_i64 fp1
= tcg_temp_new_i64();
12793 TCGv_i64 fp2
= tcg_temp_new_i64();
12795 gen_load_fpr64(ctx
, fp0
, fs
);
12796 gen_load_fpr64(ctx
, fp1
, ft
);
12797 gen_load_fpr64(ctx
, fp2
, fr
);
12798 gen_helper_float_nmsub_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12799 tcg_temp_free_i64(fp0
);
12800 tcg_temp_free_i64(fp1
);
12801 gen_store_fpr64(ctx
, fp2
, fd
);
12802 tcg_temp_free_i64(fp2
);
12808 TCGv_i64 fp0
= tcg_temp_new_i64();
12809 TCGv_i64 fp1
= tcg_temp_new_i64();
12810 TCGv_i64 fp2
= tcg_temp_new_i64();
12812 gen_load_fpr64(ctx
, fp0
, fs
);
12813 gen_load_fpr64(ctx
, fp1
, ft
);
12814 gen_load_fpr64(ctx
, fp2
, fr
);
12815 gen_helper_float_nmsub_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12816 tcg_temp_free_i64(fp0
);
12817 tcg_temp_free_i64(fp1
);
12818 gen_store_fpr64(ctx
, fp2
, fd
);
12819 tcg_temp_free_i64(fp2
);
12823 MIPS_INVAL("flt3_arith");
12824 gen_reserved_instruction(ctx
);
12829 static void gen_rdhwr(DisasContext
*ctx
, int rt
, int rd
, int sel
)
12833 #if !defined(CONFIG_USER_ONLY)
12835 * The Linux kernel will emulate rdhwr if it's not supported natively.
12836 * Therefore only check the ISA in system mode.
12838 check_insn(ctx
, ISA_MIPS_R2
);
12840 t0
= tcg_temp_new();
12844 gen_helper_rdhwr_cpunum(t0
, cpu_env
);
12845 gen_store_gpr(t0
, rt
);
12848 gen_helper_rdhwr_synci_step(t0
, cpu_env
);
12849 gen_store_gpr(t0
, rt
);
12852 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
12855 gen_helper_rdhwr_cc(t0
, cpu_env
);
12856 gen_store_gpr(t0
, rt
);
12858 * Break the TB to be able to take timer interrupts immediately
12859 * after reading count. DISAS_STOP isn't sufficient, we need to ensure
12860 * we break completely out of translated code.
12862 gen_save_pc(ctx
->base
.pc_next
+ 4);
12863 ctx
->base
.is_jmp
= DISAS_EXIT
;
12866 gen_helper_rdhwr_ccres(t0
, cpu_env
);
12867 gen_store_gpr(t0
, rt
);
12870 check_insn(ctx
, ISA_MIPS_R6
);
12873 * Performance counter registers are not implemented other than
12874 * control register 0.
12876 generate_exception(ctx
, EXCP_RI
);
12878 gen_helper_rdhwr_performance(t0
, cpu_env
);
12879 gen_store_gpr(t0
, rt
);
12882 check_insn(ctx
, ISA_MIPS_R6
);
12883 gen_helper_rdhwr_xnp(t0
, cpu_env
);
12884 gen_store_gpr(t0
, rt
);
12887 #if defined(CONFIG_USER_ONLY)
12888 tcg_gen_ld_tl(t0
, cpu_env
,
12889 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
12890 gen_store_gpr(t0
, rt
);
12893 if ((ctx
->hflags
& MIPS_HFLAG_CP0
) ||
12894 (ctx
->hflags
& MIPS_HFLAG_HWRENA_ULR
)) {
12895 tcg_gen_ld_tl(t0
, cpu_env
,
12896 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
12897 gen_store_gpr(t0
, rt
);
12899 gen_reserved_instruction(ctx
);
12903 default: /* Invalid */
12904 MIPS_INVAL("rdhwr");
12905 gen_reserved_instruction(ctx
);
12911 static inline void clear_branch_hflags(DisasContext
*ctx
)
12913 ctx
->hflags
&= ~MIPS_HFLAG_BMASK
;
12914 if (ctx
->base
.is_jmp
== DISAS_NEXT
) {
12915 save_cpu_state(ctx
, 0);
12918 * It is not safe to save ctx->hflags as hflags may be changed
12919 * in execution time by the instruction in delay / forbidden slot.
12921 tcg_gen_andi_i32(hflags
, hflags
, ~MIPS_HFLAG_BMASK
);
12925 static void gen_branch(DisasContext
*ctx
, int insn_bytes
)
12927 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
12928 int proc_hflags
= ctx
->hflags
& MIPS_HFLAG_BMASK
;
12929 /* Branches completion */
12930 clear_branch_hflags(ctx
);
12931 ctx
->base
.is_jmp
= DISAS_NORETURN
;
12932 /* FIXME: Need to clear can_do_io. */
12933 switch (proc_hflags
& MIPS_HFLAG_BMASK_BASE
) {
12934 case MIPS_HFLAG_FBNSLOT
:
12935 gen_goto_tb(ctx
, 0, ctx
->base
.pc_next
+ insn_bytes
);
12938 /* unconditional branch */
12939 if (proc_hflags
& MIPS_HFLAG_BX
) {
12940 tcg_gen_xori_i32(hflags
, hflags
, MIPS_HFLAG_M16
);
12942 gen_goto_tb(ctx
, 0, ctx
->btarget
);
12944 case MIPS_HFLAG_BL
:
12945 /* blikely taken case */
12946 gen_goto_tb(ctx
, 0, ctx
->btarget
);
12948 case MIPS_HFLAG_BC
:
12949 /* Conditional branch */
12951 TCGLabel
*l1
= gen_new_label();
12953 tcg_gen_brcondi_tl(TCG_COND_NE
, bcond
, 0, l1
);
12954 gen_goto_tb(ctx
, 1, ctx
->base
.pc_next
+ insn_bytes
);
12956 gen_goto_tb(ctx
, 0, ctx
->btarget
);
12959 case MIPS_HFLAG_BR
:
12960 /* unconditional branch to register */
12961 if (ctx
->insn_flags
& (ASE_MIPS16
| ASE_MICROMIPS
)) {
12962 TCGv t0
= tcg_temp_new();
12963 TCGv_i32 t1
= tcg_temp_new_i32();
12965 tcg_gen_andi_tl(t0
, btarget
, 0x1);
12966 tcg_gen_trunc_tl_i32(t1
, t0
);
12968 tcg_gen_andi_i32(hflags
, hflags
, ~(uint32_t)MIPS_HFLAG_M16
);
12969 tcg_gen_shli_i32(t1
, t1
, MIPS_HFLAG_M16_SHIFT
);
12970 tcg_gen_or_i32(hflags
, hflags
, t1
);
12971 tcg_temp_free_i32(t1
);
12973 tcg_gen_andi_tl(cpu_PC
, btarget
, ~(target_ulong
)0x1);
12975 tcg_gen_mov_tl(cpu_PC
, btarget
);
12977 if (ctx
->base
.singlestep_enabled
) {
12978 save_cpu_state(ctx
, 0);
12979 gen_helper_raise_exception_debug(cpu_env
);
12981 tcg_gen_lookup_and_goto_ptr();
12984 fprintf(stderr
, "unknown branch 0x%x\n", proc_hflags
);
12990 /* Compact Branches */
12991 static void gen_compute_compact_branch(DisasContext
*ctx
, uint32_t opc
,
12992 int rs
, int rt
, int32_t offset
)
12994 int bcond_compute
= 0;
12995 TCGv t0
= tcg_temp_new();
12996 TCGv t1
= tcg_temp_new();
12997 int m16_lowbit
= (ctx
->hflags
& MIPS_HFLAG_M16
) != 0;
12999 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
13000 #ifdef MIPS_DEBUG_DISAS
13001 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
13002 "\n", ctx
->base
.pc_next
);
13004 gen_reserved_instruction(ctx
);
13008 /* Load needed operands and calculate btarget */
13010 /* compact branch */
13011 case OPC_BOVC
: /* OPC_BEQZALC, OPC_BEQC */
13012 case OPC_BNVC
: /* OPC_BNEZALC, OPC_BNEC */
13013 gen_load_gpr(t0
, rs
);
13014 gen_load_gpr(t1
, rt
);
13016 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
13017 if (rs
<= rt
&& rs
== 0) {
13018 /* OPC_BEQZALC, OPC_BNEZALC */
13019 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 4 + m16_lowbit
);
13022 case OPC_BLEZC
: /* OPC_BGEZC, OPC_BGEC */
13023 case OPC_BGTZC
: /* OPC_BLTZC, OPC_BLTC */
13024 gen_load_gpr(t0
, rs
);
13025 gen_load_gpr(t1
, rt
);
13027 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
13029 case OPC_BLEZALC
: /* OPC_BGEZALC, OPC_BGEUC */
13030 case OPC_BGTZALC
: /* OPC_BLTZALC, OPC_BLTUC */
13031 if (rs
== 0 || rs
== rt
) {
13032 /* OPC_BLEZALC, OPC_BGEZALC */
13033 /* OPC_BGTZALC, OPC_BLTZALC */
13034 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 4 + m16_lowbit
);
13036 gen_load_gpr(t0
, rs
);
13037 gen_load_gpr(t1
, rt
);
13039 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
13043 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
13048 /* OPC_BEQZC, OPC_BNEZC */
13049 gen_load_gpr(t0
, rs
);
13051 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
13053 /* OPC_JIC, OPC_JIALC */
13054 TCGv tbase
= tcg_temp_new();
13055 TCGv toffset
= tcg_temp_new();
13057 gen_load_gpr(tbase
, rt
);
13058 tcg_gen_movi_tl(toffset
, offset
);
13059 gen_op_addr_add(ctx
, btarget
, tbase
, toffset
);
13060 tcg_temp_free(tbase
);
13061 tcg_temp_free(toffset
);
13065 MIPS_INVAL("Compact branch/jump");
13066 gen_reserved_instruction(ctx
);
13070 if (bcond_compute
== 0) {
13071 /* Uncoditional compact branch */
13074 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 4 + m16_lowbit
);
13077 ctx
->hflags
|= MIPS_HFLAG_BR
;
13080 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 4 + m16_lowbit
);
13083 ctx
->hflags
|= MIPS_HFLAG_B
;
13086 MIPS_INVAL("Compact branch/jump");
13087 gen_reserved_instruction(ctx
);
13091 /* Generating branch here as compact branches don't have delay slot */
13092 gen_branch(ctx
, 4);
13094 /* Conditional compact branch */
13095 TCGLabel
*fs
= gen_new_label();
13096 save_cpu_state(ctx
, 0);
13099 case OPC_BLEZALC
: /* OPC_BGEZALC, OPC_BGEUC */
13100 if (rs
== 0 && rt
!= 0) {
13102 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE
), t1
, 0, fs
);
13103 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
13105 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE
), t1
, 0, fs
);
13108 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU
), t0
, t1
, fs
);
13111 case OPC_BGTZALC
: /* OPC_BLTZALC, OPC_BLTUC */
13112 if (rs
== 0 && rt
!= 0) {
13114 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT
), t1
, 0, fs
);
13115 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
13117 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT
), t1
, 0, fs
);
13120 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU
), t0
, t1
, fs
);
13123 case OPC_BLEZC
: /* OPC_BGEZC, OPC_BGEC */
13124 if (rs
== 0 && rt
!= 0) {
13126 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE
), t1
, 0, fs
);
13127 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
13129 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE
), t1
, 0, fs
);
13132 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE
), t0
, t1
, fs
);
13135 case OPC_BGTZC
: /* OPC_BLTZC, OPC_BLTC */
13136 if (rs
== 0 && rt
!= 0) {
13138 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT
), t1
, 0, fs
);
13139 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
13141 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT
), t1
, 0, fs
);
13144 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT
), t0
, t1
, fs
);
13147 case OPC_BOVC
: /* OPC_BEQZALC, OPC_BEQC */
13148 case OPC_BNVC
: /* OPC_BNEZALC, OPC_BNEC */
13150 /* OPC_BOVC, OPC_BNVC */
13151 TCGv t2
= tcg_temp_new();
13152 TCGv t3
= tcg_temp_new();
13153 TCGv t4
= tcg_temp_new();
13154 TCGv input_overflow
= tcg_temp_new();
13156 gen_load_gpr(t0
, rs
);
13157 gen_load_gpr(t1
, rt
);
13158 tcg_gen_ext32s_tl(t2
, t0
);
13159 tcg_gen_setcond_tl(TCG_COND_NE
, input_overflow
, t2
, t0
);
13160 tcg_gen_ext32s_tl(t3
, t1
);
13161 tcg_gen_setcond_tl(TCG_COND_NE
, t4
, t3
, t1
);
13162 tcg_gen_or_tl(input_overflow
, input_overflow
, t4
);
13164 tcg_gen_add_tl(t4
, t2
, t3
);
13165 tcg_gen_ext32s_tl(t4
, t4
);
13166 tcg_gen_xor_tl(t2
, t2
, t3
);
13167 tcg_gen_xor_tl(t3
, t4
, t3
);
13168 tcg_gen_andc_tl(t2
, t3
, t2
);
13169 tcg_gen_setcondi_tl(TCG_COND_LT
, t4
, t2
, 0);
13170 tcg_gen_or_tl(t4
, t4
, input_overflow
);
13171 if (opc
== OPC_BOVC
) {
13173 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE
), t4
, 0, fs
);
13176 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ
), t4
, 0, fs
);
13178 tcg_temp_free(input_overflow
);
13182 } else if (rs
< rt
&& rs
== 0) {
13183 /* OPC_BEQZALC, OPC_BNEZALC */
13184 if (opc
== OPC_BEQZALC
) {
13186 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ
), t1
, 0, fs
);
13189 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE
), t1
, 0, fs
);
13192 /* OPC_BEQC, OPC_BNEC */
13193 if (opc
== OPC_BEQC
) {
13195 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ
), t0
, t1
, fs
);
13198 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE
), t0
, t1
, fs
);
13203 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ
), t0
, 0, fs
);
13206 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE
), t0
, 0, fs
);
13209 MIPS_INVAL("Compact conditional branch/jump");
13210 gen_reserved_instruction(ctx
);
13214 /* Generating branch here as compact branches don't have delay slot */
13215 gen_goto_tb(ctx
, 1, ctx
->btarget
);
13218 ctx
->hflags
|= MIPS_HFLAG_FBNSLOT
;
13226 /* ISA extensions (ASEs) */
13227 /* MIPS16 extension to MIPS32 */
13229 /* MIPS16 major opcodes */
13231 M16_OPC_ADDIUSP
= 0x00,
13232 M16_OPC_ADDIUPC
= 0x01,
13234 M16_OPC_JAL
= 0x03,
13235 M16_OPC_BEQZ
= 0x04,
13236 M16_OPC_BNEQZ
= 0x05,
13237 M16_OPC_SHIFT
= 0x06,
13239 M16_OPC_RRIA
= 0x08,
13240 M16_OPC_ADDIU8
= 0x09,
13241 M16_OPC_SLTI
= 0x0a,
13242 M16_OPC_SLTIU
= 0x0b,
13245 M16_OPC_CMPI
= 0x0e,
13249 M16_OPC_LWSP
= 0x12,
13251 M16_OPC_LBU
= 0x14,
13252 M16_OPC_LHU
= 0x15,
13253 M16_OPC_LWPC
= 0x16,
13254 M16_OPC_LWU
= 0x17,
13257 M16_OPC_SWSP
= 0x1a,
13259 M16_OPC_RRR
= 0x1c,
13261 M16_OPC_EXTEND
= 0x1e,
13265 /* I8 funct field */
13284 /* RR funct field */
13318 /* I64 funct field */
13326 I64_DADDIUPC
= 0x6,
13330 /* RR ry field for CNVT */
13332 RR_RY_CNVT_ZEB
= 0x0,
13333 RR_RY_CNVT_ZEH
= 0x1,
13334 RR_RY_CNVT_ZEW
= 0x2,
13335 RR_RY_CNVT_SEB
= 0x4,
13336 RR_RY_CNVT_SEH
= 0x5,
13337 RR_RY_CNVT_SEW
= 0x6,
13340 static int xlat(int r
)
13342 static int map
[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
13347 static void gen_mips16_save(DisasContext
*ctx
,
13348 int xsregs
, int aregs
,
13349 int do_ra
, int do_s0
, int do_s1
,
13352 TCGv t0
= tcg_temp_new();
13353 TCGv t1
= tcg_temp_new();
13354 TCGv t2
= tcg_temp_new();
13384 gen_reserved_instruction(ctx
);
13390 gen_base_offset_addr(ctx
, t0
, 29, 12);
13391 gen_load_gpr(t1
, 7);
13392 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
13395 gen_base_offset_addr(ctx
, t0
, 29, 8);
13396 gen_load_gpr(t1
, 6);
13397 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
13400 gen_base_offset_addr(ctx
, t0
, 29, 4);
13401 gen_load_gpr(t1
, 5);
13402 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
13405 gen_base_offset_addr(ctx
, t0
, 29, 0);
13406 gen_load_gpr(t1
, 4);
13407 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
13410 gen_load_gpr(t0
, 29);
13412 #define DECR_AND_STORE(reg) do { \
13413 tcg_gen_movi_tl(t2, -4); \
13414 gen_op_addr_add(ctx, t0, t0, t2); \
13415 gen_load_gpr(t1, reg); \
13416 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \
13420 DECR_AND_STORE(31);
13425 DECR_AND_STORE(30);
13428 DECR_AND_STORE(23);
13431 DECR_AND_STORE(22);
13434 DECR_AND_STORE(21);
13437 DECR_AND_STORE(20);
13440 DECR_AND_STORE(19);
13443 DECR_AND_STORE(18);
13447 DECR_AND_STORE(17);
13450 DECR_AND_STORE(16);
13480 gen_reserved_instruction(ctx
);
13496 #undef DECR_AND_STORE
13498 tcg_gen_movi_tl(t2
, -framesize
);
13499 gen_op_addr_add(ctx
, cpu_gpr
[29], cpu_gpr
[29], t2
);
13505 static void gen_mips16_restore(DisasContext
*ctx
,
13506 int xsregs
, int aregs
,
13507 int do_ra
, int do_s0
, int do_s1
,
13511 TCGv t0
= tcg_temp_new();
13512 TCGv t1
= tcg_temp_new();
13513 TCGv t2
= tcg_temp_new();
13515 tcg_gen_movi_tl(t2
, framesize
);
13516 gen_op_addr_add(ctx
, t0
, cpu_gpr
[29], t2
);
13518 #define DECR_AND_LOAD(reg) do { \
13519 tcg_gen_movi_tl(t2, -4); \
13520 gen_op_addr_add(ctx, t0, t0, t2); \
13521 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \
13522 gen_store_gpr(t1, reg); \
13586 gen_reserved_instruction(ctx
);
13602 #undef DECR_AND_LOAD
13604 tcg_gen_movi_tl(t2
, framesize
);
13605 gen_op_addr_add(ctx
, cpu_gpr
[29], cpu_gpr
[29], t2
);
13611 static void gen_addiupc(DisasContext
*ctx
, int rx
, int imm
,
13612 int is_64_bit
, int extended
)
13616 if (extended
&& (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
13617 gen_reserved_instruction(ctx
);
13621 t0
= tcg_temp_new();
13623 tcg_gen_movi_tl(t0
, pc_relative_pc(ctx
));
13624 tcg_gen_addi_tl(cpu_gpr
[rx
], t0
, imm
);
13626 tcg_gen_ext32s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
13632 static void gen_cache_operation(DisasContext
*ctx
, uint32_t op
, int base
,
13635 TCGv_i32 t0
= tcg_const_i32(op
);
13636 TCGv t1
= tcg_temp_new();
13637 gen_base_offset_addr(ctx
, t1
, base
, offset
);
13638 gen_helper_cache(cpu_env
, t1
, t0
);
13641 #if defined(TARGET_MIPS64)
13642 static void decode_i64_mips16(DisasContext
*ctx
,
13643 int ry
, int funct
, int16_t offset
,
13648 check_insn(ctx
, ISA_MIPS3
);
13649 check_mips_64(ctx
);
13650 offset
= extended
? offset
: offset
<< 3;
13651 gen_ld(ctx
, OPC_LD
, ry
, 29, offset
);
13654 check_insn(ctx
, ISA_MIPS3
);
13655 check_mips_64(ctx
);
13656 offset
= extended
? offset
: offset
<< 3;
13657 gen_st(ctx
, OPC_SD
, ry
, 29, offset
);
13660 check_insn(ctx
, ISA_MIPS3
);
13661 check_mips_64(ctx
);
13662 offset
= extended
? offset
: (ctx
->opcode
& 0xff) << 3;
13663 gen_st(ctx
, OPC_SD
, 31, 29, offset
);
13666 check_insn(ctx
, ISA_MIPS3
);
13667 check_mips_64(ctx
);
13668 offset
= extended
? offset
: ((int8_t)ctx
->opcode
) << 3;
13669 gen_arith_imm(ctx
, OPC_DADDIU
, 29, 29, offset
);
13672 check_insn(ctx
, ISA_MIPS3
);
13673 check_mips_64(ctx
);
13674 if (extended
&& (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
13675 gen_reserved_instruction(ctx
);
13677 offset
= extended
? offset
: offset
<< 3;
13678 gen_ld(ctx
, OPC_LDPC
, ry
, 0, offset
);
13682 check_insn(ctx
, ISA_MIPS3
);
13683 check_mips_64(ctx
);
13684 offset
= extended
? offset
: ((int8_t)(offset
<< 3)) >> 3;
13685 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, ry
, offset
);
13688 check_insn(ctx
, ISA_MIPS3
);
13689 check_mips_64(ctx
);
13690 offset
= extended
? offset
: offset
<< 2;
13691 gen_addiupc(ctx
, ry
, offset
, 1, extended
);
13694 check_insn(ctx
, ISA_MIPS3
);
13695 check_mips_64(ctx
);
13696 offset
= extended
? offset
: offset
<< 2;
13697 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, 29, offset
);
13703 static int decode_extended_mips16_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
13705 int extend
= translator_lduw(env
, ctx
->base
.pc_next
+ 2);
13706 int op
, rx
, ry
, funct
, sa
;
13707 int16_t imm
, offset
;
13709 ctx
->opcode
= (ctx
->opcode
<< 16) | extend
;
13710 op
= (ctx
->opcode
>> 11) & 0x1f;
13711 sa
= (ctx
->opcode
>> 22) & 0x1f;
13712 funct
= (ctx
->opcode
>> 8) & 0x7;
13713 rx
= xlat((ctx
->opcode
>> 8) & 0x7);
13714 ry
= xlat((ctx
->opcode
>> 5) & 0x7);
13715 offset
= imm
= (int16_t) (((ctx
->opcode
>> 16) & 0x1f) << 11
13716 | ((ctx
->opcode
>> 21) & 0x3f) << 5
13717 | (ctx
->opcode
& 0x1f));
13720 * The extended opcodes cleverly reuse the opcodes from their 16-bit
13724 case M16_OPC_ADDIUSP
:
13725 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 29, imm
);
13727 case M16_OPC_ADDIUPC
:
13728 gen_addiupc(ctx
, rx
, imm
, 0, 1);
13731 gen_compute_branch(ctx
, OPC_BEQ
, 4, 0, 0, offset
<< 1, 0);
13732 /* No delay slot, so just process as a normal instruction */
13735 gen_compute_branch(ctx
, OPC_BEQ
, 4, rx
, 0, offset
<< 1, 0);
13736 /* No delay slot, so just process as a normal instruction */
13738 case M16_OPC_BNEQZ
:
13739 gen_compute_branch(ctx
, OPC_BNE
, 4, rx
, 0, offset
<< 1, 0);
13740 /* No delay slot, so just process as a normal instruction */
13742 case M16_OPC_SHIFT
:
13743 switch (ctx
->opcode
& 0x3) {
13745 gen_shift_imm(ctx
, OPC_SLL
, rx
, ry
, sa
);
13748 #if defined(TARGET_MIPS64)
13749 check_mips_64(ctx
);
13750 gen_shift_imm(ctx
, OPC_DSLL
, rx
, ry
, sa
);
13752 gen_reserved_instruction(ctx
);
13756 gen_shift_imm(ctx
, OPC_SRL
, rx
, ry
, sa
);
13759 gen_shift_imm(ctx
, OPC_SRA
, rx
, ry
, sa
);
13763 #if defined(TARGET_MIPS64)
13765 check_insn(ctx
, ISA_MIPS3
);
13766 check_mips_64(ctx
);
13767 gen_ld(ctx
, OPC_LD
, ry
, rx
, offset
);
13771 imm
= ctx
->opcode
& 0xf;
13772 imm
= imm
| ((ctx
->opcode
>> 20) & 0x7f) << 4;
13773 imm
= imm
| ((ctx
->opcode
>> 16) & 0xf) << 11;
13774 imm
= (int16_t) (imm
<< 1) >> 1;
13775 if ((ctx
->opcode
>> 4) & 0x1) {
13776 #if defined(TARGET_MIPS64)
13777 check_mips_64(ctx
);
13778 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, rx
, imm
);
13780 gen_reserved_instruction(ctx
);
13783 gen_arith_imm(ctx
, OPC_ADDIU
, ry
, rx
, imm
);
13786 case M16_OPC_ADDIU8
:
13787 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, rx
, imm
);
13790 gen_slt_imm(ctx
, OPC_SLTI
, 24, rx
, imm
);
13792 case M16_OPC_SLTIU
:
13793 gen_slt_imm(ctx
, OPC_SLTIU
, 24, rx
, imm
);
13798 gen_compute_branch(ctx
, OPC_BEQ
, 4, 24, 0, offset
<< 1, 0);
13801 gen_compute_branch(ctx
, OPC_BNE
, 4, 24, 0, offset
<< 1, 0);
13804 gen_st(ctx
, OPC_SW
, 31, 29, imm
);
13807 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, imm
);
13810 check_insn(ctx
, ISA_MIPS_R1
);
13812 int xsregs
= (ctx
->opcode
>> 24) & 0x7;
13813 int aregs
= (ctx
->opcode
>> 16) & 0xf;
13814 int do_ra
= (ctx
->opcode
>> 6) & 0x1;
13815 int do_s0
= (ctx
->opcode
>> 5) & 0x1;
13816 int do_s1
= (ctx
->opcode
>> 4) & 0x1;
13817 int framesize
= (((ctx
->opcode
>> 20) & 0xf) << 4
13818 | (ctx
->opcode
& 0xf)) << 3;
13820 if (ctx
->opcode
& (1 << 7)) {
13821 gen_mips16_save(ctx
, xsregs
, aregs
,
13822 do_ra
, do_s0
, do_s1
,
13825 gen_mips16_restore(ctx
, xsregs
, aregs
,
13826 do_ra
, do_s0
, do_s1
,
13832 gen_reserved_instruction(ctx
);
13837 tcg_gen_movi_tl(cpu_gpr
[rx
], (uint16_t) imm
);
13840 tcg_gen_xori_tl(cpu_gpr
[24], cpu_gpr
[rx
], (uint16_t) imm
);
13842 #if defined(TARGET_MIPS64)
13844 check_insn(ctx
, ISA_MIPS3
);
13845 check_mips_64(ctx
);
13846 gen_st(ctx
, OPC_SD
, ry
, rx
, offset
);
13850 gen_ld(ctx
, OPC_LB
, ry
, rx
, offset
);
13853 gen_ld(ctx
, OPC_LH
, ry
, rx
, offset
);
13856 gen_ld(ctx
, OPC_LW
, rx
, 29, offset
);
13859 gen_ld(ctx
, OPC_LW
, ry
, rx
, offset
);
13862 gen_ld(ctx
, OPC_LBU
, ry
, rx
, offset
);
13865 gen_ld(ctx
, OPC_LHU
, ry
, rx
, offset
);
13868 gen_ld(ctx
, OPC_LWPC
, rx
, 0, offset
);
13870 #if defined(TARGET_MIPS64)
13872 check_insn(ctx
, ISA_MIPS3
);
13873 check_mips_64(ctx
);
13874 gen_ld(ctx
, OPC_LWU
, ry
, rx
, offset
);
13878 gen_st(ctx
, OPC_SB
, ry
, rx
, offset
);
13881 gen_st(ctx
, OPC_SH
, ry
, rx
, offset
);
13884 gen_st(ctx
, OPC_SW
, rx
, 29, offset
);
13887 gen_st(ctx
, OPC_SW
, ry
, rx
, offset
);
13889 #if defined(TARGET_MIPS64)
13891 decode_i64_mips16(ctx
, ry
, funct
, offset
, 1);
13895 gen_reserved_instruction(ctx
);
13902 static inline bool is_uhi(int sdbbp_code
)
13904 #ifdef CONFIG_USER_ONLY
13907 return semihosting_enabled() && sdbbp_code
== 1;
13911 #ifdef CONFIG_USER_ONLY
13912 /* The above should dead-code away any calls to this..*/
13913 static inline void gen_helper_do_semihosting(void *env
)
13915 g_assert_not_reached();
13919 static int decode_mips16_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
13923 int op
, cnvt_op
, op1
, offset
;
13927 op
= (ctx
->opcode
>> 11) & 0x1f;
13928 sa
= (ctx
->opcode
>> 2) & 0x7;
13929 sa
= sa
== 0 ? 8 : sa
;
13930 rx
= xlat((ctx
->opcode
>> 8) & 0x7);
13931 cnvt_op
= (ctx
->opcode
>> 5) & 0x7;
13932 ry
= xlat((ctx
->opcode
>> 5) & 0x7);
13933 op1
= offset
= ctx
->opcode
& 0x1f;
13938 case M16_OPC_ADDIUSP
:
13940 int16_t imm
= ((uint8_t) ctx
->opcode
) << 2;
13942 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 29, imm
);
13945 case M16_OPC_ADDIUPC
:
13946 gen_addiupc(ctx
, rx
, ((uint8_t) ctx
->opcode
) << 2, 0, 0);
13949 offset
= (ctx
->opcode
& 0x7ff) << 1;
13950 offset
= (int16_t)(offset
<< 4) >> 4;
13951 gen_compute_branch(ctx
, OPC_BEQ
, 2, 0, 0, offset
, 0);
13952 /* No delay slot, so just process as a normal instruction */
13955 offset
= translator_lduw(env
, ctx
->base
.pc_next
+ 2);
13956 offset
= (((ctx
->opcode
& 0x1f) << 21)
13957 | ((ctx
->opcode
>> 5) & 0x1f) << 16
13959 op
= ((ctx
->opcode
>> 10) & 0x1) ? OPC_JALX
: OPC_JAL
;
13960 gen_compute_branch(ctx
, op
, 4, rx
, ry
, offset
, 2);
13964 gen_compute_branch(ctx
, OPC_BEQ
, 2, rx
, 0,
13965 ((int8_t)ctx
->opcode
) << 1, 0);
13966 /* No delay slot, so just process as a normal instruction */
13968 case M16_OPC_BNEQZ
:
13969 gen_compute_branch(ctx
, OPC_BNE
, 2, rx
, 0,
13970 ((int8_t)ctx
->opcode
) << 1, 0);
13971 /* No delay slot, so just process as a normal instruction */
13973 case M16_OPC_SHIFT
:
13974 switch (ctx
->opcode
& 0x3) {
13976 gen_shift_imm(ctx
, OPC_SLL
, rx
, ry
, sa
);
13979 #if defined(TARGET_MIPS64)
13980 check_insn(ctx
, ISA_MIPS3
);
13981 check_mips_64(ctx
);
13982 gen_shift_imm(ctx
, OPC_DSLL
, rx
, ry
, sa
);
13984 gen_reserved_instruction(ctx
);
13988 gen_shift_imm(ctx
, OPC_SRL
, rx
, ry
, sa
);
13991 gen_shift_imm(ctx
, OPC_SRA
, rx
, ry
, sa
);
13995 #if defined(TARGET_MIPS64)
13997 check_insn(ctx
, ISA_MIPS3
);
13998 check_mips_64(ctx
);
13999 gen_ld(ctx
, OPC_LD
, ry
, rx
, offset
<< 3);
14004 int16_t imm
= (int8_t)((ctx
->opcode
& 0xf) << 4) >> 4;
14006 if ((ctx
->opcode
>> 4) & 1) {
14007 #if defined(TARGET_MIPS64)
14008 check_insn(ctx
, ISA_MIPS3
);
14009 check_mips_64(ctx
);
14010 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, rx
, imm
);
14012 gen_reserved_instruction(ctx
);
14015 gen_arith_imm(ctx
, OPC_ADDIU
, ry
, rx
, imm
);
14019 case M16_OPC_ADDIU8
:
14021 int16_t imm
= (int8_t) ctx
->opcode
;
14023 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, rx
, imm
);
14028 int16_t imm
= (uint8_t) ctx
->opcode
;
14029 gen_slt_imm(ctx
, OPC_SLTI
, 24, rx
, imm
);
14032 case M16_OPC_SLTIU
:
14034 int16_t imm
= (uint8_t) ctx
->opcode
;
14035 gen_slt_imm(ctx
, OPC_SLTIU
, 24, rx
, imm
);
14042 funct
= (ctx
->opcode
>> 8) & 0x7;
14045 gen_compute_branch(ctx
, OPC_BEQ
, 2, 24, 0,
14046 ((int8_t)ctx
->opcode
) << 1, 0);
14049 gen_compute_branch(ctx
, OPC_BNE
, 2, 24, 0,
14050 ((int8_t)ctx
->opcode
) << 1, 0);
14053 gen_st(ctx
, OPC_SW
, 31, 29, (ctx
->opcode
& 0xff) << 2);
14056 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29,
14057 ((int8_t)ctx
->opcode
) << 3);
14060 check_insn(ctx
, ISA_MIPS_R1
);
14062 int do_ra
= ctx
->opcode
& (1 << 6);
14063 int do_s0
= ctx
->opcode
& (1 << 5);
14064 int do_s1
= ctx
->opcode
& (1 << 4);
14065 int framesize
= ctx
->opcode
& 0xf;
14067 if (framesize
== 0) {
14070 framesize
= framesize
<< 3;
14073 if (ctx
->opcode
& (1 << 7)) {
14074 gen_mips16_save(ctx
, 0, 0,
14075 do_ra
, do_s0
, do_s1
, framesize
);
14077 gen_mips16_restore(ctx
, 0, 0,
14078 do_ra
, do_s0
, do_s1
, framesize
);
14084 int rz
= xlat(ctx
->opcode
& 0x7);
14086 reg32
= (((ctx
->opcode
>> 3) & 0x3) << 3) |
14087 ((ctx
->opcode
>> 5) & 0x7);
14088 gen_arith(ctx
, OPC_ADDU
, reg32
, rz
, 0);
14092 reg32
= ctx
->opcode
& 0x1f;
14093 gen_arith(ctx
, OPC_ADDU
, ry
, reg32
, 0);
14096 gen_reserved_instruction(ctx
);
14103 int16_t imm
= (uint8_t) ctx
->opcode
;
14105 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 0, imm
);
14110 int16_t imm
= (uint8_t) ctx
->opcode
;
14111 gen_logic_imm(ctx
, OPC_XORI
, 24, rx
, imm
);
14114 #if defined(TARGET_MIPS64)
14116 check_insn(ctx
, ISA_MIPS3
);
14117 check_mips_64(ctx
);
14118 gen_st(ctx
, OPC_SD
, ry
, rx
, offset
<< 3);
14122 gen_ld(ctx
, OPC_LB
, ry
, rx
, offset
);
14125 gen_ld(ctx
, OPC_LH
, ry
, rx
, offset
<< 1);
14128 gen_ld(ctx
, OPC_LW
, rx
, 29, ((uint8_t)ctx
->opcode
) << 2);
14131 gen_ld(ctx
, OPC_LW
, ry
, rx
, offset
<< 2);
14134 gen_ld(ctx
, OPC_LBU
, ry
, rx
, offset
);
14137 gen_ld(ctx
, OPC_LHU
, ry
, rx
, offset
<< 1);
14140 gen_ld(ctx
, OPC_LWPC
, rx
, 0, ((uint8_t)ctx
->opcode
) << 2);
14142 #if defined(TARGET_MIPS64)
14144 check_insn(ctx
, ISA_MIPS3
);
14145 check_mips_64(ctx
);
14146 gen_ld(ctx
, OPC_LWU
, ry
, rx
, offset
<< 2);
14150 gen_st(ctx
, OPC_SB
, ry
, rx
, offset
);
14153 gen_st(ctx
, OPC_SH
, ry
, rx
, offset
<< 1);
14156 gen_st(ctx
, OPC_SW
, rx
, 29, ((uint8_t)ctx
->opcode
) << 2);
14159 gen_st(ctx
, OPC_SW
, ry
, rx
, offset
<< 2);
14163 int rz
= xlat((ctx
->opcode
>> 2) & 0x7);
14166 switch (ctx
->opcode
& 0x3) {
14168 mips32_op
= OPC_ADDU
;
14171 mips32_op
= OPC_SUBU
;
14173 #if defined(TARGET_MIPS64)
14175 mips32_op
= OPC_DADDU
;
14176 check_insn(ctx
, ISA_MIPS3
);
14177 check_mips_64(ctx
);
14180 mips32_op
= OPC_DSUBU
;
14181 check_insn(ctx
, ISA_MIPS3
);
14182 check_mips_64(ctx
);
14186 gen_reserved_instruction(ctx
);
14190 gen_arith(ctx
, mips32_op
, rz
, rx
, ry
);
14199 int nd
= (ctx
->opcode
>> 7) & 0x1;
14200 int link
= (ctx
->opcode
>> 6) & 0x1;
14201 int ra
= (ctx
->opcode
>> 5) & 0x1;
14204 check_insn(ctx
, ISA_MIPS_R1
);
14213 gen_compute_branch(ctx
, op
, 2, ra
? 31 : rx
, 31, 0,
14218 if (is_uhi(extract32(ctx
->opcode
, 5, 6))) {
14219 gen_helper_do_semihosting(cpu_env
);
14222 * XXX: not clear which exception should be raised
14223 * when in debug mode...
14225 check_insn(ctx
, ISA_MIPS_R1
);
14226 generate_exception_end(ctx
, EXCP_DBp
);
14230 gen_slt(ctx
, OPC_SLT
, 24, rx
, ry
);
14233 gen_slt(ctx
, OPC_SLTU
, 24, rx
, ry
);
14236 generate_exception_end(ctx
, EXCP_BREAK
);
14239 gen_shift(ctx
, OPC_SLLV
, ry
, rx
, ry
);
14242 gen_shift(ctx
, OPC_SRLV
, ry
, rx
, ry
);
14245 gen_shift(ctx
, OPC_SRAV
, ry
, rx
, ry
);
14247 #if defined(TARGET_MIPS64)
14249 check_insn(ctx
, ISA_MIPS3
);
14250 check_mips_64(ctx
);
14251 gen_shift_imm(ctx
, OPC_DSRL
, ry
, ry
, sa
);
14255 gen_logic(ctx
, OPC_XOR
, 24, rx
, ry
);
14258 gen_arith(ctx
, OPC_SUBU
, rx
, 0, ry
);
14261 gen_logic(ctx
, OPC_AND
, rx
, rx
, ry
);
14264 gen_logic(ctx
, OPC_OR
, rx
, rx
, ry
);
14267 gen_logic(ctx
, OPC_XOR
, rx
, rx
, ry
);
14270 gen_logic(ctx
, OPC_NOR
, rx
, ry
, 0);
14273 gen_HILO(ctx
, OPC_MFHI
, 0, rx
);
14276 check_insn(ctx
, ISA_MIPS_R1
);
14278 case RR_RY_CNVT_ZEB
:
14279 tcg_gen_ext8u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
14281 case RR_RY_CNVT_ZEH
:
14282 tcg_gen_ext16u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
14284 case RR_RY_CNVT_SEB
:
14285 tcg_gen_ext8s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
14287 case RR_RY_CNVT_SEH
:
14288 tcg_gen_ext16s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
14290 #if defined(TARGET_MIPS64)
14291 case RR_RY_CNVT_ZEW
:
14292 check_insn(ctx
, ISA_MIPS_R1
);
14293 check_mips_64(ctx
);
14294 tcg_gen_ext32u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
14296 case RR_RY_CNVT_SEW
:
14297 check_insn(ctx
, ISA_MIPS_R1
);
14298 check_mips_64(ctx
);
14299 tcg_gen_ext32s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
14303 gen_reserved_instruction(ctx
);
14308 gen_HILO(ctx
, OPC_MFLO
, 0, rx
);
14310 #if defined(TARGET_MIPS64)
14312 check_insn(ctx
, ISA_MIPS3
);
14313 check_mips_64(ctx
);
14314 gen_shift_imm(ctx
, OPC_DSRA
, ry
, ry
, sa
);
14317 check_insn(ctx
, ISA_MIPS3
);
14318 check_mips_64(ctx
);
14319 gen_shift(ctx
, OPC_DSLLV
, ry
, rx
, ry
);
14322 check_insn(ctx
, ISA_MIPS3
);
14323 check_mips_64(ctx
);
14324 gen_shift(ctx
, OPC_DSRLV
, ry
, rx
, ry
);
14327 check_insn(ctx
, ISA_MIPS3
);
14328 check_mips_64(ctx
);
14329 gen_shift(ctx
, OPC_DSRAV
, ry
, rx
, ry
);
14333 gen_muldiv(ctx
, OPC_MULT
, 0, rx
, ry
);
14336 gen_muldiv(ctx
, OPC_MULTU
, 0, rx
, ry
);
14339 gen_muldiv(ctx
, OPC_DIV
, 0, rx
, ry
);
14342 gen_muldiv(ctx
, OPC_DIVU
, 0, rx
, ry
);
14344 #if defined(TARGET_MIPS64)
14346 check_insn(ctx
, ISA_MIPS3
);
14347 check_mips_64(ctx
);
14348 gen_muldiv(ctx
, OPC_DMULT
, 0, rx
, ry
);
14351 check_insn(ctx
, ISA_MIPS3
);
14352 check_mips_64(ctx
);
14353 gen_muldiv(ctx
, OPC_DMULTU
, 0, rx
, ry
);
14356 check_insn(ctx
, ISA_MIPS3
);
14357 check_mips_64(ctx
);
14358 gen_muldiv(ctx
, OPC_DDIV
, 0, rx
, ry
);
14361 check_insn(ctx
, ISA_MIPS3
);
14362 check_mips_64(ctx
);
14363 gen_muldiv(ctx
, OPC_DDIVU
, 0, rx
, ry
);
14367 gen_reserved_instruction(ctx
);
14371 case M16_OPC_EXTEND
:
14372 decode_extended_mips16_opc(env
, ctx
);
14375 #if defined(TARGET_MIPS64)
14377 funct
= (ctx
->opcode
>> 8) & 0x7;
14378 decode_i64_mips16(ctx
, ry
, funct
, offset
, 0);
14382 gen_reserved_instruction(ctx
);
14389 /* microMIPS extension to MIPS32/MIPS64 */
14392 * microMIPS32/microMIPS64 major opcodes
14394 * 1. MIPS Architecture for Programmers Volume II-B:
14395 * The microMIPS32 Instruction Set (Revision 3.05)
14397 * Table 6.2 microMIPS32 Encoding of Major Opcode Field
14399 * 2. MIPS Architecture For Programmers Volume II-A:
14400 * The MIPS64 Instruction Set (Revision 3.51)
14430 POOL32S
= 0x16, /* MIPS64 */
14431 DADDIU32
= 0x17, /* MIPS64 */
14460 /* 0x29 is reserved */
14473 /* 0x31 is reserved */
14486 SD32
= 0x36, /* MIPS64 */
14487 LD32
= 0x37, /* MIPS64 */
14489 /* 0x39 is reserved */
14505 /* PCREL Instructions perform PC-Relative address calculation. bits 20..16 */
14527 /* POOL32A encoding of minor opcode field */
14531 * These opcodes are distinguished only by bits 9..6; those bits are
14532 * what are recorded below.
14570 /* The following can be distinguished by their lower 6 bits. */
14580 /* POOL32AXF encoding of minor opcode field extension */
14583 * 1. MIPS Architecture for Programmers Volume II-B:
14584 * The microMIPS32 Instruction Set (Revision 3.05)
14586 * Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
14588 * 2. MIPS Architecture for Programmers VolumeIV-e:
14589 * The MIPS DSP Application-Specific Extension
14590 * to the microMIPS32 Architecture (Revision 2.34)
14592 * Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
14607 /* begin of microMIPS32 DSP */
14609 /* bits 13..12 for 0x01 */
14615 /* bits 13..12 for 0x2a */
14621 /* bits 13..12 for 0x32 */
14625 /* end of microMIPS32 DSP */
14627 /* bits 15..12 for 0x2c */
14644 /* bits 15..12 for 0x34 */
14652 /* bits 15..12 for 0x3c */
14654 JR
= 0x0, /* alias */
14662 /* bits 15..12 for 0x05 */
14666 /* bits 15..12 for 0x0d */
14678 /* bits 15..12 for 0x15 */
14684 /* bits 15..12 for 0x1d */
14688 /* bits 15..12 for 0x2d */
14693 /* bits 15..12 for 0x35 */
14700 /* POOL32B encoding of minor opcode field (bits 15..12) */
14716 /* POOL32C encoding of minor opcode field (bits 15..12) */
14737 /* POOL32C LD-EVA encoding of minor opcode field (bits 11..9) */
14750 /* POOL32C ST-EVA encoding of minor opcode field (bits 11..9) */
14763 /* POOL32F encoding of minor opcode field (bits 5..0) */
14766 /* These are the bit 7..6 values */
14775 /* These are the bit 8..6 values */
14800 MOVZ_FMT_05
= 0x05,
14834 CABS_COND_FMT
= 0x1c, /* MIPS3D */
14841 /* POOL32Fxf encoding of minor opcode extension field */
14879 /* POOL32I encoding of minor opcode field (bits 25..21) */
14909 /* These overlap and are distinguished by bit16 of the instruction */
14918 /* POOL16A encoding of minor opcode field */
14925 /* POOL16B encoding of minor opcode field */
14932 /* POOL16C encoding of minor opcode field */
14952 /* R6 POOL16C encoding of minor opcode field (bits 0..5) */
14976 /* POOL16D encoding of minor opcode field */
14983 /* POOL16E encoding of minor opcode field */
14990 static int mmreg(int r
)
14992 static const int map
[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
14997 /* Used for 16-bit store instructions. */
14998 static int mmreg2(int r
)
15000 static const int map
[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
15005 #define uMIPS_RD(op) ((op >> 7) & 0x7)
15006 #define uMIPS_RS(op) ((op >> 4) & 0x7)
15007 #define uMIPS_RS2(op) uMIPS_RS(op)
15008 #define uMIPS_RS1(op) ((op >> 1) & 0x7)
15009 #define uMIPS_RD5(op) ((op >> 5) & 0x1f)
15010 #define uMIPS_RS5(op) (op & 0x1f)
15012 /* Signed immediate */
15013 #define SIMM(op, start, width) \
15014 ((int32_t)(((op >> start) & ((~0U) >> (32 - width))) \
15017 /* Zero-extended immediate */
15018 #define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32 - width)))
15020 static void gen_addiur1sp(DisasContext
*ctx
)
15022 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
15024 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, 29, ((ctx
->opcode
>> 1) & 0x3f) << 2);
15027 static void gen_addiur2(DisasContext
*ctx
)
15029 static const int decoded_imm
[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
15030 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
15031 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
15033 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, rs
, decoded_imm
[ZIMM(ctx
->opcode
, 1, 3)]);
15036 static void gen_addiusp(DisasContext
*ctx
)
15038 int encoded
= ZIMM(ctx
->opcode
, 1, 9);
15041 if (encoded
<= 1) {
15042 decoded
= 256 + encoded
;
15043 } else if (encoded
<= 255) {
15045 } else if (encoded
<= 509) {
15046 decoded
= encoded
- 512;
15048 decoded
= encoded
- 768;
15051 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, decoded
<< 2);
15054 static void gen_addius5(DisasContext
*ctx
)
15056 int imm
= SIMM(ctx
->opcode
, 1, 4);
15057 int rd
= (ctx
->opcode
>> 5) & 0x1f;
15059 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, rd
, imm
);
15062 static void gen_andi16(DisasContext
*ctx
)
15064 static const int decoded_imm
[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
15065 31, 32, 63, 64, 255, 32768, 65535 };
15066 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
15067 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
15068 int encoded
= ZIMM(ctx
->opcode
, 0, 4);
15070 gen_logic_imm(ctx
, OPC_ANDI
, rd
, rs
, decoded_imm
[encoded
]);
15073 static void gen_ldst_multiple(DisasContext
*ctx
, uint32_t opc
, int reglist
,
15074 int base
, int16_t offset
)
15079 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
15080 gen_reserved_instruction(ctx
);
15084 t0
= tcg_temp_new();
15086 gen_base_offset_addr(ctx
, t0
, base
, offset
);
15088 t1
= tcg_const_tl(reglist
);
15089 t2
= tcg_const_i32(ctx
->mem_idx
);
15091 save_cpu_state(ctx
, 1);
15094 gen_helper_lwm(cpu_env
, t0
, t1
, t2
);
15097 gen_helper_swm(cpu_env
, t0
, t1
, t2
);
15099 #ifdef TARGET_MIPS64
15101 gen_helper_ldm(cpu_env
, t0
, t1
, t2
);
15104 gen_helper_sdm(cpu_env
, t0
, t1
, t2
);
15110 tcg_temp_free_i32(t2
);
15114 static void gen_pool16c_insn(DisasContext
*ctx
)
15116 int rd
= mmreg((ctx
->opcode
>> 3) & 0x7);
15117 int rs
= mmreg(ctx
->opcode
& 0x7);
15119 switch (((ctx
->opcode
) >> 4) & 0x3f) {
15124 gen_logic(ctx
, OPC_NOR
, rd
, rs
, 0);
15130 gen_logic(ctx
, OPC_XOR
, rd
, rd
, rs
);
15136 gen_logic(ctx
, OPC_AND
, rd
, rd
, rs
);
15142 gen_logic(ctx
, OPC_OR
, rd
, rd
, rs
);
15149 static const int lwm_convert
[] = { 0x11, 0x12, 0x13, 0x14 };
15150 int offset
= ZIMM(ctx
->opcode
, 0, 4);
15152 gen_ldst_multiple(ctx
, LWM32
, lwm_convert
[(ctx
->opcode
>> 4) & 0x3],
15161 static const int swm_convert
[] = { 0x11, 0x12, 0x13, 0x14 };
15162 int offset
= ZIMM(ctx
->opcode
, 0, 4);
15164 gen_ldst_multiple(ctx
, SWM32
, swm_convert
[(ctx
->opcode
>> 4) & 0x3],
15171 int reg
= ctx
->opcode
& 0x1f;
15173 gen_compute_branch(ctx
, OPC_JR
, 2, reg
, 0, 0, 4);
15179 int reg
= ctx
->opcode
& 0x1f;
15180 gen_compute_branch(ctx
, OPC_JR
, 2, reg
, 0, 0, 0);
15182 * Let normal delay slot handling in our caller take us
15183 * to the branch target.
15189 gen_compute_branch(ctx
, OPC_JALR
, 2, ctx
->opcode
& 0x1f, 31, 0, 4);
15190 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
15194 gen_compute_branch(ctx
, OPC_JALR
, 2, ctx
->opcode
& 0x1f, 31, 0, 2);
15195 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
15199 gen_HILO(ctx
, OPC_MFHI
, 0, uMIPS_RS5(ctx
->opcode
));
15203 gen_HILO(ctx
, OPC_MFLO
, 0, uMIPS_RS5(ctx
->opcode
));
15206 generate_exception_end(ctx
, EXCP_BREAK
);
15209 if (is_uhi(extract32(ctx
->opcode
, 0, 4))) {
15210 gen_helper_do_semihosting(cpu_env
);
15213 * XXX: not clear which exception should be raised
15214 * when in debug mode...
15216 check_insn(ctx
, ISA_MIPS_R1
);
15217 generate_exception_end(ctx
, EXCP_DBp
);
15220 case JRADDIUSP
+ 0:
15221 case JRADDIUSP
+ 1:
15223 int imm
= ZIMM(ctx
->opcode
, 0, 5);
15224 gen_compute_branch(ctx
, OPC_JR
, 2, 31, 0, 0, 0);
15225 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, imm
<< 2);
15227 * Let normal delay slot handling in our caller take us
15228 * to the branch target.
15233 gen_reserved_instruction(ctx
);
15238 static inline void gen_movep(DisasContext
*ctx
, int enc_dest
, int enc_rt
,
15241 int rd
, rs
, re
, rt
;
15242 static const int rd_enc
[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
15243 static const int re_enc
[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
15244 static const int rs_rt_enc
[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
15245 rd
= rd_enc
[enc_dest
];
15246 re
= re_enc
[enc_dest
];
15247 rs
= rs_rt_enc
[enc_rs
];
15248 rt
= rs_rt_enc
[enc_rt
];
15250 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
15252 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
15255 tcg_gen_mov_tl(cpu_gpr
[re
], cpu_gpr
[rt
]);
15257 tcg_gen_movi_tl(cpu_gpr
[re
], 0);
15261 static void gen_pool16c_r6_insn(DisasContext
*ctx
)
15263 int rt
= mmreg((ctx
->opcode
>> 7) & 0x7);
15264 int rs
= mmreg((ctx
->opcode
>> 4) & 0x7);
15266 switch (ctx
->opcode
& 0xf) {
15268 gen_logic(ctx
, OPC_NOR
, rt
, rs
, 0);
15271 gen_logic(ctx
, OPC_AND
, rt
, rt
, rs
);
15275 int lwm_converted
= 0x11 + extract32(ctx
->opcode
, 8, 2);
15276 int offset
= extract32(ctx
->opcode
, 4, 4);
15277 gen_ldst_multiple(ctx
, LWM32
, lwm_converted
, 29, offset
<< 2);
15280 case R6_JRC16
: /* JRCADDIUSP */
15281 if ((ctx
->opcode
>> 4) & 1) {
15283 int imm
= extract32(ctx
->opcode
, 5, 5);
15284 gen_compute_branch(ctx
, OPC_JR
, 2, 31, 0, 0, 0);
15285 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, imm
<< 2);
15288 rs
= extract32(ctx
->opcode
, 5, 5);
15289 gen_compute_branch(ctx
, OPC_JR
, 2, rs
, 0, 0, 0);
15301 int enc_dest
= uMIPS_RD(ctx
->opcode
);
15302 int enc_rt
= uMIPS_RS2(ctx
->opcode
);
15303 int enc_rs
= (ctx
->opcode
& 3) | ((ctx
->opcode
>> 1) & 4);
15304 gen_movep(ctx
, enc_dest
, enc_rt
, enc_rs
);
15308 gen_logic(ctx
, OPC_XOR
, rt
, rt
, rs
);
15311 gen_logic(ctx
, OPC_OR
, rt
, rt
, rs
);
15315 int swm_converted
= 0x11 + extract32(ctx
->opcode
, 8, 2);
15316 int offset
= extract32(ctx
->opcode
, 4, 4);
15317 gen_ldst_multiple(ctx
, SWM32
, swm_converted
, 29, offset
<< 2);
15320 case JALRC16
: /* BREAK16, SDBBP16 */
15321 switch (ctx
->opcode
& 0x3f) {
15323 case JALRC16
+ 0x20:
15325 gen_compute_branch(ctx
, OPC_JALR
, 2, (ctx
->opcode
>> 5) & 0x1f,
15330 generate_exception(ctx
, EXCP_BREAK
);
15334 if (is_uhi(extract32(ctx
->opcode
, 6, 4))) {
15335 gen_helper_do_semihosting(cpu_env
);
15337 if (ctx
->hflags
& MIPS_HFLAG_SBRI
) {
15338 generate_exception(ctx
, EXCP_RI
);
15340 generate_exception(ctx
, EXCP_DBp
);
15347 generate_exception(ctx
, EXCP_RI
);
15352 static void gen_ldxs(DisasContext
*ctx
, int base
, int index
, int rd
)
15354 TCGv t0
= tcg_temp_new();
15355 TCGv t1
= tcg_temp_new();
15357 gen_load_gpr(t0
, base
);
15360 gen_load_gpr(t1
, index
);
15361 tcg_gen_shli_tl(t1
, t1
, 2);
15362 gen_op_addr_add(ctx
, t0
, t1
, t0
);
15365 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TESL
);
15366 gen_store_gpr(t1
, rd
);
15372 static void gen_ldst_pair(DisasContext
*ctx
, uint32_t opc
, int rd
,
15373 int base
, int16_t offset
)
15377 if (ctx
->hflags
& MIPS_HFLAG_BMASK
|| rd
== 31) {
15378 gen_reserved_instruction(ctx
);
15382 t0
= tcg_temp_new();
15383 t1
= tcg_temp_new();
15385 gen_base_offset_addr(ctx
, t0
, base
, offset
);
15390 gen_reserved_instruction(ctx
);
15393 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TESL
);
15394 gen_store_gpr(t1
, rd
);
15395 tcg_gen_movi_tl(t1
, 4);
15396 gen_op_addr_add(ctx
, t0
, t0
, t1
);
15397 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TESL
);
15398 gen_store_gpr(t1
, rd
+ 1);
15401 gen_load_gpr(t1
, rd
);
15402 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
15403 tcg_gen_movi_tl(t1
, 4);
15404 gen_op_addr_add(ctx
, t0
, t0
, t1
);
15405 gen_load_gpr(t1
, rd
+ 1);
15406 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
15408 #ifdef TARGET_MIPS64
15411 gen_reserved_instruction(ctx
);
15414 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
15415 gen_store_gpr(t1
, rd
);
15416 tcg_gen_movi_tl(t1
, 8);
15417 gen_op_addr_add(ctx
, t0
, t0
, t1
);
15418 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
15419 gen_store_gpr(t1
, rd
+ 1);
15422 gen_load_gpr(t1
, rd
);
15423 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
15424 tcg_gen_movi_tl(t1
, 8);
15425 gen_op_addr_add(ctx
, t0
, t0
, t1
);
15426 gen_load_gpr(t1
, rd
+ 1);
15427 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
15435 static void gen_sync(int stype
)
15437 TCGBar tcg_mo
= TCG_BAR_SC
;
15440 case 0x4: /* SYNC_WMB */
15441 tcg_mo
|= TCG_MO_ST_ST
;
15443 case 0x10: /* SYNC_MB */
15444 tcg_mo
|= TCG_MO_ALL
;
15446 case 0x11: /* SYNC_ACQUIRE */
15447 tcg_mo
|= TCG_MO_LD_LD
| TCG_MO_LD_ST
;
15449 case 0x12: /* SYNC_RELEASE */
15450 tcg_mo
|= TCG_MO_ST_ST
| TCG_MO_LD_ST
;
15452 case 0x13: /* SYNC_RMB */
15453 tcg_mo
|= TCG_MO_LD_LD
;
15456 tcg_mo
|= TCG_MO_ALL
;
15460 tcg_gen_mb(tcg_mo
);
15463 static void gen_pool32axf(CPUMIPSState
*env
, DisasContext
*ctx
, int rt
, int rs
)
15465 int extension
= (ctx
->opcode
>> 6) & 0x3f;
15466 int minor
= (ctx
->opcode
>> 12) & 0xf;
15467 uint32_t mips32_op
;
15469 switch (extension
) {
15471 mips32_op
= OPC_TEQ
;
15474 mips32_op
= OPC_TGE
;
15477 mips32_op
= OPC_TGEU
;
15480 mips32_op
= OPC_TLT
;
15483 mips32_op
= OPC_TLTU
;
15486 mips32_op
= OPC_TNE
;
15488 gen_trap(ctx
, mips32_op
, rs
, rt
, -1);
15490 #ifndef CONFIG_USER_ONLY
15493 check_cp0_enabled(ctx
);
15495 /* Treat as NOP. */
15498 gen_mfc0(ctx
, cpu_gpr
[rt
], rs
, (ctx
->opcode
>> 11) & 0x7);
15502 check_cp0_enabled(ctx
);
15504 TCGv t0
= tcg_temp_new();
15506 gen_load_gpr(t0
, rt
);
15507 gen_mtc0(ctx
, t0
, rs
, (ctx
->opcode
>> 11) & 0x7);
15513 switch (minor
& 3) {
15515 gen_muldiv(ctx
, OPC_MADD
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
15518 gen_muldiv(ctx
, OPC_MADDU
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
15521 gen_muldiv(ctx
, OPC_MSUB
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
15524 gen_muldiv(ctx
, OPC_MSUBU
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
15527 goto pool32axf_invalid
;
15531 switch (minor
& 3) {
15533 gen_muldiv(ctx
, OPC_MULT
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
15536 gen_muldiv(ctx
, OPC_MULTU
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
15539 goto pool32axf_invalid
;
15545 check_insn(ctx
, ISA_MIPS_R6
);
15546 gen_bitswap(ctx
, OPC_BITSWAP
, rs
, rt
);
15549 gen_bshfl(ctx
, OPC_SEB
, rs
, rt
);
15552 gen_bshfl(ctx
, OPC_SEH
, rs
, rt
);
15555 mips32_op
= OPC_CLO
;
15558 mips32_op
= OPC_CLZ
;
15560 check_insn(ctx
, ISA_MIPS_R1
);
15561 gen_cl(ctx
, mips32_op
, rt
, rs
);
15564 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15565 gen_rdhwr(ctx
, rt
, rs
, 0);
15568 gen_bshfl(ctx
, OPC_WSBH
, rs
, rt
);
15571 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15572 mips32_op
= OPC_MULT
;
15575 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15576 mips32_op
= OPC_MULTU
;
15579 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15580 mips32_op
= OPC_DIV
;
15583 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15584 mips32_op
= OPC_DIVU
;
15587 check_insn(ctx
, ISA_MIPS_R1
);
15588 gen_muldiv(ctx
, mips32_op
, 0, rs
, rt
);
15591 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15592 mips32_op
= OPC_MADD
;
15595 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15596 mips32_op
= OPC_MADDU
;
15599 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15600 mips32_op
= OPC_MSUB
;
15603 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15604 mips32_op
= OPC_MSUBU
;
15606 check_insn(ctx
, ISA_MIPS_R1
);
15607 gen_muldiv(ctx
, mips32_op
, 0, rs
, rt
);
15610 goto pool32axf_invalid
;
15621 generate_exception_err(ctx
, EXCP_CpU
, 2);
15624 goto pool32axf_invalid
;
15629 case JALR
: /* JALRC */
15630 case JALR_HB
: /* JALRC_HB */
15631 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
15632 /* JALRC, JALRC_HB */
15633 gen_compute_branch(ctx
, OPC_JALR
, 4, rs
, rt
, 0, 0);
15635 /* JALR, JALR_HB */
15636 gen_compute_branch(ctx
, OPC_JALR
, 4, rs
, rt
, 0, 4);
15637 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
15642 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15643 gen_compute_branch(ctx
, OPC_JALR
, 4, rs
, rt
, 0, 2);
15644 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
15647 goto pool32axf_invalid
;
15653 check_cp0_enabled(ctx
);
15654 check_insn(ctx
, ISA_MIPS_R2
);
15655 gen_load_srsgpr(rs
, rt
);
15658 check_cp0_enabled(ctx
);
15659 check_insn(ctx
, ISA_MIPS_R2
);
15660 gen_store_srsgpr(rs
, rt
);
15663 goto pool32axf_invalid
;
15666 #ifndef CONFIG_USER_ONLY
15670 mips32_op
= OPC_TLBP
;
15673 mips32_op
= OPC_TLBR
;
15676 mips32_op
= OPC_TLBWI
;
15679 mips32_op
= OPC_TLBWR
;
15682 mips32_op
= OPC_TLBINV
;
15685 mips32_op
= OPC_TLBINVF
;
15688 mips32_op
= OPC_WAIT
;
15691 mips32_op
= OPC_DERET
;
15694 mips32_op
= OPC_ERET
;
15696 gen_cp0(env
, ctx
, mips32_op
, rt
, rs
);
15699 goto pool32axf_invalid
;
15705 check_cp0_enabled(ctx
);
15707 TCGv t0
= tcg_temp_new();
15709 save_cpu_state(ctx
, 1);
15710 gen_helper_di(t0
, cpu_env
);
15711 gen_store_gpr(t0
, rs
);
15713 * Stop translation as we may have switched the execution
15716 ctx
->base
.is_jmp
= DISAS_STOP
;
15721 check_cp0_enabled(ctx
);
15723 TCGv t0
= tcg_temp_new();
15725 save_cpu_state(ctx
, 1);
15726 gen_helper_ei(t0
, cpu_env
);
15727 gen_store_gpr(t0
, rs
);
15729 * DISAS_STOP isn't sufficient, we need to ensure we break out
15730 * of translated code to check for pending interrupts.
15732 gen_save_pc(ctx
->base
.pc_next
+ 4);
15733 ctx
->base
.is_jmp
= DISAS_EXIT
;
15738 goto pool32axf_invalid
;
15745 gen_sync(extract32(ctx
->opcode
, 16, 5));
15748 generate_exception_end(ctx
, EXCP_SYSCALL
);
15751 if (is_uhi(extract32(ctx
->opcode
, 16, 10))) {
15752 gen_helper_do_semihosting(cpu_env
);
15754 check_insn(ctx
, ISA_MIPS_R1
);
15755 if (ctx
->hflags
& MIPS_HFLAG_SBRI
) {
15756 gen_reserved_instruction(ctx
);
15758 generate_exception_end(ctx
, EXCP_DBp
);
15763 goto pool32axf_invalid
;
15767 switch (minor
& 3) {
15769 gen_HILO(ctx
, OPC_MFHI
, minor
>> 2, rs
);
15772 gen_HILO(ctx
, OPC_MFLO
, minor
>> 2, rs
);
15775 gen_HILO(ctx
, OPC_MTHI
, minor
>> 2, rs
);
15778 gen_HILO(ctx
, OPC_MTLO
, minor
>> 2, rs
);
15781 goto pool32axf_invalid
;
15785 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15788 gen_HILO(ctx
, OPC_MFHI
, 0, rs
);
15791 gen_HILO(ctx
, OPC_MFLO
, 0, rs
);
15794 gen_HILO(ctx
, OPC_MTHI
, 0, rs
);
15797 gen_HILO(ctx
, OPC_MTLO
, 0, rs
);
15800 goto pool32axf_invalid
;
15805 MIPS_INVAL("pool32axf");
15806 gen_reserved_instruction(ctx
);
15812 * Values for microMIPS fmt field. Variable-width, depending on which
15813 * formats the instruction supports.
15832 static void gen_pool32fxf(DisasContext
*ctx
, int rt
, int rs
)
15834 int extension
= (ctx
->opcode
>> 6) & 0x3ff;
15835 uint32_t mips32_op
;
15837 #define FLOAT_1BIT_FMT(opc, fmt) ((fmt << 8) | opc)
15838 #define FLOAT_2BIT_FMT(opc, fmt) ((fmt << 7) | opc)
15839 #define COND_FLOAT_MOV(opc, cond) ((cond << 7) | opc)
15841 switch (extension
) {
15842 case FLOAT_1BIT_FMT(CFC1
, 0):
15843 mips32_op
= OPC_CFC1
;
15845 case FLOAT_1BIT_FMT(CTC1
, 0):
15846 mips32_op
= OPC_CTC1
;
15848 case FLOAT_1BIT_FMT(MFC1
, 0):
15849 mips32_op
= OPC_MFC1
;
15851 case FLOAT_1BIT_FMT(MTC1
, 0):
15852 mips32_op
= OPC_MTC1
;
15854 case FLOAT_1BIT_FMT(MFHC1
, 0):
15855 mips32_op
= OPC_MFHC1
;
15857 case FLOAT_1BIT_FMT(MTHC1
, 0):
15858 mips32_op
= OPC_MTHC1
;
15860 gen_cp1(ctx
, mips32_op
, rt
, rs
);
15863 /* Reciprocal square root */
15864 case FLOAT_1BIT_FMT(RSQRT_FMT
, FMT_SD_S
):
15865 mips32_op
= OPC_RSQRT_S
;
15867 case FLOAT_1BIT_FMT(RSQRT_FMT
, FMT_SD_D
):
15868 mips32_op
= OPC_RSQRT_D
;
15872 case FLOAT_1BIT_FMT(SQRT_FMT
, FMT_SD_S
):
15873 mips32_op
= OPC_SQRT_S
;
15875 case FLOAT_1BIT_FMT(SQRT_FMT
, FMT_SD_D
):
15876 mips32_op
= OPC_SQRT_D
;
15880 case FLOAT_1BIT_FMT(RECIP_FMT
, FMT_SD_S
):
15881 mips32_op
= OPC_RECIP_S
;
15883 case FLOAT_1BIT_FMT(RECIP_FMT
, FMT_SD_D
):
15884 mips32_op
= OPC_RECIP_D
;
15888 case FLOAT_1BIT_FMT(FLOOR_L
, FMT_SD_S
):
15889 mips32_op
= OPC_FLOOR_L_S
;
15891 case FLOAT_1BIT_FMT(FLOOR_L
, FMT_SD_D
):
15892 mips32_op
= OPC_FLOOR_L_D
;
15894 case FLOAT_1BIT_FMT(FLOOR_W
, FMT_SD_S
):
15895 mips32_op
= OPC_FLOOR_W_S
;
15897 case FLOAT_1BIT_FMT(FLOOR_W
, FMT_SD_D
):
15898 mips32_op
= OPC_FLOOR_W_D
;
15902 case FLOAT_1BIT_FMT(CEIL_L
, FMT_SD_S
):
15903 mips32_op
= OPC_CEIL_L_S
;
15905 case FLOAT_1BIT_FMT(CEIL_L
, FMT_SD_D
):
15906 mips32_op
= OPC_CEIL_L_D
;
15908 case FLOAT_1BIT_FMT(CEIL_W
, FMT_SD_S
):
15909 mips32_op
= OPC_CEIL_W_S
;
15911 case FLOAT_1BIT_FMT(CEIL_W
, FMT_SD_D
):
15912 mips32_op
= OPC_CEIL_W_D
;
15916 case FLOAT_1BIT_FMT(TRUNC_L
, FMT_SD_S
):
15917 mips32_op
= OPC_TRUNC_L_S
;
15919 case FLOAT_1BIT_FMT(TRUNC_L
, FMT_SD_D
):
15920 mips32_op
= OPC_TRUNC_L_D
;
15922 case FLOAT_1BIT_FMT(TRUNC_W
, FMT_SD_S
):
15923 mips32_op
= OPC_TRUNC_W_S
;
15925 case FLOAT_1BIT_FMT(TRUNC_W
, FMT_SD_D
):
15926 mips32_op
= OPC_TRUNC_W_D
;
15930 case FLOAT_1BIT_FMT(ROUND_L
, FMT_SD_S
):
15931 mips32_op
= OPC_ROUND_L_S
;
15933 case FLOAT_1BIT_FMT(ROUND_L
, FMT_SD_D
):
15934 mips32_op
= OPC_ROUND_L_D
;
15936 case FLOAT_1BIT_FMT(ROUND_W
, FMT_SD_S
):
15937 mips32_op
= OPC_ROUND_W_S
;
15939 case FLOAT_1BIT_FMT(ROUND_W
, FMT_SD_D
):
15940 mips32_op
= OPC_ROUND_W_D
;
15943 /* Integer to floating-point conversion */
15944 case FLOAT_1BIT_FMT(CVT_L
, FMT_SD_S
):
15945 mips32_op
= OPC_CVT_L_S
;
15947 case FLOAT_1BIT_FMT(CVT_L
, FMT_SD_D
):
15948 mips32_op
= OPC_CVT_L_D
;
15950 case FLOAT_1BIT_FMT(CVT_W
, FMT_SD_S
):
15951 mips32_op
= OPC_CVT_W_S
;
15953 case FLOAT_1BIT_FMT(CVT_W
, FMT_SD_D
):
15954 mips32_op
= OPC_CVT_W_D
;
15957 /* Paired-foo conversions */
15958 case FLOAT_1BIT_FMT(CVT_S_PL
, 0):
15959 mips32_op
= OPC_CVT_S_PL
;
15961 case FLOAT_1BIT_FMT(CVT_S_PU
, 0):
15962 mips32_op
= OPC_CVT_S_PU
;
15964 case FLOAT_1BIT_FMT(CVT_PW_PS
, 0):
15965 mips32_op
= OPC_CVT_PW_PS
;
15967 case FLOAT_1BIT_FMT(CVT_PS_PW
, 0):
15968 mips32_op
= OPC_CVT_PS_PW
;
15971 /* Floating-point moves */
15972 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_S
):
15973 mips32_op
= OPC_MOV_S
;
15975 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_D
):
15976 mips32_op
= OPC_MOV_D
;
15978 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_PS
):
15979 mips32_op
= OPC_MOV_PS
;
15982 /* Absolute value */
15983 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_S
):
15984 mips32_op
= OPC_ABS_S
;
15986 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_D
):
15987 mips32_op
= OPC_ABS_D
;
15989 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_PS
):
15990 mips32_op
= OPC_ABS_PS
;
15994 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_S
):
15995 mips32_op
= OPC_NEG_S
;
15997 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_D
):
15998 mips32_op
= OPC_NEG_D
;
16000 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_PS
):
16001 mips32_op
= OPC_NEG_PS
;
16004 /* Reciprocal square root step */
16005 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_S
):
16006 mips32_op
= OPC_RSQRT1_S
;
16008 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_D
):
16009 mips32_op
= OPC_RSQRT1_D
;
16011 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_PS
):
16012 mips32_op
= OPC_RSQRT1_PS
;
16015 /* Reciprocal step */
16016 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_S
):
16017 mips32_op
= OPC_RECIP1_S
;
16019 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_D
):
16020 mips32_op
= OPC_RECIP1_S
;
16022 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_PS
):
16023 mips32_op
= OPC_RECIP1_PS
;
16026 /* Conversions from double */
16027 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_S
):
16028 mips32_op
= OPC_CVT_D_S
;
16030 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_W
):
16031 mips32_op
= OPC_CVT_D_W
;
16033 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_L
):
16034 mips32_op
= OPC_CVT_D_L
;
16037 /* Conversions from single */
16038 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_D
):
16039 mips32_op
= OPC_CVT_S_D
;
16041 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_W
):
16042 mips32_op
= OPC_CVT_S_W
;
16044 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_L
):
16045 mips32_op
= OPC_CVT_S_L
;
16047 gen_farith(ctx
, mips32_op
, -1, rs
, rt
, 0);
16050 /* Conditional moves on floating-point codes */
16051 case COND_FLOAT_MOV(MOVT
, 0):
16052 case COND_FLOAT_MOV(MOVT
, 1):
16053 case COND_FLOAT_MOV(MOVT
, 2):
16054 case COND_FLOAT_MOV(MOVT
, 3):
16055 case COND_FLOAT_MOV(MOVT
, 4):
16056 case COND_FLOAT_MOV(MOVT
, 5):
16057 case COND_FLOAT_MOV(MOVT
, 6):
16058 case COND_FLOAT_MOV(MOVT
, 7):
16059 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16060 gen_movci(ctx
, rt
, rs
, (ctx
->opcode
>> 13) & 0x7, 1);
16062 case COND_FLOAT_MOV(MOVF
, 0):
16063 case COND_FLOAT_MOV(MOVF
, 1):
16064 case COND_FLOAT_MOV(MOVF
, 2):
16065 case COND_FLOAT_MOV(MOVF
, 3):
16066 case COND_FLOAT_MOV(MOVF
, 4):
16067 case COND_FLOAT_MOV(MOVF
, 5):
16068 case COND_FLOAT_MOV(MOVF
, 6):
16069 case COND_FLOAT_MOV(MOVF
, 7):
16070 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16071 gen_movci(ctx
, rt
, rs
, (ctx
->opcode
>> 13) & 0x7, 0);
16074 MIPS_INVAL("pool32fxf");
16075 gen_reserved_instruction(ctx
);
16080 static void decode_micromips32_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
16084 int rt
, rs
, rd
, rr
;
16086 uint32_t op
, minor
, minor2
, mips32_op
;
16087 uint32_t cond
, fmt
, cc
;
16089 insn
= translator_lduw(env
, ctx
->base
.pc_next
+ 2);
16090 ctx
->opcode
= (ctx
->opcode
<< 16) | insn
;
16092 rt
= (ctx
->opcode
>> 21) & 0x1f;
16093 rs
= (ctx
->opcode
>> 16) & 0x1f;
16094 rd
= (ctx
->opcode
>> 11) & 0x1f;
16095 rr
= (ctx
->opcode
>> 6) & 0x1f;
16096 imm
= (int16_t) ctx
->opcode
;
16098 op
= (ctx
->opcode
>> 26) & 0x3f;
16101 minor
= ctx
->opcode
& 0x3f;
16104 minor
= (ctx
->opcode
>> 6) & 0xf;
16107 mips32_op
= OPC_SLL
;
16110 mips32_op
= OPC_SRA
;
16113 mips32_op
= OPC_SRL
;
16116 mips32_op
= OPC_ROTR
;
16118 gen_shift_imm(ctx
, mips32_op
, rt
, rs
, rd
);
16121 check_insn(ctx
, ISA_MIPS_R6
);
16122 gen_cond_move(ctx
, OPC_SELEQZ
, rd
, rs
, rt
);
16125 check_insn(ctx
, ISA_MIPS_R6
);
16126 gen_cond_move(ctx
, OPC_SELNEZ
, rd
, rs
, rt
);
16129 check_insn(ctx
, ISA_MIPS_R6
);
16130 gen_rdhwr(ctx
, rt
, rs
, extract32(ctx
->opcode
, 11, 3));
16133 goto pool32a_invalid
;
16137 minor
= (ctx
->opcode
>> 6) & 0xf;
16141 mips32_op
= OPC_ADD
;
16144 mips32_op
= OPC_ADDU
;
16147 mips32_op
= OPC_SUB
;
16150 mips32_op
= OPC_SUBU
;
16153 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16154 mips32_op
= OPC_MUL
;
16156 gen_arith(ctx
, mips32_op
, rd
, rs
, rt
);
16160 mips32_op
= OPC_SLLV
;
16163 mips32_op
= OPC_SRLV
;
16166 mips32_op
= OPC_SRAV
;
16169 mips32_op
= OPC_ROTRV
;
16171 gen_shift(ctx
, mips32_op
, rd
, rs
, rt
);
16173 /* Logical operations */
16175 mips32_op
= OPC_AND
;
16178 mips32_op
= OPC_OR
;
16181 mips32_op
= OPC_NOR
;
16184 mips32_op
= OPC_XOR
;
16186 gen_logic(ctx
, mips32_op
, rd
, rs
, rt
);
16188 /* Set less than */
16190 mips32_op
= OPC_SLT
;
16193 mips32_op
= OPC_SLTU
;
16195 gen_slt(ctx
, mips32_op
, rd
, rs
, rt
);
16198 goto pool32a_invalid
;
16202 minor
= (ctx
->opcode
>> 6) & 0xf;
16204 /* Conditional moves */
16205 case MOVN
: /* MUL */
16206 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16208 gen_r6_muldiv(ctx
, R6_OPC_MUL
, rd
, rs
, rt
);
16211 gen_cond_move(ctx
, OPC_MOVN
, rd
, rs
, rt
);
16214 case MOVZ
: /* MUH */
16215 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16217 gen_r6_muldiv(ctx
, R6_OPC_MUH
, rd
, rs
, rt
);
16220 gen_cond_move(ctx
, OPC_MOVZ
, rd
, rs
, rt
);
16224 check_insn(ctx
, ISA_MIPS_R6
);
16225 gen_r6_muldiv(ctx
, R6_OPC_MULU
, rd
, rs
, rt
);
16228 check_insn(ctx
, ISA_MIPS_R6
);
16229 gen_r6_muldiv(ctx
, R6_OPC_MUHU
, rd
, rs
, rt
);
16231 case LWXS
: /* DIV */
16232 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16234 gen_r6_muldiv(ctx
, R6_OPC_DIV
, rd
, rs
, rt
);
16237 gen_ldxs(ctx
, rs
, rt
, rd
);
16241 check_insn(ctx
, ISA_MIPS_R6
);
16242 gen_r6_muldiv(ctx
, R6_OPC_MOD
, rd
, rs
, rt
);
16245 check_insn(ctx
, ISA_MIPS_R6
);
16246 gen_r6_muldiv(ctx
, R6_OPC_DIVU
, rd
, rs
, rt
);
16249 check_insn(ctx
, ISA_MIPS_R6
);
16250 gen_r6_muldiv(ctx
, R6_OPC_MODU
, rd
, rs
, rt
);
16253 goto pool32a_invalid
;
16257 gen_bitops(ctx
, OPC_INS
, rt
, rs
, rr
, rd
);
16260 check_insn(ctx
, ISA_MIPS_R6
);
16261 gen_lsa(ctx
, rd
, rt
, rs
, extract32(ctx
->opcode
, 9, 2));
16264 check_insn(ctx
, ISA_MIPS_R6
);
16265 gen_align(ctx
, 32, rd
, rs
, rt
, extract32(ctx
->opcode
, 9, 2));
16268 gen_bitops(ctx
, OPC_EXT
, rt
, rs
, rr
, rd
);
16271 gen_pool32axf(env
, ctx
, rt
, rs
);
16274 generate_exception_end(ctx
, EXCP_BREAK
);
16277 check_insn(ctx
, ISA_MIPS_R6
);
16278 gen_reserved_instruction(ctx
);
16282 MIPS_INVAL("pool32a");
16283 gen_reserved_instruction(ctx
);
16288 minor
= (ctx
->opcode
>> 12) & 0xf;
16291 check_cp0_enabled(ctx
);
16292 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
16293 gen_cache_operation(ctx
, rt
, rs
, imm
);
16298 /* COP2: Not implemented. */
16299 generate_exception_err(ctx
, EXCP_CpU
, 2);
16301 #ifdef TARGET_MIPS64
16304 check_insn(ctx
, ISA_MIPS3
);
16305 check_mips_64(ctx
);
16310 gen_ldst_pair(ctx
, minor
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
16312 #ifdef TARGET_MIPS64
16315 check_insn(ctx
, ISA_MIPS3
);
16316 check_mips_64(ctx
);
16321 gen_ldst_multiple(ctx
, minor
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
16324 MIPS_INVAL("pool32b");
16325 gen_reserved_instruction(ctx
);
16330 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
16331 minor
= ctx
->opcode
& 0x3f;
16332 check_cp1_enabled(ctx
);
16335 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16336 mips32_op
= OPC_ALNV_PS
;
16339 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16340 mips32_op
= OPC_MADD_S
;
16343 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16344 mips32_op
= OPC_MADD_D
;
16347 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16348 mips32_op
= OPC_MADD_PS
;
16351 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16352 mips32_op
= OPC_MSUB_S
;
16355 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16356 mips32_op
= OPC_MSUB_D
;
16359 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16360 mips32_op
= OPC_MSUB_PS
;
16363 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16364 mips32_op
= OPC_NMADD_S
;
16367 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16368 mips32_op
= OPC_NMADD_D
;
16371 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16372 mips32_op
= OPC_NMADD_PS
;
16375 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16376 mips32_op
= OPC_NMSUB_S
;
16379 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16380 mips32_op
= OPC_NMSUB_D
;
16383 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16384 mips32_op
= OPC_NMSUB_PS
;
16386 gen_flt3_arith(ctx
, mips32_op
, rd
, rr
, rs
, rt
);
16388 case CABS_COND_FMT
:
16389 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16390 cond
= (ctx
->opcode
>> 6) & 0xf;
16391 cc
= (ctx
->opcode
>> 13) & 0x7;
16392 fmt
= (ctx
->opcode
>> 10) & 0x3;
16395 gen_cmpabs_s(ctx
, cond
, rt
, rs
, cc
);
16398 gen_cmpabs_d(ctx
, cond
, rt
, rs
, cc
);
16401 gen_cmpabs_ps(ctx
, cond
, rt
, rs
, cc
);
16404 goto pool32f_invalid
;
16408 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16409 cond
= (ctx
->opcode
>> 6) & 0xf;
16410 cc
= (ctx
->opcode
>> 13) & 0x7;
16411 fmt
= (ctx
->opcode
>> 10) & 0x3;
16414 gen_cmp_s(ctx
, cond
, rt
, rs
, cc
);
16417 gen_cmp_d(ctx
, cond
, rt
, rs
, cc
);
16420 gen_cmp_ps(ctx
, cond
, rt
, rs
, cc
);
16423 goto pool32f_invalid
;
16427 check_insn(ctx
, ISA_MIPS_R6
);
16428 gen_r6_cmp_s(ctx
, (ctx
->opcode
>> 6) & 0x1f, rt
, rs
, rd
);
16431 check_insn(ctx
, ISA_MIPS_R6
);
16432 gen_r6_cmp_d(ctx
, (ctx
->opcode
>> 6) & 0x1f, rt
, rs
, rd
);
16435 gen_pool32fxf(ctx
, rt
, rs
);
16439 switch ((ctx
->opcode
>> 6) & 0x7) {
16441 mips32_op
= OPC_PLL_PS
;
16444 mips32_op
= OPC_PLU_PS
;
16447 mips32_op
= OPC_PUL_PS
;
16450 mips32_op
= OPC_PUU_PS
;
16453 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16454 mips32_op
= OPC_CVT_PS_S
;
16456 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
16459 goto pool32f_invalid
;
16463 check_insn(ctx
, ISA_MIPS_R6
);
16464 switch ((ctx
->opcode
>> 9) & 0x3) {
16466 gen_farith(ctx
, OPC_MIN_S
, rt
, rs
, rd
, 0);
16469 gen_farith(ctx
, OPC_MIN_D
, rt
, rs
, rd
, 0);
16472 goto pool32f_invalid
;
16477 switch ((ctx
->opcode
>> 6) & 0x7) {
16479 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16480 mips32_op
= OPC_LWXC1
;
16483 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16484 mips32_op
= OPC_SWXC1
;
16487 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16488 mips32_op
= OPC_LDXC1
;
16491 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16492 mips32_op
= OPC_SDXC1
;
16495 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16496 mips32_op
= OPC_LUXC1
;
16499 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16500 mips32_op
= OPC_SUXC1
;
16502 gen_flt3_ldst(ctx
, mips32_op
, rd
, rd
, rt
, rs
);
16505 goto pool32f_invalid
;
16509 check_insn(ctx
, ISA_MIPS_R6
);
16510 switch ((ctx
->opcode
>> 9) & 0x3) {
16512 gen_farith(ctx
, OPC_MAX_S
, rt
, rs
, rd
, 0);
16515 gen_farith(ctx
, OPC_MAX_D
, rt
, rs
, rd
, 0);
16518 goto pool32f_invalid
;
16523 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16524 fmt
= (ctx
->opcode
>> 9) & 0x3;
16525 switch ((ctx
->opcode
>> 6) & 0x7) {
16529 mips32_op
= OPC_RSQRT2_S
;
16532 mips32_op
= OPC_RSQRT2_D
;
16535 mips32_op
= OPC_RSQRT2_PS
;
16538 goto pool32f_invalid
;
16544 mips32_op
= OPC_RECIP2_S
;
16547 mips32_op
= OPC_RECIP2_D
;
16550 mips32_op
= OPC_RECIP2_PS
;
16553 goto pool32f_invalid
;
16557 mips32_op
= OPC_ADDR_PS
;
16560 mips32_op
= OPC_MULR_PS
;
16562 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
16565 goto pool32f_invalid
;
16569 /* MOV[FT].fmt, PREFX, RINT.fmt, CLASS.fmt*/
16570 cc
= (ctx
->opcode
>> 13) & 0x7;
16571 fmt
= (ctx
->opcode
>> 9) & 0x3;
16572 switch ((ctx
->opcode
>> 6) & 0x7) {
16573 case MOVF_FMT
: /* RINT_FMT */
16574 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16578 gen_farith(ctx
, OPC_RINT_S
, 0, rt
, rs
, 0);
16581 gen_farith(ctx
, OPC_RINT_D
, 0, rt
, rs
, 0);
16584 goto pool32f_invalid
;
16590 gen_movcf_s(ctx
, rs
, rt
, cc
, 0);
16593 gen_movcf_d(ctx
, rs
, rt
, cc
, 0);
16597 gen_movcf_ps(ctx
, rs
, rt
, cc
, 0);
16600 goto pool32f_invalid
;
16604 case MOVT_FMT
: /* CLASS_FMT */
16605 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16609 gen_farith(ctx
, OPC_CLASS_S
, 0, rt
, rs
, 0);
16612 gen_farith(ctx
, OPC_CLASS_D
, 0, rt
, rs
, 0);
16615 goto pool32f_invalid
;
16621 gen_movcf_s(ctx
, rs
, rt
, cc
, 1);
16624 gen_movcf_d(ctx
, rs
, rt
, cc
, 1);
16628 gen_movcf_ps(ctx
, rs
, rt
, cc
, 1);
16631 goto pool32f_invalid
;
16636 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16639 goto pool32f_invalid
;
16642 #define FINSN_3ARG_SDPS(prfx) \
16643 switch ((ctx->opcode >> 8) & 0x3) { \
16645 mips32_op = OPC_##prfx##_S; \
16648 mips32_op = OPC_##prfx##_D; \
16650 case FMT_SDPS_PS: \
16652 mips32_op = OPC_##prfx##_PS; \
16655 goto pool32f_invalid; \
16658 check_insn(ctx
, ISA_MIPS_R6
);
16659 switch ((ctx
->opcode
>> 9) & 0x3) {
16661 gen_farith(ctx
, OPC_MINA_S
, rt
, rs
, rd
, 0);
16664 gen_farith(ctx
, OPC_MINA_D
, rt
, rs
, rd
, 0);
16667 goto pool32f_invalid
;
16671 check_insn(ctx
, ISA_MIPS_R6
);
16672 switch ((ctx
->opcode
>> 9) & 0x3) {
16674 gen_farith(ctx
, OPC_MAXA_S
, rt
, rs
, rd
, 0);
16677 gen_farith(ctx
, OPC_MAXA_D
, rt
, rs
, rd
, 0);
16680 goto pool32f_invalid
;
16684 /* regular FP ops */
16685 switch ((ctx
->opcode
>> 6) & 0x3) {
16687 FINSN_3ARG_SDPS(ADD
);
16690 FINSN_3ARG_SDPS(SUB
);
16693 FINSN_3ARG_SDPS(MUL
);
16696 fmt
= (ctx
->opcode
>> 8) & 0x3;
16698 mips32_op
= OPC_DIV_D
;
16699 } else if (fmt
== 0) {
16700 mips32_op
= OPC_DIV_S
;
16702 goto pool32f_invalid
;
16706 goto pool32f_invalid
;
16711 switch ((ctx
->opcode
>> 6) & 0x7) {
16712 case MOVN_FMT
: /* SELEQZ_FMT */
16713 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16715 switch ((ctx
->opcode
>> 9) & 0x3) {
16717 gen_sel_s(ctx
, OPC_SELEQZ_S
, rd
, rt
, rs
);
16720 gen_sel_d(ctx
, OPC_SELEQZ_D
, rd
, rt
, rs
);
16723 goto pool32f_invalid
;
16727 FINSN_3ARG_SDPS(MOVN
);
16731 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16732 FINSN_3ARG_SDPS(MOVN
);
16734 case MOVZ_FMT
: /* SELNEZ_FMT */
16735 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16737 switch ((ctx
->opcode
>> 9) & 0x3) {
16739 gen_sel_s(ctx
, OPC_SELNEZ_S
, rd
, rt
, rs
);
16742 gen_sel_d(ctx
, OPC_SELNEZ_D
, rd
, rt
, rs
);
16745 goto pool32f_invalid
;
16749 FINSN_3ARG_SDPS(MOVZ
);
16753 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16754 FINSN_3ARG_SDPS(MOVZ
);
16757 check_insn(ctx
, ISA_MIPS_R6
);
16758 switch ((ctx
->opcode
>> 9) & 0x3) {
16760 gen_sel_s(ctx
, OPC_SEL_S
, rd
, rt
, rs
);
16763 gen_sel_d(ctx
, OPC_SEL_D
, rd
, rt
, rs
);
16766 goto pool32f_invalid
;
16770 check_insn(ctx
, ISA_MIPS_R6
);
16771 switch ((ctx
->opcode
>> 9) & 0x3) {
16773 mips32_op
= OPC_MADDF_S
;
16776 mips32_op
= OPC_MADDF_D
;
16779 goto pool32f_invalid
;
16783 check_insn(ctx
, ISA_MIPS_R6
);
16784 switch ((ctx
->opcode
>> 9) & 0x3) {
16786 mips32_op
= OPC_MSUBF_S
;
16789 mips32_op
= OPC_MSUBF_D
;
16792 goto pool32f_invalid
;
16796 goto pool32f_invalid
;
16800 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
16804 MIPS_INVAL("pool32f");
16805 gen_reserved_instruction(ctx
);
16809 generate_exception_err(ctx
, EXCP_CpU
, 1);
16813 minor
= (ctx
->opcode
>> 21) & 0x1f;
16816 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16817 gen_compute_branch(ctx
, OPC_BLTZ
, 4, rs
, -1, imm
<< 1, 4);
16820 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16821 gen_compute_branch(ctx
, OPC_BLTZAL
, 4, rs
, -1, imm
<< 1, 4);
16822 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
16825 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16826 gen_compute_branch(ctx
, OPC_BLTZAL
, 4, rs
, -1, imm
<< 1, 2);
16827 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
16830 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16831 gen_compute_branch(ctx
, OPC_BGEZ
, 4, rs
, -1, imm
<< 1, 4);
16834 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16835 gen_compute_branch(ctx
, OPC_BGEZAL
, 4, rs
, -1, imm
<< 1, 4);
16836 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
16839 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16840 gen_compute_branch(ctx
, OPC_BGEZAL
, 4, rs
, -1, imm
<< 1, 2);
16841 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
16844 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16845 gen_compute_branch(ctx
, OPC_BLEZ
, 4, rs
, -1, imm
<< 1, 4);
16848 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16849 gen_compute_branch(ctx
, OPC_BGTZ
, 4, rs
, -1, imm
<< 1, 4);
16853 case TLTI
: /* BC1EQZC */
16854 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16856 check_cp1_enabled(ctx
);
16857 gen_compute_branch1_r6(ctx
, OPC_BC1EQZ
, rs
, imm
<< 1, 0);
16860 mips32_op
= OPC_TLTI
;
16864 case TGEI
: /* BC1NEZC */
16865 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16867 check_cp1_enabled(ctx
);
16868 gen_compute_branch1_r6(ctx
, OPC_BC1NEZ
, rs
, imm
<< 1, 0);
16871 mips32_op
= OPC_TGEI
;
16876 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16877 mips32_op
= OPC_TLTIU
;
16880 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16881 mips32_op
= OPC_TGEIU
;
16883 case TNEI
: /* SYNCI */
16884 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16887 * Break the TB to be able to sync copied instructions
16890 ctx
->base
.is_jmp
= DISAS_STOP
;
16893 mips32_op
= OPC_TNEI
;
16898 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16899 mips32_op
= OPC_TEQI
;
16901 gen_trap(ctx
, mips32_op
, rs
, -1, imm
);
16906 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16907 gen_compute_branch(ctx
, minor
== BNEZC
? OPC_BNE
: OPC_BEQ
,
16908 4, rs
, 0, imm
<< 1, 0);
16910 * Compact branches don't have a delay slot, so just let
16911 * the normal delay slot handling take us to the branch
16916 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16917 gen_logic_imm(ctx
, OPC_LUI
, rs
, 0, imm
);
16920 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16922 * Break the TB to be able to sync copied instructions
16925 ctx
->base
.is_jmp
= DISAS_STOP
;
16929 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16930 /* COP2: Not implemented. */
16931 generate_exception_err(ctx
, EXCP_CpU
, 2);
16934 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16935 mips32_op
= (ctx
->opcode
& (1 << 16)) ? OPC_BC1FANY2
: OPC_BC1F
;
16938 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16939 mips32_op
= (ctx
->opcode
& (1 << 16)) ? OPC_BC1TANY2
: OPC_BC1T
;
16942 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16943 mips32_op
= OPC_BC1FANY4
;
16946 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16947 mips32_op
= OPC_BC1TANY4
;
16950 check_insn(ctx
, ASE_MIPS3D
);
16953 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
16954 check_cp1_enabled(ctx
);
16955 gen_compute_branch1(ctx
, mips32_op
,
16956 (ctx
->opcode
>> 18) & 0x7, imm
<< 1);
16958 generate_exception_err(ctx
, EXCP_CpU
, 1);
16963 /* MIPS DSP: not implemented */
16966 MIPS_INVAL("pool32i");
16967 gen_reserved_instruction(ctx
);
16972 minor
= (ctx
->opcode
>> 12) & 0xf;
16973 offset
= sextract32(ctx
->opcode
, 0,
16974 (ctx
->insn_flags
& ISA_MIPS_R6
) ? 9 : 12);
16977 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16978 mips32_op
= OPC_LWL
;
16981 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16982 mips32_op
= OPC_SWL
;
16985 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16986 mips32_op
= OPC_LWR
;
16989 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16990 mips32_op
= OPC_SWR
;
16992 #if defined(TARGET_MIPS64)
16994 check_insn(ctx
, ISA_MIPS3
);
16995 check_mips_64(ctx
);
16996 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16997 mips32_op
= OPC_LDL
;
17000 check_insn(ctx
, ISA_MIPS3
);
17001 check_mips_64(ctx
);
17002 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17003 mips32_op
= OPC_SDL
;
17006 check_insn(ctx
, ISA_MIPS3
);
17007 check_mips_64(ctx
);
17008 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17009 mips32_op
= OPC_LDR
;
17012 check_insn(ctx
, ISA_MIPS3
);
17013 check_mips_64(ctx
);
17014 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17015 mips32_op
= OPC_SDR
;
17018 check_insn(ctx
, ISA_MIPS3
);
17019 check_mips_64(ctx
);
17020 mips32_op
= OPC_LWU
;
17023 check_insn(ctx
, ISA_MIPS3
);
17024 check_mips_64(ctx
);
17025 mips32_op
= OPC_LLD
;
17029 mips32_op
= OPC_LL
;
17032 gen_ld(ctx
, mips32_op
, rt
, rs
, offset
);
17035 gen_st(ctx
, mips32_op
, rt
, rs
, offset
);
17038 gen_st_cond(ctx
, rt
, rs
, offset
, MO_TESL
, false);
17040 #if defined(TARGET_MIPS64)
17042 check_insn(ctx
, ISA_MIPS3
);
17043 check_mips_64(ctx
);
17044 gen_st_cond(ctx
, rt
, rs
, offset
, MO_TEQ
, false);
17049 MIPS_INVAL("pool32c ld-eva");
17050 gen_reserved_instruction(ctx
);
17053 check_cp0_enabled(ctx
);
17055 minor2
= (ctx
->opcode
>> 9) & 0x7;
17056 offset
= sextract32(ctx
->opcode
, 0, 9);
17059 mips32_op
= OPC_LBUE
;
17062 mips32_op
= OPC_LHUE
;
17065 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17066 mips32_op
= OPC_LWLE
;
17069 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17070 mips32_op
= OPC_LWRE
;
17073 mips32_op
= OPC_LBE
;
17076 mips32_op
= OPC_LHE
;
17079 mips32_op
= OPC_LLE
;
17082 mips32_op
= OPC_LWE
;
17088 MIPS_INVAL("pool32c st-eva");
17089 gen_reserved_instruction(ctx
);
17092 check_cp0_enabled(ctx
);
17094 minor2
= (ctx
->opcode
>> 9) & 0x7;
17095 offset
= sextract32(ctx
->opcode
, 0, 9);
17098 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17099 mips32_op
= OPC_SWLE
;
17102 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17103 mips32_op
= OPC_SWRE
;
17106 /* Treat as no-op */
17107 if ((ctx
->insn_flags
& ISA_MIPS_R6
) && (rt
>= 24)) {
17108 /* hint codes 24-31 are reserved and signal RI */
17109 generate_exception(ctx
, EXCP_RI
);
17113 /* Treat as no-op */
17114 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
17115 gen_cache_operation(ctx
, rt
, rs
, offset
);
17119 mips32_op
= OPC_SBE
;
17122 mips32_op
= OPC_SHE
;
17125 gen_st_cond(ctx
, rt
, rs
, offset
, MO_TESL
, true);
17128 mips32_op
= OPC_SWE
;
17133 /* Treat as no-op */
17134 if ((ctx
->insn_flags
& ISA_MIPS_R6
) && (rt
>= 24)) {
17135 /* hint codes 24-31 are reserved and signal RI */
17136 generate_exception(ctx
, EXCP_RI
);
17140 MIPS_INVAL("pool32c");
17141 gen_reserved_instruction(ctx
);
17145 case ADDI32
: /* AUI, LUI */
17146 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
17148 gen_logic_imm(ctx
, OPC_LUI
, rt
, rs
, imm
);
17151 mips32_op
= OPC_ADDI
;
17156 mips32_op
= OPC_ADDIU
;
17158 gen_arith_imm(ctx
, mips32_op
, rt
, rs
, imm
);
17161 /* Logical operations */
17163 mips32_op
= OPC_ORI
;
17166 mips32_op
= OPC_XORI
;
17169 mips32_op
= OPC_ANDI
;
17171 gen_logic_imm(ctx
, mips32_op
, rt
, rs
, imm
);
17174 /* Set less than immediate */
17176 mips32_op
= OPC_SLTI
;
17179 mips32_op
= OPC_SLTIU
;
17181 gen_slt_imm(ctx
, mips32_op
, rt
, rs
, imm
);
17184 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17185 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
17186 gen_compute_branch(ctx
, OPC_JALX
, 4, rt
, rs
, offset
, 4);
17187 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
17189 case JALS32
: /* BOVC, BEQC, BEQZALC */
17190 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
17193 mips32_op
= OPC_BOVC
;
17194 } else if (rs
< rt
&& rs
== 0) {
17196 mips32_op
= OPC_BEQZALC
;
17199 mips32_op
= OPC_BEQC
;
17201 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
17204 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1;
17205 gen_compute_branch(ctx
, OPC_JAL
, 4, rt
, rs
, offset
, 2);
17206 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
17209 case BEQ32
: /* BC */
17210 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
17212 gen_compute_compact_branch(ctx
, OPC_BC
, 0, 0,
17213 sextract32(ctx
->opcode
<< 1, 0, 27));
17216 gen_compute_branch(ctx
, OPC_BEQ
, 4, rt
, rs
, imm
<< 1, 4);
17219 case BNE32
: /* BALC */
17220 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
17222 gen_compute_compact_branch(ctx
, OPC_BALC
, 0, 0,
17223 sextract32(ctx
->opcode
<< 1, 0, 27));
17226 gen_compute_branch(ctx
, OPC_BNE
, 4, rt
, rs
, imm
<< 1, 4);
17229 case J32
: /* BGTZC, BLTZC, BLTC */
17230 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
17231 if (rs
== 0 && rt
!= 0) {
17233 mips32_op
= OPC_BGTZC
;
17234 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
17236 mips32_op
= OPC_BLTZC
;
17239 mips32_op
= OPC_BLTC
;
17241 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
17244 gen_compute_branch(ctx
, OPC_J
, 4, rt
, rs
,
17245 (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1, 4);
17248 case JAL32
: /* BLEZC, BGEZC, BGEC */
17249 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
17250 if (rs
== 0 && rt
!= 0) {
17252 mips32_op
= OPC_BLEZC
;
17253 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
17255 mips32_op
= OPC_BGEZC
;
17258 mips32_op
= OPC_BGEC
;
17260 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
17263 gen_compute_branch(ctx
, OPC_JAL
, 4, rt
, rs
,
17264 (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1, 4);
17265 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
17268 /* Floating point (COP1) */
17270 mips32_op
= OPC_LWC1
;
17273 mips32_op
= OPC_LDC1
;
17276 mips32_op
= OPC_SWC1
;
17279 mips32_op
= OPC_SDC1
;
17281 gen_cop1_ldst(ctx
, mips32_op
, rt
, rs
, imm
);
17283 case ADDIUPC
: /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
17284 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
17285 /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
17286 switch ((ctx
->opcode
>> 16) & 0x1f) {
17295 gen_pcrel(ctx
, OPC_ADDIUPC
, ctx
->base
.pc_next
& ~0x3, rt
);
17298 gen_pcrel(ctx
, OPC_AUIPC
, ctx
->base
.pc_next
, rt
);
17301 gen_pcrel(ctx
, OPC_ALUIPC
, ctx
->base
.pc_next
, rt
);
17311 gen_pcrel(ctx
, R6_OPC_LWPC
, ctx
->base
.pc_next
& ~0x3, rt
);
17314 generate_exception(ctx
, EXCP_RI
);
17319 int reg
= mmreg(ZIMM(ctx
->opcode
, 23, 3));
17320 offset
= SIMM(ctx
->opcode
, 0, 23) << 2;
17322 gen_addiupc(ctx
, reg
, offset
, 0, 0);
17325 case BNVC
: /* BNEC, BNEZALC */
17326 check_insn(ctx
, ISA_MIPS_R6
);
17329 mips32_op
= OPC_BNVC
;
17330 } else if (rs
< rt
&& rs
== 0) {
17332 mips32_op
= OPC_BNEZALC
;
17335 mips32_op
= OPC_BNEC
;
17337 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
17339 case R6_BNEZC
: /* JIALC */
17340 check_insn(ctx
, ISA_MIPS_R6
);
17343 gen_compute_compact_branch(ctx
, OPC_BNEZC
, rt
, 0,
17344 sextract32(ctx
->opcode
<< 1, 0, 22));
17347 gen_compute_compact_branch(ctx
, OPC_JIALC
, 0, rs
, imm
);
17350 case R6_BEQZC
: /* JIC */
17351 check_insn(ctx
, ISA_MIPS_R6
);
17354 gen_compute_compact_branch(ctx
, OPC_BEQZC
, rt
, 0,
17355 sextract32(ctx
->opcode
<< 1, 0, 22));
17358 gen_compute_compact_branch(ctx
, OPC_JIC
, 0, rs
, imm
);
17361 case BLEZALC
: /* BGEZALC, BGEUC */
17362 check_insn(ctx
, ISA_MIPS_R6
);
17363 if (rs
== 0 && rt
!= 0) {
17365 mips32_op
= OPC_BLEZALC
;
17366 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
17368 mips32_op
= OPC_BGEZALC
;
17371 mips32_op
= OPC_BGEUC
;
17373 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
17375 case BGTZALC
: /* BLTZALC, BLTUC */
17376 check_insn(ctx
, ISA_MIPS_R6
);
17377 if (rs
== 0 && rt
!= 0) {
17379 mips32_op
= OPC_BGTZALC
;
17380 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
17382 mips32_op
= OPC_BLTZALC
;
17385 mips32_op
= OPC_BLTUC
;
17387 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
17389 /* Loads and stores */
17391 mips32_op
= OPC_LB
;
17394 mips32_op
= OPC_LBU
;
17397 mips32_op
= OPC_LH
;
17400 mips32_op
= OPC_LHU
;
17403 mips32_op
= OPC_LW
;
17405 #ifdef TARGET_MIPS64
17407 check_insn(ctx
, ISA_MIPS3
);
17408 check_mips_64(ctx
);
17409 mips32_op
= OPC_LD
;
17412 check_insn(ctx
, ISA_MIPS3
);
17413 check_mips_64(ctx
);
17414 mips32_op
= OPC_SD
;
17418 mips32_op
= OPC_SB
;
17421 mips32_op
= OPC_SH
;
17424 mips32_op
= OPC_SW
;
17427 gen_ld(ctx
, mips32_op
, rt
, rs
, imm
);
17430 gen_st(ctx
, mips32_op
, rt
, rs
, imm
);
17433 gen_reserved_instruction(ctx
);
17438 static int decode_micromips_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
17442 /* make sure instructions are on a halfword boundary */
17443 if (ctx
->base
.pc_next
& 0x1) {
17444 env
->CP0_BadVAddr
= ctx
->base
.pc_next
;
17445 generate_exception_end(ctx
, EXCP_AdEL
);
17449 op
= (ctx
->opcode
>> 10) & 0x3f;
17450 /* Enforce properly-sized instructions in a delay slot */
17451 if (ctx
->hflags
& MIPS_HFLAG_BDS_STRICT
) {
17452 switch (op
& 0x7) { /* MSB-3..MSB-5 */
17454 /* POOL32A, POOL32B, POOL32I, POOL32C */
17456 /* ADDI32, ADDIU32, ORI32, XORI32, SLTI32, SLTIU32, ANDI32, JALX32 */
17458 /* LBU32, LHU32, POOL32F, JALS32, BEQ32, BNE32, J32, JAL32 */
17460 /* SB32, SH32, ADDIUPC, SWC132, SDC132, SW32 */
17462 /* LB32, LH32, LWC132, LDC132, LW32 */
17463 if (ctx
->hflags
& MIPS_HFLAG_BDS16
) {
17464 gen_reserved_instruction(ctx
);
17469 /* POOL16A, POOL16B, POOL16C, LWGP16, POOL16F */
17471 /* LBU16, LHU16, LWSP16, LW16, SB16, SH16, SWSP16, SW16 */
17473 /* MOVE16, ANDI16, POOL16D, POOL16E, BEQZ16, BNEZ16, B16, LI16 */
17474 if (ctx
->hflags
& MIPS_HFLAG_BDS32
) {
17475 gen_reserved_instruction(ctx
);
17485 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
17486 int rs1
= mmreg(uMIPS_RS1(ctx
->opcode
));
17487 int rs2
= mmreg(uMIPS_RS2(ctx
->opcode
));
17490 switch (ctx
->opcode
& 0x1) {
17498 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
17500 * In the Release 6, the register number location in
17501 * the instruction encoding has changed.
17503 gen_arith(ctx
, opc
, rs1
, rd
, rs2
);
17505 gen_arith(ctx
, opc
, rd
, rs1
, rs2
);
17511 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
17512 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
17513 int amount
= (ctx
->opcode
>> 1) & 0x7;
17515 amount
= amount
== 0 ? 8 : amount
;
17517 switch (ctx
->opcode
& 0x1) {
17526 gen_shift_imm(ctx
, opc
, rd
, rs
, amount
);
17530 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
17531 gen_pool16c_r6_insn(ctx
);
17533 gen_pool16c_insn(ctx
);
17538 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
17539 int rb
= 28; /* GP */
17540 int16_t offset
= SIMM(ctx
->opcode
, 0, 7) << 2;
17542 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
17546 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17547 if (ctx
->opcode
& 1) {
17548 gen_reserved_instruction(ctx
);
17551 int enc_dest
= uMIPS_RD(ctx
->opcode
);
17552 int enc_rt
= uMIPS_RS2(ctx
->opcode
);
17553 int enc_rs
= uMIPS_RS1(ctx
->opcode
);
17554 gen_movep(ctx
, enc_dest
, enc_rt
, enc_rs
);
17559 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
17560 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
17561 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4);
17562 offset
= (offset
== 0xf ? -1 : offset
);
17564 gen_ld(ctx
, OPC_LBU
, rd
, rb
, offset
);
17569 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
17570 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
17571 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 1;
17573 gen_ld(ctx
, OPC_LHU
, rd
, rb
, offset
);
17578 int rd
= (ctx
->opcode
>> 5) & 0x1f;
17579 int rb
= 29; /* SP */
17580 int16_t offset
= ZIMM(ctx
->opcode
, 0, 5) << 2;
17582 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
17587 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
17588 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
17589 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 2;
17591 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
17596 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
17597 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
17598 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4);
17600 gen_st(ctx
, OPC_SB
, rd
, rb
, offset
);
17605 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
17606 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
17607 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 1;
17609 gen_st(ctx
, OPC_SH
, rd
, rb
, offset
);
17614 int rd
= (ctx
->opcode
>> 5) & 0x1f;
17615 int rb
= 29; /* SP */
17616 int16_t offset
= ZIMM(ctx
->opcode
, 0, 5) << 2;
17618 gen_st(ctx
, OPC_SW
, rd
, rb
, offset
);
17623 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
17624 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
17625 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 2;
17627 gen_st(ctx
, OPC_SW
, rd
, rb
, offset
);
17632 int rd
= uMIPS_RD5(ctx
->opcode
);
17633 int rs
= uMIPS_RS5(ctx
->opcode
);
17635 gen_arith(ctx
, OPC_ADDU
, rd
, rs
, 0);
17642 switch (ctx
->opcode
& 0x1) {
17652 switch (ctx
->opcode
& 0x1) {
17657 gen_addiur1sp(ctx
);
17661 case B16
: /* BC16 */
17662 gen_compute_branch(ctx
, OPC_BEQ
, 2, 0, 0,
17663 sextract32(ctx
->opcode
, 0, 10) << 1,
17664 (ctx
->insn_flags
& ISA_MIPS_R6
) ? 0 : 4);
17666 case BNEZ16
: /* BNEZC16 */
17667 case BEQZ16
: /* BEQZC16 */
17668 gen_compute_branch(ctx
, op
== BNEZ16
? OPC_BNE
: OPC_BEQ
, 2,
17669 mmreg(uMIPS_RD(ctx
->opcode
)),
17670 0, sextract32(ctx
->opcode
, 0, 7) << 1,
17671 (ctx
->insn_flags
& ISA_MIPS_R6
) ? 0 : 4);
17676 int reg
= mmreg(uMIPS_RD(ctx
->opcode
));
17677 int imm
= ZIMM(ctx
->opcode
, 0, 7);
17679 imm
= (imm
== 0x7f ? -1 : imm
);
17680 tcg_gen_movi_tl(cpu_gpr
[reg
], imm
);
17686 gen_reserved_instruction(ctx
);
17689 decode_micromips32_opc(env
, ctx
);
17702 /* MAJOR, P16, and P32 pools opcodes */
17706 NM_MOVE_BALC
= 0x02,
17714 NM_P16_SHIFT
= 0x0c,
17732 NM_P_LS_U12
= 0x21,
17742 NM_P16_ADDU
= 0x2c,
17756 NM_MOVEPREV
= 0x3f,
17759 /* POOL32A instruction pool */
17761 NM_POOL32A0
= 0x00,
17762 NM_SPECIAL2
= 0x01,
17765 NM_POOL32A5
= 0x05,
17766 NM_POOL32A7
= 0x07,
17769 /* P.GP.W instruction pool */
17771 NM_ADDIUGP_W
= 0x00,
17776 /* P48I instruction pool */
17780 NM_ADDIUGP48
= 0x02,
17781 NM_ADDIUPC48
= 0x03,
17786 /* P.U12 instruction pool */
17795 NM_ADDIUNEG
= 0x08,
17802 /* POOL32F instruction pool */
17804 NM_POOL32F_0
= 0x00,
17805 NM_POOL32F_3
= 0x03,
17806 NM_POOL32F_5
= 0x05,
17809 /* POOL32S instruction pool */
17811 NM_POOL32S_0
= 0x00,
17812 NM_POOL32S_4
= 0x04,
17815 /* P.LUI instruction pool */
17821 /* P.GP.BH instruction pool */
17826 NM_ADDIUGP_B
= 0x03,
17829 NM_P_GP_CP1
= 0x06,
17832 /* P.LS.U12 instruction pool */
17837 NM_P_PREFU12
= 0x03,
17850 /* P.LS.S9 instruction pool */
17856 NM_P_LS_UAWM
= 0x05,
17859 /* P.BAL instruction pool */
17865 /* P.J instruction pool */
17868 NM_JALRC_HB
= 0x01,
17869 NM_P_BALRSC
= 0x08,
17872 /* P.BR1 instruction pool */
17880 /* P.BR2 instruction pool */
17887 /* P.BRI instruction pool */
17899 /* P16.SHIFT instruction pool */
17905 /* POOL16C instruction pool */
17907 NM_POOL16C_0
= 0x00,
17911 /* P16.A1 instruction pool */
17913 NM_ADDIUR1SP
= 0x01,
17916 /* P16.A2 instruction pool */
17919 NM_P_ADDIURS5
= 0x01,
17922 /* P16.ADDU instruction pool */
17928 /* P16.SR instruction pool */
17931 NM_RESTORE_JRC16
= 0x01,
17934 /* P16.4X4 instruction pool */
17940 /* P16.LB instruction pool */
17947 /* P16.LH instruction pool */
17954 /* P.RI instruction pool */
17957 NM_P_SYSCALL
= 0x01,
17962 /* POOL32A0 instruction pool */
17997 NM_D_E_MT_VPE
= 0x56,
18005 /* CRC32 instruction pool */
18015 /* POOL32A5 instruction pool */
18017 NM_CMP_EQ_PH
= 0x00,
18018 NM_CMP_LT_PH
= 0x08,
18019 NM_CMP_LE_PH
= 0x10,
18020 NM_CMPGU_EQ_QB
= 0x18,
18021 NM_CMPGU_LT_QB
= 0x20,
18022 NM_CMPGU_LE_QB
= 0x28,
18023 NM_CMPGDU_EQ_QB
= 0x30,
18024 NM_CMPGDU_LT_QB
= 0x38,
18025 NM_CMPGDU_LE_QB
= 0x40,
18026 NM_CMPU_EQ_QB
= 0x48,
18027 NM_CMPU_LT_QB
= 0x50,
18028 NM_CMPU_LE_QB
= 0x58,
18029 NM_ADDQ_S_W
= 0x60,
18030 NM_SUBQ_S_W
= 0x68,
18034 NM_ADDQ_S_PH
= 0x01,
18035 NM_ADDQH_R_PH
= 0x09,
18036 NM_ADDQH_R_W
= 0x11,
18037 NM_ADDU_S_QB
= 0x19,
18038 NM_ADDU_S_PH
= 0x21,
18039 NM_ADDUH_R_QB
= 0x29,
18040 NM_SHRAV_R_PH
= 0x31,
18041 NM_SHRAV_R_QB
= 0x39,
18042 NM_SUBQ_S_PH
= 0x41,
18043 NM_SUBQH_R_PH
= 0x49,
18044 NM_SUBQH_R_W
= 0x51,
18045 NM_SUBU_S_QB
= 0x59,
18046 NM_SUBU_S_PH
= 0x61,
18047 NM_SUBUH_R_QB
= 0x69,
18048 NM_SHLLV_S_PH
= 0x71,
18049 NM_PRECR_SRA_R_PH_W
= 0x79,
18051 NM_MULEU_S_PH_QBL
= 0x12,
18052 NM_MULEU_S_PH_QBR
= 0x1a,
18053 NM_MULQ_RS_PH
= 0x22,
18054 NM_MULQ_S_PH
= 0x2a,
18055 NM_MULQ_RS_W
= 0x32,
18056 NM_MULQ_S_W
= 0x3a,
18059 NM_SHRAV_R_W
= 0x5a,
18060 NM_SHRLV_PH
= 0x62,
18061 NM_SHRLV_QB
= 0x6a,
18062 NM_SHLLV_QB
= 0x72,
18063 NM_SHLLV_S_W
= 0x7a,
18067 NM_MULEQ_S_W_PHL
= 0x04,
18068 NM_MULEQ_S_W_PHR
= 0x0c,
18070 NM_MUL_S_PH
= 0x05,
18071 NM_PRECR_QB_PH
= 0x0d,
18072 NM_PRECRQ_QB_PH
= 0x15,
18073 NM_PRECRQ_PH_W
= 0x1d,
18074 NM_PRECRQ_RS_PH_W
= 0x25,
18075 NM_PRECRQU_S_QB_PH
= 0x2d,
18076 NM_PACKRL_PH
= 0x35,
18080 NM_SHRA_R_W
= 0x5e,
18081 NM_SHRA_R_PH
= 0x66,
18082 NM_SHLL_S_PH
= 0x76,
18083 NM_SHLL_S_W
= 0x7e,
18088 /* POOL32A7 instruction pool */
18093 NM_POOL32AXF
= 0x07,
18096 /* P.SR instruction pool */
18102 /* P.SHIFT instruction pool */
18110 /* P.ROTX instruction pool */
18115 /* P.INS instruction pool */
18120 /* P.EXT instruction pool */
18125 /* POOL32F_0 (fmt) instruction pool */
18130 NM_SELEQZ_S
= 0x07,
18131 NM_SELEQZ_D
= 0x47,
18135 NM_SELNEZ_S
= 0x0f,
18136 NM_SELNEZ_D
= 0x4f,
18151 /* POOL32F_3 instruction pool */
18155 NM_MINA_FMT
= 0x04,
18156 NM_MAXA_FMT
= 0x05,
18157 NM_POOL32FXF
= 0x07,
18160 /* POOL32F_5 instruction pool */
18162 NM_CMP_CONDN_S
= 0x00,
18163 NM_CMP_CONDN_D
= 0x02,
18166 /* P.GP.LH instruction pool */
18172 /* P.GP.SH instruction pool */
18177 /* P.GP.CP1 instruction pool */
18185 /* P.LS.S0 instruction pool */
18202 NM_P_PREFS9
= 0x03,
18208 /* P.LS.S1 instruction pool */
18210 NM_ASET_ACLR
= 0x02,
18218 /* P.LS.E0 instruction pool */
18234 /* P.PREFE instruction pool */
18240 /* P.LLE instruction pool */
18246 /* P.SCE instruction pool */
18252 /* P.LS.WM instruction pool */
18258 /* P.LS.UAWM instruction pool */
18264 /* P.BR3A instruction pool */
18270 NM_BPOSGE32C
= 0x04,
18273 /* P16.RI instruction pool */
18275 NM_P16_SYSCALL
= 0x01,
18280 /* POOL16C_0 instruction pool */
18282 NM_POOL16C_00
= 0x00,
18285 /* P16.JRC instruction pool */
18291 /* P.SYSCALL instruction pool */
18297 /* P.TRAP instruction pool */
18303 /* P.CMOVE instruction pool */
18309 /* POOL32Axf instruction pool */
18311 NM_POOL32AXF_1
= 0x01,
18312 NM_POOL32AXF_2
= 0x02,
18313 NM_POOL32AXF_4
= 0x04,
18314 NM_POOL32AXF_5
= 0x05,
18315 NM_POOL32AXF_7
= 0x07,
18318 /* POOL32Axf_1 instruction pool */
18320 NM_POOL32AXF_1_0
= 0x00,
18321 NM_POOL32AXF_1_1
= 0x01,
18322 NM_POOL32AXF_1_3
= 0x03,
18323 NM_POOL32AXF_1_4
= 0x04,
18324 NM_POOL32AXF_1_5
= 0x05,
18325 NM_POOL32AXF_1_7
= 0x07,
18328 /* POOL32Axf_2 instruction pool */
18330 NM_POOL32AXF_2_0_7
= 0x00,
18331 NM_POOL32AXF_2_8_15
= 0x01,
18332 NM_POOL32AXF_2_16_23
= 0x02,
18333 NM_POOL32AXF_2_24_31
= 0x03,
18336 /* POOL32Axf_7 instruction pool */
18338 NM_SHRA_R_QB
= 0x0,
18343 /* POOL32Axf_1_0 instruction pool */
18351 /* POOL32Axf_1_1 instruction pool */
18357 /* POOL32Axf_1_3 instruction pool */
18365 /* POOL32Axf_1_4 instruction pool */
18371 /* POOL32Axf_1_5 instruction pool */
18373 NM_MAQ_S_W_PHR
= 0x0,
18374 NM_MAQ_S_W_PHL
= 0x1,
18375 NM_MAQ_SA_W_PHR
= 0x2,
18376 NM_MAQ_SA_W_PHL
= 0x3,
18379 /* POOL32Axf_1_7 instruction pool */
18383 NM_EXTR_RS_W
= 0x2,
18387 /* POOL32Axf_2_0_7 instruction pool */
18390 NM_DPAQ_S_W_PH
= 0x1,
18392 NM_DPSQ_S_W_PH
= 0x3,
18399 /* POOL32Axf_2_8_15 instruction pool */
18401 NM_DPAX_W_PH
= 0x0,
18402 NM_DPAQ_SA_L_W
= 0x1,
18403 NM_DPSX_W_PH
= 0x2,
18404 NM_DPSQ_SA_L_W
= 0x3,
18407 NM_EXTRV_R_W
= 0x7,
18410 /* POOL32Axf_2_16_23 instruction pool */
18412 NM_DPAU_H_QBL
= 0x0,
18413 NM_DPAQX_S_W_PH
= 0x1,
18414 NM_DPSU_H_QBL
= 0x2,
18415 NM_DPSQX_S_W_PH
= 0x3,
18418 NM_MULSA_W_PH
= 0x6,
18419 NM_EXTRV_RS_W
= 0x7,
18422 /* POOL32Axf_2_24_31 instruction pool */
18424 NM_DPAU_H_QBR
= 0x0,
18425 NM_DPAQX_SA_W_PH
= 0x1,
18426 NM_DPSU_H_QBR
= 0x2,
18427 NM_DPSQX_SA_W_PH
= 0x3,
18430 NM_MULSAQ_S_W_PH
= 0x6,
18431 NM_EXTRV_S_H
= 0x7,
18434 /* POOL32Axf_{4, 5} instruction pool */
18453 /* nanoMIPS DSP instructions */
18454 NM_ABSQ_S_QB
= 0x00,
18455 NM_ABSQ_S_PH
= 0x08,
18456 NM_ABSQ_S_W
= 0x10,
18457 NM_PRECEQ_W_PHL
= 0x28,
18458 NM_PRECEQ_W_PHR
= 0x30,
18459 NM_PRECEQU_PH_QBL
= 0x38,
18460 NM_PRECEQU_PH_QBR
= 0x48,
18461 NM_PRECEU_PH_QBL
= 0x58,
18462 NM_PRECEU_PH_QBR
= 0x68,
18463 NM_PRECEQU_PH_QBLA
= 0x39,
18464 NM_PRECEQU_PH_QBRA
= 0x49,
18465 NM_PRECEU_PH_QBLA
= 0x59,
18466 NM_PRECEU_PH_QBRA
= 0x69,
18467 NM_REPLV_PH
= 0x01,
18468 NM_REPLV_QB
= 0x09,
18471 NM_RADDU_W_QB
= 0x78,
18477 /* PP.SR instruction pool */
18481 NM_RESTORE_JRC
= 0x03,
18484 /* P.SR.F instruction pool */
18487 NM_RESTOREF
= 0x01,
18490 /* P16.SYSCALL instruction pool */
18492 NM_SYSCALL16
= 0x00,
18493 NM_HYPCALL16
= 0x01,
18496 /* POOL16C_00 instruction pool */
18504 /* PP.LSX and PP.LSXS instruction pool */
18542 /* ERETx instruction pool */
18548 /* POOL32FxF_{0, 1} insturction pool */
18557 NM_CVT_S_PL
= 0x84,
18558 NM_CVT_S_PU
= 0xa4,
18560 NM_CVT_L_S
= 0x004,
18561 NM_CVT_L_D
= 0x104,
18562 NM_CVT_W_S
= 0x024,
18563 NM_CVT_W_D
= 0x124,
18565 NM_RSQRT_S
= 0x008,
18566 NM_RSQRT_D
= 0x108,
18571 NM_RECIP_S
= 0x048,
18572 NM_RECIP_D
= 0x148,
18574 NM_FLOOR_L_S
= 0x00c,
18575 NM_FLOOR_L_D
= 0x10c,
18577 NM_FLOOR_W_S
= 0x02c,
18578 NM_FLOOR_W_D
= 0x12c,
18580 NM_CEIL_L_S
= 0x04c,
18581 NM_CEIL_L_D
= 0x14c,
18582 NM_CEIL_W_S
= 0x06c,
18583 NM_CEIL_W_D
= 0x16c,
18584 NM_TRUNC_L_S
= 0x08c,
18585 NM_TRUNC_L_D
= 0x18c,
18586 NM_TRUNC_W_S
= 0x0ac,
18587 NM_TRUNC_W_D
= 0x1ac,
18588 NM_ROUND_L_S
= 0x0cc,
18589 NM_ROUND_L_D
= 0x1cc,
18590 NM_ROUND_W_S
= 0x0ec,
18591 NM_ROUND_W_D
= 0x1ec,
18599 NM_CVT_D_S
= 0x04d,
18600 NM_CVT_D_W
= 0x0cd,
18601 NM_CVT_D_L
= 0x14d,
18602 NM_CVT_S_D
= 0x06d,
18603 NM_CVT_S_W
= 0x0ed,
18604 NM_CVT_S_L
= 0x16d,
18607 /* P.LL instruction pool */
18613 /* P.SC instruction pool */
18619 /* P.DVP instruction pool */
18628 * nanoMIPS decoding engine
18633 /* extraction utilities */
18635 #define NANOMIPS_EXTRACT_RT3(op) ((op >> 7) & 0x7)
18636 #define NANOMIPS_EXTRACT_RS3(op) ((op >> 4) & 0x7)
18637 #define NANOMIPS_EXTRACT_RD3(op) ((op >> 1) & 0x7)
18638 #define NANOMIPS_EXTRACT_RD5(op) ((op >> 5) & 0x1f)
18639 #define NANOMIPS_EXTRACT_RS5(op) (op & 0x1f)
18641 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3'). */
18642 static inline int decode_gpr_gpr3(int r
)
18644 static const int map
[] = { 16, 17, 18, 19, 4, 5, 6, 7 };
18646 return map
[r
& 0x7];
18649 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3.src.store'). */
18650 static inline int decode_gpr_gpr3_src_store(int r
)
18652 static const int map
[] = { 0, 17, 18, 19, 4, 5, 6, 7 };
18654 return map
[r
& 0x7];
18657 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4'). */
18658 static inline int decode_gpr_gpr4(int r
)
18660 static const int map
[] = { 8, 9, 10, 11, 4, 5, 6, 7,
18661 16, 17, 18, 19, 20, 21, 22, 23 };
18663 return map
[r
& 0xf];
18666 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4.zero'). */
18667 static inline int decode_gpr_gpr4_zero(int r
)
18669 static const int map
[] = { 8, 9, 10, 0, 4, 5, 6, 7,
18670 16, 17, 18, 19, 20, 21, 22, 23 };
18672 return map
[r
& 0xf];
18676 static void gen_adjust_sp(DisasContext
*ctx
, int u
)
18678 gen_op_addr_addi(ctx
, cpu_gpr
[29], cpu_gpr
[29], u
);
18681 static void gen_save(DisasContext
*ctx
, uint8_t rt
, uint8_t count
,
18682 uint8_t gp
, uint16_t u
)
18685 TCGv va
= tcg_temp_new();
18686 TCGv t0
= tcg_temp_new();
18688 while (counter
!= count
) {
18689 bool use_gp
= gp
&& (counter
== count
- 1);
18690 int this_rt
= use_gp
? 28 : (rt
& 0x10) | ((rt
+ counter
) & 0x1f);
18691 int this_offset
= -((counter
+ 1) << 2);
18692 gen_base_offset_addr(ctx
, va
, 29, this_offset
);
18693 gen_load_gpr(t0
, this_rt
);
18694 tcg_gen_qemu_st_tl(t0
, va
, ctx
->mem_idx
,
18695 (MO_TEUL
| ctx
->default_tcg_memop_mask
));
18699 /* adjust stack pointer */
18700 gen_adjust_sp(ctx
, -u
);
18706 static void gen_restore(DisasContext
*ctx
, uint8_t rt
, uint8_t count
,
18707 uint8_t gp
, uint16_t u
)
18710 TCGv va
= tcg_temp_new();
18711 TCGv t0
= tcg_temp_new();
18713 while (counter
!= count
) {
18714 bool use_gp
= gp
&& (counter
== count
- 1);
18715 int this_rt
= use_gp
? 28 : (rt
& 0x10) | ((rt
+ counter
) & 0x1f);
18716 int this_offset
= u
- ((counter
+ 1) << 2);
18717 gen_base_offset_addr(ctx
, va
, 29, this_offset
);
18718 tcg_gen_qemu_ld_tl(t0
, va
, ctx
->mem_idx
, MO_TESL
|
18719 ctx
->default_tcg_memop_mask
);
18720 tcg_gen_ext32s_tl(t0
, t0
);
18721 gen_store_gpr(t0
, this_rt
);
18725 /* adjust stack pointer */
18726 gen_adjust_sp(ctx
, u
);
18732 static void gen_pool16c_nanomips_insn(DisasContext
*ctx
)
18734 int rt
= decode_gpr_gpr3(NANOMIPS_EXTRACT_RT3(ctx
->opcode
));
18735 int rs
= decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx
->opcode
));
18737 switch (extract32(ctx
->opcode
, 2, 2)) {
18739 gen_logic(ctx
, OPC_NOR
, rt
, rs
, 0);
18742 gen_logic(ctx
, OPC_AND
, rt
, rt
, rs
);
18745 gen_logic(ctx
, OPC_XOR
, rt
, rt
, rs
);
18748 gen_logic(ctx
, OPC_OR
, rt
, rt
, rs
);
18753 static void gen_pool32a0_nanomips_insn(CPUMIPSState
*env
, DisasContext
*ctx
)
18755 int rt
= extract32(ctx
->opcode
, 21, 5);
18756 int rs
= extract32(ctx
->opcode
, 16, 5);
18757 int rd
= extract32(ctx
->opcode
, 11, 5);
18759 switch (extract32(ctx
->opcode
, 3, 7)) {
18761 switch (extract32(ctx
->opcode
, 10, 1)) {
18764 gen_trap(ctx
, OPC_TEQ
, rs
, rt
, -1);
18768 gen_trap(ctx
, OPC_TNE
, rs
, rt
, -1);
18774 gen_rdhwr(ctx
, rt
, rs
, extract32(ctx
->opcode
, 11, 3));
18778 gen_bshfl(ctx
, OPC_SEB
, rs
, rt
);
18781 gen_bshfl(ctx
, OPC_SEH
, rs
, rt
);
18784 gen_shift(ctx
, OPC_SLLV
, rd
, rt
, rs
);
18787 gen_shift(ctx
, OPC_SRLV
, rd
, rt
, rs
);
18790 gen_shift(ctx
, OPC_SRAV
, rd
, rt
, rs
);
18793 gen_shift(ctx
, OPC_ROTRV
, rd
, rt
, rs
);
18796 gen_arith(ctx
, OPC_ADD
, rd
, rs
, rt
);
18799 gen_arith(ctx
, OPC_ADDU
, rd
, rs
, rt
);
18803 gen_arith(ctx
, OPC_SUB
, rd
, rs
, rt
);
18806 gen_arith(ctx
, OPC_SUBU
, rd
, rs
, rt
);
18809 switch (extract32(ctx
->opcode
, 10, 1)) {
18811 gen_cond_move(ctx
, OPC_MOVZ
, rd
, rs
, rt
);
18814 gen_cond_move(ctx
, OPC_MOVN
, rd
, rs
, rt
);
18819 gen_logic(ctx
, OPC_AND
, rd
, rs
, rt
);
18822 gen_logic(ctx
, OPC_OR
, rd
, rs
, rt
);
18825 gen_logic(ctx
, OPC_NOR
, rd
, rs
, rt
);
18828 gen_logic(ctx
, OPC_XOR
, rd
, rs
, rt
);
18831 gen_slt(ctx
, OPC_SLT
, rd
, rs
, rt
);
18836 #ifndef CONFIG_USER_ONLY
18837 TCGv t0
= tcg_temp_new();
18838 switch (extract32(ctx
->opcode
, 10, 1)) {
18841 check_cp0_enabled(ctx
);
18842 gen_helper_dvp(t0
, cpu_env
);
18843 gen_store_gpr(t0
, rt
);
18848 check_cp0_enabled(ctx
);
18849 gen_helper_evp(t0
, cpu_env
);
18850 gen_store_gpr(t0
, rt
);
18857 gen_slt(ctx
, OPC_SLTU
, rd
, rs
, rt
);
18862 TCGv t0
= tcg_temp_new();
18863 TCGv t1
= tcg_temp_new();
18864 TCGv t2
= tcg_temp_new();
18866 gen_load_gpr(t1
, rs
);
18867 gen_load_gpr(t2
, rt
);
18868 tcg_gen_add_tl(t0
, t1
, t2
);
18869 tcg_gen_ext32s_tl(t0
, t0
);
18870 tcg_gen_xor_tl(t1
, t1
, t2
);
18871 tcg_gen_xor_tl(t2
, t0
, t2
);
18872 tcg_gen_andc_tl(t1
, t2
, t1
);
18874 /* operands of same sign, result different sign */
18875 tcg_gen_setcondi_tl(TCG_COND_LT
, t0
, t1
, 0);
18876 gen_store_gpr(t0
, rd
);
18884 gen_r6_muldiv(ctx
, R6_OPC_MUL
, rd
, rs
, rt
);
18887 gen_r6_muldiv(ctx
, R6_OPC_MUH
, rd
, rs
, rt
);
18890 gen_r6_muldiv(ctx
, R6_OPC_MULU
, rd
, rs
, rt
);
18893 gen_r6_muldiv(ctx
, R6_OPC_MUHU
, rd
, rs
, rt
);
18896 gen_r6_muldiv(ctx
, R6_OPC_DIV
, rd
, rs
, rt
);
18899 gen_r6_muldiv(ctx
, R6_OPC_MOD
, rd
, rs
, rt
);
18902 gen_r6_muldiv(ctx
, R6_OPC_DIVU
, rd
, rs
, rt
);
18905 gen_r6_muldiv(ctx
, R6_OPC_MODU
, rd
, rs
, rt
);
18907 #ifndef CONFIG_USER_ONLY
18909 check_cp0_enabled(ctx
);
18911 /* Treat as NOP. */
18914 gen_mfc0(ctx
, cpu_gpr
[rt
], rs
, extract32(ctx
->opcode
, 11, 3));
18917 check_cp0_enabled(ctx
);
18919 TCGv t0
= tcg_temp_new();
18921 gen_load_gpr(t0
, rt
);
18922 gen_mtc0(ctx
, t0
, rs
, extract32(ctx
->opcode
, 11, 3));
18926 case NM_D_E_MT_VPE
:
18928 uint8_t sc
= extract32(ctx
->opcode
, 10, 1);
18929 TCGv t0
= tcg_temp_new();
18936 gen_helper_dmt(t0
);
18937 gen_store_gpr(t0
, rt
);
18938 } else if (rs
== 0) {
18941 gen_helper_dvpe(t0
, cpu_env
);
18942 gen_store_gpr(t0
, rt
);
18944 gen_reserved_instruction(ctx
);
18951 gen_helper_emt(t0
);
18952 gen_store_gpr(t0
, rt
);
18953 } else if (rs
== 0) {
18956 gen_helper_evpe(t0
, cpu_env
);
18957 gen_store_gpr(t0
, rt
);
18959 gen_reserved_instruction(ctx
);
18970 TCGv t0
= tcg_temp_new();
18971 TCGv t1
= tcg_temp_new();
18973 gen_load_gpr(t0
, rt
);
18974 gen_load_gpr(t1
, rs
);
18975 gen_helper_fork(t0
, t1
);
18982 check_cp0_enabled(ctx
);
18984 /* Treat as NOP. */
18987 gen_mftr(env
, ctx
, rs
, rt
, extract32(ctx
->opcode
, 10, 1),
18988 extract32(ctx
->opcode
, 11, 5), extract32(ctx
->opcode
, 3, 1));
18992 check_cp0_enabled(ctx
);
18993 gen_mttr(env
, ctx
, rs
, rt
, extract32(ctx
->opcode
, 10, 1),
18994 extract32(ctx
->opcode
, 11, 5), extract32(ctx
->opcode
, 3, 1));
18999 TCGv t0
= tcg_temp_new();
19001 gen_load_gpr(t0
, rs
);
19002 gen_helper_yield(t0
, cpu_env
, t0
);
19003 gen_store_gpr(t0
, rt
);
19009 gen_reserved_instruction(ctx
);
19015 static void gen_pool32axf_1_5_nanomips_insn(DisasContext
*ctx
, uint32_t opc
,
19016 int ret
, int v1
, int v2
)
19022 t0
= tcg_temp_new_i32();
19024 v0_t
= tcg_temp_new();
19025 v1_t
= tcg_temp_new();
19027 tcg_gen_movi_i32(t0
, v2
>> 3);
19029 gen_load_gpr(v0_t
, ret
);
19030 gen_load_gpr(v1_t
, v1
);
19033 case NM_MAQ_S_W_PHR
:
19035 gen_helper_maq_s_w_phr(t0
, v1_t
, v0_t
, cpu_env
);
19037 case NM_MAQ_S_W_PHL
:
19039 gen_helper_maq_s_w_phl(t0
, v1_t
, v0_t
, cpu_env
);
19041 case NM_MAQ_SA_W_PHR
:
19043 gen_helper_maq_sa_w_phr(t0
, v1_t
, v0_t
, cpu_env
);
19045 case NM_MAQ_SA_W_PHL
:
19047 gen_helper_maq_sa_w_phl(t0
, v1_t
, v0_t
, cpu_env
);
19050 gen_reserved_instruction(ctx
);
19054 tcg_temp_free_i32(t0
);
19056 tcg_temp_free(v0_t
);
19057 tcg_temp_free(v1_t
);
19061 static void gen_pool32axf_1_nanomips_insn(DisasContext
*ctx
, uint32_t opc
,
19062 int ret
, int v1
, int v2
)
19065 TCGv t0
= tcg_temp_new();
19066 TCGv t1
= tcg_temp_new();
19067 TCGv v0_t
= tcg_temp_new();
19069 gen_load_gpr(v0_t
, v1
);
19072 case NM_POOL32AXF_1_0
:
19074 switch (extract32(ctx
->opcode
, 12, 2)) {
19076 gen_HILO(ctx
, OPC_MFHI
, v2
>> 3, ret
);
19079 gen_HILO(ctx
, OPC_MFLO
, v2
>> 3, ret
);
19082 gen_HILO(ctx
, OPC_MTHI
, v2
>> 3, v1
);
19085 gen_HILO(ctx
, OPC_MTLO
, v2
>> 3, v1
);
19089 case NM_POOL32AXF_1_1
:
19091 switch (extract32(ctx
->opcode
, 12, 2)) {
19093 tcg_gen_movi_tl(t0
, v2
);
19094 gen_helper_mthlip(t0
, v0_t
, cpu_env
);
19097 tcg_gen_movi_tl(t0
, v2
>> 3);
19098 gen_helper_shilo(t0
, v0_t
, cpu_env
);
19101 gen_reserved_instruction(ctx
);
19105 case NM_POOL32AXF_1_3
:
19107 imm
= extract32(ctx
->opcode
, 14, 7);
19108 switch (extract32(ctx
->opcode
, 12, 2)) {
19110 tcg_gen_movi_tl(t0
, imm
);
19111 gen_helper_rddsp(t0
, t0
, cpu_env
);
19112 gen_store_gpr(t0
, ret
);
19115 gen_load_gpr(t0
, ret
);
19116 tcg_gen_movi_tl(t1
, imm
);
19117 gen_helper_wrdsp(t0
, t1
, cpu_env
);
19120 tcg_gen_movi_tl(t0
, v2
>> 3);
19121 tcg_gen_movi_tl(t1
, v1
);
19122 gen_helper_extp(t0
, t0
, t1
, cpu_env
);
19123 gen_store_gpr(t0
, ret
);
19126 tcg_gen_movi_tl(t0
, v2
>> 3);
19127 tcg_gen_movi_tl(t1
, v1
);
19128 gen_helper_extpdp(t0
, t0
, t1
, cpu_env
);
19129 gen_store_gpr(t0
, ret
);
19133 case NM_POOL32AXF_1_4
:
19135 tcg_gen_movi_tl(t0
, v2
>> 2);
19136 switch (extract32(ctx
->opcode
, 12, 1)) {
19138 gen_helper_shll_qb(t0
, t0
, v0_t
, cpu_env
);
19139 gen_store_gpr(t0
, ret
);
19142 gen_helper_shrl_qb(t0
, t0
, v0_t
);
19143 gen_store_gpr(t0
, ret
);
19147 case NM_POOL32AXF_1_5
:
19148 opc
= extract32(ctx
->opcode
, 12, 2);
19149 gen_pool32axf_1_5_nanomips_insn(ctx
, opc
, ret
, v1
, v2
);
19151 case NM_POOL32AXF_1_7
:
19153 tcg_gen_movi_tl(t0
, v2
>> 3);
19154 tcg_gen_movi_tl(t1
, v1
);
19155 switch (extract32(ctx
->opcode
, 12, 2)) {
19157 gen_helper_extr_w(t0
, t0
, t1
, cpu_env
);
19158 gen_store_gpr(t0
, ret
);
19161 gen_helper_extr_r_w(t0
, t0
, t1
, cpu_env
);
19162 gen_store_gpr(t0
, ret
);
19165 gen_helper_extr_rs_w(t0
, t0
, t1
, cpu_env
);
19166 gen_store_gpr(t0
, ret
);
19169 gen_helper_extr_s_h(t0
, t0
, t1
, cpu_env
);
19170 gen_store_gpr(t0
, ret
);
19175 gen_reserved_instruction(ctx
);
19181 tcg_temp_free(v0_t
);
19184 static void gen_pool32axf_2_multiply(DisasContext
*ctx
, uint32_t opc
,
19185 TCGv v0
, TCGv v1
, int rd
)
19189 t0
= tcg_temp_new_i32();
19191 tcg_gen_movi_i32(t0
, rd
>> 3);
19194 case NM_POOL32AXF_2_0_7
:
19195 switch (extract32(ctx
->opcode
, 9, 3)) {
19198 gen_helper_dpa_w_ph(t0
, v1
, v0
, cpu_env
);
19200 case NM_DPAQ_S_W_PH
:
19202 gen_helper_dpaq_s_w_ph(t0
, v1
, v0
, cpu_env
);
19206 gen_helper_dps_w_ph(t0
, v1
, v0
, cpu_env
);
19208 case NM_DPSQ_S_W_PH
:
19210 gen_helper_dpsq_s_w_ph(t0
, v1
, v0
, cpu_env
);
19213 gen_reserved_instruction(ctx
);
19217 case NM_POOL32AXF_2_8_15
:
19218 switch (extract32(ctx
->opcode
, 9, 3)) {
19221 gen_helper_dpax_w_ph(t0
, v0
, v1
, cpu_env
);
19223 case NM_DPAQ_SA_L_W
:
19225 gen_helper_dpaq_sa_l_w(t0
, v0
, v1
, cpu_env
);
19229 gen_helper_dpsx_w_ph(t0
, v0
, v1
, cpu_env
);
19231 case NM_DPSQ_SA_L_W
:
19233 gen_helper_dpsq_sa_l_w(t0
, v0
, v1
, cpu_env
);
19236 gen_reserved_instruction(ctx
);
19240 case NM_POOL32AXF_2_16_23
:
19241 switch (extract32(ctx
->opcode
, 9, 3)) {
19242 case NM_DPAU_H_QBL
:
19244 gen_helper_dpau_h_qbl(t0
, v0
, v1
, cpu_env
);
19246 case NM_DPAQX_S_W_PH
:
19248 gen_helper_dpaqx_s_w_ph(t0
, v0
, v1
, cpu_env
);
19250 case NM_DPSU_H_QBL
:
19252 gen_helper_dpsu_h_qbl(t0
, v0
, v1
, cpu_env
);
19254 case NM_DPSQX_S_W_PH
:
19256 gen_helper_dpsqx_s_w_ph(t0
, v0
, v1
, cpu_env
);
19258 case NM_MULSA_W_PH
:
19260 gen_helper_mulsa_w_ph(t0
, v0
, v1
, cpu_env
);
19263 gen_reserved_instruction(ctx
);
19267 case NM_POOL32AXF_2_24_31
:
19268 switch (extract32(ctx
->opcode
, 9, 3)) {
19269 case NM_DPAU_H_QBR
:
19271 gen_helper_dpau_h_qbr(t0
, v1
, v0
, cpu_env
);
19273 case NM_DPAQX_SA_W_PH
:
19275 gen_helper_dpaqx_sa_w_ph(t0
, v1
, v0
, cpu_env
);
19277 case NM_DPSU_H_QBR
:
19279 gen_helper_dpsu_h_qbr(t0
, v1
, v0
, cpu_env
);
19281 case NM_DPSQX_SA_W_PH
:
19283 gen_helper_dpsqx_sa_w_ph(t0
, v1
, v0
, cpu_env
);
19285 case NM_MULSAQ_S_W_PH
:
19287 gen_helper_mulsaq_s_w_ph(t0
, v1
, v0
, cpu_env
);
19290 gen_reserved_instruction(ctx
);
19295 gen_reserved_instruction(ctx
);
19299 tcg_temp_free_i32(t0
);
19302 static void gen_pool32axf_2_nanomips_insn(DisasContext
*ctx
, uint32_t opc
,
19303 int rt
, int rs
, int rd
)
19306 TCGv t0
= tcg_temp_new();
19307 TCGv t1
= tcg_temp_new();
19308 TCGv v0_t
= tcg_temp_new();
19309 TCGv v1_t
= tcg_temp_new();
19311 gen_load_gpr(v0_t
, rt
);
19312 gen_load_gpr(v1_t
, rs
);
19315 case NM_POOL32AXF_2_0_7
:
19316 switch (extract32(ctx
->opcode
, 9, 3)) {
19318 case NM_DPAQ_S_W_PH
:
19320 case NM_DPSQ_S_W_PH
:
19321 gen_pool32axf_2_multiply(ctx
, opc
, v0_t
, v1_t
, rd
);
19326 gen_load_gpr(t0
, rs
);
19328 if (rd
!= 0 && rd
!= 2) {
19329 tcg_gen_shli_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], 8 * rd
);
19330 tcg_gen_ext32u_tl(t0
, t0
);
19331 tcg_gen_shri_tl(t0
, t0
, 8 * (4 - rd
));
19332 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
19334 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
19340 int acc
= extract32(ctx
->opcode
, 14, 2);
19341 TCGv_i64 t2
= tcg_temp_new_i64();
19342 TCGv_i64 t3
= tcg_temp_new_i64();
19344 gen_load_gpr(t0
, rt
);
19345 gen_load_gpr(t1
, rs
);
19346 tcg_gen_ext_tl_i64(t2
, t0
);
19347 tcg_gen_ext_tl_i64(t3
, t1
);
19348 tcg_gen_mul_i64(t2
, t2
, t3
);
19349 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
19350 tcg_gen_add_i64(t2
, t2
, t3
);
19351 tcg_temp_free_i64(t3
);
19352 gen_move_low32(cpu_LO
[acc
], t2
);
19353 gen_move_high32(cpu_HI
[acc
], t2
);
19354 tcg_temp_free_i64(t2
);
19360 int acc
= extract32(ctx
->opcode
, 14, 2);
19361 TCGv_i32 t2
= tcg_temp_new_i32();
19362 TCGv_i32 t3
= tcg_temp_new_i32();
19364 gen_load_gpr(t0
, rs
);
19365 gen_load_gpr(t1
, rt
);
19366 tcg_gen_trunc_tl_i32(t2
, t0
);
19367 tcg_gen_trunc_tl_i32(t3
, t1
);
19368 tcg_gen_muls2_i32(t2
, t3
, t2
, t3
);
19369 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
19370 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
19371 tcg_temp_free_i32(t2
);
19372 tcg_temp_free_i32(t3
);
19377 gen_load_gpr(v1_t
, rs
);
19378 tcg_gen_movi_tl(t0
, rd
>> 3);
19379 gen_helper_extr_w(t0
, t0
, v1_t
, cpu_env
);
19380 gen_store_gpr(t0
, ret
);
19384 case NM_POOL32AXF_2_8_15
:
19385 switch (extract32(ctx
->opcode
, 9, 3)) {
19387 case NM_DPAQ_SA_L_W
:
19389 case NM_DPSQ_SA_L_W
:
19390 gen_pool32axf_2_multiply(ctx
, opc
, v0_t
, v1_t
, rd
);
19395 int acc
= extract32(ctx
->opcode
, 14, 2);
19396 TCGv_i64 t2
= tcg_temp_new_i64();
19397 TCGv_i64 t3
= tcg_temp_new_i64();
19399 gen_load_gpr(t0
, rs
);
19400 gen_load_gpr(t1
, rt
);
19401 tcg_gen_ext32u_tl(t0
, t0
);
19402 tcg_gen_ext32u_tl(t1
, t1
);
19403 tcg_gen_extu_tl_i64(t2
, t0
);
19404 tcg_gen_extu_tl_i64(t3
, t1
);
19405 tcg_gen_mul_i64(t2
, t2
, t3
);
19406 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
19407 tcg_gen_add_i64(t2
, t2
, t3
);
19408 tcg_temp_free_i64(t3
);
19409 gen_move_low32(cpu_LO
[acc
], t2
);
19410 gen_move_high32(cpu_HI
[acc
], t2
);
19411 tcg_temp_free_i64(t2
);
19417 int acc
= extract32(ctx
->opcode
, 14, 2);
19418 TCGv_i32 t2
= tcg_temp_new_i32();
19419 TCGv_i32 t3
= tcg_temp_new_i32();
19421 gen_load_gpr(t0
, rs
);
19422 gen_load_gpr(t1
, rt
);
19423 tcg_gen_trunc_tl_i32(t2
, t0
);
19424 tcg_gen_trunc_tl_i32(t3
, t1
);
19425 tcg_gen_mulu2_i32(t2
, t3
, t2
, t3
);
19426 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
19427 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
19428 tcg_temp_free_i32(t2
);
19429 tcg_temp_free_i32(t3
);
19434 tcg_gen_movi_tl(t0
, rd
>> 3);
19435 gen_helper_extr_r_w(t0
, t0
, v1_t
, cpu_env
);
19436 gen_store_gpr(t0
, ret
);
19439 gen_reserved_instruction(ctx
);
19443 case NM_POOL32AXF_2_16_23
:
19444 switch (extract32(ctx
->opcode
, 9, 3)) {
19445 case NM_DPAU_H_QBL
:
19446 case NM_DPAQX_S_W_PH
:
19447 case NM_DPSU_H_QBL
:
19448 case NM_DPSQX_S_W_PH
:
19449 case NM_MULSA_W_PH
:
19450 gen_pool32axf_2_multiply(ctx
, opc
, v0_t
, v1_t
, rd
);
19454 tcg_gen_movi_tl(t0
, rd
>> 3);
19455 gen_helper_extp(t0
, t0
, v1_t
, cpu_env
);
19456 gen_store_gpr(t0
, ret
);
19461 int acc
= extract32(ctx
->opcode
, 14, 2);
19462 TCGv_i64 t2
= tcg_temp_new_i64();
19463 TCGv_i64 t3
= tcg_temp_new_i64();
19465 gen_load_gpr(t0
, rs
);
19466 gen_load_gpr(t1
, rt
);
19467 tcg_gen_ext_tl_i64(t2
, t0
);
19468 tcg_gen_ext_tl_i64(t3
, t1
);
19469 tcg_gen_mul_i64(t2
, t2
, t3
);
19470 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
19471 tcg_gen_sub_i64(t2
, t3
, t2
);
19472 tcg_temp_free_i64(t3
);
19473 gen_move_low32(cpu_LO
[acc
], t2
);
19474 gen_move_high32(cpu_HI
[acc
], t2
);
19475 tcg_temp_free_i64(t2
);
19478 case NM_EXTRV_RS_W
:
19480 tcg_gen_movi_tl(t0
, rd
>> 3);
19481 gen_helper_extr_rs_w(t0
, t0
, v1_t
, cpu_env
);
19482 gen_store_gpr(t0
, ret
);
19486 case NM_POOL32AXF_2_24_31
:
19487 switch (extract32(ctx
->opcode
, 9, 3)) {
19488 case NM_DPAU_H_QBR
:
19489 case NM_DPAQX_SA_W_PH
:
19490 case NM_DPSU_H_QBR
:
19491 case NM_DPSQX_SA_W_PH
:
19492 case NM_MULSAQ_S_W_PH
:
19493 gen_pool32axf_2_multiply(ctx
, opc
, v0_t
, v1_t
, rd
);
19497 tcg_gen_movi_tl(t0
, rd
>> 3);
19498 gen_helper_extpdp(t0
, t0
, v1_t
, cpu_env
);
19499 gen_store_gpr(t0
, ret
);
19504 int acc
= extract32(ctx
->opcode
, 14, 2);
19505 TCGv_i64 t2
= tcg_temp_new_i64();
19506 TCGv_i64 t3
= tcg_temp_new_i64();
19508 gen_load_gpr(t0
, rs
);
19509 gen_load_gpr(t1
, rt
);
19510 tcg_gen_ext32u_tl(t0
, t0
);
19511 tcg_gen_ext32u_tl(t1
, t1
);
19512 tcg_gen_extu_tl_i64(t2
, t0
);
19513 tcg_gen_extu_tl_i64(t3
, t1
);
19514 tcg_gen_mul_i64(t2
, t2
, t3
);
19515 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
19516 tcg_gen_sub_i64(t2
, t3
, t2
);
19517 tcg_temp_free_i64(t3
);
19518 gen_move_low32(cpu_LO
[acc
], t2
);
19519 gen_move_high32(cpu_HI
[acc
], t2
);
19520 tcg_temp_free_i64(t2
);
19525 tcg_gen_movi_tl(t0
, rd
>> 3);
19526 gen_helper_extr_s_h(t0
, t0
, v0_t
, cpu_env
);
19527 gen_store_gpr(t0
, ret
);
19532 gen_reserved_instruction(ctx
);
19539 tcg_temp_free(v0_t
);
19540 tcg_temp_free(v1_t
);
19543 static void gen_pool32axf_4_nanomips_insn(DisasContext
*ctx
, uint32_t opc
,
19547 TCGv t0
= tcg_temp_new();
19548 TCGv v0_t
= tcg_temp_new();
19550 gen_load_gpr(v0_t
, rs
);
19555 gen_helper_absq_s_qb(v0_t
, v0_t
, cpu_env
);
19556 gen_store_gpr(v0_t
, ret
);
19560 gen_helper_absq_s_ph(v0_t
, v0_t
, cpu_env
);
19561 gen_store_gpr(v0_t
, ret
);
19565 gen_helper_absq_s_w(v0_t
, v0_t
, cpu_env
);
19566 gen_store_gpr(v0_t
, ret
);
19568 case NM_PRECEQ_W_PHL
:
19570 tcg_gen_andi_tl(v0_t
, v0_t
, 0xFFFF0000);
19571 tcg_gen_ext32s_tl(v0_t
, v0_t
);
19572 gen_store_gpr(v0_t
, ret
);
19574 case NM_PRECEQ_W_PHR
:
19576 tcg_gen_andi_tl(v0_t
, v0_t
, 0x0000FFFF);
19577 tcg_gen_shli_tl(v0_t
, v0_t
, 16);
19578 tcg_gen_ext32s_tl(v0_t
, v0_t
);
19579 gen_store_gpr(v0_t
, ret
);
19581 case NM_PRECEQU_PH_QBL
:
19583 gen_helper_precequ_ph_qbl(v0_t
, v0_t
);
19584 gen_store_gpr(v0_t
, ret
);
19586 case NM_PRECEQU_PH_QBR
:
19588 gen_helper_precequ_ph_qbr(v0_t
, v0_t
);
19589 gen_store_gpr(v0_t
, ret
);
19591 case NM_PRECEQU_PH_QBLA
:
19593 gen_helper_precequ_ph_qbla(v0_t
, v0_t
);
19594 gen_store_gpr(v0_t
, ret
);
19596 case NM_PRECEQU_PH_QBRA
:
19598 gen_helper_precequ_ph_qbra(v0_t
, v0_t
);
19599 gen_store_gpr(v0_t
, ret
);
19601 case NM_PRECEU_PH_QBL
:
19603 gen_helper_preceu_ph_qbl(v0_t
, v0_t
);
19604 gen_store_gpr(v0_t
, ret
);
19606 case NM_PRECEU_PH_QBR
:
19608 gen_helper_preceu_ph_qbr(v0_t
, v0_t
);
19609 gen_store_gpr(v0_t
, ret
);
19611 case NM_PRECEU_PH_QBLA
:
19613 gen_helper_preceu_ph_qbla(v0_t
, v0_t
);
19614 gen_store_gpr(v0_t
, ret
);
19616 case NM_PRECEU_PH_QBRA
:
19618 gen_helper_preceu_ph_qbra(v0_t
, v0_t
);
19619 gen_store_gpr(v0_t
, ret
);
19623 tcg_gen_ext16u_tl(v0_t
, v0_t
);
19624 tcg_gen_shli_tl(t0
, v0_t
, 16);
19625 tcg_gen_or_tl(v0_t
, v0_t
, t0
);
19626 tcg_gen_ext32s_tl(v0_t
, v0_t
);
19627 gen_store_gpr(v0_t
, ret
);
19631 tcg_gen_ext8u_tl(v0_t
, v0_t
);
19632 tcg_gen_shli_tl(t0
, v0_t
, 8);
19633 tcg_gen_or_tl(v0_t
, v0_t
, t0
);
19634 tcg_gen_shli_tl(t0
, v0_t
, 16);
19635 tcg_gen_or_tl(v0_t
, v0_t
, t0
);
19636 tcg_gen_ext32s_tl(v0_t
, v0_t
);
19637 gen_store_gpr(v0_t
, ret
);
19641 gen_helper_bitrev(v0_t
, v0_t
);
19642 gen_store_gpr(v0_t
, ret
);
19647 TCGv tv0
= tcg_temp_new();
19649 gen_load_gpr(tv0
, rt
);
19650 gen_helper_insv(v0_t
, cpu_env
, v0_t
, tv0
);
19651 gen_store_gpr(v0_t
, ret
);
19652 tcg_temp_free(tv0
);
19655 case NM_RADDU_W_QB
:
19657 gen_helper_raddu_w_qb(v0_t
, v0_t
);
19658 gen_store_gpr(v0_t
, ret
);
19661 gen_bitswap(ctx
, OPC_BITSWAP
, ret
, rs
);
19665 gen_cl(ctx
, OPC_CLO
, ret
, rs
);
19669 gen_cl(ctx
, OPC_CLZ
, ret
, rs
);
19672 gen_bshfl(ctx
, OPC_WSBH
, ret
, rs
);
19675 gen_reserved_instruction(ctx
);
19679 tcg_temp_free(v0_t
);
19683 static void gen_pool32axf_7_nanomips_insn(DisasContext
*ctx
, uint32_t opc
,
19684 int rt
, int rs
, int rd
)
19686 TCGv t0
= tcg_temp_new();
19687 TCGv rs_t
= tcg_temp_new();
19689 gen_load_gpr(rs_t
, rs
);
19694 tcg_gen_movi_tl(t0
, rd
>> 2);
19695 switch (extract32(ctx
->opcode
, 12, 1)) {
19698 gen_helper_shra_qb(t0
, t0
, rs_t
);
19699 gen_store_gpr(t0
, rt
);
19703 gen_helper_shra_r_qb(t0
, t0
, rs_t
);
19704 gen_store_gpr(t0
, rt
);
19710 tcg_gen_movi_tl(t0
, rd
>> 1);
19711 gen_helper_shrl_ph(t0
, t0
, rs_t
);
19712 gen_store_gpr(t0
, rt
);
19718 target_long result
;
19719 imm
= extract32(ctx
->opcode
, 13, 8);
19720 result
= (uint32_t)imm
<< 24 |
19721 (uint32_t)imm
<< 16 |
19722 (uint32_t)imm
<< 8 |
19724 result
= (int32_t)result
;
19725 tcg_gen_movi_tl(t0
, result
);
19726 gen_store_gpr(t0
, rt
);
19730 gen_reserved_instruction(ctx
);
19734 tcg_temp_free(rs_t
);
19738 static void gen_pool32axf_nanomips_insn(CPUMIPSState
*env
, DisasContext
*ctx
)
19740 int rt
= extract32(ctx
->opcode
, 21, 5);
19741 int rs
= extract32(ctx
->opcode
, 16, 5);
19742 int rd
= extract32(ctx
->opcode
, 11, 5);
19744 switch (extract32(ctx
->opcode
, 6, 3)) {
19745 case NM_POOL32AXF_1
:
19747 int32_t op1
= extract32(ctx
->opcode
, 9, 3);
19748 gen_pool32axf_1_nanomips_insn(ctx
, op1
, rt
, rs
, rd
);
19751 case NM_POOL32AXF_2
:
19753 int32_t op1
= extract32(ctx
->opcode
, 12, 2);
19754 gen_pool32axf_2_nanomips_insn(ctx
, op1
, rt
, rs
, rd
);
19757 case NM_POOL32AXF_4
:
19759 int32_t op1
= extract32(ctx
->opcode
, 9, 7);
19760 gen_pool32axf_4_nanomips_insn(ctx
, op1
, rt
, rs
);
19763 case NM_POOL32AXF_5
:
19764 switch (extract32(ctx
->opcode
, 9, 7)) {
19765 #ifndef CONFIG_USER_ONLY
19767 gen_cp0(env
, ctx
, OPC_TLBP
, 0, 0);
19770 gen_cp0(env
, ctx
, OPC_TLBR
, 0, 0);
19773 gen_cp0(env
, ctx
, OPC_TLBWI
, 0, 0);
19776 gen_cp0(env
, ctx
, OPC_TLBWR
, 0, 0);
19779 gen_cp0(env
, ctx
, OPC_TLBINV
, 0, 0);
19782 gen_cp0(env
, ctx
, OPC_TLBINVF
, 0, 0);
19785 check_cp0_enabled(ctx
);
19787 TCGv t0
= tcg_temp_new();
19789 save_cpu_state(ctx
, 1);
19790 gen_helper_di(t0
, cpu_env
);
19791 gen_store_gpr(t0
, rt
);
19792 /* Stop translation as we may have switched the execution mode */
19793 ctx
->base
.is_jmp
= DISAS_STOP
;
19798 check_cp0_enabled(ctx
);
19800 TCGv t0
= tcg_temp_new();
19802 save_cpu_state(ctx
, 1);
19803 gen_helper_ei(t0
, cpu_env
);
19804 gen_store_gpr(t0
, rt
);
19805 /* Stop translation as we may have switched the execution mode */
19806 ctx
->base
.is_jmp
= DISAS_STOP
;
19811 gen_load_srsgpr(rs
, rt
);
19814 gen_store_srsgpr(rs
, rt
);
19817 gen_cp0(env
, ctx
, OPC_WAIT
, 0, 0);
19820 gen_cp0(env
, ctx
, OPC_DERET
, 0, 0);
19823 gen_cp0(env
, ctx
, OPC_ERET
, 0, 0);
19827 gen_reserved_instruction(ctx
);
19831 case NM_POOL32AXF_7
:
19833 int32_t op1
= extract32(ctx
->opcode
, 9, 3);
19834 gen_pool32axf_7_nanomips_insn(ctx
, op1
, rt
, rs
, rd
);
19838 gen_reserved_instruction(ctx
);
19843 /* Immediate Value Compact Branches */
19844 static void gen_compute_imm_branch(DisasContext
*ctx
, uint32_t opc
,
19845 int rt
, int32_t imm
, int32_t offset
)
19847 TCGCond cond
= TCG_COND_ALWAYS
;
19848 TCGv t0
= tcg_temp_new();
19849 TCGv t1
= tcg_temp_new();
19851 gen_load_gpr(t0
, rt
);
19852 tcg_gen_movi_tl(t1
, imm
);
19853 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
19855 /* Load needed operands and calculate btarget */
19858 if (rt
== 0 && imm
== 0) {
19859 /* Unconditional branch */
19860 } else if (rt
== 0 && imm
!= 0) {
19864 cond
= TCG_COND_EQ
;
19870 if (imm
>= 32 && !(ctx
->hflags
& MIPS_HFLAG_64
)) {
19871 gen_reserved_instruction(ctx
);
19873 } else if (rt
== 0 && opc
== NM_BBEQZC
) {
19874 /* Unconditional branch */
19875 } else if (rt
== 0 && opc
== NM_BBNEZC
) {
19879 tcg_gen_shri_tl(t0
, t0
, imm
);
19880 tcg_gen_andi_tl(t0
, t0
, 1);
19881 tcg_gen_movi_tl(t1
, 0);
19882 if (opc
== NM_BBEQZC
) {
19883 cond
= TCG_COND_EQ
;
19885 cond
= TCG_COND_NE
;
19890 if (rt
== 0 && imm
== 0) {
19893 } else if (rt
== 0 && imm
!= 0) {
19894 /* Unconditional branch */
19896 cond
= TCG_COND_NE
;
19900 if (rt
== 0 && imm
== 0) {
19901 /* Unconditional branch */
19903 cond
= TCG_COND_GE
;
19907 cond
= TCG_COND_LT
;
19910 if (rt
== 0 && imm
== 0) {
19911 /* Unconditional branch */
19913 cond
= TCG_COND_GEU
;
19917 cond
= TCG_COND_LTU
;
19920 MIPS_INVAL("Immediate Value Compact branch");
19921 gen_reserved_instruction(ctx
);
19925 /* branch completion */
19926 clear_branch_hflags(ctx
);
19927 ctx
->base
.is_jmp
= DISAS_NORETURN
;
19929 if (cond
== TCG_COND_ALWAYS
) {
19930 /* Uncoditional compact branch */
19931 gen_goto_tb(ctx
, 0, ctx
->btarget
);
19933 /* Conditional compact branch */
19934 TCGLabel
*fs
= gen_new_label();
19936 tcg_gen_brcond_tl(tcg_invert_cond(cond
), t0
, t1
, fs
);
19938 gen_goto_tb(ctx
, 1, ctx
->btarget
);
19941 gen_goto_tb(ctx
, 0, ctx
->base
.pc_next
+ 4);
19949 /* P.BALRSC type nanoMIPS R6 branches: BALRSC and BRSC */
19950 static void gen_compute_nanomips_pbalrsc_branch(DisasContext
*ctx
, int rs
,
19953 TCGv t0
= tcg_temp_new();
19954 TCGv t1
= tcg_temp_new();
19957 gen_load_gpr(t0
, rs
);
19961 tcg_gen_movi_tl(cpu_gpr
[rt
], ctx
->base
.pc_next
+ 4);
19964 /* calculate btarget */
19965 tcg_gen_shli_tl(t0
, t0
, 1);
19966 tcg_gen_movi_tl(t1
, ctx
->base
.pc_next
+ 4);
19967 gen_op_addr_add(ctx
, btarget
, t1
, t0
);
19969 /* branch completion */
19970 clear_branch_hflags(ctx
);
19971 ctx
->base
.is_jmp
= DISAS_NORETURN
;
19973 /* unconditional branch to register */
19974 tcg_gen_mov_tl(cpu_PC
, btarget
);
19975 tcg_gen_lookup_and_goto_ptr();
19981 /* nanoMIPS Branches */
19982 static void gen_compute_compact_branch_nm(DisasContext
*ctx
, uint32_t opc
,
19983 int rs
, int rt
, int32_t offset
)
19985 int bcond_compute
= 0;
19986 TCGv t0
= tcg_temp_new();
19987 TCGv t1
= tcg_temp_new();
19989 /* Load needed operands and calculate btarget */
19991 /* compact branch */
19994 gen_load_gpr(t0
, rs
);
19995 gen_load_gpr(t1
, rt
);
19997 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
20001 if (rs
== 0 || rs
== rt
) {
20002 /* OPC_BLEZALC, OPC_BGEZALC */
20003 /* OPC_BGTZALC, OPC_BLTZALC */
20004 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 4);
20006 gen_load_gpr(t0
, rs
);
20007 gen_load_gpr(t1
, rt
);
20009 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
20012 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
20016 /* OPC_BEQZC, OPC_BNEZC */
20017 gen_load_gpr(t0
, rs
);
20019 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
20021 /* OPC_JIC, OPC_JIALC */
20022 TCGv tbase
= tcg_temp_new();
20023 TCGv toffset
= tcg_temp_new();
20025 gen_load_gpr(tbase
, rt
);
20026 tcg_gen_movi_tl(toffset
, offset
);
20027 gen_op_addr_add(ctx
, btarget
, tbase
, toffset
);
20028 tcg_temp_free(tbase
);
20029 tcg_temp_free(toffset
);
20033 MIPS_INVAL("Compact branch/jump");
20034 gen_reserved_instruction(ctx
);
20038 if (bcond_compute
== 0) {
20039 /* Uncoditional compact branch */
20042 gen_goto_tb(ctx
, 0, ctx
->btarget
);
20045 MIPS_INVAL("Compact branch/jump");
20046 gen_reserved_instruction(ctx
);
20050 /* Conditional compact branch */
20051 TCGLabel
*fs
= gen_new_label();
20055 if (rs
== 0 && rt
!= 0) {
20057 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE
), t1
, 0, fs
);
20058 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
20060 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE
), t1
, 0, fs
);
20063 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU
), t0
, t1
, fs
);
20067 if (rs
== 0 && rt
!= 0) {
20069 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT
), t1
, 0, fs
);
20070 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
20072 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT
), t1
, 0, fs
);
20075 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU
), t0
, t1
, fs
);
20079 if (rs
== 0 && rt
!= 0) {
20081 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE
), t1
, 0, fs
);
20082 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
20084 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE
), t1
, 0, fs
);
20087 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE
), t0
, t1
, fs
);
20091 if (rs
== 0 && rt
!= 0) {
20093 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT
), t1
, 0, fs
);
20094 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
20096 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT
), t1
, 0, fs
);
20099 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT
), t0
, t1
, fs
);
20103 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ
), t0
, 0, fs
);
20106 MIPS_INVAL("Compact conditional branch/jump");
20107 gen_reserved_instruction(ctx
);
20111 /* branch completion */
20112 clear_branch_hflags(ctx
);
20113 ctx
->base
.is_jmp
= DISAS_NORETURN
;
20115 /* Generating branch here as compact branches don't have delay slot */
20116 gen_goto_tb(ctx
, 1, ctx
->btarget
);
20119 gen_goto_tb(ctx
, 0, ctx
->base
.pc_next
+ 4);
20128 /* nanoMIPS CP1 Branches */
20129 static void gen_compute_branch_cp1_nm(DisasContext
*ctx
, uint32_t op
,
20130 int32_t ft
, int32_t offset
)
20132 target_ulong btarget
;
20133 TCGv_i64 t0
= tcg_temp_new_i64();
20135 gen_load_fpr64(ctx
, t0
, ft
);
20136 tcg_gen_andi_i64(t0
, t0
, 1);
20138 btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
20142 tcg_gen_xori_i64(t0
, t0
, 1);
20143 ctx
->hflags
|= MIPS_HFLAG_BC
;
20146 /* t0 already set */
20147 ctx
->hflags
|= MIPS_HFLAG_BC
;
20150 MIPS_INVAL("cp1 cond branch");
20151 gen_reserved_instruction(ctx
);
20155 tcg_gen_trunc_i64_tl(bcond
, t0
);
20157 ctx
->btarget
= btarget
;
20160 tcg_temp_free_i64(t0
);
20164 static void gen_p_lsx(DisasContext
*ctx
, int rd
, int rs
, int rt
)
20167 t0
= tcg_temp_new();
20168 t1
= tcg_temp_new();
20170 gen_load_gpr(t0
, rs
);
20171 gen_load_gpr(t1
, rt
);
20173 if ((extract32(ctx
->opcode
, 6, 1)) == 1) {
20174 /* PP.LSXS instructions require shifting */
20175 switch (extract32(ctx
->opcode
, 7, 4)) {
20181 tcg_gen_shli_tl(t0
, t0
, 1);
20189 tcg_gen_shli_tl(t0
, t0
, 2);
20193 tcg_gen_shli_tl(t0
, t0
, 3);
20197 gen_op_addr_add(ctx
, t0
, t0
, t1
);
20199 switch (extract32(ctx
->opcode
, 7, 4)) {
20201 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
,
20203 gen_store_gpr(t0
, rd
);
20207 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
,
20209 gen_store_gpr(t0
, rd
);
20213 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
,
20215 gen_store_gpr(t0
, rd
);
20218 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
,
20220 gen_store_gpr(t0
, rd
);
20224 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
,
20226 gen_store_gpr(t0
, rd
);
20230 gen_load_gpr(t1
, rd
);
20231 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
,
20237 gen_load_gpr(t1
, rd
);
20238 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
,
20244 gen_load_gpr(t1
, rd
);
20245 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
,
20249 /*case NM_LWC1XS:*/
20251 /*case NM_LDC1XS:*/
20253 /*case NM_SWC1XS:*/
20255 /*case NM_SDC1XS:*/
20256 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
20257 check_cp1_enabled(ctx
);
20258 switch (extract32(ctx
->opcode
, 7, 4)) {
20260 /*case NM_LWC1XS:*/
20261 gen_flt_ldst(ctx
, OPC_LWC1
, rd
, t0
);
20264 /*case NM_LDC1XS:*/
20265 gen_flt_ldst(ctx
, OPC_LDC1
, rd
, t0
);
20268 /*case NM_SWC1XS:*/
20269 gen_flt_ldst(ctx
, OPC_SWC1
, rd
, t0
);
20272 /*case NM_SDC1XS:*/
20273 gen_flt_ldst(ctx
, OPC_SDC1
, rd
, t0
);
20277 generate_exception_err(ctx
, EXCP_CpU
, 1);
20281 gen_reserved_instruction(ctx
);
20289 static void gen_pool32f_nanomips_insn(DisasContext
*ctx
)
20293 rt
= extract32(ctx
->opcode
, 21, 5);
20294 rs
= extract32(ctx
->opcode
, 16, 5);
20295 rd
= extract32(ctx
->opcode
, 11, 5);
20297 if (!(ctx
->CP0_Config1
& (1 << CP0C1_FP
))) {
20298 gen_reserved_instruction(ctx
);
20301 check_cp1_enabled(ctx
);
20302 switch (extract32(ctx
->opcode
, 0, 3)) {
20304 switch (extract32(ctx
->opcode
, 3, 7)) {
20306 gen_farith(ctx
, OPC_RINT_S
, 0, rt
, rs
, 0);
20309 gen_farith(ctx
, OPC_RINT_D
, 0, rt
, rs
, 0);
20312 gen_farith(ctx
, OPC_CLASS_S
, 0, rt
, rs
, 0);
20315 gen_farith(ctx
, OPC_CLASS_D
, 0, rt
, rs
, 0);
20318 gen_farith(ctx
, OPC_ADD_S
, rt
, rs
, rd
, 0);
20321 gen_farith(ctx
, OPC_ADD_D
, rt
, rs
, rd
, 0);
20324 gen_farith(ctx
, OPC_SUB_S
, rt
, rs
, rd
, 0);
20327 gen_farith(ctx
, OPC_SUB_D
, rt
, rs
, rd
, 0);
20330 gen_farith(ctx
, OPC_MUL_S
, rt
, rs
, rd
, 0);
20333 gen_farith(ctx
, OPC_MUL_D
, rt
, rs
, rd
, 0);
20336 gen_farith(ctx
, OPC_DIV_S
, rt
, rs
, rd
, 0);
20339 gen_farith(ctx
, OPC_DIV_D
, rt
, rs
, rd
, 0);
20342 gen_sel_s(ctx
, OPC_SELEQZ_S
, rd
, rt
, rs
);
20345 gen_sel_d(ctx
, OPC_SELEQZ_D
, rd
, rt
, rs
);
20348 gen_sel_s(ctx
, OPC_SELNEZ_S
, rd
, rt
, rs
);
20351 gen_sel_d(ctx
, OPC_SELNEZ_D
, rd
, rt
, rs
);
20354 gen_sel_s(ctx
, OPC_SEL_S
, rd
, rt
, rs
);
20357 gen_sel_d(ctx
, OPC_SEL_D
, rd
, rt
, rs
);
20360 gen_farith(ctx
, OPC_MADDF_S
, rt
, rs
, rd
, 0);
20363 gen_farith(ctx
, OPC_MADDF_D
, rt
, rs
, rd
, 0);
20366 gen_farith(ctx
, OPC_MSUBF_S
, rt
, rs
, rd
, 0);
20369 gen_farith(ctx
, OPC_MSUBF_D
, rt
, rs
, rd
, 0);
20372 gen_reserved_instruction(ctx
);
20377 switch (extract32(ctx
->opcode
, 3, 3)) {
20379 switch (extract32(ctx
->opcode
, 9, 1)) {
20381 gen_farith(ctx
, OPC_MIN_S
, rt
, rs
, rd
, 0);
20384 gen_farith(ctx
, OPC_MIN_D
, rt
, rs
, rd
, 0);
20389 switch (extract32(ctx
->opcode
, 9, 1)) {
20391 gen_farith(ctx
, OPC_MAX_S
, rt
, rs
, rd
, 0);
20394 gen_farith(ctx
, OPC_MAX_D
, rt
, rs
, rd
, 0);
20399 switch (extract32(ctx
->opcode
, 9, 1)) {
20401 gen_farith(ctx
, OPC_MINA_S
, rt
, rs
, rd
, 0);
20404 gen_farith(ctx
, OPC_MINA_D
, rt
, rs
, rd
, 0);
20409 switch (extract32(ctx
->opcode
, 9, 1)) {
20411 gen_farith(ctx
, OPC_MAXA_S
, rt
, rs
, rd
, 0);
20414 gen_farith(ctx
, OPC_MAXA_D
, rt
, rs
, rd
, 0);
20419 switch (extract32(ctx
->opcode
, 6, 8)) {
20421 gen_cp1(ctx
, OPC_CFC1
, rt
, rs
);
20424 gen_cp1(ctx
, OPC_CTC1
, rt
, rs
);
20427 gen_cp1(ctx
, OPC_MFC1
, rt
, rs
);
20430 gen_cp1(ctx
, OPC_MTC1
, rt
, rs
);
20433 gen_cp1(ctx
, OPC_MFHC1
, rt
, rs
);
20436 gen_cp1(ctx
, OPC_MTHC1
, rt
, rs
);
20439 gen_farith(ctx
, OPC_CVT_S_PL
, -1, rs
, rt
, 0);
20442 gen_farith(ctx
, OPC_CVT_S_PU
, -1, rs
, rt
, 0);
20445 switch (extract32(ctx
->opcode
, 6, 9)) {
20447 gen_farith(ctx
, OPC_CVT_L_S
, -1, rs
, rt
, 0);
20450 gen_farith(ctx
, OPC_CVT_L_D
, -1, rs
, rt
, 0);
20453 gen_farith(ctx
, OPC_CVT_W_S
, -1, rs
, rt
, 0);
20456 gen_farith(ctx
, OPC_CVT_W_D
, -1, rs
, rt
, 0);
20459 gen_farith(ctx
, OPC_RSQRT_S
, -1, rs
, rt
, 0);
20462 gen_farith(ctx
, OPC_RSQRT_D
, -1, rs
, rt
, 0);
20465 gen_farith(ctx
, OPC_SQRT_S
, -1, rs
, rt
, 0);
20468 gen_farith(ctx
, OPC_SQRT_D
, -1, rs
, rt
, 0);
20471 gen_farith(ctx
, OPC_RECIP_S
, -1, rs
, rt
, 0);
20474 gen_farith(ctx
, OPC_RECIP_D
, -1, rs
, rt
, 0);
20477 gen_farith(ctx
, OPC_FLOOR_L_S
, -1, rs
, rt
, 0);
20480 gen_farith(ctx
, OPC_FLOOR_L_D
, -1, rs
, rt
, 0);
20483 gen_farith(ctx
, OPC_FLOOR_W_S
, -1, rs
, rt
, 0);
20486 gen_farith(ctx
, OPC_FLOOR_W_D
, -1, rs
, rt
, 0);
20489 gen_farith(ctx
, OPC_CEIL_L_S
, -1, rs
, rt
, 0);
20492 gen_farith(ctx
, OPC_CEIL_L_D
, -1, rs
, rt
, 0);
20495 gen_farith(ctx
, OPC_CEIL_W_S
, -1, rs
, rt
, 0);
20498 gen_farith(ctx
, OPC_CEIL_W_D
, -1, rs
, rt
, 0);
20501 gen_farith(ctx
, OPC_TRUNC_L_S
, -1, rs
, rt
, 0);
20504 gen_farith(ctx
, OPC_TRUNC_L_D
, -1, rs
, rt
, 0);
20507 gen_farith(ctx
, OPC_TRUNC_W_S
, -1, rs
, rt
, 0);
20510 gen_farith(ctx
, OPC_TRUNC_W_D
, -1, rs
, rt
, 0);
20513 gen_farith(ctx
, OPC_ROUND_L_S
, -1, rs
, rt
, 0);
20516 gen_farith(ctx
, OPC_ROUND_L_D
, -1, rs
, rt
, 0);
20519 gen_farith(ctx
, OPC_ROUND_W_S
, -1, rs
, rt
, 0);
20522 gen_farith(ctx
, OPC_ROUND_W_D
, -1, rs
, rt
, 0);
20525 gen_farith(ctx
, OPC_MOV_S
, -1, rs
, rt
, 0);
20528 gen_farith(ctx
, OPC_MOV_D
, -1, rs
, rt
, 0);
20531 gen_farith(ctx
, OPC_ABS_S
, -1, rs
, rt
, 0);
20534 gen_farith(ctx
, OPC_ABS_D
, -1, rs
, rt
, 0);
20537 gen_farith(ctx
, OPC_NEG_S
, -1, rs
, rt
, 0);
20540 gen_farith(ctx
, OPC_NEG_D
, -1, rs
, rt
, 0);
20543 gen_farith(ctx
, OPC_CVT_D_S
, -1, rs
, rt
, 0);
20546 gen_farith(ctx
, OPC_CVT_D_W
, -1, rs
, rt
, 0);
20549 gen_farith(ctx
, OPC_CVT_D_L
, -1, rs
, rt
, 0);
20552 gen_farith(ctx
, OPC_CVT_S_D
, -1, rs
, rt
, 0);
20555 gen_farith(ctx
, OPC_CVT_S_W
, -1, rs
, rt
, 0);
20558 gen_farith(ctx
, OPC_CVT_S_L
, -1, rs
, rt
, 0);
20561 gen_reserved_instruction(ctx
);
20570 switch (extract32(ctx
->opcode
, 3, 3)) {
20571 case NM_CMP_CONDN_S
:
20572 gen_r6_cmp_s(ctx
, extract32(ctx
->opcode
, 6, 5), rt
, rs
, rd
);
20574 case NM_CMP_CONDN_D
:
20575 gen_r6_cmp_d(ctx
, extract32(ctx
->opcode
, 6, 5), rt
, rs
, rd
);
20578 gen_reserved_instruction(ctx
);
20583 gen_reserved_instruction(ctx
);
20588 static void gen_pool32a5_nanomips_insn(DisasContext
*ctx
, int opc
,
20589 int rd
, int rs
, int rt
)
20592 TCGv t0
= tcg_temp_new();
20593 TCGv v1_t
= tcg_temp_new();
20594 TCGv v2_t
= tcg_temp_new();
20596 gen_load_gpr(v1_t
, rs
);
20597 gen_load_gpr(v2_t
, rt
);
20602 gen_helper_cmp_eq_ph(v1_t
, v2_t
, cpu_env
);
20606 gen_helper_cmp_lt_ph(v1_t
, v2_t
, cpu_env
);
20610 gen_helper_cmp_le_ph(v1_t
, v2_t
, cpu_env
);
20612 case NM_CMPU_EQ_QB
:
20614 gen_helper_cmpu_eq_qb(v1_t
, v2_t
, cpu_env
);
20616 case NM_CMPU_LT_QB
:
20618 gen_helper_cmpu_lt_qb(v1_t
, v2_t
, cpu_env
);
20620 case NM_CMPU_LE_QB
:
20622 gen_helper_cmpu_le_qb(v1_t
, v2_t
, cpu_env
);
20624 case NM_CMPGU_EQ_QB
:
20626 gen_helper_cmpgu_eq_qb(v1_t
, v1_t
, v2_t
);
20627 gen_store_gpr(v1_t
, ret
);
20629 case NM_CMPGU_LT_QB
:
20631 gen_helper_cmpgu_lt_qb(v1_t
, v1_t
, v2_t
);
20632 gen_store_gpr(v1_t
, ret
);
20634 case NM_CMPGU_LE_QB
:
20636 gen_helper_cmpgu_le_qb(v1_t
, v1_t
, v2_t
);
20637 gen_store_gpr(v1_t
, ret
);
20639 case NM_CMPGDU_EQ_QB
:
20641 gen_helper_cmpgu_eq_qb(v1_t
, v1_t
, v2_t
);
20642 tcg_gen_deposit_tl(cpu_dspctrl
, cpu_dspctrl
, v1_t
, 24, 4);
20643 gen_store_gpr(v1_t
, ret
);
20645 case NM_CMPGDU_LT_QB
:
20647 gen_helper_cmpgu_lt_qb(v1_t
, v1_t
, v2_t
);
20648 tcg_gen_deposit_tl(cpu_dspctrl
, cpu_dspctrl
, v1_t
, 24, 4);
20649 gen_store_gpr(v1_t
, ret
);
20651 case NM_CMPGDU_LE_QB
:
20653 gen_helper_cmpgu_le_qb(v1_t
, v1_t
, v2_t
);
20654 tcg_gen_deposit_tl(cpu_dspctrl
, cpu_dspctrl
, v1_t
, 24, 4);
20655 gen_store_gpr(v1_t
, ret
);
20659 gen_helper_packrl_ph(v1_t
, v1_t
, v2_t
);
20660 gen_store_gpr(v1_t
, ret
);
20664 gen_helper_pick_qb(v1_t
, v1_t
, v2_t
, cpu_env
);
20665 gen_store_gpr(v1_t
, ret
);
20669 gen_helper_pick_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20670 gen_store_gpr(v1_t
, ret
);
20674 gen_helper_addq_s_w(v1_t
, v1_t
, v2_t
, cpu_env
);
20675 gen_store_gpr(v1_t
, ret
);
20679 gen_helper_subq_s_w(v1_t
, v1_t
, v2_t
, cpu_env
);
20680 gen_store_gpr(v1_t
, ret
);
20684 gen_helper_addsc(v1_t
, v1_t
, v2_t
, cpu_env
);
20685 gen_store_gpr(v1_t
, ret
);
20689 gen_helper_addwc(v1_t
, v1_t
, v2_t
, cpu_env
);
20690 gen_store_gpr(v1_t
, ret
);
20694 switch (extract32(ctx
->opcode
, 10, 1)) {
20697 gen_helper_addq_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20698 gen_store_gpr(v1_t
, ret
);
20702 gen_helper_addq_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20703 gen_store_gpr(v1_t
, ret
);
20707 case NM_ADDQH_R_PH
:
20709 switch (extract32(ctx
->opcode
, 10, 1)) {
20712 gen_helper_addqh_ph(v1_t
, v1_t
, v2_t
);
20713 gen_store_gpr(v1_t
, ret
);
20717 gen_helper_addqh_r_ph(v1_t
, v1_t
, v2_t
);
20718 gen_store_gpr(v1_t
, ret
);
20724 switch (extract32(ctx
->opcode
, 10, 1)) {
20727 gen_helper_addqh_w(v1_t
, v1_t
, v2_t
);
20728 gen_store_gpr(v1_t
, ret
);
20732 gen_helper_addqh_r_w(v1_t
, v1_t
, v2_t
);
20733 gen_store_gpr(v1_t
, ret
);
20739 switch (extract32(ctx
->opcode
, 10, 1)) {
20742 gen_helper_addu_qb(v1_t
, v1_t
, v2_t
, cpu_env
);
20743 gen_store_gpr(v1_t
, ret
);
20747 gen_helper_addu_s_qb(v1_t
, v1_t
, v2_t
, cpu_env
);
20748 gen_store_gpr(v1_t
, ret
);
20754 switch (extract32(ctx
->opcode
, 10, 1)) {
20757 gen_helper_addu_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20758 gen_store_gpr(v1_t
, ret
);
20762 gen_helper_addu_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20763 gen_store_gpr(v1_t
, ret
);
20767 case NM_ADDUH_R_QB
:
20769 switch (extract32(ctx
->opcode
, 10, 1)) {
20772 gen_helper_adduh_qb(v1_t
, v1_t
, v2_t
);
20773 gen_store_gpr(v1_t
, ret
);
20777 gen_helper_adduh_r_qb(v1_t
, v1_t
, v2_t
);
20778 gen_store_gpr(v1_t
, ret
);
20782 case NM_SHRAV_R_PH
:
20784 switch (extract32(ctx
->opcode
, 10, 1)) {
20787 gen_helper_shra_ph(v1_t
, v1_t
, v2_t
);
20788 gen_store_gpr(v1_t
, ret
);
20792 gen_helper_shra_r_ph(v1_t
, v1_t
, v2_t
);
20793 gen_store_gpr(v1_t
, ret
);
20797 case NM_SHRAV_R_QB
:
20799 switch (extract32(ctx
->opcode
, 10, 1)) {
20802 gen_helper_shra_qb(v1_t
, v1_t
, v2_t
);
20803 gen_store_gpr(v1_t
, ret
);
20807 gen_helper_shra_r_qb(v1_t
, v1_t
, v2_t
);
20808 gen_store_gpr(v1_t
, ret
);
20814 switch (extract32(ctx
->opcode
, 10, 1)) {
20817 gen_helper_subq_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20818 gen_store_gpr(v1_t
, ret
);
20822 gen_helper_subq_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20823 gen_store_gpr(v1_t
, ret
);
20827 case NM_SUBQH_R_PH
:
20829 switch (extract32(ctx
->opcode
, 10, 1)) {
20832 gen_helper_subqh_ph(v1_t
, v1_t
, v2_t
);
20833 gen_store_gpr(v1_t
, ret
);
20837 gen_helper_subqh_r_ph(v1_t
, v1_t
, v2_t
);
20838 gen_store_gpr(v1_t
, ret
);
20844 switch (extract32(ctx
->opcode
, 10, 1)) {
20847 gen_helper_subqh_w(v1_t
, v1_t
, v2_t
);
20848 gen_store_gpr(v1_t
, ret
);
20852 gen_helper_subqh_r_w(v1_t
, v1_t
, v2_t
);
20853 gen_store_gpr(v1_t
, ret
);
20859 switch (extract32(ctx
->opcode
, 10, 1)) {
20862 gen_helper_subu_qb(v1_t
, v1_t
, v2_t
, cpu_env
);
20863 gen_store_gpr(v1_t
, ret
);
20867 gen_helper_subu_s_qb(v1_t
, v1_t
, v2_t
, cpu_env
);
20868 gen_store_gpr(v1_t
, ret
);
20874 switch (extract32(ctx
->opcode
, 10, 1)) {
20877 gen_helper_subu_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20878 gen_store_gpr(v1_t
, ret
);
20882 gen_helper_subu_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20883 gen_store_gpr(v1_t
, ret
);
20887 case NM_SUBUH_R_QB
:
20889 switch (extract32(ctx
->opcode
, 10, 1)) {
20892 gen_helper_subuh_qb(v1_t
, v1_t
, v2_t
);
20893 gen_store_gpr(v1_t
, ret
);
20897 gen_helper_subuh_r_qb(v1_t
, v1_t
, v2_t
);
20898 gen_store_gpr(v1_t
, ret
);
20902 case NM_SHLLV_S_PH
:
20904 switch (extract32(ctx
->opcode
, 10, 1)) {
20907 gen_helper_shll_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20908 gen_store_gpr(v1_t
, ret
);
20912 gen_helper_shll_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20913 gen_store_gpr(v1_t
, ret
);
20917 case NM_PRECR_SRA_R_PH_W
:
20919 switch (extract32(ctx
->opcode
, 10, 1)) {
20921 /* PRECR_SRA_PH_W */
20923 TCGv_i32 sa_t
= tcg_const_i32(rd
);
20924 gen_helper_precr_sra_ph_w(v1_t
, sa_t
, v1_t
,
20926 gen_store_gpr(v1_t
, rt
);
20927 tcg_temp_free_i32(sa_t
);
20931 /* PRECR_SRA_R_PH_W */
20933 TCGv_i32 sa_t
= tcg_const_i32(rd
);
20934 gen_helper_precr_sra_r_ph_w(v1_t
, sa_t
, v1_t
,
20936 gen_store_gpr(v1_t
, rt
);
20937 tcg_temp_free_i32(sa_t
);
20942 case NM_MULEU_S_PH_QBL
:
20944 gen_helper_muleu_s_ph_qbl(v1_t
, v1_t
, v2_t
, cpu_env
);
20945 gen_store_gpr(v1_t
, ret
);
20947 case NM_MULEU_S_PH_QBR
:
20949 gen_helper_muleu_s_ph_qbr(v1_t
, v1_t
, v2_t
, cpu_env
);
20950 gen_store_gpr(v1_t
, ret
);
20952 case NM_MULQ_RS_PH
:
20954 gen_helper_mulq_rs_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20955 gen_store_gpr(v1_t
, ret
);
20959 gen_helper_mulq_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20960 gen_store_gpr(v1_t
, ret
);
20964 gen_helper_mulq_rs_w(v1_t
, v1_t
, v2_t
, cpu_env
);
20965 gen_store_gpr(v1_t
, ret
);
20969 gen_helper_mulq_s_w(v1_t
, v1_t
, v2_t
, cpu_env
);
20970 gen_store_gpr(v1_t
, ret
);
20974 gen_load_gpr(t0
, rs
);
20976 tcg_gen_deposit_tl(cpu_gpr
[rt
], t0
, cpu_gpr
[rt
], rd
, 32 - rd
);
20978 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
20982 gen_helper_modsub(v1_t
, v1_t
, v2_t
);
20983 gen_store_gpr(v1_t
, ret
);
20987 gen_helper_shra_r_w(v1_t
, v1_t
, v2_t
);
20988 gen_store_gpr(v1_t
, ret
);
20992 gen_helper_shrl_ph(v1_t
, v1_t
, v2_t
);
20993 gen_store_gpr(v1_t
, ret
);
20997 gen_helper_shrl_qb(v1_t
, v1_t
, v2_t
);
20998 gen_store_gpr(v1_t
, ret
);
21002 gen_helper_shll_qb(v1_t
, v1_t
, v2_t
, cpu_env
);
21003 gen_store_gpr(v1_t
, ret
);
21007 gen_helper_shll_s_w(v1_t
, v1_t
, v2_t
, cpu_env
);
21008 gen_store_gpr(v1_t
, ret
);
21013 TCGv tv0
= tcg_temp_new();
21014 TCGv tv1
= tcg_temp_new();
21015 int16_t imm
= extract32(ctx
->opcode
, 16, 7);
21017 tcg_gen_movi_tl(tv0
, rd
>> 3);
21018 tcg_gen_movi_tl(tv1
, imm
);
21019 gen_helper_shilo(tv0
, tv1
, cpu_env
);
21022 case NM_MULEQ_S_W_PHL
:
21024 gen_helper_muleq_s_w_phl(v1_t
, v1_t
, v2_t
, cpu_env
);
21025 gen_store_gpr(v1_t
, ret
);
21027 case NM_MULEQ_S_W_PHR
:
21029 gen_helper_muleq_s_w_phr(v1_t
, v1_t
, v2_t
, cpu_env
);
21030 gen_store_gpr(v1_t
, ret
);
21034 switch (extract32(ctx
->opcode
, 10, 1)) {
21037 gen_helper_mul_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21038 gen_store_gpr(v1_t
, ret
);
21042 gen_helper_mul_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21043 gen_store_gpr(v1_t
, ret
);
21047 case NM_PRECR_QB_PH
:
21049 gen_helper_precr_qb_ph(v1_t
, v1_t
, v2_t
);
21050 gen_store_gpr(v1_t
, ret
);
21052 case NM_PRECRQ_QB_PH
:
21054 gen_helper_precrq_qb_ph(v1_t
, v1_t
, v2_t
);
21055 gen_store_gpr(v1_t
, ret
);
21057 case NM_PRECRQ_PH_W
:
21059 gen_helper_precrq_ph_w(v1_t
, v1_t
, v2_t
);
21060 gen_store_gpr(v1_t
, ret
);
21062 case NM_PRECRQ_RS_PH_W
:
21064 gen_helper_precrq_rs_ph_w(v1_t
, v1_t
, v2_t
, cpu_env
);
21065 gen_store_gpr(v1_t
, ret
);
21067 case NM_PRECRQU_S_QB_PH
:
21069 gen_helper_precrqu_s_qb_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21070 gen_store_gpr(v1_t
, ret
);
21074 tcg_gen_movi_tl(t0
, rd
);
21075 gen_helper_shra_r_w(v1_t
, t0
, v1_t
);
21076 gen_store_gpr(v1_t
, rt
);
21080 tcg_gen_movi_tl(t0
, rd
>> 1);
21081 switch (extract32(ctx
->opcode
, 10, 1)) {
21084 gen_helper_shra_ph(v1_t
, t0
, v1_t
);
21085 gen_store_gpr(v1_t
, rt
);
21089 gen_helper_shra_r_ph(v1_t
, t0
, v1_t
);
21090 gen_store_gpr(v1_t
, rt
);
21096 tcg_gen_movi_tl(t0
, rd
>> 1);
21097 switch (extract32(ctx
->opcode
, 10, 2)) {
21100 gen_helper_shll_ph(v1_t
, t0
, v1_t
, cpu_env
);
21101 gen_store_gpr(v1_t
, rt
);
21105 gen_helper_shll_s_ph(v1_t
, t0
, v1_t
, cpu_env
);
21106 gen_store_gpr(v1_t
, rt
);
21109 gen_reserved_instruction(ctx
);
21115 tcg_gen_movi_tl(t0
, rd
);
21116 gen_helper_shll_s_w(v1_t
, t0
, v1_t
, cpu_env
);
21117 gen_store_gpr(v1_t
, rt
);
21123 imm
= sextract32(ctx
->opcode
, 11, 11);
21124 imm
= (int16_t)(imm
<< 6) >> 6;
21126 tcg_gen_movi_tl(cpu_gpr
[rt
], dup_const(MO_16
, imm
));
21131 gen_reserved_instruction(ctx
);
21136 static int decode_nanomips_32_48_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
21144 insn
= translator_lduw(env
, ctx
->base
.pc_next
+ 2);
21145 ctx
->opcode
= (ctx
->opcode
<< 16) | insn
;
21147 rt
= extract32(ctx
->opcode
, 21, 5);
21148 rs
= extract32(ctx
->opcode
, 16, 5);
21149 rd
= extract32(ctx
->opcode
, 11, 5);
21151 op
= extract32(ctx
->opcode
, 26, 6);
21156 switch (extract32(ctx
->opcode
, 19, 2)) {
21159 gen_reserved_instruction(ctx
);
21162 if ((extract32(ctx
->opcode
, 18, 1)) == NM_SYSCALL
) {
21163 generate_exception_end(ctx
, EXCP_SYSCALL
);
21165 gen_reserved_instruction(ctx
);
21169 generate_exception_end(ctx
, EXCP_BREAK
);
21172 if (is_uhi(extract32(ctx
->opcode
, 0, 19))) {
21173 gen_helper_do_semihosting(cpu_env
);
21175 if (ctx
->hflags
& MIPS_HFLAG_SBRI
) {
21176 gen_reserved_instruction(ctx
);
21178 generate_exception_end(ctx
, EXCP_DBp
);
21185 imm
= extract32(ctx
->opcode
, 0, 16);
21187 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], imm
);
21189 tcg_gen_movi_tl(cpu_gpr
[rt
], imm
);
21191 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
21196 offset
= sextract32(ctx
->opcode
, 0, 1) << 21 |
21197 extract32(ctx
->opcode
, 1, 20) << 1;
21198 target_long addr
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
21199 tcg_gen_movi_tl(cpu_gpr
[rt
], addr
);
21203 switch (ctx
->opcode
& 0x07) {
21205 gen_pool32a0_nanomips_insn(env
, ctx
);
21209 int32_t op1
= extract32(ctx
->opcode
, 3, 7);
21210 gen_pool32a5_nanomips_insn(ctx
, op1
, rd
, rs
, rt
);
21214 switch (extract32(ctx
->opcode
, 3, 3)) {
21216 gen_p_lsx(ctx
, rd
, rs
, rt
);
21220 * In nanoMIPS, the shift field directly encodes the shift
21221 * amount, meaning that the supported shift values are in
21222 * the range 0 to 3 (instead of 1 to 4 in MIPSR6).
21224 gen_lsa(ctx
, rd
, rt
, rs
, extract32(ctx
->opcode
, 9, 2) - 1);
21227 gen_ext(ctx
, 32, rd
, rs
, rt
, extract32(ctx
->opcode
, 6, 5));
21230 gen_pool32axf_nanomips_insn(env
, ctx
);
21233 gen_reserved_instruction(ctx
);
21238 gen_reserved_instruction(ctx
);
21243 switch (ctx
->opcode
& 0x03) {
21246 offset
= extract32(ctx
->opcode
, 0, 21);
21247 gen_op_addr_addi(ctx
, cpu_gpr
[rt
], cpu_gpr
[28], offset
);
21251 gen_ld(ctx
, OPC_LW
, rt
, 28, extract32(ctx
->opcode
, 2, 19) << 2);
21254 gen_st(ctx
, OPC_SW
, rt
, 28, extract32(ctx
->opcode
, 2, 19) << 2);
21257 gen_reserved_instruction(ctx
);
21263 insn
= translator_lduw(env
, ctx
->base
.pc_next
+ 4);
21264 target_long addr_off
= extract32(ctx
->opcode
, 0, 16) | insn
<< 16;
21265 switch (extract32(ctx
->opcode
, 16, 5)) {
21269 tcg_gen_movi_tl(cpu_gpr
[rt
], addr_off
);
21275 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], addr_off
);
21276 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
21282 gen_op_addr_addi(ctx
, cpu_gpr
[rt
], cpu_gpr
[28], addr_off
);
21288 target_long addr
= addr_add(ctx
, ctx
->base
.pc_next
+ 6,
21291 tcg_gen_movi_tl(cpu_gpr
[rt
], addr
);
21298 t0
= tcg_temp_new();
21300 target_long addr
= addr_add(ctx
, ctx
->base
.pc_next
+ 6,
21303 tcg_gen_movi_tl(t0
, addr
);
21304 tcg_gen_qemu_ld_tl(cpu_gpr
[rt
], t0
, ctx
->mem_idx
, MO_TESL
);
21312 t0
= tcg_temp_new();
21313 t1
= tcg_temp_new();
21315 target_long addr
= addr_add(ctx
, ctx
->base
.pc_next
+ 6,
21318 tcg_gen_movi_tl(t0
, addr
);
21319 gen_load_gpr(t1
, rt
);
21321 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
21328 gen_reserved_instruction(ctx
);
21334 switch (extract32(ctx
->opcode
, 12, 4)) {
21336 gen_logic_imm(ctx
, OPC_ORI
, rt
, rs
, extract32(ctx
->opcode
, 0, 12));
21339 gen_logic_imm(ctx
, OPC_XORI
, rt
, rs
, extract32(ctx
->opcode
, 0, 12));
21342 gen_logic_imm(ctx
, OPC_ANDI
, rt
, rs
, extract32(ctx
->opcode
, 0, 12));
21345 switch (extract32(ctx
->opcode
, 20, 1)) {
21347 switch (ctx
->opcode
& 3) {
21349 gen_save(ctx
, rt
, extract32(ctx
->opcode
, 16, 4),
21350 extract32(ctx
->opcode
, 2, 1),
21351 extract32(ctx
->opcode
, 3, 9) << 3);
21354 case NM_RESTORE_JRC
:
21355 gen_restore(ctx
, rt
, extract32(ctx
->opcode
, 16, 4),
21356 extract32(ctx
->opcode
, 2, 1),
21357 extract32(ctx
->opcode
, 3, 9) << 3);
21358 if ((ctx
->opcode
& 3) == NM_RESTORE_JRC
) {
21359 gen_compute_branch_nm(ctx
, OPC_JR
, 2, 31, 0, 0);
21363 gen_reserved_instruction(ctx
);
21368 gen_reserved_instruction(ctx
);
21373 gen_slt_imm(ctx
, OPC_SLTI
, rt
, rs
, extract32(ctx
->opcode
, 0, 12));
21376 gen_slt_imm(ctx
, OPC_SLTIU
, rt
, rs
, extract32(ctx
->opcode
, 0, 12));
21380 TCGv t0
= tcg_temp_new();
21382 imm
= extract32(ctx
->opcode
, 0, 12);
21383 gen_load_gpr(t0
, rs
);
21384 tcg_gen_setcondi_tl(TCG_COND_EQ
, t0
, t0
, imm
);
21385 gen_store_gpr(t0
, rt
);
21391 imm
= (int16_t) extract32(ctx
->opcode
, 0, 12);
21392 gen_arith_imm(ctx
, OPC_ADDIU
, rt
, rs
, -imm
);
21396 int shift
= extract32(ctx
->opcode
, 0, 5);
21397 switch (extract32(ctx
->opcode
, 5, 4)) {
21399 if (rt
== 0 && shift
== 0) {
21401 } else if (rt
== 0 && shift
== 3) {
21402 /* EHB - treat as NOP */
21403 } else if (rt
== 0 && shift
== 5) {
21404 /* PAUSE - treat as NOP */
21405 } else if (rt
== 0 && shift
== 6) {
21407 gen_sync(extract32(ctx
->opcode
, 16, 5));
21410 gen_shift_imm(ctx
, OPC_SLL
, rt
, rs
,
21411 extract32(ctx
->opcode
, 0, 5));
21415 gen_shift_imm(ctx
, OPC_SRL
, rt
, rs
,
21416 extract32(ctx
->opcode
, 0, 5));
21419 gen_shift_imm(ctx
, OPC_SRA
, rt
, rs
,
21420 extract32(ctx
->opcode
, 0, 5));
21423 gen_shift_imm(ctx
, OPC_ROTR
, rt
, rs
,
21424 extract32(ctx
->opcode
, 0, 5));
21432 TCGv t0
= tcg_temp_new();
21433 TCGv_i32 shift
= tcg_const_i32(extract32(ctx
->opcode
, 0, 5));
21434 TCGv_i32 shiftx
= tcg_const_i32(extract32(ctx
->opcode
, 7, 4)
21436 TCGv_i32 stripe
= tcg_const_i32(extract32(ctx
->opcode
, 6, 1));
21438 gen_load_gpr(t0
, rs
);
21439 gen_helper_rotx(cpu_gpr
[rt
], t0
, shift
, shiftx
, stripe
);
21442 tcg_temp_free_i32(shift
);
21443 tcg_temp_free_i32(shiftx
);
21444 tcg_temp_free_i32(stripe
);
21448 switch (((ctx
->opcode
>> 10) & 2) |
21449 (extract32(ctx
->opcode
, 5, 1))) {
21452 gen_bitops(ctx
, OPC_INS
, rt
, rs
, extract32(ctx
->opcode
, 0, 5),
21453 extract32(ctx
->opcode
, 6, 5));
21456 gen_reserved_instruction(ctx
);
21461 switch (((ctx
->opcode
>> 10) & 2) |
21462 (extract32(ctx
->opcode
, 5, 1))) {
21465 gen_bitops(ctx
, OPC_EXT
, rt
, rs
, extract32(ctx
->opcode
, 0, 5),
21466 extract32(ctx
->opcode
, 6, 5));
21469 gen_reserved_instruction(ctx
);
21474 gen_reserved_instruction(ctx
);
21479 gen_pool32f_nanomips_insn(ctx
);
21484 switch (extract32(ctx
->opcode
, 1, 1)) {
21487 tcg_gen_movi_tl(cpu_gpr
[rt
],
21488 sextract32(ctx
->opcode
, 0, 1) << 31 |
21489 extract32(ctx
->opcode
, 2, 10) << 21 |
21490 extract32(ctx
->opcode
, 12, 9) << 12);
21495 offset
= sextract32(ctx
->opcode
, 0, 1) << 31 |
21496 extract32(ctx
->opcode
, 2, 10) << 21 |
21497 extract32(ctx
->opcode
, 12, 9) << 12;
21499 addr
= ~0xFFF & addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
21500 tcg_gen_movi_tl(cpu_gpr
[rt
], addr
);
21507 uint32_t u
= extract32(ctx
->opcode
, 0, 18);
21509 switch (extract32(ctx
->opcode
, 18, 3)) {
21511 gen_ld(ctx
, OPC_LB
, rt
, 28, u
);
21514 gen_st(ctx
, OPC_SB
, rt
, 28, u
);
21517 gen_ld(ctx
, OPC_LBU
, rt
, 28, u
);
21521 gen_op_addr_addi(ctx
, cpu_gpr
[rt
], cpu_gpr
[28], u
);
21526 switch (ctx
->opcode
& 1) {
21528 gen_ld(ctx
, OPC_LH
, rt
, 28, u
);
21531 gen_ld(ctx
, OPC_LHU
, rt
, 28, u
);
21537 switch (ctx
->opcode
& 1) {
21539 gen_st(ctx
, OPC_SH
, rt
, 28, u
);
21542 gen_reserved_instruction(ctx
);
21548 switch (ctx
->opcode
& 0x3) {
21550 gen_cop1_ldst(ctx
, OPC_LWC1
, rt
, 28, u
);
21553 gen_cop1_ldst(ctx
, OPC_LDC1
, rt
, 28, u
);
21556 gen_cop1_ldst(ctx
, OPC_SWC1
, rt
, 28, u
);
21559 gen_cop1_ldst(ctx
, OPC_SDC1
, rt
, 28, u
);
21564 gen_reserved_instruction(ctx
);
21571 uint32_t u
= extract32(ctx
->opcode
, 0, 12);
21573 switch (extract32(ctx
->opcode
, 12, 4)) {
21578 * Break the TB to be able to sync copied instructions
21581 ctx
->base
.is_jmp
= DISAS_STOP
;
21584 /* Treat as NOP. */
21588 gen_ld(ctx
, OPC_LB
, rt
, rs
, u
);
21591 gen_ld(ctx
, OPC_LH
, rt
, rs
, u
);
21594 gen_ld(ctx
, OPC_LW
, rt
, rs
, u
);
21597 gen_ld(ctx
, OPC_LBU
, rt
, rs
, u
);
21600 gen_ld(ctx
, OPC_LHU
, rt
, rs
, u
);
21603 gen_st(ctx
, OPC_SB
, rt
, rs
, u
);
21606 gen_st(ctx
, OPC_SH
, rt
, rs
, u
);
21609 gen_st(ctx
, OPC_SW
, rt
, rs
, u
);
21612 gen_cop1_ldst(ctx
, OPC_LWC1
, rt
, rs
, u
);
21615 gen_cop1_ldst(ctx
, OPC_LDC1
, rt
, rs
, u
);
21618 gen_cop1_ldst(ctx
, OPC_SWC1
, rt
, rs
, u
);
21621 gen_cop1_ldst(ctx
, OPC_SDC1
, rt
, rs
, u
);
21624 gen_reserved_instruction(ctx
);
21631 int32_t s
= (sextract32(ctx
->opcode
, 15, 1) << 8) |
21632 extract32(ctx
->opcode
, 0, 8);
21634 switch (extract32(ctx
->opcode
, 8, 3)) {
21636 switch (extract32(ctx
->opcode
, 11, 4)) {
21638 gen_ld(ctx
, OPC_LB
, rt
, rs
, s
);
21641 gen_ld(ctx
, OPC_LH
, rt
, rs
, s
);
21644 gen_ld(ctx
, OPC_LW
, rt
, rs
, s
);
21647 gen_ld(ctx
, OPC_LBU
, rt
, rs
, s
);
21650 gen_ld(ctx
, OPC_LHU
, rt
, rs
, s
);
21653 gen_st(ctx
, OPC_SB
, rt
, rs
, s
);
21656 gen_st(ctx
, OPC_SH
, rt
, rs
, s
);
21659 gen_st(ctx
, OPC_SW
, rt
, rs
, s
);
21662 gen_cop1_ldst(ctx
, OPC_LWC1
, rt
, rs
, s
);
21665 gen_cop1_ldst(ctx
, OPC_LDC1
, rt
, rs
, s
);
21668 gen_cop1_ldst(ctx
, OPC_SWC1
, rt
, rs
, s
);
21671 gen_cop1_ldst(ctx
, OPC_SDC1
, rt
, rs
, s
);
21677 * Break the TB to be able to sync copied instructions
21680 ctx
->base
.is_jmp
= DISAS_STOP
;
21683 /* Treat as NOP. */
21687 gen_reserved_instruction(ctx
);
21692 switch (extract32(ctx
->opcode
, 11, 4)) {
21697 TCGv t0
= tcg_temp_new();
21698 TCGv t1
= tcg_temp_new();
21700 gen_base_offset_addr(ctx
, t0
, rs
, s
);
21702 switch (extract32(ctx
->opcode
, 11, 4)) {
21704 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESW
|
21706 gen_store_gpr(t0
, rt
);
21709 gen_load_gpr(t1
, rt
);
21710 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUW
|
21719 switch (ctx
->opcode
& 0x03) {
21721 gen_ld(ctx
, OPC_LL
, rt
, rs
, s
);
21725 gen_llwp(ctx
, rs
, 0, rt
, extract32(ctx
->opcode
, 3, 5));
21730 switch (ctx
->opcode
& 0x03) {
21732 gen_st_cond(ctx
, rt
, rs
, s
, MO_TESL
, false);
21736 gen_scwp(ctx
, rs
, 0, rt
, extract32(ctx
->opcode
, 3, 5),
21742 check_cp0_enabled(ctx
);
21743 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
21744 gen_cache_operation(ctx
, rt
, rs
, s
);
21750 switch (extract32(ctx
->opcode
, 11, 4)) {
21753 check_cp0_enabled(ctx
);
21754 gen_ld(ctx
, OPC_LBE
, rt
, rs
, s
);
21758 check_cp0_enabled(ctx
);
21759 gen_st(ctx
, OPC_SBE
, rt
, rs
, s
);
21763 check_cp0_enabled(ctx
);
21764 gen_ld(ctx
, OPC_LBUE
, rt
, rs
, s
);
21768 /* case NM_SYNCIE */
21770 check_cp0_enabled(ctx
);
21772 * Break the TB to be able to sync copied instructions
21775 ctx
->base
.is_jmp
= DISAS_STOP
;
21777 /* case NM_PREFE */
21779 check_cp0_enabled(ctx
);
21780 /* Treat as NOP. */
21785 check_cp0_enabled(ctx
);
21786 gen_ld(ctx
, OPC_LHE
, rt
, rs
, s
);
21790 check_cp0_enabled(ctx
);
21791 gen_st(ctx
, OPC_SHE
, rt
, rs
, s
);
21795 check_cp0_enabled(ctx
);
21796 gen_ld(ctx
, OPC_LHUE
, rt
, rs
, s
);
21799 check_nms_dl_il_sl_tl_l2c(ctx
);
21800 gen_cache_operation(ctx
, rt
, rs
, s
);
21804 check_cp0_enabled(ctx
);
21805 gen_ld(ctx
, OPC_LWE
, rt
, rs
, s
);
21809 check_cp0_enabled(ctx
);
21810 gen_st(ctx
, OPC_SWE
, rt
, rs
, s
);
21813 switch (extract32(ctx
->opcode
, 2, 2)) {
21817 check_cp0_enabled(ctx
);
21818 gen_ld(ctx
, OPC_LLE
, rt
, rs
, s
);
21823 check_cp0_enabled(ctx
);
21824 gen_llwp(ctx
, rs
, 0, rt
, extract32(ctx
->opcode
, 3, 5));
21827 gen_reserved_instruction(ctx
);
21832 switch (extract32(ctx
->opcode
, 2, 2)) {
21836 check_cp0_enabled(ctx
);
21837 gen_st_cond(ctx
, rt
, rs
, s
, MO_TESL
, true);
21842 check_cp0_enabled(ctx
);
21843 gen_scwp(ctx
, rs
, 0, rt
, extract32(ctx
->opcode
, 3, 5),
21847 gen_reserved_instruction(ctx
);
21857 int count
= extract32(ctx
->opcode
, 12, 3);
21860 offset
= sextract32(ctx
->opcode
, 15, 1) << 8 |
21861 extract32(ctx
->opcode
, 0, 8);
21862 TCGv va
= tcg_temp_new();
21863 TCGv t1
= tcg_temp_new();
21864 MemOp memop
= (extract32(ctx
->opcode
, 8, 3)) ==
21865 NM_P_LS_UAWM
? MO_UNALN
: 0;
21867 count
= (count
== 0) ? 8 : count
;
21868 while (counter
!= count
) {
21869 int this_rt
= ((rt
+ counter
) & 0x1f) | (rt
& 0x10);
21870 int this_offset
= offset
+ (counter
<< 2);
21872 gen_base_offset_addr(ctx
, va
, rs
, this_offset
);
21874 switch (extract32(ctx
->opcode
, 11, 1)) {
21876 tcg_gen_qemu_ld_tl(t1
, va
, ctx
->mem_idx
,
21878 gen_store_gpr(t1
, this_rt
);
21879 if ((this_rt
== rs
) &&
21880 (counter
!= (count
- 1))) {
21881 /* UNPREDICTABLE */
21885 this_rt
= (rt
== 0) ? 0 : this_rt
;
21886 gen_load_gpr(t1
, this_rt
);
21887 tcg_gen_qemu_st_tl(t1
, va
, ctx
->mem_idx
,
21898 gen_reserved_instruction(ctx
);
21906 TCGv t0
= tcg_temp_new();
21907 int32_t s
= sextract32(ctx
->opcode
, 0, 1) << 21 |
21908 extract32(ctx
->opcode
, 1, 20) << 1;
21909 rd
= (extract32(ctx
->opcode
, 24, 1)) == 0 ? 4 : 5;
21910 rt
= decode_gpr_gpr4_zero(extract32(ctx
->opcode
, 25, 1) << 3 |
21911 extract32(ctx
->opcode
, 21, 3));
21912 gen_load_gpr(t0
, rt
);
21913 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
21914 gen_compute_branch_nm(ctx
, OPC_BGEZAL
, 4, 0, 0, s
);
21920 int32_t s
= sextract32(ctx
->opcode
, 0, 1) << 25 |
21921 extract32(ctx
->opcode
, 1, 24) << 1;
21923 if ((extract32(ctx
->opcode
, 25, 1)) == 0) {
21925 gen_compute_branch_nm(ctx
, OPC_BEQ
, 4, 0, 0, s
);
21928 gen_compute_branch_nm(ctx
, OPC_BGEZAL
, 4, 0, 0, s
);
21933 switch (extract32(ctx
->opcode
, 12, 4)) {
21936 gen_compute_branch_nm(ctx
, OPC_JALR
, 4, rs
, rt
, 0);
21939 gen_compute_nanomips_pbalrsc_branch(ctx
, rs
, rt
);
21942 gen_reserved_instruction(ctx
);
21948 int32_t s
= sextract32(ctx
->opcode
, 0, 1) << 14 |
21949 extract32(ctx
->opcode
, 1, 13) << 1;
21950 switch (extract32(ctx
->opcode
, 14, 2)) {
21953 gen_compute_branch_nm(ctx
, OPC_BEQ
, 4, rs
, rt
, s
);
21956 s
= sextract32(ctx
->opcode
, 0, 1) << 14 |
21957 extract32(ctx
->opcode
, 1, 13) << 1;
21958 check_cp1_enabled(ctx
);
21959 switch (extract32(ctx
->opcode
, 16, 5)) {
21961 gen_compute_branch_cp1_nm(ctx
, OPC_BC1EQZ
, rt
, s
);
21964 gen_compute_branch_cp1_nm(ctx
, OPC_BC1NEZ
, rt
, s
);
21969 int32_t imm
= extract32(ctx
->opcode
, 1, 13) |
21970 extract32(ctx
->opcode
, 0, 1) << 13;
21972 gen_compute_branch_nm(ctx
, OPC_BPOSGE32
, 4, -1, -2,
21977 gen_reserved_instruction(ctx
);
21983 gen_compute_compact_branch_nm(ctx
, OPC_BC
, rs
, rt
, s
);
21985 gen_compute_compact_branch_nm(ctx
, OPC_BGEC
, rs
, rt
, s
);
21989 if (rs
== rt
|| rt
== 0) {
21990 gen_compute_compact_branch_nm(ctx
, OPC_BC
, 0, 0, s
);
21991 } else if (rs
== 0) {
21992 gen_compute_compact_branch_nm(ctx
, OPC_BEQZC
, rt
, 0, s
);
21994 gen_compute_compact_branch_nm(ctx
, OPC_BGEUC
, rs
, rt
, s
);
22002 int32_t s
= sextract32(ctx
->opcode
, 0, 1) << 14 |
22003 extract32(ctx
->opcode
, 1, 13) << 1;
22004 switch (extract32(ctx
->opcode
, 14, 2)) {
22007 gen_compute_branch_nm(ctx
, OPC_BNE
, 4, rs
, rt
, s
);
22010 if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
22012 ctx
->hflags
|= MIPS_HFLAG_FBNSLOT
;
22014 gen_compute_compact_branch_nm(ctx
, OPC_BLTC
, rs
, rt
, s
);
22018 if (rs
== 0 || rs
== rt
) {
22020 ctx
->hflags
|= MIPS_HFLAG_FBNSLOT
;
22022 gen_compute_compact_branch_nm(ctx
, OPC_BLTUC
, rs
, rt
, s
);
22026 gen_reserved_instruction(ctx
);
22033 int32_t s
= sextract32(ctx
->opcode
, 0, 1) << 11 |
22034 extract32(ctx
->opcode
, 1, 10) << 1;
22035 uint32_t u
= extract32(ctx
->opcode
, 11, 7);
22037 gen_compute_imm_branch(ctx
, extract32(ctx
->opcode
, 18, 3),
22042 gen_reserved_instruction(ctx
);
22048 static int decode_nanomips_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
22051 int rt
= decode_gpr_gpr3(NANOMIPS_EXTRACT_RT3(ctx
->opcode
));
22052 int rs
= decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx
->opcode
));
22053 int rd
= decode_gpr_gpr3(NANOMIPS_EXTRACT_RD3(ctx
->opcode
));
22057 /* make sure instructions are on a halfword boundary */
22058 if (ctx
->base
.pc_next
& 0x1) {
22059 TCGv tmp
= tcg_const_tl(ctx
->base
.pc_next
);
22060 tcg_gen_st_tl(tmp
, cpu_env
, offsetof(CPUMIPSState
, CP0_BadVAddr
));
22061 tcg_temp_free(tmp
);
22062 generate_exception_end(ctx
, EXCP_AdEL
);
22066 op
= extract32(ctx
->opcode
, 10, 6);
22069 rt
= NANOMIPS_EXTRACT_RD5(ctx
->opcode
);
22072 rs
= NANOMIPS_EXTRACT_RS5(ctx
->opcode
);
22073 gen_arith(ctx
, OPC_ADDU
, rt
, rs
, 0);
22076 switch (extract32(ctx
->opcode
, 3, 2)) {
22077 case NM_P16_SYSCALL
:
22078 if (extract32(ctx
->opcode
, 2, 1) == 0) {
22079 generate_exception_end(ctx
, EXCP_SYSCALL
);
22081 gen_reserved_instruction(ctx
);
22085 generate_exception_end(ctx
, EXCP_BREAK
);
22088 if (is_uhi(extract32(ctx
->opcode
, 0, 3))) {
22089 gen_helper_do_semihosting(cpu_env
);
22091 if (ctx
->hflags
& MIPS_HFLAG_SBRI
) {
22092 gen_reserved_instruction(ctx
);
22094 generate_exception_end(ctx
, EXCP_DBp
);
22099 gen_reserved_instruction(ctx
);
22106 int shift
= extract32(ctx
->opcode
, 0, 3);
22108 shift
= (shift
== 0) ? 8 : shift
;
22110 switch (extract32(ctx
->opcode
, 3, 1)) {
22118 gen_shift_imm(ctx
, opc
, rt
, rs
, shift
);
22122 switch (ctx
->opcode
& 1) {
22124 gen_pool16c_nanomips_insn(ctx
);
22127 gen_ldxs(ctx
, rt
, rs
, rd
);
22132 switch (extract32(ctx
->opcode
, 6, 1)) {
22134 imm
= extract32(ctx
->opcode
, 0, 6) << 2;
22135 gen_arith_imm(ctx
, OPC_ADDIU
, rt
, 29, imm
);
22138 gen_reserved_instruction(ctx
);
22143 switch (extract32(ctx
->opcode
, 3, 1)) {
22145 imm
= extract32(ctx
->opcode
, 0, 3) << 2;
22146 gen_arith_imm(ctx
, OPC_ADDIU
, rt
, rs
, imm
);
22148 case NM_P_ADDIURS5
:
22149 rt
= extract32(ctx
->opcode
, 5, 5);
22151 /* imm = sign_extend(s[3] . s[2:0] , from_nbits = 4) */
22152 imm
= (sextract32(ctx
->opcode
, 4, 1) << 3) |
22153 (extract32(ctx
->opcode
, 0, 3));
22154 gen_arith_imm(ctx
, OPC_ADDIU
, rt
, rt
, imm
);
22160 switch (ctx
->opcode
& 0x1) {
22162 gen_arith(ctx
, OPC_ADDU
, rd
, rs
, rt
);
22165 gen_arith(ctx
, OPC_SUBU
, rd
, rs
, rt
);
22170 rt
= (extract32(ctx
->opcode
, 9, 1) << 3) |
22171 extract32(ctx
->opcode
, 5, 3);
22172 rs
= (extract32(ctx
->opcode
, 4, 1) << 3) |
22173 extract32(ctx
->opcode
, 0, 3);
22174 rt
= decode_gpr_gpr4(rt
);
22175 rs
= decode_gpr_gpr4(rs
);
22176 switch ((extract32(ctx
->opcode
, 7, 2) & 0x2) |
22177 (extract32(ctx
->opcode
, 3, 1))) {
22180 gen_arith(ctx
, OPC_ADDU
, rt
, rs
, rt
);
22184 gen_r6_muldiv(ctx
, R6_OPC_MUL
, rt
, rs
, rt
);
22187 gen_reserved_instruction(ctx
);
22193 int imm
= extract32(ctx
->opcode
, 0, 7);
22194 imm
= (imm
== 0x7f ? -1 : imm
);
22196 tcg_gen_movi_tl(cpu_gpr
[rt
], imm
);
22202 uint32_t u
= extract32(ctx
->opcode
, 0, 4);
22203 u
= (u
== 12) ? 0xff :
22204 (u
== 13) ? 0xffff : u
;
22205 gen_logic_imm(ctx
, OPC_ANDI
, rt
, rs
, u
);
22209 offset
= extract32(ctx
->opcode
, 0, 2);
22210 switch (extract32(ctx
->opcode
, 2, 2)) {
22212 gen_ld(ctx
, OPC_LB
, rt
, rs
, offset
);
22215 rt
= decode_gpr_gpr3_src_store(
22216 NANOMIPS_EXTRACT_RT3(ctx
->opcode
));
22217 gen_st(ctx
, OPC_SB
, rt
, rs
, offset
);
22220 gen_ld(ctx
, OPC_LBU
, rt
, rs
, offset
);
22223 gen_reserved_instruction(ctx
);
22228 offset
= extract32(ctx
->opcode
, 1, 2) << 1;
22229 switch ((extract32(ctx
->opcode
, 3, 1) << 1) | (ctx
->opcode
& 1)) {
22231 gen_ld(ctx
, OPC_LH
, rt
, rs
, offset
);
22234 rt
= decode_gpr_gpr3_src_store(
22235 NANOMIPS_EXTRACT_RT3(ctx
->opcode
));
22236 gen_st(ctx
, OPC_SH
, rt
, rs
, offset
);
22239 gen_ld(ctx
, OPC_LHU
, rt
, rs
, offset
);
22242 gen_reserved_instruction(ctx
);
22247 offset
= extract32(ctx
->opcode
, 0, 4) << 2;
22248 gen_ld(ctx
, OPC_LW
, rt
, rs
, offset
);
22251 rt
= NANOMIPS_EXTRACT_RD5(ctx
->opcode
);
22252 offset
= extract32(ctx
->opcode
, 0, 5) << 2;
22253 gen_ld(ctx
, OPC_LW
, rt
, 29, offset
);
22257 rt
= (extract32(ctx
->opcode
, 9, 1) << 3) |
22258 extract32(ctx
->opcode
, 5, 3);
22259 rs
= (extract32(ctx
->opcode
, 4, 1) << 3) |
22260 extract32(ctx
->opcode
, 0, 3);
22261 offset
= (extract32(ctx
->opcode
, 3, 1) << 3) |
22262 (extract32(ctx
->opcode
, 8, 1) << 2);
22263 rt
= decode_gpr_gpr4(rt
);
22264 rs
= decode_gpr_gpr4(rs
);
22265 gen_ld(ctx
, OPC_LW
, rt
, rs
, offset
);
22269 rt
= (extract32(ctx
->opcode
, 9, 1) << 3) |
22270 extract32(ctx
->opcode
, 5, 3);
22271 rs
= (extract32(ctx
->opcode
, 4, 1) << 3) |
22272 extract32(ctx
->opcode
, 0, 3);
22273 offset
= (extract32(ctx
->opcode
, 3, 1) << 3) |
22274 (extract32(ctx
->opcode
, 8, 1) << 2);
22275 rt
= decode_gpr_gpr4_zero(rt
);
22276 rs
= decode_gpr_gpr4(rs
);
22277 gen_st(ctx
, OPC_SW
, rt
, rs
, offset
);
22280 offset
= extract32(ctx
->opcode
, 0, 7) << 2;
22281 gen_ld(ctx
, OPC_LW
, rt
, 28, offset
);
22284 rt
= NANOMIPS_EXTRACT_RD5(ctx
->opcode
);
22285 offset
= extract32(ctx
->opcode
, 0, 5) << 2;
22286 gen_st(ctx
, OPC_SW
, rt
, 29, offset
);
22289 rt
= decode_gpr_gpr3_src_store(
22290 NANOMIPS_EXTRACT_RT3(ctx
->opcode
));
22291 rs
= decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx
->opcode
));
22292 offset
= extract32(ctx
->opcode
, 0, 4) << 2;
22293 gen_st(ctx
, OPC_SW
, rt
, rs
, offset
);
22296 rt
= decode_gpr_gpr3_src_store(
22297 NANOMIPS_EXTRACT_RT3(ctx
->opcode
));
22298 offset
= extract32(ctx
->opcode
, 0, 7) << 2;
22299 gen_st(ctx
, OPC_SW
, rt
, 28, offset
);
22302 gen_compute_branch_nm(ctx
, OPC_BEQ
, 2, 0, 0,
22303 (sextract32(ctx
->opcode
, 0, 1) << 10) |
22304 (extract32(ctx
->opcode
, 1, 9) << 1));
22307 gen_compute_branch_nm(ctx
, OPC_BGEZAL
, 2, 0, 0,
22308 (sextract32(ctx
->opcode
, 0, 1) << 10) |
22309 (extract32(ctx
->opcode
, 1, 9) << 1));
22312 gen_compute_branch_nm(ctx
, OPC_BEQ
, 2, rt
, 0,
22313 (sextract32(ctx
->opcode
, 0, 1) << 7) |
22314 (extract32(ctx
->opcode
, 1, 6) << 1));
22317 gen_compute_branch_nm(ctx
, OPC_BNE
, 2, rt
, 0,
22318 (sextract32(ctx
->opcode
, 0, 1) << 7) |
22319 (extract32(ctx
->opcode
, 1, 6) << 1));
22322 switch (ctx
->opcode
& 0xf) {
22325 switch (extract32(ctx
->opcode
, 4, 1)) {
22327 gen_compute_branch_nm(ctx
, OPC_JR
, 2,
22328 extract32(ctx
->opcode
, 5, 5), 0, 0);
22331 gen_compute_branch_nm(ctx
, OPC_JALR
, 2,
22332 extract32(ctx
->opcode
, 5, 5), 31, 0);
22339 uint32_t opc
= extract32(ctx
->opcode
, 4, 3) <
22340 extract32(ctx
->opcode
, 7, 3) ? OPC_BEQ
: OPC_BNE
;
22341 gen_compute_branch_nm(ctx
, opc
, 2, rs
, rt
,
22342 extract32(ctx
->opcode
, 0, 4) << 1);
22349 int count
= extract32(ctx
->opcode
, 0, 4);
22350 int u
= extract32(ctx
->opcode
, 4, 4) << 4;
22352 rt
= 30 + extract32(ctx
->opcode
, 9, 1);
22353 switch (extract32(ctx
->opcode
, 8, 1)) {
22355 gen_save(ctx
, rt
, count
, 0, u
);
22357 case NM_RESTORE_JRC16
:
22358 gen_restore(ctx
, rt
, count
, 0, u
);
22359 gen_compute_branch_nm(ctx
, OPC_JR
, 2, 31, 0, 0);
22368 static const int gpr2reg1
[] = {4, 5, 6, 7};
22369 static const int gpr2reg2
[] = {5, 6, 7, 8};
22371 int rd2
= extract32(ctx
->opcode
, 3, 1) << 1 |
22372 extract32(ctx
->opcode
, 8, 1);
22373 int r1
= gpr2reg1
[rd2
];
22374 int r2
= gpr2reg2
[rd2
];
22375 int r3
= extract32(ctx
->opcode
, 4, 1) << 3 |
22376 extract32(ctx
->opcode
, 0, 3);
22377 int r4
= extract32(ctx
->opcode
, 9, 1) << 3 |
22378 extract32(ctx
->opcode
, 5, 3);
22379 TCGv t0
= tcg_temp_new();
22380 TCGv t1
= tcg_temp_new();
22381 if (op
== NM_MOVEP
) {
22384 rs
= decode_gpr_gpr4_zero(r3
);
22385 rt
= decode_gpr_gpr4_zero(r4
);
22387 rd
= decode_gpr_gpr4(r3
);
22388 re
= decode_gpr_gpr4(r4
);
22392 gen_load_gpr(t0
, rs
);
22393 gen_load_gpr(t1
, rt
);
22394 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
22395 tcg_gen_mov_tl(cpu_gpr
[re
], t1
);
22401 return decode_nanomips_32_48_opc(env
, ctx
);
22408 /* SmartMIPS extension to MIPS32 */
22410 #if defined(TARGET_MIPS64)
22412 /* MDMX extension to MIPS64 */
22416 /* MIPSDSP functions. */
22417 static void gen_mipsdsp_ld(DisasContext
*ctx
, uint32_t opc
,
22418 int rd
, int base
, int offset
)
22423 t0
= tcg_temp_new();
22426 gen_load_gpr(t0
, offset
);
22427 } else if (offset
== 0) {
22428 gen_load_gpr(t0
, base
);
22430 gen_op_addr_add(ctx
, t0
, cpu_gpr
[base
], cpu_gpr
[offset
]);
22435 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_UB
);
22436 gen_store_gpr(t0
, rd
);
22439 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESW
);
22440 gen_store_gpr(t0
, rd
);
22443 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESL
);
22444 gen_store_gpr(t0
, rd
);
22446 #if defined(TARGET_MIPS64)
22448 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
);
22449 gen_store_gpr(t0
, rd
);
22456 static void gen_mipsdsp_arith(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
22457 int ret
, int v1
, int v2
)
22463 /* Treat as NOP. */
22467 v1_t
= tcg_temp_new();
22468 v2_t
= tcg_temp_new();
22470 gen_load_gpr(v1_t
, v1
);
22471 gen_load_gpr(v2_t
, v2
);
22474 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
22475 case OPC_MULT_G_2E
:
22479 gen_helper_adduh_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
22481 case OPC_ADDUH_R_QB
:
22482 gen_helper_adduh_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
22485 gen_helper_addqh_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
22487 case OPC_ADDQH_R_PH
:
22488 gen_helper_addqh_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
22491 gen_helper_addqh_w(cpu_gpr
[ret
], v1_t
, v2_t
);
22493 case OPC_ADDQH_R_W
:
22494 gen_helper_addqh_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
22497 gen_helper_subuh_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
22499 case OPC_SUBUH_R_QB
:
22500 gen_helper_subuh_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
22503 gen_helper_subqh_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
22505 case OPC_SUBQH_R_PH
:
22506 gen_helper_subqh_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
22509 gen_helper_subqh_w(cpu_gpr
[ret
], v1_t
, v2_t
);
22511 case OPC_SUBQH_R_W
:
22512 gen_helper_subqh_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
22516 case OPC_ABSQ_S_PH_DSP
:
22518 case OPC_ABSQ_S_QB
:
22520 gen_helper_absq_s_qb(cpu_gpr
[ret
], v2_t
, cpu_env
);
22522 case OPC_ABSQ_S_PH
:
22524 gen_helper_absq_s_ph(cpu_gpr
[ret
], v2_t
, cpu_env
);
22528 gen_helper_absq_s_w(cpu_gpr
[ret
], v2_t
, cpu_env
);
22530 case OPC_PRECEQ_W_PHL
:
22532 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0xFFFF0000);
22533 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
22535 case OPC_PRECEQ_W_PHR
:
22537 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0x0000FFFF);
22538 tcg_gen_shli_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], 16);
22539 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
22541 case OPC_PRECEQU_PH_QBL
:
22543 gen_helper_precequ_ph_qbl(cpu_gpr
[ret
], v2_t
);
22545 case OPC_PRECEQU_PH_QBR
:
22547 gen_helper_precequ_ph_qbr(cpu_gpr
[ret
], v2_t
);
22549 case OPC_PRECEQU_PH_QBLA
:
22551 gen_helper_precequ_ph_qbla(cpu_gpr
[ret
], v2_t
);
22553 case OPC_PRECEQU_PH_QBRA
:
22555 gen_helper_precequ_ph_qbra(cpu_gpr
[ret
], v2_t
);
22557 case OPC_PRECEU_PH_QBL
:
22559 gen_helper_preceu_ph_qbl(cpu_gpr
[ret
], v2_t
);
22561 case OPC_PRECEU_PH_QBR
:
22563 gen_helper_preceu_ph_qbr(cpu_gpr
[ret
], v2_t
);
22565 case OPC_PRECEU_PH_QBLA
:
22567 gen_helper_preceu_ph_qbla(cpu_gpr
[ret
], v2_t
);
22569 case OPC_PRECEU_PH_QBRA
:
22571 gen_helper_preceu_ph_qbra(cpu_gpr
[ret
], v2_t
);
22575 case OPC_ADDU_QB_DSP
:
22579 gen_helper_addq_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22581 case OPC_ADDQ_S_PH
:
22583 gen_helper_addq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22587 gen_helper_addq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22591 gen_helper_addu_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22593 case OPC_ADDU_S_QB
:
22595 gen_helper_addu_s_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22599 gen_helper_addu_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22601 case OPC_ADDU_S_PH
:
22603 gen_helper_addu_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22607 gen_helper_subq_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22609 case OPC_SUBQ_S_PH
:
22611 gen_helper_subq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22615 gen_helper_subq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22619 gen_helper_subu_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22621 case OPC_SUBU_S_QB
:
22623 gen_helper_subu_s_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22627 gen_helper_subu_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22629 case OPC_SUBU_S_PH
:
22631 gen_helper_subu_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22635 gen_helper_addsc(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22639 gen_helper_addwc(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22643 gen_helper_modsub(cpu_gpr
[ret
], v1_t
, v2_t
);
22645 case OPC_RADDU_W_QB
:
22647 gen_helper_raddu_w_qb(cpu_gpr
[ret
], v1_t
);
22651 case OPC_CMPU_EQ_QB_DSP
:
22653 case OPC_PRECR_QB_PH
:
22655 gen_helper_precr_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
22657 case OPC_PRECRQ_QB_PH
:
22659 gen_helper_precrq_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
22661 case OPC_PRECR_SRA_PH_W
:
22664 TCGv_i32 sa_t
= tcg_const_i32(v2
);
22665 gen_helper_precr_sra_ph_w(cpu_gpr
[ret
], sa_t
, v1_t
,
22667 tcg_temp_free_i32(sa_t
);
22670 case OPC_PRECR_SRA_R_PH_W
:
22673 TCGv_i32 sa_t
= tcg_const_i32(v2
);
22674 gen_helper_precr_sra_r_ph_w(cpu_gpr
[ret
], sa_t
, v1_t
,
22676 tcg_temp_free_i32(sa_t
);
22679 case OPC_PRECRQ_PH_W
:
22681 gen_helper_precrq_ph_w(cpu_gpr
[ret
], v1_t
, v2_t
);
22683 case OPC_PRECRQ_RS_PH_W
:
22685 gen_helper_precrq_rs_ph_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22687 case OPC_PRECRQU_S_QB_PH
:
22689 gen_helper_precrqu_s_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22693 #ifdef TARGET_MIPS64
22694 case OPC_ABSQ_S_QH_DSP
:
22696 case OPC_PRECEQ_L_PWL
:
22698 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0xFFFFFFFF00000000ull
);
22700 case OPC_PRECEQ_L_PWR
:
22702 tcg_gen_shli_tl(cpu_gpr
[ret
], v2_t
, 32);
22704 case OPC_PRECEQ_PW_QHL
:
22706 gen_helper_preceq_pw_qhl(cpu_gpr
[ret
], v2_t
);
22708 case OPC_PRECEQ_PW_QHR
:
22710 gen_helper_preceq_pw_qhr(cpu_gpr
[ret
], v2_t
);
22712 case OPC_PRECEQ_PW_QHLA
:
22714 gen_helper_preceq_pw_qhla(cpu_gpr
[ret
], v2_t
);
22716 case OPC_PRECEQ_PW_QHRA
:
22718 gen_helper_preceq_pw_qhra(cpu_gpr
[ret
], v2_t
);
22720 case OPC_PRECEQU_QH_OBL
:
22722 gen_helper_precequ_qh_obl(cpu_gpr
[ret
], v2_t
);
22724 case OPC_PRECEQU_QH_OBR
:
22726 gen_helper_precequ_qh_obr(cpu_gpr
[ret
], v2_t
);
22728 case OPC_PRECEQU_QH_OBLA
:
22730 gen_helper_precequ_qh_obla(cpu_gpr
[ret
], v2_t
);
22732 case OPC_PRECEQU_QH_OBRA
:
22734 gen_helper_precequ_qh_obra(cpu_gpr
[ret
], v2_t
);
22736 case OPC_PRECEU_QH_OBL
:
22738 gen_helper_preceu_qh_obl(cpu_gpr
[ret
], v2_t
);
22740 case OPC_PRECEU_QH_OBR
:
22742 gen_helper_preceu_qh_obr(cpu_gpr
[ret
], v2_t
);
22744 case OPC_PRECEU_QH_OBLA
:
22746 gen_helper_preceu_qh_obla(cpu_gpr
[ret
], v2_t
);
22748 case OPC_PRECEU_QH_OBRA
:
22750 gen_helper_preceu_qh_obra(cpu_gpr
[ret
], v2_t
);
22752 case OPC_ABSQ_S_OB
:
22754 gen_helper_absq_s_ob(cpu_gpr
[ret
], v2_t
, cpu_env
);
22756 case OPC_ABSQ_S_PW
:
22758 gen_helper_absq_s_pw(cpu_gpr
[ret
], v2_t
, cpu_env
);
22760 case OPC_ABSQ_S_QH
:
22762 gen_helper_absq_s_qh(cpu_gpr
[ret
], v2_t
, cpu_env
);
22766 case OPC_ADDU_OB_DSP
:
22768 case OPC_RADDU_L_OB
:
22770 gen_helper_raddu_l_ob(cpu_gpr
[ret
], v1_t
);
22774 gen_helper_subq_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22776 case OPC_SUBQ_S_PW
:
22778 gen_helper_subq_s_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22782 gen_helper_subq_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22784 case OPC_SUBQ_S_QH
:
22786 gen_helper_subq_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22790 gen_helper_subu_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22792 case OPC_SUBU_S_OB
:
22794 gen_helper_subu_s_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22798 gen_helper_subu_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22800 case OPC_SUBU_S_QH
:
22802 gen_helper_subu_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22806 gen_helper_subuh_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
22808 case OPC_SUBUH_R_OB
:
22810 gen_helper_subuh_r_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
22814 gen_helper_addq_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22816 case OPC_ADDQ_S_PW
:
22818 gen_helper_addq_s_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22822 gen_helper_addq_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22824 case OPC_ADDQ_S_QH
:
22826 gen_helper_addq_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22830 gen_helper_addu_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22832 case OPC_ADDU_S_OB
:
22834 gen_helper_addu_s_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22838 gen_helper_addu_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22840 case OPC_ADDU_S_QH
:
22842 gen_helper_addu_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22846 gen_helper_adduh_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
22848 case OPC_ADDUH_R_OB
:
22850 gen_helper_adduh_r_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
22854 case OPC_CMPU_EQ_OB_DSP
:
22856 case OPC_PRECR_OB_QH
:
22858 gen_helper_precr_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
);
22860 case OPC_PRECR_SRA_QH_PW
:
22863 TCGv_i32 ret_t
= tcg_const_i32(ret
);
22864 gen_helper_precr_sra_qh_pw(v2_t
, v1_t
, v2_t
, ret_t
);
22865 tcg_temp_free_i32(ret_t
);
22868 case OPC_PRECR_SRA_R_QH_PW
:
22871 TCGv_i32 sa_v
= tcg_const_i32(ret
);
22872 gen_helper_precr_sra_r_qh_pw(v2_t
, v1_t
, v2_t
, sa_v
);
22873 tcg_temp_free_i32(sa_v
);
22876 case OPC_PRECRQ_OB_QH
:
22878 gen_helper_precrq_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
);
22880 case OPC_PRECRQ_PW_L
:
22882 gen_helper_precrq_pw_l(cpu_gpr
[ret
], v1_t
, v2_t
);
22884 case OPC_PRECRQ_QH_PW
:
22886 gen_helper_precrq_qh_pw(cpu_gpr
[ret
], v1_t
, v2_t
);
22888 case OPC_PRECRQ_RS_QH_PW
:
22890 gen_helper_precrq_rs_qh_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22892 case OPC_PRECRQU_S_OB_QH
:
22894 gen_helper_precrqu_s_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22901 tcg_temp_free(v1_t
);
22902 tcg_temp_free(v2_t
);
22905 static void gen_mipsdsp_shift(DisasContext
*ctx
, uint32_t opc
,
22906 int ret
, int v1
, int v2
)
22914 /* Treat as NOP. */
22918 t0
= tcg_temp_new();
22919 v1_t
= tcg_temp_new();
22920 v2_t
= tcg_temp_new();
22922 tcg_gen_movi_tl(t0
, v1
);
22923 gen_load_gpr(v1_t
, v1
);
22924 gen_load_gpr(v2_t
, v2
);
22927 case OPC_SHLL_QB_DSP
:
22929 op2
= MASK_SHLL_QB(ctx
->opcode
);
22933 gen_helper_shll_qb(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
22937 gen_helper_shll_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22941 gen_helper_shll_ph(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
22945 gen_helper_shll_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22947 case OPC_SHLL_S_PH
:
22949 gen_helper_shll_s_ph(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
22951 case OPC_SHLLV_S_PH
:
22953 gen_helper_shll_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22957 gen_helper_shll_s_w(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
22959 case OPC_SHLLV_S_W
:
22961 gen_helper_shll_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22965 gen_helper_shrl_qb(cpu_gpr
[ret
], t0
, v2_t
);
22969 gen_helper_shrl_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
22973 gen_helper_shrl_ph(cpu_gpr
[ret
], t0
, v2_t
);
22977 gen_helper_shrl_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
22981 gen_helper_shra_qb(cpu_gpr
[ret
], t0
, v2_t
);
22983 case OPC_SHRA_R_QB
:
22985 gen_helper_shra_r_qb(cpu_gpr
[ret
], t0
, v2_t
);
22989 gen_helper_shra_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
22991 case OPC_SHRAV_R_QB
:
22993 gen_helper_shra_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
22997 gen_helper_shra_ph(cpu_gpr
[ret
], t0
, v2_t
);
22999 case OPC_SHRA_R_PH
:
23001 gen_helper_shra_r_ph(cpu_gpr
[ret
], t0
, v2_t
);
23005 gen_helper_shra_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
23007 case OPC_SHRAV_R_PH
:
23009 gen_helper_shra_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
23013 gen_helper_shra_r_w(cpu_gpr
[ret
], t0
, v2_t
);
23015 case OPC_SHRAV_R_W
:
23017 gen_helper_shra_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
23019 default: /* Invalid */
23020 MIPS_INVAL("MASK SHLL.QB");
23021 gen_reserved_instruction(ctx
);
23026 #ifdef TARGET_MIPS64
23027 case OPC_SHLL_OB_DSP
:
23028 op2
= MASK_SHLL_OB(ctx
->opcode
);
23032 gen_helper_shll_pw(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
23036 gen_helper_shll_pw(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
23038 case OPC_SHLL_S_PW
:
23040 gen_helper_shll_s_pw(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
23042 case OPC_SHLLV_S_PW
:
23044 gen_helper_shll_s_pw(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
23048 gen_helper_shll_ob(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
23052 gen_helper_shll_ob(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
23056 gen_helper_shll_qh(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
23060 gen_helper_shll_qh(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
23062 case OPC_SHLL_S_QH
:
23064 gen_helper_shll_s_qh(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
23066 case OPC_SHLLV_S_QH
:
23068 gen_helper_shll_s_qh(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
23072 gen_helper_shra_ob(cpu_gpr
[ret
], v2_t
, t0
);
23076 gen_helper_shra_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
23078 case OPC_SHRA_R_OB
:
23080 gen_helper_shra_r_ob(cpu_gpr
[ret
], v2_t
, t0
);
23082 case OPC_SHRAV_R_OB
:
23084 gen_helper_shra_r_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
23088 gen_helper_shra_pw(cpu_gpr
[ret
], v2_t
, t0
);
23092 gen_helper_shra_pw(cpu_gpr
[ret
], v2_t
, v1_t
);
23094 case OPC_SHRA_R_PW
:
23096 gen_helper_shra_r_pw(cpu_gpr
[ret
], v2_t
, t0
);
23098 case OPC_SHRAV_R_PW
:
23100 gen_helper_shra_r_pw(cpu_gpr
[ret
], v2_t
, v1_t
);
23104 gen_helper_shra_qh(cpu_gpr
[ret
], v2_t
, t0
);
23108 gen_helper_shra_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
23110 case OPC_SHRA_R_QH
:
23112 gen_helper_shra_r_qh(cpu_gpr
[ret
], v2_t
, t0
);
23114 case OPC_SHRAV_R_QH
:
23116 gen_helper_shra_r_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
23120 gen_helper_shrl_ob(cpu_gpr
[ret
], v2_t
, t0
);
23124 gen_helper_shrl_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
23128 gen_helper_shrl_qh(cpu_gpr
[ret
], v2_t
, t0
);
23132 gen_helper_shrl_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
23134 default: /* Invalid */
23135 MIPS_INVAL("MASK SHLL.OB");
23136 gen_reserved_instruction(ctx
);
23144 tcg_temp_free(v1_t
);
23145 tcg_temp_free(v2_t
);
23148 static void gen_mipsdsp_multiply(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
23149 int ret
, int v1
, int v2
, int check_ret
)
23155 if ((ret
== 0) && (check_ret
== 1)) {
23156 /* Treat as NOP. */
23160 t0
= tcg_temp_new_i32();
23161 v1_t
= tcg_temp_new();
23162 v2_t
= tcg_temp_new();
23164 tcg_gen_movi_i32(t0
, ret
);
23165 gen_load_gpr(v1_t
, v1
);
23166 gen_load_gpr(v2_t
, v2
);
23170 * OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
23171 * the same mask and op1.
23173 case OPC_MULT_G_2E
:
23177 gen_helper_mul_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23180 gen_helper_mul_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23183 gen_helper_mulq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23185 case OPC_MULQ_RS_W
:
23186 gen_helper_mulq_rs_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23190 case OPC_DPA_W_PH_DSP
:
23192 case OPC_DPAU_H_QBL
:
23194 gen_helper_dpau_h_qbl(t0
, v1_t
, v2_t
, cpu_env
);
23196 case OPC_DPAU_H_QBR
:
23198 gen_helper_dpau_h_qbr(t0
, v1_t
, v2_t
, cpu_env
);
23200 case OPC_DPSU_H_QBL
:
23202 gen_helper_dpsu_h_qbl(t0
, v1_t
, v2_t
, cpu_env
);
23204 case OPC_DPSU_H_QBR
:
23206 gen_helper_dpsu_h_qbr(t0
, v1_t
, v2_t
, cpu_env
);
23210 gen_helper_dpa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23212 case OPC_DPAX_W_PH
:
23214 gen_helper_dpax_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23216 case OPC_DPAQ_S_W_PH
:
23218 gen_helper_dpaq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23220 case OPC_DPAQX_S_W_PH
:
23222 gen_helper_dpaqx_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23224 case OPC_DPAQX_SA_W_PH
:
23226 gen_helper_dpaqx_sa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23230 gen_helper_dps_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23232 case OPC_DPSX_W_PH
:
23234 gen_helper_dpsx_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23236 case OPC_DPSQ_S_W_PH
:
23238 gen_helper_dpsq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23240 case OPC_DPSQX_S_W_PH
:
23242 gen_helper_dpsqx_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23244 case OPC_DPSQX_SA_W_PH
:
23246 gen_helper_dpsqx_sa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23248 case OPC_MULSAQ_S_W_PH
:
23250 gen_helper_mulsaq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23252 case OPC_DPAQ_SA_L_W
:
23254 gen_helper_dpaq_sa_l_w(t0
, v1_t
, v2_t
, cpu_env
);
23256 case OPC_DPSQ_SA_L_W
:
23258 gen_helper_dpsq_sa_l_w(t0
, v1_t
, v2_t
, cpu_env
);
23260 case OPC_MAQ_S_W_PHL
:
23262 gen_helper_maq_s_w_phl(t0
, v1_t
, v2_t
, cpu_env
);
23264 case OPC_MAQ_S_W_PHR
:
23266 gen_helper_maq_s_w_phr(t0
, v1_t
, v2_t
, cpu_env
);
23268 case OPC_MAQ_SA_W_PHL
:
23270 gen_helper_maq_sa_w_phl(t0
, v1_t
, v2_t
, cpu_env
);
23272 case OPC_MAQ_SA_W_PHR
:
23274 gen_helper_maq_sa_w_phr(t0
, v1_t
, v2_t
, cpu_env
);
23276 case OPC_MULSA_W_PH
:
23278 gen_helper_mulsa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23282 #ifdef TARGET_MIPS64
23283 case OPC_DPAQ_W_QH_DSP
:
23285 int ac
= ret
& 0x03;
23286 tcg_gen_movi_i32(t0
, ac
);
23291 gen_helper_dmadd(v1_t
, v2_t
, t0
, cpu_env
);
23295 gen_helper_dmaddu(v1_t
, v2_t
, t0
, cpu_env
);
23299 gen_helper_dmsub(v1_t
, v2_t
, t0
, cpu_env
);
23303 gen_helper_dmsubu(v1_t
, v2_t
, t0
, cpu_env
);
23307 gen_helper_dpa_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
23309 case OPC_DPAQ_S_W_QH
:
23311 gen_helper_dpaq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
23313 case OPC_DPAQ_SA_L_PW
:
23315 gen_helper_dpaq_sa_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
23317 case OPC_DPAU_H_OBL
:
23319 gen_helper_dpau_h_obl(v1_t
, v2_t
, t0
, cpu_env
);
23321 case OPC_DPAU_H_OBR
:
23323 gen_helper_dpau_h_obr(v1_t
, v2_t
, t0
, cpu_env
);
23327 gen_helper_dps_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
23329 case OPC_DPSQ_S_W_QH
:
23331 gen_helper_dpsq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
23333 case OPC_DPSQ_SA_L_PW
:
23335 gen_helper_dpsq_sa_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
23337 case OPC_DPSU_H_OBL
:
23339 gen_helper_dpsu_h_obl(v1_t
, v2_t
, t0
, cpu_env
);
23341 case OPC_DPSU_H_OBR
:
23343 gen_helper_dpsu_h_obr(v1_t
, v2_t
, t0
, cpu_env
);
23345 case OPC_MAQ_S_L_PWL
:
23347 gen_helper_maq_s_l_pwl(v1_t
, v2_t
, t0
, cpu_env
);
23349 case OPC_MAQ_S_L_PWR
:
23351 gen_helper_maq_s_l_pwr(v1_t
, v2_t
, t0
, cpu_env
);
23353 case OPC_MAQ_S_W_QHLL
:
23355 gen_helper_maq_s_w_qhll(v1_t
, v2_t
, t0
, cpu_env
);
23357 case OPC_MAQ_SA_W_QHLL
:
23359 gen_helper_maq_sa_w_qhll(v1_t
, v2_t
, t0
, cpu_env
);
23361 case OPC_MAQ_S_W_QHLR
:
23363 gen_helper_maq_s_w_qhlr(v1_t
, v2_t
, t0
, cpu_env
);
23365 case OPC_MAQ_SA_W_QHLR
:
23367 gen_helper_maq_sa_w_qhlr(v1_t
, v2_t
, t0
, cpu_env
);
23369 case OPC_MAQ_S_W_QHRL
:
23371 gen_helper_maq_s_w_qhrl(v1_t
, v2_t
, t0
, cpu_env
);
23373 case OPC_MAQ_SA_W_QHRL
:
23375 gen_helper_maq_sa_w_qhrl(v1_t
, v2_t
, t0
, cpu_env
);
23377 case OPC_MAQ_S_W_QHRR
:
23379 gen_helper_maq_s_w_qhrr(v1_t
, v2_t
, t0
, cpu_env
);
23381 case OPC_MAQ_SA_W_QHRR
:
23383 gen_helper_maq_sa_w_qhrr(v1_t
, v2_t
, t0
, cpu_env
);
23385 case OPC_MULSAQ_S_L_PW
:
23387 gen_helper_mulsaq_s_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
23389 case OPC_MULSAQ_S_W_QH
:
23391 gen_helper_mulsaq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
23397 case OPC_ADDU_QB_DSP
:
23399 case OPC_MULEU_S_PH_QBL
:
23401 gen_helper_muleu_s_ph_qbl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23403 case OPC_MULEU_S_PH_QBR
:
23405 gen_helper_muleu_s_ph_qbr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23407 case OPC_MULQ_RS_PH
:
23409 gen_helper_mulq_rs_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23411 case OPC_MULEQ_S_W_PHL
:
23413 gen_helper_muleq_s_w_phl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23415 case OPC_MULEQ_S_W_PHR
:
23417 gen_helper_muleq_s_w_phr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23419 case OPC_MULQ_S_PH
:
23421 gen_helper_mulq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23425 #ifdef TARGET_MIPS64
23426 case OPC_ADDU_OB_DSP
:
23428 case OPC_MULEQ_S_PW_QHL
:
23430 gen_helper_muleq_s_pw_qhl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23432 case OPC_MULEQ_S_PW_QHR
:
23434 gen_helper_muleq_s_pw_qhr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23436 case OPC_MULEU_S_QH_OBL
:
23438 gen_helper_muleu_s_qh_obl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23440 case OPC_MULEU_S_QH_OBR
:
23442 gen_helper_muleu_s_qh_obr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23444 case OPC_MULQ_RS_QH
:
23446 gen_helper_mulq_rs_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23453 tcg_temp_free_i32(t0
);
23454 tcg_temp_free(v1_t
);
23455 tcg_temp_free(v2_t
);
23458 static void gen_mipsdsp_bitinsn(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
23466 /* Treat as NOP. */
23470 t0
= tcg_temp_new();
23471 val_t
= tcg_temp_new();
23472 gen_load_gpr(val_t
, val
);
23475 case OPC_ABSQ_S_PH_DSP
:
23479 gen_helper_bitrev(cpu_gpr
[ret
], val_t
);
23484 target_long result
;
23485 imm
= (ctx
->opcode
>> 16) & 0xFF;
23486 result
= (uint32_t)imm
<< 24 |
23487 (uint32_t)imm
<< 16 |
23488 (uint32_t)imm
<< 8 |
23490 result
= (int32_t)result
;
23491 tcg_gen_movi_tl(cpu_gpr
[ret
], result
);
23496 tcg_gen_ext8u_tl(cpu_gpr
[ret
], val_t
);
23497 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 8);
23498 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
23499 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
23500 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
23501 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
23506 imm
= (ctx
->opcode
>> 16) & 0x03FF;
23507 imm
= (int16_t)(imm
<< 6) >> 6;
23508 tcg_gen_movi_tl(cpu_gpr
[ret
], \
23509 (target_long
)((int32_t)imm
<< 16 | \
23515 tcg_gen_ext16u_tl(cpu_gpr
[ret
], val_t
);
23516 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
23517 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
23518 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
23522 #ifdef TARGET_MIPS64
23523 case OPC_ABSQ_S_QH_DSP
:
23530 imm
= (ctx
->opcode
>> 16) & 0xFF;
23531 temp
= ((uint64_t)imm
<< 8) | (uint64_t)imm
;
23532 temp
= (temp
<< 16) | temp
;
23533 temp
= (temp
<< 32) | temp
;
23534 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
23542 imm
= (ctx
->opcode
>> 16) & 0x03FF;
23543 imm
= (int16_t)(imm
<< 6) >> 6;
23544 temp
= ((target_long
)imm
<< 32) \
23545 | ((target_long
)imm
& 0xFFFFFFFF);
23546 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
23554 imm
= (ctx
->opcode
>> 16) & 0x03FF;
23555 imm
= (int16_t)(imm
<< 6) >> 6;
23557 temp
= ((uint64_t)(uint16_t)imm
<< 48) |
23558 ((uint64_t)(uint16_t)imm
<< 32) |
23559 ((uint64_t)(uint16_t)imm
<< 16) |
23560 (uint64_t)(uint16_t)imm
;
23561 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
23566 tcg_gen_ext8u_tl(cpu_gpr
[ret
], val_t
);
23567 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 8);
23568 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
23569 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
23570 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
23571 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
23572 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
23576 tcg_gen_ext32u_i64(cpu_gpr
[ret
], val_t
);
23577 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
23578 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
23582 tcg_gen_ext16u_tl(cpu_gpr
[ret
], val_t
);
23583 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
23584 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
23585 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
23586 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
23593 tcg_temp_free(val_t
);
23596 static void gen_mipsdsp_add_cmp_pick(DisasContext
*ctx
,
23597 uint32_t op1
, uint32_t op2
,
23598 int ret
, int v1
, int v2
, int check_ret
)
23604 if ((ret
== 0) && (check_ret
== 1)) {
23605 /* Treat as NOP. */
23609 t1
= tcg_temp_new();
23610 v1_t
= tcg_temp_new();
23611 v2_t
= tcg_temp_new();
23613 gen_load_gpr(v1_t
, v1
);
23614 gen_load_gpr(v2_t
, v2
);
23617 case OPC_CMPU_EQ_QB_DSP
:
23619 case OPC_CMPU_EQ_QB
:
23621 gen_helper_cmpu_eq_qb(v1_t
, v2_t
, cpu_env
);
23623 case OPC_CMPU_LT_QB
:
23625 gen_helper_cmpu_lt_qb(v1_t
, v2_t
, cpu_env
);
23627 case OPC_CMPU_LE_QB
:
23629 gen_helper_cmpu_le_qb(v1_t
, v2_t
, cpu_env
);
23631 case OPC_CMPGU_EQ_QB
:
23633 gen_helper_cmpgu_eq_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
23635 case OPC_CMPGU_LT_QB
:
23637 gen_helper_cmpgu_lt_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
23639 case OPC_CMPGU_LE_QB
:
23641 gen_helper_cmpgu_le_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
23643 case OPC_CMPGDU_EQ_QB
:
23645 gen_helper_cmpgu_eq_qb(t1
, v1_t
, v2_t
);
23646 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
23647 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
23648 tcg_gen_shli_tl(t1
, t1
, 24);
23649 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
23651 case OPC_CMPGDU_LT_QB
:
23653 gen_helper_cmpgu_lt_qb(t1
, v1_t
, v2_t
);
23654 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
23655 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
23656 tcg_gen_shli_tl(t1
, t1
, 24);
23657 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
23659 case OPC_CMPGDU_LE_QB
:
23661 gen_helper_cmpgu_le_qb(t1
, v1_t
, v2_t
);
23662 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
23663 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
23664 tcg_gen_shli_tl(t1
, t1
, 24);
23665 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
23667 case OPC_CMP_EQ_PH
:
23669 gen_helper_cmp_eq_ph(v1_t
, v2_t
, cpu_env
);
23671 case OPC_CMP_LT_PH
:
23673 gen_helper_cmp_lt_ph(v1_t
, v2_t
, cpu_env
);
23675 case OPC_CMP_LE_PH
:
23677 gen_helper_cmp_le_ph(v1_t
, v2_t
, cpu_env
);
23681 gen_helper_pick_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23685 gen_helper_pick_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23687 case OPC_PACKRL_PH
:
23689 gen_helper_packrl_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
23693 #ifdef TARGET_MIPS64
23694 case OPC_CMPU_EQ_OB_DSP
:
23696 case OPC_CMP_EQ_PW
:
23698 gen_helper_cmp_eq_pw(v1_t
, v2_t
, cpu_env
);
23700 case OPC_CMP_LT_PW
:
23702 gen_helper_cmp_lt_pw(v1_t
, v2_t
, cpu_env
);
23704 case OPC_CMP_LE_PW
:
23706 gen_helper_cmp_le_pw(v1_t
, v2_t
, cpu_env
);
23708 case OPC_CMP_EQ_QH
:
23710 gen_helper_cmp_eq_qh(v1_t
, v2_t
, cpu_env
);
23712 case OPC_CMP_LT_QH
:
23714 gen_helper_cmp_lt_qh(v1_t
, v2_t
, cpu_env
);
23716 case OPC_CMP_LE_QH
:
23718 gen_helper_cmp_le_qh(v1_t
, v2_t
, cpu_env
);
23720 case OPC_CMPGDU_EQ_OB
:
23722 gen_helper_cmpgdu_eq_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23724 case OPC_CMPGDU_LT_OB
:
23726 gen_helper_cmpgdu_lt_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23728 case OPC_CMPGDU_LE_OB
:
23730 gen_helper_cmpgdu_le_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23732 case OPC_CMPGU_EQ_OB
:
23734 gen_helper_cmpgu_eq_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
23736 case OPC_CMPGU_LT_OB
:
23738 gen_helper_cmpgu_lt_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
23740 case OPC_CMPGU_LE_OB
:
23742 gen_helper_cmpgu_le_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
23744 case OPC_CMPU_EQ_OB
:
23746 gen_helper_cmpu_eq_ob(v1_t
, v2_t
, cpu_env
);
23748 case OPC_CMPU_LT_OB
:
23750 gen_helper_cmpu_lt_ob(v1_t
, v2_t
, cpu_env
);
23752 case OPC_CMPU_LE_OB
:
23754 gen_helper_cmpu_le_ob(v1_t
, v2_t
, cpu_env
);
23756 case OPC_PACKRL_PW
:
23758 gen_helper_packrl_pw(cpu_gpr
[ret
], v1_t
, v2_t
);
23762 gen_helper_pick_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23766 gen_helper_pick_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23770 gen_helper_pick_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23778 tcg_temp_free(v1_t
);
23779 tcg_temp_free(v2_t
);
23782 static void gen_mipsdsp_append(CPUMIPSState
*env
, DisasContext
*ctx
,
23783 uint32_t op1
, int rt
, int rs
, int sa
)
23790 /* Treat as NOP. */
23794 t0
= tcg_temp_new();
23795 gen_load_gpr(t0
, rs
);
23798 case OPC_APPEND_DSP
:
23799 switch (MASK_APPEND(ctx
->opcode
)) {
23802 tcg_gen_deposit_tl(cpu_gpr
[rt
], t0
, cpu_gpr
[rt
], sa
, 32 - sa
);
23804 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
23808 tcg_gen_ext32u_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
23809 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], sa
);
23810 tcg_gen_shli_tl(t0
, t0
, 32 - sa
);
23811 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
23813 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
23817 if (sa
!= 0 && sa
!= 2) {
23818 tcg_gen_shli_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 8 * sa
);
23819 tcg_gen_ext32u_tl(t0
, t0
);
23820 tcg_gen_shri_tl(t0
, t0
, 8 * (4 - sa
));
23821 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
23823 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
23825 default: /* Invalid */
23826 MIPS_INVAL("MASK APPEND");
23827 gen_reserved_instruction(ctx
);
23831 #ifdef TARGET_MIPS64
23832 case OPC_DAPPEND_DSP
:
23833 switch (MASK_DAPPEND(ctx
->opcode
)) {
23836 tcg_gen_deposit_tl(cpu_gpr
[rt
], t0
, cpu_gpr
[rt
], sa
, 64 - sa
);
23840 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 0x20 | sa
);
23841 tcg_gen_shli_tl(t0
, t0
, 64 - (0x20 | sa
));
23842 tcg_gen_or_tl(cpu_gpr
[rt
], t0
, t0
);
23846 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], sa
);
23847 tcg_gen_shli_tl(t0
, t0
, 64 - sa
);
23848 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
23853 if (sa
!= 0 && sa
!= 2 && sa
!= 4) {
23854 tcg_gen_shli_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 8 * sa
);
23855 tcg_gen_shri_tl(t0
, t0
, 8 * (8 - sa
));
23856 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
23859 default: /* Invalid */
23860 MIPS_INVAL("MASK DAPPEND");
23861 gen_reserved_instruction(ctx
);
23870 static void gen_mipsdsp_accinsn(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
23871 int ret
, int v1
, int v2
, int check_ret
)
23880 if ((ret
== 0) && (check_ret
== 1)) {
23881 /* Treat as NOP. */
23885 t0
= tcg_temp_new();
23886 t1
= tcg_temp_new();
23887 v1_t
= tcg_temp_new();
23888 v2_t
= tcg_temp_new();
23890 gen_load_gpr(v1_t
, v1
);
23891 gen_load_gpr(v2_t
, v2
);
23894 case OPC_EXTR_W_DSP
:
23898 tcg_gen_movi_tl(t0
, v2
);
23899 tcg_gen_movi_tl(t1
, v1
);
23900 gen_helper_extr_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23903 tcg_gen_movi_tl(t0
, v2
);
23904 tcg_gen_movi_tl(t1
, v1
);
23905 gen_helper_extr_r_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23907 case OPC_EXTR_RS_W
:
23908 tcg_gen_movi_tl(t0
, v2
);
23909 tcg_gen_movi_tl(t1
, v1
);
23910 gen_helper_extr_rs_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23913 tcg_gen_movi_tl(t0
, v2
);
23914 tcg_gen_movi_tl(t1
, v1
);
23915 gen_helper_extr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23917 case OPC_EXTRV_S_H
:
23918 tcg_gen_movi_tl(t0
, v2
);
23919 gen_helper_extr_s_h(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
23922 tcg_gen_movi_tl(t0
, v2
);
23923 gen_helper_extr_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
23925 case OPC_EXTRV_R_W
:
23926 tcg_gen_movi_tl(t0
, v2
);
23927 gen_helper_extr_r_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
23929 case OPC_EXTRV_RS_W
:
23930 tcg_gen_movi_tl(t0
, v2
);
23931 gen_helper_extr_rs_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
23934 tcg_gen_movi_tl(t0
, v2
);
23935 tcg_gen_movi_tl(t1
, v1
);
23936 gen_helper_extp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23939 tcg_gen_movi_tl(t0
, v2
);
23940 gen_helper_extp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
23943 tcg_gen_movi_tl(t0
, v2
);
23944 tcg_gen_movi_tl(t1
, v1
);
23945 gen_helper_extpdp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23948 tcg_gen_movi_tl(t0
, v2
);
23949 gen_helper_extpdp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
23952 imm
= (ctx
->opcode
>> 20) & 0x3F;
23953 tcg_gen_movi_tl(t0
, ret
);
23954 tcg_gen_movi_tl(t1
, imm
);
23955 gen_helper_shilo(t0
, t1
, cpu_env
);
23958 tcg_gen_movi_tl(t0
, ret
);
23959 gen_helper_shilo(t0
, v1_t
, cpu_env
);
23962 tcg_gen_movi_tl(t0
, ret
);
23963 gen_helper_mthlip(t0
, v1_t
, cpu_env
);
23966 imm
= (ctx
->opcode
>> 11) & 0x3FF;
23967 tcg_gen_movi_tl(t0
, imm
);
23968 gen_helper_wrdsp(v1_t
, t0
, cpu_env
);
23971 imm
= (ctx
->opcode
>> 16) & 0x03FF;
23972 tcg_gen_movi_tl(t0
, imm
);
23973 gen_helper_rddsp(cpu_gpr
[ret
], t0
, cpu_env
);
23977 #ifdef TARGET_MIPS64
23978 case OPC_DEXTR_W_DSP
:
23982 tcg_gen_movi_tl(t0
, ret
);
23983 gen_helper_dmthlip(v1_t
, t0
, cpu_env
);
23987 int shift
= (ctx
->opcode
>> 19) & 0x7F;
23988 int ac
= (ctx
->opcode
>> 11) & 0x03;
23989 tcg_gen_movi_tl(t0
, shift
);
23990 tcg_gen_movi_tl(t1
, ac
);
23991 gen_helper_dshilo(t0
, t1
, cpu_env
);
23996 int ac
= (ctx
->opcode
>> 11) & 0x03;
23997 tcg_gen_movi_tl(t0
, ac
);
23998 gen_helper_dshilo(v1_t
, t0
, cpu_env
);
24002 tcg_gen_movi_tl(t0
, v2
);
24003 tcg_gen_movi_tl(t1
, v1
);
24005 gen_helper_dextp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24008 tcg_gen_movi_tl(t0
, v2
);
24009 gen_helper_dextp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24012 tcg_gen_movi_tl(t0
, v2
);
24013 tcg_gen_movi_tl(t1
, v1
);
24014 gen_helper_dextpdp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24017 tcg_gen_movi_tl(t0
, v2
);
24018 gen_helper_dextpdp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24021 tcg_gen_movi_tl(t0
, v2
);
24022 tcg_gen_movi_tl(t1
, v1
);
24023 gen_helper_dextr_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24025 case OPC_DEXTR_R_L
:
24026 tcg_gen_movi_tl(t0
, v2
);
24027 tcg_gen_movi_tl(t1
, v1
);
24028 gen_helper_dextr_r_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24030 case OPC_DEXTR_RS_L
:
24031 tcg_gen_movi_tl(t0
, v2
);
24032 tcg_gen_movi_tl(t1
, v1
);
24033 gen_helper_dextr_rs_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24036 tcg_gen_movi_tl(t0
, v2
);
24037 tcg_gen_movi_tl(t1
, v1
);
24038 gen_helper_dextr_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24040 case OPC_DEXTR_R_W
:
24041 tcg_gen_movi_tl(t0
, v2
);
24042 tcg_gen_movi_tl(t1
, v1
);
24043 gen_helper_dextr_r_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24045 case OPC_DEXTR_RS_W
:
24046 tcg_gen_movi_tl(t0
, v2
);
24047 tcg_gen_movi_tl(t1
, v1
);
24048 gen_helper_dextr_rs_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24050 case OPC_DEXTR_S_H
:
24051 tcg_gen_movi_tl(t0
, v2
);
24052 tcg_gen_movi_tl(t1
, v1
);
24053 gen_helper_dextr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24055 case OPC_DEXTRV_S_H
:
24056 tcg_gen_movi_tl(t0
, v2
);
24057 tcg_gen_movi_tl(t1
, v1
);
24058 gen_helper_dextr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24061 tcg_gen_movi_tl(t0
, v2
);
24062 gen_helper_dextr_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24064 case OPC_DEXTRV_R_L
:
24065 tcg_gen_movi_tl(t0
, v2
);
24066 gen_helper_dextr_r_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24068 case OPC_DEXTRV_RS_L
:
24069 tcg_gen_movi_tl(t0
, v2
);
24070 gen_helper_dextr_rs_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24073 tcg_gen_movi_tl(t0
, v2
);
24074 gen_helper_dextr_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24076 case OPC_DEXTRV_R_W
:
24077 tcg_gen_movi_tl(t0
, v2
);
24078 gen_helper_dextr_r_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24080 case OPC_DEXTRV_RS_W
:
24081 tcg_gen_movi_tl(t0
, v2
);
24082 gen_helper_dextr_rs_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24091 tcg_temp_free(v1_t
);
24092 tcg_temp_free(v2_t
);
24095 /* End MIPSDSP functions. */
24097 static void decode_opc_special_r6(CPUMIPSState
*env
, DisasContext
*ctx
)
24099 int rs
, rt
, rd
, sa
;
24102 rs
= (ctx
->opcode
>> 21) & 0x1f;
24103 rt
= (ctx
->opcode
>> 16) & 0x1f;
24104 rd
= (ctx
->opcode
>> 11) & 0x1f;
24105 sa
= (ctx
->opcode
>> 6) & 0x1f;
24107 op1
= MASK_SPECIAL(ctx
->opcode
);
24113 op2
= MASK_R6_MULDIV(ctx
->opcode
);
24123 gen_r6_muldiv(ctx
, op2
, rd
, rs
, rt
);
24126 MIPS_INVAL("special_r6 muldiv");
24127 gen_reserved_instruction(ctx
);
24133 gen_cond_move(ctx
, op1
, rd
, rs
, rt
);
24137 if (rt
== 0 && sa
== 1) {
24139 * Major opcode and function field is shared with preR6 MFHI/MTHI.
24140 * We need additionally to check other fields.
24142 gen_cl(ctx
, op1
, rd
, rs
);
24144 gen_reserved_instruction(ctx
);
24148 if (is_uhi(extract32(ctx
->opcode
, 6, 20))) {
24149 gen_helper_do_semihosting(cpu_env
);
24151 if (ctx
->hflags
& MIPS_HFLAG_SBRI
) {
24152 gen_reserved_instruction(ctx
);
24154 generate_exception_end(ctx
, EXCP_DBp
);
24158 #if defined(TARGET_MIPS64)
24161 if (rt
== 0 && sa
== 1) {
24163 * Major opcode and function field is shared with preR6 MFHI/MTHI.
24164 * We need additionally to check other fields.
24166 check_mips_64(ctx
);
24167 gen_cl(ctx
, op1
, rd
, rs
);
24169 gen_reserved_instruction(ctx
);
24177 op2
= MASK_R6_MULDIV(ctx
->opcode
);
24187 check_mips_64(ctx
);
24188 gen_r6_muldiv(ctx
, op2
, rd
, rs
, rt
);
24191 MIPS_INVAL("special_r6 muldiv");
24192 gen_reserved_instruction(ctx
);
24197 default: /* Invalid */
24198 MIPS_INVAL("special_r6");
24199 gen_reserved_instruction(ctx
);
24204 static void decode_opc_special_tx79(CPUMIPSState
*env
, DisasContext
*ctx
)
24206 int rs
= extract32(ctx
->opcode
, 21, 5);
24207 int rt
= extract32(ctx
->opcode
, 16, 5);
24208 int rd
= extract32(ctx
->opcode
, 11, 5);
24209 uint32_t op1
= MASK_SPECIAL(ctx
->opcode
);
24212 case OPC_MOVN
: /* Conditional move */
24214 gen_cond_move(ctx
, op1
, rd
, rs
, rt
);
24216 case OPC_MFHI
: /* Move from HI/LO */
24218 gen_HILO(ctx
, op1
, 0, rd
);
24221 case OPC_MTLO
: /* Move to HI/LO */
24222 gen_HILO(ctx
, op1
, 0, rs
);
24226 gen_mul_txx9(ctx
, op1
, rd
, rs
, rt
);
24230 gen_muldiv(ctx
, op1
, 0, rs
, rt
);
24232 #if defined(TARGET_MIPS64)
24237 check_insn_opc_user_only(ctx
, INSN_R5900
);
24238 gen_muldiv(ctx
, op1
, 0, rs
, rt
);
24242 gen_compute_branch(ctx
, op1
, 4, rs
, 0, 0, 4);
24244 default: /* Invalid */
24245 MIPS_INVAL("special_tx79");
24246 gen_reserved_instruction(ctx
);
24251 static void decode_opc_special_legacy(CPUMIPSState
*env
, DisasContext
*ctx
)
24253 int rs
, rt
, rd
, sa
;
24256 rs
= (ctx
->opcode
>> 21) & 0x1f;
24257 rt
= (ctx
->opcode
>> 16) & 0x1f;
24258 rd
= (ctx
->opcode
>> 11) & 0x1f;
24259 sa
= (ctx
->opcode
>> 6) & 0x1f;
24261 op1
= MASK_SPECIAL(ctx
->opcode
);
24263 case OPC_MOVN
: /* Conditional move */
24265 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS_R1
|
24266 INSN_LOONGSON2E
| INSN_LOONGSON2F
);
24267 gen_cond_move(ctx
, op1
, rd
, rs
, rt
);
24269 case OPC_MFHI
: /* Move from HI/LO */
24271 gen_HILO(ctx
, op1
, rs
& 3, rd
);
24274 case OPC_MTLO
: /* Move to HI/LO */
24275 gen_HILO(ctx
, op1
, rd
& 3, rs
);
24278 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS_R1
);
24279 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
24280 check_cp1_enabled(ctx
);
24281 gen_movci(ctx
, rd
, rs
, (ctx
->opcode
>> 18) & 0x7,
24282 (ctx
->opcode
>> 16) & 1);
24284 generate_exception_err(ctx
, EXCP_CpU
, 1);
24290 check_insn(ctx
, INSN_VR54XX
);
24291 op1
= MASK_MUL_VR54XX(ctx
->opcode
);
24292 gen_mul_vr54xx(ctx
, op1
, rd
, rs
, rt
);
24294 gen_muldiv(ctx
, op1
, rd
& 3, rs
, rt
);
24299 gen_muldiv(ctx
, op1
, 0, rs
, rt
);
24301 #if defined(TARGET_MIPS64)
24306 check_insn(ctx
, ISA_MIPS3
);
24307 check_mips_64(ctx
);
24308 gen_muldiv(ctx
, op1
, 0, rs
, rt
);
24312 gen_compute_branch(ctx
, op1
, 4, rs
, rd
, sa
, 4);
24315 #ifdef MIPS_STRICT_STANDARD
24316 MIPS_INVAL("SPIM");
24317 gen_reserved_instruction(ctx
);
24319 /* Implemented as RI exception for now. */
24320 MIPS_INVAL("spim (unofficial)");
24321 gen_reserved_instruction(ctx
);
24324 default: /* Invalid */
24325 MIPS_INVAL("special_legacy");
24326 gen_reserved_instruction(ctx
);
24331 static void decode_opc_special(CPUMIPSState
*env
, DisasContext
*ctx
)
24333 int rs
, rt
, rd
, sa
;
24336 rs
= (ctx
->opcode
>> 21) & 0x1f;
24337 rt
= (ctx
->opcode
>> 16) & 0x1f;
24338 rd
= (ctx
->opcode
>> 11) & 0x1f;
24339 sa
= (ctx
->opcode
>> 6) & 0x1f;
24341 op1
= MASK_SPECIAL(ctx
->opcode
);
24343 case OPC_SLL
: /* Shift with immediate */
24344 if (sa
== 5 && rd
== 0 &&
24345 rs
== 0 && rt
== 0) { /* PAUSE */
24346 if ((ctx
->insn_flags
& ISA_MIPS_R6
) &&
24347 (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
24348 gen_reserved_instruction(ctx
);
24354 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
24357 switch ((ctx
->opcode
>> 21) & 0x1f) {
24359 /* rotr is decoded as srl on non-R2 CPUs */
24360 if (ctx
->insn_flags
& ISA_MIPS_R2
) {
24365 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
24368 gen_reserved_instruction(ctx
);
24376 gen_arith(ctx
, op1
, rd
, rs
, rt
);
24378 case OPC_SLLV
: /* Shifts */
24380 gen_shift(ctx
, op1
, rd
, rs
, rt
);
24383 switch ((ctx
->opcode
>> 6) & 0x1f) {
24385 /* rotrv is decoded as srlv on non-R2 CPUs */
24386 if (ctx
->insn_flags
& ISA_MIPS_R2
) {
24391 gen_shift(ctx
, op1
, rd
, rs
, rt
);
24394 gen_reserved_instruction(ctx
);
24398 case OPC_SLT
: /* Set on less than */
24400 gen_slt(ctx
, op1
, rd
, rs
, rt
);
24402 case OPC_AND
: /* Logic*/
24406 gen_logic(ctx
, op1
, rd
, rs
, rt
);
24409 gen_compute_branch(ctx
, op1
, 4, rs
, rd
, sa
, 4);
24411 case OPC_TGE
: /* Traps */
24417 check_insn(ctx
, ISA_MIPS2
);
24418 gen_trap(ctx
, op1
, rs
, rt
, -1);
24421 /* Pmon entry point, also R4010 selsl */
24422 #ifdef MIPS_STRICT_STANDARD
24423 MIPS_INVAL("PMON / selsl");
24424 gen_reserved_instruction(ctx
);
24426 gen_helper_0e0i(pmon
, sa
);
24430 generate_exception_end(ctx
, EXCP_SYSCALL
);
24433 generate_exception_end(ctx
, EXCP_BREAK
);
24436 check_insn(ctx
, ISA_MIPS2
);
24437 gen_sync(extract32(ctx
->opcode
, 6, 5));
24440 #if defined(TARGET_MIPS64)
24441 /* MIPS64 specific opcodes */
24446 check_insn(ctx
, ISA_MIPS3
);
24447 check_mips_64(ctx
);
24448 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
24451 switch ((ctx
->opcode
>> 21) & 0x1f) {
24453 /* drotr is decoded as dsrl on non-R2 CPUs */
24454 if (ctx
->insn_flags
& ISA_MIPS_R2
) {
24459 check_insn(ctx
, ISA_MIPS3
);
24460 check_mips_64(ctx
);
24461 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
24464 gen_reserved_instruction(ctx
);
24469 switch ((ctx
->opcode
>> 21) & 0x1f) {
24471 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
24472 if (ctx
->insn_flags
& ISA_MIPS_R2
) {
24477 check_insn(ctx
, ISA_MIPS3
);
24478 check_mips_64(ctx
);
24479 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
24482 gen_reserved_instruction(ctx
);
24490 check_insn(ctx
, ISA_MIPS3
);
24491 check_mips_64(ctx
);
24492 gen_arith(ctx
, op1
, rd
, rs
, rt
);
24496 check_insn(ctx
, ISA_MIPS3
);
24497 check_mips_64(ctx
);
24498 gen_shift(ctx
, op1
, rd
, rs
, rt
);
24501 switch ((ctx
->opcode
>> 6) & 0x1f) {
24503 /* drotrv is decoded as dsrlv on non-R2 CPUs */
24504 if (ctx
->insn_flags
& ISA_MIPS_R2
) {
24509 check_insn(ctx
, ISA_MIPS3
);
24510 check_mips_64(ctx
);
24511 gen_shift(ctx
, op1
, rd
, rs
, rt
);
24514 gen_reserved_instruction(ctx
);
24520 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
24521 decode_opc_special_r6(env
, ctx
);
24522 } else if (ctx
->insn_flags
& INSN_R5900
) {
24523 decode_opc_special_tx79(env
, ctx
);
24525 decode_opc_special_legacy(env
, ctx
);
24531 #if defined(TARGET_MIPS64)
24535 * MMI (MultiMedia Interface) ASE instructions
24536 * ===========================================
24540 * MMI instructions category: data communication
24541 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
24543 * PCPYH PEXCH PEXTLB PINTH PPACB PEXT5 PREVH
24544 * PCPYLD PEXCW PEXTLH PINTEH PPACH PPAC5 PROT3W
24545 * PCPYUD PEXEH PEXTLW PPACW
24554 * Parallel Copy Halfword
24556 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
24557 * +-----------+---------+---------+---------+---------+-----------+
24558 * | MMI |0 0 0 0 0| rt | rd | PCPYH | MMI3 |
24559 * +-----------+---------+---------+---------+---------+-----------+
24561 static void gen_mmi_pcpyh(DisasContext
*ctx
)
24563 uint32_t pd
, rt
, rd
;
24566 opcode
= ctx
->opcode
;
24568 pd
= extract32(opcode
, 21, 5);
24569 rt
= extract32(opcode
, 16, 5);
24570 rd
= extract32(opcode
, 11, 5);
24572 if (unlikely(pd
!= 0)) {
24573 gen_reserved_instruction(ctx
);
24574 } else if (rd
== 0) {
24576 } else if (rt
== 0) {
24577 tcg_gen_movi_i64(cpu_gpr
[rd
], 0);
24578 tcg_gen_movi_i64(cpu_gpr_hi
[rd
], 0);
24580 TCGv_i64 t0
= tcg_temp_new();
24581 TCGv_i64 t1
= tcg_temp_new();
24582 uint64_t mask
= (1ULL << 16) - 1;
24584 tcg_gen_andi_i64(t0
, cpu_gpr
[rt
], mask
);
24585 tcg_gen_movi_i64(t1
, 0);
24586 tcg_gen_or_i64(t1
, t0
, t1
);
24587 tcg_gen_shli_i64(t0
, t0
, 16);
24588 tcg_gen_or_i64(t1
, t0
, t1
);
24589 tcg_gen_shli_i64(t0
, t0
, 16);
24590 tcg_gen_or_i64(t1
, t0
, t1
);
24591 tcg_gen_shli_i64(t0
, t0
, 16);
24592 tcg_gen_or_i64(t1
, t0
, t1
);
24594 tcg_gen_mov_i64(cpu_gpr
[rd
], t1
);
24596 tcg_gen_andi_i64(t0
, cpu_gpr_hi
[rt
], mask
);
24597 tcg_gen_movi_i64(t1
, 0);
24598 tcg_gen_or_i64(t1
, t0
, t1
);
24599 tcg_gen_shli_i64(t0
, t0
, 16);
24600 tcg_gen_or_i64(t1
, t0
, t1
);
24601 tcg_gen_shli_i64(t0
, t0
, 16);
24602 tcg_gen_or_i64(t1
, t0
, t1
);
24603 tcg_gen_shli_i64(t0
, t0
, 16);
24604 tcg_gen_or_i64(t1
, t0
, t1
);
24606 tcg_gen_mov_i64(cpu_gpr_hi
[rd
], t1
);
24614 * PCPYLD rd, rs, rt
24616 * Parallel Copy Lower Doubleword
24618 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
24619 * +-----------+---------+---------+---------+---------+-----------+
24620 * | MMI | rs | rt | rd | PCPYLD | MMI2 |
24621 * +-----------+---------+---------+---------+---------+-----------+
24623 static void gen_mmi_pcpyld(DisasContext
*ctx
)
24625 uint32_t rs
, rt
, rd
;
24628 opcode
= ctx
->opcode
;
24630 rs
= extract32(opcode
, 21, 5);
24631 rt
= extract32(opcode
, 16, 5);
24632 rd
= extract32(opcode
, 11, 5);
24638 tcg_gen_movi_i64(cpu_gpr_hi
[rd
], 0);
24640 tcg_gen_mov_i64(cpu_gpr_hi
[rd
], cpu_gpr
[rs
]);
24643 tcg_gen_movi_i64(cpu_gpr
[rd
], 0);
24646 tcg_gen_mov_i64(cpu_gpr
[rd
], cpu_gpr
[rt
]);
24653 * PCPYUD rd, rs, rt
24655 * Parallel Copy Upper Doubleword
24657 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
24658 * +-----------+---------+---------+---------+---------+-----------+
24659 * | MMI | rs | rt | rd | PCPYUD | MMI3 |
24660 * +-----------+---------+---------+---------+---------+-----------+
24662 static void gen_mmi_pcpyud(DisasContext
*ctx
)
24664 uint32_t rs
, rt
, rd
;
24667 opcode
= ctx
->opcode
;
24669 rs
= extract32(opcode
, 21, 5);
24670 rt
= extract32(opcode
, 16, 5);
24671 rd
= extract32(opcode
, 11, 5);
24677 tcg_gen_movi_i64(cpu_gpr
[rd
], 0);
24679 tcg_gen_mov_i64(cpu_gpr
[rd
], cpu_gpr_hi
[rs
]);
24682 tcg_gen_movi_i64(cpu_gpr_hi
[rd
], 0);
24685 tcg_gen_mov_i64(cpu_gpr_hi
[rd
], cpu_gpr_hi
[rt
]);
24694 #if !defined(TARGET_MIPS64)
24696 /* MXU accumulate add/subtract 1-bit pattern 'aptn1' */
24697 #define MXU_APTN1_A 0
24698 #define MXU_APTN1_S 1
24700 /* MXU accumulate add/subtract 2-bit pattern 'aptn2' */
24701 #define MXU_APTN2_AA 0
24702 #define MXU_APTN2_AS 1
24703 #define MXU_APTN2_SA 2
24704 #define MXU_APTN2_SS 3
24706 /* MXU execute add/subtract 2-bit pattern 'eptn2' */
24707 #define MXU_EPTN2_AA 0
24708 #define MXU_EPTN2_AS 1
24709 #define MXU_EPTN2_SA 2
24710 #define MXU_EPTN2_SS 3
24712 /* MXU operand getting pattern 'optn2' */
24713 #define MXU_OPTN2_PTN0 0
24714 #define MXU_OPTN2_PTN1 1
24715 #define MXU_OPTN2_PTN2 2
24716 #define MXU_OPTN2_PTN3 3
24717 /* alternative naming scheme for 'optn2' */
24718 #define MXU_OPTN2_WW 0
24719 #define MXU_OPTN2_LW 1
24720 #define MXU_OPTN2_HW 2
24721 #define MXU_OPTN2_XW 3
24723 /* MXU operand getting pattern 'optn3' */
24724 #define MXU_OPTN3_PTN0 0
24725 #define MXU_OPTN3_PTN1 1
24726 #define MXU_OPTN3_PTN2 2
24727 #define MXU_OPTN3_PTN3 3
24728 #define MXU_OPTN3_PTN4 4
24729 #define MXU_OPTN3_PTN5 5
24730 #define MXU_OPTN3_PTN6 6
24731 #define MXU_OPTN3_PTN7 7
24735 * S32I2M XRa, rb - Register move from GRF to XRF
24737 static void gen_mxu_s32i2m(DisasContext
*ctx
)
24742 t0
= tcg_temp_new();
24744 XRa
= extract32(ctx
->opcode
, 6, 5);
24745 Rb
= extract32(ctx
->opcode
, 16, 5);
24747 gen_load_gpr(t0
, Rb
);
24749 gen_store_mxu_gpr(t0
, XRa
);
24750 } else if (XRa
== 16) {
24751 gen_store_mxu_cr(t0
);
24758 * S32M2I XRa, rb - Register move from XRF to GRF
24760 static void gen_mxu_s32m2i(DisasContext
*ctx
)
24765 t0
= tcg_temp_new();
24767 XRa
= extract32(ctx
->opcode
, 6, 5);
24768 Rb
= extract32(ctx
->opcode
, 16, 5);
24771 gen_load_mxu_gpr(t0
, XRa
);
24772 } else if (XRa
== 16) {
24773 gen_load_mxu_cr(t0
);
24776 gen_store_gpr(t0
, Rb
);
24782 * S8LDD XRa, Rb, s8, optn3 - Load a byte from memory to XRF
24784 static void gen_mxu_s8ldd(DisasContext
*ctx
)
24787 uint32_t XRa
, Rb
, s8
, optn3
;
24789 t0
= tcg_temp_new();
24790 t1
= tcg_temp_new();
24792 XRa
= extract32(ctx
->opcode
, 6, 4);
24793 s8
= extract32(ctx
->opcode
, 10, 8);
24794 optn3
= extract32(ctx
->opcode
, 18, 3);
24795 Rb
= extract32(ctx
->opcode
, 21, 5);
24797 gen_load_gpr(t0
, Rb
);
24798 tcg_gen_addi_tl(t0
, t0
, (int8_t)s8
);
24801 /* XRa[7:0] = tmp8 */
24802 case MXU_OPTN3_PTN0
:
24803 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
24804 gen_load_mxu_gpr(t0
, XRa
);
24805 tcg_gen_deposit_tl(t0
, t0
, t1
, 0, 8);
24807 /* XRa[15:8] = tmp8 */
24808 case MXU_OPTN3_PTN1
:
24809 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
24810 gen_load_mxu_gpr(t0
, XRa
);
24811 tcg_gen_deposit_tl(t0
, t0
, t1
, 8, 8);
24813 /* XRa[23:16] = tmp8 */
24814 case MXU_OPTN3_PTN2
:
24815 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
24816 gen_load_mxu_gpr(t0
, XRa
);
24817 tcg_gen_deposit_tl(t0
, t0
, t1
, 16, 8);
24819 /* XRa[31:24] = tmp8 */
24820 case MXU_OPTN3_PTN3
:
24821 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
24822 gen_load_mxu_gpr(t0
, XRa
);
24823 tcg_gen_deposit_tl(t0
, t0
, t1
, 24, 8);
24825 /* XRa = {8'b0, tmp8, 8'b0, tmp8} */
24826 case MXU_OPTN3_PTN4
:
24827 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
24828 tcg_gen_deposit_tl(t0
, t1
, t1
, 16, 16);
24830 /* XRa = {tmp8, 8'b0, tmp8, 8'b0} */
24831 case MXU_OPTN3_PTN5
:
24832 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
24833 tcg_gen_shli_tl(t1
, t1
, 8);
24834 tcg_gen_deposit_tl(t0
, t1
, t1
, 16, 16);
24836 /* XRa = {{8{sign of tmp8}}, tmp8, {8{sign of tmp8}}, tmp8} */
24837 case MXU_OPTN3_PTN6
:
24838 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_SB
);
24839 tcg_gen_mov_tl(t0
, t1
);
24840 tcg_gen_andi_tl(t0
, t0
, 0xFF00FFFF);
24841 tcg_gen_shli_tl(t1
, t1
, 16);
24842 tcg_gen_or_tl(t0
, t0
, t1
);
24844 /* XRa = {tmp8, tmp8, tmp8, tmp8} */
24845 case MXU_OPTN3_PTN7
:
24846 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
24847 tcg_gen_deposit_tl(t1
, t1
, t1
, 8, 8);
24848 tcg_gen_deposit_tl(t0
, t1
, t1
, 16, 16);
24852 gen_store_mxu_gpr(t0
, XRa
);
24859 * D16MUL XRa, XRb, XRc, XRd, optn2 - Signed 16 bit pattern multiplication
24861 static void gen_mxu_d16mul(DisasContext
*ctx
)
24863 TCGv t0
, t1
, t2
, t3
;
24864 uint32_t XRa
, XRb
, XRc
, XRd
, optn2
;
24866 t0
= tcg_temp_new();
24867 t1
= tcg_temp_new();
24868 t2
= tcg_temp_new();
24869 t3
= tcg_temp_new();
24871 XRa
= extract32(ctx
->opcode
, 6, 4);
24872 XRb
= extract32(ctx
->opcode
, 10, 4);
24873 XRc
= extract32(ctx
->opcode
, 14, 4);
24874 XRd
= extract32(ctx
->opcode
, 18, 4);
24875 optn2
= extract32(ctx
->opcode
, 22, 2);
24877 gen_load_mxu_gpr(t1
, XRb
);
24878 tcg_gen_sextract_tl(t0
, t1
, 0, 16);
24879 tcg_gen_sextract_tl(t1
, t1
, 16, 16);
24880 gen_load_mxu_gpr(t3
, XRc
);
24881 tcg_gen_sextract_tl(t2
, t3
, 0, 16);
24882 tcg_gen_sextract_tl(t3
, t3
, 16, 16);
24885 case MXU_OPTN2_WW
: /* XRB.H*XRC.H == lop, XRB.L*XRC.L == rop */
24886 tcg_gen_mul_tl(t3
, t1
, t3
);
24887 tcg_gen_mul_tl(t2
, t0
, t2
);
24889 case MXU_OPTN2_LW
: /* XRB.L*XRC.H == lop, XRB.L*XRC.L == rop */
24890 tcg_gen_mul_tl(t3
, t0
, t3
);
24891 tcg_gen_mul_tl(t2
, t0
, t2
);
24893 case MXU_OPTN2_HW
: /* XRB.H*XRC.H == lop, XRB.H*XRC.L == rop */
24894 tcg_gen_mul_tl(t3
, t1
, t3
);
24895 tcg_gen_mul_tl(t2
, t1
, t2
);
24897 case MXU_OPTN2_XW
: /* XRB.L*XRC.H == lop, XRB.H*XRC.L == rop */
24898 tcg_gen_mul_tl(t3
, t0
, t3
);
24899 tcg_gen_mul_tl(t2
, t1
, t2
);
24902 gen_store_mxu_gpr(t3
, XRa
);
24903 gen_store_mxu_gpr(t2
, XRd
);
24912 * D16MAC XRa, XRb, XRc, XRd, aptn2, optn2 - Signed 16 bit pattern multiply
24915 static void gen_mxu_d16mac(DisasContext
*ctx
)
24917 TCGv t0
, t1
, t2
, t3
;
24918 uint32_t XRa
, XRb
, XRc
, XRd
, optn2
, aptn2
;
24920 t0
= tcg_temp_new();
24921 t1
= tcg_temp_new();
24922 t2
= tcg_temp_new();
24923 t3
= tcg_temp_new();
24925 XRa
= extract32(ctx
->opcode
, 6, 4);
24926 XRb
= extract32(ctx
->opcode
, 10, 4);
24927 XRc
= extract32(ctx
->opcode
, 14, 4);
24928 XRd
= extract32(ctx
->opcode
, 18, 4);
24929 optn2
= extract32(ctx
->opcode
, 22, 2);
24930 aptn2
= extract32(ctx
->opcode
, 24, 2);
24932 gen_load_mxu_gpr(t1
, XRb
);
24933 tcg_gen_sextract_tl(t0
, t1
, 0, 16);
24934 tcg_gen_sextract_tl(t1
, t1
, 16, 16);
24936 gen_load_mxu_gpr(t3
, XRc
);
24937 tcg_gen_sextract_tl(t2
, t3
, 0, 16);
24938 tcg_gen_sextract_tl(t3
, t3
, 16, 16);
24941 case MXU_OPTN2_WW
: /* XRB.H*XRC.H == lop, XRB.L*XRC.L == rop */
24942 tcg_gen_mul_tl(t3
, t1
, t3
);
24943 tcg_gen_mul_tl(t2
, t0
, t2
);
24945 case MXU_OPTN2_LW
: /* XRB.L*XRC.H == lop, XRB.L*XRC.L == rop */
24946 tcg_gen_mul_tl(t3
, t0
, t3
);
24947 tcg_gen_mul_tl(t2
, t0
, t2
);
24949 case MXU_OPTN2_HW
: /* XRB.H*XRC.H == lop, XRB.H*XRC.L == rop */
24950 tcg_gen_mul_tl(t3
, t1
, t3
);
24951 tcg_gen_mul_tl(t2
, t1
, t2
);
24953 case MXU_OPTN2_XW
: /* XRB.L*XRC.H == lop, XRB.H*XRC.L == rop */
24954 tcg_gen_mul_tl(t3
, t0
, t3
);
24955 tcg_gen_mul_tl(t2
, t1
, t2
);
24958 gen_load_mxu_gpr(t0
, XRa
);
24959 gen_load_mxu_gpr(t1
, XRd
);
24963 tcg_gen_add_tl(t3
, t0
, t3
);
24964 tcg_gen_add_tl(t2
, t1
, t2
);
24967 tcg_gen_add_tl(t3
, t0
, t3
);
24968 tcg_gen_sub_tl(t2
, t1
, t2
);
24971 tcg_gen_sub_tl(t3
, t0
, t3
);
24972 tcg_gen_add_tl(t2
, t1
, t2
);
24975 tcg_gen_sub_tl(t3
, t0
, t3
);
24976 tcg_gen_sub_tl(t2
, t1
, t2
);
24979 gen_store_mxu_gpr(t3
, XRa
);
24980 gen_store_mxu_gpr(t2
, XRd
);
24989 * Q8MUL XRa, XRb, XRc, XRd - Parallel unsigned 8 bit pattern multiply
24990 * Q8MULSU XRa, XRb, XRc, XRd - Parallel signed 8 bit pattern multiply
24992 static void gen_mxu_q8mul_q8mulsu(DisasContext
*ctx
)
24994 TCGv t0
, t1
, t2
, t3
, t4
, t5
, t6
, t7
;
24995 uint32_t XRa
, XRb
, XRc
, XRd
, sel
;
24997 t0
= tcg_temp_new();
24998 t1
= tcg_temp_new();
24999 t2
= tcg_temp_new();
25000 t3
= tcg_temp_new();
25001 t4
= tcg_temp_new();
25002 t5
= tcg_temp_new();
25003 t6
= tcg_temp_new();
25004 t7
= tcg_temp_new();
25006 XRa
= extract32(ctx
->opcode
, 6, 4);
25007 XRb
= extract32(ctx
->opcode
, 10, 4);
25008 XRc
= extract32(ctx
->opcode
, 14, 4);
25009 XRd
= extract32(ctx
->opcode
, 18, 4);
25010 sel
= extract32(ctx
->opcode
, 22, 2);
25012 gen_load_mxu_gpr(t3
, XRb
);
25013 gen_load_mxu_gpr(t7
, XRc
);
25017 tcg_gen_ext8s_tl(t0
, t3
);
25018 tcg_gen_shri_tl(t3
, t3
, 8);
25019 tcg_gen_ext8s_tl(t1
, t3
);
25020 tcg_gen_shri_tl(t3
, t3
, 8);
25021 tcg_gen_ext8s_tl(t2
, t3
);
25022 tcg_gen_shri_tl(t3
, t3
, 8);
25023 tcg_gen_ext8s_tl(t3
, t3
);
25026 tcg_gen_ext8u_tl(t0
, t3
);
25027 tcg_gen_shri_tl(t3
, t3
, 8);
25028 tcg_gen_ext8u_tl(t1
, t3
);
25029 tcg_gen_shri_tl(t3
, t3
, 8);
25030 tcg_gen_ext8u_tl(t2
, t3
);
25031 tcg_gen_shri_tl(t3
, t3
, 8);
25032 tcg_gen_ext8u_tl(t3
, t3
);
25035 tcg_gen_ext8u_tl(t4
, t7
);
25036 tcg_gen_shri_tl(t7
, t7
, 8);
25037 tcg_gen_ext8u_tl(t5
, t7
);
25038 tcg_gen_shri_tl(t7
, t7
, 8);
25039 tcg_gen_ext8u_tl(t6
, t7
);
25040 tcg_gen_shri_tl(t7
, t7
, 8);
25041 tcg_gen_ext8u_tl(t7
, t7
);
25043 tcg_gen_mul_tl(t0
, t0
, t4
);
25044 tcg_gen_mul_tl(t1
, t1
, t5
);
25045 tcg_gen_mul_tl(t2
, t2
, t6
);
25046 tcg_gen_mul_tl(t3
, t3
, t7
);
25048 tcg_gen_andi_tl(t0
, t0
, 0xFFFF);
25049 tcg_gen_andi_tl(t1
, t1
, 0xFFFF);
25050 tcg_gen_andi_tl(t2
, t2
, 0xFFFF);
25051 tcg_gen_andi_tl(t3
, t3
, 0xFFFF);
25053 tcg_gen_shli_tl(t1
, t1
, 16);
25054 tcg_gen_shli_tl(t3
, t3
, 16);
25056 tcg_gen_or_tl(t0
, t0
, t1
);
25057 tcg_gen_or_tl(t1
, t2
, t3
);
25059 gen_store_mxu_gpr(t0
, XRd
);
25060 gen_store_mxu_gpr(t1
, XRa
);
25073 * S32LDD XRa, Rb, S12 - Load a word from memory to XRF
25074 * S32LDDR XRa, Rb, S12 - Load a word from memory to XRF, reversed byte seq.
25076 static void gen_mxu_s32ldd_s32lddr(DisasContext
*ctx
)
25079 uint32_t XRa
, Rb
, s12
, sel
;
25081 t0
= tcg_temp_new();
25082 t1
= tcg_temp_new();
25084 XRa
= extract32(ctx
->opcode
, 6, 4);
25085 s12
= extract32(ctx
->opcode
, 10, 10);
25086 sel
= extract32(ctx
->opcode
, 20, 1);
25087 Rb
= extract32(ctx
->opcode
, 21, 5);
25089 gen_load_gpr(t0
, Rb
);
25091 tcg_gen_movi_tl(t1
, s12
);
25092 tcg_gen_shli_tl(t1
, t1
, 2);
25094 tcg_gen_ori_tl(t1
, t1
, 0xFFFFF000);
25096 tcg_gen_add_tl(t1
, t0
, t1
);
25097 tcg_gen_qemu_ld_tl(t1
, t1
, ctx
->mem_idx
, MO_SL
);
25101 tcg_gen_bswap32_tl(t1
, t1
);
25103 gen_store_mxu_gpr(t1
, XRa
);
25111 * MXU instruction category: logic
25112 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
25114 * S32NOR S32AND S32OR S32XOR
25118 * S32NOR XRa, XRb, XRc
25119 * Update XRa with the result of logical bitwise 'nor' operation
25120 * applied to the content of XRb and XRc.
25122 static void gen_mxu_S32NOR(DisasContext
*ctx
)
25124 uint32_t pad
, XRc
, XRb
, XRa
;
25126 pad
= extract32(ctx
->opcode
, 21, 5);
25127 XRc
= extract32(ctx
->opcode
, 14, 4);
25128 XRb
= extract32(ctx
->opcode
, 10, 4);
25129 XRa
= extract32(ctx
->opcode
, 6, 4);
25131 if (unlikely(pad
!= 0)) {
25132 /* opcode padding incorrect -> do nothing */
25133 } else if (unlikely(XRa
== 0)) {
25134 /* destination is zero register -> do nothing */
25135 } else if (unlikely((XRb
== 0) && (XRc
== 0))) {
25136 /* both operands zero registers -> just set destination to all 1s */
25137 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0xFFFFFFFF);
25138 } else if (unlikely(XRb
== 0)) {
25139 /* XRb zero register -> just set destination to the negation of XRc */
25140 tcg_gen_not_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRc
- 1]);
25141 } else if (unlikely(XRc
== 0)) {
25142 /* XRa zero register -> just set destination to the negation of XRb */
25143 tcg_gen_not_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25144 } else if (unlikely(XRb
== XRc
)) {
25145 /* both operands same -> just set destination to the negation of XRb */
25146 tcg_gen_not_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25148 /* the most general case */
25149 tcg_gen_nor_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1], mxu_gpr
[XRc
- 1]);
25154 * S32AND XRa, XRb, XRc
25155 * Update XRa with the result of logical bitwise 'and' operation
25156 * applied to the content of XRb and XRc.
25158 static void gen_mxu_S32AND(DisasContext
*ctx
)
25160 uint32_t pad
, XRc
, XRb
, XRa
;
25162 pad
= extract32(ctx
->opcode
, 21, 5);
25163 XRc
= extract32(ctx
->opcode
, 14, 4);
25164 XRb
= extract32(ctx
->opcode
, 10, 4);
25165 XRa
= extract32(ctx
->opcode
, 6, 4);
25167 if (unlikely(pad
!= 0)) {
25168 /* opcode padding incorrect -> do nothing */
25169 } else if (unlikely(XRa
== 0)) {
25170 /* destination is zero register -> do nothing */
25171 } else if (unlikely((XRb
== 0) || (XRc
== 0))) {
25172 /* one of operands zero register -> just set destination to all 0s */
25173 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0);
25174 } else if (unlikely(XRb
== XRc
)) {
25175 /* both operands same -> just set destination to one of them */
25176 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25178 /* the most general case */
25179 tcg_gen_and_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1], mxu_gpr
[XRc
- 1]);
25184 * S32OR XRa, XRb, XRc
25185 * Update XRa with the result of logical bitwise 'or' operation
25186 * applied to the content of XRb and XRc.
25188 static void gen_mxu_S32OR(DisasContext
*ctx
)
25190 uint32_t pad
, XRc
, XRb
, XRa
;
25192 pad
= extract32(ctx
->opcode
, 21, 5);
25193 XRc
= extract32(ctx
->opcode
, 14, 4);
25194 XRb
= extract32(ctx
->opcode
, 10, 4);
25195 XRa
= extract32(ctx
->opcode
, 6, 4);
25197 if (unlikely(pad
!= 0)) {
25198 /* opcode padding incorrect -> do nothing */
25199 } else if (unlikely(XRa
== 0)) {
25200 /* destination is zero register -> do nothing */
25201 } else if (unlikely((XRb
== 0) && (XRc
== 0))) {
25202 /* both operands zero registers -> just set destination to all 0s */
25203 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0);
25204 } else if (unlikely(XRb
== 0)) {
25205 /* XRb zero register -> just set destination to the content of XRc */
25206 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRc
- 1]);
25207 } else if (unlikely(XRc
== 0)) {
25208 /* XRc zero register -> just set destination to the content of XRb */
25209 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25210 } else if (unlikely(XRb
== XRc
)) {
25211 /* both operands same -> just set destination to one of them */
25212 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25214 /* the most general case */
25215 tcg_gen_or_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1], mxu_gpr
[XRc
- 1]);
25220 * S32XOR XRa, XRb, XRc
25221 * Update XRa with the result of logical bitwise 'xor' operation
25222 * applied to the content of XRb and XRc.
25224 static void gen_mxu_S32XOR(DisasContext
*ctx
)
25226 uint32_t pad
, XRc
, XRb
, XRa
;
25228 pad
= extract32(ctx
->opcode
, 21, 5);
25229 XRc
= extract32(ctx
->opcode
, 14, 4);
25230 XRb
= extract32(ctx
->opcode
, 10, 4);
25231 XRa
= extract32(ctx
->opcode
, 6, 4);
25233 if (unlikely(pad
!= 0)) {
25234 /* opcode padding incorrect -> do nothing */
25235 } else if (unlikely(XRa
== 0)) {
25236 /* destination is zero register -> do nothing */
25237 } else if (unlikely((XRb
== 0) && (XRc
== 0))) {
25238 /* both operands zero registers -> just set destination to all 0s */
25239 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0);
25240 } else if (unlikely(XRb
== 0)) {
25241 /* XRb zero register -> just set destination to the content of XRc */
25242 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRc
- 1]);
25243 } else if (unlikely(XRc
== 0)) {
25244 /* XRc zero register -> just set destination to the content of XRb */
25245 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25246 } else if (unlikely(XRb
== XRc
)) {
25247 /* both operands same -> just set destination to all 0s */
25248 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0);
25250 /* the most general case */
25251 tcg_gen_xor_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1], mxu_gpr
[XRc
- 1]);
25257 * MXU instruction category max/min
25258 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
25260 * S32MAX D16MAX Q8MAX
25261 * S32MIN D16MIN Q8MIN
25265 * S32MAX XRa, XRb, XRc
25266 * Update XRa with the maximum of signed 32-bit integers contained
25269 * S32MIN XRa, XRb, XRc
25270 * Update XRa with the minimum of signed 32-bit integers contained
25273 static void gen_mxu_S32MAX_S32MIN(DisasContext
*ctx
)
25275 uint32_t pad
, opc
, XRc
, XRb
, XRa
;
25277 pad
= extract32(ctx
->opcode
, 21, 5);
25278 opc
= extract32(ctx
->opcode
, 18, 3);
25279 XRc
= extract32(ctx
->opcode
, 14, 4);
25280 XRb
= extract32(ctx
->opcode
, 10, 4);
25281 XRa
= extract32(ctx
->opcode
, 6, 4);
25283 if (unlikely(pad
!= 0)) {
25284 /* opcode padding incorrect -> do nothing */
25285 } else if (unlikely(XRa
== 0)) {
25286 /* destination is zero register -> do nothing */
25287 } else if (unlikely((XRb
== 0) && (XRc
== 0))) {
25288 /* both operands zero registers -> just set destination to zero */
25289 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0);
25290 } else if (unlikely((XRb
== 0) || (XRc
== 0))) {
25291 /* exactly one operand is zero register - find which one is not...*/
25292 uint32_t XRx
= XRb
? XRb
: XRc
;
25293 /* ...and do max/min operation with one operand 0 */
25294 if (opc
== OPC_MXU_S32MAX
) {
25295 tcg_gen_smax_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRx
- 1], 0);
25297 tcg_gen_smin_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRx
- 1], 0);
25299 } else if (unlikely(XRb
== XRc
)) {
25300 /* both operands same -> just set destination to one of them */
25301 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25303 /* the most general case */
25304 if (opc
== OPC_MXU_S32MAX
) {
25305 tcg_gen_smax_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1],
25308 tcg_gen_smin_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1],
25316 * Update XRa with the 16-bit-wise maximums of signed integers
25317 * contained in XRb and XRc.
25320 * Update XRa with the 16-bit-wise minimums of signed integers
25321 * contained in XRb and XRc.
25323 static void gen_mxu_D16MAX_D16MIN(DisasContext
*ctx
)
25325 uint32_t pad
, opc
, XRc
, XRb
, XRa
;
25327 pad
= extract32(ctx
->opcode
, 21, 5);
25328 opc
= extract32(ctx
->opcode
, 18, 3);
25329 XRc
= extract32(ctx
->opcode
, 14, 4);
25330 XRb
= extract32(ctx
->opcode
, 10, 4);
25331 XRa
= extract32(ctx
->opcode
, 6, 4);
25333 if (unlikely(pad
!= 0)) {
25334 /* opcode padding incorrect -> do nothing */
25335 } else if (unlikely(XRc
== 0)) {
25336 /* destination is zero register -> do nothing */
25337 } else if (unlikely((XRb
== 0) && (XRa
== 0))) {
25338 /* both operands zero registers -> just set destination to zero */
25339 tcg_gen_movi_i32(mxu_gpr
[XRc
- 1], 0);
25340 } else if (unlikely((XRb
== 0) || (XRa
== 0))) {
25341 /* exactly one operand is zero register - find which one is not...*/
25342 uint32_t XRx
= XRb
? XRb
: XRc
;
25343 /* ...and do half-word-wise max/min with one operand 0 */
25344 TCGv_i32 t0
= tcg_temp_new();
25345 TCGv_i32 t1
= tcg_const_i32(0);
25347 /* the left half-word first */
25348 tcg_gen_andi_i32(t0
, mxu_gpr
[XRx
- 1], 0xFFFF0000);
25349 if (opc
== OPC_MXU_D16MAX
) {
25350 tcg_gen_smax_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
25352 tcg_gen_smin_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
25355 /* the right half-word */
25356 tcg_gen_andi_i32(t0
, mxu_gpr
[XRx
- 1], 0x0000FFFF);
25357 /* move half-words to the leftmost position */
25358 tcg_gen_shli_i32(t0
, t0
, 16);
25359 /* t0 will be max/min of t0 and t1 */
25360 if (opc
== OPC_MXU_D16MAX
) {
25361 tcg_gen_smax_i32(t0
, t0
, t1
);
25363 tcg_gen_smin_i32(t0
, t0
, t1
);
25365 /* return resulting half-words to its original position */
25366 tcg_gen_shri_i32(t0
, t0
, 16);
25367 /* finally update the destination */
25368 tcg_gen_or_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRa
- 1], t0
);
25372 } else if (unlikely(XRb
== XRc
)) {
25373 /* both operands same -> just set destination to one of them */
25374 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25376 /* the most general case */
25377 TCGv_i32 t0
= tcg_temp_new();
25378 TCGv_i32 t1
= tcg_temp_new();
25380 /* the left half-word first */
25381 tcg_gen_andi_i32(t0
, mxu_gpr
[XRb
- 1], 0xFFFF0000);
25382 tcg_gen_andi_i32(t1
, mxu_gpr
[XRc
- 1], 0xFFFF0000);
25383 if (opc
== OPC_MXU_D16MAX
) {
25384 tcg_gen_smax_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
25386 tcg_gen_smin_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
25389 /* the right half-word */
25390 tcg_gen_andi_i32(t0
, mxu_gpr
[XRb
- 1], 0x0000FFFF);
25391 tcg_gen_andi_i32(t1
, mxu_gpr
[XRc
- 1], 0x0000FFFF);
25392 /* move half-words to the leftmost position */
25393 tcg_gen_shli_i32(t0
, t0
, 16);
25394 tcg_gen_shli_i32(t1
, t1
, 16);
25395 /* t0 will be max/min of t0 and t1 */
25396 if (opc
== OPC_MXU_D16MAX
) {
25397 tcg_gen_smax_i32(t0
, t0
, t1
);
25399 tcg_gen_smin_i32(t0
, t0
, t1
);
25401 /* return resulting half-words to its original position */
25402 tcg_gen_shri_i32(t0
, t0
, 16);
25403 /* finally update the destination */
25404 tcg_gen_or_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRa
- 1], t0
);
25413 * Update XRa with the 8-bit-wise maximums of signed integers
25414 * contained in XRb and XRc.
25417 * Update XRa with the 8-bit-wise minimums of signed integers
25418 * contained in XRb and XRc.
25420 static void gen_mxu_Q8MAX_Q8MIN(DisasContext
*ctx
)
25422 uint32_t pad
, opc
, XRc
, XRb
, XRa
;
25424 pad
= extract32(ctx
->opcode
, 21, 5);
25425 opc
= extract32(ctx
->opcode
, 18, 3);
25426 XRc
= extract32(ctx
->opcode
, 14, 4);
25427 XRb
= extract32(ctx
->opcode
, 10, 4);
25428 XRa
= extract32(ctx
->opcode
, 6, 4);
25430 if (unlikely(pad
!= 0)) {
25431 /* opcode padding incorrect -> do nothing */
25432 } else if (unlikely(XRa
== 0)) {
25433 /* destination is zero register -> do nothing */
25434 } else if (unlikely((XRb
== 0) && (XRc
== 0))) {
25435 /* both operands zero registers -> just set destination to zero */
25436 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0);
25437 } else if (unlikely((XRb
== 0) || (XRc
== 0))) {
25438 /* exactly one operand is zero register - make it be the first...*/
25439 uint32_t XRx
= XRb
? XRb
: XRc
;
25440 /* ...and do byte-wise max/min with one operand 0 */
25441 TCGv_i32 t0
= tcg_temp_new();
25442 TCGv_i32 t1
= tcg_const_i32(0);
25445 /* the leftmost byte (byte 3) first */
25446 tcg_gen_andi_i32(t0
, mxu_gpr
[XRx
- 1], 0xFF000000);
25447 if (opc
== OPC_MXU_Q8MAX
) {
25448 tcg_gen_smax_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
25450 tcg_gen_smin_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
25453 /* bytes 2, 1, 0 */
25454 for (i
= 2; i
>= 0; i
--) {
25455 /* extract the byte */
25456 tcg_gen_andi_i32(t0
, mxu_gpr
[XRx
- 1], 0xFF << (8 * i
));
25457 /* move the byte to the leftmost position */
25458 tcg_gen_shli_i32(t0
, t0
, 8 * (3 - i
));
25459 /* t0 will be max/min of t0 and t1 */
25460 if (opc
== OPC_MXU_Q8MAX
) {
25461 tcg_gen_smax_i32(t0
, t0
, t1
);
25463 tcg_gen_smin_i32(t0
, t0
, t1
);
25465 /* return resulting byte to its original position */
25466 tcg_gen_shri_i32(t0
, t0
, 8 * (3 - i
));
25467 /* finally update the destination */
25468 tcg_gen_or_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRa
- 1], t0
);
25473 } else if (unlikely(XRb
== XRc
)) {
25474 /* both operands same -> just set destination to one of them */
25475 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25477 /* the most general case */
25478 TCGv_i32 t0
= tcg_temp_new();
25479 TCGv_i32 t1
= tcg_temp_new();
25482 /* the leftmost bytes (bytes 3) first */
25483 tcg_gen_andi_i32(t0
, mxu_gpr
[XRb
- 1], 0xFF000000);
25484 tcg_gen_andi_i32(t1
, mxu_gpr
[XRc
- 1], 0xFF000000);
25485 if (opc
== OPC_MXU_Q8MAX
) {
25486 tcg_gen_smax_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
25488 tcg_gen_smin_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
25491 /* bytes 2, 1, 0 */
25492 for (i
= 2; i
>= 0; i
--) {
25493 /* extract corresponding bytes */
25494 tcg_gen_andi_i32(t0
, mxu_gpr
[XRb
- 1], 0xFF << (8 * i
));
25495 tcg_gen_andi_i32(t1
, mxu_gpr
[XRc
- 1], 0xFF << (8 * i
));
25496 /* move the bytes to the leftmost position */
25497 tcg_gen_shli_i32(t0
, t0
, 8 * (3 - i
));
25498 tcg_gen_shli_i32(t1
, t1
, 8 * (3 - i
));
25499 /* t0 will be max/min of t0 and t1 */
25500 if (opc
== OPC_MXU_Q8MAX
) {
25501 tcg_gen_smax_i32(t0
, t0
, t1
);
25503 tcg_gen_smin_i32(t0
, t0
, t1
);
25505 /* return resulting byte to its original position */
25506 tcg_gen_shri_i32(t0
, t0
, 8 * (3 - i
));
25507 /* finally update the destination */
25508 tcg_gen_or_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRa
- 1], t0
);
25518 * MXU instruction category: align
25519 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
25525 * S32ALNI XRc, XRb, XRa, optn3
25526 * Arrange bytes from XRb and XRc according to one of five sets of
25527 * rules determined by optn3, and place the result in XRa.
25529 static void gen_mxu_S32ALNI(DisasContext
*ctx
)
25531 uint32_t optn3
, pad
, XRc
, XRb
, XRa
;
25533 optn3
= extract32(ctx
->opcode
, 23, 3);
25534 pad
= extract32(ctx
->opcode
, 21, 2);
25535 XRc
= extract32(ctx
->opcode
, 14, 4);
25536 XRb
= extract32(ctx
->opcode
, 10, 4);
25537 XRa
= extract32(ctx
->opcode
, 6, 4);
25539 if (unlikely(pad
!= 0)) {
25540 /* opcode padding incorrect -> do nothing */
25541 } else if (unlikely(XRa
== 0)) {
25542 /* destination is zero register -> do nothing */
25543 } else if (unlikely((XRb
== 0) && (XRc
== 0))) {
25544 /* both operands zero registers -> just set destination to all 0s */
25545 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0);
25546 } else if (unlikely(XRb
== 0)) {
25547 /* XRb zero register -> just appropriatelly shift XRc into XRa */
25549 case MXU_OPTN3_PTN0
:
25550 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0);
25552 case MXU_OPTN3_PTN1
:
25553 case MXU_OPTN3_PTN2
:
25554 case MXU_OPTN3_PTN3
:
25555 tcg_gen_shri_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRc
- 1],
25558 case MXU_OPTN3_PTN4
:
25559 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRc
- 1]);
25562 } else if (unlikely(XRc
== 0)) {
25563 /* XRc zero register -> just appropriatelly shift XRb into XRa */
25565 case MXU_OPTN3_PTN0
:
25566 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25568 case MXU_OPTN3_PTN1
:
25569 case MXU_OPTN3_PTN2
:
25570 case MXU_OPTN3_PTN3
:
25571 tcg_gen_shri_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1], 8 * optn3
);
25573 case MXU_OPTN3_PTN4
:
25574 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0);
25577 } else if (unlikely(XRb
== XRc
)) {
25578 /* both operands same -> just rotation or moving from any of them */
25580 case MXU_OPTN3_PTN0
:
25581 case MXU_OPTN3_PTN4
:
25582 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25584 case MXU_OPTN3_PTN1
:
25585 case MXU_OPTN3_PTN2
:
25586 case MXU_OPTN3_PTN3
:
25587 tcg_gen_rotli_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1], 8 * optn3
);
25591 /* the most general case */
25593 case MXU_OPTN3_PTN0
:
25597 /* +---------------+ */
25598 /* | A B C D | E F G H */
25599 /* +-------+-------+ */
25604 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25607 case MXU_OPTN3_PTN1
:
25611 /* +-------------------+ */
25612 /* A | B C D E | F G H */
25613 /* +---------+---------+ */
25618 TCGv_i32 t0
= tcg_temp_new();
25619 TCGv_i32 t1
= tcg_temp_new();
25621 tcg_gen_andi_i32(t0
, mxu_gpr
[XRb
- 1], 0x00FFFFFF);
25622 tcg_gen_shli_i32(t0
, t0
, 8);
25624 tcg_gen_andi_i32(t1
, mxu_gpr
[XRc
- 1], 0xFF000000);
25625 tcg_gen_shri_i32(t1
, t1
, 24);
25627 tcg_gen_or_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
25633 case MXU_OPTN3_PTN2
:
25637 /* +-------------------+ */
25638 /* A B | C D E F | G H */
25639 /* +---------+---------+ */
25644 TCGv_i32 t0
= tcg_temp_new();
25645 TCGv_i32 t1
= tcg_temp_new();
25647 tcg_gen_andi_i32(t0
, mxu_gpr
[XRb
- 1], 0x0000FFFF);
25648 tcg_gen_shli_i32(t0
, t0
, 16);
25650 tcg_gen_andi_i32(t1
, mxu_gpr
[XRc
- 1], 0xFFFF0000);
25651 tcg_gen_shri_i32(t1
, t1
, 16);
25653 tcg_gen_or_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
25659 case MXU_OPTN3_PTN3
:
25663 /* +-------------------+ */
25664 /* A B C | D E F G | H */
25665 /* +---------+---------+ */
25670 TCGv_i32 t0
= tcg_temp_new();
25671 TCGv_i32 t1
= tcg_temp_new();
25673 tcg_gen_andi_i32(t0
, mxu_gpr
[XRb
- 1], 0x000000FF);
25674 tcg_gen_shli_i32(t0
, t0
, 24);
25676 tcg_gen_andi_i32(t1
, mxu_gpr
[XRc
- 1], 0xFFFFFF00);
25677 tcg_gen_shri_i32(t1
, t1
, 8);
25679 tcg_gen_or_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
25685 case MXU_OPTN3_PTN4
:
25689 /* +---------------+ */
25690 /* A B C D | E F G H | */
25691 /* +-------+-------+ */
25696 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRc
- 1]);
25705 * Decoding engine for MXU
25706 * =======================
25709 static void decode_opc_mxu__pool00(DisasContext
*ctx
)
25711 uint32_t opcode
= extract32(ctx
->opcode
, 18, 3);
25714 case OPC_MXU_S32MAX
:
25715 case OPC_MXU_S32MIN
:
25716 gen_mxu_S32MAX_S32MIN(ctx
);
25718 case OPC_MXU_D16MAX
:
25719 case OPC_MXU_D16MIN
:
25720 gen_mxu_D16MAX_D16MIN(ctx
);
25722 case OPC_MXU_Q8MAX
:
25723 case OPC_MXU_Q8MIN
:
25724 gen_mxu_Q8MAX_Q8MIN(ctx
);
25727 MIPS_INVAL("decode_opc_mxu");
25728 gen_reserved_instruction(ctx
);
25733 static void decode_opc_mxu__pool04(DisasContext
*ctx
)
25735 uint32_t opcode
= extract32(ctx
->opcode
, 20, 1);
25738 case OPC_MXU_S32LDD
:
25739 case OPC_MXU_S32LDDR
:
25740 gen_mxu_s32ldd_s32lddr(ctx
);
25743 MIPS_INVAL("decode_opc_mxu");
25744 gen_reserved_instruction(ctx
);
25749 static void decode_opc_mxu__pool16(DisasContext
*ctx
)
25751 uint32_t opcode
= extract32(ctx
->opcode
, 18, 3);
25754 case OPC_MXU_S32ALNI
:
25755 gen_mxu_S32ALNI(ctx
);
25757 case OPC_MXU_S32NOR
:
25758 gen_mxu_S32NOR(ctx
);
25760 case OPC_MXU_S32AND
:
25761 gen_mxu_S32AND(ctx
);
25763 case OPC_MXU_S32OR
:
25764 gen_mxu_S32OR(ctx
);
25766 case OPC_MXU_S32XOR
:
25767 gen_mxu_S32XOR(ctx
);
25770 MIPS_INVAL("decode_opc_mxu");
25771 gen_reserved_instruction(ctx
);
25776 static void decode_opc_mxu__pool19(DisasContext
*ctx
)
25778 uint32_t opcode
= extract32(ctx
->opcode
, 22, 2);
25781 case OPC_MXU_Q8MUL
:
25782 case OPC_MXU_Q8MULSU
:
25783 gen_mxu_q8mul_q8mulsu(ctx
);
25786 MIPS_INVAL("decode_opc_mxu");
25787 gen_reserved_instruction(ctx
);
25793 * Main MXU decoding function
25795 bool decode_ase_mxu(DisasContext
*ctx
, uint32_t insn
)
25797 uint32_t opcode
= extract32(insn
, 0, 6);
25799 if (opcode
== OPC_MXU_S32M2I
) {
25800 gen_mxu_s32m2i(ctx
);
25804 if (opcode
== OPC_MXU_S32I2M
) {
25805 gen_mxu_s32i2m(ctx
);
25810 TCGv t_mxu_cr
= tcg_temp_new();
25811 TCGLabel
*l_exit
= gen_new_label();
25813 gen_load_mxu_cr(t_mxu_cr
);
25814 tcg_gen_andi_tl(t_mxu_cr
, t_mxu_cr
, MXU_CR_MXU_EN
);
25815 tcg_gen_brcondi_tl(TCG_COND_NE
, t_mxu_cr
, MXU_CR_MXU_EN
, l_exit
);
25818 case OPC_MXU__POOL00
:
25819 decode_opc_mxu__pool00(ctx
);
25821 case OPC_MXU_D16MUL
:
25822 gen_mxu_d16mul(ctx
);
25824 case OPC_MXU_D16MAC
:
25825 gen_mxu_d16mac(ctx
);
25827 case OPC_MXU__POOL04
:
25828 decode_opc_mxu__pool04(ctx
);
25830 case OPC_MXU_S8LDD
:
25831 gen_mxu_s8ldd(ctx
);
25833 case OPC_MXU__POOL16
:
25834 decode_opc_mxu__pool16(ctx
);
25836 case OPC_MXU__POOL19
:
25837 decode_opc_mxu__pool19(ctx
);
25840 MIPS_INVAL("decode_opc_mxu");
25841 gen_reserved_instruction(ctx
);
25844 gen_set_label(l_exit
);
25845 tcg_temp_free(t_mxu_cr
);
25851 #endif /* !defined(TARGET_MIPS64) */
25854 static void decode_opc_special2_legacy(CPUMIPSState
*env
, DisasContext
*ctx
)
25859 rs
= (ctx
->opcode
>> 21) & 0x1f;
25860 rt
= (ctx
->opcode
>> 16) & 0x1f;
25861 rd
= (ctx
->opcode
>> 11) & 0x1f;
25863 op1
= MASK_SPECIAL2(ctx
->opcode
);
25865 case OPC_MADD
: /* Multiply and add/sub */
25869 check_insn(ctx
, ISA_MIPS_R1
);
25870 gen_muldiv(ctx
, op1
, rd
& 3, rs
, rt
);
25873 gen_arith(ctx
, op1
, rd
, rs
, rt
);
25876 case OPC_DIVU_G_2F
:
25877 case OPC_MULT_G_2F
:
25878 case OPC_MULTU_G_2F
:
25880 case OPC_MODU_G_2F
:
25881 check_insn(ctx
, INSN_LOONGSON2F
| ASE_LEXT
);
25882 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
25886 check_insn(ctx
, ISA_MIPS_R1
);
25887 gen_cl(ctx
, op1
, rd
, rs
);
25890 if (is_uhi(extract32(ctx
->opcode
, 6, 20))) {
25891 gen_helper_do_semihosting(cpu_env
);
25894 * XXX: not clear which exception should be raised
25895 * when in debug mode...
25897 check_insn(ctx
, ISA_MIPS_R1
);
25898 generate_exception_end(ctx
, EXCP_DBp
);
25901 #if defined(TARGET_MIPS64)
25904 check_insn(ctx
, ISA_MIPS_R1
);
25905 check_mips_64(ctx
);
25906 gen_cl(ctx
, op1
, rd
, rs
);
25908 case OPC_DMULT_G_2F
:
25909 case OPC_DMULTU_G_2F
:
25910 case OPC_DDIV_G_2F
:
25911 case OPC_DDIVU_G_2F
:
25912 case OPC_DMOD_G_2F
:
25913 case OPC_DMODU_G_2F
:
25914 check_insn(ctx
, INSN_LOONGSON2F
| ASE_LEXT
);
25915 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
25918 default: /* Invalid */
25919 MIPS_INVAL("special2_legacy");
25920 gen_reserved_instruction(ctx
);
25925 static void decode_opc_special3_r6(CPUMIPSState
*env
, DisasContext
*ctx
)
25927 int rs
, rt
, rd
, sa
;
25931 rs
= (ctx
->opcode
>> 21) & 0x1f;
25932 rt
= (ctx
->opcode
>> 16) & 0x1f;
25933 rd
= (ctx
->opcode
>> 11) & 0x1f;
25934 sa
= (ctx
->opcode
>> 6) & 0x1f;
25935 imm
= (int16_t)ctx
->opcode
>> 7;
25937 op1
= MASK_SPECIAL3(ctx
->opcode
);
25941 /* hint codes 24-31 are reserved and signal RI */
25942 gen_reserved_instruction(ctx
);
25944 /* Treat as NOP. */
25947 check_cp0_enabled(ctx
);
25948 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
25949 gen_cache_operation(ctx
, rt
, rs
, imm
);
25953 gen_st_cond(ctx
, rt
, rs
, imm
, MO_TESL
, false);
25956 gen_ld(ctx
, op1
, rt
, rs
, imm
);
25961 /* Treat as NOP. */
25964 op2
= MASK_BSHFL(ctx
->opcode
);
25970 gen_align(ctx
, 32, rd
, rs
, rt
, sa
& 3);
25973 gen_bitswap(ctx
, op2
, rd
, rt
);
25978 #ifndef CONFIG_USER_ONLY
25980 if (unlikely(ctx
->gi
<= 1)) {
25981 gen_reserved_instruction(ctx
);
25983 check_cp0_enabled(ctx
);
25984 switch ((ctx
->opcode
>> 6) & 3) {
25985 case 0: /* GINVI */
25986 /* Treat as NOP. */
25988 case 2: /* GINVT */
25989 gen_helper_0e1i(ginvt
, cpu_gpr
[rs
], extract32(ctx
->opcode
, 8, 2));
25992 gen_reserved_instruction(ctx
);
25997 #if defined(TARGET_MIPS64)
25999 gen_st_cond(ctx
, rt
, rs
, imm
, MO_TEQ
, false);
26002 gen_ld(ctx
, op1
, rt
, rs
, imm
);
26005 check_mips_64(ctx
);
26008 /* Treat as NOP. */
26011 op2
= MASK_DBSHFL(ctx
->opcode
);
26021 gen_align(ctx
, 64, rd
, rs
, rt
, sa
& 7);
26024 gen_bitswap(ctx
, op2
, rd
, rt
);
26031 default: /* Invalid */
26032 MIPS_INVAL("special3_r6");
26033 gen_reserved_instruction(ctx
);
26038 static void decode_opc_special3_legacy(CPUMIPSState
*env
, DisasContext
*ctx
)
26043 rs
= (ctx
->opcode
>> 21) & 0x1f;
26044 rt
= (ctx
->opcode
>> 16) & 0x1f;
26045 rd
= (ctx
->opcode
>> 11) & 0x1f;
26047 op1
= MASK_SPECIAL3(ctx
->opcode
);
26050 case OPC_DIVU_G_2E
:
26052 case OPC_MODU_G_2E
:
26053 case OPC_MULT_G_2E
:
26054 case OPC_MULTU_G_2E
:
26056 * OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
26057 * the same mask and op1.
26059 if ((ctx
->insn_flags
& ASE_DSP_R2
) && (op1
== OPC_MULT_G_2E
)) {
26060 op2
= MASK_ADDUH_QB(ctx
->opcode
);
26063 case OPC_ADDUH_R_QB
:
26065 case OPC_ADDQH_R_PH
:
26067 case OPC_ADDQH_R_W
:
26069 case OPC_SUBUH_R_QB
:
26071 case OPC_SUBQH_R_PH
:
26073 case OPC_SUBQH_R_W
:
26074 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
26079 case OPC_MULQ_RS_W
:
26080 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
26083 MIPS_INVAL("MASK ADDUH.QB");
26084 gen_reserved_instruction(ctx
);
26087 } else if (ctx
->insn_flags
& INSN_LOONGSON2E
) {
26088 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
26090 gen_reserved_instruction(ctx
);
26094 op2
= MASK_LX(ctx
->opcode
);
26096 #if defined(TARGET_MIPS64)
26102 gen_mipsdsp_ld(ctx
, op2
, rd
, rs
, rt
);
26104 default: /* Invalid */
26105 MIPS_INVAL("MASK LX");
26106 gen_reserved_instruction(ctx
);
26110 case OPC_ABSQ_S_PH_DSP
:
26111 op2
= MASK_ABSQ_S_PH(ctx
->opcode
);
26113 case OPC_ABSQ_S_QB
:
26114 case OPC_ABSQ_S_PH
:
26116 case OPC_PRECEQ_W_PHL
:
26117 case OPC_PRECEQ_W_PHR
:
26118 case OPC_PRECEQU_PH_QBL
:
26119 case OPC_PRECEQU_PH_QBR
:
26120 case OPC_PRECEQU_PH_QBLA
:
26121 case OPC_PRECEQU_PH_QBRA
:
26122 case OPC_PRECEU_PH_QBL
:
26123 case OPC_PRECEU_PH_QBR
:
26124 case OPC_PRECEU_PH_QBLA
:
26125 case OPC_PRECEU_PH_QBRA
:
26126 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
26133 gen_mipsdsp_bitinsn(ctx
, op1
, op2
, rd
, rt
);
26136 MIPS_INVAL("MASK ABSQ_S.PH");
26137 gen_reserved_instruction(ctx
);
26141 case OPC_ADDU_QB_DSP
:
26142 op2
= MASK_ADDU_QB(ctx
->opcode
);
26145 case OPC_ADDQ_S_PH
:
26148 case OPC_ADDU_S_QB
:
26150 case OPC_ADDU_S_PH
:
26152 case OPC_SUBQ_S_PH
:
26155 case OPC_SUBU_S_QB
:
26157 case OPC_SUBU_S_PH
:
26161 case OPC_RADDU_W_QB
:
26162 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
26164 case OPC_MULEU_S_PH_QBL
:
26165 case OPC_MULEU_S_PH_QBR
:
26166 case OPC_MULQ_RS_PH
:
26167 case OPC_MULEQ_S_W_PHL
:
26168 case OPC_MULEQ_S_W_PHR
:
26169 case OPC_MULQ_S_PH
:
26170 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
26172 default: /* Invalid */
26173 MIPS_INVAL("MASK ADDU.QB");
26174 gen_reserved_instruction(ctx
);
26179 case OPC_CMPU_EQ_QB_DSP
:
26180 op2
= MASK_CMPU_EQ_QB(ctx
->opcode
);
26182 case OPC_PRECR_SRA_PH_W
:
26183 case OPC_PRECR_SRA_R_PH_W
:
26184 gen_mipsdsp_arith(ctx
, op1
, op2
, rt
, rs
, rd
);
26186 case OPC_PRECR_QB_PH
:
26187 case OPC_PRECRQ_QB_PH
:
26188 case OPC_PRECRQ_PH_W
:
26189 case OPC_PRECRQ_RS_PH_W
:
26190 case OPC_PRECRQU_S_QB_PH
:
26191 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
26193 case OPC_CMPU_EQ_QB
:
26194 case OPC_CMPU_LT_QB
:
26195 case OPC_CMPU_LE_QB
:
26196 case OPC_CMP_EQ_PH
:
26197 case OPC_CMP_LT_PH
:
26198 case OPC_CMP_LE_PH
:
26199 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
26201 case OPC_CMPGU_EQ_QB
:
26202 case OPC_CMPGU_LT_QB
:
26203 case OPC_CMPGU_LE_QB
:
26204 case OPC_CMPGDU_EQ_QB
:
26205 case OPC_CMPGDU_LT_QB
:
26206 case OPC_CMPGDU_LE_QB
:
26209 case OPC_PACKRL_PH
:
26210 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
26212 default: /* Invalid */
26213 MIPS_INVAL("MASK CMPU.EQ.QB");
26214 gen_reserved_instruction(ctx
);
26218 case OPC_SHLL_QB_DSP
:
26219 gen_mipsdsp_shift(ctx
, op1
, rd
, rs
, rt
);
26221 case OPC_DPA_W_PH_DSP
:
26222 op2
= MASK_DPA_W_PH(ctx
->opcode
);
26224 case OPC_DPAU_H_QBL
:
26225 case OPC_DPAU_H_QBR
:
26226 case OPC_DPSU_H_QBL
:
26227 case OPC_DPSU_H_QBR
:
26229 case OPC_DPAX_W_PH
:
26230 case OPC_DPAQ_S_W_PH
:
26231 case OPC_DPAQX_S_W_PH
:
26232 case OPC_DPAQX_SA_W_PH
:
26234 case OPC_DPSX_W_PH
:
26235 case OPC_DPSQ_S_W_PH
:
26236 case OPC_DPSQX_S_W_PH
:
26237 case OPC_DPSQX_SA_W_PH
:
26238 case OPC_MULSAQ_S_W_PH
:
26239 case OPC_DPAQ_SA_L_W
:
26240 case OPC_DPSQ_SA_L_W
:
26241 case OPC_MAQ_S_W_PHL
:
26242 case OPC_MAQ_S_W_PHR
:
26243 case OPC_MAQ_SA_W_PHL
:
26244 case OPC_MAQ_SA_W_PHR
:
26245 case OPC_MULSA_W_PH
:
26246 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
26248 default: /* Invalid */
26249 MIPS_INVAL("MASK DPAW.PH");
26250 gen_reserved_instruction(ctx
);
26255 op2
= MASK_INSV(ctx
->opcode
);
26266 t0
= tcg_temp_new();
26267 t1
= tcg_temp_new();
26269 gen_load_gpr(t0
, rt
);
26270 gen_load_gpr(t1
, rs
);
26272 gen_helper_insv(cpu_gpr
[rt
], cpu_env
, t1
, t0
);
26278 default: /* Invalid */
26279 MIPS_INVAL("MASK INSV");
26280 gen_reserved_instruction(ctx
);
26284 case OPC_APPEND_DSP
:
26285 gen_mipsdsp_append(env
, ctx
, op1
, rt
, rs
, rd
);
26287 case OPC_EXTR_W_DSP
:
26288 op2
= MASK_EXTR_W(ctx
->opcode
);
26292 case OPC_EXTR_RS_W
:
26294 case OPC_EXTRV_S_H
:
26296 case OPC_EXTRV_R_W
:
26297 case OPC_EXTRV_RS_W
:
26302 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rt
, rs
, rd
, 1);
26305 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
26311 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
26313 default: /* Invalid */
26314 MIPS_INVAL("MASK EXTR.W");
26315 gen_reserved_instruction(ctx
);
26319 #if defined(TARGET_MIPS64)
26320 case OPC_DDIV_G_2E
:
26321 case OPC_DDIVU_G_2E
:
26322 case OPC_DMULT_G_2E
:
26323 case OPC_DMULTU_G_2E
:
26324 case OPC_DMOD_G_2E
:
26325 case OPC_DMODU_G_2E
:
26326 check_insn(ctx
, INSN_LOONGSON2E
);
26327 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
26329 case OPC_ABSQ_S_QH_DSP
:
26330 op2
= MASK_ABSQ_S_QH(ctx
->opcode
);
26332 case OPC_PRECEQ_L_PWL
:
26333 case OPC_PRECEQ_L_PWR
:
26334 case OPC_PRECEQ_PW_QHL
:
26335 case OPC_PRECEQ_PW_QHR
:
26336 case OPC_PRECEQ_PW_QHLA
:
26337 case OPC_PRECEQ_PW_QHRA
:
26338 case OPC_PRECEQU_QH_OBL
:
26339 case OPC_PRECEQU_QH_OBR
:
26340 case OPC_PRECEQU_QH_OBLA
:
26341 case OPC_PRECEQU_QH_OBRA
:
26342 case OPC_PRECEU_QH_OBL
:
26343 case OPC_PRECEU_QH_OBR
:
26344 case OPC_PRECEU_QH_OBLA
:
26345 case OPC_PRECEU_QH_OBRA
:
26346 case OPC_ABSQ_S_OB
:
26347 case OPC_ABSQ_S_PW
:
26348 case OPC_ABSQ_S_QH
:
26349 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
26357 gen_mipsdsp_bitinsn(ctx
, op1
, op2
, rd
, rt
);
26359 default: /* Invalid */
26360 MIPS_INVAL("MASK ABSQ_S.QH");
26361 gen_reserved_instruction(ctx
);
26365 case OPC_ADDU_OB_DSP
:
26366 op2
= MASK_ADDU_OB(ctx
->opcode
);
26368 case OPC_RADDU_L_OB
:
26370 case OPC_SUBQ_S_PW
:
26372 case OPC_SUBQ_S_QH
:
26374 case OPC_SUBU_S_OB
:
26376 case OPC_SUBU_S_QH
:
26378 case OPC_SUBUH_R_OB
:
26380 case OPC_ADDQ_S_PW
:
26382 case OPC_ADDQ_S_QH
:
26384 case OPC_ADDU_S_OB
:
26386 case OPC_ADDU_S_QH
:
26388 case OPC_ADDUH_R_OB
:
26389 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
26391 case OPC_MULEQ_S_PW_QHL
:
26392 case OPC_MULEQ_S_PW_QHR
:
26393 case OPC_MULEU_S_QH_OBL
:
26394 case OPC_MULEU_S_QH_OBR
:
26395 case OPC_MULQ_RS_QH
:
26396 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
26398 default: /* Invalid */
26399 MIPS_INVAL("MASK ADDU.OB");
26400 gen_reserved_instruction(ctx
);
26404 case OPC_CMPU_EQ_OB_DSP
:
26405 op2
= MASK_CMPU_EQ_OB(ctx
->opcode
);
26407 case OPC_PRECR_SRA_QH_PW
:
26408 case OPC_PRECR_SRA_R_QH_PW
:
26409 /* Return value is rt. */
26410 gen_mipsdsp_arith(ctx
, op1
, op2
, rt
, rs
, rd
);
26412 case OPC_PRECR_OB_QH
:
26413 case OPC_PRECRQ_OB_QH
:
26414 case OPC_PRECRQ_PW_L
:
26415 case OPC_PRECRQ_QH_PW
:
26416 case OPC_PRECRQ_RS_QH_PW
:
26417 case OPC_PRECRQU_S_OB_QH
:
26418 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
26420 case OPC_CMPU_EQ_OB
:
26421 case OPC_CMPU_LT_OB
:
26422 case OPC_CMPU_LE_OB
:
26423 case OPC_CMP_EQ_QH
:
26424 case OPC_CMP_LT_QH
:
26425 case OPC_CMP_LE_QH
:
26426 case OPC_CMP_EQ_PW
:
26427 case OPC_CMP_LT_PW
:
26428 case OPC_CMP_LE_PW
:
26429 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
26431 case OPC_CMPGDU_EQ_OB
:
26432 case OPC_CMPGDU_LT_OB
:
26433 case OPC_CMPGDU_LE_OB
:
26434 case OPC_CMPGU_EQ_OB
:
26435 case OPC_CMPGU_LT_OB
:
26436 case OPC_CMPGU_LE_OB
:
26437 case OPC_PACKRL_PW
:
26441 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
26443 default: /* Invalid */
26444 MIPS_INVAL("MASK CMPU_EQ.OB");
26445 gen_reserved_instruction(ctx
);
26449 case OPC_DAPPEND_DSP
:
26450 gen_mipsdsp_append(env
, ctx
, op1
, rt
, rs
, rd
);
26452 case OPC_DEXTR_W_DSP
:
26453 op2
= MASK_DEXTR_W(ctx
->opcode
);
26460 case OPC_DEXTR_R_L
:
26461 case OPC_DEXTR_RS_L
:
26463 case OPC_DEXTR_R_W
:
26464 case OPC_DEXTR_RS_W
:
26465 case OPC_DEXTR_S_H
:
26467 case OPC_DEXTRV_R_L
:
26468 case OPC_DEXTRV_RS_L
:
26469 case OPC_DEXTRV_S_H
:
26471 case OPC_DEXTRV_R_W
:
26472 case OPC_DEXTRV_RS_W
:
26473 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rt
, rs
, rd
, 1);
26478 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
26480 default: /* Invalid */
26481 MIPS_INVAL("MASK EXTR.W");
26482 gen_reserved_instruction(ctx
);
26486 case OPC_DPAQ_W_QH_DSP
:
26487 op2
= MASK_DPAQ_W_QH(ctx
->opcode
);
26489 case OPC_DPAU_H_OBL
:
26490 case OPC_DPAU_H_OBR
:
26491 case OPC_DPSU_H_OBL
:
26492 case OPC_DPSU_H_OBR
:
26494 case OPC_DPAQ_S_W_QH
:
26496 case OPC_DPSQ_S_W_QH
:
26497 case OPC_MULSAQ_S_W_QH
:
26498 case OPC_DPAQ_SA_L_PW
:
26499 case OPC_DPSQ_SA_L_PW
:
26500 case OPC_MULSAQ_S_L_PW
:
26501 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
26503 case OPC_MAQ_S_W_QHLL
:
26504 case OPC_MAQ_S_W_QHLR
:
26505 case OPC_MAQ_S_W_QHRL
:
26506 case OPC_MAQ_S_W_QHRR
:
26507 case OPC_MAQ_SA_W_QHLL
:
26508 case OPC_MAQ_SA_W_QHLR
:
26509 case OPC_MAQ_SA_W_QHRL
:
26510 case OPC_MAQ_SA_W_QHRR
:
26511 case OPC_MAQ_S_L_PWL
:
26512 case OPC_MAQ_S_L_PWR
:
26517 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
26519 default: /* Invalid */
26520 MIPS_INVAL("MASK DPAQ.W.QH");
26521 gen_reserved_instruction(ctx
);
26525 case OPC_DINSV_DSP
:
26526 op2
= MASK_INSV(ctx
->opcode
);
26537 t0
= tcg_temp_new();
26538 t1
= tcg_temp_new();
26540 gen_load_gpr(t0
, rt
);
26541 gen_load_gpr(t1
, rs
);
26543 gen_helper_dinsv(cpu_gpr
[rt
], cpu_env
, t1
, t0
);
26549 default: /* Invalid */
26550 MIPS_INVAL("MASK DINSV");
26551 gen_reserved_instruction(ctx
);
26555 case OPC_SHLL_OB_DSP
:
26556 gen_mipsdsp_shift(ctx
, op1
, rd
, rs
, rt
);
26559 default: /* Invalid */
26560 MIPS_INVAL("special3_legacy");
26561 gen_reserved_instruction(ctx
);
26567 #if defined(TARGET_MIPS64)
26569 static void decode_mmi0(CPUMIPSState
*env
, DisasContext
*ctx
)
26571 uint32_t opc
= MASK_MMI0(ctx
->opcode
);
26574 case MMI_OPC_0_PADDW
: /* TODO: MMI_OPC_0_PADDW */
26575 case MMI_OPC_0_PSUBW
: /* TODO: MMI_OPC_0_PSUBW */
26576 case MMI_OPC_0_PCGTW
: /* TODO: MMI_OPC_0_PCGTW */
26577 case MMI_OPC_0_PMAXW
: /* TODO: MMI_OPC_0_PMAXW */
26578 case MMI_OPC_0_PADDH
: /* TODO: MMI_OPC_0_PADDH */
26579 case MMI_OPC_0_PSUBH
: /* TODO: MMI_OPC_0_PSUBH */
26580 case MMI_OPC_0_PCGTH
: /* TODO: MMI_OPC_0_PCGTH */
26581 case MMI_OPC_0_PMAXH
: /* TODO: MMI_OPC_0_PMAXH */
26582 case MMI_OPC_0_PADDB
: /* TODO: MMI_OPC_0_PADDB */
26583 case MMI_OPC_0_PSUBB
: /* TODO: MMI_OPC_0_PSUBB */
26584 case MMI_OPC_0_PCGTB
: /* TODO: MMI_OPC_0_PCGTB */
26585 case MMI_OPC_0_PADDSW
: /* TODO: MMI_OPC_0_PADDSW */
26586 case MMI_OPC_0_PSUBSW
: /* TODO: MMI_OPC_0_PSUBSW */
26587 case MMI_OPC_0_PEXTLW
: /* TODO: MMI_OPC_0_PEXTLW */
26588 case MMI_OPC_0_PPACW
: /* TODO: MMI_OPC_0_PPACW */
26589 case MMI_OPC_0_PADDSH
: /* TODO: MMI_OPC_0_PADDSH */
26590 case MMI_OPC_0_PSUBSH
: /* TODO: MMI_OPC_0_PSUBSH */
26591 case MMI_OPC_0_PEXTLH
: /* TODO: MMI_OPC_0_PEXTLH */
26592 case MMI_OPC_0_PPACH
: /* TODO: MMI_OPC_0_PPACH */
26593 case MMI_OPC_0_PADDSB
: /* TODO: MMI_OPC_0_PADDSB */
26594 case MMI_OPC_0_PSUBSB
: /* TODO: MMI_OPC_0_PSUBSB */
26595 case MMI_OPC_0_PEXTLB
: /* TODO: MMI_OPC_0_PEXTLB */
26596 case MMI_OPC_0_PPACB
: /* TODO: MMI_OPC_0_PPACB */
26597 case MMI_OPC_0_PEXT5
: /* TODO: MMI_OPC_0_PEXT5 */
26598 case MMI_OPC_0_PPAC5
: /* TODO: MMI_OPC_0_PPAC5 */
26599 gen_reserved_instruction(ctx
); /* TODO: MMI_OPC_CLASS_MMI0 */
26602 MIPS_INVAL("TX79 MMI class MMI0");
26603 gen_reserved_instruction(ctx
);
26608 static void decode_mmi1(CPUMIPSState
*env
, DisasContext
*ctx
)
26610 uint32_t opc
= MASK_MMI1(ctx
->opcode
);
26613 case MMI_OPC_1_PABSW
: /* TODO: MMI_OPC_1_PABSW */
26614 case MMI_OPC_1_PCEQW
: /* TODO: MMI_OPC_1_PCEQW */
26615 case MMI_OPC_1_PMINW
: /* TODO: MMI_OPC_1_PMINW */
26616 case MMI_OPC_1_PADSBH
: /* TODO: MMI_OPC_1_PADSBH */
26617 case MMI_OPC_1_PABSH
: /* TODO: MMI_OPC_1_PABSH */
26618 case MMI_OPC_1_PCEQH
: /* TODO: MMI_OPC_1_PCEQH */
26619 case MMI_OPC_1_PMINH
: /* TODO: MMI_OPC_1_PMINH */
26620 case MMI_OPC_1_PCEQB
: /* TODO: MMI_OPC_1_PCEQB */
26621 case MMI_OPC_1_PADDUW
: /* TODO: MMI_OPC_1_PADDUW */
26622 case MMI_OPC_1_PSUBUW
: /* TODO: MMI_OPC_1_PSUBUW */
26623 case MMI_OPC_1_PEXTUW
: /* TODO: MMI_OPC_1_PEXTUW */
26624 case MMI_OPC_1_PADDUH
: /* TODO: MMI_OPC_1_PADDUH */
26625 case MMI_OPC_1_PSUBUH
: /* TODO: MMI_OPC_1_PSUBUH */
26626 case MMI_OPC_1_PEXTUH
: /* TODO: MMI_OPC_1_PEXTUH */
26627 case MMI_OPC_1_PADDUB
: /* TODO: MMI_OPC_1_PADDUB */
26628 case MMI_OPC_1_PSUBUB
: /* TODO: MMI_OPC_1_PSUBUB */
26629 case MMI_OPC_1_PEXTUB
: /* TODO: MMI_OPC_1_PEXTUB */
26630 case MMI_OPC_1_QFSRV
: /* TODO: MMI_OPC_1_QFSRV */
26631 gen_reserved_instruction(ctx
); /* TODO: MMI_OPC_CLASS_MMI1 */
26634 MIPS_INVAL("TX79 MMI class MMI1");
26635 gen_reserved_instruction(ctx
);
26640 static void decode_mmi2(CPUMIPSState
*env
, DisasContext
*ctx
)
26642 uint32_t opc
= MASK_MMI2(ctx
->opcode
);
26645 case MMI_OPC_2_PMADDW
: /* TODO: MMI_OPC_2_PMADDW */
26646 case MMI_OPC_2_PSLLVW
: /* TODO: MMI_OPC_2_PSLLVW */
26647 case MMI_OPC_2_PSRLVW
: /* TODO: MMI_OPC_2_PSRLVW */
26648 case MMI_OPC_2_PMSUBW
: /* TODO: MMI_OPC_2_PMSUBW */
26649 case MMI_OPC_2_PMFHI
: /* TODO: MMI_OPC_2_PMFHI */
26650 case MMI_OPC_2_PMFLO
: /* TODO: MMI_OPC_2_PMFLO */
26651 case MMI_OPC_2_PINTH
: /* TODO: MMI_OPC_2_PINTH */
26652 case MMI_OPC_2_PMULTW
: /* TODO: MMI_OPC_2_PMULTW */
26653 case MMI_OPC_2_PDIVW
: /* TODO: MMI_OPC_2_PDIVW */
26654 case MMI_OPC_2_PMADDH
: /* TODO: MMI_OPC_2_PMADDH */
26655 case MMI_OPC_2_PHMADH
: /* TODO: MMI_OPC_2_PHMADH */
26656 case MMI_OPC_2_PAND
: /* TODO: MMI_OPC_2_PAND */
26657 case MMI_OPC_2_PXOR
: /* TODO: MMI_OPC_2_PXOR */
26658 case MMI_OPC_2_PMSUBH
: /* TODO: MMI_OPC_2_PMSUBH */
26659 case MMI_OPC_2_PHMSBH
: /* TODO: MMI_OPC_2_PHMSBH */
26660 case MMI_OPC_2_PEXEH
: /* TODO: MMI_OPC_2_PEXEH */
26661 case MMI_OPC_2_PREVH
: /* TODO: MMI_OPC_2_PREVH */
26662 case MMI_OPC_2_PMULTH
: /* TODO: MMI_OPC_2_PMULTH */
26663 case MMI_OPC_2_PDIVBW
: /* TODO: MMI_OPC_2_PDIVBW */
26664 case MMI_OPC_2_PEXEW
: /* TODO: MMI_OPC_2_PEXEW */
26665 case MMI_OPC_2_PROT3W
: /* TODO: MMI_OPC_2_PROT3W */
26666 gen_reserved_instruction(ctx
); /* TODO: MMI_OPC_CLASS_MMI2 */
26668 case MMI_OPC_2_PCPYLD
:
26669 gen_mmi_pcpyld(ctx
);
26672 MIPS_INVAL("TX79 MMI class MMI2");
26673 gen_reserved_instruction(ctx
);
26678 static void decode_mmi3(CPUMIPSState
*env
, DisasContext
*ctx
)
26680 uint32_t opc
= MASK_MMI3(ctx
->opcode
);
26683 case MMI_OPC_3_PMADDUW
: /* TODO: MMI_OPC_3_PMADDUW */
26684 case MMI_OPC_3_PSRAVW
: /* TODO: MMI_OPC_3_PSRAVW */
26685 case MMI_OPC_3_PMTHI
: /* TODO: MMI_OPC_3_PMTHI */
26686 case MMI_OPC_3_PMTLO
: /* TODO: MMI_OPC_3_PMTLO */
26687 case MMI_OPC_3_PINTEH
: /* TODO: MMI_OPC_3_PINTEH */
26688 case MMI_OPC_3_PMULTUW
: /* TODO: MMI_OPC_3_PMULTUW */
26689 case MMI_OPC_3_PDIVUW
: /* TODO: MMI_OPC_3_PDIVUW */
26690 case MMI_OPC_3_POR
: /* TODO: MMI_OPC_3_POR */
26691 case MMI_OPC_3_PNOR
: /* TODO: MMI_OPC_3_PNOR */
26692 case MMI_OPC_3_PEXCH
: /* TODO: MMI_OPC_3_PEXCH */
26693 case MMI_OPC_3_PEXCW
: /* TODO: MMI_OPC_3_PEXCW */
26694 gen_reserved_instruction(ctx
); /* TODO: MMI_OPC_CLASS_MMI3 */
26696 case MMI_OPC_3_PCPYH
:
26697 gen_mmi_pcpyh(ctx
);
26699 case MMI_OPC_3_PCPYUD
:
26700 gen_mmi_pcpyud(ctx
);
26703 MIPS_INVAL("TX79 MMI class MMI3");
26704 gen_reserved_instruction(ctx
);
26709 static void decode_mmi(CPUMIPSState
*env
, DisasContext
*ctx
)
26711 uint32_t opc
= MASK_MMI(ctx
->opcode
);
26712 int rs
= extract32(ctx
->opcode
, 21, 5);
26713 int rt
= extract32(ctx
->opcode
, 16, 5);
26714 int rd
= extract32(ctx
->opcode
, 11, 5);
26717 case MMI_OPC_CLASS_MMI0
:
26718 decode_mmi0(env
, ctx
);
26720 case MMI_OPC_CLASS_MMI1
:
26721 decode_mmi1(env
, ctx
);
26723 case MMI_OPC_CLASS_MMI2
:
26724 decode_mmi2(env
, ctx
);
26726 case MMI_OPC_CLASS_MMI3
:
26727 decode_mmi3(env
, ctx
);
26729 case MMI_OPC_MULT1
:
26730 case MMI_OPC_MULTU1
:
26732 case MMI_OPC_MADDU
:
26733 case MMI_OPC_MADD1
:
26734 case MMI_OPC_MADDU1
:
26735 gen_mul_txx9(ctx
, opc
, rd
, rs
, rt
);
26738 case MMI_OPC_DIVU1
:
26739 gen_div1_tx79(ctx
, opc
, rs
, rt
);
26741 case MMI_OPC_MTLO1
:
26742 case MMI_OPC_MTHI1
:
26743 gen_HILO1_tx79(ctx
, opc
, rs
);
26745 case MMI_OPC_MFLO1
:
26746 case MMI_OPC_MFHI1
:
26747 gen_HILO1_tx79(ctx
, opc
, rd
);
26749 case MMI_OPC_PLZCW
: /* TODO: MMI_OPC_PLZCW */
26750 case MMI_OPC_PMFHL
: /* TODO: MMI_OPC_PMFHL */
26751 case MMI_OPC_PMTHL
: /* TODO: MMI_OPC_PMTHL */
26752 case MMI_OPC_PSLLH
: /* TODO: MMI_OPC_PSLLH */
26753 case MMI_OPC_PSRLH
: /* TODO: MMI_OPC_PSRLH */
26754 case MMI_OPC_PSRAH
: /* TODO: MMI_OPC_PSRAH */
26755 case MMI_OPC_PSLLW
: /* TODO: MMI_OPC_PSLLW */
26756 case MMI_OPC_PSRLW
: /* TODO: MMI_OPC_PSRLW */
26757 case MMI_OPC_PSRAW
: /* TODO: MMI_OPC_PSRAW */
26758 gen_reserved_instruction(ctx
); /* TODO: MMI_OPC_CLASS_MMI */
26761 MIPS_INVAL("TX79 MMI class");
26762 gen_reserved_instruction(ctx
);
26767 static void gen_mmi_lq(CPUMIPSState
*env
, DisasContext
*ctx
)
26769 gen_reserved_instruction(ctx
); /* TODO: MMI_OPC_LQ */
26772 static void gen_mmi_sq(DisasContext
*ctx
, int base
, int rt
, int offset
)
26774 gen_reserved_instruction(ctx
); /* TODO: MMI_OPC_SQ */
26778 * The TX79-specific instruction Store Quadword
26780 * +--------+-------+-------+------------------------+
26781 * | 011111 | base | rt | offset | SQ
26782 * +--------+-------+-------+------------------------+
26785 * has the same opcode as the Read Hardware Register instruction
26787 * +--------+-------+-------+-------+-------+--------+
26788 * | 011111 | 00000 | rt | rd | 00000 | 111011 | RDHWR
26789 * +--------+-------+-------+-------+-------+--------+
26792 * that is required, trapped and emulated by the Linux kernel. However, all
26793 * RDHWR encodings yield address error exceptions on the TX79 since the SQ
26794 * offset is odd. Therefore all valid SQ instructions can execute normally.
26795 * In user mode, QEMU must verify the upper and lower 11 bits to distinguish
26796 * between SQ and RDHWR, as the Linux kernel does.
26798 static void decode_mmi_sq(CPUMIPSState
*env
, DisasContext
*ctx
)
26800 int base
= extract32(ctx
->opcode
, 21, 5);
26801 int rt
= extract32(ctx
->opcode
, 16, 5);
26802 int offset
= extract32(ctx
->opcode
, 0, 16);
26804 #ifdef CONFIG_USER_ONLY
26805 uint32_t op1
= MASK_SPECIAL3(ctx
->opcode
);
26806 uint32_t op2
= extract32(ctx
->opcode
, 6, 5);
26808 if (base
== 0 && op2
== 0 && op1
== OPC_RDHWR
) {
26809 int rd
= extract32(ctx
->opcode
, 11, 5);
26811 gen_rdhwr(ctx
, rt
, rd
, 0);
26816 gen_mmi_sq(ctx
, base
, rt
, offset
);
26821 static void decode_opc_special3(CPUMIPSState
*env
, DisasContext
*ctx
)
26823 int rs
, rt
, rd
, sa
;
26827 rs
= (ctx
->opcode
>> 21) & 0x1f;
26828 rt
= (ctx
->opcode
>> 16) & 0x1f;
26829 rd
= (ctx
->opcode
>> 11) & 0x1f;
26830 sa
= (ctx
->opcode
>> 6) & 0x1f;
26831 imm
= sextract32(ctx
->opcode
, 7, 9);
26833 op1
= MASK_SPECIAL3(ctx
->opcode
);
26836 * EVA loads and stores overlap Loongson 2E instructions decoded by
26837 * decode_opc_special3_legacy(), so be careful to allow their decoding when
26850 check_cp0_enabled(ctx
);
26851 gen_ld(ctx
, op1
, rt
, rs
, imm
);
26858 check_cp0_enabled(ctx
);
26859 gen_st(ctx
, op1
, rt
, rs
, imm
);
26862 check_cp0_enabled(ctx
);
26863 gen_st_cond(ctx
, rt
, rs
, imm
, MO_TESL
, true);
26866 check_cp0_enabled(ctx
);
26867 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
26868 gen_cache_operation(ctx
, rt
, rs
, imm
);
26870 /* Treat as NOP. */
26873 check_cp0_enabled(ctx
);
26874 /* Treat as NOP. */
26882 check_insn(ctx
, ISA_MIPS_R2
);
26883 gen_bitops(ctx
, op1
, rt
, rs
, sa
, rd
);
26886 op2
= MASK_BSHFL(ctx
->opcode
);
26893 check_insn(ctx
, ISA_MIPS_R6
);
26894 decode_opc_special3_r6(env
, ctx
);
26897 check_insn(ctx
, ISA_MIPS_R2
);
26898 gen_bshfl(ctx
, op2
, rt
, rd
);
26902 #if defined(TARGET_MIPS64)
26909 check_insn(ctx
, ISA_MIPS_R2
);
26910 check_mips_64(ctx
);
26911 gen_bitops(ctx
, op1
, rt
, rs
, sa
, rd
);
26914 op2
= MASK_DBSHFL(ctx
->opcode
);
26925 check_insn(ctx
, ISA_MIPS_R6
);
26926 decode_opc_special3_r6(env
, ctx
);
26929 check_insn(ctx
, ISA_MIPS_R2
);
26930 check_mips_64(ctx
);
26931 op2
= MASK_DBSHFL(ctx
->opcode
);
26932 gen_bshfl(ctx
, op2
, rt
, rd
);
26938 gen_rdhwr(ctx
, rt
, rd
, extract32(ctx
->opcode
, 6, 3));
26943 TCGv t0
= tcg_temp_new();
26944 TCGv t1
= tcg_temp_new();
26946 gen_load_gpr(t0
, rt
);
26947 gen_load_gpr(t1
, rs
);
26948 gen_helper_fork(t0
, t1
);
26956 TCGv t0
= tcg_temp_new();
26958 gen_load_gpr(t0
, rs
);
26959 gen_helper_yield(t0
, cpu_env
, t0
);
26960 gen_store_gpr(t0
, rd
);
26965 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
26966 decode_opc_special3_r6(env
, ctx
);
26968 decode_opc_special3_legacy(env
, ctx
);
26973 static bool decode_opc_legacy(CPUMIPSState
*env
, DisasContext
*ctx
)
26976 int rs
, rt
, rd
, sa
;
26980 op
= MASK_OP_MAJOR(ctx
->opcode
);
26981 rs
= (ctx
->opcode
>> 21) & 0x1f;
26982 rt
= (ctx
->opcode
>> 16) & 0x1f;
26983 rd
= (ctx
->opcode
>> 11) & 0x1f;
26984 sa
= (ctx
->opcode
>> 6) & 0x1f;
26985 imm
= (int16_t)ctx
->opcode
;
26988 decode_opc_special(env
, ctx
);
26991 #if defined(TARGET_MIPS64)
26992 if ((ctx
->insn_flags
& INSN_R5900
) && (ctx
->insn_flags
& ASE_MMI
)) {
26993 decode_mmi(env
, ctx
);
26997 if (TARGET_LONG_BITS
== 32 && (ctx
->insn_flags
& ASE_MXU
)) {
26998 if (MASK_SPECIAL2(ctx
->opcode
) == OPC_MUL
) {
26999 gen_arith(ctx
, OPC_MUL
, rd
, rs
, rt
);
27001 decode_ase_mxu(ctx
, ctx
->opcode
);
27005 decode_opc_special2_legacy(env
, ctx
);
27008 #if defined(TARGET_MIPS64)
27009 if (ctx
->insn_flags
& INSN_R5900
) {
27010 decode_mmi_sq(env
, ctx
); /* MMI_OPC_SQ */
27012 decode_opc_special3(env
, ctx
);
27015 decode_opc_special3(env
, ctx
);
27019 op1
= MASK_REGIMM(ctx
->opcode
);
27021 case OPC_BLTZL
: /* REGIMM branches */
27025 check_insn(ctx
, ISA_MIPS2
);
27026 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
27030 gen_compute_branch(ctx
, op1
, 4, rs
, -1, imm
<< 2, 4);
27034 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
27036 /* OPC_NAL, OPC_BAL */
27037 gen_compute_branch(ctx
, op1
, 4, 0, -1, imm
<< 2, 4);
27039 gen_reserved_instruction(ctx
);
27042 gen_compute_branch(ctx
, op1
, 4, rs
, -1, imm
<< 2, 4);
27045 case OPC_TGEI
: /* REGIMM traps */
27052 check_insn(ctx
, ISA_MIPS2
);
27053 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
27054 gen_trap(ctx
, op1
, rs
, -1, imm
);
27057 check_insn(ctx
, ISA_MIPS_R6
);
27058 gen_reserved_instruction(ctx
);
27061 check_insn(ctx
, ISA_MIPS_R2
);
27063 * Break the TB to be able to sync copied instructions
27066 ctx
->base
.is_jmp
= DISAS_STOP
;
27068 case OPC_BPOSGE32
: /* MIPS DSP branch */
27069 #if defined(TARGET_MIPS64)
27073 gen_compute_branch(ctx
, op1
, 4, -1, -2, (int32_t)imm
<< 2, 4);
27075 #if defined(TARGET_MIPS64)
27077 check_insn(ctx
, ISA_MIPS_R6
);
27078 check_mips_64(ctx
);
27080 tcg_gen_addi_tl(cpu_gpr
[rs
], cpu_gpr
[rs
], (int64_t)imm
<< 32);
27084 check_insn(ctx
, ISA_MIPS_R6
);
27085 check_mips_64(ctx
);
27087 tcg_gen_addi_tl(cpu_gpr
[rs
], cpu_gpr
[rs
], (int64_t)imm
<< 48);
27091 default: /* Invalid */
27092 MIPS_INVAL("regimm");
27093 gen_reserved_instruction(ctx
);
27098 check_cp0_enabled(ctx
);
27099 op1
= MASK_CP0(ctx
->opcode
);
27107 #if defined(TARGET_MIPS64)
27111 #ifndef CONFIG_USER_ONLY
27112 gen_cp0(env
, ctx
, op1
, rt
, rd
);
27113 #endif /* !CONFIG_USER_ONLY */
27131 #ifndef CONFIG_USER_ONLY
27132 gen_cp0(env
, ctx
, MASK_C0(ctx
->opcode
), rt
, rd
);
27133 #endif /* !CONFIG_USER_ONLY */
27136 #ifndef CONFIG_USER_ONLY
27139 TCGv t0
= tcg_temp_new();
27141 op2
= MASK_MFMC0(ctx
->opcode
);
27145 gen_helper_dmt(t0
);
27146 gen_store_gpr(t0
, rt
);
27150 gen_helper_emt(t0
);
27151 gen_store_gpr(t0
, rt
);
27155 gen_helper_dvpe(t0
, cpu_env
);
27156 gen_store_gpr(t0
, rt
);
27160 gen_helper_evpe(t0
, cpu_env
);
27161 gen_store_gpr(t0
, rt
);
27164 check_insn(ctx
, ISA_MIPS_R6
);
27166 gen_helper_dvp(t0
, cpu_env
);
27167 gen_store_gpr(t0
, rt
);
27171 check_insn(ctx
, ISA_MIPS_R6
);
27173 gen_helper_evp(t0
, cpu_env
);
27174 gen_store_gpr(t0
, rt
);
27178 check_insn(ctx
, ISA_MIPS_R2
);
27179 save_cpu_state(ctx
, 1);
27180 gen_helper_di(t0
, cpu_env
);
27181 gen_store_gpr(t0
, rt
);
27183 * Stop translation as we may have switched
27184 * the execution mode.
27186 ctx
->base
.is_jmp
= DISAS_STOP
;
27189 check_insn(ctx
, ISA_MIPS_R2
);
27190 save_cpu_state(ctx
, 1);
27191 gen_helper_ei(t0
, cpu_env
);
27192 gen_store_gpr(t0
, rt
);
27194 * DISAS_STOP isn't sufficient, we need to ensure we break
27195 * out of translated code to check for pending interrupts.
27197 gen_save_pc(ctx
->base
.pc_next
+ 4);
27198 ctx
->base
.is_jmp
= DISAS_EXIT
;
27200 default: /* Invalid */
27201 MIPS_INVAL("mfmc0");
27202 gen_reserved_instruction(ctx
);
27207 #endif /* !CONFIG_USER_ONLY */
27210 check_insn(ctx
, ISA_MIPS_R2
);
27211 gen_load_srsgpr(rt
, rd
);
27214 check_insn(ctx
, ISA_MIPS_R2
);
27215 gen_store_srsgpr(rt
, rd
);
27219 gen_reserved_instruction(ctx
);
27223 case OPC_BOVC
: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */
27224 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
27225 /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */
27226 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
27229 /* Arithmetic with immediate opcode */
27230 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
27234 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
27236 case OPC_SLTI
: /* Set on less than with immediate opcode */
27238 gen_slt_imm(ctx
, op
, rt
, rs
, imm
);
27240 case OPC_ANDI
: /* Arithmetic with immediate opcode */
27241 case OPC_LUI
: /* OPC_AUI */
27244 gen_logic_imm(ctx
, op
, rt
, rs
, imm
);
27246 case OPC_J
: /* Jump */
27248 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
27249 gen_compute_branch(ctx
, op
, 4, rs
, rt
, offset
, 4);
27252 case OPC_BLEZC
: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */
27253 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
27255 gen_reserved_instruction(ctx
);
27258 /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */
27259 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
27262 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
27265 case OPC_BGTZC
: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */
27266 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
27268 gen_reserved_instruction(ctx
);
27271 /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */
27272 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
27275 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
27278 case OPC_BLEZALC
: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */
27281 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
27283 check_insn(ctx
, ISA_MIPS_R6
);
27284 /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */
27285 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
27288 case OPC_BGTZALC
: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */
27291 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
27293 check_insn(ctx
, ISA_MIPS_R6
);
27294 /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */
27295 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
27300 check_insn(ctx
, ISA_MIPS2
);
27301 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
27305 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
27307 case OPC_LL
: /* Load and stores */
27308 check_insn(ctx
, ISA_MIPS2
);
27309 if (ctx
->insn_flags
& INSN_R5900
) {
27310 check_insn_opc_user_only(ctx
, INSN_R5900
);
27321 gen_ld(ctx
, op
, rt
, rs
, imm
);
27328 gen_st(ctx
, op
, rt
, rs
, imm
);
27331 check_insn(ctx
, ISA_MIPS2
);
27332 if (ctx
->insn_flags
& INSN_R5900
) {
27333 check_insn_opc_user_only(ctx
, INSN_R5900
);
27335 gen_st_cond(ctx
, rt
, rs
, imm
, MO_TESL
, false);
27338 check_cp0_enabled(ctx
);
27339 check_insn(ctx
, ISA_MIPS3
| ISA_MIPS_R1
);
27340 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
27341 gen_cache_operation(ctx
, rt
, rs
, imm
);
27343 /* Treat as NOP. */
27346 if (ctx
->insn_flags
& INSN_R5900
) {
27347 /* Treat as NOP. */
27349 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS_R1
);
27350 /* Treat as NOP. */
27354 /* Floating point (COP1). */
27359 gen_cop1_ldst(ctx
, op
, rt
, rs
, imm
);
27363 op1
= MASK_CP1(ctx
->opcode
);
27368 check_cp1_enabled(ctx
);
27369 check_insn(ctx
, ISA_MIPS_R2
);
27375 check_cp1_enabled(ctx
);
27376 gen_cp1(ctx
, op1
, rt
, rd
);
27378 #if defined(TARGET_MIPS64)
27381 check_cp1_enabled(ctx
);
27382 check_insn(ctx
, ISA_MIPS3
);
27383 check_mips_64(ctx
);
27384 gen_cp1(ctx
, op1
, rt
, rd
);
27387 case OPC_BC1EQZ
: /* OPC_BC1ANY2 */
27388 check_cp1_enabled(ctx
);
27389 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
27391 gen_compute_branch1_r6(ctx
, MASK_CP1(ctx
->opcode
),
27396 check_insn(ctx
, ASE_MIPS3D
);
27397 gen_compute_branch1(ctx
, MASK_BC1(ctx
->opcode
),
27398 (rt
>> 2) & 0x7, imm
<< 2);
27402 check_cp1_enabled(ctx
);
27403 check_insn(ctx
, ISA_MIPS_R6
);
27404 gen_compute_branch1_r6(ctx
, MASK_CP1(ctx
->opcode
),
27408 check_cp1_enabled(ctx
);
27409 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
27411 check_insn(ctx
, ASE_MIPS3D
);
27414 check_cp1_enabled(ctx
);
27415 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
27416 gen_compute_branch1(ctx
, MASK_BC1(ctx
->opcode
),
27417 (rt
>> 2) & 0x7, imm
<< 2);
27424 check_cp1_enabled(ctx
);
27425 gen_farith(ctx
, ctx
->opcode
& FOP(0x3f, 0x1f), rt
, rd
, sa
,
27431 int r6_op
= ctx
->opcode
& FOP(0x3f, 0x1f);
27432 check_cp1_enabled(ctx
);
27433 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
27435 case R6_OPC_CMP_AF_S
:
27436 case R6_OPC_CMP_UN_S
:
27437 case R6_OPC_CMP_EQ_S
:
27438 case R6_OPC_CMP_UEQ_S
:
27439 case R6_OPC_CMP_LT_S
:
27440 case R6_OPC_CMP_ULT_S
:
27441 case R6_OPC_CMP_LE_S
:
27442 case R6_OPC_CMP_ULE_S
:
27443 case R6_OPC_CMP_SAF_S
:
27444 case R6_OPC_CMP_SUN_S
:
27445 case R6_OPC_CMP_SEQ_S
:
27446 case R6_OPC_CMP_SEUQ_S
:
27447 case R6_OPC_CMP_SLT_S
:
27448 case R6_OPC_CMP_SULT_S
:
27449 case R6_OPC_CMP_SLE_S
:
27450 case R6_OPC_CMP_SULE_S
:
27451 case R6_OPC_CMP_OR_S
:
27452 case R6_OPC_CMP_UNE_S
:
27453 case R6_OPC_CMP_NE_S
:
27454 case R6_OPC_CMP_SOR_S
:
27455 case R6_OPC_CMP_SUNE_S
:
27456 case R6_OPC_CMP_SNE_S
:
27457 gen_r6_cmp_s(ctx
, ctx
->opcode
& 0x1f, rt
, rd
, sa
);
27459 case R6_OPC_CMP_AF_D
:
27460 case R6_OPC_CMP_UN_D
:
27461 case R6_OPC_CMP_EQ_D
:
27462 case R6_OPC_CMP_UEQ_D
:
27463 case R6_OPC_CMP_LT_D
:
27464 case R6_OPC_CMP_ULT_D
:
27465 case R6_OPC_CMP_LE_D
:
27466 case R6_OPC_CMP_ULE_D
:
27467 case R6_OPC_CMP_SAF_D
:
27468 case R6_OPC_CMP_SUN_D
:
27469 case R6_OPC_CMP_SEQ_D
:
27470 case R6_OPC_CMP_SEUQ_D
:
27471 case R6_OPC_CMP_SLT_D
:
27472 case R6_OPC_CMP_SULT_D
:
27473 case R6_OPC_CMP_SLE_D
:
27474 case R6_OPC_CMP_SULE_D
:
27475 case R6_OPC_CMP_OR_D
:
27476 case R6_OPC_CMP_UNE_D
:
27477 case R6_OPC_CMP_NE_D
:
27478 case R6_OPC_CMP_SOR_D
:
27479 case R6_OPC_CMP_SUNE_D
:
27480 case R6_OPC_CMP_SNE_D
:
27481 gen_r6_cmp_d(ctx
, ctx
->opcode
& 0x1f, rt
, rd
, sa
);
27484 gen_farith(ctx
, ctx
->opcode
& FOP(0x3f, 0x1f),
27485 rt
, rd
, sa
, (imm
>> 8) & 0x7);
27490 gen_farith(ctx
, ctx
->opcode
& FOP(0x3f, 0x1f), rt
, rd
, sa
,
27497 gen_reserved_instruction(ctx
);
27502 /* Compact branches [R6] and COP2 [non-R6] */
27503 case OPC_BC
: /* OPC_LWC2 */
27504 case OPC_BALC
: /* OPC_SWC2 */
27505 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
27506 /* OPC_BC, OPC_BALC */
27507 gen_compute_compact_branch(ctx
, op
, 0, 0,
27508 sextract32(ctx
->opcode
<< 2, 0, 28));
27509 } else if (ctx
->insn_flags
& ASE_LEXT
) {
27510 gen_loongson_lswc2(ctx
, rt
, rs
, rd
);
27512 /* OPC_LWC2, OPC_SWC2 */
27513 /* COP2: Not implemented. */
27514 generate_exception_err(ctx
, EXCP_CpU
, 2);
27517 case OPC_BEQZC
: /* OPC_JIC, OPC_LDC2 */
27518 case OPC_BNEZC
: /* OPC_JIALC, OPC_SDC2 */
27519 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
27521 /* OPC_BEQZC, OPC_BNEZC */
27522 gen_compute_compact_branch(ctx
, op
, rs
, 0,
27523 sextract32(ctx
->opcode
<< 2, 0, 23));
27525 /* OPC_JIC, OPC_JIALC */
27526 gen_compute_compact_branch(ctx
, op
, 0, rt
, imm
);
27528 } else if (ctx
->insn_flags
& ASE_LEXT
) {
27529 gen_loongson_lsdc2(ctx
, rt
, rs
, rd
);
27531 /* OPC_LWC2, OPC_SWC2 */
27532 /* COP2: Not implemented. */
27533 generate_exception_err(ctx
, EXCP_CpU
, 2);
27537 check_insn(ctx
, ASE_LMMI
);
27538 /* Note that these instructions use different fields. */
27539 gen_loongson_multimedia(ctx
, sa
, rd
, rt
);
27543 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
27544 check_cp1_enabled(ctx
);
27545 op1
= MASK_CP3(ctx
->opcode
);
27549 check_insn(ctx
, ISA_MIPS5
| ISA_MIPS_R2
);
27555 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS_R2
);
27556 gen_flt3_ldst(ctx
, op1
, sa
, rd
, rs
, rt
);
27559 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS_R2
);
27560 /* Treat as NOP. */
27563 check_insn(ctx
, ISA_MIPS5
| ISA_MIPS_R2
);
27577 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS_R2
);
27578 gen_flt3_arith(ctx
, op1
, sa
, rs
, rd
, rt
);
27582 gen_reserved_instruction(ctx
);
27586 generate_exception_err(ctx
, EXCP_CpU
, 1);
27590 #if defined(TARGET_MIPS64)
27591 /* MIPS64 opcodes */
27593 if (ctx
->insn_flags
& INSN_R5900
) {
27594 check_insn_opc_user_only(ctx
, INSN_R5900
);
27601 check_insn(ctx
, ISA_MIPS3
);
27602 check_mips_64(ctx
);
27603 gen_ld(ctx
, op
, rt
, rs
, imm
);
27608 check_insn(ctx
, ISA_MIPS3
);
27609 check_mips_64(ctx
);
27610 gen_st(ctx
, op
, rt
, rs
, imm
);
27613 check_insn(ctx
, ISA_MIPS3
);
27614 if (ctx
->insn_flags
& INSN_R5900
) {
27615 check_insn_opc_user_only(ctx
, INSN_R5900
);
27617 check_mips_64(ctx
);
27618 gen_st_cond(ctx
, rt
, rs
, imm
, MO_TEQ
, false);
27620 case OPC_BNVC
: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */
27621 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
27622 /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */
27623 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
27626 check_insn(ctx
, ISA_MIPS3
);
27627 check_mips_64(ctx
);
27628 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
27632 check_insn(ctx
, ISA_MIPS3
);
27633 check_mips_64(ctx
);
27634 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
27637 case OPC_BNVC
: /* OPC_BNEZALC, OPC_BNEC */
27638 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
27639 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
27641 MIPS_INVAL("major opcode");
27642 gen_reserved_instruction(ctx
);
27646 case OPC_DAUI
: /* OPC_JALX */
27647 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
27648 #if defined(TARGET_MIPS64)
27650 check_mips_64(ctx
);
27652 generate_exception(ctx
, EXCP_RI
);
27653 } else if (rt
!= 0) {
27654 TCGv t0
= tcg_temp_new();
27655 gen_load_gpr(t0
, rs
);
27656 tcg_gen_addi_tl(cpu_gpr
[rt
], t0
, imm
<< 16);
27660 gen_reserved_instruction(ctx
);
27661 MIPS_INVAL("major opcode");
27665 check_insn(ctx
, ASE_MIPS16
| ASE_MICROMIPS
);
27666 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
27667 gen_compute_branch(ctx
, op
, 4, rs
, rt
, offset
, 4);
27670 case OPC_MDMX
: /* MMI_OPC_LQ */
27671 if (ctx
->insn_flags
& INSN_R5900
) {
27672 #if defined(TARGET_MIPS64)
27673 gen_mmi_lq(env
, ctx
);
27676 /* MDMX: Not implemented. */
27680 check_insn(ctx
, ISA_MIPS_R6
);
27681 gen_pcrel(ctx
, ctx
->opcode
, ctx
->base
.pc_next
, rs
);
27683 default: /* Invalid */
27684 MIPS_INVAL("major opcode");
27690 static void decode_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
27692 /* make sure instructions are on a word boundary */
27693 if (ctx
->base
.pc_next
& 0x3) {
27694 env
->CP0_BadVAddr
= ctx
->base
.pc_next
;
27695 generate_exception_err(ctx
, EXCP_AdEL
, EXCP_INST_NOTAVAIL
);
27699 /* Handle blikely not taken case */
27700 if ((ctx
->hflags
& MIPS_HFLAG_BMASK_BASE
) == MIPS_HFLAG_BL
) {
27701 TCGLabel
*l1
= gen_new_label();
27703 tcg_gen_brcondi_tl(TCG_COND_NE
, bcond
, 0, l1
);
27704 tcg_gen_movi_i32(hflags
, ctx
->hflags
& ~MIPS_HFLAG_BMASK
);
27705 gen_goto_tb(ctx
, 1, ctx
->base
.pc_next
+ 4);
27709 /* Transition to the auto-generated decoder. */
27711 /* ISA extensions */
27712 if (ase_msa_available(env
) && decode_ase_msa(ctx
, ctx
->opcode
)) {
27716 /* ISA (from latest to oldest) */
27717 if (cpu_supports_isa(env
, ISA_MIPS_R6
) && decode_isa_rel6(ctx
, ctx
->opcode
)) {
27721 if (decode_opc_legacy(env
, ctx
)) {
27725 gen_reserved_instruction(ctx
);
27728 static void mips_tr_init_disas_context(DisasContextBase
*dcbase
, CPUState
*cs
)
27730 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
27731 CPUMIPSState
*env
= cs
->env_ptr
;
27733 ctx
->page_start
= ctx
->base
.pc_first
& TARGET_PAGE_MASK
;
27734 ctx
->saved_pc
= -1;
27735 ctx
->insn_flags
= env
->insn_flags
;
27736 ctx
->CP0_Config1
= env
->CP0_Config1
;
27737 ctx
->CP0_Config2
= env
->CP0_Config2
;
27738 ctx
->CP0_Config3
= env
->CP0_Config3
;
27739 ctx
->CP0_Config5
= env
->CP0_Config5
;
27741 ctx
->kscrexist
= (env
->CP0_Config4
>> CP0C4_KScrExist
) & 0xff;
27742 ctx
->rxi
= (env
->CP0_Config3
>> CP0C3_RXI
) & 1;
27743 ctx
->ie
= (env
->CP0_Config4
>> CP0C4_IE
) & 3;
27744 ctx
->bi
= (env
->CP0_Config3
>> CP0C3_BI
) & 1;
27745 ctx
->bp
= (env
->CP0_Config3
>> CP0C3_BP
) & 1;
27746 ctx
->PAMask
= env
->PAMask
;
27747 ctx
->mvh
= (env
->CP0_Config5
>> CP0C5_MVH
) & 1;
27748 ctx
->eva
= (env
->CP0_Config5
>> CP0C5_EVA
) & 1;
27749 ctx
->sc
= (env
->CP0_Config3
>> CP0C3_SC
) & 1;
27750 ctx
->CP0_LLAddr_shift
= env
->CP0_LLAddr_shift
;
27751 ctx
->cmgcr
= (env
->CP0_Config3
>> CP0C3_CMGCR
) & 1;
27752 /* Restore delay slot state from the tb context. */
27753 ctx
->hflags
= (uint32_t)ctx
->base
.tb
->flags
; /* FIXME: maybe use 64 bits? */
27754 ctx
->ulri
= (env
->CP0_Config3
>> CP0C3_ULRI
) & 1;
27755 ctx
->ps
= ((env
->active_fpu
.fcr0
>> FCR0_PS
) & 1) ||
27756 (env
->insn_flags
& (INSN_LOONGSON2E
| INSN_LOONGSON2F
));
27757 ctx
->vp
= (env
->CP0_Config5
>> CP0C5_VP
) & 1;
27758 ctx
->mrp
= (env
->CP0_Config5
>> CP0C5_MRP
) & 1;
27759 ctx
->nan2008
= (env
->active_fpu
.fcr31
>> FCR31_NAN2008
) & 1;
27760 ctx
->abs2008
= (env
->active_fpu
.fcr31
>> FCR31_ABS2008
) & 1;
27761 ctx
->mi
= (env
->CP0_Config5
>> CP0C5_MI
) & 1;
27762 ctx
->gi
= (env
->CP0_Config5
>> CP0C5_GI
) & 3;
27763 restore_cpu_state(env
, ctx
);
27764 #ifdef CONFIG_USER_ONLY
27765 ctx
->mem_idx
= MIPS_HFLAG_UM
;
27767 ctx
->mem_idx
= hflags_mmu_index(ctx
->hflags
);
27769 ctx
->default_tcg_memop_mask
= (ctx
->insn_flags
& (ISA_MIPS_R6
|
27770 INSN_LOONGSON3A
)) ? MO_UNALN
: MO_ALIGN
;
27772 LOG_DISAS("\ntb %p idx %d hflags %04x\n", ctx
->base
.tb
, ctx
->mem_idx
,
27776 static void mips_tr_tb_start(DisasContextBase
*dcbase
, CPUState
*cs
)
27780 static void mips_tr_insn_start(DisasContextBase
*dcbase
, CPUState
*cs
)
27782 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
27784 tcg_gen_insn_start(ctx
->base
.pc_next
, ctx
->hflags
& MIPS_HFLAG_BMASK
,
27788 static bool mips_tr_breakpoint_check(DisasContextBase
*dcbase
, CPUState
*cs
,
27789 const CPUBreakpoint
*bp
)
27791 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
27793 save_cpu_state(ctx
, 1);
27794 ctx
->base
.is_jmp
= DISAS_NORETURN
;
27795 gen_helper_raise_exception_debug(cpu_env
);
27797 * The address covered by the breakpoint must be included in
27798 * [tb->pc, tb->pc + tb->size) in order to for it to be
27799 * properly cleared -- thus we increment the PC here so that
27800 * the logic setting tb->size below does the right thing.
27802 ctx
->base
.pc_next
+= 4;
27806 static void mips_tr_translate_insn(DisasContextBase
*dcbase
, CPUState
*cs
)
27808 CPUMIPSState
*env
= cs
->env_ptr
;
27809 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
27813 is_slot
= ctx
->hflags
& MIPS_HFLAG_BMASK
;
27814 if (ctx
->insn_flags
& ISA_NANOMIPS32
) {
27815 ctx
->opcode
= translator_lduw(env
, ctx
->base
.pc_next
);
27816 insn_bytes
= decode_nanomips_opc(env
, ctx
);
27817 } else if (!(ctx
->hflags
& MIPS_HFLAG_M16
)) {
27818 ctx
->opcode
= translator_ldl(env
, ctx
->base
.pc_next
);
27820 decode_opc(env
, ctx
);
27821 } else if (ctx
->insn_flags
& ASE_MICROMIPS
) {
27822 ctx
->opcode
= translator_lduw(env
, ctx
->base
.pc_next
);
27823 insn_bytes
= decode_micromips_opc(env
, ctx
);
27824 } else if (ctx
->insn_flags
& ASE_MIPS16
) {
27825 ctx
->opcode
= translator_lduw(env
, ctx
->base
.pc_next
);
27826 insn_bytes
= decode_mips16_opc(env
, ctx
);
27828 gen_reserved_instruction(ctx
);
27829 g_assert(ctx
->base
.is_jmp
== DISAS_NORETURN
);
27833 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
27834 if (!(ctx
->hflags
& (MIPS_HFLAG_BDS16
| MIPS_HFLAG_BDS32
|
27835 MIPS_HFLAG_FBNSLOT
))) {
27837 * Force to generate branch as there is neither delay nor
27842 if ((ctx
->hflags
& MIPS_HFLAG_M16
) &&
27843 (ctx
->hflags
& MIPS_HFLAG_FBNSLOT
)) {
27845 * Force to generate branch as microMIPS R6 doesn't restrict
27846 * branches in the forbidden slot.
27852 gen_branch(ctx
, insn_bytes
);
27854 ctx
->base
.pc_next
+= insn_bytes
;
27856 if (ctx
->base
.is_jmp
!= DISAS_NEXT
) {
27860 * Execute a branch and its delay slot as a single instruction.
27861 * This is what GDB expects and is consistent with what the
27862 * hardware does (e.g. if a delay slot instruction faults, the
27863 * reported PC is the PC of the branch).
27865 if (ctx
->base
.singlestep_enabled
&&
27866 (ctx
->hflags
& MIPS_HFLAG_BMASK
) == 0) {
27867 ctx
->base
.is_jmp
= DISAS_TOO_MANY
;
27869 if (ctx
->base
.pc_next
- ctx
->page_start
>= TARGET_PAGE_SIZE
) {
27870 ctx
->base
.is_jmp
= DISAS_TOO_MANY
;
27874 static void mips_tr_tb_stop(DisasContextBase
*dcbase
, CPUState
*cs
)
27876 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
27878 if (ctx
->base
.singlestep_enabled
&& ctx
->base
.is_jmp
!= DISAS_NORETURN
) {
27879 save_cpu_state(ctx
, ctx
->base
.is_jmp
!= DISAS_EXIT
);
27880 gen_helper_raise_exception_debug(cpu_env
);
27882 switch (ctx
->base
.is_jmp
) {
27884 gen_save_pc(ctx
->base
.pc_next
);
27885 tcg_gen_lookup_and_goto_ptr();
27888 case DISAS_TOO_MANY
:
27889 save_cpu_state(ctx
, 0);
27890 gen_goto_tb(ctx
, 0, ctx
->base
.pc_next
);
27893 tcg_gen_exit_tb(NULL
, 0);
27895 case DISAS_NORETURN
:
27898 g_assert_not_reached();
27903 static void mips_tr_disas_log(const DisasContextBase
*dcbase
, CPUState
*cs
)
27905 qemu_log("IN: %s\n", lookup_symbol(dcbase
->pc_first
));
27906 log_target_disas(cs
, dcbase
->pc_first
, dcbase
->tb
->size
);
27909 static const TranslatorOps mips_tr_ops
= {
27910 .init_disas_context
= mips_tr_init_disas_context
,
27911 .tb_start
= mips_tr_tb_start
,
27912 .insn_start
= mips_tr_insn_start
,
27913 .breakpoint_check
= mips_tr_breakpoint_check
,
27914 .translate_insn
= mips_tr_translate_insn
,
27915 .tb_stop
= mips_tr_tb_stop
,
27916 .disas_log
= mips_tr_disas_log
,
27919 void gen_intermediate_code(CPUState
*cs
, TranslationBlock
*tb
, int max_insns
)
27923 translator_loop(&mips_tr_ops
, &ctx
.base
, cs
, tb
, max_insns
);
27926 static void fpu_dump_state(CPUMIPSState
*env
, FILE * f
, int flags
)
27929 int is_fpu64
= !!(env
->hflags
& MIPS_HFLAG_F64
);
27931 #define printfpr(fp) \
27934 qemu_fprintf(f, "w:%08x d:%016" PRIx64 \
27935 " fd:%13g fs:%13g psu: %13g\n", \
27936 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
27937 (double)(fp)->fd, \
27938 (double)(fp)->fs[FP_ENDIAN_IDX], \
27939 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
27942 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
27943 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
27944 qemu_fprintf(f, "w:%08x d:%016" PRIx64 \
27945 " fd:%13g fs:%13g psu:%13g\n", \
27946 tmp.w[FP_ENDIAN_IDX], tmp.d, \
27948 (double)tmp.fs[FP_ENDIAN_IDX], \
27949 (double)tmp.fs[!FP_ENDIAN_IDX]); \
27955 "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
27956 env
->active_fpu
.fcr0
, env
->active_fpu
.fcr31
, is_fpu64
,
27957 get_float_exception_flags(&env
->active_fpu
.fp_status
));
27958 for (i
= 0; i
< 32; (is_fpu64
) ? i
++ : (i
+= 2)) {
27959 qemu_fprintf(f
, "%3s: ", fregnames
[i
]);
27960 printfpr(&env
->active_fpu
.fpr
[i
]);
27966 void mips_cpu_dump_state(CPUState
*cs
, FILE *f
, int flags
)
27968 MIPSCPU
*cpu
= MIPS_CPU(cs
);
27969 CPUMIPSState
*env
= &cpu
->env
;
27972 qemu_fprintf(f
, "pc=0x" TARGET_FMT_lx
" HI=0x" TARGET_FMT_lx
27973 " LO=0x" TARGET_FMT_lx
" ds %04x "
27974 TARGET_FMT_lx
" " TARGET_FMT_ld
"\n",
27975 env
->active_tc
.PC
, env
->active_tc
.HI
[0], env
->active_tc
.LO
[0],
27976 env
->hflags
, env
->btarget
, env
->bcond
);
27977 for (i
= 0; i
< 32; i
++) {
27978 if ((i
& 3) == 0) {
27979 qemu_fprintf(f
, "GPR%02d:", i
);
27981 qemu_fprintf(f
, " %s " TARGET_FMT_lx
,
27982 regnames
[i
], env
->active_tc
.gpr
[i
]);
27983 if ((i
& 3) == 3) {
27984 qemu_fprintf(f
, "\n");
27988 qemu_fprintf(f
, "CP0 Status 0x%08x Cause 0x%08x EPC 0x"
27989 TARGET_FMT_lx
"\n",
27990 env
->CP0_Status
, env
->CP0_Cause
, env
->CP0_EPC
);
27991 qemu_fprintf(f
, " Config0 0x%08x Config1 0x%08x LLAddr 0x%016"
27993 env
->CP0_Config0
, env
->CP0_Config1
, env
->CP0_LLAddr
);
27994 qemu_fprintf(f
, " Config2 0x%08x Config3 0x%08x\n",
27995 env
->CP0_Config2
, env
->CP0_Config3
);
27996 qemu_fprintf(f
, " Config4 0x%08x Config5 0x%08x\n",
27997 env
->CP0_Config4
, env
->CP0_Config5
);
27998 if ((flags
& CPU_DUMP_FPU
) && (env
->hflags
& MIPS_HFLAG_FPU
)) {
27999 fpu_dump_state(env
, f
, flags
);
28003 void mips_tcg_init(void)
28008 for (i
= 1; i
< 32; i
++)
28009 cpu_gpr
[i
] = tcg_global_mem_new(cpu_env
,
28010 offsetof(CPUMIPSState
,
28013 #if defined(TARGET_MIPS64)
28014 cpu_gpr_hi
[0] = NULL
;
28016 for (unsigned i
= 1; i
< 32; i
++) {
28017 g_autofree
char *rname
= g_strdup_printf("%s[hi]", regnames
[i
]);
28019 cpu_gpr_hi
[i
] = tcg_global_mem_new_i64(cpu_env
,
28020 offsetof(CPUMIPSState
,
28021 active_tc
.gpr_hi
[i
]),
28024 #endif /* !TARGET_MIPS64 */
28025 for (i
= 0; i
< 32; i
++) {
28026 int off
= offsetof(CPUMIPSState
, active_fpu
.fpr
[i
].wr
.d
[0]);
28028 fpu_f64
[i
] = tcg_global_mem_new_i64(cpu_env
, off
, fregnames
[i
]);
28030 msa_translate_init();
28031 cpu_PC
= tcg_global_mem_new(cpu_env
,
28032 offsetof(CPUMIPSState
, active_tc
.PC
), "PC");
28033 for (i
= 0; i
< MIPS_DSP_ACC
; i
++) {
28034 cpu_HI
[i
] = tcg_global_mem_new(cpu_env
,
28035 offsetof(CPUMIPSState
, active_tc
.HI
[i
]),
28037 cpu_LO
[i
] = tcg_global_mem_new(cpu_env
,
28038 offsetof(CPUMIPSState
, active_tc
.LO
[i
]),
28041 cpu_dspctrl
= tcg_global_mem_new(cpu_env
,
28042 offsetof(CPUMIPSState
,
28043 active_tc
.DSPControl
),
28045 bcond
= tcg_global_mem_new(cpu_env
,
28046 offsetof(CPUMIPSState
, bcond
), "bcond");
28047 btarget
= tcg_global_mem_new(cpu_env
,
28048 offsetof(CPUMIPSState
, btarget
), "btarget");
28049 hflags
= tcg_global_mem_new_i32(cpu_env
,
28050 offsetof(CPUMIPSState
, hflags
), "hflags");
28052 fpu_fcr0
= tcg_global_mem_new_i32(cpu_env
,
28053 offsetof(CPUMIPSState
, active_fpu
.fcr0
),
28055 fpu_fcr31
= tcg_global_mem_new_i32(cpu_env
,
28056 offsetof(CPUMIPSState
, active_fpu
.fcr31
),
28058 cpu_lladdr
= tcg_global_mem_new(cpu_env
, offsetof(CPUMIPSState
, lladdr
),
28060 cpu_llval
= tcg_global_mem_new(cpu_env
, offsetof(CPUMIPSState
, llval
),
28063 if (TARGET_LONG_BITS
== 32) {
28064 mxu_translate_init();
28068 void restore_state_to_opc(CPUMIPSState
*env
, TranslationBlock
*tb
,
28069 target_ulong
*data
)
28071 env
->active_tc
.PC
= data
[0];
28072 env
->hflags
&= ~MIPS_HFLAG_BMASK
;
28073 env
->hflags
|= data
[1];
28074 switch (env
->hflags
& MIPS_HFLAG_BMASK_BASE
) {
28075 case MIPS_HFLAG_BR
:
28077 case MIPS_HFLAG_BC
:
28078 case MIPS_HFLAG_BL
:
28080 env
->btarget
= data
[2];