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 "hw/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_S32MADD
= 0x00,
1468 OPC_MXU_S32MADDU
= 0x01,
1469 OPC__MXU_MUL
= 0x02,
1470 OPC_MXU__POOL00
= 0x03,
1471 OPC_MXU_S32MSUB
= 0x04,
1472 OPC_MXU_S32MSUBU
= 0x05,
1473 OPC_MXU__POOL01
= 0x06,
1474 OPC_MXU__POOL02
= 0x07,
1475 OPC_MXU_D16MUL
= 0x08,
1476 OPC_MXU__POOL03
= 0x09,
1477 OPC_MXU_D16MAC
= 0x0A,
1478 OPC_MXU_D16MACF
= 0x0B,
1479 OPC_MXU_D16MADL
= 0x0C,
1480 OPC_MXU_S16MAD
= 0x0D,
1481 OPC_MXU_Q16ADD
= 0x0E,
1482 OPC_MXU_D16MACE
= 0x0F,
1483 OPC_MXU__POOL04
= 0x10,
1484 OPC_MXU__POOL05
= 0x11,
1485 OPC_MXU__POOL06
= 0x12,
1486 OPC_MXU__POOL07
= 0x13,
1487 OPC_MXU__POOL08
= 0x14,
1488 OPC_MXU__POOL09
= 0x15,
1489 OPC_MXU__POOL10
= 0x16,
1490 OPC_MXU__POOL11
= 0x17,
1491 OPC_MXU_D32ADD
= 0x18,
1492 OPC_MXU__POOL12
= 0x19,
1493 /* not assigned 0x1A */
1494 OPC_MXU__POOL13
= 0x1B,
1495 OPC_MXU__POOL14
= 0x1C,
1496 OPC_MXU_Q8ACCE
= 0x1D,
1497 /* not assigned 0x1E */
1498 /* not assigned 0x1F */
1499 /* not assigned 0x20 */
1500 /* not assigned 0x21 */
1501 OPC_MXU_S8LDD
= 0x22,
1502 OPC_MXU_S8STD
= 0x23,
1503 OPC_MXU_S8LDI
= 0x24,
1504 OPC_MXU_S8SDI
= 0x25,
1505 OPC_MXU__POOL15
= 0x26,
1506 OPC_MXU__POOL16
= 0x27,
1507 OPC_MXU__POOL17
= 0x28,
1508 /* not assigned 0x29 */
1509 OPC_MXU_S16LDD
= 0x2A,
1510 OPC_MXU_S16STD
= 0x2B,
1511 OPC_MXU_S16LDI
= 0x2C,
1512 OPC_MXU_S16SDI
= 0x2D,
1513 OPC_MXU_S32M2I
= 0x2E,
1514 OPC_MXU_S32I2M
= 0x2F,
1515 OPC_MXU_D32SLL
= 0x30,
1516 OPC_MXU_D32SLR
= 0x31,
1517 OPC_MXU_D32SARL
= 0x32,
1518 OPC_MXU_D32SAR
= 0x33,
1519 OPC_MXU_Q16SLL
= 0x34,
1520 OPC_MXU_Q16SLR
= 0x35,
1521 OPC_MXU__POOL18
= 0x36,
1522 OPC_MXU_Q16SAR
= 0x37,
1523 OPC_MXU__POOL19
= 0x38,
1524 OPC_MXU__POOL20
= 0x39,
1525 OPC_MXU__POOL21
= 0x3A,
1526 OPC_MXU_Q16SCOP
= 0x3B,
1527 OPC_MXU_Q8MADL
= 0x3C,
1528 OPC_MXU_S32SFL
= 0x3D,
1529 OPC_MXU_Q8SAD
= 0x3E,
1530 /* not assigned 0x3F */
1538 OPC_MXU_S32MAX
= 0x00,
1539 OPC_MXU_S32MIN
= 0x01,
1540 OPC_MXU_D16MAX
= 0x02,
1541 OPC_MXU_D16MIN
= 0x03,
1542 OPC_MXU_Q8MAX
= 0x04,
1543 OPC_MXU_Q8MIN
= 0x05,
1544 OPC_MXU_Q8SLT
= 0x06,
1545 OPC_MXU_Q8SLTU
= 0x07,
1552 OPC_MXU_S32SLT
= 0x00,
1553 OPC_MXU_D16SLT
= 0x01,
1554 OPC_MXU_D16AVG
= 0x02,
1555 OPC_MXU_D16AVGR
= 0x03,
1556 OPC_MXU_Q8AVG
= 0x04,
1557 OPC_MXU_Q8AVGR
= 0x05,
1558 OPC_MXU_Q8ADD
= 0x07,
1565 OPC_MXU_S32CPS
= 0x00,
1566 OPC_MXU_D16CPS
= 0x02,
1567 OPC_MXU_Q8ABD
= 0x04,
1568 OPC_MXU_Q16SAT
= 0x06,
1575 OPC_MXU_D16MULF
= 0x00,
1576 OPC_MXU_D16MULE
= 0x01,
1583 OPC_MXU_S32LDD
= 0x00,
1584 OPC_MXU_S32LDDR
= 0x01,
1591 OPC_MXU_S32STD
= 0x00,
1592 OPC_MXU_S32STDR
= 0x01,
1599 OPC_MXU_S32LDDV
= 0x00,
1600 OPC_MXU_S32LDDVR
= 0x01,
1607 OPC_MXU_S32STDV
= 0x00,
1608 OPC_MXU_S32STDVR
= 0x01,
1615 OPC_MXU_S32LDI
= 0x00,
1616 OPC_MXU_S32LDIR
= 0x01,
1623 OPC_MXU_S32SDI
= 0x00,
1624 OPC_MXU_S32SDIR
= 0x01,
1631 OPC_MXU_S32LDIV
= 0x00,
1632 OPC_MXU_S32LDIVR
= 0x01,
1639 OPC_MXU_S32SDIV
= 0x00,
1640 OPC_MXU_S32SDIVR
= 0x01,
1647 OPC_MXU_D32ACC
= 0x00,
1648 OPC_MXU_D32ACCM
= 0x01,
1649 OPC_MXU_D32ASUM
= 0x02,
1656 OPC_MXU_Q16ACC
= 0x00,
1657 OPC_MXU_Q16ACCM
= 0x01,
1658 OPC_MXU_Q16ASUM
= 0x02,
1665 OPC_MXU_Q8ADDE
= 0x00,
1666 OPC_MXU_D8SUM
= 0x01,
1667 OPC_MXU_D8SUMC
= 0x02,
1674 OPC_MXU_S32MUL
= 0x00,
1675 OPC_MXU_S32MULU
= 0x01,
1676 OPC_MXU_S32EXTR
= 0x02,
1677 OPC_MXU_S32EXTRV
= 0x03,
1684 OPC_MXU_D32SARW
= 0x00,
1685 OPC_MXU_S32ALN
= 0x01,
1686 OPC_MXU_S32ALNI
= 0x02,
1687 OPC_MXU_S32LUI
= 0x03,
1688 OPC_MXU_S32NOR
= 0x04,
1689 OPC_MXU_S32AND
= 0x05,
1690 OPC_MXU_S32OR
= 0x06,
1691 OPC_MXU_S32XOR
= 0x07,
1701 OPC_MXU_LXBU
= 0x04,
1702 OPC_MXU_LXHU
= 0x05,
1709 OPC_MXU_D32SLLV
= 0x00,
1710 OPC_MXU_D32SLRV
= 0x01,
1711 OPC_MXU_D32SARV
= 0x03,
1712 OPC_MXU_Q16SLLV
= 0x04,
1713 OPC_MXU_Q16SLRV
= 0x05,
1714 OPC_MXU_Q16SARV
= 0x07,
1721 OPC_MXU_Q8MUL
= 0x00,
1722 OPC_MXU_Q8MULSU
= 0x01,
1729 OPC_MXU_Q8MOVZ
= 0x00,
1730 OPC_MXU_Q8MOVN
= 0x01,
1731 OPC_MXU_D16MOVZ
= 0x02,
1732 OPC_MXU_D16MOVN
= 0x03,
1733 OPC_MXU_S32MOVZ
= 0x04,
1734 OPC_MXU_S32MOVN
= 0x05,
1741 OPC_MXU_Q8MAC
= 0x00,
1742 OPC_MXU_Q8MACSU
= 0x01,
1746 * Overview of the TX79-specific instruction set
1747 * =============================================
1749 * The R5900 and the C790 have 128-bit wide GPRs, where the upper 64 bits
1750 * are only used by the specific quadword (128-bit) LQ/SQ load/store
1751 * instructions and certain multimedia instructions (MMIs). These MMIs
1752 * configure the 128-bit data path as two 64-bit, four 32-bit, eight 16-bit
1753 * or sixteen 8-bit paths.
1757 * The Toshiba TX System RISC TX79 Core Architecture manual,
1758 * https://wiki.qemu.org/File:C790.pdf
1760 * Three-Operand Multiply and Multiply-Add (4 instructions)
1761 * --------------------------------------------------------
1762 * MADD [rd,] rs, rt Multiply/Add
1763 * MADDU [rd,] rs, rt Multiply/Add Unsigned
1764 * MULT [rd,] rs, rt Multiply (3-operand)
1765 * MULTU [rd,] rs, rt Multiply Unsigned (3-operand)
1767 * Multiply Instructions for Pipeline 1 (10 instructions)
1768 * ------------------------------------------------------
1769 * MULT1 [rd,] rs, rt Multiply Pipeline 1
1770 * MULTU1 [rd,] rs, rt Multiply Unsigned Pipeline 1
1771 * DIV1 rs, rt Divide Pipeline 1
1772 * DIVU1 rs, rt Divide Unsigned Pipeline 1
1773 * MADD1 [rd,] rs, rt Multiply-Add Pipeline 1
1774 * MADDU1 [rd,] rs, rt Multiply-Add Unsigned Pipeline 1
1775 * MFHI1 rd Move From HI1 Register
1776 * MFLO1 rd Move From LO1 Register
1777 * MTHI1 rs Move To HI1 Register
1778 * MTLO1 rs Move To LO1 Register
1780 * Arithmetic (19 instructions)
1781 * ----------------------------
1782 * PADDB rd, rs, rt Parallel Add Byte
1783 * PSUBB rd, rs, rt Parallel Subtract Byte
1784 * PADDH rd, rs, rt Parallel Add Halfword
1785 * PSUBH rd, rs, rt Parallel Subtract Halfword
1786 * PADDW rd, rs, rt Parallel Add Word
1787 * PSUBW rd, rs, rt Parallel Subtract Word
1788 * PADSBH rd, rs, rt Parallel Add/Subtract Halfword
1789 * PADDSB rd, rs, rt Parallel Add with Signed Saturation Byte
1790 * PSUBSB rd, rs, rt Parallel Subtract with Signed Saturation Byte
1791 * PADDSH rd, rs, rt Parallel Add with Signed Saturation Halfword
1792 * PSUBSH rd, rs, rt Parallel Subtract with Signed Saturation Halfword
1793 * PADDSW rd, rs, rt Parallel Add with Signed Saturation Word
1794 * PSUBSW rd, rs, rt Parallel Subtract with Signed Saturation Word
1795 * PADDUB rd, rs, rt Parallel Add with Unsigned saturation Byte
1796 * PSUBUB rd, rs, rt Parallel Subtract with Unsigned saturation Byte
1797 * PADDUH rd, rs, rt Parallel Add with Unsigned saturation Halfword
1798 * PSUBUH rd, rs, rt Parallel Subtract with Unsigned saturation Halfword
1799 * PADDUW rd, rs, rt Parallel Add with Unsigned saturation Word
1800 * PSUBUW rd, rs, rt Parallel Subtract with Unsigned saturation Word
1802 * Min/Max (4 instructions)
1803 * ------------------------
1804 * PMAXH rd, rs, rt Parallel Maximum Halfword
1805 * PMINH rd, rs, rt Parallel Minimum Halfword
1806 * PMAXW rd, rs, rt Parallel Maximum Word
1807 * PMINW rd, rs, rt Parallel Minimum Word
1809 * Absolute (2 instructions)
1810 * -------------------------
1811 * PABSH rd, rt Parallel Absolute Halfword
1812 * PABSW rd, rt Parallel Absolute Word
1814 * Logical (4 instructions)
1815 * ------------------------
1816 * PAND rd, rs, rt Parallel AND
1817 * POR rd, rs, rt Parallel OR
1818 * PXOR rd, rs, rt Parallel XOR
1819 * PNOR rd, rs, rt Parallel NOR
1821 * Shift (9 instructions)
1822 * ----------------------
1823 * PSLLH rd, rt, sa Parallel Shift Left Logical Halfword
1824 * PSRLH rd, rt, sa Parallel Shift Right Logical Halfword
1825 * PSRAH rd, rt, sa Parallel Shift Right Arithmetic Halfword
1826 * PSLLW rd, rt, sa Parallel Shift Left Logical Word
1827 * PSRLW rd, rt, sa Parallel Shift Right Logical Word
1828 * PSRAW rd, rt, sa Parallel Shift Right Arithmetic Word
1829 * PSLLVW rd, rt, rs Parallel Shift Left Logical Variable Word
1830 * PSRLVW rd, rt, rs Parallel Shift Right Logical Variable Word
1831 * PSRAVW rd, rt, rs Parallel Shift Right Arithmetic Variable Word
1833 * Compare (6 instructions)
1834 * ------------------------
1835 * PCGTB rd, rs, rt Parallel Compare for Greater Than Byte
1836 * PCEQB rd, rs, rt Parallel Compare for Equal Byte
1837 * PCGTH rd, rs, rt Parallel Compare for Greater Than Halfword
1838 * PCEQH rd, rs, rt Parallel Compare for Equal Halfword
1839 * PCGTW rd, rs, rt Parallel Compare for Greater Than Word
1840 * PCEQW rd, rs, rt Parallel Compare for Equal Word
1842 * LZC (1 instruction)
1843 * -------------------
1844 * PLZCW rd, rs Parallel Leading Zero or One Count Word
1846 * Quadword Load and Store (2 instructions)
1847 * ----------------------------------------
1848 * LQ rt, offset(base) Load Quadword
1849 * SQ rt, offset(base) Store Quadword
1851 * Multiply and Divide (19 instructions)
1852 * -------------------------------------
1853 * PMULTW rd, rs, rt Parallel Multiply Word
1854 * PMULTUW rd, rs, rt Parallel Multiply Unsigned Word
1855 * PDIVW rs, rt Parallel Divide Word
1856 * PDIVUW rs, rt Parallel Divide Unsigned Word
1857 * PMADDW rd, rs, rt Parallel Multiply-Add Word
1858 * PMADDUW rd, rs, rt Parallel Multiply-Add Unsigned Word
1859 * PMSUBW rd, rs, rt Parallel Multiply-Subtract Word
1860 * PMULTH rd, rs, rt Parallel Multiply Halfword
1861 * PMADDH rd, rs, rt Parallel Multiply-Add Halfword
1862 * PMSUBH rd, rs, rt Parallel Multiply-Subtract Halfword
1863 * PHMADH rd, rs, rt Parallel Horizontal Multiply-Add Halfword
1864 * PHMSBH rd, rs, rt Parallel Horizontal Multiply-Subtract Halfword
1865 * PDIVBW rs, rt Parallel Divide Broadcast Word
1866 * PMFHI rd Parallel Move From HI Register
1867 * PMFLO rd Parallel Move From LO Register
1868 * PMTHI rs Parallel Move To HI Register
1869 * PMTLO rs Parallel Move To LO Register
1870 * PMFHL rd Parallel Move From HI/LO Register
1871 * PMTHL rs Parallel Move To HI/LO Register
1873 * Pack/Extend (11 instructions)
1874 * -----------------------------
1875 * PPAC5 rd, rt Parallel Pack to 5 bits
1876 * PPACB rd, rs, rt Parallel Pack to Byte
1877 * PPACH rd, rs, rt Parallel Pack to Halfword
1878 * PPACW rd, rs, rt Parallel Pack to Word
1879 * PEXT5 rd, rt Parallel Extend Upper from 5 bits
1880 * PEXTUB rd, rs, rt Parallel Extend Upper from Byte
1881 * PEXTLB rd, rs, rt Parallel Extend Lower from Byte
1882 * PEXTUH rd, rs, rt Parallel Extend Upper from Halfword
1883 * PEXTLH rd, rs, rt Parallel Extend Lower from Halfword
1884 * PEXTUW rd, rs, rt Parallel Extend Upper from Word
1885 * PEXTLW rd, rs, rt Parallel Extend Lower from Word
1887 * Others (16 instructions)
1888 * ------------------------
1889 * PCPYH rd, rt Parallel Copy Halfword
1890 * PCPYLD rd, rs, rt Parallel Copy Lower Doubleword
1891 * PCPYUD rd, rs, rt Parallel Copy Upper Doubleword
1892 * PREVH rd, rt Parallel Reverse Halfword
1893 * PINTH rd, rs, rt Parallel Interleave Halfword
1894 * PINTEH rd, rs, rt Parallel Interleave Even Halfword
1895 * PEXEH rd, rt Parallel Exchange Even Halfword
1896 * PEXCH rd, rt Parallel Exchange Center Halfword
1897 * PEXEW rd, rt Parallel Exchange Even Word
1898 * PEXCW rd, rt Parallel Exchange Center Word
1899 * QFSRV rd, rs, rt Quadword Funnel Shift Right Variable
1900 * MFSA rd Move from Shift Amount Register
1901 * MTSA rs Move to Shift Amount Register
1902 * MTSAB rs, immediate Move Byte Count to Shift Amount Register
1903 * MTSAH rs, immediate Move Halfword Count to Shift Amount Register
1904 * PROT3W rd, rt Parallel Rotate 3 Words
1906 * MMI (MultiMedia Instruction) encodings
1907 * ======================================
1909 * MMI instructions encoding table keys:
1911 * * This code is reserved for future use. An attempt to execute it
1912 * causes a Reserved Instruction exception.
1913 * % This code indicates an instruction class. The instruction word
1914 * must be further decoded by examining additional tables that show
1915 * the values for other instruction fields.
1916 * # This code is reserved for the unsupported instructions DMULT,
1917 * DMULTU, DDIV, DDIVU, LL, LLD, SC, SCD, LWC2 and SWC2. An attempt
1918 * to execute it causes a Reserved Instruction exception.
1920 * MMI instructions encoded by opcode field (MMI, LQ, SQ):
1923 * +--------+----------------------------------------+
1925 * +--------+----------------------------------------+
1927 * opcode bits 28..26
1928 * bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
1929 * 31..29 | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111
1930 * -------+-------+-------+-------+-------+-------+-------+-------+-------
1931 * 0 000 |SPECIAL| REGIMM| J | JAL | BEQ | BNE | BLEZ | BGTZ
1932 * 1 001 | ADDI | ADDIU | SLTI | SLTIU | ANDI | ORI | XORI | LUI
1933 * 2 010 | COP0 | COP1 | * | * | BEQL | BNEL | BLEZL | BGTZL
1934 * 3 011 | DADDI | DADDIU| LDL | LDR | MMI% | * | LQ | SQ
1935 * 4 100 | LB | LH | LWL | LW | LBU | LHU | LWR | LWU
1936 * 5 101 | SB | SH | SWL | SW | SDL | SDR | SWR | CACHE
1937 * 6 110 | # | LWC1 | # | PREF | # | LDC1 | # | LD
1938 * 7 111 | # | SWC1 | # | * | # | SDC1 | # | SD
1942 MMI_OPC_CLASS_MMI
= 0x1C << 26, /* Same as OPC_SPECIAL2 */
1943 MMI_OPC_LQ
= 0x1E << 26, /* Same as OPC_MSA */
1944 MMI_OPC_SQ
= 0x1F << 26, /* Same as OPC_SPECIAL3 */
1948 * MMI instructions with opcode field = MMI:
1951 * +--------+-------------------------------+--------+
1952 * | MMI | |function|
1953 * +--------+-------------------------------+--------+
1955 * function bits 2..0
1956 * bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
1957 * 5..3 | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111
1958 * -------+-------+-------+-------+-------+-------+-------+-------+-------
1959 * 0 000 | MADD | MADDU | * | * | PLZCW | * | * | *
1960 * 1 001 | MMI0% | MMI2% | * | * | * | * | * | *
1961 * 2 010 | MFHI1 | MTHI1 | MFLO1 | MTLO1 | * | * | * | *
1962 * 3 011 | MULT1 | MULTU1| DIV1 | DIVU1 | * | * | * | *
1963 * 4 100 | MADD1 | MADDU1| * | * | * | * | * | *
1964 * 5 101 | MMI1% | MMI3% | * | * | * | * | * | *
1965 * 6 110 | PMFHL | PMTHL | * | * | PSLLH | * | PSRLH | PSRAH
1966 * 7 111 | * | * | * | * | PSLLW | * | PSRLW | PSRAW
1969 #define MASK_MMI(op) (MASK_OP_MAJOR(op) | ((op) & 0x3F))
1971 MMI_OPC_MADD
= 0x00 | MMI_OPC_CLASS_MMI
, /* Same as OPC_MADD */
1972 MMI_OPC_MADDU
= 0x01 | MMI_OPC_CLASS_MMI
, /* Same as OPC_MADDU */
1973 MMI_OPC_PLZCW
= 0x04 | MMI_OPC_CLASS_MMI
,
1974 MMI_OPC_CLASS_MMI0
= 0x08 | MMI_OPC_CLASS_MMI
,
1975 MMI_OPC_CLASS_MMI2
= 0x09 | MMI_OPC_CLASS_MMI
,
1976 MMI_OPC_MFHI1
= 0x10 | MMI_OPC_CLASS_MMI
, /* Same minor as OPC_MFHI */
1977 MMI_OPC_MTHI1
= 0x11 | MMI_OPC_CLASS_MMI
, /* Same minor as OPC_MTHI */
1978 MMI_OPC_MFLO1
= 0x12 | MMI_OPC_CLASS_MMI
, /* Same minor as OPC_MFLO */
1979 MMI_OPC_MTLO1
= 0x13 | MMI_OPC_CLASS_MMI
, /* Same minor as OPC_MTLO */
1980 MMI_OPC_MULT1
= 0x18 | MMI_OPC_CLASS_MMI
, /* Same minor as OPC_MULT */
1981 MMI_OPC_MULTU1
= 0x19 | MMI_OPC_CLASS_MMI
, /* Same min. as OPC_MULTU */
1982 MMI_OPC_DIV1
= 0x1A | MMI_OPC_CLASS_MMI
, /* Same minor as OPC_DIV */
1983 MMI_OPC_DIVU1
= 0x1B | MMI_OPC_CLASS_MMI
, /* Same minor as OPC_DIVU */
1984 MMI_OPC_MADD1
= 0x20 | MMI_OPC_CLASS_MMI
,
1985 MMI_OPC_MADDU1
= 0x21 | MMI_OPC_CLASS_MMI
,
1986 MMI_OPC_CLASS_MMI1
= 0x28 | MMI_OPC_CLASS_MMI
,
1987 MMI_OPC_CLASS_MMI3
= 0x29 | MMI_OPC_CLASS_MMI
,
1988 MMI_OPC_PMFHL
= 0x30 | MMI_OPC_CLASS_MMI
,
1989 MMI_OPC_PMTHL
= 0x31 | MMI_OPC_CLASS_MMI
,
1990 MMI_OPC_PSLLH
= 0x34 | MMI_OPC_CLASS_MMI
,
1991 MMI_OPC_PSRLH
= 0x36 | MMI_OPC_CLASS_MMI
,
1992 MMI_OPC_PSRAH
= 0x37 | MMI_OPC_CLASS_MMI
,
1993 MMI_OPC_PSLLW
= 0x3C | MMI_OPC_CLASS_MMI
,
1994 MMI_OPC_PSRLW
= 0x3E | MMI_OPC_CLASS_MMI
,
1995 MMI_OPC_PSRAW
= 0x3F | MMI_OPC_CLASS_MMI
,
1999 * MMI instructions with opcode field = MMI and bits 5..0 = MMI0:
2002 * +--------+----------------------+--------+--------+
2003 * | MMI | |function| MMI0 |
2004 * +--------+----------------------+--------+--------+
2006 * function bits 7..6
2007 * bits | 0 | 1 | 2 | 3
2008 * 10..8 | 00 | 01 | 10 | 11
2009 * -------+-------+-------+-------+-------
2010 * 0 000 | PADDW | PSUBW | PCGTW | PMAXW
2011 * 1 001 | PADDH | PSUBH | PCGTH | PMAXH
2012 * 2 010 | PADDB | PSUBB | PCGTB | *
2013 * 3 011 | * | * | * | *
2014 * 4 100 | PADDSW| PSUBSW| PEXTLW| PPACW
2015 * 5 101 | PADDSH| PSUBSH| PEXTLH| PPACH
2016 * 6 110 | PADDSB| PSUBSB| PEXTLB| PPACB
2017 * 7 111 | * | * | PEXT5 | PPAC5
2020 #define MASK_MMI0(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
2022 MMI_OPC_0_PADDW
= (0x00 << 6) | MMI_OPC_CLASS_MMI0
,
2023 MMI_OPC_0_PSUBW
= (0x01 << 6) | MMI_OPC_CLASS_MMI0
,
2024 MMI_OPC_0_PCGTW
= (0x02 << 6) | MMI_OPC_CLASS_MMI0
,
2025 MMI_OPC_0_PMAXW
= (0x03 << 6) | MMI_OPC_CLASS_MMI0
,
2026 MMI_OPC_0_PADDH
= (0x04 << 6) | MMI_OPC_CLASS_MMI0
,
2027 MMI_OPC_0_PSUBH
= (0x05 << 6) | MMI_OPC_CLASS_MMI0
,
2028 MMI_OPC_0_PCGTH
= (0x06 << 6) | MMI_OPC_CLASS_MMI0
,
2029 MMI_OPC_0_PMAXH
= (0x07 << 6) | MMI_OPC_CLASS_MMI0
,
2030 MMI_OPC_0_PADDB
= (0x08 << 6) | MMI_OPC_CLASS_MMI0
,
2031 MMI_OPC_0_PSUBB
= (0x09 << 6) | MMI_OPC_CLASS_MMI0
,
2032 MMI_OPC_0_PCGTB
= (0x0A << 6) | MMI_OPC_CLASS_MMI0
,
2033 MMI_OPC_0_PADDSW
= (0x10 << 6) | MMI_OPC_CLASS_MMI0
,
2034 MMI_OPC_0_PSUBSW
= (0x11 << 6) | MMI_OPC_CLASS_MMI0
,
2035 MMI_OPC_0_PEXTLW
= (0x12 << 6) | MMI_OPC_CLASS_MMI0
,
2036 MMI_OPC_0_PPACW
= (0x13 << 6) | MMI_OPC_CLASS_MMI0
,
2037 MMI_OPC_0_PADDSH
= (0x14 << 6) | MMI_OPC_CLASS_MMI0
,
2038 MMI_OPC_0_PSUBSH
= (0x15 << 6) | MMI_OPC_CLASS_MMI0
,
2039 MMI_OPC_0_PEXTLH
= (0x16 << 6) | MMI_OPC_CLASS_MMI0
,
2040 MMI_OPC_0_PPACH
= (0x17 << 6) | MMI_OPC_CLASS_MMI0
,
2041 MMI_OPC_0_PADDSB
= (0x18 << 6) | MMI_OPC_CLASS_MMI0
,
2042 MMI_OPC_0_PSUBSB
= (0x19 << 6) | MMI_OPC_CLASS_MMI0
,
2043 MMI_OPC_0_PEXTLB
= (0x1A << 6) | MMI_OPC_CLASS_MMI0
,
2044 MMI_OPC_0_PPACB
= (0x1B << 6) | MMI_OPC_CLASS_MMI0
,
2045 MMI_OPC_0_PEXT5
= (0x1E << 6) | MMI_OPC_CLASS_MMI0
,
2046 MMI_OPC_0_PPAC5
= (0x1F << 6) | MMI_OPC_CLASS_MMI0
,
2050 * MMI instructions with opcode field = MMI and bits 5..0 = MMI1:
2053 * +--------+----------------------+--------+--------+
2054 * | MMI | |function| MMI1 |
2055 * +--------+----------------------+--------+--------+
2057 * function bits 7..6
2058 * bits | 0 | 1 | 2 | 3
2059 * 10..8 | 00 | 01 | 10 | 11
2060 * -------+-------+-------+-------+-------
2061 * 0 000 | * | PABSW | PCEQW | PMINW
2062 * 1 001 | PADSBH| PABSH | PCEQH | PMINH
2063 * 2 010 | * | * | PCEQB | *
2064 * 3 011 | * | * | * | *
2065 * 4 100 | PADDUW| PSUBUW| PEXTUW| *
2066 * 5 101 | PADDUH| PSUBUH| PEXTUH| *
2067 * 6 110 | PADDUB| PSUBUB| PEXTUB| QFSRV
2068 * 7 111 | * | * | * | *
2071 #define MASK_MMI1(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
2073 MMI_OPC_1_PABSW
= (0x01 << 6) | MMI_OPC_CLASS_MMI1
,
2074 MMI_OPC_1_PCEQW
= (0x02 << 6) | MMI_OPC_CLASS_MMI1
,
2075 MMI_OPC_1_PMINW
= (0x03 << 6) | MMI_OPC_CLASS_MMI1
,
2076 MMI_OPC_1_PADSBH
= (0x04 << 6) | MMI_OPC_CLASS_MMI1
,
2077 MMI_OPC_1_PABSH
= (0x05 << 6) | MMI_OPC_CLASS_MMI1
,
2078 MMI_OPC_1_PCEQH
= (0x06 << 6) | MMI_OPC_CLASS_MMI1
,
2079 MMI_OPC_1_PMINH
= (0x07 << 6) | MMI_OPC_CLASS_MMI1
,
2080 MMI_OPC_1_PCEQB
= (0x0A << 6) | MMI_OPC_CLASS_MMI1
,
2081 MMI_OPC_1_PADDUW
= (0x10 << 6) | MMI_OPC_CLASS_MMI1
,
2082 MMI_OPC_1_PSUBUW
= (0x11 << 6) | MMI_OPC_CLASS_MMI1
,
2083 MMI_OPC_1_PEXTUW
= (0x12 << 6) | MMI_OPC_CLASS_MMI1
,
2084 MMI_OPC_1_PADDUH
= (0x14 << 6) | MMI_OPC_CLASS_MMI1
,
2085 MMI_OPC_1_PSUBUH
= (0x15 << 6) | MMI_OPC_CLASS_MMI1
,
2086 MMI_OPC_1_PEXTUH
= (0x16 << 6) | MMI_OPC_CLASS_MMI1
,
2087 MMI_OPC_1_PADDUB
= (0x18 << 6) | MMI_OPC_CLASS_MMI1
,
2088 MMI_OPC_1_PSUBUB
= (0x19 << 6) | MMI_OPC_CLASS_MMI1
,
2089 MMI_OPC_1_PEXTUB
= (0x1A << 6) | MMI_OPC_CLASS_MMI1
,
2090 MMI_OPC_1_QFSRV
= (0x1B << 6) | MMI_OPC_CLASS_MMI1
,
2094 * MMI instructions with opcode field = MMI and bits 5..0 = MMI2:
2097 * +--------+----------------------+--------+--------+
2098 * | MMI | |function| MMI2 |
2099 * +--------+----------------------+--------+--------+
2101 * function bits 7..6
2102 * bits | 0 | 1 | 2 | 3
2103 * 10..8 | 00 | 01 | 10 | 11
2104 * -------+-------+-------+-------+-------
2105 * 0 000 | PMADDW| * | PSLLVW| PSRLVW
2106 * 1 001 | PMSUBW| * | * | *
2107 * 2 010 | PMFHI | PMFLO | PINTH | *
2108 * 3 011 | PMULTW| PDIVW | PCPYLD| *
2109 * 4 100 | PMADDH| PHMADH| PAND | PXOR
2110 * 5 101 | PMSUBH| PHMSBH| * | *
2111 * 6 110 | * | * | PEXEH | PREVH
2112 * 7 111 | PMULTH| PDIVBW| PEXEW | PROT3W
2115 #define MASK_MMI2(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
2117 MMI_OPC_2_PMADDW
= (0x00 << 6) | MMI_OPC_CLASS_MMI2
,
2118 MMI_OPC_2_PSLLVW
= (0x02 << 6) | MMI_OPC_CLASS_MMI2
,
2119 MMI_OPC_2_PSRLVW
= (0x03 << 6) | MMI_OPC_CLASS_MMI2
,
2120 MMI_OPC_2_PMSUBW
= (0x04 << 6) | MMI_OPC_CLASS_MMI2
,
2121 MMI_OPC_2_PMFHI
= (0x08 << 6) | MMI_OPC_CLASS_MMI2
,
2122 MMI_OPC_2_PMFLO
= (0x09 << 6) | MMI_OPC_CLASS_MMI2
,
2123 MMI_OPC_2_PINTH
= (0x0A << 6) | MMI_OPC_CLASS_MMI2
,
2124 MMI_OPC_2_PMULTW
= (0x0C << 6) | MMI_OPC_CLASS_MMI2
,
2125 MMI_OPC_2_PDIVW
= (0x0D << 6) | MMI_OPC_CLASS_MMI2
,
2126 MMI_OPC_2_PCPYLD
= (0x0E << 6) | MMI_OPC_CLASS_MMI2
,
2127 MMI_OPC_2_PMADDH
= (0x10 << 6) | MMI_OPC_CLASS_MMI2
,
2128 MMI_OPC_2_PHMADH
= (0x11 << 6) | MMI_OPC_CLASS_MMI2
,
2129 MMI_OPC_2_PAND
= (0x12 << 6) | MMI_OPC_CLASS_MMI2
,
2130 MMI_OPC_2_PXOR
= (0x13 << 6) | MMI_OPC_CLASS_MMI2
,
2131 MMI_OPC_2_PMSUBH
= (0x14 << 6) | MMI_OPC_CLASS_MMI2
,
2132 MMI_OPC_2_PHMSBH
= (0x15 << 6) | MMI_OPC_CLASS_MMI2
,
2133 MMI_OPC_2_PEXEH
= (0x1A << 6) | MMI_OPC_CLASS_MMI2
,
2134 MMI_OPC_2_PREVH
= (0x1B << 6) | MMI_OPC_CLASS_MMI2
,
2135 MMI_OPC_2_PMULTH
= (0x1C << 6) | MMI_OPC_CLASS_MMI2
,
2136 MMI_OPC_2_PDIVBW
= (0x1D << 6) | MMI_OPC_CLASS_MMI2
,
2137 MMI_OPC_2_PEXEW
= (0x1E << 6) | MMI_OPC_CLASS_MMI2
,
2138 MMI_OPC_2_PROT3W
= (0x1F << 6) | MMI_OPC_CLASS_MMI2
,
2142 * MMI instructions with opcode field = MMI and bits 5..0 = MMI3:
2145 * +--------+----------------------+--------+--------+
2146 * | MMI | |function| MMI3 |
2147 * +--------+----------------------+--------+--------+
2149 * function bits 7..6
2150 * bits | 0 | 1 | 2 | 3
2151 * 10..8 | 00 | 01 | 10 | 11
2152 * -------+-------+-------+-------+-------
2153 * 0 000 |PMADDUW| * | * | PSRAVW
2154 * 1 001 | * | * | * | *
2155 * 2 010 | PMTHI | PMTLO | PINTEH| *
2156 * 3 011 |PMULTUW| PDIVUW| PCPYUD| *
2157 * 4 100 | * | * | POR | PNOR
2158 * 5 101 | * | * | * | *
2159 * 6 110 | * | * | PEXCH | PCPYH
2160 * 7 111 | * | * | PEXCW | *
2163 #define MASK_MMI3(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
2165 MMI_OPC_3_PMADDUW
= (0x00 << 6) | MMI_OPC_CLASS_MMI3
,
2166 MMI_OPC_3_PSRAVW
= (0x03 << 6) | MMI_OPC_CLASS_MMI3
,
2167 MMI_OPC_3_PMTHI
= (0x08 << 6) | MMI_OPC_CLASS_MMI3
,
2168 MMI_OPC_3_PMTLO
= (0x09 << 6) | MMI_OPC_CLASS_MMI3
,
2169 MMI_OPC_3_PINTEH
= (0x0A << 6) | MMI_OPC_CLASS_MMI3
,
2170 MMI_OPC_3_PMULTUW
= (0x0C << 6) | MMI_OPC_CLASS_MMI3
,
2171 MMI_OPC_3_PDIVUW
= (0x0D << 6) | MMI_OPC_CLASS_MMI3
,
2172 MMI_OPC_3_PCPYUD
= (0x0E << 6) | MMI_OPC_CLASS_MMI3
,
2173 MMI_OPC_3_POR
= (0x12 << 6) | MMI_OPC_CLASS_MMI3
,
2174 MMI_OPC_3_PNOR
= (0x13 << 6) | MMI_OPC_CLASS_MMI3
,
2175 MMI_OPC_3_PEXCH
= (0x1A << 6) | MMI_OPC_CLASS_MMI3
,
2176 MMI_OPC_3_PCPYH
= (0x1B << 6) | MMI_OPC_CLASS_MMI3
,
2177 MMI_OPC_3_PEXCW
= (0x1E << 6) | MMI_OPC_CLASS_MMI3
,
2180 /* global register indices */
2181 TCGv cpu_gpr
[32], cpu_PC
;
2183 * For CPUs using 128-bit GPR registers, we put the lower halves in cpu_gpr[])
2184 * and the upper halves in cpu_gpr_hi[].
2186 TCGv_i64 cpu_gpr_hi
[32];
2187 TCGv cpu_HI
[MIPS_DSP_ACC
], cpu_LO
[MIPS_DSP_ACC
];
2188 static TCGv cpu_dspctrl
, btarget
;
2190 static TCGv cpu_lladdr
, cpu_llval
;
2191 static TCGv_i32 hflags
;
2192 TCGv_i32 fpu_fcr0
, fpu_fcr31
;
2193 TCGv_i64 fpu_f64
[32];
2195 #if !defined(TARGET_MIPS64)
2197 static TCGv mxu_gpr
[NUMBER_OF_MXU_REGISTERS
- 1];
2201 #include "exec/gen-icount.h"
2203 #define gen_helper_0e0i(name, arg) do { \
2204 TCGv_i32 helper_tmp = tcg_const_i32(arg); \
2205 gen_helper_##name(cpu_env, helper_tmp); \
2206 tcg_temp_free_i32(helper_tmp); \
2209 #define gen_helper_0e1i(name, arg1, arg2) do { \
2210 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
2211 gen_helper_##name(cpu_env, arg1, helper_tmp); \
2212 tcg_temp_free_i32(helper_tmp); \
2215 #define gen_helper_1e0i(name, ret, arg1) do { \
2216 TCGv_i32 helper_tmp = tcg_const_i32(arg1); \
2217 gen_helper_##name(ret, cpu_env, helper_tmp); \
2218 tcg_temp_free_i32(helper_tmp); \
2221 #define gen_helper_1e1i(name, ret, arg1, arg2) do { \
2222 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
2223 gen_helper_##name(ret, cpu_env, arg1, helper_tmp); \
2224 tcg_temp_free_i32(helper_tmp); \
2227 #define gen_helper_0e2i(name, arg1, arg2, arg3) do { \
2228 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
2229 gen_helper_##name(cpu_env, arg1, arg2, helper_tmp); \
2230 tcg_temp_free_i32(helper_tmp); \
2233 #define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do { \
2234 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
2235 gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp); \
2236 tcg_temp_free_i32(helper_tmp); \
2239 #define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do { \
2240 TCGv_i32 helper_tmp = tcg_const_i32(arg4); \
2241 gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp); \
2242 tcg_temp_free_i32(helper_tmp); \
2245 #define DISAS_STOP DISAS_TARGET_0
2246 #define DISAS_EXIT DISAS_TARGET_1
2248 static const char * const regnames
[] = {
2249 "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
2250 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
2251 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
2252 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
2255 static const char * const regnames_HI
[] = {
2256 "HI0", "HI1", "HI2", "HI3",
2259 static const char * const regnames_LO
[] = {
2260 "LO0", "LO1", "LO2", "LO3",
2263 static const char * const fregnames
[] = {
2264 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
2265 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
2266 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
2267 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
2270 #if !defined(TARGET_MIPS64)
2271 static const char * const mxuregnames
[] = {
2272 "XR1", "XR2", "XR3", "XR4", "XR5", "XR6", "XR7", "XR8",
2273 "XR9", "XR10", "XR11", "XR12", "XR13", "XR14", "XR15", "MXU_CR",
2277 /* General purpose registers moves. */
2278 void gen_load_gpr(TCGv t
, int reg
)
2281 tcg_gen_movi_tl(t
, 0);
2283 tcg_gen_mov_tl(t
, cpu_gpr
[reg
]);
2287 void gen_store_gpr(TCGv t
, int reg
)
2290 tcg_gen_mov_tl(cpu_gpr
[reg
], t
);
2294 #if defined(TARGET_MIPS64)
2295 void gen_load_gpr_hi(TCGv_i64 t
, int reg
)
2298 tcg_gen_movi_i64(t
, 0);
2300 tcg_gen_mov_i64(t
, cpu_gpr_hi
[reg
]);
2304 void gen_store_gpr_hi(TCGv_i64 t
, int reg
)
2307 tcg_gen_mov_i64(cpu_gpr_hi
[reg
], t
);
2310 #endif /* TARGET_MIPS64 */
2312 /* Moves to/from shadow registers. */
2313 static inline void gen_load_srsgpr(int from
, int to
)
2315 TCGv t0
= tcg_temp_new();
2318 tcg_gen_movi_tl(t0
, 0);
2320 TCGv_i32 t2
= tcg_temp_new_i32();
2321 TCGv_ptr addr
= tcg_temp_new_ptr();
2323 tcg_gen_ld_i32(t2
, cpu_env
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
2324 tcg_gen_shri_i32(t2
, t2
, CP0SRSCtl_PSS
);
2325 tcg_gen_andi_i32(t2
, t2
, 0xf);
2326 tcg_gen_muli_i32(t2
, t2
, sizeof(target_ulong
) * 32);
2327 tcg_gen_ext_i32_ptr(addr
, t2
);
2328 tcg_gen_add_ptr(addr
, cpu_env
, addr
);
2330 tcg_gen_ld_tl(t0
, addr
, sizeof(target_ulong
) * from
);
2331 tcg_temp_free_ptr(addr
);
2332 tcg_temp_free_i32(t2
);
2334 gen_store_gpr(t0
, to
);
2338 static inline void gen_store_srsgpr(int from
, int to
)
2341 TCGv t0
= tcg_temp_new();
2342 TCGv_i32 t2
= tcg_temp_new_i32();
2343 TCGv_ptr addr
= tcg_temp_new_ptr();
2345 gen_load_gpr(t0
, from
);
2346 tcg_gen_ld_i32(t2
, cpu_env
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
2347 tcg_gen_shri_i32(t2
, t2
, CP0SRSCtl_PSS
);
2348 tcg_gen_andi_i32(t2
, t2
, 0xf);
2349 tcg_gen_muli_i32(t2
, t2
, sizeof(target_ulong
) * 32);
2350 tcg_gen_ext_i32_ptr(addr
, t2
);
2351 tcg_gen_add_ptr(addr
, cpu_env
, addr
);
2353 tcg_gen_st_tl(t0
, addr
, sizeof(target_ulong
) * to
);
2354 tcg_temp_free_ptr(addr
);
2355 tcg_temp_free_i32(t2
);
2360 #if !defined(TARGET_MIPS64)
2361 /* MXU General purpose registers moves. */
2362 static inline void gen_load_mxu_gpr(TCGv t
, unsigned int reg
)
2365 tcg_gen_movi_tl(t
, 0);
2366 } else if (reg
<= 15) {
2367 tcg_gen_mov_tl(t
, mxu_gpr
[reg
- 1]);
2371 static inline void gen_store_mxu_gpr(TCGv t
, unsigned int reg
)
2373 if (reg
> 0 && reg
<= 15) {
2374 tcg_gen_mov_tl(mxu_gpr
[reg
- 1], t
);
2378 /* MXU control register moves. */
2379 static inline void gen_load_mxu_cr(TCGv t
)
2381 tcg_gen_mov_tl(t
, mxu_CR
);
2384 static inline void gen_store_mxu_cr(TCGv t
)
2386 /* TODO: Add handling of RW rules for MXU_CR. */
2387 tcg_gen_mov_tl(mxu_CR
, t
);
2393 static inline void gen_save_pc(target_ulong pc
)
2395 tcg_gen_movi_tl(cpu_PC
, pc
);
2398 static inline void save_cpu_state(DisasContext
*ctx
, int do_save_pc
)
2400 LOG_DISAS("hflags %08x saved %08x\n", ctx
->hflags
, ctx
->saved_hflags
);
2401 if (do_save_pc
&& ctx
->base
.pc_next
!= ctx
->saved_pc
) {
2402 gen_save_pc(ctx
->base
.pc_next
);
2403 ctx
->saved_pc
= ctx
->base
.pc_next
;
2405 if (ctx
->hflags
!= ctx
->saved_hflags
) {
2406 tcg_gen_movi_i32(hflags
, ctx
->hflags
);
2407 ctx
->saved_hflags
= ctx
->hflags
;
2408 switch (ctx
->hflags
& MIPS_HFLAG_BMASK_BASE
) {
2414 tcg_gen_movi_tl(btarget
, ctx
->btarget
);
2420 static inline void restore_cpu_state(CPUMIPSState
*env
, DisasContext
*ctx
)
2422 ctx
->saved_hflags
= ctx
->hflags
;
2423 switch (ctx
->hflags
& MIPS_HFLAG_BMASK_BASE
) {
2429 ctx
->btarget
= env
->btarget
;
2434 void generate_exception_err(DisasContext
*ctx
, int excp
, int err
)
2436 TCGv_i32 texcp
= tcg_const_i32(excp
);
2437 TCGv_i32 terr
= tcg_const_i32(err
);
2438 save_cpu_state(ctx
, 1);
2439 gen_helper_raise_exception_err(cpu_env
, texcp
, terr
);
2440 tcg_temp_free_i32(terr
);
2441 tcg_temp_free_i32(texcp
);
2442 ctx
->base
.is_jmp
= DISAS_NORETURN
;
2445 void generate_exception(DisasContext
*ctx
, int excp
)
2447 gen_helper_0e0i(raise_exception
, excp
);
2450 void generate_exception_end(DisasContext
*ctx
, int excp
)
2452 generate_exception_err(ctx
, excp
, 0);
2455 void gen_reserved_instruction(DisasContext
*ctx
)
2457 generate_exception_end(ctx
, EXCP_RI
);
2460 /* Floating point register moves. */
2461 void gen_load_fpr32(DisasContext
*ctx
, TCGv_i32 t
, int reg
)
2463 if (ctx
->hflags
& MIPS_HFLAG_FRE
) {
2464 generate_exception(ctx
, EXCP_RI
);
2466 tcg_gen_extrl_i64_i32(t
, fpu_f64
[reg
]);
2469 void gen_store_fpr32(DisasContext
*ctx
, TCGv_i32 t
, int reg
)
2472 if (ctx
->hflags
& MIPS_HFLAG_FRE
) {
2473 generate_exception(ctx
, EXCP_RI
);
2475 t64
= tcg_temp_new_i64();
2476 tcg_gen_extu_i32_i64(t64
, t
);
2477 tcg_gen_deposit_i64(fpu_f64
[reg
], fpu_f64
[reg
], t64
, 0, 32);
2478 tcg_temp_free_i64(t64
);
2481 static void gen_load_fpr32h(DisasContext
*ctx
, TCGv_i32 t
, int reg
)
2483 if (ctx
->hflags
& MIPS_HFLAG_F64
) {
2484 tcg_gen_extrh_i64_i32(t
, fpu_f64
[reg
]);
2486 gen_load_fpr32(ctx
, t
, reg
| 1);
2490 static void gen_store_fpr32h(DisasContext
*ctx
, TCGv_i32 t
, int reg
)
2492 if (ctx
->hflags
& MIPS_HFLAG_F64
) {
2493 TCGv_i64 t64
= tcg_temp_new_i64();
2494 tcg_gen_extu_i32_i64(t64
, t
);
2495 tcg_gen_deposit_i64(fpu_f64
[reg
], fpu_f64
[reg
], t64
, 32, 32);
2496 tcg_temp_free_i64(t64
);
2498 gen_store_fpr32(ctx
, t
, reg
| 1);
2502 void gen_load_fpr64(DisasContext
*ctx
, TCGv_i64 t
, int reg
)
2504 if (ctx
->hflags
& MIPS_HFLAG_F64
) {
2505 tcg_gen_mov_i64(t
, fpu_f64
[reg
]);
2507 tcg_gen_concat32_i64(t
, fpu_f64
[reg
& ~1], fpu_f64
[reg
| 1]);
2511 void gen_store_fpr64(DisasContext
*ctx
, TCGv_i64 t
, int reg
)
2513 if (ctx
->hflags
& MIPS_HFLAG_F64
) {
2514 tcg_gen_mov_i64(fpu_f64
[reg
], t
);
2517 tcg_gen_deposit_i64(fpu_f64
[reg
& ~1], fpu_f64
[reg
& ~1], t
, 0, 32);
2518 t0
= tcg_temp_new_i64();
2519 tcg_gen_shri_i64(t0
, t
, 32);
2520 tcg_gen_deposit_i64(fpu_f64
[reg
| 1], fpu_f64
[reg
| 1], t0
, 0, 32);
2521 tcg_temp_free_i64(t0
);
2525 int get_fp_bit(int cc
)
2534 /* Addresses computation */
2535 void gen_op_addr_add(DisasContext
*ctx
, TCGv ret
, TCGv arg0
, TCGv arg1
)
2537 tcg_gen_add_tl(ret
, arg0
, arg1
);
2539 #if defined(TARGET_MIPS64)
2540 if (ctx
->hflags
& MIPS_HFLAG_AWRAP
) {
2541 tcg_gen_ext32s_i64(ret
, ret
);
2546 static inline void gen_op_addr_addi(DisasContext
*ctx
, TCGv ret
, TCGv base
,
2549 tcg_gen_addi_tl(ret
, base
, ofs
);
2551 #if defined(TARGET_MIPS64)
2552 if (ctx
->hflags
& MIPS_HFLAG_AWRAP
) {
2553 tcg_gen_ext32s_i64(ret
, ret
);
2558 /* Addresses computation (translation time) */
2559 static target_long
addr_add(DisasContext
*ctx
, target_long base
,
2562 target_long sum
= base
+ offset
;
2564 #if defined(TARGET_MIPS64)
2565 if (ctx
->hflags
& MIPS_HFLAG_AWRAP
) {
2572 /* Sign-extract the low 32-bits to a target_long. */
2573 void gen_move_low32(TCGv ret
, TCGv_i64 arg
)
2575 #if defined(TARGET_MIPS64)
2576 tcg_gen_ext32s_i64(ret
, arg
);
2578 tcg_gen_extrl_i64_i32(ret
, arg
);
2582 /* Sign-extract the high 32-bits to a target_long. */
2583 void gen_move_high32(TCGv ret
, TCGv_i64 arg
)
2585 #if defined(TARGET_MIPS64)
2586 tcg_gen_sari_i64(ret
, arg
, 32);
2588 tcg_gen_extrh_i64_i32(ret
, arg
);
2592 void check_cp0_enabled(DisasContext
*ctx
)
2594 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_CP0
))) {
2595 generate_exception_end(ctx
, EXCP_CpU
);
2599 void check_cp1_enabled(DisasContext
*ctx
)
2601 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_FPU
))) {
2602 generate_exception_err(ctx
, EXCP_CpU
, 1);
2607 * Verify that the processor is running with COP1X instructions enabled.
2608 * This is associated with the nabla symbol in the MIPS32 and MIPS64
2611 void check_cop1x(DisasContext
*ctx
)
2613 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_COP1X
))) {
2614 gen_reserved_instruction(ctx
);
2619 * Verify that the processor is running with 64-bit floating-point
2620 * operations enabled.
2622 void check_cp1_64bitmode(DisasContext
*ctx
)
2624 if (unlikely(~ctx
->hflags
& (MIPS_HFLAG_F64
| MIPS_HFLAG_COP1X
))) {
2625 gen_reserved_instruction(ctx
);
2630 * Verify if floating point register is valid; an operation is not defined
2631 * if bit 0 of any register specification is set and the FR bit in the
2632 * Status register equals zero, since the register numbers specify an
2633 * even-odd pair of adjacent coprocessor general registers. When the FR bit
2634 * in the Status register equals one, both even and odd register numbers
2635 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
2637 * Multiple 64 bit wide registers can be checked by calling
2638 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
2640 void check_cp1_registers(DisasContext
*ctx
, int regs
)
2642 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_F64
) && (regs
& 1))) {
2643 gen_reserved_instruction(ctx
);
2648 * Verify that the processor is running with DSP instructions enabled.
2649 * This is enabled by CP0 Status register MX(24) bit.
2651 static inline void check_dsp(DisasContext
*ctx
)
2653 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_DSP
))) {
2654 if (ctx
->insn_flags
& ASE_DSP
) {
2655 generate_exception_end(ctx
, EXCP_DSPDIS
);
2657 gen_reserved_instruction(ctx
);
2662 static inline void check_dsp_r2(DisasContext
*ctx
)
2664 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_DSP_R2
))) {
2665 if (ctx
->insn_flags
& ASE_DSP
) {
2666 generate_exception_end(ctx
, EXCP_DSPDIS
);
2668 gen_reserved_instruction(ctx
);
2673 static inline void check_dsp_r3(DisasContext
*ctx
)
2675 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_DSP_R3
))) {
2676 if (ctx
->insn_flags
& ASE_DSP
) {
2677 generate_exception_end(ctx
, EXCP_DSPDIS
);
2679 gen_reserved_instruction(ctx
);
2685 * This code generates a "reserved instruction" exception if the
2686 * CPU does not support the instruction set corresponding to flags.
2688 void check_insn(DisasContext
*ctx
, uint64_t flags
)
2690 if (unlikely(!(ctx
->insn_flags
& flags
))) {
2691 gen_reserved_instruction(ctx
);
2696 * This code generates a "reserved instruction" exception if the
2697 * CPU has corresponding flag set which indicates that the instruction
2700 static inline void check_insn_opc_removed(DisasContext
*ctx
, uint64_t flags
)
2702 if (unlikely(ctx
->insn_flags
& flags
)) {
2703 gen_reserved_instruction(ctx
);
2708 * The Linux kernel traps certain reserved instruction exceptions to
2709 * emulate the corresponding instructions. QEMU is the kernel in user
2710 * mode, so those traps are emulated by accepting the instructions.
2712 * A reserved instruction exception is generated for flagged CPUs if
2713 * QEMU runs in system mode.
2715 static inline void check_insn_opc_user_only(DisasContext
*ctx
, uint64_t flags
)
2717 #ifndef CONFIG_USER_ONLY
2718 check_insn_opc_removed(ctx
, flags
);
2723 * This code generates a "reserved instruction" exception if the
2724 * CPU does not support 64-bit paired-single (PS) floating point data type.
2726 static inline void check_ps(DisasContext
*ctx
)
2728 if (unlikely(!ctx
->ps
)) {
2729 generate_exception(ctx
, EXCP_RI
);
2731 check_cp1_64bitmode(ctx
);
2735 * This code generates a "reserved instruction" exception if cpu is not
2736 * 64-bit or 64-bit instructions are not enabled.
2738 void check_mips_64(DisasContext
*ctx
)
2740 if (unlikely((TARGET_LONG_BITS
!= 64) || !(ctx
->hflags
& MIPS_HFLAG_64
))) {
2741 gen_reserved_instruction(ctx
);
2745 #ifndef CONFIG_USER_ONLY
2746 static inline void check_mvh(DisasContext
*ctx
)
2748 if (unlikely(!ctx
->mvh
)) {
2749 generate_exception(ctx
, EXCP_RI
);
2755 * This code generates a "reserved instruction" exception if the
2756 * Config5 XNP bit is set.
2758 static inline void check_xnp(DisasContext
*ctx
)
2760 if (unlikely(ctx
->CP0_Config5
& (1 << CP0C5_XNP
))) {
2761 gen_reserved_instruction(ctx
);
2765 #ifndef CONFIG_USER_ONLY
2767 * This code generates a "reserved instruction" exception if the
2768 * Config3 PW bit is NOT set.
2770 static inline void check_pw(DisasContext
*ctx
)
2772 if (unlikely(!(ctx
->CP0_Config3
& (1 << CP0C3_PW
)))) {
2773 gen_reserved_instruction(ctx
);
2779 * This code generates a "reserved instruction" exception if the
2780 * Config3 MT bit is NOT set.
2782 static inline void check_mt(DisasContext
*ctx
)
2784 if (unlikely(!(ctx
->CP0_Config3
& (1 << CP0C3_MT
)))) {
2785 gen_reserved_instruction(ctx
);
2789 #ifndef CONFIG_USER_ONLY
2791 * This code generates a "coprocessor unusable" exception if CP0 is not
2792 * available, and, if that is not the case, generates a "reserved instruction"
2793 * exception if the Config5 MT bit is NOT set. This is needed for availability
2794 * control of some of MT ASE instructions.
2796 static inline void check_cp0_mt(DisasContext
*ctx
)
2798 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_CP0
))) {
2799 generate_exception_end(ctx
, EXCP_CpU
);
2801 if (unlikely(!(ctx
->CP0_Config3
& (1 << CP0C3_MT
)))) {
2802 gen_reserved_instruction(ctx
);
2809 * This code generates a "reserved instruction" exception if the
2810 * Config5 NMS bit is set.
2812 static inline void check_nms(DisasContext
*ctx
)
2814 if (unlikely(ctx
->CP0_Config5
& (1 << CP0C5_NMS
))) {
2815 gen_reserved_instruction(ctx
);
2820 * This code generates a "reserved instruction" exception if the
2821 * Config5 NMS bit is set, and Config1 DL, Config1 IL, Config2 SL,
2822 * Config2 TL, and Config5 L2C are unset.
2824 static inline void check_nms_dl_il_sl_tl_l2c(DisasContext
*ctx
)
2826 if (unlikely((ctx
->CP0_Config5
& (1 << CP0C5_NMS
)) &&
2827 !(ctx
->CP0_Config1
& (1 << CP0C1_DL
)) &&
2828 !(ctx
->CP0_Config1
& (1 << CP0C1_IL
)) &&
2829 !(ctx
->CP0_Config2
& (1 << CP0C2_SL
)) &&
2830 !(ctx
->CP0_Config2
& (1 << CP0C2_TL
)) &&
2831 !(ctx
->CP0_Config5
& (1 << CP0C5_L2C
)))) {
2832 gen_reserved_instruction(ctx
);
2837 * This code generates a "reserved instruction" exception if the
2838 * Config5 EVA bit is NOT set.
2840 static inline void check_eva(DisasContext
*ctx
)
2842 if (unlikely(!(ctx
->CP0_Config5
& (1 << CP0C5_EVA
)))) {
2843 gen_reserved_instruction(ctx
);
2849 * Define small wrappers for gen_load_fpr* so that we have a uniform
2850 * calling interface for 32 and 64-bit FPRs. No sense in changing
2851 * all callers for gen_load_fpr32 when we need the CTX parameter for
2854 #define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(ctx, x, y)
2855 #define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
2856 #define FOP_CONDS(type, abs, fmt, ifmt, bits) \
2857 static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
2858 int ft, int fs, int cc) \
2860 TCGv_i##bits fp0 = tcg_temp_new_i##bits(); \
2861 TCGv_i##bits fp1 = tcg_temp_new_i##bits(); \
2870 check_cp1_registers(ctx, fs | ft); \
2878 gen_ldcmp_fpr##bits(ctx, fp0, fs); \
2879 gen_ldcmp_fpr##bits(ctx, fp1, ft); \
2882 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); \
2885 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); \
2888 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); \
2891 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); \
2894 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); \
2897 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); \
2900 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); \
2903 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); \
2906 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); \
2909 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); \
2912 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); \
2915 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); \
2918 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); \
2921 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); \
2924 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); \
2927 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); \
2932 tcg_temp_free_i##bits(fp0); \
2933 tcg_temp_free_i##bits(fp1); \
2936 FOP_CONDS(, 0, d
, FMT_D
, 64)
2937 FOP_CONDS(abs
, 1, d
, FMT_D
, 64)
2938 FOP_CONDS(, 0, s
, FMT_S
, 32)
2939 FOP_CONDS(abs
, 1, s
, FMT_S
, 32)
2940 FOP_CONDS(, 0, ps
, FMT_PS
, 64)
2941 FOP_CONDS(abs
, 1, ps
, FMT_PS
, 64)
2944 #define FOP_CONDNS(fmt, ifmt, bits, STORE) \
2945 static inline void gen_r6_cmp_ ## fmt(DisasContext *ctx, int n, \
2946 int ft, int fs, int fd) \
2948 TCGv_i ## bits fp0 = tcg_temp_new_i ## bits(); \
2949 TCGv_i ## bits fp1 = tcg_temp_new_i ## bits(); \
2950 if (ifmt == FMT_D) { \
2951 check_cp1_registers(ctx, fs | ft | fd); \
2953 gen_ldcmp_fpr ## bits(ctx, fp0, fs); \
2954 gen_ldcmp_fpr ## bits(ctx, fp1, ft); \
2957 gen_helper_r6_cmp_ ## fmt ## _af(fp0, cpu_env, fp0, fp1); \
2960 gen_helper_r6_cmp_ ## fmt ## _un(fp0, cpu_env, fp0, fp1); \
2963 gen_helper_r6_cmp_ ## fmt ## _eq(fp0, cpu_env, fp0, fp1); \
2966 gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, cpu_env, fp0, fp1); \
2969 gen_helper_r6_cmp_ ## fmt ## _lt(fp0, cpu_env, fp0, fp1); \
2972 gen_helper_r6_cmp_ ## fmt ## _ult(fp0, cpu_env, fp0, fp1); \
2975 gen_helper_r6_cmp_ ## fmt ## _le(fp0, cpu_env, fp0, fp1); \
2978 gen_helper_r6_cmp_ ## fmt ## _ule(fp0, cpu_env, fp0, fp1); \
2981 gen_helper_r6_cmp_ ## fmt ## _saf(fp0, cpu_env, fp0, fp1); \
2984 gen_helper_r6_cmp_ ## fmt ## _sun(fp0, cpu_env, fp0, fp1); \
2987 gen_helper_r6_cmp_ ## fmt ## _seq(fp0, cpu_env, fp0, fp1); \
2990 gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, cpu_env, fp0, fp1); \
2993 gen_helper_r6_cmp_ ## fmt ## _slt(fp0, cpu_env, fp0, fp1); \
2996 gen_helper_r6_cmp_ ## fmt ## _sult(fp0, cpu_env, fp0, fp1); \
2999 gen_helper_r6_cmp_ ## fmt ## _sle(fp0, cpu_env, fp0, fp1); \
3002 gen_helper_r6_cmp_ ## fmt ## _sule(fp0, cpu_env, fp0, fp1); \
3005 gen_helper_r6_cmp_ ## fmt ## _or(fp0, cpu_env, fp0, fp1); \
3008 gen_helper_r6_cmp_ ## fmt ## _une(fp0, cpu_env, fp0, fp1); \
3011 gen_helper_r6_cmp_ ## fmt ## _ne(fp0, cpu_env, fp0, fp1); \
3014 gen_helper_r6_cmp_ ## fmt ## _sor(fp0, cpu_env, fp0, fp1); \
3017 gen_helper_r6_cmp_ ## fmt ## _sune(fp0, cpu_env, fp0, fp1); \
3020 gen_helper_r6_cmp_ ## fmt ## _sne(fp0, cpu_env, fp0, fp1); \
3026 tcg_temp_free_i ## bits(fp0); \
3027 tcg_temp_free_i ## bits(fp1); \
3030 FOP_CONDNS(d
, FMT_D
, 64, gen_store_fpr64(ctx
, fp0
, fd
))
3031 FOP_CONDNS(s
, FMT_S
, 32, gen_store_fpr32(ctx
, fp0
, fd
))
3033 #undef gen_ldcmp_fpr32
3034 #undef gen_ldcmp_fpr64
3036 /* load/store instructions. */
3037 #ifdef CONFIG_USER_ONLY
3038 #define OP_LD_ATOMIC(insn, fname) \
3039 static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \
3040 DisasContext *ctx) \
3042 TCGv t0 = tcg_temp_new(); \
3043 tcg_gen_mov_tl(t0, arg1); \
3044 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
3045 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
3046 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
3047 tcg_temp_free(t0); \
3050 #define OP_LD_ATOMIC(insn, fname) \
3051 static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \
3052 DisasContext *ctx) \
3054 gen_helper_1e1i(insn, ret, arg1, mem_idx); \
3057 OP_LD_ATOMIC(ll
, ld32s
);
3058 #if defined(TARGET_MIPS64)
3059 OP_LD_ATOMIC(lld
, ld64
);
3063 void gen_base_offset_addr(DisasContext
*ctx
, TCGv addr
, int base
, int offset
)
3066 tcg_gen_movi_tl(addr
, offset
);
3067 } else if (offset
== 0) {
3068 gen_load_gpr(addr
, base
);
3070 tcg_gen_movi_tl(addr
, offset
);
3071 gen_op_addr_add(ctx
, addr
, cpu_gpr
[base
], addr
);
3075 static target_ulong
pc_relative_pc(DisasContext
*ctx
)
3077 target_ulong pc
= ctx
->base
.pc_next
;
3079 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
3080 int branch_bytes
= ctx
->hflags
& MIPS_HFLAG_BDS16
? 2 : 4;
3085 pc
&= ~(target_ulong
)3;
3090 static void gen_ld(DisasContext
*ctx
, uint32_t opc
,
3091 int rt
, int base
, int offset
)
3094 int mem_idx
= ctx
->mem_idx
;
3096 if (rt
== 0 && ctx
->insn_flags
& (INSN_LOONGSON2E
| INSN_LOONGSON2F
|
3099 * Loongson CPU uses a load to zero register for prefetch.
3100 * We emulate it as a NOP. On other CPU we must perform the
3101 * actual memory access.
3106 t0
= tcg_temp_new();
3107 gen_base_offset_addr(ctx
, t0
, base
, offset
);
3110 #if defined(TARGET_MIPS64)
3112 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEUL
|
3113 ctx
->default_tcg_memop_mask
);
3114 gen_store_gpr(t0
, rt
);
3117 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEQ
|
3118 ctx
->default_tcg_memop_mask
);
3119 gen_store_gpr(t0
, rt
);
3123 op_ld_lld(t0
, t0
, mem_idx
, ctx
);
3124 gen_store_gpr(t0
, rt
);
3127 t1
= tcg_temp_new();
3129 * Do a byte access to possibly trigger a page
3130 * fault with the unaligned address.
3132 tcg_gen_qemu_ld_tl(t1
, t0
, mem_idx
, MO_UB
);
3133 tcg_gen_andi_tl(t1
, t0
, 7);
3134 #ifndef TARGET_WORDS_BIGENDIAN
3135 tcg_gen_xori_tl(t1
, t1
, 7);
3137 tcg_gen_shli_tl(t1
, t1
, 3);
3138 tcg_gen_andi_tl(t0
, t0
, ~7);
3139 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEQ
);
3140 tcg_gen_shl_tl(t0
, t0
, t1
);
3141 t2
= tcg_const_tl(-1);
3142 tcg_gen_shl_tl(t2
, t2
, t1
);
3143 gen_load_gpr(t1
, rt
);
3144 tcg_gen_andc_tl(t1
, t1
, t2
);
3146 tcg_gen_or_tl(t0
, t0
, t1
);
3148 gen_store_gpr(t0
, rt
);
3151 t1
= tcg_temp_new();
3153 * Do a byte access to possibly trigger a page
3154 * fault with the unaligned address.
3156 tcg_gen_qemu_ld_tl(t1
, t0
, mem_idx
, MO_UB
);
3157 tcg_gen_andi_tl(t1
, t0
, 7);
3158 #ifdef TARGET_WORDS_BIGENDIAN
3159 tcg_gen_xori_tl(t1
, t1
, 7);
3161 tcg_gen_shli_tl(t1
, t1
, 3);
3162 tcg_gen_andi_tl(t0
, t0
, ~7);
3163 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEQ
);
3164 tcg_gen_shr_tl(t0
, t0
, t1
);
3165 tcg_gen_xori_tl(t1
, t1
, 63);
3166 t2
= tcg_const_tl(0xfffffffffffffffeull
);
3167 tcg_gen_shl_tl(t2
, t2
, t1
);
3168 gen_load_gpr(t1
, rt
);
3169 tcg_gen_and_tl(t1
, t1
, t2
);
3171 tcg_gen_or_tl(t0
, t0
, t1
);
3173 gen_store_gpr(t0
, rt
);
3176 t1
= tcg_const_tl(pc_relative_pc(ctx
));
3177 gen_op_addr_add(ctx
, t0
, t0
, t1
);
3179 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEQ
);
3180 gen_store_gpr(t0
, rt
);
3184 t1
= tcg_const_tl(pc_relative_pc(ctx
));
3185 gen_op_addr_add(ctx
, t0
, t0
, t1
);
3187 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TESL
);
3188 gen_store_gpr(t0
, rt
);
3191 mem_idx
= MIPS_HFLAG_UM
;
3194 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TESL
|
3195 ctx
->default_tcg_memop_mask
);
3196 gen_store_gpr(t0
, rt
);
3199 mem_idx
= MIPS_HFLAG_UM
;
3202 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TESW
|
3203 ctx
->default_tcg_memop_mask
);
3204 gen_store_gpr(t0
, rt
);
3207 mem_idx
= MIPS_HFLAG_UM
;
3210 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEUW
|
3211 ctx
->default_tcg_memop_mask
);
3212 gen_store_gpr(t0
, rt
);
3215 mem_idx
= MIPS_HFLAG_UM
;
3218 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_SB
);
3219 gen_store_gpr(t0
, rt
);
3222 mem_idx
= MIPS_HFLAG_UM
;
3225 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_UB
);
3226 gen_store_gpr(t0
, rt
);
3229 mem_idx
= MIPS_HFLAG_UM
;
3232 t1
= tcg_temp_new();
3234 * Do a byte access to possibly trigger a page
3235 * fault with the unaligned address.
3237 tcg_gen_qemu_ld_tl(t1
, t0
, mem_idx
, MO_UB
);
3238 tcg_gen_andi_tl(t1
, t0
, 3);
3239 #ifndef TARGET_WORDS_BIGENDIAN
3240 tcg_gen_xori_tl(t1
, t1
, 3);
3242 tcg_gen_shli_tl(t1
, t1
, 3);
3243 tcg_gen_andi_tl(t0
, t0
, ~3);
3244 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEUL
);
3245 tcg_gen_shl_tl(t0
, t0
, t1
);
3246 t2
= tcg_const_tl(-1);
3247 tcg_gen_shl_tl(t2
, t2
, t1
);
3248 gen_load_gpr(t1
, rt
);
3249 tcg_gen_andc_tl(t1
, t1
, t2
);
3251 tcg_gen_or_tl(t0
, t0
, t1
);
3253 tcg_gen_ext32s_tl(t0
, t0
);
3254 gen_store_gpr(t0
, rt
);
3257 mem_idx
= MIPS_HFLAG_UM
;
3260 t1
= tcg_temp_new();
3262 * Do a byte access to possibly trigger a page
3263 * fault with the unaligned address.
3265 tcg_gen_qemu_ld_tl(t1
, t0
, mem_idx
, MO_UB
);
3266 tcg_gen_andi_tl(t1
, t0
, 3);
3267 #ifdef TARGET_WORDS_BIGENDIAN
3268 tcg_gen_xori_tl(t1
, t1
, 3);
3270 tcg_gen_shli_tl(t1
, t1
, 3);
3271 tcg_gen_andi_tl(t0
, t0
, ~3);
3272 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEUL
);
3273 tcg_gen_shr_tl(t0
, t0
, t1
);
3274 tcg_gen_xori_tl(t1
, t1
, 31);
3275 t2
= tcg_const_tl(0xfffffffeull
);
3276 tcg_gen_shl_tl(t2
, t2
, t1
);
3277 gen_load_gpr(t1
, rt
);
3278 tcg_gen_and_tl(t1
, t1
, t2
);
3280 tcg_gen_or_tl(t0
, t0
, t1
);
3282 tcg_gen_ext32s_tl(t0
, t0
);
3283 gen_store_gpr(t0
, rt
);
3286 mem_idx
= MIPS_HFLAG_UM
;
3290 op_ld_ll(t0
, t0
, mem_idx
, ctx
);
3291 gen_store_gpr(t0
, rt
);
3297 static void gen_llwp(DisasContext
*ctx
, uint32_t base
, int16_t offset
,
3298 uint32_t reg1
, uint32_t reg2
)
3300 TCGv taddr
= tcg_temp_new();
3301 TCGv_i64 tval
= tcg_temp_new_i64();
3302 TCGv tmp1
= tcg_temp_new();
3303 TCGv tmp2
= tcg_temp_new();
3305 gen_base_offset_addr(ctx
, taddr
, base
, offset
);
3306 tcg_gen_qemu_ld64(tval
, taddr
, ctx
->mem_idx
);
3307 #ifdef TARGET_WORDS_BIGENDIAN
3308 tcg_gen_extr_i64_tl(tmp2
, tmp1
, tval
);
3310 tcg_gen_extr_i64_tl(tmp1
, tmp2
, tval
);
3312 gen_store_gpr(tmp1
, reg1
);
3313 tcg_temp_free(tmp1
);
3314 gen_store_gpr(tmp2
, reg2
);
3315 tcg_temp_free(tmp2
);
3316 tcg_gen_st_i64(tval
, cpu_env
, offsetof(CPUMIPSState
, llval_wp
));
3317 tcg_temp_free_i64(tval
);
3318 tcg_gen_st_tl(taddr
, cpu_env
, offsetof(CPUMIPSState
, lladdr
));
3319 tcg_temp_free(taddr
);
3323 static void gen_st(DisasContext
*ctx
, uint32_t opc
, int rt
,
3324 int base
, int offset
)
3326 TCGv t0
= tcg_temp_new();
3327 TCGv t1
= tcg_temp_new();
3328 int mem_idx
= ctx
->mem_idx
;
3330 gen_base_offset_addr(ctx
, t0
, base
, offset
);
3331 gen_load_gpr(t1
, rt
);
3333 #if defined(TARGET_MIPS64)
3335 tcg_gen_qemu_st_tl(t1
, t0
, mem_idx
, MO_TEQ
|
3336 ctx
->default_tcg_memop_mask
);
3339 gen_helper_0e2i(sdl
, t1
, t0
, mem_idx
);
3342 gen_helper_0e2i(sdr
, t1
, t0
, mem_idx
);
3346 mem_idx
= MIPS_HFLAG_UM
;
3349 tcg_gen_qemu_st_tl(t1
, t0
, mem_idx
, MO_TEUL
|
3350 ctx
->default_tcg_memop_mask
);
3353 mem_idx
= MIPS_HFLAG_UM
;
3356 tcg_gen_qemu_st_tl(t1
, t0
, mem_idx
, MO_TEUW
|
3357 ctx
->default_tcg_memop_mask
);
3360 mem_idx
= MIPS_HFLAG_UM
;
3363 tcg_gen_qemu_st_tl(t1
, t0
, mem_idx
, MO_8
);
3366 mem_idx
= MIPS_HFLAG_UM
;
3369 gen_helper_0e2i(swl
, t1
, t0
, mem_idx
);
3372 mem_idx
= MIPS_HFLAG_UM
;
3375 gen_helper_0e2i(swr
, t1
, t0
, mem_idx
);
3383 /* Store conditional */
3384 static void gen_st_cond(DisasContext
*ctx
, int rt
, int base
, int offset
,
3385 MemOp tcg_mo
, bool eva
)
3388 TCGLabel
*l1
= gen_new_label();
3389 TCGLabel
*done
= gen_new_label();
3391 t0
= tcg_temp_new();
3392 addr
= tcg_temp_new();
3393 /* compare the address against that of the preceding LL */
3394 gen_base_offset_addr(ctx
, addr
, base
, offset
);
3395 tcg_gen_brcond_tl(TCG_COND_EQ
, addr
, cpu_lladdr
, l1
);
3396 tcg_temp_free(addr
);
3397 tcg_gen_movi_tl(t0
, 0);
3398 gen_store_gpr(t0
, rt
);
3402 /* generate cmpxchg */
3403 val
= tcg_temp_new();
3404 gen_load_gpr(val
, rt
);
3405 tcg_gen_atomic_cmpxchg_tl(t0
, cpu_lladdr
, cpu_llval
, val
,
3406 eva
? MIPS_HFLAG_UM
: ctx
->mem_idx
, tcg_mo
);
3407 tcg_gen_setcond_tl(TCG_COND_EQ
, t0
, t0
, cpu_llval
);
3408 gen_store_gpr(t0
, rt
);
3411 gen_set_label(done
);
3416 static void gen_scwp(DisasContext
*ctx
, uint32_t base
, int16_t offset
,
3417 uint32_t reg1
, uint32_t reg2
, bool eva
)
3419 TCGv taddr
= tcg_temp_local_new();
3420 TCGv lladdr
= tcg_temp_local_new();
3421 TCGv_i64 tval
= tcg_temp_new_i64();
3422 TCGv_i64 llval
= tcg_temp_new_i64();
3423 TCGv_i64 val
= tcg_temp_new_i64();
3424 TCGv tmp1
= tcg_temp_new();
3425 TCGv tmp2
= tcg_temp_new();
3426 TCGLabel
*lab_fail
= gen_new_label();
3427 TCGLabel
*lab_done
= gen_new_label();
3429 gen_base_offset_addr(ctx
, taddr
, base
, offset
);
3431 tcg_gen_ld_tl(lladdr
, cpu_env
, offsetof(CPUMIPSState
, lladdr
));
3432 tcg_gen_brcond_tl(TCG_COND_NE
, taddr
, lladdr
, lab_fail
);
3434 gen_load_gpr(tmp1
, reg1
);
3435 gen_load_gpr(tmp2
, reg2
);
3437 #ifdef TARGET_WORDS_BIGENDIAN
3438 tcg_gen_concat_tl_i64(tval
, tmp2
, tmp1
);
3440 tcg_gen_concat_tl_i64(tval
, tmp1
, tmp2
);
3443 tcg_gen_ld_i64(llval
, cpu_env
, offsetof(CPUMIPSState
, llval_wp
));
3444 tcg_gen_atomic_cmpxchg_i64(val
, taddr
, llval
, tval
,
3445 eva
? MIPS_HFLAG_UM
: ctx
->mem_idx
, MO_64
);
3447 tcg_gen_movi_tl(cpu_gpr
[reg1
], 1);
3449 tcg_gen_brcond_i64(TCG_COND_EQ
, val
, llval
, lab_done
);
3451 gen_set_label(lab_fail
);
3454 tcg_gen_movi_tl(cpu_gpr
[reg1
], 0);
3456 gen_set_label(lab_done
);
3457 tcg_gen_movi_tl(lladdr
, -1);
3458 tcg_gen_st_tl(lladdr
, cpu_env
, offsetof(CPUMIPSState
, lladdr
));
3461 /* Load and store */
3462 static void gen_flt_ldst(DisasContext
*ctx
, uint32_t opc
, int ft
,
3466 * Don't do NOP if destination is zero: we must perform the actual
3472 TCGv_i32 fp0
= tcg_temp_new_i32();
3473 tcg_gen_qemu_ld_i32(fp0
, t0
, ctx
->mem_idx
, MO_TESL
|
3474 ctx
->default_tcg_memop_mask
);
3475 gen_store_fpr32(ctx
, fp0
, ft
);
3476 tcg_temp_free_i32(fp0
);
3481 TCGv_i32 fp0
= tcg_temp_new_i32();
3482 gen_load_fpr32(ctx
, fp0
, ft
);
3483 tcg_gen_qemu_st_i32(fp0
, t0
, ctx
->mem_idx
, MO_TEUL
|
3484 ctx
->default_tcg_memop_mask
);
3485 tcg_temp_free_i32(fp0
);
3490 TCGv_i64 fp0
= tcg_temp_new_i64();
3491 tcg_gen_qemu_ld_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
|
3492 ctx
->default_tcg_memop_mask
);
3493 gen_store_fpr64(ctx
, fp0
, ft
);
3494 tcg_temp_free_i64(fp0
);
3499 TCGv_i64 fp0
= tcg_temp_new_i64();
3500 gen_load_fpr64(ctx
, fp0
, ft
);
3501 tcg_gen_qemu_st_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
|
3502 ctx
->default_tcg_memop_mask
);
3503 tcg_temp_free_i64(fp0
);
3507 MIPS_INVAL("flt_ldst");
3508 gen_reserved_instruction(ctx
);
3513 static void gen_cop1_ldst(DisasContext
*ctx
, uint32_t op
, int rt
,
3514 int rs
, int16_t imm
)
3516 TCGv t0
= tcg_temp_new();
3518 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
3519 check_cp1_enabled(ctx
);
3523 check_insn(ctx
, ISA_MIPS2
);
3526 gen_base_offset_addr(ctx
, t0
, rs
, imm
);
3527 gen_flt_ldst(ctx
, op
, rt
, t0
);
3530 generate_exception_err(ctx
, EXCP_CpU
, 1);
3535 /* Arithmetic with immediate operand */
3536 static void gen_arith_imm(DisasContext
*ctx
, uint32_t opc
,
3537 int rt
, int rs
, int imm
)
3539 target_ulong uimm
= (target_long
)imm
; /* Sign extend to 32/64 bits */
3541 if (rt
== 0 && opc
!= OPC_ADDI
&& opc
!= OPC_DADDI
) {
3543 * If no destination, treat it as a NOP.
3544 * For addi, we must generate the overflow exception when needed.
3551 TCGv t0
= tcg_temp_local_new();
3552 TCGv t1
= tcg_temp_new();
3553 TCGv t2
= tcg_temp_new();
3554 TCGLabel
*l1
= gen_new_label();
3556 gen_load_gpr(t1
, rs
);
3557 tcg_gen_addi_tl(t0
, t1
, uimm
);
3558 tcg_gen_ext32s_tl(t0
, t0
);
3560 tcg_gen_xori_tl(t1
, t1
, ~uimm
);
3561 tcg_gen_xori_tl(t2
, t0
, uimm
);
3562 tcg_gen_and_tl(t1
, t1
, t2
);
3564 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
3566 /* operands of same sign, result different sign */
3567 generate_exception(ctx
, EXCP_OVERFLOW
);
3569 tcg_gen_ext32s_tl(t0
, t0
);
3570 gen_store_gpr(t0
, rt
);
3576 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
3577 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
3579 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
3582 #if defined(TARGET_MIPS64)
3585 TCGv t0
= tcg_temp_local_new();
3586 TCGv t1
= tcg_temp_new();
3587 TCGv t2
= tcg_temp_new();
3588 TCGLabel
*l1
= gen_new_label();
3590 gen_load_gpr(t1
, rs
);
3591 tcg_gen_addi_tl(t0
, t1
, uimm
);
3593 tcg_gen_xori_tl(t1
, t1
, ~uimm
);
3594 tcg_gen_xori_tl(t2
, t0
, uimm
);
3595 tcg_gen_and_tl(t1
, t1
, t2
);
3597 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
3599 /* operands of same sign, result different sign */
3600 generate_exception(ctx
, EXCP_OVERFLOW
);
3602 gen_store_gpr(t0
, rt
);
3608 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
3610 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
3617 /* Logic with immediate operand */
3618 static void gen_logic_imm(DisasContext
*ctx
, uint32_t opc
,
3619 int rt
, int rs
, int16_t imm
)
3624 /* If no destination, treat it as a NOP. */
3627 uimm
= (uint16_t)imm
;
3630 if (likely(rs
!= 0)) {
3631 tcg_gen_andi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
3633 tcg_gen_movi_tl(cpu_gpr
[rt
], 0);
3638 tcg_gen_ori_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
3640 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
3644 if (likely(rs
!= 0)) {
3645 tcg_gen_xori_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
3647 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
3651 if (rs
!= 0 && (ctx
->insn_flags
& ISA_MIPS_R6
)) {
3653 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], imm
<< 16);
3654 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
3656 tcg_gen_movi_tl(cpu_gpr
[rt
], imm
<< 16);
3665 /* Set on less than with immediate operand */
3666 static void gen_slt_imm(DisasContext
*ctx
, uint32_t opc
,
3667 int rt
, int rs
, int16_t imm
)
3669 target_ulong uimm
= (target_long
)imm
; /* Sign extend to 32/64 bits */
3673 /* If no destination, treat it as a NOP. */
3676 t0
= tcg_temp_new();
3677 gen_load_gpr(t0
, rs
);
3680 tcg_gen_setcondi_tl(TCG_COND_LT
, cpu_gpr
[rt
], t0
, uimm
);
3683 tcg_gen_setcondi_tl(TCG_COND_LTU
, cpu_gpr
[rt
], t0
, uimm
);
3689 /* Shifts with immediate operand */
3690 static void gen_shift_imm(DisasContext
*ctx
, uint32_t opc
,
3691 int rt
, int rs
, int16_t imm
)
3693 target_ulong uimm
= ((uint16_t)imm
) & 0x1f;
3697 /* If no destination, treat it as a NOP. */
3701 t0
= tcg_temp_new();
3702 gen_load_gpr(t0
, rs
);
3705 tcg_gen_shli_tl(t0
, t0
, uimm
);
3706 tcg_gen_ext32s_tl(cpu_gpr
[rt
], t0
);
3709 tcg_gen_sari_tl(cpu_gpr
[rt
], t0
, uimm
);
3713 tcg_gen_ext32u_tl(t0
, t0
);
3714 tcg_gen_shri_tl(cpu_gpr
[rt
], t0
, uimm
);
3716 tcg_gen_ext32s_tl(cpu_gpr
[rt
], t0
);
3721 TCGv_i32 t1
= tcg_temp_new_i32();
3723 tcg_gen_trunc_tl_i32(t1
, t0
);
3724 tcg_gen_rotri_i32(t1
, t1
, uimm
);
3725 tcg_gen_ext_i32_tl(cpu_gpr
[rt
], t1
);
3726 tcg_temp_free_i32(t1
);
3728 tcg_gen_ext32s_tl(cpu_gpr
[rt
], t0
);
3731 #if defined(TARGET_MIPS64)
3733 tcg_gen_shli_tl(cpu_gpr
[rt
], t0
, uimm
);
3736 tcg_gen_sari_tl(cpu_gpr
[rt
], t0
, uimm
);
3739 tcg_gen_shri_tl(cpu_gpr
[rt
], t0
, uimm
);
3743 tcg_gen_rotri_tl(cpu_gpr
[rt
], t0
, uimm
);
3745 tcg_gen_mov_tl(cpu_gpr
[rt
], t0
);
3749 tcg_gen_shli_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
3752 tcg_gen_sari_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
3755 tcg_gen_shri_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
3758 tcg_gen_rotri_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
3766 static void gen_arith(DisasContext
*ctx
, uint32_t opc
,
3767 int rd
, int rs
, int rt
)
3769 if (rd
== 0 && opc
!= OPC_ADD
&& opc
!= OPC_SUB
3770 && opc
!= OPC_DADD
&& opc
!= OPC_DSUB
) {
3772 * If no destination, treat it as a NOP.
3773 * For add & sub, we must generate the overflow exception when needed.
3781 TCGv t0
= tcg_temp_local_new();
3782 TCGv t1
= tcg_temp_new();
3783 TCGv t2
= tcg_temp_new();
3784 TCGLabel
*l1
= gen_new_label();
3786 gen_load_gpr(t1
, rs
);
3787 gen_load_gpr(t2
, rt
);
3788 tcg_gen_add_tl(t0
, t1
, t2
);
3789 tcg_gen_ext32s_tl(t0
, t0
);
3790 tcg_gen_xor_tl(t1
, t1
, t2
);
3791 tcg_gen_xor_tl(t2
, t0
, t2
);
3792 tcg_gen_andc_tl(t1
, t2
, t1
);
3794 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
3796 /* operands of same sign, result different sign */
3797 generate_exception(ctx
, EXCP_OVERFLOW
);
3799 gen_store_gpr(t0
, rd
);
3804 if (rs
!= 0 && rt
!= 0) {
3805 tcg_gen_add_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
3806 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3807 } else if (rs
== 0 && rt
!= 0) {
3808 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
3809 } else if (rs
!= 0 && rt
== 0) {
3810 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
3812 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3817 TCGv t0
= tcg_temp_local_new();
3818 TCGv t1
= tcg_temp_new();
3819 TCGv t2
= tcg_temp_new();
3820 TCGLabel
*l1
= gen_new_label();
3822 gen_load_gpr(t1
, rs
);
3823 gen_load_gpr(t2
, rt
);
3824 tcg_gen_sub_tl(t0
, t1
, t2
);
3825 tcg_gen_ext32s_tl(t0
, t0
);
3826 tcg_gen_xor_tl(t2
, t1
, t2
);
3827 tcg_gen_xor_tl(t1
, t0
, t1
);
3828 tcg_gen_and_tl(t1
, t1
, t2
);
3830 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
3833 * operands of different sign, first operand and the result
3836 generate_exception(ctx
, EXCP_OVERFLOW
);
3838 gen_store_gpr(t0
, rd
);
3843 if (rs
!= 0 && rt
!= 0) {
3844 tcg_gen_sub_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
3845 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3846 } else if (rs
== 0 && rt
!= 0) {
3847 tcg_gen_neg_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
3848 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3849 } else if (rs
!= 0 && rt
== 0) {
3850 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
3852 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3855 #if defined(TARGET_MIPS64)
3858 TCGv t0
= tcg_temp_local_new();
3859 TCGv t1
= tcg_temp_new();
3860 TCGv t2
= tcg_temp_new();
3861 TCGLabel
*l1
= gen_new_label();
3863 gen_load_gpr(t1
, rs
);
3864 gen_load_gpr(t2
, rt
);
3865 tcg_gen_add_tl(t0
, t1
, t2
);
3866 tcg_gen_xor_tl(t1
, t1
, t2
);
3867 tcg_gen_xor_tl(t2
, t0
, t2
);
3868 tcg_gen_andc_tl(t1
, t2
, t1
);
3870 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
3872 /* operands of same sign, result different sign */
3873 generate_exception(ctx
, EXCP_OVERFLOW
);
3875 gen_store_gpr(t0
, rd
);
3880 if (rs
!= 0 && rt
!= 0) {
3881 tcg_gen_add_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
3882 } else if (rs
== 0 && rt
!= 0) {
3883 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
3884 } else if (rs
!= 0 && rt
== 0) {
3885 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
3887 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3892 TCGv t0
= tcg_temp_local_new();
3893 TCGv t1
= tcg_temp_new();
3894 TCGv t2
= tcg_temp_new();
3895 TCGLabel
*l1
= gen_new_label();
3897 gen_load_gpr(t1
, rs
);
3898 gen_load_gpr(t2
, rt
);
3899 tcg_gen_sub_tl(t0
, t1
, t2
);
3900 tcg_gen_xor_tl(t2
, t1
, t2
);
3901 tcg_gen_xor_tl(t1
, t0
, t1
);
3902 tcg_gen_and_tl(t1
, t1
, t2
);
3904 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
3907 * Operands of different sign, first operand and result different
3910 generate_exception(ctx
, EXCP_OVERFLOW
);
3912 gen_store_gpr(t0
, rd
);
3917 if (rs
!= 0 && rt
!= 0) {
3918 tcg_gen_sub_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
3919 } else if (rs
== 0 && rt
!= 0) {
3920 tcg_gen_neg_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
3921 } else if (rs
!= 0 && rt
== 0) {
3922 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
3924 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3929 if (likely(rs
!= 0 && rt
!= 0)) {
3930 tcg_gen_mul_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
3931 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3933 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3939 /* Conditional move */
3940 static void gen_cond_move(DisasContext
*ctx
, uint32_t opc
,
3941 int rd
, int rs
, int rt
)
3946 /* If no destination, treat it as a NOP. */
3950 t0
= tcg_temp_new();
3951 gen_load_gpr(t0
, rt
);
3952 t1
= tcg_const_tl(0);
3953 t2
= tcg_temp_new();
3954 gen_load_gpr(t2
, rs
);
3957 tcg_gen_movcond_tl(TCG_COND_NE
, cpu_gpr
[rd
], t0
, t1
, t2
, cpu_gpr
[rd
]);
3960 tcg_gen_movcond_tl(TCG_COND_EQ
, cpu_gpr
[rd
], t0
, t1
, t2
, cpu_gpr
[rd
]);
3963 tcg_gen_movcond_tl(TCG_COND_NE
, cpu_gpr
[rd
], t0
, t1
, t2
, t1
);
3966 tcg_gen_movcond_tl(TCG_COND_EQ
, cpu_gpr
[rd
], t0
, t1
, t2
, t1
);
3975 static void gen_logic(DisasContext
*ctx
, uint32_t opc
,
3976 int rd
, int rs
, int rt
)
3979 /* If no destination, treat it as a NOP. */
3985 if (likely(rs
!= 0 && rt
!= 0)) {
3986 tcg_gen_and_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
3988 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3992 if (rs
!= 0 && rt
!= 0) {
3993 tcg_gen_nor_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
3994 } else if (rs
== 0 && rt
!= 0) {
3995 tcg_gen_not_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
3996 } else if (rs
!= 0 && rt
== 0) {
3997 tcg_gen_not_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
3999 tcg_gen_movi_tl(cpu_gpr
[rd
], ~((target_ulong
)0));
4003 if (likely(rs
!= 0 && rt
!= 0)) {
4004 tcg_gen_or_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
4005 } else if (rs
== 0 && rt
!= 0) {
4006 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
4007 } else if (rs
!= 0 && rt
== 0) {
4008 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
4010 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4014 if (likely(rs
!= 0 && rt
!= 0)) {
4015 tcg_gen_xor_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
4016 } else if (rs
== 0 && rt
!= 0) {
4017 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
4018 } else if (rs
!= 0 && rt
== 0) {
4019 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
4021 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4027 /* Set on lower than */
4028 static void gen_slt(DisasContext
*ctx
, uint32_t opc
,
4029 int rd
, int rs
, int rt
)
4034 /* If no destination, treat it as a NOP. */
4038 t0
= tcg_temp_new();
4039 t1
= tcg_temp_new();
4040 gen_load_gpr(t0
, rs
);
4041 gen_load_gpr(t1
, rt
);
4044 tcg_gen_setcond_tl(TCG_COND_LT
, cpu_gpr
[rd
], t0
, t1
);
4047 tcg_gen_setcond_tl(TCG_COND_LTU
, cpu_gpr
[rd
], t0
, t1
);
4055 static void gen_shift(DisasContext
*ctx
, uint32_t opc
,
4056 int rd
, int rs
, int rt
)
4062 * If no destination, treat it as a NOP.
4063 * For add & sub, we must generate the overflow exception when needed.
4068 t0
= tcg_temp_new();
4069 t1
= tcg_temp_new();
4070 gen_load_gpr(t0
, rs
);
4071 gen_load_gpr(t1
, rt
);
4074 tcg_gen_andi_tl(t0
, t0
, 0x1f);
4075 tcg_gen_shl_tl(t0
, t1
, t0
);
4076 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
4079 tcg_gen_andi_tl(t0
, t0
, 0x1f);
4080 tcg_gen_sar_tl(cpu_gpr
[rd
], t1
, t0
);
4083 tcg_gen_ext32u_tl(t1
, t1
);
4084 tcg_gen_andi_tl(t0
, t0
, 0x1f);
4085 tcg_gen_shr_tl(t0
, t1
, t0
);
4086 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
4090 TCGv_i32 t2
= tcg_temp_new_i32();
4091 TCGv_i32 t3
= tcg_temp_new_i32();
4093 tcg_gen_trunc_tl_i32(t2
, t0
);
4094 tcg_gen_trunc_tl_i32(t3
, t1
);
4095 tcg_gen_andi_i32(t2
, t2
, 0x1f);
4096 tcg_gen_rotr_i32(t2
, t3
, t2
);
4097 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
4098 tcg_temp_free_i32(t2
);
4099 tcg_temp_free_i32(t3
);
4102 #if defined(TARGET_MIPS64)
4104 tcg_gen_andi_tl(t0
, t0
, 0x3f);
4105 tcg_gen_shl_tl(cpu_gpr
[rd
], t1
, t0
);
4108 tcg_gen_andi_tl(t0
, t0
, 0x3f);
4109 tcg_gen_sar_tl(cpu_gpr
[rd
], t1
, t0
);
4112 tcg_gen_andi_tl(t0
, t0
, 0x3f);
4113 tcg_gen_shr_tl(cpu_gpr
[rd
], t1
, t0
);
4116 tcg_gen_andi_tl(t0
, t0
, 0x3f);
4117 tcg_gen_rotr_tl(cpu_gpr
[rd
], t1
, t0
);
4125 #if defined(TARGET_MIPS64)
4126 /* Copy GPR to and from TX79 HI1/LO1 register. */
4127 static void gen_HILO1_tx79(DisasContext
*ctx
, uint32_t opc
, int reg
)
4131 gen_store_gpr(cpu_HI
[1], reg
);
4134 gen_store_gpr(cpu_LO
[1], reg
);
4137 gen_load_gpr(cpu_HI
[1], reg
);
4140 gen_load_gpr(cpu_LO
[1], reg
);
4143 MIPS_INVAL("mfthilo1 TX79");
4144 gen_reserved_instruction(ctx
);
4150 /* Arithmetic on HI/LO registers */
4151 static void gen_HILO(DisasContext
*ctx
, uint32_t opc
, int acc
, int reg
)
4153 if (reg
== 0 && (opc
== OPC_MFHI
|| opc
== OPC_MFLO
)) {
4164 #if defined(TARGET_MIPS64)
4166 tcg_gen_ext32s_tl(cpu_gpr
[reg
], cpu_HI
[acc
]);
4170 tcg_gen_mov_tl(cpu_gpr
[reg
], cpu_HI
[acc
]);
4174 #if defined(TARGET_MIPS64)
4176 tcg_gen_ext32s_tl(cpu_gpr
[reg
], cpu_LO
[acc
]);
4180 tcg_gen_mov_tl(cpu_gpr
[reg
], cpu_LO
[acc
]);
4185 #if defined(TARGET_MIPS64)
4187 tcg_gen_ext32s_tl(cpu_HI
[acc
], cpu_gpr
[reg
]);
4191 tcg_gen_mov_tl(cpu_HI
[acc
], cpu_gpr
[reg
]);
4194 tcg_gen_movi_tl(cpu_HI
[acc
], 0);
4199 #if defined(TARGET_MIPS64)
4201 tcg_gen_ext32s_tl(cpu_LO
[acc
], cpu_gpr
[reg
]);
4205 tcg_gen_mov_tl(cpu_LO
[acc
], cpu_gpr
[reg
]);
4208 tcg_gen_movi_tl(cpu_LO
[acc
], 0);
4214 static inline void gen_r6_ld(target_long addr
, int reg
, int memidx
,
4217 TCGv t0
= tcg_const_tl(addr
);
4218 tcg_gen_qemu_ld_tl(t0
, t0
, memidx
, memop
);
4219 gen_store_gpr(t0
, reg
);
4223 static inline void gen_pcrel(DisasContext
*ctx
, int opc
, target_ulong pc
,
4229 switch (MASK_OPC_PCREL_TOP2BITS(opc
)) {
4232 offset
= sextract32(ctx
->opcode
<< 2, 0, 21);
4233 addr
= addr_add(ctx
, pc
, offset
);
4234 tcg_gen_movi_tl(cpu_gpr
[rs
], addr
);
4238 offset
= sextract32(ctx
->opcode
<< 2, 0, 21);
4239 addr
= addr_add(ctx
, pc
, offset
);
4240 gen_r6_ld(addr
, rs
, ctx
->mem_idx
, MO_TESL
);
4242 #if defined(TARGET_MIPS64)
4245 offset
= sextract32(ctx
->opcode
<< 2, 0, 21);
4246 addr
= addr_add(ctx
, pc
, offset
);
4247 gen_r6_ld(addr
, rs
, ctx
->mem_idx
, MO_TEUL
);
4251 switch (MASK_OPC_PCREL_TOP5BITS(opc
)) {
4254 offset
= sextract32(ctx
->opcode
, 0, 16) << 16;
4255 addr
= addr_add(ctx
, pc
, offset
);
4256 tcg_gen_movi_tl(cpu_gpr
[rs
], addr
);
4261 offset
= sextract32(ctx
->opcode
, 0, 16) << 16;
4262 addr
= ~0xFFFF & addr_add(ctx
, pc
, offset
);
4263 tcg_gen_movi_tl(cpu_gpr
[rs
], addr
);
4266 #if defined(TARGET_MIPS64)
4267 case R6_OPC_LDPC
: /* bits 16 and 17 are part of immediate */
4268 case R6_OPC_LDPC
+ (1 << 16):
4269 case R6_OPC_LDPC
+ (2 << 16):
4270 case R6_OPC_LDPC
+ (3 << 16):
4272 offset
= sextract32(ctx
->opcode
<< 3, 0, 21);
4273 addr
= addr_add(ctx
, (pc
& ~0x7), offset
);
4274 gen_r6_ld(addr
, rs
, ctx
->mem_idx
, MO_TEQ
);
4278 MIPS_INVAL("OPC_PCREL");
4279 gen_reserved_instruction(ctx
);
4286 static void gen_r6_muldiv(DisasContext
*ctx
, int opc
, int rd
, int rs
, int rt
)
4295 t0
= tcg_temp_new();
4296 t1
= tcg_temp_new();
4298 gen_load_gpr(t0
, rs
);
4299 gen_load_gpr(t1
, rt
);
4304 TCGv t2
= tcg_temp_new();
4305 TCGv t3
= tcg_temp_new();
4306 tcg_gen_ext32s_tl(t0
, t0
);
4307 tcg_gen_ext32s_tl(t1
, t1
);
4308 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, INT_MIN
);
4309 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1);
4310 tcg_gen_and_tl(t2
, t2
, t3
);
4311 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
4312 tcg_gen_or_tl(t2
, t2
, t3
);
4313 tcg_gen_movi_tl(t3
, 0);
4314 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
4315 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
4316 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
4323 TCGv t2
= tcg_temp_new();
4324 TCGv t3
= tcg_temp_new();
4325 tcg_gen_ext32s_tl(t0
, t0
);
4326 tcg_gen_ext32s_tl(t1
, t1
);
4327 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, INT_MIN
);
4328 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1);
4329 tcg_gen_and_tl(t2
, t2
, t3
);
4330 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
4331 tcg_gen_or_tl(t2
, t2
, t3
);
4332 tcg_gen_movi_tl(t3
, 0);
4333 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
4334 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
4335 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
4342 TCGv t2
= tcg_const_tl(0);
4343 TCGv t3
= tcg_const_tl(1);
4344 tcg_gen_ext32u_tl(t0
, t0
);
4345 tcg_gen_ext32u_tl(t1
, t1
);
4346 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
4347 tcg_gen_divu_tl(cpu_gpr
[rd
], t0
, t1
);
4348 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
4355 TCGv t2
= tcg_const_tl(0);
4356 TCGv t3
= tcg_const_tl(1);
4357 tcg_gen_ext32u_tl(t0
, t0
);
4358 tcg_gen_ext32u_tl(t1
, t1
);
4359 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
4360 tcg_gen_remu_tl(cpu_gpr
[rd
], t0
, t1
);
4361 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
4368 TCGv_i32 t2
= tcg_temp_new_i32();
4369 TCGv_i32 t3
= tcg_temp_new_i32();
4370 tcg_gen_trunc_tl_i32(t2
, t0
);
4371 tcg_gen_trunc_tl_i32(t3
, t1
);
4372 tcg_gen_mul_i32(t2
, t2
, t3
);
4373 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
4374 tcg_temp_free_i32(t2
);
4375 tcg_temp_free_i32(t3
);
4380 TCGv_i32 t2
= tcg_temp_new_i32();
4381 TCGv_i32 t3
= tcg_temp_new_i32();
4382 tcg_gen_trunc_tl_i32(t2
, t0
);
4383 tcg_gen_trunc_tl_i32(t3
, t1
);
4384 tcg_gen_muls2_i32(t2
, t3
, t2
, t3
);
4385 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t3
);
4386 tcg_temp_free_i32(t2
);
4387 tcg_temp_free_i32(t3
);
4392 TCGv_i32 t2
= tcg_temp_new_i32();
4393 TCGv_i32 t3
= tcg_temp_new_i32();
4394 tcg_gen_trunc_tl_i32(t2
, t0
);
4395 tcg_gen_trunc_tl_i32(t3
, t1
);
4396 tcg_gen_mul_i32(t2
, t2
, t3
);
4397 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
4398 tcg_temp_free_i32(t2
);
4399 tcg_temp_free_i32(t3
);
4404 TCGv_i32 t2
= tcg_temp_new_i32();
4405 TCGv_i32 t3
= tcg_temp_new_i32();
4406 tcg_gen_trunc_tl_i32(t2
, t0
);
4407 tcg_gen_trunc_tl_i32(t3
, t1
);
4408 tcg_gen_mulu2_i32(t2
, t3
, t2
, t3
);
4409 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t3
);
4410 tcg_temp_free_i32(t2
);
4411 tcg_temp_free_i32(t3
);
4414 #if defined(TARGET_MIPS64)
4417 TCGv t2
= tcg_temp_new();
4418 TCGv t3
= tcg_temp_new();
4419 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, -1LL << 63);
4420 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1LL);
4421 tcg_gen_and_tl(t2
, t2
, t3
);
4422 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
4423 tcg_gen_or_tl(t2
, t2
, t3
);
4424 tcg_gen_movi_tl(t3
, 0);
4425 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
4426 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
4433 TCGv t2
= tcg_temp_new();
4434 TCGv t3
= tcg_temp_new();
4435 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, -1LL << 63);
4436 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1LL);
4437 tcg_gen_and_tl(t2
, t2
, t3
);
4438 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
4439 tcg_gen_or_tl(t2
, t2
, t3
);
4440 tcg_gen_movi_tl(t3
, 0);
4441 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
4442 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
4449 TCGv t2
= tcg_const_tl(0);
4450 TCGv t3
= tcg_const_tl(1);
4451 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
4452 tcg_gen_divu_i64(cpu_gpr
[rd
], t0
, t1
);
4459 TCGv t2
= tcg_const_tl(0);
4460 TCGv t3
= tcg_const_tl(1);
4461 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
4462 tcg_gen_remu_i64(cpu_gpr
[rd
], t0
, t1
);
4468 tcg_gen_mul_i64(cpu_gpr
[rd
], t0
, t1
);
4472 TCGv t2
= tcg_temp_new();
4473 tcg_gen_muls2_i64(t2
, cpu_gpr
[rd
], t0
, t1
);
4478 tcg_gen_mul_i64(cpu_gpr
[rd
], t0
, t1
);
4482 TCGv t2
= tcg_temp_new();
4483 tcg_gen_mulu2_i64(t2
, cpu_gpr
[rd
], t0
, t1
);
4489 MIPS_INVAL("r6 mul/div");
4490 gen_reserved_instruction(ctx
);
4498 #if defined(TARGET_MIPS64)
4499 static void gen_div1_tx79(DisasContext
*ctx
, uint32_t opc
, int rs
, int rt
)
4503 t0
= tcg_temp_new();
4504 t1
= tcg_temp_new();
4506 gen_load_gpr(t0
, rs
);
4507 gen_load_gpr(t1
, rt
);
4512 TCGv t2
= tcg_temp_new();
4513 TCGv t3
= tcg_temp_new();
4514 tcg_gen_ext32s_tl(t0
, t0
);
4515 tcg_gen_ext32s_tl(t1
, t1
);
4516 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, INT_MIN
);
4517 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1);
4518 tcg_gen_and_tl(t2
, t2
, t3
);
4519 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
4520 tcg_gen_or_tl(t2
, t2
, t3
);
4521 tcg_gen_movi_tl(t3
, 0);
4522 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
4523 tcg_gen_div_tl(cpu_LO
[1], t0
, t1
);
4524 tcg_gen_rem_tl(cpu_HI
[1], t0
, t1
);
4525 tcg_gen_ext32s_tl(cpu_LO
[1], cpu_LO
[1]);
4526 tcg_gen_ext32s_tl(cpu_HI
[1], cpu_HI
[1]);
4533 TCGv t2
= tcg_const_tl(0);
4534 TCGv t3
= tcg_const_tl(1);
4535 tcg_gen_ext32u_tl(t0
, t0
);
4536 tcg_gen_ext32u_tl(t1
, t1
);
4537 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
4538 tcg_gen_divu_tl(cpu_LO
[1], t0
, t1
);
4539 tcg_gen_remu_tl(cpu_HI
[1], t0
, t1
);
4540 tcg_gen_ext32s_tl(cpu_LO
[1], cpu_LO
[1]);
4541 tcg_gen_ext32s_tl(cpu_HI
[1], cpu_HI
[1]);
4547 MIPS_INVAL("div1 TX79");
4548 gen_reserved_instruction(ctx
);
4557 static void gen_muldiv(DisasContext
*ctx
, uint32_t opc
,
4558 int acc
, int rs
, int rt
)
4562 t0
= tcg_temp_new();
4563 t1
= tcg_temp_new();
4565 gen_load_gpr(t0
, rs
);
4566 gen_load_gpr(t1
, rt
);
4575 TCGv t2
= tcg_temp_new();
4576 TCGv t3
= tcg_temp_new();
4577 tcg_gen_ext32s_tl(t0
, t0
);
4578 tcg_gen_ext32s_tl(t1
, t1
);
4579 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, INT_MIN
);
4580 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1);
4581 tcg_gen_and_tl(t2
, t2
, t3
);
4582 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
4583 tcg_gen_or_tl(t2
, t2
, t3
);
4584 tcg_gen_movi_tl(t3
, 0);
4585 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
4586 tcg_gen_div_tl(cpu_LO
[acc
], t0
, t1
);
4587 tcg_gen_rem_tl(cpu_HI
[acc
], t0
, t1
);
4588 tcg_gen_ext32s_tl(cpu_LO
[acc
], cpu_LO
[acc
]);
4589 tcg_gen_ext32s_tl(cpu_HI
[acc
], cpu_HI
[acc
]);
4596 TCGv t2
= tcg_const_tl(0);
4597 TCGv t3
= tcg_const_tl(1);
4598 tcg_gen_ext32u_tl(t0
, t0
);
4599 tcg_gen_ext32u_tl(t1
, t1
);
4600 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
4601 tcg_gen_divu_tl(cpu_LO
[acc
], t0
, t1
);
4602 tcg_gen_remu_tl(cpu_HI
[acc
], t0
, t1
);
4603 tcg_gen_ext32s_tl(cpu_LO
[acc
], cpu_LO
[acc
]);
4604 tcg_gen_ext32s_tl(cpu_HI
[acc
], cpu_HI
[acc
]);
4611 TCGv_i32 t2
= tcg_temp_new_i32();
4612 TCGv_i32 t3
= tcg_temp_new_i32();
4613 tcg_gen_trunc_tl_i32(t2
, t0
);
4614 tcg_gen_trunc_tl_i32(t3
, t1
);
4615 tcg_gen_muls2_i32(t2
, t3
, t2
, t3
);
4616 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
4617 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
4618 tcg_temp_free_i32(t2
);
4619 tcg_temp_free_i32(t3
);
4624 TCGv_i32 t2
= tcg_temp_new_i32();
4625 TCGv_i32 t3
= tcg_temp_new_i32();
4626 tcg_gen_trunc_tl_i32(t2
, t0
);
4627 tcg_gen_trunc_tl_i32(t3
, t1
);
4628 tcg_gen_mulu2_i32(t2
, t3
, t2
, t3
);
4629 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
4630 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
4631 tcg_temp_free_i32(t2
);
4632 tcg_temp_free_i32(t3
);
4635 #if defined(TARGET_MIPS64)
4638 TCGv t2
= tcg_temp_new();
4639 TCGv t3
= tcg_temp_new();
4640 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, -1LL << 63);
4641 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1LL);
4642 tcg_gen_and_tl(t2
, t2
, t3
);
4643 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
4644 tcg_gen_or_tl(t2
, t2
, t3
);
4645 tcg_gen_movi_tl(t3
, 0);
4646 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
4647 tcg_gen_div_tl(cpu_LO
[acc
], t0
, t1
);
4648 tcg_gen_rem_tl(cpu_HI
[acc
], t0
, t1
);
4655 TCGv t2
= tcg_const_tl(0);
4656 TCGv t3
= tcg_const_tl(1);
4657 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
4658 tcg_gen_divu_i64(cpu_LO
[acc
], t0
, t1
);
4659 tcg_gen_remu_i64(cpu_HI
[acc
], t0
, t1
);
4665 tcg_gen_muls2_i64(cpu_LO
[acc
], cpu_HI
[acc
], t0
, t1
);
4668 tcg_gen_mulu2_i64(cpu_LO
[acc
], cpu_HI
[acc
], t0
, t1
);
4673 TCGv_i64 t2
= tcg_temp_new_i64();
4674 TCGv_i64 t3
= tcg_temp_new_i64();
4676 tcg_gen_ext_tl_i64(t2
, t0
);
4677 tcg_gen_ext_tl_i64(t3
, t1
);
4678 tcg_gen_mul_i64(t2
, t2
, t3
);
4679 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
4680 tcg_gen_add_i64(t2
, t2
, t3
);
4681 tcg_temp_free_i64(t3
);
4682 gen_move_low32(cpu_LO
[acc
], t2
);
4683 gen_move_high32(cpu_HI
[acc
], t2
);
4684 tcg_temp_free_i64(t2
);
4689 TCGv_i64 t2
= tcg_temp_new_i64();
4690 TCGv_i64 t3
= tcg_temp_new_i64();
4692 tcg_gen_ext32u_tl(t0
, t0
);
4693 tcg_gen_ext32u_tl(t1
, t1
);
4694 tcg_gen_extu_tl_i64(t2
, t0
);
4695 tcg_gen_extu_tl_i64(t3
, t1
);
4696 tcg_gen_mul_i64(t2
, t2
, t3
);
4697 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
4698 tcg_gen_add_i64(t2
, t2
, t3
);
4699 tcg_temp_free_i64(t3
);
4700 gen_move_low32(cpu_LO
[acc
], t2
);
4701 gen_move_high32(cpu_HI
[acc
], t2
);
4702 tcg_temp_free_i64(t2
);
4707 TCGv_i64 t2
= tcg_temp_new_i64();
4708 TCGv_i64 t3
= tcg_temp_new_i64();
4710 tcg_gen_ext_tl_i64(t2
, t0
);
4711 tcg_gen_ext_tl_i64(t3
, t1
);
4712 tcg_gen_mul_i64(t2
, t2
, t3
);
4713 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
4714 tcg_gen_sub_i64(t2
, t3
, t2
);
4715 tcg_temp_free_i64(t3
);
4716 gen_move_low32(cpu_LO
[acc
], t2
);
4717 gen_move_high32(cpu_HI
[acc
], t2
);
4718 tcg_temp_free_i64(t2
);
4723 TCGv_i64 t2
= tcg_temp_new_i64();
4724 TCGv_i64 t3
= tcg_temp_new_i64();
4726 tcg_gen_ext32u_tl(t0
, t0
);
4727 tcg_gen_ext32u_tl(t1
, t1
);
4728 tcg_gen_extu_tl_i64(t2
, t0
);
4729 tcg_gen_extu_tl_i64(t3
, t1
);
4730 tcg_gen_mul_i64(t2
, t2
, t3
);
4731 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
4732 tcg_gen_sub_i64(t2
, t3
, t2
);
4733 tcg_temp_free_i64(t3
);
4734 gen_move_low32(cpu_LO
[acc
], t2
);
4735 gen_move_high32(cpu_HI
[acc
], t2
);
4736 tcg_temp_free_i64(t2
);
4740 MIPS_INVAL("mul/div");
4741 gen_reserved_instruction(ctx
);
4750 * These MULT[U] and MADD[U] instructions implemented in for example
4751 * the Toshiba/Sony R5900 and the Toshiba TX19, TX39 and TX79 core
4752 * architectures are special three-operand variants with the syntax
4754 * MULT[U][1] rd, rs, rt
4758 * (rd, LO, HI) <- rs * rt
4762 * MADD[U][1] rd, rs, rt
4766 * (rd, LO, HI) <- (LO, HI) + rs * rt
4768 * where the low-order 32-bits of the result is placed into both the
4769 * GPR rd and the special register LO. The high-order 32-bits of the
4770 * result is placed into the special register HI.
4772 * If the GPR rd is omitted in assembly language, it is taken to be 0,
4773 * which is the zero register that always reads as 0.
4775 static void gen_mul_txx9(DisasContext
*ctx
, uint32_t opc
,
4776 int rd
, int rs
, int rt
)
4778 TCGv t0
= tcg_temp_new();
4779 TCGv t1
= tcg_temp_new();
4782 gen_load_gpr(t0
, rs
);
4783 gen_load_gpr(t1
, rt
);
4791 TCGv_i32 t2
= tcg_temp_new_i32();
4792 TCGv_i32 t3
= tcg_temp_new_i32();
4793 tcg_gen_trunc_tl_i32(t2
, t0
);
4794 tcg_gen_trunc_tl_i32(t3
, t1
);
4795 tcg_gen_muls2_i32(t2
, t3
, t2
, t3
);
4797 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
4799 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
4800 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
4801 tcg_temp_free_i32(t2
);
4802 tcg_temp_free_i32(t3
);
4805 case MMI_OPC_MULTU1
:
4810 TCGv_i32 t2
= tcg_temp_new_i32();
4811 TCGv_i32 t3
= tcg_temp_new_i32();
4812 tcg_gen_trunc_tl_i32(t2
, t0
);
4813 tcg_gen_trunc_tl_i32(t3
, t1
);
4814 tcg_gen_mulu2_i32(t2
, t3
, t2
, t3
);
4816 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
4818 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
4819 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
4820 tcg_temp_free_i32(t2
);
4821 tcg_temp_free_i32(t3
);
4829 TCGv_i64 t2
= tcg_temp_new_i64();
4830 TCGv_i64 t3
= tcg_temp_new_i64();
4832 tcg_gen_ext_tl_i64(t2
, t0
);
4833 tcg_gen_ext_tl_i64(t3
, t1
);
4834 tcg_gen_mul_i64(t2
, t2
, t3
);
4835 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
4836 tcg_gen_add_i64(t2
, t2
, t3
);
4837 tcg_temp_free_i64(t3
);
4838 gen_move_low32(cpu_LO
[acc
], t2
);
4839 gen_move_high32(cpu_HI
[acc
], t2
);
4841 gen_move_low32(cpu_gpr
[rd
], t2
);
4843 tcg_temp_free_i64(t2
);
4846 case MMI_OPC_MADDU1
:
4851 TCGv_i64 t2
= tcg_temp_new_i64();
4852 TCGv_i64 t3
= tcg_temp_new_i64();
4854 tcg_gen_ext32u_tl(t0
, t0
);
4855 tcg_gen_ext32u_tl(t1
, t1
);
4856 tcg_gen_extu_tl_i64(t2
, t0
);
4857 tcg_gen_extu_tl_i64(t3
, t1
);
4858 tcg_gen_mul_i64(t2
, t2
, t3
);
4859 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
4860 tcg_gen_add_i64(t2
, t2
, t3
);
4861 tcg_temp_free_i64(t3
);
4862 gen_move_low32(cpu_LO
[acc
], t2
);
4863 gen_move_high32(cpu_HI
[acc
], t2
);
4865 gen_move_low32(cpu_gpr
[rd
], t2
);
4867 tcg_temp_free_i64(t2
);
4871 MIPS_INVAL("mul/madd TXx9");
4872 gen_reserved_instruction(ctx
);
4881 static void gen_mul_vr54xx(DisasContext
*ctx
, uint32_t opc
,
4882 int rd
, int rs
, int rt
)
4884 TCGv t0
= tcg_temp_new();
4885 TCGv t1
= tcg_temp_new();
4887 gen_load_gpr(t0
, rs
);
4888 gen_load_gpr(t1
, rt
);
4891 case OPC_VR54XX_MULS
:
4892 gen_helper_muls(t0
, cpu_env
, t0
, t1
);
4894 case OPC_VR54XX_MULSU
:
4895 gen_helper_mulsu(t0
, cpu_env
, t0
, t1
);
4897 case OPC_VR54XX_MACC
:
4898 gen_helper_macc(t0
, cpu_env
, t0
, t1
);
4900 case OPC_VR54XX_MACCU
:
4901 gen_helper_maccu(t0
, cpu_env
, t0
, t1
);
4903 case OPC_VR54XX_MSAC
:
4904 gen_helper_msac(t0
, cpu_env
, t0
, t1
);
4906 case OPC_VR54XX_MSACU
:
4907 gen_helper_msacu(t0
, cpu_env
, t0
, t1
);
4909 case OPC_VR54XX_MULHI
:
4910 gen_helper_mulhi(t0
, cpu_env
, t0
, t1
);
4912 case OPC_VR54XX_MULHIU
:
4913 gen_helper_mulhiu(t0
, cpu_env
, t0
, t1
);
4915 case OPC_VR54XX_MULSHI
:
4916 gen_helper_mulshi(t0
, cpu_env
, t0
, t1
);
4918 case OPC_VR54XX_MULSHIU
:
4919 gen_helper_mulshiu(t0
, cpu_env
, t0
, t1
);
4921 case OPC_VR54XX_MACCHI
:
4922 gen_helper_macchi(t0
, cpu_env
, t0
, t1
);
4924 case OPC_VR54XX_MACCHIU
:
4925 gen_helper_macchiu(t0
, cpu_env
, t0
, t1
);
4927 case OPC_VR54XX_MSACHI
:
4928 gen_helper_msachi(t0
, cpu_env
, t0
, t1
);
4930 case OPC_VR54XX_MSACHIU
:
4931 gen_helper_msachiu(t0
, cpu_env
, t0
, t1
);
4934 MIPS_INVAL("mul vr54xx");
4935 gen_reserved_instruction(ctx
);
4938 gen_store_gpr(t0
, rd
);
4945 static void gen_cl(DisasContext
*ctx
, uint32_t opc
,
4955 gen_load_gpr(t0
, rs
);
4960 #if defined(TARGET_MIPS64)
4964 tcg_gen_not_tl(t0
, t0
);
4973 tcg_gen_ext32u_tl(t0
, t0
);
4974 tcg_gen_clzi_tl(t0
, t0
, TARGET_LONG_BITS
);
4975 tcg_gen_subi_tl(t0
, t0
, TARGET_LONG_BITS
- 32);
4977 #if defined(TARGET_MIPS64)
4982 tcg_gen_clzi_i64(t0
, t0
, 64);
4988 /* Godson integer instructions */
4989 static void gen_loongson_integer(DisasContext
*ctx
, uint32_t opc
,
4990 int rd
, int rs
, int rt
)
5002 case OPC_MULTU_G_2E
:
5003 case OPC_MULTU_G_2F
:
5004 #if defined(TARGET_MIPS64)
5005 case OPC_DMULT_G_2E
:
5006 case OPC_DMULT_G_2F
:
5007 case OPC_DMULTU_G_2E
:
5008 case OPC_DMULTU_G_2F
:
5010 t0
= tcg_temp_new();
5011 t1
= tcg_temp_new();
5014 t0
= tcg_temp_local_new();
5015 t1
= tcg_temp_local_new();
5019 gen_load_gpr(t0
, rs
);
5020 gen_load_gpr(t1
, rt
);
5025 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
5026 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
5028 case OPC_MULTU_G_2E
:
5029 case OPC_MULTU_G_2F
:
5030 tcg_gen_ext32u_tl(t0
, t0
);
5031 tcg_gen_ext32u_tl(t1
, t1
);
5032 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
5033 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
5038 TCGLabel
*l1
= gen_new_label();
5039 TCGLabel
*l2
= gen_new_label();
5040 TCGLabel
*l3
= gen_new_label();
5041 tcg_gen_ext32s_tl(t0
, t0
);
5042 tcg_gen_ext32s_tl(t1
, t1
);
5043 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
5044 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
5047 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, INT_MIN
, l2
);
5048 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1, l2
);
5049 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
5052 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
5053 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
5060 TCGLabel
*l1
= gen_new_label();
5061 TCGLabel
*l2
= gen_new_label();
5062 tcg_gen_ext32u_tl(t0
, t0
);
5063 tcg_gen_ext32u_tl(t1
, t1
);
5064 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
5065 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
5068 tcg_gen_divu_tl(cpu_gpr
[rd
], t0
, t1
);
5069 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
5076 TCGLabel
*l1
= gen_new_label();
5077 TCGLabel
*l2
= gen_new_label();
5078 TCGLabel
*l3
= gen_new_label();
5079 tcg_gen_ext32u_tl(t0
, t0
);
5080 tcg_gen_ext32u_tl(t1
, t1
);
5081 tcg_gen_brcondi_tl(TCG_COND_EQ
, t1
, 0, l1
);
5082 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, INT_MIN
, l2
);
5083 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1, l2
);
5085 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
5088 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
5089 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
5096 TCGLabel
*l1
= gen_new_label();
5097 TCGLabel
*l2
= gen_new_label();
5098 tcg_gen_ext32u_tl(t0
, t0
);
5099 tcg_gen_ext32u_tl(t1
, t1
);
5100 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
5101 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
5104 tcg_gen_remu_tl(cpu_gpr
[rd
], t0
, t1
);
5105 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
5109 #if defined(TARGET_MIPS64)
5110 case OPC_DMULT_G_2E
:
5111 case OPC_DMULT_G_2F
:
5112 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
5114 case OPC_DMULTU_G_2E
:
5115 case OPC_DMULTU_G_2F
:
5116 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
5121 TCGLabel
*l1
= gen_new_label();
5122 TCGLabel
*l2
= gen_new_label();
5123 TCGLabel
*l3
= gen_new_label();
5124 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
5125 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
5128 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, -1LL << 63, l2
);
5129 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1LL, l2
);
5130 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
5133 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
5137 case OPC_DDIVU_G_2E
:
5138 case OPC_DDIVU_G_2F
:
5140 TCGLabel
*l1
= gen_new_label();
5141 TCGLabel
*l2
= gen_new_label();
5142 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
5143 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
5146 tcg_gen_divu_tl(cpu_gpr
[rd
], t0
, t1
);
5153 TCGLabel
*l1
= gen_new_label();
5154 TCGLabel
*l2
= gen_new_label();
5155 TCGLabel
*l3
= gen_new_label();
5156 tcg_gen_brcondi_tl(TCG_COND_EQ
, t1
, 0, l1
);
5157 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, -1LL << 63, l2
);
5158 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1LL, l2
);
5160 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
5163 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
5167 case OPC_DMODU_G_2E
:
5168 case OPC_DMODU_G_2F
:
5170 TCGLabel
*l1
= gen_new_label();
5171 TCGLabel
*l2
= gen_new_label();
5172 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
5173 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
5176 tcg_gen_remu_tl(cpu_gpr
[rd
], t0
, t1
);
5187 /* Loongson multimedia instructions */
5188 static void gen_loongson_multimedia(DisasContext
*ctx
, int rd
, int rs
, int rt
)
5190 uint32_t opc
, shift_max
;
5194 opc
= MASK_LMMI(ctx
->opcode
);
5200 t0
= tcg_temp_local_new_i64();
5201 t1
= tcg_temp_local_new_i64();
5204 t0
= tcg_temp_new_i64();
5205 t1
= tcg_temp_new_i64();
5209 check_cp1_enabled(ctx
);
5210 gen_load_fpr64(ctx
, t0
, rs
);
5211 gen_load_fpr64(ctx
, t1
, rt
);
5215 gen_helper_paddsh(t0
, t0
, t1
);
5218 gen_helper_paddush(t0
, t0
, t1
);
5221 gen_helper_paddh(t0
, t0
, t1
);
5224 gen_helper_paddw(t0
, t0
, t1
);
5227 gen_helper_paddsb(t0
, t0
, t1
);
5230 gen_helper_paddusb(t0
, t0
, t1
);
5233 gen_helper_paddb(t0
, t0
, t1
);
5237 gen_helper_psubsh(t0
, t0
, t1
);
5240 gen_helper_psubush(t0
, t0
, t1
);
5243 gen_helper_psubh(t0
, t0
, t1
);
5246 gen_helper_psubw(t0
, t0
, t1
);
5249 gen_helper_psubsb(t0
, t0
, t1
);
5252 gen_helper_psubusb(t0
, t0
, t1
);
5255 gen_helper_psubb(t0
, t0
, t1
);
5259 gen_helper_pshufh(t0
, t0
, t1
);
5262 gen_helper_packsswh(t0
, t0
, t1
);
5265 gen_helper_packsshb(t0
, t0
, t1
);
5268 gen_helper_packushb(t0
, t0
, t1
);
5272 gen_helper_punpcklhw(t0
, t0
, t1
);
5275 gen_helper_punpckhhw(t0
, t0
, t1
);
5278 gen_helper_punpcklbh(t0
, t0
, t1
);
5281 gen_helper_punpckhbh(t0
, t0
, t1
);
5284 gen_helper_punpcklwd(t0
, t0
, t1
);
5287 gen_helper_punpckhwd(t0
, t0
, t1
);
5291 gen_helper_pavgh(t0
, t0
, t1
);
5294 gen_helper_pavgb(t0
, t0
, t1
);
5297 gen_helper_pmaxsh(t0
, t0
, t1
);
5300 gen_helper_pminsh(t0
, t0
, t1
);
5303 gen_helper_pmaxub(t0
, t0
, t1
);
5306 gen_helper_pminub(t0
, t0
, t1
);
5310 gen_helper_pcmpeqw(t0
, t0
, t1
);
5313 gen_helper_pcmpgtw(t0
, t0
, t1
);
5316 gen_helper_pcmpeqh(t0
, t0
, t1
);
5319 gen_helper_pcmpgth(t0
, t0
, t1
);
5322 gen_helper_pcmpeqb(t0
, t0
, t1
);
5325 gen_helper_pcmpgtb(t0
, t0
, t1
);
5329 gen_helper_psllw(t0
, t0
, t1
);
5332 gen_helper_psllh(t0
, t0
, t1
);
5335 gen_helper_psrlw(t0
, t0
, t1
);
5338 gen_helper_psrlh(t0
, t0
, t1
);
5341 gen_helper_psraw(t0
, t0
, t1
);
5344 gen_helper_psrah(t0
, t0
, t1
);
5348 gen_helper_pmullh(t0
, t0
, t1
);
5351 gen_helper_pmulhh(t0
, t0
, t1
);
5354 gen_helper_pmulhuh(t0
, t0
, t1
);
5357 gen_helper_pmaddhw(t0
, t0
, t1
);
5361 gen_helper_pasubub(t0
, t0
, t1
);
5364 gen_helper_biadd(t0
, t0
);
5367 gen_helper_pmovmskb(t0
, t0
);
5371 tcg_gen_add_i64(t0
, t0
, t1
);
5374 tcg_gen_sub_i64(t0
, t0
, t1
);
5377 tcg_gen_xor_i64(t0
, t0
, t1
);
5380 tcg_gen_nor_i64(t0
, t0
, t1
);
5383 tcg_gen_and_i64(t0
, t0
, t1
);
5386 tcg_gen_or_i64(t0
, t0
, t1
);
5390 tcg_gen_andc_i64(t0
, t1
, t0
);
5394 tcg_gen_deposit_i64(t0
, t0
, t1
, 0, 16);
5397 tcg_gen_deposit_i64(t0
, t0
, t1
, 16, 16);
5400 tcg_gen_deposit_i64(t0
, t0
, t1
, 32, 16);
5403 tcg_gen_deposit_i64(t0
, t0
, t1
, 48, 16);
5407 tcg_gen_andi_i64(t1
, t1
, 3);
5408 tcg_gen_shli_i64(t1
, t1
, 4);
5409 tcg_gen_shr_i64(t0
, t0
, t1
);
5410 tcg_gen_ext16u_i64(t0
, t0
);
5414 tcg_gen_add_i64(t0
, t0
, t1
);
5415 tcg_gen_ext32s_i64(t0
, t0
);
5418 tcg_gen_sub_i64(t0
, t0
, t1
);
5419 tcg_gen_ext32s_i64(t0
, t0
);
5441 /* Make sure shift count isn't TCG undefined behaviour. */
5442 tcg_gen_andi_i64(t1
, t1
, shift_max
- 1);
5447 tcg_gen_shl_i64(t0
, t0
, t1
);
5452 * Since SRA is UndefinedResult without sign-extended inputs,
5453 * we can treat SRA and DSRA the same.
5455 tcg_gen_sar_i64(t0
, t0
, t1
);
5458 /* We want to shift in zeros for SRL; zero-extend first. */
5459 tcg_gen_ext32u_i64(t0
, t0
);
5462 tcg_gen_shr_i64(t0
, t0
, t1
);
5466 if (shift_max
== 32) {
5467 tcg_gen_ext32s_i64(t0
, t0
);
5470 /* Shifts larger than MAX produce zero. */
5471 tcg_gen_setcondi_i64(TCG_COND_LTU
, t1
, t1
, shift_max
);
5472 tcg_gen_neg_i64(t1
, t1
);
5473 tcg_gen_and_i64(t0
, t0
, t1
);
5479 TCGv_i64 t2
= tcg_temp_new_i64();
5480 TCGLabel
*lab
= gen_new_label();
5482 tcg_gen_mov_i64(t2
, t0
);
5483 tcg_gen_add_i64(t0
, t1
, t2
);
5484 if (opc
== OPC_ADD_CP2
) {
5485 tcg_gen_ext32s_i64(t0
, t0
);
5487 tcg_gen_xor_i64(t1
, t1
, t2
);
5488 tcg_gen_xor_i64(t2
, t2
, t0
);
5489 tcg_gen_andc_i64(t1
, t2
, t1
);
5490 tcg_temp_free_i64(t2
);
5491 tcg_gen_brcondi_i64(TCG_COND_GE
, t1
, 0, lab
);
5492 generate_exception(ctx
, EXCP_OVERFLOW
);
5500 TCGv_i64 t2
= tcg_temp_new_i64();
5501 TCGLabel
*lab
= gen_new_label();
5503 tcg_gen_mov_i64(t2
, t0
);
5504 tcg_gen_sub_i64(t0
, t1
, t2
);
5505 if (opc
== OPC_SUB_CP2
) {
5506 tcg_gen_ext32s_i64(t0
, t0
);
5508 tcg_gen_xor_i64(t1
, t1
, t2
);
5509 tcg_gen_xor_i64(t2
, t2
, t0
);
5510 tcg_gen_and_i64(t1
, t1
, t2
);
5511 tcg_temp_free_i64(t2
);
5512 tcg_gen_brcondi_i64(TCG_COND_GE
, t1
, 0, lab
);
5513 generate_exception(ctx
, EXCP_OVERFLOW
);
5519 tcg_gen_ext32u_i64(t0
, t0
);
5520 tcg_gen_ext32u_i64(t1
, t1
);
5521 tcg_gen_mul_i64(t0
, t0
, t1
);
5530 cond
= TCG_COND_LTU
;
5538 cond
= TCG_COND_LEU
;
5545 int cc
= (ctx
->opcode
>> 8) & 0x7;
5546 TCGv_i64 t64
= tcg_temp_new_i64();
5547 TCGv_i32 t32
= tcg_temp_new_i32();
5549 tcg_gen_setcond_i64(cond
, t64
, t0
, t1
);
5550 tcg_gen_extrl_i64_i32(t32
, t64
);
5551 tcg_gen_deposit_i32(fpu_fcr31
, fpu_fcr31
, t32
,
5554 tcg_temp_free_i32(t32
);
5555 tcg_temp_free_i64(t64
);
5560 MIPS_INVAL("loongson_cp2");
5561 gen_reserved_instruction(ctx
);
5565 gen_store_fpr64(ctx
, t0
, rd
);
5568 tcg_temp_free_i64(t0
);
5569 tcg_temp_free_i64(t1
);
5572 static void gen_loongson_lswc2(DisasContext
*ctx
, int rt
,
5577 #if defined(TARGET_MIPS64)
5578 int lsq_rt1
= ctx
->opcode
& 0x1f;
5579 int lsq_offset
= sextract32(ctx
->opcode
, 6, 9) << 4;
5581 int shf_offset
= sextract32(ctx
->opcode
, 6, 8);
5583 t0
= tcg_temp_new();
5585 switch (MASK_LOONGSON_GSLSQ(ctx
->opcode
)) {
5586 #if defined(TARGET_MIPS64)
5588 t1
= tcg_temp_new();
5589 gen_base_offset_addr(ctx
, t0
, rs
, lsq_offset
);
5590 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
|
5591 ctx
->default_tcg_memop_mask
);
5592 gen_base_offset_addr(ctx
, t0
, rs
, lsq_offset
+ 8);
5593 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
|
5594 ctx
->default_tcg_memop_mask
);
5595 gen_store_gpr(t1
, rt
);
5596 gen_store_gpr(t0
, lsq_rt1
);
5600 check_cp1_enabled(ctx
);
5601 t1
= tcg_temp_new();
5602 gen_base_offset_addr(ctx
, t0
, rs
, lsq_offset
);
5603 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
|
5604 ctx
->default_tcg_memop_mask
);
5605 gen_base_offset_addr(ctx
, t0
, rs
, lsq_offset
+ 8);
5606 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
|
5607 ctx
->default_tcg_memop_mask
);
5608 gen_store_fpr64(ctx
, t1
, rt
);
5609 gen_store_fpr64(ctx
, t0
, lsq_rt1
);
5613 t1
= tcg_temp_new();
5614 gen_base_offset_addr(ctx
, t0
, rs
, lsq_offset
);
5615 gen_load_gpr(t1
, rt
);
5616 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
|
5617 ctx
->default_tcg_memop_mask
);
5618 gen_base_offset_addr(ctx
, t0
, rs
, lsq_offset
+ 8);
5619 gen_load_gpr(t1
, lsq_rt1
);
5620 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
|
5621 ctx
->default_tcg_memop_mask
);
5625 check_cp1_enabled(ctx
);
5626 t1
= tcg_temp_new();
5627 gen_base_offset_addr(ctx
, t0
, rs
, lsq_offset
);
5628 gen_load_fpr64(ctx
, t1
, rt
);
5629 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
|
5630 ctx
->default_tcg_memop_mask
);
5631 gen_base_offset_addr(ctx
, t0
, rs
, lsq_offset
+ 8);
5632 gen_load_fpr64(ctx
, t1
, lsq_rt1
);
5633 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
|
5634 ctx
->default_tcg_memop_mask
);
5639 switch (MASK_LOONGSON_GSSHFLS(ctx
->opcode
)) {
5641 check_cp1_enabled(ctx
);
5642 gen_base_offset_addr(ctx
, t0
, rs
, shf_offset
);
5643 t1
= tcg_temp_new();
5644 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
5645 tcg_gen_andi_tl(t1
, t0
, 3);
5646 #ifndef TARGET_WORDS_BIGENDIAN
5647 tcg_gen_xori_tl(t1
, t1
, 3);
5649 tcg_gen_shli_tl(t1
, t1
, 3);
5650 tcg_gen_andi_tl(t0
, t0
, ~3);
5651 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEUL
);
5652 tcg_gen_shl_tl(t0
, t0
, t1
);
5653 t2
= tcg_const_tl(-1);
5654 tcg_gen_shl_tl(t2
, t2
, t1
);
5655 fp0
= tcg_temp_new_i32();
5656 gen_load_fpr32(ctx
, fp0
, rt
);
5657 tcg_gen_ext_i32_tl(t1
, fp0
);
5658 tcg_gen_andc_tl(t1
, t1
, t2
);
5660 tcg_gen_or_tl(t0
, t0
, t1
);
5662 #if defined(TARGET_MIPS64)
5663 tcg_gen_extrl_i64_i32(fp0
, t0
);
5665 tcg_gen_ext32s_tl(fp0
, t0
);
5667 gen_store_fpr32(ctx
, fp0
, rt
);
5668 tcg_temp_free_i32(fp0
);
5671 check_cp1_enabled(ctx
);
5672 gen_base_offset_addr(ctx
, t0
, rs
, shf_offset
);
5673 t1
= tcg_temp_new();
5674 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
5675 tcg_gen_andi_tl(t1
, t0
, 3);
5676 #ifdef TARGET_WORDS_BIGENDIAN
5677 tcg_gen_xori_tl(t1
, t1
, 3);
5679 tcg_gen_shli_tl(t1
, t1
, 3);
5680 tcg_gen_andi_tl(t0
, t0
, ~3);
5681 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEUL
);
5682 tcg_gen_shr_tl(t0
, t0
, t1
);
5683 tcg_gen_xori_tl(t1
, t1
, 31);
5684 t2
= tcg_const_tl(0xfffffffeull
);
5685 tcg_gen_shl_tl(t2
, t2
, t1
);
5686 fp0
= tcg_temp_new_i32();
5687 gen_load_fpr32(ctx
, fp0
, rt
);
5688 tcg_gen_ext_i32_tl(t1
, fp0
);
5689 tcg_gen_and_tl(t1
, t1
, t2
);
5691 tcg_gen_or_tl(t0
, t0
, t1
);
5693 #if defined(TARGET_MIPS64)
5694 tcg_gen_extrl_i64_i32(fp0
, t0
);
5696 tcg_gen_ext32s_tl(fp0
, t0
);
5698 gen_store_fpr32(ctx
, fp0
, rt
);
5699 tcg_temp_free_i32(fp0
);
5701 #if defined(TARGET_MIPS64)
5703 check_cp1_enabled(ctx
);
5704 gen_base_offset_addr(ctx
, t0
, rs
, shf_offset
);
5705 t1
= tcg_temp_new();
5706 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
5707 tcg_gen_andi_tl(t1
, t0
, 7);
5708 #ifndef TARGET_WORDS_BIGENDIAN
5709 tcg_gen_xori_tl(t1
, t1
, 7);
5711 tcg_gen_shli_tl(t1
, t1
, 3);
5712 tcg_gen_andi_tl(t0
, t0
, ~7);
5713 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
);
5714 tcg_gen_shl_tl(t0
, t0
, t1
);
5715 t2
= tcg_const_tl(-1);
5716 tcg_gen_shl_tl(t2
, t2
, t1
);
5717 gen_load_fpr64(ctx
, t1
, rt
);
5718 tcg_gen_andc_tl(t1
, t1
, t2
);
5720 tcg_gen_or_tl(t0
, t0
, t1
);
5722 gen_store_fpr64(ctx
, t0
, rt
);
5725 check_cp1_enabled(ctx
);
5726 gen_base_offset_addr(ctx
, t0
, rs
, shf_offset
);
5727 t1
= tcg_temp_new();
5728 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
5729 tcg_gen_andi_tl(t1
, t0
, 7);
5730 #ifdef TARGET_WORDS_BIGENDIAN
5731 tcg_gen_xori_tl(t1
, t1
, 7);
5733 tcg_gen_shli_tl(t1
, t1
, 3);
5734 tcg_gen_andi_tl(t0
, t0
, ~7);
5735 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
);
5736 tcg_gen_shr_tl(t0
, t0
, t1
);
5737 tcg_gen_xori_tl(t1
, t1
, 63);
5738 t2
= tcg_const_tl(0xfffffffffffffffeull
);
5739 tcg_gen_shl_tl(t2
, t2
, t1
);
5740 gen_load_fpr64(ctx
, t1
, rt
);
5741 tcg_gen_and_tl(t1
, t1
, t2
);
5743 tcg_gen_or_tl(t0
, t0
, t1
);
5745 gen_store_fpr64(ctx
, t0
, rt
);
5749 MIPS_INVAL("loongson_gsshfl");
5750 gen_reserved_instruction(ctx
);
5755 switch (MASK_LOONGSON_GSSHFLS(ctx
->opcode
)) {
5757 check_cp1_enabled(ctx
);
5758 t1
= tcg_temp_new();
5759 gen_base_offset_addr(ctx
, t0
, rs
, shf_offset
);
5760 fp0
= tcg_temp_new_i32();
5761 gen_load_fpr32(ctx
, fp0
, rt
);
5762 tcg_gen_ext_i32_tl(t1
, fp0
);
5763 gen_helper_0e2i(swl
, t1
, t0
, ctx
->mem_idx
);
5764 tcg_temp_free_i32(fp0
);
5768 check_cp1_enabled(ctx
);
5769 t1
= tcg_temp_new();
5770 gen_base_offset_addr(ctx
, t0
, rs
, shf_offset
);
5771 fp0
= tcg_temp_new_i32();
5772 gen_load_fpr32(ctx
, fp0
, rt
);
5773 tcg_gen_ext_i32_tl(t1
, fp0
);
5774 gen_helper_0e2i(swr
, t1
, t0
, ctx
->mem_idx
);
5775 tcg_temp_free_i32(fp0
);
5778 #if defined(TARGET_MIPS64)
5780 check_cp1_enabled(ctx
);
5781 t1
= tcg_temp_new();
5782 gen_base_offset_addr(ctx
, t0
, rs
, shf_offset
);
5783 gen_load_fpr64(ctx
, t1
, rt
);
5784 gen_helper_0e2i(sdl
, t1
, t0
, ctx
->mem_idx
);
5788 check_cp1_enabled(ctx
);
5789 t1
= tcg_temp_new();
5790 gen_base_offset_addr(ctx
, t0
, rs
, shf_offset
);
5791 gen_load_fpr64(ctx
, t1
, rt
);
5792 gen_helper_0e2i(sdr
, t1
, t0
, ctx
->mem_idx
);
5797 MIPS_INVAL("loongson_gsshfs");
5798 gen_reserved_instruction(ctx
);
5803 MIPS_INVAL("loongson_gslsq");
5804 gen_reserved_instruction(ctx
);
5810 /* Loongson EXT LDC2/SDC2 */
5811 static void gen_loongson_lsdc2(DisasContext
*ctx
, int rt
,
5814 int offset
= sextract32(ctx
->opcode
, 3, 8);
5815 uint32_t opc
= MASK_LOONGSON_LSDC2(ctx
->opcode
);
5819 /* Pre-conditions */
5825 /* prefetch, implement as NOP */
5836 #if defined(TARGET_MIPS64)
5839 check_cp1_enabled(ctx
);
5840 /* prefetch, implement as NOP */
5846 #if defined(TARGET_MIPS64)
5849 check_cp1_enabled(ctx
);
5852 MIPS_INVAL("loongson_lsdc2");
5853 gen_reserved_instruction(ctx
);
5858 t0
= tcg_temp_new();
5860 gen_base_offset_addr(ctx
, t0
, rs
, offset
);
5861 gen_op_addr_add(ctx
, t0
, cpu_gpr
[rd
], t0
);
5865 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_SB
);
5866 gen_store_gpr(t0
, rt
);
5869 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESW
|
5870 ctx
->default_tcg_memop_mask
);
5871 gen_store_gpr(t0
, rt
);
5874 gen_base_offset_addr(ctx
, t0
, rs
, offset
);
5876 gen_op_addr_add(ctx
, t0
, cpu_gpr
[rd
], t0
);
5878 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESL
|
5879 ctx
->default_tcg_memop_mask
);
5880 gen_store_gpr(t0
, rt
);
5882 #if defined(TARGET_MIPS64)
5884 gen_base_offset_addr(ctx
, t0
, rs
, offset
);
5886 gen_op_addr_add(ctx
, t0
, cpu_gpr
[rd
], t0
);
5888 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
|
5889 ctx
->default_tcg_memop_mask
);
5890 gen_store_gpr(t0
, rt
);
5894 check_cp1_enabled(ctx
);
5895 gen_base_offset_addr(ctx
, t0
, rs
, offset
);
5897 gen_op_addr_add(ctx
, t0
, cpu_gpr
[rd
], t0
);
5899 fp0
= tcg_temp_new_i32();
5900 tcg_gen_qemu_ld_i32(fp0
, t0
, ctx
->mem_idx
, MO_TESL
|
5901 ctx
->default_tcg_memop_mask
);
5902 gen_store_fpr32(ctx
, fp0
, rt
);
5903 tcg_temp_free_i32(fp0
);
5905 #if defined(TARGET_MIPS64)
5907 check_cp1_enabled(ctx
);
5908 gen_base_offset_addr(ctx
, t0
, rs
, offset
);
5910 gen_op_addr_add(ctx
, t0
, cpu_gpr
[rd
], t0
);
5912 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
|
5913 ctx
->default_tcg_memop_mask
);
5914 gen_store_fpr64(ctx
, t0
, rt
);
5918 t1
= tcg_temp_new();
5919 gen_load_gpr(t1
, rt
);
5920 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_SB
);
5924 t1
= tcg_temp_new();
5925 gen_load_gpr(t1
, rt
);
5926 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUW
|
5927 ctx
->default_tcg_memop_mask
);
5931 t1
= tcg_temp_new();
5932 gen_load_gpr(t1
, rt
);
5933 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
|
5934 ctx
->default_tcg_memop_mask
);
5937 #if defined(TARGET_MIPS64)
5939 t1
= tcg_temp_new();
5940 gen_load_gpr(t1
, rt
);
5941 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
|
5942 ctx
->default_tcg_memop_mask
);
5947 fp0
= tcg_temp_new_i32();
5948 gen_load_fpr32(ctx
, fp0
, rt
);
5949 tcg_gen_qemu_st_i32(fp0
, t0
, ctx
->mem_idx
, MO_TEUL
|
5950 ctx
->default_tcg_memop_mask
);
5951 tcg_temp_free_i32(fp0
);
5953 #if defined(TARGET_MIPS64)
5955 t1
= tcg_temp_new();
5956 gen_load_fpr64(ctx
, t1
, rt
);
5957 tcg_gen_qemu_st_i64(t1
, t0
, ctx
->mem_idx
, MO_TEQ
|
5958 ctx
->default_tcg_memop_mask
);
5970 static void gen_trap(DisasContext
*ctx
, uint32_t opc
,
5971 int rs
, int rt
, int16_t imm
)
5974 TCGv t0
= tcg_temp_new();
5975 TCGv t1
= tcg_temp_new();
5978 /* Load needed operands */
5986 /* Compare two registers */
5988 gen_load_gpr(t0
, rs
);
5989 gen_load_gpr(t1
, rt
);
5999 /* Compare register to immediate */
6000 if (rs
!= 0 || imm
!= 0) {
6001 gen_load_gpr(t0
, rs
);
6002 tcg_gen_movi_tl(t1
, (int32_t)imm
);
6009 case OPC_TEQ
: /* rs == rs */
6010 case OPC_TEQI
: /* r0 == 0 */
6011 case OPC_TGE
: /* rs >= rs */
6012 case OPC_TGEI
: /* r0 >= 0 */
6013 case OPC_TGEU
: /* rs >= rs unsigned */
6014 case OPC_TGEIU
: /* r0 >= 0 unsigned */
6016 generate_exception_end(ctx
, EXCP_TRAP
);
6018 case OPC_TLT
: /* rs < rs */
6019 case OPC_TLTI
: /* r0 < 0 */
6020 case OPC_TLTU
: /* rs < rs unsigned */
6021 case OPC_TLTIU
: /* r0 < 0 unsigned */
6022 case OPC_TNE
: /* rs != rs */
6023 case OPC_TNEI
: /* r0 != 0 */
6024 /* Never trap: treat as NOP. */
6028 TCGLabel
*l1
= gen_new_label();
6033 tcg_gen_brcond_tl(TCG_COND_NE
, t0
, t1
, l1
);
6037 tcg_gen_brcond_tl(TCG_COND_LT
, t0
, t1
, l1
);
6041 tcg_gen_brcond_tl(TCG_COND_LTU
, t0
, t1
, l1
);
6045 tcg_gen_brcond_tl(TCG_COND_GE
, t0
, t1
, l1
);
6049 tcg_gen_brcond_tl(TCG_COND_GEU
, t0
, t1
, l1
);
6053 tcg_gen_brcond_tl(TCG_COND_EQ
, t0
, t1
, l1
);
6056 generate_exception(ctx
, EXCP_TRAP
);
6063 static inline bool use_goto_tb(DisasContext
*ctx
, target_ulong dest
)
6065 if (unlikely(ctx
->base
.singlestep_enabled
)) {
6069 #ifndef CONFIG_USER_ONLY
6070 return (ctx
->base
.tb
->pc
& TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
);
6076 static inline void gen_goto_tb(DisasContext
*ctx
, int n
, target_ulong dest
)
6078 if (use_goto_tb(ctx
, dest
)) {
6081 tcg_gen_exit_tb(ctx
->base
.tb
, n
);
6084 if (ctx
->base
.singlestep_enabled
) {
6085 save_cpu_state(ctx
, 0);
6086 gen_helper_raise_exception_debug(cpu_env
);
6088 tcg_gen_lookup_and_goto_ptr();
6092 /* Branches (before delay slot) */
6093 static void gen_compute_branch(DisasContext
*ctx
, uint32_t opc
,
6095 int rs
, int rt
, int32_t offset
,
6098 target_ulong btgt
= -1;
6100 int bcond_compute
= 0;
6101 TCGv t0
= tcg_temp_new();
6102 TCGv t1
= tcg_temp_new();
6104 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
6105 #ifdef MIPS_DEBUG_DISAS
6106 LOG_DISAS("Branch in delay / forbidden slot at PC 0x"
6107 TARGET_FMT_lx
"\n", ctx
->base
.pc_next
);
6109 gen_reserved_instruction(ctx
);
6113 /* Load needed operands */
6119 /* Compare two registers */
6121 gen_load_gpr(t0
, rs
);
6122 gen_load_gpr(t1
, rt
);
6125 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ offset
;
6139 /* Compare to zero */
6141 gen_load_gpr(t0
, rs
);
6144 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ offset
;
6147 #if defined(TARGET_MIPS64)
6149 tcg_gen_andi_tl(t0
, cpu_dspctrl
, 0x7F);
6151 tcg_gen_andi_tl(t0
, cpu_dspctrl
, 0x3F);
6154 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ offset
;
6159 /* Jump to immediate */
6160 btgt
= ((ctx
->base
.pc_next
+ insn_bytes
) & (int32_t)0xF0000000) |
6165 /* Jump to register */
6166 if (offset
!= 0 && offset
!= 16) {
6168 * Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
6169 * others are reserved.
6171 MIPS_INVAL("jump hint");
6172 gen_reserved_instruction(ctx
);
6175 gen_load_gpr(btarget
, rs
);
6178 MIPS_INVAL("branch/jump");
6179 gen_reserved_instruction(ctx
);
6182 if (bcond_compute
== 0) {
6183 /* No condition to be computed */
6185 case OPC_BEQ
: /* rx == rx */
6186 case OPC_BEQL
: /* rx == rx likely */
6187 case OPC_BGEZ
: /* 0 >= 0 */
6188 case OPC_BGEZL
: /* 0 >= 0 likely */
6189 case OPC_BLEZ
: /* 0 <= 0 */
6190 case OPC_BLEZL
: /* 0 <= 0 likely */
6192 ctx
->hflags
|= MIPS_HFLAG_B
;
6194 case OPC_BGEZAL
: /* 0 >= 0 */
6195 case OPC_BGEZALL
: /* 0 >= 0 likely */
6196 /* Always take and link */
6198 ctx
->hflags
|= MIPS_HFLAG_B
;
6200 case OPC_BNE
: /* rx != rx */
6201 case OPC_BGTZ
: /* 0 > 0 */
6202 case OPC_BLTZ
: /* 0 < 0 */
6205 case OPC_BLTZAL
: /* 0 < 0 */
6207 * Handle as an unconditional branch to get correct delay
6211 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ delayslot_size
;
6212 ctx
->hflags
|= MIPS_HFLAG_B
;
6214 case OPC_BLTZALL
: /* 0 < 0 likely */
6215 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 8);
6216 /* Skip the instruction in the delay slot */
6217 ctx
->base
.pc_next
+= 4;
6219 case OPC_BNEL
: /* rx != rx likely */
6220 case OPC_BGTZL
: /* 0 > 0 likely */
6221 case OPC_BLTZL
: /* 0 < 0 likely */
6222 /* Skip the instruction in the delay slot */
6223 ctx
->base
.pc_next
+= 4;
6226 ctx
->hflags
|= MIPS_HFLAG_B
;
6229 ctx
->hflags
|= MIPS_HFLAG_BX
;
6233 ctx
->hflags
|= MIPS_HFLAG_B
;
6236 ctx
->hflags
|= MIPS_HFLAG_BR
;
6240 ctx
->hflags
|= MIPS_HFLAG_BR
;
6243 MIPS_INVAL("branch/jump");
6244 gen_reserved_instruction(ctx
);
6250 tcg_gen_setcond_tl(TCG_COND_EQ
, bcond
, t0
, t1
);
6253 tcg_gen_setcond_tl(TCG_COND_EQ
, bcond
, t0
, t1
);
6256 tcg_gen_setcond_tl(TCG_COND_NE
, bcond
, t0
, t1
);
6259 tcg_gen_setcond_tl(TCG_COND_NE
, bcond
, t0
, t1
);
6262 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
6265 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
6268 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
6272 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
6276 tcg_gen_setcondi_tl(TCG_COND_GT
, bcond
, t0
, 0);
6279 tcg_gen_setcondi_tl(TCG_COND_GT
, bcond
, t0
, 0);
6282 tcg_gen_setcondi_tl(TCG_COND_LE
, bcond
, t0
, 0);
6285 tcg_gen_setcondi_tl(TCG_COND_LE
, bcond
, t0
, 0);
6288 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
6291 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
6294 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 32);
6296 #if defined(TARGET_MIPS64)
6298 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 64);
6302 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
6305 ctx
->hflags
|= MIPS_HFLAG_BC
;
6308 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
6311 ctx
->hflags
|= MIPS_HFLAG_BL
;
6314 MIPS_INVAL("conditional branch/jump");
6315 gen_reserved_instruction(ctx
);
6320 ctx
->btarget
= btgt
;
6322 switch (delayslot_size
) {
6324 ctx
->hflags
|= MIPS_HFLAG_BDS16
;
6327 ctx
->hflags
|= MIPS_HFLAG_BDS32
;
6332 int post_delay
= insn_bytes
+ delayslot_size
;
6333 int lowbit
= !!(ctx
->hflags
& MIPS_HFLAG_M16
);
6335 tcg_gen_movi_tl(cpu_gpr
[blink
],
6336 ctx
->base
.pc_next
+ post_delay
+ lowbit
);
6340 if (insn_bytes
== 2) {
6341 ctx
->hflags
|= MIPS_HFLAG_B16
;
6348 /* nanoMIPS Branches */
6349 static void gen_compute_branch_nm(DisasContext
*ctx
, uint32_t opc
,
6351 int rs
, int rt
, int32_t offset
)
6353 target_ulong btgt
= -1;
6354 int bcond_compute
= 0;
6355 TCGv t0
= tcg_temp_new();
6356 TCGv t1
= tcg_temp_new();
6358 /* Load needed operands */
6362 /* Compare two registers */
6364 gen_load_gpr(t0
, rs
);
6365 gen_load_gpr(t1
, rt
);
6368 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ offset
;
6371 /* Compare to zero */
6373 gen_load_gpr(t0
, rs
);
6376 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ offset
;
6379 tcg_gen_andi_tl(t0
, cpu_dspctrl
, 0x3F);
6381 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ offset
;
6385 /* Jump to register */
6386 if (offset
!= 0 && offset
!= 16) {
6388 * Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
6389 * others are reserved.
6391 MIPS_INVAL("jump hint");
6392 gen_reserved_instruction(ctx
);
6395 gen_load_gpr(btarget
, rs
);
6398 MIPS_INVAL("branch/jump");
6399 gen_reserved_instruction(ctx
);
6402 if (bcond_compute
== 0) {
6403 /* No condition to be computed */
6405 case OPC_BEQ
: /* rx == rx */
6407 ctx
->hflags
|= MIPS_HFLAG_B
;
6409 case OPC_BGEZAL
: /* 0 >= 0 */
6410 /* Always take and link */
6411 tcg_gen_movi_tl(cpu_gpr
[31],
6412 ctx
->base
.pc_next
+ insn_bytes
);
6413 ctx
->hflags
|= MIPS_HFLAG_B
;
6415 case OPC_BNE
: /* rx != rx */
6416 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 8);
6417 /* Skip the instruction in the delay slot */
6418 ctx
->base
.pc_next
+= 4;
6421 ctx
->hflags
|= MIPS_HFLAG_BR
;
6425 tcg_gen_movi_tl(cpu_gpr
[rt
],
6426 ctx
->base
.pc_next
+ insn_bytes
);
6428 ctx
->hflags
|= MIPS_HFLAG_BR
;
6431 MIPS_INVAL("branch/jump");
6432 gen_reserved_instruction(ctx
);
6438 tcg_gen_setcond_tl(TCG_COND_EQ
, bcond
, t0
, t1
);
6441 tcg_gen_setcond_tl(TCG_COND_NE
, bcond
, t0
, t1
);
6444 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
6445 tcg_gen_movi_tl(cpu_gpr
[31],
6446 ctx
->base
.pc_next
+ insn_bytes
);
6449 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 32);
6451 ctx
->hflags
|= MIPS_HFLAG_BC
;
6454 MIPS_INVAL("conditional branch/jump");
6455 gen_reserved_instruction(ctx
);
6460 ctx
->btarget
= btgt
;
6463 if (insn_bytes
== 2) {
6464 ctx
->hflags
|= MIPS_HFLAG_B16
;
6471 /* special3 bitfield operations */
6472 static void gen_bitops(DisasContext
*ctx
, uint32_t opc
, int rt
,
6473 int rs
, int lsb
, int msb
)
6475 TCGv t0
= tcg_temp_new();
6476 TCGv t1
= tcg_temp_new();
6478 gen_load_gpr(t1
, rs
);
6481 if (lsb
+ msb
> 31) {
6485 tcg_gen_extract_tl(t0
, t1
, lsb
, msb
+ 1);
6488 * The two checks together imply that lsb == 0,
6489 * so this is a simple sign-extension.
6491 tcg_gen_ext32s_tl(t0
, t1
);
6494 #if defined(TARGET_MIPS64)
6503 if (lsb
+ msb
> 63) {
6506 tcg_gen_extract_tl(t0
, t1
, lsb
, msb
+ 1);
6513 gen_load_gpr(t0
, rt
);
6514 tcg_gen_deposit_tl(t0
, t0
, t1
, lsb
, msb
- lsb
+ 1);
6515 tcg_gen_ext32s_tl(t0
, t0
);
6517 #if defined(TARGET_MIPS64)
6528 gen_load_gpr(t0
, rt
);
6529 tcg_gen_deposit_tl(t0
, t0
, t1
, lsb
, msb
- lsb
+ 1);
6534 MIPS_INVAL("bitops");
6535 gen_reserved_instruction(ctx
);
6540 gen_store_gpr(t0
, rt
);
6545 static void gen_bshfl(DisasContext
*ctx
, uint32_t op2
, int rt
, int rd
)
6550 /* If no destination, treat it as a NOP. */
6554 t0
= tcg_temp_new();
6555 gen_load_gpr(t0
, rt
);
6559 TCGv t1
= tcg_temp_new();
6560 TCGv t2
= tcg_const_tl(0x00FF00FF);
6562 tcg_gen_shri_tl(t1
, t0
, 8);
6563 tcg_gen_and_tl(t1
, t1
, t2
);
6564 tcg_gen_and_tl(t0
, t0
, t2
);
6565 tcg_gen_shli_tl(t0
, t0
, 8);
6566 tcg_gen_or_tl(t0
, t0
, t1
);
6569 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
6573 tcg_gen_ext8s_tl(cpu_gpr
[rd
], t0
);
6576 tcg_gen_ext16s_tl(cpu_gpr
[rd
], t0
);
6578 #if defined(TARGET_MIPS64)
6581 TCGv t1
= tcg_temp_new();
6582 TCGv t2
= tcg_const_tl(0x00FF00FF00FF00FFULL
);
6584 tcg_gen_shri_tl(t1
, t0
, 8);
6585 tcg_gen_and_tl(t1
, t1
, t2
);
6586 tcg_gen_and_tl(t0
, t0
, t2
);
6587 tcg_gen_shli_tl(t0
, t0
, 8);
6588 tcg_gen_or_tl(cpu_gpr
[rd
], t0
, t1
);
6595 TCGv t1
= tcg_temp_new();
6596 TCGv t2
= tcg_const_tl(0x0000FFFF0000FFFFULL
);
6598 tcg_gen_shri_tl(t1
, t0
, 16);
6599 tcg_gen_and_tl(t1
, t1
, t2
);
6600 tcg_gen_and_tl(t0
, t0
, t2
);
6601 tcg_gen_shli_tl(t0
, t0
, 16);
6602 tcg_gen_or_tl(t0
, t0
, t1
);
6603 tcg_gen_shri_tl(t1
, t0
, 32);
6604 tcg_gen_shli_tl(t0
, t0
, 32);
6605 tcg_gen_or_tl(cpu_gpr
[rd
], t0
, t1
);
6612 MIPS_INVAL("bsfhl");
6613 gen_reserved_instruction(ctx
);
6620 static void gen_align_bits(DisasContext
*ctx
, int wordsz
, int rd
, int rs
,
6628 t0
= tcg_temp_new();
6629 if (bits
== 0 || bits
== wordsz
) {
6631 gen_load_gpr(t0
, rt
);
6633 gen_load_gpr(t0
, rs
);
6637 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
6639 #if defined(TARGET_MIPS64)
6641 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
6646 TCGv t1
= tcg_temp_new();
6647 gen_load_gpr(t0
, rt
);
6648 gen_load_gpr(t1
, rs
);
6652 TCGv_i64 t2
= tcg_temp_new_i64();
6653 tcg_gen_concat_tl_i64(t2
, t1
, t0
);
6654 tcg_gen_shri_i64(t2
, t2
, 32 - bits
);
6655 gen_move_low32(cpu_gpr
[rd
], t2
);
6656 tcg_temp_free_i64(t2
);
6659 #if defined(TARGET_MIPS64)
6661 tcg_gen_shli_tl(t0
, t0
, bits
);
6662 tcg_gen_shri_tl(t1
, t1
, 64 - bits
);
6663 tcg_gen_or_tl(cpu_gpr
[rd
], t1
, t0
);
6673 static void gen_align(DisasContext
*ctx
, int wordsz
, int rd
, int rs
, int rt
,
6676 gen_align_bits(ctx
, wordsz
, rd
, rs
, rt
, bp
* 8);
6679 static void gen_ext(DisasContext
*ctx
, int wordsz
, int rd
, int rs
, int rt
,
6682 gen_align_bits(ctx
, wordsz
, rd
, rs
, rt
, wordsz
- shift
);
6685 static void gen_bitswap(DisasContext
*ctx
, int opc
, int rd
, int rt
)
6692 t0
= tcg_temp_new();
6693 gen_load_gpr(t0
, rt
);
6696 gen_helper_bitswap(cpu_gpr
[rd
], t0
);
6698 #if defined(TARGET_MIPS64)
6700 gen_helper_dbitswap(cpu_gpr
[rd
], t0
);
6707 #ifndef CONFIG_USER_ONLY
6708 /* CP0 (MMU and control) */
6709 static inline void gen_mthc0_entrylo(TCGv arg
, target_ulong off
)
6711 TCGv_i64 t0
= tcg_temp_new_i64();
6712 TCGv_i64 t1
= tcg_temp_new_i64();
6714 tcg_gen_ext_tl_i64(t0
, arg
);
6715 tcg_gen_ld_i64(t1
, cpu_env
, off
);
6716 #if defined(TARGET_MIPS64)
6717 tcg_gen_deposit_i64(t1
, t1
, t0
, 30, 32);
6719 tcg_gen_concat32_i64(t1
, t1
, t0
);
6721 tcg_gen_st_i64(t1
, cpu_env
, off
);
6722 tcg_temp_free_i64(t1
);
6723 tcg_temp_free_i64(t0
);
6726 static inline void gen_mthc0_store64(TCGv arg
, target_ulong off
)
6728 TCGv_i64 t0
= tcg_temp_new_i64();
6729 TCGv_i64 t1
= tcg_temp_new_i64();
6731 tcg_gen_ext_tl_i64(t0
, arg
);
6732 tcg_gen_ld_i64(t1
, cpu_env
, off
);
6733 tcg_gen_concat32_i64(t1
, t1
, t0
);
6734 tcg_gen_st_i64(t1
, cpu_env
, off
);
6735 tcg_temp_free_i64(t1
);
6736 tcg_temp_free_i64(t0
);
6739 static inline void gen_mfhc0_entrylo(TCGv arg
, target_ulong off
)
6741 TCGv_i64 t0
= tcg_temp_new_i64();
6743 tcg_gen_ld_i64(t0
, cpu_env
, off
);
6744 #if defined(TARGET_MIPS64)
6745 tcg_gen_shri_i64(t0
, t0
, 30);
6747 tcg_gen_shri_i64(t0
, t0
, 32);
6749 gen_move_low32(arg
, t0
);
6750 tcg_temp_free_i64(t0
);
6753 static inline void gen_mfhc0_load64(TCGv arg
, target_ulong off
, int shift
)
6755 TCGv_i64 t0
= tcg_temp_new_i64();
6757 tcg_gen_ld_i64(t0
, cpu_env
, off
);
6758 tcg_gen_shri_i64(t0
, t0
, 32 + shift
);
6759 gen_move_low32(arg
, t0
);
6760 tcg_temp_free_i64(t0
);
6763 static inline void gen_mfc0_load32(TCGv arg
, target_ulong off
)
6765 TCGv_i32 t0
= tcg_temp_new_i32();
6767 tcg_gen_ld_i32(t0
, cpu_env
, off
);
6768 tcg_gen_ext_i32_tl(arg
, t0
);
6769 tcg_temp_free_i32(t0
);
6772 static inline void gen_mfc0_load64(TCGv arg
, target_ulong off
)
6774 tcg_gen_ld_tl(arg
, cpu_env
, off
);
6775 tcg_gen_ext32s_tl(arg
, arg
);
6778 static inline void gen_mtc0_store32(TCGv arg
, target_ulong off
)
6780 TCGv_i32 t0
= tcg_temp_new_i32();
6782 tcg_gen_trunc_tl_i32(t0
, arg
);
6783 tcg_gen_st_i32(t0
, cpu_env
, off
);
6784 tcg_temp_free_i32(t0
);
6787 #define CP0_CHECK(c) \
6790 goto cp0_unimplemented; \
6794 static void gen_mfhc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
6796 const char *register_name
= "invalid";
6799 case CP0_REGISTER_02
:
6802 CP0_CHECK(ctx
->hflags
& MIPS_HFLAG_ELPA
);
6803 gen_mfhc0_entrylo(arg
, offsetof(CPUMIPSState
, CP0_EntryLo0
));
6804 register_name
= "EntryLo0";
6807 goto cp0_unimplemented
;
6810 case CP0_REGISTER_03
:
6812 case CP0_REG03__ENTRYLO1
:
6813 CP0_CHECK(ctx
->hflags
& MIPS_HFLAG_ELPA
);
6814 gen_mfhc0_entrylo(arg
, offsetof(CPUMIPSState
, CP0_EntryLo1
));
6815 register_name
= "EntryLo1";
6818 goto cp0_unimplemented
;
6821 case CP0_REGISTER_09
:
6823 case CP0_REG09__SAAR
:
6824 CP0_CHECK(ctx
->saar
);
6825 gen_helper_mfhc0_saar(arg
, cpu_env
);
6826 register_name
= "SAAR";
6829 goto cp0_unimplemented
;
6832 case CP0_REGISTER_17
:
6834 case CP0_REG17__LLADDR
:
6835 gen_mfhc0_load64(arg
, offsetof(CPUMIPSState
, CP0_LLAddr
),
6836 ctx
->CP0_LLAddr_shift
);
6837 register_name
= "LLAddr";
6839 case CP0_REG17__MAAR
:
6840 CP0_CHECK(ctx
->mrp
);
6841 gen_helper_mfhc0_maar(arg
, cpu_env
);
6842 register_name
= "MAAR";
6845 goto cp0_unimplemented
;
6848 case CP0_REGISTER_19
:
6850 case CP0_REG19__WATCHHI0
:
6851 case CP0_REG19__WATCHHI1
:
6852 case CP0_REG19__WATCHHI2
:
6853 case CP0_REG19__WATCHHI3
:
6854 case CP0_REG19__WATCHHI4
:
6855 case CP0_REG19__WATCHHI5
:
6856 case CP0_REG19__WATCHHI6
:
6857 case CP0_REG19__WATCHHI7
:
6858 /* upper 32 bits are only available when Config5MI != 0 */
6860 gen_mfhc0_load64(arg
, offsetof(CPUMIPSState
, CP0_WatchHi
[sel
]), 0);
6861 register_name
= "WatchHi";
6864 goto cp0_unimplemented
;
6867 case CP0_REGISTER_28
:
6873 gen_mfhc0_load64(arg
, offsetof(CPUMIPSState
, CP0_TagLo
), 0);
6874 register_name
= "TagLo";
6877 goto cp0_unimplemented
;
6881 goto cp0_unimplemented
;
6883 trace_mips_translate_c0("mfhc0", register_name
, reg
, sel
);
6887 qemu_log_mask(LOG_UNIMP
, "mfhc0 %s (reg %d sel %d)\n",
6888 register_name
, reg
, sel
);
6889 tcg_gen_movi_tl(arg
, 0);
6892 static void gen_mthc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
6894 const char *register_name
= "invalid";
6895 uint64_t mask
= ctx
->PAMask
>> 36;
6898 case CP0_REGISTER_02
:
6901 CP0_CHECK(ctx
->hflags
& MIPS_HFLAG_ELPA
);
6902 tcg_gen_andi_tl(arg
, arg
, mask
);
6903 gen_mthc0_entrylo(arg
, offsetof(CPUMIPSState
, CP0_EntryLo0
));
6904 register_name
= "EntryLo0";
6907 goto cp0_unimplemented
;
6910 case CP0_REGISTER_03
:
6912 case CP0_REG03__ENTRYLO1
:
6913 CP0_CHECK(ctx
->hflags
& MIPS_HFLAG_ELPA
);
6914 tcg_gen_andi_tl(arg
, arg
, mask
);
6915 gen_mthc0_entrylo(arg
, offsetof(CPUMIPSState
, CP0_EntryLo1
));
6916 register_name
= "EntryLo1";
6919 goto cp0_unimplemented
;
6922 case CP0_REGISTER_09
:
6924 case CP0_REG09__SAAR
:
6925 CP0_CHECK(ctx
->saar
);
6926 gen_helper_mthc0_saar(cpu_env
, arg
);
6927 register_name
= "SAAR";
6930 goto cp0_unimplemented
;
6933 case CP0_REGISTER_17
:
6935 case CP0_REG17__LLADDR
:
6937 * LLAddr is read-only (the only exception is bit 0 if LLB is
6938 * supported); the CP0_LLAddr_rw_bitmask does not seem to be
6939 * relevant for modern MIPS cores supporting MTHC0, therefore
6940 * treating MTHC0 to LLAddr as NOP.
6942 register_name
= "LLAddr";
6944 case CP0_REG17__MAAR
:
6945 CP0_CHECK(ctx
->mrp
);
6946 gen_helper_mthc0_maar(cpu_env
, arg
);
6947 register_name
= "MAAR";
6950 goto cp0_unimplemented
;
6953 case CP0_REGISTER_19
:
6955 case CP0_REG19__WATCHHI0
:
6956 case CP0_REG19__WATCHHI1
:
6957 case CP0_REG19__WATCHHI2
:
6958 case CP0_REG19__WATCHHI3
:
6959 case CP0_REG19__WATCHHI4
:
6960 case CP0_REG19__WATCHHI5
:
6961 case CP0_REG19__WATCHHI6
:
6962 case CP0_REG19__WATCHHI7
:
6963 /* upper 32 bits are only available when Config5MI != 0 */
6965 gen_helper_0e1i(mthc0_watchhi
, arg
, sel
);
6966 register_name
= "WatchHi";
6969 goto cp0_unimplemented
;
6972 case CP0_REGISTER_28
:
6978 tcg_gen_andi_tl(arg
, arg
, mask
);
6979 gen_mthc0_store64(arg
, offsetof(CPUMIPSState
, CP0_TagLo
));
6980 register_name
= "TagLo";
6983 goto cp0_unimplemented
;
6987 goto cp0_unimplemented
;
6989 trace_mips_translate_c0("mthc0", register_name
, reg
, sel
);
6992 qemu_log_mask(LOG_UNIMP
, "mthc0 %s (reg %d sel %d)\n",
6993 register_name
, reg
, sel
);
6996 static inline void gen_mfc0_unimplemented(DisasContext
*ctx
, TCGv arg
)
6998 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
6999 tcg_gen_movi_tl(arg
, 0);
7001 tcg_gen_movi_tl(arg
, ~0);
7005 static void gen_mfc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
7007 const char *register_name
= "invalid";
7010 check_insn(ctx
, ISA_MIPS_R1
);
7014 case CP0_REGISTER_00
:
7016 case CP0_REG00__INDEX
:
7017 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Index
));
7018 register_name
= "Index";
7020 case CP0_REG00__MVPCONTROL
:
7021 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7022 gen_helper_mfc0_mvpcontrol(arg
, cpu_env
);
7023 register_name
= "MVPControl";
7025 case CP0_REG00__MVPCONF0
:
7026 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7027 gen_helper_mfc0_mvpconf0(arg
, cpu_env
);
7028 register_name
= "MVPConf0";
7030 case CP0_REG00__MVPCONF1
:
7031 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7032 gen_helper_mfc0_mvpconf1(arg
, cpu_env
);
7033 register_name
= "MVPConf1";
7035 case CP0_REG00__VPCONTROL
:
7037 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPControl
));
7038 register_name
= "VPControl";
7041 goto cp0_unimplemented
;
7044 case CP0_REGISTER_01
:
7046 case CP0_REG01__RANDOM
:
7047 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS_R6
));
7048 gen_helper_mfc0_random(arg
, cpu_env
);
7049 register_name
= "Random";
7051 case CP0_REG01__VPECONTROL
:
7052 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7053 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEControl
));
7054 register_name
= "VPEControl";
7056 case CP0_REG01__VPECONF0
:
7057 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7058 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf0
));
7059 register_name
= "VPEConf0";
7061 case CP0_REG01__VPECONF1
:
7062 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7063 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf1
));
7064 register_name
= "VPEConf1";
7066 case CP0_REG01__YQMASK
:
7067 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7068 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_YQMask
));
7069 register_name
= "YQMask";
7071 case CP0_REG01__VPESCHEDULE
:
7072 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7073 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_VPESchedule
));
7074 register_name
= "VPESchedule";
7076 case CP0_REG01__VPESCHEFBACK
:
7077 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7078 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
7079 register_name
= "VPEScheFBack";
7081 case CP0_REG01__VPEOPT
:
7082 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7083 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEOpt
));
7084 register_name
= "VPEOpt";
7087 goto cp0_unimplemented
;
7090 case CP0_REGISTER_02
:
7092 case CP0_REG02__ENTRYLO0
:
7094 TCGv_i64 tmp
= tcg_temp_new_i64();
7095 tcg_gen_ld_i64(tmp
, cpu_env
,
7096 offsetof(CPUMIPSState
, CP0_EntryLo0
));
7097 #if defined(TARGET_MIPS64)
7099 /* Move RI/XI fields to bits 31:30 */
7100 tcg_gen_shri_tl(arg
, tmp
, CP0EnLo_XI
);
7101 tcg_gen_deposit_tl(tmp
, tmp
, arg
, 30, 2);
7104 gen_move_low32(arg
, tmp
);
7105 tcg_temp_free_i64(tmp
);
7107 register_name
= "EntryLo0";
7109 case CP0_REG02__TCSTATUS
:
7110 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7111 gen_helper_mfc0_tcstatus(arg
, cpu_env
);
7112 register_name
= "TCStatus";
7114 case CP0_REG02__TCBIND
:
7115 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7116 gen_helper_mfc0_tcbind(arg
, cpu_env
);
7117 register_name
= "TCBind";
7119 case CP0_REG02__TCRESTART
:
7120 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7121 gen_helper_mfc0_tcrestart(arg
, cpu_env
);
7122 register_name
= "TCRestart";
7124 case CP0_REG02__TCHALT
:
7125 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7126 gen_helper_mfc0_tchalt(arg
, cpu_env
);
7127 register_name
= "TCHalt";
7129 case CP0_REG02__TCCONTEXT
:
7130 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7131 gen_helper_mfc0_tccontext(arg
, cpu_env
);
7132 register_name
= "TCContext";
7134 case CP0_REG02__TCSCHEDULE
:
7135 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7136 gen_helper_mfc0_tcschedule(arg
, cpu_env
);
7137 register_name
= "TCSchedule";
7139 case CP0_REG02__TCSCHEFBACK
:
7140 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7141 gen_helper_mfc0_tcschefback(arg
, cpu_env
);
7142 register_name
= "TCScheFBack";
7145 goto cp0_unimplemented
;
7148 case CP0_REGISTER_03
:
7150 case CP0_REG03__ENTRYLO1
:
7152 TCGv_i64 tmp
= tcg_temp_new_i64();
7153 tcg_gen_ld_i64(tmp
, cpu_env
,
7154 offsetof(CPUMIPSState
, CP0_EntryLo1
));
7155 #if defined(TARGET_MIPS64)
7157 /* Move RI/XI fields to bits 31:30 */
7158 tcg_gen_shri_tl(arg
, tmp
, CP0EnLo_XI
);
7159 tcg_gen_deposit_tl(tmp
, tmp
, arg
, 30, 2);
7162 gen_move_low32(arg
, tmp
);
7163 tcg_temp_free_i64(tmp
);
7165 register_name
= "EntryLo1";
7167 case CP0_REG03__GLOBALNUM
:
7169 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_GlobalNumber
));
7170 register_name
= "GlobalNumber";
7173 goto cp0_unimplemented
;
7176 case CP0_REGISTER_04
:
7178 case CP0_REG04__CONTEXT
:
7179 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_Context
));
7180 tcg_gen_ext32s_tl(arg
, arg
);
7181 register_name
= "Context";
7183 case CP0_REG04__CONTEXTCONFIG
:
7185 /* gen_helper_mfc0_contextconfig(arg); */
7186 register_name
= "ContextConfig";
7187 goto cp0_unimplemented
;
7188 case CP0_REG04__USERLOCAL
:
7189 CP0_CHECK(ctx
->ulri
);
7190 tcg_gen_ld_tl(arg
, cpu_env
,
7191 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
7192 tcg_gen_ext32s_tl(arg
, arg
);
7193 register_name
= "UserLocal";
7195 case CP0_REG04__MMID
:
7197 gen_helper_mtc0_memorymapid(cpu_env
, arg
);
7198 register_name
= "MMID";
7201 goto cp0_unimplemented
;
7204 case CP0_REGISTER_05
:
7206 case CP0_REG05__PAGEMASK
:
7207 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageMask
));
7208 register_name
= "PageMask";
7210 case CP0_REG05__PAGEGRAIN
:
7211 check_insn(ctx
, ISA_MIPS_R2
);
7212 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageGrain
));
7213 register_name
= "PageGrain";
7215 case CP0_REG05__SEGCTL0
:
7217 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_SegCtl0
));
7218 tcg_gen_ext32s_tl(arg
, arg
);
7219 register_name
= "SegCtl0";
7221 case CP0_REG05__SEGCTL1
:
7223 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_SegCtl1
));
7224 tcg_gen_ext32s_tl(arg
, arg
);
7225 register_name
= "SegCtl1";
7227 case CP0_REG05__SEGCTL2
:
7229 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_SegCtl2
));
7230 tcg_gen_ext32s_tl(arg
, arg
);
7231 register_name
= "SegCtl2";
7233 case CP0_REG05__PWBASE
:
7235 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PWBase
));
7236 register_name
= "PWBase";
7238 case CP0_REG05__PWFIELD
:
7240 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PWField
));
7241 register_name
= "PWField";
7243 case CP0_REG05__PWSIZE
:
7245 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PWSize
));
7246 register_name
= "PWSize";
7249 goto cp0_unimplemented
;
7252 case CP0_REGISTER_06
:
7254 case CP0_REG06__WIRED
:
7255 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Wired
));
7256 register_name
= "Wired";
7258 case CP0_REG06__SRSCONF0
:
7259 check_insn(ctx
, ISA_MIPS_R2
);
7260 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf0
));
7261 register_name
= "SRSConf0";
7263 case CP0_REG06__SRSCONF1
:
7264 check_insn(ctx
, ISA_MIPS_R2
);
7265 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf1
));
7266 register_name
= "SRSConf1";
7268 case CP0_REG06__SRSCONF2
:
7269 check_insn(ctx
, ISA_MIPS_R2
);
7270 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf2
));
7271 register_name
= "SRSConf2";
7273 case CP0_REG06__SRSCONF3
:
7274 check_insn(ctx
, ISA_MIPS_R2
);
7275 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf3
));
7276 register_name
= "SRSConf3";
7278 case CP0_REG06__SRSCONF4
:
7279 check_insn(ctx
, ISA_MIPS_R2
);
7280 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf4
));
7281 register_name
= "SRSConf4";
7283 case CP0_REG06__PWCTL
:
7285 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PWCtl
));
7286 register_name
= "PWCtl";
7289 goto cp0_unimplemented
;
7292 case CP0_REGISTER_07
:
7294 case CP0_REG07__HWRENA
:
7295 check_insn(ctx
, ISA_MIPS_R2
);
7296 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_HWREna
));
7297 register_name
= "HWREna";
7300 goto cp0_unimplemented
;
7303 case CP0_REGISTER_08
:
7305 case CP0_REG08__BADVADDR
:
7306 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_BadVAddr
));
7307 tcg_gen_ext32s_tl(arg
, arg
);
7308 register_name
= "BadVAddr";
7310 case CP0_REG08__BADINSTR
:
7312 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstr
));
7313 register_name
= "BadInstr";
7315 case CP0_REG08__BADINSTRP
:
7317 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstrP
));
7318 register_name
= "BadInstrP";
7320 case CP0_REG08__BADINSTRX
:
7322 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstrX
));
7323 tcg_gen_andi_tl(arg
, arg
, ~0xffff);
7324 register_name
= "BadInstrX";
7327 goto cp0_unimplemented
;
7330 case CP0_REGISTER_09
:
7332 case CP0_REG09__COUNT
:
7333 /* Mark as an IO operation because we read the time. */
7334 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
7337 gen_helper_mfc0_count(arg
, cpu_env
);
7339 * Break the TB to be able to take timer interrupts immediately
7340 * after reading count. DISAS_STOP isn't sufficient, we need to
7341 * ensure we break completely out of translated code.
7343 gen_save_pc(ctx
->base
.pc_next
+ 4);
7344 ctx
->base
.is_jmp
= DISAS_EXIT
;
7345 register_name
= "Count";
7347 case CP0_REG09__SAARI
:
7348 CP0_CHECK(ctx
->saar
);
7349 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SAARI
));
7350 register_name
= "SAARI";
7352 case CP0_REG09__SAAR
:
7353 CP0_CHECK(ctx
->saar
);
7354 gen_helper_mfc0_saar(arg
, cpu_env
);
7355 register_name
= "SAAR";
7358 goto cp0_unimplemented
;
7361 case CP0_REGISTER_10
:
7363 case CP0_REG10__ENTRYHI
:
7364 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryHi
));
7365 tcg_gen_ext32s_tl(arg
, arg
);
7366 register_name
= "EntryHi";
7369 goto cp0_unimplemented
;
7372 case CP0_REGISTER_11
:
7374 case CP0_REG11__COMPARE
:
7375 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Compare
));
7376 register_name
= "Compare";
7378 /* 6,7 are implementation dependent */
7380 goto cp0_unimplemented
;
7383 case CP0_REGISTER_12
:
7385 case CP0_REG12__STATUS
:
7386 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Status
));
7387 register_name
= "Status";
7389 case CP0_REG12__INTCTL
:
7390 check_insn(ctx
, ISA_MIPS_R2
);
7391 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_IntCtl
));
7392 register_name
= "IntCtl";
7394 case CP0_REG12__SRSCTL
:
7395 check_insn(ctx
, ISA_MIPS_R2
);
7396 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
7397 register_name
= "SRSCtl";
7399 case CP0_REG12__SRSMAP
:
7400 check_insn(ctx
, ISA_MIPS_R2
);
7401 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
7402 register_name
= "SRSMap";
7405 goto cp0_unimplemented
;
7408 case CP0_REGISTER_13
:
7410 case CP0_REG13__CAUSE
:
7411 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Cause
));
7412 register_name
= "Cause";
7415 goto cp0_unimplemented
;
7418 case CP0_REGISTER_14
:
7420 case CP0_REG14__EPC
:
7421 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
7422 tcg_gen_ext32s_tl(arg
, arg
);
7423 register_name
= "EPC";
7426 goto cp0_unimplemented
;
7429 case CP0_REGISTER_15
:
7431 case CP0_REG15__PRID
:
7432 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PRid
));
7433 register_name
= "PRid";
7435 case CP0_REG15__EBASE
:
7436 check_insn(ctx
, ISA_MIPS_R2
);
7437 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EBase
));
7438 tcg_gen_ext32s_tl(arg
, arg
);
7439 register_name
= "EBase";
7441 case CP0_REG15__CMGCRBASE
:
7442 check_insn(ctx
, ISA_MIPS_R2
);
7443 CP0_CHECK(ctx
->cmgcr
);
7444 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_CMGCRBase
));
7445 tcg_gen_ext32s_tl(arg
, arg
);
7446 register_name
= "CMGCRBase";
7449 goto cp0_unimplemented
;
7452 case CP0_REGISTER_16
:
7454 case CP0_REG16__CONFIG
:
7455 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config0
));
7456 register_name
= "Config";
7458 case CP0_REG16__CONFIG1
:
7459 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config1
));
7460 register_name
= "Config1";
7462 case CP0_REG16__CONFIG2
:
7463 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config2
));
7464 register_name
= "Config2";
7466 case CP0_REG16__CONFIG3
:
7467 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config3
));
7468 register_name
= "Config3";
7470 case CP0_REG16__CONFIG4
:
7471 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config4
));
7472 register_name
= "Config4";
7474 case CP0_REG16__CONFIG5
:
7475 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config5
));
7476 register_name
= "Config5";
7478 /* 6,7 are implementation dependent */
7479 case CP0_REG16__CONFIG6
:
7480 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config6
));
7481 register_name
= "Config6";
7483 case CP0_REG16__CONFIG7
:
7484 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config7
));
7485 register_name
= "Config7";
7488 goto cp0_unimplemented
;
7491 case CP0_REGISTER_17
:
7493 case CP0_REG17__LLADDR
:
7494 gen_helper_mfc0_lladdr(arg
, cpu_env
);
7495 register_name
= "LLAddr";
7497 case CP0_REG17__MAAR
:
7498 CP0_CHECK(ctx
->mrp
);
7499 gen_helper_mfc0_maar(arg
, cpu_env
);
7500 register_name
= "MAAR";
7502 case CP0_REG17__MAARI
:
7503 CP0_CHECK(ctx
->mrp
);
7504 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_MAARI
));
7505 register_name
= "MAARI";
7508 goto cp0_unimplemented
;
7511 case CP0_REGISTER_18
:
7513 case CP0_REG18__WATCHLO0
:
7514 case CP0_REG18__WATCHLO1
:
7515 case CP0_REG18__WATCHLO2
:
7516 case CP0_REG18__WATCHLO3
:
7517 case CP0_REG18__WATCHLO4
:
7518 case CP0_REG18__WATCHLO5
:
7519 case CP0_REG18__WATCHLO6
:
7520 case CP0_REG18__WATCHLO7
:
7521 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
7522 gen_helper_1e0i(mfc0_watchlo
, arg
, sel
);
7523 register_name
= "WatchLo";
7526 goto cp0_unimplemented
;
7529 case CP0_REGISTER_19
:
7531 case CP0_REG19__WATCHHI0
:
7532 case CP0_REG19__WATCHHI1
:
7533 case CP0_REG19__WATCHHI2
:
7534 case CP0_REG19__WATCHHI3
:
7535 case CP0_REG19__WATCHHI4
:
7536 case CP0_REG19__WATCHHI5
:
7537 case CP0_REG19__WATCHHI6
:
7538 case CP0_REG19__WATCHHI7
:
7539 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
7540 gen_helper_1e0i(mfc0_watchhi
, arg
, sel
);
7541 register_name
= "WatchHi";
7544 goto cp0_unimplemented
;
7547 case CP0_REGISTER_20
:
7549 case CP0_REG20__XCONTEXT
:
7550 #if defined(TARGET_MIPS64)
7551 check_insn(ctx
, ISA_MIPS3
);
7552 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_XContext
));
7553 tcg_gen_ext32s_tl(arg
, arg
);
7554 register_name
= "XContext";
7558 goto cp0_unimplemented
;
7561 case CP0_REGISTER_21
:
7562 /* Officially reserved, but sel 0 is used for R1x000 framemask */
7563 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS_R6
));
7566 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Framemask
));
7567 register_name
= "Framemask";
7570 goto cp0_unimplemented
;
7573 case CP0_REGISTER_22
:
7574 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
7575 register_name
= "'Diagnostic"; /* implementation dependent */
7577 case CP0_REGISTER_23
:
7579 case CP0_REG23__DEBUG
:
7580 gen_helper_mfc0_debug(arg
, cpu_env
); /* EJTAG support */
7581 register_name
= "Debug";
7583 case CP0_REG23__TRACECONTROL
:
7584 /* PDtrace support */
7585 /* gen_helper_mfc0_tracecontrol(arg); */
7586 register_name
= "TraceControl";
7587 goto cp0_unimplemented
;
7588 case CP0_REG23__TRACECONTROL2
:
7589 /* PDtrace support */
7590 /* gen_helper_mfc0_tracecontrol2(arg); */
7591 register_name
= "TraceControl2";
7592 goto cp0_unimplemented
;
7593 case CP0_REG23__USERTRACEDATA1
:
7594 /* PDtrace support */
7595 /* gen_helper_mfc0_usertracedata1(arg);*/
7596 register_name
= "UserTraceData1";
7597 goto cp0_unimplemented
;
7598 case CP0_REG23__TRACEIBPC
:
7599 /* PDtrace support */
7600 /* gen_helper_mfc0_traceibpc(arg); */
7601 register_name
= "TraceIBPC";
7602 goto cp0_unimplemented
;
7603 case CP0_REG23__TRACEDBPC
:
7604 /* PDtrace support */
7605 /* gen_helper_mfc0_tracedbpc(arg); */
7606 register_name
= "TraceDBPC";
7607 goto cp0_unimplemented
;
7609 goto cp0_unimplemented
;
7612 case CP0_REGISTER_24
:
7614 case CP0_REG24__DEPC
:
7616 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
7617 tcg_gen_ext32s_tl(arg
, arg
);
7618 register_name
= "DEPC";
7621 goto cp0_unimplemented
;
7624 case CP0_REGISTER_25
:
7626 case CP0_REG25__PERFCTL0
:
7627 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Performance0
));
7628 register_name
= "Performance0";
7630 case CP0_REG25__PERFCNT0
:
7631 /* gen_helper_mfc0_performance1(arg); */
7632 register_name
= "Performance1";
7633 goto cp0_unimplemented
;
7634 case CP0_REG25__PERFCTL1
:
7635 /* gen_helper_mfc0_performance2(arg); */
7636 register_name
= "Performance2";
7637 goto cp0_unimplemented
;
7638 case CP0_REG25__PERFCNT1
:
7639 /* gen_helper_mfc0_performance3(arg); */
7640 register_name
= "Performance3";
7641 goto cp0_unimplemented
;
7642 case CP0_REG25__PERFCTL2
:
7643 /* gen_helper_mfc0_performance4(arg); */
7644 register_name
= "Performance4";
7645 goto cp0_unimplemented
;
7646 case CP0_REG25__PERFCNT2
:
7647 /* gen_helper_mfc0_performance5(arg); */
7648 register_name
= "Performance5";
7649 goto cp0_unimplemented
;
7650 case CP0_REG25__PERFCTL3
:
7651 /* gen_helper_mfc0_performance6(arg); */
7652 register_name
= "Performance6";
7653 goto cp0_unimplemented
;
7654 case CP0_REG25__PERFCNT3
:
7655 /* gen_helper_mfc0_performance7(arg); */
7656 register_name
= "Performance7";
7657 goto cp0_unimplemented
;
7659 goto cp0_unimplemented
;
7662 case CP0_REGISTER_26
:
7664 case CP0_REG26__ERRCTL
:
7665 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_ErrCtl
));
7666 register_name
= "ErrCtl";
7669 goto cp0_unimplemented
;
7672 case CP0_REGISTER_27
:
7674 case CP0_REG27__CACHERR
:
7675 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
7676 register_name
= "CacheErr";
7679 goto cp0_unimplemented
;
7682 case CP0_REGISTER_28
:
7684 case CP0_REG28__TAGLO
:
7685 case CP0_REG28__TAGLO1
:
7686 case CP0_REG28__TAGLO2
:
7687 case CP0_REG28__TAGLO3
:
7689 TCGv_i64 tmp
= tcg_temp_new_i64();
7690 tcg_gen_ld_i64(tmp
, cpu_env
, offsetof(CPUMIPSState
, CP0_TagLo
));
7691 gen_move_low32(arg
, tmp
);
7692 tcg_temp_free_i64(tmp
);
7694 register_name
= "TagLo";
7696 case CP0_REG28__DATALO
:
7697 case CP0_REG28__DATALO1
:
7698 case CP0_REG28__DATALO2
:
7699 case CP0_REG28__DATALO3
:
7700 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataLo
));
7701 register_name
= "DataLo";
7704 goto cp0_unimplemented
;
7707 case CP0_REGISTER_29
:
7709 case CP0_REG29__TAGHI
:
7710 case CP0_REG29__TAGHI1
:
7711 case CP0_REG29__TAGHI2
:
7712 case CP0_REG29__TAGHI3
:
7713 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagHi
));
7714 register_name
= "TagHi";
7716 case CP0_REG29__DATAHI
:
7717 case CP0_REG29__DATAHI1
:
7718 case CP0_REG29__DATAHI2
:
7719 case CP0_REG29__DATAHI3
:
7720 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataHi
));
7721 register_name
= "DataHi";
7724 goto cp0_unimplemented
;
7727 case CP0_REGISTER_30
:
7729 case CP0_REG30__ERROREPC
:
7730 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
7731 tcg_gen_ext32s_tl(arg
, arg
);
7732 register_name
= "ErrorEPC";
7735 goto cp0_unimplemented
;
7738 case CP0_REGISTER_31
:
7740 case CP0_REG31__DESAVE
:
7742 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
7743 register_name
= "DESAVE";
7745 case CP0_REG31__KSCRATCH1
:
7746 case CP0_REG31__KSCRATCH2
:
7747 case CP0_REG31__KSCRATCH3
:
7748 case CP0_REG31__KSCRATCH4
:
7749 case CP0_REG31__KSCRATCH5
:
7750 case CP0_REG31__KSCRATCH6
:
7751 CP0_CHECK(ctx
->kscrexist
& (1 << sel
));
7752 tcg_gen_ld_tl(arg
, cpu_env
,
7753 offsetof(CPUMIPSState
, CP0_KScratch
[sel
- 2]));
7754 tcg_gen_ext32s_tl(arg
, arg
);
7755 register_name
= "KScratch";
7758 goto cp0_unimplemented
;
7762 goto cp0_unimplemented
;
7764 trace_mips_translate_c0("mfc0", register_name
, reg
, sel
);
7768 qemu_log_mask(LOG_UNIMP
, "mfc0 %s (reg %d sel %d)\n",
7769 register_name
, reg
, sel
);
7770 gen_mfc0_unimplemented(ctx
, arg
);
7773 static void gen_mtc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
7775 const char *register_name
= "invalid";
7778 check_insn(ctx
, ISA_MIPS_R1
);
7781 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
7786 case CP0_REGISTER_00
:
7788 case CP0_REG00__INDEX
:
7789 gen_helper_mtc0_index(cpu_env
, arg
);
7790 register_name
= "Index";
7792 case CP0_REG00__MVPCONTROL
:
7793 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7794 gen_helper_mtc0_mvpcontrol(cpu_env
, arg
);
7795 register_name
= "MVPControl";
7797 case CP0_REG00__MVPCONF0
:
7798 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7800 register_name
= "MVPConf0";
7802 case CP0_REG00__MVPCONF1
:
7803 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7805 register_name
= "MVPConf1";
7807 case CP0_REG00__VPCONTROL
:
7810 register_name
= "VPControl";
7813 goto cp0_unimplemented
;
7816 case CP0_REGISTER_01
:
7818 case CP0_REG01__RANDOM
:
7820 register_name
= "Random";
7822 case CP0_REG01__VPECONTROL
:
7823 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7824 gen_helper_mtc0_vpecontrol(cpu_env
, arg
);
7825 register_name
= "VPEControl";
7827 case CP0_REG01__VPECONF0
:
7828 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7829 gen_helper_mtc0_vpeconf0(cpu_env
, arg
);
7830 register_name
= "VPEConf0";
7832 case CP0_REG01__VPECONF1
:
7833 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7834 gen_helper_mtc0_vpeconf1(cpu_env
, arg
);
7835 register_name
= "VPEConf1";
7837 case CP0_REG01__YQMASK
:
7838 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7839 gen_helper_mtc0_yqmask(cpu_env
, arg
);
7840 register_name
= "YQMask";
7842 case CP0_REG01__VPESCHEDULE
:
7843 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7844 tcg_gen_st_tl(arg
, cpu_env
,
7845 offsetof(CPUMIPSState
, CP0_VPESchedule
));
7846 register_name
= "VPESchedule";
7848 case CP0_REG01__VPESCHEFBACK
:
7849 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7850 tcg_gen_st_tl(arg
, cpu_env
,
7851 offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
7852 register_name
= "VPEScheFBack";
7854 case CP0_REG01__VPEOPT
:
7855 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7856 gen_helper_mtc0_vpeopt(cpu_env
, arg
);
7857 register_name
= "VPEOpt";
7860 goto cp0_unimplemented
;
7863 case CP0_REGISTER_02
:
7865 case CP0_REG02__ENTRYLO0
:
7866 gen_helper_mtc0_entrylo0(cpu_env
, arg
);
7867 register_name
= "EntryLo0";
7869 case CP0_REG02__TCSTATUS
:
7870 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7871 gen_helper_mtc0_tcstatus(cpu_env
, arg
);
7872 register_name
= "TCStatus";
7874 case CP0_REG02__TCBIND
:
7875 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7876 gen_helper_mtc0_tcbind(cpu_env
, arg
);
7877 register_name
= "TCBind";
7879 case CP0_REG02__TCRESTART
:
7880 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7881 gen_helper_mtc0_tcrestart(cpu_env
, arg
);
7882 register_name
= "TCRestart";
7884 case CP0_REG02__TCHALT
:
7885 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7886 gen_helper_mtc0_tchalt(cpu_env
, arg
);
7887 register_name
= "TCHalt";
7889 case CP0_REG02__TCCONTEXT
:
7890 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7891 gen_helper_mtc0_tccontext(cpu_env
, arg
);
7892 register_name
= "TCContext";
7894 case CP0_REG02__TCSCHEDULE
:
7895 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7896 gen_helper_mtc0_tcschedule(cpu_env
, arg
);
7897 register_name
= "TCSchedule";
7899 case CP0_REG02__TCSCHEFBACK
:
7900 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7901 gen_helper_mtc0_tcschefback(cpu_env
, arg
);
7902 register_name
= "TCScheFBack";
7905 goto cp0_unimplemented
;
7908 case CP0_REGISTER_03
:
7910 case CP0_REG03__ENTRYLO1
:
7911 gen_helper_mtc0_entrylo1(cpu_env
, arg
);
7912 register_name
= "EntryLo1";
7914 case CP0_REG03__GLOBALNUM
:
7917 register_name
= "GlobalNumber";
7920 goto cp0_unimplemented
;
7923 case CP0_REGISTER_04
:
7925 case CP0_REG04__CONTEXT
:
7926 gen_helper_mtc0_context(cpu_env
, arg
);
7927 register_name
= "Context";
7929 case CP0_REG04__CONTEXTCONFIG
:
7931 /* gen_helper_mtc0_contextconfig(arg); */
7932 register_name
= "ContextConfig";
7933 goto cp0_unimplemented
;
7934 case CP0_REG04__USERLOCAL
:
7935 CP0_CHECK(ctx
->ulri
);
7936 tcg_gen_st_tl(arg
, cpu_env
,
7937 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
7938 register_name
= "UserLocal";
7940 case CP0_REG04__MMID
:
7942 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_MemoryMapID
));
7943 register_name
= "MMID";
7946 goto cp0_unimplemented
;
7949 case CP0_REGISTER_05
:
7951 case CP0_REG05__PAGEMASK
:
7952 gen_helper_mtc0_pagemask(cpu_env
, arg
);
7953 register_name
= "PageMask";
7955 case CP0_REG05__PAGEGRAIN
:
7956 check_insn(ctx
, ISA_MIPS_R2
);
7957 gen_helper_mtc0_pagegrain(cpu_env
, arg
);
7958 register_name
= "PageGrain";
7959 ctx
->base
.is_jmp
= DISAS_STOP
;
7961 case CP0_REG05__SEGCTL0
:
7963 gen_helper_mtc0_segctl0(cpu_env
, arg
);
7964 register_name
= "SegCtl0";
7966 case CP0_REG05__SEGCTL1
:
7968 gen_helper_mtc0_segctl1(cpu_env
, arg
);
7969 register_name
= "SegCtl1";
7971 case CP0_REG05__SEGCTL2
:
7973 gen_helper_mtc0_segctl2(cpu_env
, arg
);
7974 register_name
= "SegCtl2";
7976 case CP0_REG05__PWBASE
:
7978 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_PWBase
));
7979 register_name
= "PWBase";
7981 case CP0_REG05__PWFIELD
:
7983 gen_helper_mtc0_pwfield(cpu_env
, arg
);
7984 register_name
= "PWField";
7986 case CP0_REG05__PWSIZE
:
7988 gen_helper_mtc0_pwsize(cpu_env
, arg
);
7989 register_name
= "PWSize";
7992 goto cp0_unimplemented
;
7995 case CP0_REGISTER_06
:
7997 case CP0_REG06__WIRED
:
7998 gen_helper_mtc0_wired(cpu_env
, arg
);
7999 register_name
= "Wired";
8001 case CP0_REG06__SRSCONF0
:
8002 check_insn(ctx
, ISA_MIPS_R2
);
8003 gen_helper_mtc0_srsconf0(cpu_env
, arg
);
8004 register_name
= "SRSConf0";
8006 case CP0_REG06__SRSCONF1
:
8007 check_insn(ctx
, ISA_MIPS_R2
);
8008 gen_helper_mtc0_srsconf1(cpu_env
, arg
);
8009 register_name
= "SRSConf1";
8011 case CP0_REG06__SRSCONF2
:
8012 check_insn(ctx
, ISA_MIPS_R2
);
8013 gen_helper_mtc0_srsconf2(cpu_env
, arg
);
8014 register_name
= "SRSConf2";
8016 case CP0_REG06__SRSCONF3
:
8017 check_insn(ctx
, ISA_MIPS_R2
);
8018 gen_helper_mtc0_srsconf3(cpu_env
, arg
);
8019 register_name
= "SRSConf3";
8021 case CP0_REG06__SRSCONF4
:
8022 check_insn(ctx
, ISA_MIPS_R2
);
8023 gen_helper_mtc0_srsconf4(cpu_env
, arg
);
8024 register_name
= "SRSConf4";
8026 case CP0_REG06__PWCTL
:
8028 gen_helper_mtc0_pwctl(cpu_env
, arg
);
8029 register_name
= "PWCtl";
8032 goto cp0_unimplemented
;
8035 case CP0_REGISTER_07
:
8037 case CP0_REG07__HWRENA
:
8038 check_insn(ctx
, ISA_MIPS_R2
);
8039 gen_helper_mtc0_hwrena(cpu_env
, arg
);
8040 ctx
->base
.is_jmp
= DISAS_STOP
;
8041 register_name
= "HWREna";
8044 goto cp0_unimplemented
;
8047 case CP0_REGISTER_08
:
8049 case CP0_REG08__BADVADDR
:
8051 register_name
= "BadVAddr";
8053 case CP0_REG08__BADINSTR
:
8055 register_name
= "BadInstr";
8057 case CP0_REG08__BADINSTRP
:
8059 register_name
= "BadInstrP";
8061 case CP0_REG08__BADINSTRX
:
8063 register_name
= "BadInstrX";
8066 goto cp0_unimplemented
;
8069 case CP0_REGISTER_09
:
8071 case CP0_REG09__COUNT
:
8072 gen_helper_mtc0_count(cpu_env
, arg
);
8073 register_name
= "Count";
8075 case CP0_REG09__SAARI
:
8076 CP0_CHECK(ctx
->saar
);
8077 gen_helper_mtc0_saari(cpu_env
, arg
);
8078 register_name
= "SAARI";
8080 case CP0_REG09__SAAR
:
8081 CP0_CHECK(ctx
->saar
);
8082 gen_helper_mtc0_saar(cpu_env
, arg
);
8083 register_name
= "SAAR";
8086 goto cp0_unimplemented
;
8089 case CP0_REGISTER_10
:
8091 case CP0_REG10__ENTRYHI
:
8092 gen_helper_mtc0_entryhi(cpu_env
, arg
);
8093 register_name
= "EntryHi";
8096 goto cp0_unimplemented
;
8099 case CP0_REGISTER_11
:
8101 case CP0_REG11__COMPARE
:
8102 gen_helper_mtc0_compare(cpu_env
, arg
);
8103 register_name
= "Compare";
8105 /* 6,7 are implementation dependent */
8107 goto cp0_unimplemented
;
8110 case CP0_REGISTER_12
:
8112 case CP0_REG12__STATUS
:
8113 save_cpu_state(ctx
, 1);
8114 gen_helper_mtc0_status(cpu_env
, arg
);
8115 /* DISAS_STOP isn't good enough here, hflags may have changed. */
8116 gen_save_pc(ctx
->base
.pc_next
+ 4);
8117 ctx
->base
.is_jmp
= DISAS_EXIT
;
8118 register_name
= "Status";
8120 case CP0_REG12__INTCTL
:
8121 check_insn(ctx
, ISA_MIPS_R2
);
8122 gen_helper_mtc0_intctl(cpu_env
, arg
);
8123 /* Stop translation as we may have switched the execution mode */
8124 ctx
->base
.is_jmp
= DISAS_STOP
;
8125 register_name
= "IntCtl";
8127 case CP0_REG12__SRSCTL
:
8128 check_insn(ctx
, ISA_MIPS_R2
);
8129 gen_helper_mtc0_srsctl(cpu_env
, arg
);
8130 /* Stop translation as we may have switched the execution mode */
8131 ctx
->base
.is_jmp
= DISAS_STOP
;
8132 register_name
= "SRSCtl";
8134 case CP0_REG12__SRSMAP
:
8135 check_insn(ctx
, ISA_MIPS_R2
);
8136 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
8137 /* Stop translation as we may have switched the execution mode */
8138 ctx
->base
.is_jmp
= DISAS_STOP
;
8139 register_name
= "SRSMap";
8142 goto cp0_unimplemented
;
8145 case CP0_REGISTER_13
:
8147 case CP0_REG13__CAUSE
:
8148 save_cpu_state(ctx
, 1);
8149 gen_helper_mtc0_cause(cpu_env
, arg
);
8151 * Stop translation as we may have triggered an interrupt.
8152 * DISAS_STOP isn't sufficient, we need to ensure we break out of
8153 * translated code to check for pending interrupts.
8155 gen_save_pc(ctx
->base
.pc_next
+ 4);
8156 ctx
->base
.is_jmp
= DISAS_EXIT
;
8157 register_name
= "Cause";
8160 goto cp0_unimplemented
;
8163 case CP0_REGISTER_14
:
8165 case CP0_REG14__EPC
:
8166 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
8167 register_name
= "EPC";
8170 goto cp0_unimplemented
;
8173 case CP0_REGISTER_15
:
8175 case CP0_REG15__PRID
:
8177 register_name
= "PRid";
8179 case CP0_REG15__EBASE
:
8180 check_insn(ctx
, ISA_MIPS_R2
);
8181 gen_helper_mtc0_ebase(cpu_env
, arg
);
8182 register_name
= "EBase";
8185 goto cp0_unimplemented
;
8188 case CP0_REGISTER_16
:
8190 case CP0_REG16__CONFIG
:
8191 gen_helper_mtc0_config0(cpu_env
, arg
);
8192 register_name
= "Config";
8193 /* Stop translation as we may have switched the execution mode */
8194 ctx
->base
.is_jmp
= DISAS_STOP
;
8196 case CP0_REG16__CONFIG1
:
8197 /* ignored, read only */
8198 register_name
= "Config1";
8200 case CP0_REG16__CONFIG2
:
8201 gen_helper_mtc0_config2(cpu_env
, arg
);
8202 register_name
= "Config2";
8203 /* Stop translation as we may have switched the execution mode */
8204 ctx
->base
.is_jmp
= DISAS_STOP
;
8206 case CP0_REG16__CONFIG3
:
8207 gen_helper_mtc0_config3(cpu_env
, arg
);
8208 register_name
= "Config3";
8209 /* Stop translation as we may have switched the execution mode */
8210 ctx
->base
.is_jmp
= DISAS_STOP
;
8212 case CP0_REG16__CONFIG4
:
8213 gen_helper_mtc0_config4(cpu_env
, arg
);
8214 register_name
= "Config4";
8215 ctx
->base
.is_jmp
= DISAS_STOP
;
8217 case CP0_REG16__CONFIG5
:
8218 gen_helper_mtc0_config5(cpu_env
, arg
);
8219 register_name
= "Config5";
8220 /* Stop translation as we may have switched the execution mode */
8221 ctx
->base
.is_jmp
= DISAS_STOP
;
8223 /* 6,7 are implementation dependent */
8224 case CP0_REG16__CONFIG6
:
8226 register_name
= "Config6";
8228 case CP0_REG16__CONFIG7
:
8230 register_name
= "Config7";
8233 register_name
= "Invalid config selector";
8234 goto cp0_unimplemented
;
8237 case CP0_REGISTER_17
:
8239 case CP0_REG17__LLADDR
:
8240 gen_helper_mtc0_lladdr(cpu_env
, arg
);
8241 register_name
= "LLAddr";
8243 case CP0_REG17__MAAR
:
8244 CP0_CHECK(ctx
->mrp
);
8245 gen_helper_mtc0_maar(cpu_env
, arg
);
8246 register_name
= "MAAR";
8248 case CP0_REG17__MAARI
:
8249 CP0_CHECK(ctx
->mrp
);
8250 gen_helper_mtc0_maari(cpu_env
, arg
);
8251 register_name
= "MAARI";
8254 goto cp0_unimplemented
;
8257 case CP0_REGISTER_18
:
8259 case CP0_REG18__WATCHLO0
:
8260 case CP0_REG18__WATCHLO1
:
8261 case CP0_REG18__WATCHLO2
:
8262 case CP0_REG18__WATCHLO3
:
8263 case CP0_REG18__WATCHLO4
:
8264 case CP0_REG18__WATCHLO5
:
8265 case CP0_REG18__WATCHLO6
:
8266 case CP0_REG18__WATCHLO7
:
8267 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
8268 gen_helper_0e1i(mtc0_watchlo
, arg
, sel
);
8269 register_name
= "WatchLo";
8272 goto cp0_unimplemented
;
8275 case CP0_REGISTER_19
:
8277 case CP0_REG19__WATCHHI0
:
8278 case CP0_REG19__WATCHHI1
:
8279 case CP0_REG19__WATCHHI2
:
8280 case CP0_REG19__WATCHHI3
:
8281 case CP0_REG19__WATCHHI4
:
8282 case CP0_REG19__WATCHHI5
:
8283 case CP0_REG19__WATCHHI6
:
8284 case CP0_REG19__WATCHHI7
:
8285 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
8286 gen_helper_0e1i(mtc0_watchhi
, arg
, sel
);
8287 register_name
= "WatchHi";
8290 goto cp0_unimplemented
;
8293 case CP0_REGISTER_20
:
8295 case CP0_REG20__XCONTEXT
:
8296 #if defined(TARGET_MIPS64)
8297 check_insn(ctx
, ISA_MIPS3
);
8298 gen_helper_mtc0_xcontext(cpu_env
, arg
);
8299 register_name
= "XContext";
8303 goto cp0_unimplemented
;
8306 case CP0_REGISTER_21
:
8307 /* Officially reserved, but sel 0 is used for R1x000 framemask */
8308 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS_R6
));
8311 gen_helper_mtc0_framemask(cpu_env
, arg
);
8312 register_name
= "Framemask";
8315 goto cp0_unimplemented
;
8318 case CP0_REGISTER_22
:
8320 register_name
= "Diagnostic"; /* implementation dependent */
8322 case CP0_REGISTER_23
:
8324 case CP0_REG23__DEBUG
:
8325 gen_helper_mtc0_debug(cpu_env
, arg
); /* EJTAG support */
8326 /* DISAS_STOP isn't good enough here, hflags may have changed. */
8327 gen_save_pc(ctx
->base
.pc_next
+ 4);
8328 ctx
->base
.is_jmp
= DISAS_EXIT
;
8329 register_name
= "Debug";
8331 case CP0_REG23__TRACECONTROL
:
8332 /* PDtrace support */
8333 /* gen_helper_mtc0_tracecontrol(cpu_env, arg); */
8334 register_name
= "TraceControl";
8335 /* Stop translation as we may have switched the execution mode */
8336 ctx
->base
.is_jmp
= DISAS_STOP
;
8337 goto cp0_unimplemented
;
8338 case CP0_REG23__TRACECONTROL2
:
8339 /* PDtrace support */
8340 /* gen_helper_mtc0_tracecontrol2(cpu_env, arg); */
8341 register_name
= "TraceControl2";
8342 /* Stop translation as we may have switched the execution mode */
8343 ctx
->base
.is_jmp
= DISAS_STOP
;
8344 goto cp0_unimplemented
;
8345 case CP0_REG23__USERTRACEDATA1
:
8346 /* Stop translation as we may have switched the execution mode */
8347 ctx
->base
.is_jmp
= DISAS_STOP
;
8348 /* PDtrace support */
8349 /* gen_helper_mtc0_usertracedata1(cpu_env, arg);*/
8350 register_name
= "UserTraceData";
8351 /* Stop translation as we may have switched the execution mode */
8352 ctx
->base
.is_jmp
= DISAS_STOP
;
8353 goto cp0_unimplemented
;
8354 case CP0_REG23__TRACEIBPC
:
8355 /* PDtrace support */
8356 /* gen_helper_mtc0_traceibpc(cpu_env, arg); */
8357 /* Stop translation as we may have switched the execution mode */
8358 ctx
->base
.is_jmp
= DISAS_STOP
;
8359 register_name
= "TraceIBPC";
8360 goto cp0_unimplemented
;
8361 case CP0_REG23__TRACEDBPC
:
8362 /* PDtrace support */
8363 /* gen_helper_mtc0_tracedbpc(cpu_env, arg); */
8364 /* Stop translation as we may have switched the execution mode */
8365 ctx
->base
.is_jmp
= DISAS_STOP
;
8366 register_name
= "TraceDBPC";
8367 goto cp0_unimplemented
;
8369 goto cp0_unimplemented
;
8372 case CP0_REGISTER_24
:
8374 case CP0_REG24__DEPC
:
8376 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
8377 register_name
= "DEPC";
8380 goto cp0_unimplemented
;
8383 case CP0_REGISTER_25
:
8385 case CP0_REG25__PERFCTL0
:
8386 gen_helper_mtc0_performance0(cpu_env
, arg
);
8387 register_name
= "Performance0";
8389 case CP0_REG25__PERFCNT0
:
8390 /* gen_helper_mtc0_performance1(arg); */
8391 register_name
= "Performance1";
8392 goto cp0_unimplemented
;
8393 case CP0_REG25__PERFCTL1
:
8394 /* gen_helper_mtc0_performance2(arg); */
8395 register_name
= "Performance2";
8396 goto cp0_unimplemented
;
8397 case CP0_REG25__PERFCNT1
:
8398 /* gen_helper_mtc0_performance3(arg); */
8399 register_name
= "Performance3";
8400 goto cp0_unimplemented
;
8401 case CP0_REG25__PERFCTL2
:
8402 /* gen_helper_mtc0_performance4(arg); */
8403 register_name
= "Performance4";
8404 goto cp0_unimplemented
;
8405 case CP0_REG25__PERFCNT2
:
8406 /* gen_helper_mtc0_performance5(arg); */
8407 register_name
= "Performance5";
8408 goto cp0_unimplemented
;
8409 case CP0_REG25__PERFCTL3
:
8410 /* gen_helper_mtc0_performance6(arg); */
8411 register_name
= "Performance6";
8412 goto cp0_unimplemented
;
8413 case CP0_REG25__PERFCNT3
:
8414 /* gen_helper_mtc0_performance7(arg); */
8415 register_name
= "Performance7";
8416 goto cp0_unimplemented
;
8418 goto cp0_unimplemented
;
8421 case CP0_REGISTER_26
:
8423 case CP0_REG26__ERRCTL
:
8424 gen_helper_mtc0_errctl(cpu_env
, arg
);
8425 ctx
->base
.is_jmp
= DISAS_STOP
;
8426 register_name
= "ErrCtl";
8429 goto cp0_unimplemented
;
8432 case CP0_REGISTER_27
:
8434 case CP0_REG27__CACHERR
:
8436 register_name
= "CacheErr";
8439 goto cp0_unimplemented
;
8442 case CP0_REGISTER_28
:
8444 case CP0_REG28__TAGLO
:
8445 case CP0_REG28__TAGLO1
:
8446 case CP0_REG28__TAGLO2
:
8447 case CP0_REG28__TAGLO3
:
8448 gen_helper_mtc0_taglo(cpu_env
, arg
);
8449 register_name
= "TagLo";
8451 case CP0_REG28__DATALO
:
8452 case CP0_REG28__DATALO1
:
8453 case CP0_REG28__DATALO2
:
8454 case CP0_REG28__DATALO3
:
8455 gen_helper_mtc0_datalo(cpu_env
, arg
);
8456 register_name
= "DataLo";
8459 goto cp0_unimplemented
;
8462 case CP0_REGISTER_29
:
8464 case CP0_REG29__TAGHI
:
8465 case CP0_REG29__TAGHI1
:
8466 case CP0_REG29__TAGHI2
:
8467 case CP0_REG29__TAGHI3
:
8468 gen_helper_mtc0_taghi(cpu_env
, arg
);
8469 register_name
= "TagHi";
8471 case CP0_REG29__DATAHI
:
8472 case CP0_REG29__DATAHI1
:
8473 case CP0_REG29__DATAHI2
:
8474 case CP0_REG29__DATAHI3
:
8475 gen_helper_mtc0_datahi(cpu_env
, arg
);
8476 register_name
= "DataHi";
8479 register_name
= "invalid sel";
8480 goto cp0_unimplemented
;
8483 case CP0_REGISTER_30
:
8485 case CP0_REG30__ERROREPC
:
8486 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
8487 register_name
= "ErrorEPC";
8490 goto cp0_unimplemented
;
8493 case CP0_REGISTER_31
:
8495 case CP0_REG31__DESAVE
:
8497 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
8498 register_name
= "DESAVE";
8500 case CP0_REG31__KSCRATCH1
:
8501 case CP0_REG31__KSCRATCH2
:
8502 case CP0_REG31__KSCRATCH3
:
8503 case CP0_REG31__KSCRATCH4
:
8504 case CP0_REG31__KSCRATCH5
:
8505 case CP0_REG31__KSCRATCH6
:
8506 CP0_CHECK(ctx
->kscrexist
& (1 << sel
));
8507 tcg_gen_st_tl(arg
, cpu_env
,
8508 offsetof(CPUMIPSState
, CP0_KScratch
[sel
- 2]));
8509 register_name
= "KScratch";
8512 goto cp0_unimplemented
;
8516 goto cp0_unimplemented
;
8518 trace_mips_translate_c0("mtc0", register_name
, reg
, sel
);
8520 /* For simplicity assume that all writes can cause interrupts. */
8521 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
8523 * DISAS_STOP isn't sufficient, we need to ensure we break out of
8524 * translated code to check for pending interrupts.
8526 gen_save_pc(ctx
->base
.pc_next
+ 4);
8527 ctx
->base
.is_jmp
= DISAS_EXIT
;
8532 qemu_log_mask(LOG_UNIMP
, "mtc0 %s (reg %d sel %d)\n",
8533 register_name
, reg
, sel
);
8536 #if defined(TARGET_MIPS64)
8537 static void gen_dmfc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
8539 const char *register_name
= "invalid";
8542 check_insn(ctx
, ISA_MIPS_R1
);
8546 case CP0_REGISTER_00
:
8548 case CP0_REG00__INDEX
:
8549 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Index
));
8550 register_name
= "Index";
8552 case CP0_REG00__MVPCONTROL
:
8553 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8554 gen_helper_mfc0_mvpcontrol(arg
, cpu_env
);
8555 register_name
= "MVPControl";
8557 case CP0_REG00__MVPCONF0
:
8558 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8559 gen_helper_mfc0_mvpconf0(arg
, cpu_env
);
8560 register_name
= "MVPConf0";
8562 case CP0_REG00__MVPCONF1
:
8563 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8564 gen_helper_mfc0_mvpconf1(arg
, cpu_env
);
8565 register_name
= "MVPConf1";
8567 case CP0_REG00__VPCONTROL
:
8569 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPControl
));
8570 register_name
= "VPControl";
8573 goto cp0_unimplemented
;
8576 case CP0_REGISTER_01
:
8578 case CP0_REG01__RANDOM
:
8579 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS_R6
));
8580 gen_helper_mfc0_random(arg
, cpu_env
);
8581 register_name
= "Random";
8583 case CP0_REG01__VPECONTROL
:
8584 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8585 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEControl
));
8586 register_name
= "VPEControl";
8588 case CP0_REG01__VPECONF0
:
8589 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8590 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf0
));
8591 register_name
= "VPEConf0";
8593 case CP0_REG01__VPECONF1
:
8594 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8595 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf1
));
8596 register_name
= "VPEConf1";
8598 case CP0_REG01__YQMASK
:
8599 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8600 tcg_gen_ld_tl(arg
, cpu_env
,
8601 offsetof(CPUMIPSState
, CP0_YQMask
));
8602 register_name
= "YQMask";
8604 case CP0_REG01__VPESCHEDULE
:
8605 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8606 tcg_gen_ld_tl(arg
, cpu_env
,
8607 offsetof(CPUMIPSState
, CP0_VPESchedule
));
8608 register_name
= "VPESchedule";
8610 case CP0_REG01__VPESCHEFBACK
:
8611 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8612 tcg_gen_ld_tl(arg
, cpu_env
,
8613 offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
8614 register_name
= "VPEScheFBack";
8616 case CP0_REG01__VPEOPT
:
8617 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8618 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEOpt
));
8619 register_name
= "VPEOpt";
8622 goto cp0_unimplemented
;
8625 case CP0_REGISTER_02
:
8627 case CP0_REG02__ENTRYLO0
:
8628 tcg_gen_ld_tl(arg
, cpu_env
,
8629 offsetof(CPUMIPSState
, CP0_EntryLo0
));
8630 register_name
= "EntryLo0";
8632 case CP0_REG02__TCSTATUS
:
8633 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8634 gen_helper_mfc0_tcstatus(arg
, cpu_env
);
8635 register_name
= "TCStatus";
8637 case CP0_REG02__TCBIND
:
8638 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8639 gen_helper_mfc0_tcbind(arg
, cpu_env
);
8640 register_name
= "TCBind";
8642 case CP0_REG02__TCRESTART
:
8643 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8644 gen_helper_dmfc0_tcrestart(arg
, cpu_env
);
8645 register_name
= "TCRestart";
8647 case CP0_REG02__TCHALT
:
8648 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8649 gen_helper_dmfc0_tchalt(arg
, cpu_env
);
8650 register_name
= "TCHalt";
8652 case CP0_REG02__TCCONTEXT
:
8653 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8654 gen_helper_dmfc0_tccontext(arg
, cpu_env
);
8655 register_name
= "TCContext";
8657 case CP0_REG02__TCSCHEDULE
:
8658 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8659 gen_helper_dmfc0_tcschedule(arg
, cpu_env
);
8660 register_name
= "TCSchedule";
8662 case CP0_REG02__TCSCHEFBACK
:
8663 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8664 gen_helper_dmfc0_tcschefback(arg
, cpu_env
);
8665 register_name
= "TCScheFBack";
8668 goto cp0_unimplemented
;
8671 case CP0_REGISTER_03
:
8673 case CP0_REG03__ENTRYLO1
:
8674 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryLo1
));
8675 register_name
= "EntryLo1";
8677 case CP0_REG03__GLOBALNUM
:
8679 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_GlobalNumber
));
8680 register_name
= "GlobalNumber";
8683 goto cp0_unimplemented
;
8686 case CP0_REGISTER_04
:
8688 case CP0_REG04__CONTEXT
:
8689 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_Context
));
8690 register_name
= "Context";
8692 case CP0_REG04__CONTEXTCONFIG
:
8694 /* gen_helper_dmfc0_contextconfig(arg); */
8695 register_name
= "ContextConfig";
8696 goto cp0_unimplemented
;
8697 case CP0_REG04__USERLOCAL
:
8698 CP0_CHECK(ctx
->ulri
);
8699 tcg_gen_ld_tl(arg
, cpu_env
,
8700 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
8701 register_name
= "UserLocal";
8703 case CP0_REG04__MMID
:
8705 gen_helper_mtc0_memorymapid(cpu_env
, arg
);
8706 register_name
= "MMID";
8709 goto cp0_unimplemented
;
8712 case CP0_REGISTER_05
:
8714 case CP0_REG05__PAGEMASK
:
8715 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageMask
));
8716 register_name
= "PageMask";
8718 case CP0_REG05__PAGEGRAIN
:
8719 check_insn(ctx
, ISA_MIPS_R2
);
8720 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageGrain
));
8721 register_name
= "PageGrain";
8723 case CP0_REG05__SEGCTL0
:
8725 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_SegCtl0
));
8726 register_name
= "SegCtl0";
8728 case CP0_REG05__SEGCTL1
:
8730 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_SegCtl1
));
8731 register_name
= "SegCtl1";
8733 case CP0_REG05__SEGCTL2
:
8735 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_SegCtl2
));
8736 register_name
= "SegCtl2";
8738 case CP0_REG05__PWBASE
:
8740 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_PWBase
));
8741 register_name
= "PWBase";
8743 case CP0_REG05__PWFIELD
:
8745 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_PWField
));
8746 register_name
= "PWField";
8748 case CP0_REG05__PWSIZE
:
8750 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_PWSize
));
8751 register_name
= "PWSize";
8754 goto cp0_unimplemented
;
8757 case CP0_REGISTER_06
:
8759 case CP0_REG06__WIRED
:
8760 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Wired
));
8761 register_name
= "Wired";
8763 case CP0_REG06__SRSCONF0
:
8764 check_insn(ctx
, ISA_MIPS_R2
);
8765 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf0
));
8766 register_name
= "SRSConf0";
8768 case CP0_REG06__SRSCONF1
:
8769 check_insn(ctx
, ISA_MIPS_R2
);
8770 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf1
));
8771 register_name
= "SRSConf1";
8773 case CP0_REG06__SRSCONF2
:
8774 check_insn(ctx
, ISA_MIPS_R2
);
8775 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf2
));
8776 register_name
= "SRSConf2";
8778 case CP0_REG06__SRSCONF3
:
8779 check_insn(ctx
, ISA_MIPS_R2
);
8780 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf3
));
8781 register_name
= "SRSConf3";
8783 case CP0_REG06__SRSCONF4
:
8784 check_insn(ctx
, ISA_MIPS_R2
);
8785 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf4
));
8786 register_name
= "SRSConf4";
8788 case CP0_REG06__PWCTL
:
8790 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PWCtl
));
8791 register_name
= "PWCtl";
8794 goto cp0_unimplemented
;
8797 case CP0_REGISTER_07
:
8799 case CP0_REG07__HWRENA
:
8800 check_insn(ctx
, ISA_MIPS_R2
);
8801 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_HWREna
));
8802 register_name
= "HWREna";
8805 goto cp0_unimplemented
;
8808 case CP0_REGISTER_08
:
8810 case CP0_REG08__BADVADDR
:
8811 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_BadVAddr
));
8812 register_name
= "BadVAddr";
8814 case CP0_REG08__BADINSTR
:
8816 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstr
));
8817 register_name
= "BadInstr";
8819 case CP0_REG08__BADINSTRP
:
8821 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstrP
));
8822 register_name
= "BadInstrP";
8824 case CP0_REG08__BADINSTRX
:
8826 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstrX
));
8827 tcg_gen_andi_tl(arg
, arg
, ~0xffff);
8828 register_name
= "BadInstrX";
8831 goto cp0_unimplemented
;
8834 case CP0_REGISTER_09
:
8836 case CP0_REG09__COUNT
:
8837 /* Mark as an IO operation because we read the time. */
8838 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
8841 gen_helper_mfc0_count(arg
, cpu_env
);
8843 * Break the TB to be able to take timer interrupts immediately
8844 * after reading count. DISAS_STOP isn't sufficient, we need to
8845 * ensure we break completely out of translated code.
8847 gen_save_pc(ctx
->base
.pc_next
+ 4);
8848 ctx
->base
.is_jmp
= DISAS_EXIT
;
8849 register_name
= "Count";
8851 case CP0_REG09__SAARI
:
8852 CP0_CHECK(ctx
->saar
);
8853 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SAARI
));
8854 register_name
= "SAARI";
8856 case CP0_REG09__SAAR
:
8857 CP0_CHECK(ctx
->saar
);
8858 gen_helper_dmfc0_saar(arg
, cpu_env
);
8859 register_name
= "SAAR";
8862 goto cp0_unimplemented
;
8865 case CP0_REGISTER_10
:
8867 case CP0_REG10__ENTRYHI
:
8868 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryHi
));
8869 register_name
= "EntryHi";
8872 goto cp0_unimplemented
;
8875 case CP0_REGISTER_11
:
8877 case CP0_REG11__COMPARE
:
8878 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Compare
));
8879 register_name
= "Compare";
8881 /* 6,7 are implementation dependent */
8883 goto cp0_unimplemented
;
8886 case CP0_REGISTER_12
:
8888 case CP0_REG12__STATUS
:
8889 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Status
));
8890 register_name
= "Status";
8892 case CP0_REG12__INTCTL
:
8893 check_insn(ctx
, ISA_MIPS_R2
);
8894 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_IntCtl
));
8895 register_name
= "IntCtl";
8897 case CP0_REG12__SRSCTL
:
8898 check_insn(ctx
, ISA_MIPS_R2
);
8899 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
8900 register_name
= "SRSCtl";
8902 case CP0_REG12__SRSMAP
:
8903 check_insn(ctx
, ISA_MIPS_R2
);
8904 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
8905 register_name
= "SRSMap";
8908 goto cp0_unimplemented
;
8911 case CP0_REGISTER_13
:
8913 case CP0_REG13__CAUSE
:
8914 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Cause
));
8915 register_name
= "Cause";
8918 goto cp0_unimplemented
;
8921 case CP0_REGISTER_14
:
8923 case CP0_REG14__EPC
:
8924 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
8925 register_name
= "EPC";
8928 goto cp0_unimplemented
;
8931 case CP0_REGISTER_15
:
8933 case CP0_REG15__PRID
:
8934 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PRid
));
8935 register_name
= "PRid";
8937 case CP0_REG15__EBASE
:
8938 check_insn(ctx
, ISA_MIPS_R2
);
8939 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EBase
));
8940 register_name
= "EBase";
8942 case CP0_REG15__CMGCRBASE
:
8943 check_insn(ctx
, ISA_MIPS_R2
);
8944 CP0_CHECK(ctx
->cmgcr
);
8945 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_CMGCRBase
));
8946 register_name
= "CMGCRBase";
8949 goto cp0_unimplemented
;
8952 case CP0_REGISTER_16
:
8954 case CP0_REG16__CONFIG
:
8955 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config0
));
8956 register_name
= "Config";
8958 case CP0_REG16__CONFIG1
:
8959 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config1
));
8960 register_name
= "Config1";
8962 case CP0_REG16__CONFIG2
:
8963 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config2
));
8964 register_name
= "Config2";
8966 case CP0_REG16__CONFIG3
:
8967 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config3
));
8968 register_name
= "Config3";
8970 case CP0_REG16__CONFIG4
:
8971 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config4
));
8972 register_name
= "Config4";
8974 case CP0_REG16__CONFIG5
:
8975 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config5
));
8976 register_name
= "Config5";
8978 /* 6,7 are implementation dependent */
8979 case CP0_REG16__CONFIG6
:
8980 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config6
));
8981 register_name
= "Config6";
8983 case CP0_REG16__CONFIG7
:
8984 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config7
));
8985 register_name
= "Config7";
8988 goto cp0_unimplemented
;
8991 case CP0_REGISTER_17
:
8993 case CP0_REG17__LLADDR
:
8994 gen_helper_dmfc0_lladdr(arg
, cpu_env
);
8995 register_name
= "LLAddr";
8997 case CP0_REG17__MAAR
:
8998 CP0_CHECK(ctx
->mrp
);
8999 gen_helper_dmfc0_maar(arg
, cpu_env
);
9000 register_name
= "MAAR";
9002 case CP0_REG17__MAARI
:
9003 CP0_CHECK(ctx
->mrp
);
9004 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_MAARI
));
9005 register_name
= "MAARI";
9008 goto cp0_unimplemented
;
9011 case CP0_REGISTER_18
:
9013 case CP0_REG18__WATCHLO0
:
9014 case CP0_REG18__WATCHLO1
:
9015 case CP0_REG18__WATCHLO2
:
9016 case CP0_REG18__WATCHLO3
:
9017 case CP0_REG18__WATCHLO4
:
9018 case CP0_REG18__WATCHLO5
:
9019 case CP0_REG18__WATCHLO6
:
9020 case CP0_REG18__WATCHLO7
:
9021 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
9022 gen_helper_1e0i(dmfc0_watchlo
, arg
, sel
);
9023 register_name
= "WatchLo";
9026 goto cp0_unimplemented
;
9029 case CP0_REGISTER_19
:
9031 case CP0_REG19__WATCHHI0
:
9032 case CP0_REG19__WATCHHI1
:
9033 case CP0_REG19__WATCHHI2
:
9034 case CP0_REG19__WATCHHI3
:
9035 case CP0_REG19__WATCHHI4
:
9036 case CP0_REG19__WATCHHI5
:
9037 case CP0_REG19__WATCHHI6
:
9038 case CP0_REG19__WATCHHI7
:
9039 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
9040 gen_helper_1e0i(dmfc0_watchhi
, arg
, sel
);
9041 register_name
= "WatchHi";
9044 goto cp0_unimplemented
;
9047 case CP0_REGISTER_20
:
9049 case CP0_REG20__XCONTEXT
:
9050 check_insn(ctx
, ISA_MIPS3
);
9051 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_XContext
));
9052 register_name
= "XContext";
9055 goto cp0_unimplemented
;
9058 case CP0_REGISTER_21
:
9059 /* Officially reserved, but sel 0 is used for R1x000 framemask */
9060 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS_R6
));
9063 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Framemask
));
9064 register_name
= "Framemask";
9067 goto cp0_unimplemented
;
9070 case CP0_REGISTER_22
:
9071 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
9072 register_name
= "'Diagnostic"; /* implementation dependent */
9074 case CP0_REGISTER_23
:
9076 case CP0_REG23__DEBUG
:
9077 gen_helper_mfc0_debug(arg
, cpu_env
); /* EJTAG support */
9078 register_name
= "Debug";
9080 case CP0_REG23__TRACECONTROL
:
9081 /* PDtrace support */
9082 /* gen_helper_dmfc0_tracecontrol(arg, cpu_env); */
9083 register_name
= "TraceControl";
9084 goto cp0_unimplemented
;
9085 case CP0_REG23__TRACECONTROL2
:
9086 /* PDtrace support */
9087 /* gen_helper_dmfc0_tracecontrol2(arg, cpu_env); */
9088 register_name
= "TraceControl2";
9089 goto cp0_unimplemented
;
9090 case CP0_REG23__USERTRACEDATA1
:
9091 /* PDtrace support */
9092 /* gen_helper_dmfc0_usertracedata1(arg, cpu_env);*/
9093 register_name
= "UserTraceData1";
9094 goto cp0_unimplemented
;
9095 case CP0_REG23__TRACEIBPC
:
9096 /* PDtrace support */
9097 /* gen_helper_dmfc0_traceibpc(arg, cpu_env); */
9098 register_name
= "TraceIBPC";
9099 goto cp0_unimplemented
;
9100 case CP0_REG23__TRACEDBPC
:
9101 /* PDtrace support */
9102 /* gen_helper_dmfc0_tracedbpc(arg, cpu_env); */
9103 register_name
= "TraceDBPC";
9104 goto cp0_unimplemented
;
9106 goto cp0_unimplemented
;
9109 case CP0_REGISTER_24
:
9111 case CP0_REG24__DEPC
:
9113 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
9114 register_name
= "DEPC";
9117 goto cp0_unimplemented
;
9120 case CP0_REGISTER_25
:
9122 case CP0_REG25__PERFCTL0
:
9123 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Performance0
));
9124 register_name
= "Performance0";
9126 case CP0_REG25__PERFCNT0
:
9127 /* gen_helper_dmfc0_performance1(arg); */
9128 register_name
= "Performance1";
9129 goto cp0_unimplemented
;
9130 case CP0_REG25__PERFCTL1
:
9131 /* gen_helper_dmfc0_performance2(arg); */
9132 register_name
= "Performance2";
9133 goto cp0_unimplemented
;
9134 case CP0_REG25__PERFCNT1
:
9135 /* gen_helper_dmfc0_performance3(arg); */
9136 register_name
= "Performance3";
9137 goto cp0_unimplemented
;
9138 case CP0_REG25__PERFCTL2
:
9139 /* gen_helper_dmfc0_performance4(arg); */
9140 register_name
= "Performance4";
9141 goto cp0_unimplemented
;
9142 case CP0_REG25__PERFCNT2
:
9143 /* gen_helper_dmfc0_performance5(arg); */
9144 register_name
= "Performance5";
9145 goto cp0_unimplemented
;
9146 case CP0_REG25__PERFCTL3
:
9147 /* gen_helper_dmfc0_performance6(arg); */
9148 register_name
= "Performance6";
9149 goto cp0_unimplemented
;
9150 case CP0_REG25__PERFCNT3
:
9151 /* gen_helper_dmfc0_performance7(arg); */
9152 register_name
= "Performance7";
9153 goto cp0_unimplemented
;
9155 goto cp0_unimplemented
;
9158 case CP0_REGISTER_26
:
9160 case CP0_REG26__ERRCTL
:
9161 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_ErrCtl
));
9162 register_name
= "ErrCtl";
9165 goto cp0_unimplemented
;
9168 case CP0_REGISTER_27
:
9171 case CP0_REG27__CACHERR
:
9172 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
9173 register_name
= "CacheErr";
9176 goto cp0_unimplemented
;
9179 case CP0_REGISTER_28
:
9181 case CP0_REG28__TAGLO
:
9182 case CP0_REG28__TAGLO1
:
9183 case CP0_REG28__TAGLO2
:
9184 case CP0_REG28__TAGLO3
:
9185 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagLo
));
9186 register_name
= "TagLo";
9188 case CP0_REG28__DATALO
:
9189 case CP0_REG28__DATALO1
:
9190 case CP0_REG28__DATALO2
:
9191 case CP0_REG28__DATALO3
:
9192 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataLo
));
9193 register_name
= "DataLo";
9196 goto cp0_unimplemented
;
9199 case CP0_REGISTER_29
:
9201 case CP0_REG29__TAGHI
:
9202 case CP0_REG29__TAGHI1
:
9203 case CP0_REG29__TAGHI2
:
9204 case CP0_REG29__TAGHI3
:
9205 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagHi
));
9206 register_name
= "TagHi";
9208 case CP0_REG29__DATAHI
:
9209 case CP0_REG29__DATAHI1
:
9210 case CP0_REG29__DATAHI2
:
9211 case CP0_REG29__DATAHI3
:
9212 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataHi
));
9213 register_name
= "DataHi";
9216 goto cp0_unimplemented
;
9219 case CP0_REGISTER_30
:
9221 case CP0_REG30__ERROREPC
:
9222 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
9223 register_name
= "ErrorEPC";
9226 goto cp0_unimplemented
;
9229 case CP0_REGISTER_31
:
9231 case CP0_REG31__DESAVE
:
9233 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
9234 register_name
= "DESAVE";
9236 case CP0_REG31__KSCRATCH1
:
9237 case CP0_REG31__KSCRATCH2
:
9238 case CP0_REG31__KSCRATCH3
:
9239 case CP0_REG31__KSCRATCH4
:
9240 case CP0_REG31__KSCRATCH5
:
9241 case CP0_REG31__KSCRATCH6
:
9242 CP0_CHECK(ctx
->kscrexist
& (1 << sel
));
9243 tcg_gen_ld_tl(arg
, cpu_env
,
9244 offsetof(CPUMIPSState
, CP0_KScratch
[sel
- 2]));
9245 register_name
= "KScratch";
9248 goto cp0_unimplemented
;
9252 goto cp0_unimplemented
;
9254 trace_mips_translate_c0("dmfc0", register_name
, reg
, sel
);
9258 qemu_log_mask(LOG_UNIMP
, "dmfc0 %s (reg %d sel %d)\n",
9259 register_name
, reg
, sel
);
9260 gen_mfc0_unimplemented(ctx
, arg
);
9263 static void gen_dmtc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
9265 const char *register_name
= "invalid";
9268 check_insn(ctx
, ISA_MIPS_R1
);
9271 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
9276 case CP0_REGISTER_00
:
9278 case CP0_REG00__INDEX
:
9279 gen_helper_mtc0_index(cpu_env
, arg
);
9280 register_name
= "Index";
9282 case CP0_REG00__MVPCONTROL
:
9283 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9284 gen_helper_mtc0_mvpcontrol(cpu_env
, arg
);
9285 register_name
= "MVPControl";
9287 case CP0_REG00__MVPCONF0
:
9288 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9290 register_name
= "MVPConf0";
9292 case CP0_REG00__MVPCONF1
:
9293 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9295 register_name
= "MVPConf1";
9297 case CP0_REG00__VPCONTROL
:
9300 register_name
= "VPControl";
9303 goto cp0_unimplemented
;
9306 case CP0_REGISTER_01
:
9308 case CP0_REG01__RANDOM
:
9310 register_name
= "Random";
9312 case CP0_REG01__VPECONTROL
:
9313 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9314 gen_helper_mtc0_vpecontrol(cpu_env
, arg
);
9315 register_name
= "VPEControl";
9317 case CP0_REG01__VPECONF0
:
9318 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9319 gen_helper_mtc0_vpeconf0(cpu_env
, arg
);
9320 register_name
= "VPEConf0";
9322 case CP0_REG01__VPECONF1
:
9323 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9324 gen_helper_mtc0_vpeconf1(cpu_env
, arg
);
9325 register_name
= "VPEConf1";
9327 case CP0_REG01__YQMASK
:
9328 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9329 gen_helper_mtc0_yqmask(cpu_env
, arg
);
9330 register_name
= "YQMask";
9332 case CP0_REG01__VPESCHEDULE
:
9333 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9334 tcg_gen_st_tl(arg
, cpu_env
,
9335 offsetof(CPUMIPSState
, CP0_VPESchedule
));
9336 register_name
= "VPESchedule";
9338 case CP0_REG01__VPESCHEFBACK
:
9339 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9340 tcg_gen_st_tl(arg
, cpu_env
,
9341 offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
9342 register_name
= "VPEScheFBack";
9344 case CP0_REG01__VPEOPT
:
9345 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9346 gen_helper_mtc0_vpeopt(cpu_env
, arg
);
9347 register_name
= "VPEOpt";
9350 goto cp0_unimplemented
;
9353 case CP0_REGISTER_02
:
9355 case CP0_REG02__ENTRYLO0
:
9356 gen_helper_dmtc0_entrylo0(cpu_env
, arg
);
9357 register_name
= "EntryLo0";
9359 case CP0_REG02__TCSTATUS
:
9360 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9361 gen_helper_mtc0_tcstatus(cpu_env
, arg
);
9362 register_name
= "TCStatus";
9364 case CP0_REG02__TCBIND
:
9365 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9366 gen_helper_mtc0_tcbind(cpu_env
, arg
);
9367 register_name
= "TCBind";
9369 case CP0_REG02__TCRESTART
:
9370 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9371 gen_helper_mtc0_tcrestart(cpu_env
, arg
);
9372 register_name
= "TCRestart";
9374 case CP0_REG02__TCHALT
:
9375 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9376 gen_helper_mtc0_tchalt(cpu_env
, arg
);
9377 register_name
= "TCHalt";
9379 case CP0_REG02__TCCONTEXT
:
9380 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9381 gen_helper_mtc0_tccontext(cpu_env
, arg
);
9382 register_name
= "TCContext";
9384 case CP0_REG02__TCSCHEDULE
:
9385 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9386 gen_helper_mtc0_tcschedule(cpu_env
, arg
);
9387 register_name
= "TCSchedule";
9389 case CP0_REG02__TCSCHEFBACK
:
9390 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9391 gen_helper_mtc0_tcschefback(cpu_env
, arg
);
9392 register_name
= "TCScheFBack";
9395 goto cp0_unimplemented
;
9398 case CP0_REGISTER_03
:
9400 case CP0_REG03__ENTRYLO1
:
9401 gen_helper_dmtc0_entrylo1(cpu_env
, arg
);
9402 register_name
= "EntryLo1";
9404 case CP0_REG03__GLOBALNUM
:
9407 register_name
= "GlobalNumber";
9410 goto cp0_unimplemented
;
9413 case CP0_REGISTER_04
:
9415 case CP0_REG04__CONTEXT
:
9416 gen_helper_mtc0_context(cpu_env
, arg
);
9417 register_name
= "Context";
9419 case CP0_REG04__CONTEXTCONFIG
:
9421 /* gen_helper_dmtc0_contextconfig(arg); */
9422 register_name
= "ContextConfig";
9423 goto cp0_unimplemented
;
9424 case CP0_REG04__USERLOCAL
:
9425 CP0_CHECK(ctx
->ulri
);
9426 tcg_gen_st_tl(arg
, cpu_env
,
9427 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
9428 register_name
= "UserLocal";
9430 case CP0_REG04__MMID
:
9432 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_MemoryMapID
));
9433 register_name
= "MMID";
9436 goto cp0_unimplemented
;
9439 case CP0_REGISTER_05
:
9441 case CP0_REG05__PAGEMASK
:
9442 gen_helper_mtc0_pagemask(cpu_env
, arg
);
9443 register_name
= "PageMask";
9445 case CP0_REG05__PAGEGRAIN
:
9446 check_insn(ctx
, ISA_MIPS_R2
);
9447 gen_helper_mtc0_pagegrain(cpu_env
, arg
);
9448 register_name
= "PageGrain";
9450 case CP0_REG05__SEGCTL0
:
9452 gen_helper_mtc0_segctl0(cpu_env
, arg
);
9453 register_name
= "SegCtl0";
9455 case CP0_REG05__SEGCTL1
:
9457 gen_helper_mtc0_segctl1(cpu_env
, arg
);
9458 register_name
= "SegCtl1";
9460 case CP0_REG05__SEGCTL2
:
9462 gen_helper_mtc0_segctl2(cpu_env
, arg
);
9463 register_name
= "SegCtl2";
9465 case CP0_REG05__PWBASE
:
9467 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_PWBase
));
9468 register_name
= "PWBase";
9470 case CP0_REG05__PWFIELD
:
9472 gen_helper_mtc0_pwfield(cpu_env
, arg
);
9473 register_name
= "PWField";
9475 case CP0_REG05__PWSIZE
:
9477 gen_helper_mtc0_pwsize(cpu_env
, arg
);
9478 register_name
= "PWSize";
9481 goto cp0_unimplemented
;
9484 case CP0_REGISTER_06
:
9486 case CP0_REG06__WIRED
:
9487 gen_helper_mtc0_wired(cpu_env
, arg
);
9488 register_name
= "Wired";
9490 case CP0_REG06__SRSCONF0
:
9491 check_insn(ctx
, ISA_MIPS_R2
);
9492 gen_helper_mtc0_srsconf0(cpu_env
, arg
);
9493 register_name
= "SRSConf0";
9495 case CP0_REG06__SRSCONF1
:
9496 check_insn(ctx
, ISA_MIPS_R2
);
9497 gen_helper_mtc0_srsconf1(cpu_env
, arg
);
9498 register_name
= "SRSConf1";
9500 case CP0_REG06__SRSCONF2
:
9501 check_insn(ctx
, ISA_MIPS_R2
);
9502 gen_helper_mtc0_srsconf2(cpu_env
, arg
);
9503 register_name
= "SRSConf2";
9505 case CP0_REG06__SRSCONF3
:
9506 check_insn(ctx
, ISA_MIPS_R2
);
9507 gen_helper_mtc0_srsconf3(cpu_env
, arg
);
9508 register_name
= "SRSConf3";
9510 case CP0_REG06__SRSCONF4
:
9511 check_insn(ctx
, ISA_MIPS_R2
);
9512 gen_helper_mtc0_srsconf4(cpu_env
, arg
);
9513 register_name
= "SRSConf4";
9515 case CP0_REG06__PWCTL
:
9517 gen_helper_mtc0_pwctl(cpu_env
, arg
);
9518 register_name
= "PWCtl";
9521 goto cp0_unimplemented
;
9524 case CP0_REGISTER_07
:
9526 case CP0_REG07__HWRENA
:
9527 check_insn(ctx
, ISA_MIPS_R2
);
9528 gen_helper_mtc0_hwrena(cpu_env
, arg
);
9529 ctx
->base
.is_jmp
= DISAS_STOP
;
9530 register_name
= "HWREna";
9533 goto cp0_unimplemented
;
9536 case CP0_REGISTER_08
:
9538 case CP0_REG08__BADVADDR
:
9540 register_name
= "BadVAddr";
9542 case CP0_REG08__BADINSTR
:
9544 register_name
= "BadInstr";
9546 case CP0_REG08__BADINSTRP
:
9548 register_name
= "BadInstrP";
9550 case CP0_REG08__BADINSTRX
:
9552 register_name
= "BadInstrX";
9555 goto cp0_unimplemented
;
9558 case CP0_REGISTER_09
:
9560 case CP0_REG09__COUNT
:
9561 gen_helper_mtc0_count(cpu_env
, arg
);
9562 register_name
= "Count";
9564 case CP0_REG09__SAARI
:
9565 CP0_CHECK(ctx
->saar
);
9566 gen_helper_mtc0_saari(cpu_env
, arg
);
9567 register_name
= "SAARI";
9569 case CP0_REG09__SAAR
:
9570 CP0_CHECK(ctx
->saar
);
9571 gen_helper_mtc0_saar(cpu_env
, arg
);
9572 register_name
= "SAAR";
9575 goto cp0_unimplemented
;
9577 /* Stop translation as we may have switched the execution mode */
9578 ctx
->base
.is_jmp
= DISAS_STOP
;
9580 case CP0_REGISTER_10
:
9582 case CP0_REG10__ENTRYHI
:
9583 gen_helper_mtc0_entryhi(cpu_env
, arg
);
9584 register_name
= "EntryHi";
9587 goto cp0_unimplemented
;
9590 case CP0_REGISTER_11
:
9592 case CP0_REG11__COMPARE
:
9593 gen_helper_mtc0_compare(cpu_env
, arg
);
9594 register_name
= "Compare";
9596 /* 6,7 are implementation dependent */
9598 goto cp0_unimplemented
;
9600 /* Stop translation as we may have switched the execution mode */
9601 ctx
->base
.is_jmp
= DISAS_STOP
;
9603 case CP0_REGISTER_12
:
9605 case CP0_REG12__STATUS
:
9606 save_cpu_state(ctx
, 1);
9607 gen_helper_mtc0_status(cpu_env
, arg
);
9608 /* DISAS_STOP isn't good enough here, hflags may have changed. */
9609 gen_save_pc(ctx
->base
.pc_next
+ 4);
9610 ctx
->base
.is_jmp
= DISAS_EXIT
;
9611 register_name
= "Status";
9613 case CP0_REG12__INTCTL
:
9614 check_insn(ctx
, ISA_MIPS_R2
);
9615 gen_helper_mtc0_intctl(cpu_env
, arg
);
9616 /* Stop translation as we may have switched the execution mode */
9617 ctx
->base
.is_jmp
= DISAS_STOP
;
9618 register_name
= "IntCtl";
9620 case CP0_REG12__SRSCTL
:
9621 check_insn(ctx
, ISA_MIPS_R2
);
9622 gen_helper_mtc0_srsctl(cpu_env
, arg
);
9623 /* Stop translation as we may have switched the execution mode */
9624 ctx
->base
.is_jmp
= DISAS_STOP
;
9625 register_name
= "SRSCtl";
9627 case CP0_REG12__SRSMAP
:
9628 check_insn(ctx
, ISA_MIPS_R2
);
9629 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
9630 /* Stop translation as we may have switched the execution mode */
9631 ctx
->base
.is_jmp
= DISAS_STOP
;
9632 register_name
= "SRSMap";
9635 goto cp0_unimplemented
;
9638 case CP0_REGISTER_13
:
9640 case CP0_REG13__CAUSE
:
9641 save_cpu_state(ctx
, 1);
9642 gen_helper_mtc0_cause(cpu_env
, arg
);
9644 * Stop translation as we may have triggered an interrupt.
9645 * DISAS_STOP isn't sufficient, we need to ensure we break out of
9646 * translated code to check for pending interrupts.
9648 gen_save_pc(ctx
->base
.pc_next
+ 4);
9649 ctx
->base
.is_jmp
= DISAS_EXIT
;
9650 register_name
= "Cause";
9653 goto cp0_unimplemented
;
9656 case CP0_REGISTER_14
:
9658 case CP0_REG14__EPC
:
9659 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
9660 register_name
= "EPC";
9663 goto cp0_unimplemented
;
9666 case CP0_REGISTER_15
:
9668 case CP0_REG15__PRID
:
9670 register_name
= "PRid";
9672 case CP0_REG15__EBASE
:
9673 check_insn(ctx
, ISA_MIPS_R2
);
9674 gen_helper_mtc0_ebase(cpu_env
, arg
);
9675 register_name
= "EBase";
9678 goto cp0_unimplemented
;
9681 case CP0_REGISTER_16
:
9683 case CP0_REG16__CONFIG
:
9684 gen_helper_mtc0_config0(cpu_env
, arg
);
9685 register_name
= "Config";
9686 /* Stop translation as we may have switched the execution mode */
9687 ctx
->base
.is_jmp
= DISAS_STOP
;
9689 case CP0_REG16__CONFIG1
:
9690 /* ignored, read only */
9691 register_name
= "Config1";
9693 case CP0_REG16__CONFIG2
:
9694 gen_helper_mtc0_config2(cpu_env
, arg
);
9695 register_name
= "Config2";
9696 /* Stop translation as we may have switched the execution mode */
9697 ctx
->base
.is_jmp
= DISAS_STOP
;
9699 case CP0_REG16__CONFIG3
:
9700 gen_helper_mtc0_config3(cpu_env
, arg
);
9701 register_name
= "Config3";
9702 /* Stop translation as we may have switched the execution mode */
9703 ctx
->base
.is_jmp
= DISAS_STOP
;
9705 case CP0_REG16__CONFIG4
:
9706 /* currently ignored */
9707 register_name
= "Config4";
9709 case CP0_REG16__CONFIG5
:
9710 gen_helper_mtc0_config5(cpu_env
, arg
);
9711 register_name
= "Config5";
9712 /* Stop translation as we may have switched the execution mode */
9713 ctx
->base
.is_jmp
= DISAS_STOP
;
9715 /* 6,7 are implementation dependent */
9717 register_name
= "Invalid config selector";
9718 goto cp0_unimplemented
;
9721 case CP0_REGISTER_17
:
9723 case CP0_REG17__LLADDR
:
9724 gen_helper_mtc0_lladdr(cpu_env
, arg
);
9725 register_name
= "LLAddr";
9727 case CP0_REG17__MAAR
:
9728 CP0_CHECK(ctx
->mrp
);
9729 gen_helper_mtc0_maar(cpu_env
, arg
);
9730 register_name
= "MAAR";
9732 case CP0_REG17__MAARI
:
9733 CP0_CHECK(ctx
->mrp
);
9734 gen_helper_mtc0_maari(cpu_env
, arg
);
9735 register_name
= "MAARI";
9738 goto cp0_unimplemented
;
9741 case CP0_REGISTER_18
:
9743 case CP0_REG18__WATCHLO0
:
9744 case CP0_REG18__WATCHLO1
:
9745 case CP0_REG18__WATCHLO2
:
9746 case CP0_REG18__WATCHLO3
:
9747 case CP0_REG18__WATCHLO4
:
9748 case CP0_REG18__WATCHLO5
:
9749 case CP0_REG18__WATCHLO6
:
9750 case CP0_REG18__WATCHLO7
:
9751 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
9752 gen_helper_0e1i(mtc0_watchlo
, arg
, sel
);
9753 register_name
= "WatchLo";
9756 goto cp0_unimplemented
;
9759 case CP0_REGISTER_19
:
9761 case CP0_REG19__WATCHHI0
:
9762 case CP0_REG19__WATCHHI1
:
9763 case CP0_REG19__WATCHHI2
:
9764 case CP0_REG19__WATCHHI3
:
9765 case CP0_REG19__WATCHHI4
:
9766 case CP0_REG19__WATCHHI5
:
9767 case CP0_REG19__WATCHHI6
:
9768 case CP0_REG19__WATCHHI7
:
9769 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
9770 gen_helper_0e1i(mtc0_watchhi
, arg
, sel
);
9771 register_name
= "WatchHi";
9774 goto cp0_unimplemented
;
9777 case CP0_REGISTER_20
:
9779 case CP0_REG20__XCONTEXT
:
9780 check_insn(ctx
, ISA_MIPS3
);
9781 gen_helper_mtc0_xcontext(cpu_env
, arg
);
9782 register_name
= "XContext";
9785 goto cp0_unimplemented
;
9788 case CP0_REGISTER_21
:
9789 /* Officially reserved, but sel 0 is used for R1x000 framemask */
9790 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS_R6
));
9793 gen_helper_mtc0_framemask(cpu_env
, arg
);
9794 register_name
= "Framemask";
9797 goto cp0_unimplemented
;
9800 case CP0_REGISTER_22
:
9802 register_name
= "Diagnostic"; /* implementation dependent */
9804 case CP0_REGISTER_23
:
9806 case CP0_REG23__DEBUG
:
9807 gen_helper_mtc0_debug(cpu_env
, arg
); /* EJTAG support */
9808 /* DISAS_STOP isn't good enough here, hflags may have changed. */
9809 gen_save_pc(ctx
->base
.pc_next
+ 4);
9810 ctx
->base
.is_jmp
= DISAS_EXIT
;
9811 register_name
= "Debug";
9813 case CP0_REG23__TRACECONTROL
:
9814 /* PDtrace support */
9815 /* gen_helper_mtc0_tracecontrol(cpu_env, arg); */
9816 /* Stop translation as we may have switched the execution mode */
9817 ctx
->base
.is_jmp
= DISAS_STOP
;
9818 register_name
= "TraceControl";
9819 goto cp0_unimplemented
;
9820 case CP0_REG23__TRACECONTROL2
:
9821 /* PDtrace support */
9822 /* gen_helper_mtc0_tracecontrol2(cpu_env, arg); */
9823 /* Stop translation as we may have switched the execution mode */
9824 ctx
->base
.is_jmp
= DISAS_STOP
;
9825 register_name
= "TraceControl2";
9826 goto cp0_unimplemented
;
9827 case CP0_REG23__USERTRACEDATA1
:
9828 /* PDtrace support */
9829 /* gen_helper_mtc0_usertracedata1(cpu_env, arg);*/
9830 /* Stop translation as we may have switched the execution mode */
9831 ctx
->base
.is_jmp
= DISAS_STOP
;
9832 register_name
= "UserTraceData1";
9833 goto cp0_unimplemented
;
9834 case CP0_REG23__TRACEIBPC
:
9835 /* PDtrace support */
9836 /* gen_helper_mtc0_traceibpc(cpu_env, arg); */
9837 /* Stop translation as we may have switched the execution mode */
9838 ctx
->base
.is_jmp
= DISAS_STOP
;
9839 register_name
= "TraceIBPC";
9840 goto cp0_unimplemented
;
9841 case CP0_REG23__TRACEDBPC
:
9842 /* PDtrace support */
9843 /* gen_helper_mtc0_tracedbpc(cpu_env, arg); */
9844 /* Stop translation as we may have switched the execution mode */
9845 ctx
->base
.is_jmp
= DISAS_STOP
;
9846 register_name
= "TraceDBPC";
9847 goto cp0_unimplemented
;
9849 goto cp0_unimplemented
;
9852 case CP0_REGISTER_24
:
9854 case CP0_REG24__DEPC
:
9856 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
9857 register_name
= "DEPC";
9860 goto cp0_unimplemented
;
9863 case CP0_REGISTER_25
:
9865 case CP0_REG25__PERFCTL0
:
9866 gen_helper_mtc0_performance0(cpu_env
, arg
);
9867 register_name
= "Performance0";
9869 case CP0_REG25__PERFCNT0
:
9870 /* gen_helper_mtc0_performance1(cpu_env, arg); */
9871 register_name
= "Performance1";
9872 goto cp0_unimplemented
;
9873 case CP0_REG25__PERFCTL1
:
9874 /* gen_helper_mtc0_performance2(cpu_env, arg); */
9875 register_name
= "Performance2";
9876 goto cp0_unimplemented
;
9877 case CP0_REG25__PERFCNT1
:
9878 /* gen_helper_mtc0_performance3(cpu_env, arg); */
9879 register_name
= "Performance3";
9880 goto cp0_unimplemented
;
9881 case CP0_REG25__PERFCTL2
:
9882 /* gen_helper_mtc0_performance4(cpu_env, arg); */
9883 register_name
= "Performance4";
9884 goto cp0_unimplemented
;
9885 case CP0_REG25__PERFCNT2
:
9886 /* gen_helper_mtc0_performance5(cpu_env, arg); */
9887 register_name
= "Performance5";
9888 goto cp0_unimplemented
;
9889 case CP0_REG25__PERFCTL3
:
9890 /* gen_helper_mtc0_performance6(cpu_env, arg); */
9891 register_name
= "Performance6";
9892 goto cp0_unimplemented
;
9893 case CP0_REG25__PERFCNT3
:
9894 /* gen_helper_mtc0_performance7(cpu_env, arg); */
9895 register_name
= "Performance7";
9896 goto cp0_unimplemented
;
9898 goto cp0_unimplemented
;
9901 case CP0_REGISTER_26
:
9903 case CP0_REG26__ERRCTL
:
9904 gen_helper_mtc0_errctl(cpu_env
, arg
);
9905 ctx
->base
.is_jmp
= DISAS_STOP
;
9906 register_name
= "ErrCtl";
9909 goto cp0_unimplemented
;
9912 case CP0_REGISTER_27
:
9914 case CP0_REG27__CACHERR
:
9916 register_name
= "CacheErr";
9919 goto cp0_unimplemented
;
9922 case CP0_REGISTER_28
:
9924 case CP0_REG28__TAGLO
:
9925 case CP0_REG28__TAGLO1
:
9926 case CP0_REG28__TAGLO2
:
9927 case CP0_REG28__TAGLO3
:
9928 gen_helper_mtc0_taglo(cpu_env
, arg
);
9929 register_name
= "TagLo";
9931 case CP0_REG28__DATALO
:
9932 case CP0_REG28__DATALO1
:
9933 case CP0_REG28__DATALO2
:
9934 case CP0_REG28__DATALO3
:
9935 gen_helper_mtc0_datalo(cpu_env
, arg
);
9936 register_name
= "DataLo";
9939 goto cp0_unimplemented
;
9942 case CP0_REGISTER_29
:
9944 case CP0_REG29__TAGHI
:
9945 case CP0_REG29__TAGHI1
:
9946 case CP0_REG29__TAGHI2
:
9947 case CP0_REG29__TAGHI3
:
9948 gen_helper_mtc0_taghi(cpu_env
, arg
);
9949 register_name
= "TagHi";
9951 case CP0_REG29__DATAHI
:
9952 case CP0_REG29__DATAHI1
:
9953 case CP0_REG29__DATAHI2
:
9954 case CP0_REG29__DATAHI3
:
9955 gen_helper_mtc0_datahi(cpu_env
, arg
);
9956 register_name
= "DataHi";
9959 register_name
= "invalid sel";
9960 goto cp0_unimplemented
;
9963 case CP0_REGISTER_30
:
9965 case CP0_REG30__ERROREPC
:
9966 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
9967 register_name
= "ErrorEPC";
9970 goto cp0_unimplemented
;
9973 case CP0_REGISTER_31
:
9975 case CP0_REG31__DESAVE
:
9977 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
9978 register_name
= "DESAVE";
9980 case CP0_REG31__KSCRATCH1
:
9981 case CP0_REG31__KSCRATCH2
:
9982 case CP0_REG31__KSCRATCH3
:
9983 case CP0_REG31__KSCRATCH4
:
9984 case CP0_REG31__KSCRATCH5
:
9985 case CP0_REG31__KSCRATCH6
:
9986 CP0_CHECK(ctx
->kscrexist
& (1 << sel
));
9987 tcg_gen_st_tl(arg
, cpu_env
,
9988 offsetof(CPUMIPSState
, CP0_KScratch
[sel
- 2]));
9989 register_name
= "KScratch";
9992 goto cp0_unimplemented
;
9996 goto cp0_unimplemented
;
9998 trace_mips_translate_c0("dmtc0", register_name
, reg
, sel
);
10000 /* For simplicity assume that all writes can cause interrupts. */
10001 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
10003 * DISAS_STOP isn't sufficient, we need to ensure we break out of
10004 * translated code to check for pending interrupts.
10006 gen_save_pc(ctx
->base
.pc_next
+ 4);
10007 ctx
->base
.is_jmp
= DISAS_EXIT
;
10012 qemu_log_mask(LOG_UNIMP
, "dmtc0 %s (reg %d sel %d)\n",
10013 register_name
, reg
, sel
);
10015 #endif /* TARGET_MIPS64 */
10017 static void gen_mftr(CPUMIPSState
*env
, DisasContext
*ctx
, int rt
, int rd
,
10018 int u
, int sel
, int h
)
10020 int other_tc
= env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
);
10021 TCGv t0
= tcg_temp_local_new();
10023 if ((env
->CP0_VPEConf0
& (1 << CP0VPEC0_MVP
)) == 0 &&
10024 ((env
->tcs
[other_tc
].CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)) !=
10025 (env
->active_tc
.CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)))) {
10026 tcg_gen_movi_tl(t0
, -1);
10027 } else if ((env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
)) >
10028 (env
->mvp
->CP0_MVPConf0
& (0xff << CP0MVPC0_PTC
))) {
10029 tcg_gen_movi_tl(t0
, -1);
10030 } else if (u
== 0) {
10035 gen_helper_mftc0_vpecontrol(t0
, cpu_env
);
10038 gen_helper_mftc0_vpeconf0(t0
, cpu_env
);
10048 gen_helper_mftc0_tcstatus(t0
, cpu_env
);
10051 gen_helper_mftc0_tcbind(t0
, cpu_env
);
10054 gen_helper_mftc0_tcrestart(t0
, cpu_env
);
10057 gen_helper_mftc0_tchalt(t0
, cpu_env
);
10060 gen_helper_mftc0_tccontext(t0
, cpu_env
);
10063 gen_helper_mftc0_tcschedule(t0
, cpu_env
);
10066 gen_helper_mftc0_tcschefback(t0
, cpu_env
);
10069 gen_mfc0(ctx
, t0
, rt
, sel
);
10076 gen_helper_mftc0_entryhi(t0
, cpu_env
);
10079 gen_mfc0(ctx
, t0
, rt
, sel
);
10086 gen_helper_mftc0_status(t0
, cpu_env
);
10089 gen_mfc0(ctx
, t0
, rt
, sel
);
10096 gen_helper_mftc0_cause(t0
, cpu_env
);
10106 gen_helper_mftc0_epc(t0
, cpu_env
);
10116 gen_helper_mftc0_ebase(t0
, cpu_env
);
10133 gen_helper_mftc0_configx(t0
, cpu_env
, tcg_const_tl(sel
));
10143 gen_helper_mftc0_debug(t0
, cpu_env
);
10146 gen_mfc0(ctx
, t0
, rt
, sel
);
10151 gen_mfc0(ctx
, t0
, rt
, sel
);
10155 /* GPR registers. */
10157 gen_helper_1e0i(mftgpr
, t0
, rt
);
10159 /* Auxiliary CPU registers */
10163 gen_helper_1e0i(mftlo
, t0
, 0);
10166 gen_helper_1e0i(mfthi
, t0
, 0);
10169 gen_helper_1e0i(mftacx
, t0
, 0);
10172 gen_helper_1e0i(mftlo
, t0
, 1);
10175 gen_helper_1e0i(mfthi
, t0
, 1);
10178 gen_helper_1e0i(mftacx
, t0
, 1);
10181 gen_helper_1e0i(mftlo
, t0
, 2);
10184 gen_helper_1e0i(mfthi
, t0
, 2);
10187 gen_helper_1e0i(mftacx
, t0
, 2);
10190 gen_helper_1e0i(mftlo
, t0
, 3);
10193 gen_helper_1e0i(mfthi
, t0
, 3);
10196 gen_helper_1e0i(mftacx
, t0
, 3);
10199 gen_helper_mftdsp(t0
, cpu_env
);
10205 /* Floating point (COP1). */
10207 /* XXX: For now we support only a single FPU context. */
10209 TCGv_i32 fp0
= tcg_temp_new_i32();
10211 gen_load_fpr32(ctx
, fp0
, rt
);
10212 tcg_gen_ext_i32_tl(t0
, fp0
);
10213 tcg_temp_free_i32(fp0
);
10215 TCGv_i32 fp0
= tcg_temp_new_i32();
10217 gen_load_fpr32h(ctx
, fp0
, rt
);
10218 tcg_gen_ext_i32_tl(t0
, fp0
);
10219 tcg_temp_free_i32(fp0
);
10223 /* XXX: For now we support only a single FPU context. */
10224 gen_helper_1e0i(cfc1
, t0
, rt
);
10226 /* COP2: Not implemented. */
10234 trace_mips_translate_tr("mftr", rt
, u
, sel
, h
);
10235 gen_store_gpr(t0
, rd
);
10241 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt
, u
, sel
, h
);
10242 gen_reserved_instruction(ctx
);
10245 static void gen_mttr(CPUMIPSState
*env
, DisasContext
*ctx
, int rd
, int rt
,
10246 int u
, int sel
, int h
)
10248 int other_tc
= env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
);
10249 TCGv t0
= tcg_temp_local_new();
10251 gen_load_gpr(t0
, rt
);
10252 if ((env
->CP0_VPEConf0
& (1 << CP0VPEC0_MVP
)) == 0 &&
10253 ((env
->tcs
[other_tc
].CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)) !=
10254 (env
->active_tc
.CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)))) {
10257 } else if ((env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
)) >
10258 (env
->mvp
->CP0_MVPConf0
& (0xff << CP0MVPC0_PTC
))) {
10261 } else if (u
== 0) {
10266 gen_helper_mttc0_vpecontrol(cpu_env
, t0
);
10269 gen_helper_mttc0_vpeconf0(cpu_env
, t0
);
10279 gen_helper_mttc0_tcstatus(cpu_env
, t0
);
10282 gen_helper_mttc0_tcbind(cpu_env
, t0
);
10285 gen_helper_mttc0_tcrestart(cpu_env
, t0
);
10288 gen_helper_mttc0_tchalt(cpu_env
, t0
);
10291 gen_helper_mttc0_tccontext(cpu_env
, t0
);
10294 gen_helper_mttc0_tcschedule(cpu_env
, t0
);
10297 gen_helper_mttc0_tcschefback(cpu_env
, t0
);
10300 gen_mtc0(ctx
, t0
, rd
, sel
);
10307 gen_helper_mttc0_entryhi(cpu_env
, t0
);
10310 gen_mtc0(ctx
, t0
, rd
, sel
);
10317 gen_helper_mttc0_status(cpu_env
, t0
);
10320 gen_mtc0(ctx
, t0
, rd
, sel
);
10327 gen_helper_mttc0_cause(cpu_env
, t0
);
10337 gen_helper_mttc0_ebase(cpu_env
, t0
);
10347 gen_helper_mttc0_debug(cpu_env
, t0
);
10350 gen_mtc0(ctx
, t0
, rd
, sel
);
10355 gen_mtc0(ctx
, t0
, rd
, sel
);
10359 /* GPR registers. */
10361 gen_helper_0e1i(mttgpr
, t0
, rd
);
10363 /* Auxiliary CPU registers */
10367 gen_helper_0e1i(mttlo
, t0
, 0);
10370 gen_helper_0e1i(mtthi
, t0
, 0);
10373 gen_helper_0e1i(mttacx
, t0
, 0);
10376 gen_helper_0e1i(mttlo
, t0
, 1);
10379 gen_helper_0e1i(mtthi
, t0
, 1);
10382 gen_helper_0e1i(mttacx
, t0
, 1);
10385 gen_helper_0e1i(mttlo
, t0
, 2);
10388 gen_helper_0e1i(mtthi
, t0
, 2);
10391 gen_helper_0e1i(mttacx
, t0
, 2);
10394 gen_helper_0e1i(mttlo
, t0
, 3);
10397 gen_helper_0e1i(mtthi
, t0
, 3);
10400 gen_helper_0e1i(mttacx
, t0
, 3);
10403 gen_helper_mttdsp(cpu_env
, t0
);
10409 /* Floating point (COP1). */
10411 /* XXX: For now we support only a single FPU context. */
10413 TCGv_i32 fp0
= tcg_temp_new_i32();
10415 tcg_gen_trunc_tl_i32(fp0
, t0
);
10416 gen_store_fpr32(ctx
, fp0
, rd
);
10417 tcg_temp_free_i32(fp0
);
10419 TCGv_i32 fp0
= tcg_temp_new_i32();
10421 tcg_gen_trunc_tl_i32(fp0
, t0
);
10422 gen_store_fpr32h(ctx
, fp0
, rd
);
10423 tcg_temp_free_i32(fp0
);
10427 /* XXX: For now we support only a single FPU context. */
10429 TCGv_i32 fs_tmp
= tcg_const_i32(rd
);
10431 gen_helper_0e2i(ctc1
, t0
, fs_tmp
, rt
);
10432 tcg_temp_free_i32(fs_tmp
);
10434 /* Stop translation as we may have changed hflags */
10435 ctx
->base
.is_jmp
= DISAS_STOP
;
10437 /* COP2: Not implemented. */
10445 trace_mips_translate_tr("mttr", rd
, u
, sel
, h
);
10451 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd
, u
, sel
, h
);
10452 gen_reserved_instruction(ctx
);
10455 static void gen_cp0(CPUMIPSState
*env
, DisasContext
*ctx
, uint32_t opc
,
10458 const char *opn
= "ldst";
10460 check_cp0_enabled(ctx
);
10464 /* Treat as NOP. */
10467 gen_mfc0(ctx
, cpu_gpr
[rt
], rd
, ctx
->opcode
& 0x7);
10472 TCGv t0
= tcg_temp_new();
10474 gen_load_gpr(t0
, rt
);
10475 gen_mtc0(ctx
, t0
, rd
, ctx
->opcode
& 0x7);
10480 #if defined(TARGET_MIPS64)
10482 check_insn(ctx
, ISA_MIPS3
);
10484 /* Treat as NOP. */
10487 gen_dmfc0(ctx
, cpu_gpr
[rt
], rd
, ctx
->opcode
& 0x7);
10491 check_insn(ctx
, ISA_MIPS3
);
10493 TCGv t0
= tcg_temp_new();
10495 gen_load_gpr(t0
, rt
);
10496 gen_dmtc0(ctx
, t0
, rd
, ctx
->opcode
& 0x7);
10505 /* Treat as NOP. */
10508 gen_mfhc0(ctx
, cpu_gpr
[rt
], rd
, ctx
->opcode
& 0x7);
10514 TCGv t0
= tcg_temp_new();
10515 gen_load_gpr(t0
, rt
);
10516 gen_mthc0(ctx
, t0
, rd
, ctx
->opcode
& 0x7);
10522 check_cp0_enabled(ctx
);
10524 /* Treat as NOP. */
10527 gen_mftr(env
, ctx
, rt
, rd
, (ctx
->opcode
>> 5) & 1,
10528 ctx
->opcode
& 0x7, (ctx
->opcode
>> 4) & 1);
10532 check_cp0_enabled(ctx
);
10533 gen_mttr(env
, ctx
, rd
, rt
, (ctx
->opcode
>> 5) & 1,
10534 ctx
->opcode
& 0x7, (ctx
->opcode
>> 4) & 1);
10539 if (!env
->tlb
->helper_tlbwi
) {
10542 gen_helper_tlbwi(cpu_env
);
10546 if (ctx
->ie
>= 2) {
10547 if (!env
->tlb
->helper_tlbinv
) {
10550 gen_helper_tlbinv(cpu_env
);
10551 } /* treat as nop if TLBINV not supported */
10555 if (ctx
->ie
>= 2) {
10556 if (!env
->tlb
->helper_tlbinvf
) {
10559 gen_helper_tlbinvf(cpu_env
);
10560 } /* treat as nop if TLBINV not supported */
10564 if (!env
->tlb
->helper_tlbwr
) {
10567 gen_helper_tlbwr(cpu_env
);
10571 if (!env
->tlb
->helper_tlbp
) {
10574 gen_helper_tlbp(cpu_env
);
10578 if (!env
->tlb
->helper_tlbr
) {
10581 gen_helper_tlbr(cpu_env
);
10583 case OPC_ERET
: /* OPC_ERETNC */
10584 if ((ctx
->insn_flags
& ISA_MIPS_R6
) &&
10585 (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
10588 int bit_shift
= (ctx
->hflags
& MIPS_HFLAG_M16
) ? 16 : 6;
10589 if (ctx
->opcode
& (1 << bit_shift
)) {
10592 check_insn(ctx
, ISA_MIPS_R5
);
10593 gen_helper_eretnc(cpu_env
);
10597 check_insn(ctx
, ISA_MIPS2
);
10598 gen_helper_eret(cpu_env
);
10600 ctx
->base
.is_jmp
= DISAS_EXIT
;
10605 check_insn(ctx
, ISA_MIPS_R1
);
10606 if ((ctx
->insn_flags
& ISA_MIPS_R6
) &&
10607 (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
10610 if (!(ctx
->hflags
& MIPS_HFLAG_DM
)) {
10612 gen_reserved_instruction(ctx
);
10614 gen_helper_deret(cpu_env
);
10615 ctx
->base
.is_jmp
= DISAS_EXIT
;
10620 check_insn(ctx
, ISA_MIPS3
| ISA_MIPS_R1
);
10621 if ((ctx
->insn_flags
& ISA_MIPS_R6
) &&
10622 (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
10625 /* If we get an exception, we want to restart at next instruction */
10626 ctx
->base
.pc_next
+= 4;
10627 save_cpu_state(ctx
, 1);
10628 ctx
->base
.pc_next
-= 4;
10629 gen_helper_wait(cpu_env
);
10630 ctx
->base
.is_jmp
= DISAS_NORETURN
;
10635 gen_reserved_instruction(ctx
);
10638 (void)opn
; /* avoid a compiler warning */
10640 #endif /* !CONFIG_USER_ONLY */
10642 /* CP1 Branches (before delay slot) */
10643 static void gen_compute_branch1(DisasContext
*ctx
, uint32_t op
,
10644 int32_t cc
, int32_t offset
)
10646 target_ulong btarget
;
10647 TCGv_i32 t0
= tcg_temp_new_i32();
10649 if ((ctx
->insn_flags
& ISA_MIPS_R6
) && (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
10650 gen_reserved_instruction(ctx
);
10655 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS_R1
);
10658 btarget
= ctx
->base
.pc_next
+ 4 + offset
;
10662 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
10663 tcg_gen_not_i32(t0
, t0
);
10664 tcg_gen_andi_i32(t0
, t0
, 1);
10665 tcg_gen_extu_i32_tl(bcond
, t0
);
10668 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
10669 tcg_gen_not_i32(t0
, t0
);
10670 tcg_gen_andi_i32(t0
, t0
, 1);
10671 tcg_gen_extu_i32_tl(bcond
, t0
);
10674 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
10675 tcg_gen_andi_i32(t0
, t0
, 1);
10676 tcg_gen_extu_i32_tl(bcond
, t0
);
10679 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
10680 tcg_gen_andi_i32(t0
, t0
, 1);
10681 tcg_gen_extu_i32_tl(bcond
, t0
);
10683 ctx
->hflags
|= MIPS_HFLAG_BL
;
10687 TCGv_i32 t1
= tcg_temp_new_i32();
10688 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
10689 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 1));
10690 tcg_gen_nand_i32(t0
, t0
, t1
);
10691 tcg_temp_free_i32(t1
);
10692 tcg_gen_andi_i32(t0
, t0
, 1);
10693 tcg_gen_extu_i32_tl(bcond
, t0
);
10698 TCGv_i32 t1
= tcg_temp_new_i32();
10699 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
10700 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 1));
10701 tcg_gen_or_i32(t0
, t0
, t1
);
10702 tcg_temp_free_i32(t1
);
10703 tcg_gen_andi_i32(t0
, t0
, 1);
10704 tcg_gen_extu_i32_tl(bcond
, t0
);
10709 TCGv_i32 t1
= tcg_temp_new_i32();
10710 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
10711 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 1));
10712 tcg_gen_and_i32(t0
, t0
, t1
);
10713 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 2));
10714 tcg_gen_and_i32(t0
, t0
, t1
);
10715 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 3));
10716 tcg_gen_nand_i32(t0
, t0
, t1
);
10717 tcg_temp_free_i32(t1
);
10718 tcg_gen_andi_i32(t0
, t0
, 1);
10719 tcg_gen_extu_i32_tl(bcond
, t0
);
10724 TCGv_i32 t1
= tcg_temp_new_i32();
10725 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
10726 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 1));
10727 tcg_gen_or_i32(t0
, t0
, t1
);
10728 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 2));
10729 tcg_gen_or_i32(t0
, t0
, t1
);
10730 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 3));
10731 tcg_gen_or_i32(t0
, t0
, t1
);
10732 tcg_temp_free_i32(t1
);
10733 tcg_gen_andi_i32(t0
, t0
, 1);
10734 tcg_gen_extu_i32_tl(bcond
, t0
);
10737 ctx
->hflags
|= MIPS_HFLAG_BC
;
10740 MIPS_INVAL("cp1 cond branch");
10741 gen_reserved_instruction(ctx
);
10744 ctx
->btarget
= btarget
;
10745 ctx
->hflags
|= MIPS_HFLAG_BDS32
;
10747 tcg_temp_free_i32(t0
);
10750 /* R6 CP1 Branches */
10751 static void gen_compute_branch1_r6(DisasContext
*ctx
, uint32_t op
,
10752 int32_t ft
, int32_t offset
,
10753 int delayslot_size
)
10755 target_ulong btarget
;
10756 TCGv_i64 t0
= tcg_temp_new_i64();
10758 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
10759 #ifdef MIPS_DEBUG_DISAS
10760 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
10761 "\n", ctx
->base
.pc_next
);
10763 gen_reserved_instruction(ctx
);
10767 gen_load_fpr64(ctx
, t0
, ft
);
10768 tcg_gen_andi_i64(t0
, t0
, 1);
10770 btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
10774 tcg_gen_xori_i64(t0
, t0
, 1);
10775 ctx
->hflags
|= MIPS_HFLAG_BC
;
10778 /* t0 already set */
10779 ctx
->hflags
|= MIPS_HFLAG_BC
;
10782 MIPS_INVAL("cp1 cond branch");
10783 gen_reserved_instruction(ctx
);
10787 tcg_gen_trunc_i64_tl(bcond
, t0
);
10789 ctx
->btarget
= btarget
;
10791 switch (delayslot_size
) {
10793 ctx
->hflags
|= MIPS_HFLAG_BDS16
;
10796 ctx
->hflags
|= MIPS_HFLAG_BDS32
;
10801 tcg_temp_free_i64(t0
);
10804 /* Coprocessor 1 (FPU) */
10806 #define FOP(func, fmt) (((fmt) << 21) | (func))
10809 OPC_ADD_S
= FOP(0, FMT_S
),
10810 OPC_SUB_S
= FOP(1, FMT_S
),
10811 OPC_MUL_S
= FOP(2, FMT_S
),
10812 OPC_DIV_S
= FOP(3, FMT_S
),
10813 OPC_SQRT_S
= FOP(4, FMT_S
),
10814 OPC_ABS_S
= FOP(5, FMT_S
),
10815 OPC_MOV_S
= FOP(6, FMT_S
),
10816 OPC_NEG_S
= FOP(7, FMT_S
),
10817 OPC_ROUND_L_S
= FOP(8, FMT_S
),
10818 OPC_TRUNC_L_S
= FOP(9, FMT_S
),
10819 OPC_CEIL_L_S
= FOP(10, FMT_S
),
10820 OPC_FLOOR_L_S
= FOP(11, FMT_S
),
10821 OPC_ROUND_W_S
= FOP(12, FMT_S
),
10822 OPC_TRUNC_W_S
= FOP(13, FMT_S
),
10823 OPC_CEIL_W_S
= FOP(14, FMT_S
),
10824 OPC_FLOOR_W_S
= FOP(15, FMT_S
),
10825 OPC_SEL_S
= FOP(16, FMT_S
),
10826 OPC_MOVCF_S
= FOP(17, FMT_S
),
10827 OPC_MOVZ_S
= FOP(18, FMT_S
),
10828 OPC_MOVN_S
= FOP(19, FMT_S
),
10829 OPC_SELEQZ_S
= FOP(20, FMT_S
),
10830 OPC_RECIP_S
= FOP(21, FMT_S
),
10831 OPC_RSQRT_S
= FOP(22, FMT_S
),
10832 OPC_SELNEZ_S
= FOP(23, FMT_S
),
10833 OPC_MADDF_S
= FOP(24, FMT_S
),
10834 OPC_MSUBF_S
= FOP(25, FMT_S
),
10835 OPC_RINT_S
= FOP(26, FMT_S
),
10836 OPC_CLASS_S
= FOP(27, FMT_S
),
10837 OPC_MIN_S
= FOP(28, FMT_S
),
10838 OPC_RECIP2_S
= FOP(28, FMT_S
),
10839 OPC_MINA_S
= FOP(29, FMT_S
),
10840 OPC_RECIP1_S
= FOP(29, FMT_S
),
10841 OPC_MAX_S
= FOP(30, FMT_S
),
10842 OPC_RSQRT1_S
= FOP(30, FMT_S
),
10843 OPC_MAXA_S
= FOP(31, FMT_S
),
10844 OPC_RSQRT2_S
= FOP(31, FMT_S
),
10845 OPC_CVT_D_S
= FOP(33, FMT_S
),
10846 OPC_CVT_W_S
= FOP(36, FMT_S
),
10847 OPC_CVT_L_S
= FOP(37, FMT_S
),
10848 OPC_CVT_PS_S
= FOP(38, FMT_S
),
10849 OPC_CMP_F_S
= FOP(48, FMT_S
),
10850 OPC_CMP_UN_S
= FOP(49, FMT_S
),
10851 OPC_CMP_EQ_S
= FOP(50, FMT_S
),
10852 OPC_CMP_UEQ_S
= FOP(51, FMT_S
),
10853 OPC_CMP_OLT_S
= FOP(52, FMT_S
),
10854 OPC_CMP_ULT_S
= FOP(53, FMT_S
),
10855 OPC_CMP_OLE_S
= FOP(54, FMT_S
),
10856 OPC_CMP_ULE_S
= FOP(55, FMT_S
),
10857 OPC_CMP_SF_S
= FOP(56, FMT_S
),
10858 OPC_CMP_NGLE_S
= FOP(57, FMT_S
),
10859 OPC_CMP_SEQ_S
= FOP(58, FMT_S
),
10860 OPC_CMP_NGL_S
= FOP(59, FMT_S
),
10861 OPC_CMP_LT_S
= FOP(60, FMT_S
),
10862 OPC_CMP_NGE_S
= FOP(61, FMT_S
),
10863 OPC_CMP_LE_S
= FOP(62, FMT_S
),
10864 OPC_CMP_NGT_S
= FOP(63, FMT_S
),
10866 OPC_ADD_D
= FOP(0, FMT_D
),
10867 OPC_SUB_D
= FOP(1, FMT_D
),
10868 OPC_MUL_D
= FOP(2, FMT_D
),
10869 OPC_DIV_D
= FOP(3, FMT_D
),
10870 OPC_SQRT_D
= FOP(4, FMT_D
),
10871 OPC_ABS_D
= FOP(5, FMT_D
),
10872 OPC_MOV_D
= FOP(6, FMT_D
),
10873 OPC_NEG_D
= FOP(7, FMT_D
),
10874 OPC_ROUND_L_D
= FOP(8, FMT_D
),
10875 OPC_TRUNC_L_D
= FOP(9, FMT_D
),
10876 OPC_CEIL_L_D
= FOP(10, FMT_D
),
10877 OPC_FLOOR_L_D
= FOP(11, FMT_D
),
10878 OPC_ROUND_W_D
= FOP(12, FMT_D
),
10879 OPC_TRUNC_W_D
= FOP(13, FMT_D
),
10880 OPC_CEIL_W_D
= FOP(14, FMT_D
),
10881 OPC_FLOOR_W_D
= FOP(15, FMT_D
),
10882 OPC_SEL_D
= FOP(16, FMT_D
),
10883 OPC_MOVCF_D
= FOP(17, FMT_D
),
10884 OPC_MOVZ_D
= FOP(18, FMT_D
),
10885 OPC_MOVN_D
= FOP(19, FMT_D
),
10886 OPC_SELEQZ_D
= FOP(20, FMT_D
),
10887 OPC_RECIP_D
= FOP(21, FMT_D
),
10888 OPC_RSQRT_D
= FOP(22, FMT_D
),
10889 OPC_SELNEZ_D
= FOP(23, FMT_D
),
10890 OPC_MADDF_D
= FOP(24, FMT_D
),
10891 OPC_MSUBF_D
= FOP(25, FMT_D
),
10892 OPC_RINT_D
= FOP(26, FMT_D
),
10893 OPC_CLASS_D
= FOP(27, FMT_D
),
10894 OPC_MIN_D
= FOP(28, FMT_D
),
10895 OPC_RECIP2_D
= FOP(28, FMT_D
),
10896 OPC_MINA_D
= FOP(29, FMT_D
),
10897 OPC_RECIP1_D
= FOP(29, FMT_D
),
10898 OPC_MAX_D
= FOP(30, FMT_D
),
10899 OPC_RSQRT1_D
= FOP(30, FMT_D
),
10900 OPC_MAXA_D
= FOP(31, FMT_D
),
10901 OPC_RSQRT2_D
= FOP(31, FMT_D
),
10902 OPC_CVT_S_D
= FOP(32, FMT_D
),
10903 OPC_CVT_W_D
= FOP(36, FMT_D
),
10904 OPC_CVT_L_D
= FOP(37, FMT_D
),
10905 OPC_CMP_F_D
= FOP(48, FMT_D
),
10906 OPC_CMP_UN_D
= FOP(49, FMT_D
),
10907 OPC_CMP_EQ_D
= FOP(50, FMT_D
),
10908 OPC_CMP_UEQ_D
= FOP(51, FMT_D
),
10909 OPC_CMP_OLT_D
= FOP(52, FMT_D
),
10910 OPC_CMP_ULT_D
= FOP(53, FMT_D
),
10911 OPC_CMP_OLE_D
= FOP(54, FMT_D
),
10912 OPC_CMP_ULE_D
= FOP(55, FMT_D
),
10913 OPC_CMP_SF_D
= FOP(56, FMT_D
),
10914 OPC_CMP_NGLE_D
= FOP(57, FMT_D
),
10915 OPC_CMP_SEQ_D
= FOP(58, FMT_D
),
10916 OPC_CMP_NGL_D
= FOP(59, FMT_D
),
10917 OPC_CMP_LT_D
= FOP(60, FMT_D
),
10918 OPC_CMP_NGE_D
= FOP(61, FMT_D
),
10919 OPC_CMP_LE_D
= FOP(62, FMT_D
),
10920 OPC_CMP_NGT_D
= FOP(63, FMT_D
),
10922 OPC_CVT_S_W
= FOP(32, FMT_W
),
10923 OPC_CVT_D_W
= FOP(33, FMT_W
),
10924 OPC_CVT_S_L
= FOP(32, FMT_L
),
10925 OPC_CVT_D_L
= FOP(33, FMT_L
),
10926 OPC_CVT_PS_PW
= FOP(38, FMT_W
),
10928 OPC_ADD_PS
= FOP(0, FMT_PS
),
10929 OPC_SUB_PS
= FOP(1, FMT_PS
),
10930 OPC_MUL_PS
= FOP(2, FMT_PS
),
10931 OPC_DIV_PS
= FOP(3, FMT_PS
),
10932 OPC_ABS_PS
= FOP(5, FMT_PS
),
10933 OPC_MOV_PS
= FOP(6, FMT_PS
),
10934 OPC_NEG_PS
= FOP(7, FMT_PS
),
10935 OPC_MOVCF_PS
= FOP(17, FMT_PS
),
10936 OPC_MOVZ_PS
= FOP(18, FMT_PS
),
10937 OPC_MOVN_PS
= FOP(19, FMT_PS
),
10938 OPC_ADDR_PS
= FOP(24, FMT_PS
),
10939 OPC_MULR_PS
= FOP(26, FMT_PS
),
10940 OPC_RECIP2_PS
= FOP(28, FMT_PS
),
10941 OPC_RECIP1_PS
= FOP(29, FMT_PS
),
10942 OPC_RSQRT1_PS
= FOP(30, FMT_PS
),
10943 OPC_RSQRT2_PS
= FOP(31, FMT_PS
),
10945 OPC_CVT_S_PU
= FOP(32, FMT_PS
),
10946 OPC_CVT_PW_PS
= FOP(36, FMT_PS
),
10947 OPC_CVT_S_PL
= FOP(40, FMT_PS
),
10948 OPC_PLL_PS
= FOP(44, FMT_PS
),
10949 OPC_PLU_PS
= FOP(45, FMT_PS
),
10950 OPC_PUL_PS
= FOP(46, FMT_PS
),
10951 OPC_PUU_PS
= FOP(47, FMT_PS
),
10952 OPC_CMP_F_PS
= FOP(48, FMT_PS
),
10953 OPC_CMP_UN_PS
= FOP(49, FMT_PS
),
10954 OPC_CMP_EQ_PS
= FOP(50, FMT_PS
),
10955 OPC_CMP_UEQ_PS
= FOP(51, FMT_PS
),
10956 OPC_CMP_OLT_PS
= FOP(52, FMT_PS
),
10957 OPC_CMP_ULT_PS
= FOP(53, FMT_PS
),
10958 OPC_CMP_OLE_PS
= FOP(54, FMT_PS
),
10959 OPC_CMP_ULE_PS
= FOP(55, FMT_PS
),
10960 OPC_CMP_SF_PS
= FOP(56, FMT_PS
),
10961 OPC_CMP_NGLE_PS
= FOP(57, FMT_PS
),
10962 OPC_CMP_SEQ_PS
= FOP(58, FMT_PS
),
10963 OPC_CMP_NGL_PS
= FOP(59, FMT_PS
),
10964 OPC_CMP_LT_PS
= FOP(60, FMT_PS
),
10965 OPC_CMP_NGE_PS
= FOP(61, FMT_PS
),
10966 OPC_CMP_LE_PS
= FOP(62, FMT_PS
),
10967 OPC_CMP_NGT_PS
= FOP(63, FMT_PS
),
10971 R6_OPC_CMP_AF_S
= FOP(0, FMT_W
),
10972 R6_OPC_CMP_UN_S
= FOP(1, FMT_W
),
10973 R6_OPC_CMP_EQ_S
= FOP(2, FMT_W
),
10974 R6_OPC_CMP_UEQ_S
= FOP(3, FMT_W
),
10975 R6_OPC_CMP_LT_S
= FOP(4, FMT_W
),
10976 R6_OPC_CMP_ULT_S
= FOP(5, FMT_W
),
10977 R6_OPC_CMP_LE_S
= FOP(6, FMT_W
),
10978 R6_OPC_CMP_ULE_S
= FOP(7, FMT_W
),
10979 R6_OPC_CMP_SAF_S
= FOP(8, FMT_W
),
10980 R6_OPC_CMP_SUN_S
= FOP(9, FMT_W
),
10981 R6_OPC_CMP_SEQ_S
= FOP(10, FMT_W
),
10982 R6_OPC_CMP_SEUQ_S
= FOP(11, FMT_W
),
10983 R6_OPC_CMP_SLT_S
= FOP(12, FMT_W
),
10984 R6_OPC_CMP_SULT_S
= FOP(13, FMT_W
),
10985 R6_OPC_CMP_SLE_S
= FOP(14, FMT_W
),
10986 R6_OPC_CMP_SULE_S
= FOP(15, FMT_W
),
10987 R6_OPC_CMP_OR_S
= FOP(17, FMT_W
),
10988 R6_OPC_CMP_UNE_S
= FOP(18, FMT_W
),
10989 R6_OPC_CMP_NE_S
= FOP(19, FMT_W
),
10990 R6_OPC_CMP_SOR_S
= FOP(25, FMT_W
),
10991 R6_OPC_CMP_SUNE_S
= FOP(26, FMT_W
),
10992 R6_OPC_CMP_SNE_S
= FOP(27, FMT_W
),
10994 R6_OPC_CMP_AF_D
= FOP(0, FMT_L
),
10995 R6_OPC_CMP_UN_D
= FOP(1, FMT_L
),
10996 R6_OPC_CMP_EQ_D
= FOP(2, FMT_L
),
10997 R6_OPC_CMP_UEQ_D
= FOP(3, FMT_L
),
10998 R6_OPC_CMP_LT_D
= FOP(4, FMT_L
),
10999 R6_OPC_CMP_ULT_D
= FOP(5, FMT_L
),
11000 R6_OPC_CMP_LE_D
= FOP(6, FMT_L
),
11001 R6_OPC_CMP_ULE_D
= FOP(7, FMT_L
),
11002 R6_OPC_CMP_SAF_D
= FOP(8, FMT_L
),
11003 R6_OPC_CMP_SUN_D
= FOP(9, FMT_L
),
11004 R6_OPC_CMP_SEQ_D
= FOP(10, FMT_L
),
11005 R6_OPC_CMP_SEUQ_D
= FOP(11, FMT_L
),
11006 R6_OPC_CMP_SLT_D
= FOP(12, FMT_L
),
11007 R6_OPC_CMP_SULT_D
= FOP(13, FMT_L
),
11008 R6_OPC_CMP_SLE_D
= FOP(14, FMT_L
),
11009 R6_OPC_CMP_SULE_D
= FOP(15, FMT_L
),
11010 R6_OPC_CMP_OR_D
= FOP(17, FMT_L
),
11011 R6_OPC_CMP_UNE_D
= FOP(18, FMT_L
),
11012 R6_OPC_CMP_NE_D
= FOP(19, FMT_L
),
11013 R6_OPC_CMP_SOR_D
= FOP(25, FMT_L
),
11014 R6_OPC_CMP_SUNE_D
= FOP(26, FMT_L
),
11015 R6_OPC_CMP_SNE_D
= FOP(27, FMT_L
),
11018 static void gen_cp1(DisasContext
*ctx
, uint32_t opc
, int rt
, int fs
)
11020 TCGv t0
= tcg_temp_new();
11025 TCGv_i32 fp0
= tcg_temp_new_i32();
11027 gen_load_fpr32(ctx
, fp0
, fs
);
11028 tcg_gen_ext_i32_tl(t0
, fp0
);
11029 tcg_temp_free_i32(fp0
);
11031 gen_store_gpr(t0
, rt
);
11034 gen_load_gpr(t0
, rt
);
11036 TCGv_i32 fp0
= tcg_temp_new_i32();
11038 tcg_gen_trunc_tl_i32(fp0
, t0
);
11039 gen_store_fpr32(ctx
, fp0
, fs
);
11040 tcg_temp_free_i32(fp0
);
11044 gen_helper_1e0i(cfc1
, t0
, fs
);
11045 gen_store_gpr(t0
, rt
);
11048 gen_load_gpr(t0
, rt
);
11049 save_cpu_state(ctx
, 0);
11051 TCGv_i32 fs_tmp
= tcg_const_i32(fs
);
11053 gen_helper_0e2i(ctc1
, t0
, fs_tmp
, rt
);
11054 tcg_temp_free_i32(fs_tmp
);
11056 /* Stop translation as we may have changed hflags */
11057 ctx
->base
.is_jmp
= DISAS_STOP
;
11059 #if defined(TARGET_MIPS64)
11061 gen_load_fpr64(ctx
, t0
, fs
);
11062 gen_store_gpr(t0
, rt
);
11065 gen_load_gpr(t0
, rt
);
11066 gen_store_fpr64(ctx
, t0
, fs
);
11071 TCGv_i32 fp0
= tcg_temp_new_i32();
11073 gen_load_fpr32h(ctx
, fp0
, fs
);
11074 tcg_gen_ext_i32_tl(t0
, fp0
);
11075 tcg_temp_free_i32(fp0
);
11077 gen_store_gpr(t0
, rt
);
11080 gen_load_gpr(t0
, rt
);
11082 TCGv_i32 fp0
= tcg_temp_new_i32();
11084 tcg_gen_trunc_tl_i32(fp0
, t0
);
11085 gen_store_fpr32h(ctx
, fp0
, fs
);
11086 tcg_temp_free_i32(fp0
);
11090 MIPS_INVAL("cp1 move");
11091 gen_reserved_instruction(ctx
);
11099 static void gen_movci(DisasContext
*ctx
, int rd
, int rs
, int cc
, int tf
)
11106 /* Treat as NOP. */
11111 cond
= TCG_COND_EQ
;
11113 cond
= TCG_COND_NE
;
11116 l1
= gen_new_label();
11117 t0
= tcg_temp_new_i32();
11118 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
11119 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
11120 tcg_temp_free_i32(t0
);
11122 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
11124 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
11129 static inline void gen_movcf_s(DisasContext
*ctx
, int fs
, int fd
, int cc
,
11133 TCGv_i32 t0
= tcg_temp_new_i32();
11134 TCGLabel
*l1
= gen_new_label();
11137 cond
= TCG_COND_EQ
;
11139 cond
= TCG_COND_NE
;
11142 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
11143 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
11144 gen_load_fpr32(ctx
, t0
, fs
);
11145 gen_store_fpr32(ctx
, t0
, fd
);
11147 tcg_temp_free_i32(t0
);
11150 static inline void gen_movcf_d(DisasContext
*ctx
, int fs
, int fd
, int cc
,
11154 TCGv_i32 t0
= tcg_temp_new_i32();
11156 TCGLabel
*l1
= gen_new_label();
11159 cond
= TCG_COND_EQ
;
11161 cond
= TCG_COND_NE
;
11164 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
11165 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
11166 tcg_temp_free_i32(t0
);
11167 fp0
= tcg_temp_new_i64();
11168 gen_load_fpr64(ctx
, fp0
, fs
);
11169 gen_store_fpr64(ctx
, fp0
, fd
);
11170 tcg_temp_free_i64(fp0
);
11174 static inline void gen_movcf_ps(DisasContext
*ctx
, int fs
, int fd
,
11178 TCGv_i32 t0
= tcg_temp_new_i32();
11179 TCGLabel
*l1
= gen_new_label();
11180 TCGLabel
*l2
= gen_new_label();
11183 cond
= TCG_COND_EQ
;
11185 cond
= TCG_COND_NE
;
11188 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
11189 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
11190 gen_load_fpr32(ctx
, t0
, fs
);
11191 gen_store_fpr32(ctx
, t0
, fd
);
11194 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
+ 1));
11195 tcg_gen_brcondi_i32(cond
, t0
, 0, l2
);
11196 gen_load_fpr32h(ctx
, t0
, fs
);
11197 gen_store_fpr32h(ctx
, t0
, fd
);
11198 tcg_temp_free_i32(t0
);
11202 static void gen_sel_s(DisasContext
*ctx
, enum fopcode op1
, int fd
, int ft
,
11205 TCGv_i32 t1
= tcg_const_i32(0);
11206 TCGv_i32 fp0
= tcg_temp_new_i32();
11207 TCGv_i32 fp1
= tcg_temp_new_i32();
11208 TCGv_i32 fp2
= tcg_temp_new_i32();
11209 gen_load_fpr32(ctx
, fp0
, fd
);
11210 gen_load_fpr32(ctx
, fp1
, ft
);
11211 gen_load_fpr32(ctx
, fp2
, fs
);
11215 tcg_gen_andi_i32(fp0
, fp0
, 1);
11216 tcg_gen_movcond_i32(TCG_COND_NE
, fp0
, fp0
, t1
, fp1
, fp2
);
11219 tcg_gen_andi_i32(fp1
, fp1
, 1);
11220 tcg_gen_movcond_i32(TCG_COND_EQ
, fp0
, fp1
, t1
, fp2
, t1
);
11223 tcg_gen_andi_i32(fp1
, fp1
, 1);
11224 tcg_gen_movcond_i32(TCG_COND_NE
, fp0
, fp1
, t1
, fp2
, t1
);
11227 MIPS_INVAL("gen_sel_s");
11228 gen_reserved_instruction(ctx
);
11232 gen_store_fpr32(ctx
, fp0
, fd
);
11233 tcg_temp_free_i32(fp2
);
11234 tcg_temp_free_i32(fp1
);
11235 tcg_temp_free_i32(fp0
);
11236 tcg_temp_free_i32(t1
);
11239 static void gen_sel_d(DisasContext
*ctx
, enum fopcode op1
, int fd
, int ft
,
11242 TCGv_i64 t1
= tcg_const_i64(0);
11243 TCGv_i64 fp0
= tcg_temp_new_i64();
11244 TCGv_i64 fp1
= tcg_temp_new_i64();
11245 TCGv_i64 fp2
= tcg_temp_new_i64();
11246 gen_load_fpr64(ctx
, fp0
, fd
);
11247 gen_load_fpr64(ctx
, fp1
, ft
);
11248 gen_load_fpr64(ctx
, fp2
, fs
);
11252 tcg_gen_andi_i64(fp0
, fp0
, 1);
11253 tcg_gen_movcond_i64(TCG_COND_NE
, fp0
, fp0
, t1
, fp1
, fp2
);
11256 tcg_gen_andi_i64(fp1
, fp1
, 1);
11257 tcg_gen_movcond_i64(TCG_COND_EQ
, fp0
, fp1
, t1
, fp2
, t1
);
11260 tcg_gen_andi_i64(fp1
, fp1
, 1);
11261 tcg_gen_movcond_i64(TCG_COND_NE
, fp0
, fp1
, t1
, fp2
, t1
);
11264 MIPS_INVAL("gen_sel_d");
11265 gen_reserved_instruction(ctx
);
11269 gen_store_fpr64(ctx
, fp0
, fd
);
11270 tcg_temp_free_i64(fp2
);
11271 tcg_temp_free_i64(fp1
);
11272 tcg_temp_free_i64(fp0
);
11273 tcg_temp_free_i64(t1
);
11276 static void gen_farith(DisasContext
*ctx
, enum fopcode op1
,
11277 int ft
, int fs
, int fd
, int cc
)
11279 uint32_t func
= ctx
->opcode
& 0x3f;
11283 TCGv_i32 fp0
= tcg_temp_new_i32();
11284 TCGv_i32 fp1
= tcg_temp_new_i32();
11286 gen_load_fpr32(ctx
, fp0
, fs
);
11287 gen_load_fpr32(ctx
, fp1
, ft
);
11288 gen_helper_float_add_s(fp0
, cpu_env
, fp0
, fp1
);
11289 tcg_temp_free_i32(fp1
);
11290 gen_store_fpr32(ctx
, fp0
, fd
);
11291 tcg_temp_free_i32(fp0
);
11296 TCGv_i32 fp0
= tcg_temp_new_i32();
11297 TCGv_i32 fp1
= tcg_temp_new_i32();
11299 gen_load_fpr32(ctx
, fp0
, fs
);
11300 gen_load_fpr32(ctx
, fp1
, ft
);
11301 gen_helper_float_sub_s(fp0
, cpu_env
, fp0
, fp1
);
11302 tcg_temp_free_i32(fp1
);
11303 gen_store_fpr32(ctx
, fp0
, fd
);
11304 tcg_temp_free_i32(fp0
);
11309 TCGv_i32 fp0
= tcg_temp_new_i32();
11310 TCGv_i32 fp1
= tcg_temp_new_i32();
11312 gen_load_fpr32(ctx
, fp0
, fs
);
11313 gen_load_fpr32(ctx
, fp1
, ft
);
11314 gen_helper_float_mul_s(fp0
, cpu_env
, fp0
, fp1
);
11315 tcg_temp_free_i32(fp1
);
11316 gen_store_fpr32(ctx
, fp0
, fd
);
11317 tcg_temp_free_i32(fp0
);
11322 TCGv_i32 fp0
= tcg_temp_new_i32();
11323 TCGv_i32 fp1
= tcg_temp_new_i32();
11325 gen_load_fpr32(ctx
, fp0
, fs
);
11326 gen_load_fpr32(ctx
, fp1
, ft
);
11327 gen_helper_float_div_s(fp0
, cpu_env
, fp0
, fp1
);
11328 tcg_temp_free_i32(fp1
);
11329 gen_store_fpr32(ctx
, fp0
, fd
);
11330 tcg_temp_free_i32(fp0
);
11335 TCGv_i32 fp0
= tcg_temp_new_i32();
11337 gen_load_fpr32(ctx
, fp0
, fs
);
11338 gen_helper_float_sqrt_s(fp0
, cpu_env
, fp0
);
11339 gen_store_fpr32(ctx
, fp0
, fd
);
11340 tcg_temp_free_i32(fp0
);
11345 TCGv_i32 fp0
= tcg_temp_new_i32();
11347 gen_load_fpr32(ctx
, fp0
, fs
);
11348 if (ctx
->abs2008
) {
11349 tcg_gen_andi_i32(fp0
, fp0
, 0x7fffffffUL
);
11351 gen_helper_float_abs_s(fp0
, fp0
);
11353 gen_store_fpr32(ctx
, fp0
, fd
);
11354 tcg_temp_free_i32(fp0
);
11359 TCGv_i32 fp0
= tcg_temp_new_i32();
11361 gen_load_fpr32(ctx
, fp0
, fs
);
11362 gen_store_fpr32(ctx
, fp0
, fd
);
11363 tcg_temp_free_i32(fp0
);
11368 TCGv_i32 fp0
= tcg_temp_new_i32();
11370 gen_load_fpr32(ctx
, fp0
, fs
);
11371 if (ctx
->abs2008
) {
11372 tcg_gen_xori_i32(fp0
, fp0
, 1UL << 31);
11374 gen_helper_float_chs_s(fp0
, fp0
);
11376 gen_store_fpr32(ctx
, fp0
, fd
);
11377 tcg_temp_free_i32(fp0
);
11380 case OPC_ROUND_L_S
:
11381 check_cp1_64bitmode(ctx
);
11383 TCGv_i32 fp32
= tcg_temp_new_i32();
11384 TCGv_i64 fp64
= tcg_temp_new_i64();
11386 gen_load_fpr32(ctx
, fp32
, fs
);
11387 if (ctx
->nan2008
) {
11388 gen_helper_float_round_2008_l_s(fp64
, cpu_env
, fp32
);
11390 gen_helper_float_round_l_s(fp64
, cpu_env
, fp32
);
11392 tcg_temp_free_i32(fp32
);
11393 gen_store_fpr64(ctx
, fp64
, fd
);
11394 tcg_temp_free_i64(fp64
);
11397 case OPC_TRUNC_L_S
:
11398 check_cp1_64bitmode(ctx
);
11400 TCGv_i32 fp32
= tcg_temp_new_i32();
11401 TCGv_i64 fp64
= tcg_temp_new_i64();
11403 gen_load_fpr32(ctx
, fp32
, fs
);
11404 if (ctx
->nan2008
) {
11405 gen_helper_float_trunc_2008_l_s(fp64
, cpu_env
, fp32
);
11407 gen_helper_float_trunc_l_s(fp64
, cpu_env
, fp32
);
11409 tcg_temp_free_i32(fp32
);
11410 gen_store_fpr64(ctx
, fp64
, fd
);
11411 tcg_temp_free_i64(fp64
);
11415 check_cp1_64bitmode(ctx
);
11417 TCGv_i32 fp32
= tcg_temp_new_i32();
11418 TCGv_i64 fp64
= tcg_temp_new_i64();
11420 gen_load_fpr32(ctx
, fp32
, fs
);
11421 if (ctx
->nan2008
) {
11422 gen_helper_float_ceil_2008_l_s(fp64
, cpu_env
, fp32
);
11424 gen_helper_float_ceil_l_s(fp64
, cpu_env
, fp32
);
11426 tcg_temp_free_i32(fp32
);
11427 gen_store_fpr64(ctx
, fp64
, fd
);
11428 tcg_temp_free_i64(fp64
);
11431 case OPC_FLOOR_L_S
:
11432 check_cp1_64bitmode(ctx
);
11434 TCGv_i32 fp32
= tcg_temp_new_i32();
11435 TCGv_i64 fp64
= tcg_temp_new_i64();
11437 gen_load_fpr32(ctx
, fp32
, fs
);
11438 if (ctx
->nan2008
) {
11439 gen_helper_float_floor_2008_l_s(fp64
, cpu_env
, fp32
);
11441 gen_helper_float_floor_l_s(fp64
, cpu_env
, fp32
);
11443 tcg_temp_free_i32(fp32
);
11444 gen_store_fpr64(ctx
, fp64
, fd
);
11445 tcg_temp_free_i64(fp64
);
11448 case OPC_ROUND_W_S
:
11450 TCGv_i32 fp0
= tcg_temp_new_i32();
11452 gen_load_fpr32(ctx
, fp0
, fs
);
11453 if (ctx
->nan2008
) {
11454 gen_helper_float_round_2008_w_s(fp0
, cpu_env
, fp0
);
11456 gen_helper_float_round_w_s(fp0
, cpu_env
, fp0
);
11458 gen_store_fpr32(ctx
, fp0
, fd
);
11459 tcg_temp_free_i32(fp0
);
11462 case OPC_TRUNC_W_S
:
11464 TCGv_i32 fp0
= tcg_temp_new_i32();
11466 gen_load_fpr32(ctx
, fp0
, fs
);
11467 if (ctx
->nan2008
) {
11468 gen_helper_float_trunc_2008_w_s(fp0
, cpu_env
, fp0
);
11470 gen_helper_float_trunc_w_s(fp0
, cpu_env
, fp0
);
11472 gen_store_fpr32(ctx
, fp0
, fd
);
11473 tcg_temp_free_i32(fp0
);
11478 TCGv_i32 fp0
= tcg_temp_new_i32();
11480 gen_load_fpr32(ctx
, fp0
, fs
);
11481 if (ctx
->nan2008
) {
11482 gen_helper_float_ceil_2008_w_s(fp0
, cpu_env
, fp0
);
11484 gen_helper_float_ceil_w_s(fp0
, cpu_env
, fp0
);
11486 gen_store_fpr32(ctx
, fp0
, fd
);
11487 tcg_temp_free_i32(fp0
);
11490 case OPC_FLOOR_W_S
:
11492 TCGv_i32 fp0
= tcg_temp_new_i32();
11494 gen_load_fpr32(ctx
, fp0
, fs
);
11495 if (ctx
->nan2008
) {
11496 gen_helper_float_floor_2008_w_s(fp0
, cpu_env
, fp0
);
11498 gen_helper_float_floor_w_s(fp0
, cpu_env
, fp0
);
11500 gen_store_fpr32(ctx
, fp0
, fd
);
11501 tcg_temp_free_i32(fp0
);
11505 check_insn(ctx
, ISA_MIPS_R6
);
11506 gen_sel_s(ctx
, op1
, fd
, ft
, fs
);
11509 check_insn(ctx
, ISA_MIPS_R6
);
11510 gen_sel_s(ctx
, op1
, fd
, ft
, fs
);
11513 check_insn(ctx
, ISA_MIPS_R6
);
11514 gen_sel_s(ctx
, op1
, fd
, ft
, fs
);
11517 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
11518 gen_movcf_s(ctx
, fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
11521 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
11523 TCGLabel
*l1
= gen_new_label();
11527 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
11529 fp0
= tcg_temp_new_i32();
11530 gen_load_fpr32(ctx
, fp0
, fs
);
11531 gen_store_fpr32(ctx
, fp0
, fd
);
11532 tcg_temp_free_i32(fp0
);
11537 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
11539 TCGLabel
*l1
= gen_new_label();
11543 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
11544 fp0
= tcg_temp_new_i32();
11545 gen_load_fpr32(ctx
, fp0
, fs
);
11546 gen_store_fpr32(ctx
, fp0
, fd
);
11547 tcg_temp_free_i32(fp0
);
11554 TCGv_i32 fp0
= tcg_temp_new_i32();
11556 gen_load_fpr32(ctx
, fp0
, fs
);
11557 gen_helper_float_recip_s(fp0
, cpu_env
, fp0
);
11558 gen_store_fpr32(ctx
, fp0
, fd
);
11559 tcg_temp_free_i32(fp0
);
11564 TCGv_i32 fp0
= tcg_temp_new_i32();
11566 gen_load_fpr32(ctx
, fp0
, fs
);
11567 gen_helper_float_rsqrt_s(fp0
, cpu_env
, fp0
);
11568 gen_store_fpr32(ctx
, fp0
, fd
);
11569 tcg_temp_free_i32(fp0
);
11573 check_insn(ctx
, ISA_MIPS_R6
);
11575 TCGv_i32 fp0
= tcg_temp_new_i32();
11576 TCGv_i32 fp1
= tcg_temp_new_i32();
11577 TCGv_i32 fp2
= tcg_temp_new_i32();
11578 gen_load_fpr32(ctx
, fp0
, fs
);
11579 gen_load_fpr32(ctx
, fp1
, ft
);
11580 gen_load_fpr32(ctx
, fp2
, fd
);
11581 gen_helper_float_maddf_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
11582 gen_store_fpr32(ctx
, fp2
, fd
);
11583 tcg_temp_free_i32(fp2
);
11584 tcg_temp_free_i32(fp1
);
11585 tcg_temp_free_i32(fp0
);
11589 check_insn(ctx
, ISA_MIPS_R6
);
11591 TCGv_i32 fp0
= tcg_temp_new_i32();
11592 TCGv_i32 fp1
= tcg_temp_new_i32();
11593 TCGv_i32 fp2
= tcg_temp_new_i32();
11594 gen_load_fpr32(ctx
, fp0
, fs
);
11595 gen_load_fpr32(ctx
, fp1
, ft
);
11596 gen_load_fpr32(ctx
, fp2
, fd
);
11597 gen_helper_float_msubf_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
11598 gen_store_fpr32(ctx
, fp2
, fd
);
11599 tcg_temp_free_i32(fp2
);
11600 tcg_temp_free_i32(fp1
);
11601 tcg_temp_free_i32(fp0
);
11605 check_insn(ctx
, ISA_MIPS_R6
);
11607 TCGv_i32 fp0
= tcg_temp_new_i32();
11608 gen_load_fpr32(ctx
, fp0
, fs
);
11609 gen_helper_float_rint_s(fp0
, cpu_env
, fp0
);
11610 gen_store_fpr32(ctx
, fp0
, fd
);
11611 tcg_temp_free_i32(fp0
);
11615 check_insn(ctx
, ISA_MIPS_R6
);
11617 TCGv_i32 fp0
= tcg_temp_new_i32();
11618 gen_load_fpr32(ctx
, fp0
, fs
);
11619 gen_helper_float_class_s(fp0
, cpu_env
, fp0
);
11620 gen_store_fpr32(ctx
, fp0
, fd
);
11621 tcg_temp_free_i32(fp0
);
11624 case OPC_MIN_S
: /* OPC_RECIP2_S */
11625 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
11627 TCGv_i32 fp0
= tcg_temp_new_i32();
11628 TCGv_i32 fp1
= tcg_temp_new_i32();
11629 TCGv_i32 fp2
= tcg_temp_new_i32();
11630 gen_load_fpr32(ctx
, fp0
, fs
);
11631 gen_load_fpr32(ctx
, fp1
, ft
);
11632 gen_helper_float_min_s(fp2
, cpu_env
, fp0
, fp1
);
11633 gen_store_fpr32(ctx
, fp2
, fd
);
11634 tcg_temp_free_i32(fp2
);
11635 tcg_temp_free_i32(fp1
);
11636 tcg_temp_free_i32(fp0
);
11639 check_cp1_64bitmode(ctx
);
11641 TCGv_i32 fp0
= tcg_temp_new_i32();
11642 TCGv_i32 fp1
= tcg_temp_new_i32();
11644 gen_load_fpr32(ctx
, fp0
, fs
);
11645 gen_load_fpr32(ctx
, fp1
, ft
);
11646 gen_helper_float_recip2_s(fp0
, cpu_env
, fp0
, fp1
);
11647 tcg_temp_free_i32(fp1
);
11648 gen_store_fpr32(ctx
, fp0
, fd
);
11649 tcg_temp_free_i32(fp0
);
11653 case OPC_MINA_S
: /* OPC_RECIP1_S */
11654 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
11656 TCGv_i32 fp0
= tcg_temp_new_i32();
11657 TCGv_i32 fp1
= tcg_temp_new_i32();
11658 TCGv_i32 fp2
= tcg_temp_new_i32();
11659 gen_load_fpr32(ctx
, fp0
, fs
);
11660 gen_load_fpr32(ctx
, fp1
, ft
);
11661 gen_helper_float_mina_s(fp2
, cpu_env
, fp0
, fp1
);
11662 gen_store_fpr32(ctx
, fp2
, fd
);
11663 tcg_temp_free_i32(fp2
);
11664 tcg_temp_free_i32(fp1
);
11665 tcg_temp_free_i32(fp0
);
11668 check_cp1_64bitmode(ctx
);
11670 TCGv_i32 fp0
= tcg_temp_new_i32();
11672 gen_load_fpr32(ctx
, fp0
, fs
);
11673 gen_helper_float_recip1_s(fp0
, cpu_env
, fp0
);
11674 gen_store_fpr32(ctx
, fp0
, fd
);
11675 tcg_temp_free_i32(fp0
);
11679 case OPC_MAX_S
: /* OPC_RSQRT1_S */
11680 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
11682 TCGv_i32 fp0
= tcg_temp_new_i32();
11683 TCGv_i32 fp1
= tcg_temp_new_i32();
11684 gen_load_fpr32(ctx
, fp0
, fs
);
11685 gen_load_fpr32(ctx
, fp1
, ft
);
11686 gen_helper_float_max_s(fp1
, cpu_env
, fp0
, fp1
);
11687 gen_store_fpr32(ctx
, fp1
, fd
);
11688 tcg_temp_free_i32(fp1
);
11689 tcg_temp_free_i32(fp0
);
11692 check_cp1_64bitmode(ctx
);
11694 TCGv_i32 fp0
= tcg_temp_new_i32();
11696 gen_load_fpr32(ctx
, fp0
, fs
);
11697 gen_helper_float_rsqrt1_s(fp0
, cpu_env
, fp0
);
11698 gen_store_fpr32(ctx
, fp0
, fd
);
11699 tcg_temp_free_i32(fp0
);
11703 case OPC_MAXA_S
: /* OPC_RSQRT2_S */
11704 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
11706 TCGv_i32 fp0
= tcg_temp_new_i32();
11707 TCGv_i32 fp1
= tcg_temp_new_i32();
11708 gen_load_fpr32(ctx
, fp0
, fs
);
11709 gen_load_fpr32(ctx
, fp1
, ft
);
11710 gen_helper_float_maxa_s(fp1
, cpu_env
, fp0
, fp1
);
11711 gen_store_fpr32(ctx
, fp1
, fd
);
11712 tcg_temp_free_i32(fp1
);
11713 tcg_temp_free_i32(fp0
);
11716 check_cp1_64bitmode(ctx
);
11718 TCGv_i32 fp0
= tcg_temp_new_i32();
11719 TCGv_i32 fp1
= tcg_temp_new_i32();
11721 gen_load_fpr32(ctx
, fp0
, fs
);
11722 gen_load_fpr32(ctx
, fp1
, ft
);
11723 gen_helper_float_rsqrt2_s(fp0
, cpu_env
, fp0
, fp1
);
11724 tcg_temp_free_i32(fp1
);
11725 gen_store_fpr32(ctx
, fp0
, fd
);
11726 tcg_temp_free_i32(fp0
);
11731 check_cp1_registers(ctx
, fd
);
11733 TCGv_i32 fp32
= tcg_temp_new_i32();
11734 TCGv_i64 fp64
= tcg_temp_new_i64();
11736 gen_load_fpr32(ctx
, fp32
, fs
);
11737 gen_helper_float_cvtd_s(fp64
, cpu_env
, fp32
);
11738 tcg_temp_free_i32(fp32
);
11739 gen_store_fpr64(ctx
, fp64
, fd
);
11740 tcg_temp_free_i64(fp64
);
11745 TCGv_i32 fp0
= tcg_temp_new_i32();
11747 gen_load_fpr32(ctx
, fp0
, fs
);
11748 if (ctx
->nan2008
) {
11749 gen_helper_float_cvt_2008_w_s(fp0
, cpu_env
, fp0
);
11751 gen_helper_float_cvt_w_s(fp0
, cpu_env
, fp0
);
11753 gen_store_fpr32(ctx
, fp0
, fd
);
11754 tcg_temp_free_i32(fp0
);
11758 check_cp1_64bitmode(ctx
);
11760 TCGv_i32 fp32
= tcg_temp_new_i32();
11761 TCGv_i64 fp64
= tcg_temp_new_i64();
11763 gen_load_fpr32(ctx
, fp32
, fs
);
11764 if (ctx
->nan2008
) {
11765 gen_helper_float_cvt_2008_l_s(fp64
, cpu_env
, fp32
);
11767 gen_helper_float_cvt_l_s(fp64
, cpu_env
, fp32
);
11769 tcg_temp_free_i32(fp32
);
11770 gen_store_fpr64(ctx
, fp64
, fd
);
11771 tcg_temp_free_i64(fp64
);
11777 TCGv_i64 fp64
= tcg_temp_new_i64();
11778 TCGv_i32 fp32_0
= tcg_temp_new_i32();
11779 TCGv_i32 fp32_1
= tcg_temp_new_i32();
11781 gen_load_fpr32(ctx
, fp32_0
, fs
);
11782 gen_load_fpr32(ctx
, fp32_1
, ft
);
11783 tcg_gen_concat_i32_i64(fp64
, fp32_1
, fp32_0
);
11784 tcg_temp_free_i32(fp32_1
);
11785 tcg_temp_free_i32(fp32_0
);
11786 gen_store_fpr64(ctx
, fp64
, fd
);
11787 tcg_temp_free_i64(fp64
);
11793 case OPC_CMP_UEQ_S
:
11794 case OPC_CMP_OLT_S
:
11795 case OPC_CMP_ULT_S
:
11796 case OPC_CMP_OLE_S
:
11797 case OPC_CMP_ULE_S
:
11799 case OPC_CMP_NGLE_S
:
11800 case OPC_CMP_SEQ_S
:
11801 case OPC_CMP_NGL_S
:
11803 case OPC_CMP_NGE_S
:
11805 case OPC_CMP_NGT_S
:
11806 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
11807 if (ctx
->opcode
& (1 << 6)) {
11808 gen_cmpabs_s(ctx
, func
- 48, ft
, fs
, cc
);
11810 gen_cmp_s(ctx
, func
- 48, ft
, fs
, cc
);
11814 check_cp1_registers(ctx
, fs
| ft
| fd
);
11816 TCGv_i64 fp0
= tcg_temp_new_i64();
11817 TCGv_i64 fp1
= tcg_temp_new_i64();
11819 gen_load_fpr64(ctx
, fp0
, fs
);
11820 gen_load_fpr64(ctx
, fp1
, ft
);
11821 gen_helper_float_add_d(fp0
, cpu_env
, fp0
, fp1
);
11822 tcg_temp_free_i64(fp1
);
11823 gen_store_fpr64(ctx
, fp0
, fd
);
11824 tcg_temp_free_i64(fp0
);
11828 check_cp1_registers(ctx
, fs
| ft
| fd
);
11830 TCGv_i64 fp0
= tcg_temp_new_i64();
11831 TCGv_i64 fp1
= tcg_temp_new_i64();
11833 gen_load_fpr64(ctx
, fp0
, fs
);
11834 gen_load_fpr64(ctx
, fp1
, ft
);
11835 gen_helper_float_sub_d(fp0
, cpu_env
, fp0
, fp1
);
11836 tcg_temp_free_i64(fp1
);
11837 gen_store_fpr64(ctx
, fp0
, fd
);
11838 tcg_temp_free_i64(fp0
);
11842 check_cp1_registers(ctx
, fs
| ft
| fd
);
11844 TCGv_i64 fp0
= tcg_temp_new_i64();
11845 TCGv_i64 fp1
= tcg_temp_new_i64();
11847 gen_load_fpr64(ctx
, fp0
, fs
);
11848 gen_load_fpr64(ctx
, fp1
, ft
);
11849 gen_helper_float_mul_d(fp0
, cpu_env
, fp0
, fp1
);
11850 tcg_temp_free_i64(fp1
);
11851 gen_store_fpr64(ctx
, fp0
, fd
);
11852 tcg_temp_free_i64(fp0
);
11856 check_cp1_registers(ctx
, fs
| ft
| fd
);
11858 TCGv_i64 fp0
= tcg_temp_new_i64();
11859 TCGv_i64 fp1
= tcg_temp_new_i64();
11861 gen_load_fpr64(ctx
, fp0
, fs
);
11862 gen_load_fpr64(ctx
, fp1
, ft
);
11863 gen_helper_float_div_d(fp0
, cpu_env
, fp0
, fp1
);
11864 tcg_temp_free_i64(fp1
);
11865 gen_store_fpr64(ctx
, fp0
, fd
);
11866 tcg_temp_free_i64(fp0
);
11870 check_cp1_registers(ctx
, fs
| fd
);
11872 TCGv_i64 fp0
= tcg_temp_new_i64();
11874 gen_load_fpr64(ctx
, fp0
, fs
);
11875 gen_helper_float_sqrt_d(fp0
, cpu_env
, fp0
);
11876 gen_store_fpr64(ctx
, fp0
, fd
);
11877 tcg_temp_free_i64(fp0
);
11881 check_cp1_registers(ctx
, fs
| fd
);
11883 TCGv_i64 fp0
= tcg_temp_new_i64();
11885 gen_load_fpr64(ctx
, fp0
, fs
);
11886 if (ctx
->abs2008
) {
11887 tcg_gen_andi_i64(fp0
, fp0
, 0x7fffffffffffffffULL
);
11889 gen_helper_float_abs_d(fp0
, fp0
);
11891 gen_store_fpr64(ctx
, fp0
, fd
);
11892 tcg_temp_free_i64(fp0
);
11896 check_cp1_registers(ctx
, fs
| fd
);
11898 TCGv_i64 fp0
= tcg_temp_new_i64();
11900 gen_load_fpr64(ctx
, fp0
, fs
);
11901 gen_store_fpr64(ctx
, fp0
, fd
);
11902 tcg_temp_free_i64(fp0
);
11906 check_cp1_registers(ctx
, fs
| fd
);
11908 TCGv_i64 fp0
= tcg_temp_new_i64();
11910 gen_load_fpr64(ctx
, fp0
, fs
);
11911 if (ctx
->abs2008
) {
11912 tcg_gen_xori_i64(fp0
, fp0
, 1ULL << 63);
11914 gen_helper_float_chs_d(fp0
, fp0
);
11916 gen_store_fpr64(ctx
, fp0
, fd
);
11917 tcg_temp_free_i64(fp0
);
11920 case OPC_ROUND_L_D
:
11921 check_cp1_64bitmode(ctx
);
11923 TCGv_i64 fp0
= tcg_temp_new_i64();
11925 gen_load_fpr64(ctx
, fp0
, fs
);
11926 if (ctx
->nan2008
) {
11927 gen_helper_float_round_2008_l_d(fp0
, cpu_env
, fp0
);
11929 gen_helper_float_round_l_d(fp0
, cpu_env
, fp0
);
11931 gen_store_fpr64(ctx
, fp0
, fd
);
11932 tcg_temp_free_i64(fp0
);
11935 case OPC_TRUNC_L_D
:
11936 check_cp1_64bitmode(ctx
);
11938 TCGv_i64 fp0
= tcg_temp_new_i64();
11940 gen_load_fpr64(ctx
, fp0
, fs
);
11941 if (ctx
->nan2008
) {
11942 gen_helper_float_trunc_2008_l_d(fp0
, cpu_env
, fp0
);
11944 gen_helper_float_trunc_l_d(fp0
, cpu_env
, fp0
);
11946 gen_store_fpr64(ctx
, fp0
, fd
);
11947 tcg_temp_free_i64(fp0
);
11951 check_cp1_64bitmode(ctx
);
11953 TCGv_i64 fp0
= tcg_temp_new_i64();
11955 gen_load_fpr64(ctx
, fp0
, fs
);
11956 if (ctx
->nan2008
) {
11957 gen_helper_float_ceil_2008_l_d(fp0
, cpu_env
, fp0
);
11959 gen_helper_float_ceil_l_d(fp0
, cpu_env
, fp0
);
11961 gen_store_fpr64(ctx
, fp0
, fd
);
11962 tcg_temp_free_i64(fp0
);
11965 case OPC_FLOOR_L_D
:
11966 check_cp1_64bitmode(ctx
);
11968 TCGv_i64 fp0
= tcg_temp_new_i64();
11970 gen_load_fpr64(ctx
, fp0
, fs
);
11971 if (ctx
->nan2008
) {
11972 gen_helper_float_floor_2008_l_d(fp0
, cpu_env
, fp0
);
11974 gen_helper_float_floor_l_d(fp0
, cpu_env
, fp0
);
11976 gen_store_fpr64(ctx
, fp0
, fd
);
11977 tcg_temp_free_i64(fp0
);
11980 case OPC_ROUND_W_D
:
11981 check_cp1_registers(ctx
, fs
);
11983 TCGv_i32 fp32
= tcg_temp_new_i32();
11984 TCGv_i64 fp64
= tcg_temp_new_i64();
11986 gen_load_fpr64(ctx
, fp64
, fs
);
11987 if (ctx
->nan2008
) {
11988 gen_helper_float_round_2008_w_d(fp32
, cpu_env
, fp64
);
11990 gen_helper_float_round_w_d(fp32
, cpu_env
, fp64
);
11992 tcg_temp_free_i64(fp64
);
11993 gen_store_fpr32(ctx
, fp32
, fd
);
11994 tcg_temp_free_i32(fp32
);
11997 case OPC_TRUNC_W_D
:
11998 check_cp1_registers(ctx
, fs
);
12000 TCGv_i32 fp32
= tcg_temp_new_i32();
12001 TCGv_i64 fp64
= tcg_temp_new_i64();
12003 gen_load_fpr64(ctx
, fp64
, fs
);
12004 if (ctx
->nan2008
) {
12005 gen_helper_float_trunc_2008_w_d(fp32
, cpu_env
, fp64
);
12007 gen_helper_float_trunc_w_d(fp32
, cpu_env
, fp64
);
12009 tcg_temp_free_i64(fp64
);
12010 gen_store_fpr32(ctx
, fp32
, fd
);
12011 tcg_temp_free_i32(fp32
);
12015 check_cp1_registers(ctx
, fs
);
12017 TCGv_i32 fp32
= tcg_temp_new_i32();
12018 TCGv_i64 fp64
= tcg_temp_new_i64();
12020 gen_load_fpr64(ctx
, fp64
, fs
);
12021 if (ctx
->nan2008
) {
12022 gen_helper_float_ceil_2008_w_d(fp32
, cpu_env
, fp64
);
12024 gen_helper_float_ceil_w_d(fp32
, cpu_env
, fp64
);
12026 tcg_temp_free_i64(fp64
);
12027 gen_store_fpr32(ctx
, fp32
, fd
);
12028 tcg_temp_free_i32(fp32
);
12031 case OPC_FLOOR_W_D
:
12032 check_cp1_registers(ctx
, fs
);
12034 TCGv_i32 fp32
= tcg_temp_new_i32();
12035 TCGv_i64 fp64
= tcg_temp_new_i64();
12037 gen_load_fpr64(ctx
, fp64
, fs
);
12038 if (ctx
->nan2008
) {
12039 gen_helper_float_floor_2008_w_d(fp32
, cpu_env
, fp64
);
12041 gen_helper_float_floor_w_d(fp32
, cpu_env
, fp64
);
12043 tcg_temp_free_i64(fp64
);
12044 gen_store_fpr32(ctx
, fp32
, fd
);
12045 tcg_temp_free_i32(fp32
);
12049 check_insn(ctx
, ISA_MIPS_R6
);
12050 gen_sel_d(ctx
, op1
, fd
, ft
, fs
);
12053 check_insn(ctx
, ISA_MIPS_R6
);
12054 gen_sel_d(ctx
, op1
, fd
, ft
, fs
);
12057 check_insn(ctx
, ISA_MIPS_R6
);
12058 gen_sel_d(ctx
, op1
, fd
, ft
, fs
);
12061 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
12062 gen_movcf_d(ctx
, fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
12065 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
12067 TCGLabel
*l1
= gen_new_label();
12071 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
12073 fp0
= tcg_temp_new_i64();
12074 gen_load_fpr64(ctx
, fp0
, fs
);
12075 gen_store_fpr64(ctx
, fp0
, fd
);
12076 tcg_temp_free_i64(fp0
);
12081 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
12083 TCGLabel
*l1
= gen_new_label();
12087 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
12088 fp0
= tcg_temp_new_i64();
12089 gen_load_fpr64(ctx
, fp0
, fs
);
12090 gen_store_fpr64(ctx
, fp0
, fd
);
12091 tcg_temp_free_i64(fp0
);
12097 check_cp1_registers(ctx
, fs
| fd
);
12099 TCGv_i64 fp0
= tcg_temp_new_i64();
12101 gen_load_fpr64(ctx
, fp0
, fs
);
12102 gen_helper_float_recip_d(fp0
, cpu_env
, fp0
);
12103 gen_store_fpr64(ctx
, fp0
, fd
);
12104 tcg_temp_free_i64(fp0
);
12108 check_cp1_registers(ctx
, fs
| fd
);
12110 TCGv_i64 fp0
= tcg_temp_new_i64();
12112 gen_load_fpr64(ctx
, fp0
, fs
);
12113 gen_helper_float_rsqrt_d(fp0
, cpu_env
, fp0
);
12114 gen_store_fpr64(ctx
, fp0
, fd
);
12115 tcg_temp_free_i64(fp0
);
12119 check_insn(ctx
, ISA_MIPS_R6
);
12121 TCGv_i64 fp0
= tcg_temp_new_i64();
12122 TCGv_i64 fp1
= tcg_temp_new_i64();
12123 TCGv_i64 fp2
= tcg_temp_new_i64();
12124 gen_load_fpr64(ctx
, fp0
, fs
);
12125 gen_load_fpr64(ctx
, fp1
, ft
);
12126 gen_load_fpr64(ctx
, fp2
, fd
);
12127 gen_helper_float_maddf_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12128 gen_store_fpr64(ctx
, fp2
, fd
);
12129 tcg_temp_free_i64(fp2
);
12130 tcg_temp_free_i64(fp1
);
12131 tcg_temp_free_i64(fp0
);
12135 check_insn(ctx
, ISA_MIPS_R6
);
12137 TCGv_i64 fp0
= tcg_temp_new_i64();
12138 TCGv_i64 fp1
= tcg_temp_new_i64();
12139 TCGv_i64 fp2
= tcg_temp_new_i64();
12140 gen_load_fpr64(ctx
, fp0
, fs
);
12141 gen_load_fpr64(ctx
, fp1
, ft
);
12142 gen_load_fpr64(ctx
, fp2
, fd
);
12143 gen_helper_float_msubf_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12144 gen_store_fpr64(ctx
, fp2
, fd
);
12145 tcg_temp_free_i64(fp2
);
12146 tcg_temp_free_i64(fp1
);
12147 tcg_temp_free_i64(fp0
);
12151 check_insn(ctx
, ISA_MIPS_R6
);
12153 TCGv_i64 fp0
= tcg_temp_new_i64();
12154 gen_load_fpr64(ctx
, fp0
, fs
);
12155 gen_helper_float_rint_d(fp0
, cpu_env
, fp0
);
12156 gen_store_fpr64(ctx
, fp0
, fd
);
12157 tcg_temp_free_i64(fp0
);
12161 check_insn(ctx
, ISA_MIPS_R6
);
12163 TCGv_i64 fp0
= tcg_temp_new_i64();
12164 gen_load_fpr64(ctx
, fp0
, fs
);
12165 gen_helper_float_class_d(fp0
, cpu_env
, fp0
);
12166 gen_store_fpr64(ctx
, fp0
, fd
);
12167 tcg_temp_free_i64(fp0
);
12170 case OPC_MIN_D
: /* OPC_RECIP2_D */
12171 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
12173 TCGv_i64 fp0
= tcg_temp_new_i64();
12174 TCGv_i64 fp1
= tcg_temp_new_i64();
12175 gen_load_fpr64(ctx
, fp0
, fs
);
12176 gen_load_fpr64(ctx
, fp1
, ft
);
12177 gen_helper_float_min_d(fp1
, cpu_env
, fp0
, fp1
);
12178 gen_store_fpr64(ctx
, fp1
, fd
);
12179 tcg_temp_free_i64(fp1
);
12180 tcg_temp_free_i64(fp0
);
12183 check_cp1_64bitmode(ctx
);
12185 TCGv_i64 fp0
= tcg_temp_new_i64();
12186 TCGv_i64 fp1
= tcg_temp_new_i64();
12188 gen_load_fpr64(ctx
, fp0
, fs
);
12189 gen_load_fpr64(ctx
, fp1
, ft
);
12190 gen_helper_float_recip2_d(fp0
, cpu_env
, fp0
, fp1
);
12191 tcg_temp_free_i64(fp1
);
12192 gen_store_fpr64(ctx
, fp0
, fd
);
12193 tcg_temp_free_i64(fp0
);
12197 case OPC_MINA_D
: /* OPC_RECIP1_D */
12198 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
12200 TCGv_i64 fp0
= tcg_temp_new_i64();
12201 TCGv_i64 fp1
= tcg_temp_new_i64();
12202 gen_load_fpr64(ctx
, fp0
, fs
);
12203 gen_load_fpr64(ctx
, fp1
, ft
);
12204 gen_helper_float_mina_d(fp1
, cpu_env
, fp0
, fp1
);
12205 gen_store_fpr64(ctx
, fp1
, fd
);
12206 tcg_temp_free_i64(fp1
);
12207 tcg_temp_free_i64(fp0
);
12210 check_cp1_64bitmode(ctx
);
12212 TCGv_i64 fp0
= tcg_temp_new_i64();
12214 gen_load_fpr64(ctx
, fp0
, fs
);
12215 gen_helper_float_recip1_d(fp0
, cpu_env
, fp0
);
12216 gen_store_fpr64(ctx
, fp0
, fd
);
12217 tcg_temp_free_i64(fp0
);
12221 case OPC_MAX_D
: /* OPC_RSQRT1_D */
12222 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
12224 TCGv_i64 fp0
= tcg_temp_new_i64();
12225 TCGv_i64 fp1
= tcg_temp_new_i64();
12226 gen_load_fpr64(ctx
, fp0
, fs
);
12227 gen_load_fpr64(ctx
, fp1
, ft
);
12228 gen_helper_float_max_d(fp1
, cpu_env
, fp0
, fp1
);
12229 gen_store_fpr64(ctx
, fp1
, fd
);
12230 tcg_temp_free_i64(fp1
);
12231 tcg_temp_free_i64(fp0
);
12234 check_cp1_64bitmode(ctx
);
12236 TCGv_i64 fp0
= tcg_temp_new_i64();
12238 gen_load_fpr64(ctx
, fp0
, fs
);
12239 gen_helper_float_rsqrt1_d(fp0
, cpu_env
, fp0
);
12240 gen_store_fpr64(ctx
, fp0
, fd
);
12241 tcg_temp_free_i64(fp0
);
12245 case OPC_MAXA_D
: /* OPC_RSQRT2_D */
12246 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
12248 TCGv_i64 fp0
= tcg_temp_new_i64();
12249 TCGv_i64 fp1
= tcg_temp_new_i64();
12250 gen_load_fpr64(ctx
, fp0
, fs
);
12251 gen_load_fpr64(ctx
, fp1
, ft
);
12252 gen_helper_float_maxa_d(fp1
, cpu_env
, fp0
, fp1
);
12253 gen_store_fpr64(ctx
, fp1
, fd
);
12254 tcg_temp_free_i64(fp1
);
12255 tcg_temp_free_i64(fp0
);
12258 check_cp1_64bitmode(ctx
);
12260 TCGv_i64 fp0
= tcg_temp_new_i64();
12261 TCGv_i64 fp1
= tcg_temp_new_i64();
12263 gen_load_fpr64(ctx
, fp0
, fs
);
12264 gen_load_fpr64(ctx
, fp1
, ft
);
12265 gen_helper_float_rsqrt2_d(fp0
, cpu_env
, fp0
, fp1
);
12266 tcg_temp_free_i64(fp1
);
12267 gen_store_fpr64(ctx
, fp0
, fd
);
12268 tcg_temp_free_i64(fp0
);
12275 case OPC_CMP_UEQ_D
:
12276 case OPC_CMP_OLT_D
:
12277 case OPC_CMP_ULT_D
:
12278 case OPC_CMP_OLE_D
:
12279 case OPC_CMP_ULE_D
:
12281 case OPC_CMP_NGLE_D
:
12282 case OPC_CMP_SEQ_D
:
12283 case OPC_CMP_NGL_D
:
12285 case OPC_CMP_NGE_D
:
12287 case OPC_CMP_NGT_D
:
12288 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
12289 if (ctx
->opcode
& (1 << 6)) {
12290 gen_cmpabs_d(ctx
, func
- 48, ft
, fs
, cc
);
12292 gen_cmp_d(ctx
, func
- 48, ft
, fs
, cc
);
12296 check_cp1_registers(ctx
, fs
);
12298 TCGv_i32 fp32
= tcg_temp_new_i32();
12299 TCGv_i64 fp64
= tcg_temp_new_i64();
12301 gen_load_fpr64(ctx
, fp64
, fs
);
12302 gen_helper_float_cvts_d(fp32
, cpu_env
, fp64
);
12303 tcg_temp_free_i64(fp64
);
12304 gen_store_fpr32(ctx
, fp32
, fd
);
12305 tcg_temp_free_i32(fp32
);
12309 check_cp1_registers(ctx
, fs
);
12311 TCGv_i32 fp32
= tcg_temp_new_i32();
12312 TCGv_i64 fp64
= tcg_temp_new_i64();
12314 gen_load_fpr64(ctx
, fp64
, fs
);
12315 if (ctx
->nan2008
) {
12316 gen_helper_float_cvt_2008_w_d(fp32
, cpu_env
, fp64
);
12318 gen_helper_float_cvt_w_d(fp32
, cpu_env
, fp64
);
12320 tcg_temp_free_i64(fp64
);
12321 gen_store_fpr32(ctx
, fp32
, fd
);
12322 tcg_temp_free_i32(fp32
);
12326 check_cp1_64bitmode(ctx
);
12328 TCGv_i64 fp0
= tcg_temp_new_i64();
12330 gen_load_fpr64(ctx
, fp0
, fs
);
12331 if (ctx
->nan2008
) {
12332 gen_helper_float_cvt_2008_l_d(fp0
, cpu_env
, fp0
);
12334 gen_helper_float_cvt_l_d(fp0
, cpu_env
, fp0
);
12336 gen_store_fpr64(ctx
, fp0
, fd
);
12337 tcg_temp_free_i64(fp0
);
12342 TCGv_i32 fp0
= tcg_temp_new_i32();
12344 gen_load_fpr32(ctx
, fp0
, fs
);
12345 gen_helper_float_cvts_w(fp0
, cpu_env
, fp0
);
12346 gen_store_fpr32(ctx
, fp0
, fd
);
12347 tcg_temp_free_i32(fp0
);
12351 check_cp1_registers(ctx
, fd
);
12353 TCGv_i32 fp32
= tcg_temp_new_i32();
12354 TCGv_i64 fp64
= tcg_temp_new_i64();
12356 gen_load_fpr32(ctx
, fp32
, fs
);
12357 gen_helper_float_cvtd_w(fp64
, cpu_env
, fp32
);
12358 tcg_temp_free_i32(fp32
);
12359 gen_store_fpr64(ctx
, fp64
, fd
);
12360 tcg_temp_free_i64(fp64
);
12364 check_cp1_64bitmode(ctx
);
12366 TCGv_i32 fp32
= tcg_temp_new_i32();
12367 TCGv_i64 fp64
= tcg_temp_new_i64();
12369 gen_load_fpr64(ctx
, fp64
, fs
);
12370 gen_helper_float_cvts_l(fp32
, cpu_env
, fp64
);
12371 tcg_temp_free_i64(fp64
);
12372 gen_store_fpr32(ctx
, fp32
, fd
);
12373 tcg_temp_free_i32(fp32
);
12377 check_cp1_64bitmode(ctx
);
12379 TCGv_i64 fp0
= tcg_temp_new_i64();
12381 gen_load_fpr64(ctx
, fp0
, fs
);
12382 gen_helper_float_cvtd_l(fp0
, cpu_env
, fp0
);
12383 gen_store_fpr64(ctx
, fp0
, fd
);
12384 tcg_temp_free_i64(fp0
);
12387 case OPC_CVT_PS_PW
:
12390 TCGv_i64 fp0
= tcg_temp_new_i64();
12392 gen_load_fpr64(ctx
, fp0
, fs
);
12393 gen_helper_float_cvtps_pw(fp0
, cpu_env
, fp0
);
12394 gen_store_fpr64(ctx
, fp0
, fd
);
12395 tcg_temp_free_i64(fp0
);
12401 TCGv_i64 fp0
= tcg_temp_new_i64();
12402 TCGv_i64 fp1
= tcg_temp_new_i64();
12404 gen_load_fpr64(ctx
, fp0
, fs
);
12405 gen_load_fpr64(ctx
, fp1
, ft
);
12406 gen_helper_float_add_ps(fp0
, cpu_env
, fp0
, fp1
);
12407 tcg_temp_free_i64(fp1
);
12408 gen_store_fpr64(ctx
, fp0
, fd
);
12409 tcg_temp_free_i64(fp0
);
12415 TCGv_i64 fp0
= tcg_temp_new_i64();
12416 TCGv_i64 fp1
= tcg_temp_new_i64();
12418 gen_load_fpr64(ctx
, fp0
, fs
);
12419 gen_load_fpr64(ctx
, fp1
, ft
);
12420 gen_helper_float_sub_ps(fp0
, cpu_env
, fp0
, fp1
);
12421 tcg_temp_free_i64(fp1
);
12422 gen_store_fpr64(ctx
, fp0
, fd
);
12423 tcg_temp_free_i64(fp0
);
12429 TCGv_i64 fp0
= tcg_temp_new_i64();
12430 TCGv_i64 fp1
= tcg_temp_new_i64();
12432 gen_load_fpr64(ctx
, fp0
, fs
);
12433 gen_load_fpr64(ctx
, fp1
, ft
);
12434 gen_helper_float_mul_ps(fp0
, cpu_env
, fp0
, fp1
);
12435 tcg_temp_free_i64(fp1
);
12436 gen_store_fpr64(ctx
, fp0
, fd
);
12437 tcg_temp_free_i64(fp0
);
12443 TCGv_i64 fp0
= tcg_temp_new_i64();
12445 gen_load_fpr64(ctx
, fp0
, fs
);
12446 gen_helper_float_abs_ps(fp0
, fp0
);
12447 gen_store_fpr64(ctx
, fp0
, fd
);
12448 tcg_temp_free_i64(fp0
);
12454 TCGv_i64 fp0
= tcg_temp_new_i64();
12456 gen_load_fpr64(ctx
, fp0
, fs
);
12457 gen_store_fpr64(ctx
, fp0
, fd
);
12458 tcg_temp_free_i64(fp0
);
12464 TCGv_i64 fp0
= tcg_temp_new_i64();
12466 gen_load_fpr64(ctx
, fp0
, fs
);
12467 gen_helper_float_chs_ps(fp0
, fp0
);
12468 gen_store_fpr64(ctx
, fp0
, fd
);
12469 tcg_temp_free_i64(fp0
);
12474 gen_movcf_ps(ctx
, fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
12479 TCGLabel
*l1
= gen_new_label();
12483 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
12485 fp0
= tcg_temp_new_i64();
12486 gen_load_fpr64(ctx
, fp0
, fs
);
12487 gen_store_fpr64(ctx
, fp0
, fd
);
12488 tcg_temp_free_i64(fp0
);
12495 TCGLabel
*l1
= gen_new_label();
12499 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
12500 fp0
= tcg_temp_new_i64();
12501 gen_load_fpr64(ctx
, fp0
, fs
);
12502 gen_store_fpr64(ctx
, fp0
, fd
);
12503 tcg_temp_free_i64(fp0
);
12511 TCGv_i64 fp0
= tcg_temp_new_i64();
12512 TCGv_i64 fp1
= tcg_temp_new_i64();
12514 gen_load_fpr64(ctx
, fp0
, ft
);
12515 gen_load_fpr64(ctx
, fp1
, fs
);
12516 gen_helper_float_addr_ps(fp0
, cpu_env
, fp0
, fp1
);
12517 tcg_temp_free_i64(fp1
);
12518 gen_store_fpr64(ctx
, fp0
, fd
);
12519 tcg_temp_free_i64(fp0
);
12525 TCGv_i64 fp0
= tcg_temp_new_i64();
12526 TCGv_i64 fp1
= tcg_temp_new_i64();
12528 gen_load_fpr64(ctx
, fp0
, ft
);
12529 gen_load_fpr64(ctx
, fp1
, fs
);
12530 gen_helper_float_mulr_ps(fp0
, cpu_env
, fp0
, fp1
);
12531 tcg_temp_free_i64(fp1
);
12532 gen_store_fpr64(ctx
, fp0
, fd
);
12533 tcg_temp_free_i64(fp0
);
12536 case OPC_RECIP2_PS
:
12539 TCGv_i64 fp0
= tcg_temp_new_i64();
12540 TCGv_i64 fp1
= tcg_temp_new_i64();
12542 gen_load_fpr64(ctx
, fp0
, fs
);
12543 gen_load_fpr64(ctx
, fp1
, ft
);
12544 gen_helper_float_recip2_ps(fp0
, cpu_env
, fp0
, fp1
);
12545 tcg_temp_free_i64(fp1
);
12546 gen_store_fpr64(ctx
, fp0
, fd
);
12547 tcg_temp_free_i64(fp0
);
12550 case OPC_RECIP1_PS
:
12553 TCGv_i64 fp0
= tcg_temp_new_i64();
12555 gen_load_fpr64(ctx
, fp0
, fs
);
12556 gen_helper_float_recip1_ps(fp0
, cpu_env
, fp0
);
12557 gen_store_fpr64(ctx
, fp0
, fd
);
12558 tcg_temp_free_i64(fp0
);
12561 case OPC_RSQRT1_PS
:
12564 TCGv_i64 fp0
= tcg_temp_new_i64();
12566 gen_load_fpr64(ctx
, fp0
, fs
);
12567 gen_helper_float_rsqrt1_ps(fp0
, cpu_env
, fp0
);
12568 gen_store_fpr64(ctx
, fp0
, fd
);
12569 tcg_temp_free_i64(fp0
);
12572 case OPC_RSQRT2_PS
:
12575 TCGv_i64 fp0
= tcg_temp_new_i64();
12576 TCGv_i64 fp1
= tcg_temp_new_i64();
12578 gen_load_fpr64(ctx
, fp0
, fs
);
12579 gen_load_fpr64(ctx
, fp1
, ft
);
12580 gen_helper_float_rsqrt2_ps(fp0
, cpu_env
, fp0
, fp1
);
12581 tcg_temp_free_i64(fp1
);
12582 gen_store_fpr64(ctx
, fp0
, fd
);
12583 tcg_temp_free_i64(fp0
);
12587 check_cp1_64bitmode(ctx
);
12589 TCGv_i32 fp0
= tcg_temp_new_i32();
12591 gen_load_fpr32h(ctx
, fp0
, fs
);
12592 gen_helper_float_cvts_pu(fp0
, cpu_env
, fp0
);
12593 gen_store_fpr32(ctx
, fp0
, fd
);
12594 tcg_temp_free_i32(fp0
);
12597 case OPC_CVT_PW_PS
:
12600 TCGv_i64 fp0
= tcg_temp_new_i64();
12602 gen_load_fpr64(ctx
, fp0
, fs
);
12603 gen_helper_float_cvtpw_ps(fp0
, cpu_env
, fp0
);
12604 gen_store_fpr64(ctx
, fp0
, fd
);
12605 tcg_temp_free_i64(fp0
);
12609 check_cp1_64bitmode(ctx
);
12611 TCGv_i32 fp0
= tcg_temp_new_i32();
12613 gen_load_fpr32(ctx
, fp0
, fs
);
12614 gen_helper_float_cvts_pl(fp0
, cpu_env
, fp0
);
12615 gen_store_fpr32(ctx
, fp0
, fd
);
12616 tcg_temp_free_i32(fp0
);
12622 TCGv_i32 fp0
= tcg_temp_new_i32();
12623 TCGv_i32 fp1
= tcg_temp_new_i32();
12625 gen_load_fpr32(ctx
, fp0
, fs
);
12626 gen_load_fpr32(ctx
, fp1
, ft
);
12627 gen_store_fpr32h(ctx
, fp0
, fd
);
12628 gen_store_fpr32(ctx
, fp1
, fd
);
12629 tcg_temp_free_i32(fp0
);
12630 tcg_temp_free_i32(fp1
);
12636 TCGv_i32 fp0
= tcg_temp_new_i32();
12637 TCGv_i32 fp1
= tcg_temp_new_i32();
12639 gen_load_fpr32(ctx
, fp0
, fs
);
12640 gen_load_fpr32h(ctx
, fp1
, ft
);
12641 gen_store_fpr32(ctx
, fp1
, fd
);
12642 gen_store_fpr32h(ctx
, fp0
, fd
);
12643 tcg_temp_free_i32(fp0
);
12644 tcg_temp_free_i32(fp1
);
12650 TCGv_i32 fp0
= tcg_temp_new_i32();
12651 TCGv_i32 fp1
= tcg_temp_new_i32();
12653 gen_load_fpr32h(ctx
, fp0
, fs
);
12654 gen_load_fpr32(ctx
, fp1
, ft
);
12655 gen_store_fpr32(ctx
, fp1
, fd
);
12656 gen_store_fpr32h(ctx
, fp0
, fd
);
12657 tcg_temp_free_i32(fp0
);
12658 tcg_temp_free_i32(fp1
);
12664 TCGv_i32 fp0
= tcg_temp_new_i32();
12665 TCGv_i32 fp1
= tcg_temp_new_i32();
12667 gen_load_fpr32h(ctx
, fp0
, fs
);
12668 gen_load_fpr32h(ctx
, fp1
, ft
);
12669 gen_store_fpr32(ctx
, fp1
, fd
);
12670 gen_store_fpr32h(ctx
, fp0
, fd
);
12671 tcg_temp_free_i32(fp0
);
12672 tcg_temp_free_i32(fp1
);
12676 case OPC_CMP_UN_PS
:
12677 case OPC_CMP_EQ_PS
:
12678 case OPC_CMP_UEQ_PS
:
12679 case OPC_CMP_OLT_PS
:
12680 case OPC_CMP_ULT_PS
:
12681 case OPC_CMP_OLE_PS
:
12682 case OPC_CMP_ULE_PS
:
12683 case OPC_CMP_SF_PS
:
12684 case OPC_CMP_NGLE_PS
:
12685 case OPC_CMP_SEQ_PS
:
12686 case OPC_CMP_NGL_PS
:
12687 case OPC_CMP_LT_PS
:
12688 case OPC_CMP_NGE_PS
:
12689 case OPC_CMP_LE_PS
:
12690 case OPC_CMP_NGT_PS
:
12691 if (ctx
->opcode
& (1 << 6)) {
12692 gen_cmpabs_ps(ctx
, func
- 48, ft
, fs
, cc
);
12694 gen_cmp_ps(ctx
, func
- 48, ft
, fs
, cc
);
12698 MIPS_INVAL("farith");
12699 gen_reserved_instruction(ctx
);
12704 /* Coprocessor 3 (FPU) */
12705 static void gen_flt3_ldst(DisasContext
*ctx
, uint32_t opc
,
12706 int fd
, int fs
, int base
, int index
)
12708 TCGv t0
= tcg_temp_new();
12711 gen_load_gpr(t0
, index
);
12712 } else if (index
== 0) {
12713 gen_load_gpr(t0
, base
);
12715 gen_op_addr_add(ctx
, t0
, cpu_gpr
[base
], cpu_gpr
[index
]);
12718 * Don't do NOP if destination is zero: we must perform the actual
12725 TCGv_i32 fp0
= tcg_temp_new_i32();
12727 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESL
);
12728 tcg_gen_trunc_tl_i32(fp0
, t0
);
12729 gen_store_fpr32(ctx
, fp0
, fd
);
12730 tcg_temp_free_i32(fp0
);
12735 check_cp1_registers(ctx
, fd
);
12737 TCGv_i64 fp0
= tcg_temp_new_i64();
12738 tcg_gen_qemu_ld_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
12739 gen_store_fpr64(ctx
, fp0
, fd
);
12740 tcg_temp_free_i64(fp0
);
12744 check_cp1_64bitmode(ctx
);
12745 tcg_gen_andi_tl(t0
, t0
, ~0x7);
12747 TCGv_i64 fp0
= tcg_temp_new_i64();
12749 tcg_gen_qemu_ld_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
12750 gen_store_fpr64(ctx
, fp0
, fd
);
12751 tcg_temp_free_i64(fp0
);
12757 TCGv_i32 fp0
= tcg_temp_new_i32();
12758 gen_load_fpr32(ctx
, fp0
, fs
);
12759 tcg_gen_qemu_st_i32(fp0
, t0
, ctx
->mem_idx
, MO_TEUL
);
12760 tcg_temp_free_i32(fp0
);
12765 check_cp1_registers(ctx
, fs
);
12767 TCGv_i64 fp0
= tcg_temp_new_i64();
12768 gen_load_fpr64(ctx
, fp0
, fs
);
12769 tcg_gen_qemu_st_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
12770 tcg_temp_free_i64(fp0
);
12774 check_cp1_64bitmode(ctx
);
12775 tcg_gen_andi_tl(t0
, t0
, ~0x7);
12777 TCGv_i64 fp0
= tcg_temp_new_i64();
12778 gen_load_fpr64(ctx
, fp0
, fs
);
12779 tcg_gen_qemu_st_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
12780 tcg_temp_free_i64(fp0
);
12787 static void gen_flt3_arith(DisasContext
*ctx
, uint32_t opc
,
12788 int fd
, int fr
, int fs
, int ft
)
12794 TCGv t0
= tcg_temp_local_new();
12795 TCGv_i32 fp
= tcg_temp_new_i32();
12796 TCGv_i32 fph
= tcg_temp_new_i32();
12797 TCGLabel
*l1
= gen_new_label();
12798 TCGLabel
*l2
= gen_new_label();
12800 gen_load_gpr(t0
, fr
);
12801 tcg_gen_andi_tl(t0
, t0
, 0x7);
12803 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, 0, l1
);
12804 gen_load_fpr32(ctx
, fp
, fs
);
12805 gen_load_fpr32h(ctx
, fph
, fs
);
12806 gen_store_fpr32(ctx
, fp
, fd
);
12807 gen_store_fpr32h(ctx
, fph
, fd
);
12810 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, 4, l2
);
12812 #ifdef TARGET_WORDS_BIGENDIAN
12813 gen_load_fpr32(ctx
, fp
, fs
);
12814 gen_load_fpr32h(ctx
, fph
, ft
);
12815 gen_store_fpr32h(ctx
, fp
, fd
);
12816 gen_store_fpr32(ctx
, fph
, fd
);
12818 gen_load_fpr32h(ctx
, fph
, fs
);
12819 gen_load_fpr32(ctx
, fp
, ft
);
12820 gen_store_fpr32(ctx
, fph
, fd
);
12821 gen_store_fpr32h(ctx
, fp
, fd
);
12824 tcg_temp_free_i32(fp
);
12825 tcg_temp_free_i32(fph
);
12831 TCGv_i32 fp0
= tcg_temp_new_i32();
12832 TCGv_i32 fp1
= tcg_temp_new_i32();
12833 TCGv_i32 fp2
= tcg_temp_new_i32();
12835 gen_load_fpr32(ctx
, fp0
, fs
);
12836 gen_load_fpr32(ctx
, fp1
, ft
);
12837 gen_load_fpr32(ctx
, fp2
, fr
);
12838 gen_helper_float_madd_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12839 tcg_temp_free_i32(fp0
);
12840 tcg_temp_free_i32(fp1
);
12841 gen_store_fpr32(ctx
, fp2
, fd
);
12842 tcg_temp_free_i32(fp2
);
12847 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
12849 TCGv_i64 fp0
= tcg_temp_new_i64();
12850 TCGv_i64 fp1
= tcg_temp_new_i64();
12851 TCGv_i64 fp2
= tcg_temp_new_i64();
12853 gen_load_fpr64(ctx
, fp0
, fs
);
12854 gen_load_fpr64(ctx
, fp1
, ft
);
12855 gen_load_fpr64(ctx
, fp2
, fr
);
12856 gen_helper_float_madd_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12857 tcg_temp_free_i64(fp0
);
12858 tcg_temp_free_i64(fp1
);
12859 gen_store_fpr64(ctx
, fp2
, fd
);
12860 tcg_temp_free_i64(fp2
);
12866 TCGv_i64 fp0
= tcg_temp_new_i64();
12867 TCGv_i64 fp1
= tcg_temp_new_i64();
12868 TCGv_i64 fp2
= tcg_temp_new_i64();
12870 gen_load_fpr64(ctx
, fp0
, fs
);
12871 gen_load_fpr64(ctx
, fp1
, ft
);
12872 gen_load_fpr64(ctx
, fp2
, fr
);
12873 gen_helper_float_madd_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12874 tcg_temp_free_i64(fp0
);
12875 tcg_temp_free_i64(fp1
);
12876 gen_store_fpr64(ctx
, fp2
, fd
);
12877 tcg_temp_free_i64(fp2
);
12883 TCGv_i32 fp0
= tcg_temp_new_i32();
12884 TCGv_i32 fp1
= tcg_temp_new_i32();
12885 TCGv_i32 fp2
= tcg_temp_new_i32();
12887 gen_load_fpr32(ctx
, fp0
, fs
);
12888 gen_load_fpr32(ctx
, fp1
, ft
);
12889 gen_load_fpr32(ctx
, fp2
, fr
);
12890 gen_helper_float_msub_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12891 tcg_temp_free_i32(fp0
);
12892 tcg_temp_free_i32(fp1
);
12893 gen_store_fpr32(ctx
, fp2
, fd
);
12894 tcg_temp_free_i32(fp2
);
12899 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
12901 TCGv_i64 fp0
= tcg_temp_new_i64();
12902 TCGv_i64 fp1
= tcg_temp_new_i64();
12903 TCGv_i64 fp2
= tcg_temp_new_i64();
12905 gen_load_fpr64(ctx
, fp0
, fs
);
12906 gen_load_fpr64(ctx
, fp1
, ft
);
12907 gen_load_fpr64(ctx
, fp2
, fr
);
12908 gen_helper_float_msub_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12909 tcg_temp_free_i64(fp0
);
12910 tcg_temp_free_i64(fp1
);
12911 gen_store_fpr64(ctx
, fp2
, fd
);
12912 tcg_temp_free_i64(fp2
);
12918 TCGv_i64 fp0
= tcg_temp_new_i64();
12919 TCGv_i64 fp1
= tcg_temp_new_i64();
12920 TCGv_i64 fp2
= tcg_temp_new_i64();
12922 gen_load_fpr64(ctx
, fp0
, fs
);
12923 gen_load_fpr64(ctx
, fp1
, ft
);
12924 gen_load_fpr64(ctx
, fp2
, fr
);
12925 gen_helper_float_msub_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12926 tcg_temp_free_i64(fp0
);
12927 tcg_temp_free_i64(fp1
);
12928 gen_store_fpr64(ctx
, fp2
, fd
);
12929 tcg_temp_free_i64(fp2
);
12935 TCGv_i32 fp0
= tcg_temp_new_i32();
12936 TCGv_i32 fp1
= tcg_temp_new_i32();
12937 TCGv_i32 fp2
= tcg_temp_new_i32();
12939 gen_load_fpr32(ctx
, fp0
, fs
);
12940 gen_load_fpr32(ctx
, fp1
, ft
);
12941 gen_load_fpr32(ctx
, fp2
, fr
);
12942 gen_helper_float_nmadd_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12943 tcg_temp_free_i32(fp0
);
12944 tcg_temp_free_i32(fp1
);
12945 gen_store_fpr32(ctx
, fp2
, fd
);
12946 tcg_temp_free_i32(fp2
);
12951 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
12953 TCGv_i64 fp0
= tcg_temp_new_i64();
12954 TCGv_i64 fp1
= tcg_temp_new_i64();
12955 TCGv_i64 fp2
= tcg_temp_new_i64();
12957 gen_load_fpr64(ctx
, fp0
, fs
);
12958 gen_load_fpr64(ctx
, fp1
, ft
);
12959 gen_load_fpr64(ctx
, fp2
, fr
);
12960 gen_helper_float_nmadd_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12961 tcg_temp_free_i64(fp0
);
12962 tcg_temp_free_i64(fp1
);
12963 gen_store_fpr64(ctx
, fp2
, fd
);
12964 tcg_temp_free_i64(fp2
);
12970 TCGv_i64 fp0
= tcg_temp_new_i64();
12971 TCGv_i64 fp1
= tcg_temp_new_i64();
12972 TCGv_i64 fp2
= tcg_temp_new_i64();
12974 gen_load_fpr64(ctx
, fp0
, fs
);
12975 gen_load_fpr64(ctx
, fp1
, ft
);
12976 gen_load_fpr64(ctx
, fp2
, fr
);
12977 gen_helper_float_nmadd_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12978 tcg_temp_free_i64(fp0
);
12979 tcg_temp_free_i64(fp1
);
12980 gen_store_fpr64(ctx
, fp2
, fd
);
12981 tcg_temp_free_i64(fp2
);
12987 TCGv_i32 fp0
= tcg_temp_new_i32();
12988 TCGv_i32 fp1
= tcg_temp_new_i32();
12989 TCGv_i32 fp2
= tcg_temp_new_i32();
12991 gen_load_fpr32(ctx
, fp0
, fs
);
12992 gen_load_fpr32(ctx
, fp1
, ft
);
12993 gen_load_fpr32(ctx
, fp2
, fr
);
12994 gen_helper_float_nmsub_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12995 tcg_temp_free_i32(fp0
);
12996 tcg_temp_free_i32(fp1
);
12997 gen_store_fpr32(ctx
, fp2
, fd
);
12998 tcg_temp_free_i32(fp2
);
13003 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
13005 TCGv_i64 fp0
= tcg_temp_new_i64();
13006 TCGv_i64 fp1
= tcg_temp_new_i64();
13007 TCGv_i64 fp2
= tcg_temp_new_i64();
13009 gen_load_fpr64(ctx
, fp0
, fs
);
13010 gen_load_fpr64(ctx
, fp1
, ft
);
13011 gen_load_fpr64(ctx
, fp2
, fr
);
13012 gen_helper_float_nmsub_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
13013 tcg_temp_free_i64(fp0
);
13014 tcg_temp_free_i64(fp1
);
13015 gen_store_fpr64(ctx
, fp2
, fd
);
13016 tcg_temp_free_i64(fp2
);
13022 TCGv_i64 fp0
= tcg_temp_new_i64();
13023 TCGv_i64 fp1
= tcg_temp_new_i64();
13024 TCGv_i64 fp2
= tcg_temp_new_i64();
13026 gen_load_fpr64(ctx
, fp0
, fs
);
13027 gen_load_fpr64(ctx
, fp1
, ft
);
13028 gen_load_fpr64(ctx
, fp2
, fr
);
13029 gen_helper_float_nmsub_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
13030 tcg_temp_free_i64(fp0
);
13031 tcg_temp_free_i64(fp1
);
13032 gen_store_fpr64(ctx
, fp2
, fd
);
13033 tcg_temp_free_i64(fp2
);
13037 MIPS_INVAL("flt3_arith");
13038 gen_reserved_instruction(ctx
);
13043 static void gen_rdhwr(DisasContext
*ctx
, int rt
, int rd
, int sel
)
13047 #if !defined(CONFIG_USER_ONLY)
13049 * The Linux kernel will emulate rdhwr if it's not supported natively.
13050 * Therefore only check the ISA in system mode.
13052 check_insn(ctx
, ISA_MIPS_R2
);
13054 t0
= tcg_temp_new();
13058 gen_helper_rdhwr_cpunum(t0
, cpu_env
);
13059 gen_store_gpr(t0
, rt
);
13062 gen_helper_rdhwr_synci_step(t0
, cpu_env
);
13063 gen_store_gpr(t0
, rt
);
13066 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
13069 gen_helper_rdhwr_cc(t0
, cpu_env
);
13070 gen_store_gpr(t0
, rt
);
13072 * Break the TB to be able to take timer interrupts immediately
13073 * after reading count. DISAS_STOP isn't sufficient, we need to ensure
13074 * we break completely out of translated code.
13076 gen_save_pc(ctx
->base
.pc_next
+ 4);
13077 ctx
->base
.is_jmp
= DISAS_EXIT
;
13080 gen_helper_rdhwr_ccres(t0
, cpu_env
);
13081 gen_store_gpr(t0
, rt
);
13084 check_insn(ctx
, ISA_MIPS_R6
);
13087 * Performance counter registers are not implemented other than
13088 * control register 0.
13090 generate_exception(ctx
, EXCP_RI
);
13092 gen_helper_rdhwr_performance(t0
, cpu_env
);
13093 gen_store_gpr(t0
, rt
);
13096 check_insn(ctx
, ISA_MIPS_R6
);
13097 gen_helper_rdhwr_xnp(t0
, cpu_env
);
13098 gen_store_gpr(t0
, rt
);
13101 #if defined(CONFIG_USER_ONLY)
13102 tcg_gen_ld_tl(t0
, cpu_env
,
13103 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
13104 gen_store_gpr(t0
, rt
);
13107 if ((ctx
->hflags
& MIPS_HFLAG_CP0
) ||
13108 (ctx
->hflags
& MIPS_HFLAG_HWRENA_ULR
)) {
13109 tcg_gen_ld_tl(t0
, cpu_env
,
13110 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
13111 gen_store_gpr(t0
, rt
);
13113 gen_reserved_instruction(ctx
);
13117 default: /* Invalid */
13118 MIPS_INVAL("rdhwr");
13119 gen_reserved_instruction(ctx
);
13125 static inline void clear_branch_hflags(DisasContext
*ctx
)
13127 ctx
->hflags
&= ~MIPS_HFLAG_BMASK
;
13128 if (ctx
->base
.is_jmp
== DISAS_NEXT
) {
13129 save_cpu_state(ctx
, 0);
13132 * It is not safe to save ctx->hflags as hflags may be changed
13133 * in execution time by the instruction in delay / forbidden slot.
13135 tcg_gen_andi_i32(hflags
, hflags
, ~MIPS_HFLAG_BMASK
);
13139 static void gen_branch(DisasContext
*ctx
, int insn_bytes
)
13141 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
13142 int proc_hflags
= ctx
->hflags
& MIPS_HFLAG_BMASK
;
13143 /* Branches completion */
13144 clear_branch_hflags(ctx
);
13145 ctx
->base
.is_jmp
= DISAS_NORETURN
;
13146 /* FIXME: Need to clear can_do_io. */
13147 switch (proc_hflags
& MIPS_HFLAG_BMASK_BASE
) {
13148 case MIPS_HFLAG_FBNSLOT
:
13149 gen_goto_tb(ctx
, 0, ctx
->base
.pc_next
+ insn_bytes
);
13152 /* unconditional branch */
13153 if (proc_hflags
& MIPS_HFLAG_BX
) {
13154 tcg_gen_xori_i32(hflags
, hflags
, MIPS_HFLAG_M16
);
13156 gen_goto_tb(ctx
, 0, ctx
->btarget
);
13158 case MIPS_HFLAG_BL
:
13159 /* blikely taken case */
13160 gen_goto_tb(ctx
, 0, ctx
->btarget
);
13162 case MIPS_HFLAG_BC
:
13163 /* Conditional branch */
13165 TCGLabel
*l1
= gen_new_label();
13167 tcg_gen_brcondi_tl(TCG_COND_NE
, bcond
, 0, l1
);
13168 gen_goto_tb(ctx
, 1, ctx
->base
.pc_next
+ insn_bytes
);
13170 gen_goto_tb(ctx
, 0, ctx
->btarget
);
13173 case MIPS_HFLAG_BR
:
13174 /* unconditional branch to register */
13175 if (ctx
->insn_flags
& (ASE_MIPS16
| ASE_MICROMIPS
)) {
13176 TCGv t0
= tcg_temp_new();
13177 TCGv_i32 t1
= tcg_temp_new_i32();
13179 tcg_gen_andi_tl(t0
, btarget
, 0x1);
13180 tcg_gen_trunc_tl_i32(t1
, t0
);
13182 tcg_gen_andi_i32(hflags
, hflags
, ~(uint32_t)MIPS_HFLAG_M16
);
13183 tcg_gen_shli_i32(t1
, t1
, MIPS_HFLAG_M16_SHIFT
);
13184 tcg_gen_or_i32(hflags
, hflags
, t1
);
13185 tcg_temp_free_i32(t1
);
13187 tcg_gen_andi_tl(cpu_PC
, btarget
, ~(target_ulong
)0x1);
13189 tcg_gen_mov_tl(cpu_PC
, btarget
);
13191 if (ctx
->base
.singlestep_enabled
) {
13192 save_cpu_state(ctx
, 0);
13193 gen_helper_raise_exception_debug(cpu_env
);
13195 tcg_gen_lookup_and_goto_ptr();
13198 fprintf(stderr
, "unknown branch 0x%x\n", proc_hflags
);
13204 /* Compact Branches */
13205 static void gen_compute_compact_branch(DisasContext
*ctx
, uint32_t opc
,
13206 int rs
, int rt
, int32_t offset
)
13208 int bcond_compute
= 0;
13209 TCGv t0
= tcg_temp_new();
13210 TCGv t1
= tcg_temp_new();
13211 int m16_lowbit
= (ctx
->hflags
& MIPS_HFLAG_M16
) != 0;
13213 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
13214 #ifdef MIPS_DEBUG_DISAS
13215 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
13216 "\n", ctx
->base
.pc_next
);
13218 gen_reserved_instruction(ctx
);
13222 /* Load needed operands and calculate btarget */
13224 /* compact branch */
13225 case OPC_BOVC
: /* OPC_BEQZALC, OPC_BEQC */
13226 case OPC_BNVC
: /* OPC_BNEZALC, OPC_BNEC */
13227 gen_load_gpr(t0
, rs
);
13228 gen_load_gpr(t1
, rt
);
13230 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
13231 if (rs
<= rt
&& rs
== 0) {
13232 /* OPC_BEQZALC, OPC_BNEZALC */
13233 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 4 + m16_lowbit
);
13236 case OPC_BLEZC
: /* OPC_BGEZC, OPC_BGEC */
13237 case OPC_BGTZC
: /* OPC_BLTZC, OPC_BLTC */
13238 gen_load_gpr(t0
, rs
);
13239 gen_load_gpr(t1
, rt
);
13241 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
13243 case OPC_BLEZALC
: /* OPC_BGEZALC, OPC_BGEUC */
13244 case OPC_BGTZALC
: /* OPC_BLTZALC, OPC_BLTUC */
13245 if (rs
== 0 || rs
== rt
) {
13246 /* OPC_BLEZALC, OPC_BGEZALC */
13247 /* OPC_BGTZALC, OPC_BLTZALC */
13248 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 4 + m16_lowbit
);
13250 gen_load_gpr(t0
, rs
);
13251 gen_load_gpr(t1
, rt
);
13253 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
13257 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
13262 /* OPC_BEQZC, OPC_BNEZC */
13263 gen_load_gpr(t0
, rs
);
13265 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
13267 /* OPC_JIC, OPC_JIALC */
13268 TCGv tbase
= tcg_temp_new();
13269 TCGv toffset
= tcg_temp_new();
13271 gen_load_gpr(tbase
, rt
);
13272 tcg_gen_movi_tl(toffset
, offset
);
13273 gen_op_addr_add(ctx
, btarget
, tbase
, toffset
);
13274 tcg_temp_free(tbase
);
13275 tcg_temp_free(toffset
);
13279 MIPS_INVAL("Compact branch/jump");
13280 gen_reserved_instruction(ctx
);
13284 if (bcond_compute
== 0) {
13285 /* Uncoditional compact branch */
13288 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 4 + m16_lowbit
);
13291 ctx
->hflags
|= MIPS_HFLAG_BR
;
13294 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 4 + m16_lowbit
);
13297 ctx
->hflags
|= MIPS_HFLAG_B
;
13300 MIPS_INVAL("Compact branch/jump");
13301 gen_reserved_instruction(ctx
);
13305 /* Generating branch here as compact branches don't have delay slot */
13306 gen_branch(ctx
, 4);
13308 /* Conditional compact branch */
13309 TCGLabel
*fs
= gen_new_label();
13310 save_cpu_state(ctx
, 0);
13313 case OPC_BLEZALC
: /* OPC_BGEZALC, OPC_BGEUC */
13314 if (rs
== 0 && rt
!= 0) {
13316 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE
), t1
, 0, fs
);
13317 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
13319 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE
), t1
, 0, fs
);
13322 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU
), t0
, t1
, fs
);
13325 case OPC_BGTZALC
: /* OPC_BLTZALC, OPC_BLTUC */
13326 if (rs
== 0 && rt
!= 0) {
13328 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT
), t1
, 0, fs
);
13329 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
13331 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT
), t1
, 0, fs
);
13334 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU
), t0
, t1
, fs
);
13337 case OPC_BLEZC
: /* OPC_BGEZC, OPC_BGEC */
13338 if (rs
== 0 && rt
!= 0) {
13340 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE
), t1
, 0, fs
);
13341 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
13343 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE
), t1
, 0, fs
);
13346 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE
), t0
, t1
, fs
);
13349 case OPC_BGTZC
: /* OPC_BLTZC, OPC_BLTC */
13350 if (rs
== 0 && rt
!= 0) {
13352 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT
), t1
, 0, fs
);
13353 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
13355 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT
), t1
, 0, fs
);
13358 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT
), t0
, t1
, fs
);
13361 case OPC_BOVC
: /* OPC_BEQZALC, OPC_BEQC */
13362 case OPC_BNVC
: /* OPC_BNEZALC, OPC_BNEC */
13364 /* OPC_BOVC, OPC_BNVC */
13365 TCGv t2
= tcg_temp_new();
13366 TCGv t3
= tcg_temp_new();
13367 TCGv t4
= tcg_temp_new();
13368 TCGv input_overflow
= tcg_temp_new();
13370 gen_load_gpr(t0
, rs
);
13371 gen_load_gpr(t1
, rt
);
13372 tcg_gen_ext32s_tl(t2
, t0
);
13373 tcg_gen_setcond_tl(TCG_COND_NE
, input_overflow
, t2
, t0
);
13374 tcg_gen_ext32s_tl(t3
, t1
);
13375 tcg_gen_setcond_tl(TCG_COND_NE
, t4
, t3
, t1
);
13376 tcg_gen_or_tl(input_overflow
, input_overflow
, t4
);
13378 tcg_gen_add_tl(t4
, t2
, t3
);
13379 tcg_gen_ext32s_tl(t4
, t4
);
13380 tcg_gen_xor_tl(t2
, t2
, t3
);
13381 tcg_gen_xor_tl(t3
, t4
, t3
);
13382 tcg_gen_andc_tl(t2
, t3
, t2
);
13383 tcg_gen_setcondi_tl(TCG_COND_LT
, t4
, t2
, 0);
13384 tcg_gen_or_tl(t4
, t4
, input_overflow
);
13385 if (opc
== OPC_BOVC
) {
13387 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE
), t4
, 0, fs
);
13390 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ
), t4
, 0, fs
);
13392 tcg_temp_free(input_overflow
);
13396 } else if (rs
< rt
&& rs
== 0) {
13397 /* OPC_BEQZALC, OPC_BNEZALC */
13398 if (opc
== OPC_BEQZALC
) {
13400 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ
), t1
, 0, fs
);
13403 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE
), t1
, 0, fs
);
13406 /* OPC_BEQC, OPC_BNEC */
13407 if (opc
== OPC_BEQC
) {
13409 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ
), t0
, t1
, fs
);
13412 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE
), t0
, t1
, fs
);
13417 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ
), t0
, 0, fs
);
13420 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE
), t0
, 0, fs
);
13423 MIPS_INVAL("Compact conditional branch/jump");
13424 gen_reserved_instruction(ctx
);
13428 /* Generating branch here as compact branches don't have delay slot */
13429 gen_goto_tb(ctx
, 1, ctx
->btarget
);
13432 ctx
->hflags
|= MIPS_HFLAG_FBNSLOT
;
13440 /* ISA extensions (ASEs) */
13441 /* MIPS16 extension to MIPS32 */
13443 /* MIPS16 major opcodes */
13445 M16_OPC_ADDIUSP
= 0x00,
13446 M16_OPC_ADDIUPC
= 0x01,
13448 M16_OPC_JAL
= 0x03,
13449 M16_OPC_BEQZ
= 0x04,
13450 M16_OPC_BNEQZ
= 0x05,
13451 M16_OPC_SHIFT
= 0x06,
13453 M16_OPC_RRIA
= 0x08,
13454 M16_OPC_ADDIU8
= 0x09,
13455 M16_OPC_SLTI
= 0x0a,
13456 M16_OPC_SLTIU
= 0x0b,
13459 M16_OPC_CMPI
= 0x0e,
13463 M16_OPC_LWSP
= 0x12,
13465 M16_OPC_LBU
= 0x14,
13466 M16_OPC_LHU
= 0x15,
13467 M16_OPC_LWPC
= 0x16,
13468 M16_OPC_LWU
= 0x17,
13471 M16_OPC_SWSP
= 0x1a,
13473 M16_OPC_RRR
= 0x1c,
13475 M16_OPC_EXTEND
= 0x1e,
13479 /* I8 funct field */
13498 /* RR funct field */
13532 /* I64 funct field */
13540 I64_DADDIUPC
= 0x6,
13544 /* RR ry field for CNVT */
13546 RR_RY_CNVT_ZEB
= 0x0,
13547 RR_RY_CNVT_ZEH
= 0x1,
13548 RR_RY_CNVT_ZEW
= 0x2,
13549 RR_RY_CNVT_SEB
= 0x4,
13550 RR_RY_CNVT_SEH
= 0x5,
13551 RR_RY_CNVT_SEW
= 0x6,
13554 static int xlat(int r
)
13556 static int map
[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
13561 static void gen_mips16_save(DisasContext
*ctx
,
13562 int xsregs
, int aregs
,
13563 int do_ra
, int do_s0
, int do_s1
,
13566 TCGv t0
= tcg_temp_new();
13567 TCGv t1
= tcg_temp_new();
13568 TCGv t2
= tcg_temp_new();
13598 gen_reserved_instruction(ctx
);
13604 gen_base_offset_addr(ctx
, t0
, 29, 12);
13605 gen_load_gpr(t1
, 7);
13606 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
13609 gen_base_offset_addr(ctx
, t0
, 29, 8);
13610 gen_load_gpr(t1
, 6);
13611 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
13614 gen_base_offset_addr(ctx
, t0
, 29, 4);
13615 gen_load_gpr(t1
, 5);
13616 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
13619 gen_base_offset_addr(ctx
, t0
, 29, 0);
13620 gen_load_gpr(t1
, 4);
13621 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
13624 gen_load_gpr(t0
, 29);
13626 #define DECR_AND_STORE(reg) do { \
13627 tcg_gen_movi_tl(t2, -4); \
13628 gen_op_addr_add(ctx, t0, t0, t2); \
13629 gen_load_gpr(t1, reg); \
13630 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \
13634 DECR_AND_STORE(31);
13639 DECR_AND_STORE(30);
13642 DECR_AND_STORE(23);
13645 DECR_AND_STORE(22);
13648 DECR_AND_STORE(21);
13651 DECR_AND_STORE(20);
13654 DECR_AND_STORE(19);
13657 DECR_AND_STORE(18);
13661 DECR_AND_STORE(17);
13664 DECR_AND_STORE(16);
13694 gen_reserved_instruction(ctx
);
13710 #undef DECR_AND_STORE
13712 tcg_gen_movi_tl(t2
, -framesize
);
13713 gen_op_addr_add(ctx
, cpu_gpr
[29], cpu_gpr
[29], t2
);
13719 static void gen_mips16_restore(DisasContext
*ctx
,
13720 int xsregs
, int aregs
,
13721 int do_ra
, int do_s0
, int do_s1
,
13725 TCGv t0
= tcg_temp_new();
13726 TCGv t1
= tcg_temp_new();
13727 TCGv t2
= tcg_temp_new();
13729 tcg_gen_movi_tl(t2
, framesize
);
13730 gen_op_addr_add(ctx
, t0
, cpu_gpr
[29], t2
);
13732 #define DECR_AND_LOAD(reg) do { \
13733 tcg_gen_movi_tl(t2, -4); \
13734 gen_op_addr_add(ctx, t0, t0, t2); \
13735 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \
13736 gen_store_gpr(t1, reg); \
13800 gen_reserved_instruction(ctx
);
13816 #undef DECR_AND_LOAD
13818 tcg_gen_movi_tl(t2
, framesize
);
13819 gen_op_addr_add(ctx
, cpu_gpr
[29], cpu_gpr
[29], t2
);
13825 static void gen_addiupc(DisasContext
*ctx
, int rx
, int imm
,
13826 int is_64_bit
, int extended
)
13830 if (extended
&& (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
13831 gen_reserved_instruction(ctx
);
13835 t0
= tcg_temp_new();
13837 tcg_gen_movi_tl(t0
, pc_relative_pc(ctx
));
13838 tcg_gen_addi_tl(cpu_gpr
[rx
], t0
, imm
);
13840 tcg_gen_ext32s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
13846 static void gen_cache_operation(DisasContext
*ctx
, uint32_t op
, int base
,
13849 TCGv_i32 t0
= tcg_const_i32(op
);
13850 TCGv t1
= tcg_temp_new();
13851 gen_base_offset_addr(ctx
, t1
, base
, offset
);
13852 gen_helper_cache(cpu_env
, t1
, t0
);
13855 #if defined(TARGET_MIPS64)
13856 static void decode_i64_mips16(DisasContext
*ctx
,
13857 int ry
, int funct
, int16_t offset
,
13862 check_insn(ctx
, ISA_MIPS3
);
13863 check_mips_64(ctx
);
13864 offset
= extended
? offset
: offset
<< 3;
13865 gen_ld(ctx
, OPC_LD
, ry
, 29, offset
);
13868 check_insn(ctx
, ISA_MIPS3
);
13869 check_mips_64(ctx
);
13870 offset
= extended
? offset
: offset
<< 3;
13871 gen_st(ctx
, OPC_SD
, ry
, 29, offset
);
13874 check_insn(ctx
, ISA_MIPS3
);
13875 check_mips_64(ctx
);
13876 offset
= extended
? offset
: (ctx
->opcode
& 0xff) << 3;
13877 gen_st(ctx
, OPC_SD
, 31, 29, offset
);
13880 check_insn(ctx
, ISA_MIPS3
);
13881 check_mips_64(ctx
);
13882 offset
= extended
? offset
: ((int8_t)ctx
->opcode
) << 3;
13883 gen_arith_imm(ctx
, OPC_DADDIU
, 29, 29, offset
);
13886 check_insn(ctx
, ISA_MIPS3
);
13887 check_mips_64(ctx
);
13888 if (extended
&& (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
13889 gen_reserved_instruction(ctx
);
13891 offset
= extended
? offset
: offset
<< 3;
13892 gen_ld(ctx
, OPC_LDPC
, ry
, 0, offset
);
13896 check_insn(ctx
, ISA_MIPS3
);
13897 check_mips_64(ctx
);
13898 offset
= extended
? offset
: ((int8_t)(offset
<< 3)) >> 3;
13899 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, ry
, offset
);
13902 check_insn(ctx
, ISA_MIPS3
);
13903 check_mips_64(ctx
);
13904 offset
= extended
? offset
: offset
<< 2;
13905 gen_addiupc(ctx
, ry
, offset
, 1, extended
);
13908 check_insn(ctx
, ISA_MIPS3
);
13909 check_mips_64(ctx
);
13910 offset
= extended
? offset
: offset
<< 2;
13911 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, 29, offset
);
13917 static int decode_extended_mips16_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
13919 int extend
= translator_lduw(env
, ctx
->base
.pc_next
+ 2);
13920 int op
, rx
, ry
, funct
, sa
;
13921 int16_t imm
, offset
;
13923 ctx
->opcode
= (ctx
->opcode
<< 16) | extend
;
13924 op
= (ctx
->opcode
>> 11) & 0x1f;
13925 sa
= (ctx
->opcode
>> 22) & 0x1f;
13926 funct
= (ctx
->opcode
>> 8) & 0x7;
13927 rx
= xlat((ctx
->opcode
>> 8) & 0x7);
13928 ry
= xlat((ctx
->opcode
>> 5) & 0x7);
13929 offset
= imm
= (int16_t) (((ctx
->opcode
>> 16) & 0x1f) << 11
13930 | ((ctx
->opcode
>> 21) & 0x3f) << 5
13931 | (ctx
->opcode
& 0x1f));
13934 * The extended opcodes cleverly reuse the opcodes from their 16-bit
13938 case M16_OPC_ADDIUSP
:
13939 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 29, imm
);
13941 case M16_OPC_ADDIUPC
:
13942 gen_addiupc(ctx
, rx
, imm
, 0, 1);
13945 gen_compute_branch(ctx
, OPC_BEQ
, 4, 0, 0, offset
<< 1, 0);
13946 /* No delay slot, so just process as a normal instruction */
13949 gen_compute_branch(ctx
, OPC_BEQ
, 4, rx
, 0, offset
<< 1, 0);
13950 /* No delay slot, so just process as a normal instruction */
13952 case M16_OPC_BNEQZ
:
13953 gen_compute_branch(ctx
, OPC_BNE
, 4, rx
, 0, offset
<< 1, 0);
13954 /* No delay slot, so just process as a normal instruction */
13956 case M16_OPC_SHIFT
:
13957 switch (ctx
->opcode
& 0x3) {
13959 gen_shift_imm(ctx
, OPC_SLL
, rx
, ry
, sa
);
13962 #if defined(TARGET_MIPS64)
13963 check_mips_64(ctx
);
13964 gen_shift_imm(ctx
, OPC_DSLL
, rx
, ry
, sa
);
13966 gen_reserved_instruction(ctx
);
13970 gen_shift_imm(ctx
, OPC_SRL
, rx
, ry
, sa
);
13973 gen_shift_imm(ctx
, OPC_SRA
, rx
, ry
, sa
);
13977 #if defined(TARGET_MIPS64)
13979 check_insn(ctx
, ISA_MIPS3
);
13980 check_mips_64(ctx
);
13981 gen_ld(ctx
, OPC_LD
, ry
, rx
, offset
);
13985 imm
= ctx
->opcode
& 0xf;
13986 imm
= imm
| ((ctx
->opcode
>> 20) & 0x7f) << 4;
13987 imm
= imm
| ((ctx
->opcode
>> 16) & 0xf) << 11;
13988 imm
= (int16_t) (imm
<< 1) >> 1;
13989 if ((ctx
->opcode
>> 4) & 0x1) {
13990 #if defined(TARGET_MIPS64)
13991 check_mips_64(ctx
);
13992 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, rx
, imm
);
13994 gen_reserved_instruction(ctx
);
13997 gen_arith_imm(ctx
, OPC_ADDIU
, ry
, rx
, imm
);
14000 case M16_OPC_ADDIU8
:
14001 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, rx
, imm
);
14004 gen_slt_imm(ctx
, OPC_SLTI
, 24, rx
, imm
);
14006 case M16_OPC_SLTIU
:
14007 gen_slt_imm(ctx
, OPC_SLTIU
, 24, rx
, imm
);
14012 gen_compute_branch(ctx
, OPC_BEQ
, 4, 24, 0, offset
<< 1, 0);
14015 gen_compute_branch(ctx
, OPC_BNE
, 4, 24, 0, offset
<< 1, 0);
14018 gen_st(ctx
, OPC_SW
, 31, 29, imm
);
14021 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, imm
);
14024 check_insn(ctx
, ISA_MIPS_R1
);
14026 int xsregs
= (ctx
->opcode
>> 24) & 0x7;
14027 int aregs
= (ctx
->opcode
>> 16) & 0xf;
14028 int do_ra
= (ctx
->opcode
>> 6) & 0x1;
14029 int do_s0
= (ctx
->opcode
>> 5) & 0x1;
14030 int do_s1
= (ctx
->opcode
>> 4) & 0x1;
14031 int framesize
= (((ctx
->opcode
>> 20) & 0xf) << 4
14032 | (ctx
->opcode
& 0xf)) << 3;
14034 if (ctx
->opcode
& (1 << 7)) {
14035 gen_mips16_save(ctx
, xsregs
, aregs
,
14036 do_ra
, do_s0
, do_s1
,
14039 gen_mips16_restore(ctx
, xsregs
, aregs
,
14040 do_ra
, do_s0
, do_s1
,
14046 gen_reserved_instruction(ctx
);
14051 tcg_gen_movi_tl(cpu_gpr
[rx
], (uint16_t) imm
);
14054 tcg_gen_xori_tl(cpu_gpr
[24], cpu_gpr
[rx
], (uint16_t) imm
);
14056 #if defined(TARGET_MIPS64)
14058 check_insn(ctx
, ISA_MIPS3
);
14059 check_mips_64(ctx
);
14060 gen_st(ctx
, OPC_SD
, ry
, rx
, offset
);
14064 gen_ld(ctx
, OPC_LB
, ry
, rx
, offset
);
14067 gen_ld(ctx
, OPC_LH
, ry
, rx
, offset
);
14070 gen_ld(ctx
, OPC_LW
, rx
, 29, offset
);
14073 gen_ld(ctx
, OPC_LW
, ry
, rx
, offset
);
14076 gen_ld(ctx
, OPC_LBU
, ry
, rx
, offset
);
14079 gen_ld(ctx
, OPC_LHU
, ry
, rx
, offset
);
14082 gen_ld(ctx
, OPC_LWPC
, rx
, 0, offset
);
14084 #if defined(TARGET_MIPS64)
14086 check_insn(ctx
, ISA_MIPS3
);
14087 check_mips_64(ctx
);
14088 gen_ld(ctx
, OPC_LWU
, ry
, rx
, offset
);
14092 gen_st(ctx
, OPC_SB
, ry
, rx
, offset
);
14095 gen_st(ctx
, OPC_SH
, ry
, rx
, offset
);
14098 gen_st(ctx
, OPC_SW
, rx
, 29, offset
);
14101 gen_st(ctx
, OPC_SW
, ry
, rx
, offset
);
14103 #if defined(TARGET_MIPS64)
14105 decode_i64_mips16(ctx
, ry
, funct
, offset
, 1);
14109 gen_reserved_instruction(ctx
);
14116 static inline bool is_uhi(int sdbbp_code
)
14118 #ifdef CONFIG_USER_ONLY
14121 return semihosting_enabled() && sdbbp_code
== 1;
14125 #ifdef CONFIG_USER_ONLY
14126 /* The above should dead-code away any calls to this..*/
14127 static inline void gen_helper_do_semihosting(void *env
)
14129 g_assert_not_reached();
14133 static int decode_mips16_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
14137 int op
, cnvt_op
, op1
, offset
;
14141 op
= (ctx
->opcode
>> 11) & 0x1f;
14142 sa
= (ctx
->opcode
>> 2) & 0x7;
14143 sa
= sa
== 0 ? 8 : sa
;
14144 rx
= xlat((ctx
->opcode
>> 8) & 0x7);
14145 cnvt_op
= (ctx
->opcode
>> 5) & 0x7;
14146 ry
= xlat((ctx
->opcode
>> 5) & 0x7);
14147 op1
= offset
= ctx
->opcode
& 0x1f;
14152 case M16_OPC_ADDIUSP
:
14154 int16_t imm
= ((uint8_t) ctx
->opcode
) << 2;
14156 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 29, imm
);
14159 case M16_OPC_ADDIUPC
:
14160 gen_addiupc(ctx
, rx
, ((uint8_t) ctx
->opcode
) << 2, 0, 0);
14163 offset
= (ctx
->opcode
& 0x7ff) << 1;
14164 offset
= (int16_t)(offset
<< 4) >> 4;
14165 gen_compute_branch(ctx
, OPC_BEQ
, 2, 0, 0, offset
, 0);
14166 /* No delay slot, so just process as a normal instruction */
14169 offset
= translator_lduw(env
, ctx
->base
.pc_next
+ 2);
14170 offset
= (((ctx
->opcode
& 0x1f) << 21)
14171 | ((ctx
->opcode
>> 5) & 0x1f) << 16
14173 op
= ((ctx
->opcode
>> 10) & 0x1) ? OPC_JALX
: OPC_JAL
;
14174 gen_compute_branch(ctx
, op
, 4, rx
, ry
, offset
, 2);
14178 gen_compute_branch(ctx
, OPC_BEQ
, 2, rx
, 0,
14179 ((int8_t)ctx
->opcode
) << 1, 0);
14180 /* No delay slot, so just process as a normal instruction */
14182 case M16_OPC_BNEQZ
:
14183 gen_compute_branch(ctx
, OPC_BNE
, 2, rx
, 0,
14184 ((int8_t)ctx
->opcode
) << 1, 0);
14185 /* No delay slot, so just process as a normal instruction */
14187 case M16_OPC_SHIFT
:
14188 switch (ctx
->opcode
& 0x3) {
14190 gen_shift_imm(ctx
, OPC_SLL
, rx
, ry
, sa
);
14193 #if defined(TARGET_MIPS64)
14194 check_insn(ctx
, ISA_MIPS3
);
14195 check_mips_64(ctx
);
14196 gen_shift_imm(ctx
, OPC_DSLL
, rx
, ry
, sa
);
14198 gen_reserved_instruction(ctx
);
14202 gen_shift_imm(ctx
, OPC_SRL
, rx
, ry
, sa
);
14205 gen_shift_imm(ctx
, OPC_SRA
, rx
, ry
, sa
);
14209 #if defined(TARGET_MIPS64)
14211 check_insn(ctx
, ISA_MIPS3
);
14212 check_mips_64(ctx
);
14213 gen_ld(ctx
, OPC_LD
, ry
, rx
, offset
<< 3);
14218 int16_t imm
= (int8_t)((ctx
->opcode
& 0xf) << 4) >> 4;
14220 if ((ctx
->opcode
>> 4) & 1) {
14221 #if defined(TARGET_MIPS64)
14222 check_insn(ctx
, ISA_MIPS3
);
14223 check_mips_64(ctx
);
14224 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, rx
, imm
);
14226 gen_reserved_instruction(ctx
);
14229 gen_arith_imm(ctx
, OPC_ADDIU
, ry
, rx
, imm
);
14233 case M16_OPC_ADDIU8
:
14235 int16_t imm
= (int8_t) ctx
->opcode
;
14237 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, rx
, imm
);
14242 int16_t imm
= (uint8_t) ctx
->opcode
;
14243 gen_slt_imm(ctx
, OPC_SLTI
, 24, rx
, imm
);
14246 case M16_OPC_SLTIU
:
14248 int16_t imm
= (uint8_t) ctx
->opcode
;
14249 gen_slt_imm(ctx
, OPC_SLTIU
, 24, rx
, imm
);
14256 funct
= (ctx
->opcode
>> 8) & 0x7;
14259 gen_compute_branch(ctx
, OPC_BEQ
, 2, 24, 0,
14260 ((int8_t)ctx
->opcode
) << 1, 0);
14263 gen_compute_branch(ctx
, OPC_BNE
, 2, 24, 0,
14264 ((int8_t)ctx
->opcode
) << 1, 0);
14267 gen_st(ctx
, OPC_SW
, 31, 29, (ctx
->opcode
& 0xff) << 2);
14270 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29,
14271 ((int8_t)ctx
->opcode
) << 3);
14274 check_insn(ctx
, ISA_MIPS_R1
);
14276 int do_ra
= ctx
->opcode
& (1 << 6);
14277 int do_s0
= ctx
->opcode
& (1 << 5);
14278 int do_s1
= ctx
->opcode
& (1 << 4);
14279 int framesize
= ctx
->opcode
& 0xf;
14281 if (framesize
== 0) {
14284 framesize
= framesize
<< 3;
14287 if (ctx
->opcode
& (1 << 7)) {
14288 gen_mips16_save(ctx
, 0, 0,
14289 do_ra
, do_s0
, do_s1
, framesize
);
14291 gen_mips16_restore(ctx
, 0, 0,
14292 do_ra
, do_s0
, do_s1
, framesize
);
14298 int rz
= xlat(ctx
->opcode
& 0x7);
14300 reg32
= (((ctx
->opcode
>> 3) & 0x3) << 3) |
14301 ((ctx
->opcode
>> 5) & 0x7);
14302 gen_arith(ctx
, OPC_ADDU
, reg32
, rz
, 0);
14306 reg32
= ctx
->opcode
& 0x1f;
14307 gen_arith(ctx
, OPC_ADDU
, ry
, reg32
, 0);
14310 gen_reserved_instruction(ctx
);
14317 int16_t imm
= (uint8_t) ctx
->opcode
;
14319 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 0, imm
);
14324 int16_t imm
= (uint8_t) ctx
->opcode
;
14325 gen_logic_imm(ctx
, OPC_XORI
, 24, rx
, imm
);
14328 #if defined(TARGET_MIPS64)
14330 check_insn(ctx
, ISA_MIPS3
);
14331 check_mips_64(ctx
);
14332 gen_st(ctx
, OPC_SD
, ry
, rx
, offset
<< 3);
14336 gen_ld(ctx
, OPC_LB
, ry
, rx
, offset
);
14339 gen_ld(ctx
, OPC_LH
, ry
, rx
, offset
<< 1);
14342 gen_ld(ctx
, OPC_LW
, rx
, 29, ((uint8_t)ctx
->opcode
) << 2);
14345 gen_ld(ctx
, OPC_LW
, ry
, rx
, offset
<< 2);
14348 gen_ld(ctx
, OPC_LBU
, ry
, rx
, offset
);
14351 gen_ld(ctx
, OPC_LHU
, ry
, rx
, offset
<< 1);
14354 gen_ld(ctx
, OPC_LWPC
, rx
, 0, ((uint8_t)ctx
->opcode
) << 2);
14356 #if defined(TARGET_MIPS64)
14358 check_insn(ctx
, ISA_MIPS3
);
14359 check_mips_64(ctx
);
14360 gen_ld(ctx
, OPC_LWU
, ry
, rx
, offset
<< 2);
14364 gen_st(ctx
, OPC_SB
, ry
, rx
, offset
);
14367 gen_st(ctx
, OPC_SH
, ry
, rx
, offset
<< 1);
14370 gen_st(ctx
, OPC_SW
, rx
, 29, ((uint8_t)ctx
->opcode
) << 2);
14373 gen_st(ctx
, OPC_SW
, ry
, rx
, offset
<< 2);
14377 int rz
= xlat((ctx
->opcode
>> 2) & 0x7);
14380 switch (ctx
->opcode
& 0x3) {
14382 mips32_op
= OPC_ADDU
;
14385 mips32_op
= OPC_SUBU
;
14387 #if defined(TARGET_MIPS64)
14389 mips32_op
= OPC_DADDU
;
14390 check_insn(ctx
, ISA_MIPS3
);
14391 check_mips_64(ctx
);
14394 mips32_op
= OPC_DSUBU
;
14395 check_insn(ctx
, ISA_MIPS3
);
14396 check_mips_64(ctx
);
14400 gen_reserved_instruction(ctx
);
14404 gen_arith(ctx
, mips32_op
, rz
, rx
, ry
);
14413 int nd
= (ctx
->opcode
>> 7) & 0x1;
14414 int link
= (ctx
->opcode
>> 6) & 0x1;
14415 int ra
= (ctx
->opcode
>> 5) & 0x1;
14418 check_insn(ctx
, ISA_MIPS_R1
);
14427 gen_compute_branch(ctx
, op
, 2, ra
? 31 : rx
, 31, 0,
14432 if (is_uhi(extract32(ctx
->opcode
, 5, 6))) {
14433 gen_helper_do_semihosting(cpu_env
);
14436 * XXX: not clear which exception should be raised
14437 * when in debug mode...
14439 check_insn(ctx
, ISA_MIPS_R1
);
14440 generate_exception_end(ctx
, EXCP_DBp
);
14444 gen_slt(ctx
, OPC_SLT
, 24, rx
, ry
);
14447 gen_slt(ctx
, OPC_SLTU
, 24, rx
, ry
);
14450 generate_exception_end(ctx
, EXCP_BREAK
);
14453 gen_shift(ctx
, OPC_SLLV
, ry
, rx
, ry
);
14456 gen_shift(ctx
, OPC_SRLV
, ry
, rx
, ry
);
14459 gen_shift(ctx
, OPC_SRAV
, ry
, rx
, ry
);
14461 #if defined(TARGET_MIPS64)
14463 check_insn(ctx
, ISA_MIPS3
);
14464 check_mips_64(ctx
);
14465 gen_shift_imm(ctx
, OPC_DSRL
, ry
, ry
, sa
);
14469 gen_logic(ctx
, OPC_XOR
, 24, rx
, ry
);
14472 gen_arith(ctx
, OPC_SUBU
, rx
, 0, ry
);
14475 gen_logic(ctx
, OPC_AND
, rx
, rx
, ry
);
14478 gen_logic(ctx
, OPC_OR
, rx
, rx
, ry
);
14481 gen_logic(ctx
, OPC_XOR
, rx
, rx
, ry
);
14484 gen_logic(ctx
, OPC_NOR
, rx
, ry
, 0);
14487 gen_HILO(ctx
, OPC_MFHI
, 0, rx
);
14490 check_insn(ctx
, ISA_MIPS_R1
);
14492 case RR_RY_CNVT_ZEB
:
14493 tcg_gen_ext8u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
14495 case RR_RY_CNVT_ZEH
:
14496 tcg_gen_ext16u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
14498 case RR_RY_CNVT_SEB
:
14499 tcg_gen_ext8s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
14501 case RR_RY_CNVT_SEH
:
14502 tcg_gen_ext16s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
14504 #if defined(TARGET_MIPS64)
14505 case RR_RY_CNVT_ZEW
:
14506 check_insn(ctx
, ISA_MIPS_R1
);
14507 check_mips_64(ctx
);
14508 tcg_gen_ext32u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
14510 case RR_RY_CNVT_SEW
:
14511 check_insn(ctx
, ISA_MIPS_R1
);
14512 check_mips_64(ctx
);
14513 tcg_gen_ext32s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
14517 gen_reserved_instruction(ctx
);
14522 gen_HILO(ctx
, OPC_MFLO
, 0, rx
);
14524 #if defined(TARGET_MIPS64)
14526 check_insn(ctx
, ISA_MIPS3
);
14527 check_mips_64(ctx
);
14528 gen_shift_imm(ctx
, OPC_DSRA
, ry
, ry
, sa
);
14531 check_insn(ctx
, ISA_MIPS3
);
14532 check_mips_64(ctx
);
14533 gen_shift(ctx
, OPC_DSLLV
, ry
, rx
, ry
);
14536 check_insn(ctx
, ISA_MIPS3
);
14537 check_mips_64(ctx
);
14538 gen_shift(ctx
, OPC_DSRLV
, ry
, rx
, ry
);
14541 check_insn(ctx
, ISA_MIPS3
);
14542 check_mips_64(ctx
);
14543 gen_shift(ctx
, OPC_DSRAV
, ry
, rx
, ry
);
14547 gen_muldiv(ctx
, OPC_MULT
, 0, rx
, ry
);
14550 gen_muldiv(ctx
, OPC_MULTU
, 0, rx
, ry
);
14553 gen_muldiv(ctx
, OPC_DIV
, 0, rx
, ry
);
14556 gen_muldiv(ctx
, OPC_DIVU
, 0, rx
, ry
);
14558 #if defined(TARGET_MIPS64)
14560 check_insn(ctx
, ISA_MIPS3
);
14561 check_mips_64(ctx
);
14562 gen_muldiv(ctx
, OPC_DMULT
, 0, rx
, ry
);
14565 check_insn(ctx
, ISA_MIPS3
);
14566 check_mips_64(ctx
);
14567 gen_muldiv(ctx
, OPC_DMULTU
, 0, rx
, ry
);
14570 check_insn(ctx
, ISA_MIPS3
);
14571 check_mips_64(ctx
);
14572 gen_muldiv(ctx
, OPC_DDIV
, 0, rx
, ry
);
14575 check_insn(ctx
, ISA_MIPS3
);
14576 check_mips_64(ctx
);
14577 gen_muldiv(ctx
, OPC_DDIVU
, 0, rx
, ry
);
14581 gen_reserved_instruction(ctx
);
14585 case M16_OPC_EXTEND
:
14586 decode_extended_mips16_opc(env
, ctx
);
14589 #if defined(TARGET_MIPS64)
14591 funct
= (ctx
->opcode
>> 8) & 0x7;
14592 decode_i64_mips16(ctx
, ry
, funct
, offset
, 0);
14596 gen_reserved_instruction(ctx
);
14603 /* microMIPS extension to MIPS32/MIPS64 */
14606 * microMIPS32/microMIPS64 major opcodes
14608 * 1. MIPS Architecture for Programmers Volume II-B:
14609 * The microMIPS32 Instruction Set (Revision 3.05)
14611 * Table 6.2 microMIPS32 Encoding of Major Opcode Field
14613 * 2. MIPS Architecture For Programmers Volume II-A:
14614 * The MIPS64 Instruction Set (Revision 3.51)
14644 POOL32S
= 0x16, /* MIPS64 */
14645 DADDIU32
= 0x17, /* MIPS64 */
14674 /* 0x29 is reserved */
14687 /* 0x31 is reserved */
14700 SD32
= 0x36, /* MIPS64 */
14701 LD32
= 0x37, /* MIPS64 */
14703 /* 0x39 is reserved */
14719 /* PCREL Instructions perform PC-Relative address calculation. bits 20..16 */
14741 /* POOL32A encoding of minor opcode field */
14745 * These opcodes are distinguished only by bits 9..6; those bits are
14746 * what are recorded below.
14784 /* The following can be distinguished by their lower 6 bits. */
14794 /* POOL32AXF encoding of minor opcode field extension */
14797 * 1. MIPS Architecture for Programmers Volume II-B:
14798 * The microMIPS32 Instruction Set (Revision 3.05)
14800 * Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
14802 * 2. MIPS Architecture for Programmers VolumeIV-e:
14803 * The MIPS DSP Application-Specific Extension
14804 * to the microMIPS32 Architecture (Revision 2.34)
14806 * Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
14821 /* begin of microMIPS32 DSP */
14823 /* bits 13..12 for 0x01 */
14829 /* bits 13..12 for 0x2a */
14835 /* bits 13..12 for 0x32 */
14839 /* end of microMIPS32 DSP */
14841 /* bits 15..12 for 0x2c */
14858 /* bits 15..12 for 0x34 */
14866 /* bits 15..12 for 0x3c */
14868 JR
= 0x0, /* alias */
14876 /* bits 15..12 for 0x05 */
14880 /* bits 15..12 for 0x0d */
14892 /* bits 15..12 for 0x15 */
14898 /* bits 15..12 for 0x1d */
14902 /* bits 15..12 for 0x2d */
14907 /* bits 15..12 for 0x35 */
14914 /* POOL32B encoding of minor opcode field (bits 15..12) */
14930 /* POOL32C encoding of minor opcode field (bits 15..12) */
14951 /* POOL32C LD-EVA encoding of minor opcode field (bits 11..9) */
14964 /* POOL32C ST-EVA encoding of minor opcode field (bits 11..9) */
14977 /* POOL32F encoding of minor opcode field (bits 5..0) */
14980 /* These are the bit 7..6 values */
14989 /* These are the bit 8..6 values */
15014 MOVZ_FMT_05
= 0x05,
15048 CABS_COND_FMT
= 0x1c, /* MIPS3D */
15055 /* POOL32Fxf encoding of minor opcode extension field */
15093 /* POOL32I encoding of minor opcode field (bits 25..21) */
15123 /* These overlap and are distinguished by bit16 of the instruction */
15132 /* POOL16A encoding of minor opcode field */
15139 /* POOL16B encoding of minor opcode field */
15146 /* POOL16C encoding of minor opcode field */
15166 /* R6 POOL16C encoding of minor opcode field (bits 0..5) */
15190 /* POOL16D encoding of minor opcode field */
15197 /* POOL16E encoding of minor opcode field */
15204 static int mmreg(int r
)
15206 static const int map
[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
15211 /* Used for 16-bit store instructions. */
15212 static int mmreg2(int r
)
15214 static const int map
[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
15219 #define uMIPS_RD(op) ((op >> 7) & 0x7)
15220 #define uMIPS_RS(op) ((op >> 4) & 0x7)
15221 #define uMIPS_RS2(op) uMIPS_RS(op)
15222 #define uMIPS_RS1(op) ((op >> 1) & 0x7)
15223 #define uMIPS_RD5(op) ((op >> 5) & 0x1f)
15224 #define uMIPS_RS5(op) (op & 0x1f)
15226 /* Signed immediate */
15227 #define SIMM(op, start, width) \
15228 ((int32_t)(((op >> start) & ((~0U) >> (32 - width))) \
15231 /* Zero-extended immediate */
15232 #define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32 - width)))
15234 static void gen_addiur1sp(DisasContext
*ctx
)
15236 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
15238 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, 29, ((ctx
->opcode
>> 1) & 0x3f) << 2);
15241 static void gen_addiur2(DisasContext
*ctx
)
15243 static const int decoded_imm
[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
15244 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
15245 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
15247 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, rs
, decoded_imm
[ZIMM(ctx
->opcode
, 1, 3)]);
15250 static void gen_addiusp(DisasContext
*ctx
)
15252 int encoded
= ZIMM(ctx
->opcode
, 1, 9);
15255 if (encoded
<= 1) {
15256 decoded
= 256 + encoded
;
15257 } else if (encoded
<= 255) {
15259 } else if (encoded
<= 509) {
15260 decoded
= encoded
- 512;
15262 decoded
= encoded
- 768;
15265 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, decoded
<< 2);
15268 static void gen_addius5(DisasContext
*ctx
)
15270 int imm
= SIMM(ctx
->opcode
, 1, 4);
15271 int rd
= (ctx
->opcode
>> 5) & 0x1f;
15273 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, rd
, imm
);
15276 static void gen_andi16(DisasContext
*ctx
)
15278 static const int decoded_imm
[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
15279 31, 32, 63, 64, 255, 32768, 65535 };
15280 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
15281 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
15282 int encoded
= ZIMM(ctx
->opcode
, 0, 4);
15284 gen_logic_imm(ctx
, OPC_ANDI
, rd
, rs
, decoded_imm
[encoded
]);
15287 static void gen_ldst_multiple(DisasContext
*ctx
, uint32_t opc
, int reglist
,
15288 int base
, int16_t offset
)
15293 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
15294 gen_reserved_instruction(ctx
);
15298 t0
= tcg_temp_new();
15300 gen_base_offset_addr(ctx
, t0
, base
, offset
);
15302 t1
= tcg_const_tl(reglist
);
15303 t2
= tcg_const_i32(ctx
->mem_idx
);
15305 save_cpu_state(ctx
, 1);
15308 gen_helper_lwm(cpu_env
, t0
, t1
, t2
);
15311 gen_helper_swm(cpu_env
, t0
, t1
, t2
);
15313 #ifdef TARGET_MIPS64
15315 gen_helper_ldm(cpu_env
, t0
, t1
, t2
);
15318 gen_helper_sdm(cpu_env
, t0
, t1
, t2
);
15324 tcg_temp_free_i32(t2
);
15328 static void gen_pool16c_insn(DisasContext
*ctx
)
15330 int rd
= mmreg((ctx
->opcode
>> 3) & 0x7);
15331 int rs
= mmreg(ctx
->opcode
& 0x7);
15333 switch (((ctx
->opcode
) >> 4) & 0x3f) {
15338 gen_logic(ctx
, OPC_NOR
, rd
, rs
, 0);
15344 gen_logic(ctx
, OPC_XOR
, rd
, rd
, rs
);
15350 gen_logic(ctx
, OPC_AND
, rd
, rd
, rs
);
15356 gen_logic(ctx
, OPC_OR
, rd
, rd
, rs
);
15363 static const int lwm_convert
[] = { 0x11, 0x12, 0x13, 0x14 };
15364 int offset
= ZIMM(ctx
->opcode
, 0, 4);
15366 gen_ldst_multiple(ctx
, LWM32
, lwm_convert
[(ctx
->opcode
>> 4) & 0x3],
15375 static const int swm_convert
[] = { 0x11, 0x12, 0x13, 0x14 };
15376 int offset
= ZIMM(ctx
->opcode
, 0, 4);
15378 gen_ldst_multiple(ctx
, SWM32
, swm_convert
[(ctx
->opcode
>> 4) & 0x3],
15385 int reg
= ctx
->opcode
& 0x1f;
15387 gen_compute_branch(ctx
, OPC_JR
, 2, reg
, 0, 0, 4);
15393 int reg
= ctx
->opcode
& 0x1f;
15394 gen_compute_branch(ctx
, OPC_JR
, 2, reg
, 0, 0, 0);
15396 * Let normal delay slot handling in our caller take us
15397 * to the branch target.
15403 gen_compute_branch(ctx
, OPC_JALR
, 2, ctx
->opcode
& 0x1f, 31, 0, 4);
15404 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
15408 gen_compute_branch(ctx
, OPC_JALR
, 2, ctx
->opcode
& 0x1f, 31, 0, 2);
15409 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
15413 gen_HILO(ctx
, OPC_MFHI
, 0, uMIPS_RS5(ctx
->opcode
));
15417 gen_HILO(ctx
, OPC_MFLO
, 0, uMIPS_RS5(ctx
->opcode
));
15420 generate_exception_end(ctx
, EXCP_BREAK
);
15423 if (is_uhi(extract32(ctx
->opcode
, 0, 4))) {
15424 gen_helper_do_semihosting(cpu_env
);
15427 * XXX: not clear which exception should be raised
15428 * when in debug mode...
15430 check_insn(ctx
, ISA_MIPS_R1
);
15431 generate_exception_end(ctx
, EXCP_DBp
);
15434 case JRADDIUSP
+ 0:
15435 case JRADDIUSP
+ 1:
15437 int imm
= ZIMM(ctx
->opcode
, 0, 5);
15438 gen_compute_branch(ctx
, OPC_JR
, 2, 31, 0, 0, 0);
15439 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, imm
<< 2);
15441 * Let normal delay slot handling in our caller take us
15442 * to the branch target.
15447 gen_reserved_instruction(ctx
);
15452 static inline void gen_movep(DisasContext
*ctx
, int enc_dest
, int enc_rt
,
15455 int rd
, rs
, re
, rt
;
15456 static const int rd_enc
[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
15457 static const int re_enc
[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
15458 static const int rs_rt_enc
[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
15459 rd
= rd_enc
[enc_dest
];
15460 re
= re_enc
[enc_dest
];
15461 rs
= rs_rt_enc
[enc_rs
];
15462 rt
= rs_rt_enc
[enc_rt
];
15464 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
15466 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
15469 tcg_gen_mov_tl(cpu_gpr
[re
], cpu_gpr
[rt
]);
15471 tcg_gen_movi_tl(cpu_gpr
[re
], 0);
15475 static void gen_pool16c_r6_insn(DisasContext
*ctx
)
15477 int rt
= mmreg((ctx
->opcode
>> 7) & 0x7);
15478 int rs
= mmreg((ctx
->opcode
>> 4) & 0x7);
15480 switch (ctx
->opcode
& 0xf) {
15482 gen_logic(ctx
, OPC_NOR
, rt
, rs
, 0);
15485 gen_logic(ctx
, OPC_AND
, rt
, rt
, rs
);
15489 int lwm_converted
= 0x11 + extract32(ctx
->opcode
, 8, 2);
15490 int offset
= extract32(ctx
->opcode
, 4, 4);
15491 gen_ldst_multiple(ctx
, LWM32
, lwm_converted
, 29, offset
<< 2);
15494 case R6_JRC16
: /* JRCADDIUSP */
15495 if ((ctx
->opcode
>> 4) & 1) {
15497 int imm
= extract32(ctx
->opcode
, 5, 5);
15498 gen_compute_branch(ctx
, OPC_JR
, 2, 31, 0, 0, 0);
15499 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, imm
<< 2);
15502 rs
= extract32(ctx
->opcode
, 5, 5);
15503 gen_compute_branch(ctx
, OPC_JR
, 2, rs
, 0, 0, 0);
15515 int enc_dest
= uMIPS_RD(ctx
->opcode
);
15516 int enc_rt
= uMIPS_RS2(ctx
->opcode
);
15517 int enc_rs
= (ctx
->opcode
& 3) | ((ctx
->opcode
>> 1) & 4);
15518 gen_movep(ctx
, enc_dest
, enc_rt
, enc_rs
);
15522 gen_logic(ctx
, OPC_XOR
, rt
, rt
, rs
);
15525 gen_logic(ctx
, OPC_OR
, rt
, rt
, rs
);
15529 int swm_converted
= 0x11 + extract32(ctx
->opcode
, 8, 2);
15530 int offset
= extract32(ctx
->opcode
, 4, 4);
15531 gen_ldst_multiple(ctx
, SWM32
, swm_converted
, 29, offset
<< 2);
15534 case JALRC16
: /* BREAK16, SDBBP16 */
15535 switch (ctx
->opcode
& 0x3f) {
15537 case JALRC16
+ 0x20:
15539 gen_compute_branch(ctx
, OPC_JALR
, 2, (ctx
->opcode
>> 5) & 0x1f,
15544 generate_exception(ctx
, EXCP_BREAK
);
15548 if (is_uhi(extract32(ctx
->opcode
, 6, 4))) {
15549 gen_helper_do_semihosting(cpu_env
);
15551 if (ctx
->hflags
& MIPS_HFLAG_SBRI
) {
15552 generate_exception(ctx
, EXCP_RI
);
15554 generate_exception(ctx
, EXCP_DBp
);
15561 generate_exception(ctx
, EXCP_RI
);
15566 static void gen_ldxs(DisasContext
*ctx
, int base
, int index
, int rd
)
15568 TCGv t0
= tcg_temp_new();
15569 TCGv t1
= tcg_temp_new();
15571 gen_load_gpr(t0
, base
);
15574 gen_load_gpr(t1
, index
);
15575 tcg_gen_shli_tl(t1
, t1
, 2);
15576 gen_op_addr_add(ctx
, t0
, t1
, t0
);
15579 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TESL
);
15580 gen_store_gpr(t1
, rd
);
15586 static void gen_ldst_pair(DisasContext
*ctx
, uint32_t opc
, int rd
,
15587 int base
, int16_t offset
)
15591 if (ctx
->hflags
& MIPS_HFLAG_BMASK
|| rd
== 31) {
15592 gen_reserved_instruction(ctx
);
15596 t0
= tcg_temp_new();
15597 t1
= tcg_temp_new();
15599 gen_base_offset_addr(ctx
, t0
, base
, offset
);
15604 gen_reserved_instruction(ctx
);
15607 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TESL
);
15608 gen_store_gpr(t1
, rd
);
15609 tcg_gen_movi_tl(t1
, 4);
15610 gen_op_addr_add(ctx
, t0
, t0
, t1
);
15611 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TESL
);
15612 gen_store_gpr(t1
, rd
+ 1);
15615 gen_load_gpr(t1
, rd
);
15616 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
15617 tcg_gen_movi_tl(t1
, 4);
15618 gen_op_addr_add(ctx
, t0
, t0
, t1
);
15619 gen_load_gpr(t1
, rd
+ 1);
15620 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
15622 #ifdef TARGET_MIPS64
15625 gen_reserved_instruction(ctx
);
15628 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
15629 gen_store_gpr(t1
, rd
);
15630 tcg_gen_movi_tl(t1
, 8);
15631 gen_op_addr_add(ctx
, t0
, t0
, t1
);
15632 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
15633 gen_store_gpr(t1
, rd
+ 1);
15636 gen_load_gpr(t1
, rd
);
15637 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
15638 tcg_gen_movi_tl(t1
, 8);
15639 gen_op_addr_add(ctx
, t0
, t0
, t1
);
15640 gen_load_gpr(t1
, rd
+ 1);
15641 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
15649 static void gen_sync(int stype
)
15651 TCGBar tcg_mo
= TCG_BAR_SC
;
15654 case 0x4: /* SYNC_WMB */
15655 tcg_mo
|= TCG_MO_ST_ST
;
15657 case 0x10: /* SYNC_MB */
15658 tcg_mo
|= TCG_MO_ALL
;
15660 case 0x11: /* SYNC_ACQUIRE */
15661 tcg_mo
|= TCG_MO_LD_LD
| TCG_MO_LD_ST
;
15663 case 0x12: /* SYNC_RELEASE */
15664 tcg_mo
|= TCG_MO_ST_ST
| TCG_MO_LD_ST
;
15666 case 0x13: /* SYNC_RMB */
15667 tcg_mo
|= TCG_MO_LD_LD
;
15670 tcg_mo
|= TCG_MO_ALL
;
15674 tcg_gen_mb(tcg_mo
);
15677 static void gen_pool32axf(CPUMIPSState
*env
, DisasContext
*ctx
, int rt
, int rs
)
15679 int extension
= (ctx
->opcode
>> 6) & 0x3f;
15680 int minor
= (ctx
->opcode
>> 12) & 0xf;
15681 uint32_t mips32_op
;
15683 switch (extension
) {
15685 mips32_op
= OPC_TEQ
;
15688 mips32_op
= OPC_TGE
;
15691 mips32_op
= OPC_TGEU
;
15694 mips32_op
= OPC_TLT
;
15697 mips32_op
= OPC_TLTU
;
15700 mips32_op
= OPC_TNE
;
15702 gen_trap(ctx
, mips32_op
, rs
, rt
, -1);
15704 #ifndef CONFIG_USER_ONLY
15707 check_cp0_enabled(ctx
);
15709 /* Treat as NOP. */
15712 gen_mfc0(ctx
, cpu_gpr
[rt
], rs
, (ctx
->opcode
>> 11) & 0x7);
15716 check_cp0_enabled(ctx
);
15718 TCGv t0
= tcg_temp_new();
15720 gen_load_gpr(t0
, rt
);
15721 gen_mtc0(ctx
, t0
, rs
, (ctx
->opcode
>> 11) & 0x7);
15727 switch (minor
& 3) {
15729 gen_muldiv(ctx
, OPC_MADD
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
15732 gen_muldiv(ctx
, OPC_MADDU
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
15735 gen_muldiv(ctx
, OPC_MSUB
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
15738 gen_muldiv(ctx
, OPC_MSUBU
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
15741 goto pool32axf_invalid
;
15745 switch (minor
& 3) {
15747 gen_muldiv(ctx
, OPC_MULT
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
15750 gen_muldiv(ctx
, OPC_MULTU
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
15753 goto pool32axf_invalid
;
15759 check_insn(ctx
, ISA_MIPS_R6
);
15760 gen_bitswap(ctx
, OPC_BITSWAP
, rs
, rt
);
15763 gen_bshfl(ctx
, OPC_SEB
, rs
, rt
);
15766 gen_bshfl(ctx
, OPC_SEH
, rs
, rt
);
15769 mips32_op
= OPC_CLO
;
15772 mips32_op
= OPC_CLZ
;
15774 check_insn(ctx
, ISA_MIPS_R1
);
15775 gen_cl(ctx
, mips32_op
, rt
, rs
);
15778 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15779 gen_rdhwr(ctx
, rt
, rs
, 0);
15782 gen_bshfl(ctx
, OPC_WSBH
, rs
, rt
);
15785 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15786 mips32_op
= OPC_MULT
;
15789 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15790 mips32_op
= OPC_MULTU
;
15793 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15794 mips32_op
= OPC_DIV
;
15797 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15798 mips32_op
= OPC_DIVU
;
15801 check_insn(ctx
, ISA_MIPS_R1
);
15802 gen_muldiv(ctx
, mips32_op
, 0, rs
, rt
);
15805 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15806 mips32_op
= OPC_MADD
;
15809 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15810 mips32_op
= OPC_MADDU
;
15813 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15814 mips32_op
= OPC_MSUB
;
15817 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15818 mips32_op
= OPC_MSUBU
;
15820 check_insn(ctx
, ISA_MIPS_R1
);
15821 gen_muldiv(ctx
, mips32_op
, 0, rs
, rt
);
15824 goto pool32axf_invalid
;
15835 generate_exception_err(ctx
, EXCP_CpU
, 2);
15838 goto pool32axf_invalid
;
15843 case JALR
: /* JALRC */
15844 case JALR_HB
: /* JALRC_HB */
15845 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
15846 /* JALRC, JALRC_HB */
15847 gen_compute_branch(ctx
, OPC_JALR
, 4, rs
, rt
, 0, 0);
15849 /* JALR, JALR_HB */
15850 gen_compute_branch(ctx
, OPC_JALR
, 4, rs
, rt
, 0, 4);
15851 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
15856 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
15857 gen_compute_branch(ctx
, OPC_JALR
, 4, rs
, rt
, 0, 2);
15858 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
15861 goto pool32axf_invalid
;
15867 check_cp0_enabled(ctx
);
15868 check_insn(ctx
, ISA_MIPS_R2
);
15869 gen_load_srsgpr(rs
, rt
);
15872 check_cp0_enabled(ctx
);
15873 check_insn(ctx
, ISA_MIPS_R2
);
15874 gen_store_srsgpr(rs
, rt
);
15877 goto pool32axf_invalid
;
15880 #ifndef CONFIG_USER_ONLY
15884 mips32_op
= OPC_TLBP
;
15887 mips32_op
= OPC_TLBR
;
15890 mips32_op
= OPC_TLBWI
;
15893 mips32_op
= OPC_TLBWR
;
15896 mips32_op
= OPC_TLBINV
;
15899 mips32_op
= OPC_TLBINVF
;
15902 mips32_op
= OPC_WAIT
;
15905 mips32_op
= OPC_DERET
;
15908 mips32_op
= OPC_ERET
;
15910 gen_cp0(env
, ctx
, mips32_op
, rt
, rs
);
15913 goto pool32axf_invalid
;
15919 check_cp0_enabled(ctx
);
15921 TCGv t0
= tcg_temp_new();
15923 save_cpu_state(ctx
, 1);
15924 gen_helper_di(t0
, cpu_env
);
15925 gen_store_gpr(t0
, rs
);
15927 * Stop translation as we may have switched the execution
15930 ctx
->base
.is_jmp
= DISAS_STOP
;
15935 check_cp0_enabled(ctx
);
15937 TCGv t0
= tcg_temp_new();
15939 save_cpu_state(ctx
, 1);
15940 gen_helper_ei(t0
, cpu_env
);
15941 gen_store_gpr(t0
, rs
);
15943 * DISAS_STOP isn't sufficient, we need to ensure we break out
15944 * of translated code to check for pending interrupts.
15946 gen_save_pc(ctx
->base
.pc_next
+ 4);
15947 ctx
->base
.is_jmp
= DISAS_EXIT
;
15952 goto pool32axf_invalid
;
15959 gen_sync(extract32(ctx
->opcode
, 16, 5));
15962 generate_exception_end(ctx
, EXCP_SYSCALL
);
15965 if (is_uhi(extract32(ctx
->opcode
, 16, 10))) {
15966 gen_helper_do_semihosting(cpu_env
);
15968 check_insn(ctx
, ISA_MIPS_R1
);
15969 if (ctx
->hflags
& MIPS_HFLAG_SBRI
) {
15970 gen_reserved_instruction(ctx
);
15972 generate_exception_end(ctx
, EXCP_DBp
);
15977 goto pool32axf_invalid
;
15981 switch (minor
& 3) {
15983 gen_HILO(ctx
, OPC_MFHI
, minor
>> 2, rs
);
15986 gen_HILO(ctx
, OPC_MFLO
, minor
>> 2, rs
);
15989 gen_HILO(ctx
, OPC_MTHI
, minor
>> 2, rs
);
15992 gen_HILO(ctx
, OPC_MTLO
, minor
>> 2, rs
);
15995 goto pool32axf_invalid
;
15999 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16002 gen_HILO(ctx
, OPC_MFHI
, 0, rs
);
16005 gen_HILO(ctx
, OPC_MFLO
, 0, rs
);
16008 gen_HILO(ctx
, OPC_MTHI
, 0, rs
);
16011 gen_HILO(ctx
, OPC_MTLO
, 0, rs
);
16014 goto pool32axf_invalid
;
16019 MIPS_INVAL("pool32axf");
16020 gen_reserved_instruction(ctx
);
16026 * Values for microMIPS fmt field. Variable-width, depending on which
16027 * formats the instruction supports.
16046 static void gen_pool32fxf(DisasContext
*ctx
, int rt
, int rs
)
16048 int extension
= (ctx
->opcode
>> 6) & 0x3ff;
16049 uint32_t mips32_op
;
16051 #define FLOAT_1BIT_FMT(opc, fmt) ((fmt << 8) | opc)
16052 #define FLOAT_2BIT_FMT(opc, fmt) ((fmt << 7) | opc)
16053 #define COND_FLOAT_MOV(opc, cond) ((cond << 7) | opc)
16055 switch (extension
) {
16056 case FLOAT_1BIT_FMT(CFC1
, 0):
16057 mips32_op
= OPC_CFC1
;
16059 case FLOAT_1BIT_FMT(CTC1
, 0):
16060 mips32_op
= OPC_CTC1
;
16062 case FLOAT_1BIT_FMT(MFC1
, 0):
16063 mips32_op
= OPC_MFC1
;
16065 case FLOAT_1BIT_FMT(MTC1
, 0):
16066 mips32_op
= OPC_MTC1
;
16068 case FLOAT_1BIT_FMT(MFHC1
, 0):
16069 mips32_op
= OPC_MFHC1
;
16071 case FLOAT_1BIT_FMT(MTHC1
, 0):
16072 mips32_op
= OPC_MTHC1
;
16074 gen_cp1(ctx
, mips32_op
, rt
, rs
);
16077 /* Reciprocal square root */
16078 case FLOAT_1BIT_FMT(RSQRT_FMT
, FMT_SD_S
):
16079 mips32_op
= OPC_RSQRT_S
;
16081 case FLOAT_1BIT_FMT(RSQRT_FMT
, FMT_SD_D
):
16082 mips32_op
= OPC_RSQRT_D
;
16086 case FLOAT_1BIT_FMT(SQRT_FMT
, FMT_SD_S
):
16087 mips32_op
= OPC_SQRT_S
;
16089 case FLOAT_1BIT_FMT(SQRT_FMT
, FMT_SD_D
):
16090 mips32_op
= OPC_SQRT_D
;
16094 case FLOAT_1BIT_FMT(RECIP_FMT
, FMT_SD_S
):
16095 mips32_op
= OPC_RECIP_S
;
16097 case FLOAT_1BIT_FMT(RECIP_FMT
, FMT_SD_D
):
16098 mips32_op
= OPC_RECIP_D
;
16102 case FLOAT_1BIT_FMT(FLOOR_L
, FMT_SD_S
):
16103 mips32_op
= OPC_FLOOR_L_S
;
16105 case FLOAT_1BIT_FMT(FLOOR_L
, FMT_SD_D
):
16106 mips32_op
= OPC_FLOOR_L_D
;
16108 case FLOAT_1BIT_FMT(FLOOR_W
, FMT_SD_S
):
16109 mips32_op
= OPC_FLOOR_W_S
;
16111 case FLOAT_1BIT_FMT(FLOOR_W
, FMT_SD_D
):
16112 mips32_op
= OPC_FLOOR_W_D
;
16116 case FLOAT_1BIT_FMT(CEIL_L
, FMT_SD_S
):
16117 mips32_op
= OPC_CEIL_L_S
;
16119 case FLOAT_1BIT_FMT(CEIL_L
, FMT_SD_D
):
16120 mips32_op
= OPC_CEIL_L_D
;
16122 case FLOAT_1BIT_FMT(CEIL_W
, FMT_SD_S
):
16123 mips32_op
= OPC_CEIL_W_S
;
16125 case FLOAT_1BIT_FMT(CEIL_W
, FMT_SD_D
):
16126 mips32_op
= OPC_CEIL_W_D
;
16130 case FLOAT_1BIT_FMT(TRUNC_L
, FMT_SD_S
):
16131 mips32_op
= OPC_TRUNC_L_S
;
16133 case FLOAT_1BIT_FMT(TRUNC_L
, FMT_SD_D
):
16134 mips32_op
= OPC_TRUNC_L_D
;
16136 case FLOAT_1BIT_FMT(TRUNC_W
, FMT_SD_S
):
16137 mips32_op
= OPC_TRUNC_W_S
;
16139 case FLOAT_1BIT_FMT(TRUNC_W
, FMT_SD_D
):
16140 mips32_op
= OPC_TRUNC_W_D
;
16144 case FLOAT_1BIT_FMT(ROUND_L
, FMT_SD_S
):
16145 mips32_op
= OPC_ROUND_L_S
;
16147 case FLOAT_1BIT_FMT(ROUND_L
, FMT_SD_D
):
16148 mips32_op
= OPC_ROUND_L_D
;
16150 case FLOAT_1BIT_FMT(ROUND_W
, FMT_SD_S
):
16151 mips32_op
= OPC_ROUND_W_S
;
16153 case FLOAT_1BIT_FMT(ROUND_W
, FMT_SD_D
):
16154 mips32_op
= OPC_ROUND_W_D
;
16157 /* Integer to floating-point conversion */
16158 case FLOAT_1BIT_FMT(CVT_L
, FMT_SD_S
):
16159 mips32_op
= OPC_CVT_L_S
;
16161 case FLOAT_1BIT_FMT(CVT_L
, FMT_SD_D
):
16162 mips32_op
= OPC_CVT_L_D
;
16164 case FLOAT_1BIT_FMT(CVT_W
, FMT_SD_S
):
16165 mips32_op
= OPC_CVT_W_S
;
16167 case FLOAT_1BIT_FMT(CVT_W
, FMT_SD_D
):
16168 mips32_op
= OPC_CVT_W_D
;
16171 /* Paired-foo conversions */
16172 case FLOAT_1BIT_FMT(CVT_S_PL
, 0):
16173 mips32_op
= OPC_CVT_S_PL
;
16175 case FLOAT_1BIT_FMT(CVT_S_PU
, 0):
16176 mips32_op
= OPC_CVT_S_PU
;
16178 case FLOAT_1BIT_FMT(CVT_PW_PS
, 0):
16179 mips32_op
= OPC_CVT_PW_PS
;
16181 case FLOAT_1BIT_FMT(CVT_PS_PW
, 0):
16182 mips32_op
= OPC_CVT_PS_PW
;
16185 /* Floating-point moves */
16186 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_S
):
16187 mips32_op
= OPC_MOV_S
;
16189 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_D
):
16190 mips32_op
= OPC_MOV_D
;
16192 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_PS
):
16193 mips32_op
= OPC_MOV_PS
;
16196 /* Absolute value */
16197 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_S
):
16198 mips32_op
= OPC_ABS_S
;
16200 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_D
):
16201 mips32_op
= OPC_ABS_D
;
16203 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_PS
):
16204 mips32_op
= OPC_ABS_PS
;
16208 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_S
):
16209 mips32_op
= OPC_NEG_S
;
16211 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_D
):
16212 mips32_op
= OPC_NEG_D
;
16214 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_PS
):
16215 mips32_op
= OPC_NEG_PS
;
16218 /* Reciprocal square root step */
16219 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_S
):
16220 mips32_op
= OPC_RSQRT1_S
;
16222 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_D
):
16223 mips32_op
= OPC_RSQRT1_D
;
16225 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_PS
):
16226 mips32_op
= OPC_RSQRT1_PS
;
16229 /* Reciprocal step */
16230 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_S
):
16231 mips32_op
= OPC_RECIP1_S
;
16233 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_D
):
16234 mips32_op
= OPC_RECIP1_S
;
16236 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_PS
):
16237 mips32_op
= OPC_RECIP1_PS
;
16240 /* Conversions from double */
16241 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_S
):
16242 mips32_op
= OPC_CVT_D_S
;
16244 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_W
):
16245 mips32_op
= OPC_CVT_D_W
;
16247 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_L
):
16248 mips32_op
= OPC_CVT_D_L
;
16251 /* Conversions from single */
16252 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_D
):
16253 mips32_op
= OPC_CVT_S_D
;
16255 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_W
):
16256 mips32_op
= OPC_CVT_S_W
;
16258 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_L
):
16259 mips32_op
= OPC_CVT_S_L
;
16261 gen_farith(ctx
, mips32_op
, -1, rs
, rt
, 0);
16264 /* Conditional moves on floating-point codes */
16265 case COND_FLOAT_MOV(MOVT
, 0):
16266 case COND_FLOAT_MOV(MOVT
, 1):
16267 case COND_FLOAT_MOV(MOVT
, 2):
16268 case COND_FLOAT_MOV(MOVT
, 3):
16269 case COND_FLOAT_MOV(MOVT
, 4):
16270 case COND_FLOAT_MOV(MOVT
, 5):
16271 case COND_FLOAT_MOV(MOVT
, 6):
16272 case COND_FLOAT_MOV(MOVT
, 7):
16273 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16274 gen_movci(ctx
, rt
, rs
, (ctx
->opcode
>> 13) & 0x7, 1);
16276 case COND_FLOAT_MOV(MOVF
, 0):
16277 case COND_FLOAT_MOV(MOVF
, 1):
16278 case COND_FLOAT_MOV(MOVF
, 2):
16279 case COND_FLOAT_MOV(MOVF
, 3):
16280 case COND_FLOAT_MOV(MOVF
, 4):
16281 case COND_FLOAT_MOV(MOVF
, 5):
16282 case COND_FLOAT_MOV(MOVF
, 6):
16283 case COND_FLOAT_MOV(MOVF
, 7):
16284 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16285 gen_movci(ctx
, rt
, rs
, (ctx
->opcode
>> 13) & 0x7, 0);
16288 MIPS_INVAL("pool32fxf");
16289 gen_reserved_instruction(ctx
);
16294 static void decode_micromips32_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
16298 int rt
, rs
, rd
, rr
;
16300 uint32_t op
, minor
, minor2
, mips32_op
;
16301 uint32_t cond
, fmt
, cc
;
16303 insn
= translator_lduw(env
, ctx
->base
.pc_next
+ 2);
16304 ctx
->opcode
= (ctx
->opcode
<< 16) | insn
;
16306 rt
= (ctx
->opcode
>> 21) & 0x1f;
16307 rs
= (ctx
->opcode
>> 16) & 0x1f;
16308 rd
= (ctx
->opcode
>> 11) & 0x1f;
16309 rr
= (ctx
->opcode
>> 6) & 0x1f;
16310 imm
= (int16_t) ctx
->opcode
;
16312 op
= (ctx
->opcode
>> 26) & 0x3f;
16315 minor
= ctx
->opcode
& 0x3f;
16318 minor
= (ctx
->opcode
>> 6) & 0xf;
16321 mips32_op
= OPC_SLL
;
16324 mips32_op
= OPC_SRA
;
16327 mips32_op
= OPC_SRL
;
16330 mips32_op
= OPC_ROTR
;
16332 gen_shift_imm(ctx
, mips32_op
, rt
, rs
, rd
);
16335 check_insn(ctx
, ISA_MIPS_R6
);
16336 gen_cond_move(ctx
, OPC_SELEQZ
, rd
, rs
, rt
);
16339 check_insn(ctx
, ISA_MIPS_R6
);
16340 gen_cond_move(ctx
, OPC_SELNEZ
, rd
, rs
, rt
);
16343 check_insn(ctx
, ISA_MIPS_R6
);
16344 gen_rdhwr(ctx
, rt
, rs
, extract32(ctx
->opcode
, 11, 3));
16347 goto pool32a_invalid
;
16351 minor
= (ctx
->opcode
>> 6) & 0xf;
16355 mips32_op
= OPC_ADD
;
16358 mips32_op
= OPC_ADDU
;
16361 mips32_op
= OPC_SUB
;
16364 mips32_op
= OPC_SUBU
;
16367 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16368 mips32_op
= OPC_MUL
;
16370 gen_arith(ctx
, mips32_op
, rd
, rs
, rt
);
16374 mips32_op
= OPC_SLLV
;
16377 mips32_op
= OPC_SRLV
;
16380 mips32_op
= OPC_SRAV
;
16383 mips32_op
= OPC_ROTRV
;
16385 gen_shift(ctx
, mips32_op
, rd
, rs
, rt
);
16387 /* Logical operations */
16389 mips32_op
= OPC_AND
;
16392 mips32_op
= OPC_OR
;
16395 mips32_op
= OPC_NOR
;
16398 mips32_op
= OPC_XOR
;
16400 gen_logic(ctx
, mips32_op
, rd
, rs
, rt
);
16402 /* Set less than */
16404 mips32_op
= OPC_SLT
;
16407 mips32_op
= OPC_SLTU
;
16409 gen_slt(ctx
, mips32_op
, rd
, rs
, rt
);
16412 goto pool32a_invalid
;
16416 minor
= (ctx
->opcode
>> 6) & 0xf;
16418 /* Conditional moves */
16419 case MOVN
: /* MUL */
16420 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16422 gen_r6_muldiv(ctx
, R6_OPC_MUL
, rd
, rs
, rt
);
16425 gen_cond_move(ctx
, OPC_MOVN
, rd
, rs
, rt
);
16428 case MOVZ
: /* MUH */
16429 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16431 gen_r6_muldiv(ctx
, R6_OPC_MUH
, rd
, rs
, rt
);
16434 gen_cond_move(ctx
, OPC_MOVZ
, rd
, rs
, rt
);
16438 check_insn(ctx
, ISA_MIPS_R6
);
16439 gen_r6_muldiv(ctx
, R6_OPC_MULU
, rd
, rs
, rt
);
16442 check_insn(ctx
, ISA_MIPS_R6
);
16443 gen_r6_muldiv(ctx
, R6_OPC_MUHU
, rd
, rs
, rt
);
16445 case LWXS
: /* DIV */
16446 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16448 gen_r6_muldiv(ctx
, R6_OPC_DIV
, rd
, rs
, rt
);
16451 gen_ldxs(ctx
, rs
, rt
, rd
);
16455 check_insn(ctx
, ISA_MIPS_R6
);
16456 gen_r6_muldiv(ctx
, R6_OPC_MOD
, rd
, rs
, rt
);
16459 check_insn(ctx
, ISA_MIPS_R6
);
16460 gen_r6_muldiv(ctx
, R6_OPC_DIVU
, rd
, rs
, rt
);
16463 check_insn(ctx
, ISA_MIPS_R6
);
16464 gen_r6_muldiv(ctx
, R6_OPC_MODU
, rd
, rs
, rt
);
16467 goto pool32a_invalid
;
16471 gen_bitops(ctx
, OPC_INS
, rt
, rs
, rr
, rd
);
16474 check_insn(ctx
, ISA_MIPS_R6
);
16475 gen_lsa(ctx
, rd
, rt
, rs
, extract32(ctx
->opcode
, 9, 2));
16478 check_insn(ctx
, ISA_MIPS_R6
);
16479 gen_align(ctx
, 32, rd
, rs
, rt
, extract32(ctx
->opcode
, 9, 2));
16482 gen_bitops(ctx
, OPC_EXT
, rt
, rs
, rr
, rd
);
16485 gen_pool32axf(env
, ctx
, rt
, rs
);
16488 generate_exception_end(ctx
, EXCP_BREAK
);
16491 check_insn(ctx
, ISA_MIPS_R6
);
16492 gen_reserved_instruction(ctx
);
16496 MIPS_INVAL("pool32a");
16497 gen_reserved_instruction(ctx
);
16502 minor
= (ctx
->opcode
>> 12) & 0xf;
16505 check_cp0_enabled(ctx
);
16506 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
16507 gen_cache_operation(ctx
, rt
, rs
, imm
);
16512 /* COP2: Not implemented. */
16513 generate_exception_err(ctx
, EXCP_CpU
, 2);
16515 #ifdef TARGET_MIPS64
16518 check_insn(ctx
, ISA_MIPS3
);
16519 check_mips_64(ctx
);
16524 gen_ldst_pair(ctx
, minor
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
16526 #ifdef TARGET_MIPS64
16529 check_insn(ctx
, ISA_MIPS3
);
16530 check_mips_64(ctx
);
16535 gen_ldst_multiple(ctx
, minor
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
16538 MIPS_INVAL("pool32b");
16539 gen_reserved_instruction(ctx
);
16544 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
16545 minor
= ctx
->opcode
& 0x3f;
16546 check_cp1_enabled(ctx
);
16549 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16550 mips32_op
= OPC_ALNV_PS
;
16553 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16554 mips32_op
= OPC_MADD_S
;
16557 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16558 mips32_op
= OPC_MADD_D
;
16561 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16562 mips32_op
= OPC_MADD_PS
;
16565 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16566 mips32_op
= OPC_MSUB_S
;
16569 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16570 mips32_op
= OPC_MSUB_D
;
16573 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16574 mips32_op
= OPC_MSUB_PS
;
16577 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16578 mips32_op
= OPC_NMADD_S
;
16581 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16582 mips32_op
= OPC_NMADD_D
;
16585 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16586 mips32_op
= OPC_NMADD_PS
;
16589 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16590 mips32_op
= OPC_NMSUB_S
;
16593 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16594 mips32_op
= OPC_NMSUB_D
;
16597 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16598 mips32_op
= OPC_NMSUB_PS
;
16600 gen_flt3_arith(ctx
, mips32_op
, rd
, rr
, rs
, rt
);
16602 case CABS_COND_FMT
:
16603 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16604 cond
= (ctx
->opcode
>> 6) & 0xf;
16605 cc
= (ctx
->opcode
>> 13) & 0x7;
16606 fmt
= (ctx
->opcode
>> 10) & 0x3;
16609 gen_cmpabs_s(ctx
, cond
, rt
, rs
, cc
);
16612 gen_cmpabs_d(ctx
, cond
, rt
, rs
, cc
);
16615 gen_cmpabs_ps(ctx
, cond
, rt
, rs
, cc
);
16618 goto pool32f_invalid
;
16622 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16623 cond
= (ctx
->opcode
>> 6) & 0xf;
16624 cc
= (ctx
->opcode
>> 13) & 0x7;
16625 fmt
= (ctx
->opcode
>> 10) & 0x3;
16628 gen_cmp_s(ctx
, cond
, rt
, rs
, cc
);
16631 gen_cmp_d(ctx
, cond
, rt
, rs
, cc
);
16634 gen_cmp_ps(ctx
, cond
, rt
, rs
, cc
);
16637 goto pool32f_invalid
;
16641 check_insn(ctx
, ISA_MIPS_R6
);
16642 gen_r6_cmp_s(ctx
, (ctx
->opcode
>> 6) & 0x1f, rt
, rs
, rd
);
16645 check_insn(ctx
, ISA_MIPS_R6
);
16646 gen_r6_cmp_d(ctx
, (ctx
->opcode
>> 6) & 0x1f, rt
, rs
, rd
);
16649 gen_pool32fxf(ctx
, rt
, rs
);
16653 switch ((ctx
->opcode
>> 6) & 0x7) {
16655 mips32_op
= OPC_PLL_PS
;
16658 mips32_op
= OPC_PLU_PS
;
16661 mips32_op
= OPC_PUL_PS
;
16664 mips32_op
= OPC_PUU_PS
;
16667 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16668 mips32_op
= OPC_CVT_PS_S
;
16670 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
16673 goto pool32f_invalid
;
16677 check_insn(ctx
, ISA_MIPS_R6
);
16678 switch ((ctx
->opcode
>> 9) & 0x3) {
16680 gen_farith(ctx
, OPC_MIN_S
, rt
, rs
, rd
, 0);
16683 gen_farith(ctx
, OPC_MIN_D
, rt
, rs
, rd
, 0);
16686 goto pool32f_invalid
;
16691 switch ((ctx
->opcode
>> 6) & 0x7) {
16693 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16694 mips32_op
= OPC_LWXC1
;
16697 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16698 mips32_op
= OPC_SWXC1
;
16701 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16702 mips32_op
= OPC_LDXC1
;
16705 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16706 mips32_op
= OPC_SDXC1
;
16709 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16710 mips32_op
= OPC_LUXC1
;
16713 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16714 mips32_op
= OPC_SUXC1
;
16716 gen_flt3_ldst(ctx
, mips32_op
, rd
, rd
, rt
, rs
);
16719 goto pool32f_invalid
;
16723 check_insn(ctx
, ISA_MIPS_R6
);
16724 switch ((ctx
->opcode
>> 9) & 0x3) {
16726 gen_farith(ctx
, OPC_MAX_S
, rt
, rs
, rd
, 0);
16729 gen_farith(ctx
, OPC_MAX_D
, rt
, rs
, rd
, 0);
16732 goto pool32f_invalid
;
16737 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16738 fmt
= (ctx
->opcode
>> 9) & 0x3;
16739 switch ((ctx
->opcode
>> 6) & 0x7) {
16743 mips32_op
= OPC_RSQRT2_S
;
16746 mips32_op
= OPC_RSQRT2_D
;
16749 mips32_op
= OPC_RSQRT2_PS
;
16752 goto pool32f_invalid
;
16758 mips32_op
= OPC_RECIP2_S
;
16761 mips32_op
= OPC_RECIP2_D
;
16764 mips32_op
= OPC_RECIP2_PS
;
16767 goto pool32f_invalid
;
16771 mips32_op
= OPC_ADDR_PS
;
16774 mips32_op
= OPC_MULR_PS
;
16776 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
16779 goto pool32f_invalid
;
16783 /* MOV[FT].fmt, PREFX, RINT.fmt, CLASS.fmt*/
16784 cc
= (ctx
->opcode
>> 13) & 0x7;
16785 fmt
= (ctx
->opcode
>> 9) & 0x3;
16786 switch ((ctx
->opcode
>> 6) & 0x7) {
16787 case MOVF_FMT
: /* RINT_FMT */
16788 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16792 gen_farith(ctx
, OPC_RINT_S
, 0, rt
, rs
, 0);
16795 gen_farith(ctx
, OPC_RINT_D
, 0, rt
, rs
, 0);
16798 goto pool32f_invalid
;
16804 gen_movcf_s(ctx
, rs
, rt
, cc
, 0);
16807 gen_movcf_d(ctx
, rs
, rt
, cc
, 0);
16811 gen_movcf_ps(ctx
, rs
, rt
, cc
, 0);
16814 goto pool32f_invalid
;
16818 case MOVT_FMT
: /* CLASS_FMT */
16819 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16823 gen_farith(ctx
, OPC_CLASS_S
, 0, rt
, rs
, 0);
16826 gen_farith(ctx
, OPC_CLASS_D
, 0, rt
, rs
, 0);
16829 goto pool32f_invalid
;
16835 gen_movcf_s(ctx
, rs
, rt
, cc
, 1);
16838 gen_movcf_d(ctx
, rs
, rt
, cc
, 1);
16842 gen_movcf_ps(ctx
, rs
, rt
, cc
, 1);
16845 goto pool32f_invalid
;
16850 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16853 goto pool32f_invalid
;
16856 #define FINSN_3ARG_SDPS(prfx) \
16857 switch ((ctx->opcode >> 8) & 0x3) { \
16859 mips32_op = OPC_##prfx##_S; \
16862 mips32_op = OPC_##prfx##_D; \
16864 case FMT_SDPS_PS: \
16866 mips32_op = OPC_##prfx##_PS; \
16869 goto pool32f_invalid; \
16872 check_insn(ctx
, ISA_MIPS_R6
);
16873 switch ((ctx
->opcode
>> 9) & 0x3) {
16875 gen_farith(ctx
, OPC_MINA_S
, rt
, rs
, rd
, 0);
16878 gen_farith(ctx
, OPC_MINA_D
, rt
, rs
, rd
, 0);
16881 goto pool32f_invalid
;
16885 check_insn(ctx
, ISA_MIPS_R6
);
16886 switch ((ctx
->opcode
>> 9) & 0x3) {
16888 gen_farith(ctx
, OPC_MAXA_S
, rt
, rs
, rd
, 0);
16891 gen_farith(ctx
, OPC_MAXA_D
, rt
, rs
, rd
, 0);
16894 goto pool32f_invalid
;
16898 /* regular FP ops */
16899 switch ((ctx
->opcode
>> 6) & 0x3) {
16901 FINSN_3ARG_SDPS(ADD
);
16904 FINSN_3ARG_SDPS(SUB
);
16907 FINSN_3ARG_SDPS(MUL
);
16910 fmt
= (ctx
->opcode
>> 8) & 0x3;
16912 mips32_op
= OPC_DIV_D
;
16913 } else if (fmt
== 0) {
16914 mips32_op
= OPC_DIV_S
;
16916 goto pool32f_invalid
;
16920 goto pool32f_invalid
;
16925 switch ((ctx
->opcode
>> 6) & 0x7) {
16926 case MOVN_FMT
: /* SELEQZ_FMT */
16927 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16929 switch ((ctx
->opcode
>> 9) & 0x3) {
16931 gen_sel_s(ctx
, OPC_SELEQZ_S
, rd
, rt
, rs
);
16934 gen_sel_d(ctx
, OPC_SELEQZ_D
, rd
, rt
, rs
);
16937 goto pool32f_invalid
;
16941 FINSN_3ARG_SDPS(MOVN
);
16945 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16946 FINSN_3ARG_SDPS(MOVN
);
16948 case MOVZ_FMT
: /* SELNEZ_FMT */
16949 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16951 switch ((ctx
->opcode
>> 9) & 0x3) {
16953 gen_sel_s(ctx
, OPC_SELNEZ_S
, rd
, rt
, rs
);
16956 gen_sel_d(ctx
, OPC_SELNEZ_D
, rd
, rt
, rs
);
16959 goto pool32f_invalid
;
16963 FINSN_3ARG_SDPS(MOVZ
);
16967 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16968 FINSN_3ARG_SDPS(MOVZ
);
16971 check_insn(ctx
, ISA_MIPS_R6
);
16972 switch ((ctx
->opcode
>> 9) & 0x3) {
16974 gen_sel_s(ctx
, OPC_SEL_S
, rd
, rt
, rs
);
16977 gen_sel_d(ctx
, OPC_SEL_D
, rd
, rt
, rs
);
16980 goto pool32f_invalid
;
16984 check_insn(ctx
, ISA_MIPS_R6
);
16985 switch ((ctx
->opcode
>> 9) & 0x3) {
16987 mips32_op
= OPC_MADDF_S
;
16990 mips32_op
= OPC_MADDF_D
;
16993 goto pool32f_invalid
;
16997 check_insn(ctx
, ISA_MIPS_R6
);
16998 switch ((ctx
->opcode
>> 9) & 0x3) {
17000 mips32_op
= OPC_MSUBF_S
;
17003 mips32_op
= OPC_MSUBF_D
;
17006 goto pool32f_invalid
;
17010 goto pool32f_invalid
;
17014 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
17018 MIPS_INVAL("pool32f");
17019 gen_reserved_instruction(ctx
);
17023 generate_exception_err(ctx
, EXCP_CpU
, 1);
17027 minor
= (ctx
->opcode
>> 21) & 0x1f;
17030 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17031 gen_compute_branch(ctx
, OPC_BLTZ
, 4, rs
, -1, imm
<< 1, 4);
17034 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17035 gen_compute_branch(ctx
, OPC_BLTZAL
, 4, rs
, -1, imm
<< 1, 4);
17036 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
17039 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17040 gen_compute_branch(ctx
, OPC_BLTZAL
, 4, rs
, -1, imm
<< 1, 2);
17041 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
17044 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17045 gen_compute_branch(ctx
, OPC_BGEZ
, 4, rs
, -1, imm
<< 1, 4);
17048 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17049 gen_compute_branch(ctx
, OPC_BGEZAL
, 4, rs
, -1, imm
<< 1, 4);
17050 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
17053 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17054 gen_compute_branch(ctx
, OPC_BGEZAL
, 4, rs
, -1, imm
<< 1, 2);
17055 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
17058 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17059 gen_compute_branch(ctx
, OPC_BLEZ
, 4, rs
, -1, imm
<< 1, 4);
17062 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17063 gen_compute_branch(ctx
, OPC_BGTZ
, 4, rs
, -1, imm
<< 1, 4);
17067 case TLTI
: /* BC1EQZC */
17068 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
17070 check_cp1_enabled(ctx
);
17071 gen_compute_branch1_r6(ctx
, OPC_BC1EQZ
, rs
, imm
<< 1, 0);
17074 mips32_op
= OPC_TLTI
;
17078 case TGEI
: /* BC1NEZC */
17079 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
17081 check_cp1_enabled(ctx
);
17082 gen_compute_branch1_r6(ctx
, OPC_BC1NEZ
, rs
, imm
<< 1, 0);
17085 mips32_op
= OPC_TGEI
;
17090 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17091 mips32_op
= OPC_TLTIU
;
17094 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17095 mips32_op
= OPC_TGEIU
;
17097 case TNEI
: /* SYNCI */
17098 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
17101 * Break the TB to be able to sync copied instructions
17104 ctx
->base
.is_jmp
= DISAS_STOP
;
17107 mips32_op
= OPC_TNEI
;
17112 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17113 mips32_op
= OPC_TEQI
;
17115 gen_trap(ctx
, mips32_op
, rs
, -1, imm
);
17120 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17121 gen_compute_branch(ctx
, minor
== BNEZC
? OPC_BNE
: OPC_BEQ
,
17122 4, rs
, 0, imm
<< 1, 0);
17124 * Compact branches don't have a delay slot, so just let
17125 * the normal delay slot handling take us to the branch
17130 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17131 gen_logic_imm(ctx
, OPC_LUI
, rs
, 0, imm
);
17134 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17136 * Break the TB to be able to sync copied instructions
17139 ctx
->base
.is_jmp
= DISAS_STOP
;
17143 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17144 /* COP2: Not implemented. */
17145 generate_exception_err(ctx
, EXCP_CpU
, 2);
17148 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17149 mips32_op
= (ctx
->opcode
& (1 << 16)) ? OPC_BC1FANY2
: OPC_BC1F
;
17152 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17153 mips32_op
= (ctx
->opcode
& (1 << 16)) ? OPC_BC1TANY2
: OPC_BC1T
;
17156 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17157 mips32_op
= OPC_BC1FANY4
;
17160 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17161 mips32_op
= OPC_BC1TANY4
;
17164 check_insn(ctx
, ASE_MIPS3D
);
17167 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
17168 check_cp1_enabled(ctx
);
17169 gen_compute_branch1(ctx
, mips32_op
,
17170 (ctx
->opcode
>> 18) & 0x7, imm
<< 1);
17172 generate_exception_err(ctx
, EXCP_CpU
, 1);
17177 /* MIPS DSP: not implemented */
17180 MIPS_INVAL("pool32i");
17181 gen_reserved_instruction(ctx
);
17186 minor
= (ctx
->opcode
>> 12) & 0xf;
17187 offset
= sextract32(ctx
->opcode
, 0,
17188 (ctx
->insn_flags
& ISA_MIPS_R6
) ? 9 : 12);
17191 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17192 mips32_op
= OPC_LWL
;
17195 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17196 mips32_op
= OPC_SWL
;
17199 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17200 mips32_op
= OPC_LWR
;
17203 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17204 mips32_op
= OPC_SWR
;
17206 #if defined(TARGET_MIPS64)
17208 check_insn(ctx
, ISA_MIPS3
);
17209 check_mips_64(ctx
);
17210 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17211 mips32_op
= OPC_LDL
;
17214 check_insn(ctx
, ISA_MIPS3
);
17215 check_mips_64(ctx
);
17216 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17217 mips32_op
= OPC_SDL
;
17220 check_insn(ctx
, ISA_MIPS3
);
17221 check_mips_64(ctx
);
17222 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17223 mips32_op
= OPC_LDR
;
17226 check_insn(ctx
, ISA_MIPS3
);
17227 check_mips_64(ctx
);
17228 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17229 mips32_op
= OPC_SDR
;
17232 check_insn(ctx
, ISA_MIPS3
);
17233 check_mips_64(ctx
);
17234 mips32_op
= OPC_LWU
;
17237 check_insn(ctx
, ISA_MIPS3
);
17238 check_mips_64(ctx
);
17239 mips32_op
= OPC_LLD
;
17243 mips32_op
= OPC_LL
;
17246 gen_ld(ctx
, mips32_op
, rt
, rs
, offset
);
17249 gen_st(ctx
, mips32_op
, rt
, rs
, offset
);
17252 gen_st_cond(ctx
, rt
, rs
, offset
, MO_TESL
, false);
17254 #if defined(TARGET_MIPS64)
17256 check_insn(ctx
, ISA_MIPS3
);
17257 check_mips_64(ctx
);
17258 gen_st_cond(ctx
, rt
, rs
, offset
, MO_TEQ
, false);
17263 MIPS_INVAL("pool32c ld-eva");
17264 gen_reserved_instruction(ctx
);
17267 check_cp0_enabled(ctx
);
17269 minor2
= (ctx
->opcode
>> 9) & 0x7;
17270 offset
= sextract32(ctx
->opcode
, 0, 9);
17273 mips32_op
= OPC_LBUE
;
17276 mips32_op
= OPC_LHUE
;
17279 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17280 mips32_op
= OPC_LWLE
;
17283 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17284 mips32_op
= OPC_LWRE
;
17287 mips32_op
= OPC_LBE
;
17290 mips32_op
= OPC_LHE
;
17293 mips32_op
= OPC_LLE
;
17296 mips32_op
= OPC_LWE
;
17302 MIPS_INVAL("pool32c st-eva");
17303 gen_reserved_instruction(ctx
);
17306 check_cp0_enabled(ctx
);
17308 minor2
= (ctx
->opcode
>> 9) & 0x7;
17309 offset
= sextract32(ctx
->opcode
, 0, 9);
17312 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17313 mips32_op
= OPC_SWLE
;
17316 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17317 mips32_op
= OPC_SWRE
;
17320 /* Treat as no-op */
17321 if ((ctx
->insn_flags
& ISA_MIPS_R6
) && (rt
>= 24)) {
17322 /* hint codes 24-31 are reserved and signal RI */
17323 generate_exception(ctx
, EXCP_RI
);
17327 /* Treat as no-op */
17328 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
17329 gen_cache_operation(ctx
, rt
, rs
, offset
);
17333 mips32_op
= OPC_SBE
;
17336 mips32_op
= OPC_SHE
;
17339 gen_st_cond(ctx
, rt
, rs
, offset
, MO_TESL
, true);
17342 mips32_op
= OPC_SWE
;
17347 /* Treat as no-op */
17348 if ((ctx
->insn_flags
& ISA_MIPS_R6
) && (rt
>= 24)) {
17349 /* hint codes 24-31 are reserved and signal RI */
17350 generate_exception(ctx
, EXCP_RI
);
17354 MIPS_INVAL("pool32c");
17355 gen_reserved_instruction(ctx
);
17359 case ADDI32
: /* AUI, LUI */
17360 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
17362 gen_logic_imm(ctx
, OPC_LUI
, rt
, rs
, imm
);
17365 mips32_op
= OPC_ADDI
;
17370 mips32_op
= OPC_ADDIU
;
17372 gen_arith_imm(ctx
, mips32_op
, rt
, rs
, imm
);
17375 /* Logical operations */
17377 mips32_op
= OPC_ORI
;
17380 mips32_op
= OPC_XORI
;
17383 mips32_op
= OPC_ANDI
;
17385 gen_logic_imm(ctx
, mips32_op
, rt
, rs
, imm
);
17388 /* Set less than immediate */
17390 mips32_op
= OPC_SLTI
;
17393 mips32_op
= OPC_SLTIU
;
17395 gen_slt_imm(ctx
, mips32_op
, rt
, rs
, imm
);
17398 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17399 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
17400 gen_compute_branch(ctx
, OPC_JALX
, 4, rt
, rs
, offset
, 4);
17401 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
17403 case JALS32
: /* BOVC, BEQC, BEQZALC */
17404 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
17407 mips32_op
= OPC_BOVC
;
17408 } else if (rs
< rt
&& rs
== 0) {
17410 mips32_op
= OPC_BEQZALC
;
17413 mips32_op
= OPC_BEQC
;
17415 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
17418 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1;
17419 gen_compute_branch(ctx
, OPC_JAL
, 4, rt
, rs
, offset
, 2);
17420 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
17423 case BEQ32
: /* BC */
17424 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
17426 gen_compute_compact_branch(ctx
, OPC_BC
, 0, 0,
17427 sextract32(ctx
->opcode
<< 1, 0, 27));
17430 gen_compute_branch(ctx
, OPC_BEQ
, 4, rt
, rs
, imm
<< 1, 4);
17433 case BNE32
: /* BALC */
17434 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
17436 gen_compute_compact_branch(ctx
, OPC_BALC
, 0, 0,
17437 sextract32(ctx
->opcode
<< 1, 0, 27));
17440 gen_compute_branch(ctx
, OPC_BNE
, 4, rt
, rs
, imm
<< 1, 4);
17443 case J32
: /* BGTZC, BLTZC, BLTC */
17444 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
17445 if (rs
== 0 && rt
!= 0) {
17447 mips32_op
= OPC_BGTZC
;
17448 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
17450 mips32_op
= OPC_BLTZC
;
17453 mips32_op
= OPC_BLTC
;
17455 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
17458 gen_compute_branch(ctx
, OPC_J
, 4, rt
, rs
,
17459 (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1, 4);
17462 case JAL32
: /* BLEZC, BGEZC, BGEC */
17463 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
17464 if (rs
== 0 && rt
!= 0) {
17466 mips32_op
= OPC_BLEZC
;
17467 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
17469 mips32_op
= OPC_BGEZC
;
17472 mips32_op
= OPC_BGEC
;
17474 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
17477 gen_compute_branch(ctx
, OPC_JAL
, 4, rt
, rs
,
17478 (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1, 4);
17479 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
17482 /* Floating point (COP1) */
17484 mips32_op
= OPC_LWC1
;
17487 mips32_op
= OPC_LDC1
;
17490 mips32_op
= OPC_SWC1
;
17493 mips32_op
= OPC_SDC1
;
17495 gen_cop1_ldst(ctx
, mips32_op
, rt
, rs
, imm
);
17497 case ADDIUPC
: /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
17498 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
17499 /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
17500 switch ((ctx
->opcode
>> 16) & 0x1f) {
17509 gen_pcrel(ctx
, OPC_ADDIUPC
, ctx
->base
.pc_next
& ~0x3, rt
);
17512 gen_pcrel(ctx
, OPC_AUIPC
, ctx
->base
.pc_next
, rt
);
17515 gen_pcrel(ctx
, OPC_ALUIPC
, ctx
->base
.pc_next
, rt
);
17525 gen_pcrel(ctx
, R6_OPC_LWPC
, ctx
->base
.pc_next
& ~0x3, rt
);
17528 generate_exception(ctx
, EXCP_RI
);
17533 int reg
= mmreg(ZIMM(ctx
->opcode
, 23, 3));
17534 offset
= SIMM(ctx
->opcode
, 0, 23) << 2;
17536 gen_addiupc(ctx
, reg
, offset
, 0, 0);
17539 case BNVC
: /* BNEC, BNEZALC */
17540 check_insn(ctx
, ISA_MIPS_R6
);
17543 mips32_op
= OPC_BNVC
;
17544 } else if (rs
< rt
&& rs
== 0) {
17546 mips32_op
= OPC_BNEZALC
;
17549 mips32_op
= OPC_BNEC
;
17551 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
17553 case R6_BNEZC
: /* JIALC */
17554 check_insn(ctx
, ISA_MIPS_R6
);
17557 gen_compute_compact_branch(ctx
, OPC_BNEZC
, rt
, 0,
17558 sextract32(ctx
->opcode
<< 1, 0, 22));
17561 gen_compute_compact_branch(ctx
, OPC_JIALC
, 0, rs
, imm
);
17564 case R6_BEQZC
: /* JIC */
17565 check_insn(ctx
, ISA_MIPS_R6
);
17568 gen_compute_compact_branch(ctx
, OPC_BEQZC
, rt
, 0,
17569 sextract32(ctx
->opcode
<< 1, 0, 22));
17572 gen_compute_compact_branch(ctx
, OPC_JIC
, 0, rs
, imm
);
17575 case BLEZALC
: /* BGEZALC, BGEUC */
17576 check_insn(ctx
, ISA_MIPS_R6
);
17577 if (rs
== 0 && rt
!= 0) {
17579 mips32_op
= OPC_BLEZALC
;
17580 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
17582 mips32_op
= OPC_BGEZALC
;
17585 mips32_op
= OPC_BGEUC
;
17587 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
17589 case BGTZALC
: /* BLTZALC, BLTUC */
17590 check_insn(ctx
, ISA_MIPS_R6
);
17591 if (rs
== 0 && rt
!= 0) {
17593 mips32_op
= OPC_BGTZALC
;
17594 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
17596 mips32_op
= OPC_BLTZALC
;
17599 mips32_op
= OPC_BLTUC
;
17601 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
17603 /* Loads and stores */
17605 mips32_op
= OPC_LB
;
17608 mips32_op
= OPC_LBU
;
17611 mips32_op
= OPC_LH
;
17614 mips32_op
= OPC_LHU
;
17617 mips32_op
= OPC_LW
;
17619 #ifdef TARGET_MIPS64
17621 check_insn(ctx
, ISA_MIPS3
);
17622 check_mips_64(ctx
);
17623 mips32_op
= OPC_LD
;
17626 check_insn(ctx
, ISA_MIPS3
);
17627 check_mips_64(ctx
);
17628 mips32_op
= OPC_SD
;
17632 mips32_op
= OPC_SB
;
17635 mips32_op
= OPC_SH
;
17638 mips32_op
= OPC_SW
;
17641 gen_ld(ctx
, mips32_op
, rt
, rs
, imm
);
17644 gen_st(ctx
, mips32_op
, rt
, rs
, imm
);
17647 gen_reserved_instruction(ctx
);
17652 static int decode_micromips_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
17656 /* make sure instructions are on a halfword boundary */
17657 if (ctx
->base
.pc_next
& 0x1) {
17658 env
->CP0_BadVAddr
= ctx
->base
.pc_next
;
17659 generate_exception_end(ctx
, EXCP_AdEL
);
17663 op
= (ctx
->opcode
>> 10) & 0x3f;
17664 /* Enforce properly-sized instructions in a delay slot */
17665 if (ctx
->hflags
& MIPS_HFLAG_BDS_STRICT
) {
17666 switch (op
& 0x7) { /* MSB-3..MSB-5 */
17668 /* POOL32A, POOL32B, POOL32I, POOL32C */
17670 /* ADDI32, ADDIU32, ORI32, XORI32, SLTI32, SLTIU32, ANDI32, JALX32 */
17672 /* LBU32, LHU32, POOL32F, JALS32, BEQ32, BNE32, J32, JAL32 */
17674 /* SB32, SH32, ADDIUPC, SWC132, SDC132, SW32 */
17676 /* LB32, LH32, LWC132, LDC132, LW32 */
17677 if (ctx
->hflags
& MIPS_HFLAG_BDS16
) {
17678 gen_reserved_instruction(ctx
);
17683 /* POOL16A, POOL16B, POOL16C, LWGP16, POOL16F */
17685 /* LBU16, LHU16, LWSP16, LW16, SB16, SH16, SWSP16, SW16 */
17687 /* MOVE16, ANDI16, POOL16D, POOL16E, BEQZ16, BNEZ16, B16, LI16 */
17688 if (ctx
->hflags
& MIPS_HFLAG_BDS32
) {
17689 gen_reserved_instruction(ctx
);
17699 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
17700 int rs1
= mmreg(uMIPS_RS1(ctx
->opcode
));
17701 int rs2
= mmreg(uMIPS_RS2(ctx
->opcode
));
17704 switch (ctx
->opcode
& 0x1) {
17712 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
17714 * In the Release 6, the register number location in
17715 * the instruction encoding has changed.
17717 gen_arith(ctx
, opc
, rs1
, rd
, rs2
);
17719 gen_arith(ctx
, opc
, rd
, rs1
, rs2
);
17725 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
17726 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
17727 int amount
= (ctx
->opcode
>> 1) & 0x7;
17729 amount
= amount
== 0 ? 8 : amount
;
17731 switch (ctx
->opcode
& 0x1) {
17740 gen_shift_imm(ctx
, opc
, rd
, rs
, amount
);
17744 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
17745 gen_pool16c_r6_insn(ctx
);
17747 gen_pool16c_insn(ctx
);
17752 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
17753 int rb
= 28; /* GP */
17754 int16_t offset
= SIMM(ctx
->opcode
, 0, 7) << 2;
17756 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
17760 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17761 if (ctx
->opcode
& 1) {
17762 gen_reserved_instruction(ctx
);
17765 int enc_dest
= uMIPS_RD(ctx
->opcode
);
17766 int enc_rt
= uMIPS_RS2(ctx
->opcode
);
17767 int enc_rs
= uMIPS_RS1(ctx
->opcode
);
17768 gen_movep(ctx
, enc_dest
, enc_rt
, enc_rs
);
17773 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
17774 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
17775 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4);
17776 offset
= (offset
== 0xf ? -1 : offset
);
17778 gen_ld(ctx
, OPC_LBU
, rd
, rb
, offset
);
17783 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
17784 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
17785 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 1;
17787 gen_ld(ctx
, OPC_LHU
, rd
, rb
, offset
);
17792 int rd
= (ctx
->opcode
>> 5) & 0x1f;
17793 int rb
= 29; /* SP */
17794 int16_t offset
= ZIMM(ctx
->opcode
, 0, 5) << 2;
17796 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
17801 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
17802 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
17803 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 2;
17805 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
17810 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
17811 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
17812 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4);
17814 gen_st(ctx
, OPC_SB
, rd
, rb
, offset
);
17819 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
17820 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
17821 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 1;
17823 gen_st(ctx
, OPC_SH
, rd
, rb
, offset
);
17828 int rd
= (ctx
->opcode
>> 5) & 0x1f;
17829 int rb
= 29; /* SP */
17830 int16_t offset
= ZIMM(ctx
->opcode
, 0, 5) << 2;
17832 gen_st(ctx
, OPC_SW
, rd
, rb
, offset
);
17837 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
17838 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
17839 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 2;
17841 gen_st(ctx
, OPC_SW
, rd
, rb
, offset
);
17846 int rd
= uMIPS_RD5(ctx
->opcode
);
17847 int rs
= uMIPS_RS5(ctx
->opcode
);
17849 gen_arith(ctx
, OPC_ADDU
, rd
, rs
, 0);
17856 switch (ctx
->opcode
& 0x1) {
17866 switch (ctx
->opcode
& 0x1) {
17871 gen_addiur1sp(ctx
);
17875 case B16
: /* BC16 */
17876 gen_compute_branch(ctx
, OPC_BEQ
, 2, 0, 0,
17877 sextract32(ctx
->opcode
, 0, 10) << 1,
17878 (ctx
->insn_flags
& ISA_MIPS_R6
) ? 0 : 4);
17880 case BNEZ16
: /* BNEZC16 */
17881 case BEQZ16
: /* BEQZC16 */
17882 gen_compute_branch(ctx
, op
== BNEZ16
? OPC_BNE
: OPC_BEQ
, 2,
17883 mmreg(uMIPS_RD(ctx
->opcode
)),
17884 0, sextract32(ctx
->opcode
, 0, 7) << 1,
17885 (ctx
->insn_flags
& ISA_MIPS_R6
) ? 0 : 4);
17890 int reg
= mmreg(uMIPS_RD(ctx
->opcode
));
17891 int imm
= ZIMM(ctx
->opcode
, 0, 7);
17893 imm
= (imm
== 0x7f ? -1 : imm
);
17894 tcg_gen_movi_tl(cpu_gpr
[reg
], imm
);
17900 gen_reserved_instruction(ctx
);
17903 decode_micromips32_opc(env
, ctx
);
17916 /* MAJOR, P16, and P32 pools opcodes */
17920 NM_MOVE_BALC
= 0x02,
17928 NM_P16_SHIFT
= 0x0c,
17946 NM_P_LS_U12
= 0x21,
17956 NM_P16_ADDU
= 0x2c,
17970 NM_MOVEPREV
= 0x3f,
17973 /* POOL32A instruction pool */
17975 NM_POOL32A0
= 0x00,
17976 NM_SPECIAL2
= 0x01,
17979 NM_POOL32A5
= 0x05,
17980 NM_POOL32A7
= 0x07,
17983 /* P.GP.W instruction pool */
17985 NM_ADDIUGP_W
= 0x00,
17990 /* P48I instruction pool */
17994 NM_ADDIUGP48
= 0x02,
17995 NM_ADDIUPC48
= 0x03,
18000 /* P.U12 instruction pool */
18009 NM_ADDIUNEG
= 0x08,
18016 /* POOL32F instruction pool */
18018 NM_POOL32F_0
= 0x00,
18019 NM_POOL32F_3
= 0x03,
18020 NM_POOL32F_5
= 0x05,
18023 /* POOL32S instruction pool */
18025 NM_POOL32S_0
= 0x00,
18026 NM_POOL32S_4
= 0x04,
18029 /* P.LUI instruction pool */
18035 /* P.GP.BH instruction pool */
18040 NM_ADDIUGP_B
= 0x03,
18043 NM_P_GP_CP1
= 0x06,
18046 /* P.LS.U12 instruction pool */
18051 NM_P_PREFU12
= 0x03,
18064 /* P.LS.S9 instruction pool */
18070 NM_P_LS_UAWM
= 0x05,
18073 /* P.BAL instruction pool */
18079 /* P.J instruction pool */
18082 NM_JALRC_HB
= 0x01,
18083 NM_P_BALRSC
= 0x08,
18086 /* P.BR1 instruction pool */
18094 /* P.BR2 instruction pool */
18101 /* P.BRI instruction pool */
18113 /* P16.SHIFT instruction pool */
18119 /* POOL16C instruction pool */
18121 NM_POOL16C_0
= 0x00,
18125 /* P16.A1 instruction pool */
18127 NM_ADDIUR1SP
= 0x01,
18130 /* P16.A2 instruction pool */
18133 NM_P_ADDIURS5
= 0x01,
18136 /* P16.ADDU instruction pool */
18142 /* P16.SR instruction pool */
18145 NM_RESTORE_JRC16
= 0x01,
18148 /* P16.4X4 instruction pool */
18154 /* P16.LB instruction pool */
18161 /* P16.LH instruction pool */
18168 /* P.RI instruction pool */
18171 NM_P_SYSCALL
= 0x01,
18176 /* POOL32A0 instruction pool */
18211 NM_D_E_MT_VPE
= 0x56,
18219 /* CRC32 instruction pool */
18229 /* POOL32A5 instruction pool */
18231 NM_CMP_EQ_PH
= 0x00,
18232 NM_CMP_LT_PH
= 0x08,
18233 NM_CMP_LE_PH
= 0x10,
18234 NM_CMPGU_EQ_QB
= 0x18,
18235 NM_CMPGU_LT_QB
= 0x20,
18236 NM_CMPGU_LE_QB
= 0x28,
18237 NM_CMPGDU_EQ_QB
= 0x30,
18238 NM_CMPGDU_LT_QB
= 0x38,
18239 NM_CMPGDU_LE_QB
= 0x40,
18240 NM_CMPU_EQ_QB
= 0x48,
18241 NM_CMPU_LT_QB
= 0x50,
18242 NM_CMPU_LE_QB
= 0x58,
18243 NM_ADDQ_S_W
= 0x60,
18244 NM_SUBQ_S_W
= 0x68,
18248 NM_ADDQ_S_PH
= 0x01,
18249 NM_ADDQH_R_PH
= 0x09,
18250 NM_ADDQH_R_W
= 0x11,
18251 NM_ADDU_S_QB
= 0x19,
18252 NM_ADDU_S_PH
= 0x21,
18253 NM_ADDUH_R_QB
= 0x29,
18254 NM_SHRAV_R_PH
= 0x31,
18255 NM_SHRAV_R_QB
= 0x39,
18256 NM_SUBQ_S_PH
= 0x41,
18257 NM_SUBQH_R_PH
= 0x49,
18258 NM_SUBQH_R_W
= 0x51,
18259 NM_SUBU_S_QB
= 0x59,
18260 NM_SUBU_S_PH
= 0x61,
18261 NM_SUBUH_R_QB
= 0x69,
18262 NM_SHLLV_S_PH
= 0x71,
18263 NM_PRECR_SRA_R_PH_W
= 0x79,
18265 NM_MULEU_S_PH_QBL
= 0x12,
18266 NM_MULEU_S_PH_QBR
= 0x1a,
18267 NM_MULQ_RS_PH
= 0x22,
18268 NM_MULQ_S_PH
= 0x2a,
18269 NM_MULQ_RS_W
= 0x32,
18270 NM_MULQ_S_W
= 0x3a,
18273 NM_SHRAV_R_W
= 0x5a,
18274 NM_SHRLV_PH
= 0x62,
18275 NM_SHRLV_QB
= 0x6a,
18276 NM_SHLLV_QB
= 0x72,
18277 NM_SHLLV_S_W
= 0x7a,
18281 NM_MULEQ_S_W_PHL
= 0x04,
18282 NM_MULEQ_S_W_PHR
= 0x0c,
18284 NM_MUL_S_PH
= 0x05,
18285 NM_PRECR_QB_PH
= 0x0d,
18286 NM_PRECRQ_QB_PH
= 0x15,
18287 NM_PRECRQ_PH_W
= 0x1d,
18288 NM_PRECRQ_RS_PH_W
= 0x25,
18289 NM_PRECRQU_S_QB_PH
= 0x2d,
18290 NM_PACKRL_PH
= 0x35,
18294 NM_SHRA_R_W
= 0x5e,
18295 NM_SHRA_R_PH
= 0x66,
18296 NM_SHLL_S_PH
= 0x76,
18297 NM_SHLL_S_W
= 0x7e,
18302 /* POOL32A7 instruction pool */
18307 NM_POOL32AXF
= 0x07,
18310 /* P.SR instruction pool */
18316 /* P.SHIFT instruction pool */
18324 /* P.ROTX instruction pool */
18329 /* P.INS instruction pool */
18334 /* P.EXT instruction pool */
18339 /* POOL32F_0 (fmt) instruction pool */
18344 NM_SELEQZ_S
= 0x07,
18345 NM_SELEQZ_D
= 0x47,
18349 NM_SELNEZ_S
= 0x0f,
18350 NM_SELNEZ_D
= 0x4f,
18365 /* POOL32F_3 instruction pool */
18369 NM_MINA_FMT
= 0x04,
18370 NM_MAXA_FMT
= 0x05,
18371 NM_POOL32FXF
= 0x07,
18374 /* POOL32F_5 instruction pool */
18376 NM_CMP_CONDN_S
= 0x00,
18377 NM_CMP_CONDN_D
= 0x02,
18380 /* P.GP.LH instruction pool */
18386 /* P.GP.SH instruction pool */
18391 /* P.GP.CP1 instruction pool */
18399 /* P.LS.S0 instruction pool */
18416 NM_P_PREFS9
= 0x03,
18422 /* P.LS.S1 instruction pool */
18424 NM_ASET_ACLR
= 0x02,
18432 /* P.LS.E0 instruction pool */
18448 /* P.PREFE instruction pool */
18454 /* P.LLE instruction pool */
18460 /* P.SCE instruction pool */
18466 /* P.LS.WM instruction pool */
18472 /* P.LS.UAWM instruction pool */
18478 /* P.BR3A instruction pool */
18484 NM_BPOSGE32C
= 0x04,
18487 /* P16.RI instruction pool */
18489 NM_P16_SYSCALL
= 0x01,
18494 /* POOL16C_0 instruction pool */
18496 NM_POOL16C_00
= 0x00,
18499 /* P16.JRC instruction pool */
18505 /* P.SYSCALL instruction pool */
18511 /* P.TRAP instruction pool */
18517 /* P.CMOVE instruction pool */
18523 /* POOL32Axf instruction pool */
18525 NM_POOL32AXF_1
= 0x01,
18526 NM_POOL32AXF_2
= 0x02,
18527 NM_POOL32AXF_4
= 0x04,
18528 NM_POOL32AXF_5
= 0x05,
18529 NM_POOL32AXF_7
= 0x07,
18532 /* POOL32Axf_1 instruction pool */
18534 NM_POOL32AXF_1_0
= 0x00,
18535 NM_POOL32AXF_1_1
= 0x01,
18536 NM_POOL32AXF_1_3
= 0x03,
18537 NM_POOL32AXF_1_4
= 0x04,
18538 NM_POOL32AXF_1_5
= 0x05,
18539 NM_POOL32AXF_1_7
= 0x07,
18542 /* POOL32Axf_2 instruction pool */
18544 NM_POOL32AXF_2_0_7
= 0x00,
18545 NM_POOL32AXF_2_8_15
= 0x01,
18546 NM_POOL32AXF_2_16_23
= 0x02,
18547 NM_POOL32AXF_2_24_31
= 0x03,
18550 /* POOL32Axf_7 instruction pool */
18552 NM_SHRA_R_QB
= 0x0,
18557 /* POOL32Axf_1_0 instruction pool */
18565 /* POOL32Axf_1_1 instruction pool */
18571 /* POOL32Axf_1_3 instruction pool */
18579 /* POOL32Axf_1_4 instruction pool */
18585 /* POOL32Axf_1_5 instruction pool */
18587 NM_MAQ_S_W_PHR
= 0x0,
18588 NM_MAQ_S_W_PHL
= 0x1,
18589 NM_MAQ_SA_W_PHR
= 0x2,
18590 NM_MAQ_SA_W_PHL
= 0x3,
18593 /* POOL32Axf_1_7 instruction pool */
18597 NM_EXTR_RS_W
= 0x2,
18601 /* POOL32Axf_2_0_7 instruction pool */
18604 NM_DPAQ_S_W_PH
= 0x1,
18606 NM_DPSQ_S_W_PH
= 0x3,
18613 /* POOL32Axf_2_8_15 instruction pool */
18615 NM_DPAX_W_PH
= 0x0,
18616 NM_DPAQ_SA_L_W
= 0x1,
18617 NM_DPSX_W_PH
= 0x2,
18618 NM_DPSQ_SA_L_W
= 0x3,
18621 NM_EXTRV_R_W
= 0x7,
18624 /* POOL32Axf_2_16_23 instruction pool */
18626 NM_DPAU_H_QBL
= 0x0,
18627 NM_DPAQX_S_W_PH
= 0x1,
18628 NM_DPSU_H_QBL
= 0x2,
18629 NM_DPSQX_S_W_PH
= 0x3,
18632 NM_MULSA_W_PH
= 0x6,
18633 NM_EXTRV_RS_W
= 0x7,
18636 /* POOL32Axf_2_24_31 instruction pool */
18638 NM_DPAU_H_QBR
= 0x0,
18639 NM_DPAQX_SA_W_PH
= 0x1,
18640 NM_DPSU_H_QBR
= 0x2,
18641 NM_DPSQX_SA_W_PH
= 0x3,
18644 NM_MULSAQ_S_W_PH
= 0x6,
18645 NM_EXTRV_S_H
= 0x7,
18648 /* POOL32Axf_{4, 5} instruction pool */
18667 /* nanoMIPS DSP instructions */
18668 NM_ABSQ_S_QB
= 0x00,
18669 NM_ABSQ_S_PH
= 0x08,
18670 NM_ABSQ_S_W
= 0x10,
18671 NM_PRECEQ_W_PHL
= 0x28,
18672 NM_PRECEQ_W_PHR
= 0x30,
18673 NM_PRECEQU_PH_QBL
= 0x38,
18674 NM_PRECEQU_PH_QBR
= 0x48,
18675 NM_PRECEU_PH_QBL
= 0x58,
18676 NM_PRECEU_PH_QBR
= 0x68,
18677 NM_PRECEQU_PH_QBLA
= 0x39,
18678 NM_PRECEQU_PH_QBRA
= 0x49,
18679 NM_PRECEU_PH_QBLA
= 0x59,
18680 NM_PRECEU_PH_QBRA
= 0x69,
18681 NM_REPLV_PH
= 0x01,
18682 NM_REPLV_QB
= 0x09,
18685 NM_RADDU_W_QB
= 0x78,
18691 /* PP.SR instruction pool */
18695 NM_RESTORE_JRC
= 0x03,
18698 /* P.SR.F instruction pool */
18701 NM_RESTOREF
= 0x01,
18704 /* P16.SYSCALL instruction pool */
18706 NM_SYSCALL16
= 0x00,
18707 NM_HYPCALL16
= 0x01,
18710 /* POOL16C_00 instruction pool */
18718 /* PP.LSX and PP.LSXS instruction pool */
18756 /* ERETx instruction pool */
18762 /* POOL32FxF_{0, 1} insturction pool */
18771 NM_CVT_S_PL
= 0x84,
18772 NM_CVT_S_PU
= 0xa4,
18774 NM_CVT_L_S
= 0x004,
18775 NM_CVT_L_D
= 0x104,
18776 NM_CVT_W_S
= 0x024,
18777 NM_CVT_W_D
= 0x124,
18779 NM_RSQRT_S
= 0x008,
18780 NM_RSQRT_D
= 0x108,
18785 NM_RECIP_S
= 0x048,
18786 NM_RECIP_D
= 0x148,
18788 NM_FLOOR_L_S
= 0x00c,
18789 NM_FLOOR_L_D
= 0x10c,
18791 NM_FLOOR_W_S
= 0x02c,
18792 NM_FLOOR_W_D
= 0x12c,
18794 NM_CEIL_L_S
= 0x04c,
18795 NM_CEIL_L_D
= 0x14c,
18796 NM_CEIL_W_S
= 0x06c,
18797 NM_CEIL_W_D
= 0x16c,
18798 NM_TRUNC_L_S
= 0x08c,
18799 NM_TRUNC_L_D
= 0x18c,
18800 NM_TRUNC_W_S
= 0x0ac,
18801 NM_TRUNC_W_D
= 0x1ac,
18802 NM_ROUND_L_S
= 0x0cc,
18803 NM_ROUND_L_D
= 0x1cc,
18804 NM_ROUND_W_S
= 0x0ec,
18805 NM_ROUND_W_D
= 0x1ec,
18813 NM_CVT_D_S
= 0x04d,
18814 NM_CVT_D_W
= 0x0cd,
18815 NM_CVT_D_L
= 0x14d,
18816 NM_CVT_S_D
= 0x06d,
18817 NM_CVT_S_W
= 0x0ed,
18818 NM_CVT_S_L
= 0x16d,
18821 /* P.LL instruction pool */
18827 /* P.SC instruction pool */
18833 /* P.DVP instruction pool */
18842 * nanoMIPS decoding engine
18847 /* extraction utilities */
18849 #define NANOMIPS_EXTRACT_RT3(op) ((op >> 7) & 0x7)
18850 #define NANOMIPS_EXTRACT_RS3(op) ((op >> 4) & 0x7)
18851 #define NANOMIPS_EXTRACT_RD3(op) ((op >> 1) & 0x7)
18852 #define NANOMIPS_EXTRACT_RD5(op) ((op >> 5) & 0x1f)
18853 #define NANOMIPS_EXTRACT_RS5(op) (op & 0x1f)
18855 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3'). */
18856 static inline int decode_gpr_gpr3(int r
)
18858 static const int map
[] = { 16, 17, 18, 19, 4, 5, 6, 7 };
18860 return map
[r
& 0x7];
18863 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3.src.store'). */
18864 static inline int decode_gpr_gpr3_src_store(int r
)
18866 static const int map
[] = { 0, 17, 18, 19, 4, 5, 6, 7 };
18868 return map
[r
& 0x7];
18871 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4'). */
18872 static inline int decode_gpr_gpr4(int r
)
18874 static const int map
[] = { 8, 9, 10, 11, 4, 5, 6, 7,
18875 16, 17, 18, 19, 20, 21, 22, 23 };
18877 return map
[r
& 0xf];
18880 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4.zero'). */
18881 static inline int decode_gpr_gpr4_zero(int r
)
18883 static const int map
[] = { 8, 9, 10, 0, 4, 5, 6, 7,
18884 16, 17, 18, 19, 20, 21, 22, 23 };
18886 return map
[r
& 0xf];
18890 static void gen_adjust_sp(DisasContext
*ctx
, int u
)
18892 gen_op_addr_addi(ctx
, cpu_gpr
[29], cpu_gpr
[29], u
);
18895 static void gen_save(DisasContext
*ctx
, uint8_t rt
, uint8_t count
,
18896 uint8_t gp
, uint16_t u
)
18899 TCGv va
= tcg_temp_new();
18900 TCGv t0
= tcg_temp_new();
18902 while (counter
!= count
) {
18903 bool use_gp
= gp
&& (counter
== count
- 1);
18904 int this_rt
= use_gp
? 28 : (rt
& 0x10) | ((rt
+ counter
) & 0x1f);
18905 int this_offset
= -((counter
+ 1) << 2);
18906 gen_base_offset_addr(ctx
, va
, 29, this_offset
);
18907 gen_load_gpr(t0
, this_rt
);
18908 tcg_gen_qemu_st_tl(t0
, va
, ctx
->mem_idx
,
18909 (MO_TEUL
| ctx
->default_tcg_memop_mask
));
18913 /* adjust stack pointer */
18914 gen_adjust_sp(ctx
, -u
);
18920 static void gen_restore(DisasContext
*ctx
, uint8_t rt
, uint8_t count
,
18921 uint8_t gp
, uint16_t u
)
18924 TCGv va
= tcg_temp_new();
18925 TCGv t0
= tcg_temp_new();
18927 while (counter
!= count
) {
18928 bool use_gp
= gp
&& (counter
== count
- 1);
18929 int this_rt
= use_gp
? 28 : (rt
& 0x10) | ((rt
+ counter
) & 0x1f);
18930 int this_offset
= u
- ((counter
+ 1) << 2);
18931 gen_base_offset_addr(ctx
, va
, 29, this_offset
);
18932 tcg_gen_qemu_ld_tl(t0
, va
, ctx
->mem_idx
, MO_TESL
|
18933 ctx
->default_tcg_memop_mask
);
18934 tcg_gen_ext32s_tl(t0
, t0
);
18935 gen_store_gpr(t0
, this_rt
);
18939 /* adjust stack pointer */
18940 gen_adjust_sp(ctx
, u
);
18946 static void gen_pool16c_nanomips_insn(DisasContext
*ctx
)
18948 int rt
= decode_gpr_gpr3(NANOMIPS_EXTRACT_RT3(ctx
->opcode
));
18949 int rs
= decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx
->opcode
));
18951 switch (extract32(ctx
->opcode
, 2, 2)) {
18953 gen_logic(ctx
, OPC_NOR
, rt
, rs
, 0);
18956 gen_logic(ctx
, OPC_AND
, rt
, rt
, rs
);
18959 gen_logic(ctx
, OPC_XOR
, rt
, rt
, rs
);
18962 gen_logic(ctx
, OPC_OR
, rt
, rt
, rs
);
18967 static void gen_pool32a0_nanomips_insn(CPUMIPSState
*env
, DisasContext
*ctx
)
18969 int rt
= extract32(ctx
->opcode
, 21, 5);
18970 int rs
= extract32(ctx
->opcode
, 16, 5);
18971 int rd
= extract32(ctx
->opcode
, 11, 5);
18973 switch (extract32(ctx
->opcode
, 3, 7)) {
18975 switch (extract32(ctx
->opcode
, 10, 1)) {
18978 gen_trap(ctx
, OPC_TEQ
, rs
, rt
, -1);
18982 gen_trap(ctx
, OPC_TNE
, rs
, rt
, -1);
18988 gen_rdhwr(ctx
, rt
, rs
, extract32(ctx
->opcode
, 11, 3));
18992 gen_bshfl(ctx
, OPC_SEB
, rs
, rt
);
18995 gen_bshfl(ctx
, OPC_SEH
, rs
, rt
);
18998 gen_shift(ctx
, OPC_SLLV
, rd
, rt
, rs
);
19001 gen_shift(ctx
, OPC_SRLV
, rd
, rt
, rs
);
19004 gen_shift(ctx
, OPC_SRAV
, rd
, rt
, rs
);
19007 gen_shift(ctx
, OPC_ROTRV
, rd
, rt
, rs
);
19010 gen_arith(ctx
, OPC_ADD
, rd
, rs
, rt
);
19013 gen_arith(ctx
, OPC_ADDU
, rd
, rs
, rt
);
19017 gen_arith(ctx
, OPC_SUB
, rd
, rs
, rt
);
19020 gen_arith(ctx
, OPC_SUBU
, rd
, rs
, rt
);
19023 switch (extract32(ctx
->opcode
, 10, 1)) {
19025 gen_cond_move(ctx
, OPC_MOVZ
, rd
, rs
, rt
);
19028 gen_cond_move(ctx
, OPC_MOVN
, rd
, rs
, rt
);
19033 gen_logic(ctx
, OPC_AND
, rd
, rs
, rt
);
19036 gen_logic(ctx
, OPC_OR
, rd
, rs
, rt
);
19039 gen_logic(ctx
, OPC_NOR
, rd
, rs
, rt
);
19042 gen_logic(ctx
, OPC_XOR
, rd
, rs
, rt
);
19045 gen_slt(ctx
, OPC_SLT
, rd
, rs
, rt
);
19050 #ifndef CONFIG_USER_ONLY
19051 TCGv t0
= tcg_temp_new();
19052 switch (extract32(ctx
->opcode
, 10, 1)) {
19055 check_cp0_enabled(ctx
);
19056 gen_helper_dvp(t0
, cpu_env
);
19057 gen_store_gpr(t0
, rt
);
19062 check_cp0_enabled(ctx
);
19063 gen_helper_evp(t0
, cpu_env
);
19064 gen_store_gpr(t0
, rt
);
19071 gen_slt(ctx
, OPC_SLTU
, rd
, rs
, rt
);
19076 TCGv t0
= tcg_temp_new();
19077 TCGv t1
= tcg_temp_new();
19078 TCGv t2
= tcg_temp_new();
19080 gen_load_gpr(t1
, rs
);
19081 gen_load_gpr(t2
, rt
);
19082 tcg_gen_add_tl(t0
, t1
, t2
);
19083 tcg_gen_ext32s_tl(t0
, t0
);
19084 tcg_gen_xor_tl(t1
, t1
, t2
);
19085 tcg_gen_xor_tl(t2
, t0
, t2
);
19086 tcg_gen_andc_tl(t1
, t2
, t1
);
19088 /* operands of same sign, result different sign */
19089 tcg_gen_setcondi_tl(TCG_COND_LT
, t0
, t1
, 0);
19090 gen_store_gpr(t0
, rd
);
19098 gen_r6_muldiv(ctx
, R6_OPC_MUL
, rd
, rs
, rt
);
19101 gen_r6_muldiv(ctx
, R6_OPC_MUH
, rd
, rs
, rt
);
19104 gen_r6_muldiv(ctx
, R6_OPC_MULU
, rd
, rs
, rt
);
19107 gen_r6_muldiv(ctx
, R6_OPC_MUHU
, rd
, rs
, rt
);
19110 gen_r6_muldiv(ctx
, R6_OPC_DIV
, rd
, rs
, rt
);
19113 gen_r6_muldiv(ctx
, R6_OPC_MOD
, rd
, rs
, rt
);
19116 gen_r6_muldiv(ctx
, R6_OPC_DIVU
, rd
, rs
, rt
);
19119 gen_r6_muldiv(ctx
, R6_OPC_MODU
, rd
, rs
, rt
);
19121 #ifndef CONFIG_USER_ONLY
19123 check_cp0_enabled(ctx
);
19125 /* Treat as NOP. */
19128 gen_mfc0(ctx
, cpu_gpr
[rt
], rs
, extract32(ctx
->opcode
, 11, 3));
19131 check_cp0_enabled(ctx
);
19133 TCGv t0
= tcg_temp_new();
19135 gen_load_gpr(t0
, rt
);
19136 gen_mtc0(ctx
, t0
, rs
, extract32(ctx
->opcode
, 11, 3));
19140 case NM_D_E_MT_VPE
:
19142 uint8_t sc
= extract32(ctx
->opcode
, 10, 1);
19143 TCGv t0
= tcg_temp_new();
19150 gen_helper_dmt(t0
);
19151 gen_store_gpr(t0
, rt
);
19152 } else if (rs
== 0) {
19155 gen_helper_dvpe(t0
, cpu_env
);
19156 gen_store_gpr(t0
, rt
);
19158 gen_reserved_instruction(ctx
);
19165 gen_helper_emt(t0
);
19166 gen_store_gpr(t0
, rt
);
19167 } else if (rs
== 0) {
19170 gen_helper_evpe(t0
, cpu_env
);
19171 gen_store_gpr(t0
, rt
);
19173 gen_reserved_instruction(ctx
);
19184 TCGv t0
= tcg_temp_new();
19185 TCGv t1
= tcg_temp_new();
19187 gen_load_gpr(t0
, rt
);
19188 gen_load_gpr(t1
, rs
);
19189 gen_helper_fork(t0
, t1
);
19196 check_cp0_enabled(ctx
);
19198 /* Treat as NOP. */
19201 gen_mftr(env
, ctx
, rs
, rt
, extract32(ctx
->opcode
, 10, 1),
19202 extract32(ctx
->opcode
, 11, 5), extract32(ctx
->opcode
, 3, 1));
19206 check_cp0_enabled(ctx
);
19207 gen_mttr(env
, ctx
, rs
, rt
, extract32(ctx
->opcode
, 10, 1),
19208 extract32(ctx
->opcode
, 11, 5), extract32(ctx
->opcode
, 3, 1));
19213 TCGv t0
= tcg_temp_new();
19215 gen_load_gpr(t0
, rs
);
19216 gen_helper_yield(t0
, cpu_env
, t0
);
19217 gen_store_gpr(t0
, rt
);
19223 gen_reserved_instruction(ctx
);
19229 static void gen_pool32axf_1_5_nanomips_insn(DisasContext
*ctx
, uint32_t opc
,
19230 int ret
, int v1
, int v2
)
19236 t0
= tcg_temp_new_i32();
19238 v0_t
= tcg_temp_new();
19239 v1_t
= tcg_temp_new();
19241 tcg_gen_movi_i32(t0
, v2
>> 3);
19243 gen_load_gpr(v0_t
, ret
);
19244 gen_load_gpr(v1_t
, v1
);
19247 case NM_MAQ_S_W_PHR
:
19249 gen_helper_maq_s_w_phr(t0
, v1_t
, v0_t
, cpu_env
);
19251 case NM_MAQ_S_W_PHL
:
19253 gen_helper_maq_s_w_phl(t0
, v1_t
, v0_t
, cpu_env
);
19255 case NM_MAQ_SA_W_PHR
:
19257 gen_helper_maq_sa_w_phr(t0
, v1_t
, v0_t
, cpu_env
);
19259 case NM_MAQ_SA_W_PHL
:
19261 gen_helper_maq_sa_w_phl(t0
, v1_t
, v0_t
, cpu_env
);
19264 gen_reserved_instruction(ctx
);
19268 tcg_temp_free_i32(t0
);
19270 tcg_temp_free(v0_t
);
19271 tcg_temp_free(v1_t
);
19275 static void gen_pool32axf_1_nanomips_insn(DisasContext
*ctx
, uint32_t opc
,
19276 int ret
, int v1
, int v2
)
19279 TCGv t0
= tcg_temp_new();
19280 TCGv t1
= tcg_temp_new();
19281 TCGv v0_t
= tcg_temp_new();
19283 gen_load_gpr(v0_t
, v1
);
19286 case NM_POOL32AXF_1_0
:
19288 switch (extract32(ctx
->opcode
, 12, 2)) {
19290 gen_HILO(ctx
, OPC_MFHI
, v2
>> 3, ret
);
19293 gen_HILO(ctx
, OPC_MFLO
, v2
>> 3, ret
);
19296 gen_HILO(ctx
, OPC_MTHI
, v2
>> 3, v1
);
19299 gen_HILO(ctx
, OPC_MTLO
, v2
>> 3, v1
);
19303 case NM_POOL32AXF_1_1
:
19305 switch (extract32(ctx
->opcode
, 12, 2)) {
19307 tcg_gen_movi_tl(t0
, v2
);
19308 gen_helper_mthlip(t0
, v0_t
, cpu_env
);
19311 tcg_gen_movi_tl(t0
, v2
>> 3);
19312 gen_helper_shilo(t0
, v0_t
, cpu_env
);
19315 gen_reserved_instruction(ctx
);
19319 case NM_POOL32AXF_1_3
:
19321 imm
= extract32(ctx
->opcode
, 14, 7);
19322 switch (extract32(ctx
->opcode
, 12, 2)) {
19324 tcg_gen_movi_tl(t0
, imm
);
19325 gen_helper_rddsp(t0
, t0
, cpu_env
);
19326 gen_store_gpr(t0
, ret
);
19329 gen_load_gpr(t0
, ret
);
19330 tcg_gen_movi_tl(t1
, imm
);
19331 gen_helper_wrdsp(t0
, t1
, cpu_env
);
19334 tcg_gen_movi_tl(t0
, v2
>> 3);
19335 tcg_gen_movi_tl(t1
, v1
);
19336 gen_helper_extp(t0
, t0
, t1
, cpu_env
);
19337 gen_store_gpr(t0
, ret
);
19340 tcg_gen_movi_tl(t0
, v2
>> 3);
19341 tcg_gen_movi_tl(t1
, v1
);
19342 gen_helper_extpdp(t0
, t0
, t1
, cpu_env
);
19343 gen_store_gpr(t0
, ret
);
19347 case NM_POOL32AXF_1_4
:
19349 tcg_gen_movi_tl(t0
, v2
>> 2);
19350 switch (extract32(ctx
->opcode
, 12, 1)) {
19352 gen_helper_shll_qb(t0
, t0
, v0_t
, cpu_env
);
19353 gen_store_gpr(t0
, ret
);
19356 gen_helper_shrl_qb(t0
, t0
, v0_t
);
19357 gen_store_gpr(t0
, ret
);
19361 case NM_POOL32AXF_1_5
:
19362 opc
= extract32(ctx
->opcode
, 12, 2);
19363 gen_pool32axf_1_5_nanomips_insn(ctx
, opc
, ret
, v1
, v2
);
19365 case NM_POOL32AXF_1_7
:
19367 tcg_gen_movi_tl(t0
, v2
>> 3);
19368 tcg_gen_movi_tl(t1
, v1
);
19369 switch (extract32(ctx
->opcode
, 12, 2)) {
19371 gen_helper_extr_w(t0
, t0
, t1
, cpu_env
);
19372 gen_store_gpr(t0
, ret
);
19375 gen_helper_extr_r_w(t0
, t0
, t1
, cpu_env
);
19376 gen_store_gpr(t0
, ret
);
19379 gen_helper_extr_rs_w(t0
, t0
, t1
, cpu_env
);
19380 gen_store_gpr(t0
, ret
);
19383 gen_helper_extr_s_h(t0
, t0
, t1
, cpu_env
);
19384 gen_store_gpr(t0
, ret
);
19389 gen_reserved_instruction(ctx
);
19395 tcg_temp_free(v0_t
);
19398 static void gen_pool32axf_2_multiply(DisasContext
*ctx
, uint32_t opc
,
19399 TCGv v0
, TCGv v1
, int rd
)
19403 t0
= tcg_temp_new_i32();
19405 tcg_gen_movi_i32(t0
, rd
>> 3);
19408 case NM_POOL32AXF_2_0_7
:
19409 switch (extract32(ctx
->opcode
, 9, 3)) {
19412 gen_helper_dpa_w_ph(t0
, v1
, v0
, cpu_env
);
19414 case NM_DPAQ_S_W_PH
:
19416 gen_helper_dpaq_s_w_ph(t0
, v1
, v0
, cpu_env
);
19420 gen_helper_dps_w_ph(t0
, v1
, v0
, cpu_env
);
19422 case NM_DPSQ_S_W_PH
:
19424 gen_helper_dpsq_s_w_ph(t0
, v1
, v0
, cpu_env
);
19427 gen_reserved_instruction(ctx
);
19431 case NM_POOL32AXF_2_8_15
:
19432 switch (extract32(ctx
->opcode
, 9, 3)) {
19435 gen_helper_dpax_w_ph(t0
, v0
, v1
, cpu_env
);
19437 case NM_DPAQ_SA_L_W
:
19439 gen_helper_dpaq_sa_l_w(t0
, v0
, v1
, cpu_env
);
19443 gen_helper_dpsx_w_ph(t0
, v0
, v1
, cpu_env
);
19445 case NM_DPSQ_SA_L_W
:
19447 gen_helper_dpsq_sa_l_w(t0
, v0
, v1
, cpu_env
);
19450 gen_reserved_instruction(ctx
);
19454 case NM_POOL32AXF_2_16_23
:
19455 switch (extract32(ctx
->opcode
, 9, 3)) {
19456 case NM_DPAU_H_QBL
:
19458 gen_helper_dpau_h_qbl(t0
, v0
, v1
, cpu_env
);
19460 case NM_DPAQX_S_W_PH
:
19462 gen_helper_dpaqx_s_w_ph(t0
, v0
, v1
, cpu_env
);
19464 case NM_DPSU_H_QBL
:
19466 gen_helper_dpsu_h_qbl(t0
, v0
, v1
, cpu_env
);
19468 case NM_DPSQX_S_W_PH
:
19470 gen_helper_dpsqx_s_w_ph(t0
, v0
, v1
, cpu_env
);
19472 case NM_MULSA_W_PH
:
19474 gen_helper_mulsa_w_ph(t0
, v0
, v1
, cpu_env
);
19477 gen_reserved_instruction(ctx
);
19481 case NM_POOL32AXF_2_24_31
:
19482 switch (extract32(ctx
->opcode
, 9, 3)) {
19483 case NM_DPAU_H_QBR
:
19485 gen_helper_dpau_h_qbr(t0
, v1
, v0
, cpu_env
);
19487 case NM_DPAQX_SA_W_PH
:
19489 gen_helper_dpaqx_sa_w_ph(t0
, v1
, v0
, cpu_env
);
19491 case NM_DPSU_H_QBR
:
19493 gen_helper_dpsu_h_qbr(t0
, v1
, v0
, cpu_env
);
19495 case NM_DPSQX_SA_W_PH
:
19497 gen_helper_dpsqx_sa_w_ph(t0
, v1
, v0
, cpu_env
);
19499 case NM_MULSAQ_S_W_PH
:
19501 gen_helper_mulsaq_s_w_ph(t0
, v1
, v0
, cpu_env
);
19504 gen_reserved_instruction(ctx
);
19509 gen_reserved_instruction(ctx
);
19513 tcg_temp_free_i32(t0
);
19516 static void gen_pool32axf_2_nanomips_insn(DisasContext
*ctx
, uint32_t opc
,
19517 int rt
, int rs
, int rd
)
19520 TCGv t0
= tcg_temp_new();
19521 TCGv t1
= tcg_temp_new();
19522 TCGv v0_t
= tcg_temp_new();
19523 TCGv v1_t
= tcg_temp_new();
19525 gen_load_gpr(v0_t
, rt
);
19526 gen_load_gpr(v1_t
, rs
);
19529 case NM_POOL32AXF_2_0_7
:
19530 switch (extract32(ctx
->opcode
, 9, 3)) {
19532 case NM_DPAQ_S_W_PH
:
19534 case NM_DPSQ_S_W_PH
:
19535 gen_pool32axf_2_multiply(ctx
, opc
, v0_t
, v1_t
, rd
);
19540 gen_load_gpr(t0
, rs
);
19542 if (rd
!= 0 && rd
!= 2) {
19543 tcg_gen_shli_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], 8 * rd
);
19544 tcg_gen_ext32u_tl(t0
, t0
);
19545 tcg_gen_shri_tl(t0
, t0
, 8 * (4 - rd
));
19546 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
19548 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
19554 int acc
= extract32(ctx
->opcode
, 14, 2);
19555 TCGv_i64 t2
= tcg_temp_new_i64();
19556 TCGv_i64 t3
= tcg_temp_new_i64();
19558 gen_load_gpr(t0
, rt
);
19559 gen_load_gpr(t1
, rs
);
19560 tcg_gen_ext_tl_i64(t2
, t0
);
19561 tcg_gen_ext_tl_i64(t3
, t1
);
19562 tcg_gen_mul_i64(t2
, t2
, t3
);
19563 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
19564 tcg_gen_add_i64(t2
, t2
, t3
);
19565 tcg_temp_free_i64(t3
);
19566 gen_move_low32(cpu_LO
[acc
], t2
);
19567 gen_move_high32(cpu_HI
[acc
], t2
);
19568 tcg_temp_free_i64(t2
);
19574 int acc
= extract32(ctx
->opcode
, 14, 2);
19575 TCGv_i32 t2
= tcg_temp_new_i32();
19576 TCGv_i32 t3
= tcg_temp_new_i32();
19578 gen_load_gpr(t0
, rs
);
19579 gen_load_gpr(t1
, rt
);
19580 tcg_gen_trunc_tl_i32(t2
, t0
);
19581 tcg_gen_trunc_tl_i32(t3
, t1
);
19582 tcg_gen_muls2_i32(t2
, t3
, t2
, t3
);
19583 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
19584 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
19585 tcg_temp_free_i32(t2
);
19586 tcg_temp_free_i32(t3
);
19591 gen_load_gpr(v1_t
, rs
);
19592 tcg_gen_movi_tl(t0
, rd
>> 3);
19593 gen_helper_extr_w(t0
, t0
, v1_t
, cpu_env
);
19594 gen_store_gpr(t0
, ret
);
19598 case NM_POOL32AXF_2_8_15
:
19599 switch (extract32(ctx
->opcode
, 9, 3)) {
19601 case NM_DPAQ_SA_L_W
:
19603 case NM_DPSQ_SA_L_W
:
19604 gen_pool32axf_2_multiply(ctx
, opc
, v0_t
, v1_t
, rd
);
19609 int acc
= extract32(ctx
->opcode
, 14, 2);
19610 TCGv_i64 t2
= tcg_temp_new_i64();
19611 TCGv_i64 t3
= tcg_temp_new_i64();
19613 gen_load_gpr(t0
, rs
);
19614 gen_load_gpr(t1
, rt
);
19615 tcg_gen_ext32u_tl(t0
, t0
);
19616 tcg_gen_ext32u_tl(t1
, t1
);
19617 tcg_gen_extu_tl_i64(t2
, t0
);
19618 tcg_gen_extu_tl_i64(t3
, t1
);
19619 tcg_gen_mul_i64(t2
, t2
, t3
);
19620 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
19621 tcg_gen_add_i64(t2
, t2
, t3
);
19622 tcg_temp_free_i64(t3
);
19623 gen_move_low32(cpu_LO
[acc
], t2
);
19624 gen_move_high32(cpu_HI
[acc
], t2
);
19625 tcg_temp_free_i64(t2
);
19631 int acc
= extract32(ctx
->opcode
, 14, 2);
19632 TCGv_i32 t2
= tcg_temp_new_i32();
19633 TCGv_i32 t3
= tcg_temp_new_i32();
19635 gen_load_gpr(t0
, rs
);
19636 gen_load_gpr(t1
, rt
);
19637 tcg_gen_trunc_tl_i32(t2
, t0
);
19638 tcg_gen_trunc_tl_i32(t3
, t1
);
19639 tcg_gen_mulu2_i32(t2
, t3
, t2
, t3
);
19640 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
19641 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
19642 tcg_temp_free_i32(t2
);
19643 tcg_temp_free_i32(t3
);
19648 tcg_gen_movi_tl(t0
, rd
>> 3);
19649 gen_helper_extr_r_w(t0
, t0
, v1_t
, cpu_env
);
19650 gen_store_gpr(t0
, ret
);
19653 gen_reserved_instruction(ctx
);
19657 case NM_POOL32AXF_2_16_23
:
19658 switch (extract32(ctx
->opcode
, 9, 3)) {
19659 case NM_DPAU_H_QBL
:
19660 case NM_DPAQX_S_W_PH
:
19661 case NM_DPSU_H_QBL
:
19662 case NM_DPSQX_S_W_PH
:
19663 case NM_MULSA_W_PH
:
19664 gen_pool32axf_2_multiply(ctx
, opc
, v0_t
, v1_t
, rd
);
19668 tcg_gen_movi_tl(t0
, rd
>> 3);
19669 gen_helper_extp(t0
, t0
, v1_t
, cpu_env
);
19670 gen_store_gpr(t0
, ret
);
19675 int acc
= extract32(ctx
->opcode
, 14, 2);
19676 TCGv_i64 t2
= tcg_temp_new_i64();
19677 TCGv_i64 t3
= tcg_temp_new_i64();
19679 gen_load_gpr(t0
, rs
);
19680 gen_load_gpr(t1
, rt
);
19681 tcg_gen_ext_tl_i64(t2
, t0
);
19682 tcg_gen_ext_tl_i64(t3
, t1
);
19683 tcg_gen_mul_i64(t2
, t2
, t3
);
19684 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
19685 tcg_gen_sub_i64(t2
, t3
, t2
);
19686 tcg_temp_free_i64(t3
);
19687 gen_move_low32(cpu_LO
[acc
], t2
);
19688 gen_move_high32(cpu_HI
[acc
], t2
);
19689 tcg_temp_free_i64(t2
);
19692 case NM_EXTRV_RS_W
:
19694 tcg_gen_movi_tl(t0
, rd
>> 3);
19695 gen_helper_extr_rs_w(t0
, t0
, v1_t
, cpu_env
);
19696 gen_store_gpr(t0
, ret
);
19700 case NM_POOL32AXF_2_24_31
:
19701 switch (extract32(ctx
->opcode
, 9, 3)) {
19702 case NM_DPAU_H_QBR
:
19703 case NM_DPAQX_SA_W_PH
:
19704 case NM_DPSU_H_QBR
:
19705 case NM_DPSQX_SA_W_PH
:
19706 case NM_MULSAQ_S_W_PH
:
19707 gen_pool32axf_2_multiply(ctx
, opc
, v0_t
, v1_t
, rd
);
19711 tcg_gen_movi_tl(t0
, rd
>> 3);
19712 gen_helper_extpdp(t0
, t0
, v1_t
, cpu_env
);
19713 gen_store_gpr(t0
, ret
);
19718 int acc
= extract32(ctx
->opcode
, 14, 2);
19719 TCGv_i64 t2
= tcg_temp_new_i64();
19720 TCGv_i64 t3
= tcg_temp_new_i64();
19722 gen_load_gpr(t0
, rs
);
19723 gen_load_gpr(t1
, rt
);
19724 tcg_gen_ext32u_tl(t0
, t0
);
19725 tcg_gen_ext32u_tl(t1
, t1
);
19726 tcg_gen_extu_tl_i64(t2
, t0
);
19727 tcg_gen_extu_tl_i64(t3
, t1
);
19728 tcg_gen_mul_i64(t2
, t2
, t3
);
19729 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
19730 tcg_gen_sub_i64(t2
, t3
, t2
);
19731 tcg_temp_free_i64(t3
);
19732 gen_move_low32(cpu_LO
[acc
], t2
);
19733 gen_move_high32(cpu_HI
[acc
], t2
);
19734 tcg_temp_free_i64(t2
);
19739 tcg_gen_movi_tl(t0
, rd
>> 3);
19740 gen_helper_extr_s_h(t0
, t0
, v0_t
, cpu_env
);
19741 gen_store_gpr(t0
, ret
);
19746 gen_reserved_instruction(ctx
);
19753 tcg_temp_free(v0_t
);
19754 tcg_temp_free(v1_t
);
19757 static void gen_pool32axf_4_nanomips_insn(DisasContext
*ctx
, uint32_t opc
,
19761 TCGv t0
= tcg_temp_new();
19762 TCGv v0_t
= tcg_temp_new();
19764 gen_load_gpr(v0_t
, rs
);
19769 gen_helper_absq_s_qb(v0_t
, v0_t
, cpu_env
);
19770 gen_store_gpr(v0_t
, ret
);
19774 gen_helper_absq_s_ph(v0_t
, v0_t
, cpu_env
);
19775 gen_store_gpr(v0_t
, ret
);
19779 gen_helper_absq_s_w(v0_t
, v0_t
, cpu_env
);
19780 gen_store_gpr(v0_t
, ret
);
19782 case NM_PRECEQ_W_PHL
:
19784 tcg_gen_andi_tl(v0_t
, v0_t
, 0xFFFF0000);
19785 tcg_gen_ext32s_tl(v0_t
, v0_t
);
19786 gen_store_gpr(v0_t
, ret
);
19788 case NM_PRECEQ_W_PHR
:
19790 tcg_gen_andi_tl(v0_t
, v0_t
, 0x0000FFFF);
19791 tcg_gen_shli_tl(v0_t
, v0_t
, 16);
19792 tcg_gen_ext32s_tl(v0_t
, v0_t
);
19793 gen_store_gpr(v0_t
, ret
);
19795 case NM_PRECEQU_PH_QBL
:
19797 gen_helper_precequ_ph_qbl(v0_t
, v0_t
);
19798 gen_store_gpr(v0_t
, ret
);
19800 case NM_PRECEQU_PH_QBR
:
19802 gen_helper_precequ_ph_qbr(v0_t
, v0_t
);
19803 gen_store_gpr(v0_t
, ret
);
19805 case NM_PRECEQU_PH_QBLA
:
19807 gen_helper_precequ_ph_qbla(v0_t
, v0_t
);
19808 gen_store_gpr(v0_t
, ret
);
19810 case NM_PRECEQU_PH_QBRA
:
19812 gen_helper_precequ_ph_qbra(v0_t
, v0_t
);
19813 gen_store_gpr(v0_t
, ret
);
19815 case NM_PRECEU_PH_QBL
:
19817 gen_helper_preceu_ph_qbl(v0_t
, v0_t
);
19818 gen_store_gpr(v0_t
, ret
);
19820 case NM_PRECEU_PH_QBR
:
19822 gen_helper_preceu_ph_qbr(v0_t
, v0_t
);
19823 gen_store_gpr(v0_t
, ret
);
19825 case NM_PRECEU_PH_QBLA
:
19827 gen_helper_preceu_ph_qbla(v0_t
, v0_t
);
19828 gen_store_gpr(v0_t
, ret
);
19830 case NM_PRECEU_PH_QBRA
:
19832 gen_helper_preceu_ph_qbra(v0_t
, v0_t
);
19833 gen_store_gpr(v0_t
, ret
);
19837 tcg_gen_ext16u_tl(v0_t
, v0_t
);
19838 tcg_gen_shli_tl(t0
, v0_t
, 16);
19839 tcg_gen_or_tl(v0_t
, v0_t
, t0
);
19840 tcg_gen_ext32s_tl(v0_t
, v0_t
);
19841 gen_store_gpr(v0_t
, ret
);
19845 tcg_gen_ext8u_tl(v0_t
, v0_t
);
19846 tcg_gen_shli_tl(t0
, v0_t
, 8);
19847 tcg_gen_or_tl(v0_t
, v0_t
, t0
);
19848 tcg_gen_shli_tl(t0
, v0_t
, 16);
19849 tcg_gen_or_tl(v0_t
, v0_t
, t0
);
19850 tcg_gen_ext32s_tl(v0_t
, v0_t
);
19851 gen_store_gpr(v0_t
, ret
);
19855 gen_helper_bitrev(v0_t
, v0_t
);
19856 gen_store_gpr(v0_t
, ret
);
19861 TCGv tv0
= tcg_temp_new();
19863 gen_load_gpr(tv0
, rt
);
19864 gen_helper_insv(v0_t
, cpu_env
, v0_t
, tv0
);
19865 gen_store_gpr(v0_t
, ret
);
19866 tcg_temp_free(tv0
);
19869 case NM_RADDU_W_QB
:
19871 gen_helper_raddu_w_qb(v0_t
, v0_t
);
19872 gen_store_gpr(v0_t
, ret
);
19875 gen_bitswap(ctx
, OPC_BITSWAP
, ret
, rs
);
19879 gen_cl(ctx
, OPC_CLO
, ret
, rs
);
19883 gen_cl(ctx
, OPC_CLZ
, ret
, rs
);
19886 gen_bshfl(ctx
, OPC_WSBH
, ret
, rs
);
19889 gen_reserved_instruction(ctx
);
19893 tcg_temp_free(v0_t
);
19897 static void gen_pool32axf_7_nanomips_insn(DisasContext
*ctx
, uint32_t opc
,
19898 int rt
, int rs
, int rd
)
19900 TCGv t0
= tcg_temp_new();
19901 TCGv rs_t
= tcg_temp_new();
19903 gen_load_gpr(rs_t
, rs
);
19908 tcg_gen_movi_tl(t0
, rd
>> 2);
19909 switch (extract32(ctx
->opcode
, 12, 1)) {
19912 gen_helper_shra_qb(t0
, t0
, rs_t
);
19913 gen_store_gpr(t0
, rt
);
19917 gen_helper_shra_r_qb(t0
, t0
, rs_t
);
19918 gen_store_gpr(t0
, rt
);
19924 tcg_gen_movi_tl(t0
, rd
>> 1);
19925 gen_helper_shrl_ph(t0
, t0
, rs_t
);
19926 gen_store_gpr(t0
, rt
);
19932 target_long result
;
19933 imm
= extract32(ctx
->opcode
, 13, 8);
19934 result
= (uint32_t)imm
<< 24 |
19935 (uint32_t)imm
<< 16 |
19936 (uint32_t)imm
<< 8 |
19938 result
= (int32_t)result
;
19939 tcg_gen_movi_tl(t0
, result
);
19940 gen_store_gpr(t0
, rt
);
19944 gen_reserved_instruction(ctx
);
19948 tcg_temp_free(rs_t
);
19952 static void gen_pool32axf_nanomips_insn(CPUMIPSState
*env
, DisasContext
*ctx
)
19954 int rt
= extract32(ctx
->opcode
, 21, 5);
19955 int rs
= extract32(ctx
->opcode
, 16, 5);
19956 int rd
= extract32(ctx
->opcode
, 11, 5);
19958 switch (extract32(ctx
->opcode
, 6, 3)) {
19959 case NM_POOL32AXF_1
:
19961 int32_t op1
= extract32(ctx
->opcode
, 9, 3);
19962 gen_pool32axf_1_nanomips_insn(ctx
, op1
, rt
, rs
, rd
);
19965 case NM_POOL32AXF_2
:
19967 int32_t op1
= extract32(ctx
->opcode
, 12, 2);
19968 gen_pool32axf_2_nanomips_insn(ctx
, op1
, rt
, rs
, rd
);
19971 case NM_POOL32AXF_4
:
19973 int32_t op1
= extract32(ctx
->opcode
, 9, 7);
19974 gen_pool32axf_4_nanomips_insn(ctx
, op1
, rt
, rs
);
19977 case NM_POOL32AXF_5
:
19978 switch (extract32(ctx
->opcode
, 9, 7)) {
19979 #ifndef CONFIG_USER_ONLY
19981 gen_cp0(env
, ctx
, OPC_TLBP
, 0, 0);
19984 gen_cp0(env
, ctx
, OPC_TLBR
, 0, 0);
19987 gen_cp0(env
, ctx
, OPC_TLBWI
, 0, 0);
19990 gen_cp0(env
, ctx
, OPC_TLBWR
, 0, 0);
19993 gen_cp0(env
, ctx
, OPC_TLBINV
, 0, 0);
19996 gen_cp0(env
, ctx
, OPC_TLBINVF
, 0, 0);
19999 check_cp0_enabled(ctx
);
20001 TCGv t0
= tcg_temp_new();
20003 save_cpu_state(ctx
, 1);
20004 gen_helper_di(t0
, cpu_env
);
20005 gen_store_gpr(t0
, rt
);
20006 /* Stop translation as we may have switched the execution mode */
20007 ctx
->base
.is_jmp
= DISAS_STOP
;
20012 check_cp0_enabled(ctx
);
20014 TCGv t0
= tcg_temp_new();
20016 save_cpu_state(ctx
, 1);
20017 gen_helper_ei(t0
, cpu_env
);
20018 gen_store_gpr(t0
, rt
);
20019 /* Stop translation as we may have switched the execution mode */
20020 ctx
->base
.is_jmp
= DISAS_STOP
;
20025 gen_load_srsgpr(rs
, rt
);
20028 gen_store_srsgpr(rs
, rt
);
20031 gen_cp0(env
, ctx
, OPC_WAIT
, 0, 0);
20034 gen_cp0(env
, ctx
, OPC_DERET
, 0, 0);
20037 gen_cp0(env
, ctx
, OPC_ERET
, 0, 0);
20041 gen_reserved_instruction(ctx
);
20045 case NM_POOL32AXF_7
:
20047 int32_t op1
= extract32(ctx
->opcode
, 9, 3);
20048 gen_pool32axf_7_nanomips_insn(ctx
, op1
, rt
, rs
, rd
);
20052 gen_reserved_instruction(ctx
);
20057 /* Immediate Value Compact Branches */
20058 static void gen_compute_imm_branch(DisasContext
*ctx
, uint32_t opc
,
20059 int rt
, int32_t imm
, int32_t offset
)
20061 TCGCond cond
= TCG_COND_ALWAYS
;
20062 TCGv t0
= tcg_temp_new();
20063 TCGv t1
= tcg_temp_new();
20065 gen_load_gpr(t0
, rt
);
20066 tcg_gen_movi_tl(t1
, imm
);
20067 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
20069 /* Load needed operands and calculate btarget */
20072 if (rt
== 0 && imm
== 0) {
20073 /* Unconditional branch */
20074 } else if (rt
== 0 && imm
!= 0) {
20078 cond
= TCG_COND_EQ
;
20084 if (imm
>= 32 && !(ctx
->hflags
& MIPS_HFLAG_64
)) {
20085 gen_reserved_instruction(ctx
);
20087 } else if (rt
== 0 && opc
== NM_BBEQZC
) {
20088 /* Unconditional branch */
20089 } else if (rt
== 0 && opc
== NM_BBNEZC
) {
20093 tcg_gen_shri_tl(t0
, t0
, imm
);
20094 tcg_gen_andi_tl(t0
, t0
, 1);
20095 tcg_gen_movi_tl(t1
, 0);
20096 if (opc
== NM_BBEQZC
) {
20097 cond
= TCG_COND_EQ
;
20099 cond
= TCG_COND_NE
;
20104 if (rt
== 0 && imm
== 0) {
20107 } else if (rt
== 0 && imm
!= 0) {
20108 /* Unconditional branch */
20110 cond
= TCG_COND_NE
;
20114 if (rt
== 0 && imm
== 0) {
20115 /* Unconditional branch */
20117 cond
= TCG_COND_GE
;
20121 cond
= TCG_COND_LT
;
20124 if (rt
== 0 && imm
== 0) {
20125 /* Unconditional branch */
20127 cond
= TCG_COND_GEU
;
20131 cond
= TCG_COND_LTU
;
20134 MIPS_INVAL("Immediate Value Compact branch");
20135 gen_reserved_instruction(ctx
);
20139 /* branch completion */
20140 clear_branch_hflags(ctx
);
20141 ctx
->base
.is_jmp
= DISAS_NORETURN
;
20143 if (cond
== TCG_COND_ALWAYS
) {
20144 /* Uncoditional compact branch */
20145 gen_goto_tb(ctx
, 0, ctx
->btarget
);
20147 /* Conditional compact branch */
20148 TCGLabel
*fs
= gen_new_label();
20150 tcg_gen_brcond_tl(tcg_invert_cond(cond
), t0
, t1
, fs
);
20152 gen_goto_tb(ctx
, 1, ctx
->btarget
);
20155 gen_goto_tb(ctx
, 0, ctx
->base
.pc_next
+ 4);
20163 /* P.BALRSC type nanoMIPS R6 branches: BALRSC and BRSC */
20164 static void gen_compute_nanomips_pbalrsc_branch(DisasContext
*ctx
, int rs
,
20167 TCGv t0
= tcg_temp_new();
20168 TCGv t1
= tcg_temp_new();
20171 gen_load_gpr(t0
, rs
);
20175 tcg_gen_movi_tl(cpu_gpr
[rt
], ctx
->base
.pc_next
+ 4);
20178 /* calculate btarget */
20179 tcg_gen_shli_tl(t0
, t0
, 1);
20180 tcg_gen_movi_tl(t1
, ctx
->base
.pc_next
+ 4);
20181 gen_op_addr_add(ctx
, btarget
, t1
, t0
);
20183 /* branch completion */
20184 clear_branch_hflags(ctx
);
20185 ctx
->base
.is_jmp
= DISAS_NORETURN
;
20187 /* unconditional branch to register */
20188 tcg_gen_mov_tl(cpu_PC
, btarget
);
20189 tcg_gen_lookup_and_goto_ptr();
20195 /* nanoMIPS Branches */
20196 static void gen_compute_compact_branch_nm(DisasContext
*ctx
, uint32_t opc
,
20197 int rs
, int rt
, int32_t offset
)
20199 int bcond_compute
= 0;
20200 TCGv t0
= tcg_temp_new();
20201 TCGv t1
= tcg_temp_new();
20203 /* Load needed operands and calculate btarget */
20205 /* compact branch */
20208 gen_load_gpr(t0
, rs
);
20209 gen_load_gpr(t1
, rt
);
20211 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
20215 if (rs
== 0 || rs
== rt
) {
20216 /* OPC_BLEZALC, OPC_BGEZALC */
20217 /* OPC_BGTZALC, OPC_BLTZALC */
20218 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 4);
20220 gen_load_gpr(t0
, rs
);
20221 gen_load_gpr(t1
, rt
);
20223 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
20226 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
20230 /* OPC_BEQZC, OPC_BNEZC */
20231 gen_load_gpr(t0
, rs
);
20233 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
20235 /* OPC_JIC, OPC_JIALC */
20236 TCGv tbase
= tcg_temp_new();
20237 TCGv toffset
= tcg_temp_new();
20239 gen_load_gpr(tbase
, rt
);
20240 tcg_gen_movi_tl(toffset
, offset
);
20241 gen_op_addr_add(ctx
, btarget
, tbase
, toffset
);
20242 tcg_temp_free(tbase
);
20243 tcg_temp_free(toffset
);
20247 MIPS_INVAL("Compact branch/jump");
20248 gen_reserved_instruction(ctx
);
20252 if (bcond_compute
== 0) {
20253 /* Uncoditional compact branch */
20256 gen_goto_tb(ctx
, 0, ctx
->btarget
);
20259 MIPS_INVAL("Compact branch/jump");
20260 gen_reserved_instruction(ctx
);
20264 /* Conditional compact branch */
20265 TCGLabel
*fs
= gen_new_label();
20269 if (rs
== 0 && rt
!= 0) {
20271 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE
), t1
, 0, fs
);
20272 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
20274 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE
), t1
, 0, fs
);
20277 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU
), t0
, t1
, fs
);
20281 if (rs
== 0 && rt
!= 0) {
20283 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT
), t1
, 0, fs
);
20284 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
20286 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT
), t1
, 0, fs
);
20289 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU
), t0
, t1
, fs
);
20293 if (rs
== 0 && rt
!= 0) {
20295 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE
), t1
, 0, fs
);
20296 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
20298 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE
), t1
, 0, fs
);
20301 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE
), t0
, t1
, fs
);
20305 if (rs
== 0 && rt
!= 0) {
20307 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT
), t1
, 0, fs
);
20308 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
20310 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT
), t1
, 0, fs
);
20313 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT
), t0
, t1
, fs
);
20317 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ
), t0
, 0, fs
);
20320 MIPS_INVAL("Compact conditional branch/jump");
20321 gen_reserved_instruction(ctx
);
20325 /* branch completion */
20326 clear_branch_hflags(ctx
);
20327 ctx
->base
.is_jmp
= DISAS_NORETURN
;
20329 /* Generating branch here as compact branches don't have delay slot */
20330 gen_goto_tb(ctx
, 1, ctx
->btarget
);
20333 gen_goto_tb(ctx
, 0, ctx
->base
.pc_next
+ 4);
20342 /* nanoMIPS CP1 Branches */
20343 static void gen_compute_branch_cp1_nm(DisasContext
*ctx
, uint32_t op
,
20344 int32_t ft
, int32_t offset
)
20346 target_ulong btarget
;
20347 TCGv_i64 t0
= tcg_temp_new_i64();
20349 gen_load_fpr64(ctx
, t0
, ft
);
20350 tcg_gen_andi_i64(t0
, t0
, 1);
20352 btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
20356 tcg_gen_xori_i64(t0
, t0
, 1);
20357 ctx
->hflags
|= MIPS_HFLAG_BC
;
20360 /* t0 already set */
20361 ctx
->hflags
|= MIPS_HFLAG_BC
;
20364 MIPS_INVAL("cp1 cond branch");
20365 gen_reserved_instruction(ctx
);
20369 tcg_gen_trunc_i64_tl(bcond
, t0
);
20371 ctx
->btarget
= btarget
;
20374 tcg_temp_free_i64(t0
);
20378 static void gen_p_lsx(DisasContext
*ctx
, int rd
, int rs
, int rt
)
20381 t0
= tcg_temp_new();
20382 t1
= tcg_temp_new();
20384 gen_load_gpr(t0
, rs
);
20385 gen_load_gpr(t1
, rt
);
20387 if ((extract32(ctx
->opcode
, 6, 1)) == 1) {
20388 /* PP.LSXS instructions require shifting */
20389 switch (extract32(ctx
->opcode
, 7, 4)) {
20395 tcg_gen_shli_tl(t0
, t0
, 1);
20403 tcg_gen_shli_tl(t0
, t0
, 2);
20407 tcg_gen_shli_tl(t0
, t0
, 3);
20411 gen_op_addr_add(ctx
, t0
, t0
, t1
);
20413 switch (extract32(ctx
->opcode
, 7, 4)) {
20415 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
,
20417 gen_store_gpr(t0
, rd
);
20421 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
,
20423 gen_store_gpr(t0
, rd
);
20427 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
,
20429 gen_store_gpr(t0
, rd
);
20432 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
,
20434 gen_store_gpr(t0
, rd
);
20438 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
,
20440 gen_store_gpr(t0
, rd
);
20444 gen_load_gpr(t1
, rd
);
20445 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
,
20451 gen_load_gpr(t1
, rd
);
20452 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
,
20458 gen_load_gpr(t1
, rd
);
20459 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
,
20463 /*case NM_LWC1XS:*/
20465 /*case NM_LDC1XS:*/
20467 /*case NM_SWC1XS:*/
20469 /*case NM_SDC1XS:*/
20470 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
20471 check_cp1_enabled(ctx
);
20472 switch (extract32(ctx
->opcode
, 7, 4)) {
20474 /*case NM_LWC1XS:*/
20475 gen_flt_ldst(ctx
, OPC_LWC1
, rd
, t0
);
20478 /*case NM_LDC1XS:*/
20479 gen_flt_ldst(ctx
, OPC_LDC1
, rd
, t0
);
20482 /*case NM_SWC1XS:*/
20483 gen_flt_ldst(ctx
, OPC_SWC1
, rd
, t0
);
20486 /*case NM_SDC1XS:*/
20487 gen_flt_ldst(ctx
, OPC_SDC1
, rd
, t0
);
20491 generate_exception_err(ctx
, EXCP_CpU
, 1);
20495 gen_reserved_instruction(ctx
);
20503 static void gen_pool32f_nanomips_insn(DisasContext
*ctx
)
20507 rt
= extract32(ctx
->opcode
, 21, 5);
20508 rs
= extract32(ctx
->opcode
, 16, 5);
20509 rd
= extract32(ctx
->opcode
, 11, 5);
20511 if (!(ctx
->CP0_Config1
& (1 << CP0C1_FP
))) {
20512 gen_reserved_instruction(ctx
);
20515 check_cp1_enabled(ctx
);
20516 switch (extract32(ctx
->opcode
, 0, 3)) {
20518 switch (extract32(ctx
->opcode
, 3, 7)) {
20520 gen_farith(ctx
, OPC_RINT_S
, 0, rt
, rs
, 0);
20523 gen_farith(ctx
, OPC_RINT_D
, 0, rt
, rs
, 0);
20526 gen_farith(ctx
, OPC_CLASS_S
, 0, rt
, rs
, 0);
20529 gen_farith(ctx
, OPC_CLASS_D
, 0, rt
, rs
, 0);
20532 gen_farith(ctx
, OPC_ADD_S
, rt
, rs
, rd
, 0);
20535 gen_farith(ctx
, OPC_ADD_D
, rt
, rs
, rd
, 0);
20538 gen_farith(ctx
, OPC_SUB_S
, rt
, rs
, rd
, 0);
20541 gen_farith(ctx
, OPC_SUB_D
, rt
, rs
, rd
, 0);
20544 gen_farith(ctx
, OPC_MUL_S
, rt
, rs
, rd
, 0);
20547 gen_farith(ctx
, OPC_MUL_D
, rt
, rs
, rd
, 0);
20550 gen_farith(ctx
, OPC_DIV_S
, rt
, rs
, rd
, 0);
20553 gen_farith(ctx
, OPC_DIV_D
, rt
, rs
, rd
, 0);
20556 gen_sel_s(ctx
, OPC_SELEQZ_S
, rd
, rt
, rs
);
20559 gen_sel_d(ctx
, OPC_SELEQZ_D
, rd
, rt
, rs
);
20562 gen_sel_s(ctx
, OPC_SELNEZ_S
, rd
, rt
, rs
);
20565 gen_sel_d(ctx
, OPC_SELNEZ_D
, rd
, rt
, rs
);
20568 gen_sel_s(ctx
, OPC_SEL_S
, rd
, rt
, rs
);
20571 gen_sel_d(ctx
, OPC_SEL_D
, rd
, rt
, rs
);
20574 gen_farith(ctx
, OPC_MADDF_S
, rt
, rs
, rd
, 0);
20577 gen_farith(ctx
, OPC_MADDF_D
, rt
, rs
, rd
, 0);
20580 gen_farith(ctx
, OPC_MSUBF_S
, rt
, rs
, rd
, 0);
20583 gen_farith(ctx
, OPC_MSUBF_D
, rt
, rs
, rd
, 0);
20586 gen_reserved_instruction(ctx
);
20591 switch (extract32(ctx
->opcode
, 3, 3)) {
20593 switch (extract32(ctx
->opcode
, 9, 1)) {
20595 gen_farith(ctx
, OPC_MIN_S
, rt
, rs
, rd
, 0);
20598 gen_farith(ctx
, OPC_MIN_D
, rt
, rs
, rd
, 0);
20603 switch (extract32(ctx
->opcode
, 9, 1)) {
20605 gen_farith(ctx
, OPC_MAX_S
, rt
, rs
, rd
, 0);
20608 gen_farith(ctx
, OPC_MAX_D
, rt
, rs
, rd
, 0);
20613 switch (extract32(ctx
->opcode
, 9, 1)) {
20615 gen_farith(ctx
, OPC_MINA_S
, rt
, rs
, rd
, 0);
20618 gen_farith(ctx
, OPC_MINA_D
, rt
, rs
, rd
, 0);
20623 switch (extract32(ctx
->opcode
, 9, 1)) {
20625 gen_farith(ctx
, OPC_MAXA_S
, rt
, rs
, rd
, 0);
20628 gen_farith(ctx
, OPC_MAXA_D
, rt
, rs
, rd
, 0);
20633 switch (extract32(ctx
->opcode
, 6, 8)) {
20635 gen_cp1(ctx
, OPC_CFC1
, rt
, rs
);
20638 gen_cp1(ctx
, OPC_CTC1
, rt
, rs
);
20641 gen_cp1(ctx
, OPC_MFC1
, rt
, rs
);
20644 gen_cp1(ctx
, OPC_MTC1
, rt
, rs
);
20647 gen_cp1(ctx
, OPC_MFHC1
, rt
, rs
);
20650 gen_cp1(ctx
, OPC_MTHC1
, rt
, rs
);
20653 gen_farith(ctx
, OPC_CVT_S_PL
, -1, rs
, rt
, 0);
20656 gen_farith(ctx
, OPC_CVT_S_PU
, -1, rs
, rt
, 0);
20659 switch (extract32(ctx
->opcode
, 6, 9)) {
20661 gen_farith(ctx
, OPC_CVT_L_S
, -1, rs
, rt
, 0);
20664 gen_farith(ctx
, OPC_CVT_L_D
, -1, rs
, rt
, 0);
20667 gen_farith(ctx
, OPC_CVT_W_S
, -1, rs
, rt
, 0);
20670 gen_farith(ctx
, OPC_CVT_W_D
, -1, rs
, rt
, 0);
20673 gen_farith(ctx
, OPC_RSQRT_S
, -1, rs
, rt
, 0);
20676 gen_farith(ctx
, OPC_RSQRT_D
, -1, rs
, rt
, 0);
20679 gen_farith(ctx
, OPC_SQRT_S
, -1, rs
, rt
, 0);
20682 gen_farith(ctx
, OPC_SQRT_D
, -1, rs
, rt
, 0);
20685 gen_farith(ctx
, OPC_RECIP_S
, -1, rs
, rt
, 0);
20688 gen_farith(ctx
, OPC_RECIP_D
, -1, rs
, rt
, 0);
20691 gen_farith(ctx
, OPC_FLOOR_L_S
, -1, rs
, rt
, 0);
20694 gen_farith(ctx
, OPC_FLOOR_L_D
, -1, rs
, rt
, 0);
20697 gen_farith(ctx
, OPC_FLOOR_W_S
, -1, rs
, rt
, 0);
20700 gen_farith(ctx
, OPC_FLOOR_W_D
, -1, rs
, rt
, 0);
20703 gen_farith(ctx
, OPC_CEIL_L_S
, -1, rs
, rt
, 0);
20706 gen_farith(ctx
, OPC_CEIL_L_D
, -1, rs
, rt
, 0);
20709 gen_farith(ctx
, OPC_CEIL_W_S
, -1, rs
, rt
, 0);
20712 gen_farith(ctx
, OPC_CEIL_W_D
, -1, rs
, rt
, 0);
20715 gen_farith(ctx
, OPC_TRUNC_L_S
, -1, rs
, rt
, 0);
20718 gen_farith(ctx
, OPC_TRUNC_L_D
, -1, rs
, rt
, 0);
20721 gen_farith(ctx
, OPC_TRUNC_W_S
, -1, rs
, rt
, 0);
20724 gen_farith(ctx
, OPC_TRUNC_W_D
, -1, rs
, rt
, 0);
20727 gen_farith(ctx
, OPC_ROUND_L_S
, -1, rs
, rt
, 0);
20730 gen_farith(ctx
, OPC_ROUND_L_D
, -1, rs
, rt
, 0);
20733 gen_farith(ctx
, OPC_ROUND_W_S
, -1, rs
, rt
, 0);
20736 gen_farith(ctx
, OPC_ROUND_W_D
, -1, rs
, rt
, 0);
20739 gen_farith(ctx
, OPC_MOV_S
, -1, rs
, rt
, 0);
20742 gen_farith(ctx
, OPC_MOV_D
, -1, rs
, rt
, 0);
20745 gen_farith(ctx
, OPC_ABS_S
, -1, rs
, rt
, 0);
20748 gen_farith(ctx
, OPC_ABS_D
, -1, rs
, rt
, 0);
20751 gen_farith(ctx
, OPC_NEG_S
, -1, rs
, rt
, 0);
20754 gen_farith(ctx
, OPC_NEG_D
, -1, rs
, rt
, 0);
20757 gen_farith(ctx
, OPC_CVT_D_S
, -1, rs
, rt
, 0);
20760 gen_farith(ctx
, OPC_CVT_D_W
, -1, rs
, rt
, 0);
20763 gen_farith(ctx
, OPC_CVT_D_L
, -1, rs
, rt
, 0);
20766 gen_farith(ctx
, OPC_CVT_S_D
, -1, rs
, rt
, 0);
20769 gen_farith(ctx
, OPC_CVT_S_W
, -1, rs
, rt
, 0);
20772 gen_farith(ctx
, OPC_CVT_S_L
, -1, rs
, rt
, 0);
20775 gen_reserved_instruction(ctx
);
20784 switch (extract32(ctx
->opcode
, 3, 3)) {
20785 case NM_CMP_CONDN_S
:
20786 gen_r6_cmp_s(ctx
, extract32(ctx
->opcode
, 6, 5), rt
, rs
, rd
);
20788 case NM_CMP_CONDN_D
:
20789 gen_r6_cmp_d(ctx
, extract32(ctx
->opcode
, 6, 5), rt
, rs
, rd
);
20792 gen_reserved_instruction(ctx
);
20797 gen_reserved_instruction(ctx
);
20802 static void gen_pool32a5_nanomips_insn(DisasContext
*ctx
, int opc
,
20803 int rd
, int rs
, int rt
)
20806 TCGv t0
= tcg_temp_new();
20807 TCGv v1_t
= tcg_temp_new();
20808 TCGv v2_t
= tcg_temp_new();
20810 gen_load_gpr(v1_t
, rs
);
20811 gen_load_gpr(v2_t
, rt
);
20816 gen_helper_cmp_eq_ph(v1_t
, v2_t
, cpu_env
);
20820 gen_helper_cmp_lt_ph(v1_t
, v2_t
, cpu_env
);
20824 gen_helper_cmp_le_ph(v1_t
, v2_t
, cpu_env
);
20826 case NM_CMPU_EQ_QB
:
20828 gen_helper_cmpu_eq_qb(v1_t
, v2_t
, cpu_env
);
20830 case NM_CMPU_LT_QB
:
20832 gen_helper_cmpu_lt_qb(v1_t
, v2_t
, cpu_env
);
20834 case NM_CMPU_LE_QB
:
20836 gen_helper_cmpu_le_qb(v1_t
, v2_t
, cpu_env
);
20838 case NM_CMPGU_EQ_QB
:
20840 gen_helper_cmpgu_eq_qb(v1_t
, v1_t
, v2_t
);
20841 gen_store_gpr(v1_t
, ret
);
20843 case NM_CMPGU_LT_QB
:
20845 gen_helper_cmpgu_lt_qb(v1_t
, v1_t
, v2_t
);
20846 gen_store_gpr(v1_t
, ret
);
20848 case NM_CMPGU_LE_QB
:
20850 gen_helper_cmpgu_le_qb(v1_t
, v1_t
, v2_t
);
20851 gen_store_gpr(v1_t
, ret
);
20853 case NM_CMPGDU_EQ_QB
:
20855 gen_helper_cmpgu_eq_qb(v1_t
, v1_t
, v2_t
);
20856 tcg_gen_deposit_tl(cpu_dspctrl
, cpu_dspctrl
, v1_t
, 24, 4);
20857 gen_store_gpr(v1_t
, ret
);
20859 case NM_CMPGDU_LT_QB
:
20861 gen_helper_cmpgu_lt_qb(v1_t
, v1_t
, v2_t
);
20862 tcg_gen_deposit_tl(cpu_dspctrl
, cpu_dspctrl
, v1_t
, 24, 4);
20863 gen_store_gpr(v1_t
, ret
);
20865 case NM_CMPGDU_LE_QB
:
20867 gen_helper_cmpgu_le_qb(v1_t
, v1_t
, v2_t
);
20868 tcg_gen_deposit_tl(cpu_dspctrl
, cpu_dspctrl
, v1_t
, 24, 4);
20869 gen_store_gpr(v1_t
, ret
);
20873 gen_helper_packrl_ph(v1_t
, v1_t
, v2_t
);
20874 gen_store_gpr(v1_t
, ret
);
20878 gen_helper_pick_qb(v1_t
, v1_t
, v2_t
, cpu_env
);
20879 gen_store_gpr(v1_t
, ret
);
20883 gen_helper_pick_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20884 gen_store_gpr(v1_t
, ret
);
20888 gen_helper_addq_s_w(v1_t
, v1_t
, v2_t
, cpu_env
);
20889 gen_store_gpr(v1_t
, ret
);
20893 gen_helper_subq_s_w(v1_t
, v1_t
, v2_t
, cpu_env
);
20894 gen_store_gpr(v1_t
, ret
);
20898 gen_helper_addsc(v1_t
, v1_t
, v2_t
, cpu_env
);
20899 gen_store_gpr(v1_t
, ret
);
20903 gen_helper_addwc(v1_t
, v1_t
, v2_t
, cpu_env
);
20904 gen_store_gpr(v1_t
, ret
);
20908 switch (extract32(ctx
->opcode
, 10, 1)) {
20911 gen_helper_addq_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20912 gen_store_gpr(v1_t
, ret
);
20916 gen_helper_addq_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20917 gen_store_gpr(v1_t
, ret
);
20921 case NM_ADDQH_R_PH
:
20923 switch (extract32(ctx
->opcode
, 10, 1)) {
20926 gen_helper_addqh_ph(v1_t
, v1_t
, v2_t
);
20927 gen_store_gpr(v1_t
, ret
);
20931 gen_helper_addqh_r_ph(v1_t
, v1_t
, v2_t
);
20932 gen_store_gpr(v1_t
, ret
);
20938 switch (extract32(ctx
->opcode
, 10, 1)) {
20941 gen_helper_addqh_w(v1_t
, v1_t
, v2_t
);
20942 gen_store_gpr(v1_t
, ret
);
20946 gen_helper_addqh_r_w(v1_t
, v1_t
, v2_t
);
20947 gen_store_gpr(v1_t
, ret
);
20953 switch (extract32(ctx
->opcode
, 10, 1)) {
20956 gen_helper_addu_qb(v1_t
, v1_t
, v2_t
, cpu_env
);
20957 gen_store_gpr(v1_t
, ret
);
20961 gen_helper_addu_s_qb(v1_t
, v1_t
, v2_t
, cpu_env
);
20962 gen_store_gpr(v1_t
, ret
);
20968 switch (extract32(ctx
->opcode
, 10, 1)) {
20971 gen_helper_addu_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20972 gen_store_gpr(v1_t
, ret
);
20976 gen_helper_addu_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20977 gen_store_gpr(v1_t
, ret
);
20981 case NM_ADDUH_R_QB
:
20983 switch (extract32(ctx
->opcode
, 10, 1)) {
20986 gen_helper_adduh_qb(v1_t
, v1_t
, v2_t
);
20987 gen_store_gpr(v1_t
, ret
);
20991 gen_helper_adduh_r_qb(v1_t
, v1_t
, v2_t
);
20992 gen_store_gpr(v1_t
, ret
);
20996 case NM_SHRAV_R_PH
:
20998 switch (extract32(ctx
->opcode
, 10, 1)) {
21001 gen_helper_shra_ph(v1_t
, v1_t
, v2_t
);
21002 gen_store_gpr(v1_t
, ret
);
21006 gen_helper_shra_r_ph(v1_t
, v1_t
, v2_t
);
21007 gen_store_gpr(v1_t
, ret
);
21011 case NM_SHRAV_R_QB
:
21013 switch (extract32(ctx
->opcode
, 10, 1)) {
21016 gen_helper_shra_qb(v1_t
, v1_t
, v2_t
);
21017 gen_store_gpr(v1_t
, ret
);
21021 gen_helper_shra_r_qb(v1_t
, v1_t
, v2_t
);
21022 gen_store_gpr(v1_t
, ret
);
21028 switch (extract32(ctx
->opcode
, 10, 1)) {
21031 gen_helper_subq_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21032 gen_store_gpr(v1_t
, ret
);
21036 gen_helper_subq_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21037 gen_store_gpr(v1_t
, ret
);
21041 case NM_SUBQH_R_PH
:
21043 switch (extract32(ctx
->opcode
, 10, 1)) {
21046 gen_helper_subqh_ph(v1_t
, v1_t
, v2_t
);
21047 gen_store_gpr(v1_t
, ret
);
21051 gen_helper_subqh_r_ph(v1_t
, v1_t
, v2_t
);
21052 gen_store_gpr(v1_t
, ret
);
21058 switch (extract32(ctx
->opcode
, 10, 1)) {
21061 gen_helper_subqh_w(v1_t
, v1_t
, v2_t
);
21062 gen_store_gpr(v1_t
, ret
);
21066 gen_helper_subqh_r_w(v1_t
, v1_t
, v2_t
);
21067 gen_store_gpr(v1_t
, ret
);
21073 switch (extract32(ctx
->opcode
, 10, 1)) {
21076 gen_helper_subu_qb(v1_t
, v1_t
, v2_t
, cpu_env
);
21077 gen_store_gpr(v1_t
, ret
);
21081 gen_helper_subu_s_qb(v1_t
, v1_t
, v2_t
, cpu_env
);
21082 gen_store_gpr(v1_t
, ret
);
21088 switch (extract32(ctx
->opcode
, 10, 1)) {
21091 gen_helper_subu_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21092 gen_store_gpr(v1_t
, ret
);
21096 gen_helper_subu_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21097 gen_store_gpr(v1_t
, ret
);
21101 case NM_SUBUH_R_QB
:
21103 switch (extract32(ctx
->opcode
, 10, 1)) {
21106 gen_helper_subuh_qb(v1_t
, v1_t
, v2_t
);
21107 gen_store_gpr(v1_t
, ret
);
21111 gen_helper_subuh_r_qb(v1_t
, v1_t
, v2_t
);
21112 gen_store_gpr(v1_t
, ret
);
21116 case NM_SHLLV_S_PH
:
21118 switch (extract32(ctx
->opcode
, 10, 1)) {
21121 gen_helper_shll_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21122 gen_store_gpr(v1_t
, ret
);
21126 gen_helper_shll_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21127 gen_store_gpr(v1_t
, ret
);
21131 case NM_PRECR_SRA_R_PH_W
:
21133 switch (extract32(ctx
->opcode
, 10, 1)) {
21135 /* PRECR_SRA_PH_W */
21137 TCGv_i32 sa_t
= tcg_const_i32(rd
);
21138 gen_helper_precr_sra_ph_w(v1_t
, sa_t
, v1_t
,
21140 gen_store_gpr(v1_t
, rt
);
21141 tcg_temp_free_i32(sa_t
);
21145 /* PRECR_SRA_R_PH_W */
21147 TCGv_i32 sa_t
= tcg_const_i32(rd
);
21148 gen_helper_precr_sra_r_ph_w(v1_t
, sa_t
, v1_t
,
21150 gen_store_gpr(v1_t
, rt
);
21151 tcg_temp_free_i32(sa_t
);
21156 case NM_MULEU_S_PH_QBL
:
21158 gen_helper_muleu_s_ph_qbl(v1_t
, v1_t
, v2_t
, cpu_env
);
21159 gen_store_gpr(v1_t
, ret
);
21161 case NM_MULEU_S_PH_QBR
:
21163 gen_helper_muleu_s_ph_qbr(v1_t
, v1_t
, v2_t
, cpu_env
);
21164 gen_store_gpr(v1_t
, ret
);
21166 case NM_MULQ_RS_PH
:
21168 gen_helper_mulq_rs_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21169 gen_store_gpr(v1_t
, ret
);
21173 gen_helper_mulq_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21174 gen_store_gpr(v1_t
, ret
);
21178 gen_helper_mulq_rs_w(v1_t
, v1_t
, v2_t
, cpu_env
);
21179 gen_store_gpr(v1_t
, ret
);
21183 gen_helper_mulq_s_w(v1_t
, v1_t
, v2_t
, cpu_env
);
21184 gen_store_gpr(v1_t
, ret
);
21188 gen_load_gpr(t0
, rs
);
21190 tcg_gen_deposit_tl(cpu_gpr
[rt
], t0
, cpu_gpr
[rt
], rd
, 32 - rd
);
21192 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
21196 gen_helper_modsub(v1_t
, v1_t
, v2_t
);
21197 gen_store_gpr(v1_t
, ret
);
21201 gen_helper_shra_r_w(v1_t
, v1_t
, v2_t
);
21202 gen_store_gpr(v1_t
, ret
);
21206 gen_helper_shrl_ph(v1_t
, v1_t
, v2_t
);
21207 gen_store_gpr(v1_t
, ret
);
21211 gen_helper_shrl_qb(v1_t
, v1_t
, v2_t
);
21212 gen_store_gpr(v1_t
, ret
);
21216 gen_helper_shll_qb(v1_t
, v1_t
, v2_t
, cpu_env
);
21217 gen_store_gpr(v1_t
, ret
);
21221 gen_helper_shll_s_w(v1_t
, v1_t
, v2_t
, cpu_env
);
21222 gen_store_gpr(v1_t
, ret
);
21227 TCGv tv0
= tcg_temp_new();
21228 TCGv tv1
= tcg_temp_new();
21229 int16_t imm
= extract32(ctx
->opcode
, 16, 7);
21231 tcg_gen_movi_tl(tv0
, rd
>> 3);
21232 tcg_gen_movi_tl(tv1
, imm
);
21233 gen_helper_shilo(tv0
, tv1
, cpu_env
);
21236 case NM_MULEQ_S_W_PHL
:
21238 gen_helper_muleq_s_w_phl(v1_t
, v1_t
, v2_t
, cpu_env
);
21239 gen_store_gpr(v1_t
, ret
);
21241 case NM_MULEQ_S_W_PHR
:
21243 gen_helper_muleq_s_w_phr(v1_t
, v1_t
, v2_t
, cpu_env
);
21244 gen_store_gpr(v1_t
, ret
);
21248 switch (extract32(ctx
->opcode
, 10, 1)) {
21251 gen_helper_mul_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21252 gen_store_gpr(v1_t
, ret
);
21256 gen_helper_mul_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21257 gen_store_gpr(v1_t
, ret
);
21261 case NM_PRECR_QB_PH
:
21263 gen_helper_precr_qb_ph(v1_t
, v1_t
, v2_t
);
21264 gen_store_gpr(v1_t
, ret
);
21266 case NM_PRECRQ_QB_PH
:
21268 gen_helper_precrq_qb_ph(v1_t
, v1_t
, v2_t
);
21269 gen_store_gpr(v1_t
, ret
);
21271 case NM_PRECRQ_PH_W
:
21273 gen_helper_precrq_ph_w(v1_t
, v1_t
, v2_t
);
21274 gen_store_gpr(v1_t
, ret
);
21276 case NM_PRECRQ_RS_PH_W
:
21278 gen_helper_precrq_rs_ph_w(v1_t
, v1_t
, v2_t
, cpu_env
);
21279 gen_store_gpr(v1_t
, ret
);
21281 case NM_PRECRQU_S_QB_PH
:
21283 gen_helper_precrqu_s_qb_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21284 gen_store_gpr(v1_t
, ret
);
21288 tcg_gen_movi_tl(t0
, rd
);
21289 gen_helper_shra_r_w(v1_t
, t0
, v1_t
);
21290 gen_store_gpr(v1_t
, rt
);
21294 tcg_gen_movi_tl(t0
, rd
>> 1);
21295 switch (extract32(ctx
->opcode
, 10, 1)) {
21298 gen_helper_shra_ph(v1_t
, t0
, v1_t
);
21299 gen_store_gpr(v1_t
, rt
);
21303 gen_helper_shra_r_ph(v1_t
, t0
, v1_t
);
21304 gen_store_gpr(v1_t
, rt
);
21310 tcg_gen_movi_tl(t0
, rd
>> 1);
21311 switch (extract32(ctx
->opcode
, 10, 2)) {
21314 gen_helper_shll_ph(v1_t
, t0
, v1_t
, cpu_env
);
21315 gen_store_gpr(v1_t
, rt
);
21319 gen_helper_shll_s_ph(v1_t
, t0
, v1_t
, cpu_env
);
21320 gen_store_gpr(v1_t
, rt
);
21323 gen_reserved_instruction(ctx
);
21329 tcg_gen_movi_tl(t0
, rd
);
21330 gen_helper_shll_s_w(v1_t
, t0
, v1_t
, cpu_env
);
21331 gen_store_gpr(v1_t
, rt
);
21337 imm
= sextract32(ctx
->opcode
, 11, 11);
21338 imm
= (int16_t)(imm
<< 6) >> 6;
21340 tcg_gen_movi_tl(cpu_gpr
[rt
], dup_const(MO_16
, imm
));
21345 gen_reserved_instruction(ctx
);
21350 static int decode_nanomips_32_48_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
21358 insn
= translator_lduw(env
, ctx
->base
.pc_next
+ 2);
21359 ctx
->opcode
= (ctx
->opcode
<< 16) | insn
;
21361 rt
= extract32(ctx
->opcode
, 21, 5);
21362 rs
= extract32(ctx
->opcode
, 16, 5);
21363 rd
= extract32(ctx
->opcode
, 11, 5);
21365 op
= extract32(ctx
->opcode
, 26, 6);
21370 switch (extract32(ctx
->opcode
, 19, 2)) {
21373 gen_reserved_instruction(ctx
);
21376 if ((extract32(ctx
->opcode
, 18, 1)) == NM_SYSCALL
) {
21377 generate_exception_end(ctx
, EXCP_SYSCALL
);
21379 gen_reserved_instruction(ctx
);
21383 generate_exception_end(ctx
, EXCP_BREAK
);
21386 if (is_uhi(extract32(ctx
->opcode
, 0, 19))) {
21387 gen_helper_do_semihosting(cpu_env
);
21389 if (ctx
->hflags
& MIPS_HFLAG_SBRI
) {
21390 gen_reserved_instruction(ctx
);
21392 generate_exception_end(ctx
, EXCP_DBp
);
21399 imm
= extract32(ctx
->opcode
, 0, 16);
21401 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], imm
);
21403 tcg_gen_movi_tl(cpu_gpr
[rt
], imm
);
21405 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
21410 offset
= sextract32(ctx
->opcode
, 0, 1) << 21 |
21411 extract32(ctx
->opcode
, 1, 20) << 1;
21412 target_long addr
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
21413 tcg_gen_movi_tl(cpu_gpr
[rt
], addr
);
21417 switch (ctx
->opcode
& 0x07) {
21419 gen_pool32a0_nanomips_insn(env
, ctx
);
21423 int32_t op1
= extract32(ctx
->opcode
, 3, 7);
21424 gen_pool32a5_nanomips_insn(ctx
, op1
, rd
, rs
, rt
);
21428 switch (extract32(ctx
->opcode
, 3, 3)) {
21430 gen_p_lsx(ctx
, rd
, rs
, rt
);
21434 * In nanoMIPS, the shift field directly encodes the shift
21435 * amount, meaning that the supported shift values are in
21436 * the range 0 to 3 (instead of 1 to 4 in MIPSR6).
21438 gen_lsa(ctx
, rd
, rt
, rs
, extract32(ctx
->opcode
, 9, 2) - 1);
21441 gen_ext(ctx
, 32, rd
, rs
, rt
, extract32(ctx
->opcode
, 6, 5));
21444 gen_pool32axf_nanomips_insn(env
, ctx
);
21447 gen_reserved_instruction(ctx
);
21452 gen_reserved_instruction(ctx
);
21457 switch (ctx
->opcode
& 0x03) {
21460 offset
= extract32(ctx
->opcode
, 0, 21);
21461 gen_op_addr_addi(ctx
, cpu_gpr
[rt
], cpu_gpr
[28], offset
);
21465 gen_ld(ctx
, OPC_LW
, rt
, 28, extract32(ctx
->opcode
, 2, 19) << 2);
21468 gen_st(ctx
, OPC_SW
, rt
, 28, extract32(ctx
->opcode
, 2, 19) << 2);
21471 gen_reserved_instruction(ctx
);
21477 insn
= translator_lduw(env
, ctx
->base
.pc_next
+ 4);
21478 target_long addr_off
= extract32(ctx
->opcode
, 0, 16) | insn
<< 16;
21479 switch (extract32(ctx
->opcode
, 16, 5)) {
21483 tcg_gen_movi_tl(cpu_gpr
[rt
], addr_off
);
21489 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], addr_off
);
21490 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
21496 gen_op_addr_addi(ctx
, cpu_gpr
[rt
], cpu_gpr
[28], addr_off
);
21502 target_long addr
= addr_add(ctx
, ctx
->base
.pc_next
+ 6,
21505 tcg_gen_movi_tl(cpu_gpr
[rt
], addr
);
21512 t0
= tcg_temp_new();
21514 target_long addr
= addr_add(ctx
, ctx
->base
.pc_next
+ 6,
21517 tcg_gen_movi_tl(t0
, addr
);
21518 tcg_gen_qemu_ld_tl(cpu_gpr
[rt
], t0
, ctx
->mem_idx
, MO_TESL
);
21526 t0
= tcg_temp_new();
21527 t1
= tcg_temp_new();
21529 target_long addr
= addr_add(ctx
, ctx
->base
.pc_next
+ 6,
21532 tcg_gen_movi_tl(t0
, addr
);
21533 gen_load_gpr(t1
, rt
);
21535 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
21542 gen_reserved_instruction(ctx
);
21548 switch (extract32(ctx
->opcode
, 12, 4)) {
21550 gen_logic_imm(ctx
, OPC_ORI
, rt
, rs
, extract32(ctx
->opcode
, 0, 12));
21553 gen_logic_imm(ctx
, OPC_XORI
, rt
, rs
, extract32(ctx
->opcode
, 0, 12));
21556 gen_logic_imm(ctx
, OPC_ANDI
, rt
, rs
, extract32(ctx
->opcode
, 0, 12));
21559 switch (extract32(ctx
->opcode
, 20, 1)) {
21561 switch (ctx
->opcode
& 3) {
21563 gen_save(ctx
, rt
, extract32(ctx
->opcode
, 16, 4),
21564 extract32(ctx
->opcode
, 2, 1),
21565 extract32(ctx
->opcode
, 3, 9) << 3);
21568 case NM_RESTORE_JRC
:
21569 gen_restore(ctx
, rt
, extract32(ctx
->opcode
, 16, 4),
21570 extract32(ctx
->opcode
, 2, 1),
21571 extract32(ctx
->opcode
, 3, 9) << 3);
21572 if ((ctx
->opcode
& 3) == NM_RESTORE_JRC
) {
21573 gen_compute_branch_nm(ctx
, OPC_JR
, 2, 31, 0, 0);
21577 gen_reserved_instruction(ctx
);
21582 gen_reserved_instruction(ctx
);
21587 gen_slt_imm(ctx
, OPC_SLTI
, rt
, rs
, extract32(ctx
->opcode
, 0, 12));
21590 gen_slt_imm(ctx
, OPC_SLTIU
, rt
, rs
, extract32(ctx
->opcode
, 0, 12));
21594 TCGv t0
= tcg_temp_new();
21596 imm
= extract32(ctx
->opcode
, 0, 12);
21597 gen_load_gpr(t0
, rs
);
21598 tcg_gen_setcondi_tl(TCG_COND_EQ
, t0
, t0
, imm
);
21599 gen_store_gpr(t0
, rt
);
21605 imm
= (int16_t) extract32(ctx
->opcode
, 0, 12);
21606 gen_arith_imm(ctx
, OPC_ADDIU
, rt
, rs
, -imm
);
21610 int shift
= extract32(ctx
->opcode
, 0, 5);
21611 switch (extract32(ctx
->opcode
, 5, 4)) {
21613 if (rt
== 0 && shift
== 0) {
21615 } else if (rt
== 0 && shift
== 3) {
21616 /* EHB - treat as NOP */
21617 } else if (rt
== 0 && shift
== 5) {
21618 /* PAUSE - treat as NOP */
21619 } else if (rt
== 0 && shift
== 6) {
21621 gen_sync(extract32(ctx
->opcode
, 16, 5));
21624 gen_shift_imm(ctx
, OPC_SLL
, rt
, rs
,
21625 extract32(ctx
->opcode
, 0, 5));
21629 gen_shift_imm(ctx
, OPC_SRL
, rt
, rs
,
21630 extract32(ctx
->opcode
, 0, 5));
21633 gen_shift_imm(ctx
, OPC_SRA
, rt
, rs
,
21634 extract32(ctx
->opcode
, 0, 5));
21637 gen_shift_imm(ctx
, OPC_ROTR
, rt
, rs
,
21638 extract32(ctx
->opcode
, 0, 5));
21646 TCGv t0
= tcg_temp_new();
21647 TCGv_i32 shift
= tcg_const_i32(extract32(ctx
->opcode
, 0, 5));
21648 TCGv_i32 shiftx
= tcg_const_i32(extract32(ctx
->opcode
, 7, 4)
21650 TCGv_i32 stripe
= tcg_const_i32(extract32(ctx
->opcode
, 6, 1));
21652 gen_load_gpr(t0
, rs
);
21653 gen_helper_rotx(cpu_gpr
[rt
], t0
, shift
, shiftx
, stripe
);
21656 tcg_temp_free_i32(shift
);
21657 tcg_temp_free_i32(shiftx
);
21658 tcg_temp_free_i32(stripe
);
21662 switch (((ctx
->opcode
>> 10) & 2) |
21663 (extract32(ctx
->opcode
, 5, 1))) {
21666 gen_bitops(ctx
, OPC_INS
, rt
, rs
, extract32(ctx
->opcode
, 0, 5),
21667 extract32(ctx
->opcode
, 6, 5));
21670 gen_reserved_instruction(ctx
);
21675 switch (((ctx
->opcode
>> 10) & 2) |
21676 (extract32(ctx
->opcode
, 5, 1))) {
21679 gen_bitops(ctx
, OPC_EXT
, rt
, rs
, extract32(ctx
->opcode
, 0, 5),
21680 extract32(ctx
->opcode
, 6, 5));
21683 gen_reserved_instruction(ctx
);
21688 gen_reserved_instruction(ctx
);
21693 gen_pool32f_nanomips_insn(ctx
);
21698 switch (extract32(ctx
->opcode
, 1, 1)) {
21701 tcg_gen_movi_tl(cpu_gpr
[rt
],
21702 sextract32(ctx
->opcode
, 0, 1) << 31 |
21703 extract32(ctx
->opcode
, 2, 10) << 21 |
21704 extract32(ctx
->opcode
, 12, 9) << 12);
21709 offset
= sextract32(ctx
->opcode
, 0, 1) << 31 |
21710 extract32(ctx
->opcode
, 2, 10) << 21 |
21711 extract32(ctx
->opcode
, 12, 9) << 12;
21713 addr
= ~0xFFF & addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
21714 tcg_gen_movi_tl(cpu_gpr
[rt
], addr
);
21721 uint32_t u
= extract32(ctx
->opcode
, 0, 18);
21723 switch (extract32(ctx
->opcode
, 18, 3)) {
21725 gen_ld(ctx
, OPC_LB
, rt
, 28, u
);
21728 gen_st(ctx
, OPC_SB
, rt
, 28, u
);
21731 gen_ld(ctx
, OPC_LBU
, rt
, 28, u
);
21735 gen_op_addr_addi(ctx
, cpu_gpr
[rt
], cpu_gpr
[28], u
);
21740 switch (ctx
->opcode
& 1) {
21742 gen_ld(ctx
, OPC_LH
, rt
, 28, u
);
21745 gen_ld(ctx
, OPC_LHU
, rt
, 28, u
);
21751 switch (ctx
->opcode
& 1) {
21753 gen_st(ctx
, OPC_SH
, rt
, 28, u
);
21756 gen_reserved_instruction(ctx
);
21762 switch (ctx
->opcode
& 0x3) {
21764 gen_cop1_ldst(ctx
, OPC_LWC1
, rt
, 28, u
);
21767 gen_cop1_ldst(ctx
, OPC_LDC1
, rt
, 28, u
);
21770 gen_cop1_ldst(ctx
, OPC_SWC1
, rt
, 28, u
);
21773 gen_cop1_ldst(ctx
, OPC_SDC1
, rt
, 28, u
);
21778 gen_reserved_instruction(ctx
);
21785 uint32_t u
= extract32(ctx
->opcode
, 0, 12);
21787 switch (extract32(ctx
->opcode
, 12, 4)) {
21792 * Break the TB to be able to sync copied instructions
21795 ctx
->base
.is_jmp
= DISAS_STOP
;
21798 /* Treat as NOP. */
21802 gen_ld(ctx
, OPC_LB
, rt
, rs
, u
);
21805 gen_ld(ctx
, OPC_LH
, rt
, rs
, u
);
21808 gen_ld(ctx
, OPC_LW
, rt
, rs
, u
);
21811 gen_ld(ctx
, OPC_LBU
, rt
, rs
, u
);
21814 gen_ld(ctx
, OPC_LHU
, rt
, rs
, u
);
21817 gen_st(ctx
, OPC_SB
, rt
, rs
, u
);
21820 gen_st(ctx
, OPC_SH
, rt
, rs
, u
);
21823 gen_st(ctx
, OPC_SW
, rt
, rs
, u
);
21826 gen_cop1_ldst(ctx
, OPC_LWC1
, rt
, rs
, u
);
21829 gen_cop1_ldst(ctx
, OPC_LDC1
, rt
, rs
, u
);
21832 gen_cop1_ldst(ctx
, OPC_SWC1
, rt
, rs
, u
);
21835 gen_cop1_ldst(ctx
, OPC_SDC1
, rt
, rs
, u
);
21838 gen_reserved_instruction(ctx
);
21845 int32_t s
= (sextract32(ctx
->opcode
, 15, 1) << 8) |
21846 extract32(ctx
->opcode
, 0, 8);
21848 switch (extract32(ctx
->opcode
, 8, 3)) {
21850 switch (extract32(ctx
->opcode
, 11, 4)) {
21852 gen_ld(ctx
, OPC_LB
, rt
, rs
, s
);
21855 gen_ld(ctx
, OPC_LH
, rt
, rs
, s
);
21858 gen_ld(ctx
, OPC_LW
, rt
, rs
, s
);
21861 gen_ld(ctx
, OPC_LBU
, rt
, rs
, s
);
21864 gen_ld(ctx
, OPC_LHU
, rt
, rs
, s
);
21867 gen_st(ctx
, OPC_SB
, rt
, rs
, s
);
21870 gen_st(ctx
, OPC_SH
, rt
, rs
, s
);
21873 gen_st(ctx
, OPC_SW
, rt
, rs
, s
);
21876 gen_cop1_ldst(ctx
, OPC_LWC1
, rt
, rs
, s
);
21879 gen_cop1_ldst(ctx
, OPC_LDC1
, rt
, rs
, s
);
21882 gen_cop1_ldst(ctx
, OPC_SWC1
, rt
, rs
, s
);
21885 gen_cop1_ldst(ctx
, OPC_SDC1
, rt
, rs
, s
);
21891 * Break the TB to be able to sync copied instructions
21894 ctx
->base
.is_jmp
= DISAS_STOP
;
21897 /* Treat as NOP. */
21901 gen_reserved_instruction(ctx
);
21906 switch (extract32(ctx
->opcode
, 11, 4)) {
21911 TCGv t0
= tcg_temp_new();
21912 TCGv t1
= tcg_temp_new();
21914 gen_base_offset_addr(ctx
, t0
, rs
, s
);
21916 switch (extract32(ctx
->opcode
, 11, 4)) {
21918 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESW
|
21920 gen_store_gpr(t0
, rt
);
21923 gen_load_gpr(t1
, rt
);
21924 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUW
|
21933 switch (ctx
->opcode
& 0x03) {
21935 gen_ld(ctx
, OPC_LL
, rt
, rs
, s
);
21939 gen_llwp(ctx
, rs
, 0, rt
, extract32(ctx
->opcode
, 3, 5));
21944 switch (ctx
->opcode
& 0x03) {
21946 gen_st_cond(ctx
, rt
, rs
, s
, MO_TESL
, false);
21950 gen_scwp(ctx
, rs
, 0, rt
, extract32(ctx
->opcode
, 3, 5),
21956 check_cp0_enabled(ctx
);
21957 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
21958 gen_cache_operation(ctx
, rt
, rs
, s
);
21964 switch (extract32(ctx
->opcode
, 11, 4)) {
21967 check_cp0_enabled(ctx
);
21968 gen_ld(ctx
, OPC_LBE
, rt
, rs
, s
);
21972 check_cp0_enabled(ctx
);
21973 gen_st(ctx
, OPC_SBE
, rt
, rs
, s
);
21977 check_cp0_enabled(ctx
);
21978 gen_ld(ctx
, OPC_LBUE
, rt
, rs
, s
);
21982 /* case NM_SYNCIE */
21984 check_cp0_enabled(ctx
);
21986 * Break the TB to be able to sync copied instructions
21989 ctx
->base
.is_jmp
= DISAS_STOP
;
21991 /* case NM_PREFE */
21993 check_cp0_enabled(ctx
);
21994 /* Treat as NOP. */
21999 check_cp0_enabled(ctx
);
22000 gen_ld(ctx
, OPC_LHE
, rt
, rs
, s
);
22004 check_cp0_enabled(ctx
);
22005 gen_st(ctx
, OPC_SHE
, rt
, rs
, s
);
22009 check_cp0_enabled(ctx
);
22010 gen_ld(ctx
, OPC_LHUE
, rt
, rs
, s
);
22013 check_nms_dl_il_sl_tl_l2c(ctx
);
22014 gen_cache_operation(ctx
, rt
, rs
, s
);
22018 check_cp0_enabled(ctx
);
22019 gen_ld(ctx
, OPC_LWE
, rt
, rs
, s
);
22023 check_cp0_enabled(ctx
);
22024 gen_st(ctx
, OPC_SWE
, rt
, rs
, s
);
22027 switch (extract32(ctx
->opcode
, 2, 2)) {
22031 check_cp0_enabled(ctx
);
22032 gen_ld(ctx
, OPC_LLE
, rt
, rs
, s
);
22037 check_cp0_enabled(ctx
);
22038 gen_llwp(ctx
, rs
, 0, rt
, extract32(ctx
->opcode
, 3, 5));
22041 gen_reserved_instruction(ctx
);
22046 switch (extract32(ctx
->opcode
, 2, 2)) {
22050 check_cp0_enabled(ctx
);
22051 gen_st_cond(ctx
, rt
, rs
, s
, MO_TESL
, true);
22056 check_cp0_enabled(ctx
);
22057 gen_scwp(ctx
, rs
, 0, rt
, extract32(ctx
->opcode
, 3, 5),
22061 gen_reserved_instruction(ctx
);
22071 int count
= extract32(ctx
->opcode
, 12, 3);
22074 offset
= sextract32(ctx
->opcode
, 15, 1) << 8 |
22075 extract32(ctx
->opcode
, 0, 8);
22076 TCGv va
= tcg_temp_new();
22077 TCGv t1
= tcg_temp_new();
22078 MemOp memop
= (extract32(ctx
->opcode
, 8, 3)) ==
22079 NM_P_LS_UAWM
? MO_UNALN
: 0;
22081 count
= (count
== 0) ? 8 : count
;
22082 while (counter
!= count
) {
22083 int this_rt
= ((rt
+ counter
) & 0x1f) | (rt
& 0x10);
22084 int this_offset
= offset
+ (counter
<< 2);
22086 gen_base_offset_addr(ctx
, va
, rs
, this_offset
);
22088 switch (extract32(ctx
->opcode
, 11, 1)) {
22090 tcg_gen_qemu_ld_tl(t1
, va
, ctx
->mem_idx
,
22092 gen_store_gpr(t1
, this_rt
);
22093 if ((this_rt
== rs
) &&
22094 (counter
!= (count
- 1))) {
22095 /* UNPREDICTABLE */
22099 this_rt
= (rt
== 0) ? 0 : this_rt
;
22100 gen_load_gpr(t1
, this_rt
);
22101 tcg_gen_qemu_st_tl(t1
, va
, ctx
->mem_idx
,
22112 gen_reserved_instruction(ctx
);
22120 TCGv t0
= tcg_temp_new();
22121 int32_t s
= sextract32(ctx
->opcode
, 0, 1) << 21 |
22122 extract32(ctx
->opcode
, 1, 20) << 1;
22123 rd
= (extract32(ctx
->opcode
, 24, 1)) == 0 ? 4 : 5;
22124 rt
= decode_gpr_gpr4_zero(extract32(ctx
->opcode
, 25, 1) << 3 |
22125 extract32(ctx
->opcode
, 21, 3));
22126 gen_load_gpr(t0
, rt
);
22127 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
22128 gen_compute_branch_nm(ctx
, OPC_BGEZAL
, 4, 0, 0, s
);
22134 int32_t s
= sextract32(ctx
->opcode
, 0, 1) << 25 |
22135 extract32(ctx
->opcode
, 1, 24) << 1;
22137 if ((extract32(ctx
->opcode
, 25, 1)) == 0) {
22139 gen_compute_branch_nm(ctx
, OPC_BEQ
, 4, 0, 0, s
);
22142 gen_compute_branch_nm(ctx
, OPC_BGEZAL
, 4, 0, 0, s
);
22147 switch (extract32(ctx
->opcode
, 12, 4)) {
22150 gen_compute_branch_nm(ctx
, OPC_JALR
, 4, rs
, rt
, 0);
22153 gen_compute_nanomips_pbalrsc_branch(ctx
, rs
, rt
);
22156 gen_reserved_instruction(ctx
);
22162 int32_t s
= sextract32(ctx
->opcode
, 0, 1) << 14 |
22163 extract32(ctx
->opcode
, 1, 13) << 1;
22164 switch (extract32(ctx
->opcode
, 14, 2)) {
22167 gen_compute_branch_nm(ctx
, OPC_BEQ
, 4, rs
, rt
, s
);
22170 s
= sextract32(ctx
->opcode
, 0, 1) << 14 |
22171 extract32(ctx
->opcode
, 1, 13) << 1;
22172 check_cp1_enabled(ctx
);
22173 switch (extract32(ctx
->opcode
, 16, 5)) {
22175 gen_compute_branch_cp1_nm(ctx
, OPC_BC1EQZ
, rt
, s
);
22178 gen_compute_branch_cp1_nm(ctx
, OPC_BC1NEZ
, rt
, s
);
22183 int32_t imm
= extract32(ctx
->opcode
, 1, 13) |
22184 extract32(ctx
->opcode
, 0, 1) << 13;
22186 gen_compute_branch_nm(ctx
, OPC_BPOSGE32
, 4, -1, -2,
22191 gen_reserved_instruction(ctx
);
22197 gen_compute_compact_branch_nm(ctx
, OPC_BC
, rs
, rt
, s
);
22199 gen_compute_compact_branch_nm(ctx
, OPC_BGEC
, rs
, rt
, s
);
22203 if (rs
== rt
|| rt
== 0) {
22204 gen_compute_compact_branch_nm(ctx
, OPC_BC
, 0, 0, s
);
22205 } else if (rs
== 0) {
22206 gen_compute_compact_branch_nm(ctx
, OPC_BEQZC
, rt
, 0, s
);
22208 gen_compute_compact_branch_nm(ctx
, OPC_BGEUC
, rs
, rt
, s
);
22216 int32_t s
= sextract32(ctx
->opcode
, 0, 1) << 14 |
22217 extract32(ctx
->opcode
, 1, 13) << 1;
22218 switch (extract32(ctx
->opcode
, 14, 2)) {
22221 gen_compute_branch_nm(ctx
, OPC_BNE
, 4, rs
, rt
, s
);
22224 if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
22226 ctx
->hflags
|= MIPS_HFLAG_FBNSLOT
;
22228 gen_compute_compact_branch_nm(ctx
, OPC_BLTC
, rs
, rt
, s
);
22232 if (rs
== 0 || rs
== rt
) {
22234 ctx
->hflags
|= MIPS_HFLAG_FBNSLOT
;
22236 gen_compute_compact_branch_nm(ctx
, OPC_BLTUC
, rs
, rt
, s
);
22240 gen_reserved_instruction(ctx
);
22247 int32_t s
= sextract32(ctx
->opcode
, 0, 1) << 11 |
22248 extract32(ctx
->opcode
, 1, 10) << 1;
22249 uint32_t u
= extract32(ctx
->opcode
, 11, 7);
22251 gen_compute_imm_branch(ctx
, extract32(ctx
->opcode
, 18, 3),
22256 gen_reserved_instruction(ctx
);
22262 static int decode_nanomips_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
22265 int rt
= decode_gpr_gpr3(NANOMIPS_EXTRACT_RT3(ctx
->opcode
));
22266 int rs
= decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx
->opcode
));
22267 int rd
= decode_gpr_gpr3(NANOMIPS_EXTRACT_RD3(ctx
->opcode
));
22271 /* make sure instructions are on a halfword boundary */
22272 if (ctx
->base
.pc_next
& 0x1) {
22273 TCGv tmp
= tcg_const_tl(ctx
->base
.pc_next
);
22274 tcg_gen_st_tl(tmp
, cpu_env
, offsetof(CPUMIPSState
, CP0_BadVAddr
));
22275 tcg_temp_free(tmp
);
22276 generate_exception_end(ctx
, EXCP_AdEL
);
22280 op
= extract32(ctx
->opcode
, 10, 6);
22283 rt
= NANOMIPS_EXTRACT_RD5(ctx
->opcode
);
22286 rs
= NANOMIPS_EXTRACT_RS5(ctx
->opcode
);
22287 gen_arith(ctx
, OPC_ADDU
, rt
, rs
, 0);
22290 switch (extract32(ctx
->opcode
, 3, 2)) {
22291 case NM_P16_SYSCALL
:
22292 if (extract32(ctx
->opcode
, 2, 1) == 0) {
22293 generate_exception_end(ctx
, EXCP_SYSCALL
);
22295 gen_reserved_instruction(ctx
);
22299 generate_exception_end(ctx
, EXCP_BREAK
);
22302 if (is_uhi(extract32(ctx
->opcode
, 0, 3))) {
22303 gen_helper_do_semihosting(cpu_env
);
22305 if (ctx
->hflags
& MIPS_HFLAG_SBRI
) {
22306 gen_reserved_instruction(ctx
);
22308 generate_exception_end(ctx
, EXCP_DBp
);
22313 gen_reserved_instruction(ctx
);
22320 int shift
= extract32(ctx
->opcode
, 0, 3);
22322 shift
= (shift
== 0) ? 8 : shift
;
22324 switch (extract32(ctx
->opcode
, 3, 1)) {
22332 gen_shift_imm(ctx
, opc
, rt
, rs
, shift
);
22336 switch (ctx
->opcode
& 1) {
22338 gen_pool16c_nanomips_insn(ctx
);
22341 gen_ldxs(ctx
, rt
, rs
, rd
);
22346 switch (extract32(ctx
->opcode
, 6, 1)) {
22348 imm
= extract32(ctx
->opcode
, 0, 6) << 2;
22349 gen_arith_imm(ctx
, OPC_ADDIU
, rt
, 29, imm
);
22352 gen_reserved_instruction(ctx
);
22357 switch (extract32(ctx
->opcode
, 3, 1)) {
22359 imm
= extract32(ctx
->opcode
, 0, 3) << 2;
22360 gen_arith_imm(ctx
, OPC_ADDIU
, rt
, rs
, imm
);
22362 case NM_P_ADDIURS5
:
22363 rt
= extract32(ctx
->opcode
, 5, 5);
22365 /* imm = sign_extend(s[3] . s[2:0] , from_nbits = 4) */
22366 imm
= (sextract32(ctx
->opcode
, 4, 1) << 3) |
22367 (extract32(ctx
->opcode
, 0, 3));
22368 gen_arith_imm(ctx
, OPC_ADDIU
, rt
, rt
, imm
);
22374 switch (ctx
->opcode
& 0x1) {
22376 gen_arith(ctx
, OPC_ADDU
, rd
, rs
, rt
);
22379 gen_arith(ctx
, OPC_SUBU
, rd
, rs
, rt
);
22384 rt
= (extract32(ctx
->opcode
, 9, 1) << 3) |
22385 extract32(ctx
->opcode
, 5, 3);
22386 rs
= (extract32(ctx
->opcode
, 4, 1) << 3) |
22387 extract32(ctx
->opcode
, 0, 3);
22388 rt
= decode_gpr_gpr4(rt
);
22389 rs
= decode_gpr_gpr4(rs
);
22390 switch ((extract32(ctx
->opcode
, 7, 2) & 0x2) |
22391 (extract32(ctx
->opcode
, 3, 1))) {
22394 gen_arith(ctx
, OPC_ADDU
, rt
, rs
, rt
);
22398 gen_r6_muldiv(ctx
, R6_OPC_MUL
, rt
, rs
, rt
);
22401 gen_reserved_instruction(ctx
);
22407 int imm
= extract32(ctx
->opcode
, 0, 7);
22408 imm
= (imm
== 0x7f ? -1 : imm
);
22410 tcg_gen_movi_tl(cpu_gpr
[rt
], imm
);
22416 uint32_t u
= extract32(ctx
->opcode
, 0, 4);
22417 u
= (u
== 12) ? 0xff :
22418 (u
== 13) ? 0xffff : u
;
22419 gen_logic_imm(ctx
, OPC_ANDI
, rt
, rs
, u
);
22423 offset
= extract32(ctx
->opcode
, 0, 2);
22424 switch (extract32(ctx
->opcode
, 2, 2)) {
22426 gen_ld(ctx
, OPC_LB
, rt
, rs
, offset
);
22429 rt
= decode_gpr_gpr3_src_store(
22430 NANOMIPS_EXTRACT_RT3(ctx
->opcode
));
22431 gen_st(ctx
, OPC_SB
, rt
, rs
, offset
);
22434 gen_ld(ctx
, OPC_LBU
, rt
, rs
, offset
);
22437 gen_reserved_instruction(ctx
);
22442 offset
= extract32(ctx
->opcode
, 1, 2) << 1;
22443 switch ((extract32(ctx
->opcode
, 3, 1) << 1) | (ctx
->opcode
& 1)) {
22445 gen_ld(ctx
, OPC_LH
, rt
, rs
, offset
);
22448 rt
= decode_gpr_gpr3_src_store(
22449 NANOMIPS_EXTRACT_RT3(ctx
->opcode
));
22450 gen_st(ctx
, OPC_SH
, rt
, rs
, offset
);
22453 gen_ld(ctx
, OPC_LHU
, rt
, rs
, offset
);
22456 gen_reserved_instruction(ctx
);
22461 offset
= extract32(ctx
->opcode
, 0, 4) << 2;
22462 gen_ld(ctx
, OPC_LW
, rt
, rs
, offset
);
22465 rt
= NANOMIPS_EXTRACT_RD5(ctx
->opcode
);
22466 offset
= extract32(ctx
->opcode
, 0, 5) << 2;
22467 gen_ld(ctx
, OPC_LW
, rt
, 29, offset
);
22471 rt
= (extract32(ctx
->opcode
, 9, 1) << 3) |
22472 extract32(ctx
->opcode
, 5, 3);
22473 rs
= (extract32(ctx
->opcode
, 4, 1) << 3) |
22474 extract32(ctx
->opcode
, 0, 3);
22475 offset
= (extract32(ctx
->opcode
, 3, 1) << 3) |
22476 (extract32(ctx
->opcode
, 8, 1) << 2);
22477 rt
= decode_gpr_gpr4(rt
);
22478 rs
= decode_gpr_gpr4(rs
);
22479 gen_ld(ctx
, OPC_LW
, rt
, rs
, offset
);
22483 rt
= (extract32(ctx
->opcode
, 9, 1) << 3) |
22484 extract32(ctx
->opcode
, 5, 3);
22485 rs
= (extract32(ctx
->opcode
, 4, 1) << 3) |
22486 extract32(ctx
->opcode
, 0, 3);
22487 offset
= (extract32(ctx
->opcode
, 3, 1) << 3) |
22488 (extract32(ctx
->opcode
, 8, 1) << 2);
22489 rt
= decode_gpr_gpr4_zero(rt
);
22490 rs
= decode_gpr_gpr4(rs
);
22491 gen_st(ctx
, OPC_SW
, rt
, rs
, offset
);
22494 offset
= extract32(ctx
->opcode
, 0, 7) << 2;
22495 gen_ld(ctx
, OPC_LW
, rt
, 28, offset
);
22498 rt
= NANOMIPS_EXTRACT_RD5(ctx
->opcode
);
22499 offset
= extract32(ctx
->opcode
, 0, 5) << 2;
22500 gen_st(ctx
, OPC_SW
, rt
, 29, offset
);
22503 rt
= decode_gpr_gpr3_src_store(
22504 NANOMIPS_EXTRACT_RT3(ctx
->opcode
));
22505 rs
= decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx
->opcode
));
22506 offset
= extract32(ctx
->opcode
, 0, 4) << 2;
22507 gen_st(ctx
, OPC_SW
, rt
, rs
, offset
);
22510 rt
= decode_gpr_gpr3_src_store(
22511 NANOMIPS_EXTRACT_RT3(ctx
->opcode
));
22512 offset
= extract32(ctx
->opcode
, 0, 7) << 2;
22513 gen_st(ctx
, OPC_SW
, rt
, 28, offset
);
22516 gen_compute_branch_nm(ctx
, OPC_BEQ
, 2, 0, 0,
22517 (sextract32(ctx
->opcode
, 0, 1) << 10) |
22518 (extract32(ctx
->opcode
, 1, 9) << 1));
22521 gen_compute_branch_nm(ctx
, OPC_BGEZAL
, 2, 0, 0,
22522 (sextract32(ctx
->opcode
, 0, 1) << 10) |
22523 (extract32(ctx
->opcode
, 1, 9) << 1));
22526 gen_compute_branch_nm(ctx
, OPC_BEQ
, 2, rt
, 0,
22527 (sextract32(ctx
->opcode
, 0, 1) << 7) |
22528 (extract32(ctx
->opcode
, 1, 6) << 1));
22531 gen_compute_branch_nm(ctx
, OPC_BNE
, 2, rt
, 0,
22532 (sextract32(ctx
->opcode
, 0, 1) << 7) |
22533 (extract32(ctx
->opcode
, 1, 6) << 1));
22536 switch (ctx
->opcode
& 0xf) {
22539 switch (extract32(ctx
->opcode
, 4, 1)) {
22541 gen_compute_branch_nm(ctx
, OPC_JR
, 2,
22542 extract32(ctx
->opcode
, 5, 5), 0, 0);
22545 gen_compute_branch_nm(ctx
, OPC_JALR
, 2,
22546 extract32(ctx
->opcode
, 5, 5), 31, 0);
22553 uint32_t opc
= extract32(ctx
->opcode
, 4, 3) <
22554 extract32(ctx
->opcode
, 7, 3) ? OPC_BEQ
: OPC_BNE
;
22555 gen_compute_branch_nm(ctx
, opc
, 2, rs
, rt
,
22556 extract32(ctx
->opcode
, 0, 4) << 1);
22563 int count
= extract32(ctx
->opcode
, 0, 4);
22564 int u
= extract32(ctx
->opcode
, 4, 4) << 4;
22566 rt
= 30 + extract32(ctx
->opcode
, 9, 1);
22567 switch (extract32(ctx
->opcode
, 8, 1)) {
22569 gen_save(ctx
, rt
, count
, 0, u
);
22571 case NM_RESTORE_JRC16
:
22572 gen_restore(ctx
, rt
, count
, 0, u
);
22573 gen_compute_branch_nm(ctx
, OPC_JR
, 2, 31, 0, 0);
22582 static const int gpr2reg1
[] = {4, 5, 6, 7};
22583 static const int gpr2reg2
[] = {5, 6, 7, 8};
22585 int rd2
= extract32(ctx
->opcode
, 3, 1) << 1 |
22586 extract32(ctx
->opcode
, 8, 1);
22587 int r1
= gpr2reg1
[rd2
];
22588 int r2
= gpr2reg2
[rd2
];
22589 int r3
= extract32(ctx
->opcode
, 4, 1) << 3 |
22590 extract32(ctx
->opcode
, 0, 3);
22591 int r4
= extract32(ctx
->opcode
, 9, 1) << 3 |
22592 extract32(ctx
->opcode
, 5, 3);
22593 TCGv t0
= tcg_temp_new();
22594 TCGv t1
= tcg_temp_new();
22595 if (op
== NM_MOVEP
) {
22598 rs
= decode_gpr_gpr4_zero(r3
);
22599 rt
= decode_gpr_gpr4_zero(r4
);
22601 rd
= decode_gpr_gpr4(r3
);
22602 re
= decode_gpr_gpr4(r4
);
22606 gen_load_gpr(t0
, rs
);
22607 gen_load_gpr(t1
, rt
);
22608 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
22609 tcg_gen_mov_tl(cpu_gpr
[re
], t1
);
22615 return decode_nanomips_32_48_opc(env
, ctx
);
22622 /* SmartMIPS extension to MIPS32 */
22624 #if defined(TARGET_MIPS64)
22626 /* MDMX extension to MIPS64 */
22630 /* MIPSDSP functions. */
22631 static void gen_mipsdsp_ld(DisasContext
*ctx
, uint32_t opc
,
22632 int rd
, int base
, int offset
)
22637 t0
= tcg_temp_new();
22640 gen_load_gpr(t0
, offset
);
22641 } else if (offset
== 0) {
22642 gen_load_gpr(t0
, base
);
22644 gen_op_addr_add(ctx
, t0
, cpu_gpr
[base
], cpu_gpr
[offset
]);
22649 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_UB
);
22650 gen_store_gpr(t0
, rd
);
22653 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESW
);
22654 gen_store_gpr(t0
, rd
);
22657 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESL
);
22658 gen_store_gpr(t0
, rd
);
22660 #if defined(TARGET_MIPS64)
22662 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
);
22663 gen_store_gpr(t0
, rd
);
22670 static void gen_mipsdsp_arith(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
22671 int ret
, int v1
, int v2
)
22677 /* Treat as NOP. */
22681 v1_t
= tcg_temp_new();
22682 v2_t
= tcg_temp_new();
22684 gen_load_gpr(v1_t
, v1
);
22685 gen_load_gpr(v2_t
, v2
);
22688 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
22689 case OPC_MULT_G_2E
:
22693 gen_helper_adduh_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
22695 case OPC_ADDUH_R_QB
:
22696 gen_helper_adduh_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
22699 gen_helper_addqh_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
22701 case OPC_ADDQH_R_PH
:
22702 gen_helper_addqh_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
22705 gen_helper_addqh_w(cpu_gpr
[ret
], v1_t
, v2_t
);
22707 case OPC_ADDQH_R_W
:
22708 gen_helper_addqh_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
22711 gen_helper_subuh_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
22713 case OPC_SUBUH_R_QB
:
22714 gen_helper_subuh_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
22717 gen_helper_subqh_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
22719 case OPC_SUBQH_R_PH
:
22720 gen_helper_subqh_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
22723 gen_helper_subqh_w(cpu_gpr
[ret
], v1_t
, v2_t
);
22725 case OPC_SUBQH_R_W
:
22726 gen_helper_subqh_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
22730 case OPC_ABSQ_S_PH_DSP
:
22732 case OPC_ABSQ_S_QB
:
22734 gen_helper_absq_s_qb(cpu_gpr
[ret
], v2_t
, cpu_env
);
22736 case OPC_ABSQ_S_PH
:
22738 gen_helper_absq_s_ph(cpu_gpr
[ret
], v2_t
, cpu_env
);
22742 gen_helper_absq_s_w(cpu_gpr
[ret
], v2_t
, cpu_env
);
22744 case OPC_PRECEQ_W_PHL
:
22746 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0xFFFF0000);
22747 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
22749 case OPC_PRECEQ_W_PHR
:
22751 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0x0000FFFF);
22752 tcg_gen_shli_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], 16);
22753 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
22755 case OPC_PRECEQU_PH_QBL
:
22757 gen_helper_precequ_ph_qbl(cpu_gpr
[ret
], v2_t
);
22759 case OPC_PRECEQU_PH_QBR
:
22761 gen_helper_precequ_ph_qbr(cpu_gpr
[ret
], v2_t
);
22763 case OPC_PRECEQU_PH_QBLA
:
22765 gen_helper_precequ_ph_qbla(cpu_gpr
[ret
], v2_t
);
22767 case OPC_PRECEQU_PH_QBRA
:
22769 gen_helper_precequ_ph_qbra(cpu_gpr
[ret
], v2_t
);
22771 case OPC_PRECEU_PH_QBL
:
22773 gen_helper_preceu_ph_qbl(cpu_gpr
[ret
], v2_t
);
22775 case OPC_PRECEU_PH_QBR
:
22777 gen_helper_preceu_ph_qbr(cpu_gpr
[ret
], v2_t
);
22779 case OPC_PRECEU_PH_QBLA
:
22781 gen_helper_preceu_ph_qbla(cpu_gpr
[ret
], v2_t
);
22783 case OPC_PRECEU_PH_QBRA
:
22785 gen_helper_preceu_ph_qbra(cpu_gpr
[ret
], v2_t
);
22789 case OPC_ADDU_QB_DSP
:
22793 gen_helper_addq_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22795 case OPC_ADDQ_S_PH
:
22797 gen_helper_addq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22801 gen_helper_addq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22805 gen_helper_addu_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22807 case OPC_ADDU_S_QB
:
22809 gen_helper_addu_s_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22813 gen_helper_addu_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22815 case OPC_ADDU_S_PH
:
22817 gen_helper_addu_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22821 gen_helper_subq_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22823 case OPC_SUBQ_S_PH
:
22825 gen_helper_subq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22829 gen_helper_subq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22833 gen_helper_subu_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22835 case OPC_SUBU_S_QB
:
22837 gen_helper_subu_s_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22841 gen_helper_subu_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22843 case OPC_SUBU_S_PH
:
22845 gen_helper_subu_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22849 gen_helper_addsc(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22853 gen_helper_addwc(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22857 gen_helper_modsub(cpu_gpr
[ret
], v1_t
, v2_t
);
22859 case OPC_RADDU_W_QB
:
22861 gen_helper_raddu_w_qb(cpu_gpr
[ret
], v1_t
);
22865 case OPC_CMPU_EQ_QB_DSP
:
22867 case OPC_PRECR_QB_PH
:
22869 gen_helper_precr_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
22871 case OPC_PRECRQ_QB_PH
:
22873 gen_helper_precrq_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
22875 case OPC_PRECR_SRA_PH_W
:
22878 TCGv_i32 sa_t
= tcg_const_i32(v2
);
22879 gen_helper_precr_sra_ph_w(cpu_gpr
[ret
], sa_t
, v1_t
,
22881 tcg_temp_free_i32(sa_t
);
22884 case OPC_PRECR_SRA_R_PH_W
:
22887 TCGv_i32 sa_t
= tcg_const_i32(v2
);
22888 gen_helper_precr_sra_r_ph_w(cpu_gpr
[ret
], sa_t
, v1_t
,
22890 tcg_temp_free_i32(sa_t
);
22893 case OPC_PRECRQ_PH_W
:
22895 gen_helper_precrq_ph_w(cpu_gpr
[ret
], v1_t
, v2_t
);
22897 case OPC_PRECRQ_RS_PH_W
:
22899 gen_helper_precrq_rs_ph_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22901 case OPC_PRECRQU_S_QB_PH
:
22903 gen_helper_precrqu_s_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22907 #ifdef TARGET_MIPS64
22908 case OPC_ABSQ_S_QH_DSP
:
22910 case OPC_PRECEQ_L_PWL
:
22912 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0xFFFFFFFF00000000ull
);
22914 case OPC_PRECEQ_L_PWR
:
22916 tcg_gen_shli_tl(cpu_gpr
[ret
], v2_t
, 32);
22918 case OPC_PRECEQ_PW_QHL
:
22920 gen_helper_preceq_pw_qhl(cpu_gpr
[ret
], v2_t
);
22922 case OPC_PRECEQ_PW_QHR
:
22924 gen_helper_preceq_pw_qhr(cpu_gpr
[ret
], v2_t
);
22926 case OPC_PRECEQ_PW_QHLA
:
22928 gen_helper_preceq_pw_qhla(cpu_gpr
[ret
], v2_t
);
22930 case OPC_PRECEQ_PW_QHRA
:
22932 gen_helper_preceq_pw_qhra(cpu_gpr
[ret
], v2_t
);
22934 case OPC_PRECEQU_QH_OBL
:
22936 gen_helper_precequ_qh_obl(cpu_gpr
[ret
], v2_t
);
22938 case OPC_PRECEQU_QH_OBR
:
22940 gen_helper_precequ_qh_obr(cpu_gpr
[ret
], v2_t
);
22942 case OPC_PRECEQU_QH_OBLA
:
22944 gen_helper_precequ_qh_obla(cpu_gpr
[ret
], v2_t
);
22946 case OPC_PRECEQU_QH_OBRA
:
22948 gen_helper_precequ_qh_obra(cpu_gpr
[ret
], v2_t
);
22950 case OPC_PRECEU_QH_OBL
:
22952 gen_helper_preceu_qh_obl(cpu_gpr
[ret
], v2_t
);
22954 case OPC_PRECEU_QH_OBR
:
22956 gen_helper_preceu_qh_obr(cpu_gpr
[ret
], v2_t
);
22958 case OPC_PRECEU_QH_OBLA
:
22960 gen_helper_preceu_qh_obla(cpu_gpr
[ret
], v2_t
);
22962 case OPC_PRECEU_QH_OBRA
:
22964 gen_helper_preceu_qh_obra(cpu_gpr
[ret
], v2_t
);
22966 case OPC_ABSQ_S_OB
:
22968 gen_helper_absq_s_ob(cpu_gpr
[ret
], v2_t
, cpu_env
);
22970 case OPC_ABSQ_S_PW
:
22972 gen_helper_absq_s_pw(cpu_gpr
[ret
], v2_t
, cpu_env
);
22974 case OPC_ABSQ_S_QH
:
22976 gen_helper_absq_s_qh(cpu_gpr
[ret
], v2_t
, cpu_env
);
22980 case OPC_ADDU_OB_DSP
:
22982 case OPC_RADDU_L_OB
:
22984 gen_helper_raddu_l_ob(cpu_gpr
[ret
], v1_t
);
22988 gen_helper_subq_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22990 case OPC_SUBQ_S_PW
:
22992 gen_helper_subq_s_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22996 gen_helper_subq_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22998 case OPC_SUBQ_S_QH
:
23000 gen_helper_subq_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23004 gen_helper_subu_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23006 case OPC_SUBU_S_OB
:
23008 gen_helper_subu_s_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23012 gen_helper_subu_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23014 case OPC_SUBU_S_QH
:
23016 gen_helper_subu_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23020 gen_helper_subuh_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
23022 case OPC_SUBUH_R_OB
:
23024 gen_helper_subuh_r_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
23028 gen_helper_addq_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23030 case OPC_ADDQ_S_PW
:
23032 gen_helper_addq_s_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23036 gen_helper_addq_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23038 case OPC_ADDQ_S_QH
:
23040 gen_helper_addq_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23044 gen_helper_addu_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23046 case OPC_ADDU_S_OB
:
23048 gen_helper_addu_s_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23052 gen_helper_addu_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23054 case OPC_ADDU_S_QH
:
23056 gen_helper_addu_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23060 gen_helper_adduh_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
23062 case OPC_ADDUH_R_OB
:
23064 gen_helper_adduh_r_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
23068 case OPC_CMPU_EQ_OB_DSP
:
23070 case OPC_PRECR_OB_QH
:
23072 gen_helper_precr_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
);
23074 case OPC_PRECR_SRA_QH_PW
:
23077 TCGv_i32 ret_t
= tcg_const_i32(ret
);
23078 gen_helper_precr_sra_qh_pw(v2_t
, v1_t
, v2_t
, ret_t
);
23079 tcg_temp_free_i32(ret_t
);
23082 case OPC_PRECR_SRA_R_QH_PW
:
23085 TCGv_i32 sa_v
= tcg_const_i32(ret
);
23086 gen_helper_precr_sra_r_qh_pw(v2_t
, v1_t
, v2_t
, sa_v
);
23087 tcg_temp_free_i32(sa_v
);
23090 case OPC_PRECRQ_OB_QH
:
23092 gen_helper_precrq_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
);
23094 case OPC_PRECRQ_PW_L
:
23096 gen_helper_precrq_pw_l(cpu_gpr
[ret
], v1_t
, v2_t
);
23098 case OPC_PRECRQ_QH_PW
:
23100 gen_helper_precrq_qh_pw(cpu_gpr
[ret
], v1_t
, v2_t
);
23102 case OPC_PRECRQ_RS_QH_PW
:
23104 gen_helper_precrq_rs_qh_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23106 case OPC_PRECRQU_S_OB_QH
:
23108 gen_helper_precrqu_s_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23115 tcg_temp_free(v1_t
);
23116 tcg_temp_free(v2_t
);
23119 static void gen_mipsdsp_shift(DisasContext
*ctx
, uint32_t opc
,
23120 int ret
, int v1
, int v2
)
23128 /* Treat as NOP. */
23132 t0
= tcg_temp_new();
23133 v1_t
= tcg_temp_new();
23134 v2_t
= tcg_temp_new();
23136 tcg_gen_movi_tl(t0
, v1
);
23137 gen_load_gpr(v1_t
, v1
);
23138 gen_load_gpr(v2_t
, v2
);
23141 case OPC_SHLL_QB_DSP
:
23143 op2
= MASK_SHLL_QB(ctx
->opcode
);
23147 gen_helper_shll_qb(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
23151 gen_helper_shll_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23155 gen_helper_shll_ph(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
23159 gen_helper_shll_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23161 case OPC_SHLL_S_PH
:
23163 gen_helper_shll_s_ph(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
23165 case OPC_SHLLV_S_PH
:
23167 gen_helper_shll_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23171 gen_helper_shll_s_w(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
23173 case OPC_SHLLV_S_W
:
23175 gen_helper_shll_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23179 gen_helper_shrl_qb(cpu_gpr
[ret
], t0
, v2_t
);
23183 gen_helper_shrl_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
23187 gen_helper_shrl_ph(cpu_gpr
[ret
], t0
, v2_t
);
23191 gen_helper_shrl_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
23195 gen_helper_shra_qb(cpu_gpr
[ret
], t0
, v2_t
);
23197 case OPC_SHRA_R_QB
:
23199 gen_helper_shra_r_qb(cpu_gpr
[ret
], t0
, v2_t
);
23203 gen_helper_shra_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
23205 case OPC_SHRAV_R_QB
:
23207 gen_helper_shra_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
23211 gen_helper_shra_ph(cpu_gpr
[ret
], t0
, v2_t
);
23213 case OPC_SHRA_R_PH
:
23215 gen_helper_shra_r_ph(cpu_gpr
[ret
], t0
, v2_t
);
23219 gen_helper_shra_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
23221 case OPC_SHRAV_R_PH
:
23223 gen_helper_shra_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
23227 gen_helper_shra_r_w(cpu_gpr
[ret
], t0
, v2_t
);
23229 case OPC_SHRAV_R_W
:
23231 gen_helper_shra_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
23233 default: /* Invalid */
23234 MIPS_INVAL("MASK SHLL.QB");
23235 gen_reserved_instruction(ctx
);
23240 #ifdef TARGET_MIPS64
23241 case OPC_SHLL_OB_DSP
:
23242 op2
= MASK_SHLL_OB(ctx
->opcode
);
23246 gen_helper_shll_pw(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
23250 gen_helper_shll_pw(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
23252 case OPC_SHLL_S_PW
:
23254 gen_helper_shll_s_pw(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
23256 case OPC_SHLLV_S_PW
:
23258 gen_helper_shll_s_pw(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
23262 gen_helper_shll_ob(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
23266 gen_helper_shll_ob(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
23270 gen_helper_shll_qh(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
23274 gen_helper_shll_qh(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
23276 case OPC_SHLL_S_QH
:
23278 gen_helper_shll_s_qh(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
23280 case OPC_SHLLV_S_QH
:
23282 gen_helper_shll_s_qh(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
23286 gen_helper_shra_ob(cpu_gpr
[ret
], v2_t
, t0
);
23290 gen_helper_shra_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
23292 case OPC_SHRA_R_OB
:
23294 gen_helper_shra_r_ob(cpu_gpr
[ret
], v2_t
, t0
);
23296 case OPC_SHRAV_R_OB
:
23298 gen_helper_shra_r_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
23302 gen_helper_shra_pw(cpu_gpr
[ret
], v2_t
, t0
);
23306 gen_helper_shra_pw(cpu_gpr
[ret
], v2_t
, v1_t
);
23308 case OPC_SHRA_R_PW
:
23310 gen_helper_shra_r_pw(cpu_gpr
[ret
], v2_t
, t0
);
23312 case OPC_SHRAV_R_PW
:
23314 gen_helper_shra_r_pw(cpu_gpr
[ret
], v2_t
, v1_t
);
23318 gen_helper_shra_qh(cpu_gpr
[ret
], v2_t
, t0
);
23322 gen_helper_shra_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
23324 case OPC_SHRA_R_QH
:
23326 gen_helper_shra_r_qh(cpu_gpr
[ret
], v2_t
, t0
);
23328 case OPC_SHRAV_R_QH
:
23330 gen_helper_shra_r_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
23334 gen_helper_shrl_ob(cpu_gpr
[ret
], v2_t
, t0
);
23338 gen_helper_shrl_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
23342 gen_helper_shrl_qh(cpu_gpr
[ret
], v2_t
, t0
);
23346 gen_helper_shrl_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
23348 default: /* Invalid */
23349 MIPS_INVAL("MASK SHLL.OB");
23350 gen_reserved_instruction(ctx
);
23358 tcg_temp_free(v1_t
);
23359 tcg_temp_free(v2_t
);
23362 static void gen_mipsdsp_multiply(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
23363 int ret
, int v1
, int v2
, int check_ret
)
23369 if ((ret
== 0) && (check_ret
== 1)) {
23370 /* Treat as NOP. */
23374 t0
= tcg_temp_new_i32();
23375 v1_t
= tcg_temp_new();
23376 v2_t
= tcg_temp_new();
23378 tcg_gen_movi_i32(t0
, ret
);
23379 gen_load_gpr(v1_t
, v1
);
23380 gen_load_gpr(v2_t
, v2
);
23384 * OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
23385 * the same mask and op1.
23387 case OPC_MULT_G_2E
:
23391 gen_helper_mul_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23394 gen_helper_mul_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23397 gen_helper_mulq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23399 case OPC_MULQ_RS_W
:
23400 gen_helper_mulq_rs_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23404 case OPC_DPA_W_PH_DSP
:
23406 case OPC_DPAU_H_QBL
:
23408 gen_helper_dpau_h_qbl(t0
, v1_t
, v2_t
, cpu_env
);
23410 case OPC_DPAU_H_QBR
:
23412 gen_helper_dpau_h_qbr(t0
, v1_t
, v2_t
, cpu_env
);
23414 case OPC_DPSU_H_QBL
:
23416 gen_helper_dpsu_h_qbl(t0
, v1_t
, v2_t
, cpu_env
);
23418 case OPC_DPSU_H_QBR
:
23420 gen_helper_dpsu_h_qbr(t0
, v1_t
, v2_t
, cpu_env
);
23424 gen_helper_dpa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23426 case OPC_DPAX_W_PH
:
23428 gen_helper_dpax_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23430 case OPC_DPAQ_S_W_PH
:
23432 gen_helper_dpaq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23434 case OPC_DPAQX_S_W_PH
:
23436 gen_helper_dpaqx_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23438 case OPC_DPAQX_SA_W_PH
:
23440 gen_helper_dpaqx_sa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23444 gen_helper_dps_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23446 case OPC_DPSX_W_PH
:
23448 gen_helper_dpsx_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23450 case OPC_DPSQ_S_W_PH
:
23452 gen_helper_dpsq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23454 case OPC_DPSQX_S_W_PH
:
23456 gen_helper_dpsqx_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23458 case OPC_DPSQX_SA_W_PH
:
23460 gen_helper_dpsqx_sa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23462 case OPC_MULSAQ_S_W_PH
:
23464 gen_helper_mulsaq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23466 case OPC_DPAQ_SA_L_W
:
23468 gen_helper_dpaq_sa_l_w(t0
, v1_t
, v2_t
, cpu_env
);
23470 case OPC_DPSQ_SA_L_W
:
23472 gen_helper_dpsq_sa_l_w(t0
, v1_t
, v2_t
, cpu_env
);
23474 case OPC_MAQ_S_W_PHL
:
23476 gen_helper_maq_s_w_phl(t0
, v1_t
, v2_t
, cpu_env
);
23478 case OPC_MAQ_S_W_PHR
:
23480 gen_helper_maq_s_w_phr(t0
, v1_t
, v2_t
, cpu_env
);
23482 case OPC_MAQ_SA_W_PHL
:
23484 gen_helper_maq_sa_w_phl(t0
, v1_t
, v2_t
, cpu_env
);
23486 case OPC_MAQ_SA_W_PHR
:
23488 gen_helper_maq_sa_w_phr(t0
, v1_t
, v2_t
, cpu_env
);
23490 case OPC_MULSA_W_PH
:
23492 gen_helper_mulsa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23496 #ifdef TARGET_MIPS64
23497 case OPC_DPAQ_W_QH_DSP
:
23499 int ac
= ret
& 0x03;
23500 tcg_gen_movi_i32(t0
, ac
);
23505 gen_helper_dmadd(v1_t
, v2_t
, t0
, cpu_env
);
23509 gen_helper_dmaddu(v1_t
, v2_t
, t0
, cpu_env
);
23513 gen_helper_dmsub(v1_t
, v2_t
, t0
, cpu_env
);
23517 gen_helper_dmsubu(v1_t
, v2_t
, t0
, cpu_env
);
23521 gen_helper_dpa_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
23523 case OPC_DPAQ_S_W_QH
:
23525 gen_helper_dpaq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
23527 case OPC_DPAQ_SA_L_PW
:
23529 gen_helper_dpaq_sa_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
23531 case OPC_DPAU_H_OBL
:
23533 gen_helper_dpau_h_obl(v1_t
, v2_t
, t0
, cpu_env
);
23535 case OPC_DPAU_H_OBR
:
23537 gen_helper_dpau_h_obr(v1_t
, v2_t
, t0
, cpu_env
);
23541 gen_helper_dps_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
23543 case OPC_DPSQ_S_W_QH
:
23545 gen_helper_dpsq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
23547 case OPC_DPSQ_SA_L_PW
:
23549 gen_helper_dpsq_sa_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
23551 case OPC_DPSU_H_OBL
:
23553 gen_helper_dpsu_h_obl(v1_t
, v2_t
, t0
, cpu_env
);
23555 case OPC_DPSU_H_OBR
:
23557 gen_helper_dpsu_h_obr(v1_t
, v2_t
, t0
, cpu_env
);
23559 case OPC_MAQ_S_L_PWL
:
23561 gen_helper_maq_s_l_pwl(v1_t
, v2_t
, t0
, cpu_env
);
23563 case OPC_MAQ_S_L_PWR
:
23565 gen_helper_maq_s_l_pwr(v1_t
, v2_t
, t0
, cpu_env
);
23567 case OPC_MAQ_S_W_QHLL
:
23569 gen_helper_maq_s_w_qhll(v1_t
, v2_t
, t0
, cpu_env
);
23571 case OPC_MAQ_SA_W_QHLL
:
23573 gen_helper_maq_sa_w_qhll(v1_t
, v2_t
, t0
, cpu_env
);
23575 case OPC_MAQ_S_W_QHLR
:
23577 gen_helper_maq_s_w_qhlr(v1_t
, v2_t
, t0
, cpu_env
);
23579 case OPC_MAQ_SA_W_QHLR
:
23581 gen_helper_maq_sa_w_qhlr(v1_t
, v2_t
, t0
, cpu_env
);
23583 case OPC_MAQ_S_W_QHRL
:
23585 gen_helper_maq_s_w_qhrl(v1_t
, v2_t
, t0
, cpu_env
);
23587 case OPC_MAQ_SA_W_QHRL
:
23589 gen_helper_maq_sa_w_qhrl(v1_t
, v2_t
, t0
, cpu_env
);
23591 case OPC_MAQ_S_W_QHRR
:
23593 gen_helper_maq_s_w_qhrr(v1_t
, v2_t
, t0
, cpu_env
);
23595 case OPC_MAQ_SA_W_QHRR
:
23597 gen_helper_maq_sa_w_qhrr(v1_t
, v2_t
, t0
, cpu_env
);
23599 case OPC_MULSAQ_S_L_PW
:
23601 gen_helper_mulsaq_s_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
23603 case OPC_MULSAQ_S_W_QH
:
23605 gen_helper_mulsaq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
23611 case OPC_ADDU_QB_DSP
:
23613 case OPC_MULEU_S_PH_QBL
:
23615 gen_helper_muleu_s_ph_qbl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23617 case OPC_MULEU_S_PH_QBR
:
23619 gen_helper_muleu_s_ph_qbr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23621 case OPC_MULQ_RS_PH
:
23623 gen_helper_mulq_rs_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23625 case OPC_MULEQ_S_W_PHL
:
23627 gen_helper_muleq_s_w_phl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23629 case OPC_MULEQ_S_W_PHR
:
23631 gen_helper_muleq_s_w_phr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23633 case OPC_MULQ_S_PH
:
23635 gen_helper_mulq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23639 #ifdef TARGET_MIPS64
23640 case OPC_ADDU_OB_DSP
:
23642 case OPC_MULEQ_S_PW_QHL
:
23644 gen_helper_muleq_s_pw_qhl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23646 case OPC_MULEQ_S_PW_QHR
:
23648 gen_helper_muleq_s_pw_qhr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23650 case OPC_MULEU_S_QH_OBL
:
23652 gen_helper_muleu_s_qh_obl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23654 case OPC_MULEU_S_QH_OBR
:
23656 gen_helper_muleu_s_qh_obr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23658 case OPC_MULQ_RS_QH
:
23660 gen_helper_mulq_rs_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23667 tcg_temp_free_i32(t0
);
23668 tcg_temp_free(v1_t
);
23669 tcg_temp_free(v2_t
);
23672 static void gen_mipsdsp_bitinsn(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
23680 /* Treat as NOP. */
23684 t0
= tcg_temp_new();
23685 val_t
= tcg_temp_new();
23686 gen_load_gpr(val_t
, val
);
23689 case OPC_ABSQ_S_PH_DSP
:
23693 gen_helper_bitrev(cpu_gpr
[ret
], val_t
);
23698 target_long result
;
23699 imm
= (ctx
->opcode
>> 16) & 0xFF;
23700 result
= (uint32_t)imm
<< 24 |
23701 (uint32_t)imm
<< 16 |
23702 (uint32_t)imm
<< 8 |
23704 result
= (int32_t)result
;
23705 tcg_gen_movi_tl(cpu_gpr
[ret
], result
);
23710 tcg_gen_ext8u_tl(cpu_gpr
[ret
], val_t
);
23711 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 8);
23712 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
23713 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
23714 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
23715 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
23720 imm
= (ctx
->opcode
>> 16) & 0x03FF;
23721 imm
= (int16_t)(imm
<< 6) >> 6;
23722 tcg_gen_movi_tl(cpu_gpr
[ret
], \
23723 (target_long
)((int32_t)imm
<< 16 | \
23729 tcg_gen_ext16u_tl(cpu_gpr
[ret
], val_t
);
23730 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
23731 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
23732 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
23736 #ifdef TARGET_MIPS64
23737 case OPC_ABSQ_S_QH_DSP
:
23744 imm
= (ctx
->opcode
>> 16) & 0xFF;
23745 temp
= ((uint64_t)imm
<< 8) | (uint64_t)imm
;
23746 temp
= (temp
<< 16) | temp
;
23747 temp
= (temp
<< 32) | temp
;
23748 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
23756 imm
= (ctx
->opcode
>> 16) & 0x03FF;
23757 imm
= (int16_t)(imm
<< 6) >> 6;
23758 temp
= ((target_long
)imm
<< 32) \
23759 | ((target_long
)imm
& 0xFFFFFFFF);
23760 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
23768 imm
= (ctx
->opcode
>> 16) & 0x03FF;
23769 imm
= (int16_t)(imm
<< 6) >> 6;
23771 temp
= ((uint64_t)(uint16_t)imm
<< 48) |
23772 ((uint64_t)(uint16_t)imm
<< 32) |
23773 ((uint64_t)(uint16_t)imm
<< 16) |
23774 (uint64_t)(uint16_t)imm
;
23775 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
23780 tcg_gen_ext8u_tl(cpu_gpr
[ret
], val_t
);
23781 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 8);
23782 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
23783 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
23784 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
23785 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
23786 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
23790 tcg_gen_ext32u_i64(cpu_gpr
[ret
], val_t
);
23791 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
23792 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
23796 tcg_gen_ext16u_tl(cpu_gpr
[ret
], val_t
);
23797 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
23798 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
23799 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
23800 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
23807 tcg_temp_free(val_t
);
23810 static void gen_mipsdsp_add_cmp_pick(DisasContext
*ctx
,
23811 uint32_t op1
, uint32_t op2
,
23812 int ret
, int v1
, int v2
, int check_ret
)
23818 if ((ret
== 0) && (check_ret
== 1)) {
23819 /* Treat as NOP. */
23823 t1
= tcg_temp_new();
23824 v1_t
= tcg_temp_new();
23825 v2_t
= tcg_temp_new();
23827 gen_load_gpr(v1_t
, v1
);
23828 gen_load_gpr(v2_t
, v2
);
23831 case OPC_CMPU_EQ_QB_DSP
:
23833 case OPC_CMPU_EQ_QB
:
23835 gen_helper_cmpu_eq_qb(v1_t
, v2_t
, cpu_env
);
23837 case OPC_CMPU_LT_QB
:
23839 gen_helper_cmpu_lt_qb(v1_t
, v2_t
, cpu_env
);
23841 case OPC_CMPU_LE_QB
:
23843 gen_helper_cmpu_le_qb(v1_t
, v2_t
, cpu_env
);
23845 case OPC_CMPGU_EQ_QB
:
23847 gen_helper_cmpgu_eq_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
23849 case OPC_CMPGU_LT_QB
:
23851 gen_helper_cmpgu_lt_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
23853 case OPC_CMPGU_LE_QB
:
23855 gen_helper_cmpgu_le_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
23857 case OPC_CMPGDU_EQ_QB
:
23859 gen_helper_cmpgu_eq_qb(t1
, v1_t
, v2_t
);
23860 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
23861 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
23862 tcg_gen_shli_tl(t1
, t1
, 24);
23863 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
23865 case OPC_CMPGDU_LT_QB
:
23867 gen_helper_cmpgu_lt_qb(t1
, v1_t
, v2_t
);
23868 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
23869 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
23870 tcg_gen_shli_tl(t1
, t1
, 24);
23871 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
23873 case OPC_CMPGDU_LE_QB
:
23875 gen_helper_cmpgu_le_qb(t1
, v1_t
, v2_t
);
23876 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
23877 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
23878 tcg_gen_shli_tl(t1
, t1
, 24);
23879 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
23881 case OPC_CMP_EQ_PH
:
23883 gen_helper_cmp_eq_ph(v1_t
, v2_t
, cpu_env
);
23885 case OPC_CMP_LT_PH
:
23887 gen_helper_cmp_lt_ph(v1_t
, v2_t
, cpu_env
);
23889 case OPC_CMP_LE_PH
:
23891 gen_helper_cmp_le_ph(v1_t
, v2_t
, cpu_env
);
23895 gen_helper_pick_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23899 gen_helper_pick_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23901 case OPC_PACKRL_PH
:
23903 gen_helper_packrl_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
23907 #ifdef TARGET_MIPS64
23908 case OPC_CMPU_EQ_OB_DSP
:
23910 case OPC_CMP_EQ_PW
:
23912 gen_helper_cmp_eq_pw(v1_t
, v2_t
, cpu_env
);
23914 case OPC_CMP_LT_PW
:
23916 gen_helper_cmp_lt_pw(v1_t
, v2_t
, cpu_env
);
23918 case OPC_CMP_LE_PW
:
23920 gen_helper_cmp_le_pw(v1_t
, v2_t
, cpu_env
);
23922 case OPC_CMP_EQ_QH
:
23924 gen_helper_cmp_eq_qh(v1_t
, v2_t
, cpu_env
);
23926 case OPC_CMP_LT_QH
:
23928 gen_helper_cmp_lt_qh(v1_t
, v2_t
, cpu_env
);
23930 case OPC_CMP_LE_QH
:
23932 gen_helper_cmp_le_qh(v1_t
, v2_t
, cpu_env
);
23934 case OPC_CMPGDU_EQ_OB
:
23936 gen_helper_cmpgdu_eq_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23938 case OPC_CMPGDU_LT_OB
:
23940 gen_helper_cmpgdu_lt_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23942 case OPC_CMPGDU_LE_OB
:
23944 gen_helper_cmpgdu_le_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23946 case OPC_CMPGU_EQ_OB
:
23948 gen_helper_cmpgu_eq_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
23950 case OPC_CMPGU_LT_OB
:
23952 gen_helper_cmpgu_lt_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
23954 case OPC_CMPGU_LE_OB
:
23956 gen_helper_cmpgu_le_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
23958 case OPC_CMPU_EQ_OB
:
23960 gen_helper_cmpu_eq_ob(v1_t
, v2_t
, cpu_env
);
23962 case OPC_CMPU_LT_OB
:
23964 gen_helper_cmpu_lt_ob(v1_t
, v2_t
, cpu_env
);
23966 case OPC_CMPU_LE_OB
:
23968 gen_helper_cmpu_le_ob(v1_t
, v2_t
, cpu_env
);
23970 case OPC_PACKRL_PW
:
23972 gen_helper_packrl_pw(cpu_gpr
[ret
], v1_t
, v2_t
);
23976 gen_helper_pick_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23980 gen_helper_pick_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23984 gen_helper_pick_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23992 tcg_temp_free(v1_t
);
23993 tcg_temp_free(v2_t
);
23996 static void gen_mipsdsp_append(CPUMIPSState
*env
, DisasContext
*ctx
,
23997 uint32_t op1
, int rt
, int rs
, int sa
)
24004 /* Treat as NOP. */
24008 t0
= tcg_temp_new();
24009 gen_load_gpr(t0
, rs
);
24012 case OPC_APPEND_DSP
:
24013 switch (MASK_APPEND(ctx
->opcode
)) {
24016 tcg_gen_deposit_tl(cpu_gpr
[rt
], t0
, cpu_gpr
[rt
], sa
, 32 - sa
);
24018 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
24022 tcg_gen_ext32u_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
24023 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], sa
);
24024 tcg_gen_shli_tl(t0
, t0
, 32 - sa
);
24025 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
24027 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
24031 if (sa
!= 0 && sa
!= 2) {
24032 tcg_gen_shli_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 8 * sa
);
24033 tcg_gen_ext32u_tl(t0
, t0
);
24034 tcg_gen_shri_tl(t0
, t0
, 8 * (4 - sa
));
24035 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
24037 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
24039 default: /* Invalid */
24040 MIPS_INVAL("MASK APPEND");
24041 gen_reserved_instruction(ctx
);
24045 #ifdef TARGET_MIPS64
24046 case OPC_DAPPEND_DSP
:
24047 switch (MASK_DAPPEND(ctx
->opcode
)) {
24050 tcg_gen_deposit_tl(cpu_gpr
[rt
], t0
, cpu_gpr
[rt
], sa
, 64 - sa
);
24054 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 0x20 | sa
);
24055 tcg_gen_shli_tl(t0
, t0
, 64 - (0x20 | sa
));
24056 tcg_gen_or_tl(cpu_gpr
[rt
], t0
, t0
);
24060 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], sa
);
24061 tcg_gen_shli_tl(t0
, t0
, 64 - sa
);
24062 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
24067 if (sa
!= 0 && sa
!= 2 && sa
!= 4) {
24068 tcg_gen_shli_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 8 * sa
);
24069 tcg_gen_shri_tl(t0
, t0
, 8 * (8 - sa
));
24070 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
24073 default: /* Invalid */
24074 MIPS_INVAL("MASK DAPPEND");
24075 gen_reserved_instruction(ctx
);
24084 static void gen_mipsdsp_accinsn(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
24085 int ret
, int v1
, int v2
, int check_ret
)
24094 if ((ret
== 0) && (check_ret
== 1)) {
24095 /* Treat as NOP. */
24099 t0
= tcg_temp_new();
24100 t1
= tcg_temp_new();
24101 v1_t
= tcg_temp_new();
24102 v2_t
= tcg_temp_new();
24104 gen_load_gpr(v1_t
, v1
);
24105 gen_load_gpr(v2_t
, v2
);
24108 case OPC_EXTR_W_DSP
:
24112 tcg_gen_movi_tl(t0
, v2
);
24113 tcg_gen_movi_tl(t1
, v1
);
24114 gen_helper_extr_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24117 tcg_gen_movi_tl(t0
, v2
);
24118 tcg_gen_movi_tl(t1
, v1
);
24119 gen_helper_extr_r_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24121 case OPC_EXTR_RS_W
:
24122 tcg_gen_movi_tl(t0
, v2
);
24123 tcg_gen_movi_tl(t1
, v1
);
24124 gen_helper_extr_rs_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24127 tcg_gen_movi_tl(t0
, v2
);
24128 tcg_gen_movi_tl(t1
, v1
);
24129 gen_helper_extr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24131 case OPC_EXTRV_S_H
:
24132 tcg_gen_movi_tl(t0
, v2
);
24133 gen_helper_extr_s_h(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24136 tcg_gen_movi_tl(t0
, v2
);
24137 gen_helper_extr_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24139 case OPC_EXTRV_R_W
:
24140 tcg_gen_movi_tl(t0
, v2
);
24141 gen_helper_extr_r_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24143 case OPC_EXTRV_RS_W
:
24144 tcg_gen_movi_tl(t0
, v2
);
24145 gen_helper_extr_rs_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24148 tcg_gen_movi_tl(t0
, v2
);
24149 tcg_gen_movi_tl(t1
, v1
);
24150 gen_helper_extp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24153 tcg_gen_movi_tl(t0
, v2
);
24154 gen_helper_extp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24157 tcg_gen_movi_tl(t0
, v2
);
24158 tcg_gen_movi_tl(t1
, v1
);
24159 gen_helper_extpdp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24162 tcg_gen_movi_tl(t0
, v2
);
24163 gen_helper_extpdp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24166 imm
= (ctx
->opcode
>> 20) & 0x3F;
24167 tcg_gen_movi_tl(t0
, ret
);
24168 tcg_gen_movi_tl(t1
, imm
);
24169 gen_helper_shilo(t0
, t1
, cpu_env
);
24172 tcg_gen_movi_tl(t0
, ret
);
24173 gen_helper_shilo(t0
, v1_t
, cpu_env
);
24176 tcg_gen_movi_tl(t0
, ret
);
24177 gen_helper_mthlip(t0
, v1_t
, cpu_env
);
24180 imm
= (ctx
->opcode
>> 11) & 0x3FF;
24181 tcg_gen_movi_tl(t0
, imm
);
24182 gen_helper_wrdsp(v1_t
, t0
, cpu_env
);
24185 imm
= (ctx
->opcode
>> 16) & 0x03FF;
24186 tcg_gen_movi_tl(t0
, imm
);
24187 gen_helper_rddsp(cpu_gpr
[ret
], t0
, cpu_env
);
24191 #ifdef TARGET_MIPS64
24192 case OPC_DEXTR_W_DSP
:
24196 tcg_gen_movi_tl(t0
, ret
);
24197 gen_helper_dmthlip(v1_t
, t0
, cpu_env
);
24201 int shift
= (ctx
->opcode
>> 19) & 0x7F;
24202 int ac
= (ctx
->opcode
>> 11) & 0x03;
24203 tcg_gen_movi_tl(t0
, shift
);
24204 tcg_gen_movi_tl(t1
, ac
);
24205 gen_helper_dshilo(t0
, t1
, cpu_env
);
24210 int ac
= (ctx
->opcode
>> 11) & 0x03;
24211 tcg_gen_movi_tl(t0
, ac
);
24212 gen_helper_dshilo(v1_t
, t0
, cpu_env
);
24216 tcg_gen_movi_tl(t0
, v2
);
24217 tcg_gen_movi_tl(t1
, v1
);
24219 gen_helper_dextp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24222 tcg_gen_movi_tl(t0
, v2
);
24223 gen_helper_dextp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24226 tcg_gen_movi_tl(t0
, v2
);
24227 tcg_gen_movi_tl(t1
, v1
);
24228 gen_helper_dextpdp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24231 tcg_gen_movi_tl(t0
, v2
);
24232 gen_helper_dextpdp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24235 tcg_gen_movi_tl(t0
, v2
);
24236 tcg_gen_movi_tl(t1
, v1
);
24237 gen_helper_dextr_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24239 case OPC_DEXTR_R_L
:
24240 tcg_gen_movi_tl(t0
, v2
);
24241 tcg_gen_movi_tl(t1
, v1
);
24242 gen_helper_dextr_r_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24244 case OPC_DEXTR_RS_L
:
24245 tcg_gen_movi_tl(t0
, v2
);
24246 tcg_gen_movi_tl(t1
, v1
);
24247 gen_helper_dextr_rs_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24250 tcg_gen_movi_tl(t0
, v2
);
24251 tcg_gen_movi_tl(t1
, v1
);
24252 gen_helper_dextr_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24254 case OPC_DEXTR_R_W
:
24255 tcg_gen_movi_tl(t0
, v2
);
24256 tcg_gen_movi_tl(t1
, v1
);
24257 gen_helper_dextr_r_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24259 case OPC_DEXTR_RS_W
:
24260 tcg_gen_movi_tl(t0
, v2
);
24261 tcg_gen_movi_tl(t1
, v1
);
24262 gen_helper_dextr_rs_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24264 case OPC_DEXTR_S_H
:
24265 tcg_gen_movi_tl(t0
, v2
);
24266 tcg_gen_movi_tl(t1
, v1
);
24267 gen_helper_dextr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24269 case OPC_DEXTRV_S_H
:
24270 tcg_gen_movi_tl(t0
, v2
);
24271 tcg_gen_movi_tl(t1
, v1
);
24272 gen_helper_dextr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24275 tcg_gen_movi_tl(t0
, v2
);
24276 gen_helper_dextr_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24278 case OPC_DEXTRV_R_L
:
24279 tcg_gen_movi_tl(t0
, v2
);
24280 gen_helper_dextr_r_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24282 case OPC_DEXTRV_RS_L
:
24283 tcg_gen_movi_tl(t0
, v2
);
24284 gen_helper_dextr_rs_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24287 tcg_gen_movi_tl(t0
, v2
);
24288 gen_helper_dextr_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24290 case OPC_DEXTRV_R_W
:
24291 tcg_gen_movi_tl(t0
, v2
);
24292 gen_helper_dextr_r_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24294 case OPC_DEXTRV_RS_W
:
24295 tcg_gen_movi_tl(t0
, v2
);
24296 gen_helper_dextr_rs_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24305 tcg_temp_free(v1_t
);
24306 tcg_temp_free(v2_t
);
24309 /* End MIPSDSP functions. */
24311 static void decode_opc_special_r6(CPUMIPSState
*env
, DisasContext
*ctx
)
24313 int rs
, rt
, rd
, sa
;
24316 rs
= (ctx
->opcode
>> 21) & 0x1f;
24317 rt
= (ctx
->opcode
>> 16) & 0x1f;
24318 rd
= (ctx
->opcode
>> 11) & 0x1f;
24319 sa
= (ctx
->opcode
>> 6) & 0x1f;
24321 op1
= MASK_SPECIAL(ctx
->opcode
);
24327 op2
= MASK_R6_MULDIV(ctx
->opcode
);
24337 gen_r6_muldiv(ctx
, op2
, rd
, rs
, rt
);
24340 MIPS_INVAL("special_r6 muldiv");
24341 gen_reserved_instruction(ctx
);
24347 gen_cond_move(ctx
, op1
, rd
, rs
, rt
);
24351 if (rt
== 0 && sa
== 1) {
24353 * Major opcode and function field is shared with preR6 MFHI/MTHI.
24354 * We need additionally to check other fields.
24356 gen_cl(ctx
, op1
, rd
, rs
);
24358 gen_reserved_instruction(ctx
);
24362 if (is_uhi(extract32(ctx
->opcode
, 6, 20))) {
24363 gen_helper_do_semihosting(cpu_env
);
24365 if (ctx
->hflags
& MIPS_HFLAG_SBRI
) {
24366 gen_reserved_instruction(ctx
);
24368 generate_exception_end(ctx
, EXCP_DBp
);
24372 #if defined(TARGET_MIPS64)
24375 if (rt
== 0 && sa
== 1) {
24377 * Major opcode and function field is shared with preR6 MFHI/MTHI.
24378 * We need additionally to check other fields.
24380 check_mips_64(ctx
);
24381 gen_cl(ctx
, op1
, rd
, rs
);
24383 gen_reserved_instruction(ctx
);
24391 op2
= MASK_R6_MULDIV(ctx
->opcode
);
24401 check_mips_64(ctx
);
24402 gen_r6_muldiv(ctx
, op2
, rd
, rs
, rt
);
24405 MIPS_INVAL("special_r6 muldiv");
24406 gen_reserved_instruction(ctx
);
24411 default: /* Invalid */
24412 MIPS_INVAL("special_r6");
24413 gen_reserved_instruction(ctx
);
24418 static void decode_opc_special_tx79(CPUMIPSState
*env
, DisasContext
*ctx
)
24420 int rs
= extract32(ctx
->opcode
, 21, 5);
24421 int rt
= extract32(ctx
->opcode
, 16, 5);
24422 int rd
= extract32(ctx
->opcode
, 11, 5);
24423 uint32_t op1
= MASK_SPECIAL(ctx
->opcode
);
24426 case OPC_MOVN
: /* Conditional move */
24428 gen_cond_move(ctx
, op1
, rd
, rs
, rt
);
24430 case OPC_MFHI
: /* Move from HI/LO */
24432 gen_HILO(ctx
, op1
, 0, rd
);
24435 case OPC_MTLO
: /* Move to HI/LO */
24436 gen_HILO(ctx
, op1
, 0, rs
);
24440 gen_mul_txx9(ctx
, op1
, rd
, rs
, rt
);
24444 gen_muldiv(ctx
, op1
, 0, rs
, rt
);
24446 #if defined(TARGET_MIPS64)
24451 check_insn_opc_user_only(ctx
, INSN_R5900
);
24452 gen_muldiv(ctx
, op1
, 0, rs
, rt
);
24456 gen_compute_branch(ctx
, op1
, 4, rs
, 0, 0, 4);
24458 default: /* Invalid */
24459 MIPS_INVAL("special_tx79");
24460 gen_reserved_instruction(ctx
);
24465 static void decode_opc_special_legacy(CPUMIPSState
*env
, DisasContext
*ctx
)
24467 int rs
, rt
, rd
, sa
;
24470 rs
= (ctx
->opcode
>> 21) & 0x1f;
24471 rt
= (ctx
->opcode
>> 16) & 0x1f;
24472 rd
= (ctx
->opcode
>> 11) & 0x1f;
24473 sa
= (ctx
->opcode
>> 6) & 0x1f;
24475 op1
= MASK_SPECIAL(ctx
->opcode
);
24477 case OPC_MOVN
: /* Conditional move */
24479 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS_R1
|
24480 INSN_LOONGSON2E
| INSN_LOONGSON2F
);
24481 gen_cond_move(ctx
, op1
, rd
, rs
, rt
);
24483 case OPC_MFHI
: /* Move from HI/LO */
24485 gen_HILO(ctx
, op1
, rs
& 3, rd
);
24488 case OPC_MTLO
: /* Move to HI/LO */
24489 gen_HILO(ctx
, op1
, rd
& 3, rs
);
24492 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS_R1
);
24493 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
24494 check_cp1_enabled(ctx
);
24495 gen_movci(ctx
, rd
, rs
, (ctx
->opcode
>> 18) & 0x7,
24496 (ctx
->opcode
>> 16) & 1);
24498 generate_exception_err(ctx
, EXCP_CpU
, 1);
24504 check_insn(ctx
, INSN_VR54XX
);
24505 op1
= MASK_MUL_VR54XX(ctx
->opcode
);
24506 gen_mul_vr54xx(ctx
, op1
, rd
, rs
, rt
);
24508 gen_muldiv(ctx
, op1
, rd
& 3, rs
, rt
);
24513 gen_muldiv(ctx
, op1
, 0, rs
, rt
);
24515 #if defined(TARGET_MIPS64)
24520 check_insn(ctx
, ISA_MIPS3
);
24521 check_mips_64(ctx
);
24522 gen_muldiv(ctx
, op1
, 0, rs
, rt
);
24526 gen_compute_branch(ctx
, op1
, 4, rs
, rd
, sa
, 4);
24529 #ifdef MIPS_STRICT_STANDARD
24530 MIPS_INVAL("SPIM");
24531 gen_reserved_instruction(ctx
);
24533 /* Implemented as RI exception for now. */
24534 MIPS_INVAL("spim (unofficial)");
24535 gen_reserved_instruction(ctx
);
24538 default: /* Invalid */
24539 MIPS_INVAL("special_legacy");
24540 gen_reserved_instruction(ctx
);
24545 static void decode_opc_special(CPUMIPSState
*env
, DisasContext
*ctx
)
24547 int rs
, rt
, rd
, sa
;
24550 rs
= (ctx
->opcode
>> 21) & 0x1f;
24551 rt
= (ctx
->opcode
>> 16) & 0x1f;
24552 rd
= (ctx
->opcode
>> 11) & 0x1f;
24553 sa
= (ctx
->opcode
>> 6) & 0x1f;
24555 op1
= MASK_SPECIAL(ctx
->opcode
);
24557 case OPC_SLL
: /* Shift with immediate */
24558 if (sa
== 5 && rd
== 0 &&
24559 rs
== 0 && rt
== 0) { /* PAUSE */
24560 if ((ctx
->insn_flags
& ISA_MIPS_R6
) &&
24561 (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
24562 gen_reserved_instruction(ctx
);
24568 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
24571 switch ((ctx
->opcode
>> 21) & 0x1f) {
24573 /* rotr is decoded as srl on non-R2 CPUs */
24574 if (ctx
->insn_flags
& ISA_MIPS_R2
) {
24579 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
24582 gen_reserved_instruction(ctx
);
24590 gen_arith(ctx
, op1
, rd
, rs
, rt
);
24592 case OPC_SLLV
: /* Shifts */
24594 gen_shift(ctx
, op1
, rd
, rs
, rt
);
24597 switch ((ctx
->opcode
>> 6) & 0x1f) {
24599 /* rotrv is decoded as srlv on non-R2 CPUs */
24600 if (ctx
->insn_flags
& ISA_MIPS_R2
) {
24605 gen_shift(ctx
, op1
, rd
, rs
, rt
);
24608 gen_reserved_instruction(ctx
);
24612 case OPC_SLT
: /* Set on less than */
24614 gen_slt(ctx
, op1
, rd
, rs
, rt
);
24616 case OPC_AND
: /* Logic*/
24620 gen_logic(ctx
, op1
, rd
, rs
, rt
);
24623 gen_compute_branch(ctx
, op1
, 4, rs
, rd
, sa
, 4);
24625 case OPC_TGE
: /* Traps */
24631 check_insn(ctx
, ISA_MIPS2
);
24632 gen_trap(ctx
, op1
, rs
, rt
, -1);
24635 /* Pmon entry point, also R4010 selsl */
24636 #ifdef MIPS_STRICT_STANDARD
24637 MIPS_INVAL("PMON / selsl");
24638 gen_reserved_instruction(ctx
);
24640 gen_helper_0e0i(pmon
, sa
);
24644 generate_exception_end(ctx
, EXCP_SYSCALL
);
24647 generate_exception_end(ctx
, EXCP_BREAK
);
24650 check_insn(ctx
, ISA_MIPS2
);
24651 gen_sync(extract32(ctx
->opcode
, 6, 5));
24654 #if defined(TARGET_MIPS64)
24655 /* MIPS64 specific opcodes */
24660 check_insn(ctx
, ISA_MIPS3
);
24661 check_mips_64(ctx
);
24662 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
24665 switch ((ctx
->opcode
>> 21) & 0x1f) {
24667 /* drotr is decoded as dsrl on non-R2 CPUs */
24668 if (ctx
->insn_flags
& ISA_MIPS_R2
) {
24673 check_insn(ctx
, ISA_MIPS3
);
24674 check_mips_64(ctx
);
24675 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
24678 gen_reserved_instruction(ctx
);
24683 switch ((ctx
->opcode
>> 21) & 0x1f) {
24685 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
24686 if (ctx
->insn_flags
& ISA_MIPS_R2
) {
24691 check_insn(ctx
, ISA_MIPS3
);
24692 check_mips_64(ctx
);
24693 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
24696 gen_reserved_instruction(ctx
);
24704 check_insn(ctx
, ISA_MIPS3
);
24705 check_mips_64(ctx
);
24706 gen_arith(ctx
, op1
, rd
, rs
, rt
);
24710 check_insn(ctx
, ISA_MIPS3
);
24711 check_mips_64(ctx
);
24712 gen_shift(ctx
, op1
, rd
, rs
, rt
);
24715 switch ((ctx
->opcode
>> 6) & 0x1f) {
24717 /* drotrv is decoded as dsrlv on non-R2 CPUs */
24718 if (ctx
->insn_flags
& ISA_MIPS_R2
) {
24723 check_insn(ctx
, ISA_MIPS3
);
24724 check_mips_64(ctx
);
24725 gen_shift(ctx
, op1
, rd
, rs
, rt
);
24728 gen_reserved_instruction(ctx
);
24734 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
24735 decode_opc_special_r6(env
, ctx
);
24736 } else if (ctx
->insn_flags
& INSN_R5900
) {
24737 decode_opc_special_tx79(env
, ctx
);
24739 decode_opc_special_legacy(env
, ctx
);
24745 #if defined(TARGET_MIPS64)
24749 * MMI (MultiMedia Interface) ASE instructions
24750 * ===========================================
24754 * MMI instructions category: data communication
24755 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
24757 * PCPYH PEXCH PEXTLB PINTH PPACB PEXT5 PREVH
24758 * PCPYLD PEXCW PEXTLH PINTEH PPACH PPAC5 PROT3W
24759 * PCPYUD PEXEH PEXTLW PPACW
24768 * Parallel Copy Halfword
24770 * 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
24771 * +-----------+---------+---------+---------+---------+-----------+
24772 * | MMI |0 0 0 0 0| rt | rd | PCPYH | MMI3 |
24773 * +-----------+---------+---------+---------+---------+-----------+
24775 static void gen_mmi_pcpyh(DisasContext
*ctx
)
24777 uint32_t pd
, rt
, rd
;
24780 opcode
= ctx
->opcode
;
24782 pd
= extract32(opcode
, 21, 5);
24783 rt
= extract32(opcode
, 16, 5);
24784 rd
= extract32(opcode
, 11, 5);
24786 if (unlikely(pd
!= 0)) {
24787 gen_reserved_instruction(ctx
);
24788 } else if (rd
== 0) {
24790 } else if (rt
== 0) {
24791 tcg_gen_movi_i64(cpu_gpr
[rd
], 0);
24792 tcg_gen_movi_i64(cpu_gpr_hi
[rd
], 0);
24794 TCGv_i64 t0
= tcg_temp_new();
24795 TCGv_i64 t1
= tcg_temp_new();
24796 uint64_t mask
= (1ULL << 16) - 1;
24798 tcg_gen_andi_i64(t0
, cpu_gpr
[rt
], mask
);
24799 tcg_gen_movi_i64(t1
, 0);
24800 tcg_gen_or_i64(t1
, t0
, t1
);
24801 tcg_gen_shli_i64(t0
, t0
, 16);
24802 tcg_gen_or_i64(t1
, t0
, t1
);
24803 tcg_gen_shli_i64(t0
, t0
, 16);
24804 tcg_gen_or_i64(t1
, t0
, t1
);
24805 tcg_gen_shli_i64(t0
, t0
, 16);
24806 tcg_gen_or_i64(t1
, t0
, t1
);
24808 tcg_gen_mov_i64(cpu_gpr
[rd
], t1
);
24810 tcg_gen_andi_i64(t0
, cpu_gpr_hi
[rt
], mask
);
24811 tcg_gen_movi_i64(t1
, 0);
24812 tcg_gen_or_i64(t1
, t0
, t1
);
24813 tcg_gen_shli_i64(t0
, t0
, 16);
24814 tcg_gen_or_i64(t1
, t0
, t1
);
24815 tcg_gen_shli_i64(t0
, t0
, 16);
24816 tcg_gen_or_i64(t1
, t0
, t1
);
24817 tcg_gen_shli_i64(t0
, t0
, 16);
24818 tcg_gen_or_i64(t1
, t0
, t1
);
24820 tcg_gen_mov_i64(cpu_gpr_hi
[rd
], t1
);
24828 * PCPYLD rd, rs, rt
24830 * Parallel Copy Lower Doubleword
24832 * 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
24833 * +-----------+---------+---------+---------+---------+-----------+
24834 * | MMI | rs | rt | rd | PCPYLD | MMI2 |
24835 * +-----------+---------+---------+---------+---------+-----------+
24837 static void gen_mmi_pcpyld(DisasContext
*ctx
)
24839 uint32_t rs
, rt
, rd
;
24842 opcode
= ctx
->opcode
;
24844 rs
= extract32(opcode
, 21, 5);
24845 rt
= extract32(opcode
, 16, 5);
24846 rd
= extract32(opcode
, 11, 5);
24852 tcg_gen_movi_i64(cpu_gpr_hi
[rd
], 0);
24854 tcg_gen_mov_i64(cpu_gpr_hi
[rd
], cpu_gpr
[rs
]);
24857 tcg_gen_movi_i64(cpu_gpr
[rd
], 0);
24860 tcg_gen_mov_i64(cpu_gpr
[rd
], cpu_gpr
[rt
]);
24867 * PCPYUD rd, rs, rt
24869 * Parallel Copy Upper Doubleword
24871 * 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
24872 * +-----------+---------+---------+---------+---------+-----------+
24873 * | MMI | rs | rt | rd | PCPYUD | MMI3 |
24874 * +-----------+---------+---------+---------+---------+-----------+
24876 static void gen_mmi_pcpyud(DisasContext
*ctx
)
24878 uint32_t rs
, rt
, rd
;
24881 opcode
= ctx
->opcode
;
24883 rs
= extract32(opcode
, 21, 5);
24884 rt
= extract32(opcode
, 16, 5);
24885 rd
= extract32(opcode
, 11, 5);
24891 tcg_gen_movi_i64(cpu_gpr
[rd
], 0);
24893 tcg_gen_mov_i64(cpu_gpr
[rd
], cpu_gpr_hi
[rs
]);
24896 tcg_gen_movi_i64(cpu_gpr_hi
[rd
], 0);
24899 tcg_gen_mov_i64(cpu_gpr_hi
[rd
], cpu_gpr_hi
[rt
]);
24908 #if !defined(TARGET_MIPS64)
24910 /* MXU accumulate add/subtract 1-bit pattern 'aptn1' */
24911 #define MXU_APTN1_A 0
24912 #define MXU_APTN1_S 1
24914 /* MXU accumulate add/subtract 2-bit pattern 'aptn2' */
24915 #define MXU_APTN2_AA 0
24916 #define MXU_APTN2_AS 1
24917 #define MXU_APTN2_SA 2
24918 #define MXU_APTN2_SS 3
24920 /* MXU execute add/subtract 2-bit pattern 'eptn2' */
24921 #define MXU_EPTN2_AA 0
24922 #define MXU_EPTN2_AS 1
24923 #define MXU_EPTN2_SA 2
24924 #define MXU_EPTN2_SS 3
24926 /* MXU operand getting pattern 'optn2' */
24927 #define MXU_OPTN2_PTN0 0
24928 #define MXU_OPTN2_PTN1 1
24929 #define MXU_OPTN2_PTN2 2
24930 #define MXU_OPTN2_PTN3 3
24931 /* alternative naming scheme for 'optn2' */
24932 #define MXU_OPTN2_WW 0
24933 #define MXU_OPTN2_LW 1
24934 #define MXU_OPTN2_HW 2
24935 #define MXU_OPTN2_XW 3
24937 /* MXU operand getting pattern 'optn3' */
24938 #define MXU_OPTN3_PTN0 0
24939 #define MXU_OPTN3_PTN1 1
24940 #define MXU_OPTN3_PTN2 2
24941 #define MXU_OPTN3_PTN3 3
24942 #define MXU_OPTN3_PTN4 4
24943 #define MXU_OPTN3_PTN5 5
24944 #define MXU_OPTN3_PTN6 6
24945 #define MXU_OPTN3_PTN7 7
24949 * S32I2M XRa, rb - Register move from GRF to XRF
24951 static void gen_mxu_s32i2m(DisasContext
*ctx
)
24956 t0
= tcg_temp_new();
24958 XRa
= extract32(ctx
->opcode
, 6, 5);
24959 Rb
= extract32(ctx
->opcode
, 16, 5);
24961 gen_load_gpr(t0
, Rb
);
24963 gen_store_mxu_gpr(t0
, XRa
);
24964 } else if (XRa
== 16) {
24965 gen_store_mxu_cr(t0
);
24972 * S32M2I XRa, rb - Register move from XRF to GRF
24974 static void gen_mxu_s32m2i(DisasContext
*ctx
)
24979 t0
= tcg_temp_new();
24981 XRa
= extract32(ctx
->opcode
, 6, 5);
24982 Rb
= extract32(ctx
->opcode
, 16, 5);
24985 gen_load_mxu_gpr(t0
, XRa
);
24986 } else if (XRa
== 16) {
24987 gen_load_mxu_cr(t0
);
24990 gen_store_gpr(t0
, Rb
);
24996 * S8LDD XRa, Rb, s8, optn3 - Load a byte from memory to XRF
24998 static void gen_mxu_s8ldd(DisasContext
*ctx
)
25001 uint32_t XRa
, Rb
, s8
, optn3
;
25003 t0
= tcg_temp_new();
25004 t1
= tcg_temp_new();
25006 XRa
= extract32(ctx
->opcode
, 6, 4);
25007 s8
= extract32(ctx
->opcode
, 10, 8);
25008 optn3
= extract32(ctx
->opcode
, 18, 3);
25009 Rb
= extract32(ctx
->opcode
, 21, 5);
25011 gen_load_gpr(t0
, Rb
);
25012 tcg_gen_addi_tl(t0
, t0
, (int8_t)s8
);
25015 /* XRa[7:0] = tmp8 */
25016 case MXU_OPTN3_PTN0
:
25017 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
25018 gen_load_mxu_gpr(t0
, XRa
);
25019 tcg_gen_deposit_tl(t0
, t0
, t1
, 0, 8);
25021 /* XRa[15:8] = tmp8 */
25022 case MXU_OPTN3_PTN1
:
25023 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
25024 gen_load_mxu_gpr(t0
, XRa
);
25025 tcg_gen_deposit_tl(t0
, t0
, t1
, 8, 8);
25027 /* XRa[23:16] = tmp8 */
25028 case MXU_OPTN3_PTN2
:
25029 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
25030 gen_load_mxu_gpr(t0
, XRa
);
25031 tcg_gen_deposit_tl(t0
, t0
, t1
, 16, 8);
25033 /* XRa[31:24] = tmp8 */
25034 case MXU_OPTN3_PTN3
:
25035 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
25036 gen_load_mxu_gpr(t0
, XRa
);
25037 tcg_gen_deposit_tl(t0
, t0
, t1
, 24, 8);
25039 /* XRa = {8'b0, tmp8, 8'b0, tmp8} */
25040 case MXU_OPTN3_PTN4
:
25041 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
25042 tcg_gen_deposit_tl(t0
, t1
, t1
, 16, 16);
25044 /* XRa = {tmp8, 8'b0, tmp8, 8'b0} */
25045 case MXU_OPTN3_PTN5
:
25046 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
25047 tcg_gen_shli_tl(t1
, t1
, 8);
25048 tcg_gen_deposit_tl(t0
, t1
, t1
, 16, 16);
25050 /* XRa = {{8{sign of tmp8}}, tmp8, {8{sign of tmp8}}, tmp8} */
25051 case MXU_OPTN3_PTN6
:
25052 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_SB
);
25053 tcg_gen_mov_tl(t0
, t1
);
25054 tcg_gen_andi_tl(t0
, t0
, 0xFF00FFFF);
25055 tcg_gen_shli_tl(t1
, t1
, 16);
25056 tcg_gen_or_tl(t0
, t0
, t1
);
25058 /* XRa = {tmp8, tmp8, tmp8, tmp8} */
25059 case MXU_OPTN3_PTN7
:
25060 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
25061 tcg_gen_deposit_tl(t1
, t1
, t1
, 8, 8);
25062 tcg_gen_deposit_tl(t0
, t1
, t1
, 16, 16);
25066 gen_store_mxu_gpr(t0
, XRa
);
25073 * D16MUL XRa, XRb, XRc, XRd, optn2 - Signed 16 bit pattern multiplication
25075 static void gen_mxu_d16mul(DisasContext
*ctx
)
25077 TCGv t0
, t1
, t2
, t3
;
25078 uint32_t XRa
, XRb
, XRc
, XRd
, optn2
;
25080 t0
= tcg_temp_new();
25081 t1
= tcg_temp_new();
25082 t2
= tcg_temp_new();
25083 t3
= tcg_temp_new();
25085 XRa
= extract32(ctx
->opcode
, 6, 4);
25086 XRb
= extract32(ctx
->opcode
, 10, 4);
25087 XRc
= extract32(ctx
->opcode
, 14, 4);
25088 XRd
= extract32(ctx
->opcode
, 18, 4);
25089 optn2
= extract32(ctx
->opcode
, 22, 2);
25091 gen_load_mxu_gpr(t1
, XRb
);
25092 tcg_gen_sextract_tl(t0
, t1
, 0, 16);
25093 tcg_gen_sextract_tl(t1
, t1
, 16, 16);
25094 gen_load_mxu_gpr(t3
, XRc
);
25095 tcg_gen_sextract_tl(t2
, t3
, 0, 16);
25096 tcg_gen_sextract_tl(t3
, t3
, 16, 16);
25099 case MXU_OPTN2_WW
: /* XRB.H*XRC.H == lop, XRB.L*XRC.L == rop */
25100 tcg_gen_mul_tl(t3
, t1
, t3
);
25101 tcg_gen_mul_tl(t2
, t0
, t2
);
25103 case MXU_OPTN2_LW
: /* XRB.L*XRC.H == lop, XRB.L*XRC.L == rop */
25104 tcg_gen_mul_tl(t3
, t0
, t3
);
25105 tcg_gen_mul_tl(t2
, t0
, t2
);
25107 case MXU_OPTN2_HW
: /* XRB.H*XRC.H == lop, XRB.H*XRC.L == rop */
25108 tcg_gen_mul_tl(t3
, t1
, t3
);
25109 tcg_gen_mul_tl(t2
, t1
, t2
);
25111 case MXU_OPTN2_XW
: /* XRB.L*XRC.H == lop, XRB.H*XRC.L == rop */
25112 tcg_gen_mul_tl(t3
, t0
, t3
);
25113 tcg_gen_mul_tl(t2
, t1
, t2
);
25116 gen_store_mxu_gpr(t3
, XRa
);
25117 gen_store_mxu_gpr(t2
, XRd
);
25126 * D16MAC XRa, XRb, XRc, XRd, aptn2, optn2 - Signed 16 bit pattern multiply
25129 static void gen_mxu_d16mac(DisasContext
*ctx
)
25131 TCGv t0
, t1
, t2
, t3
;
25132 uint32_t XRa
, XRb
, XRc
, XRd
, optn2
, aptn2
;
25134 t0
= tcg_temp_new();
25135 t1
= tcg_temp_new();
25136 t2
= tcg_temp_new();
25137 t3
= tcg_temp_new();
25139 XRa
= extract32(ctx
->opcode
, 6, 4);
25140 XRb
= extract32(ctx
->opcode
, 10, 4);
25141 XRc
= extract32(ctx
->opcode
, 14, 4);
25142 XRd
= extract32(ctx
->opcode
, 18, 4);
25143 optn2
= extract32(ctx
->opcode
, 22, 2);
25144 aptn2
= extract32(ctx
->opcode
, 24, 2);
25146 gen_load_mxu_gpr(t1
, XRb
);
25147 tcg_gen_sextract_tl(t0
, t1
, 0, 16);
25148 tcg_gen_sextract_tl(t1
, t1
, 16, 16);
25150 gen_load_mxu_gpr(t3
, XRc
);
25151 tcg_gen_sextract_tl(t2
, t3
, 0, 16);
25152 tcg_gen_sextract_tl(t3
, t3
, 16, 16);
25155 case MXU_OPTN2_WW
: /* XRB.H*XRC.H == lop, XRB.L*XRC.L == rop */
25156 tcg_gen_mul_tl(t3
, t1
, t3
);
25157 tcg_gen_mul_tl(t2
, t0
, t2
);
25159 case MXU_OPTN2_LW
: /* XRB.L*XRC.H == lop, XRB.L*XRC.L == rop */
25160 tcg_gen_mul_tl(t3
, t0
, t3
);
25161 tcg_gen_mul_tl(t2
, t0
, t2
);
25163 case MXU_OPTN2_HW
: /* XRB.H*XRC.H == lop, XRB.H*XRC.L == rop */
25164 tcg_gen_mul_tl(t3
, t1
, t3
);
25165 tcg_gen_mul_tl(t2
, t1
, t2
);
25167 case MXU_OPTN2_XW
: /* XRB.L*XRC.H == lop, XRB.H*XRC.L == rop */
25168 tcg_gen_mul_tl(t3
, t0
, t3
);
25169 tcg_gen_mul_tl(t2
, t1
, t2
);
25172 gen_load_mxu_gpr(t0
, XRa
);
25173 gen_load_mxu_gpr(t1
, XRd
);
25177 tcg_gen_add_tl(t3
, t0
, t3
);
25178 tcg_gen_add_tl(t2
, t1
, t2
);
25181 tcg_gen_add_tl(t3
, t0
, t3
);
25182 tcg_gen_sub_tl(t2
, t1
, t2
);
25185 tcg_gen_sub_tl(t3
, t0
, t3
);
25186 tcg_gen_add_tl(t2
, t1
, t2
);
25189 tcg_gen_sub_tl(t3
, t0
, t3
);
25190 tcg_gen_sub_tl(t2
, t1
, t2
);
25193 gen_store_mxu_gpr(t3
, XRa
);
25194 gen_store_mxu_gpr(t2
, XRd
);
25203 * Q8MUL XRa, XRb, XRc, XRd - Parallel unsigned 8 bit pattern multiply
25204 * Q8MULSU XRa, XRb, XRc, XRd - Parallel signed 8 bit pattern multiply
25206 static void gen_mxu_q8mul_q8mulsu(DisasContext
*ctx
)
25208 TCGv t0
, t1
, t2
, t3
, t4
, t5
, t6
, t7
;
25209 uint32_t XRa
, XRb
, XRc
, XRd
, sel
;
25211 t0
= tcg_temp_new();
25212 t1
= tcg_temp_new();
25213 t2
= tcg_temp_new();
25214 t3
= tcg_temp_new();
25215 t4
= tcg_temp_new();
25216 t5
= tcg_temp_new();
25217 t6
= tcg_temp_new();
25218 t7
= tcg_temp_new();
25220 XRa
= extract32(ctx
->opcode
, 6, 4);
25221 XRb
= extract32(ctx
->opcode
, 10, 4);
25222 XRc
= extract32(ctx
->opcode
, 14, 4);
25223 XRd
= extract32(ctx
->opcode
, 18, 4);
25224 sel
= extract32(ctx
->opcode
, 22, 2);
25226 gen_load_mxu_gpr(t3
, XRb
);
25227 gen_load_mxu_gpr(t7
, XRc
);
25231 tcg_gen_ext8s_tl(t0
, t3
);
25232 tcg_gen_shri_tl(t3
, t3
, 8);
25233 tcg_gen_ext8s_tl(t1
, t3
);
25234 tcg_gen_shri_tl(t3
, t3
, 8);
25235 tcg_gen_ext8s_tl(t2
, t3
);
25236 tcg_gen_shri_tl(t3
, t3
, 8);
25237 tcg_gen_ext8s_tl(t3
, t3
);
25240 tcg_gen_ext8u_tl(t0
, t3
);
25241 tcg_gen_shri_tl(t3
, t3
, 8);
25242 tcg_gen_ext8u_tl(t1
, t3
);
25243 tcg_gen_shri_tl(t3
, t3
, 8);
25244 tcg_gen_ext8u_tl(t2
, t3
);
25245 tcg_gen_shri_tl(t3
, t3
, 8);
25246 tcg_gen_ext8u_tl(t3
, t3
);
25249 tcg_gen_ext8u_tl(t4
, t7
);
25250 tcg_gen_shri_tl(t7
, t7
, 8);
25251 tcg_gen_ext8u_tl(t5
, t7
);
25252 tcg_gen_shri_tl(t7
, t7
, 8);
25253 tcg_gen_ext8u_tl(t6
, t7
);
25254 tcg_gen_shri_tl(t7
, t7
, 8);
25255 tcg_gen_ext8u_tl(t7
, t7
);
25257 tcg_gen_mul_tl(t0
, t0
, t4
);
25258 tcg_gen_mul_tl(t1
, t1
, t5
);
25259 tcg_gen_mul_tl(t2
, t2
, t6
);
25260 tcg_gen_mul_tl(t3
, t3
, t7
);
25262 tcg_gen_andi_tl(t0
, t0
, 0xFFFF);
25263 tcg_gen_andi_tl(t1
, t1
, 0xFFFF);
25264 tcg_gen_andi_tl(t2
, t2
, 0xFFFF);
25265 tcg_gen_andi_tl(t3
, t3
, 0xFFFF);
25267 tcg_gen_shli_tl(t1
, t1
, 16);
25268 tcg_gen_shli_tl(t3
, t3
, 16);
25270 tcg_gen_or_tl(t0
, t0
, t1
);
25271 tcg_gen_or_tl(t1
, t2
, t3
);
25273 gen_store_mxu_gpr(t0
, XRd
);
25274 gen_store_mxu_gpr(t1
, XRa
);
25287 * S32LDD XRa, Rb, S12 - Load a word from memory to XRF
25288 * S32LDDR XRa, Rb, S12 - Load a word from memory to XRF, reversed byte seq.
25290 static void gen_mxu_s32ldd_s32lddr(DisasContext
*ctx
)
25293 uint32_t XRa
, Rb
, s12
, sel
;
25295 t0
= tcg_temp_new();
25296 t1
= tcg_temp_new();
25298 XRa
= extract32(ctx
->opcode
, 6, 4);
25299 s12
= extract32(ctx
->opcode
, 10, 10);
25300 sel
= extract32(ctx
->opcode
, 20, 1);
25301 Rb
= extract32(ctx
->opcode
, 21, 5);
25303 gen_load_gpr(t0
, Rb
);
25305 tcg_gen_movi_tl(t1
, s12
);
25306 tcg_gen_shli_tl(t1
, t1
, 2);
25308 tcg_gen_ori_tl(t1
, t1
, 0xFFFFF000);
25310 tcg_gen_add_tl(t1
, t0
, t1
);
25311 tcg_gen_qemu_ld_tl(t1
, t1
, ctx
->mem_idx
, MO_SL
);
25315 tcg_gen_bswap32_tl(t1
, t1
);
25317 gen_store_mxu_gpr(t1
, XRa
);
25325 * MXU instruction category: logic
25326 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
25328 * S32NOR S32AND S32OR S32XOR
25332 * S32NOR XRa, XRb, XRc
25333 * Update XRa with the result of logical bitwise 'nor' operation
25334 * applied to the content of XRb and XRc.
25336 * 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
25337 * +-----------+---------+-----+-------+-------+-------+-----------+
25338 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL16|
25339 * +-----------+---------+-----+-------+-------+-------+-----------+
25341 static void gen_mxu_S32NOR(DisasContext
*ctx
)
25343 uint32_t pad
, XRc
, XRb
, XRa
;
25345 pad
= extract32(ctx
->opcode
, 21, 5);
25346 XRc
= extract32(ctx
->opcode
, 14, 4);
25347 XRb
= extract32(ctx
->opcode
, 10, 4);
25348 XRa
= extract32(ctx
->opcode
, 6, 4);
25350 if (unlikely(pad
!= 0)) {
25351 /* opcode padding incorrect -> do nothing */
25352 } else if (unlikely(XRa
== 0)) {
25353 /* destination is zero register -> do nothing */
25354 } else if (unlikely((XRb
== 0) && (XRc
== 0))) {
25355 /* both operands zero registers -> just set destination to all 1s */
25356 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0xFFFFFFFF);
25357 } else if (unlikely(XRb
== 0)) {
25358 /* XRb zero register -> just set destination to the negation of XRc */
25359 tcg_gen_not_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRc
- 1]);
25360 } else if (unlikely(XRc
== 0)) {
25361 /* XRa zero register -> just set destination to the negation of XRb */
25362 tcg_gen_not_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25363 } else if (unlikely(XRb
== XRc
)) {
25364 /* both operands same -> just set destination to the negation of XRb */
25365 tcg_gen_not_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25367 /* the most general case */
25368 tcg_gen_nor_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1], mxu_gpr
[XRc
- 1]);
25373 * S32AND XRa, XRb, XRc
25374 * Update XRa with the result of logical bitwise 'and' operation
25375 * applied to the content of XRb and XRc.
25377 * 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
25378 * +-----------+---------+-----+-------+-------+-------+-----------+
25379 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL16|
25380 * +-----------+---------+-----+-------+-------+-------+-----------+
25382 static void gen_mxu_S32AND(DisasContext
*ctx
)
25384 uint32_t pad
, XRc
, XRb
, XRa
;
25386 pad
= extract32(ctx
->opcode
, 21, 5);
25387 XRc
= extract32(ctx
->opcode
, 14, 4);
25388 XRb
= extract32(ctx
->opcode
, 10, 4);
25389 XRa
= extract32(ctx
->opcode
, 6, 4);
25391 if (unlikely(pad
!= 0)) {
25392 /* opcode padding incorrect -> do nothing */
25393 } else if (unlikely(XRa
== 0)) {
25394 /* destination is zero register -> do nothing */
25395 } else if (unlikely((XRb
== 0) || (XRc
== 0))) {
25396 /* one of operands zero register -> just set destination to all 0s */
25397 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0);
25398 } else if (unlikely(XRb
== XRc
)) {
25399 /* both operands same -> just set destination to one of them */
25400 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25402 /* the most general case */
25403 tcg_gen_and_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1], mxu_gpr
[XRc
- 1]);
25408 * S32OR XRa, XRb, XRc
25409 * Update XRa with the result of logical bitwise 'or' operation
25410 * applied to the content of XRb and XRc.
25412 * 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
25413 * +-----------+---------+-----+-------+-------+-------+-----------+
25414 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL16|
25415 * +-----------+---------+-----+-------+-------+-------+-----------+
25417 static void gen_mxu_S32OR(DisasContext
*ctx
)
25419 uint32_t pad
, XRc
, XRb
, XRa
;
25421 pad
= extract32(ctx
->opcode
, 21, 5);
25422 XRc
= extract32(ctx
->opcode
, 14, 4);
25423 XRb
= extract32(ctx
->opcode
, 10, 4);
25424 XRa
= extract32(ctx
->opcode
, 6, 4);
25426 if (unlikely(pad
!= 0)) {
25427 /* opcode padding incorrect -> do nothing */
25428 } else if (unlikely(XRa
== 0)) {
25429 /* destination is zero register -> do nothing */
25430 } else if (unlikely((XRb
== 0) && (XRc
== 0))) {
25431 /* both operands zero registers -> just set destination to all 0s */
25432 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0);
25433 } else if (unlikely(XRb
== 0)) {
25434 /* XRb zero register -> just set destination to the content of XRc */
25435 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRc
- 1]);
25436 } else if (unlikely(XRc
== 0)) {
25437 /* XRc zero register -> just set destination to the content of XRb */
25438 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25439 } else if (unlikely(XRb
== XRc
)) {
25440 /* both operands same -> just set destination to one of them */
25441 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25443 /* the most general case */
25444 tcg_gen_or_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1], mxu_gpr
[XRc
- 1]);
25449 * S32XOR XRa, XRb, XRc
25450 * Update XRa with the result of logical bitwise 'xor' operation
25451 * applied to the content of XRb and XRc.
25453 * 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
25454 * +-----------+---------+-----+-------+-------+-------+-----------+
25455 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL16|
25456 * +-----------+---------+-----+-------+-------+-------+-----------+
25458 static void gen_mxu_S32XOR(DisasContext
*ctx
)
25460 uint32_t pad
, XRc
, XRb
, XRa
;
25462 pad
= extract32(ctx
->opcode
, 21, 5);
25463 XRc
= extract32(ctx
->opcode
, 14, 4);
25464 XRb
= extract32(ctx
->opcode
, 10, 4);
25465 XRa
= extract32(ctx
->opcode
, 6, 4);
25467 if (unlikely(pad
!= 0)) {
25468 /* opcode padding incorrect -> do nothing */
25469 } else if (unlikely(XRa
== 0)) {
25470 /* destination is zero register -> do nothing */
25471 } else if (unlikely((XRb
== 0) && (XRc
== 0))) {
25472 /* both operands zero registers -> just set destination to all 0s */
25473 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0);
25474 } else if (unlikely(XRb
== 0)) {
25475 /* XRb zero register -> just set destination to the content of XRc */
25476 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRc
- 1]);
25477 } else if (unlikely(XRc
== 0)) {
25478 /* XRc zero register -> just set destination to the content of XRb */
25479 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25480 } else if (unlikely(XRb
== XRc
)) {
25481 /* both operands same -> just set destination to all 0s */
25482 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0);
25484 /* the most general case */
25485 tcg_gen_xor_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1], mxu_gpr
[XRc
- 1]);
25491 * MXU instruction category max/min
25492 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
25494 * S32MAX D16MAX Q8MAX
25495 * S32MIN D16MIN Q8MIN
25499 * S32MAX XRa, XRb, XRc
25500 * Update XRa with the maximum of signed 32-bit integers contained
25503 * S32MIN XRa, XRb, XRc
25504 * Update XRa with the minimum of signed 32-bit integers contained
25507 * 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
25508 * +-----------+---------+-----+-------+-------+-------+-----------+
25509 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL00|
25510 * +-----------+---------+-----+-------+-------+-------+-----------+
25512 static void gen_mxu_S32MAX_S32MIN(DisasContext
*ctx
)
25514 uint32_t pad
, opc
, XRc
, XRb
, XRa
;
25516 pad
= extract32(ctx
->opcode
, 21, 5);
25517 opc
= extract32(ctx
->opcode
, 18, 3);
25518 XRc
= extract32(ctx
->opcode
, 14, 4);
25519 XRb
= extract32(ctx
->opcode
, 10, 4);
25520 XRa
= extract32(ctx
->opcode
, 6, 4);
25522 if (unlikely(pad
!= 0)) {
25523 /* opcode padding incorrect -> do nothing */
25524 } else if (unlikely(XRa
== 0)) {
25525 /* destination is zero register -> do nothing */
25526 } else if (unlikely((XRb
== 0) && (XRc
== 0))) {
25527 /* both operands zero registers -> just set destination to zero */
25528 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0);
25529 } else if (unlikely((XRb
== 0) || (XRc
== 0))) {
25530 /* exactly one operand is zero register - find which one is not...*/
25531 uint32_t XRx
= XRb
? XRb
: XRc
;
25532 /* ...and do max/min operation with one operand 0 */
25533 if (opc
== OPC_MXU_S32MAX
) {
25534 tcg_gen_smax_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRx
- 1], 0);
25536 tcg_gen_smin_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRx
- 1], 0);
25538 } else if (unlikely(XRb
== XRc
)) {
25539 /* both operands same -> just set destination to one of them */
25540 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25542 /* the most general case */
25543 if (opc
== OPC_MXU_S32MAX
) {
25544 tcg_gen_smax_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1],
25547 tcg_gen_smin_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1],
25555 * Update XRa with the 16-bit-wise maximums of signed integers
25556 * contained in XRb and XRc.
25559 * Update XRa with the 16-bit-wise minimums of signed integers
25560 * contained in XRb and XRc.
25562 * 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
25563 * +-----------+---------+-----+-------+-------+-------+-----------+
25564 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL00|
25565 * +-----------+---------+-----+-------+-------+-------+-----------+
25567 static void gen_mxu_D16MAX_D16MIN(DisasContext
*ctx
)
25569 uint32_t pad
, opc
, XRc
, XRb
, XRa
;
25571 pad
= extract32(ctx
->opcode
, 21, 5);
25572 opc
= extract32(ctx
->opcode
, 18, 3);
25573 XRc
= extract32(ctx
->opcode
, 14, 4);
25574 XRb
= extract32(ctx
->opcode
, 10, 4);
25575 XRa
= extract32(ctx
->opcode
, 6, 4);
25577 if (unlikely(pad
!= 0)) {
25578 /* opcode padding incorrect -> do nothing */
25579 } else if (unlikely(XRc
== 0)) {
25580 /* destination is zero register -> do nothing */
25581 } else if (unlikely((XRb
== 0) && (XRa
== 0))) {
25582 /* both operands zero registers -> just set destination to zero */
25583 tcg_gen_movi_i32(mxu_gpr
[XRc
- 1], 0);
25584 } else if (unlikely((XRb
== 0) || (XRa
== 0))) {
25585 /* exactly one operand is zero register - find which one is not...*/
25586 uint32_t XRx
= XRb
? XRb
: XRc
;
25587 /* ...and do half-word-wise max/min with one operand 0 */
25588 TCGv_i32 t0
= tcg_temp_new();
25589 TCGv_i32 t1
= tcg_const_i32(0);
25591 /* the left half-word first */
25592 tcg_gen_andi_i32(t0
, mxu_gpr
[XRx
- 1], 0xFFFF0000);
25593 if (opc
== OPC_MXU_D16MAX
) {
25594 tcg_gen_smax_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
25596 tcg_gen_smin_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
25599 /* the right half-word */
25600 tcg_gen_andi_i32(t0
, mxu_gpr
[XRx
- 1], 0x0000FFFF);
25601 /* move half-words to the leftmost position */
25602 tcg_gen_shli_i32(t0
, t0
, 16);
25603 /* t0 will be max/min of t0 and t1 */
25604 if (opc
== OPC_MXU_D16MAX
) {
25605 tcg_gen_smax_i32(t0
, t0
, t1
);
25607 tcg_gen_smin_i32(t0
, t0
, t1
);
25609 /* return resulting half-words to its original position */
25610 tcg_gen_shri_i32(t0
, t0
, 16);
25611 /* finally update the destination */
25612 tcg_gen_or_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRa
- 1], t0
);
25616 } else if (unlikely(XRb
== XRc
)) {
25617 /* both operands same -> just set destination to one of them */
25618 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25620 /* the most general case */
25621 TCGv_i32 t0
= tcg_temp_new();
25622 TCGv_i32 t1
= tcg_temp_new();
25624 /* the left half-word first */
25625 tcg_gen_andi_i32(t0
, mxu_gpr
[XRb
- 1], 0xFFFF0000);
25626 tcg_gen_andi_i32(t1
, mxu_gpr
[XRc
- 1], 0xFFFF0000);
25627 if (opc
== OPC_MXU_D16MAX
) {
25628 tcg_gen_smax_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
25630 tcg_gen_smin_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
25633 /* the right half-word */
25634 tcg_gen_andi_i32(t0
, mxu_gpr
[XRb
- 1], 0x0000FFFF);
25635 tcg_gen_andi_i32(t1
, mxu_gpr
[XRc
- 1], 0x0000FFFF);
25636 /* move half-words to the leftmost position */
25637 tcg_gen_shli_i32(t0
, t0
, 16);
25638 tcg_gen_shli_i32(t1
, t1
, 16);
25639 /* t0 will be max/min of t0 and t1 */
25640 if (opc
== OPC_MXU_D16MAX
) {
25641 tcg_gen_smax_i32(t0
, t0
, t1
);
25643 tcg_gen_smin_i32(t0
, t0
, t1
);
25645 /* return resulting half-words to its original position */
25646 tcg_gen_shri_i32(t0
, t0
, 16);
25647 /* finally update the destination */
25648 tcg_gen_or_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRa
- 1], t0
);
25657 * Update XRa with the 8-bit-wise maximums of signed integers
25658 * contained in XRb and XRc.
25661 * Update XRa with the 8-bit-wise minimums of signed integers
25662 * contained in XRb and XRc.
25664 * 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
25665 * +-----------+---------+-----+-------+-------+-------+-----------+
25666 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL00|
25667 * +-----------+---------+-----+-------+-------+-------+-----------+
25669 static void gen_mxu_Q8MAX_Q8MIN(DisasContext
*ctx
)
25671 uint32_t pad
, opc
, XRc
, XRb
, XRa
;
25673 pad
= extract32(ctx
->opcode
, 21, 5);
25674 opc
= extract32(ctx
->opcode
, 18, 3);
25675 XRc
= extract32(ctx
->opcode
, 14, 4);
25676 XRb
= extract32(ctx
->opcode
, 10, 4);
25677 XRa
= extract32(ctx
->opcode
, 6, 4);
25679 if (unlikely(pad
!= 0)) {
25680 /* opcode padding incorrect -> do nothing */
25681 } else if (unlikely(XRa
== 0)) {
25682 /* destination is zero register -> do nothing */
25683 } else if (unlikely((XRb
== 0) && (XRc
== 0))) {
25684 /* both operands zero registers -> just set destination to zero */
25685 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0);
25686 } else if (unlikely((XRb
== 0) || (XRc
== 0))) {
25687 /* exactly one operand is zero register - make it be the first...*/
25688 uint32_t XRx
= XRb
? XRb
: XRc
;
25689 /* ...and do byte-wise max/min with one operand 0 */
25690 TCGv_i32 t0
= tcg_temp_new();
25691 TCGv_i32 t1
= tcg_const_i32(0);
25694 /* the leftmost byte (byte 3) first */
25695 tcg_gen_andi_i32(t0
, mxu_gpr
[XRx
- 1], 0xFF000000);
25696 if (opc
== OPC_MXU_Q8MAX
) {
25697 tcg_gen_smax_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
25699 tcg_gen_smin_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
25702 /* bytes 2, 1, 0 */
25703 for (i
= 2; i
>= 0; i
--) {
25704 /* extract the byte */
25705 tcg_gen_andi_i32(t0
, mxu_gpr
[XRx
- 1], 0xFF << (8 * i
));
25706 /* move the byte to the leftmost position */
25707 tcg_gen_shli_i32(t0
, t0
, 8 * (3 - i
));
25708 /* t0 will be max/min of t0 and t1 */
25709 if (opc
== OPC_MXU_Q8MAX
) {
25710 tcg_gen_smax_i32(t0
, t0
, t1
);
25712 tcg_gen_smin_i32(t0
, t0
, t1
);
25714 /* return resulting byte to its original position */
25715 tcg_gen_shri_i32(t0
, t0
, 8 * (3 - i
));
25716 /* finally update the destination */
25717 tcg_gen_or_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRa
- 1], t0
);
25722 } else if (unlikely(XRb
== XRc
)) {
25723 /* both operands same -> just set destination to one of them */
25724 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25726 /* the most general case */
25727 TCGv_i32 t0
= tcg_temp_new();
25728 TCGv_i32 t1
= tcg_temp_new();
25731 /* the leftmost bytes (bytes 3) first */
25732 tcg_gen_andi_i32(t0
, mxu_gpr
[XRb
- 1], 0xFF000000);
25733 tcg_gen_andi_i32(t1
, mxu_gpr
[XRc
- 1], 0xFF000000);
25734 if (opc
== OPC_MXU_Q8MAX
) {
25735 tcg_gen_smax_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
25737 tcg_gen_smin_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
25740 /* bytes 2, 1, 0 */
25741 for (i
= 2; i
>= 0; i
--) {
25742 /* extract corresponding bytes */
25743 tcg_gen_andi_i32(t0
, mxu_gpr
[XRb
- 1], 0xFF << (8 * i
));
25744 tcg_gen_andi_i32(t1
, mxu_gpr
[XRc
- 1], 0xFF << (8 * i
));
25745 /* move the bytes to the leftmost position */
25746 tcg_gen_shli_i32(t0
, t0
, 8 * (3 - i
));
25747 tcg_gen_shli_i32(t1
, t1
, 8 * (3 - i
));
25748 /* t0 will be max/min of t0 and t1 */
25749 if (opc
== OPC_MXU_Q8MAX
) {
25750 tcg_gen_smax_i32(t0
, t0
, t1
);
25752 tcg_gen_smin_i32(t0
, t0
, t1
);
25754 /* return resulting byte to its original position */
25755 tcg_gen_shri_i32(t0
, t0
, 8 * (3 - i
));
25756 /* finally update the destination */
25757 tcg_gen_or_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRa
- 1], t0
);
25767 * MXU instruction category: align
25768 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
25774 * S32ALNI XRc, XRb, XRa, optn3
25775 * Arrange bytes from XRb and XRc according to one of five sets of
25776 * rules determined by optn3, and place the result in XRa.
25778 * 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
25779 * +-----------+-----+---+-----+-------+-------+-------+-----------+
25780 * | SPECIAL2 |optn3|0 0|x x x| XRc | XRb | XRa |MXU__POOL16|
25781 * +-----------+-----+---+-----+-------+-------+-------+-----------+
25784 static void gen_mxu_S32ALNI(DisasContext
*ctx
)
25786 uint32_t optn3
, pad
, XRc
, XRb
, XRa
;
25788 optn3
= extract32(ctx
->opcode
, 23, 3);
25789 pad
= extract32(ctx
->opcode
, 21, 2);
25790 XRc
= extract32(ctx
->opcode
, 14, 4);
25791 XRb
= extract32(ctx
->opcode
, 10, 4);
25792 XRa
= extract32(ctx
->opcode
, 6, 4);
25794 if (unlikely(pad
!= 0)) {
25795 /* opcode padding incorrect -> do nothing */
25796 } else if (unlikely(XRa
== 0)) {
25797 /* destination is zero register -> do nothing */
25798 } else if (unlikely((XRb
== 0) && (XRc
== 0))) {
25799 /* both operands zero registers -> just set destination to all 0s */
25800 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0);
25801 } else if (unlikely(XRb
== 0)) {
25802 /* XRb zero register -> just appropriatelly shift XRc into XRa */
25804 case MXU_OPTN3_PTN0
:
25805 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0);
25807 case MXU_OPTN3_PTN1
:
25808 case MXU_OPTN3_PTN2
:
25809 case MXU_OPTN3_PTN3
:
25810 tcg_gen_shri_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRc
- 1],
25813 case MXU_OPTN3_PTN4
:
25814 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRc
- 1]);
25817 } else if (unlikely(XRc
== 0)) {
25818 /* XRc zero register -> just appropriatelly shift XRb into XRa */
25820 case MXU_OPTN3_PTN0
:
25821 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25823 case MXU_OPTN3_PTN1
:
25824 case MXU_OPTN3_PTN2
:
25825 case MXU_OPTN3_PTN3
:
25826 tcg_gen_shri_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1], 8 * optn3
);
25828 case MXU_OPTN3_PTN4
:
25829 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0);
25832 } else if (unlikely(XRb
== XRc
)) {
25833 /* both operands same -> just rotation or moving from any of them */
25835 case MXU_OPTN3_PTN0
:
25836 case MXU_OPTN3_PTN4
:
25837 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25839 case MXU_OPTN3_PTN1
:
25840 case MXU_OPTN3_PTN2
:
25841 case MXU_OPTN3_PTN3
:
25842 tcg_gen_rotli_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1], 8 * optn3
);
25846 /* the most general case */
25848 case MXU_OPTN3_PTN0
:
25852 /* +---------------+ */
25853 /* | A B C D | E F G H */
25854 /* +-------+-------+ */
25859 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25862 case MXU_OPTN3_PTN1
:
25866 /* +-------------------+ */
25867 /* A | B C D E | F G H */
25868 /* +---------+---------+ */
25873 TCGv_i32 t0
= tcg_temp_new();
25874 TCGv_i32 t1
= tcg_temp_new();
25876 tcg_gen_andi_i32(t0
, mxu_gpr
[XRb
- 1], 0x00FFFFFF);
25877 tcg_gen_shli_i32(t0
, t0
, 8);
25879 tcg_gen_andi_i32(t1
, mxu_gpr
[XRc
- 1], 0xFF000000);
25880 tcg_gen_shri_i32(t1
, t1
, 24);
25882 tcg_gen_or_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
25888 case MXU_OPTN3_PTN2
:
25892 /* +-------------------+ */
25893 /* A B | C D E F | G H */
25894 /* +---------+---------+ */
25899 TCGv_i32 t0
= tcg_temp_new();
25900 TCGv_i32 t1
= tcg_temp_new();
25902 tcg_gen_andi_i32(t0
, mxu_gpr
[XRb
- 1], 0x0000FFFF);
25903 tcg_gen_shli_i32(t0
, t0
, 16);
25905 tcg_gen_andi_i32(t1
, mxu_gpr
[XRc
- 1], 0xFFFF0000);
25906 tcg_gen_shri_i32(t1
, t1
, 16);
25908 tcg_gen_or_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
25914 case MXU_OPTN3_PTN3
:
25918 /* +-------------------+ */
25919 /* A B C | D E F G | H */
25920 /* +---------+---------+ */
25925 TCGv_i32 t0
= tcg_temp_new();
25926 TCGv_i32 t1
= tcg_temp_new();
25928 tcg_gen_andi_i32(t0
, mxu_gpr
[XRb
- 1], 0x000000FF);
25929 tcg_gen_shli_i32(t0
, t0
, 24);
25931 tcg_gen_andi_i32(t1
, mxu_gpr
[XRc
- 1], 0xFFFFFF00);
25932 tcg_gen_shri_i32(t1
, t1
, 8);
25934 tcg_gen_or_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
25940 case MXU_OPTN3_PTN4
:
25944 /* +---------------+ */
25945 /* A B C D | E F G H | */
25946 /* +-------+-------+ */
25951 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRc
- 1]);
25960 * Decoding engine for MXU
25961 * =======================
25966 * Decode MXU pool00
25968 * 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
25969 * +-----------+---------+-----+-------+-------+-------+-----------+
25970 * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL00|
25971 * +-----------+---------+-----+-------+-------+-------+-----------+
25974 static void decode_opc_mxu__pool00(CPUMIPSState
*env
, DisasContext
*ctx
)
25976 uint32_t opcode
= extract32(ctx
->opcode
, 18, 3);
25979 case OPC_MXU_S32MAX
:
25980 case OPC_MXU_S32MIN
:
25981 gen_mxu_S32MAX_S32MIN(ctx
);
25983 case OPC_MXU_D16MAX
:
25984 case OPC_MXU_D16MIN
:
25985 gen_mxu_D16MAX_D16MIN(ctx
);
25987 case OPC_MXU_Q8MAX
:
25988 case OPC_MXU_Q8MIN
:
25989 gen_mxu_Q8MAX_Q8MIN(ctx
);
25991 case OPC_MXU_Q8SLT
:
25992 /* TODO: Implement emulation of Q8SLT instruction. */
25993 MIPS_INVAL("OPC_MXU_Q8SLT");
25994 gen_reserved_instruction(ctx
);
25996 case OPC_MXU_Q8SLTU
:
25997 /* TODO: Implement emulation of Q8SLTU instruction. */
25998 MIPS_INVAL("OPC_MXU_Q8SLTU");
25999 gen_reserved_instruction(ctx
);
26002 MIPS_INVAL("decode_opc_mxu");
26003 gen_reserved_instruction(ctx
);
26010 * Decode MXU pool01
26012 * S32SLT, D16SLT, D16AVG, D16AVGR, Q8AVG, Q8AVGR:
26013 * 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
26014 * +-----------+---------+-----+-------+-------+-------+-----------+
26015 * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL01|
26016 * +-----------+---------+-----+-------+-------+-------+-----------+
26019 * 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
26020 * +-----------+---+-----+-----+-------+-------+-------+-----------+
26021 * | SPECIAL2 |en2|0 0 0|x x x| XRc | XRb | XRa |MXU__POOL01|
26022 * +-----------+---+-----+-----+-------+-------+-------+-----------+
26025 static void decode_opc_mxu__pool01(CPUMIPSState
*env
, DisasContext
*ctx
)
26027 uint32_t opcode
= extract32(ctx
->opcode
, 18, 3);
26030 case OPC_MXU_S32SLT
:
26031 /* TODO: Implement emulation of S32SLT instruction. */
26032 MIPS_INVAL("OPC_MXU_S32SLT");
26033 gen_reserved_instruction(ctx
);
26035 case OPC_MXU_D16SLT
:
26036 /* TODO: Implement emulation of D16SLT instruction. */
26037 MIPS_INVAL("OPC_MXU_D16SLT");
26038 gen_reserved_instruction(ctx
);
26040 case OPC_MXU_D16AVG
:
26041 /* TODO: Implement emulation of D16AVG instruction. */
26042 MIPS_INVAL("OPC_MXU_D16AVG");
26043 gen_reserved_instruction(ctx
);
26045 case OPC_MXU_D16AVGR
:
26046 /* TODO: Implement emulation of D16AVGR instruction. */
26047 MIPS_INVAL("OPC_MXU_D16AVGR");
26048 gen_reserved_instruction(ctx
);
26050 case OPC_MXU_Q8AVG
:
26051 /* TODO: Implement emulation of Q8AVG instruction. */
26052 MIPS_INVAL("OPC_MXU_Q8AVG");
26053 gen_reserved_instruction(ctx
);
26055 case OPC_MXU_Q8AVGR
:
26056 /* TODO: Implement emulation of Q8AVGR instruction. */
26057 MIPS_INVAL("OPC_MXU_Q8AVGR");
26058 gen_reserved_instruction(ctx
);
26060 case OPC_MXU_Q8ADD
:
26061 /* TODO: Implement emulation of Q8ADD instruction. */
26062 MIPS_INVAL("OPC_MXU_Q8ADD");
26063 gen_reserved_instruction(ctx
);
26066 MIPS_INVAL("decode_opc_mxu");
26067 gen_reserved_instruction(ctx
);
26074 * Decode MXU pool02
26076 * 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
26077 * +-----------+---------+-----+-------+-------+-------+-----------+
26078 * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL02|
26079 * +-----------+---------+-----+-------+-------+-------+-----------+
26082 static void decode_opc_mxu__pool02(CPUMIPSState
*env
, DisasContext
*ctx
)
26084 uint32_t opcode
= extract32(ctx
->opcode
, 18, 3);
26087 case OPC_MXU_S32CPS
:
26088 /* TODO: Implement emulation of S32CPS instruction. */
26089 MIPS_INVAL("OPC_MXU_S32CPS");
26090 gen_reserved_instruction(ctx
);
26092 case OPC_MXU_D16CPS
:
26093 /* TODO: Implement emulation of D16CPS instruction. */
26094 MIPS_INVAL("OPC_MXU_D16CPS");
26095 gen_reserved_instruction(ctx
);
26097 case OPC_MXU_Q8ABD
:
26098 /* TODO: Implement emulation of Q8ABD instruction. */
26099 MIPS_INVAL("OPC_MXU_Q8ABD");
26100 gen_reserved_instruction(ctx
);
26102 case OPC_MXU_Q16SAT
:
26103 /* TODO: Implement emulation of Q16SAT instruction. */
26104 MIPS_INVAL("OPC_MXU_Q16SAT");
26105 gen_reserved_instruction(ctx
);
26108 MIPS_INVAL("decode_opc_mxu");
26109 gen_reserved_instruction(ctx
);
26116 * Decode MXU pool03
26119 * 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
26120 * +-----------+---+---+-------+-------+-------+-------+-----------+
26121 * | SPECIAL2 |x x|on2|0 0 0 0| XRc | XRb | XRa |MXU__POOL03|
26122 * +-----------+---+---+-------+-------+-------+-------+-----------+
26125 * 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
26126 * +-----------+---+---+-------+-------+-------+-------+-----------+
26127 * | SPECIAL2 |x x|on2| Xd | XRc | XRb | XRa |MXU__POOL03|
26128 * +-----------+---+---+-------+-------+-------+-------+-----------+
26131 static void decode_opc_mxu__pool03(CPUMIPSState
*env
, DisasContext
*ctx
)
26133 uint32_t opcode
= extract32(ctx
->opcode
, 24, 2);
26136 case OPC_MXU_D16MULF
:
26137 /* TODO: Implement emulation of D16MULF instruction. */
26138 MIPS_INVAL("OPC_MXU_D16MULF");
26139 gen_reserved_instruction(ctx
);
26141 case OPC_MXU_D16MULE
:
26142 /* TODO: Implement emulation of D16MULE instruction. */
26143 MIPS_INVAL("OPC_MXU_D16MULE");
26144 gen_reserved_instruction(ctx
);
26147 MIPS_INVAL("decode_opc_mxu");
26148 gen_reserved_instruction(ctx
);
26155 * Decode MXU pool04
26157 * 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
26158 * +-----------+---------+-+-------------------+-------+-----------+
26159 * | SPECIAL2 | rb |x| s12 | XRa |MXU__POOL04|
26160 * +-----------+---------+-+-------------------+-------+-----------+
26163 static void decode_opc_mxu__pool04(CPUMIPSState
*env
, DisasContext
*ctx
)
26165 uint32_t opcode
= extract32(ctx
->opcode
, 20, 1);
26168 case OPC_MXU_S32LDD
:
26169 case OPC_MXU_S32LDDR
:
26170 gen_mxu_s32ldd_s32lddr(ctx
);
26173 MIPS_INVAL("decode_opc_mxu");
26174 gen_reserved_instruction(ctx
);
26181 * Decode MXU pool05
26183 * 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
26184 * +-----------+---------+-+-------------------+-------+-----------+
26185 * | SPECIAL2 | rb |x| s12 | XRa |MXU__POOL05|
26186 * +-----------+---------+-+-------------------+-------+-----------+
26189 static void decode_opc_mxu__pool05(CPUMIPSState
*env
, DisasContext
*ctx
)
26191 uint32_t opcode
= extract32(ctx
->opcode
, 20, 1);
26194 case OPC_MXU_S32STD
:
26195 /* TODO: Implement emulation of S32STD instruction. */
26196 MIPS_INVAL("OPC_MXU_S32STD");
26197 gen_reserved_instruction(ctx
);
26199 case OPC_MXU_S32STDR
:
26200 /* TODO: Implement emulation of S32STDR instruction. */
26201 MIPS_INVAL("OPC_MXU_S32STDR");
26202 gen_reserved_instruction(ctx
);
26205 MIPS_INVAL("decode_opc_mxu");
26206 gen_reserved_instruction(ctx
);
26213 * Decode MXU pool06
26215 * 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
26216 * +-----------+---------+---------+---+-------+-------+-----------+
26217 * | SPECIAL2 | rb | rc |st2|x x x x| XRa |MXU__POOL06|
26218 * +-----------+---------+---------+---+-------+-------+-----------+
26221 static void decode_opc_mxu__pool06(CPUMIPSState
*env
, DisasContext
*ctx
)
26223 uint32_t opcode
= extract32(ctx
->opcode
, 10, 4);
26226 case OPC_MXU_S32LDDV
:
26227 /* TODO: Implement emulation of S32LDDV instruction. */
26228 MIPS_INVAL("OPC_MXU_S32LDDV");
26229 gen_reserved_instruction(ctx
);
26231 case OPC_MXU_S32LDDVR
:
26232 /* TODO: Implement emulation of S32LDDVR instruction. */
26233 MIPS_INVAL("OPC_MXU_S32LDDVR");
26234 gen_reserved_instruction(ctx
);
26237 MIPS_INVAL("decode_opc_mxu");
26238 gen_reserved_instruction(ctx
);
26245 * Decode MXU pool07
26247 * 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
26248 * +-----------+---------+---------+---+-------+-------+-----------+
26249 * | SPECIAL2 | rb | rc |st2|x x x x| XRa |MXU__POOL07|
26250 * +-----------+---------+---------+---+-------+-------+-----------+
26253 static void decode_opc_mxu__pool07(CPUMIPSState
*env
, DisasContext
*ctx
)
26255 uint32_t opcode
= extract32(ctx
->opcode
, 10, 4);
26258 case OPC_MXU_S32STDV
:
26259 /* TODO: Implement emulation of S32TDV instruction. */
26260 MIPS_INVAL("OPC_MXU_S32TDV");
26261 gen_reserved_instruction(ctx
);
26263 case OPC_MXU_S32STDVR
:
26264 /* TODO: Implement emulation of S32TDVR instruction. */
26265 MIPS_INVAL("OPC_MXU_S32TDVR");
26266 gen_reserved_instruction(ctx
);
26269 MIPS_INVAL("decode_opc_mxu");
26270 gen_reserved_instruction(ctx
);
26277 * Decode MXU pool08
26279 * 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
26280 * +-----------+---------+-+-------------------+-------+-----------+
26281 * | SPECIAL2 | rb |x| s12 | XRa |MXU__POOL08|
26282 * +-----------+---------+-+-------------------+-------+-----------+
26285 static void decode_opc_mxu__pool08(CPUMIPSState
*env
, DisasContext
*ctx
)
26287 uint32_t opcode
= extract32(ctx
->opcode
, 20, 1);
26290 case OPC_MXU_S32LDI
:
26291 /* TODO: Implement emulation of S32LDI instruction. */
26292 MIPS_INVAL("OPC_MXU_S32LDI");
26293 gen_reserved_instruction(ctx
);
26295 case OPC_MXU_S32LDIR
:
26296 /* TODO: Implement emulation of S32LDIR instruction. */
26297 MIPS_INVAL("OPC_MXU_S32LDIR");
26298 gen_reserved_instruction(ctx
);
26301 MIPS_INVAL("decode_opc_mxu");
26302 gen_reserved_instruction(ctx
);
26309 * Decode MXU pool09
26311 * 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
26312 * +-----------+---------+-+-------------------+-------+-----------+
26313 * | SPECIAL2 | rb |x| s12 | XRa |MXU__POOL09|
26314 * +-----------+---------+-+-------------------+-------+-----------+
26317 static void decode_opc_mxu__pool09(CPUMIPSState
*env
, DisasContext
*ctx
)
26319 uint32_t opcode
= extract32(ctx
->opcode
, 5, 0);
26322 case OPC_MXU_S32SDI
:
26323 /* TODO: Implement emulation of S32SDI instruction. */
26324 MIPS_INVAL("OPC_MXU_S32SDI");
26325 gen_reserved_instruction(ctx
);
26327 case OPC_MXU_S32SDIR
:
26328 /* TODO: Implement emulation of S32SDIR instruction. */
26329 MIPS_INVAL("OPC_MXU_S32SDIR");
26330 gen_reserved_instruction(ctx
);
26333 MIPS_INVAL("decode_opc_mxu");
26334 gen_reserved_instruction(ctx
);
26341 * Decode MXU pool10
26343 * 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
26344 * +-----------+---------+---------+---+-------+-------+-----------+
26345 * | SPECIAL2 | rb | rc |st2|x x x x| XRa |MXU__POOL10|
26346 * +-----------+---------+---------+---+-------+-------+-----------+
26349 static void decode_opc_mxu__pool10(CPUMIPSState
*env
, DisasContext
*ctx
)
26351 uint32_t opcode
= extract32(ctx
->opcode
, 5, 0);
26354 case OPC_MXU_S32LDIV
:
26355 /* TODO: Implement emulation of S32LDIV instruction. */
26356 MIPS_INVAL("OPC_MXU_S32LDIV");
26357 gen_reserved_instruction(ctx
);
26359 case OPC_MXU_S32LDIVR
:
26360 /* TODO: Implement emulation of S32LDIVR instruction. */
26361 MIPS_INVAL("OPC_MXU_S32LDIVR");
26362 gen_reserved_instruction(ctx
);
26365 MIPS_INVAL("decode_opc_mxu");
26366 gen_reserved_instruction(ctx
);
26373 * Decode MXU pool11
26375 * 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
26376 * +-----------+---------+---------+---+-------+-------+-----------+
26377 * | SPECIAL2 | rb | rc |st2|x x x x| XRa |MXU__POOL11|
26378 * +-----------+---------+---------+---+-------+-------+-----------+
26381 static void decode_opc_mxu__pool11(CPUMIPSState
*env
, DisasContext
*ctx
)
26383 uint32_t opcode
= extract32(ctx
->opcode
, 10, 4);
26386 case OPC_MXU_S32SDIV
:
26387 /* TODO: Implement emulation of S32SDIV instruction. */
26388 MIPS_INVAL("OPC_MXU_S32SDIV");
26389 gen_reserved_instruction(ctx
);
26391 case OPC_MXU_S32SDIVR
:
26392 /* TODO: Implement emulation of S32SDIVR instruction. */
26393 MIPS_INVAL("OPC_MXU_S32SDIVR");
26394 gen_reserved_instruction(ctx
);
26397 MIPS_INVAL("decode_opc_mxu");
26398 gen_reserved_instruction(ctx
);
26405 * Decode MXU pool12
26407 * 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
26408 * +-----------+---+---+-------+-------+-------+-------+-----------+
26409 * | SPECIAL2 |an2|x x| Xd | XRc | XRb | XRa |MXU__POOL12|
26410 * +-----------+---+---+-------+-------+-------+-------+-----------+
26413 static void decode_opc_mxu__pool12(CPUMIPSState
*env
, DisasContext
*ctx
)
26415 uint32_t opcode
= extract32(ctx
->opcode
, 22, 2);
26418 case OPC_MXU_D32ACC
:
26419 /* TODO: Implement emulation of D32ACC instruction. */
26420 MIPS_INVAL("OPC_MXU_D32ACC");
26421 gen_reserved_instruction(ctx
);
26423 case OPC_MXU_D32ACCM
:
26424 /* TODO: Implement emulation of D32ACCM instruction. */
26425 MIPS_INVAL("OPC_MXU_D32ACCM");
26426 gen_reserved_instruction(ctx
);
26428 case OPC_MXU_D32ASUM
:
26429 /* TODO: Implement emulation of D32ASUM instruction. */
26430 MIPS_INVAL("OPC_MXU_D32ASUM");
26431 gen_reserved_instruction(ctx
);
26434 MIPS_INVAL("decode_opc_mxu");
26435 gen_reserved_instruction(ctx
);
26442 * Decode MXU pool13
26444 * 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
26445 * +-----------+---+---+-------+-------+-------+-------+-----------+
26446 * | SPECIAL2 |en2|x x|0 0 0 0| XRc | XRb | XRa |MXU__POOL13|
26447 * +-----------+---+---+-------+-------+-------+-------+-----------+
26450 static void decode_opc_mxu__pool13(CPUMIPSState
*env
, DisasContext
*ctx
)
26452 uint32_t opcode
= extract32(ctx
->opcode
, 22, 2);
26455 case OPC_MXU_Q16ACC
:
26456 /* TODO: Implement emulation of Q16ACC instruction. */
26457 MIPS_INVAL("OPC_MXU_Q16ACC");
26458 gen_reserved_instruction(ctx
);
26460 case OPC_MXU_Q16ACCM
:
26461 /* TODO: Implement emulation of Q16ACCM instruction. */
26462 MIPS_INVAL("OPC_MXU_Q16ACCM");
26463 gen_reserved_instruction(ctx
);
26465 case OPC_MXU_Q16ASUM
:
26466 /* TODO: Implement emulation of Q16ASUM instruction. */
26467 MIPS_INVAL("OPC_MXU_Q16ASUM");
26468 gen_reserved_instruction(ctx
);
26471 MIPS_INVAL("decode_opc_mxu");
26472 gen_reserved_instruction(ctx
);
26479 * Decode MXU pool14
26482 * 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
26483 * +-----------+---+---+-------+-------+-------+-------+-----------+
26484 * | SPECIAL2 |0 0|x x| XRd | XRc | XRb | XRa |MXU__POOL14|
26485 * +-----------+---+---+-------+-------+-------+-------+-----------+
26488 * 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
26489 * +-----------+---+---+-------+-------+-------+-------+-----------+
26490 * | SPECIAL2 |en2|x x|0 0 0 0| XRc | XRb | XRa |MXU__POOL14|
26491 * +-----------+---+---+-------+-------+-------+-------+-----------+
26494 static void decode_opc_mxu__pool14(CPUMIPSState
*env
, DisasContext
*ctx
)
26496 uint32_t opcode
= extract32(ctx
->opcode
, 22, 2);
26499 case OPC_MXU_Q8ADDE
:
26500 /* TODO: Implement emulation of Q8ADDE instruction. */
26501 MIPS_INVAL("OPC_MXU_Q8ADDE");
26502 gen_reserved_instruction(ctx
);
26504 case OPC_MXU_D8SUM
:
26505 /* TODO: Implement emulation of D8SUM instruction. */
26506 MIPS_INVAL("OPC_MXU_D8SUM");
26507 gen_reserved_instruction(ctx
);
26509 case OPC_MXU_D8SUMC
:
26510 /* TODO: Implement emulation of D8SUMC instruction. */
26511 MIPS_INVAL("OPC_MXU_D8SUMC");
26512 gen_reserved_instruction(ctx
);
26515 MIPS_INVAL("decode_opc_mxu");
26516 gen_reserved_instruction(ctx
);
26523 * Decode MXU pool15
26525 * S32MUL, S32MULU, S32EXTRV:
26526 * 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
26527 * +-----------+---------+---------+---+-------+-------+-----------+
26528 * | SPECIAL2 | rs | rt |x x| XRd | XRa |MXU__POOL15|
26529 * +-----------+---------+---------+---+-------+-------+-----------+
26532 * 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
26533 * +-----------+---------+---------+---+-------+-------+-----------+
26534 * | SPECIAL2 | rb | sft5 |x x| XRd | XRa |MXU__POOL15|
26535 * +-----------+---------+---------+---+-------+-------+-----------+
26538 static void decode_opc_mxu__pool15(CPUMIPSState
*env
, DisasContext
*ctx
)
26540 uint32_t opcode
= extract32(ctx
->opcode
, 14, 2);
26543 case OPC_MXU_S32MUL
:
26544 /* TODO: Implement emulation of S32MUL instruction. */
26545 MIPS_INVAL("OPC_MXU_S32MUL");
26546 gen_reserved_instruction(ctx
);
26548 case OPC_MXU_S32MULU
:
26549 /* TODO: Implement emulation of S32MULU instruction. */
26550 MIPS_INVAL("OPC_MXU_S32MULU");
26551 gen_reserved_instruction(ctx
);
26553 case OPC_MXU_S32EXTR
:
26554 /* TODO: Implement emulation of S32EXTR instruction. */
26555 MIPS_INVAL("OPC_MXU_S32EXTR");
26556 gen_reserved_instruction(ctx
);
26558 case OPC_MXU_S32EXTRV
:
26559 /* TODO: Implement emulation of S32EXTRV instruction. */
26560 MIPS_INVAL("OPC_MXU_S32EXTRV");
26561 gen_reserved_instruction(ctx
);
26564 MIPS_INVAL("decode_opc_mxu");
26565 gen_reserved_instruction(ctx
);
26572 * Decode MXU pool16
26575 * 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
26576 * +-----------+---------+-----+-------+-------+-------+-----------+
26577 * | SPECIAL2 | rb |x x x| XRc | XRb | XRa |MXU__POOL16|
26578 * +-----------+---------+-----+-------+-------+-------+-----------+
26581 * 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
26582 * +-----------+---------+-----+-------+-------+-------+-----------+
26583 * | SPECIAL2 | rs |x x x| XRc | XRb | XRa |MXU__POOL16|
26584 * +-----------+---------+-----+-------+-------+-------+-----------+
26587 * 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
26588 * +-----------+-----+---+-----+-------+-------+-------+-----------+
26589 * | SPECIAL2 | s3 |0 0|x x x| XRc | XRb | XRa |MXU__POOL16|
26590 * +-----------+-----+---+-----+-------+-------+-------+-----------+
26593 * 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
26594 * +-----------+-----+---+-----+-------+---------------+-----------+
26595 * | SPECIAL2 |optn3|0 0|x x x| XRc | s8 |MXU__POOL16|
26596 * +-----------+-----+---+-----+-------+---------------+-----------+
26598 * S32NOR, S32AND, S32OR, S32XOR:
26599 * 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
26600 * +-----------+---------+-----+-------+-------+-------+-----------+
26601 * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL16|
26602 * +-----------+---------+-----+-------+-------+-------+-----------+
26605 static void decode_opc_mxu__pool16(CPUMIPSState
*env
, DisasContext
*ctx
)
26607 uint32_t opcode
= extract32(ctx
->opcode
, 18, 3);
26610 case OPC_MXU_D32SARW
:
26611 /* TODO: Implement emulation of D32SARW instruction. */
26612 MIPS_INVAL("OPC_MXU_D32SARW");
26613 gen_reserved_instruction(ctx
);
26615 case OPC_MXU_S32ALN
:
26616 /* TODO: Implement emulation of S32ALN instruction. */
26617 MIPS_INVAL("OPC_MXU_S32ALN");
26618 gen_reserved_instruction(ctx
);
26620 case OPC_MXU_S32ALNI
:
26621 gen_mxu_S32ALNI(ctx
);
26623 case OPC_MXU_S32LUI
:
26624 /* TODO: Implement emulation of S32LUI instruction. */
26625 MIPS_INVAL("OPC_MXU_S32LUI");
26626 gen_reserved_instruction(ctx
);
26628 case OPC_MXU_S32NOR
:
26629 gen_mxu_S32NOR(ctx
);
26631 case OPC_MXU_S32AND
:
26632 gen_mxu_S32AND(ctx
);
26634 case OPC_MXU_S32OR
:
26635 gen_mxu_S32OR(ctx
);
26637 case OPC_MXU_S32XOR
:
26638 gen_mxu_S32XOR(ctx
);
26641 MIPS_INVAL("decode_opc_mxu");
26642 gen_reserved_instruction(ctx
);
26649 * Decode MXU pool17
26651 * 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
26652 * +-----------+---------+---------+---+---------+-----+-----------+
26653 * | SPECIAL2 | rs | rt |0 0| rd |x x x|MXU__POOL15|
26654 * +-----------+---------+---------+---+---------+-----+-----------+
26657 static void decode_opc_mxu__pool17(CPUMIPSState
*env
, DisasContext
*ctx
)
26659 uint32_t opcode
= extract32(ctx
->opcode
, 6, 2);
26663 /* TODO: Implement emulation of LXW instruction. */
26664 MIPS_INVAL("OPC_MXU_LXW");
26665 gen_reserved_instruction(ctx
);
26668 /* TODO: Implement emulation of LXH instruction. */
26669 MIPS_INVAL("OPC_MXU_LXH");
26670 gen_reserved_instruction(ctx
);
26673 /* TODO: Implement emulation of LXHU instruction. */
26674 MIPS_INVAL("OPC_MXU_LXHU");
26675 gen_reserved_instruction(ctx
);
26678 /* TODO: Implement emulation of LXB instruction. */
26679 MIPS_INVAL("OPC_MXU_LXB");
26680 gen_reserved_instruction(ctx
);
26683 /* TODO: Implement emulation of LXBU instruction. */
26684 MIPS_INVAL("OPC_MXU_LXBU");
26685 gen_reserved_instruction(ctx
);
26688 MIPS_INVAL("decode_opc_mxu");
26689 gen_reserved_instruction(ctx
);
26695 * Decode MXU pool18
26697 * 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
26698 * +-----------+---------+-----+-------+-------+-------+-----------+
26699 * | SPECIAL2 | rb |x x x| XRd | XRa |0 0 0 0|MXU__POOL18|
26700 * +-----------+---------+-----+-------+-------+-------+-----------+
26703 static void decode_opc_mxu__pool18(CPUMIPSState
*env
, DisasContext
*ctx
)
26705 uint32_t opcode
= extract32(ctx
->opcode
, 18, 3);
26708 case OPC_MXU_D32SLLV
:
26709 /* TODO: Implement emulation of D32SLLV instruction. */
26710 MIPS_INVAL("OPC_MXU_D32SLLV");
26711 gen_reserved_instruction(ctx
);
26713 case OPC_MXU_D32SLRV
:
26714 /* TODO: Implement emulation of D32SLRV instruction. */
26715 MIPS_INVAL("OPC_MXU_D32SLRV");
26716 gen_reserved_instruction(ctx
);
26718 case OPC_MXU_D32SARV
:
26719 /* TODO: Implement emulation of D32SARV instruction. */
26720 MIPS_INVAL("OPC_MXU_D32SARV");
26721 gen_reserved_instruction(ctx
);
26723 case OPC_MXU_Q16SLLV
:
26724 /* TODO: Implement emulation of Q16SLLV instruction. */
26725 MIPS_INVAL("OPC_MXU_Q16SLLV");
26726 gen_reserved_instruction(ctx
);
26728 case OPC_MXU_Q16SLRV
:
26729 /* TODO: Implement emulation of Q16SLRV instruction. */
26730 MIPS_INVAL("OPC_MXU_Q16SLRV");
26731 gen_reserved_instruction(ctx
);
26733 case OPC_MXU_Q16SARV
:
26734 /* TODO: Implement emulation of Q16SARV instruction. */
26735 MIPS_INVAL("OPC_MXU_Q16SARV");
26736 gen_reserved_instruction(ctx
);
26739 MIPS_INVAL("decode_opc_mxu");
26740 gen_reserved_instruction(ctx
);
26747 * Decode MXU pool19
26749 * 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
26750 * +-----------+---+---+-------+-------+-------+-------+-----------+
26751 * | SPECIAL2 |0 0|x x| XRd | XRc | XRb | XRa |MXU__POOL19|
26752 * +-----------+---+---+-------+-------+-------+-------+-----------+
26755 static void decode_opc_mxu__pool19(CPUMIPSState
*env
, DisasContext
*ctx
)
26757 uint32_t opcode
= extract32(ctx
->opcode
, 22, 2);
26760 case OPC_MXU_Q8MUL
:
26761 case OPC_MXU_Q8MULSU
:
26762 gen_mxu_q8mul_q8mulsu(ctx
);
26765 MIPS_INVAL("decode_opc_mxu");
26766 gen_reserved_instruction(ctx
);
26773 * Decode MXU pool20
26775 * 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
26776 * +-----------+---------+-----+-------+-------+-------+-----------+
26777 * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL20|
26778 * +-----------+---------+-----+-------+-------+-------+-----------+
26781 static void decode_opc_mxu__pool20(CPUMIPSState
*env
, DisasContext
*ctx
)
26783 uint32_t opcode
= extract32(ctx
->opcode
, 18, 3);
26786 case OPC_MXU_Q8MOVZ
:
26787 /* TODO: Implement emulation of Q8MOVZ instruction. */
26788 MIPS_INVAL("OPC_MXU_Q8MOVZ");
26789 gen_reserved_instruction(ctx
);
26791 case OPC_MXU_Q8MOVN
:
26792 /* TODO: Implement emulation of Q8MOVN instruction. */
26793 MIPS_INVAL("OPC_MXU_Q8MOVN");
26794 gen_reserved_instruction(ctx
);
26796 case OPC_MXU_D16MOVZ
:
26797 /* TODO: Implement emulation of D16MOVZ instruction. */
26798 MIPS_INVAL("OPC_MXU_D16MOVZ");
26799 gen_reserved_instruction(ctx
);
26801 case OPC_MXU_D16MOVN
:
26802 /* TODO: Implement emulation of D16MOVN instruction. */
26803 MIPS_INVAL("OPC_MXU_D16MOVN");
26804 gen_reserved_instruction(ctx
);
26806 case OPC_MXU_S32MOVZ
:
26807 /* TODO: Implement emulation of S32MOVZ instruction. */
26808 MIPS_INVAL("OPC_MXU_S32MOVZ");
26809 gen_reserved_instruction(ctx
);
26811 case OPC_MXU_S32MOVN
:
26812 /* TODO: Implement emulation of S32MOVN instruction. */
26813 MIPS_INVAL("OPC_MXU_S32MOVN");
26814 gen_reserved_instruction(ctx
);
26817 MIPS_INVAL("decode_opc_mxu");
26818 gen_reserved_instruction(ctx
);
26825 * Decode MXU pool21
26827 * 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
26828 * +-----------+---+---+-------+-------+-------+-------+-----------+
26829 * | SPECIAL2 |an2|x x| XRd | XRc | XRb | XRa |MXU__POOL21|
26830 * +-----------+---+---+-------+-------+-------+-------+-----------+
26833 static void decode_opc_mxu__pool21(CPUMIPSState
*env
, DisasContext
*ctx
)
26835 uint32_t opcode
= extract32(ctx
->opcode
, 22, 2);
26838 case OPC_MXU_Q8MAC
:
26839 /* TODO: Implement emulation of Q8MAC instruction. */
26840 MIPS_INVAL("OPC_MXU_Q8MAC");
26841 gen_reserved_instruction(ctx
);
26843 case OPC_MXU_Q8MACSU
:
26844 /* TODO: Implement emulation of Q8MACSU instruction. */
26845 MIPS_INVAL("OPC_MXU_Q8MACSU");
26846 gen_reserved_instruction(ctx
);
26849 MIPS_INVAL("decode_opc_mxu");
26850 gen_reserved_instruction(ctx
);
26857 * Main MXU decoding function
26859 * 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
26860 * +-----------+---------------------------------------+-----------+
26861 * | SPECIAL2 | |x x x x x x|
26862 * +-----------+---------------------------------------+-----------+
26865 static void decode_opc_mxu(CPUMIPSState
*env
, DisasContext
*ctx
)
26868 * TODO: Investigate necessity of including handling of
26869 * CLZ, CLO, SDBB in this function, as they belong to
26870 * SPECIAL2 opcode space for regular pre-R6 MIPS ISAs.
26872 uint32_t opcode
= extract32(ctx
->opcode
, 0, 6);
26874 if (opcode
== OPC__MXU_MUL
) {
26875 uint32_t rs
, rt
, rd
, op1
;
26877 rs
= extract32(ctx
->opcode
, 21, 5);
26878 rt
= extract32(ctx
->opcode
, 16, 5);
26879 rd
= extract32(ctx
->opcode
, 11, 5);
26880 op1
= MASK_SPECIAL2(ctx
->opcode
);
26882 gen_arith(ctx
, op1
, rd
, rs
, rt
);
26887 if (opcode
== OPC_MXU_S32M2I
) {
26888 gen_mxu_s32m2i(ctx
);
26892 if (opcode
== OPC_MXU_S32I2M
) {
26893 gen_mxu_s32i2m(ctx
);
26898 TCGv t_mxu_cr
= tcg_temp_new();
26899 TCGLabel
*l_exit
= gen_new_label();
26901 gen_load_mxu_cr(t_mxu_cr
);
26902 tcg_gen_andi_tl(t_mxu_cr
, t_mxu_cr
, MXU_CR_MXU_EN
);
26903 tcg_gen_brcondi_tl(TCG_COND_NE
, t_mxu_cr
, MXU_CR_MXU_EN
, l_exit
);
26906 case OPC_MXU_S32MADD
:
26907 /* TODO: Implement emulation of S32MADD instruction. */
26908 MIPS_INVAL("OPC_MXU_S32MADD");
26909 gen_reserved_instruction(ctx
);
26911 case OPC_MXU_S32MADDU
:
26912 /* TODO: Implement emulation of S32MADDU instruction. */
26913 MIPS_INVAL("OPC_MXU_S32MADDU");
26914 gen_reserved_instruction(ctx
);
26916 case OPC_MXU__POOL00
:
26917 decode_opc_mxu__pool00(env
, ctx
);
26919 case OPC_MXU_S32MSUB
:
26920 /* TODO: Implement emulation of S32MSUB instruction. */
26921 MIPS_INVAL("OPC_MXU_S32MSUB");
26922 gen_reserved_instruction(ctx
);
26924 case OPC_MXU_S32MSUBU
:
26925 /* TODO: Implement emulation of S32MSUBU instruction. */
26926 MIPS_INVAL("OPC_MXU_S32MSUBU");
26927 gen_reserved_instruction(ctx
);
26929 case OPC_MXU__POOL01
:
26930 decode_opc_mxu__pool01(env
, ctx
);
26932 case OPC_MXU__POOL02
:
26933 decode_opc_mxu__pool02(env
, ctx
);
26935 case OPC_MXU_D16MUL
:
26936 gen_mxu_d16mul(ctx
);
26938 case OPC_MXU__POOL03
:
26939 decode_opc_mxu__pool03(env
, ctx
);
26941 case OPC_MXU_D16MAC
:
26942 gen_mxu_d16mac(ctx
);
26944 case OPC_MXU_D16MACF
:
26945 /* TODO: Implement emulation of D16MACF instruction. */
26946 MIPS_INVAL("OPC_MXU_D16MACF");
26947 gen_reserved_instruction(ctx
);
26949 case OPC_MXU_D16MADL
:
26950 /* TODO: Implement emulation of D16MADL instruction. */
26951 MIPS_INVAL("OPC_MXU_D16MADL");
26952 gen_reserved_instruction(ctx
);
26954 case OPC_MXU_S16MAD
:
26955 /* TODO: Implement emulation of S16MAD instruction. */
26956 MIPS_INVAL("OPC_MXU_S16MAD");
26957 gen_reserved_instruction(ctx
);
26959 case OPC_MXU_Q16ADD
:
26960 /* TODO: Implement emulation of Q16ADD instruction. */
26961 MIPS_INVAL("OPC_MXU_Q16ADD");
26962 gen_reserved_instruction(ctx
);
26964 case OPC_MXU_D16MACE
:
26965 /* TODO: Implement emulation of D16MACE instruction. */
26966 MIPS_INVAL("OPC_MXU_D16MACE");
26967 gen_reserved_instruction(ctx
);
26969 case OPC_MXU__POOL04
:
26970 decode_opc_mxu__pool04(env
, ctx
);
26972 case OPC_MXU__POOL05
:
26973 decode_opc_mxu__pool05(env
, ctx
);
26975 case OPC_MXU__POOL06
:
26976 decode_opc_mxu__pool06(env
, ctx
);
26978 case OPC_MXU__POOL07
:
26979 decode_opc_mxu__pool07(env
, ctx
);
26981 case OPC_MXU__POOL08
:
26982 decode_opc_mxu__pool08(env
, ctx
);
26984 case OPC_MXU__POOL09
:
26985 decode_opc_mxu__pool09(env
, ctx
);
26987 case OPC_MXU__POOL10
:
26988 decode_opc_mxu__pool10(env
, ctx
);
26990 case OPC_MXU__POOL11
:
26991 decode_opc_mxu__pool11(env
, ctx
);
26993 case OPC_MXU_D32ADD
:
26994 /* TODO: Implement emulation of D32ADD instruction. */
26995 MIPS_INVAL("OPC_MXU_D32ADD");
26996 gen_reserved_instruction(ctx
);
26998 case OPC_MXU__POOL12
:
26999 decode_opc_mxu__pool12(env
, ctx
);
27001 case OPC_MXU__POOL13
:
27002 decode_opc_mxu__pool13(env
, ctx
);
27004 case OPC_MXU__POOL14
:
27005 decode_opc_mxu__pool14(env
, ctx
);
27007 case OPC_MXU_Q8ACCE
:
27008 /* TODO: Implement emulation of Q8ACCE instruction. */
27009 MIPS_INVAL("OPC_MXU_Q8ACCE");
27010 gen_reserved_instruction(ctx
);
27012 case OPC_MXU_S8LDD
:
27013 gen_mxu_s8ldd(ctx
);
27015 case OPC_MXU_S8STD
:
27016 /* TODO: Implement emulation of S8STD instruction. */
27017 MIPS_INVAL("OPC_MXU_S8STD");
27018 gen_reserved_instruction(ctx
);
27020 case OPC_MXU_S8LDI
:
27021 /* TODO: Implement emulation of S8LDI instruction. */
27022 MIPS_INVAL("OPC_MXU_S8LDI");
27023 gen_reserved_instruction(ctx
);
27025 case OPC_MXU_S8SDI
:
27026 /* TODO: Implement emulation of S8SDI instruction. */
27027 MIPS_INVAL("OPC_MXU_S8SDI");
27028 gen_reserved_instruction(ctx
);
27030 case OPC_MXU__POOL15
:
27031 decode_opc_mxu__pool15(env
, ctx
);
27033 case OPC_MXU__POOL16
:
27034 decode_opc_mxu__pool16(env
, ctx
);
27036 case OPC_MXU__POOL17
:
27037 decode_opc_mxu__pool17(env
, ctx
);
27039 case OPC_MXU_S16LDD
:
27040 /* TODO: Implement emulation of S16LDD instruction. */
27041 MIPS_INVAL("OPC_MXU_S16LDD");
27042 gen_reserved_instruction(ctx
);
27044 case OPC_MXU_S16STD
:
27045 /* TODO: Implement emulation of S16STD instruction. */
27046 MIPS_INVAL("OPC_MXU_S16STD");
27047 gen_reserved_instruction(ctx
);
27049 case OPC_MXU_S16LDI
:
27050 /* TODO: Implement emulation of S16LDI instruction. */
27051 MIPS_INVAL("OPC_MXU_S16LDI");
27052 gen_reserved_instruction(ctx
);
27054 case OPC_MXU_S16SDI
:
27055 /* TODO: Implement emulation of S16SDI instruction. */
27056 MIPS_INVAL("OPC_MXU_S16SDI");
27057 gen_reserved_instruction(ctx
);
27059 case OPC_MXU_D32SLL
:
27060 /* TODO: Implement emulation of D32SLL instruction. */
27061 MIPS_INVAL("OPC_MXU_D32SLL");
27062 gen_reserved_instruction(ctx
);
27064 case OPC_MXU_D32SLR
:
27065 /* TODO: Implement emulation of D32SLR instruction. */
27066 MIPS_INVAL("OPC_MXU_D32SLR");
27067 gen_reserved_instruction(ctx
);
27069 case OPC_MXU_D32SARL
:
27070 /* TODO: Implement emulation of D32SARL instruction. */
27071 MIPS_INVAL("OPC_MXU_D32SARL");
27072 gen_reserved_instruction(ctx
);
27074 case OPC_MXU_D32SAR
:
27075 /* TODO: Implement emulation of D32SAR instruction. */
27076 MIPS_INVAL("OPC_MXU_D32SAR");
27077 gen_reserved_instruction(ctx
);
27079 case OPC_MXU_Q16SLL
:
27080 /* TODO: Implement emulation of Q16SLL instruction. */
27081 MIPS_INVAL("OPC_MXU_Q16SLL");
27082 gen_reserved_instruction(ctx
);
27084 case OPC_MXU_Q16SLR
:
27085 /* TODO: Implement emulation of Q16SLR instruction. */
27086 MIPS_INVAL("OPC_MXU_Q16SLR");
27087 gen_reserved_instruction(ctx
);
27089 case OPC_MXU__POOL18
:
27090 decode_opc_mxu__pool18(env
, ctx
);
27092 case OPC_MXU_Q16SAR
:
27093 /* TODO: Implement emulation of Q16SAR instruction. */
27094 MIPS_INVAL("OPC_MXU_Q16SAR");
27095 gen_reserved_instruction(ctx
);
27097 case OPC_MXU__POOL19
:
27098 decode_opc_mxu__pool19(env
, ctx
);
27100 case OPC_MXU__POOL20
:
27101 decode_opc_mxu__pool20(env
, ctx
);
27103 case OPC_MXU__POOL21
:
27104 decode_opc_mxu__pool21(env
, ctx
);
27106 case OPC_MXU_Q16SCOP
:
27107 /* TODO: Implement emulation of Q16SCOP instruction. */
27108 MIPS_INVAL("OPC_MXU_Q16SCOP");
27109 gen_reserved_instruction(ctx
);
27111 case OPC_MXU_Q8MADL
:
27112 /* TODO: Implement emulation of Q8MADL instruction. */
27113 MIPS_INVAL("OPC_MXU_Q8MADL");
27114 gen_reserved_instruction(ctx
);
27116 case OPC_MXU_S32SFL
:
27117 /* TODO: Implement emulation of S32SFL instruction. */
27118 MIPS_INVAL("OPC_MXU_S32SFL");
27119 gen_reserved_instruction(ctx
);
27121 case OPC_MXU_Q8SAD
:
27122 /* TODO: Implement emulation of Q8SAD instruction. */
27123 MIPS_INVAL("OPC_MXU_Q8SAD");
27124 gen_reserved_instruction(ctx
);
27127 MIPS_INVAL("decode_opc_mxu");
27128 gen_reserved_instruction(ctx
);
27131 gen_set_label(l_exit
);
27132 tcg_temp_free(t_mxu_cr
);
27136 #endif /* !defined(TARGET_MIPS64) */
27139 static void decode_opc_special2_legacy(CPUMIPSState
*env
, DisasContext
*ctx
)
27144 rs
= (ctx
->opcode
>> 21) & 0x1f;
27145 rt
= (ctx
->opcode
>> 16) & 0x1f;
27146 rd
= (ctx
->opcode
>> 11) & 0x1f;
27148 op1
= MASK_SPECIAL2(ctx
->opcode
);
27150 case OPC_MADD
: /* Multiply and add/sub */
27154 check_insn(ctx
, ISA_MIPS_R1
);
27155 gen_muldiv(ctx
, op1
, rd
& 3, rs
, rt
);
27158 gen_arith(ctx
, op1
, rd
, rs
, rt
);
27161 case OPC_DIVU_G_2F
:
27162 case OPC_MULT_G_2F
:
27163 case OPC_MULTU_G_2F
:
27165 case OPC_MODU_G_2F
:
27166 check_insn(ctx
, INSN_LOONGSON2F
| ASE_LEXT
);
27167 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
27171 check_insn(ctx
, ISA_MIPS_R1
);
27172 gen_cl(ctx
, op1
, rd
, rs
);
27175 if (is_uhi(extract32(ctx
->opcode
, 6, 20))) {
27176 gen_helper_do_semihosting(cpu_env
);
27179 * XXX: not clear which exception should be raised
27180 * when in debug mode...
27182 check_insn(ctx
, ISA_MIPS_R1
);
27183 generate_exception_end(ctx
, EXCP_DBp
);
27186 #if defined(TARGET_MIPS64)
27189 check_insn(ctx
, ISA_MIPS_R1
);
27190 check_mips_64(ctx
);
27191 gen_cl(ctx
, op1
, rd
, rs
);
27193 case OPC_DMULT_G_2F
:
27194 case OPC_DMULTU_G_2F
:
27195 case OPC_DDIV_G_2F
:
27196 case OPC_DDIVU_G_2F
:
27197 case OPC_DMOD_G_2F
:
27198 case OPC_DMODU_G_2F
:
27199 check_insn(ctx
, INSN_LOONGSON2F
| ASE_LEXT
);
27200 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
27203 default: /* Invalid */
27204 MIPS_INVAL("special2_legacy");
27205 gen_reserved_instruction(ctx
);
27210 static void decode_opc_special3_r6(CPUMIPSState
*env
, DisasContext
*ctx
)
27212 int rs
, rt
, rd
, sa
;
27216 rs
= (ctx
->opcode
>> 21) & 0x1f;
27217 rt
= (ctx
->opcode
>> 16) & 0x1f;
27218 rd
= (ctx
->opcode
>> 11) & 0x1f;
27219 sa
= (ctx
->opcode
>> 6) & 0x1f;
27220 imm
= (int16_t)ctx
->opcode
>> 7;
27222 op1
= MASK_SPECIAL3(ctx
->opcode
);
27226 /* hint codes 24-31 are reserved and signal RI */
27227 gen_reserved_instruction(ctx
);
27229 /* Treat as NOP. */
27232 check_cp0_enabled(ctx
);
27233 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
27234 gen_cache_operation(ctx
, rt
, rs
, imm
);
27238 gen_st_cond(ctx
, rt
, rs
, imm
, MO_TESL
, false);
27241 gen_ld(ctx
, op1
, rt
, rs
, imm
);
27246 /* Treat as NOP. */
27249 op2
= MASK_BSHFL(ctx
->opcode
);
27255 gen_align(ctx
, 32, rd
, rs
, rt
, sa
& 3);
27258 gen_bitswap(ctx
, op2
, rd
, rt
);
27263 #ifndef CONFIG_USER_ONLY
27265 if (unlikely(ctx
->gi
<= 1)) {
27266 gen_reserved_instruction(ctx
);
27268 check_cp0_enabled(ctx
);
27269 switch ((ctx
->opcode
>> 6) & 3) {
27270 case 0: /* GINVI */
27271 /* Treat as NOP. */
27273 case 2: /* GINVT */
27274 gen_helper_0e1i(ginvt
, cpu_gpr
[rs
], extract32(ctx
->opcode
, 8, 2));
27277 gen_reserved_instruction(ctx
);
27282 #if defined(TARGET_MIPS64)
27284 gen_st_cond(ctx
, rt
, rs
, imm
, MO_TEQ
, false);
27287 gen_ld(ctx
, op1
, rt
, rs
, imm
);
27290 check_mips_64(ctx
);
27293 /* Treat as NOP. */
27296 op2
= MASK_DBSHFL(ctx
->opcode
);
27306 gen_align(ctx
, 64, rd
, rs
, rt
, sa
& 7);
27309 gen_bitswap(ctx
, op2
, rd
, rt
);
27316 default: /* Invalid */
27317 MIPS_INVAL("special3_r6");
27318 gen_reserved_instruction(ctx
);
27323 static void decode_opc_special3_legacy(CPUMIPSState
*env
, DisasContext
*ctx
)
27328 rs
= (ctx
->opcode
>> 21) & 0x1f;
27329 rt
= (ctx
->opcode
>> 16) & 0x1f;
27330 rd
= (ctx
->opcode
>> 11) & 0x1f;
27332 op1
= MASK_SPECIAL3(ctx
->opcode
);
27335 case OPC_DIVU_G_2E
:
27337 case OPC_MODU_G_2E
:
27338 case OPC_MULT_G_2E
:
27339 case OPC_MULTU_G_2E
:
27341 * OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
27342 * the same mask and op1.
27344 if ((ctx
->insn_flags
& ASE_DSP_R2
) && (op1
== OPC_MULT_G_2E
)) {
27345 op2
= MASK_ADDUH_QB(ctx
->opcode
);
27348 case OPC_ADDUH_R_QB
:
27350 case OPC_ADDQH_R_PH
:
27352 case OPC_ADDQH_R_W
:
27354 case OPC_SUBUH_R_QB
:
27356 case OPC_SUBQH_R_PH
:
27358 case OPC_SUBQH_R_W
:
27359 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
27364 case OPC_MULQ_RS_W
:
27365 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
27368 MIPS_INVAL("MASK ADDUH.QB");
27369 gen_reserved_instruction(ctx
);
27372 } else if (ctx
->insn_flags
& INSN_LOONGSON2E
) {
27373 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
27375 gen_reserved_instruction(ctx
);
27379 op2
= MASK_LX(ctx
->opcode
);
27381 #if defined(TARGET_MIPS64)
27387 gen_mipsdsp_ld(ctx
, op2
, rd
, rs
, rt
);
27389 default: /* Invalid */
27390 MIPS_INVAL("MASK LX");
27391 gen_reserved_instruction(ctx
);
27395 case OPC_ABSQ_S_PH_DSP
:
27396 op2
= MASK_ABSQ_S_PH(ctx
->opcode
);
27398 case OPC_ABSQ_S_QB
:
27399 case OPC_ABSQ_S_PH
:
27401 case OPC_PRECEQ_W_PHL
:
27402 case OPC_PRECEQ_W_PHR
:
27403 case OPC_PRECEQU_PH_QBL
:
27404 case OPC_PRECEQU_PH_QBR
:
27405 case OPC_PRECEQU_PH_QBLA
:
27406 case OPC_PRECEQU_PH_QBRA
:
27407 case OPC_PRECEU_PH_QBL
:
27408 case OPC_PRECEU_PH_QBR
:
27409 case OPC_PRECEU_PH_QBLA
:
27410 case OPC_PRECEU_PH_QBRA
:
27411 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
27418 gen_mipsdsp_bitinsn(ctx
, op1
, op2
, rd
, rt
);
27421 MIPS_INVAL("MASK ABSQ_S.PH");
27422 gen_reserved_instruction(ctx
);
27426 case OPC_ADDU_QB_DSP
:
27427 op2
= MASK_ADDU_QB(ctx
->opcode
);
27430 case OPC_ADDQ_S_PH
:
27433 case OPC_ADDU_S_QB
:
27435 case OPC_ADDU_S_PH
:
27437 case OPC_SUBQ_S_PH
:
27440 case OPC_SUBU_S_QB
:
27442 case OPC_SUBU_S_PH
:
27446 case OPC_RADDU_W_QB
:
27447 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
27449 case OPC_MULEU_S_PH_QBL
:
27450 case OPC_MULEU_S_PH_QBR
:
27451 case OPC_MULQ_RS_PH
:
27452 case OPC_MULEQ_S_W_PHL
:
27453 case OPC_MULEQ_S_W_PHR
:
27454 case OPC_MULQ_S_PH
:
27455 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
27457 default: /* Invalid */
27458 MIPS_INVAL("MASK ADDU.QB");
27459 gen_reserved_instruction(ctx
);
27464 case OPC_CMPU_EQ_QB_DSP
:
27465 op2
= MASK_CMPU_EQ_QB(ctx
->opcode
);
27467 case OPC_PRECR_SRA_PH_W
:
27468 case OPC_PRECR_SRA_R_PH_W
:
27469 gen_mipsdsp_arith(ctx
, op1
, op2
, rt
, rs
, rd
);
27471 case OPC_PRECR_QB_PH
:
27472 case OPC_PRECRQ_QB_PH
:
27473 case OPC_PRECRQ_PH_W
:
27474 case OPC_PRECRQ_RS_PH_W
:
27475 case OPC_PRECRQU_S_QB_PH
:
27476 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
27478 case OPC_CMPU_EQ_QB
:
27479 case OPC_CMPU_LT_QB
:
27480 case OPC_CMPU_LE_QB
:
27481 case OPC_CMP_EQ_PH
:
27482 case OPC_CMP_LT_PH
:
27483 case OPC_CMP_LE_PH
:
27484 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
27486 case OPC_CMPGU_EQ_QB
:
27487 case OPC_CMPGU_LT_QB
:
27488 case OPC_CMPGU_LE_QB
:
27489 case OPC_CMPGDU_EQ_QB
:
27490 case OPC_CMPGDU_LT_QB
:
27491 case OPC_CMPGDU_LE_QB
:
27494 case OPC_PACKRL_PH
:
27495 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
27497 default: /* Invalid */
27498 MIPS_INVAL("MASK CMPU.EQ.QB");
27499 gen_reserved_instruction(ctx
);
27503 case OPC_SHLL_QB_DSP
:
27504 gen_mipsdsp_shift(ctx
, op1
, rd
, rs
, rt
);
27506 case OPC_DPA_W_PH_DSP
:
27507 op2
= MASK_DPA_W_PH(ctx
->opcode
);
27509 case OPC_DPAU_H_QBL
:
27510 case OPC_DPAU_H_QBR
:
27511 case OPC_DPSU_H_QBL
:
27512 case OPC_DPSU_H_QBR
:
27514 case OPC_DPAX_W_PH
:
27515 case OPC_DPAQ_S_W_PH
:
27516 case OPC_DPAQX_S_W_PH
:
27517 case OPC_DPAQX_SA_W_PH
:
27519 case OPC_DPSX_W_PH
:
27520 case OPC_DPSQ_S_W_PH
:
27521 case OPC_DPSQX_S_W_PH
:
27522 case OPC_DPSQX_SA_W_PH
:
27523 case OPC_MULSAQ_S_W_PH
:
27524 case OPC_DPAQ_SA_L_W
:
27525 case OPC_DPSQ_SA_L_W
:
27526 case OPC_MAQ_S_W_PHL
:
27527 case OPC_MAQ_S_W_PHR
:
27528 case OPC_MAQ_SA_W_PHL
:
27529 case OPC_MAQ_SA_W_PHR
:
27530 case OPC_MULSA_W_PH
:
27531 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
27533 default: /* Invalid */
27534 MIPS_INVAL("MASK DPAW.PH");
27535 gen_reserved_instruction(ctx
);
27540 op2
= MASK_INSV(ctx
->opcode
);
27551 t0
= tcg_temp_new();
27552 t1
= tcg_temp_new();
27554 gen_load_gpr(t0
, rt
);
27555 gen_load_gpr(t1
, rs
);
27557 gen_helper_insv(cpu_gpr
[rt
], cpu_env
, t1
, t0
);
27563 default: /* Invalid */
27564 MIPS_INVAL("MASK INSV");
27565 gen_reserved_instruction(ctx
);
27569 case OPC_APPEND_DSP
:
27570 gen_mipsdsp_append(env
, ctx
, op1
, rt
, rs
, rd
);
27572 case OPC_EXTR_W_DSP
:
27573 op2
= MASK_EXTR_W(ctx
->opcode
);
27577 case OPC_EXTR_RS_W
:
27579 case OPC_EXTRV_S_H
:
27581 case OPC_EXTRV_R_W
:
27582 case OPC_EXTRV_RS_W
:
27587 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rt
, rs
, rd
, 1);
27590 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
27596 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
27598 default: /* Invalid */
27599 MIPS_INVAL("MASK EXTR.W");
27600 gen_reserved_instruction(ctx
);
27604 #if defined(TARGET_MIPS64)
27605 case OPC_DDIV_G_2E
:
27606 case OPC_DDIVU_G_2E
:
27607 case OPC_DMULT_G_2E
:
27608 case OPC_DMULTU_G_2E
:
27609 case OPC_DMOD_G_2E
:
27610 case OPC_DMODU_G_2E
:
27611 check_insn(ctx
, INSN_LOONGSON2E
);
27612 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
27614 case OPC_ABSQ_S_QH_DSP
:
27615 op2
= MASK_ABSQ_S_QH(ctx
->opcode
);
27617 case OPC_PRECEQ_L_PWL
:
27618 case OPC_PRECEQ_L_PWR
:
27619 case OPC_PRECEQ_PW_QHL
:
27620 case OPC_PRECEQ_PW_QHR
:
27621 case OPC_PRECEQ_PW_QHLA
:
27622 case OPC_PRECEQ_PW_QHRA
:
27623 case OPC_PRECEQU_QH_OBL
:
27624 case OPC_PRECEQU_QH_OBR
:
27625 case OPC_PRECEQU_QH_OBLA
:
27626 case OPC_PRECEQU_QH_OBRA
:
27627 case OPC_PRECEU_QH_OBL
:
27628 case OPC_PRECEU_QH_OBR
:
27629 case OPC_PRECEU_QH_OBLA
:
27630 case OPC_PRECEU_QH_OBRA
:
27631 case OPC_ABSQ_S_OB
:
27632 case OPC_ABSQ_S_PW
:
27633 case OPC_ABSQ_S_QH
:
27634 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
27642 gen_mipsdsp_bitinsn(ctx
, op1
, op2
, rd
, rt
);
27644 default: /* Invalid */
27645 MIPS_INVAL("MASK ABSQ_S.QH");
27646 gen_reserved_instruction(ctx
);
27650 case OPC_ADDU_OB_DSP
:
27651 op2
= MASK_ADDU_OB(ctx
->opcode
);
27653 case OPC_RADDU_L_OB
:
27655 case OPC_SUBQ_S_PW
:
27657 case OPC_SUBQ_S_QH
:
27659 case OPC_SUBU_S_OB
:
27661 case OPC_SUBU_S_QH
:
27663 case OPC_SUBUH_R_OB
:
27665 case OPC_ADDQ_S_PW
:
27667 case OPC_ADDQ_S_QH
:
27669 case OPC_ADDU_S_OB
:
27671 case OPC_ADDU_S_QH
:
27673 case OPC_ADDUH_R_OB
:
27674 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
27676 case OPC_MULEQ_S_PW_QHL
:
27677 case OPC_MULEQ_S_PW_QHR
:
27678 case OPC_MULEU_S_QH_OBL
:
27679 case OPC_MULEU_S_QH_OBR
:
27680 case OPC_MULQ_RS_QH
:
27681 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
27683 default: /* Invalid */
27684 MIPS_INVAL("MASK ADDU.OB");
27685 gen_reserved_instruction(ctx
);
27689 case OPC_CMPU_EQ_OB_DSP
:
27690 op2
= MASK_CMPU_EQ_OB(ctx
->opcode
);
27692 case OPC_PRECR_SRA_QH_PW
:
27693 case OPC_PRECR_SRA_R_QH_PW
:
27694 /* Return value is rt. */
27695 gen_mipsdsp_arith(ctx
, op1
, op2
, rt
, rs
, rd
);
27697 case OPC_PRECR_OB_QH
:
27698 case OPC_PRECRQ_OB_QH
:
27699 case OPC_PRECRQ_PW_L
:
27700 case OPC_PRECRQ_QH_PW
:
27701 case OPC_PRECRQ_RS_QH_PW
:
27702 case OPC_PRECRQU_S_OB_QH
:
27703 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
27705 case OPC_CMPU_EQ_OB
:
27706 case OPC_CMPU_LT_OB
:
27707 case OPC_CMPU_LE_OB
:
27708 case OPC_CMP_EQ_QH
:
27709 case OPC_CMP_LT_QH
:
27710 case OPC_CMP_LE_QH
:
27711 case OPC_CMP_EQ_PW
:
27712 case OPC_CMP_LT_PW
:
27713 case OPC_CMP_LE_PW
:
27714 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
27716 case OPC_CMPGDU_EQ_OB
:
27717 case OPC_CMPGDU_LT_OB
:
27718 case OPC_CMPGDU_LE_OB
:
27719 case OPC_CMPGU_EQ_OB
:
27720 case OPC_CMPGU_LT_OB
:
27721 case OPC_CMPGU_LE_OB
:
27722 case OPC_PACKRL_PW
:
27726 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
27728 default: /* Invalid */
27729 MIPS_INVAL("MASK CMPU_EQ.OB");
27730 gen_reserved_instruction(ctx
);
27734 case OPC_DAPPEND_DSP
:
27735 gen_mipsdsp_append(env
, ctx
, op1
, rt
, rs
, rd
);
27737 case OPC_DEXTR_W_DSP
:
27738 op2
= MASK_DEXTR_W(ctx
->opcode
);
27745 case OPC_DEXTR_R_L
:
27746 case OPC_DEXTR_RS_L
:
27748 case OPC_DEXTR_R_W
:
27749 case OPC_DEXTR_RS_W
:
27750 case OPC_DEXTR_S_H
:
27752 case OPC_DEXTRV_R_L
:
27753 case OPC_DEXTRV_RS_L
:
27754 case OPC_DEXTRV_S_H
:
27756 case OPC_DEXTRV_R_W
:
27757 case OPC_DEXTRV_RS_W
:
27758 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rt
, rs
, rd
, 1);
27763 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
27765 default: /* Invalid */
27766 MIPS_INVAL("MASK EXTR.W");
27767 gen_reserved_instruction(ctx
);
27771 case OPC_DPAQ_W_QH_DSP
:
27772 op2
= MASK_DPAQ_W_QH(ctx
->opcode
);
27774 case OPC_DPAU_H_OBL
:
27775 case OPC_DPAU_H_OBR
:
27776 case OPC_DPSU_H_OBL
:
27777 case OPC_DPSU_H_OBR
:
27779 case OPC_DPAQ_S_W_QH
:
27781 case OPC_DPSQ_S_W_QH
:
27782 case OPC_MULSAQ_S_W_QH
:
27783 case OPC_DPAQ_SA_L_PW
:
27784 case OPC_DPSQ_SA_L_PW
:
27785 case OPC_MULSAQ_S_L_PW
:
27786 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
27788 case OPC_MAQ_S_W_QHLL
:
27789 case OPC_MAQ_S_W_QHLR
:
27790 case OPC_MAQ_S_W_QHRL
:
27791 case OPC_MAQ_S_W_QHRR
:
27792 case OPC_MAQ_SA_W_QHLL
:
27793 case OPC_MAQ_SA_W_QHLR
:
27794 case OPC_MAQ_SA_W_QHRL
:
27795 case OPC_MAQ_SA_W_QHRR
:
27796 case OPC_MAQ_S_L_PWL
:
27797 case OPC_MAQ_S_L_PWR
:
27802 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
27804 default: /* Invalid */
27805 MIPS_INVAL("MASK DPAQ.W.QH");
27806 gen_reserved_instruction(ctx
);
27810 case OPC_DINSV_DSP
:
27811 op2
= MASK_INSV(ctx
->opcode
);
27822 t0
= tcg_temp_new();
27823 t1
= tcg_temp_new();
27825 gen_load_gpr(t0
, rt
);
27826 gen_load_gpr(t1
, rs
);
27828 gen_helper_dinsv(cpu_gpr
[rt
], cpu_env
, t1
, t0
);
27834 default: /* Invalid */
27835 MIPS_INVAL("MASK DINSV");
27836 gen_reserved_instruction(ctx
);
27840 case OPC_SHLL_OB_DSP
:
27841 gen_mipsdsp_shift(ctx
, op1
, rd
, rs
, rt
);
27844 default: /* Invalid */
27845 MIPS_INVAL("special3_legacy");
27846 gen_reserved_instruction(ctx
);
27852 #if defined(TARGET_MIPS64)
27854 static void decode_mmi0(CPUMIPSState
*env
, DisasContext
*ctx
)
27856 uint32_t opc
= MASK_MMI0(ctx
->opcode
);
27859 case MMI_OPC_0_PADDW
: /* TODO: MMI_OPC_0_PADDW */
27860 case MMI_OPC_0_PSUBW
: /* TODO: MMI_OPC_0_PSUBW */
27861 case MMI_OPC_0_PCGTW
: /* TODO: MMI_OPC_0_PCGTW */
27862 case MMI_OPC_0_PMAXW
: /* TODO: MMI_OPC_0_PMAXW */
27863 case MMI_OPC_0_PADDH
: /* TODO: MMI_OPC_0_PADDH */
27864 case MMI_OPC_0_PSUBH
: /* TODO: MMI_OPC_0_PSUBH */
27865 case MMI_OPC_0_PCGTH
: /* TODO: MMI_OPC_0_PCGTH */
27866 case MMI_OPC_0_PMAXH
: /* TODO: MMI_OPC_0_PMAXH */
27867 case MMI_OPC_0_PADDB
: /* TODO: MMI_OPC_0_PADDB */
27868 case MMI_OPC_0_PSUBB
: /* TODO: MMI_OPC_0_PSUBB */
27869 case MMI_OPC_0_PCGTB
: /* TODO: MMI_OPC_0_PCGTB */
27870 case MMI_OPC_0_PADDSW
: /* TODO: MMI_OPC_0_PADDSW */
27871 case MMI_OPC_0_PSUBSW
: /* TODO: MMI_OPC_0_PSUBSW */
27872 case MMI_OPC_0_PEXTLW
: /* TODO: MMI_OPC_0_PEXTLW */
27873 case MMI_OPC_0_PPACW
: /* TODO: MMI_OPC_0_PPACW */
27874 case MMI_OPC_0_PADDSH
: /* TODO: MMI_OPC_0_PADDSH */
27875 case MMI_OPC_0_PSUBSH
: /* TODO: MMI_OPC_0_PSUBSH */
27876 case MMI_OPC_0_PEXTLH
: /* TODO: MMI_OPC_0_PEXTLH */
27877 case MMI_OPC_0_PPACH
: /* TODO: MMI_OPC_0_PPACH */
27878 case MMI_OPC_0_PADDSB
: /* TODO: MMI_OPC_0_PADDSB */
27879 case MMI_OPC_0_PSUBSB
: /* TODO: MMI_OPC_0_PSUBSB */
27880 case MMI_OPC_0_PEXTLB
: /* TODO: MMI_OPC_0_PEXTLB */
27881 case MMI_OPC_0_PPACB
: /* TODO: MMI_OPC_0_PPACB */
27882 case MMI_OPC_0_PEXT5
: /* TODO: MMI_OPC_0_PEXT5 */
27883 case MMI_OPC_0_PPAC5
: /* TODO: MMI_OPC_0_PPAC5 */
27884 gen_reserved_instruction(ctx
); /* TODO: MMI_OPC_CLASS_MMI0 */
27887 MIPS_INVAL("TX79 MMI class MMI0");
27888 gen_reserved_instruction(ctx
);
27893 static void decode_mmi1(CPUMIPSState
*env
, DisasContext
*ctx
)
27895 uint32_t opc
= MASK_MMI1(ctx
->opcode
);
27898 case MMI_OPC_1_PABSW
: /* TODO: MMI_OPC_1_PABSW */
27899 case MMI_OPC_1_PCEQW
: /* TODO: MMI_OPC_1_PCEQW */
27900 case MMI_OPC_1_PMINW
: /* TODO: MMI_OPC_1_PMINW */
27901 case MMI_OPC_1_PADSBH
: /* TODO: MMI_OPC_1_PADSBH */
27902 case MMI_OPC_1_PABSH
: /* TODO: MMI_OPC_1_PABSH */
27903 case MMI_OPC_1_PCEQH
: /* TODO: MMI_OPC_1_PCEQH */
27904 case MMI_OPC_1_PMINH
: /* TODO: MMI_OPC_1_PMINH */
27905 case MMI_OPC_1_PCEQB
: /* TODO: MMI_OPC_1_PCEQB */
27906 case MMI_OPC_1_PADDUW
: /* TODO: MMI_OPC_1_PADDUW */
27907 case MMI_OPC_1_PSUBUW
: /* TODO: MMI_OPC_1_PSUBUW */
27908 case MMI_OPC_1_PEXTUW
: /* TODO: MMI_OPC_1_PEXTUW */
27909 case MMI_OPC_1_PADDUH
: /* TODO: MMI_OPC_1_PADDUH */
27910 case MMI_OPC_1_PSUBUH
: /* TODO: MMI_OPC_1_PSUBUH */
27911 case MMI_OPC_1_PEXTUH
: /* TODO: MMI_OPC_1_PEXTUH */
27912 case MMI_OPC_1_PADDUB
: /* TODO: MMI_OPC_1_PADDUB */
27913 case MMI_OPC_1_PSUBUB
: /* TODO: MMI_OPC_1_PSUBUB */
27914 case MMI_OPC_1_PEXTUB
: /* TODO: MMI_OPC_1_PEXTUB */
27915 case MMI_OPC_1_QFSRV
: /* TODO: MMI_OPC_1_QFSRV */
27916 gen_reserved_instruction(ctx
); /* TODO: MMI_OPC_CLASS_MMI1 */
27919 MIPS_INVAL("TX79 MMI class MMI1");
27920 gen_reserved_instruction(ctx
);
27925 static void decode_mmi2(CPUMIPSState
*env
, DisasContext
*ctx
)
27927 uint32_t opc
= MASK_MMI2(ctx
->opcode
);
27930 case MMI_OPC_2_PMADDW
: /* TODO: MMI_OPC_2_PMADDW */
27931 case MMI_OPC_2_PSLLVW
: /* TODO: MMI_OPC_2_PSLLVW */
27932 case MMI_OPC_2_PSRLVW
: /* TODO: MMI_OPC_2_PSRLVW */
27933 case MMI_OPC_2_PMSUBW
: /* TODO: MMI_OPC_2_PMSUBW */
27934 case MMI_OPC_2_PMFHI
: /* TODO: MMI_OPC_2_PMFHI */
27935 case MMI_OPC_2_PMFLO
: /* TODO: MMI_OPC_2_PMFLO */
27936 case MMI_OPC_2_PINTH
: /* TODO: MMI_OPC_2_PINTH */
27937 case MMI_OPC_2_PMULTW
: /* TODO: MMI_OPC_2_PMULTW */
27938 case MMI_OPC_2_PDIVW
: /* TODO: MMI_OPC_2_PDIVW */
27939 case MMI_OPC_2_PMADDH
: /* TODO: MMI_OPC_2_PMADDH */
27940 case MMI_OPC_2_PHMADH
: /* TODO: MMI_OPC_2_PHMADH */
27941 case MMI_OPC_2_PAND
: /* TODO: MMI_OPC_2_PAND */
27942 case MMI_OPC_2_PXOR
: /* TODO: MMI_OPC_2_PXOR */
27943 case MMI_OPC_2_PMSUBH
: /* TODO: MMI_OPC_2_PMSUBH */
27944 case MMI_OPC_2_PHMSBH
: /* TODO: MMI_OPC_2_PHMSBH */
27945 case MMI_OPC_2_PEXEH
: /* TODO: MMI_OPC_2_PEXEH */
27946 case MMI_OPC_2_PREVH
: /* TODO: MMI_OPC_2_PREVH */
27947 case MMI_OPC_2_PMULTH
: /* TODO: MMI_OPC_2_PMULTH */
27948 case MMI_OPC_2_PDIVBW
: /* TODO: MMI_OPC_2_PDIVBW */
27949 case MMI_OPC_2_PEXEW
: /* TODO: MMI_OPC_2_PEXEW */
27950 case MMI_OPC_2_PROT3W
: /* TODO: MMI_OPC_2_PROT3W */
27951 gen_reserved_instruction(ctx
); /* TODO: MMI_OPC_CLASS_MMI2 */
27953 case MMI_OPC_2_PCPYLD
:
27954 gen_mmi_pcpyld(ctx
);
27957 MIPS_INVAL("TX79 MMI class MMI2");
27958 gen_reserved_instruction(ctx
);
27963 static void decode_mmi3(CPUMIPSState
*env
, DisasContext
*ctx
)
27965 uint32_t opc
= MASK_MMI3(ctx
->opcode
);
27968 case MMI_OPC_3_PMADDUW
: /* TODO: MMI_OPC_3_PMADDUW */
27969 case MMI_OPC_3_PSRAVW
: /* TODO: MMI_OPC_3_PSRAVW */
27970 case MMI_OPC_3_PMTHI
: /* TODO: MMI_OPC_3_PMTHI */
27971 case MMI_OPC_3_PMTLO
: /* TODO: MMI_OPC_3_PMTLO */
27972 case MMI_OPC_3_PINTEH
: /* TODO: MMI_OPC_3_PINTEH */
27973 case MMI_OPC_3_PMULTUW
: /* TODO: MMI_OPC_3_PMULTUW */
27974 case MMI_OPC_3_PDIVUW
: /* TODO: MMI_OPC_3_PDIVUW */
27975 case MMI_OPC_3_POR
: /* TODO: MMI_OPC_3_POR */
27976 case MMI_OPC_3_PNOR
: /* TODO: MMI_OPC_3_PNOR */
27977 case MMI_OPC_3_PEXCH
: /* TODO: MMI_OPC_3_PEXCH */
27978 case MMI_OPC_3_PEXCW
: /* TODO: MMI_OPC_3_PEXCW */
27979 gen_reserved_instruction(ctx
); /* TODO: MMI_OPC_CLASS_MMI3 */
27981 case MMI_OPC_3_PCPYH
:
27982 gen_mmi_pcpyh(ctx
);
27984 case MMI_OPC_3_PCPYUD
:
27985 gen_mmi_pcpyud(ctx
);
27988 MIPS_INVAL("TX79 MMI class MMI3");
27989 gen_reserved_instruction(ctx
);
27994 static void decode_mmi(CPUMIPSState
*env
, DisasContext
*ctx
)
27996 uint32_t opc
= MASK_MMI(ctx
->opcode
);
27997 int rs
= extract32(ctx
->opcode
, 21, 5);
27998 int rt
= extract32(ctx
->opcode
, 16, 5);
27999 int rd
= extract32(ctx
->opcode
, 11, 5);
28002 case MMI_OPC_CLASS_MMI0
:
28003 decode_mmi0(env
, ctx
);
28005 case MMI_OPC_CLASS_MMI1
:
28006 decode_mmi1(env
, ctx
);
28008 case MMI_OPC_CLASS_MMI2
:
28009 decode_mmi2(env
, ctx
);
28011 case MMI_OPC_CLASS_MMI3
:
28012 decode_mmi3(env
, ctx
);
28014 case MMI_OPC_MULT1
:
28015 case MMI_OPC_MULTU1
:
28017 case MMI_OPC_MADDU
:
28018 case MMI_OPC_MADD1
:
28019 case MMI_OPC_MADDU1
:
28020 gen_mul_txx9(ctx
, opc
, rd
, rs
, rt
);
28023 case MMI_OPC_DIVU1
:
28024 gen_div1_tx79(ctx
, opc
, rs
, rt
);
28026 case MMI_OPC_MTLO1
:
28027 case MMI_OPC_MTHI1
:
28028 gen_HILO1_tx79(ctx
, opc
, rs
);
28030 case MMI_OPC_MFLO1
:
28031 case MMI_OPC_MFHI1
:
28032 gen_HILO1_tx79(ctx
, opc
, rd
);
28034 case MMI_OPC_PLZCW
: /* TODO: MMI_OPC_PLZCW */
28035 case MMI_OPC_PMFHL
: /* TODO: MMI_OPC_PMFHL */
28036 case MMI_OPC_PMTHL
: /* TODO: MMI_OPC_PMTHL */
28037 case MMI_OPC_PSLLH
: /* TODO: MMI_OPC_PSLLH */
28038 case MMI_OPC_PSRLH
: /* TODO: MMI_OPC_PSRLH */
28039 case MMI_OPC_PSRAH
: /* TODO: MMI_OPC_PSRAH */
28040 case MMI_OPC_PSLLW
: /* TODO: MMI_OPC_PSLLW */
28041 case MMI_OPC_PSRLW
: /* TODO: MMI_OPC_PSRLW */
28042 case MMI_OPC_PSRAW
: /* TODO: MMI_OPC_PSRAW */
28043 gen_reserved_instruction(ctx
); /* TODO: MMI_OPC_CLASS_MMI */
28046 MIPS_INVAL("TX79 MMI class");
28047 gen_reserved_instruction(ctx
);
28052 static void gen_mmi_lq(CPUMIPSState
*env
, DisasContext
*ctx
)
28054 gen_reserved_instruction(ctx
); /* TODO: MMI_OPC_LQ */
28057 static void gen_mmi_sq(DisasContext
*ctx
, int base
, int rt
, int offset
)
28059 gen_reserved_instruction(ctx
); /* TODO: MMI_OPC_SQ */
28063 * The TX79-specific instruction Store Quadword
28065 * +--------+-------+-------+------------------------+
28066 * | 011111 | base | rt | offset | SQ
28067 * +--------+-------+-------+------------------------+
28070 * has the same opcode as the Read Hardware Register instruction
28072 * +--------+-------+-------+-------+-------+--------+
28073 * | 011111 | 00000 | rt | rd | 00000 | 111011 | RDHWR
28074 * +--------+-------+-------+-------+-------+--------+
28077 * that is required, trapped and emulated by the Linux kernel. However, all
28078 * RDHWR encodings yield address error exceptions on the TX79 since the SQ
28079 * offset is odd. Therefore all valid SQ instructions can execute normally.
28080 * In user mode, QEMU must verify the upper and lower 11 bits to distinguish
28081 * between SQ and RDHWR, as the Linux kernel does.
28083 static void decode_mmi_sq(CPUMIPSState
*env
, DisasContext
*ctx
)
28085 int base
= extract32(ctx
->opcode
, 21, 5);
28086 int rt
= extract32(ctx
->opcode
, 16, 5);
28087 int offset
= extract32(ctx
->opcode
, 0, 16);
28089 #ifdef CONFIG_USER_ONLY
28090 uint32_t op1
= MASK_SPECIAL3(ctx
->opcode
);
28091 uint32_t op2
= extract32(ctx
->opcode
, 6, 5);
28093 if (base
== 0 && op2
== 0 && op1
== OPC_RDHWR
) {
28094 int rd
= extract32(ctx
->opcode
, 11, 5);
28096 gen_rdhwr(ctx
, rt
, rd
, 0);
28101 gen_mmi_sq(ctx
, base
, rt
, offset
);
28106 static void decode_opc_special3(CPUMIPSState
*env
, DisasContext
*ctx
)
28108 int rs
, rt
, rd
, sa
;
28112 rs
= (ctx
->opcode
>> 21) & 0x1f;
28113 rt
= (ctx
->opcode
>> 16) & 0x1f;
28114 rd
= (ctx
->opcode
>> 11) & 0x1f;
28115 sa
= (ctx
->opcode
>> 6) & 0x1f;
28116 imm
= sextract32(ctx
->opcode
, 7, 9);
28118 op1
= MASK_SPECIAL3(ctx
->opcode
);
28121 * EVA loads and stores overlap Loongson 2E instructions decoded by
28122 * decode_opc_special3_legacy(), so be careful to allow their decoding when
28135 check_cp0_enabled(ctx
);
28136 gen_ld(ctx
, op1
, rt
, rs
, imm
);
28143 check_cp0_enabled(ctx
);
28144 gen_st(ctx
, op1
, rt
, rs
, imm
);
28147 check_cp0_enabled(ctx
);
28148 gen_st_cond(ctx
, rt
, rs
, imm
, MO_TESL
, true);
28151 check_cp0_enabled(ctx
);
28152 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
28153 gen_cache_operation(ctx
, rt
, rs
, imm
);
28155 /* Treat as NOP. */
28158 check_cp0_enabled(ctx
);
28159 /* Treat as NOP. */
28167 check_insn(ctx
, ISA_MIPS_R2
);
28168 gen_bitops(ctx
, op1
, rt
, rs
, sa
, rd
);
28171 op2
= MASK_BSHFL(ctx
->opcode
);
28178 check_insn(ctx
, ISA_MIPS_R6
);
28179 decode_opc_special3_r6(env
, ctx
);
28182 check_insn(ctx
, ISA_MIPS_R2
);
28183 gen_bshfl(ctx
, op2
, rt
, rd
);
28187 #if defined(TARGET_MIPS64)
28194 check_insn(ctx
, ISA_MIPS_R2
);
28195 check_mips_64(ctx
);
28196 gen_bitops(ctx
, op1
, rt
, rs
, sa
, rd
);
28199 op2
= MASK_DBSHFL(ctx
->opcode
);
28210 check_insn(ctx
, ISA_MIPS_R6
);
28211 decode_opc_special3_r6(env
, ctx
);
28214 check_insn(ctx
, ISA_MIPS_R2
);
28215 check_mips_64(ctx
);
28216 op2
= MASK_DBSHFL(ctx
->opcode
);
28217 gen_bshfl(ctx
, op2
, rt
, rd
);
28223 gen_rdhwr(ctx
, rt
, rd
, extract32(ctx
->opcode
, 6, 3));
28228 TCGv t0
= tcg_temp_new();
28229 TCGv t1
= tcg_temp_new();
28231 gen_load_gpr(t0
, rt
);
28232 gen_load_gpr(t1
, rs
);
28233 gen_helper_fork(t0
, t1
);
28241 TCGv t0
= tcg_temp_new();
28243 gen_load_gpr(t0
, rs
);
28244 gen_helper_yield(t0
, cpu_env
, t0
);
28245 gen_store_gpr(t0
, rd
);
28250 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
28251 decode_opc_special3_r6(env
, ctx
);
28253 decode_opc_special3_legacy(env
, ctx
);
28258 static bool decode_opc_legacy(CPUMIPSState
*env
, DisasContext
*ctx
)
28261 int rs
, rt
, rd
, sa
;
28265 op
= MASK_OP_MAJOR(ctx
->opcode
);
28266 rs
= (ctx
->opcode
>> 21) & 0x1f;
28267 rt
= (ctx
->opcode
>> 16) & 0x1f;
28268 rd
= (ctx
->opcode
>> 11) & 0x1f;
28269 sa
= (ctx
->opcode
>> 6) & 0x1f;
28270 imm
= (int16_t)ctx
->opcode
;
28273 decode_opc_special(env
, ctx
);
28276 #if defined(TARGET_MIPS64)
28277 if ((ctx
->insn_flags
& INSN_R5900
) && (ctx
->insn_flags
& ASE_MMI
)) {
28278 decode_mmi(env
, ctx
);
28280 if (ctx
->insn_flags
& ASE_MXU
) {
28281 decode_opc_mxu(env
, ctx
);
28284 decode_opc_special2_legacy(env
, ctx
);
28288 #if defined(TARGET_MIPS64)
28289 if (ctx
->insn_flags
& INSN_R5900
) {
28290 decode_mmi_sq(env
, ctx
); /* MMI_OPC_SQ */
28292 decode_opc_special3(env
, ctx
);
28295 decode_opc_special3(env
, ctx
);
28299 op1
= MASK_REGIMM(ctx
->opcode
);
28301 case OPC_BLTZL
: /* REGIMM branches */
28305 check_insn(ctx
, ISA_MIPS2
);
28306 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
28310 gen_compute_branch(ctx
, op1
, 4, rs
, -1, imm
<< 2, 4);
28314 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
28316 /* OPC_NAL, OPC_BAL */
28317 gen_compute_branch(ctx
, op1
, 4, 0, -1, imm
<< 2, 4);
28319 gen_reserved_instruction(ctx
);
28322 gen_compute_branch(ctx
, op1
, 4, rs
, -1, imm
<< 2, 4);
28325 case OPC_TGEI
: /* REGIMM traps */
28332 check_insn(ctx
, ISA_MIPS2
);
28333 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
28334 gen_trap(ctx
, op1
, rs
, -1, imm
);
28337 check_insn(ctx
, ISA_MIPS_R6
);
28338 gen_reserved_instruction(ctx
);
28341 check_insn(ctx
, ISA_MIPS_R2
);
28343 * Break the TB to be able to sync copied instructions
28346 ctx
->base
.is_jmp
= DISAS_STOP
;
28348 case OPC_BPOSGE32
: /* MIPS DSP branch */
28349 #if defined(TARGET_MIPS64)
28353 gen_compute_branch(ctx
, op1
, 4, -1, -2, (int32_t)imm
<< 2, 4);
28355 #if defined(TARGET_MIPS64)
28357 check_insn(ctx
, ISA_MIPS_R6
);
28358 check_mips_64(ctx
);
28360 tcg_gen_addi_tl(cpu_gpr
[rs
], cpu_gpr
[rs
], (int64_t)imm
<< 32);
28364 check_insn(ctx
, ISA_MIPS_R6
);
28365 check_mips_64(ctx
);
28367 tcg_gen_addi_tl(cpu_gpr
[rs
], cpu_gpr
[rs
], (int64_t)imm
<< 48);
28371 default: /* Invalid */
28372 MIPS_INVAL("regimm");
28373 gen_reserved_instruction(ctx
);
28378 check_cp0_enabled(ctx
);
28379 op1
= MASK_CP0(ctx
->opcode
);
28387 #if defined(TARGET_MIPS64)
28391 #ifndef CONFIG_USER_ONLY
28392 gen_cp0(env
, ctx
, op1
, rt
, rd
);
28393 #endif /* !CONFIG_USER_ONLY */
28411 #ifndef CONFIG_USER_ONLY
28412 gen_cp0(env
, ctx
, MASK_C0(ctx
->opcode
), rt
, rd
);
28413 #endif /* !CONFIG_USER_ONLY */
28416 #ifndef CONFIG_USER_ONLY
28419 TCGv t0
= tcg_temp_new();
28421 op2
= MASK_MFMC0(ctx
->opcode
);
28425 gen_helper_dmt(t0
);
28426 gen_store_gpr(t0
, rt
);
28430 gen_helper_emt(t0
);
28431 gen_store_gpr(t0
, rt
);
28435 gen_helper_dvpe(t0
, cpu_env
);
28436 gen_store_gpr(t0
, rt
);
28440 gen_helper_evpe(t0
, cpu_env
);
28441 gen_store_gpr(t0
, rt
);
28444 check_insn(ctx
, ISA_MIPS_R6
);
28446 gen_helper_dvp(t0
, cpu_env
);
28447 gen_store_gpr(t0
, rt
);
28451 check_insn(ctx
, ISA_MIPS_R6
);
28453 gen_helper_evp(t0
, cpu_env
);
28454 gen_store_gpr(t0
, rt
);
28458 check_insn(ctx
, ISA_MIPS_R2
);
28459 save_cpu_state(ctx
, 1);
28460 gen_helper_di(t0
, cpu_env
);
28461 gen_store_gpr(t0
, rt
);
28463 * Stop translation as we may have switched
28464 * the execution mode.
28466 ctx
->base
.is_jmp
= DISAS_STOP
;
28469 check_insn(ctx
, ISA_MIPS_R2
);
28470 save_cpu_state(ctx
, 1);
28471 gen_helper_ei(t0
, cpu_env
);
28472 gen_store_gpr(t0
, rt
);
28474 * DISAS_STOP isn't sufficient, we need to ensure we break
28475 * out of translated code to check for pending interrupts.
28477 gen_save_pc(ctx
->base
.pc_next
+ 4);
28478 ctx
->base
.is_jmp
= DISAS_EXIT
;
28480 default: /* Invalid */
28481 MIPS_INVAL("mfmc0");
28482 gen_reserved_instruction(ctx
);
28487 #endif /* !CONFIG_USER_ONLY */
28490 check_insn(ctx
, ISA_MIPS_R2
);
28491 gen_load_srsgpr(rt
, rd
);
28494 check_insn(ctx
, ISA_MIPS_R2
);
28495 gen_store_srsgpr(rt
, rd
);
28499 gen_reserved_instruction(ctx
);
28503 case OPC_BOVC
: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */
28504 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
28505 /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */
28506 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
28509 /* Arithmetic with immediate opcode */
28510 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
28514 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
28516 case OPC_SLTI
: /* Set on less than with immediate opcode */
28518 gen_slt_imm(ctx
, op
, rt
, rs
, imm
);
28520 case OPC_ANDI
: /* Arithmetic with immediate opcode */
28521 case OPC_LUI
: /* OPC_AUI */
28524 gen_logic_imm(ctx
, op
, rt
, rs
, imm
);
28526 case OPC_J
: /* Jump */
28528 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
28529 gen_compute_branch(ctx
, op
, 4, rs
, rt
, offset
, 4);
28532 case OPC_BLEZC
: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */
28533 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
28535 gen_reserved_instruction(ctx
);
28538 /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */
28539 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
28542 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
28545 case OPC_BGTZC
: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */
28546 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
28548 gen_reserved_instruction(ctx
);
28551 /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */
28552 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
28555 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
28558 case OPC_BLEZALC
: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */
28561 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
28563 check_insn(ctx
, ISA_MIPS_R6
);
28564 /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */
28565 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
28568 case OPC_BGTZALC
: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */
28571 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
28573 check_insn(ctx
, ISA_MIPS_R6
);
28574 /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */
28575 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
28580 check_insn(ctx
, ISA_MIPS2
);
28581 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
28585 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
28587 case OPC_LL
: /* Load and stores */
28588 check_insn(ctx
, ISA_MIPS2
);
28589 if (ctx
->insn_flags
& INSN_R5900
) {
28590 check_insn_opc_user_only(ctx
, INSN_R5900
);
28601 gen_ld(ctx
, op
, rt
, rs
, imm
);
28608 gen_st(ctx
, op
, rt
, rs
, imm
);
28611 check_insn(ctx
, ISA_MIPS2
);
28612 if (ctx
->insn_flags
& INSN_R5900
) {
28613 check_insn_opc_user_only(ctx
, INSN_R5900
);
28615 gen_st_cond(ctx
, rt
, rs
, imm
, MO_TESL
, false);
28618 check_cp0_enabled(ctx
);
28619 check_insn(ctx
, ISA_MIPS3
| ISA_MIPS_R1
);
28620 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
28621 gen_cache_operation(ctx
, rt
, rs
, imm
);
28623 /* Treat as NOP. */
28626 if (ctx
->insn_flags
& INSN_R5900
) {
28627 /* Treat as NOP. */
28629 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS_R1
);
28630 /* Treat as NOP. */
28634 /* Floating point (COP1). */
28639 gen_cop1_ldst(ctx
, op
, rt
, rs
, imm
);
28643 op1
= MASK_CP1(ctx
->opcode
);
28648 check_cp1_enabled(ctx
);
28649 check_insn(ctx
, ISA_MIPS_R2
);
28655 check_cp1_enabled(ctx
);
28656 gen_cp1(ctx
, op1
, rt
, rd
);
28658 #if defined(TARGET_MIPS64)
28661 check_cp1_enabled(ctx
);
28662 check_insn(ctx
, ISA_MIPS3
);
28663 check_mips_64(ctx
);
28664 gen_cp1(ctx
, op1
, rt
, rd
);
28667 case OPC_BC1EQZ
: /* OPC_BC1ANY2 */
28668 check_cp1_enabled(ctx
);
28669 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
28671 gen_compute_branch1_r6(ctx
, MASK_CP1(ctx
->opcode
),
28676 check_insn(ctx
, ASE_MIPS3D
);
28677 gen_compute_branch1(ctx
, MASK_BC1(ctx
->opcode
),
28678 (rt
>> 2) & 0x7, imm
<< 2);
28682 check_cp1_enabled(ctx
);
28683 check_insn(ctx
, ISA_MIPS_R6
);
28684 gen_compute_branch1_r6(ctx
, MASK_CP1(ctx
->opcode
),
28688 check_cp1_enabled(ctx
);
28689 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
28691 check_insn(ctx
, ASE_MIPS3D
);
28694 check_cp1_enabled(ctx
);
28695 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
28696 gen_compute_branch1(ctx
, MASK_BC1(ctx
->opcode
),
28697 (rt
>> 2) & 0x7, imm
<< 2);
28704 check_cp1_enabled(ctx
);
28705 gen_farith(ctx
, ctx
->opcode
& FOP(0x3f, 0x1f), rt
, rd
, sa
,
28711 int r6_op
= ctx
->opcode
& FOP(0x3f, 0x1f);
28712 check_cp1_enabled(ctx
);
28713 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
28715 case R6_OPC_CMP_AF_S
:
28716 case R6_OPC_CMP_UN_S
:
28717 case R6_OPC_CMP_EQ_S
:
28718 case R6_OPC_CMP_UEQ_S
:
28719 case R6_OPC_CMP_LT_S
:
28720 case R6_OPC_CMP_ULT_S
:
28721 case R6_OPC_CMP_LE_S
:
28722 case R6_OPC_CMP_ULE_S
:
28723 case R6_OPC_CMP_SAF_S
:
28724 case R6_OPC_CMP_SUN_S
:
28725 case R6_OPC_CMP_SEQ_S
:
28726 case R6_OPC_CMP_SEUQ_S
:
28727 case R6_OPC_CMP_SLT_S
:
28728 case R6_OPC_CMP_SULT_S
:
28729 case R6_OPC_CMP_SLE_S
:
28730 case R6_OPC_CMP_SULE_S
:
28731 case R6_OPC_CMP_OR_S
:
28732 case R6_OPC_CMP_UNE_S
:
28733 case R6_OPC_CMP_NE_S
:
28734 case R6_OPC_CMP_SOR_S
:
28735 case R6_OPC_CMP_SUNE_S
:
28736 case R6_OPC_CMP_SNE_S
:
28737 gen_r6_cmp_s(ctx
, ctx
->opcode
& 0x1f, rt
, rd
, sa
);
28739 case R6_OPC_CMP_AF_D
:
28740 case R6_OPC_CMP_UN_D
:
28741 case R6_OPC_CMP_EQ_D
:
28742 case R6_OPC_CMP_UEQ_D
:
28743 case R6_OPC_CMP_LT_D
:
28744 case R6_OPC_CMP_ULT_D
:
28745 case R6_OPC_CMP_LE_D
:
28746 case R6_OPC_CMP_ULE_D
:
28747 case R6_OPC_CMP_SAF_D
:
28748 case R6_OPC_CMP_SUN_D
:
28749 case R6_OPC_CMP_SEQ_D
:
28750 case R6_OPC_CMP_SEUQ_D
:
28751 case R6_OPC_CMP_SLT_D
:
28752 case R6_OPC_CMP_SULT_D
:
28753 case R6_OPC_CMP_SLE_D
:
28754 case R6_OPC_CMP_SULE_D
:
28755 case R6_OPC_CMP_OR_D
:
28756 case R6_OPC_CMP_UNE_D
:
28757 case R6_OPC_CMP_NE_D
:
28758 case R6_OPC_CMP_SOR_D
:
28759 case R6_OPC_CMP_SUNE_D
:
28760 case R6_OPC_CMP_SNE_D
:
28761 gen_r6_cmp_d(ctx
, ctx
->opcode
& 0x1f, rt
, rd
, sa
);
28764 gen_farith(ctx
, ctx
->opcode
& FOP(0x3f, 0x1f),
28765 rt
, rd
, sa
, (imm
>> 8) & 0x7);
28770 gen_farith(ctx
, ctx
->opcode
& FOP(0x3f, 0x1f), rt
, rd
, sa
,
28777 gen_reserved_instruction(ctx
);
28782 /* Compact branches [R6] and COP2 [non-R6] */
28783 case OPC_BC
: /* OPC_LWC2 */
28784 case OPC_BALC
: /* OPC_SWC2 */
28785 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
28786 /* OPC_BC, OPC_BALC */
28787 gen_compute_compact_branch(ctx
, op
, 0, 0,
28788 sextract32(ctx
->opcode
<< 2, 0, 28));
28789 } else if (ctx
->insn_flags
& ASE_LEXT
) {
28790 gen_loongson_lswc2(ctx
, rt
, rs
, rd
);
28792 /* OPC_LWC2, OPC_SWC2 */
28793 /* COP2: Not implemented. */
28794 generate_exception_err(ctx
, EXCP_CpU
, 2);
28797 case OPC_BEQZC
: /* OPC_JIC, OPC_LDC2 */
28798 case OPC_BNEZC
: /* OPC_JIALC, OPC_SDC2 */
28799 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
28801 /* OPC_BEQZC, OPC_BNEZC */
28802 gen_compute_compact_branch(ctx
, op
, rs
, 0,
28803 sextract32(ctx
->opcode
<< 2, 0, 23));
28805 /* OPC_JIC, OPC_JIALC */
28806 gen_compute_compact_branch(ctx
, op
, 0, rt
, imm
);
28808 } else if (ctx
->insn_flags
& ASE_LEXT
) {
28809 gen_loongson_lsdc2(ctx
, rt
, rs
, rd
);
28811 /* OPC_LWC2, OPC_SWC2 */
28812 /* COP2: Not implemented. */
28813 generate_exception_err(ctx
, EXCP_CpU
, 2);
28817 check_insn(ctx
, ASE_LMMI
);
28818 /* Note that these instructions use different fields. */
28819 gen_loongson_multimedia(ctx
, sa
, rd
, rt
);
28823 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
28824 check_cp1_enabled(ctx
);
28825 op1
= MASK_CP3(ctx
->opcode
);
28829 check_insn(ctx
, ISA_MIPS5
| ISA_MIPS_R2
);
28835 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS_R2
);
28836 gen_flt3_ldst(ctx
, op1
, sa
, rd
, rs
, rt
);
28839 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS_R2
);
28840 /* Treat as NOP. */
28843 check_insn(ctx
, ISA_MIPS5
| ISA_MIPS_R2
);
28857 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS_R2
);
28858 gen_flt3_arith(ctx
, op1
, sa
, rs
, rd
, rt
);
28862 gen_reserved_instruction(ctx
);
28866 generate_exception_err(ctx
, EXCP_CpU
, 1);
28870 #if defined(TARGET_MIPS64)
28871 /* MIPS64 opcodes */
28873 if (ctx
->insn_flags
& INSN_R5900
) {
28874 check_insn_opc_user_only(ctx
, INSN_R5900
);
28881 check_insn(ctx
, ISA_MIPS3
);
28882 check_mips_64(ctx
);
28883 gen_ld(ctx
, op
, rt
, rs
, imm
);
28888 check_insn(ctx
, ISA_MIPS3
);
28889 check_mips_64(ctx
);
28890 gen_st(ctx
, op
, rt
, rs
, imm
);
28893 check_insn(ctx
, ISA_MIPS3
);
28894 if (ctx
->insn_flags
& INSN_R5900
) {
28895 check_insn_opc_user_only(ctx
, INSN_R5900
);
28897 check_mips_64(ctx
);
28898 gen_st_cond(ctx
, rt
, rs
, imm
, MO_TEQ
, false);
28900 case OPC_BNVC
: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */
28901 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
28902 /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */
28903 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
28906 check_insn(ctx
, ISA_MIPS3
);
28907 check_mips_64(ctx
);
28908 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
28912 check_insn(ctx
, ISA_MIPS3
);
28913 check_mips_64(ctx
);
28914 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
28917 case OPC_BNVC
: /* OPC_BNEZALC, OPC_BNEC */
28918 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
28919 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
28921 MIPS_INVAL("major opcode");
28922 gen_reserved_instruction(ctx
);
28926 case OPC_DAUI
: /* OPC_JALX */
28927 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
28928 #if defined(TARGET_MIPS64)
28930 check_mips_64(ctx
);
28932 generate_exception(ctx
, EXCP_RI
);
28933 } else if (rt
!= 0) {
28934 TCGv t0
= tcg_temp_new();
28935 gen_load_gpr(t0
, rs
);
28936 tcg_gen_addi_tl(cpu_gpr
[rt
], t0
, imm
<< 16);
28940 gen_reserved_instruction(ctx
);
28941 MIPS_INVAL("major opcode");
28945 check_insn(ctx
, ASE_MIPS16
| ASE_MICROMIPS
);
28946 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
28947 gen_compute_branch(ctx
, op
, 4, rs
, rt
, offset
, 4);
28950 case OPC_MDMX
: /* MMI_OPC_LQ */
28951 if (ctx
->insn_flags
& INSN_R5900
) {
28952 #if defined(TARGET_MIPS64)
28953 gen_mmi_lq(env
, ctx
);
28956 /* MDMX: Not implemented. */
28960 check_insn(ctx
, ISA_MIPS_R6
);
28961 gen_pcrel(ctx
, ctx
->opcode
, ctx
->base
.pc_next
, rs
);
28963 default: /* Invalid */
28964 MIPS_INVAL("major opcode");
28970 static void decode_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
28972 /* make sure instructions are on a word boundary */
28973 if (ctx
->base
.pc_next
& 0x3) {
28974 env
->CP0_BadVAddr
= ctx
->base
.pc_next
;
28975 generate_exception_err(ctx
, EXCP_AdEL
, EXCP_INST_NOTAVAIL
);
28979 /* Handle blikely not taken case */
28980 if ((ctx
->hflags
& MIPS_HFLAG_BMASK_BASE
) == MIPS_HFLAG_BL
) {
28981 TCGLabel
*l1
= gen_new_label();
28983 tcg_gen_brcondi_tl(TCG_COND_NE
, bcond
, 0, l1
);
28984 tcg_gen_movi_i32(hflags
, ctx
->hflags
& ~MIPS_HFLAG_BMASK
);
28985 gen_goto_tb(ctx
, 1, ctx
->base
.pc_next
+ 4);
28989 /* Transition to the auto-generated decoder. */
28991 /* ISA extensions */
28992 if (ase_msa_available(env
) && decode_ase_msa(ctx
, ctx
->opcode
)) {
28996 /* ISA (from latest to oldest) */
28997 if (cpu_supports_isa(env
, ISA_MIPS_R6
) && decode_isa_rel6(ctx
, ctx
->opcode
)) {
29001 if (decode_opc_legacy(env
, ctx
)) {
29005 gen_reserved_instruction(ctx
);
29008 static void mips_tr_init_disas_context(DisasContextBase
*dcbase
, CPUState
*cs
)
29010 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
29011 CPUMIPSState
*env
= cs
->env_ptr
;
29013 ctx
->page_start
= ctx
->base
.pc_first
& TARGET_PAGE_MASK
;
29014 ctx
->saved_pc
= -1;
29015 ctx
->insn_flags
= env
->insn_flags
;
29016 ctx
->CP0_Config1
= env
->CP0_Config1
;
29017 ctx
->CP0_Config2
= env
->CP0_Config2
;
29018 ctx
->CP0_Config3
= env
->CP0_Config3
;
29019 ctx
->CP0_Config5
= env
->CP0_Config5
;
29021 ctx
->kscrexist
= (env
->CP0_Config4
>> CP0C4_KScrExist
) & 0xff;
29022 ctx
->rxi
= (env
->CP0_Config3
>> CP0C3_RXI
) & 1;
29023 ctx
->ie
= (env
->CP0_Config4
>> CP0C4_IE
) & 3;
29024 ctx
->bi
= (env
->CP0_Config3
>> CP0C3_BI
) & 1;
29025 ctx
->bp
= (env
->CP0_Config3
>> CP0C3_BP
) & 1;
29026 ctx
->PAMask
= env
->PAMask
;
29027 ctx
->mvh
= (env
->CP0_Config5
>> CP0C5_MVH
) & 1;
29028 ctx
->eva
= (env
->CP0_Config5
>> CP0C5_EVA
) & 1;
29029 ctx
->sc
= (env
->CP0_Config3
>> CP0C3_SC
) & 1;
29030 ctx
->CP0_LLAddr_shift
= env
->CP0_LLAddr_shift
;
29031 ctx
->cmgcr
= (env
->CP0_Config3
>> CP0C3_CMGCR
) & 1;
29032 /* Restore delay slot state from the tb context. */
29033 ctx
->hflags
= (uint32_t)ctx
->base
.tb
->flags
; /* FIXME: maybe use 64 bits? */
29034 ctx
->ulri
= (env
->CP0_Config3
>> CP0C3_ULRI
) & 1;
29035 ctx
->ps
= ((env
->active_fpu
.fcr0
>> FCR0_PS
) & 1) ||
29036 (env
->insn_flags
& (INSN_LOONGSON2E
| INSN_LOONGSON2F
));
29037 ctx
->vp
= (env
->CP0_Config5
>> CP0C5_VP
) & 1;
29038 ctx
->mrp
= (env
->CP0_Config5
>> CP0C5_MRP
) & 1;
29039 ctx
->nan2008
= (env
->active_fpu
.fcr31
>> FCR31_NAN2008
) & 1;
29040 ctx
->abs2008
= (env
->active_fpu
.fcr31
>> FCR31_ABS2008
) & 1;
29041 ctx
->mi
= (env
->CP0_Config5
>> CP0C5_MI
) & 1;
29042 ctx
->gi
= (env
->CP0_Config5
>> CP0C5_GI
) & 3;
29043 restore_cpu_state(env
, ctx
);
29044 #ifdef CONFIG_USER_ONLY
29045 ctx
->mem_idx
= MIPS_HFLAG_UM
;
29047 ctx
->mem_idx
= hflags_mmu_index(ctx
->hflags
);
29049 ctx
->default_tcg_memop_mask
= (ctx
->insn_flags
& (ISA_MIPS_R6
|
29050 INSN_LOONGSON3A
)) ? MO_UNALN
: MO_ALIGN
;
29052 LOG_DISAS("\ntb %p idx %d hflags %04x\n", ctx
->base
.tb
, ctx
->mem_idx
,
29056 static void mips_tr_tb_start(DisasContextBase
*dcbase
, CPUState
*cs
)
29060 static void mips_tr_insn_start(DisasContextBase
*dcbase
, CPUState
*cs
)
29062 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
29064 tcg_gen_insn_start(ctx
->base
.pc_next
, ctx
->hflags
& MIPS_HFLAG_BMASK
,
29068 static bool mips_tr_breakpoint_check(DisasContextBase
*dcbase
, CPUState
*cs
,
29069 const CPUBreakpoint
*bp
)
29071 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
29073 save_cpu_state(ctx
, 1);
29074 ctx
->base
.is_jmp
= DISAS_NORETURN
;
29075 gen_helper_raise_exception_debug(cpu_env
);
29077 * The address covered by the breakpoint must be included in
29078 * [tb->pc, tb->pc + tb->size) in order to for it to be
29079 * properly cleared -- thus we increment the PC here so that
29080 * the logic setting tb->size below does the right thing.
29082 ctx
->base
.pc_next
+= 4;
29086 static void mips_tr_translate_insn(DisasContextBase
*dcbase
, CPUState
*cs
)
29088 CPUMIPSState
*env
= cs
->env_ptr
;
29089 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
29093 is_slot
= ctx
->hflags
& MIPS_HFLAG_BMASK
;
29094 if (ctx
->insn_flags
& ISA_NANOMIPS32
) {
29095 ctx
->opcode
= translator_lduw(env
, ctx
->base
.pc_next
);
29096 insn_bytes
= decode_nanomips_opc(env
, ctx
);
29097 } else if (!(ctx
->hflags
& MIPS_HFLAG_M16
)) {
29098 ctx
->opcode
= translator_ldl(env
, ctx
->base
.pc_next
);
29100 decode_opc(env
, ctx
);
29101 } else if (ctx
->insn_flags
& ASE_MICROMIPS
) {
29102 ctx
->opcode
= translator_lduw(env
, ctx
->base
.pc_next
);
29103 insn_bytes
= decode_micromips_opc(env
, ctx
);
29104 } else if (ctx
->insn_flags
& ASE_MIPS16
) {
29105 ctx
->opcode
= translator_lduw(env
, ctx
->base
.pc_next
);
29106 insn_bytes
= decode_mips16_opc(env
, ctx
);
29108 gen_reserved_instruction(ctx
);
29109 g_assert(ctx
->base
.is_jmp
== DISAS_NORETURN
);
29113 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
29114 if (!(ctx
->hflags
& (MIPS_HFLAG_BDS16
| MIPS_HFLAG_BDS32
|
29115 MIPS_HFLAG_FBNSLOT
))) {
29117 * Force to generate branch as there is neither delay nor
29122 if ((ctx
->hflags
& MIPS_HFLAG_M16
) &&
29123 (ctx
->hflags
& MIPS_HFLAG_FBNSLOT
)) {
29125 * Force to generate branch as microMIPS R6 doesn't restrict
29126 * branches in the forbidden slot.
29132 gen_branch(ctx
, insn_bytes
);
29134 ctx
->base
.pc_next
+= insn_bytes
;
29136 if (ctx
->base
.is_jmp
!= DISAS_NEXT
) {
29140 * Execute a branch and its delay slot as a single instruction.
29141 * This is what GDB expects and is consistent with what the
29142 * hardware does (e.g. if a delay slot instruction faults, the
29143 * reported PC is the PC of the branch).
29145 if (ctx
->base
.singlestep_enabled
&&
29146 (ctx
->hflags
& MIPS_HFLAG_BMASK
) == 0) {
29147 ctx
->base
.is_jmp
= DISAS_TOO_MANY
;
29149 if (ctx
->base
.pc_next
- ctx
->page_start
>= TARGET_PAGE_SIZE
) {
29150 ctx
->base
.is_jmp
= DISAS_TOO_MANY
;
29154 static void mips_tr_tb_stop(DisasContextBase
*dcbase
, CPUState
*cs
)
29156 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
29158 if (ctx
->base
.singlestep_enabled
&& ctx
->base
.is_jmp
!= DISAS_NORETURN
) {
29159 save_cpu_state(ctx
, ctx
->base
.is_jmp
!= DISAS_EXIT
);
29160 gen_helper_raise_exception_debug(cpu_env
);
29162 switch (ctx
->base
.is_jmp
) {
29164 gen_save_pc(ctx
->base
.pc_next
);
29165 tcg_gen_lookup_and_goto_ptr();
29168 case DISAS_TOO_MANY
:
29169 save_cpu_state(ctx
, 0);
29170 gen_goto_tb(ctx
, 0, ctx
->base
.pc_next
);
29173 tcg_gen_exit_tb(NULL
, 0);
29175 case DISAS_NORETURN
:
29178 g_assert_not_reached();
29183 static void mips_tr_disas_log(const DisasContextBase
*dcbase
, CPUState
*cs
)
29185 qemu_log("IN: %s\n", lookup_symbol(dcbase
->pc_first
));
29186 log_target_disas(cs
, dcbase
->pc_first
, dcbase
->tb
->size
);
29189 static const TranslatorOps mips_tr_ops
= {
29190 .init_disas_context
= mips_tr_init_disas_context
,
29191 .tb_start
= mips_tr_tb_start
,
29192 .insn_start
= mips_tr_insn_start
,
29193 .breakpoint_check
= mips_tr_breakpoint_check
,
29194 .translate_insn
= mips_tr_translate_insn
,
29195 .tb_stop
= mips_tr_tb_stop
,
29196 .disas_log
= mips_tr_disas_log
,
29199 void gen_intermediate_code(CPUState
*cs
, TranslationBlock
*tb
, int max_insns
)
29203 translator_loop(&mips_tr_ops
, &ctx
.base
, cs
, tb
, max_insns
);
29206 static void fpu_dump_state(CPUMIPSState
*env
, FILE * f
, int flags
)
29209 int is_fpu64
= !!(env
->hflags
& MIPS_HFLAG_F64
);
29211 #define printfpr(fp) \
29214 qemu_fprintf(f, "w:%08x d:%016" PRIx64 \
29215 " fd:%13g fs:%13g psu: %13g\n", \
29216 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
29217 (double)(fp)->fd, \
29218 (double)(fp)->fs[FP_ENDIAN_IDX], \
29219 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
29222 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
29223 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
29224 qemu_fprintf(f, "w:%08x d:%016" PRIx64 \
29225 " fd:%13g fs:%13g psu:%13g\n", \
29226 tmp.w[FP_ENDIAN_IDX], tmp.d, \
29228 (double)tmp.fs[FP_ENDIAN_IDX], \
29229 (double)tmp.fs[!FP_ENDIAN_IDX]); \
29235 "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
29236 env
->active_fpu
.fcr0
, env
->active_fpu
.fcr31
, is_fpu64
,
29237 get_float_exception_flags(&env
->active_fpu
.fp_status
));
29238 for (i
= 0; i
< 32; (is_fpu64
) ? i
++ : (i
+= 2)) {
29239 qemu_fprintf(f
, "%3s: ", fregnames
[i
]);
29240 printfpr(&env
->active_fpu
.fpr
[i
]);
29246 void mips_cpu_dump_state(CPUState
*cs
, FILE *f
, int flags
)
29248 MIPSCPU
*cpu
= MIPS_CPU(cs
);
29249 CPUMIPSState
*env
= &cpu
->env
;
29252 qemu_fprintf(f
, "pc=0x" TARGET_FMT_lx
" HI=0x" TARGET_FMT_lx
29253 " LO=0x" TARGET_FMT_lx
" ds %04x "
29254 TARGET_FMT_lx
" " TARGET_FMT_ld
"\n",
29255 env
->active_tc
.PC
, env
->active_tc
.HI
[0], env
->active_tc
.LO
[0],
29256 env
->hflags
, env
->btarget
, env
->bcond
);
29257 for (i
= 0; i
< 32; i
++) {
29258 if ((i
& 3) == 0) {
29259 qemu_fprintf(f
, "GPR%02d:", i
);
29261 qemu_fprintf(f
, " %s " TARGET_FMT_lx
,
29262 regnames
[i
], env
->active_tc
.gpr
[i
]);
29263 if ((i
& 3) == 3) {
29264 qemu_fprintf(f
, "\n");
29268 qemu_fprintf(f
, "CP0 Status 0x%08x Cause 0x%08x EPC 0x"
29269 TARGET_FMT_lx
"\n",
29270 env
->CP0_Status
, env
->CP0_Cause
, env
->CP0_EPC
);
29271 qemu_fprintf(f
, " Config0 0x%08x Config1 0x%08x LLAddr 0x%016"
29273 env
->CP0_Config0
, env
->CP0_Config1
, env
->CP0_LLAddr
);
29274 qemu_fprintf(f
, " Config2 0x%08x Config3 0x%08x\n",
29275 env
->CP0_Config2
, env
->CP0_Config3
);
29276 qemu_fprintf(f
, " Config4 0x%08x Config5 0x%08x\n",
29277 env
->CP0_Config4
, env
->CP0_Config5
);
29278 if ((flags
& CPU_DUMP_FPU
) && (env
->hflags
& MIPS_HFLAG_FPU
)) {
29279 fpu_dump_state(env
, f
, flags
);
29283 void mips_tcg_init(void)
29288 for (i
= 1; i
< 32; i
++)
29289 cpu_gpr
[i
] = tcg_global_mem_new(cpu_env
,
29290 offsetof(CPUMIPSState
,
29293 #if defined(TARGET_MIPS64)
29294 cpu_gpr_hi
[0] = NULL
;
29296 for (unsigned i
= 1; i
< 32; i
++) {
29297 g_autofree
char *rname
= g_strdup_printf("%s[hi]", regnames
[i
]);
29299 cpu_gpr_hi
[i
] = tcg_global_mem_new_i64(cpu_env
,
29300 offsetof(CPUMIPSState
,
29301 active_tc
.gpr_hi
[i
]),
29304 #endif /* !TARGET_MIPS64 */
29305 for (i
= 0; i
< 32; i
++) {
29306 int off
= offsetof(CPUMIPSState
, active_fpu
.fpr
[i
].wr
.d
[0]);
29308 fpu_f64
[i
] = tcg_global_mem_new_i64(cpu_env
, off
, fregnames
[i
]);
29310 msa_translate_init();
29311 cpu_PC
= tcg_global_mem_new(cpu_env
,
29312 offsetof(CPUMIPSState
, active_tc
.PC
), "PC");
29313 for (i
= 0; i
< MIPS_DSP_ACC
; i
++) {
29314 cpu_HI
[i
] = tcg_global_mem_new(cpu_env
,
29315 offsetof(CPUMIPSState
, active_tc
.HI
[i
]),
29317 cpu_LO
[i
] = tcg_global_mem_new(cpu_env
,
29318 offsetof(CPUMIPSState
, active_tc
.LO
[i
]),
29321 cpu_dspctrl
= tcg_global_mem_new(cpu_env
,
29322 offsetof(CPUMIPSState
,
29323 active_tc
.DSPControl
),
29325 bcond
= tcg_global_mem_new(cpu_env
,
29326 offsetof(CPUMIPSState
, bcond
), "bcond");
29327 btarget
= tcg_global_mem_new(cpu_env
,
29328 offsetof(CPUMIPSState
, btarget
), "btarget");
29329 hflags
= tcg_global_mem_new_i32(cpu_env
,
29330 offsetof(CPUMIPSState
, hflags
), "hflags");
29332 fpu_fcr0
= tcg_global_mem_new_i32(cpu_env
,
29333 offsetof(CPUMIPSState
, active_fpu
.fcr0
),
29335 fpu_fcr31
= tcg_global_mem_new_i32(cpu_env
,
29336 offsetof(CPUMIPSState
, active_fpu
.fcr31
),
29338 cpu_lladdr
= tcg_global_mem_new(cpu_env
, offsetof(CPUMIPSState
, lladdr
),
29340 cpu_llval
= tcg_global_mem_new(cpu_env
, offsetof(CPUMIPSState
, llval
),
29343 #if !defined(TARGET_MIPS64)
29344 for (i
= 0; i
< NUMBER_OF_MXU_REGISTERS
- 1; i
++) {
29345 mxu_gpr
[i
] = tcg_global_mem_new(cpu_env
,
29346 offsetof(CPUMIPSState
,
29347 active_tc
.mxu_gpr
[i
]),
29351 mxu_CR
= tcg_global_mem_new(cpu_env
,
29352 offsetof(CPUMIPSState
, active_tc
.mxu_cr
),
29353 mxuregnames
[NUMBER_OF_MXU_REGISTERS
- 1]);
29354 #endif /* !TARGET_MIPS64 */
29357 void restore_state_to_opc(CPUMIPSState
*env
, TranslationBlock
*tb
,
29358 target_ulong
*data
)
29360 env
->active_tc
.PC
= data
[0];
29361 env
->hflags
&= ~MIPS_HFLAG_BMASK
;
29362 env
->hflags
|= data
[1];
29363 switch (env
->hflags
& MIPS_HFLAG_BMASK_BASE
) {
29364 case MIPS_HFLAG_BR
:
29366 case MIPS_HFLAG_BC
:
29367 case MIPS_HFLAG_BL
:
29369 env
->btarget
= data
[2];